aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--bl31/bl31.ld.S40
-rw-r--r--docs/design/firmware-design.rst5
-rw-r--r--docs/getting_started/build-options.rst7
-rw-r--r--include/arch/aarch64/el3_common_macros.S8
-rw-r--r--make_helpers/defaults.mk4
6 files changed, 62 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index 073c2ed3e..42fdb7326 100644
--- a/Makefile
+++ b/Makefile
@@ -736,6 +736,7 @@ $(eval $(call assert_boolean,RAS_EXTENSION))
$(eval $(call assert_boolean,RESET_TO_BL31))
$(eval $(call assert_boolean,SAVE_KEYS))
$(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
+$(eval $(call assert_boolean,SEPARATE_NOBITS_REGION))
$(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
$(eval $(call assert_boolean,SPM_MM))
$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
@@ -800,6 +801,7 @@ $(eval $(call add_define,PSCI_EXTENDED_STATE_ID))
$(eval $(call add_define,RAS_EXTENSION))
$(eval $(call add_define,RESET_TO_BL31))
$(eval $(call add_define,SEPARATE_CODE_AND_RODATA))
+$(eval $(call add_define,SEPARATE_NOBITS_REGION))
$(eval $(call add_define,RECLAIM_INIT_CODE))
$(eval $(call add_define,SPD_${SPD}))
$(eval $(call add_define,SPIN_ON_BL1_EXIT))
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index a598e59cf..42227f0f3 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -15,6 +15,11 @@ ENTRY(bl31_entrypoint)
MEMORY {
RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE
+#if SEPARATE_NOBITS_REGION
+ NOBITS (rw!a): ORIGIN = BL31_NOBITS_BASE, LENGTH = BL31_NOBITS_LIMIT - BL31_NOBITS_BASE
+#else
+#define NOBITS RAM
+#endif
}
#ifdef PLAT_EXTRA_LD_SCRIPT
@@ -198,11 +203,28 @@ SECTIONS
ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.")
#endif
+#if SEPARATE_NOBITS_REGION
+ /*
+ * Define a linker symbol to mark end of the RW memory area for this
+ * image.
+ */
+ __RW_END__ = .;
+ __BL31_END__ = .;
+
+ ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
+
+ . = BL31_NOBITS_BASE;
+ ASSERT(. == ALIGN(PAGE_SIZE),
+ "BL31 NOBITS base address is not aligned on a page boundary.")
+
+ __NOBITS_START__ = .;
+#endif
+
stacks (NOLOAD) : {
__STACKS_START__ = .;
*(tzfw_normal_stacks)
__STACKS_END__ = .;
- } >RAM
+ } >NOBITS
/*
* The .bss section gets initialised to 0 at runtime.
@@ -262,7 +284,7 @@ SECTIONS
__PMF_TIMESTAMP_END__ = .;
#endif /* ENABLE_PMF */
__BSS_END__ = .;
- } >RAM
+ } >NOBITS
/*
* The xlat_table section is for full, aligned page tables (4K).
@@ -272,7 +294,7 @@ SECTIONS
*/
xlat_table (NOLOAD) : {
*(xlat_table)
- } >RAM
+ } >NOBITS
#if USE_COHERENT_MEM
/*
@@ -298,9 +320,18 @@ SECTIONS
*/
. = ALIGN(PAGE_SIZE);
__COHERENT_RAM_END__ = .;
- } >RAM
+ } >NOBITS
#endif
+#if SEPARATE_NOBITS_REGION
+ /*
+ * Define a linker symbol to mark end of the NOBITS memory area for this
+ * image.
+ */
+ __NOBITS_END__ = .;
+
+ ASSERT(. <= BL31_NOBITS_LIMIT, "BL31 NOBITS region has exceeded its limit.")
+#else
/*
* Define a linker symbol to mark end of the RW memory area for this
* image.
@@ -309,4 +340,5 @@ SECTIONS
__BL31_END__ = .;
ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
+#endif
}
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index cae94b5d8..5fc1335b3 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -1500,6 +1500,11 @@ sections then the resulting binary file would contain zero bytes in place of
this NOBITS section, making the image unnecessarily bigger. Smaller images
allow faster loading from the FIP to the main memory.
+For BL31, a platform can specify an alternate location for NOBITS sections
+(other than immediately following PROGBITS sections) by setting
+``SEPARATE_NOBITS_REGION`` to 1 and defining ``BL31_NOBITS_BASE`` and
+``BL31_NOBITS_LIMIT``.
+
Linker scripts and symbols
~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 37c28a5a4..d7bb0449e 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -491,6 +491,13 @@ Common build options
pages" section in :ref:`Firmware Design`. This flag is disabled by default and
affects all BL images.
+- ``SEPARATE_NOBITS_REGION``: Setting this option to ``1`` allows the NOBITS
+ sections of BL31 (.bss, stacks, page tables, and coherent memory) to be
+ allocated in RAM discontiguous from the loaded firmware image. When set, the
+ platform is expected to provide definitons for ``BL31_NOBITS_BASE`` and
+ ``BL31_NOBITS_LIMIT``. When the option is ``0`` (the default), NOBITS
+ sections are placed in RAM immediately following the loaded firmware image.
+
- ``SPD``: Choose a Secure Payload Dispatcher component to be built into TF-A.
This build option is only valid if ``ARCH=aarch64``. The value should be
the path to the directory containing the SPD source, relative to
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index b14b7b66e..156b18a4f 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -382,6 +382,14 @@
add x1, x1, :lo12:__RW_END__
sub x1, x1, x0
bl inv_dcache_range
+#if defined(IMAGE_BL31) && SEPARATE_NOBITS_REGION
+ adrp x0, __NOBITS_START__
+ add x0, x0, :lo12:__NOBITS_START__
+ adrp x1, __NOBITS_END__
+ add x1, x1, :lo12:__NOBITS_END__
+ sub x1, x1, x0
+ bl inv_dcache_range
+#endif
#endif
adrp x0, __BSS_START__
add x0, x0, :lo12:__BSS_START__
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index a1f9db9d3..53832c561 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -171,6 +171,10 @@ SDEI_SUPPORT := 0
# platform Makefile is free to override this value.
SEPARATE_CODE_AND_RODATA := 0
+# Put NOBITS sections (.bss, stacks, page tables, and coherent memory) in a
+# separate memory region, which may be discontiguous from the rest of BL31.
+SEPARATE_NOBITS_REGION := 0
+
# If the BL31 image initialisation code is recalimed after use for the secondary
# cores stack
RECLAIM_INIT_CODE := 0