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:
@@ -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
|
||||
|
Reference in New Issue
Block a user