[PATCH 6/9] arm: Clarify memory layout calculation

Markus Pargmann mpa at pengutronix.de
Wed Dec 2 05:48:48 PST 2015


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 at pengutronix.de>
---
 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 | 53 ++++++++++++++++++++++++++------------
 4 files changed, 82 insertions(+), 64 deletions(-)

diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c
index 2075ffeee75f..f723edc61318 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 c054f3c4400c..e06c4c8f37a0 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 dbf6b1e3f807..5bcce6b9e36d 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 76e356413aec..da7717538b61 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 = 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)
 {
-	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
-	 */
+	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);
+
+#ifdef CONFIG_RELOCATABLE
+	endmem -= size;
 	endmem &= ~(SZ_1M - 1);
+#endif
 
 	return endmem;
 }
-- 
2.6.2




More information about the barebox mailing list