diff --git a/Makefile b/Makefile index 23a1b0a..d487eae 100644 --- a/Makefile +++ b/Makefile @@ -634,6 +634,7 @@ $(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 4b7f63c..62bea01 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -57,7 +57,7 @@ /******************************************************************************* * 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 @@ * 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 3d6d674..fa036cb 100644 --- a/bl31/ehf.c +++ b/bl31/ehf.c @@ -451,7 +451,7 @@ /* * 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 ad564f5..03f7f7e 100644 --- a/common/runtime_svc.c +++ b/common/runtime_svc.c @@ -93,7 +93,7 @@ * 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 79bdec9..7cc7485 100644 --- a/docs/firmware-design.rst +++ b/docs/firmware-design.rst @@ -2336,6 +2336,29 @@ 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 91245d4..605971c 100644 --- a/drivers/arm/cci/cci.c +++ b/drivers/arm/cci/cci.c @@ -107,7 +107,8 @@ } #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 afb7d9d..910cd7c 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 @@ * 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 @@ * 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 5af7e40..60f2e10 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -55,7 +55,7 @@ * 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 @@ * 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 ddb9963..78a9ffa 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 #include #include #include -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 @@ * * 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 b1d10cc..0d00722 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_common.ld.S b/include/plat/arm/common/arm_common.ld.S deleted file mode 100644 index 3f6e29b..0000000 --- a/include/plat/arm/common/arm_common.ld.S +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#ifndef __ARM_COMMON_LD_S__ -#define __ARM_COMMON_LD_S__ - -#include - -MEMORY { - EL3_SEC_DRAM (rw): ORIGIN = ARM_EL3_TZC_DRAM1_BASE, LENGTH = ARM_EL3_TZC_DRAM1_SIZE -} - -SECTIONS -{ - . = ARM_EL3_TZC_DRAM1_BASE; - ASSERT(. == ALIGN(PAGE_SIZE), - "ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.") - el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) { - __EL3_SEC_DRAM_START__ = .; - *(arm_el3_tzc_dram) - __EL3_SEC_DRAM_UNALIGNED_END__ = .; - - . = ALIGN(PAGE_SIZE); - __EL3_SEC_DRAM_END__ = .; - } >EL3_SEC_DRAM -} - -#endif /* __ARM_COMMON_LD_S__ */ diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 23cd12f..8d81af9 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 0000000..8f22170 --- /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_tzc_dram.ld.S b/include/plat/arm/common/arm_tzc_dram.ld.S new file mode 100644 index 0000000..df951e1 --- /dev/null +++ b/include/plat/arm/common/arm_tzc_dram.ld.S @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef ARM_TZC_DRAM_LD_S__ +#define ARM_TZC_DRAM_LD_S__ + +#include + +MEMORY { + EL3_SEC_DRAM (rw): ORIGIN = ARM_EL3_TZC_DRAM1_BASE, LENGTH = ARM_EL3_TZC_DRAM1_SIZE +} + +SECTIONS +{ + . = ARM_EL3_TZC_DRAM1_BASE; + ASSERT(. == ALIGN(PAGE_SIZE), + "ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.") + el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) { + __EL3_SEC_DRAM_START__ = .; + *(arm_el3_tzc_dram) + __EL3_SEC_DRAM_UNALIGNED_END__ = .; + + . = ALIGN(PAGE_SIZE); + __EL3_SEC_DRAM_END__ = .; + } >EL3_SEC_DRAM +} + +#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 3f344ab..d543894 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -221,6 +221,12 @@ 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 */ unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr); diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index ee5fe4f..acc8d6d 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 2e65eeb..f39e5f5 100644 --- a/lib/extensions/ras/ras_common.c +++ b/lib/extensions/ras/ras_common.c @@ -128,7 +128,7 @@ 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 b877b4b..adce843 100644 --- a/lib/psci/psci_common.c +++ b/lib/psci/psci_common.c @@ -216,7 +216,7 @@ /****************************************************************************** * 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 e59e163..6b3081e 100644 --- a/lib/psci/psci_setup.c +++ b/lib/psci/psci_setup.c @@ -32,7 +32,7 @@ * 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 @@ * 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 @@ * 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 @@ * | 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 ca67f2a..a9aaeee 100644 --- a/lib/xlat_tables/xlat_tables_common.c +++ b/lib/xlat_tables/xlat_tables_common.c @@ -176,7 +176,7 @@ { 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 4a4cb94..f180774 100644 --- a/lib/xlat_tables_v2/xlat_tables_context.c +++ b/lib/xlat_tables_v2/xlat_tables_context.c @@ -56,7 +56,7 @@ #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 003718e..3b6c6bc 100644 --- a/lib/xlat_tables_v2/xlat_tables_core.c +++ b/lib/xlat_tables_v2/xlat_tables_core.c @@ -815,7 +815,7 @@ { 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 @@ #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 92a0f6e..520725b 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -252,10 +252,11 @@ 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 7df4cd2..435de20 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -146,6 +146,10 @@ # 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 5948e14..b17446c 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 @@ } /* 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 ea11708..1c8804f 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -10,8 +10,8 @@ #include #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 3f7857e..aa4f839 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -241,7 +241,7 @@ * 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_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 24c3deb..f2a3ea6 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 +#include +#include #endif /* __PLAT_LD_S__ */ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 4cd6a24..9bd3bde 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -201,6 +201,9 @@ # 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 364e46a..ed2c3fb 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include /* * Placeholder variables for copying the arguments that have been passed to @@ -35,10 +37,20 @@ #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 @@ * 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 @@ /* 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 @@ * 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 @@ 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 fc24cc3..6505b91 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 @@ /****************************************************************************** * 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 84a529f..ddf3286 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 @@ /****************************************************************************** * 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 28ff5d9..a21d189 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -38,10 +38,11 @@ * 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 a8df5ba..276f780 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -273,3 +273,14 @@ 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 6c8587f..bd3dca1 100644 --- a/plat/arm/common/arm_console.c +++ b/plat/arm/common/arm_console.c @@ -19,7 +19,7 @@ #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 b8ffd6b..e9e8a74 100644 --- a/plat/arm/common/arm_gicv3.c +++ b/plat/arm/common/arm_gicv3.c @@ -68,7 +68,7 @@ .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 @@ /****************************************************************************** * 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 bf548c1..85efc7d 100644 --- a/plat/arm/common/arm_pm.c +++ b/plat/arm/common/arm_pm.c @@ -208,7 +208,7 @@ * 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 30492a6..7b33317 100644 --- a/plat/arm/css/drivers/mhu/css_mhu.c +++ b/plat/arm/css/drivers/mhu/css_mhu.c @@ -81,7 +81,7 @@ arm_lock_release(); } -void mhu_secure_init(void) +void __init mhu_secure_init(void) { arm_lock_init(); @@ -93,7 +93,7 @@ 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 258c1c2..d280101 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 @@ 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 f4e7676..325b5b1 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 301ea84..5b45341 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 + /* * 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) { }