summaryrefslogtreecommitdiff
path: root/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPlatformPkg/PrePi/ModuleEntryPoint.asm')
-rw-r--r--ArmPlatformPkg/PrePi/ModuleEntryPoint.asm96
1 files changed, 78 insertions, 18 deletions
diff --git a/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm b/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm
index 881871d34e..965bb00318 100644
--- a/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm
+++ b/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm
@@ -20,6 +20,7 @@
IMPORT CEntryPoint
IMPORT ArmReadMpidr
+ IMPORT ArmIsMPCore
EXPORT _ModuleEntryPoint
PRESERVE8
@@ -38,7 +39,7 @@ _SetSVCMode
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 +61,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,4 +143,21 @@ _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
+
END