[platform] add zybo and vexpress-a9 support for the VM
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <platform/vexpress-a9.h>
|
||||
|
||||
#define GICBASE(n) (CPUPRIV_BASE)
|
||||
#define GICBASE(n) (CPUPRIV_BASE_VIRT)
|
||||
#define GICC_OFFSET (0x0100)
|
||||
#define GICD_OFFSET (0x1000)
|
||||
|
||||
|
||||
@@ -23,22 +23,37 @@
|
||||
#pragma once
|
||||
|
||||
/* memory map of the motherboard */
|
||||
#define MOTHERBOARD_CS0 (0x40000000)
|
||||
#define MOTHERBOARD_CS1 (0x44000000)
|
||||
#define MOTHERBOARD_CS2 (0x48000000)
|
||||
#define MOTHERBOARD_CS3 (0x4c000000)
|
||||
#define MOTHERBOARD_CS4 (0x50000000)
|
||||
#define MOTHERBOARD_CS5 (0x54000000)
|
||||
#define MOTHERBOARD_CS6 (0x58000000)
|
||||
#define MOTHERBOARD_CS7 (0x10000000)
|
||||
#define MOTHERBOARD_CS0_PHYS (0x40000000)
|
||||
#define MOTHERBOARD_CS1_PHYS (0x44000000)
|
||||
#define MOTHERBOARD_CS2_PHYS (0x48000000)
|
||||
#define MOTHERBOARD_CS3_PHYS (0x4c000000)
|
||||
#define MOTHERBOARD_CS4_PHYS (0x50000000)
|
||||
#define MOTHERBOARD_CS5_PHYS (0x54000000)
|
||||
#define MOTHERBOARD_CS6_PHYS (0x58000000)
|
||||
#define MOTHERBOARD_CS7_PHYS (0x10000000)
|
||||
#define MOTHERBOARD_CS_SIZE (0x04000000)
|
||||
|
||||
#define MOTHERBOARD_CS0_VIRT (0xe0000000)
|
||||
#define MOTHERBOARD_CS1_VIRT (0xe4000000)
|
||||
#define MOTHERBOARD_CS2_VIRT (0xe8000000)
|
||||
#define MOTHERBOARD_CS3_VIRT (0xec000000)
|
||||
#define MOTHERBOARD_CS4_VIRT (0xf0000000)
|
||||
#define MOTHERBOARD_CS5_VIRT (0xf4000000)
|
||||
#define MOTHERBOARD_CS6_VIRT (0xf8000000)
|
||||
#define MOTHERBOARD_CS7_VIRT (0xfc000000)
|
||||
|
||||
#define SDRAM_BASE (0x60000000)
|
||||
#define SDRAM_APERTURE_SIZE (0x40000000)
|
||||
|
||||
/* most of the peripherals live on the motherboard CS7 */
|
||||
#define UART0_BASE (MOTHERBOARD_CS7 + 0x9000)
|
||||
#define UART1_BASE (MOTHERBOARD_CS7 + 0xa000)
|
||||
#define UART2_BASE (MOTHERBOARD_CS7 + 0xb000)
|
||||
#define UART3_BASE (MOTHERBOARD_CS7 + 0xc000)
|
||||
#define UART0_BASE (MOTHERBOARD_CS7_VIRT + 0x9000)
|
||||
#define UART1_BASE (MOTHERBOARD_CS7_VIRT + 0xa000)
|
||||
#define UART2_BASE (MOTHERBOARD_CS7_VIRT + 0xb000)
|
||||
#define UART3_BASE (MOTHERBOARD_CS7_VIRT + 0xc000)
|
||||
|
||||
#define CPUPRIV_BASE (0x1e000000)
|
||||
#define CPUPRIV_SIZE (0x00100000)
|
||||
#define CPUPRIV_BASE_PHYS (0x1e000000)
|
||||
#define CPUPRIV_BASE_VIRT (MOTHERBOARD_CS0_VIRT - CPUPRIV_SIZE)
|
||||
|
||||
/* interrupts */
|
||||
#define ARM_GENERIC_TIMER_INT 29
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Travis Geiselbrecht
|
||||
* Copyright (c) 2012-2014 Travis Geiselbrecht
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
@@ -29,12 +29,62 @@
|
||||
#include <dev/timer/arm_cortex_a9.h>
|
||||
#include <dev/uart.h>
|
||||
#include <lk/init.h>
|
||||
#include <kernel/vm.h>
|
||||
#include <platform.h>
|
||||
#include <platform/gic.h>
|
||||
#include <platform/interrupts.h>
|
||||
#include <platform/vexpress-a9.h>
|
||||
#include "platform_p.h"
|
||||
|
||||
#define SDRAM_SIZE (512*1024*1024) // XXX get this from the emulator somehow
|
||||
|
||||
/* initial memory mappings. parsed by start.S */
|
||||
struct mmu_initial_mapping mmu_initial_mappings[] = {
|
||||
/* 1GB of sdram space */
|
||||
{ .phys = SDRAM_BASE,
|
||||
.virt = KERNEL_BASE,
|
||||
.size = SDRAM_SIZE,
|
||||
.flags = 0,
|
||||
.name = "memory" },
|
||||
|
||||
/* CS0 - CS6 devices */
|
||||
{ .phys = MOTHERBOARD_CS0_PHYS,
|
||||
.virt = MOTHERBOARD_CS0_VIRT,
|
||||
.size = MOTHERBOARD_CS_SIZE * 7,
|
||||
.flags = MMU_INITIAL_MAPPING_FLAG_DEVICE,
|
||||
.name = "cs0-cs6" },
|
||||
|
||||
/* CS7 devices */
|
||||
{ .phys = MOTHERBOARD_CS7_PHYS,
|
||||
.virt = MOTHERBOARD_CS7_VIRT,
|
||||
.size = MOTHERBOARD_CS_SIZE,
|
||||
.flags = MMU_INITIAL_MAPPING_FLAG_DEVICE,
|
||||
.name = "cs7" },
|
||||
|
||||
/* cortex-a9 private memory area */
|
||||
{ .phys = CPUPRIV_BASE_PHYS,
|
||||
.virt = CPUPRIV_BASE_VIRT,
|
||||
.size = CPUPRIV_SIZE,
|
||||
.flags = MMU_INITIAL_MAPPING_FLAG_DEVICE,
|
||||
.name = "cpu_priv"},
|
||||
|
||||
/* identity map to let the boot code run */
|
||||
{ .phys = SDRAM_BASE,
|
||||
.virt = SDRAM_BASE,
|
||||
.size = 16*1024*1024,
|
||||
.flags = MMU_INITIAL_MAPPING_TEMPORARY },
|
||||
|
||||
/* null entry to terminate the list */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static pmm_arena_t arena = {
|
||||
.name = "sdram",
|
||||
.base = SDRAM_BASE,
|
||||
.size = SDRAM_SIZE,
|
||||
.flags = PMM_ARENA_FLAG_KMAP,
|
||||
};
|
||||
|
||||
void platform_init_mmu_mappings(void)
|
||||
{
|
||||
}
|
||||
@@ -45,9 +95,12 @@ void platform_early_init(void)
|
||||
arm_gic_init();
|
||||
|
||||
/* initialize the timer block */
|
||||
arm_cortex_a9_timer_init(CPUPRIV_BASE, 100000000);
|
||||
arm_cortex_a9_timer_init(CPUPRIV_BASE_VIRT, 100000000);
|
||||
|
||||
uart_init_early();
|
||||
|
||||
/* add the main memory arena */
|
||||
pmm_add_arena(&arena);
|
||||
}
|
||||
|
||||
void platform_init(void)
|
||||
|
||||
@@ -22,14 +22,15 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
#include <reg.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/* memory addresses */
|
||||
#define SDRAM_BASE (0)
|
||||
#define SDRAM_APERTURE_SIZE (0x40000000)
|
||||
#define SRAM_BASE (0xfffc0000)
|
||||
/* assumes sram is mapped at 0 the first MB of sdram is covered by it */
|
||||
#define SDRAM_BASE (0x00100000)
|
||||
#define SDRAM_APERTURE_SIZE (0x3ff00000)
|
||||
#define SRAM_BASE (0x0)
|
||||
#define SRAM_APERTURE_SIZE (0x00040000)
|
||||
|
||||
/* hardware base addresses */
|
||||
@@ -104,7 +105,9 @@
|
||||
|
||||
#define SCL 0x00000000
|
||||
#define SLCR_LOCK 0x00000004
|
||||
#define SLCR_LOCK_KEY 0x767b
|
||||
#define SLCR_UNLOCK 0x00000008
|
||||
#define SLCR_UNLOCK_KEY 0xdf0d
|
||||
#define SLCR_LOCKSTA 0x0000000c
|
||||
#define ARM_PLL_CTRL 0x00000100
|
||||
#define DDR_PLL_CTRL 0x00000104
|
||||
@@ -265,6 +268,11 @@
|
||||
#define DDRIOB_DCI_CTRL 0x00000B70
|
||||
#define DDRIOB_DCI_STATU 0x00000B74
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
static inline void zynq_slcr_unlock(void) { SLCR_REG(SLCR_UNLOCK) = 0xdf0d; }
|
||||
static inline void zynq_slcr_lock(void) { SLCR_REG(SLCR_LOCK) = 0x767b; }
|
||||
|
||||
@@ -306,4 +314,5 @@ enum zynq_periph {
|
||||
|
||||
status_t zynq_set_clock(enum zynq_periph, bool enable, enum zynq_clock_source, uint32_t divisor, uint32_t divisor2);
|
||||
uint32_t zynq_get_clock(enum zynq_periph);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <debug.h>
|
||||
#include <stdio.h>
|
||||
#include <arch/arm/mmu.h>
|
||||
#include <kernel/vm.h>
|
||||
#include <dev/uart.h>
|
||||
#include <dev/interrupt/arm_gic.h>
|
||||
#include <dev/timer/arm_cortex_a9.h>
|
||||
@@ -34,14 +35,75 @@
|
||||
/* target can specify this as the initial jam table to set up the soc */
|
||||
__WEAK void ps7_init(void) { }
|
||||
|
||||
STATIC_ASSERT(IS_ALIGNED(SDRAM_BASE, MB));
|
||||
STATIC_ASSERT(IS_ALIGNED(SDRAM_SIZE, MB));
|
||||
|
||||
/* initial memory mappings. parsed by start.S */
|
||||
struct mmu_initial_mapping mmu_initial_mappings[] = {
|
||||
/* 1GB of sram + sdram space */
|
||||
{ .phys = SRAM_BASE,
|
||||
.virt = KERNEL_BASE,
|
||||
.size = MB + SDRAM_SIZE - MB,
|
||||
.flags = 0,
|
||||
.name = "memory" },
|
||||
|
||||
/* 0xe0000000 hardware devices */
|
||||
{ .phys = 0xe0000000,
|
||||
.virt = 0xe0000000,
|
||||
.size = 0x00300000,
|
||||
.flags = MMU_INITIAL_MAPPING_FLAG_DEVICE,
|
||||
.name = "hw" },
|
||||
|
||||
/* 0xe1000000 hardware devices */
|
||||
{ .phys = 0xe1000000,
|
||||
.virt = 0xe1000000,
|
||||
.size = 0x05000000,
|
||||
.flags = MMU_INITIAL_MAPPING_FLAG_DEVICE,
|
||||
.name = "hw" },
|
||||
|
||||
/* 0xf8000000 hardware devices */
|
||||
{ .phys = 0xf8000000,
|
||||
.virt = 0xf8000000,
|
||||
.size = 0x01000000,
|
||||
.flags = MMU_INITIAL_MAPPING_FLAG_DEVICE,
|
||||
.name = "hw" },
|
||||
|
||||
/* 0xfc000000 hardware devices */
|
||||
{ .phys = 0xfc000000,
|
||||
.virt = 0xfc000000,
|
||||
.size = 0x02000000,
|
||||
.flags = MMU_INITIAL_MAPPING_FLAG_DEVICE,
|
||||
.name = "hw" },
|
||||
|
||||
/* identity map to let the boot code run */
|
||||
{ .phys = SRAM_BASE,
|
||||
.virt = SRAM_BASE,
|
||||
.size = MB,
|
||||
.flags = MMU_INITIAL_MAPPING_TEMPORARY },
|
||||
|
||||
/* null entry to terminate the list */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#if SDRAM_SIZE != 0
|
||||
static pmm_arena_t sdram_arena = {
|
||||
.name = "sdram",
|
||||
.base = SDRAM_BASE,
|
||||
.size = SDRAM_SIZE - MB,
|
||||
.flags = PMM_ARENA_FLAG_KMAP
|
||||
};
|
||||
#endif
|
||||
|
||||
static pmm_arena_t sram_arena = {
|
||||
.name = "sram",
|
||||
.base = SRAM_BASE,
|
||||
.size = MEMSIZE,
|
||||
.priority = 1,
|
||||
.flags = PMM_ARENA_FLAG_KMAP
|
||||
};
|
||||
|
||||
void platform_init_mmu_mappings(void)
|
||||
{
|
||||
#define MB (1024*1024)
|
||||
|
||||
/* map dram as full cacheable */
|
||||
for (addr_t a = SDRAM_BASE; a < (SDRAM_BASE + SDRAM_APERTURE_SIZE); a += MB) {
|
||||
arm_mmu_map_section(a, a, MMU_MEMORY_L1_TYPE_NORMAL_WRITE_BACK_ALLOCATE | MMU_MEMORY_L1_AP_P_RW_U_NA);
|
||||
}
|
||||
}
|
||||
|
||||
void platform_early_init(void)
|
||||
@@ -59,6 +121,21 @@ void platform_early_init(void)
|
||||
|
||||
/* initialize the timer block */
|
||||
arm_cortex_a9_timer_init(CPUPRIV_BASE, zynq_get_arm_timer_freq());
|
||||
|
||||
/* add the main memory arena */
|
||||
#if SDRAM_SIZE != 0
|
||||
/* since we have a discontinuity between the end of SRAM (256K) and the start of SDRAM (1MB),
|
||||
* intentionally bump the boot-time allocator to start in the base of SDRAM.
|
||||
*/
|
||||
extern uintptr_t boot_alloc_start;
|
||||
extern uintptr_t boot_alloc_end;
|
||||
|
||||
boot_alloc_start = KERNEL_BASE + MB;
|
||||
boot_alloc_end = KERNEL_BASE + MB;
|
||||
|
||||
pmm_add_arena(&sdram_arena);
|
||||
#endif
|
||||
pmm_add_arena(&sram_arena);
|
||||
}
|
||||
|
||||
void platform_init(void)
|
||||
|
||||
@@ -18,20 +18,27 @@ MODULE_SRCS += \
|
||||
$(LOCAL_DIR)/clocks.c \
|
||||
$(LOCAL_DIR)/debug.c \
|
||||
$(LOCAL_DIR)/platform.c \
|
||||
$(LOCAL_DIR)/start.S \
|
||||
$(LOCAL_DIR)/uart.c \
|
||||
$(LOCAL_DIR)/fpga.c
|
||||
|
||||
# default to no sdram unless the target calls it out
|
||||
ZYNQ_SDRAM_SIZE ?= 0
|
||||
|
||||
ifeq ($(ZYNQ_USE_SRAM),1)
|
||||
MEMBASE := 0x0
|
||||
MEMSIZE ?= 0x40000 # 256KB
|
||||
MEMSIZE := 0x30000 # 3 * 64K
|
||||
else
|
||||
MEMBASE := 0x0
|
||||
MEMSIZE ?= 0x10000000 # 256MB
|
||||
# XXX untested path
|
||||
MEMBASE := 0x00000000
|
||||
MEMSIZE ?= $(ZYNQ_SDRAM_SIZE) # 256MB
|
||||
#KERNEL_LOAD_OFFSET := 0x00100000 # loaded 1MB into physical space
|
||||
endif
|
||||
|
||||
GLOBAL_DEFINES += \
|
||||
MEMBASE=$(MEMBASE) \
|
||||
MEMSIZE=$(MEMSIZE)
|
||||
MEMSIZE=$(MEMSIZE) \
|
||||
SDRAM_SIZE=$(ZYNQ_SDRAM_SIZE)
|
||||
|
||||
LINKER_SCRIPT += \
|
||||
$(BUILDDIR)/system-onesegment.ld
|
||||
|
||||
88
platform/zynq/start.S
Normal file
88
platform/zynq/start.S
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Travis Geiselbrecht
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <asm.h>
|
||||
#include <platform/zynq.h>
|
||||
|
||||
/* this code attempts to remap sram to 0xfffc0000 - 0xffffffff and
|
||||
branch the cpu into the equivalent spot. Assumes the cpu is running
|
||||
at the initial 0 based mapping */
|
||||
|
||||
/* disabled for now */
|
||||
#if 0
|
||||
|
||||
/* a spot of the top bank of OCM memory for us to run our code from
|
||||
needs to be below where the second cpu is running (0xffffe00-0xfffffff0) */
|
||||
#define TARGET_SPOT 0xfffff800
|
||||
|
||||
/* first piece of code run out of the reset vector. use
|
||||
to relocate sram to the final location at 0xfffc0000
|
||||
and switch to there */
|
||||
FUNCTION(platform_reset)
|
||||
/* relocate the below code to TARGET_SPOT */
|
||||
ldr r8, =TARGET_SPOT
|
||||
adr r9, .Lcore_reloc_start
|
||||
adr r10, .Lcore_reloc_end
|
||||
|
||||
0:
|
||||
ldr r12, [r9], #4
|
||||
str r12, [r8], #4
|
||||
cmp r9, r10
|
||||
bne 0b
|
||||
|
||||
/* load constants we will need below */
|
||||
ldr r8, =SLCR_BASE
|
||||
ldr r9, =SCU_CONTROL_BASE
|
||||
|
||||
/* calculate the new return address this code will need to branch to */
|
||||
adr r12, .Ldone
|
||||
add r12, #0xfffc0000
|
||||
|
||||
ldr r10, =TARGET_SPOT
|
||||
bx r10
|
||||
|
||||
.Ldone:
|
||||
b arm_reset
|
||||
|
||||
.Lcore_reloc_start:
|
||||
# use SCLR to map the sram blocks to the top of their segment
|
||||
movw r10, #SLCR_UNLOCK_KEY
|
||||
str r10, [r8, #SLCR_UNLOCK]
|
||||
|
||||
ldr r10, [r8, #OCM_CFG]
|
||||
orr r10, #0xf
|
||||
str r10, [r8, #OCM_CFG]
|
||||
|
||||
movw r10, #SLCR_LOCK_KEY
|
||||
str r10, [r8, #SLCR_LOCK]
|
||||
|
||||
# tell the SCU to not filter first 1MB
|
||||
mov r10, #0
|
||||
str r10, [r9, #0x40] /* SCU filter start address */
|
||||
dmb
|
||||
|
||||
bx r12
|
||||
.Lcore_reloc_end:
|
||||
|
||||
.ltorg
|
||||
#endif
|
||||
|
||||
@@ -7,14 +7,14 @@ PLATFORM := zynq
|
||||
# set the system base to sram
|
||||
ZYNQ_USE_SRAM := 1
|
||||
|
||||
# we have sdram
|
||||
ZYNQ_SDRAM_SIZE := 0x10000000
|
||||
|
||||
GLOBAL_INCLUDES += \
|
||||
$(LOCAL_DIR)/include
|
||||
|
||||
GLOBAL_DEFINES += \
|
||||
EXTERNAL_CLOCK_FREQ=50000000 \
|
||||
WITH_STATIC_HEAP=1 \
|
||||
HEAP_START=0x00100000 \
|
||||
HEAP_LEN=0x1ff00000
|
||||
EXTERNAL_CLOCK_FREQ=50000000
|
||||
|
||||
MODULE_SRCS += \
|
||||
$(LOCAL_DIR)/target.c \
|
||||
|
||||
Reference in New Issue
Block a user