ArmPlatformPkg: Updated the stack setup to have the same geometry between the Secure and Normal World

Having a similar setup reduces the error during the MPCore stack setup.
The stack setup is described on this wikipage:
https://sourceforge.net/apps/mediawiki/tianocore/index.php?title=ArmPlatformPkg/Stack



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13058 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
oliviermartin 2012-02-28 17:23:53 +00:00
parent 2569b06868
commit 1377db63ff
8 changed files with 169 additions and 186 deletions

View File

@ -2,6 +2,7 @@
Macros to work around lack of Apple support for LDR register, =expr
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@ -132,7 +133,16 @@
and Tmp, GlobalSize, #7 ; \
rsbne Tmp, Tmp, #8 ; \
add GlobalSize, GlobalSize, Tmp ; \
sub sp, StackTop, GlobalSize
sub sp, StackTop, GlobalSize ; \
; \
mov Tmp, sp ; \
mov GlobalSize, #0x0 ; \
_SetPrimaryStackInitGlobals: ; \
cmp Tmp, StackTop ; \
beq _SetPrimaryStackEnd ; \
str GlobalSize, [Tmp], #4 ; \
b _SetPrimaryStackInitGlobals ; \
_SetPrimaryStackEnd:
#elif defined (__GNUC__)
@ -192,7 +202,16 @@
and Tmp, GlobalSize, #7 ; \
rsbne Tmp, Tmp, #8 ; \
add GlobalSize, GlobalSize, Tmp ; \
sub sp, StackTop, GlobalSize
sub sp, StackTop, GlobalSize ; \
; \
mov Tmp, sp ; \
mov GlobalSize, #0x0 ; \
_SetPrimaryStackInitGlobals: ; \
cmp Tmp, StackTop ; \
beq _SetPrimaryStackEnd ; \
str GlobalSize, [Tmp], #4 ; \
b _SetPrimaryStackInitGlobals ; \
_SetPrimaryStackEnd:
#else

View File

@ -3,6 +3,8 @@
; Macros to work around lack of Apple support for LDR register, =expr
;
; Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
; Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
;
; 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
@ -86,12 +88,24 @@
MEND
; The reserved place must be 8-bytes aligned for pushing 64-bit variable on the stack
; Note: Global Size will be modified
MACRO
SetPrimaryStack $StackTop, $GlobalSize, $Tmp
and $Tmp, $GlobalSize, #7
rsbne $Tmp, $Tmp, #8
add $GlobalSize, $GlobalSize, $Tmp
sub sp, $StackTop, $GlobalSize
; Set all the global variables to 0
mov $Tmp, sp
mov $GlobalSize, #0x0
_SetPrimaryStackInitGlobals
cmp $Tmp, $StackTop
beq _SetPrimaryStackEnd
str $GlobalSize, [$Tmp], #4
b _SetPrimaryStackInitGlobals
_SetPrimaryStackEnd
MEND
END

View File

@ -30,50 +30,31 @@ ASM_PFX(_ModuleEntryPoint):
bl ASM_PFX(ArmReadMpidr)
// Get ID of this CPU in Multicore system
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1)
and r0, r0, r1
// Calculate the top of the primary stack
and r5, r0, r1
// Get the top of the primary stacks (and the base of the secondary stacks)
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresStackBase), r1)
LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2)
add r2, r2, r1
add r1, r1, r2
// Is it the Primary Core ?
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r1)
cmp r0, r1
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r3)
cmp r5, r3
beq _SetupPrimaryCoreStack
_SetupSecondaryCoreStack:
// r2 = Top of the primary stack = Base of the Secondary Stacks
// r1 contains the base of the secondary stacks
// Get the position of the cores (ClusterId * 4) + CoreId
GetCorePositionInStack(r3, r0, r1)
// Get the Core Position (ClusterId * 4) + CoreId
GetCorePositionInStack(r0, r5, r2)
// 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
add r0, r0, #1
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), r1)
// StackOffset = CorePos * StackSize
mul r3, r3, r1
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), r2)
mul r0, r0, r2
// 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:
cmp r3, r2
beq _PrepareArguments
str r1, [r3], #4
b _InitGlobals
add sp, r1, r0
_PrepareArguments:
// The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector
@ -81,14 +62,24 @@ _PrepareArguments:
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)
ldr r2, StartupAddr
// jump to PrePeiCore C code
// 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
// Jump to PrePeiCore C code
// r0 = mp_id
// r1 = pei_core_address
blx r2
mov r0, r5
blx r3
_SetupPrimaryCoreStack:
// r1 contains the top of the primary stack
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)
b _PrepareArguments
_NeverReturn:
b _NeverReturn

