mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-05-04 01:48:39 +00:00
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: Samuel Holland <samuel@sholland.org> Change-Id: Idedfec5e4dbee77e94f2fdd356e6ae6f4dc79d37
This commit is contained in:
parent
caa0c85d2f
commit
f8578e641b
6 changed files with 62 additions and 4 deletions
2
Makefile
2
Makefile
|
@ -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))
|
||||||
$(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)
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
__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
|
||||||
*/
|
*/
|
||||||
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
|
||||||
*/
|
*/
|
||||||
. = 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
|
||||||
__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
|
||||||
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
|
||||||
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 @@
|
||||||
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
|
||||||
# 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
|
||||||
|
|
Loading…
Add table
Reference in a new issue