diff --git a/src/arch/armv7/Makefile.inc b/src/arch/armv7/Makefile.inc index 2188706e06..bf2f332f4f 100644 --- a/src/arch/armv7/Makefile.inc +++ b/src/arch/armv7/Makefile.inc @@ -56,6 +56,7 @@ bootblock-y += eabi_compat.c bootblock-y += memset.S bootblock-y += memcpy.S bootblock-y += memmove.S +bootblock-y += mmu.c bootblock_lds = $(src)/arch/armv7/bootblock.lds bootblock_lds += $(chipset_bootblock_lds) diff --git a/src/arch/armv7/mmu.c b/src/arch/armv7/mmu.c index 7d6d46a8a1..17ad8b73ed 100644 --- a/src/arch/armv7/mmu.c +++ b/src/arch/armv7/mmu.c @@ -27,6 +27,7 @@ * SUCH DAMAGE. */ +#include #include #include @@ -36,14 +37,12 @@ #include #include -#define L1_TLB_ENTRIES 4096 /* 1 entry for each 1MB address space */ - -static uintptr_t ttb_addr; +static void *const ttb_buff = (void *)CONFIG_TTB_BUFFER; void mmu_disable_range(unsigned long start_mb, unsigned long size_mb) { unsigned int i; - uint32_t *ttb_entry = (uint32_t *)ttb_addr; + uint32_t *ttb_entry = ttb_buff; printk(BIOS_DEBUG, "Disabling: 0x%08lx:0x%08lx\n", start_mb*MiB, start_mb*MiB + size_mb*MiB - 1); @@ -61,7 +60,7 @@ void mmu_config_range(unsigned long start_mb, unsigned long size_mb, { unsigned int i; uint32_t attr; - uint32_t *ttb_entry = (uint32_t *)ttb_addr; + uint32_t *ttb_entry = ttb_buff; const char *str = NULL; /* @@ -116,24 +115,14 @@ void mmu_config_range(unsigned long start_mb, unsigned long size_mb, void mmu_init(void) { - unsigned int ttb_size; - uint32_t ttbcr; - /* * For coreboot's purposes, we will create a simple L1 page table * in RAM with 1MB section translation entries over the 4GB address * space. * (ref: section 10.2 and example 15-4 in Cortex-A series * programmer's guide) - * - * FIXME: TLB needs to be aligned to 16KB, but cbmem_add() aligns to - * 512 bytes. So allocate some extra space in cbmem and fix-up the - * pointer. - */ - ttb_size = L1_TLB_ENTRIES * sizeof(uint32_t); - ttb_addr = (uintptr_t)cbmem_add(CBMEM_ID_GDT, ttb_size + 16*KiB); - ttb_addr = ALIGN(ttb_addr, 16*KiB); - printk(BIOS_DEBUG, "Translation table is @ 0x%08x\n", ttb_addr); + */ + printk(BIOS_DEBUG, "Translation table is @ %p\n", ttb_buff); /* * Disable TTBR1 by setting TTBCR.N to 0b000, which means the TTBR0 @@ -141,16 +130,14 @@ void mmu_init(void) * * ref: Arch Ref. Manual for ARMv7-A, B3.5.4, */ - ttbcr = read_ttbcr(); - ttbcr &= ~(0x3); - write_ttbcr(ttbcr); + write_ttbcr(read_ttbcr() & ~0x3); /* * Translation table base 0 address is in bits 31:14-N, where N is given * by bits 2:0 in TTBCR (which we set to 0). All lower bits in this * register should be zero for coreboot. */ - write_ttbr0(ttb_addr); + write_ttbr0((uintptr_t)ttb_buff); /* disable domain-level checking of permissions */ write_dacr(~0); diff --git a/src/cpu/samsung/exynos5250/Kconfig b/src/cpu/samsung/exynos5250/Kconfig index e0e179dd64..f937e7b21e 100644 --- a/src/cpu/samsung/exynos5250/Kconfig +++ b/src/cpu/samsung/exynos5250/Kconfig @@ -85,6 +85,15 @@ config CBFS_CACHE_SIZE hex "size of CBFS cache data" default 0x00018000 +# TTB needs to be aligned to 16KB. +config TTB_BUFFER + hex "memory address of the TTB buffer" + default 0x02058000 + +config TTB_SIZE + hex "size of the TTB buffer" + default 0x4000 + config SYS_SDRAM_BASE hex default 0x40000000 diff --git a/src/cpu/samsung/exynos5420/Kconfig b/src/cpu/samsung/exynos5420/Kconfig index 66679a000b..fe475ab4b3 100644 --- a/src/cpu/samsung/exynos5420/Kconfig +++ b/src/cpu/samsung/exynos5420/Kconfig @@ -46,6 +46,7 @@ config CBFS_ROM_OFFSET # 0x0202_4400: variable length bootblock checksum header. # 0x0202_4410: bootblock, assume up to 32KB in size # 0x0203_0000: romstage, assume up to 128KB in size. +# 0x0205_8000: TTB buffer. # 0x0205_c000: cache for CBFS data. # 0x0206_f000: stack bottom # 0x0207_3000: stack pointer @@ -110,6 +111,14 @@ config CBFS_CACHE_SIZE hex "size of CBFS cache data" default 0x00013000 +config TTB_BUFFER + hex "memory address of the TTB buffer" + default 0x02058000 + +config TTB_SIZE + hex "size of the TTB buffer" + default 0x4000 + config SYS_SDRAM_BASE hex default 0x20000000 diff --git a/src/cpu/samsung/exynos5420/bootblock.c b/src/cpu/samsung/exynos5420/bootblock.c index 5cc9ef6af2..3df51a7421 100644 --- a/src/cpu/samsung/exynos5420/bootblock.c +++ b/src/cpu/samsung/exynos5420/bootblock.c @@ -17,10 +17,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "clk.h" #include "wakeup.h" #include "cpu.h" +/* convenient shorthand (in MB) */ +#define SRAM_START (0x02020000 >> 20) +#define SRAM_SIZE 1 +#define SRAM_END (SRAM_START + SRAM_SIZE) /* plus one... */ + void bootblock_cpu_init(void); void bootblock_cpu_init(void) { @@ -51,6 +58,14 @@ void bootblock_cpu_init(void) /* Never returns. */ } + /* set up dcache and MMU */ + mmu_init(); + mmu_config_range(0, SRAM_START, DCACHE_OFF); + mmu_config_range(SRAM_START, SRAM_SIZE, DCACHE_WRITEBACK); + mmu_config_range(SRAM_END, 4096 - SRAM_END, DCACHE_OFF); + dcache_invalidate_all(); + dcache_mmu_enable(); + /* For most ARM systems, we have to initialize firmware media source * (ex, SPI, SD/MMC, or eMMC) now; but for Exynos platform, that is * already handled by iROM so there's no need to setup again. diff --git a/src/cpu/samsung/exynos5420/wakeup.c b/src/cpu/samsung/exynos5420/wakeup.c index 5764c83bd6..af7ef73f89 100644 --- a/src/cpu/samsung/exynos5420/wakeup.c +++ b/src/cpu/samsung/exynos5420/wakeup.c @@ -17,6 +17,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include "power.h" #include "wakeup.h" @@ -27,6 +28,8 @@ void wakeup(void) power_reset(); power_init(); /* Ensure ps_hold_setup() for early wakeup. */ + dcache_mmu_disable(); + icache_invalidate_all(); power_exit_wakeup(); /* Should never return. */ die("Failed to wake up.\n"); diff --git a/src/mainboard/google/pit/mainboard.c b/src/mainboard/google/pit/mainboard.c index e453e679e4..a02967b1c6 100644 --- a/src/mainboard/google/pit/mainboard.c +++ b/src/mainboard/google/pit/mainboard.c @@ -43,7 +43,6 @@ /* convenient shorthand (in MB) */ #define DRAM_START (CONFIG_SYS_SDRAM_BASE >> 20) #define DRAM_SIZE CONFIG_DRAM_SIZE_MB -#define DRAM_END (DRAM_START + DRAM_SIZE) /* plus one... */ static struct edid edid = { .ha = 1366, @@ -432,14 +431,9 @@ static void mainboard_enable(device_t dev) { dev->ops->init = &mainboard_init; - /* set up dcache and MMU */ - /* FIXME: this should happen via resource allocator */ - mmu_init(); - mmu_config_range(0, DRAM_START, DCACHE_OFF); + /* set up caching for the DRAM */ mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK); - mmu_config_range(DRAM_END, 4096 - DRAM_END, DCACHE_OFF); - dcache_invalidate_all(); - dcache_mmu_enable(); + tlb_invalidate_all(); /* this is going to move, but we must have it now and we're * not sure where */