diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S index e4d4f1254..717f65e2b 100644 --- a/include/plat/arm/common/arm_reclaim_init.ld.S +++ b/include/plat/arm/common/arm_reclaim_init.ld.S @@ -14,54 +14,30 @@ SECTIONS __INIT_CODE_START__ = .; *(*text.init*); __INIT_CODE_END__ = .; + INIT_CODE_END_ALIGNED = ALIGN(PAGE_SIZE); } >RAM #ifdef BL31_PROGBITS_LIMIT ASSERT(__INIT_CODE_END__ <= BL31_PROGBITS_LIMIT, "BL31 init has exceeded progbits limit.") #endif - - ASSERT(__INIT_CODE_END__ <= __STACKS_END__, - "Init code ends past the end of the stacks") - } -#undef MIN #define ABS ABSOLUTE -#define COUNT PLATFORM_CORE_COUNT -#define ALIGN_MASK ~(CACHE_WRITEBACK_GRANULE - 1) -#define PRIMARY_STACK \ - __STACKS_START__ = .; \ - *(tzfw_normal_stacks) \ - OFFSET = ABS(SIZEOF(.init) - (. - __STACKS_START__)); \ - /* Offset sign */ \ - SIGN = ABS(OFFSET) & (1 << 63); \ - /* Offset mask */ \ - MASK = ABS(SIGN >> 63) - 1; \ - . += ABS(OFFSET) & ABS(MASK); \ - . = ALIGN(PAGE_SIZE); \ - __STACKS_END__ = .; \ - /* Total stack size */ \ - SIZE = ABS(. - __STACKS_START__); \ - /* Maximum primary CPU stack */ \ - STACK = ABS(__STACKS_START__ + SIZE / COUNT) & ALIGN_MASK; \ - /* Primary CPU stack */ \ - __PRIMARY_STACK__ = MIN(STACK, ABS(__INIT_CODE_START__)); - -#if (COUNT > 1) -#define SECONDARY_STACK \ - /* Size of the secondary CPUs' stack */ \ - REST = ABS(__STACKS_END__ - __PRIMARY_STACK__); \ - /* Secondary per-CPU stack size */ \ - __STACK_SIZE__ = ABS(REST / (COUNT - 1)); -#else -#define SECONDARY_STACK -#endif - -#define STACK_SECTION \ - stacks (NOLOAD) : { \ - PRIMARY_STACK \ - SECONDARY_STACK \ +#define STACK_SECTION \ + stacks (NOLOAD) : { \ + __STACKS_START__ = .; \ + *(tzfw_normal_stacks) \ + __STACKS_END__ = .; \ + /* Allow room for the init section where necessary. */ \ + OFFSET = ABS(SIZEOF(.init) - (. - __STACKS_START__)); \ + /* Offset sign */ \ + SIGN = ABS(OFFSET) & (1 << 63); \ + /* Offset mask */ \ + MASK = ABS(SIGN >> 63) - 1; \ + . += ABS(OFFSET) & ABS(MASK); \ + . = ALIGN(PAGE_SIZE); \ } + #endif /* ARM_RECLAIM_INIT_LD_S */ diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index fc238b1d8..81ef6e7b2 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -47,9 +47,12 @@ CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows); #if RECLAIM_INIT_CODE IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE); IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED); +IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED); #define BL_INIT_CODE_END ((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \ ~(PAGE_SIZE - 1)) +#define BL_STACKS_END ((BL_STACKS_END_UNALIGNED + PAGE_SIZE - 1) & \ + ~(PAGE_SIZE - 1)) #define MAP_BL_INIT_CODE MAP_REGION_FLAT( \ BL_INIT_CODE_BASE, \ @@ -291,14 +294,39 @@ void arm_bl31_plat_runtime_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 + * Make memory for image boot time code RW to reclaim it as stack for the + * secondary cores, or RO where it cannot be reclaimed: + * + * |-------- INIT SECTION --------| + * ----------------------------------------- + * | CORE 0 | CORE 1 | CORE 2 | EXTRA | + * | STACK | STACK | STACK | SPACE | + * ----------------------------------------- + * <-------------------> <------> + * MAKE RW AND XN MAKE + * FOR STACKS RO AND XN */ void arm_free_init_memory(void) { - int ret = xlat_change_mem_attributes(BL_INIT_CODE_BASE, + int ret = 0; + + if (BL_STACKS_END < BL_INIT_CODE_END) { + /* Reclaim some of the init section as stack if possible. */ + if (BL_INIT_CODE_BASE < BL_STACKS_END) { + ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE, + BL_STACKS_END - BL_INIT_CODE_BASE, + MT_RW_DATA); + } + /* Make the rest of the init section read-only. */ + ret |= xlat_change_mem_attributes(BL_STACKS_END, + BL_INIT_CODE_END - BL_STACKS_END, + MT_RO_DATA); + } else { + /* The stacks cover the init section, so reclaim it all. */ + 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"); diff --git a/plat/common/aarch64/platform_mp_stack.S b/plat/common/aarch64/platform_mp_stack.S index ee0dbb4f6..c34a4cf3b 100644 --- a/plat/common/aarch64/platform_mp_stack.S +++ b/plat/common/aarch64/platform_mp_stack.S @@ -32,42 +32,9 @@ * ----------------------------------------------------- */ func plat_get_my_stack -#if (defined(IMAGE_BL31) && RECLAIM_INIT_CODE) -#if (PLATFORM_CORE_COUNT == 1) - /* Single CPU */ - adrp x0, __PRIMARY_STACK__ - add x0, x0, :lo12:__PRIMARY_STACK__ - ret -#else - mov x10, x30 - bl plat_my_core_pos - cbnz x0, 2f - - /* Primary CPU */ - adrp x0, __PRIMARY_STACK__ - add x0, x0, :lo12:__PRIMARY_STACK__ - ret x10 - - /* Secondary CPU */ -2: sub x0, x0, #(PLATFORM_CORE_COUNT - 1) - adrp x1, __STACKS_END__ - adrp x2, __STACK_SIZE__ - add x1, x1, :lo12:__STACKS_END__ - add x2, x2, :lo12:__STACK_SIZE__ - - madd x0, x0, x2, x1 - bic x0, x0, #(CACHE_WRITEBACK_GRANULE - 1) - ret x10 -#endif - /* Prevent linker from removal of stack section */ - .quad platform_normal_stacks - -#else /* !(IMAGE_BL31 && RECLAIM_INIT_CODE) */ mov x10, x30 get_my_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE ret x10 - -#endif /* IMAGE_BL31 && RECLAIM_INIT_CODE */ endfunc plat_get_my_stack /* -----------------------------------------------------