From 86acbbe2d88688cdd506192983e315b4e9ca94f7 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Fri, 26 Aug 2022 13:48:31 +0800 Subject: [PATCH] build(bl31): support separated memory for RW DATA Update linker file and init codes to allow using separated memory region for RW DATA. Init codes will copy the RW DATA from the image to the linked address. On some NXP platforms, after the BL31 image has been verified, the bl31 image space will be locked/protected as RO only, so need to move the RW DATA and NOBITS out of the bl31 image. Signed-off-by: Ye Li Reviewed-by: Peng Fan Signed-off-by: Jacky Bai Change-Id: I361d9a715890961bf30790a3325f8085a40c0c39 --- Makefile | 2 ++ bl31/bl31.ld.S | 42 +++++++++++++++++++++++- include/arch/aarch64/el3_common_macros.S | 4 ++- make_helpers/defaults.mk | 4 +++ 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f736a3bc3..d73926906 100644 --- a/Makefile +++ b/Makefile @@ -1189,6 +1189,7 @@ $(eval $(call assert_booleans,\ SEPARATE_CODE_AND_RODATA \ SEPARATE_BL2_NOLOAD_REGION \ SEPARATE_NOBITS_REGION \ + SEPARATE_RWDATA_REGION \ SEPARATE_SIMD_SECTION \ SPIN_ON_BL1_EXIT \ SPM_MM \ @@ -1367,6 +1368,7 @@ $(eval $(call add_defines,\ SEPARATE_CODE_AND_RODATA \ SEPARATE_BL2_NOLOAD_REGION \ SEPARATE_NOBITS_REGION \ + SEPARATE_RWDATA_REGION \ SEPARATE_SIMD_SECTION \ RECLAIM_INIT_CODE \ SPD_${SPD} \ diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 8698dffd4..867dedb99 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -19,6 +19,12 @@ MEMORY { #else /* SEPARATE_NOBITS_REGION */ # define NOBITS RAM #endif /* SEPARATE_NOBITS_REGION */ + +#if SEPARATE_RWDATA_REGION + RAM_RW (rw): ORIGIN = BL31_RWDATA_BASE, LENGTH = BL31_RWDATA_LIMIT - BL31_RWDATA_BASE +#else /* SEPARATE_RWDATA_REGION */ +#define RAM_RW RAM +#endif /* SEPARATE_RWDATA_REGION */ } #ifdef PLAT_EXTRA_LD_SCRIPT @@ -136,10 +142,36 @@ SECTIONS { . = LOADADDR(.spm_shim_exceptions) + SIZEOF(.spm_shim_exceptions); #endif /* SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP) */ - __RW_START__ = .; +#if SEPARATE_RWDATA_REGION + . = BL31_RWDATA_BASE; + ASSERT(BL31_RWDATA_BASE == ALIGN(PAGE_SIZE), + "BL31_RWDATA_BASE address is not aligned on a page boundary.") + + /* + * Define a linker symbol to mark the start of the RW memory area for this + * image. + */ + __RW_START__ = . ; + + DATA_SECTION >RAM_RW AT>RAM + __DATA_RAM_START__ = __DATA_START__; + __DATA_RAM_END__ = __DATA_END__; + __DATA_ROM_START__ = LOADADDR(.data); + + . = ALIGN(PAGE_SIZE); + __RW_END__ = .; + + RELA_SECTION >RAM +#else /* SEPARATE_RWDATA_REGION */ + /* + * Define a linker symbol to mark the start of the RW memory area for this + * image. + */ + __RW_START__ = . ; DATA_SECTION >RAM RELA_SECTION >RAM +#endif /* SEPARATE_RWDATA_REGION */ #ifdef BL31_PROGBITS_LIMIT ASSERT( @@ -151,7 +183,9 @@ SECTIONS { #if SEPARATE_NOBITS_REGION . = ALIGN(PAGE_SIZE); +#if !SEPARATE_RWDATA_REGION __RW_END__ = .; +#endif /* SEPARATE_RWDATA_REGION */ __BL31_END__ = .; ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.") @@ -203,7 +237,13 @@ SECTIONS { ASSERT(. <= BL31_NOBITS_LIMIT, "BL31 NOBITS region has exceeded its limit.") #else /* SEPARATE_NOBITS_REGION */ + /* + * Define a linker symbol to mark the end of the RW memory area for this + * image. + */ +#if !SEPARATE_RWDATA_REGION __RW_END__ = .; +#endif /* SEPARATE_RWDATA_REGION */ __BL31_END__ = .; ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.") diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index 1666e3bfe..204625cee 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -340,7 +340,9 @@ #endif #if defined(IMAGE_BL1) || \ - (defined(IMAGE_BL2) && RESET_TO_BL2 && BL2_IN_XIP_MEM) + (defined(IMAGE_BL2) && RESET_TO_BL2 && BL2_IN_XIP_MEM) || \ + (defined(IMAGE_BL31) && SEPARATE_RWDATA_REGION) + adrp x0, __DATA_RAM_START__ add x0, x0, :lo12:__DATA_RAM_START__ adrp x1, __DATA_ROM_START__ diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 584542c30..d6c09de66 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -240,6 +240,10 @@ SEPARATE_NOBITS_REGION := 0 # region, platform Makefile is free to override this value. SEPARATE_BL2_NOLOAD_REGION := 0 +# Put RW DATA sections (.rwdata) in a separate memory region, which may be +# discontiguous from the rest of BL31. +SEPARATE_RWDATA_REGION := 0 + # Put SIMD context data structures in a separate memory region. Platforms # have the choice to put it outside of default BSS region of EL3 firmware. SEPARATE_SIMD_SECTION := 0