diff --git a/Makefile b/Makefile index be543facb61ce43e10b4016bb01e44c619ff1238..74d518043363b71c743ba5d54c2a5a50d0c2b3c8 100644 --- a/Makefile +++ b/Makefile @@ -205,11 +205,6 @@ TF_CFLAGS += $(CPPFLAGS) $(TF_CFLAGS_$(ARCH)) \ -Os -ffunction-sections -fdata-sections GCC_V_OUTPUT := $(shell $(CC) -v 2>&1) -PIE_FOUND := $(findstring --enable-default-pie,${GCC_V_OUTPUT}) - -ifneq ($(PIE_FOUND),) -TF_CFLAGS += -fno-PIE -endif # Force the compiler to include the frame pointer ifeq (${ENABLE_BACKTRACE},1) @@ -335,6 +330,16 @@ ifeq (${ARM_ARCH_MAJOR},7) include make_helpers/armv7-a-cpus.mk endif +ifeq ($(ENABLE_PIE),1) + TF_CFLAGS += -fpie + TF_LDFLAGS += -pie +else + PIE_FOUND := $(findstring --enable-default-pie,${GCC_V_OUTPUT}) + ifneq ($(PIE_FOUND),) + TF_CFLAGS += -fno-PIE + endif +endif + # Include the CPU specific operations makefile, which provides default # values for all CPU errata workarounds and CPU specific optimisations. # This can be overridden by the platform. @@ -565,6 +570,7 @@ $(eval $(call assert_boolean,ENABLE_AMU)) $(eval $(call assert_boolean,ENABLE_ASSERTIONS)) $(eval $(call assert_boolean,ENABLE_BACKTRACE)) $(eval $(call assert_boolean,ENABLE_MPAM_FOR_LOWER_ELS)) +$(eval $(call assert_boolean,ENABLE_PIE)) $(eval $(call assert_boolean,ENABLE_PMF)) $(eval $(call assert_boolean,ENABLE_PSCI_STAT)) $(eval $(call assert_boolean,ENABLE_RUNTIME_INSTRUMENTATION)) @@ -615,6 +621,7 @@ $(eval $(call add_define,ENABLE_AMU)) $(eval $(call add_define,ENABLE_ASSERTIONS)) $(eval $(call add_define,ENABLE_BACKTRACE)) $(eval $(call add_define,ENABLE_MPAM_FOR_LOWER_ELS)) +$(eval $(call add_define,ENABLE_PIE)) $(eval $(call add_define,ENABLE_PMF)) $(eval $(call add_define,ENABLE_PSCI_STAT)) $(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION)) diff --git a/bl2/aarch64/bl2_entrypoint.S b/bl2/aarch64/bl2_entrypoint.S index bc8cbfd653601935e92ff47672a6ccad86ffb2e8..30a5c599a676aedf236602f2c05b5df239517ed4 100644 --- a/bl2/aarch64/bl2_entrypoint.S +++ b/bl2/aarch64/bl2_entrypoint.S @@ -70,13 +70,19 @@ func bl2_entrypoint * - the coherent memory section. * --------------------------------------------- */ - ldr x0, =__BSS_START__ - ldr x1, =__BSS_SIZE__ + adrp x0, __BSS_START__ + add x0, x0, :lo12:__BSS_START__ + adrp x1, __BSS_END__ + add x1, x1, :lo12:__BSS_END__ + sub x1, x1, x0 bl zeromem #if USE_COHERENT_MEM - ldr x0, =__COHERENT_RAM_START__ - ldr x1, =__COHERENT_RAM_UNALIGNED_SIZE__ + adrp x0, __COHERENT_RAM_START__ + add x0, x0, :lo12:__COHERENT_RAM_START__ + adrp x1, __COHERENT_RAM_END_UNALIGNED__ + add x1, x1, :lo12:__COHERENT_RAM_END_UNALIGNED__ + sub x1, x1, x0 bl zeromem #endif diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S index 3a45e53f4b621bc43ee8cbedc0cfd2fc62254e03..7c116a2e0d21e0ebe8ef95a6600e7f017611bea4 100644 --- a/bl31/aarch64/bl31_entrypoint.S +++ b/bl31/aarch64/bl31_entrypoint.S @@ -7,6 +7,7 @@ #include <arch.h> #include <bl_common.h> #include <el3_common_macros.S> +#include <platform_def.h> #include <pmf_asm_macros.S> #include <runtime_instr.h> #include <xlat_mmu_helpers.h> @@ -73,6 +74,18 @@ func bl31_entrypoint mov x22, 0 mov x23, 0 #endif /* RESET_TO_BL31 */ + + /* -------------------------------------------------------------------- + * If PIE is enabled, fixup the Global descriptor Table and dynamic + * relocations + * -------------------------------------------------------------------- + */ +#if ENABLE_PIE + mov_imm x0, BL31_BASE + mov_imm x1, BL31_LIMIT + bl fixup_gdt_reloc +#endif /* ENABLE_PIE */ + /* --------------------------------------------- * Perform platform specific early arch. setup * --------------------------------------------- diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 81e7ba3a3428b66ca112e48c5d9bc03a57e74507..43d0ed440d8101883045a95e39d4b5c9035a61f7 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -26,6 +26,8 @@ SECTIONS ASSERT(. == ALIGN(PAGE_SIZE), "BL31_BASE address is not aligned on a page boundary.") + __BL31_START__ = .; + #if SEPARATE_CODE_AND_RODATA .text . : { __TEXT_START__ = .; @@ -63,6 +65,16 @@ SECTIONS KEEP(*(cpu_ops)) __CPU_OPS_END__ = .; + /* + * Keep the .got section in the RO section as the it is patched + * prior to enabling the MMU and having the .got in RO is better for + * security. + */ + . = ALIGN(16); + __GOT_START__ = .; + *(.got) + __GOT_END__ = .; + /* Place pubsub sections for events */ . = ALIGN(8); #include <pubsub_events.h> @@ -153,6 +165,16 @@ SECTIONS __DATA_END__ = .; } >RAM + . = ALIGN(16); + /* + * .rela.dyn needs to come after .data for the read-elf utility to parse + * this section correctly. + */ + __RELA_START__ = .; + .rela.dyn . : { + } >RAM + __RELA_END__ = .; + #ifdef BL31_PROGBITS_LIMIT ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.") #endif @@ -265,11 +287,5 @@ SECTIONS __RW_END__ = .; __BL31_END__ = .; - __BSS_SIZE__ = SIZEOF(.bss); -#if USE_COHERENT_MEM - __COHERENT_RAM_UNALIGNED_SIZE__ = - __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__; -#endif - ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.") } diff --git a/docs/user-guide.rst b/docs/user-guide.rst index f4ef85d2a140f0356be80d283683298cbace3d73..52cb45c09a18e799fa4ec8c6bd018fbf7a236986 100644 --- a/docs/user-guide.rst +++ b/docs/user-guide.rst @@ -371,6 +371,10 @@ Common build options partitioning in EL3, however. Platform initialisation code should configure and use partitions in EL3 as required. This option defaults to ``0``. +- ``ENABLE_PIE``: Boolean option to enable Position Independent Executable(PIE) + support within generic code in TF-A. This option is currently only supported + in BL31. Default is 0. + - ``ENABLE_PMF``: Boolean option to enable support for optional Performance Measurement Framework(PMF). Default is 0. diff --git a/include/common/aarch64/asm_macros.S b/include/common/aarch64/asm_macros.S index 9621a1c02c8215dcf4d974a7fd044c77e9060a03..91416e4e4f8d6322616d814fc1511befb7bdc973 100644 --- a/include/common/aarch64/asm_macros.S +++ b/include/common/aarch64/asm_macros.S @@ -105,8 +105,9 @@ * Clobber: X30, X1, X2 */ .macro get_my_mp_stack _name, _size - bl plat_my_core_pos - ldr x2, =(\_name + \_size) + bl plat_my_core_pos + adrp x2, (\_name + \_size) + add x2, x2, :lo12:(\_name + \_size) mov x1, #\_size madd x0, x0, x1, x2 .endm @@ -117,7 +118,8 @@ * Out: X0 = physical address of stack base */ .macro get_up_stack _name, _size - ldr x0, =(\_name + \_size) + adrp x0, (\_name + \_size) + add x0, x0, :lo12:(\_name + \_size) .endm /* diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S index 143c70c3912289e39f204a99d7a86a00e7527180..4902583b15b4931051630fd147d5ac1ac9c163b6 100644 --- a/include/common/aarch64/el3_common_macros.S +++ b/include/common/aarch64/el3_common_macros.S @@ -283,26 +283,38 @@ * an earlier boot loader stage. * ------------------------------------------------------------- */ - ldr x0, =__RW_START__ - ldr x1, =__RW_END__ + adrp x0, __RW_START__ + add x0, x0, :lo12:__RW_START__ + adrp x1, __RW_END__ + add x1, x1, :lo12:__RW_END__ sub x1, x1, x0 bl inv_dcache_range #endif + adrp x0, __BSS_START__ + add x0, x0, :lo12:__BSS_START__ - ldr x0, =__BSS_START__ - ldr x1, =__BSS_SIZE__ + adrp x1, __BSS_END__ + add x1, x1, :lo12:__BSS_END__ + sub x1, x1, x0 bl zeromem #if USE_COHERENT_MEM - ldr x0, =__COHERENT_RAM_START__ - ldr x1, =__COHERENT_RAM_UNALIGNED_SIZE__ + adrp x0, __COHERENT_RAM_START__ + add x0, x0, :lo12:__COHERENT_RAM_START__ + adrp x1, __COHERENT_RAM_END_UNALIGNED__ + add x1, x1, :lo12: __COHERENT_RAM_END_UNALIGNED__ + sub x1, x1, x0 bl zeromem #endif #if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_IN_XIP_MEM) - ldr x0, =__DATA_RAM_START__ - ldr x1, =__DATA_ROM_START__ - ldr x2, =__DATA_SIZE__ + adrp x0, __DATA_RAM_START__ + add x0, x0, :lo12:__DATA_RAM_START__ + adrp x1, __DATA_ROM_START__ + add x1, x1, :lo12:__DATA_ROM_START__ + adrp x2, __DATA_RAM_END__ + add x2, x2, :lo12:__DATA_RAM_END__ + sub x2, x2, x0 bl memcpy16 #endif .endif /* _init_c_runtime */ diff --git a/include/common/bl_common.h b/include/common/bl_common.h index 2ecf281c00da15f43404afab85cb49039f3a6084..6a79dc33fe54e6d520e06688a97d55a3980bb8c3 100644 --- a/include/common/bl_common.h +++ b/include/common/bl_common.h @@ -83,6 +83,7 @@ IMPORT_SYM(unsigned long, __BL2_END__, BL2_END); #elif defined(IMAGE_BL2U) IMPORT_SYM(unsigned long, __BL2U_END__, BL2U_END); #elif defined(IMAGE_BL31) +IMPORT_SYM(unsigned long, __BL31_START__, BL31_START); IMPORT_SYM(unsigned long, __BL31_END__, BL31_END); #elif defined(IMAGE_BL32) IMPORT_SYM(unsigned long, __BL32_END__, BL32_END); diff --git a/include/lib/cpus/aarch32/cpu_macros.S b/include/lib/cpus/aarch32/cpu_macros.S index 525e18caf415d1664bd3eaf62c8826054fd37d9e..aa728b2415d16653b9270eddf8fc82f3249969bf 100644 --- a/include/lib/cpus/aarch32/cpu_macros.S +++ b/include/lib/cpus/aarch32/cpu_macros.S @@ -161,10 +161,9 @@ .endif /* - * Weakly-bound, optional errata status printing function for CPUs of + * Mandatory errata status printing function for CPUs of * this class. */ - .weak \_name\()_errata_report .word \_name\()_errata_report #ifdef IMAGE_BL32 diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S index 4672cbc061623e07e503ae2b71ec4b460680709f..14616ace4f516b4b6a700a58b1fc6b7bf98733f0 100644 --- a/include/lib/cpus/aarch64/cpu_macros.S +++ b/include/lib/cpus/aarch64/cpu_macros.S @@ -183,10 +183,9 @@ .endif /* - * Weakly-bound, optional errata status printing function for CPUs of + * Mandatory errata status printing function for CPUs of * this class. */ - .weak \_name\()_errata_report .quad \_name\()_errata_report #ifdef IMAGE_BL31 diff --git a/include/lib/pmf/pmf_asm_macros.S b/include/lib/pmf/pmf_asm_macros.S index d58829eeccca19c7f0374948b11093006e9306e0..5e19e62f708c3fb242b3b93bddcc540aec89a500 100644 --- a/include/lib/pmf/pmf_asm_macros.S +++ b/include/lib/pmf/pmf_asm_macros.S @@ -18,10 +18,12 @@ mov x9, x30 bl plat_my_core_pos mov x30, x9 - ldr x1, =__PERCPU_TIMESTAMP_SIZE__ + adr x2, __PMF_PERCPU_TIMESTAMP_END__ + adr x1, __PMF_TIMESTAMP_START__ + sub x1, x2, x1 mov x2, #(\_tid * PMF_TS_SIZE) madd x0, x0, x1, x2 - ldr x1, =pmf_ts_mem_\_name + adr x1, pmf_ts_mem_\_name add x0, x0, x1 .endm diff --git a/include/lib/utils.h b/include/lib/utils.h index d46d8461dfaedce858b9ac282d580e3032e74bcc..f324a990916b5e98bdb71cc4259347ab9802174b 100644 --- a/include/lib/utils.h +++ b/include/lib/utils.h @@ -67,6 +67,29 @@ void zero_normalmem(void *mem, u_register_t length); * zeroing. */ void zeromem(void *mem, u_register_t length); + +/* + * Utility function to return the address of a symbol. By default, the + * compiler generates adr/adrp instruction pair to return the reference + * to the symbol and this utility is used to override this compiler + * generated to code to use `ldr` instruction. + * + * This helps when Position Independent Executable needs to reference a symbol + * which is constant and does not depend on the execute address of the binary. + */ +#define DEFINE_LOAD_SYM_ADDR(_name) \ +static inline u_register_t load_addr_## _name(void) \ +{ \ + u_register_t v; \ + /* Create a void reference to silence compiler */ \ + (void) _name; \ + __asm__ volatile ("ldr %0, =" #_name : "=r" (v)); \ + return v; \ +} + +/* Helper to invoke the function defined by DEFINE_LOAD_SYM_ADDR() */ +#define LOAD_ADDR_OF(_name) (typeof(_name) *) load_addr_## _name() + #endif /* !(defined(__LINKER__) || defined(__ASSEMBLY__)) */ #endif /* __UTILS_H__ */ diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S index 1a075aa5ad1953fa7fc0482e34718fc3cf6d858f..002942e8da6340de7a0570b941fe833582d96f7a 100644 --- a/lib/aarch64/misc_helpers.S +++ b/lib/aarch64/misc_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,7 @@ #include <arch.h> #include <asm_macros.S> #include <assert_macros.S> +#include <xlat_tables_defs.h> .globl get_afflvl_shift .globl mpidr_mask_lower_afflvls @@ -23,6 +24,8 @@ .globl disable_mmu_icache_el1 .globl disable_mmu_icache_el3 + .globl fixup_gdt_reloc + #if SUPPORT_VFP .globl enable_vfp #endif @@ -497,3 +500,114 @@ func enable_vfp ret endfunc enable_vfp #endif + +/* --------------------------------------------------------------------------- + * Helper to fixup Global Descriptor table (GDT) and dynamic relocations + * (.rela.dyn) at runtime. + * + * This function is meant to be used when the firmware is compiled with -fpie + * and linked with -pie options. We rely on the linker script exporting + * appropriate markers for start and end of the section. For GOT, we + * expect __GOT_START__ and __GOT_END__. Similarly for .rela.dyn, we expect + * __RELA_START__ and __RELA_END__. + * + * The function takes the limits of the memory to apply fixups to as + * arguments (which is usually the limits of the relocable BL image). + * x0 - the start of the fixup region + * x1 - the limit of the fixup region + * These addresses have to be page (4KB aligned). + * --------------------------------------------------------------------------- + */ +func fixup_gdt_reloc + mov x6, x0 + mov x7, x1 + + /* Test if the limits are 4K aligned */ +#if ENABLE_ASSERTIONS + orr x0, x0, x1 + tst x0, #(PAGE_SIZE - 1) + ASM_ASSERT(eq) +#endif + /* + * Calculate the offset based on return address in x30. + * Assume that this funtion is called within a page of the start of + * of fixup region. + */ + and x2, x30, #~(PAGE_SIZE - 1) + sub x0, x2, x6 /* Diff(S) = Current Address - Compiled Address */ + + adrp x1, __GOT_START__ + add x1, x1, :lo12:__GOT_START__ + adrp x2, __GOT_END__ + add x2, x2, :lo12:__GOT_END__ + + /* + * GOT is an array of 64_bit addresses which must be fixed up as + * new_addr = old_addr + Diff(S). + * The new_addr is the address currently the binary is executing from + * and old_addr is the address at compile time. + */ +1: + ldr x3, [x1] + /* Skip adding offset if address is < lower limit */ + cmp x3, x6 + b.lo 2f + /* Skip adding offset if address is >= upper limit */ + cmp x3, x7 + b.ge 2f + add x3, x3, x0 + str x3, [x1] +2: + add x1, x1, #8 + cmp x1, x2 + b.lo 1b + + /* Starting dynamic relocations. Use adrp/adr to get RELA_START and END */ + adrp x1, __RELA_START__ + add x1, x1, :lo12:__RELA_START__ + adrp x2, __RELA_END__ + add x2, x2, :lo12:__RELA_END__ + /* + * According to ELF-64 specification, the RELA data structure is as + * follows: + * typedef struct + * { + * Elf64_Addr r_offset; + * Elf64_Xword r_info; + * Elf64_Sxword r_addend; + * } Elf64_Rela; + * + * r_offset is address of reference + * r_info is symbol index and type of relocation (in this case + * 0x403 which corresponds to R_AARCH64_RELATIV). + * r_addend is constant part of expression. + * + * Size of Elf64_Rela structure is 24 bytes. + */ +1: + /* Assert that the relocation type is R_AARCH64_RELATIV */ +#if ENABLE_ASSERTIONS + ldr x3, [x1, #8] + cmp x3, #0x403 + ASM_ASSERT(eq) +#endif + ldr x3, [x1] /* r_offset */ + add x3, x0, x3 + ldr x4, [x1, #16] /* r_addend */ + + /* Skip adding offset if r_addend is < lower limit */ + cmp x4, x6 + b.lo 2f + /* Skip adding offset if r_addend entry is >= upper limit */ + cmp x4, x7 + b.ge 2f + + add x4, x0, x4 /* Diff(S) + r_addend */ + str x4, [x3] + +2: add x1, x1, #24 + cmp x1, x2 + b.lo 1b + + ret +endfunc fixup_gdt_reloc diff --git a/lib/cpus/aarch32/aem_generic.S b/lib/cpus/aarch32/aem_generic.S index 5f3d744701cb594b4f5933669df78f6642b5ba44..7bd586ad9abac0f245fc6d85c192e16f144a8fc3 100644 --- a/lib/cpus/aarch32/aem_generic.S +++ b/lib/cpus/aarch32/aem_generic.S @@ -40,6 +40,15 @@ func aem_generic_cluster_pwr_dwn b dcsw_op_all endfunc aem_generic_cluster_pwr_dwn +#if REPORT_ERRATA +/* + * Errata printing function for AEM. Must follow AAPCS. + */ +func aem_generic_errata_report + bx lr +endfunc aem_generic_errata_report +#endif + /* cpu_ops for Base AEM FVP */ declare_cpu_ops aem_generic, BASE_AEM_MIDR, CPU_NO_RESET_FUNC, \ aem_generic_core_pwr_dwn, \ diff --git a/lib/cpus/aarch32/cortex_a12.S b/lib/cpus/aarch32/cortex_a12.S index 73c9750722963685d987254dd2056cbc5b13b73c..5300fe00907763823e3c5c3f7133b72d7d19381d 100644 --- a/lib/cpus/aarch32/cortex_a12.S +++ b/lib/cpus/aarch32/cortex_a12.S @@ -69,6 +69,15 @@ func cortex_a12_cluster_pwr_dwn b cortex_a12_disable_smp endfunc cortex_a12_cluster_pwr_dwn +#if REPORT_ERRATA +/* + * Errata printing function for Cortex-A12. Must follow AAPCS. + */ +func cortex_a12_errata_report + bx lr +endfunc cortex_a12_errata_report +#endif + declare_cpu_ops cortex_a12, CORTEX_A12_MIDR, \ cortex_a12_reset_func, \ cortex_a12_core_pwr_dwn, \ diff --git a/lib/cpus/aarch32/cortex_a32.S b/lib/cpus/aarch32/cortex_a32.S index 2b6df272d289ff31970aa62ec1ca7ed87f0c74ce..c262276224607ba9a6dd442b45fc82960a601842 100644 --- a/lib/cpus/aarch32/cortex_a32.S +++ b/lib/cpus/aarch32/cortex_a32.S @@ -117,6 +117,15 @@ func cortex_a32_cluster_pwr_dwn b cortex_a32_disable_smp endfunc cortex_a32_cluster_pwr_dwn +#if REPORT_ERRATA +/* + * Errata printing function for Cortex-A32. Must follow AAPCS. + */ +func cortex_a32_errata_report + bx lr +endfunc cortex_a32_errata_report +#endif + declare_cpu_ops cortex_a32, CORTEX_A32_MIDR, \ cortex_a32_reset_func, \ cortex_a32_core_pwr_dwn, \ diff --git a/lib/cpus/aarch32/cortex_a5.S b/lib/cpus/aarch32/cortex_a5.S index c07c13ea1dcb0962fc228385b48603852d56d9ce..8abb66f0e527d917750e92c5835594448c0ae265 100644 --- a/lib/cpus/aarch32/cortex_a5.S +++ b/lib/cpus/aarch32/cortex_a5.S @@ -69,6 +69,15 @@ func cortex_a5_cluster_pwr_dwn b cortex_a5_disable_smp endfunc cortex_a5_cluster_pwr_dwn +#if REPORT_ERRATA +/* + * Errata printing function for Cortex-A5. Must follow AAPCS. + */ +func cortex_a5_errata_report + bx lr +endfunc cortex_a5_errata_report +#endif + declare_cpu_ops cortex_a5, CORTEX_A5_MIDR, \ cortex_a5_reset_func, \ cortex_a5_core_pwr_dwn, \ diff --git a/lib/cpus/aarch32/cortex_a7.S b/lib/cpus/aarch32/cortex_a7.S index 0278d1fdaab99dd89b912073aafea138aa4185c9..4d4bb77bb8a30fd4bf9b70ffb77b9e505d658f47 100644 --- a/lib/cpus/aarch32/cortex_a7.S +++ b/lib/cpus/aarch32/cortex_a7.S @@ -69,6 +69,15 @@ func cortex_a7_cluster_pwr_dwn b cortex_a7_disable_smp endfunc cortex_a7_cluster_pwr_dwn +#if REPORT_ERRATA +/* + * Errata printing function for Cortex-A7. Must follow AAPCS. + */ +func cortex_a7_errata_report + bx lr +endfunc cortex_a7_errata_report +#endif + declare_cpu_ops cortex_a7, CORTEX_A7_MIDR, \ cortex_a7_reset_func, \ cortex_a7_core_pwr_dwn, \ diff --git a/lib/cpus/aarch64/aem_generic.S b/lib/cpus/aarch64/aem_generic.S index 7592e3dc99d1027a969b7eafc8653620accbf222..51b5ce91cb744b49701cad9b5442cb75c4f20104 100644 --- a/lib/cpus/aarch64/aem_generic.S +++ b/lib/cpus/aarch64/aem_generic.S @@ -46,6 +46,15 @@ func aem_generic_cluster_pwr_dwn b dcsw_op_all endfunc aem_generic_cluster_pwr_dwn +#if REPORT_ERRATA +/* + * Errata printing function for AEM. Must follow AAPCS. + */ +func aem_generic_errata_report + ret +endfunc aem_generic_errata_report +#endif + /* --------------------------------------------- * This function provides cpu specific * register information for crash reporting. diff --git a/lib/cpus/aarch64/cortex_a35.S b/lib/cpus/aarch64/cortex_a35.S index b22189c8042a145029a12d22412d9e731c9ca26d..2e0d63161ad81102fa093de09fc615992ae29ae6 100644 --- a/lib/cpus/aarch64/cortex_a35.S +++ b/lib/cpus/aarch64/cortex_a35.S @@ -114,6 +114,16 @@ func cortex_a35_cluster_pwr_dwn b cortex_a35_disable_smp endfunc cortex_a35_cluster_pwr_dwn +#if REPORT_ERRATA +/* + * Errata printing function for Cortex A35. Must follow AAPCS. + */ +func cortex_a35_errata_report + ret +endfunc cortex_a35_errata_report +#endif + + /* --------------------------------------------- * This function provides cortex_a35 specific * register information for crash reporting. diff --git a/lib/cpus/aarch64/cortex_deimos.S b/lib/cpus/aarch64/cortex_deimos.S index aec62a28708c3ca04cd69b200a2786ab405b5de4..cad906f65cbf882794a7f4016572270aeb97bec9 100644 --- a/lib/cpus/aarch64/cortex_deimos.S +++ b/lib/cpus/aarch64/cortex_deimos.S @@ -27,6 +27,16 @@ func cortex_deimos_core_pwr_dwn ret endfunc cortex_deimos_core_pwr_dwn +#if REPORT_ERRATA +/* + * Errata printing function for Cortex Deimos. Must follow AAPCS. + */ +func cortex_deimos_errata_report + ret +endfunc cortex_deimos_errata_report +#endif + + /* --------------------------------------------- * This function provides Cortex-Deimos specific * register information for crash reporting. diff --git a/lib/cpus/aarch64/cortex_helios.S b/lib/cpus/aarch64/cortex_helios.S index bcda74114ebb6f50d2e2283d070ed86da89bb746..4812ac47ca73b8867d8c9ef66753d919fd063167 100644 --- a/lib/cpus/aarch64/cortex_helios.S +++ b/lib/cpus/aarch64/cortex_helios.S @@ -19,6 +19,16 @@ func cortex_helios_cpu_pwr_dwn ret endfunc cortex_helios_cpu_pwr_dwn +#if REPORT_ERRATA +/* + * Errata printing function for Cortex Helios. Must follow AAPCS. + */ +func cortex_helios_errata_report + ret +endfunc cortex_helios_errata_report +#endif + + .section .rodata.cortex_helios_regs, "aS" cortex_helios_regs: /* The ascii list of register names to be reported */ .asciz "cpuectlr_el1", "" diff --git a/lib/pmf/pmf_main.c b/lib/pmf/pmf_main.c index a020860088301396883ca21e98e435ed7a22e319..25513c1915ff75114762c5462232c8af4f6ced71 100644 --- a/lib/pmf/pmf_main.c +++ b/lib/pmf/pmf_main.c @@ -25,9 +25,10 @@ IMPORT_SYM(uintptr_t, __PMF_SVC_DESCS_START__, PMF_SVC_DESCS_START); IMPORT_SYM(uintptr_t, __PMF_SVC_DESCS_END__, PMF_SVC_DESCS_END); -IMPORT_SYM(uintptr_t, __PERCPU_TIMESTAMP_SIZE__, PMF_PERCPU_TIMESTAMP_SIZE); +IMPORT_SYM(uintptr_t, __PMF_PERCPU_TIMESTAMP_END__, PMF_PERCPU_TIMESTAMP_END); IMPORT_SYM(intptr_t, __PMF_TIMESTAMP_START__, PMF_TIMESTAMP_ARRAY_START); -IMPORT_SYM(uintptr_t, __PMF_TIMESTAMP_END__, PMF_TIMESTAMP_ARRAY_END); + +#define PMF_PERCPU_TIMESTAMP_SIZE (PMF_PERCPU_TIMESTAMP_END - PMF_TIMESTAMP_ARRAY_START) #define PMF_SVC_DESCS_MAX 10 diff --git a/lib/romlib/init.s b/lib/romlib/init.s index 5cf2aca045b86f789ffda9d3f446dc8bcefb3800..7d97e4d1de5820ef8c31c54ab84109a252fa8883 100644 --- a/lib/romlib/init.s +++ b/lib/romlib/init.s @@ -5,7 +5,7 @@ */ .globl rom_lib_init - .extern __DATA_RAM_START__, __DATA_ROM_START__, __DATA_SIZE__ + .extern __DATA_RAM_START__, __DATA_ROM_START__, __DATA_RAM_END__ .extern memset, memcpy rom_lib_init: @@ -16,13 +16,19 @@ rom_lib_init: 1: stp x29, x30, [sp, #-16]! adrp x0, __DATA_RAM_START__ - ldr x1,= __DATA_ROM_START__ - ldr x2, =__DATA_SIZE__ + adrp x1, __DATA_ROM_START__ + add x1, x1, :lo12:__DATA_ROM_START__ + adrp x2, __DATA_RAM_END__ + add x2, x2, :lo12:__DATA_RAM_END__ + sub x2, x2, x0 bl memcpy - ldr x0, =__BSS_START__ + adrp x0,__BSS_START__ + add x0, x0, :lo12:__BSS_START__ mov x1, #0 - ldr x2, =__BSS_SIZE__ + adrp x2, __BSS_END__ + add x2, x2, :lo12:__BSS_END__ + sub x2, x2, x0 bl memset ldp x29, x30, [sp], #16 diff --git a/lib/xlat_tables_v2/aarch64/enable_mmu.S b/lib/xlat_tables_v2/aarch64/enable_mmu.S index 21717d28a847ab04367554ee12cbd3824a4fc0c4..504c03c152674179afee3e2bb5c7b330a59e1b29 100644 --- a/lib/xlat_tables_v2/aarch64/enable_mmu.S +++ b/lib/xlat_tables_v2/aarch64/enable_mmu.S @@ -45,7 +45,8 @@ tlbi_invalidate_all \el mov x7, x0 - ldr x0, =mmu_cfg_params + adrp x0, mmu_cfg_params + add x0, x0, :lo12:mmu_cfg_params /* MAIR */ ldr x1, [x0, #(MMU_CFG_MAIR << 3)] diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 435de20e3edc36ea6b0b6e7e1187c6e0d0831c6f..4a3f54116ad51a1d3c0005969ab8e5f1f41b8f5f 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -64,6 +64,9 @@ DYN_DISABLE_AUTH := 0 # Build option to enable MPAM for lower ELs ENABLE_MPAM_FOR_LOWER_ELS := 0 +# Flag to Enable Position Independant support (PIE) +ENABLE_PIE := 0 + # Flag to enable Performance Measurement Framework ENABLE_PMF := 0 diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S index 88fcdb1b0981e05c60d103921e4a9476db617eb2..abc3ceb00fa35564a8b04989bb0d230290aa787e 100644 --- a/plat/arm/board/fvp/aarch64/fvp_helpers.S +++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S @@ -19,7 +19,7 @@ .globl plat_arm_calc_core_pos .macro fvp_choose_gicmmap param1, param2, x_tmp, w_tmp, res - ldr \x_tmp, =V2M_SYSREGS_BASE + V2M_SYS_ID + mov_imm \x_tmp, V2M_SYSREGS_BASE + V2M_SYS_ID ldr \w_tmp, [\x_tmp] ubfx \w_tmp, \w_tmp, #V2M_SYS_ID_BLD_SHIFT, #V2M_SYS_ID_BLD_LENGTH cmp \w_tmp, #BLD_GIC_VE_MMAP @@ -48,7 +48,7 @@ func plat_secondary_cold_boot_setup * --------------------------------------------- */ mrs x0, mpidr_el1 - ldr x1, =PWRC_BASE + mov_imm x1, PWRC_BASE str w0, [x1, #PPOFFR_OFF] /* --------------------------------------------- @@ -72,8 +72,8 @@ func plat_secondary_cold_boot_setup b secondary_cold_boot_wait gicv2_bypass_disable: - ldr x0, =VE_GICC_BASE - ldr x1, =BASE_GICC_BASE + mov_imm x0, VE_GICC_BASE + mov_imm x1, BASE_GICC_BASE fvp_choose_gicmmap x0, x1, x2, w2, x1 mov w0, #(IRQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP1) orr w0, w0, #(IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP0) @@ -128,7 +128,7 @@ func plat_get_my_entrypoint * --------------------------------------------------------------------- */ mrs x2, mpidr_el1 - ldr x1, =PWRC_BASE + mov_imm x1, PWRC_BASE str w2, [x1, #PSYSR_OFF] ldr w2, [x1, #PSYSR_OFF] ubfx w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_WIDTH @@ -171,7 +171,7 @@ endfunc plat_get_my_entrypoint */ func plat_is_my_cpu_primary mrs x0, mpidr_el1 - ldr x1, =MPIDR_AFFINITY_MASK + mov_imm x1, MPIDR_AFFINITY_MASK and x0, x0, x1 cmp x0, #FVP_PRIMARY_CPU cset w0, eq diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 332df4d4464d30382426d7d4ef9d3b1498583bc3..3d858c20e78815aa6fa5e681134c700ed5d56038 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -202,7 +202,9 @@ ENABLE_AMU := 1 DYNAMIC_WORKAROUND_CVE_2018_3639 := 1 # Enable reclaiming of BL31 initialisation code for secondary cores stacks for FVP +ifneq (${RESET_TO_BL31},1) RECLAIM_INIT_CODE := 1 +endif ifeq (${ENABLE_AMU},1) BL31_SOURCES += lib/cpus/aarch64/cortex_a75_pubsub.c \ diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 24d55709545fd43dc2f1a6d8602e2ca83efea3b7..1b05f46e90adf372ce0d63ba2131b3b3408f3c1e 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -25,11 +25,13 @@ static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; +#if !RESET_TO_BL31 /* * Check that BL31_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. */ CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows); +#endif /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak bl31_early_platform_setup2 @@ -38,8 +40,8 @@ CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows); #pragma weak bl31_plat_get_next_image_ep_info #define MAP_BL31_TOTAL MAP_REGION_FLAT( \ - BL31_BASE, \ - BL31_END - BL31_BASE, \ + BL31_START, \ + BL31_END - BL31_START, \ MT_MEMORY | MT_RW | MT_SECURE) #if RECLAIM_INIT_CODE IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE); diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 3fb1eff2d8a4b2fca94b5b666b3f7f9fff9163cd..23777fb7b7d371d767386e8a353be57ec7e32da6 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -130,6 +130,11 @@ ARM_CRYPTOCELL_INTEG := 0 $(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG)) $(eval $(call add_define,ARM_CRYPTOCELL_INTEG)) +# Enable PIE support for RESET_TO_BL31 case +ifeq (${RESET_TO_BL31},1) + ENABLE_PIE := 1 +endif + # CryptoCell integration relies on coherent buffers for passing data from # the AP CPU to the CryptoCell ifeq (${ARM_CRYPTOCELL_INTEG},1) diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c index e9e8a74d924f14fd6a43fc869b81d871ce15a7a5..a43bff3d4837c2449e11dbd320305f39b6749793 100644 --- a/plat/arm/common/arm_gicv3.c +++ b/plat/arm/common/arm_gicv3.c @@ -10,6 +10,7 @@ #include <plat_arm.h> #include <platform.h> #include <platform_def.h> +#include <utils.h> /****************************************************************************** * The following functions are defined as weak to allow a platform to override @@ -33,10 +34,16 @@ static const interrupt_prop_t arm_interrupt_props[] = { /* * We save and restore the GICv3 context on system suspend. Allocate the - * data in the designated EL3 Secure carve-out memory + * data in the designated EL3 Secure carve-out memory. The `volatile` + * is used to prevent the compiler from removing the gicv3 contexts even + * though the DEFINE_LOAD_SYM_ADDR creates a dummy reference to it. */ -static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); -static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); +static volatile gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); +static volatile gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); + +/* Define accessor function to get reference to the GICv3 context */ +DEFINE_LOAD_SYM_ADDR(rdist_ctx) +DEFINE_LOAD_SYM_ADDR(dist_ctx) /* * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register @@ -134,6 +141,10 @@ void plat_arm_gic_redistif_off(void) *****************************************************************************/ void plat_arm_gic_save(void) { + gicv3_redist_ctx_t * const rdist_context = + (gicv3_redist_ctx_t *)LOAD_ADDR_OF(rdist_ctx); + gicv3_dist_ctx_t * const dist_context = + (gicv3_dist_ctx_t *)LOAD_ADDR_OF(dist_ctx); /* * If an ITS is available, save its context before @@ -149,10 +160,10 @@ void plat_arm_gic_save(void) * we only need to save the context of the CPU that is issuing * the SYSTEM SUSPEND call, i.e. the current CPU. */ - gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); + gicv3_rdistif_save(plat_my_core_pos(), rdist_context); /* Save the GIC Distributor context */ - gicv3_distif_save(&dist_ctx); + gicv3_distif_save(dist_context); /* * From here, all the components of the GIC can be safely powered down @@ -163,8 +174,13 @@ void plat_arm_gic_save(void) void plat_arm_gic_resume(void) { + const gicv3_redist_ctx_t *rdist_context = + (gicv3_redist_ctx_t *)LOAD_ADDR_OF(rdist_ctx); + const gicv3_dist_ctx_t *dist_context = + (gicv3_dist_ctx_t *)LOAD_ADDR_OF(dist_ctx); + /* Restore the GIC Distributor context */ - gicv3_distif_init_restore(&dist_ctx); + gicv3_distif_init_restore(dist_context); /* * Restore the GIC Redistributor and ITS contexts after the @@ -172,7 +188,7 @@ void plat_arm_gic_resume(void) * we only need to restore the context of the CPU that issued * the SYSTEM SUSPEND call. */ - gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); + gicv3_rdistif_init_restore(plat_my_core_pos(), rdist_context); /* * If an ITS is available, restore its context after diff --git a/plat/arm/css/common/aarch64/css_helpers.S b/plat/arm/css/common/aarch64/css_helpers.S index 59d920650c02102ee701a5c492bb72dd801bde1f..5096d8d957118233c221e87ccdfc0bc3d075afa7 100644 --- a/plat/arm/css/common/aarch64/css_helpers.S +++ b/plat/arm/css/common/aarch64/css_helpers.S @@ -108,7 +108,7 @@ endfunc plat_is_my_cpu_primary func plat_is_my_cpu_primary mov x9, x30 bl plat_my_core_pos - ldr x1, =SCP_BOOT_CFG_ADDR + mov_imm x1, SCP_BOOT_CFG_ADDR ldr x1, [x1] ubfx x1, x1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \ #PLAT_CSS_PRIMARY_CPU_BIT_WIDTH