View File

@ -32,50 +32,31 @@ _ModuleEntryPoint
bl ArmReadMpidr
// Get ID of this CPU in Multicore system
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1)
and r0, r0, r1
// Calculate the top of the primary stack
and r5, r0, r1
// Get the top of the primary stacks (and the base of the secondary stacks)
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresStackBase), r1)
LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2)
add r2, r2, r1
add r1, r1, r2
// Is it the Primary Core ?
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r1)
cmp r0, r1
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r3)
cmp r5, r3
beq _SetupPrimaryCoreStack
_SetupSecondaryCoreStack
// r2 = Top of the primary stack = Base of the Secondary Stacks
// r1 contains the base of the secondary stacks
// Get the position of the cores (ClusterId * 4) + CoreId
GetCorePositionInStack(r3, r0, r1)
// Get the Core Position (ClusterId * 4) + CoreId
GetCorePositionInStack(r0, r5, r2)
// 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
add r0, r0, #1
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), r1)
// StackOffset = CorePos * StackSize
mul r3, r3, r1
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), r2)
mul r0, r0, r2
// 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
cmp r3, r2
beq _PrepareArguments
str r1, [r3], #4
b _InitGlobals
add sp, r1, r0
_PrepareArguments
// The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector
@ -83,14 +64,24 @@ _PrepareArguments
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)
ldr r2, StartupAddr
// jump to PrePeiCore C code
// 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
// Jump to PrePeiCore C code
// r0 = mp_id
// r1 = pei_core_address
blx r2
mov r0, r5
blx r3
_SetupPrimaryCoreStack
// r1 contains the top of the primary stack
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)
b _PrepareArguments
_NeverReturn
b _NeverReturn

View File

@ -103,6 +103,7 @@ _GetStackBase:
beq _SetupUnicoreStack
_GetStackBaseMpCore:
// r1 = The top of the Mpcore Stacks
// Stack for the primary core = PrimaryCoreStack
LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2)
sub r7, r1, r2
@ -113,8 +114,12 @@ _GetStackBaseMpCore:
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
// The base of the secondary Stacks = Top of Primary stack
LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2)
add r1, r7, r2
// r7 = The base of the MpCore Stacks
// r1 = The base of the secondary Stacks = Top of the Primary stack
// Is it the Primary Core ?
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r4)
@ -122,7 +127,7 @@ _GetStackBaseMpCore:
beq _SetupPrimaryCoreStack
_SetupSecondaryCoreStack:
// Base of the stack for the secondary cores is in r7
// r1 = The base of the secondary Stacks
// Get the position of the cores (ClusterId * 4) + CoreId
GetCorePositionInStack(r0, r5, r4)
@ -130,28 +135,28 @@ _SetupSecondaryCoreStack:
add r0, r0, #1
// Get the offset for the Secondary Stack
mul r0, r0, r3
add sp, r7, r0
add sp, r1, r0
bne _PrepareArguments
_SetupPrimaryCoreStack:
// The top of the Mpcore Stacks is in r1
// 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)
_SetGlobals:
// Set all the PrePi global variables to 0
mov r3, sp
mov r2, #0x0
_InitGlobals:
cmp r3, r1
beq _PrepareArguments
str r2, [r3], #4
b _InitGlobals
_PrepareArguments:
mov r0, r5
mov r1, r6
@ -172,17 +177,3 @@ _PrepareArguments:
_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

View File

