From 65071bd0910ef109c86b9645c570a6ceed7de534 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Tue, 8 Dec 2015 10:39:29 +0100 Subject: arm: Clarify memory layout calculation The memory calculations used are all hardcoded into three different files, start-pbl.c, uncompress.c and start.c. To make this more readable and reliable, this patch gathers these information in barebox-arm.h with static inline functions for the calculation of the memory offsets. This patch also adds proper handling of different barebox/board data sizes. Currently only 1MB+Alignment of RAM is reserved for Barebox and board data. This could be too small for bigger devicetrees and barebox. Signed-off-by: Markus Pargmann Signed-off-by: Sascha Hauer --- arch/arm/cpu/start-pbl.c | 14 ++++------ arch/arm/cpu/start.c | 48 ++++++++++++++++++--------------- arch/arm/cpu/uncompress.c | 31 ++++++++++----------- arch/arm/include/asm/barebox-arm.h | 55 +++++++++++++++++++++++++------------- 4 files changed, 83 insertions(+), 65 deletions(-) diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c index 2075ffeee7..f723edc613 100644 --- a/arch/arm/cpu/start-pbl.c +++ b/arch/arm/cpu/start-pbl.c @@ -54,8 +54,6 @@ __noreturn void barebox_single_pbl_start(unsigned long membase, uint32_t endmem = membase + memsize; unsigned long barebox_base; - endmem -= STACK_SIZE; /* stack */ - if (IS_ENABLED(CONFIG_PBL_RELOCATABLE)) relocate_to_current_adr(); @@ -67,7 +65,7 @@ __noreturn void barebox_single_pbl_start(unsigned long membase, pg_len = pg_end - pg_start; if (IS_ENABLED(CONFIG_RELOCATABLE)) - barebox_base = arm_barebox_image_place(membase + memsize); + barebox_base = arm_mem_barebox_image(membase, endmem, pg_len); else barebox_base = TEXT_BASE; @@ -83,14 +81,12 @@ __noreturn void barebox_single_pbl_start(unsigned long membase, setup_c(); if (IS_ENABLED(CONFIG_MMU_EARLY)) { - endmem &= ~0x3fff; - endmem -= SZ_16K; /* ttb */ - mmu_early_enable(membase, memsize, endmem); + unsigned long ttb = arm_mem_ttb(membase, endmem); + mmu_early_enable(membase, memsize, ttb); } - endmem -= SZ_128K; /* early malloc */ - free_mem_ptr = endmem; - free_mem_end_ptr = free_mem_ptr + SZ_128K; + free_mem_ptr = arm_mem_early_malloc(membase, endmem); + free_mem_end_ptr = arm_mem_early_malloc_end(membase, endmem); pbl_barebox_uncompress((void*)barebox_base, (void *)pg_start, pg_len); diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c index c054f3c440..e06c4c8f37 100644 --- a/arch/arm/cpu/start.c +++ b/arch/arm/cpu/start.c @@ -104,14 +104,31 @@ void *barebox_arm_boot_dtb(void) return barebox_boarddata; } +static inline unsigned long arm_mem_boarddata(unsigned long membase, + unsigned long endmem, + unsigned long size) +{ + unsigned long mem; + + mem = arm_mem_barebox_image(membase, endmem, barebox_image_size); + mem -= ALIGN(size, 64); + + return mem; +} + __noreturn void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { unsigned long endmem = membase + memsize; unsigned long malloc_start, malloc_end; + unsigned long barebox_size = barebox_image_size + + ((unsigned long)&__bss_stop - (unsigned long)&__bss_start); + unsigned long arm_head_bottom; if (IS_ENABLED(CONFIG_RELOCATABLE)) { - unsigned long barebox_base = arm_barebox_image_place(endmem); + unsigned long barebox_base = arm_mem_barebox_image(membase, + endmem, + barebox_size); relocate_to_adr(barebox_base); } @@ -122,19 +139,16 @@ __noreturn void barebox_non_pbl_start(unsigned long membase, pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize); arm_stack_top = endmem; - endmem -= STACK_SIZE; /* Stack */ if (IS_ENABLED(CONFIG_MMU_EARLY)) { - - endmem &= ~0x3fff; - endmem -= SZ_16K; /* ttb */ + unsigned long ttb = arm_mem_ttb(membase, endmem); if (IS_ENABLED(CONFIG_PBL_IMAGE)) { arm_set_cache_functions(); } else { - pr_debug("enabling MMU, ttb @ 0x%08lx\n", endmem); + pr_debug("enabling MMU, ttb @ 0x%08lx\n", ttb); arm_early_mmu_cache_invalidate(); - mmu_early_enable(membase, memsize, endmem); + mmu_early_enable(membase, memsize, ttb); } } @@ -155,24 +169,16 @@ __noreturn void barebox_non_pbl_start(unsigned long membase, } if (totalsize) { - endmem -= ALIGN(totalsize, 64); + unsigned long mem = arm_mem_boarddata(membase, endmem, + totalsize); pr_debug("found %s in boarddata, copying to 0x%lu\n", - name, endmem); - barebox_boarddata = memcpy((void *)endmem, - boarddata, totalsize); + name, mem); + barebox_boarddata = memcpy((void *)mem, boarddata, + totalsize); } } - if ((unsigned long)_text > membase + memsize || - (unsigned long)_text < membase) - /* - * barebox is either outside SDRAM or in another - * memory bank, so we can use the whole bank for - * malloc. - */ - malloc_end = endmem; - else - malloc_end = (unsigned long)_text; + malloc_end = arm_head_bottom; /* * Maximum malloc space is the Kconfig value if given diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c index dbf6b1e3f8..5bcce6b9e3 100644 --- a/arch/arm/cpu/uncompress.c +++ b/arch/arm/cpu/uncompress.c @@ -52,8 +52,6 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase, void *pg_start; unsigned long pc = get_pc(); - endmem -= STACK_SIZE; /* stack */ - image_end = (void *)ld_var(__image_end) - get_runtime_offset(); if (IS_ENABLED(CONFIG_PBL_RELOCATABLE)) { @@ -68,8 +66,16 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase, relocate_to_adr(membase); } + /* + * image_end is the first location after the executable. It contains + * the size of the appended compressed binary followed by the binary. + */ + pg_start = image_end + 1; + pg_len = *(image_end); + if (IS_ENABLED(CONFIG_RELOCATABLE)) - barebox_base = arm_barebox_image_place(membase + memsize); + barebox_base = arm_mem_barebox_image(membase, endmem, + pg_len); else barebox_base = TEXT_BASE; @@ -78,22 +84,13 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase, pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize); if (IS_ENABLED(CONFIG_MMU_EARLY)) { - endmem &= ~0x3fff; - endmem -= SZ_16K; /* ttb */ - pr_debug("enabling MMU, ttb @ 0x%08x\n", endmem); - mmu_early_enable(membase, memsize, endmem); + unsigned long ttb = arm_mem_ttb(membase, endmem); + pr_debug("enabling MMU, ttb @ 0x%08lx\n", ttb); + mmu_early_enable(membase, memsize, ttb); } - endmem -= SZ_128K; /* early malloc */ - free_mem_ptr = endmem; - free_mem_end_ptr = free_mem_ptr + SZ_128K; - - /* - * image_end is the first location after the executable. It contains - * the size of the appended compressed binary followed by the binary. - */ - pg_start = image_end + 1; - pg_len = *(image_end); + free_mem_ptr = arm_mem_early_malloc(membase, endmem); + free_mem_end_ptr = arm_mem_early_malloc_end(membase, endmem); pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx\n", pg_start, pg_len, barebox_base); diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index 76e356413a..8d52882981 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -94,25 +94,44 @@ static inline void arm_fixup_vectors(void) void *barebox_arm_boot_dtb(void); -/* - * For relocatable binaries find a suitable start address for the - * relocated binary. Beginning at the memory end substract the reserved - * space and round down a bit at the end. This is used by the pbl to - * extract the image to a suitable place so that the uncompressed image - * does not have to copy itself to another place. Also it's used by - * the uncompressed image to relocate itself to the same place. - */ -static inline unsigned long arm_barebox_image_place(unsigned long endmem) +static inline unsigned long arm_mem_stack(unsigned long membase, + unsigned long endmem) +{ + return endmem - STACK_SIZE; +} + +static inline unsigned long arm_mem_ttb(unsigned long membase, + unsigned long endmem) { - endmem -= STACK_SIZE; - endmem -= SZ_32K; /* ttb */ - endmem -= SZ_128K; /* early malloc */ - endmem -= SZ_1M; /* place for barebox image */ - - /* - * round down to make translating the objdump easier - */ - endmem &= ~(SZ_1M - 1); + endmem = arm_mem_stack(membase, endmem); + endmem &= ~(SZ_16K - 1); + endmem -= SZ_16K; + + return endmem; +} + +static inline unsigned long arm_mem_early_malloc(unsigned long membase, + unsigned long endmem) +{ + return arm_mem_ttb(membase, endmem) - SZ_128K; +} + +static inline unsigned long arm_mem_early_malloc_end(unsigned long membase, + unsigned long endmem) +{ + return arm_mem_ttb(membase, endmem); +} + +static inline unsigned long arm_mem_barebox_image(unsigned long membase, + unsigned long endmem, + unsigned long size) +{ + endmem = arm_mem_ttb(membase, endmem); + + if (IS_ENABLED(CONFIG_RELOCATABLE)) { + endmem -= size; + endmem &= ~(SZ_1M - 1); + } return endmem; } -- cgit v1.2.3