Commit f8578e64 authored by Samuel Holland's avatar Samuel Holland
Browse files

bl31: Split into two separate memory regions



Some platforms are extremely memory constrained and must split BL31
between multiple non-contiguous areas in SRAM. Allow the NOBITS
sections (.bss, stacks, page tables, and coherent memory) to be placed
in a separate region of RAM from the loaded firmware image.

Because the NOBITS region may be at a lower address than the rest of
BL31, __RW_{START,END}__ and __BL31_{START,END}__ cannot include this
region, or el3_entrypoint_common would attempt to invalidate the dcache
for the entire address space. New symbols __NOBITS_{START,END}__ are
added when SEPARATE_NOBITS_REGION is enabled, and the dcached for the
NOBITS region is invalidated separately.
Signed-off-by: default avatarSamuel Holland <samuel@sholland.org>
Change-Id: Idedfec5e4dbee77e94f2fdd356e6ae6f4dc79d37
parent caa0c85d
...@@ -736,6 +736,7 @@ $(eval $(call assert_boolean,RAS_EXTENSION)) ...@@ -736,6 +736,7 @@ $(eval $(call assert_boolean,RAS_EXTENSION))
$(eval $(call assert_boolean,RESET_TO_BL31)) $(eval $(call assert_boolean,RESET_TO_BL31))
$(eval $(call assert_boolean,SAVE_KEYS)) $(eval $(call assert_boolean,SAVE_KEYS))
$(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA)) $(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,SPIN_ON_BL1_EXIT))
$(eval $(call assert_boolean,SPM_MM)) $(eval $(call assert_boolean,SPM_MM))
$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
...@@ -800,6 +801,7 @@ $(eval $(call add_define,PSCI_EXTENDED_STATE_ID)) ...@@ -800,6 +801,7 @@ $(eval $(call add_define,PSCI_EXTENDED_STATE_ID))
$(eval $(call add_define,RAS_EXTENSION)) $(eval $(call add_define,RAS_EXTENSION))
$(eval $(call add_define,RESET_TO_BL31)) $(eval $(call add_define,RESET_TO_BL31))
$(eval $(call add_define,SEPARATE_CODE_AND_RODATA)) $(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,RECLAIM_INIT_CODE))
$(eval $(call add_define,SPD_${SPD})) $(eval $(call add_define,SPD_${SPD}))
$(eval $(call add_define,SPIN_ON_BL1_EXIT)) $(eval $(call add_define,SPIN_ON_BL1_EXIT))
......
...@@ -15,6 +15,11 @@ ENTRY(bl31_entrypoint) ...@@ -15,6 +15,11 @@ ENTRY(bl31_entrypoint)
MEMORY { MEMORY {
RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE 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 #ifdef PLAT_EXTRA_LD_SCRIPT
...@@ -198,11 +203,28 @@ SECTIONS ...@@ -198,11 +203,28 @@ SECTIONS
ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.") ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.")
#endif #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 (NOLOAD) : {
__STACKS_START__ = .; __STACKS_START__ = .;
*(tzfw_normal_stacks) *(tzfw_normal_stacks)
__STACKS_END__ = .; __STACKS_END__ = .;
} >RAM } >NOBITS
/* /*
* The .bss section gets initialised to 0 at runtime. * The .bss section gets initialised to 0 at runtime.
...@@ -262,7 +284,7 @@ SECTIONS ...@@ -262,7 +284,7 @@ SECTIONS
__PMF_TIMESTAMP_END__ = .; __PMF_TIMESTAMP_END__ = .;
#endif /* ENABLE_PMF */ #endif /* ENABLE_PMF */
__BSS_END__ = .; __BSS_END__ = .;
} >RAM } >NOBITS
/* /*
* The xlat_table section is for full, aligned page tables (4K). * The xlat_table section is for full, aligned page tables (4K).
...@@ -272,7 +294,7 @@ SECTIONS ...@@ -272,7 +294,7 @@ SECTIONS
*/ */
xlat_table (NOLOAD) : { xlat_table (NOLOAD) : {
*(xlat_table) *(xlat_table)
} >RAM } >NOBITS
#if USE_COHERENT_MEM #if USE_COHERENT_MEM
/* /*
...@@ -298,9 +320,18 @@ SECTIONS ...@@ -298,9 +320,18 @@ SECTIONS
*/ */
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
__COHERENT_RAM_END__ = .; __COHERENT_RAM_END__ = .;
} >RAM } >NOBITS
#endif #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 * Define a linker symbol to mark end of the RW memory area for this
* image. * image.
...@@ -309,4 +340,5 @@ SECTIONS ...@@ -309,4 +340,5 @@ SECTIONS
__BL31_END__ = .; __BL31_END__ = .;
ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.") ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
#endif
} }
...@@ -1500,6 +1500,11 @@ sections then the resulting binary file would contain zero bytes in place of ...@@ -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 this NOBITS section, making the image unnecessarily bigger. Smaller images
allow faster loading from the FIP to the main memory. 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 Linker scripts and symbols
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
......
...@@ -491,6 +491,13 @@ Common build options ...@@ -491,6 +491,13 @@ Common build options
pages" section in :ref:`Firmware Design`. This flag is disabled by default and pages" section in :ref:`Firmware Design`. This flag is disabled by default and
affects all BL images. 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. - ``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 This build option is only valid if ``ARCH=aarch64``. The value should be
the path to the directory containing the SPD source, relative to the path to the directory containing the SPD source, relative to
......
...@@ -382,6 +382,14 @@ ...@@ -382,6 +382,14 @@
add x1, x1, :lo12:__RW_END__ add x1, x1, :lo12:__RW_END__
sub x1, x1, x0 sub x1, x1, x0
bl inv_dcache_range 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 #endif
adrp x0, __BSS_START__ adrp x0, __BSS_START__
add x0, x0, :lo12:__BSS_START__ add x0, x0, :lo12:__BSS_START__
......
...@@ -171,6 +171,10 @@ SDEI_SUPPORT := 0 ...@@ -171,6 +171,10 @@ SDEI_SUPPORT := 0
# platform Makefile is free to override this value. # platform Makefile is free to override this value.
SEPARATE_CODE_AND_RODATA := 0 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 # If the BL31 image initialisation code is recalimed after use for the secondary
# cores stack # cores stack
RECLAIM_INIT_CODE := 0 RECLAIM_INIT_CODE := 0
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment