summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ArmPkg/Include/AsmMacroIoLib.h15
-rw-r--r--ArmPkg/Include/AsmMacroIoLib.inc16
-rw-r--r--ArmPlatformPkg/ArmPlatformPkg.dec14
-rw-r--r--ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc11
-rw-r--r--ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc12
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc12
-rw-r--r--ArmPlatformPkg/Documentation/ArmPlatformPkg.txt15
-rw-r--r--ArmPlatformPkg/PrePeiCore/MainMPCore.c4
-rw-r--r--ArmPlatformPkg/PrePeiCore/MainUniCore.c4
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.S77
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.asm59
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf5
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf8
-rwxr-xr-xArmPlatformPkg/PrePi/ModuleEntryPoint.S99
-rw-r--r--ArmPlatformPkg/PrePi/ModuleEntryPoint.asm96
-rwxr-xr-xArmPlatformPkg/PrePi/PeiMPCore.inf10
-rwxr-xr-xArmPlatformPkg/PrePi/PeiUniCore.inf4
-rwxr-xr-xArmPlatformPkg/PrePi/PrePi.c2
-rw-r--r--ArmPlatformPkg/Sec/Sec.inf3
-rw-r--r--ArmPlatformPkg/Sec/SecEntryPoint.S133
-rw-r--r--ArmPlatformPkg/Sec/SecEntryPoint.asm57
21 files changed, 447 insertions, 209 deletions
diff --git a/ArmPkg/Include/AsmMacroIoLib.h b/ArmPkg/Include/AsmMacroIoLib.h
index 1ea2c33ff..9ef3430aa 100644
--- a/ArmPkg/Include/AsmMacroIoLib.h
+++ b/ArmPkg/Include/AsmMacroIoLib.h
@@ -168,6 +168,17 @@
#define LoadConstantToReg(Data, Reg) \
ldr Reg, =Data
+#define GetCorePositionInStack(Pos, MpId, Tmp) \
+ lsr Pos, MpId, #6 ; \
+ and Tmp, MpId, #3 ; \
+ add Pos, Pos, Tmp
+
+#define SetPrimaryStack(StackTop, GlobalSize, Tmp) \
+ and Tmp, GlobalSize, #7 ; \
+ rsbne Tmp, Tmp, #8 ; \
+ add GlobalSize, GlobalSize, Tmp ; \
+ sub sp, StackTop, GlobalSize
+
#else
//
@@ -229,8 +240,10 @@
// conditional load testing eq flag
#define LoadConstantToRegIfEq(Data, Reg) LoadConstantToRegIfEqMacro Data, Reg
+#define GetCorePositionInStack(Pos, MpId, Tmp) GetCorePositionInStack Pos, MpId, Tmp
-#endif
+#define SetPrimaryStack(StackTop,GlobalSize,Tmp) SetPrimaryStack StackTop, GlobalSize, Tmp
+#endif
#endif
diff --git a/ArmPkg/Include/AsmMacroIoLib.inc b/ArmPkg/Include/AsmMacroIoLib.inc
index 78e2ae294..5644bf9b3 100644
--- a/ArmPkg/Include/AsmMacroIoLib.inc
+++ b/ArmPkg/Include/AsmMacroIoLib.inc
@@ -77,5 +77,21 @@
LoadConstantToRegMacro $Data, $Reg
ldr $Reg, =($Data)
MEND
+
+ MACRO
+ GetCorePositionInStack $Pos, $MpId, $Tmp
+ lsr $Pos, $MpId, #6
+ and $Tmp, $MpId, #3
+ add $Pos, $Pos, $Tmp
+ MEND
+
+ ; The reserved place must be 8-bytes aligned for pushing 64-bit variable on the stack
+ MACRO
+ SetPrimaryStack $StackTop, $GlobalSize, $Tmp
+ and $Tmp, $GlobalSize, #7
+ rsbne $Tmp, $Tmp, #8
+ add $GlobalSize, $GlobalSize, $Tmp
+ sub sp, $StackTop, $GlobalSize
+ MEND
END
diff --git a/ArmPlatformPkg/ArmPlatformPkg.dec b/ArmPlatformPkg/ArmPlatformPkg.dec
index 65b4977fd..c5e40105e 100644
--- a/ArmPlatformPkg/ArmPlatformPkg.dec
+++ b/ArmPlatformPkg/ArmPlatformPkg.dec
@@ -49,19 +49,21 @@
# These PCDs should be FeaturePcds. But we used these PCDs as an '#if' in an ASM file.
# Using a FeaturePcd make a '(BOOLEAN) casting for its value which is not understood by the preprocessor.
gArmPlatformTokenSpaceGuid.PcdMPCoreSupport|0|UINT32|0x00000003
- gArmPlatformTokenSpaceGuid.PcdMPCoreMaxCores|1|UINT32|0x0000002D
-
+ gArmPlatformTokenSpaceGuid.PcdClusterCount|1|UINT32|0x00000038
+
# Stack for CPU Cores in Secure Mode
gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0|UINT32|0x00000005
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecStackSize|0|UINT32|0x00000006
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize|0x10000|UINT32|0x00000036
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecSecondaryStackSize|0x1000|UINT32|0x00000006
# Stack for CPU Cores in Secure Monitor Mode
gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0|UINT32|0x00000007
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0|UINT32|0x00000008
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x1000|UINT32|0x00000008
# Stack for CPU Cores in Non Secure Mode
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase|0|UINT32|0x00000009
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize|0|UINT32|0x0000000A
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0|UINT32|0x00000009
+ gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x10000|UINT32|0x00000037
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize|0x1000|UINT32|0x0000000A
# Size of the region used by UEFI in permanent memory (Reserved 128MB by default)
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x08000000|UINT32|0x00000015
diff --git a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc
index 12f2cbb11..808793cb2 100644
--- a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc
+++ b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc
@@ -344,16 +344,11 @@
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0x00000000
# Stack for CPU Cores in Secure Mode
- gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x4B000000 # Top of SEC Stack for Secure World
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecStackSize|0x2000 # Size of SEC Stack for Secure World
-
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x4B000000
# Stack for CPU Cores in Secure Monitor Mode
- gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0x4A000000 # Top of SEC Stack for Monitor World
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x2000 # Size of SEC Stack for Monitor World
-
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0x4A000000
# Stack for CPU Cores in Non Secure Mode
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase|0x48000000 # Top of SEC Stack for Normal World
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize|0x20000 # Size of SEC Stack for Normal World
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x48000000
# System Memory (256MB)
gArmTokenSpaceGuid.PcdSystemMemoryBase|0x70000000
diff --git a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc
index 1852552cd..4c3cf6e69 100644
--- a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc
+++ b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc
@@ -346,19 +346,13 @@
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0x00000000
gArmPlatformTokenSpaceGuid.PcdMPCoreSupport|1
- gArmPlatformTokenSpaceGuid.PcdMPCoreMaxCores|2
# Stacks for MPCores in Secure World
- gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x4B000000 # Top of SEC Stack for Secure World
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecStackSize|0x2000 # Stack for each of the 4 CPU cores
-
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x4B000000
# Stacks for MPCores in Monitor Mode
- gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0x4A000000 # Top of SEC Stack for Monitor World
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x2000 # Stack for each of the 4 CPU cores
-
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0x4A000000
# Stacks for MPCores in Normal World
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase|0x48000000 # Top of SEC Stack for Normal World
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize|0x20000 # Stack for each of the 4 CPU cores
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x48000000
# System Memory (256MB)
gArmTokenSpaceGuid.PcdSystemMemoryBase|0x70000000
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc
index d4be10b02..74c28af89 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc
@@ -385,20 +385,14 @@
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
gArmPlatformTokenSpaceGuid.PcdMPCoreSupport|1
- gArmPlatformTokenSpaceGuid.PcdMPCoreMaxCores|4
gArmTokenSpaceGuid.PcdVFPEnabled|1
# Stacks for MPCores in Secure World
- gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x49E00000 # Top of SEC Stack for Secure World
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecStackSize|0x2000 # Stack for each of the 4 CPU cores
-
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x49E00000
# Stacks for MPCores in Monitor Mode
- gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0x49D00000 # Top of SEC Stack for Monitor World
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x2000 # Stack for each of the 4 CPU cores
-
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0x49D00000
# Stacks for MPCores in Normal World
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase|0x48000000 # Top of SEC Stack for Normal World
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize|0x00020000 # Stack for each of the 4 CPU cores
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x48000000
# System Memory (1GB)
gArmTokenSpaceGuid.PcdSystemMemoryBase|0x60000000
diff --git a/ArmPlatformPkg/Documentation/ArmPlatformPkg.txt b/ArmPlatformPkg/Documentation/ArmPlatformPkg.txt
index e45a3f066..418706fde 100644
--- a/ArmPlatformPkg/Documentation/ArmPlatformPkg.txt
+++ b/ArmPlatformPkg/Documentation/ArmPlatformPkg.txt
@@ -19,18 +19,19 @@ gArmTokenSpaceGuid.PcdNormalFdBaseAddress : Base Address of your Non-Secur
gArmTokenSpaceGuid.PcdNormalFdSize : Size in bytes of your Non-Secure/Normal World Firmware Device
# Stacks
-gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase : Top of Secure Stack for Secure World
-gArmPlatformTokenSpaceGuid.PcdCPUCoreSecStackSize : Size of the stack for each of the 4 CPU cores
-gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase : Top of Stack for Monitor World
-gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize : Size of the stack for each of the 4 CPU cores
-gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase : Top of SEC Stack for Normal World
-gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize : Size of the stack for each of the 4 CPU Cores
+gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase : Base of Secure Stack for Secure World
+gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize : Size of the stack for the Primary Core in Secure World
+gArmPlatformTokenSpaceGuid.PcdCPUCoreSecSecondaryStackSize : Size of the stack for the Secondary Cores in Secure World
+gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase : Base of Stack for Monitor World
+gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize : Size of the stack for each cores
+gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase : Base of SEC Stack for Normal World
+gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize : Size of the stack for the Primary Core
+gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize : Size of the stack for the Secondary Core
# CPU / Architectural controllers
gArmTokenSpaceGuid.PcdGicDistributorBase : Base address of the Distributor of your General Interrupt Controller
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase : Base address of the Interface of your General Interrupt Controller
gArmPlatformTokenSpaceGuid.PcdMPCoreSupport : Set to 1 when MP Core platforms
-gArmPlatformTokenSpaceGuid.PcdMPCoreMaxCores : Maximum number of CPU cores on the platform (used for instance to know how many stacks we need to configure)
# Memory Regions
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize : Size of the region reserve for PI & UEFI
diff --git a/ArmPlatformPkg/PrePeiCore/MainMPCore.c b/ArmPlatformPkg/PrePeiCore/MainMPCore.c
index 036b19206..732e751c9 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 179e1ea34..64877d1cc 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 01723a2ea..f9b85a604 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 e4eb61261..1964f18eb 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 25dae0fb9..145893505 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 be846c581..028330d03 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
diff --git a/ArmPlatformPkg/PrePi/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/ModuleEntryPoint.S
index 4d64aa7e8..b5f2ee2e5 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
+
diff --git a/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm b/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm
index 881871d34..965bb0031 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
diff --git a/ArmPlatformPkg/PrePi/PeiMPCore.inf b/ArmPlatformPkg/PrePi/PeiMPCore.inf
index c8af14d19..f141dc03b 100755
--- a/ArmPlatformPkg/PrePi/PeiMPCore.inf
+++ b/ArmPlatformPkg/PrePi/PeiMPCore.inf
@@ -70,8 +70,9 @@
gArmTokenSpaceGuid.PcdNormalFvBaseAddress
gArmTokenSpaceGuid.PcdNormalFvSize
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase
+ gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize
gArmPlatformTokenSpaceGuid.PcdHobListPtrGlobalOffset
@@ -83,7 +84,10 @@
gArmTokenSpaceGuid.PcdSystemMemorySize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
- gArmPlatformTokenSpaceGuid.PcdMPCoreMaxCores
+ gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+ gArmTokenSpaceGuid.PcdArmPrimaryCore
+
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PrePi/PeiUniCore.inf
index 5882afc13..ccf421ca6 100755
--- a/ArmPlatformPkg/PrePi/PeiUniCore.inf
+++ b/ArmPlatformPkg/PrePi/PeiUniCore.inf
@@ -68,8 +68,8 @@
gArmTokenSpaceGuid.PcdNormalFvBaseAddress
gArmTokenSpaceGuid.PcdNormalFvSize
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase
- gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize
gArmPlatformTokenSpaceGuid.PcdHobListPtrGlobalOffset
diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c
index a0198d89b..64c371c80 100755
--- a/ArmPlatformPkg/PrePi/PrePi.c
+++ b/ArmPlatformPkg/PrePi/PrePi.c
@@ -79,7 +79,6 @@ PrePiMain (
SaveAndSetDebugTimerInterrupt (TRUE);
UefiMemoryTop = UefiMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
- StacksSize = PcdGet32 (PcdCPUCoresNonSecStackSize) * PcdGet32 (PcdMPCoreMaxCores);
StacksBase = UefiMemoryTop - StacksSize;
// Check the PcdCPUCoresNonSecStackBase match with the calculated StackBase
@@ -99,6 +98,7 @@ PrePiMain (
ASSERT_EFI_ERROR (Status);
// Create the Stacks HOB (reserve the memory for all stacks)
+ StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) + (FixedPcdGet32(PcdClusterCount) * 4 * FixedPcdGet32(PcdCPUCoreSecondaryStackSize));
BuildStackHob (StacksBase, StacksSize);
// Set the Boot Mode
diff --git a/ArmPlatformPkg/Sec/Sec.inf b/ArmPlatformPkg/Sec/Sec.inf
index 7b116c7fd..d2c5083c2 100644
--- a/ArmPlatformPkg/Sec/Sec.inf
+++ b/ArmPlatformPkg/Sec/Sec.inf
@@ -59,7 +59,8 @@
gArmTokenSpaceGuid.PcdNormalFvBaseAddress
gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecSecondaryStackSize
gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase
gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize
diff --git a/ArmPlatformPkg/Sec/SecEntryPoint.S b/ArmPlatformPkg/Sec/SecEntryPoint.S
index 5d83bf1ee..7f13057f6 100644
--- a/ArmPlatformPkg/Sec/SecEntryPoint.S
+++ b/ArmPlatformPkg/Sec/SecEntryPoint.S
@@ -1,34 +1,27 @@
-#------------------------------------------------------------------------------
-#
-# ARM VE Entry point. Reset vector in FV header will brach to
-# _ModuleEntryPoint.
-#
-# Copyright (c) 2011, ARM Limited. All rights reserved.
-#
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-#------------------------------------------------------------------------------
+//
+// Copyright (c) 2011, ARM Limited. All rights reserved.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+#include <AutoGen.h>
#include <AsmMacroIoLib.h>
#include <Base.h>
#include <Library/PcdLib.h>
#include <Library/ArmPlatformLib.h>
-#include <AutoGen.h>
-#Start of Code section
.text
.align 3
-#make _ModuleEntryPoint as global
GCC_ASM_EXPORT(_ModuleEntryPoint)
-#global functions referenced by this module
GCC_ASM_IMPORT(CEntryPoint)
GCC_ASM_IMPORT(ArmPlatformSecBootAction)
GCC_ASM_IMPORT(ArmPlatformInitializeBootMemory)
@@ -42,75 +35,99 @@ GCC_ASM_IMPORT(SecVectorTable)
GCC_ASM_IMPORT(ArmIsScuEnable)
#endif
-StartupAddr: .word ASM_PFX(CEntryPoint)
-SecVectorTableAddr: .word ASM_PFX(SecVectorTable)
+StartupAddr: .word ASM_PFX(CEntryPoint)
+SecVectorTableAddr: .word ASM_PFX(SecVectorTable)
ASM_PFX(_ModuleEntryPoint):
- # First ensure all interrupts are disabled
- bl ASM_PFX(ArmDisableInterrupts)
+ // First ensure all interrupts are disabled
+ bl ASM_PFX(ArmDisableInterrupts)
- # Ensure that the MMU and caches are off
- bl ASM_PFX(ArmDisableCachesAndMmu)
+ // Ensure that the MMU and caches are off
+ bl ASM_PFX(ArmDisableCachesAndMmu)
- # Jump to Platform Specific Boot Action function
+ // Jump to Platform Specific Boot Action function
blx ASM_PFX(ArmPlatformSecBootAction)
- # Set VBAR to the start of the exception vectors in Secure Mode
+ // Set VBAR to the start of the exception vectors in Secure Mode
ldr r0, =SecVectorTable
bl ASM_PFX(ArmWriteVBar)
-_IdentifyCpu:
- # Identify CPU ID
+_IdentifyCpu:
+ // Identify CPU ID
bl ASM_PFX(ArmReadMpidr)
// Get ID of this CPU in Multicore system
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1)
and r5, r0, r1
- #get ID of this CPU in Multicore system
+ // Is it the Primary Core ?
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r1)
cmp r5, r1
- # Only the primary core initialize the memory (SMC)
+ // Only the primary core initialize the memory (SMC)
beq _InitMem
#if (FixedPcdGet32(PcdMPCoreSupport))
- # ... The secondary cores wait for SCU to be enabled
+ // ... The secondary cores wait for SCU to be enabled
_WaitForEnabledScu:
bl ASM_PFX(ArmIsScuEnable)
tst r1, #1
beq _WaitForEnabledScu
- b _SetupStack
+ b _SetupSecondaryCoreStack
#endif
_InitMem:
// Initialize Init Boot Memory
bl ASM_PFX(ArmPlatformInitializeBootMemory)
-
- # Only Primary CPU could run this line (the secondary cores have jumped from _IdentifyCpu to _SetupStack)
- mov r5, #0
-
-_SetupStack:
- # Setup Stack for the 4 CPU cores
- #Read Stack Base address from PCD
+
+ // Only Primary CPU could run this line (the secondary cores have jumped from _IdentifyCpu to _SetupStack)
+ LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r5)
+
+_SetupPrimaryCoreStack:
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r2)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r3)
+ // Calculate the Top of the Stack
+ add r2, r2, r3
+ LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), 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 SEC global variables to 0
+ mov r3, sp
+ mov r1, #0x0
+_InitGlobals:
+ str r1, [r3], #4
+ cmp r3, r2
+ blt _InitGlobals
+
+ b _PrepareArguments
+
+_SetupSecondaryCoreStack:
+ // Get the Core Position (ClusterId * 4) + CoreId
+ GetCorePositionInStack(r0, r5, 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 r0, r0, #1
+
+ // Get the base of the stack for the secondary cores
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
+ add r1, r1, r2
- #read Stack size from PCD
- LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecStackSize), r2)
+ // StackOffset = CorePos * StackSize
+ mul r0, r0, r2
+ // SP = StackBase + StackOffset
+ add sp, r1, r0
- #calcuate Stack Pointer reg value using Stack size and CPU ID.
- mov r3,r5 @ r3 = core_id
- mul r3,r3,r2 @ r3 = core_id * stack_size = offset from the stack base
- add r3,r3,r1 @ r3 ldr= stack_base + offset
- mov sp, r3
-
- # move sec startup address into a data register
- # ensure we're jumping to FV version of the code (not boot remapped alias)
+
+_PrepareArguments:
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
ldr r3, StartupAddr
- # Move the CoreId in r0 to be the first argument of the SEC Entry Point
+ // Jump to SEC C code
+ // r0 = mp_id
mov r0, r5
-
- # jump to SEC C code
- # r0 = core_id
- blx r3
-
-
+ blx r3
+
+_NeverReturn:
+ b _NeverReturn
diff --git a/ArmPlatformPkg/Sec/SecEntryPoint.asm b/ArmPlatformPkg/Sec/SecEntryPoint.asm
index e85d6ce60..c39b80a85 100644
--- a/ArmPlatformPkg/Sec/SecEntryPoint.asm
+++ b/ArmPlatformPkg/Sec/SecEntryPoint.asm
@@ -71,32 +71,57 @@ _WaitForEnabledScu
bl ArmIsScuEnable
tst r1, #1
beq _WaitForEnabledScu
- b _SetupStack
+ b _SetupSecondaryCoreStack
#endif
_InitMem
// Initialize Init Boot Memory
bl ArmPlatformInitializeBootMemory
-
+
// Only Primary CPU could run this line (the secondary cores have jumped from _IdentifyCpu to _SetupStack)
- mov r5, #0
+ LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r5)
+
+_SetupPrimaryCoreStack
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r2)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r3)
+ // Calculate the Top of the Stack
+ add r2, r2, r3
+ LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), 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 SEC global variables to 0
+ mov r3, sp
+ mov r1, #0x0
+_InitGlobals
+ str r1, [r3], #4
+ cmp r3, r2
+ blt _InitGlobals
-_SetupStack
- // Setup Stack for the 4 CPU cores
- //Read Stack Base address from PCD
+ b _PrepareArguments
+
+_SetupSecondaryCoreStack
+ // Get the Core Position (ClusterId * 4) + CoreId
+ GetCorePositionInStack(r0, r5, 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 r0, r0, #1
+
+ // Get the base of the stack for the secondary cores
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), r2)
+ add r1, r1, r2
- // Read Stack size from PCD
- LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecStackSize), r2)
+ // StackOffset = CorePos * StackSize
+ mul r0, r0, r2
+ // SP = StackBase + StackOffset
+ add sp, r1, r0
- // Calcuate Stack Pointer reg value using Stack size and CPU ID.
- mov r3,r5 // 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
- mov sp, r3
-
+
+_PrepareArguments
// Move sec startup address into a data register
- // ensure we're jumping to FV version of the code (not boot remapped alias)
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
ldr r3, StartupAddr
// Jump to SEC C code
@@ -104,4 +129,6 @@ _SetupStack
mov r0, r5
blx r3
+_NeverReturn
+ b _NeverReturn
END