From 2dbcb8f0a3250395c0ea8436ac519b6908dc0ee7 Mon Sep 17 00:00:00 2001 From: oliviermartin Date: Thu, 22 Sep 2011 23:05:20 +0000 Subject: ArmPlatformPkg: Changed memory model for the stacks In the previous version, every cores had the same stack size. To avoid to waste memory with secondary core stacks, the primary core stack size is now different from the secondary cores stack size. These are the Stack PCDs and their default values: gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0 gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize|0x10000 gArmPlatformTokenSpaceGuid.PcdCPUCoreSecSecondaryStackSize|0x1000 gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0 gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x1000 gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0 gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x10000 gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize|0x1000 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12415 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPlatformPkg/PrePeiCore/MainMPCore.c | 4 +- ArmPlatformPkg/PrePeiCore/MainUniCore.c | 4 +- ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.S | 77 ++++++++++++++-------- ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.asm | 59 ++++++++++++----- ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf | 5 +- ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf | 8 ++- 6 files changed, 106 insertions(+), 51 deletions(-) (limited to 'ArmPlatformPkg/PrePeiCore') diff --git a/ArmPlatformPkg/PrePeiCore/MainMPCore.c b/ArmPlatformPkg/PrePeiCore/MainMPCore.c index 036b192064..732e751c95 100644 --- a/ArmPlatformPkg/PrePeiCore/MainMPCore.c +++ b/ArmPlatformPkg/PrePeiCore/MainMPCore.c @@ -82,8 +82,8 @@ PrimaryMain ( SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF); SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet32 (PcdNormalFvBaseAddress); SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdNormalFvSize); - SecCoreData.TemporaryRamBase = (VOID *)(UINTN)PcdGet32 (PcdCPUCoresNonSecStackBase); // We consider we run on the primary core (and so we use the first stack) - SecCoreData.TemporaryRamSize = (UINTN)(UINTN)PcdGet32 (PcdCPUCoresNonSecStackSize); + SecCoreData.TemporaryRamBase = (VOID *)(UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize); // We consider we run on the primary core (and so we use the first stack) + SecCoreData.TemporaryRamSize = (UINTN)(UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize); SecCoreData.PeiTemporaryRamBase = (VOID *)((UINTN)(SecCoreData.TemporaryRamBase) + (SecCoreData.TemporaryRamSize / 2)); SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize / 2; SecCoreData.StackBase = SecCoreData.TemporaryRamBase; diff --git a/ArmPlatformPkg/PrePeiCore/MainUniCore.c b/ArmPlatformPkg/PrePeiCore/MainUniCore.c index 179e1ea344..64877d1cc1 100644 --- a/ArmPlatformPkg/PrePeiCore/MainUniCore.c +++ b/ArmPlatformPkg/PrePeiCore/MainUniCore.c @@ -44,8 +44,8 @@ PrimaryMain ( SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF); SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet32 (PcdNormalFvBaseAddress); SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdNormalFvSize); - SecCoreData.TemporaryRamBase = (VOID *)(UINTN)PcdGet32 (PcdCPUCoresNonSecStackBase); // We consider we run on the primary core (and so we use the first stack) - SecCoreData.TemporaryRamSize = (UINTN)(UINTN)PcdGet32 (PcdCPUCoresNonSecStackSize); + SecCoreData.TemporaryRamBase = (VOID *)(UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize); // We consider we run on the primary core (and so we use the first stack) + SecCoreData.TemporaryRamSize = (UINTN)(UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize); SecCoreData.PeiTemporaryRamBase = (VOID *)((UINTN)(SecCoreData.TemporaryRamBase) + (SecCoreData.TemporaryRamSize / 2)); SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize / 2; SecCoreData.StackBase = SecCoreData.TemporaryRamBase; diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.S b/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.S index 01723a2eac..f9b85a604e 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.S +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.S @@ -26,43 +26,68 @@ GCC_ASM_EXPORT(_ModuleEntryPoint) StartupAddr: .word CEntryPoint ASM_PFX(_ModuleEntryPoint): - # Identify CPU ID + // Identify CPU ID bl ASM_PFX(ArmReadMpidr) // Get ID of this CPU in Multicore system LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1) and r0, r0, r1 -_SetupStack: - # Setup Stack for the 4 CPU cores - LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackBase), r1) - LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackSize), r2) - - mov r3,r0 @ r3 = core_id - mul r3,r3,r2 @ r3 = core_id * stack_size = offset from the stack base - add r3,r3,r1 @ r3 = stack_base + offset - add r3,r3,r2,LSR #1 @ r3 = stack_offset + (stack_size/2) <-- the top half is for the heap - mov sp, r3 - - # Only allocate memory in top of the primary core stack - cmp r0, #0 - bne _PrepareArguments - -_AllocateGlobalPeiVariables: - # Reserve top of the stack for Global PEI Variables (eg: PeiServicesTablePointer) - LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r1) - sub sp, sp, r1 + // Calculate the top of the primary stack + LoadConstantToReg (FixedPcdGet32(PcdCPUCoresStackBase), r1) + LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2) + add r2, r2, r1 + + // Is it the Primary Core ? + LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r1) + cmp r0, r1 + beq _SetupPrimaryCoreStack + +_SetupSecondaryCoreStack: + // r2 = Top of the primary stack = Base of the Secondary Stacks + + // Get the position of the cores (ClusterId * 4) + CoreId + GetCorePositionInStack(r3, r0, r1) + // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack + add r3, r3, #1 + + LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), r1) + // StackOffset = CorePos * StackSize + mul r3, r3, r1 + // SP = StackBase + StackOffset + add sp, r2, r3 + + b _PrepareArguments + +_SetupPrimaryCoreStack: + // r2 = Top of the primary stack + LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r3) + + // The reserved space for global variable must be 8-bytes aligned for pushing + // 64-bit variable on the stack + SetPrimaryStack (r2, r3, r1) + + // Set all the PEI global variables to 0 + mov r3, sp + mov r1, #0x0 +_InitGlobals: + str r1, [r3], #4 + cmp r3, r2 + blt _InitGlobals _PrepareArguments: - # The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector + // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector LoadConstantToReg (FixedPcdGet32(PcdNormalFvBaseAddress), r2) add r2, r2, #4 ldr r1, [r2] - # move sec startup address into a data register - # ensure we're jumping to FV version of the code (not boot remapped alias) + // move sec startup address into a data register + // ensure we're jumping to FV version of the code (not boot remapped alias) ldr r2, StartupAddr - # jump to PrePeiCore C code - # r0 = core_id - # r1 = pei_core_address + // jump to PrePeiCore C code + // r0 = mp_id + // r1 = pei_core_address blx r2 + +_NeverReturn: + b _NeverReturn diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.asm b/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.asm index e4eb612610..1964f18ebf 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.asm +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.asm @@ -34,25 +34,47 @@ _ModuleEntryPoint LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1) and r0, r0, r1 -_SetupStack - // Setup Stack for the 4 CPU cores - LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackBase), r1) - LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackSize), r2) - - mov r3, r0 // r3 = core_id - mul r3, r3, r2 // r3 = core_id * stack_size = offset from the stack base - add r3, r3, r1 // r3 = stack_base + offset - add r3, r3, r2, LSR #1 // r3 = stack_offset + (stack_size/2) <-- the top half is for the heap - mov sp, r3 + // Calculate the top of the primary stack + LoadConstantToReg (FixedPcdGet32(PcdCPUCoresStackBase), r1) + LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2) + add r2, r2, r1 + + // Is it the Primary Core ? + LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r1) + cmp r0, r1 + beq _SetupPrimaryCoreStack + +_SetupSecondaryCoreStack + // r2 = Top of the primary stack = Base of the Secondary Stacks + + // Get the position of the cores (ClusterId * 4) + CoreId + GetCorePositionInStack(r3, r0, r1) + // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack + add r3, r3, #1 - // Only allocate memory in top of the primary core stack - cmp r0, #0 - bne _PrepareArguments + LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), r1) + // StackOffset = CorePos * StackSize + mul r3, r3, r1 + // SP = StackBase + StackOffset + add sp, r2, r3 -_AllocateGlobalPeiVariables - // Reserve top of the stack for Global PEI Variables (eg: PeiServicesTablePointer) - LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r1) - sub sp, sp, r1 + b _PrepareArguments + +_SetupPrimaryCoreStack + // r2 = Top of the primary stack + LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r3) + + // The reserved space for global variable must be 8-bytes aligned for pushing + // 64-bit variable on the stack + SetPrimaryStack (r2, r3, r1) + + // Set all the PEI global variables to 0 + mov r3, sp + mov r1, #0x0 +_InitGlobals + str r1, [r3], #4 + cmp r3, r2 + blt _InitGlobals _PrepareArguments // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector @@ -69,4 +91,7 @@ _PrepareArguments // r1 = pei_core_address blx r2 +_NeverReturn + b _NeverReturn + END diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf index 25dae0fb9e..145893505d 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf @@ -61,8 +61,9 @@ gArmTokenSpaceGuid.PcdArmPrimaryCoreMask gArmTokenSpaceGuid.PcdArmPrimaryCore - gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase - gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize + gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase + gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize + gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf index be846c581c..028330d03b 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf @@ -56,8 +56,12 @@ gArmTokenSpaceGuid.PcdNormalFvBaseAddress gArmTokenSpaceGuid.PcdNormalFvSize - gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase - gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask + gArmTokenSpaceGuid.PcdArmPrimaryCore + + gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase + gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize + gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize -- cgit v1.2.3