diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 2a32e419b0f132ee9304fcda43b95e4f30be7c6c..06912eba7ceb0f79d956f17ddd26dd52bff17247 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -47,8 +47,10 @@ */ void arm_setup_page_tables(unsigned long total_base, unsigned long total_size, - unsigned long ro_start, - unsigned long ro_limit + unsigned long code_start, + unsigned long code_limit, + unsigned long rodata_start, + unsigned long rodata_limit #if USE_COHERENT_MEM , unsigned long coh_start, unsigned long coh_limit diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h index 9fac9fa22131c648f82f4251985ad5eee05ac758..d6b777278f11342ee2769db407959dd668337c8f 100644 --- a/include/plat/common/common_def.h +++ b/include/plat/common/common_def.h @@ -80,5 +80,44 @@ .ep_info.pc = BL2_BASE, \ } -#endif /* __COMMON_DEF_H__ */ +/* + * The following constants identify the extents of the code & read-only data + * regions. These addresses are used by the MMU setup code and therefore they + * must be page-aligned. + * + * When the code and read-only data are mapped as a single atomic section + * (i.e. when SEPARATE_CODE_AND_RODATA=0) then we treat the whole section as + * code by specifying the read-only data section as empty. + * + * BL1 is different than the other images in the sense that its read-write data + * originally lives in Trusted ROM and needs to be relocated in Trusted SRAM at + * run-time. Therefore, the read-write data in ROM can be mapped with the same + * memory attributes as the read-only data region. For this reason, BL1 uses + * different macros. + * + * Note that BL1_ROM_END is not necessarily aligned on a page boundary as it + * just points to the end of BL1's actual content in Trusted ROM. Therefore it + * needs to be rounded up to the next page size in order to map the whole last + * page of it with the right memory attributes. + */ +#if SEPARATE_CODE_AND_RODATA +#define BL_CODE_BASE (unsigned long)(&__TEXT_START__) +#define BL_CODE_LIMIT (unsigned long)(&__TEXT_END__) +#define BL_RO_DATA_BASE (unsigned long)(&__RODATA_START__) +#define BL_RO_DATA_LIMIT (unsigned long)(&__RODATA_END__) + +#define BL1_CODE_LIMIT BL_CODE_LIMIT +#define BL1_RO_DATA_BASE (unsigned long)(&__RODATA_START__) +#define BL1_RO_DATA_LIMIT round_up(BL1_ROM_END, PAGE_SIZE) +#else +#define BL_CODE_BASE (unsigned long)(&__RO_START__) +#define BL_CODE_LIMIT (unsigned long)(&__RO_END__) +#define BL_RO_DATA_BASE 0 +#define BL_RO_DATA_LIMIT 0 +#define BL1_CODE_LIMIT round_up(BL1_ROM_END, PAGE_SIZE) +#define BL1_RO_DATA_BASE 0 +#define BL1_RO_DATA_LIMIT 0 +#endif /* SEPARATE_CODE_AND_RODATA */ + +#endif /* __COMMON_DEF_H__ */ diff --git a/plat/arm/common/aarch64/arm_common.c b/plat/arm/common/aarch64/arm_common.c index c0a7e6b47ad58c7d37a785b9d4ca519f4f2477e2..36ba4c18bab68d03c9d7b89e48871b86bcc20323 100644 --- a/plat/arm/common/aarch64/arm_common.c +++ b/plat/arm/common/aarch64/arm_common.c @@ -55,13 +55,16 @@ extern const mmap_region_t plat_arm_mmap[]; * The extents of the generic memory regions are specified by the function * arguments and consist of: * - Trusted SRAM seen by the BL image; - * - Read-only section (code and read-only data); + * - Code section; + * - Read-only data section; * - Coherent memory region, if applicable. */ void arm_setup_page_tables(unsigned long total_base, unsigned long total_size, - unsigned long ro_start, - unsigned long ro_limit + unsigned long code_start, + unsigned long code_limit, + unsigned long rodata_start, + unsigned long rodata_limit #if USE_COHERENT_MEM , unsigned long coh_start, @@ -76,16 +79,24 @@ void arm_setup_page_tables(unsigned long total_base, mmap_add_region(total_base, total_base, total_size, MT_MEMORY | MT_RW | MT_SECURE); - /* Re-map the read-only section */ - mmap_add_region(ro_start, ro_start, - ro_limit - ro_start, - MT_MEMORY | MT_RO | MT_SECURE); + + /* Re-map the code section */ + mmap_add_region(code_start, code_start, + code_limit - code_start, + MT_CODE | MT_SECURE); + + /* Re-map the read-only data section */ + mmap_add_region(rodata_start, rodata_start, + rodata_limit - rodata_start, + MT_RO_DATA | MT_SECURE); + #if USE_COHERENT_MEM /* Re-map the coherent memory region */ mmap_add_region(coh_start, coh_start, coh_limit - coh_start, MT_DEVICE | MT_RW | MT_SECURE); #endif + /* Now (re-)map the platform-specific memory regions */ mmap_add(plat_arm_get_mmap()); diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index 34996604b4f7e27e6ef44c4bb84d5c102fb9a77f..c94f0cd773a99d50852116e9dcd68219197bcb38 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -120,16 +120,12 @@ void bl1_early_platform_setup(void) *****************************************************************************/ void arm_bl1_plat_arch_setup(void) { - /* - * BL1_ROM_END is not necessarily aligned on a page boundary as it - * just points to the end of BL1's actual content in Trusted ROM. - * Therefore it needs to be rounded up to the next page size in order to - * map the whole last page of it with the right memory attributes. - */ arm_setup_page_tables(bl1_tzram_layout.total_base, bl1_tzram_layout.total_size, - BL1_RO_BASE, - round_up(BL1_ROM_END, PAGE_SIZE) + BL_CODE_BASE, + BL1_CODE_LIMIT, + BL1_RO_DATA_BASE, + BL1_RO_DATA_LIMIT #if USE_COHERENT_MEM , BL1_COHERENT_RAM_BASE, BL1_COHERENT_RAM_LIMIT diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index e8e7928c02d5af5b833a1fdfed38d17716e57359..b6afaa7f519844f63df910e091b6956310c6046e 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -36,16 +36,6 @@ #include <plat_arm.h> #include <string.h> - -/* - * The next 2 constants identify the extents of the code & RO data region. - * These addresses are used by the MMU setup code and therefore they must be - * page-aligned. It is the responsibility of the linker script to ensure that - * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. - */ -#define BL2_RO_BASE (unsigned long)(&__RO_START__) -#define BL2_RO_LIMIT (unsigned long)(&__RO_END__) - #if USE_COHERENT_MEM /* * The next 2 constants identify the extents of the coherent memory region. @@ -236,8 +226,10 @@ void arm_bl2_plat_arch_setup(void) { arm_setup_page_tables(bl2_tzram_layout.total_base, bl2_tzram_layout.total_size, - BL2_RO_BASE, - BL2_RO_LIMIT + BL_CODE_BASE, + BL_CODE_LIMIT, + BL_RO_DATA_BASE, + BL_RO_DATA_LIMIT #if USE_COHERENT_MEM , BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c index 8185f9f5174c598ab4a22c098776cfabdcfabedd..de7d0c2f9e582d3a3cb102b3efbac875f1ff92c3 100644 --- a/plat/arm/common/arm_bl2u_setup.c +++ b/plat/arm/common/arm_bl2u_setup.c @@ -36,16 +36,6 @@ #include <plat_arm.h> #include <string.h> - -/* - * The next 2 constants identify the extents of the code & RO data region. - * These addresses are used by the MMU setup code and therefore they must be - * page-aligned. It is the responsibility of the linker script to ensure that - * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses. - */ -#define BL2U_RO_BASE (unsigned long)(&__RO_START__) -#define BL2U_RO_LIMIT (unsigned long)(&__RO_END__) - #if USE_COHERENT_MEM /* * The next 2 constants identify the extents of the coherent memory region. @@ -104,8 +94,10 @@ void arm_bl2u_plat_arch_setup(void) { arm_setup_page_tables(BL2U_BASE, BL31_LIMIT, - BL2U_RO_BASE, - BL2U_RO_LIMIT + BL_CODE_BASE, + BL_CODE_LIMIT, + BL_RO_DATA_BASE, + BL_RO_DATA_LIMIT #if USE_COHERENT_MEM , BL2U_COHERENT_RAM_BASE, diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 9cfa3b8b7d1ead6e3b2672f5945fb6e8dc5091b4..87cafced8501f326aceaa2f70231a5ffe35a2c05 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -38,16 +38,6 @@ #include <plat_arm.h> #include <platform.h> - -/* - * The next 3 constants identify the extents of the code, RO data region and the - * limit of the BL31 image. These addresses are used by the MMU setup code and - * therefore they must be page-aligned. It is the responsibility of the linker - * script to ensure that __RO_START__, __RO_END__ & __BL31_END__ linker symbols - * refer to page-aligned addresses. - */ -#define BL31_RO_BASE (unsigned long)(&__RO_START__) -#define BL31_RO_LIMIT (unsigned long)(&__RO_END__) #define BL31_END (unsigned long)(&__BL31_END__) #if USE_COHERENT_MEM @@ -253,10 +243,12 @@ void bl31_plat_runtime_setup(void) ******************************************************************************/ void arm_bl31_plat_arch_setup(void) { - arm_setup_page_tables(BL31_RO_BASE, - (BL31_END - BL31_RO_BASE), - BL31_RO_BASE, - BL31_RO_LIMIT + arm_setup_page_tables(BL31_BASE, + BL31_END - BL31_BASE, + BL_CODE_BASE, + BL_CODE_LIMIT, + BL_RO_DATA_BASE, + BL_RO_DATA_LIMIT #if USE_COHERENT_MEM , BL31_COHERENT_RAM_BASE, BL31_COHERENT_RAM_LIMIT diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index bcb3f6f6ece98cff6ca8b309081c9f4233a409f2..9e5ddea7703c68d748e6dd108793262ab7f96699 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -85,6 +85,11 @@ $(eval $(call add_define,ARM_BL31_IN_DRAM)) # Enable PSCI_STAT_COUNT/RESIDENCY APIs on ARM platforms ENABLE_PSCI_STAT = 1 +# On ARM platforms, separate the code and read-only data sections to allow +# mapping the former as executable and the latter as execute-never. +SEPARATE_CODE_AND_RODATA := 1 + + PLAT_INCLUDES += -Iinclude/common/tbbr \ -Iinclude/plat/arm/common \ -Iinclude/plat/arm/common/aarch64 diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c index 6c6ceea0816e4798720feacf03d916c81b1d2858..09029f4c2a1b5a7c7494c417b816de976c935be0 100644 --- a/plat/arm/common/tsp/arm_tsp_setup.c +++ b/plat/arm/common/tsp/arm_tsp_setup.c @@ -35,16 +35,6 @@ #include <platform_tsp.h> #include <plat_arm.h> - -/* - * The next 3 constants identify the extents of the code & RO data region and - * the limit of the BL32 image. These addresses are used by the MMU setup code - * and therefore they must be page-aligned. It is the responsibility of the - * linker script to ensure that __RO_START__, __RO_END__ & & __BL32_END__ - * linker symbols refer to page-aligned addresses. - */ -#define BL32_RO_BASE (unsigned long)(&__RO_START__) -#define BL32_RO_LIMIT (unsigned long)(&__RO_END__) #define BL32_END (unsigned long)(&__BL32_END__) #if USE_COHERENT_MEM @@ -98,10 +88,12 @@ void tsp_platform_setup(void) ******************************************************************************/ void tsp_plat_arch_setup(void) { - arm_setup_page_tables(BL32_RO_BASE, - (BL32_END - BL32_RO_BASE), - BL32_RO_BASE, - BL32_RO_LIMIT + arm_setup_page_tables(BL32_BASE, + (BL32_END - BL32_BASE), + BL_CODE_BASE, + BL_CODE_LIMIT, + BL_RO_DATA_BASE, + BL_RO_DATA_LIMIT #if USE_COHERENT_MEM , BL32_COHERENT_RAM_BASE, BL32_COHERENT_RAM_LIMIT diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c index 2ea8b1c982dad835c1f2ab211bcbd51e913733d2..ffed591cf9aa04e5040e8613f3006571f1d8d44c 100644 --- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c +++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c @@ -158,6 +158,8 @@ void bl31_plat_arch_setup(void) BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE, BL31_RO_BASE, BL31_RO_LIMIT, + 0, + 0, BL31_COHERENT_RAM_BASE, BL31_COHERENT_RAM_LIMIT); enable_mmu_el3(0); diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c index 19e2c12987a304c7b21f708e23e4f60bc4ee6260..ae66fa4157c5901c410d688a5c68ae5b7b347682 100644 --- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c +++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c @@ -93,7 +93,9 @@ void tsp_plat_arch_setup(void) arm_setup_page_tables(BL32_RO_BASE, (BL32_END - BL32_RO_BASE), BL32_RO_BASE, - BL32_RO_LIMIT + BL32_RO_LIMIT, + 0, + 0 #if USE_COHERENT_MEM , BL32_COHERENT_RAM_BASE, BL32_COHERENT_RAM_LIMIT