diff options
Diffstat (limited to 'ArmPlatformPkg/PrePi/ModuleEntryPoint.S')
-rwxr-xr-x | ArmPlatformPkg/PrePi/ModuleEntryPoint.S | 99 |
1 files changed, 79 insertions, 20 deletions
diff --git a/ArmPlatformPkg/PrePi/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/ModuleEntryPoint.S index 4d64aa7e86..b5f2ee2e57 100755 --- a/ArmPlatformPkg/PrePi/ModuleEntryPoint.S +++ b/ArmPlatformPkg/PrePi/ModuleEntryPoint.S @@ -19,9 +19,9 @@ .text
.align 3
-# Global symbols referenced by this module
GCC_ASM_IMPORT(CEntryPoint)
GCC_ASM_IMPORT(ArmReadMpidr)
+GCC_ASM_IMPORT(ArmIsMPCore)
GCC_ASM_EXPORT(_ModuleEntryPoint)
StartupAddr: .word CEntryPoint
@@ -31,14 +31,14 @@ ASM_PFX(_ModuleEntryPoint): // Get ID of this CPU in Multicore system
bl ASM_PFX(ArmReadMpidr)
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1)
- and r0, r0, r1
+ and r5, r0, r1
_SetSVCMode:
// Enter SVC mode
mov r1, #0x13|0x80|0x40
msr CPSR_c, r1
-// Check if we can install the size at the top of the System Memory or if we need
+// Check if we can install the stack at the top of the System Memory or if we need
// to install the stacks at the bottom of the Firmware Device (case the FD is located
// at the top of the DRAM)
_SetupStackPosition:
@@ -60,35 +60,77 @@ _SetupStackPosition: //
// Calculate how much space there is between the top of the Firmware and the Top of the System Memory
- subs r5, r1, r3 // r5 = SystemMemoryTop - FdTop
- bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop)
- cmp r5, r4
+ subs r0, r1, r3 // r0 = SystemMemoryTop - FdTop
+ bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
+ cmp r0, r4
bge _SetupStack
// Case the top of stacks is the FdBaseAddress
mov r1, r2
_SetupStack:
- // Compute Base of Normal stacks for CPU Cores
- LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackSize), r5)
- mul r3, r0, r5 // r3 = core_id * stack_size = offset from the stack base
- sub sp, r1, r3 // r3 = (SystemMemoryTop|FdBaseAddress) - StackOffset = TopOfStack
+ // r1 contains the top of the stack (and the UEFI Memory)
// Calculate the Base of the UEFI Memory
- sub r1, r1, r4
+ sub r6, r1, r4
- // Only allocate memory for global variables at top of the primary core stack
+_GetStackBase:
+ // Compute Base of Normal stacks for CPU Cores
+ // Is it MpCore system
+ bl ArmIsMPCore
cmp r0, #0
+ // Case it is not an MP Core system. Just setup the primary core
+ beq _SetupUnicoreStack
+
+_GetStackBaseMpCore:
+ // Stack for the primary core = PrimaryCoreStack
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2)
+ sub r7, r1, r2
+ // Stack for the secondary core = Number of Cluster * (4 Core per cluster) * SecondaryStackSize
+ LoadConstantToReg (FixedPcdGet32(PcdClusterCount), r2)
+ lsl r2, r2, #2
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), r3)
+ mul r2, r2, r3
+ sub r7, r7, r2
+
+ // The top of the Mpcore Stacks is in r1
+ // The base of the MpCore Stacks is in r7
+
+ // Is it the Primary Core ?
+ LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r4)
+ cmp r0, r4
+ beq _SetupPrimaryCoreStack
+
+_SetupSecondaryCoreStack:
+ // Base of the stack for the secondary cores is in r7
+
+ // Get the position of the cores (ClusterId * 4) + CoreId
+ GetCorePositionInStack(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, r7, r0
+
bne _PrepareArguments
-_AllocateGlobalPrePiVariables:
- // Reserve top of the stack for Global PEI Variables (eg: PeiServicesTablePointer)
- LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r4)
- // The reserved place must be 8-bytes aligned for pushing 64-bit variable on the stack
- and r5, r4, #7
- rsb r5, r5, #8
- add r4, r4, r5
- sub sp, sp, r4
+_SetupPrimaryCoreStack:
+ // The top of the Mpcore Stacks is in r1
+ LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r2)
+
+ // The reserved space for global variable must be 8-bytes aligned for pushing
+ // 64-bit variable on the stack
+ SetPrimaryStack (r1, r2, r3)
+
+_SetGlobals:
+ // Set all the PrePi global variables to 0
+ mov r3, sp
+ mov r2, #0x0
+_InitGlobals:
+ str r2, [r3], #4
+ cmp r3, r1
+ blt _InitGlobals
+
_PrepareArguments:
// Move sec startup address into a data register
@@ -100,3 +142,20 @@ _PrepareArguments: // r1 = UefiMemoryBase
blx r2
+_NeverReturn:
+ b _NeverReturn
+
+_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
+
+ // The reserved space for global variable must be 8-bytes aligned for pushing
+ // 64-bit variable on the stack
+ SetPrimaryStack (r1, r2, r3)
+
+ b _SetGlobals
+
|