diff --git a/Makefile b/Makefile index 23a1b0a372ae25f057b56abf83ce86390da1f57f..d487eae7f2427ef8074fab4e36efaa2b5be3a46a 100644 --- a/Makefile +++ b/Makefile @@ -634,6 +634,7 @@ $(eval $(call add_define,PSCI_EXTENDED_STATE_ID)) $(eval $(call add_define,RAS_EXTENSION)) $(eval $(call add_define,RESET_TO_BL31)) $(eval $(call add_define,SEPARATE_CODE_AND_RODATA)) +$(eval $(call add_define,RECLAIM_INIT_CODE)) $(eval $(call add_define,SMCCC_MAJOR_VERSION)) $(eval $(call add_define,SPD_${SPD})) $(eval $(call add_define,SPIN_ON_BL1_EXIT)) diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index 4b7f63c21099a33d8a9351b448bb977d52cbe4da..62bea010bd53dd990bc65ff5a153a30980a833d3 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -57,7 +57,7 @@ uintptr_t get_arm_std_svc_args(unsigned int svc_mask) /******************************************************************************* * Simple function to initialise all BL31 helper libraries. ******************************************************************************/ -void bl31_lib_init(void) +void __init bl31_lib_init(void) { cm_init(); } @@ -149,7 +149,7 @@ uint32_t bl31_get_next_image_type(void) * This function programs EL3 registers and performs other setup to enable entry * into the next image after BL31 at the next ERET. ******************************************************************************/ -void bl31_prepare_next_image_entry(void) +void __init bl31_prepare_next_image_entry(void) { entry_point_info_t *next_image_info; uint32_t image_type; diff --git a/bl31/ehf.c b/bl31/ehf.c index 3d6d674bf66a3f9a867cbb6a05b8117c4d9ab775..fa036cb1c99873242a2c1261b05b1901a0931c22 100644 --- a/bl31/ehf.c +++ b/bl31/ehf.c @@ -451,7 +451,7 @@ static uint64_t ehf_el3_interrupt_handler(uint32_t id, uint32_t flags, /* * Initialize the EL3 exception handling. */ -void ehf_init(void) +void __init ehf_init(void) { unsigned int flags = 0; int ret __unused; diff --git a/common/runtime_svc.c b/common/runtime_svc.c index ad564f566b7a31a87b3ba6816e13e018f043a04e..03f7f7ef32d78087ffe0b4ef29cdcc5c9032fd3a 100644 --- a/common/runtime_svc.c +++ b/common/runtime_svc.c @@ -93,7 +93,7 @@ static int32_t validate_rt_svc_desc(const rt_svc_desc_t *desc) * The unique oen is used as an index into the 'rt_svc_descs_indices' array. * The index of the runtime service descriptor is stored at this index. ******************************************************************************/ -void runtime_svc_init(void) +void __init runtime_svc_init(void) { int rc = 0; unsigned int index, start_idx, end_idx; diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst index 79bdec98f9cd81e13f79476eb1385c1b7178190e..7cc74855ded3e3db0054a806aa9cb2cc1e06f33d 100644 --- a/docs/firmware-design.rst +++ b/docs/firmware-design.rst @@ -2336,6 +2336,29 @@ implement: SUBSCRIBE_TO_EVENT(foo, foo_handler); + +Reclaiming the BL31 initialization code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A significant amount of the code used for the initialization of BL31 is never +needed again after boot time. In order to reduce the runtime memory +footprint, the memory used for this code can be reclaimed after initialization +has finished and be used for runtime data. + +The build option ``RECLAIM_INIT_CODE`` can be set to mark this boot time code +with a ``.text.init.*`` attribute which can be filtered and placed suitably +within the BL image for later reclaimation by the platform. The platform can +specify the fiter and the memory region for this init section in BL31 via the +plat.ld.S linker script. For example, on the FVP, this section is placed +overlapping the secondary CPU stacks so that after the cold boot is done, this +memory can be reclaimed for the stacks. The init memory section is initially +mapped with ``RO``, ``EXECUTE`` attributes. After BL31 initilization has +completed, the FVP changes the attributes of this section to ``RW``, +``EXECUTE_NEVER`` allowing it to be used for runtime data. The memory attributes +are changed within the ``bl31_plat_runtime_setup`` platform hook. The init +section section can be reclaimed for any data which is accessed after cold +boot initialization and it is upto the platform to make the decision. + Performance Measurement Framework --------------------------------- diff --git a/drivers/arm/cci/cci.c b/drivers/arm/cci/cci.c index 91245d46caa6f88b1a3cc3a2d98bc88cd4297dda..605971cac72199740c4eae8c8dfc9cb8540538b5 100644 --- a/drivers/arm/cci/cci.c +++ b/drivers/arm/cci/cci.c @@ -107,7 +107,8 @@ static int get_slave_ports(unsigned int part_num) } #endif /* ENABLE_ASSERTIONS */ -void cci_init(uintptr_t base, const int *map, unsigned int num_cci_masters) +void __init cci_init(uintptr_t base, const int *map, + unsigned int num_cci_masters) { assert(map != NULL); assert(base != 0U); diff --git a/drivers/arm/ccn/ccn.c b/drivers/arm/ccn/ccn.c index afb7d9d3b40757ca24f1394b71051c41b090fadd..910cd7cd27b2845bb2c6145bace59b8bbc33af93 100644 --- a/drivers/arm/ccn/ccn.c +++ b/drivers/arm/ccn/ccn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -167,7 +167,7 @@ static unsigned int ccn_get_rn_master_info(uintptr_t periphbase, * It compares this with the information provided by the platform to determine * the validity of the latter. ******************************************************************************/ -static void ccn_validate_plat_params(const ccn_desc_t *plat_desc) +static void __init ccn_validate_plat_params(const ccn_desc_t *plat_desc) { unsigned int master_id, num_rn_masters; rn_info_t info = { {0} }; @@ -208,7 +208,7 @@ static void ccn_validate_plat_params(const ccn_desc_t *plat_desc) * simultaneous CCN operations at runtime (only BL31) to add and remove Request * nodes from coherency. ******************************************************************************/ -void ccn_init(const ccn_desc_t *plat_desc) +void __init ccn_init(const ccn_desc_t *plat_desc) { #if ENABLE_ASSERTIONS ccn_validate_plat_params(plat_desc); diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index 5af7e40278e2cc52aa2bbcada92f39c7e89a02c4..60f2e108a0f73ab4417eec1c4ffea78236c25482 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -55,7 +55,7 @@ static spinlock_t gic_lock; * This function initialises the ARM GICv3 driver in EL3 with provided platform * inputs. ******************************************************************************/ -void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) +void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) { unsigned int gic_version; @@ -129,7 +129,7 @@ void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) * This function initialises the GIC distributor interface based upon the data * provided by the platform while initialising the driver. ******************************************************************************/ -void gicv3_distif_init(void) +void __init gicv3_distif_init(void) { unsigned int bitmap = 0; diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c index ddb99634e71ea10cdcd8f10aca318f92eb6eb2c7..78a9ffa6dfa9880b0d362c862f519c4657748750 100644 --- a/drivers/arm/smmu/smmu_v3.c +++ b/drivers/arm/smmu/smmu_v3.c @@ -4,21 +4,22 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <cdefs.h> #include <mmio.h> #include <smmu_v3.h> #include <stdbool.h> -static inline uint32_t smmuv3_read_s_idr1(uintptr_t base) +static inline uint32_t __init smmuv3_read_s_idr1(uintptr_t base) { return mmio_read_32(base + SMMU_S_IDR1); } -static inline uint32_t smmuv3_read_s_init(uintptr_t base) +static inline uint32_t __init smmuv3_read_s_init(uintptr_t base) { return mmio_read_32(base + SMMU_S_INIT); } -static inline void smmuv3_write_s_init(uintptr_t base, uint32_t value) +static inline void __init smmuv3_write_s_init(uintptr_t base, uint32_t value) { mmio_write_32(base + SMMU_S_INIT, value); } @@ -34,7 +35,7 @@ static inline bool smmuv3_inval_pending(uintptr_t base) * * Returns 0 on success, and -1 on failure. */ -int smmuv3_init(uintptr_t smmu_base) +int __init smmuv3_init(uintptr_t smmu_base) { uint32_t idr1_reg; diff --git a/include/lib/libc/cdefs.h b/include/lib/libc/cdefs.h index b1d10ccce5340aae687a520e36db28793ac1303b..0d0072254ae0b439520705ebd52e901c41245f69 100644 --- a/include/lib/libc/cdefs.h +++ b/include/lib/libc/cdefs.h @@ -14,6 +14,15 @@ #define __unused __attribute__((__unused__)) #define __aligned(x) __attribute__((__aligned__(x))) #define __section(x) __attribute__((__section__(x))) +#if RECLAIM_INIT_CODE +/* + * Add each function to a section that is unique so the functions can still + * be garbage collected + */ +#define __init __section(".text.init." __FILE__ "." __XSTRING(__LINE__)) +#else +#define __init +#endif #define __printflike(fmtarg, firstvararg) \ __attribute__((__format__ (__printf__, fmtarg, firstvararg))) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 23cd12f51d1e1782e175f4d59a42a9e8b3c50b0c..8d81af960d8fb08f5fa83d38533340911cc0e15f 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -280,7 +280,7 @@ * The max number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. */ -# define ARM_BL_REGIONS 4 +#define ARM_BL_REGIONS 5 #define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ ARM_BL_REGIONS) diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S new file mode 100644 index 0000000000000000000000000000000000000000..8f22170fe6261b98549f10a47fe818d77ceea3eb --- /dev/null +++ b/include/plat/arm/common/arm_reclaim_init.ld.S @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef ARM_RECLAIM_INIT_LD_S +#define ARM_RECLAIM_INIT_LD_S + +SECTIONS +{ + .init __STACKS_START__ : { + . = . + PLATFORM_STACK_SIZE; + . = ALIGN(PAGE_SIZE); + __INIT_CODE_START__ = .; + /* + * Exclude PSCI initialization functions to ensure the init section + * does not become larger than the overlaid stack region + */ + *(EXCLUDE_FILE (*psci_setup.o).text.init*) + __INIT_CODE_UNALIGNED__ = .; + . = ALIGN(PAGE_SIZE); + __INIT_CODE_END__ = .; + } >RAM + +#ifdef BL31_PROGBITS_LIMIT + ASSERT(__INIT_CODE_END__ <= BL31_PROGBITS_LIMIT, + "BL31 init has exceeded progbits limit.") +#endif + +#if RECLAIM_INIT_CODE + ASSERT(__INIT_CODE_END__ <= __STACKS_END__, + "Init code ends past the end of the stacks") +#endif +} + +#endif /* ARM_RECLAIM_INIT_LD_S */ diff --git a/include/plat/arm/common/arm_common.ld.S b/include/plat/arm/common/arm_tzc_dram.ld.S similarity index 87% rename from include/plat/arm/common/arm_common.ld.S rename to include/plat/arm/common/arm_tzc_dram.ld.S index 3f6e29b0ae27f2fda6cd27702495af387068ae0e..df951e117f47447f2ea94da8a68ec42e3404f29d 100644 --- a/include/plat/arm/common/arm_common.ld.S +++ b/include/plat/arm/common/arm_tzc_dram.ld.S @@ -3,8 +3,8 @@ * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef __ARM_COMMON_LD_S__ -#define __ARM_COMMON_LD_S__ +#ifndef ARM_TZC_DRAM_LD_S__ +#define ARM_TZC_DRAM_LD_S__ #include <xlat_tables_defs.h> @@ -27,4 +27,4 @@ SECTIONS } >EL3_SEC_DRAM } -#endif /* __ARM_COMMON_LD_S__ */ +#endif /* ARM_TZC_DRAM_LD_S__ */ diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 3f344abce0ab577ebcb92a72c1398f34176ead4a..d543894d7b1eeda815e5b099d3b99c8eb9469abd 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -220,6 +220,12 @@ void arm_bl2_dyn_cfg_init(void); void arm_bl1_set_mbedtls_heap(void); int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size); +/* + * Free the memory storing initialization code only used during an images boot + * time so it can be reclaimed for runtime data + */ +void arm_free_init_memory(void); + /* * Mandatory functions required in ARM standard platforms */ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index ee5fe4f9d05b71d68a800591476dab51619ecf6e..acc8d6d26c61b14954c7041095fa835389785a76 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -36,7 +36,7 @@ * which will used for programming an entry into a lower EL. The same context * will used to save state upon exception entry from that EL. ******************************************************************************/ -void cm_init(void) +void __init cm_init(void) { /* * The context management library has only global data to intialize, but diff --git a/lib/extensions/ras/ras_common.c b/lib/extensions/ras/ras_common.c index 2e65eebb9aa970b36c62a53eb6a4e9b58f25705b..f39e5f5f1b28b21cc7e2a93ebaf2a6539b549bc5 100644 --- a/lib/extensions/ras/ras_common.c +++ b/lib/extensions/ras/ras_common.c @@ -128,7 +128,7 @@ static int ras_interrupt_handler(uint32_t intr_raw, uint32_t flags, return 0; } -void ras_init(void) +void __init ras_init(void) { #if ENABLE_ASSERTIONS /* Check RAS interrupts are sorted */ diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c index b877b4ba2eb647045932f899bb305bde0494b797..adce843aa60daf648532cfcfc71f69e93d9eda2c 100644 --- a/lib/psci/psci_common.c +++ b/lib/psci/psci_common.c @@ -216,7 +216,7 @@ static void psci_set_req_local_pwr_state(unsigned int pwrlvl, /****************************************************************************** * This function initializes the psci_req_local_pwr_states. *****************************************************************************/ -void psci_init_req_local_pwr_states(void) +void __init psci_init_req_local_pwr_states(void) { /* Initialize the requested state of all non CPU power domains as OFF */ unsigned int pwrlvl; diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c index e59e163ead70a2e1e322e20cd8c56f0bd14e8e41..6b3081eb58c97ab8a39c4ed7811fa8e234496bba 100644 --- a/lib/psci/psci_setup.c +++ b/lib/psci/psci_setup.c @@ -32,7 +32,7 @@ unsigned int psci_caps; * Function which initializes the 'psci_non_cpu_pd_nodes' or the * 'psci_cpu_pd_nodes' corresponding to the power level. ******************************************************************************/ -static void psci_init_pwr_domain_node(unsigned char node_idx, +static void __init psci_init_pwr_domain_node(unsigned char node_idx, unsigned int parent_idx, unsigned char level) { @@ -80,7 +80,7 @@ static void psci_init_pwr_domain_node(unsigned char node_idx, * mapping of the CPUs to indices via plat_core_pos_by_mpidr() and * plat_my_core_pos() APIs. *******************************************************************************/ -static void psci_update_pwrlvl_limits(void) +static void __init psci_update_pwrlvl_limits(void) { int j, cpu_idx; unsigned int nodes_idx[PLAT_MAX_PWR_LVL] = {0}; @@ -107,7 +107,7 @@ static void psci_update_pwrlvl_limits(void) * informs the number of root power domains. The parent nodes of the root nodes * will point to an invalid entry(-1). ******************************************************************************/ -static void populate_power_domain_tree(const unsigned char *topology) +static void __init populate_power_domain_tree(const unsigned char *topology) { unsigned int i, j = 0U, num_nodes_at_lvl = 1U, num_nodes_at_next_lvl; unsigned int node_index = 0U, num_children; @@ -184,7 +184,7 @@ static void populate_power_domain_tree(const unsigned char *topology) * | CPU 0 | CPU 1 | CPU 2 | CPU 3 | * ------------------------------------------------ ******************************************************************************/ -int psci_setup(const psci_lib_args_t *lib_args) +int __init psci_setup(const psci_lib_args_t *lib_args) { const unsigned char *topology_tree; diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c index ca67f2a091f09cf89c3ae982ec56c5c3416b01f8..a9aaeee8d487302d39139b100c62e1916c9ec37a 100644 --- a/lib/xlat_tables/xlat_tables_common.c +++ b/lib/xlat_tables/xlat_tables_common.c @@ -176,7 +176,7 @@ void mmap_add(const mmap_region_t *mm) { const mmap_region_t *mm_cursor = mm; - while (mm_cursor->size != 0U) { + while (mm_cursor->attr != 0U) { mmap_add_region(mm_cursor->base_pa, mm_cursor->base_va, mm_cursor->size, mm_cursor->attr); mm_cursor++; diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c index 4a4cb946c249648bf240c2530ba95f9cfe82a652..f180774524e7b24456a7ebd2e734c7521b262ac4 100644 --- a/lib/xlat_tables_v2/xlat_tables_context.c +++ b/lib/xlat_tables_v2/xlat_tables_context.c @@ -56,7 +56,7 @@ int mmap_remove_dynamic_region(uintptr_t base_va, size_t size) #endif /* PLAT_XLAT_TABLES_DYNAMIC */ -void init_xlat_tables(void) +void __init init_xlat_tables(void) { assert(tf_xlat_ctx.xlat_regime == EL_REGIME_INVALID); diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c index 003718e760289763fa93d4d2e117668d9d4fb8dc..3b6c6bcb259450c54b25c948d26afa1f63fc8139 100644 --- a/lib/xlat_tables_v2/xlat_tables_core.c +++ b/lib/xlat_tables_v2/xlat_tables_core.c @@ -815,7 +815,7 @@ void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm) { const mmap_region_t *mm_cursor = mm; - while (mm_cursor->size != 0U) { + while (mm_cursor->attr != 0U) { mmap_add_region_ctx(ctx, mm_cursor); mm_cursor++; } @@ -1012,7 +1012,7 @@ int mmap_remove_dynamic_region_ctx(xlat_ctx_t *ctx, uintptr_t base_va, #endif /* PLAT_XLAT_TABLES_DYNAMIC */ -void init_xlat_tables_ctx(xlat_ctx_t *ctx) +void __init init_xlat_tables_ctx(xlat_ctx_t *ctx) { assert(ctx != NULL); assert(!ctx->initialized); diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index 92a0f6e86efbd49d7b47f2b5503535717730426e..520725bbb94ecd44cbea2f9bddf7ddbeb3bc9497 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -252,10 +252,11 @@ endef define MAKE_LD $(eval DEP := $(1).d) +$(eval IMAGE := IMAGE_BL$(call uppercase,$(3))) $(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs @echo " PP $$<" - $$(Q)$$(CPP) $$(CPPFLAGS) -P -D__ASSEMBLY__ -D__LINKER__ $(MAKE_DEP) -o $$@ $$< + $$(Q)$$(CPP) $$(CPPFLAGS) -P -D__ASSEMBLY__ -D__LINKER__ $(MAKE_DEP) -D$(IMAGE) -o $$@ $$< -include $(DEP) diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 7df4cd286d145f1eec12691ff5986e362501aec4..435de20e3edc36ea6b0b6e7e1187c6e0d0831c6f 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -146,6 +146,10 @@ SDEI_SUPPORT := 0 # platform Makefile is free to override this value. SEPARATE_CODE_AND_RODATA := 0 +# If the BL31 image initialisation code is recalimed after use for the secondary +# cores stack +RECLAIM_INIT_CODE := 0 + # Default to SMCCC Version 1.X SMCCC_MAJOR_VERSION := 1 diff --git a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c b/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c index 5948e149fcd39b29980a2c6394676500b22cd483..b17446c10c92405c889890748b15031734b60a99 100644 --- a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c +++ b/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c @@ -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 */ @@ -70,7 +70,7 @@ void fvp_pwrc_write_pcoffr(u_register_t mpidr) } /* Nothing else to do here apart from initializing the lock */ -void plat_arm_pwrc_setup(void) +void __init plat_arm_pwrc_setup(void) { arm_lock_init(); } diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index ea1170859efdf41b08c5c8e76bf5f01a9a8b8a17..1c8804f10a47d92368db49ad5e256410c46d8c09 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -10,8 +10,8 @@ #include <smmu_v3.h> #include "fvp_private.h" -void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, - u_register_t arg2, u_register_t arg3) +void __init bl31_early_platform_setup2(u_register_t arg0, + u_register_t arg1, u_register_t arg2, u_register_t arg3) { arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 3f7857eb8f211e4b13ddf8e04c4a2b454ee41e82..aa4f8398de776581d3a2e42e19704a2e3164e785 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -241,7 +241,7 @@ const struct secure_partition_boot_info *plat_get_secure_partition_boot_info( * these platforms. This information is stored in a per-BL array to allow the * code to take the correct path.Per BL platform configuration. ******************************************************************************/ -void fvp_config_setup(void) +void __init fvp_config_setup(void) { unsigned int rev, hbi, bld, arch, sys_id; @@ -331,7 +331,7 @@ void fvp_config_setup(void) } -void fvp_interconnect_init(void) +void __init fvp_interconnect_init(void) { #if FVP_INTERCONNECT_DRIVER == FVP_CCN if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) { diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S index 24c3debd927c4571b70c73f540e138a450797fcb..f2a3ea6a43a1a9a9e6deb83860b63f7a8a21a437 100644 --- a/plat/arm/board/fvp/include/plat.ld.S +++ b/plat/arm/board/fvp/include/plat.ld.S @@ -6,6 +6,7 @@ #ifndef __PLAT_LD_S__ #define __PLAT_LD_S__ -#include <arm_common.ld.S> +#include <arm_tzc_dram.ld.S> +#include <arm_reclaim_init.ld.S> #endif /* __PLAT_LD_S__ */ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 4cd6a24de676ca8a1746bbc3de9d6a787c087813..9bd3bde6579262e1205d3cbee93dcfaf8ac1caf6 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -201,6 +201,9 @@ ENABLE_AMU := 1 # Enable dynamic mitigation support by default DYNAMIC_WORKAROUND_CVE_2018_3639 := 1 +# Enable reclaiming of BL31 initialisation code for secondary cores stacks for FVP +RECLAIM_INIT_CODE := 1 + ifeq (${ENABLE_AMU},1) BL31_SOURCES += lib/cpus/aarch64/cortex_a75_pubsub.c \ lib/cpus/aarch64/cortex_ares_pubsub.c \ diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 364e46a9c2285a120c0e11568b137fac29c0895a..ed2c3fbceed47415de35f37150f33622a42c66c1 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -15,6 +15,8 @@ #include <plat_arm.h> #include <platform.h> #include <ras.h> +#include <utils.h> +#include <arm_xlat_tables.h> /* * Placeholder variables for copying the arguments that have been passed to @@ -35,10 +37,20 @@ CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows); #pragma weak bl31_plat_arch_setup #pragma weak bl31_plat_get_next_image_ep_info -#define MAP_BL31_TOTAL MAP_REGION_FLAT( \ +#define MAP_BL31_TOTAL MAP_REGION_FLAT( \ BL31_BASE, \ BL31_END - BL31_BASE, \ MT_MEMORY | MT_RW | MT_SECURE) +#if RECLAIM_INIT_CODE +IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE); +IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END); + +#define MAP_BL_INIT_CODE MAP_REGION_FLAT( \ + BL_INIT_CODE_BASE, \ + BL_INIT_CODE_END \ + - BL_INIT_CODE_BASE, \ + MT_CODE | MT_SECURE) +#endif /******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for the @@ -71,7 +83,7 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type) * while creating page tables. BL2 has flushed this information to memory, so * we are guaranteed to pick up good data. ******************************************************************************/ -void arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config, +void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config, uintptr_t hw_config, void *plat_params_from_bl2) { /* Initialize the console to provide early debug support */ @@ -233,9 +245,30 @@ void arm_bl31_plat_runtime_setup(void) /* Initialize the runtime console */ arm_console_runtime_init(); +#if RECLAIM_INIT_CODE + arm_free_init_memory(); +#endif } -void bl31_platform_setup(void) +#if RECLAIM_INIT_CODE +/* + * Zero out and make RW memory used to store image boot time code so it can + * be reclaimed during runtime + */ +void arm_free_init_memory(void) +{ + int ret = xlat_change_mem_attributes(BL_INIT_CODE_BASE, + BL_INIT_CODE_END - BL_INIT_CODE_BASE, + MT_RW_DATA); + + if (ret != 0) { + ERROR("Could not reclaim initialization code"); + panic(); + } +} +#endif + +void __init bl31_platform_setup(void) { arm_bl31_platform_setup(); } @@ -251,16 +284,13 @@ void bl31_plat_runtime_setup(void) * architectural setup (bl31_arch_setup()) does not do anything platform * specific. ******************************************************************************/ -void arm_bl31_plat_arch_setup(void) +void __init arm_bl31_plat_arch_setup(void) { - -#define ARM_MAP_BL_ROMLIB MAP_REGION_FLAT( \ - BL31_BASE, \ - BL31_END - BL31_BASE, \ - MT_MEMORY | MT_RW | MT_SECURE) - const mmap_region_t bl_regions[] = { MAP_BL31_TOTAL, +#if RECLAIM_INIT_CODE + MAP_BL_INIT_CODE, +#endif ARM_MAP_BL_RO, #if USE_ROMLIB ARM_MAP_ROMLIB_CODE, @@ -279,7 +309,7 @@ void arm_bl31_plat_arch_setup(void) arm_setup_romlib(); } -void bl31_plat_arch_setup(void) +void __init bl31_plat_arch_setup(void) { arm_bl31_plat_arch_setup(); } diff --git a/plat/arm/common/arm_cci.c b/plat/arm/common/arm_cci.c index fc24cc3531fe800fc538b6aba19e6c8b966b1cd0..6505b9174f45010cc9fd62d41f1599e5d8a8c7a8 100644 --- a/plat/arm/common/arm_cci.c +++ b/plat/arm/common/arm_cci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,7 +27,7 @@ static const int cci_map[] = { /****************************************************************************** * Helper function to initialize ARM CCI driver. *****************************************************************************/ -void plat_arm_interconnect_init(void) +void __init plat_arm_interconnect_init(void) { cci_init(PLAT_ARM_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); } diff --git a/plat/arm/common/arm_ccn.c b/plat/arm/common/arm_ccn.c index 84a529f42a86c98b744ecb34540b485486426cbc..ddf3286d79cc989a1d56fe2e0afa24a5dacb1206 100644 --- a/plat/arm/common/arm_ccn.c +++ b/plat/arm/common/arm_ccn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -34,7 +34,7 @@ CASSERT(PLAT_ARM_CLUSTER_COUNT == ARRAY_SIZE(master_to_rn_id_map), /****************************************************************************** * Helper function to initialize ARM CCN driver. *****************************************************************************/ -void plat_arm_interconnect_init(void) +void __init plat_arm_interconnect_init(void) { ccn_init(&arm_ccn_desc); } diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index 28ff5d9b91dae86a4adca504a66fa049ece1e5c2..a21d189e9b7606df65f68a2f62a7cfa0698ed0f6 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -38,10 +38,11 @@ void arm_setup_romlib(void) * as an array specifying the generic memory regions which can be; * - Code section; * - Read-only data section; + * - Init code section, if applicable * - Coherent memory region, if applicable. */ -void arm_setup_page_tables(const mmap_region_t bl_regions[], +void __init arm_setup_page_tables(const mmap_region_t bl_regions[], const mmap_region_t plat_regions[]) { #if LOG_LEVEL >= LOG_LEVEL_VERBOSE diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index a8df5bad368a763eaea35666513d142d88f315c0..276f7801caab1b7c0aa45cfb69cbb90c4531daff 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -273,3 +273,14 @@ endif include ${IMG_PARSER_LIB_MK} endif + +# RECLAIM_INIT_CODE can only be set when LOAD_IMAGE_V2=2 and xlat tables v2 +# are used +ifeq (${RECLAIM_INIT_CODE}, 1) + ifeq (${LOAD_IMAGE_V2}, 0) + $(error "LOAD_IMAGE_V2 must be enabled to use RECLAIM_INIT_CODE") + endif + ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1) + $(error "To reclaim init code xlat tables v2 must be used") + endif +endif diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c index 6c8587fc4406370a7909ba11fb78f8e564df31fe..bd3dca17f60a6154acf76c6b4aaed35be96925aa 100644 --- a/plat/arm/common/arm_console.c +++ b/plat/arm/common/arm_console.c @@ -19,7 +19,7 @@ static console_pl011_t arm_runtime_console; #endif /* Initialize the console to provide early debug support */ -void arm_console_boot_init(void) +void __init arm_console_boot_init(void) { #if MULTI_CONSOLE_API int rc = console_pl011_register(PLAT_ARM_BOOT_UART_BASE, diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c index b8ffd6bc4303461d13e5cc9580bec9524048d483..e9e8a74d924f14fd6a43fc869b81d871ce15a7a5 100644 --- a/plat/arm/common/arm_gicv3.c +++ b/plat/arm/common/arm_gicv3.c @@ -68,7 +68,7 @@ static const gicv3_driver_data_t arm_gic_data __unused = { .mpidr_to_core_pos = arm_gicv3_mpidr_hash }; -void plat_arm_gic_driver_init(void) +void __init plat_arm_gic_driver_init(void) { /* * The GICv3 driver is initialized in EL3 and does not need @@ -85,7 +85,7 @@ void plat_arm_gic_driver_init(void) /****************************************************************************** * ARM common helper to initialize the GIC. Only invoked by BL31 *****************************************************************************/ -void plat_arm_gic_init(void) +void __init plat_arm_gic_init(void) { gicv3_distif_init(); gicv3_rdistif_init(plat_my_core_pos()); diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c index bf548c10c9a26902ac7de12fd9e8afd9cd115fab..85efc7dd2e7021a2845676a5624ca89c4a1152f0 100644 --- a/plat/arm/common/arm_pm.c +++ b/plat/arm/common/arm_pm.c @@ -208,7 +208,7 @@ void plat_arm_program_trusted_mailbox(uintptr_t address) * The ARM Standard platform definition of platform porting API * `plat_setup_psci_ops`. ******************************************************************************/ -int plat_setup_psci_ops(uintptr_t sec_entrypoint, +int __init plat_setup_psci_ops(uintptr_t sec_entrypoint, const plat_psci_ops_t **psci_ops) { *psci_ops = plat_arm_psci_override_pm_ops(&plat_arm_psci_pm_ops); diff --git a/plat/arm/css/drivers/mhu/css_mhu.c b/plat/arm/css/drivers/mhu/css_mhu.c index 30492a69546fec9faad73b0f84df435a08d4c6be..7b33317566eeb1fdaf9a868ec6b2a4837be14825 100644 --- a/plat/arm/css/drivers/mhu/css_mhu.c +++ b/plat/arm/css/drivers/mhu/css_mhu.c @@ -81,7 +81,7 @@ void mhu_secure_message_end(unsigned int slot_id) arm_lock_release(); } -void mhu_secure_init(void) +void __init mhu_secure_init(void) { arm_lock_init(); @@ -93,7 +93,7 @@ void mhu_secure_init(void) assert(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0); } -void plat_arm_pwrc_setup(void) +void __init plat_arm_pwrc_setup(void) { mhu_secure_init(); } diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c index 258c1c29ca435d0152e3d12c7762a61b84761f4f..d280101d6ec651da08d757e70a215ec327334730 100644 --- a/plat/arm/css/drivers/scp/css_pm_scmi.c +++ b/plat/arm/css/drivers/scp/css_pm_scmi.c @@ -328,7 +328,7 @@ static int scmi_ap_core_init(scmi_channel_t *ch) return 0; } -void plat_arm_pwrc_setup(void) +void __init plat_arm_pwrc_setup(void) { channel.info = &plat_css_scmi_plat_info; channel.lock = ARM_LOCK_GET_INSTANCE; diff --git a/plat/arm/css/sgi/sgi_interconnect.c b/plat/arm/css/sgi/sgi_interconnect.c index f4e7676a4f5eb6f0dd11ad459b5246e0e6c5186a..325b5b1523e5ce8496fd6a1ec44cfaa30e164aa2 100644 --- a/plat/arm/css/sgi/sgi_interconnect.c +++ b/plat/arm/css/sgi/sgi_interconnect.c @@ -17,7 +17,7 @@ /****************************************************************************** * Helper function to initialize ARM interconnect driver. *****************************************************************************/ -void plat_arm_interconnect_init(void) +void __init plat_arm_interconnect_init(void) { } diff --git a/plat/arm/css/sgm/sgm_interconnect.c b/plat/arm/css/sgm/sgm_interconnect.c index 301ea84f0bd6fcf0ef98fc47c640330830cc3b62..5b45341b9737a4730c6f7d643f3a66434abbd13c 100644 --- a/plat/arm/css/sgm/sgm_interconnect.c +++ b/plat/arm/css/sgm/sgm_interconnect.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <cdefs.h> + /* * As the SGM platform supports FCM (with automatic interconnect * enter/exit), we should not do anything in these interface functions. @@ -13,7 +15,7 @@ /****************************************************************************** * Helper function to initialize ARM interconnect driver. *****************************************************************************/ -void plat_arm_interconnect_init(void) +void __init plat_arm_interconnect_init(void) { }