Add support for BL2 in XIP memory
In some use-cases BL2 will be stored in eXecute In Place (XIP) memory,
like BL1. In these use-cases, it is necessary to initialize the RW sections
in RAM, while leaving the RO sections in place. This patch enable this
use-case with a new build option, BL2_IN_XIP_MEM. For now, this option
is only supported when BL2_AT_EL3 is 1.
Signed-off-by: Jiafei Pan <Jiafei.Pan@nxp.com>
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 3728643..0f91edc 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -12,15 +12,26 @@
ENTRY(bl2_entrypoint)
MEMORY {
+#if BL2_IN_XIP_MEM
+ ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE
+ RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
+#else
RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
+#endif
}
SECTIONS
{
+#if BL2_IN_XIP_MEM
+ . = BL2_RO_BASE;
+ ASSERT(. == ALIGN(PAGE_SIZE),
+ "BL2_RO_BASE address is not aligned on a page boundary.")
+#else
. = BL2_BASE;
ASSERT(. == ALIGN(PAGE_SIZE),
"BL2_BASE address is not aligned on a page boundary.")
+#endif
#if SEPARATE_CODE_AND_RODATA
.text . : {
@@ -33,7 +44,11 @@
*(.vectors)
. = NEXT(PAGE_SIZE);
__TEXT_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >ROM
+#else
} >RAM
+#endif
.rodata . : {
__RODATA_START__ = .;
@@ -56,7 +71,11 @@
. = NEXT(PAGE_SIZE);
__RODATA_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >ROM
+#else
} >RAM
+#endif
ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
"Resident part of BL2 has exceeded its limit.")
@@ -95,12 +114,22 @@
. = NEXT(PAGE_SIZE);
__RO_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >ROM
+#else
} >RAM
#endif
+#endif
ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
"cpu_ops not defined for this platform.")
+#if BL2_IN_XIP_MEM
+ . = BL2_RW_BASE;
+ ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
+ "BL2_RW_BASE address is not aligned on a page boundary.")
+#endif
+
/*
* Define a linker symbol to mark start of the RW memory area for this
* image.
@@ -113,10 +142,14 @@
* section can be placed independently of the main .data section.
*/
.data . : {
- __DATA_START__ = .;
+ __DATA_RAM_START__ = .;
*(.data*)
- __DATA_END__ = .;
+ __DATA_RAM_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >RAM AT>ROM
+#else
} >RAM
+#endif
stacks (NOLOAD) : {
__STACKS_START__ = .;
@@ -174,12 +207,32 @@
__RW_END__ = .;
__BL2_END__ = .;
+#if BL2_IN_XIP_MEM
+ __BL2_RAM_START__ = ADDR(.data);
+ __BL2_RAM_END__ = .;
+
+ __DATA_ROM_START__ = LOADADDR(.data);
+ __DATA_SIZE__ = SIZEOF(.data);
+
+ /*
+ * The .data section is the last PROGBITS section so its end marks the end
+ * of BL2's RO content in XIP memory..
+ */
+ __BL2_ROM_END__ = __DATA_ROM_START__ + __DATA_SIZE__;
+ ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT,
+ "BL2's RO content has exceeded its limit.")
+#endif
__BSS_SIZE__ = SIZEOF(.bss);
+
#if USE_COHERENT_MEM
__COHERENT_RAM_UNALIGNED_SIZE__ =
__COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
#endif
+#if BL2_IN_XIP_MEM
+ ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
+#else
ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
+#endif
}
diff --git a/bl2/bl2_private.h b/bl2/bl2_private.h
index 50295d6..f93a179 100644
--- a/bl2/bl2_private.h
+++ b/bl2/bl2_private.h
@@ -7,6 +7,20 @@
#ifndef __BL2_PRIVATE_H__
#define __BL2_PRIVATE_H__
+#if BL2_IN_XIP_MEM
+/*******************************************************************************
+ * Declarations of linker defined symbols which will tell us where BL2 lives
+ * in Trusted ROM and RAM
+ ******************************************************************************/
+extern uintptr_t __BL2_ROM_END__;
+#define BL2_ROM_END (uintptr_t)(&__BL2_ROM_END__)
+
+extern uintptr_t __BL2_RAM_START__;
+extern uintptr_t __BL2_RAM_END__;
+#define BL2_RAM_BASE (uintptr_t)(&__BL2_RAM_START__)
+#define BL2_RAM_LIMIT (uintptr_t)(&__BL2_RAM_END__)
+#endif
+
/******************************************
* Forward declarations
*****************************************/