summaryrefslogtreecommitdiff
path: root/ArmPlatformPkg/PrePeiCore
diff options
context:
space:
mode:
authorandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>2011-02-01 05:41:42 +0000
committerandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>2011-02-01 05:41:42 +0000
commit1d5d0ae92d95410f20bc6daab7a47e129fb2547a (patch)
tree8679c57c5f85cadad47d4604450c1c3702276cf1 /ArmPlatformPkg/PrePeiCore
parentfb334ef6c543b1babc9d8a613ad5d1ce6fe536e1 (diff)
Add ArmPlatformPkg from ARM Ltd. patch.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11291 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPlatformPkg/PrePeiCore')
-rw-r--r--ArmPlatformPkg/PrePeiCore/Exception.S106
-rw-r--r--ArmPlatformPkg/PrePeiCore/Exception.asm94
-rw-r--r--ArmPlatformPkg/PrePeiCore/MainMPCore.c91
-rw-r--r--ArmPlatformPkg/PrePeiCore/MainUniCore.c53
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCore.c147
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.S65
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.asm61
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf63
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf61
-rw-r--r--ArmPlatformPkg/PrePeiCore/SwitchStack.S43
-rw-r--r--ArmPlatformPkg/PrePeiCore/SwitchStack.asm38
11 files changed, 822 insertions, 0 deletions
diff --git a/ArmPlatformPkg/PrePeiCore/Exception.S b/ArmPlatformPkg/PrePeiCore/Exception.S
new file mode 100644
index 000000000..618e0787b
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/Exception.S
@@ -0,0 +1,106 @@
+//
+// 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 <AsmMacroIoLib.h>
+#include <Base.h>
+#include <AutoGen.h>
+
+#start of the code section
+.text
+.align 5
+
+# IMPORT
+GCC_ASM_IMPORT(PeiCommonExceptionEntry)
+
+# EXPORT
+GCC_ASM_EXPORT(PeiVectorTable)
+
+//============================================================
+//Default Exception Handlers
+//============================================================
+
+//FIXME: One of the EDK2 tool is broken. It does not look to respect the alignment. Even, if we specify 32-byte alignment for this file.
+Dummy1: .word 0
+Dummy2: .word 0
+
+ASM_PFX(PeiVectorTable):
+ b _DefaultResetHandler
+ b _DefaultUndefined
+ b _DefaultSWI
+ b _DefaultPrefetchAbort
+ b _DefaultDataAbort
+ b _DefaultReserved
+ b _DefaultIrq
+ b _DefaultFiq
+
+//
+// Default Exception handlers: There is no plan to return from any of these exceptions.
+// No context saving at all.
+//
+_DefaultResetHandler:
+ mov r1, lr
+ # Switch to SVC for common stack
+ cps #0x13
+ mov r0, #0
+ blx ASM_PFX(PeiCommonExceptionEntry)
+
+_DefaultUndefined:
+ sub r1, LR, #4
+ # Switch to SVC for common stack
+ cps #0x13
+ mov r0, #1
+ blx ASM_PFX(PeiCommonExceptionEntry)
+
+_DefaultSWI:
+ sub r1, LR, #4
+ # Switch to SVC for common stack
+ cps #0x13
+ mov r0, #2
+ blx ASM_PFX(PeiCommonExceptionEntry)
+
+_DefaultPrefetchAbort:
+ sub r1, LR, #4
+ # Switch to SVC for common stack
+ cps #0x13
+ mov r0, #3
+ blx ASM_PFX(PeiCommonExceptionEntry)
+
+_DefaultDataAbort:
+ sub r1, LR, #8
+ # Switch to SVC for common stack
+ cps #0x13
+ mov r0, #4
+ blx ASM_PFX(PeiCommonExceptionEntry)
+
+_DefaultReserved:
+ mov r1, lr
+ # Switch to SVC for common stack
+ cps #0x13
+ mov r0, #5
+ blx PeiCommonExceptionEntry
+
+_DefaultIrq:
+ sub r1, LR, #4
+ # Switch to SVC for common stack
+ cps #0x13
+ mov r0, #6
+ blx PeiCommonExceptionEntry
+
+_DefaultFiq:
+ sub r1, LR, #4
+ # Switch to SVC for common stack
+ cps #0x13
+ mov r0, #7
+ blx PeiCommonExceptionEntry
+
+.end
diff --git a/ArmPlatformPkg/PrePeiCore/Exception.asm b/ArmPlatformPkg/PrePeiCore/Exception.asm
new file mode 100644
index 000000000..d081c4956
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/Exception.asm
@@ -0,0 +1,94 @@
+//
+// 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 <AsmMacroIoLib.h>
+#include <Base.h>
+#include <AutoGen.h>
+
+ IMPORT PeiCommonExceptionEntry
+ EXPORT PeiVectorTable
+
+ PRESERVE8
+ AREA PrePeiCoreException, CODE, READONLY, CODEALIGN, ALIGN=5
+
+//============================================================
+//Default Exception Handlers
+//============================================================
+
+//FIXME: One of the EDK2 tool is broken. It does not look to respect the alignment. Even, if we specify 32-byte alignment for this file.
+Dummy1 DCD 0
+Dummy2 DCD 0
+
+PeiVectorTable
+ b _DefaultResetHandler
+ b _DefaultUndefined
+ b _DefaultSWI
+ b _DefaultPrefetchAbort
+ b _DefaultDataAbort
+ b _DefaultReserved
+ b _DefaultIrq
+ b _DefaultFiq
+
+//
+// Default Exception handlers: There is no plan to return from any of these exceptions.
+// No context saving at all.
+//
+_DefaultResetHandler
+ mov r1, lr
+ cps #0x13 ; Switch to SVC for common stack
+ mov r0, #0
+ blx PeiCommonExceptionEntry
+
+_DefaultUndefined
+ sub r1, LR, #4
+ cps #0x13 ; Switch to SVC for common stack
+ mov r0, #1
+ blx PeiCommonExceptionEntry
+
+_DefaultSWI
+ sub r1, LR, #4
+ cps #0x13 ; Switch to SVC for common stack
+ mov r0, #2
+ blx PeiCommonExceptionEntry
+
+_DefaultPrefetchAbort
+ sub r1, LR, #4
+ cps #0x13 ; Switch to SVC for common stack
+ mov r0, #3
+ blx PeiCommonExceptionEntry
+
+_DefaultDataAbort
+ sub r1, LR, #8
+ cps #0x13 ; Switch to SVC for common stack
+ mov r0, #4
+ blx PeiCommonExceptionEntry
+
+_DefaultReserved
+ mov r1, lr
+ cps #0x13 ; Switch to SVC for common stack
+ mov r0, #5
+ blx PeiCommonExceptionEntry
+
+_DefaultIrq
+ sub r1, LR, #4
+ cps #0x13 ; Switch to SVC for common stack
+ mov r0, #6
+ blx PeiCommonExceptionEntry
+
+_DefaultFiq
+ sub r1, LR, #4
+ cps #0x13 ; Switch to SVC for common stack
+ mov r0, #7
+ blx PeiCommonExceptionEntry
+
+ END
diff --git a/ArmPlatformPkg/PrePeiCore/MainMPCore.c b/ArmPlatformPkg/PrePeiCore/MainMPCore.c
new file mode 100644
index 000000000..ea69b8ec2
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/MainMPCore.c
@@ -0,0 +1,91 @@
+/** @file
+*
+* 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 <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/ArmMPCoreMailBoxLib.h>
+#include <Chipset/ArmV7.h>
+#include <Drivers/PL390Gic.h>
+
+extern EFI_PEI_PPI_DESCRIPTOR *gSecPpiTable;
+
+/*
+ * This is the main function for secondary cores. They loop around until a non Null value is written to
+ * SYS_FLAGS register.The SYS_FLAGS register is platform specific.
+ * Note:The secondary cores, while executing secondary_main, assumes that:
+ * : SGI 0 is configured as Non-secure interrupt
+ * : Priority Mask is configured to allow SGI 0
+ * : Interrupt Distributor and CPU interfaces are enabled
+ *
+ */
+VOID
+EFIAPI
+secondary_main(IN UINTN CoreId)
+{
+ //Function pointer to Secondary Core entry point
+ VOID (*secondary_start)(VOID);
+ UINTN secondary_entry_addr=0;
+
+ //Clear Secondary cores MailBox
+ ArmClearMPCoreMailbox();
+
+ while (secondary_entry_addr = ArmGetMPCoreMailbox(), secondary_entry_addr == 0) {
+ ArmCallWFI();
+ //Acknowledge the interrupt and send End of Interrupt signal.
+ PL390GicAcknowledgeSgiFrom(PcdGet32(PcdGicInterruptInterfaceBase),0/*CoreId*/);
+ }
+
+ secondary_start = (VOID (*)())secondary_entry_addr;
+
+ //Jump to secondary core entry point.
+ secondary_start();
+
+ //the secondaries shouldn't reach here
+ ASSERT(FALSE);
+}
+
+VOID primary_main (
+ IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
+ )
+{
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+
+ //Enable the GIC Distributor
+ PL390GicEnableDistributor(PcdGet32(PcdGicDistributorBase));
+
+ // If ArmVe has not been built as Standalone then we need to wake up the secondary cores
+ if (FeaturePcdGet(PcdStandalone) == FALSE) {
+ // Sending SGI to all the Secondary CPU interfaces
+ PL390GicSendSgiTo (PcdGet32(PcdGicDistributorBase), GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E);
+ }
+
+ //
+ // Bind this information into the SEC hand-off state
+ // Note: this must be in sync with the stuff in the asm file
+ // Note also: HOBs (pei temp ram) MUST be above stack
+ //
+ SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
+ SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet32 (PcdEmbeddedFdBaseAddress);
+ SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdEmbeddedFdSize);
+ 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.PeiTemporaryRamBase = (VOID *)((UINTN)(SecCoreData.TemporaryRamBase) + (SecCoreData.TemporaryRamSize / 2));
+ SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize / 2;
+ SecCoreData.StackBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.StackSize = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize;
+
+ // jump to pei core entry point
+ (PeiCoreEntryPoint)(&SecCoreData, (VOID *)&gSecPpiTable);
+}
diff --git a/ArmPlatformPkg/PrePeiCore/MainUniCore.c b/ArmPlatformPkg/PrePeiCore/MainUniCore.c
new file mode 100644
index 000000000..cf7d029bf
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/MainUniCore.c
@@ -0,0 +1,53 @@
+/** @file
+*
+* 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 <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Chipset/ArmV7.h>
+
+extern EFI_PEI_PPI_DESCRIPTOR *gSecPpiTable;
+
+VOID
+EFIAPI
+secondary_main(IN UINTN CoreId)
+{
+ ASSERT(FALSE);
+}
+
+VOID primary_main (
+ IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
+ )
+{
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+
+
+ //
+ // Bind this information into the SEC hand-off state
+ // Note: this must be in sync with the stuff in the asm file
+ // Note also: HOBs (pei temp ram) MUST be above stack
+ //
+ SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
+ SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet32 (PcdEmbeddedFdBaseAddress);
+ SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdEmbeddedFdSize);
+ 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.PeiTemporaryRamBase = (VOID *)((UINTN)(SecCoreData.TemporaryRamBase) + (SecCoreData.TemporaryRamSize / 2));
+ SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize / 2;
+ SecCoreData.StackBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.StackSize = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize;
+
+ // jump to pei core entry point
+ (PeiCoreEntryPoint)(&SecCoreData, (VOID *)&gSecPpiTable);
+}
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
new file mode 100644
index 000000000..51c09223d
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
@@ -0,0 +1,147 @@
+/** @file
+* Main file supporting the transition to PEI Core in Normal World for Versatile Express
+*
+* 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 <PiPei.h>
+#include <Ppi/TemporaryRamSupport.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ArmLib.h>
+#include <Chipset/ArmV7.h>
+
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupport (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ );
+
+VOID
+SecSwitchStack (
+ INTN StackDelta
+ );
+
+TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = {SecTemporaryRamSupport};
+
+EFI_PEI_PPI_DESCRIPTOR gSecPpiTable[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiTemporaryRamSupportPpiGuid,
+ &mSecTemporaryRamSupportPpi
+ }
+};
+
+// Vector Table for Pei Phase
+VOID PeiVectorTable (VOID);
+
+
+VOID
+CEntryPoint (
+ IN UINTN CoreId,
+ IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
+ )
+{
+ //Clean Data cache
+ ArmCleanInvalidateDataCache();
+
+ //Invalidate instruction cache
+ ArmInvalidateInstructionCache();
+
+ // Enable Instruction & Data caches
+ ArmEnableDataCache();
+ ArmEnableInstructionCache();
+
+ //
+ // Note: Doesn't have to Enable CPU interface in non-secure world,
+ // as Non-secure interface is already enabled in Secure world.
+ //
+
+ // Write VBAR - The Vector table must be 32-byte aligned
+ ASSERT(((UINT32)PeiVectorTable & ((1 << 5)-1)) == 0);
+ ArmWriteVBar((UINT32)PeiVectorTable);
+
+ //Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on.
+
+ //If not primary Jump to Secondary Main
+ if(0 == CoreId) {
+ //Goto primary Main.
+ primary_main(PeiCoreEntryPoint);
+ } else {
+ secondary_main(CoreId);
+ }
+
+ // PEI Core should always load and never return
+ ASSERT (FALSE);
+}
+
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupport (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ )
+{
+ //
+ // Migrate the whole temporary memory to permenent memory.
+ //
+ CopyMem (
+ (VOID*)(UINTN)PermanentMemoryBase,
+ (VOID*)(UINTN)TemporaryMemoryBase,
+ CopySize
+ );
+
+ SecSwitchStack((UINTN)(PermanentMemoryBase - TemporaryMemoryBase));
+
+ return EFI_SUCCESS;
+}
+
+VOID PeiCommonExceptionEntry(UINT32 Entry, UINT32 LR) {
+ switch (Entry) {
+ case 0:
+ DEBUG((EFI_D_ERROR,"Reset Exception at 0x%X\n",LR));
+ break;
+ case 1:
+ DEBUG((EFI_D_ERROR,"Undefined Exception at 0x%X\n",LR));
+ break;
+ case 2:
+ DEBUG((EFI_D_ERROR,"SWI Exception at 0x%X\n",LR));
+ break;
+ case 3:
+ DEBUG((EFI_D_ERROR,"PrefetchAbort Exception at 0x%X\n",LR));
+ break;
+ case 4:
+ DEBUG((EFI_D_ERROR,"DataAbort Exception at 0x%X\n",LR));
+ break;
+ case 5:
+ DEBUG((EFI_D_ERROR,"Reserved Exception at 0x%X\n",LR));
+ break;
+ case 6:
+ DEBUG((EFI_D_ERROR,"IRQ Exception at 0x%X\n",LR));
+ break;
+ case 7:
+ DEBUG((EFI_D_ERROR,"FIQ Exception at 0x%X\n",LR));
+ break;
+ default:
+ DEBUG((EFI_D_ERROR,"Unknown Exception at 0x%X\n",LR));
+ break;
+ }
+ while(1);
+}
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.S b/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.S
new file mode 100644
index 000000000..cf9cb9f9c
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.S
@@ -0,0 +1,65 @@
+//
+// 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 <AsmMacroIoLib.h>
+#include <Base.h>
+#include <Library/PcdLib.h>
+#include <AutoGen.h>
+
+#start of the code section
+.text
+.align 3
+
+#global symbols referenced by this module
+GCC_ASM_IMPORT(CEntryPoint)
+
+StartupAddr: .word CEntryPoint
+
+#make _ModuleEntryPoint as global
+GCC_ASM_EXPORT(_ModuleEntryPoint)
+
+
+ASM_PFX(_ModuleEntryPoint):
+ # Identify CPU ID
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, #0xf
+
+_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
+
+ # lr points to area in reset vector block containing PEI core address. lr needs to
+ # be saved from the beginning as the _ModuleEntryPoint could call helper functions
+ # that will overwrite 'lr'
+ LoadConstantToReg (FixedPcdGet32(PcdEmbeddedFdBaseAddress), 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)
+ ldr r2, StartupAddr
+
+ # jump to SEC C code
+ # r0 = core_id
+ # r1 = pei_core_address
+ blx r2
+
+#end of the file
+.end
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.asm b/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.asm
new file mode 100644
index 000000000..44263391a
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreEntryPoint.asm
@@ -0,0 +1,61 @@
+//
+// 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 <AsmMacroIoLib.h>
+#include <Base.h>
+#include <Library/PcdLib.h>
+#include <AutoGen.h>
+
+ INCLUDE AsmMacroIoLib.inc
+
+ IMPORT CEntryPoint
+ EXPORT _ModuleEntryPoint
+
+ PRESERVE8
+ AREA PrePeiCoreEntryPoint, CODE, READONLY
+
+StartupAddr DCD CEntryPoint
+
+SCC_SYS_SW EQU 0x0004
+
+_ModuleEntryPoint
+ // Identify CPU ID
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, #0xf
+
+_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
+
+ // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector
+ LoadConstantToReg (FixedPcdGet32(PcdEmbeddedFdBaseAddress), 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)
+ ldr r2, StartupAddr
+
+ // jump to SEC C code
+ // r0 = core_id
+ // r1 = pei_core_address
+ blx r2
+
+ END
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
new file mode 100644
index 000000000..3f133d270
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
@@ -0,0 +1,63 @@
+#/** @file
+# Pre PeiCore - Hand-off to PEI Core in Normal World
+#
+# 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.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmPlatformPrePeiCore
+ FILE_GUID = 469fc080-aec1-11df-927c-0002a5d5c51b
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+[Sources.ARM]
+ PrePeiCoreEntryPoint.asm | RVCT
+ PrePeiCoreEntryPoint.S | GCC
+ PrePeiCore.c
+ MainMPCore.c
+ SwitchStack.asm | RVCT
+ SwitchStack.S | GCC
+ Exception.asm | RVCT
+ Exception.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
+ ArmLib
+ ArmPlatformLib
+ ArmMPCoreMailBoxLib
+ PL390GicNonSecLib
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid
+
+[FeaturePcd]
+ gArmPlatformTokenSpaceGuid.PcdStandalone
+
+[FixedPcd]
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedFdBaseAddress
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedFdSize
+
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize
+
+ gArmTokenSpaceGuid.PcdGicDistributorBase
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
new file mode 100644
index 000000000..3144a7a46
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
@@ -0,0 +1,61 @@
+#/** @file
+# Pre PeiCore - Hand-off to PEI Core in Normal World
+#
+# 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.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmPlatformPrePeiCore
+ FILE_GUID = 469fc080-aec1-11df-927c-0002a5d5c51b
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+[Sources.ARM]
+ PrePeiCoreEntryPoint.asm | RVCT
+ PrePeiCoreEntryPoint.S | GCC
+ PrePeiCore.c
+ MainUniCore.c
+ SwitchStack.asm | RVCT
+ SwitchStack.S | GCC
+ Exception.asm | RVCT
+ Exception.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
+ ArmLib
+ ArmPlatformLib
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid
+
+[FeaturePcd]
+ gArmPlatformTokenSpaceGuid.PcdStandalone
+
+[FixedPcd]
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedFdBaseAddress
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedFdSize
+
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize
+
+ gArmTokenSpaceGuid.PcdGicDistributorBase
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
diff --git a/ArmPlatformPkg/PrePeiCore/SwitchStack.S b/ArmPlatformPkg/PrePeiCore/SwitchStack.S
new file mode 100644
index 000000000..2543f5841
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/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>
+# 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
+
+GCC_ASM_EXPORT(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 R1, R13
+ add R1, R0, R1
+ mov R13, R1
+ bx LR
+
+
+
diff --git a/ArmPlatformPkg/PrePeiCore/SwitchStack.asm b/ArmPlatformPkg/PrePeiCore/SwitchStack.asm
new file mode 100644
index 000000000..10da81d6a
--- /dev/null
+++ b/ArmPlatformPkg/PrePeiCore/SwitchStack.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+; Portions copyright (c) 2008 - 2009, Apple Inc. 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.
+;
+;------------------------------------------------------------------------------
+
+ EXPORT SecSwitchStack
+
+ AREA Switch_Stack, CODE, READONLY
+
+;/**
+; 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
+; );
+;
+SecSwitchStack
+ MOV R1, SP
+ ADD R1, R0, R1
+ MOV SP, R1
+ BX LR
+ END