diff --git a/ArmPlatformPkg/PrePi/Exception.S b/ArmPlatformPkg/PrePi/Exception.S
new file mode 100755
index 0000000000..628793e031
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/Exception.S
@@ -0,0 +1,102 @@
+//
+//  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(PrePiCommonExceptionEntry)
+
+# EXPORT
+GCC_ASM_EXPORT(PrePiVectorTable)
+
+//============================================================
+//Default Exception Handlers
+//============================================================
+  
+  
+ASM_PFX(PrePiVectorTable):
+  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(PrePiCommonExceptionEntry)
+
+_DefaultUndefined:
+  sub  r1, LR, #4
+  # Switch to SVC for common stack
+  cps  #0x13
+  mov  r0, #1
+   blx   ASM_PFX(PrePiCommonExceptionEntry)
+
+_DefaultSWI:
+  sub  r1, LR, #4
+  # Switch to SVC for common stack
+  cps  #0x13
+  mov  r0, #2
+   blx   ASM_PFX(PrePiCommonExceptionEntry)
+
+_DefaultPrefetchAbort:
+  sub  r1, LR, #4
+  # Switch to SVC for common stack
+  cps  #0x13
+  mov  r0, #3
+   blx   ASM_PFX(PrePiCommonExceptionEntry)
+
+_DefaultDataAbort:
+  sub  r1, LR, #8
+  # Switch to SVC for common stack
+  cps  #0x13
+  mov  r0, #4
+   blx   ASM_PFX(PrePiCommonExceptionEntry)
+
+_DefaultReserved:
+  mov  r1, lr
+  # Switch to SVC for common stack
+  cps  #0x13
+  mov  r0, #5
+   blx   ASM_PFX(PrePiCommonExceptionEntry)
+
+_DefaultIrq:
+  sub  r1, LR, #4
+  # Switch to SVC for common stack
+  cps  #0x13
+  mov  r0, #6
+   blx   ASM_PFX(PrePiCommonExceptionEntry)
+
+_DefaultFiq:
+  sub  r1, LR, #4
+  # Switch to SVC for common stack
+  cps  #0x13
+  mov  r0, #7
+   blx   ASM_PFX(PrePiCommonExceptionEntry)
+
diff --git a/ArmPlatformPkg/PrePi/Exception.asm b/ArmPlatformPkg/PrePi/Exception.asm
new file mode 100644
index 0000000000..26f41d19e0
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/Exception.asm
@@ -0,0 +1,91 @@
+//
+//  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  PrePiCommonExceptionEntry
+  EXPORT  PrePiVectorTable
+  
+  PRESERVE8
+  AREA    PrePeiCoreException, CODE, READONLY, CODEALIGN, ALIGN=5
+
+//============================================================
+//Default Exception Handlers
+//============================================================
+//TODO: there should be better way to handle the exceptions during the early stage. At the moment they are spinning in infinite loop
+  
+PrePiVectorTable
+  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   PrePiCommonExceptionEntry
+
+_DefaultUndefined
+   sub  r1, LR, #4
+   cps       #0x13                     ; Switch to SVC for common stack
+   mov  r0, #1
+   blx   PrePiCommonExceptionEntry
+
+_DefaultSWI
+   sub  r1, LR, #4
+   cps       #0x13                     ; Switch to SVC for common stack
+   mov  r0, #2
+   blx   PrePiCommonExceptionEntry
+
+_DefaultPrefetchAbort
+   sub  r1, LR, #4
+   cps       #0x13                     ; Switch to SVC for common stack
+   mov  r0, #3
+   blx   PrePiCommonExceptionEntry
+
+_DefaultDataAbort
+   sub  r1, LR, #8
+   cps       #0x13                     ; Switch to SVC for common stack
+   mov  r0, #4
+   blx   PrePiCommonExceptionEntry
+
+_DefaultReserved
+   mov  r1, lr
+   cps       #0x13                     ; Switch to SVC for common stack
+   mov  r0, #5
+   blx   PrePiCommonExceptionEntry
+   
+_DefaultIrq
+   sub  r1, LR, #4
+   cps       #0x13                     ; Switch to SVC for common stack
+   mov  r0, #6
+   blx   PrePiCommonExceptionEntry
+
+_DefaultFiq
+   sub  r1, LR, #4
+   cps       #0x13                     ; Switch to SVC for common stack
+   mov  r0, #7
+   blx   PrePiCommonExceptionEntry
+
+  END
diff --git a/ArmPlatformPkg/PrePi/LzmaDecompress.h b/ArmPlatformPkg/PrePi/LzmaDecompress.h
new file mode 100644
index 0000000000..e4483b6823
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/LzmaDecompress.h
@@ -0,0 +1,103 @@
+/** @file
+  LZMA Decompress Library header file
+
+  Copyright (c) 2006 - 2010, Intel Corporation. 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.
+
+**/
+
+#ifndef __LZMA_DECOMPRESS_H___
+#define __LZMA_DECOMPRESS_H___
+
+/**
+  Examines a GUIDed section and returns the size of the decoded buffer and the
+  size of an scratch buffer required to actually decode the data in a GUIDed section.
+
+  Examines a GUIDed section specified by InputSection.  
+  If GUID for InputSection does not match the GUID that this handler supports,
+  then RETURN_UNSUPPORTED is returned.  
+  If the required information can not be retrieved from InputSection,
+  then RETURN_INVALID_PARAMETER is returned.
+  If the GUID of InputSection does match the GUID that this handler supports,
+  then the size required to hold the decoded buffer is returned in OututBufferSize,
+  the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field
+  from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute.
+  
+  If InputSection is NULL, then ASSERT().
+  If OutputBufferSize is NULL, then ASSERT().
+  If ScratchBufferSize is NULL, then ASSERT().
+  If SectionAttribute is NULL, then ASSERT().
+
+
+  @param[in]  InputSection       A pointer to a GUIDed section of an FFS formatted file.
+  @param[out] OutputBufferSize   A pointer to the size, in bytes, of an output buffer required
+                                 if the buffer specified by InputSection were decoded.
+  @param[out] ScratchBufferSize  A pointer to the size, in bytes, required as scratch space
+                                 if the buffer specified by InputSection were decoded.
+  @param[out] SectionAttribute   A pointer to the attributes of the GUIDed section. See the Attributes
+                                 field of EFI_GUID_DEFINED_SECTION in the PI Specification.
+
+  @retval  RETURN_SUCCESS            The information about InputSection was returned.
+  @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.
+  @retval  RETURN_INVALID_PARAMETER  The information can not be retrieved from the section specified by InputSection.
+
+**/
+RETURN_STATUS
+EFIAPI
+LzmaGuidedSectionGetInfo (
+  IN  CONST VOID  *InputSection,
+  OUT UINT32      *OutputBufferSize,
+  OUT UINT32      *ScratchBufferSize,
+  OUT UINT16      *SectionAttribute
+  );
+
+/**
+  Decompress a LZAM compressed GUIDed section into a caller allocated output buffer.
+  
+  Decodes the GUIDed section specified by InputSection.  
+  If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned.  
+  If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned.
+  If the GUID of InputSection does match the GUID that this handler supports, then InputSection
+  is decoded into the buffer specified by OutputBuffer and the authentication status of this
+  decode operation is returned in AuthenticationStatus.  If the decoded buffer is identical to the
+  data in InputSection, then OutputBuffer is set to point at the data in InputSection.  Otherwise,
+  the decoded data will be placed in caller allocated buffer specified by OutputBuffer.
+  
+  If InputSection is NULL, then ASSERT().
+  If OutputBuffer is NULL, then ASSERT().
+  If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().
+  If AuthenticationStatus is NULL, then ASSERT().
+
+
+  @param[in]  InputSection  A pointer to a GUIDed section of an FFS formatted file.
+  @param[out] OutputBuffer  A pointer to a buffer that contains the result of a decode operation. 
+  @param[out] ScratchBuffer A caller allocated buffer that may be required by this function
+                            as a scratch buffer to perform the decode operation. 
+  @param[out] AuthenticationStatus 
+                            A pointer to the authentication status of the decoded output buffer.
+                            See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
+                            section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must
+                            never be set by this handler.
+
+  @retval  RETURN_SUCCESS            The buffer specified by InputSection was decoded.
+  @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.
+  @retval  RETURN_INVALID_PARAMETER  The section specified by InputSection can not be decoded.
+
+**/
+RETURN_STATUS
+EFIAPI
+LzmaGuidedSectionExtraction (
+  IN CONST  VOID    *InputSection,
+  OUT       VOID    **OutputBuffer,
+  OUT       VOID    *ScratchBuffer,        OPTIONAL
+  OUT       UINT32  *AuthenticationStatus
+  );
+  
+#endif // __LZMADECOMPRESS_H__
+
diff --git a/ArmPlatformPkg/PrePi/MainMPCore.c b/ArmPlatformPkg/PrePi/MainMPCore.c
new file mode 100644
index 0000000000..238b919e29
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/MainMPCore.c
@@ -0,0 +1,68 @@
+/** @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 "PrePi.h"
+
+#include <Library/ArmMPCoreMailBoxLib.h>
+#include <Chipset/ArmV7.h>
+#include <Drivers/PL390Gic.h>
+
+VOID
+PrimaryMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StackBase,
+  IN  UINT64                    StartTimeStamp
+  )
+{
+  //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 (!FixedPcdGet32(PcdStandalone)) {
+    // Sending SGI to all the Secondary CPU interfaces
+    PL390GicSendSgiTo (PcdGet32(PcdGicDistributorBase), GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E);
+  }
+
+  PrePiMain (UefiMemoryBase, StackBase, StartTimeStamp);
+
+  // We must never return
+  ASSERT(FALSE);
+}
+
+VOID
+SecondaryMain (
+  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);
+}
diff --git a/ArmPlatformPkg/PrePi/MainUniCore.c b/ArmPlatformPkg/PrePi/MainUniCore.c
new file mode 100644
index 0000000000..f8ce408f6d
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/MainUniCore.c
@@ -0,0 +1,38 @@
+/** @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 "PrePi.h"
+
+VOID
+PrimaryMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StackBase,
+  IN  UINT64                    StartTimeStamp
+  )
+{
+  PrePiMain (UefiMemoryBase, StackBase, StartTimeStamp);
+
+  // We must never return
+  ASSERT(FALSE);
+}
+
+VOID
+SecondaryMain (
+  IN  UINTN                     CoreId
+  )
+{
+  // We must never get into this function on UniCore system
+  ASSERT(FALSE);
+}
+
diff --git a/ArmPlatformPkg/PrePi/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/ModuleEntryPoint.S
new file mode 100755
index 0000000000..0857024a27
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/ModuleEntryPoint.S
@@ -0,0 +1,84 @@
+//
+//  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
+
+_UefiMemoryBase:
+#if FixedPcdGet32(PcdStandalone)
+  // Compute Top of System Memory
+  LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryBase), r1)
+  LoadConstantToReg (FixedPcdGet32(PcdSystemMemorySize), r2)
+  add   r1, r1, r2      // r1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize
+#else
+  // If it is not a Standalone, we must compute the top of the UEFI memory with the base of the FD
+  LoadConstantToReg (FixedPcdGet32(PcdNormalFdBaseAddress), r1)
+#endif
+
+  // Compute Base of UEFI Memory
+  LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), r2)
+  sub   r1, r1, r2      // r1 = SystemMemoryTop - PcdSystemMemoryUefiRegionSize = UefiMemoryBase
+
+_SetupStack:
+  // Compute Base of Normal stacks for CPU Cores
+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackSize), r2)
+  mul   r3, r0, r2      // r3 = core_id * stack_size = offset from the stack base
+  sub   sp, r1, r3      // r3 = UefiMemoryBase - StackOffset = TopOfStack
+
+  // Only allocate memory in top of the primary core stack
+  cmp   r0, #0
+  bne   _PrepareArguments
+
+_AllocateGlobalPeiVariables:
+  // Reserve top of the stack for Global PEI Variables (eg: PeiServicesTablePointer)
+  LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r4)
+  // The reserved place must be 8-bytes aligned for pushing 64-bit variable on the stack
+  and   r5, r4, #7
+  rsb   r5, r5, #8
+  add   r4, r4, r5
+  sub   sp, sp, r4
+
+_PrepareArguments:
+  // Pass the StackBase to the C Entrypoint (UefiMemoryBase - StackSize - StackOffset)
+  sub   r2, r1, r2
+  sub   r2, r3
+  // 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 PrePiCore C code
+  //    r0 = core_id
+  //    r1 = UefiMemoryBase
+  //    r2 = StackBase
+  blx   r3
+
diff --git a/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm b/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm
new file mode 100644
index 0000000000..52690f8ecd
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm
@@ -0,0 +1,82 @@
+//
+//  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    PrePiCoreEntryPoint, CODE, READONLY
+  
+StartupAddr        DCD      CEntryPoint
+
+_ModuleEntryPoint
+  // Identify CPU ID
+  mrc   p15, 0, r0, c0, c0, 5
+  and   r0, #0xf
+
+_UefiMemoryBase
+#if FixedPcdGet32(PcdStandalone)
+  // Compute Top of System Memory
+  LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryBase), r1)
+  LoadConstantToReg (FixedPcdGet32(PcdSystemMemorySize), r2)
+  add   r1, r1, r2      // r1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize
+#else
+  // If it is not a Standalone, we must compute the top of the UEFI memory with the base of the FD
+  LoadConstantToReg (FixedPcdGet32(PcdNormalFdBaseAddress), r1)
+#endif
+
+  // Compute Base of UEFI Memory
+  LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), r2)
+  sub   r1, r1, r2      // r1 = SystemMemoryTop - PcdSystemMemoryUefiRegionSize = UefiMemoryBase
+
+_SetupStack
+  // Compute Base of Normal stacks for CPU Cores
+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackSize), r2)
+  mul   r3, r0, r2      // r3 = core_id * stack_size = offset from the stack base
+  sub   sp, r1, r3      // r3 = UefiMemoryBase - StackOffset = TopOfStack
+
+  // Only allocate memory in top of the primary core stack
+  cmp   r0, #0
+  bne   _PrepareArguments
+
+_AllocateGlobalPrePiVariables
+  // Reserve top of the stack for Global PEI Variables (eg: PeiServicesTablePointer)
+  LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r4)
+  // The reserved place must be 8-bytes aligned for pushing 64-bit variable on the stack
+  and   r5, r4, #7
+  rsb   r5, r5, #8
+  add   r4, r4, r5
+  sub   sp, sp, r4
+
+_PrepareArguments
+  // Pass the StackBase to the C Entrypoint (UefiMemoryBase - StackSize - StackOffset)
+  sub   r2, r1, r2
+  sub   r2, r3
+  // 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 PrePiCore C code
+  //    r0 = core_id
+  //    r1 = UefiMemoryBase
+  //    r2 = StackBase
+  blx   r3
+
+  END
diff --git a/ArmPlatformPkg/PrePi/PeiMPCore.inf b/ArmPlatformPkg/PrePi/PeiMPCore.inf
new file mode 100755
index 0000000000..256fcafee9
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/PeiMPCore.inf
@@ -0,0 +1,99 @@
+#/** @file
+#  
+#  Copyright (c) 2011, 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.
+#  
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmPlatformPrePiMPCore
+  FILE_GUID                      = d959e387-7b91-452c-90e0-a1dbac90ddb8
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+
+[Sources.ARM]
+  PrePi.c
+  ModuleEntryPoint.S   | GCC
+  ModuleEntryPoint.asm | RVCT
+  Exception.S | GCC
+  Exception.asm | RVCT
+  MainMPCore.c
+  
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  DebugAgentLib
+  ArmLib
+  ArmMPCoreMailBoxLib
+  PL390GicNonSecLib
+  IoLib
+  TimerLib
+  SerialPortLib
+  ExtractGuidedSectionLib
+  LzmaDecompressLib
+  PeCoffGetEntryPointLib
+  DebugAgentLib
+  PrePiLib
+  ArmPlatformLib
+  MemoryAllocationLib
+  HobLib
+  PrePiHobListPointerLib
+  PlatformPeiLib
+  MemoryInitPeiLib
+
+[FeaturePcd]  
+  gEmbeddedTokenSpaceGuid.PcdCacheEnable
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+
+[FixedPcd]
+  gArmPlatformTokenSpaceGuid.PcdStandalone
+  gArmTokenSpaceGuid.PcdVFPEnabled
+
+  gArmTokenSpaceGuid.PcdNormalFdBaseAddress
+  gArmTokenSpaceGuid.PcdNormalFdSize
+
+  gArmTokenSpaceGuid.PcdNormalFvBaseAddress
+  gArmTokenSpaceGuid.PcdNormalFvSize
+
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize
+
+  gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize
+  gArmPlatformTokenSpaceGuid.PcdHobListPtrGlobalOffset
+
+  gArmTokenSpaceGuid.PcdGicDistributorBase
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
+
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryFixRegionSize
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+  
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
+
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PrePi/PeiUniCore.inf
new file mode 100755
index 0000000000..c28fe3c6cb
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/PeiUniCore.inf
@@ -0,0 +1,93 @@
+#/** @file
+#  
+#  Copyright (c) 2011, 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.
+#  
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmPlatformPrePiUniCore
+  FILE_GUID                      = d959e387-7b91-452c-90e0-a1dbac90ddb8
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+
+[Sources.ARM]
+  PrePi.c
+  ModuleEntryPoint.S   | GCC
+  ModuleEntryPoint.asm | RVCT
+  Exception.asm | RVCT
+  Exception.S | GCC
+  MainUniCore.c
+  
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  DebugAgentLib
+  ArmLib
+  IoLib
+  TimerLib
+  SerialPortLib
+  ExtractGuidedSectionLib
+  LzmaDecompressLib
+  PeCoffGetEntryPointLib
+  DebugAgentLib
+  PrePiLib
+  ArmPlatformLib
+  MemoryAllocationLib
+  HobLib
+  PrePiHobListPointerLib
+  PlatformPeiLib
+  MemoryInitPeiLib
+
+[FeaturePcd]  
+  gEmbeddedTokenSpaceGuid.PcdCacheEnable
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+
+[FixedPcd]
+  gArmPlatformTokenSpaceGuid.PcdStandalone
+  gArmTokenSpaceGuid.PcdVFPEnabled
+
+  gArmTokenSpaceGuid.PcdNormalFdBaseAddress
+  gArmTokenSpaceGuid.PcdNormalFdSize
+
+  gArmTokenSpaceGuid.PcdNormalFvBaseAddress
+  gArmTokenSpaceGuid.PcdNormalFvSize
+
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize
+
+  gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize
+  gArmPlatformTokenSpaceGuid.PcdHobListPtrGlobalOffset
+
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryFixRegionSize
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+  
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
+
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c
new file mode 100755
index 0000000000..501821465a
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/PrePi.c
@@ -0,0 +1,213 @@
+/** @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/DebugAgentLib.h>
+#include <Library/PrePiLib.h>
+#include <Library/IoLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PerformanceLib.h>
+
+#include <Ppi/GuidedSectionExtraction.h>
+#include <Guid/LzmaDecompress.h>
+
+#include "PrePi.h"
+#include "LzmaDecompress.h"
+
+VOID
+PrePiCommonExceptionEntry (
+  IN UINT32 Entry,
+  IN UINT32 LR
+  );
+
+EFI_STATUS
+EFIAPI
+ExtractGuidedSectionLibConstructor (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+LzmaDecompressLibConstructor (
+  VOID
+  );
+
+VOID
+PrePiMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StackBase,
+  IN  UINT64                    StartTimeStamp
+  )
+{
+  EFI_HOB_HANDOFF_INFO_TABLE**   PrePiHobBase;
+  EFI_STATUS                    Status;
+  CHAR8                         Buffer[100];
+  UINTN                         CharCount;
+
+  // Enable program flow prediction, if supported.
+  ArmEnableBranchPrediction ();
+
+  if (FixedPcdGet32(PcdVFPEnabled)) {
+    ArmEnableVFP();
+  }
+
+  // Initialize the Serial Port
+  SerialPortInitialize ();
+  CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware built at %a on %a\n\r",__TIME__, __DATE__);
+  SerialPortWrite ((UINT8 *) Buffer, CharCount);
+
+  // Initialize the Debug Agent for Source Level Debugging
+  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
+  SaveAndSetDebugTimerInterrupt (TRUE);
+
+  PrePiHobBase = (EFI_HOB_HANDOFF_INFO_TABLE**)(PcdGet32 (PcdCPUCoresNonSecStackBase) + (PcdGet32 (PcdCPUCoresNonSecStackSize) / 2) - PcdGet32 (PcdHobListPtrGlobalOffset));
+
+  // We leave UINT32 at the top of UEFI memory for PcdPrePiHobBase
+  *PrePiHobBase = HobConstructor (
+    (VOID*)UefiMemoryBase,
+    FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
+    (VOID*)UefiMemoryBase,
+    (VOID*)(UefiMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) - sizeof(UINT32)));
+
+  // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
+  Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
+  ASSERT_EFI_ERROR (Status);
+
+  // Create the Stack HOB
+  BuildStackHob (StackBase, FixedPcdGet32(PcdCPUCoresNonSecStackSize));
+
+  // Set the Boot Mode
+  SetBootMode (ArmPlatformGetBootMode ());
+
+  // Initialize Platform HOBs (CpuHob and FvHob)
+  Status = PlatformPeim ();
+  ASSERT_EFI_ERROR (Status);
+
+  BuildMemoryTypeInformationHob ();
+
+  //InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL, NULL);
+  //SaveAndSetDebugTimerInterrupt (TRUE);
+
+  // Now, the HOB List has been initialized, we can register performance information
+  PERF_START (NULL, "PEI", NULL, StartTimeStamp);
+
+  // SEC phase needs to run library constructors by hand.
+  ExtractGuidedSectionLibConstructor ();
+  LzmaDecompressLibConstructor ();
+
+  // Build HOBs to pass up our version of stuff the DXE Core needs to save space
+  BuildPeCoffLoaderHob ();
+  BuildExtractSectionHob (
+    &gLzmaCustomDecompressGuid,
+    LzmaGuidedSectionGetInfo,
+    LzmaGuidedSectionExtraction
+    );
+
+  // Assume the FV that contains the SEC (our code) also contains a compressed FV.
+  Status = DecompressFirstFv ();
+  ASSERT_EFI_ERROR (Status);
+
+  // Load the DXE Core and transfer control to it
+  Status = LoadDxeCoreFromFv (NULL, 0);
+  ASSERT_EFI_ERROR (Status);
+}
+
+VOID
+CEntryPoint (
+  IN  UINTN                     CoreId,
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StackBase
+  )
+{
+  UINT64   StartTimeStamp;
+
+  if ((CoreId == 0) && PerformanceMeasurementEnabled ()) {
+    // Initialize the Timer Library to setup the Timer HW controller
+    TimerConstructor ();
+    // We cannot call yet the PerformanceLib because the HOB List has not been initialized
+    StartTimeStamp = GetPerformanceCounter ();
+  }
+
+  //Clean Data cache
+  ArmCleanInvalidateDataCache();
+
+  //Invalidate instruction cache
+  ArmInvalidateInstructionCache();
+
+  //TODO:Drain Write Buffer
+
+  // Enable Instruction & Data caches
+  ArmEnableDataCache();
+  ArmEnableInstructionCache();
+
+  // Write VBAR - The Vector table must be 32-byte aligned
+  ASSERT(((UINT32)PrePiVectorTable & ((1 << 5)-1)) == 0);
+  ArmWriteVBar((UINT32)PrePiVectorTable);
+
+  //If not primary Jump to Secondary Main
+  if(0 == CoreId) {
+    // Goto primary Main.
+    PrimaryMain (UefiMemoryBase, StackBase, StartTimeStamp);
+  } else {
+    SecondaryMain (CoreId);
+  }
+
+  // DXE Core should always load and never return
+  ASSERT (FALSE);
+}
+
+VOID
+PrePiCommonExceptionEntry (
+  IN UINT32 Entry,
+  IN UINT32 LR
+  )
+{
+  CHAR8           Buffer[100];
+  UINTN           CharCount;
+
+  switch (Entry) {
+  case 0:
+    CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Reset Exception at 0x%X\n\r",LR);
+    break;
+  case 1:
+    CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Undefined Exception at 0x%X\n\r",LR);
+    break;
+  case 2:
+    CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"SWI Exception at 0x%X\n\r",LR);
+    break;
+  case 3:
+    CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"PrefetchAbort Exception at 0x%X\n\r",LR);
+    break;
+  case 4:
+    CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"DataAbort Exception at 0x%X\n\r",LR);
+    break;
+  case 5:
+    CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Reserved Exception at 0x%X\n\r",LR);
+    break;
+  case 6:
+    CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"IRQ Exception at 0x%X\n\r",LR);
+    break;
+  case 7:
+    CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"FIQ 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/PrePi/PrePi.h b/ArmPlatformPkg/PrePi/PrePi.h
new file mode 100644
index 0000000000..b1d39c669a
--- /dev/null
+++ b/ArmPlatformPkg/PrePi/PrePi.h
@@ -0,0 +1,82 @@
+/** @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.
+*
+**/
+
+#ifndef _PREPI_H_
+#define _PREPI_H_
+
+#include <PiPei.h>
+
+#include <Library/PcdLib.h>
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/ArmPlatformLib.h>
+
+#include <Chipset/ArmV7.h>
+
+#define SerialPrint(txt)  SerialPortWrite (txt, AsciiStrLen(txt)+1);
+
+// Vector Table for PrePi Phase
+VOID
+PrePiVectorTable (
+  VOID
+  );
+
+RETURN_STATUS
+EFIAPI
+TimerConstructor (
+  VOID
+  );
+
+VOID
+PrePiMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StackBase,
+  IN  UINT64                    StartTimeStamp
+  );
+
+EFI_STATUS
+EFIAPI
+MemoryPeim (
+  IN EFI_PHYSICAL_ADDRESS               UefiMemoryBase,
+  IN UINT64                             UefiMemorySize
+  );
+
+EFI_STATUS
+EFIAPI
+PlatformPeim (
+  VOID
+  );
+
+VOID
+PrimaryMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StackBase,
+  IN  UINT64                    StartTimeStamp
+  );
+
+VOID
+SecondaryMain (
+  IN  UINTN                     CoreId
+  );
+
+// Either implemented by PrePiLib or by MemoryInitPei
+VOID
+BuildMemoryTypeInformationHob (
+  VOID
+  );
+
+#endif /* _PREPI_H_ */