diff --git a/BeagleBoardPkg/BeagleBoardPkg.dsc b/BeagleBoardPkg/BeagleBoardPkg.dsc
index f74e58399989..a1715593770a 100644
--- a/BeagleBoardPkg/BeagleBoardPkg.dsc
+++ b/BeagleBoardPkg/BeagleBoardPkg.dsc
@@ -142,7 +142,6 @@ [LibraryClasses.common.SEC]
   ReportStatusCodeLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
   UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
   ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
-  LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
 
   PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
 
@@ -377,7 +376,10 @@ [Components.common]
   #
   # SEC
   #
-  ArmPlatformPkg/PrePi/PeiUniCore.inf
+  BeagleBoardPkg/PrePi/PeiUniCore.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
 
   #
   # DXE
diff --git a/BeagleBoardPkg/BeagleBoardPkg.fdf b/BeagleBoardPkg/BeagleBoardPkg.fdf
index 71249c7eb3d7..83d85fce4070 100644
--- a/BeagleBoardPkg/BeagleBoardPkg.fdf
+++ b/BeagleBoardPkg/BeagleBoardPkg.fdf
@@ -209,7 +209,7 @@ [FV.FVMAIN_COMPACT]
 READ_LOCK_CAP      = TRUE
 READ_LOCK_STATUS   = TRUE
 
-  INF ArmPlatformPkg/PrePi/PeiUniCore.inf
+  INF BeagleBoardPkg/PrePi/PeiUniCore.inf
 
   FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
     SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
