ArmPlatformPkg/ArmPlatformStackLib: Introduced helper library to initialize stacks

The new functions are:
- ArmPlatformStackSet(IN UINTN StackBase, IN UINTN MpId, IN UINTN PrimaryStackSize, IN UINTN SecondaryStackSize);
- ArmPlatformStackSetPrimary(IN UINTN StackBase, IN UINTN MpId, IN UINTN PrimaryStackSize, IN UINTN SecondaryStackSize);
- ArmPlatformStackSetSecondary(IN UINTN StackBase, IN UINTN MpId, IN UINTN PrimaryStackSize, IN UINTN SecondaryStackSize);

The stack topology can be changed by implementing a new ArmPlatformStackLib

Signed-off-by: Olivier Martin <olivier.martin@arm.com>




git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13774 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
oliviermartin
2012-09-28 11:01:36 +00:00
parent 7d49ced0cf
commit 17839a45b8
11 changed files with 360 additions and 122 deletions

View File

@@ -21,7 +21,7 @@
GCC_ASM_IMPORT(CEntryPoint)
GCC_ASM_IMPORT(ArmReadMpidr)
GCC_ASM_IMPORT(ArmIsMpCore)
GCC_ASM_IMPORT(ArmPlatformStackSet)
GCC_ASM_EXPORT(_ModuleEntryPoint)
StartupAddr: .word CEntryPoint
@@ -31,10 +31,11 @@ ASM_PFX(_ModuleEntryPoint):
// Get ID of this CPU in Multicore system
bl ASM_PFX(ArmReadMpidr)
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1)
and r5, r0, r1
and r6, r0, r1
_SetSVCMode:
// Enter SVC mode, Disable FIQ and IRQ
//TODO: remove hardcoded values
mov r1, #0x13|0x80|0x40
msr CPSR_c, r1
@@ -76,92 +77,59 @@ _SetupStack:
// Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment
// one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the
// top of the memory space)
adds r6, r1, #1
adds r7, r1, #1
bcs _SetupOverflowStack
_SetupAlignedStack:
mov r1, r6
mov r1, r7
b _GetBaseUefiMemory
_SetupOverflowStack:
// Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE
// aligned (4KB)
LoadConstantToReg (EFI_PAGE_MASK, r6)
and r6, r6, r1
sub r1, r1, r6
LoadConstantToReg (EFI_PAGE_MASK, r7)
and r7, r7, r1
sub r1, r1, r7
_GetBaseUefiMemory:
// Calculate the Base of the UEFI Memory
sub r6, r1, r4
sub r7, r1, r4
_GetStackBase:
// Compute Base of Normal stacks for CPU Cores
// Is it MpCore system
bl ASM_PFX(ArmIsMpCore)
cmp r0, #0
// Case it is not an MP Core system. Just setup the primary core
beq _SetupUnicoreStack
_GetStackBaseMpCore:
// r1 = The top of the Mpcore Stacks
// Stack for the primary core = PrimaryCoreStack
LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2)
sub r7, r1, r2
sub r8, r1, r2
// Stack for the secondary core = Number of Clusters * (4 Cores per cluster) * SecondaryStackSize
LoadConstantToReg (FixedPcdGet32(PcdClusterCount), r2)
lsl r2, r2, #2
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), r3)
mul r2, r2, r3
sub r7, r7, r2
// Stack for the secondary core = Number of Cores - 1
LoadConstantToReg (FixedPcdGet32(PcdCoreCount), r0)
sub r0, r0, #1
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), r1)
mul r1, r1, r0
sub r8, r8, r1
// The base of the secondary Stacks = Top of Primary stack
// r8 = The base of the MpCore Stacks (primary stack & secondary stacks)
mov r0, r8
mov r1, r6
//ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2)
add r1, r7, r2
// r7 = The base of the MpCore Stacks (primary stack + cluster_count * 4 * secondary stacks)
// r1 = The base of the secondary Stacks = Top of the Primary stack
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), r3)
bl ASM_PFX(ArmPlatformStackSet)
// Is it the Primary Core ?
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r4)
cmp r5, r4
beq _SetupPrimaryCoreStack
_SetupSecondaryCoreStack:
// r1 = The base of the secondary Stacks
// Get the position of the cores (ClusterId * 4) + CoreId
GetCorePositionFromMpId(r0, r5, r4)
// The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack
add r0, r0, #1
// Get the offset for the Secondary Stack
mul r0, r0, r3
add sp, r1, r0
cmp r6, r4
bne _PrepareArguments
_SetupPrimaryCoreStack:
// r1 = Top of the primary stack
LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r2)
b _PreparePrimaryStack
_SetupUnicoreStack:
// The top of the Unicore Stack is in r1
LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r2)
LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r3)
// Calculate the bottom of the primary stack (StackBase)
sub r7, r1, r3
_PreparePrimaryStack:
// The reserved space for global variable must be 8-bytes aligned for pushing
// 64-bit variable on the stack
SetPrimaryStack (r1, r2, r3)
_ReserveGlobalVariable:
LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r0)
// InitializePrimaryStack($GlobalVariableSize, $Tmp1)
InitializePrimaryStack(r0, r1)
_PrepareArguments:
mov r0, r5
mov r1, r6
mov r2, r7
mov r0, r6
mov r1, r7
mov r2, r8
mov r3, sp
// Move sec startup address into a data register