diff --git a/Makefile b/Makefile index 5f4a93c94feb04060e7e7b3168537c358b96fe15..800312c94feabd1afb4e4b0d7a271ca02967d5fc 100644 --- a/Makefile +++ b/Makefile @@ -108,6 +108,10 @@ PL011_GENERIC_UART := 0 ENABLE_PMF := 0 # Flag to enable PSCI STATs functionality ENABLE_PSCI_STAT := 0 +# Whether code and read-only data should be put on separate memory pages. +# The platform Makefile is free to override this value. +SEPARATE_CODE_AND_RODATA := 0 + ################################################################################ # Checkpatch script options @@ -419,6 +423,7 @@ $(eval $(call assert_boolean,SPIN_ON_BL1_EXIT)) $(eval $(call assert_boolean,PL011_GENERIC_UART)) $(eval $(call assert_boolean,ENABLE_PMF)) $(eval $(call assert_boolean,ENABLE_PSCI_STAT)) +$(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA)) ################################################################################ @@ -448,6 +453,7 @@ $(eval $(call add_define,SPIN_ON_BL1_EXIT)) $(eval $(call add_define,PL011_GENERIC_UART)) $(eval $(call add_define,ENABLE_PMF)) $(eval $(call add_define,ENABLE_PSCI_STAT)) +$(eval $(call add_define,SEPARATE_CODE_AND_RODATA)) # Define the EL3_PAYLOAD_BASE flag only if it is provided. ifdef EL3_PAYLOAD_BASE $(eval $(call add_define,EL3_PAYLOAD_BASE)) diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S index df9a799481315105380454329b4566fa2c888fdf..b9554d15cf6cbc67d8aa126f9296b6b06bddb338 100644 --- a/bl1/bl1.ld.S +++ b/bl1/bl1.ld.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -45,6 +45,43 @@ SECTIONS ASSERT(. == ALIGN(4096), "BL1_RO_BASE address is not aligned on a page boundary.") +#if SEPARATE_CODE_AND_RODATA + .text . : { + __TEXT_START__ = .; + *bl1_entrypoint.o(.text*) + *(.text*) + *(.vectors) + . = NEXT(4096); + __TEXT_END__ = .; + } >ROM + + .rodata . : { + __RODATA_START__ = .; + *(.rodata*) + + /* Ensure 8-byte alignment for descriptors and ensure inclusion */ + . = ALIGN(8); + __PARSER_LIB_DESCS_START__ = .; + KEEP(*(.img_parser_lib_descs)) + __PARSER_LIB_DESCS_END__ = .; + + /* + * Ensure 8-byte alignment for cpu_ops so that its fields are also + * aligned. Also ensure cpu_ops inclusion. + */ + . = ALIGN(8); + __CPU_OPS_START__ = .; + KEEP(*(cpu_ops)) + __CPU_OPS_END__ = .; + + /* + * No need to pad out the .rodata section to a page boundary. Next is + * the .data section, which can mapped in ROM with the same memory + * attributes as the .rodata section. + */ + __RODATA_END__ = .; + } >ROM +#else ro . : { __RO_START__ = .; *bl1_entrypoint.o(.text*) @@ -69,6 +106,7 @@ SECTIONS *(.vectors) __RO_END__ = .; } >ROM +#endif ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__, "cpu_ops not defined for this platform.") @@ -139,12 +177,14 @@ SECTIONS __DATA_ROM_START__ = LOADADDR(.data); __DATA_SIZE__ = SIZEOF(.data); + /* * The .data section is the last PROGBITS section so its end marks the end - * of the read-only part of BL1's binary. + * of BL1's actual content in Trusted ROM. */ - ASSERT(__DATA_ROM_START__ + __DATA_SIZE__ <= BL1_RO_LIMIT, - "BL1's RO section has exceeded its limit.") + __BL1_ROM_END__ = __DATA_ROM_START__ + __DATA_SIZE__; + ASSERT(__BL1_ROM_END__ <= BL1_RO_LIMIT, + "BL1's ROM content has exceeded its limit.") __BSS_SIZE__ = SIZEOF(.bss); diff --git a/bl1/bl1_private.h b/bl1/bl1_private.h index 283bbb972fb91e8484c5771d9326b8fac8fac105..79dde738dbf77d60183a6f0f55808cbb92b788db 100644 --- a/bl1/bl1_private.h +++ b/bl1/bl1_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,8 +35,11 @@ /******************************************************************************* * Declarations of linker defined symbols which will tell us where BL1 lives - * in Trusted RAM + * in Trusted ROM and RAM ******************************************************************************/ +extern uint64_t __BL1_ROM_END__; +#define BL1_ROM_END (uint64_t)(&__BL1_ROM_END__) + extern uint64_t __BL1_RAM_START__; extern uint64_t __BL1_RAM_END__; #define BL1_RAM_BASE (uint64_t)(&__BL1_RAM_START__) diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index a660bda63c51516ecd9ad2c83d15aa57714ea76e..fa694de280ca945e6e2a39fc9d65ddb878af6065 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -45,6 +45,30 @@ SECTIONS ASSERT(. == ALIGN(4096), "BL2_BASE address is not aligned on a page boundary.") +#if SEPARATE_CODE_AND_RODATA + .text . : { + __TEXT_START__ = .; + *bl2_entrypoint.o(.text*) + *(.text*) + *(.vectors) + . = NEXT(4096); + __TEXT_END__ = .; + } >RAM + + .rodata . : { + __RODATA_START__ = .; + *(.rodata*) + + /* Ensure 8-byte alignment for descriptors and ensure inclusion */ + . = ALIGN(8); + __PARSER_LIB_DESCS_START__ = .; + KEEP(*(.img_parser_lib_descs)) + __PARSER_LIB_DESCS_END__ = .; + + . = NEXT(4096); + __RODATA_END__ = .; + } >RAM +#else ro . : { __RO_START__ = .; *bl2_entrypoint.o(.text*) @@ -67,6 +91,7 @@ SECTIONS . = NEXT(4096); __RO_END__ = .; } >RAM +#endif /* * Define a linker symbol to mark start of the RW memory area for this diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S index ec12077917b4b782719d447237e7cb3b81c7cbaa..d72589fcaf5f2360e22cb349c6e1de78f58320b7 100644 --- a/bl2u/bl2u.ld.S +++ b/bl2u/bl2u.ld.S @@ -45,6 +45,23 @@ SECTIONS ASSERT(. == ALIGN(4096), "BL2U_BASE address is not aligned on a page boundary.") +#if SEPARATE_CODE_AND_RODATA + .text . : { + __TEXT_START__ = .; + *bl2u_entrypoint.o(.text*) + *(.text*) + *(.vectors) + . = NEXT(4096); + __TEXT_END__ = .; + } >RAM + + .rodata . : { + __RODATA_START__ = .; + *(.rodata*) + . = NEXT(4096); + __RODATA_END__ = .; + } >RAM +#else ro . : { __RO_START__ = .; *bl2u_entrypoint.o(.text*) @@ -61,6 +78,7 @@ SECTIONS . = NEXT(4096); __RO_END__ = .; } >RAM +#endif /* * Define a linker symbol to mark start of the RW memory area for this diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 33cbe4b79cf7a124d835cfa884b72c7265cdaf21..743e65c4059f1695ddab4ad92aeeb6c46ee97390 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -46,6 +46,47 @@ SECTIONS ASSERT(. == ALIGN(4096), "BL31_BASE address is not aligned on a page boundary.") +#if SEPARATE_CODE_AND_RODATA + .text . : { + __TEXT_START__ = .; + *bl31_entrypoint.o(.text*) + *(.text*) + *(.vectors) + . = NEXT(4096); + __TEXT_END__ = .; + } >RAM + + .rodata . : { + __RODATA_START__ = .; + *(.rodata*) + + /* Ensure 8-byte alignment for descriptors and ensure inclusion */ + . = ALIGN(8); + __RT_SVC_DESCS_START__ = .; + KEEP(*(rt_svc_descs)) + __RT_SVC_DESCS_END__ = .; + +#if ENABLE_PMF + /* Ensure 8-byte alignment for descriptors and ensure inclusion */ + . = ALIGN(8); + __PMF_SVC_DESCS_START__ = .; + KEEP(*(pmf_svc_descs)) + __PMF_SVC_DESCS_END__ = .; +#endif /* ENABLE_PMF */ + + /* + * Ensure 8-byte alignment for cpu_ops so that its fields are also + * aligned. Also ensure cpu_ops inclusion. + */ + . = ALIGN(8); + __CPU_OPS_START__ = .; + KEEP(*(cpu_ops)) + __CPU_OPS_END__ = .; + + . = NEXT(4096); + __RODATA_END__ = .; + } >RAM +#else ro . : { __RO_START__ = .; *bl31_entrypoint.o(.text*) @@ -85,6 +126,7 @@ SECTIONS . = NEXT(4096); __RO_END__ = .; } >RAM +#endif ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__, "cpu_ops not defined for this platform.") diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S index 9c7ed3815cf6b4d0f61c2b6793c0975f011c5fe5..7e24f66d7ba02452527ffcaa441d5f70e70efbc0 100644 --- a/bl32/tsp/tsp.ld.S +++ b/bl32/tsp/tsp.ld.S @@ -46,6 +46,23 @@ SECTIONS ASSERT(. == ALIGN(4096), "BL32_BASE address is not aligned on a page boundary.") +#if SEPARATE_CODE_AND_RODATA + .text . : { + __TEXT_START__ = .; + *tsp_entrypoint.o(.text*) + *(.text*) + *(.vectors) + . = NEXT(4096); + __TEXT_END__ = .; + } >RAM + + .rodata . : { + __RODATA_START__ = .; + *(.rodata*) + . = NEXT(4096); + __RODATA_END__ = .; + } >RAM +#else ro . : { __RO_START__ = .; *tsp_entrypoint.o(.text*) @@ -61,6 +78,7 @@ SECTIONS . = NEXT(4096); __RO_END__ = .; } >RAM +#endif /* * Define a linker symbol to mark start of the RW memory area for this diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c index 359b9e1692b121bb3c8b0ab11b22ea3868681265..d03f7e2214c98273de4ab1655189bf991b63e474 100644 --- a/bl32/tsp/tsp_main.c +++ b/bl32/tsp/tsp_main.c @@ -56,12 +56,12 @@ static tsp_args_t tsp_smc_args[PLATFORM_CORE_COUNT]; work_statistics_t tsp_stats[PLATFORM_CORE_COUNT]; /******************************************************************************* - * The BL32 memory footprint starts with an RO sections and ends - * with the linker symbol __BL32_END__. Use it to find the memory size + * The TSP memory footprint starts at address BL32_BASE and ends with the + * linker symbol __BL32_END__. Use these addresses to compute the TSP image + * size. ******************************************************************************/ -#define BL32_TOTAL_BASE (unsigned long)(&__RO_START__) - #define BL32_TOTAL_LIMIT (unsigned long)(&__BL32_END__) +#define BL32_TOTAL_SIZE (BL32_TOTAL_LIMIT - (unsigned long) BL32_BASE) static tsp_args_t *set_smc_args(uint64_t arg0, uint64_t arg1, @@ -102,9 +102,8 @@ uint64_t tsp_main(void) { NOTICE("TSP: %s\n", version_string); NOTICE("TSP: %s\n", build_message); - INFO("TSP: Total memory base : 0x%lx\n", BL32_TOTAL_BASE); - INFO("TSP: Total memory size : 0x%lx bytes\n", - BL32_TOTAL_LIMIT - BL32_TOTAL_BASE); + INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE); + INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE); uint32_t linear_id = plat_my_core_pos(); diff --git a/docs/firmware-design.md b/docs/firmware-design.md index 294349d9c686f57a71b790a14c172ef0ff23d72c..b99a2838f905d109285d464ab383b09827cbd7cc 100644 --- a/docs/firmware-design.md +++ b/docs/firmware-design.md @@ -1052,10 +1052,10 @@ Each bootloader image can be divided in 2 parts: All PROGBITS sections are grouped together at the beginning of the image, followed by all NOBITS sections. This is true for all Trusted Firmware images and it is governed by the linker scripts. This ensures that the raw binary -images are as small as possible. If a NOBITS section would sneak in between -PROGBITS sections then the resulting binary file would contain a bunch of zero -bytes at the location of this NOBITS section, making the image unnecessarily -bigger. Smaller images allow faster loading from the FIP to the main memory. +images are as small as possible. If a NOBITS section was inserted in between +PROGBITS sections then the resulting binary file would contain zero bytes in +place of this NOBITS section, making the image unnecessarily bigger. Smaller +images allow faster loading from the FIP to the main memory. ### Linker scripts and symbols @@ -1110,47 +1110,48 @@ layout as they are easy to spot in the link map files. #### Common linker symbols -Early setup code needs to know the extents of the BSS section to zero-initialise -it before executing any C code. The following linker symbols are defined for -this purpose: - -* `__BSS_START__` This address must be aligned on a 16-byte boundary. -* `__BSS_SIZE__` - -Similarly, the coherent memory section (if enabled) must be zero-initialised. -Also, the MMU setup code needs to know the extents of this section to set the -right memory attributes for it. The following linker symbols are defined for -this purpose: - -* `__COHERENT_RAM_START__` This address must be aligned on a page-size boundary. -* `__COHERENT_RAM_END__` This address must be aligned on a page-size boundary. -* `__COHERENT_RAM_UNALIGNED_SIZE__` +All BL images share the following requirements: + +* The BSS section must be zero-initialised before executing any C code. +* The coherent memory section (if enabled) must be zero-initialised as well. +* The MMU setup code needs to know the extents of the coherent and read-only + memory regions to set the right memory attributes. When + `SEPARATE_CODE_AND_RODATA=1`, it needs to know more specifically how the + read-only memory region is divided between code and data. + +The following linker symbols are defined for this purpose: + +* `__BSS_START__` Must be aligned on a 16-byte boundary. +* `__BSS_SIZE__` +* `__COHERENT_RAM_START__` Must be aligned on a page-size boundary. +* `__COHERENT_RAM_END__` Must be aligned on a page-size boundary. +* `__COHERENT_RAM_UNALIGNED_SIZE__` +* `__RO_START__` +* `__RO_END__` +* `__TEXT_START__` +* `__TEXT_END__` +* `__RODATA_START__` +* `__RODATA_END__` #### BL1's linker symbols -BL1's early setup code needs to know the extents of the .data section to -relocate it from ROM to RAM before executing any C code. The following linker -symbols are defined for this purpose: - -* `__DATA_ROM_START__` This address must be aligned on a 16-byte boundary. -* `__DATA_RAM_START__` This address must be aligned on a 16-byte boundary. -* `__DATA_SIZE__` - -BL1's platform setup code needs to know the extents of its read-write data -region to figure out its memory layout. The following linker symbols are defined -for this purpose: - -* `__BL1_RAM_START__` This is the start address of BL1 RW data. -* `__BL1_RAM_END__` This is the end address of BL1 RW data. +BL1 being the ROM image, it has additional requirements. BL1 resides in ROM and +it is entirely executed in place but it needs some read-write memory for its +mutable data. Its `.data` section (i.e. its allocated read-write data) must be +relocated from ROM to RAM before executing any C code. -#### BL2's, BL31's and TSP's linker symbols +The following additional linker symbols are defined for BL1: -BL2, BL31 and TSP need to know the extents of their read-only section to set -the right memory attributes for this memory region in their MMU setup code. The -following linker symbols are defined for this purpose: +* `__BL1_ROM_END__` End address of BL1's ROM contents, covering its code + and `.data` section in ROM. +* `__DATA_ROM_START__` Start address of the `.data` section in ROM. Must be + aligned on a 16-byte boundary. +* `__DATA_RAM_START__` Address in RAM where the `.data` section should be + copied over. Must be aligned on a 16-byte boundary. +* `__DATA_SIZE__` Size of the `.data` section (in ROM or RAM). +* `__BL1_RAM_START__` Start address of BL1 read-write data. +* `__BL1_RAM_END__` End address of BL1 read-write data. -* `__RO_START__` -* `__RO_END__` ### How to choose the right base addresses for each bootloader stage image diff --git a/include/common/bl_common.h b/include/common/bl_common.h index f13dc316cfd01434f2e8fa398e7da4111291dfaa..646a817242f2c32a1f9d3b5718119b8f9fcb4f0c 100644 --- a/include/common/bl_common.h +++ b/include/common/bl_common.h @@ -137,15 +137,22 @@ #include #include #include - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#include /* To retain compatibility */ /* * Declarations of linker defined symbols to help determine memory layout of * BL images */ +#if SEPARATE_CODE_AND_RODATA +extern unsigned long __TEXT_START__; +extern unsigned long __TEXT_END__; +extern unsigned long __RODATA_START__; +extern unsigned long __RODATA_END__; +#else extern unsigned long __RO_START__; extern unsigned long __RO_END__; +#endif + #if IMAGE_BL2 extern unsigned long __BL2_END__; #elif IMAGE_BL2U diff --git a/include/lib/utils.h b/include/lib/utils.h new file mode 100644 index 0000000000000000000000000000000000000000..9cc5468b3de029856a7d856767d908eaa0475edb --- /dev/null +++ b/include/lib/utils.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __UTILS_H__ +#define __UTILS_H__ + +/* Compute the number of elements in the given array */ +#define ARRAY_SIZE(a) \ + (sizeof(a) / sizeof((a)[0])) + +#define IS_POWER_OF_TWO(x) \ + (((x) & ((x) - 1)) == 0) + +/* + * The round_up() macro rounds up a value to the given boundary in a + * type-agnostic yet type-safe manner. The boundary must be a power of two. + * In other words, it computes the smallest multiple of boundary which is + * greater than or equal to value. + * + * round_down() is similar but rounds the value down instead. + */ +#define round_boundary(value, boundary) \ + ((__typeof__(value))((boundary) - 1)) + +#define round_up(value, boundary) \ + ((((value) - 1) | round_boundary(value, boundary)) + 1) + +#define round_down(value, boundary) \ + ((value) & ~round_boundary(value, boundary)) + +#endif /* __UTILS_H__ */ diff --git a/include/lib/xlat_tables.h b/include/lib/xlat_tables.h index 7d57521b7e6b42f458a2908f16e0704b018b325e..b51a1de5c413fd976c1ae8d97730a87587f936dd 100644 --- a/include/lib/xlat_tables.h +++ b/include/lib/xlat_tables.h @@ -134,6 +134,8 @@ #define MT_PERM_SHIFT 3 /* Security state (SECURE/NS) */ #define MT_SEC_SHIFT 4 +/* Access permissions for instruction execution (EXECUTE/EXECUTE_NEVER) */ +#define MT_EXECUTE_SHIFT 5 /* * Memory mapping attributes @@ -155,8 +157,21 @@ typedef enum { MT_SECURE = 0 << MT_SEC_SHIFT, MT_NS = 1 << MT_SEC_SHIFT, + + /* + * Access permissions for instruction execution are only relevant for + * normal read-only memory, i.e. MT_MEMORY | MT_RO. They are ignored + * (and potentially overridden) otherwise: + * - Device memory is always marked as execute-never. + * - Read-write normal memory is always marked as execute-never. + */ + MT_EXECUTE = 0 << MT_EXECUTE_SHIFT, + MT_EXECUTE_NEVER = 1 << MT_EXECUTE_SHIFT, } mmap_attr_t; +#define MT_CODE (MT_MEMORY | MT_RO | MT_EXECUTE) +#define MT_RO_DATA (MT_MEMORY | MT_RO | MT_EXECUTE_NEVER) + /* * Structure for specifying a single region of memory. */ diff --git a/include/plat/arm/board/common/v2m_def.h b/include/plat/arm/board/common/v2m_def.h index 888792edd2d47b934bb19f0d47a21726be6b00f0..7cee4e8f17e3eb3cdf92381a05d828f0f1785be2 100644 --- a/include/plat/arm/board/common/v2m_def.h +++ b/include/plat/arm/board/common/v2m_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -119,13 +119,26 @@ #define V2M_SP810_CTRL_TIM2_SEL (1 << 19) #define V2M_SP810_CTRL_TIM3_SEL (1 << 21) +/* + * The flash can be mapped either as read-only or read-write. + * + * If it is read-write then it should also be mapped as device memory because + * NOR flash programming involves sending a fixed, ordered sequence of commands. + * + * If it is read-only then it should also be mapped as: + * - Normal memory, because reading from NOR flash is transparent, it is like + * reading from RAM. + * - Non-executable by default. If some parts of the flash need to be executable + * then platform code is responsible for re-mapping the appropriate portion + * of it as executable. + */ #define V2M_MAP_FLASH0_RW MAP_REGION_FLAT(V2M_FLASH0_BASE,\ V2M_FLASH0_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) #define V2M_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\ V2M_FLASH0_SIZE, \ - MT_MEMORY | MT_RO | MT_SECURE) + MT_RO_DATA | MT_SECURE) #define V2M_MAP_IOFPGA MAP_REGION_FLAT(V2M_IOFPGA_BASE,\ V2M_IOFPGA_SIZE, \ diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 2fe0a6905e6920b594a25e11dd71fe85541d0731..06912eba7ceb0f79d956f17ddd26dd52bff17247 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -31,10 +31,10 @@ #define __PLAT_ARM_H__ #include -#include #include #include #include +#include #include #define ARM_CASSERT_MMAP \ @@ -45,20 +45,12 @@ /* * Utility functions common to ARM standard platforms */ - -void arm_configure_mmu_el1(unsigned long total_base, - unsigned long total_size, - unsigned long ro_start, - unsigned long ro_limit -#if USE_COHERENT_MEM - , unsigned long coh_start, - unsigned long coh_limit -#endif -); -void arm_configure_mmu_el3(unsigned long total_base, +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/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c index 051e46a224b87e0522b504d6c059e237b690ff78..19eb7d5ded9877f28bac14f6aba60745bb19f992 100644 --- a/lib/xlat_tables/aarch64/xlat_tables.c +++ b/lib/xlat_tables/aarch64/xlat_tables.c @@ -33,11 +33,10 @@ #include #include #include +#include #include #include "../xlat_tables_private.h" -#define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0) - /* * The virtual address space size must be a power of two (as set in TCR.T0SZ). * As we start the initial lookup at level 1, it must also be between 2 GB and diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c index fd100846464096c15f5451e4e52e22814594dfc3..71e3efca94bf375dbfee2ef4269c4134df994231 100644 --- a/lib/xlat_tables/xlat_tables_common.c +++ b/lib/xlat_tables/xlat_tables_common.c @@ -31,11 +31,11 @@ #include #include #include -#include #include #include #include #include +#include #include #if LOG_LEVEL >= LOG_LEVEL_VERBOSE @@ -194,37 +194,66 @@ void mmap_add(const mmap_region_t *mm) static uint64_t mmap_desc(unsigned attr, unsigned long long addr_pa, int level) { - uint64_t desc = addr_pa; + uint64_t desc; int mem_type; - desc |= level == 3 ? TABLE_DESC : BLOCK_DESC; - - desc |= attr & MT_NS ? LOWER_ATTRS(NS) : 0; - - desc |= attr & MT_RW ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO); - + desc = addr_pa; + desc |= (level == 3) ? TABLE_DESC : BLOCK_DESC; + desc |= (attr & MT_NS) ? LOWER_ATTRS(NS) : 0; + desc |= (attr & MT_RW) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO); desc |= LOWER_ATTRS(ACCESS_FLAG); + /* + * Deduce shareability domain and executability of the memory region + * from the memory type. + * + * Data accesses to device memory and non-cacheable normal memory are + * coherent for all observers in the system, and correspondingly are + * always treated as being Outer Shareable. Therefore, for these 2 types + * of memory, it is not strictly needed to set the shareability field + * in the translation tables. + */ mem_type = MT_TYPE(attr); - if (mem_type == MT_MEMORY) { - desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX | ISH); - if (attr & MT_RW) - desc |= UPPER_ATTRS(XN); - } else if (mem_type == MT_NON_CACHEABLE) { - desc |= LOWER_ATTRS(ATTR_NON_CACHEABLE_INDEX | OSH); - if (attr & MT_RW) - desc |= UPPER_ATTRS(XN); - } else { - assert(mem_type == MT_DEVICE); + if (mem_type == MT_DEVICE) { desc |= LOWER_ATTRS(ATTR_DEVICE_INDEX | OSH); + /* + * Always map device memory as execute-never. + * This is to avoid the possibility of a speculative instruction + * fetch, which could be an issue if this memory region + * corresponds to a read-sensitive peripheral. + */ desc |= UPPER_ATTRS(XN); + } else { /* Normal memory */ + /* + * Always map read-write normal memory as execute-never. + * (Trusted Firmware doesn't self-modify its code, therefore + * R/W memory is reserved for data storage, which must not be + * executable.) + * Note that setting the XN bit here is for consistency only. + * The enable_mmu_elx() function sets the SCTLR_EL3.WXN bit, + * which makes any writable memory region to be treated as + * execute-never, regardless of the value of the XN bit in the + * translation table. + * + * For read-only memory, rely on the MT_EXECUTE/MT_EXECUTE_NEVER + * attribute to figure out the value of the XN bit. + */ + if ((attr & MT_RW) || (attr & MT_EXECUTE_NEVER)) + desc |= UPPER_ATTRS(XN); + + if (mem_type == MT_MEMORY) { + desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX | ISH); + } else { + assert(mem_type == MT_NON_CACHEABLE); + desc |= LOWER_ATTRS(ATTR_NON_CACHEABLE_INDEX | OSH); + } } debug_print((mem_type == MT_MEMORY) ? "MEM" : ((mem_type == MT_NON_CACHEABLE) ? "NC" : "DEV")); debug_print(attr & MT_RW ? "-RW" : "-RO"); debug_print(attr & MT_NS ? "-NS" : "-S"); - + debug_print(attr & MT_EXECUTE_NEVER ? "-XN" : "-EXEC"); return desc; } diff --git a/plat/arm/board/common/board_css_common.c b/plat/arm/board/common/board_css_common.c index 62253f8c47535c0f020ad6a28fb10f603704ae2e..69b744d97386707508573ffb1d71deaab9c3d345 100644 --- a/plat/arm/board/common/board_css_common.c +++ b/plat/arm/board/common/board_css_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,9 +31,9 @@ #include /* - * Table of regions for different BL stages to map using the MMU. - * This doesn't include Trusted RAM as the 'mem_layout' argument passed to - * arm_configure_mmu_elx() will give the available subset of that, + * Table of memory regions for different BL stages to map using the MMU. + * This doesn't include Trusted SRAM as arm_setup_page_tables() already + * takes care of mapping it. */ #if IMAGE_BL1 const mmap_region_t plat_arm_mmap[] = { diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 0f557af243497afd870689d19914a185d16d51e0..002cff6707c35e7cae3b0b7d1c78107b77149404 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -66,9 +66,12 @@ arm_config_t arm_config; /* - * Table of regions for various BL stages to map using the MMU. - * This doesn't include TZRAM as the 'mem_layout' argument passed to - * arm_configure_mmu_elx() will give the available subset of that, + * Table of memory regions for various BL stages to map using the MMU. + * This doesn't include Trusted SRAM as arm_setup_page_tables() already + * takes care of mapping it. + * + * The flash needs to be mapped as writable in order to erase the FIP's Table of + * Contents in case of unrecoverable error (see plat_error_handler()). */ #if IMAGE_BL1 const mmap_region_t plat_arm_mmap[] = { diff --git a/plat/arm/common/aarch64/arm_common.c b/plat/arm/common/aarch64/arm_common.c index c4cc80e6de031eea63c525e9e2f331fcec6d9244..7c0b93db8c7ca31b7fec8c7c8b0bfb2fb879526c 100644 --- a/plat/arm/common/aarch64/arm_common.c +++ b/plat/arm/common/aarch64/arm_common.c @@ -50,57 +50,67 @@ extern const mmap_region_t plat_arm_mmap[]; #pragma weak plat_get_syscnt_freq #endif -/******************************************************************************* - * Macro generating the code for the function setting up the pagetables as per - * the platform memory map & initialize the mmu, for the given exception level - ******************************************************************************/ +/* + * Set up the page tables for the generic and platform-specific memory regions. + * The extents of the generic memory regions are specified by the function + * arguments and consist of: + * - Trusted SRAM seen by the BL image; + * - 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 code_start, + unsigned long code_limit, + unsigned long rodata_start, + unsigned long rodata_limit #if USE_COHERENT_MEM -#define DEFINE_CONFIGURE_MMU_EL(_el) \ - void arm_configure_mmu_el##_el(unsigned long total_base, \ - unsigned long total_size, \ - unsigned long ro_start, \ - unsigned long ro_limit, \ - unsigned long coh_start, \ - unsigned long coh_limit) \ - { \ - mmap_add_region(total_base, total_base, \ - total_size, \ - MT_MEMORY | MT_RW | MT_SECURE); \ - mmap_add_region(ro_start, ro_start, \ - ro_limit - ro_start, \ - MT_MEMORY | MT_RO | MT_SECURE); \ - mmap_add_region(coh_start, coh_start, \ - coh_limit - coh_start, \ - MT_DEVICE | MT_RW | MT_SECURE); \ - mmap_add(plat_arm_get_mmap()); \ - init_xlat_tables(); \ - \ - enable_mmu_el##_el(0); \ - } -#else -#define DEFINE_CONFIGURE_MMU_EL(_el) \ - void arm_configure_mmu_el##_el(unsigned long total_base, \ - unsigned long total_size, \ - unsigned long ro_start, \ - unsigned long ro_limit) \ - { \ - mmap_add_region(total_base, total_base, \ - total_size, \ - MT_MEMORY | MT_RW | MT_SECURE); \ - mmap_add_region(ro_start, ro_start, \ - ro_limit - ro_start, \ - MT_MEMORY | MT_RO | MT_SECURE); \ - mmap_add(plat_arm_get_mmap()); \ - init_xlat_tables(); \ - \ - enable_mmu_el##_el(0); \ - } + , + unsigned long coh_start, + unsigned long coh_limit +#endif + ) +{ + /* + * Map the Trusted SRAM with appropriate memory attributes. + * Subsequent mappings will adjust the attributes for specific regions. + */ + VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n", + (void *) total_base, (void *) (total_base + total_size)); + mmap_add_region(total_base, total_base, + total_size, + MT_MEMORY | MT_RW | MT_SECURE); + + /* Re-map the code section */ + VERBOSE("Code region: %p - %p\n", + (void *) code_start, (void *) code_limit); + mmap_add_region(code_start, code_start, + code_limit - code_start, + MT_CODE | MT_SECURE); + + /* Re-map the read-only data section */ + VERBOSE("Read-only data region: %p - %p\n", + (void *) rodata_start, (void *) rodata_limit); + 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 */ + VERBOSE("Coherent region: %p - %p\n", + (void *) coh_start, (void *) coh_limit); + mmap_add_region(coh_start, coh_start, + coh_limit - coh_start, + MT_DEVICE | MT_RW | MT_SECURE); #endif -/* Define EL1 and EL3 variants of the function initialising the MMU */ -DEFINE_CONFIGURE_MMU_EL(1) -DEFINE_CONFIGURE_MMU_EL(3) + /* Now (re-)map the platform-specific memory regions */ + mmap_add(plat_arm_get_mmap()); + /* Create the page tables to reflect the above mappings */ + init_xlat_tables(); +} uintptr_t plat_get_ns_image_entrypoint(void) { diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index 951f48a5b76d0bb47725c98cf2894c824a0c9344..c94f0cd773a99d50852116e9dcd68219197bcb38 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include "../../../bl1/bl1_private.h" @@ -118,15 +120,18 @@ void bl1_early_platform_setup(void) *****************************************************************************/ void arm_bl1_plat_arch_setup(void) { - arm_configure_mmu_el3(bl1_tzram_layout.total_base, + arm_setup_page_tables(bl1_tzram_layout.total_base, bl1_tzram_layout.total_size, - BL1_RO_BASE, - BL1_RO_LIMIT + 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 #endif ); + enable_mmu_el3(0); } void bl1_plat_arch_setup(void) diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 681dc8adf8bfe406c3c439d6438c4d44a919429b..b6afaa7f519844f63df910e091b6956310c6046e 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -36,16 +36,6 @@ #include #include - -/* - * 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. @@ -234,15 +224,18 @@ void bl2_platform_setup(void) ******************************************************************************/ void arm_bl2_plat_arch_setup(void) { - arm_configure_mmu_el1(bl2_tzram_layout.total_base, + 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 #endif ); + enable_mmu_el1(0); } void bl2_plat_arch_setup(void) diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c index 5b7354b3ebc13eab1546c7e97e167d13deb74ba0..de7d0c2f9e582d3a3cb102b3efbac875f1ff92c3 100644 --- a/plat/arm/common/arm_bl2u_setup.c +++ b/plat/arm/common/arm_bl2u_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -36,16 +36,6 @@ #include #include - -/* - * 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. @@ -102,16 +92,19 @@ void bl2u_early_platform_setup(meminfo_t *mem_layout, void *plat_info) ******************************************************************************/ void arm_bl2u_plat_arch_setup(void) { - arm_configure_mmu_el1(BL2U_RO_LIMIT, + 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, BL2U_COHERENT_RAM_LIMIT #endif ); + enable_mmu_el1(0); } void bl2u_plat_arch_setup(void) diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 8eb681802ccb8544ad946e2ad801f1f07c28a284..87cafced8501f326aceaa2f70231a5ffe35a2c05 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -38,16 +38,6 @@ #include #include - -/* - * 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 @@ -246,20 +236,25 @@ void bl31_plat_runtime_setup(void) } /******************************************************************************* - * Perform the very early platform specific architectural setup here. At the - * moment this is only intializes the mmu in a quick and dirty way. + * Perform the very early platform specific architectural setup shared between + * ARM standard platforms. This only does basic initialization. Later + * architectural setup (bl31_arch_setup()) does not do anything platform + * specific. ******************************************************************************/ void arm_bl31_plat_arch_setup(void) { - arm_configure_mmu_el3(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 #endif ); + enable_mmu_el3(0); } void bl31_plat_arch_setup(void) diff --git a/plat/arm/common/arm_cci.c b/plat/arm/common/arm_cci.c index 41054c242b23a8ab0cfc3c1180fe581981402461..40cfb480dfc21c6c5cf09794e70ac3b5da054dc7 100644 --- a/plat/arm/common/arm_cci.c +++ b/plat/arm/common/arm_cci.c @@ -32,6 +32,7 @@ #include #include #include +#include static const int cci_map[] = { PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX, 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/arm_io_storage.c b/plat/arm/common/arm_io_storage.c index 153fdfe8d88a8aaf556c90f3e154313be5b4e556..42435a74cfa5a3dca230e995056303192f486504 100644 --- a/plat/arm/common/arm_io_storage.c +++ b/plat/arm/common/arm_io_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -28,7 +28,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include -#include /* For ARRAY_SIZE */ #include #include #include @@ -37,6 +36,7 @@ #include #include #include +#include /* IO devices */ static const io_dev_connector_t *fip_dev_con; diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c index 2a67fd10256c4e098e2e59baee0b8917bf646ad2..09029f4c2a1b5a7c7494c417b816de976c935be0 100644 --- a/plat/arm/common/tsp/arm_tsp_setup.c +++ b/plat/arm/common/tsp/arm_tsp_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,16 +35,6 @@ #include #include - -/* - * 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,13 +88,16 @@ void tsp_platform_setup(void) ******************************************************************************/ void tsp_plat_arch_setup(void) { - arm_configure_mmu_el1(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 #endif ); + enable_mmu_el1(0); } diff --git a/plat/mediatek/mt8173/aarch64/platform_common.c b/plat/mediatek/mt8173/aarch64/platform_common.c index 365df1b0407cb543de58051e10ca93d1cb25f80e..70639edb0528cca75a61eb4b9b46072f8370b61a 100644 --- a/plat/mediatek/mt8173/aarch64/platform_common.c +++ b/plat/mediatek/mt8173/aarch64/platform_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -34,6 +34,7 @@ #include #include #include +#include #include static const int cci_map[] = { diff --git a/plat/mediatek/mt8173/plat_mt_gic.c b/plat/mediatek/mt8173/plat_mt_gic.c index c9bdaa9072e4eebef2467763d87c5883e8a4f765..402a0f4b5a10bc5ff42b546138b2f98172645ac1 100644 --- a/plat/mediatek/mt8173/plat_mt_gic.c +++ b/plat/mediatek/mt8173/plat_mt_gic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ #include #include #include +#include const unsigned int mt_irq_sec_array[] = { MT_IRQ_SEC_SGI_0, diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c index 6e9dab792e3ebb745b6840fa989762d1f5e9e159..40cd29e36f2dd60867a56d6ab73fbdf86774c643 100644 --- a/plat/rockchip/common/aarch64/platform_common.c +++ b/plat/rockchip/common/aarch64/platform_common.c @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef PLAT_RK_CCI_BASE static const int cci_map[] = { diff --git a/plat/rockchip/common/rockchip_gicv2.c b/plat/rockchip/common/rockchip_gicv2.c index 3e1fa91212f05c3d845e2989c26cd02a9a4b8296..c2dca1fcb3578de16d21c54046703ce80ddb9a8a 100644 --- a/plat/rockchip/common/rockchip_gicv2.c +++ b/plat/rockchip/common/rockchip_gicv2.c @@ -31,6 +31,7 @@ #include #include #include +#include /****************************************************************************** * The following functions are defined as weak to allow a platform to override diff --git a/plat/rockchip/common/rockchip_gicv3.c b/plat/rockchip/common/rockchip_gicv3.c index d197aba5d897e431820fbcb6ea1f91f1b76c73e4..77308965e9cf660449d44ba2d33ef255c7de6c41 100644 --- a/plat/rockchip/common/rockchip_gicv3.c +++ b/plat/rockchip/common/rockchip_gicv3.c @@ -32,6 +32,7 @@ #include #include #include +#include /****************************************************************************** * The following functions are defined as weak to allow a platform to override diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c index 6f1a18b102deb8b56c5ec1db812f0ff133d3ed22..ffed591cf9aa04e5040e8613f3006571f1d8d44c 100644 --- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c +++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c @@ -147,18 +147,20 @@ void bl31_plat_runtime_setup(void) } /* - * Perform the very early platform specific architectural setup here. At the - * moment this is only intializes the MMU in a quick and dirty way. + * Perform the very early platform specific architectural setup here. */ void bl31_plat_arch_setup(void) { plat_arm_interconnect_init(); plat_arm_interconnect_enter_coherency(); - arm_configure_mmu_el3(BL31_RO_BASE, + arm_setup_page_tables(BL31_RO_BASE, 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/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c index d3396dfa9c79060d9c1393b12b01dad76d38ed73..cf0d5f08d3607cf83e6efae364c5a49186d983d4 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_client.c +++ b/plat/xilinx/zynqmp/pm_service/pm_client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -37,6 +37,7 @@ #include #include #include +#include #include "pm_api_sys.h" #include "pm_client.h" #include "pm_ipi.h" diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c index 58a3e2a18d6e89031c9a3757786befcfaf9fb9a0..ae66fa4157c5901c410d688a5c68ae5b7b347682 100644 --- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c +++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -90,13 +90,16 @@ void tsp_platform_setup(void) ******************************************************************************/ void tsp_plat_arch_setup(void) { - arm_configure_mmu_el1(BL32_RO_BASE, + 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 #endif ); + enable_mmu_el1(0); }