summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarry Liebel <Harry.Liebel@arm.com>2013-07-18 19:06:52 +0000
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2013-07-18 19:06:52 +0000
commit1bc8326695a2181cb5934c3dfb01b0a26c4096a0 (patch)
tree759dbcb62f7e0222f5962b9228a72a6d170b215b
parent93deac7e25a9adc43ea314e829ec50502ce5c39e (diff)
ArmPlatformPkg: Added Aarch64 support
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Harry Liebel <Harry.Liebel@arm.com> Signed-off-by: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14489 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc12
-rw-r--r--ArmPlatformPkg/ArmPlatformPkg.dec20
-rw-r--r--ArmPlatformPkg/ArmPlatformPkg.dsc22
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S65
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf3
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNullSec.inf3
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformSecLibNull/AArch64/ArmPlatformLibNullBoot.S61
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf4
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S129
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S36
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf3
-rw-r--r--ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/AArch64/ArmTrustedMonitorLibNull.c24
-rw-r--r--ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/Arm/ArmTrustedMonitorLibNull.c (renamed from ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.c)0
-rw-r--r--ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf7
-rw-r--r--ArmPlatformPkg/Library/EblCmdLib/AArch64/EblCmdMmu.c33
-rw-r--r--ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf3
-rw-r--r--ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c52
-rw-r--r--ArmPlatformPkg/PrePeiCore/AArch64/Exception.S84
-rw-r--r--ArmPlatformPkg/PrePeiCore/AArch64/Helper.S51
-rw-r--r--ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S114
-rw-r--r--ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S43
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCore.c3
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf7
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf9
-rw-r--r--ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c33
-rw-r--r--ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S148
-rw-r--r--ArmPlatformPkg/PrePi/Arm/ArchPrePi.c29
-rwxr-xr-xArmPlatformPkg/PrePi/PeiMPCore.inf5
-rwxr-xr-xArmPlatformPkg/PrePi/PeiUniCore.inf5
-rwxr-xr-xArmPlatformPkg/PrePi/PrePi.c8
-rw-r--r--ArmPlatformPkg/PrePi/PrePi.h6
-rw-r--r--ArmPlatformPkg/Sec/AArch64/Helper.S156
-rw-r--r--ArmPlatformPkg/Sec/AArch64/SecEntryPoint.S146
-rw-r--r--ArmPlatformPkg/Sec/Sec.inf8
34 files changed, 1288 insertions, 44 deletions
diff --git a/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc b/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc
index 126fb3648..b8b439555 100644
--- a/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc
+++ b/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc
@@ -21,14 +21,12 @@
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME)
- SUPPORTED_ARCHITECTURES = ARM
+ SUPPORTED_ARCHITECTURES = ARM|AARCH64
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
FLASH_DEFINITION = ArmPlatformPkg/ArmPlatformPkg-2ndstage.fdf
[LibraryClasses.common]
- ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
- ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
!if $(TARGET) == RELEASE
@@ -113,6 +111,14 @@
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+[LibraryClasses.ARM]
+ ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
+ ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
+
+[LibraryClasses.AARCH64]
+ ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
+ ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
+
[LibraryClasses.common.SEC]
ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf
diff --git a/ArmPlatformPkg/ArmPlatformPkg.dec b/ArmPlatformPkg/ArmPlatformPkg.dec
index 3e2900ba3..3358225ae 100644
--- a/ArmPlatformPkg/ArmPlatformPkg.dec
+++ b/ArmPlatformPkg/ArmPlatformPkg.dec
@@ -1,6 +1,6 @@
#/** @file
#
-# Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+# Copyright (c) 2011-2013, 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
@@ -63,10 +63,6 @@
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|0x1000|UINT32|0x00000008
-
# Stack for CPU Cores in Non Secure Mode
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0|UINT32|0x00000009
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x10000|UINT32|0x00000037
@@ -142,4 +138,16 @@
gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L""|VOID*|0x0000001B
gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L""|VOID*|0x0000001C
-
+
+[PcdsFixedAtBuild.ARM]
+ # Stack for CPU Cores in Secure Monitor Mode
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0|UINT32|0x00000007
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x1000|UINT32|0x00000008
+
+[PcdsFixedAtBuild.AARCH64]
+ # The Secure World is only running in EL3. Only one set of stacks is needed for AArch64.
+ # The Secure stacks are described by PcdCPUCoresSecStackBase, PcdCPUCoreSecPrimaryStackSize
+ # and PcdCPUCoreSecSecondaryStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0|UINT32|0x00000007
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x0|UINT32|0x00000008
+
diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc
index 495896c88..c353e6f90 100644
--- a/ArmPlatformPkg/ArmPlatformPkg.dsc
+++ b/ArmPlatformPkg/ArmPlatformPkg.dsc
@@ -21,14 +21,12 @@
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME)
- SUPPORTED_ARCHITECTURES = ARM
+ SUPPORTED_ARCHITECTURES = ARM|AARCH64
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
FLASH_DEFINITION = ArmPlatformPkg/ArmPlatformPkg.fdf
[LibraryClasses.common]
- ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
- ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
!if $(TARGET) == RELEASE
@@ -112,8 +110,15 @@
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+[LibraryClasses.ARM]
+ ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
+ ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
+
+[LibraryClasses.AARCH64]
+ ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
+ ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
+
[LibraryClasses.common.SEC]
- ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
ArmPlatformSecLib|ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNullSec.inf
ArmTrustedMonitorLib|ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf
@@ -124,6 +129,12 @@
DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
+[LibraryClasses.ARM.SEC]
+ ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
+
+[LibraryClasses.AARCH64.SEC]
+ ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
+
[LibraryClasses.common.PEI_CORE]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
@@ -200,6 +211,9 @@
#
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+[LibraryClasses.AARCH64]
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
[BuildOptions]
XCODE:*_*_ARM_PLATFORM_FLAGS == -arch armv7
diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S b/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S
new file mode 100644
index 000000000..8c099b469
--- /dev/null
+++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S
@@ -0,0 +1,65 @@
+//
+// Copyright (c) 2012-2013, 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 <AsmMacroIoLibV8.h>
+#include <Library/ArmLib.h>
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
+GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
+GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
+GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
+
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
+
+ASM_PFX(ArmPlatformPeiBootAction):
+ ret
+
+//UINTN
+//ArmPlatformGetCorePosition (
+// IN UINTN MpId
+// );
+// With this function: CorePos = (ClusterId * 4) + CoreId
+ASM_PFX(ArmPlatformGetCorePosition):
+ and x1, x0, #ARM_CORE_MASK
+ and x0, x0, #ARM_CLUSTER_MASK
+ add x0, x1, x0, LSR #6
+ ret
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+// VOID
+// );
+ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
+ LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0)
+ ldrh w0, [x0]
+ ret
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+// IN UINTN MpId
+// );
+ASM_PFX(ArmPlatformIsPrimaryCore):
+ LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask, x1)
+ ldrh w1, [x1]
+ and x0, x0, x1
+ LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x1)
+ ldrh w1, [x1]
+ cmp w0, w1
+ mov x0, #1
+ mov x1, #0
+ csel x0, x0, x1, eq
+ ret
diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
index a6c2e8f48..18a506af1 100644
--- a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
+++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
@@ -37,6 +37,9 @@
Arm/ArmPlatformHelper.S | GCC
Arm/ArmPlatformHelper.asm | RVCT
+[Sources.AArch64]
+ AArch64/ArmPlatformHelper.S | GCC
+
[FixedPcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNullSec.inf b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNullSec.inf
index 128b0b59e..bdd0a4833 100644
--- a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNullSec.inf
+++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNullSec.inf
@@ -36,6 +36,9 @@
Arm/ArmPlatformHelper.S | GCC
Arm/ArmPlatformHelper.asm | RVCT
+[Sources.AArch64]
+ AArch64/ArmPlatformHelper.S | GCC
+
[FixedPcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
diff --git a/ArmPlatformPkg/Library/ArmPlatformSecLibNull/AArch64/ArmPlatformLibNullBoot.S b/ArmPlatformPkg/Library/ArmPlatformSecLibNull/AArch64/ArmPlatformLibNullBoot.S
new file mode 100644
index 000000000..0bfb947d1
--- /dev/null
+++ b/ArmPlatformPkg/Library/ArmPlatformSecLibNull/AArch64/ArmPlatformLibNullBoot.S
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 2011 - 2013, 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 <Base.h>
+#include <AutoGen.h>
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(ArmPlatformSecBootAction)
+GCC_ASM_EXPORT(ArmPlatformSecBootMemoryInit)
+GCC_ASM_EXPORT(ArmSecMpCoreSecondariesWrite)
+GCC_ASM_EXPORT(ArmSecMpCoreSecondariesRead)
+
+/**
+ Call at the beginning of the platform boot up
+
+ This function allows the firmware platform to do extra actions at the early
+ stage of the platform power up.
+
+ Note: This function must be implemented in assembler as there is no stack set up yet
+
+**/
+ASM_PFX(ArmPlatformSecBootAction):
+ ret
+
+/**
+ Initialize the memory where the initial stacks will reside
+
+ This memory can contain the initial stacks (Secure and Secure Monitor stacks).
+ In some platform, this region is already initialized and the implementation of this function can
+ do nothing. This memory can also represent the Secure RAM.
+ This function is called before the satck has been set up. Its implementation must ensure the stack
+ pointer is not used (probably required to use assembly language)
+
+**/
+ASM_PFX(ArmPlatformSecBootMemoryInit):
+ // The SMC does not need to be initialized for RTSM
+ ret
+
+/* Write the flag register used to start Secondary cores */
+ASM_PFX(ArmSecMpCoreSecondariesWrite):
+ // Write to the CPU Mailbox
+ ret
+
+
+/* Read the flag register used to start Secondary cores */
+ASM_PFX(ArmSecMpCoreSecondariesRead):
+ // Return the value from the CPU Mailbox
+ mov x0, #0
+ ret
diff --git a/ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf b/ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf
index f39954757..8fe933af2 100644
--- a/ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf
+++ b/ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf
@@ -36,6 +36,10 @@
Arm/ArmPlatformLibNullBoot.asm | RVCT
Arm/ArmPlatformLibNullBoot.S | GCC
+[Sources.AARCH64]
+ AArch64/ArmPlatformLibNullBoot.S | GCC
+
+
[FixedPcd]
gArmTokenSpaceGuid.PcdFvBaseAddress
diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S b/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S
new file mode 100644
index 000000000..337af9c6a
--- /dev/null
+++ b/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S
@@ -0,0 +1,129 @@
+//
+// Copyright (c) 2012-2013, 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 <AsmMacroIoLib.h>
+#include <Base.h>
+#include <AutoGen.h>
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(ArmPlatformStackSet)
+GCC_ASM_EXPORT(ArmPlatformStackSetPrimary)
+GCC_ASM_EXPORT(ArmPlatformStackSetSecondary)
+
+GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_IMPORT(ArmPlatformGetCorePosition)
+GCC_ASM_IMPORT(ArmPlatformGetPrimaryCoreMpId)
+
+GCC_ASM_IMPORT(gPcd_FixedAtBuild_PcdCoreCount)
+
+//VOID
+//ArmPlatformStackSet (
+// IN UINTN StackBase,
+// IN UINTN MpId,
+// IN UINTN PrimaryStackSize,
+// IN UINTN SecondaryStackSize
+// );
+ASM_PFX(ArmPlatformStackSet):
+ // Save parameters
+ mov x6, x3
+ mov x5, x2
+ mov x4, x1
+ mov x3, x0
+
+ // Save the Link register
+ mov x7, x30
+
+ // Identify Stack
+ mov x0, x1
+ bl ASM_PFX(ArmPlatformIsPrimaryCore)
+ cmp x0, #1
+
+ // Restore parameters
+ mov x0, x3
+ mov x1, x4
+ mov x2, x5
+ mov x3, x6
+
+ // Restore the Link register
+ mov x30, x7
+
+ // Should be ASM_PFX(ArmPlatformStackSetPrimary) but generate linker error 'unsupported ELF EM_AARCH64'
+ b.eq ArmPlatformStackSetPrimaryL
+ // Should be ASM_PFX(ArmPlatformStackSetSecondary) but generate linker error 'unsupported ELF EM_AARCH64'
+ b.ne ArmPlatformStackSetSecondaryL
+
+//VOID
+//ArmPlatformStackSetPrimary (
+// IN UINTN StackBase,
+// IN UINTN MpId,
+// IN UINTN PrimaryStackSize,
+// IN UINTN SecondaryStackSize
+// );
+ArmPlatformStackSetPrimaryL:
+ASM_PFX(ArmPlatformStackSetPrimary):
+ // Save the Link register
+ mov x4, x30
+
+ // Add stack of primary stack to StackBase
+ add x0, x0, x2
+
+ // Compute SecondaryCoresCount * SecondaryCoreStackSize
+ LoadConstantToReg (_gPcd_FixedAtBuild_PcdCoreCount, x1)
+ ldr w1, [x1]
+ sub x1, x1, #1
+ mul x3, x3, x1
+
+ // Set Primary Stack ((StackBase + PrimaryStackSize) + (SecondaryCoresCount * SecondaryCoreStackSize))
+ add sp, x0, x3
+
+ br x4
+
+//VOID
+//ArmPlatformStackSetSecondary (
+// IN UINTN StackBase,
+// IN UINTN MpId,
+// IN UINTN PrimaryStackSize,
+// IN UINTN SecondaryStackSize
+// );
+ArmPlatformStackSetSecondaryL:
+ASM_PFX(ArmPlatformStackSetSecondary):
+ // Save the Link register
+ mov x4, x30
+ mov sp, x0
+
+ // Get Core Position
+ mov x0, x1
+ bl ASM_PFX(ArmPlatformGetCorePosition)
+ mov x5, x0
+
+ // Get Primary Core Position
+ bl ASM_PFX(ArmPlatformGetPrimaryCoreMpId)
+ bl ASM_PFX(ArmPlatformGetCorePosition)
+
+ // Get Secondary Core Position. We should get consecutive secondary stack number from 1...(CoreCount-1)
+ cmp x5, x0
+ b.ls 1f
+ // Decrement the position if after the primary core
+ sub x5, x5, #1
+1:
+ add x5, x5, #1
+
+ // Compute top of the secondary stack
+ mul x3, x3, x5
+
+ // Set stack
+ add sp, sp, x3
+
+ br x4
diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S b/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S
index 94660c97f..34fab31dd 100644
--- a/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S
+++ b/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2012, ARM Limited. All rights reserved.
+// Copyright (c) 2012-2013, 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
@@ -38,12 +38,12 @@ ASM_PFX(ArmPlatformStackSet):
// Identify Stack
// Mask for ClusterId|CoreId
LoadConstantToReg (0xFFFF, r4)
- and r1, r1, r4
+ and r1, r1, r4
// Is it the Primary Core ?
LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r4)
- ldr r4, [r4]
+ ldr r4, [r4]
cmp r1, r4
- beq ASM_PFX(ArmPlatformStackSetPrimary)
+ beq ASM_PFX(ArmPlatformStackSetPrimary)
bne ASM_PFX(ArmPlatformStackSetSecondary)
//VOID
@@ -54,19 +54,19 @@ ASM_PFX(ArmPlatformStackSet):
// IN UINTN SecondaryStackSize
// );
ASM_PFX(ArmPlatformStackSetPrimary):
- mov r4, lr
+ mov r4, lr
// Add stack of primary stack to StackBase
- add r0, r0, r2
+ add r0, r0, r2
// Compute SecondaryCoresCount * SecondaryCoreStackSize
LoadConstantToReg (_gPcd_FixedAtBuild_PcdCoreCount, r1)
- ldr r1, [r1]
- sub r1, #1
- mul r3, r3, r1
+ ldr r1, [r1]
+ sub r1, #1
+ mul r3, r3, r1
// Set Primary Stack ((StackBase + PrimaryStackSize) + (SecondaryCoresCount * SecondaryCoreStackSize))
- add sp, r0, r3
+ add sp, r0, r3
bx r4
@@ -78,29 +78,29 @@ ASM_PFX(ArmPlatformStackSetPrimary):
// IN UINTN SecondaryStackSize
// );
ASM_PFX(ArmPlatformStackSetSecondary):
- mov r4, lr
+ mov r4, lr
mov sp, r0
// Get Core Position
- mov r0, r1
+ mov r0, r1
bl ASM_PFX(ArmPlatformGetCorePosition)
- mov r5, r0
+ mov r5, r0
// Get Primary Core Position
LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0)
- ldr r0, [r0]
+ ldr r0, [r0]
bl ASM_PFX(ArmPlatformGetCorePosition)
// Get Secondary Core Position. We should get consecutive secondary stack number from 1...(CoreCount-1)
- cmp r5, r0
+ cmp r5, r0
subhi r5, r5, #1
- add r5, r5, #1
+ add r5, r5, #1
// Compute top of the secondary stack
- mul r3, r3, r5
+ mul r3, r3, r5
// Set stack
- add sp, sp, r3
+ add sp, sp, r3
bx r4
diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf b/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
index e48a65801..700bc89ea 100644
--- a/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
+++ b/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
@@ -30,6 +30,9 @@
Arm/ArmPlatformStackLib.asm | RVCT
Arm/ArmPlatformStackLib.S | GCC
+[Sources.AARCH64]
+ AArch64/ArmPlatformStackLib.S | GCC
+
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/AArch64/ArmTrustedMonitorLibNull.c b/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/AArch64/ArmTrustedMonitorLibNull.c
new file mode 100644
index 000000000..72c62d7f1
--- /dev/null
+++ b/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/AArch64/ArmTrustedMonitorLibNull.c
@@ -0,0 +1,24 @@
+/** @file
+* Main file supporting the Monitor World on ARM PLatforms
+*
+* Copyright (c) 2012-2013, 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.
+*
+**/
+
+VOID
+ArmSecureMonitorWorldInitialize (
+ VOID
+ )
+{
+ // Do not touch the EL3 Exception Vector Table Register.
+ // The default default DebugAgentLib could have already set its own vector
+ // into EL3 to catch abort exceptions.
+}
diff --git a/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.c b/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/Arm/ArmTrustedMonitorLibNull.c
index 1f950d78f..1f950d78f 100644
--- a/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.c
+++ b/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/Arm/ArmTrustedMonitorLibNull.c
diff --git a/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf b/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf
index 2a9c54bab..da867e1fe 100644
--- a/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf
+++ b/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf
@@ -19,13 +19,14 @@
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmTrustedMonitorLib
-[Sources.common]
- ArmTrustedMonitorLibNull.c
-
[Sources.ARM]
+ Arm/ArmTrustedMonitorLibNull.c
Arm/MonitorTable.asm | RVCT
Arm/MonitorTable.S | GCC
+[Sources.AARCH64]
+ AArch64/ArmTrustedMonitorLibNull.c
+
[Packages]
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
diff --git a/ArmPlatformPkg/Library/EblCmdLib/AArch64/EblCmdMmu.c b/ArmPlatformPkg/Library/EblCmdLib/AArch64/EblCmdMmu.c
new file mode 100644
index 000000000..169267576
--- /dev/null
+++ b/ArmPlatformPkg/Library/EblCmdLib/AArch64/EblCmdMmu.c
@@ -0,0 +1,33 @@
+/** @file
+*
+* Copyright (c) 2011 - 2013, 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 <PiDxe.h>
+#include <Library/UefiLib.h>
+#include <Library/ArmLib.h>
+#include <Chipset/AArch64.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/EblCmdLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EblDumpMmu (
+ IN UINTN Argc,
+ IN CHAR8 **Argv
+ )
+{
+ AsciiPrint ("\nNot supported on this platform.\n");
+
+ return EFI_SUCCESS;
+}
diff --git a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
index 33508c26e..4de0d9d9d 100644
--- a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
+++ b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
@@ -34,6 +34,9 @@
[Sources.ARM]
Arm/EblCmdMmu.c
+[Sources.AARCH64]
+ AArch64/EblCmdMmu.c
+
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c b/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c
new file mode 100644
index 000000000..e1842f2a0
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c
@@ -0,0 +1,52 @@
+/** @file
+* Main file supporting the transition to PEI Core in Normal World for Versatile Express
+*
+* Copyright (c) 2012-2013, 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 <Library/PrintLib.h>
+#include <Library/SerialPortLib.h>
+
+#include "PrePeiCore.h"
+
+VOID
+PeiCommonExceptionEntry (
+ IN UINT32 Entry,
+ IN UINTN LR
+ )
+{
+ CHAR8 Buffer[100];
+ UINTN CharCount;
+
+ switch (Entry) {
+ case EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS:
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Synchronous Exception at 0x%X\n\r", LR);
+ break;
+ case EXCEPT_AARCH64_IRQ:
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"IRQ Exception at 0x%X\n\r", LR);
+ break;
+ case EXCEPT_AARCH64_FIQ:
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"FIQ Exception at 0x%X\n\r", LR);
+ break;
+ case EXCEPT_AARCH64_SERROR:
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"SError/Abort Exception at 0x%X\n\r", LR);
+ break;
+ default:
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Unknown Exception at 0x%X\n\r", LR);
+ break;
+ }
+
+ SerialPortWrite ((UINT8 *) Buffer, CharCount);
+
+ while(1);
+}
+
diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S b/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S
new file mode 100644
index 000000000..9ca422b2f
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S
@@ -0,0 +1,84 @@
+#
+# Copyright (c) 2011-2013, 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 <AsmMacroIoLibV8.h>
+#include <Base.h>
+#include <AutoGen.h>
+
+.text
+.align 11
+
+ASM_GLOBAL ASM_PFX(PeiVectorTable)
+
+//============================================================
+//Default Exception Handlers
+//============================================================
+
+ASM_PFX(PeiVectorTable):
+
+
+#define TO_HANDLER \
+ EL1_OR_EL2(x1) \
+1: mrs x1, elr_el1 /* EL1 Exception Link Register */ ;\
+ b 3f ;\
+2: mrs x1, elr_el2 /* EL2 Exception Link Register */ ;\
+3: bl ASM_PFX(PeiCommonExceptionEntry) ;
+
+
+//
+// Default Exception handlers: There is no plan to return from any of these exceptions.
+// No context saving at all.
+//
+
+.align 7
+_DefaultSyncExceptHandler_t:
+ mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS
+ TO_HANDLER
+
+.align 7
+_DefaultIrq_t:
+ mov x0, #EXCEPT_AARCH64_IRQ
+ TO_HANDLER
+
+.align 7
+_DefaultFiq_t:
+ mov x0, #EXCEPT_AARCH64_FIQ
+ TO_HANDLER
+
+.align 7
+_DefaultSError_t:
+ mov x0, #EXCEPT_AARCH64_SERROR
+ TO_HANDLER
+
+.align 7
+_DefaultSyncExceptHandler_h:
+ mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS
+ TO_HANDLER
+
+.align 7
+_DefaultIrq_h:
+ mov x0, #EXCEPT_AARCH64_IRQ
+ TO_HANDLER
+
+.align 7
+_DefaultFiq_h:
+ mov x0, #EXCEPT_AARCH64_FIQ
+ TO_HANDLER
+
+.align 7
+_DefaultSError_h:
+ mov x0, #EXCEPT_AARCH64_SERROR
+ TO_HANDLER
+
+dead:
+ b dead
diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S b/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S
new file mode 100644
index 000000000..14e9cb8d8
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S
@@ -0,0 +1,51 @@
+#========================================================================================
+# Copyright (c) 2011-2013, 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 <AsmMacroIoLibV8.h>
+#include <Chipset/AArch64.h>
+
+#start of the code section
+.text
+.align 3
+
+ASM_GLOBAL ASM_PFX(SetupExceptionLevel1)
+ASM_GLOBAL ASM_PFX(SetupExceptionLevel2)
+
+// Setup EL1 while in EL1
+ASM_PFX(SetupExceptionLevel1):
+ mov x5, x30 // Save LR
+
+ mov x0, #CPACR_CP_FULL_ACCESS
+ bl ASM_PFX(ArmWriteCpacr) // Disable copro traps to EL1
+
+ ret x5
+
+// Setup EL2 while in EL2
+ASM_PFX(SetupExceptionLevel2):
+ msr sctlr_el2, xzr
+ mrs x0, hcr_el2 // Read EL2 Hypervisor configuration Register
+
+ // Send all interrupts to their respective Exception levels for EL2
+ orr x0, x0, #(1 << 3) // Enable EL2 FIQ
+ orr x0, x0, #(1 << 4) // Enable EL2 IRQ
+ orr x0, x0, #(1 << 5) // Enable EL2 SError and Abort
+ msr hcr_el2, x0 // Write back our settings
+
+ msr cptr_el2, xzr // Disable copro traps to EL2
+
+ ret
+
+dead:
+ b dead
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S b/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S
new file mode 100644
index 000000000..5bdbe4585
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S
@@ -0,0 +1,114 @@
+//
+// Copyright (c) 2011-2013, 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 <AsmMacroIoLibV8.h>
+#include <Base.h>
+#include <Library/PcdLib.h>
+#include <AutoGen.h>
+
+.text
+.align 3
+
+GCC_ASM_IMPORT(CEntryPoint)
+GCC_ASM_IMPORT(ArmPlatformGetCorePosition)
+GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_IMPORT(ArmReadMpidr)
+GCC_ASM_IMPORT(ArmPlatformPeiBootAction)
+GCC_ASM_EXPORT(_ModuleEntryPoint)
+
+StartupAddr: .dword CEntryPoint
+
+ASM_PFX(_ModuleEntryPoint):
+ // Do early platform specific actions
+ bl ASM_PFX(ArmPlatformPeiBootAction)
+
+// NOTE: We could be booting from EL3, EL2 or EL1. Need to correctly detect
+// and configure the system accordingly. EL2 is default if possible.
+// If we started in EL3 we need to switch and run at EL2.
+// If we are running at EL2 stay in EL2
+// If we are starting at EL1 stay in EL1.
+
+// If started at EL3 Sec is run and switches to EL2 before jumping to PEI.
+// If started at EL1 or EL2 Sec jumps directly to PEI without making any
+// changes.
+
+// Which EL are we running at? Every EL needs some level of setup...
+ EL1_OR_EL2_OR_EL3(x0)
+1:bl ASM_PFX(SetupExceptionLevel1)
+ b ASM_PFX(MainEntryPoint)
+2:bl ASM_PFX(SetupExceptionLevel2)
+ b ASM_PFX(MainEntryPoint)
+3:// If we are at EL3 we die.
+ b dead
+
+ASM_PFX(MainEntryPoint):
+ // Identify CPU ID
+ bl ASM_PFX(ArmReadMpidr)
+ // Keep a copy of the MpId register value
+ mov x5, x0
+
+ // Is it the Primary Core ?
+ bl ASM_PFX(ArmPlatformIsPrimaryCore)
+
+ // Get the top of the primary stacks (and the base of the secondary stacks)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoresStackBase), x1)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2)
+ add x1, x1, x2
+
+ // x0 is equal to 1 if I am the primary core
+ cmp x0, #1
+ b.eq _SetupPrimaryCoreStack
+
+_SetupSecondaryCoreStack:
+ // x1 contains the base of the secondary stacks
+
+ // Get the Core Position
+ mov x6, x1 // Save base of the secondary stacks
+ mov x0, x5
+ bl ASM_PFX(ArmPlatformGetCorePosition)
+ // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack
+ add x0, x0, #1
+
+ // StackOffset = CorePos * StackSize
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x2)
+ mul x0, x0, x2
+ // SP = StackBase + StackOffset
+ add sp, x6, x0
+
+_PrepareArguments:
+ // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector
+ LoadConstantToReg (FixedPcdGet64(PcdFvBaseAddress), x2)
+ add x2, x2, #8
+ ldr x1, [x2]
+
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
+ ldr x3, StartupAddr
+
+ // Jump to PrePeiCore C code
+ // x0 = mp_id
+ // x1 = pei_core_address
+ mov x0, x5
+ blr x3
+
+_SetupPrimaryCoreStack:
+ // x1 contains the top of the primary stack
+ LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), x2)
+
+ // The reserved space for global variable must be 16-bytes aligned for pushing
+ // 128-bit variable on the stack
+ SetPrimaryStack (x1, x2, x3, x4)
+ b _PrepareArguments
+
+dead:
+ b dead
diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S b/ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S
new file mode 100644
index 000000000..d3fcd0aa1
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+# Portions copyright (c) 2011 - 2013, 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
+# 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.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 3
+
+ASM_GLOBAL ASM_PFX(SecSwitchStack)
+
+
+
+#/**
+# This allows the caller to switch the stack and return
+#
+# @param StackDelta Signed amount by which to modify the stack pointer
+#
+# @return Nothing. Goes to the Entry Point passing in the new parameters
+#
+#**/
+#VOID
+#EFIAPI
+#SecSwitchStack (
+# VOID *StackDelta
+# )#
+#
+ASM_PFX(SecSwitchStack):
+ mov x1, sp
+ add x1, x0, x1
+ mov sp, x1
+ ret
+
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
index ececd4c76..e165fd945 100644
--- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
+++ b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
@@ -87,7 +87,8 @@ CEntryPoint (
//
// Write VBAR - The Exception Vector table must be aligned to its requirement
- ASSERT (((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
+ //TODO: Fix baseTools to ensure the Exception Vector Table is correctly aligned in AArch64
+ //ASSERT(((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
ArmWriteVBar ((UINTN)PeiVectorTable);
//Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on.
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
index 351ac6780..d90481e75 100644
--- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
@@ -33,6 +33,13 @@
Arm/Exception.asm | RVCT
Arm/Exception.S | GCC
+[Sources.AARCH64]
+ AArch64/ArchPrePeiCore.c
+ AArch64/PrePeiCoreEntryPoint.S | GCC
+ AArch64/SwitchStack.S | GCC
+ AArch64/Exception.S | GCC
+ AArch64/Helper.S | GCC
+
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
index 13f86902b..94b7a6cf0 100644
--- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
+++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
@@ -32,7 +32,14 @@
Arm/SwitchStack.S | GCC
Arm/Exception.asm | RVCT
Arm/Exception.S | GCC
-
+
+[Sources.AARCH64]
+ AArch64/ArchPrePeiCore.c
+ AArch64/PrePeiCoreEntryPoint.S | GCC
+ AArch64/SwitchStack.S | GCC
+ AArch64/Exception.S | GCC
+ AArch64/Helper.S | GCC
+
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
diff --git a/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c b/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c
new file mode 100644
index 000000000..217986107
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c
@@ -0,0 +1,33 @@
+/** @file
+*
+* Copyright (c) 2011-2013, 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 "PrePi.h"
+
+#include <Chipset/AArch64.h>
+
+VOID
+ArchInitialize (
+ VOID
+ )
+{
+ // Enable Floating Point
+ if (FixedPcdGet32 (PcdVFPEnabled)) {
+ ArmEnableVFP ();
+ }
+
+ if (ArmReadCurrentEL () == AARCH64_EL2) {
+ // Trap General Exceptions. All exceptions that would be routed to EL1 are routed to EL2
+ ArmWriteHcr (ARM_HCR_TGE);
+ }
+}
diff --git a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
new file mode 100644
index 000000000..e44281953
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
@@ -0,0 +1,148 @@
+//
+// Copyright (c) 2011-2013, 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 <AsmMacroIoLibV8.h>
+#include <Base.h>
+#include <Library/PcdLib.h>
+#include <AutoGen.h>
+
+#include <Chipset/ArmV7.h>
+
+.text
+.align 3
+
+GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_IMPORT(ArmReadMpidr)
+GCC_ASM_IMPORT(ArmPlatformPeiBootAction)
+GCC_ASM_IMPORT(ArmPlatformStackSet)
+GCC_ASM_EXPORT(_ModuleEntryPoint)
+
+StartupAddr: .dword ASM_PFX(CEntryPoint)
+
+ASM_PFX(_ModuleEntryPoint):
+ // Do early platform specific actions
+ bl ASM_PFX(ArmPlatformPeiBootAction)
+
+ // Get ID of this CPU in Multicore system
+ bl ASM_PFX(ArmReadMpidr)
+ // Keep a copy of the MpId register value
+ mov x10, x0
+
+_SetSVCMode:
+// 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:
+ // Compute Top of System Memory
+ LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryBase), x1)
+ LoadConstantToReg (FixedPcdGet32(PcdSystemMemorySize), x2)
+ sub x2, x2, #1
+ add x1, x1, x2 // x1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize
+
+ // Calculate Top of the Firmware Device
+ LoadConstantToReg (FixedPcdGet32(PcdFdBaseAddress), x2)
+ LoadConstantToReg (FixedPcdGet32(PcdFdSize), x3)
+ sub x3, x3, #1
+ add x3, x3, x2 // x3 = FdTop = PcdFdBaseAddress + PcdFdSize
+
+ // UEFI Memory Size (stacks are allocated in this region)
+ LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), x4)
+
+ //
+ // Reserve the memory for the UEFI region (contain stacks on its top)
+ //
+
+ // Calculate how much space there is between the top of the Firmware and the Top of the System Memory
+ subs x0, x1, x3 // x0 = SystemMemoryTop - FdTop
+ b.mi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
+ cmp x0, x4
+ b.ge _SetupStack
+
+ // Case the top of stacks is the FdBaseAddress
+ mov x1, x2
+
+_SetupStack:
+ // x1 contains the top of the stack (and the UEFI Memory)
+
+ // 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 x11, x1, #1
+ b.cs _SetupOverflowStack
+
+_SetupAlignedStack:
+ mov x1, x11
+ 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, x11)
+ and x11, x11, x1
+ sub x1, x1, x11
+
+_GetBaseUefiMemory:
+ // Calculate the Base of the UEFI Memory
+ sub x11, x1, x4
+
+_GetStackBase:
+ // r1 = The top of the Mpcore Stacks
+ // Stack for the primary core = PrimaryCoreStack
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2)
+ sub x12, x1, x2
+
+ // Stack for the secondary core = Number of Cores - 1
+ LoadConstantToReg (FixedPcdGet32(PcdCoreCount), x0)
+ sub x0, x0, #1
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x1)
+ mul x1, x1, x0
+ sub x12, x12, x1
+
+ // x12 = The base of the MpCore Stacks (primary stack & secondary stacks)
+ mov x0, x12
+ mov x1, x10
+ //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x3)
+ bl ASM_PFX(ArmPlatformStackSet)
+
+ // Is it the Primary Core ?
+ mov x0, x10
+ bl ASM_PFX(ArmPlatformIsPrimaryCore)
+ cmp x0, #1
+ bne _PrepareArguments
+
+_ReserveGlobalVariable:
+ LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), x0)
+ // InitializePrimaryStack($GlobalVariableSize, $Tmp1, $Tmp2)
+ InitializePrimaryStack(x0, x1, x2)
+
+_PrepareArguments:
+ mov x0, x10
+ mov x1, x11
+ mov x2, x12
+ mov x3, sp
+
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
+ ldr x4, StartupAddr
+
+ // Jump to PrePiCore C code
+ // x0 = MpId
+ // x1 = UefiMemoryBase
+ // x2 = StacksBase
+ // x3 = GlobalVariableBase
+ blr x4
+
+_NeverReturn:
+ b _NeverReturn
diff --git a/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c b/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c
new file mode 100644
index 000000000..075eb89e1
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c
@@ -0,0 +1,29 @@
+/** @file
+*
+* Copyright (c) 2011 - 2013, 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 "PrePi.h"
+
+VOID
+ArchInitialize (
+ VOID
+ )
+{
+ // Enable program flow prediction, if supported.
+ ArmEnableBranchPrediction ();
+
+ if (FixedPcdGet32 (PcdVFPEnabled)) {
+ ArmEnableVFP ();
+ }
+}
+
diff --git a/ArmPlatformPkg/PrePi/PeiMPCore.inf b/ArmPlatformPkg/PrePi/PeiMPCore.inf
index a2814b671..ee89c04ae 100755
--- a/ArmPlatformPkg/PrePi/PeiMPCore.inf
+++ b/ArmPlatformPkg/PrePi/PeiMPCore.inf
@@ -24,8 +24,13 @@
MainMPCore.c
[Sources.ARM]
+ Arm/ArchPrePi.c
Arm/ModuleEntryPoint.S | GCC
Arm/ModuleEntryPoint.asm | RVCT
+
+[Sources.AArch64]
+ AArch64/ArchPrePi.c
+ AArch64/ModuleEntryPoint.S | GCC
[Packages]
MdePkg/MdePkg.dec
diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PrePi/PeiUniCore.inf
index dd6b82ed3..6cb94cbd7 100755
--- a/ArmPlatformPkg/PrePi/PeiUniCore.inf
+++ b/ArmPlatformPkg/PrePi/PeiUniCore.inf
@@ -24,8 +24,13 @@
MainUniCore.c
[Sources.ARM]
+ Arm/ArchPrePi.c
Arm/ModuleEntryPoint.S | GCC
Arm/ModuleEntryPoint.asm | RVCT
+
+[Sources.AArch64]
+ AArch64/ArchPrePi.c
+ AArch64/ModuleEntryPoint.S | GCC
[Packages]
MdePkg/MdePkg.dec
diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c
index 238b0989a..e8b1ff7ed 100755
--- a/ArmPlatformPkg/PrePi/PrePi.c
+++ b/ArmPlatformPkg/PrePi/PrePi.c
@@ -111,12 +111,8 @@ PrePiMain (
((FixedPcdGet32 (PcdFdBaseAddress) >= FixedPcdGet32 (PcdSystemMemoryBase)) &&
((UINT32)(FixedPcdGet32 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT32)(FixedPcdGet32 (PcdSystemMemoryBase) + FixedPcdGet32 (PcdSystemMemorySize)))));
- // Enable program flow prediction, if supported.
- ArmEnableBranchPrediction ();
-
- if (FixedPcdGet32(PcdVFPEnabled)) {
- ArmEnableVFP();
- }
+ // Initialize the architecture specific bits
+ ArchInitialize ();
// Initialize the Serial Port
SerialPortInitialize ();
diff --git a/ArmPlatformPkg/PrePi/PrePi.h b/ArmPlatformPkg/PrePi/PrePi.h
index deb885168..e67795f44 100644
--- a/ArmPlatformPkg/PrePi/PrePi.h
+++ b/ArmPlatformPkg/PrePi/PrePi.h
@@ -81,4 +81,10 @@ GetPlatformPpi (
OUT VOID **Ppi
);
+// Initialize the Architecture specific controllers
+VOID
+ArchInitialize (
+ VOID
+ );
+
#endif /* _PREPI_H_ */
diff --git a/ArmPlatformPkg/Sec/AArch64/Helper.S b/ArmPlatformPkg/Sec/AArch64/Helper.S
new file mode 100644
index 000000000..ff4625576
--- /dev/null
+++ b/ArmPlatformPkg/Sec/AArch64/Helper.S
@@ -0,0 +1,156 @@
+#========================================================================================
+# Copyright (c) 2011-2013, 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 <AsmMacroIoLibV8.h>
+#include <Chipset/AArch64.h>
+
+#start of the code section
+.text
+.align 3
+
+ASM_GLOBAL ASM_PFX(SetupExceptionLevel3)
+ASM_GLOBAL ASM_PFX(SwitchToNSExceptionLevel1)
+ASM_GLOBAL ASM_PFX(enter_monitor_mode)
+ASM_GLOBAL ASM_PFX(return_from_exception)
+ASM_GLOBAL ASM_PFX(copy_cpsr_into_spsr)
+ASM_GLOBAL ASM_PFX(set_non_secure_mode)
+
+ASM_PFX(SetupExceptionLevel3):
+ mrs x0, scr_el3 // Read EL3 Secure Configuration Register
+ orr x0, x0, #1 // EL0 an EL1 cannot access secure memory
+
+ // Send all interrupts to their respective Exception levels for EL3
+ bic x0, x0, #(1 << 1) // IRQ
+ bic x0, x0, #(1 << 2) // FIQ
+ bic x0, x0, #(1 << 3) // Serror and Abort
+ orr x0, x0, #(1 << 8) // Enable HVC
+ orr x0, x0, #(1 << 10) // Make next level down 64Bit. This is EL2 in the case of the Model.
+ // We need a nice way to detect this.
+ msr scr_el3, x0 // Write back our settings
+
+ msr cptr_el3, xzr // Disable copro traps to EL3
+
+ // Check for the primary CPU to avoid a race on the distributor registers.
+ mrs x0, mpidr_el1
+ tst x0, #15
+ b.ne 1f // secondary CPU
+
+ LoadConstantToReg (FixedPcdGet32(PcdGicInterruptInterfaceBase), x1)
+ mov w0, #3 // EnableGrp0 | EnableGrp1
+ str w0, [x1]
+
+1: LoadConstantToReg (FixedPcdGet32(PcdGicDistributorBase), x1)
+ add x1, x1, #0x80
+ mov w0, #~0 // Grp1 interrupts
+ str w0, [x1], #4
+ b.ne 2f // Only local interrupts for secondary CPUs
+ str w0, [x1], #4
+ str w0, [x1], #4
+
+2: LoadConstantToReg (FixedPcdGet32(PcdGicInterruptInterfaceBase), x1)
+ ldr w0, [x1]
+ mov w0, #3 // EnableGrp0 | EnableGrp1
+ str w0, [x1]
+
+ mov w0, #1 << 7 // allow NS access to GICC_PMR
+ str w0, [x1, #4] // GICC_PMR
+
+ ret
+
+// Switch from EL3 to NS-EL1
+ASM_PFX(SwitchToNSExceptionLevel1):
+ // Now setup our EL1. Controlled by EL2 config on Model
+ mrs x0, hcr_el2 // Read EL2 Hypervisor configuration Register
+ orr x0, x0, #(1 << 31) // Set EL1 to be 64bit
+
+ // Send all interrupts to their respective Exception levels for EL2
+ bic x0, x0, #(1 << 3) // Disable virtual FIQ
+ bic x0, x0, #(1 << 4) // Disable virtual IRQ
+ bic x0, x0, #(1 << 5) // Disable virtual SError and Abort
+ msr hcr_el2, x0 // Write back our settings
+
+ msr cptr_el2, xzr // Disable copro traps to EL2
+
+ msr sctlr_el2, xzr
+
+ // Enable architected timer access
+ mrs x0, cnthctl_el2
+ orr x0, x0, #3 // Enable EL1 access to timers
+ msr cnthctl_el2, x0
+
+ mrs x0, cntkctl_el1
+ orr x0, x0, #3 // EL0 access to counters
+ msr cntkctl_el1, x0
+
+ // Set ID regs
+ mrs x0, midr_el1
+ mrs x1, mpidr_el1
+ msr vpidr_el2, x0
+ msr vmpidr_el2, x1
+
+ ret
+
+
+// EL3 on AArch64 is Secure/monitor so this funtion is reduced vs ARMv7
+// we don't need a mode switch, just setup the Arguments and jump.
+// x0: Monitor World EntryPoint
+// x1: MpId
+// x2: SecBootMode
+// x3: Secure Monitor mode stack
+ASM_PFX(enter_monitor_mode):
+ mov x4, x0 // Swap EntryPoint and MpId registers
+ mov x0, x1
+ mov x1, x2
+ mov x2, x3
+ br x4
+
+// Put the address in correct ELR_ELx and do a eret.
+// We may need to do some config before we change to another Mode.
+ASM_PFX(return_from_exception):
+ msr elr_el3, x0
+
+ mrs x7, spsr_el3
+ ands w7, w7, #0xC
+ cmp w7, #0xC // EL3?
+ b.eq 3f
+ bl ASM_PFX(SetupExceptionLevel3)
+ cmp w7, #0x8 // EL2?
+ b.eq 2f
+ cmp w7, #0x4 // EL1?
+ b.eq 1f
+ b dead // We should never get here.
+
+1: bl ASM_PFX(SwitchToNSExceptionLevel1)
+2: // EL2: No more setup required.
+3: // EL3: Not sure why we would do this.
+ eret
+
+// For AArch64 we need to construct the spsr we want from individual bits and pieces.
+ASM_PFX(copy_cpsr_into_spsr):
+ mrs x0, CurrentEl // Get the current exception level we are running at.
+ mrs x1, SPSel // Which Stack are we using
+ orr x0, x0, x1
+ mrs x1, daif // Which interrupts are enabled
+ orr x0, x0, x1
+ msr spsr_el3, x0 // Write to spsr
+ ret
+
+// Get this from platform file.
+ASM_PFX(set_non_secure_mode):
+ msr spsr_el3, x0
+ ret
+
+dead:
+ b dead
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPlatformPkg/Sec/AArch64/SecEntryPoint.S b/ArmPlatformPkg/Sec/AArch64/SecEntryPoint.S
new file mode 100644
index 000000000..e678f4c18
--- /dev/null
+++ b/ArmPlatformPkg/Sec/AArch64/SecEntryPoint.S
@@ -0,0 +1,146 @@
+//
+// Copyright (c) 2011-2013, 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 <AsmMacroIoLibV8.h>
+#include "SecInternal.h"
+
+.text
+.align 3
+
+GCC_ASM_IMPORT(CEntryPoint)
+GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_IMPORT(ArmPlatformGetCorePosition)
+GCC_ASM_IMPORT(ArmPlatformSecBootAction)
+GCC_ASM_IMPORT(ArmPlatformSecBootMemoryInit)
+GCC_ASM_IMPORT(ArmDisableInterrupts)
+GCC_ASM_IMPORT(ArmDisableCachesAndMmu)
+GCC_ASM_IMPORT(ArmReadMpidr)
+GCC_ASM_IMPORT(ArmCallWFE)
+GCC_ASM_EXPORT(_ModuleEntryPoint)
+
+StartupAddr: .dword ASM_PFX(CEntryPoint)
+
+ASM_PFX(_ModuleEntryPoint):
+
+// NOTE: We could be booting from EL3, EL2 or EL1. Need to correctly detect
+// and configure the system accordingly. EL2 is default if possible.
+// If we started in EL3 we need to switch and run at EL2.
+// If we are running at EL2 stay in EL2
+// If we are starting at EL1 stay in EL1.
+
+// Sec only runs in EL3. Othewise we jump to PEI without changing anything.
+// If Sec runs we change to EL2 before switching to PEI.
+
+// Which EL are we running at? Every EL needs some level of setup...
+ EL1_OR_EL2_OR_EL3(x0)
+1:// If we are at EL1 or EL2 leave SEC for PEI.
+2:b ASM_PFX(JumpToPEI)
+ // If we are at EL3 we need to configure it and switch to EL2
+3:b ASM_PFX(MainEntryPoint)
+
+ASM_PFX(MainEntryPoint):
+ // First ensure all interrupts are disabled
+ bl ASM_PFX(ArmDisableInterrupts)
+
+ // Ensure that the MMU and caches are off
+ bl ASM_PFX(ArmDisableCachesAndMmu)
+
+ // By default, we are doing a cold boot
+ mov x10, #ARM_SEC_COLD_BOOT
+
+ // Jump to Platform Specific Boot Action function
+ bl ASM_PFX(ArmPlatformSecBootAction)
+
+_IdentifyCpu:
+ // Identify CPU ID
+ bl ASM_PFX(ArmReadMpidr)
+ // Keep a copy of the MpId register value
+ mov x5, x0
+
+ // Is it the Primary Core ?
+ bl ASM_PFX(ArmPlatformIsPrimaryCore)
+ cmp x0, #1
+ // Only the primary core initialize the memory (SMC)
+ b.eq _InitMem
+
+_WaitInitMem:
+ // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized
+ // Otherwise we have to wait the Primary Core to finish the initialization
+ cmp x10, #ARM_SEC_COLD_BOOT
+ b.ne _SetupSecondaryCoreStack
+
+ // Wait for the primary core to initialize the initial memory (event: BOOT_MEM_INIT)
+ bl ASM_PFX(ArmCallWFE)
+ // Now the Init Mem is initialized, we setup the secondary core stacks
+ b _SetupSecondaryCoreStack
+
+_InitMem:
+ // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized
+ cmp x10, #ARM_SEC_COLD_BOOT
+ b.ne _SetupPrimaryCoreStack
+
+ // Initialize Init Boot Memory
+ bl ASM_PFX(ArmPlatformSecBootMemoryInit)
+
+_SetupPrimaryCoreStack:
+ // Get the top of the primary stacks (and the base of the secondary stacks)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), x1)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), x2)
+ add x1, x1, x2
+
+ LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), x2)
+
+ // The reserved space for global variable must be 8-bytes aligned for pushing
+ // 64-bit variable on the stack
+ SetPrimaryStack (x1, x2, x3, x4)
+ b _PrepareArguments
+
+_SetupSecondaryCoreStack:
+ // Get the top of the primary stacks (and the base of the secondary stacks)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), x1)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), x2)
+ add x6, x1, x2
+
+ // Get the Core Position
+ mov x0, x5
+ bl ASM_PFX(ArmPlatformGetCorePosition)
+ // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack
+ add x0, x0, #1
+
+ // StackOffset = CorePos * StackSize
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), x2)
+ mul x0, x0, x2
+ // SP = StackBase + StackOffset
+ add sp, x6, x0
+
+_PrepareArguments:
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
+ ldr x3, StartupAddr
+
+ // Jump to SEC C code
+ // r0 = mp_id
+ // r1 = Boot Mode
+ mov x0, x5
+ mov x1, x10
+ blr x3
+
+ ret
+
+ASM_PFX(JumpToPEI):
+ LoadConstantToReg (FixedPcdGet32(PcdFvBaseAddress), x0)
+ blr x0
+
+dead:
+ b dead
diff --git a/ArmPlatformPkg/Sec/Sec.inf b/ArmPlatformPkg/Sec/Sec.inf
index 8e64a7314..dc1c4f2be 100644
--- a/ArmPlatformPkg/Sec/Sec.inf
+++ b/ArmPlatformPkg/Sec/Sec.inf
@@ -1,7 +1,7 @@
#/** @file
-# SEC - Reset vector code that jumps to C and loads DXE core
+# SEC - Reset vector code that jumps to C and starts the PEI phase
#
-# Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+# Copyright (c) 2011-2013, 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
@@ -29,6 +29,10 @@
Arm/SecEntryPoint.S | GCC
Arm/SecEntryPoint.asm | RVCT
+[Sources.AARCH64]
+ AArch64/Helper.S | GCC
+ AArch64/SecEntryPoint.S | GCC
+
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec