diff options
| author | John Powell <john.powell@arm.com> | 2026-05-20 16:42:56 -0500 |
|---|---|---|
| committer | John Powell <john.powell@arm.com> | 2026-06-30 14:56:12 +0000 |
| commit | 769380b33b0a20f6c05b22e6897680a9e28f573d (patch) | |
| tree | 266fee0f77e19b014a2202d42fcf1a0d11e48a11 | |
| parent | 1a95ccecd33ed1ac13c748461cdd5df5c9a41657 (diff) | |
| download | arm-trusted-firmware-769380b33b0a20f6c05b22e6897680a9e28f573d.tar.gz arm-trusted-firmware-769380b33b0a20f6c05b22e6897680a9e28f573d.zip | |
feat(lfa): bl31 linker file updates for lfa
This patch modifies the BL31 linker script to carve out regions
needed by BL31 live activation framework.
Change-Id: I8b5f38a62e159bf1cad8dc4ab74cf6a9bb137074
Signed-off-by: John Powell <john.powell@arm.com>
| -rw-r--r-- | bl31/bl31.ld.S | 86 |
1 files changed, 84 insertions, 2 deletions
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index bb337f403..d156680b8 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -7,13 +7,20 @@ #include <common/bl_common.ld.h> #include <lib/per_cpu/per_cpu_defs.h> #include <lib/xlat_tables/xlat_tables_defs.h> +#include <platform_def.h> OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) OUTPUT_ARCH(PLATFORM_LINKER_ARCH) ENTRY(bl31_entrypoint) MEMORY { - RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE + + RAM (rwx): ORIGIN = BL31_BASE, \ + LENGTH = BL31_LIMIT - BL31_BASE - (ENABLE_LFA_BL31 * (2 * PAGE_SIZE)) + +#if ENABLE_LFA_BL31 + LFA (rwx): ORIGIN = BL31_LIMIT - (2 * PAGE_SIZE), LENGTH = (2 * PAGE_SIZE) +#endif #if SEPARATE_NOBITS_REGION NOBITS (rw!a): ORIGIN = BL31_NOBITS_BASE, LENGTH = BL31_NOBITS_LIMIT - BL31_NOBITS_BASE @@ -50,6 +57,33 @@ SECTIONS { __TEXT_START__ = .; *bl31_entrypoint.o(.text*) + +#if ENABLE_LFA_BL31 + /* + * When LFA for BL31 is enabled we must group these two subsections + * together so they live in a fixed area of the binary that can be + * padded to a constant size. This means this section can be replaced + * on it's own and expand for new workarounds to be added. Otherwise + * the linker is free to do whatever it likes with them in text and + * rodata as usual. + */ + . = ALIGN(PAGE_SIZE); + __ERRATA_START__ = .; + *(.text.errata*) + *(.rodata.errata*) + + ASSERT(PLAT_LFA_ERRATA_SECTION_SIZE >= (. - __ERRATA_START__), + "Section .errata is too big for PLAT_LFA_ERRATA_SECTION_SIZE!"); + + FILL(0x00) + . += (( PLAT_LFA_ERRATA_SECTION_SIZE > (. - __ERRATA_START__) ) + ? ( PLAT_LFA_ERRATA_SECTION_SIZE - (. - __ERRATA_START__) ) + : 0); + + . = ALIGN(PAGE_SIZE); + __ERRATA_END__ = .; +#endif + *(SORT_BY_ALIGNMENT(SORT(.text*))) *(.vectors) __TEXT_END_UNALIGNED__ = .; @@ -91,6 +125,33 @@ SECTIONS { __RO_START__ = .; *bl31_entrypoint.o(.text*) + +#if ENABLE_LFA_BL31 + /* + * When LFA for BL31 is enabled we must group these two subsections + * together so they live in a fixed area of the binary that can be + * padded to a constant size. This means this section can be replaced + * on it's own and expand for new workarounds to be added. Otherwise + * the linker is free to do whatever it likes with them in text and + * rodata as usual. + */ + . = ALIGN(PAGE_SIZE); + __ERRATA_START__ = .; + *(.text.errata*) + *(.rodata.errata*) + + ASSERT(PLAT_LFA_ERRATA_SECTION_SIZE >= (. - __ERRATA_START__), + "Section .errata is too big for PLAT_LFA_ERRATA_SECTION_SIZE!"); + + FILL(0x00) + . += (( PLAT_LFA_ERRATA_SECTION_SIZE > (. - __ERRATA_START__) ) + ? ( PLAT_LFA_ERRATA_SECTION_SIZE - (. - __ERRATA_START__) ) + : 0); + + . = ALIGN(PAGE_SIZE); + __ERRATA_END__ = .; +#endif + *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) @@ -147,6 +208,26 @@ SECTIONS { . = LOADADDR(.spm_shim_exceptions) + SIZEOF(.spm_shim_exceptions); #endif /* SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP) */ +#if ENABLE_LFA_BL31 + .lfa_relocatable : ALIGN(PAGE_SIZE) { + __LFA_RELOCATABLE_CODE_START__ = .; + KEEP(*(.lfa_relocatable_code*)) + __LFA_RELOCATABLE_CODE_END__ = .; + . = ALIGN(PAGE_SIZE); + __LFA_RELOCATABLE_DATA_START__ = .; + KEEP(*(.lfa_relocatable_data*)) + . = ALIGN(PAGE_SIZE); + __LFA_RELOCATABLE_DATA_END__ = .; + __LFA_RELOCATABLE_LIMIT__ = .; + } >LFA AT> RAM + + PROVIDE(__LFA_RELOCATABLE_LMA__ = LOADADDR(.lfa_relocatable)); + + . = LOADADDR(.lfa_relocatable) + SIZEOF(.lfa_relocatable); + ASSERT(__LFA_RELOCATABLE_LIMIT__ <= BL31_LIMIT, \ + "__LFA_RELOCATABLE_END__ has exceeded its limit.") +#endif /* ENABLE_LFA_BL31 */ + #if SEPARATE_RWDATA_REGION . = BL31_RWDATA_BASE; ASSERT(BL31_RWDATA_BASE == ALIGN(PAGE_SIZE), @@ -193,7 +274,8 @@ SECTIONS { #endif /* SEPARATE_RWDATA_REGION */ __BL31_END__ = .; - ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.") + ASSERT(. <= BL31_LIMIT - (ENABLE_LFA_BL31 * (2 * PAGE_SIZE)), \ + "BL31 image has exceeded its limit.") . = BL31_NOBITS_BASE; |