@ -104,6 +104,7 @@ _GetStackBase
beq _SetupUnicoreStack
_GetStackBaseMpCore
// r1 = The top of the Mpcore Stacks
// Stack for the primary core = PrimaryCoreStack
LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2)
sub r7, r1, r2
@ -114,8 +115,12 @@ _GetStackBaseMpCore
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
// The base of the secondary Stacks = Top of Primary stack
LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), r2)
add r1, r7, r2
// r7 = The base of the MpCore Stacks
// r1 = The base of the secondary Stacks = Top of the Primary stack
// Is it the Primary Core ?
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r4)
@ -123,7 +128,7 @@ _GetStackBaseMpCore
beq _SetupPrimaryCoreStack
_SetupSecondaryCoreStack
// Base of the stack for the secondary cores is in r7
// r1 = The base of the secondary Stacks
// Get the position of the cores (ClusterId * 4) + CoreId
GetCorePositionInStack(r0, r5, r4)
@ -131,28 +136,28 @@ _SetupSecondaryCoreStack
add r0, r0, #1
// Get the offset for the Secondary Stack
mul r0, r0, r3
add sp, r7, r0
add sp, r1, r0
bne _PrepareArguments
_SetupPrimaryCoreStack
// The top of the Mpcore Stacks is in r1
// 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)
_SetGlobals
// Set all the PrePi global variables to 0
mov r3, sp
mov r2, #0x0
_InitGlobals
cmp r3, r1
beq _PrepareArguments
str r2, [r3], #4
b _InitGlobals
_PrepareArguments
mov r0, r5
mov r1, r6
@ -173,18 +178,4 @@ _PrepareArguments
_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

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2011, ARM Limited. All rights reserved.
// Copyright (c) 2011-2012, 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
@ -53,8 +53,8 @@ _IdentifyCpu:
and r5, r0, r1
// Is it the Primary Core ?
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r1)
cmp r5, r1
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r3)
cmp r5, r3
// Only the primary core initialize the memory (SMC)
beq _InitMem
@ -72,42 +72,35 @@ _InitMem:
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)
// Get the top of the primary stacks (and the base of the secondary stacks)
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
add r1, r1, r2
LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), r2)
// 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:
cmp r3, r2
beq _PrepareArguments
str r1, [r3], #4
b _InitGlobals
SetPrimaryStack (r1, r2, r3)
b _PrepareArguments
_SetupSecondaryCoreStack:
// Get the top of the primary stacks (and the base of the secondary stacks)
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
add r1, r1, r2
// Get the Core Position (ClusterId * 4) + CoreId
GetCorePositionInStack(r0, r5, r1)
GetCorePositionInStack(r0, r5, r2)
// 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
// StackOffset = CorePos * StackSize
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), r2)
mul r0, r0, r2
// SP = StackBase + StackOffset
add sp, r1, r0
_PrepareArguments:
// Move sec startup address into a data register
// Ensure we're jumping to FV version of the code (not boot remapped alias)

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2011, ARM Limited. All rights reserved.
// Copyright (c) 2011-2012, 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
@ -55,8 +55,8 @@ _IdentifyCpu
and r5, r0, r1
// Is it the Primary Core ?
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r1)
cmp r5, r1
LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r3)
cmp r5, r3
// Only the primary core initialize the memory (SMC)
beq _InitMem
@ -74,42 +74,35 @@ _InitMem
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)
// Get the top of the primary stacks (and the base of the secondary stacks)
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
add r1, r1, r2
LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), r2)
// 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
cmp r3, r2
beq _PrepareArguments
str r1, [r3], #4
b _InitGlobals
SetPrimaryStack (r1, r2, r3)
b _PrepareArguments
_SetupSecondaryCoreStack
// Get the top of the primary stacks (and the base of the secondary stacks)
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
add r1, r1, r2
// Get the Core Position (ClusterId * 4) + CoreId
GetCorePositionInStack(r0, r5, r1)
GetCorePositionInStack(r0, r5, r2)
// 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
// StackOffset = CorePos * StackSize
LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), r2)
mul r0, r0, r2
// SP = StackBase + StackOffset
add sp, r1, r0
_PrepareArguments
// Move sec startup address into a data register
// Ensure we're jumping to FV version of the code (not boot remapped alias)