diff --git a/BeagleBoardPkg/PrePi/Arm/ArchPrePi.c b/BeagleBoardPkg/PrePi/Arm/ArchPrePi.c
new file mode 100644
index 000000000000..075eb89e1b03
--- /dev/null
+++ b/BeagleBoardPkg/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/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.S b/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.S
new file mode 100644
index 000000000000..212cab62d44b
--- /dev/null
+++ b/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.S
@@ -0,0 +1,130 @@
+//
+//  Copyright (c) 2011-2015, 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 <Chipset/ArmV7.h>
+
+ASM_FUNC(_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   r8, r0
+
+_SetSVCMode:
+  // Enter SVC mode, Disable FIQ and IRQ
+  mov     r1, #(CPSR_MODE_SVC | CPSR_IRQ | CPSR_FIQ)
+  msr     CPSR_c, r1
+
+// 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)
+_SystemMemoryEndInit:
+  ADRL  (r1, mSystemMemoryEnd)
+  ldrd  r2, r3, [r1]
+  teq   r3, #0
+  moveq r1, r2
+  mvnne r1, #0
+
+_SetupStackPosition:
+  // r1 = SystemMemoryTop
+
+  // Calculate Top of the Firmware Device
+  MOV32 (r2, FixedPcdGet32(PcdFdBaseAddress))
+  MOV32 (r3, FixedPcdGet32(PcdFdSize) - 1)
+  add   r3, r3, r2      // r3 = FdTop = PcdFdBaseAddress + PcdFdSize
+
+  // UEFI Memory Size (stacks are allocated in this region)
+  MOV32 (r4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize))
+
+  //
+  // 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  r0, r1, r3      // r0 = SystemMemoryTop - FdTop
+  bmi   _SetupStack     // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
+  cmp   r0, r4
+  bge   _SetupStack
+
+  // Case the top of stacks is the FdBaseAddress
+  mov   r1, r2
+
+_SetupStack:
+  // r1 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  r9, r1, #1
+  bcs   _SetupOverflowStack
+
+_SetupAlignedStack:
+  mov   r1, r9
+  b     _GetBaseUefiMemory
+
+_SetupOverflowStack:
+  // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE
+  // aligned (4KB)
+  MOV32 (r9, ~EFI_PAGE_MASK & 0xFFFFFFFF)
+  and   r1, r1, r9
+
+_GetBaseUefiMemory:
+  // Calculate the Base of the UEFI Memory
+  sub   r9, r1, r4
+
+_GetStackBase:
+  // r1 = The top of the Mpcore Stacks
+  // Stack for the primary core = PrimaryCoreStack
+  MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+  sub   r10, r1, r2
+
+  // Stack for the secondary core = Number of Cores - 1
+  MOV32 (r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
+  sub   r10, r10, r1
+
+  // r10 = The base of the MpCore Stacks (primary stack & secondary stacks)
+  mov   r0, r10
+  mov   r1, r8
+  //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
+  MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+  MOV32 (r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
+  bl    ASM_PFX(ArmPlatformStackSet)
+
+  // Is it the Primary Core ?
+  mov   r0, r8
+  bl    ASM_PFX(ArmPlatformIsPrimaryCore)
+  cmp   r0, #1
+  bne   _PrepareArguments
+
+_PrepareArguments:
+  mov   r0, r8
+  mov   r1, r9
+  mov   r2, r10
+  mov   r3, sp
+
+  // Move sec startup address into a data register
+  // Ensure we're jumping to FV version of the code (not boot remapped alias)
+  ldr   r4, =ASM_PFX(CEntryPoint)
+
+  // Jump to PrePiCore C code
+  //    r0 = MpId
+  //    r1 = UefiMemoryBase
+  //    r2 = StacksBase
+  blx   r4
+
+_NeverReturn:
+  b _NeverReturn
diff --git a/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.asm b/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.asm
new file mode 100644
index 000000000000..80c2877cbdbf
--- /dev/null
+++ b/BeagleBoardPkg/PrePi/Arm/ModuleEntryPoint.asm
@@ -0,0 +1,148 @@
+//
+//  Copyright (c) 2011-2015, 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 <Chipset/ArmV7.h>
+
+  INCLUDE AsmMacroIoLib.inc
+
+  IMPORT  CEntryPoint
+  IMPORT  ArmPlatformIsPrimaryCore
+  IMPORT  ArmReadMpidr
+  IMPORT  ArmPlatformPeiBootAction
+  IMPORT  ArmPlatformStackSet
+  IMPORT  mSystemMemoryEnd
+
+  EXPORT  _ModuleEntryPoint
+
+  PRESERVE8
+  AREA    PrePiCoreEntryPoint, CODE, READONLY
+
+StartupAddr        DCD      CEntryPoint
+
+_ModuleEntryPoint
+  // Do early platform specific actions
+  bl    ArmPlatformPeiBootAction
+
+  // Get ID of this CPU in Multicore system
+  bl    ArmReadMpidr
+  // Keep a copy of the MpId register value
+  mov   r8, r0
+
+_SetSVCMode
+  // Enter SVC mode, Disable FIQ and IRQ
+  mov     r1, #(CPSR_MODE_SVC :OR: CPSR_IRQ :OR: CPSR_FIQ)
+  msr     CPSR_c, r1
+
+// 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)
+_SystemMemoryEndInit
+  adrll r1, mSystemMemoryEnd
+  ldrd  r2, r3, [r1]
+  teq   r3, #0
+  moveq r1, r2
+  mvnne r1, #0
+
+_SetupStackPosition
+  // r1 = SystemMemoryTop
+
+  // Calculate Top of the Firmware Device
+  mov32 r2, FixedPcdGet32(PcdFdBaseAddress)
+  mov32 r3, FixedPcdGet32(PcdFdSize)
+  sub   r3, r3, #1
+  add   r3, r3, r2      // r3 = FdTop = PcdFdBaseAddress + PcdFdSize
+
+  // UEFI Memory Size (stacks are allocated in this region)
+  mov32 r4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize)
+
+  //
+  // 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  r0, r1, r3      // r0 = SystemMemoryTop - FdTop
+  bmi   _SetupStack     // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
+  cmp   r0, r4
+  bge   _SetupStack
+
+  // Case the top of stacks is the FdBaseAddress
+  mov   r1, r2
+
+_SetupStack
+  // r1 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  r9, r1, #1
+  bcs   _SetupOverflowStack
+
+_SetupAlignedStack
+  mov   r1, r9
+  b     _GetBaseUefiMemory
+
+_SetupOverflowStack
+  // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE
+  // aligned (4KB)
+  mov32 r9, EFI_PAGE_MASK
+  and   r9, r9, r1
+  sub   r1, r1, r9
+
+_GetBaseUefiMemory
+  // Calculate the Base of the UEFI Memory
+  sub   r9, r1, r4
+
+_GetStackBase
+  // r1 = The top of the Mpcore Stacks
+  // Stack for the primary core = PrimaryCoreStack
+  mov32 r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)
+  sub   r10, r1, r2
+
+  // Stack for the secondary core = Number of Cores - 1
+  mov32 r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize)
+  sub   r10, r10, r1
+
+  // r10 = The base of the MpCore Stacks (primary stack & secondary stacks)
+  mov   r0, r10
+  mov   r1, r8
+  //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
+  mov32 r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)
+  mov32 r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize)
+  bl    ArmPlatformStackSet
+
+  // Is it the Primary Core ?
+  mov   r0, r8
+  bl    ArmPlatformIsPrimaryCore
+  cmp   r0, #1
+  bne   _PrepareArguments
+
+_PrepareArguments
+  mov   r0, r8
+  mov   r1, r9
+  mov   r2, r10
+
+  // Move sec startup address into a data register
+  // Ensure we're jumping to FV version of the code (not boot remapped alias)
+  ldr   r4, StartupAddr
+
+  // Jump to PrePiCore C code
+  //    r0 = MpId
+  //    r1 = UefiMemoryBase
+  //    r2 = StacksBase
+  blx   r4
+
+_NeverReturn
+  b _NeverReturn
+
+  END
diff --git a/BeagleBoardPkg/PrePi/LzmaDecompress.h b/BeagleBoardPkg/PrePi/LzmaDecompress.h
new file mode 100644
index 000000000000..a79ff343d231
--- /dev/null
+++ b/BeagleBoardPkg/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/BeagleBoardPkg/PrePi/MainUniCore.c b/BeagleBoardPkg/PrePi/MainUniCore.c
new file mode 100644
index 000000000000..56707362dcd1
--- /dev/null
+++ b/BeagleBoardPkg/PrePi/MainUniCore.c
@@ -0,0 +1,39 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  Copyright (c) 2017, Linaro, Ltd. 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                     StacksBase,
+  IN  UINT64                    StartTimeStamp
+  )
+{
+  PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
+
+  // We must never return
+  ASSERT(FALSE);
+}
+
+VOID
+SecondaryMain (
+  IN  UINTN                     MpId
+  )
+{
+  // We must never get into this function on UniCore system
+  ASSERT(FALSE);
+}
+
diff --git a/BeagleBoardPkg/PrePi/PeiUniCore.inf b/BeagleBoardPkg/PrePi/PeiUniCore.inf
new file mode 100644
index 000000000000..3d72bc5b46e1
--- /dev/null
+++ b/BeagleBoardPkg/PrePi/PeiUniCore.inf
@@ -0,0 +1,104 @@
+#/** @file
+#
+#  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
+#  Copyright (c) 2011-2017, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2017, Linaro, 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                    = 0x0001001A
+  BASE_NAME                      = BeagleBoardPrePiUniCore
+  FILE_GUID                      = 8a5dc3de-fe31-4ad9-9c93-dd73626932e7
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+
+[Sources]
+  PrePi.c
+  MainUniCore.c
+
+[Sources.ARM]
+  Arm/ArchPrePi.c
+  Arm/ModuleEntryPoint.S   | GCC
+  Arm/ModuleEntryPoint.asm | RVCT
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  ArmLib
+  ArmPlatformLib
+  ArmPlatformStackLib
+  BaseLib
+  DebugLib
+  DebugAgentLib
+  ExtractGuidedSectionLib
+  HobLib
+  IoLib
+  MemoryAllocationLib
+  MemoryInitPeiLib
+  PeCoffGetEntryPointLib
+  PlatformPeiLib
+  PrePiHobListPointerLib
+  PrePiLib
+  SerialPortLib
+  TimerLib
+
+[Ppis]
+  gArmMpCoreInfoPpiGuid
+
+[Guids]
+  gArmMpCoreInfoGuid
+  gEfiFirmwarePerformanceGuid
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+  gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdVFPEnabled
+
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+
+  gArmTokenSpaceGuid.PcdFvBaseAddress
+  gArmTokenSpaceGuid.PcdFvSize
+
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
+
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
+
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
diff --git a/BeagleBoardPkg/PrePi/PrePi.c b/BeagleBoardPkg/PrePi/PrePi.c
new file mode 100644
index 000000000000..6c4f34692dfb
--- /dev/null
+++ b/BeagleBoardPkg/PrePi/PrePi.c
@@ -0,0 +1,198 @@
+/** @file
+*
+*  Copyright (c) 2011-2017, ARM Limited. All rights reserved.
+*  Copyright (c) 2017, Linaro, Ltd. 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/PrintLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PerformanceLib.h>
+
+#include <Ppi/GuidedSectionExtraction.h>
+#include <Ppi/ArmMpCoreInfo.h>
+#include <Ppi/SecPerformance.h>
+#include <Guid/LzmaDecompress.h>
+
+#include "PrePi.h"
+#include "LzmaDecompress.h"
+
+#define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) || \
+                  ((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) < FixedPcdGet64 (PcdSystemMemoryBase)))
+
+UINT64 mSystemMemoryEnd = FixedPcdGet64(PcdSystemMemoryBase) +
+                          FixedPcdGet64(PcdSystemMemorySize) - 1;
+
+EFI_STATUS
+EFIAPI
+ExtractGuidedSectionLibConstructor (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+LzmaDecompressLibConstructor (
+  VOID
+  );
+
+EFI_STATUS
+GetPlatformPpi (
+  IN  EFI_GUID  *PpiGuid,
+  OUT VOID      **Ppi
+  )
+{
+  UINTN                   PpiListSize;
+  UINTN                   PpiListCount;
+  EFI_PEI_PPI_DESCRIPTOR  *PpiList;
+  UINTN                   Index;
+
+  PpiListSize = 0;
+  ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList);
+  PpiListCount = PpiListSize / sizeof(EFI_PEI_PPI_DESCRIPTOR);
+  for (Index = 0; Index < PpiListCount; Index++, PpiList++) {
+    if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) {
+      *Ppi = PpiList->Ppi;
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+VOID
+PrePiMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StacksBase,
+  IN  UINT64                    StartTimeStamp
+  )
+{
+  EFI_HOB_HANDOFF_INFO_TABLE*   HobList;
+  EFI_STATUS                    Status;
+  CHAR8                         Buffer[100];
+  UINTN                         CharCount;
+  UINTN                         StacksSize;
+  FIRMWARE_SEC_PERFORMANCE      Performance;
+
+  // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP)
+  ASSERT (IS_XIP() ||
+          ((FixedPcdGet64 (PcdFdBaseAddress) >= FixedPcdGet64 (PcdSystemMemoryBase)) &&
+           ((UINT64)(FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT64)mSystemMemoryEnd)));
+
+  // Initialize the architecture specific bits
+  ArchInitialize ();
+
+  // Initialize the Serial Port
+  SerialPortInitialize ();
+  CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware (version %s built at %a on %a)\n\r",
+    (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);
+  SerialPortWrite ((UINT8 *) Buffer, CharCount);
+
+  // Initialize the Debug Agent for Source Level Debugging
+  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
+  SaveAndSetDebugTimerInterrupt (TRUE);
+
+  // Declare the PI/UEFI memory region
+  HobList = HobConstructor (
+    (VOID*)UefiMemoryBase,
+    FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
+    (VOID*)UefiMemoryBase,
+    (VOID*)StacksBase  // The top of the UEFI Memory is reserved for the stacks
+    );
+  PrePeiSetHobList (HobList);
+
+  // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
+  Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
+  ASSERT_EFI_ERROR (Status);
+
+  StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
+  BuildStackHob (StacksBase, StacksSize);
+
+  //TODO: Call CpuPei as a library
+  BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
+
+  // Store timer value logged at the beginning of firmware image execution
+  Performance.ResetEnd = GetTimeInNanoSecond (StartTimeStamp);
+
+  // Build SEC Performance Data Hob
+  BuildGuidDataHob (&gEfiFirmwarePerformanceGuid, &Performance, sizeof (Performance));
+
+  // Set the Boot Mode
+  SetBootMode (ArmPlatformGetBootMode ());
+
+  // Initialize Platform HOBs (CpuHob and FvHob)
+  Status = PlatformPeim ();
+  ASSERT_EFI_ERROR (Status);
+
+  // 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                     MpId,
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StacksBase
+  )
+{
+  UINT64   StartTimeStamp;
+
+  // Initialize the platform specific controllers
+  ArmPlatformInitialize (MpId);
+
+  if (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 ();
+  } else {
+    StartTimeStamp = 0;
+  }
+
+  // Data Cache enabled on Primary core when MMU is enabled.
+  ArmDisableDataCache ();
+  // Invalidate Data cache
+  ArmInvalidateDataCache ();
+  // Invalidate instruction cache
+  ArmInvalidateInstructionCache ();
+  // Enable Instruction Caches on all cores.
+  ArmEnableInstructionCache ();
+
+  PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp);
+
+  // DXE Core should always load and never return
+  ASSERT (FALSE);
+}
diff --git a/BeagleBoardPkg/PrePi/PrePi.h b/BeagleBoardPkg/PrePi/PrePi.h
new file mode 100644
index 000000000000..e7f58e59240c
--- /dev/null
+++ b/BeagleBoardPkg/PrePi/PrePi.h
@@ -0,0 +1,90 @@
+/** @file
+*
+*  Copyright (c) 2011-2015, 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/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/ArmPlatformLib.h>
+
+#define SerialPrint(txt)  SerialPortWrite (txt, AsciiStrLen(txt)+1);
+
+extern UINT64 mSystemMemoryEnd;
+
+RETURN_STATUS
+EFIAPI
+TimerConstructor (
+  VOID
+  );
+
+VOID
+PrePiMain (
+  IN  UINTN                     UefiMemoryBase,
+  IN  UINTN                     StacksBase,
+  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                     StacksBase,
+  IN  UINT64                    StartTimeStamp
+  );
+
+VOID
+SecondaryMain (
+  IN  UINTN                     MpId
+  );
+
+// Either implemented by PrePiLib or by MemoryInitPei
+VOID
+BuildMemoryTypeInformationHob (
+  VOID
+  );
+
+EFI_STATUS
+GetPlatformPpi (
+  IN  EFI_GUID  *PpiGuid,
+  OUT VOID      **Ppi
+  );
+
+// Initialize the Architecture specific controllers
+VOID
+ArchInitialize (
+  VOID
+  );
+
+#endif /* _PREPI_H_ */
