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 <mpa@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
899b3822d2
commit
65071bd091
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
endmem -= STACK_SIZE;
|
||||
endmem -= SZ_32K; /* ttb */
|
||||
endmem -= SZ_128K; /* early malloc */
|
||||
endmem -= SZ_1M; /* place for barebox image */
|
||||
return endmem - STACK_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* round down to make translating the objdump easier
|
||||
*/
|
||||
endmem &= ~(SZ_1M - 1);
|
||||
static inline unsigned long arm_mem_ttb(unsigned long membase,
|
||||
unsigned long endmem)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue