summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlias Apalodimas <ilias.apalodimas@linaro.org>2020-05-14 10:43:44 +0300
committerIlias Apalodimas <ilias.apalodimas@linaro.org>2020-06-02 15:00:47 +0300
commit71f6a5e46cae4e248c9f9a02eb0781b8051e9d99 (patch)
tree50d111f9055d191093e606518f2280f161f77142
parent17d3a820ff7f0f22e5f556be5a09ca244eaf77d9 (diff)
StandaloneMmPkg/StandaloneMmCoreEntryPointRelocatable: Relocatable version for StandAloneMMstmm_reloc
Since StMM can be compiled as a binary that runs on OP-TEE, we need to make it self-relocatable since the OP-TEE load address can be randomized Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-rw-r--r--StandaloneMmPkg/Core/Scripts/StMM-PIE.lds54
-rw-r--r--StandaloneMmPkg/Core/StandaloneMmCoreRelocatable.inf79
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/ModuleEntryPoint.S107
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPointRelocatable.c301
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPointRelocatable.inf51
5 files changed, 592 insertions, 0 deletions
diff --git a/StandaloneMmPkg/Core/Scripts/StMM-PIE.lds b/StandaloneMmPkg/Core/Scripts/StMM-PIE.lds
new file mode 100644
index 0000000000..a1d7012c4c
--- /dev/null
+++ b/StandaloneMmPkg/Core/Scripts/StMM-PIE.lds
@@ -0,0 +1,54 @@
+/** @file
+
+ Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+SECTIONS
+{
+ PROVIDE(__reloc_base = .);
+
+ . = PECOFF_HEADER_SIZE;
+ .text : ALIGN(CONSTANT(COMMONPAGESIZE)) {
+ *(.text.reloc*)
+ . = ALIGN(0x1000);
+ PROVIDE(__stmm_start = .);
+ *(.text .text*)
+ . = ALIGN(0x20);
+ PROVIDE(__reloc_start = .);
+ *(.rel .rel.*)
+ *(.rela .rela.*)
+ PROVIDE(__reloc_end = .);
+ }
+ PROVIDE(__ro_start = .);
+ .got : ALIGN(CONSTANT(COMMONPAGESIZE)) {
+ *(.got .got*)
+ }
+ .rodata : ALIGN(CONSTANT(COMMONPAGESIZE)) {
+ *(.rodata .rodata*)
+ }
+ PROVIDE(__ro_end = .);
+ .data : ALIGN(CONSTANT(COMMONPAGESIZE)) {
+ *(.data .data*)
+ }
+ .bss : ALIGN(CONSTANT(COMMONPAGESIZE)) {
+ *(.bss .bss*)
+ }
+ PROVIDE(__stmm_end = .);
+
+ .note (INFO) : { *(.note.gnu.build-id) }
+
+ /DISCARD/ : {
+ *(.note.GNU-stack)
+ *(.gnu.hash)
+ *(.gnu_debuglink)
+ *(.interp)
+ *(.dynamic)
+ *(.dynsym)
+ *(.dynstr)
+ *(.hash)
+ *(.comment)
+ }
+}
diff --git a/StandaloneMmPkg/Core/StandaloneMmCoreRelocatable.inf b/StandaloneMmPkg/Core/StandaloneMmCoreRelocatable.inf
new file mode 100644
index 0000000000..1de7e52d4c
--- /dev/null
+++ b/StandaloneMmPkg/Core/StandaloneMmCoreRelocatable.inf
@@ -0,0 +1,79 @@
+## @file
+# This module provide an SMM CIS compliant implementation of SMM Core.
+#
+# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = StandaloneMmCore
+ FILE_GUID = 6E14B6FD-3600-4DD6-A17A-206B3B6DCE16
+ MODULE_TYPE = MM_CORE_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ ENTRY_POINT = StandaloneMmMain
+
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+
+[Sources]
+ StandaloneMmCore.c
+ StandaloneMmCore.h
+ StandaloneMmCorePrivateData.h
+ Page.c
+ Pool.c
+ Handle.c
+ Locate.c
+ Notify.c
+ Dependency.c
+ Dispatcher.c
+ Mmi.c
+ InstallConfigurationTable.c
+ FwVol.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ CacheMaintenanceLib
+ DebugLib
+ ExtractGuidedSectionLib
+ FvLib
+ HobLib
+ MemoryAllocationLib
+ MemLib
+ PeCoffLib
+ ReportStatusCodeLib
+ StandaloneMmCoreEntryPoint
+
+[Protocols]
+ gEfiDxeMmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister
+ gEfiMmReadyToLockProtocolGuid ## PRODUCES
+ gEfiMmEndOfDxeProtocolGuid ## PRODUCES
+ gEfiLoadedImageProtocolGuid ## PRODUCES
+ gEfiMmConfigurationProtocolGuid ## CONSUMES
+
+[Guids]
+ gAprioriGuid ## SOMETIMES_CONSUMES ## File
+ gEfiEventDxeDispatchGuid ## PRODUCES ## GUID # SmiHandlerRegister
+ gEfiEndOfDxeEventGroupGuid ## PRODUCES ## GUID # SmiHandlerRegister
+ ## SOMETIMES_CONSUMES ## GUID # Locate protocol
+ ## SOMETIMES_PRODUCES ## GUID # SmiHandlerRegister
+ gEdkiiMemoryProfileGuid
+ gZeroGuid ## SOMETIMES_CONSUMES ## GUID
+ gEfiHobListGuid
+ gMmCoreDataHobGuid
+ gMmFvDispatchGuid
+ gEfiEventLegacyBootGuid
+ gEfiEventExitBootServicesGuid
+ gEfiEventReadyToBootGuid
+
+[BuildOptions]
+ GCC:*_*_*_DLINK_FLAGS = -Wl,-Bsymbolic,-pie,-T,$(MODULE_DIR)/Scripts/StMM-PIE.lds
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/ModuleEntryPoint.S b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/ModuleEntryPoint.S
new file mode 100644
index 0000000000..212b9b4431
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/ModuleEntryPoint.S
@@ -0,0 +1,107 @@
+//
+// Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+// Copyright (c) 2015-2016, Linaro Limited. All rights reserved.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroIoLibV8.h>
+ASM_FUNC(_ModuleEntryPoint)
+ //
+ // We are built as a ET_DYN PIE executable, so we need to process all
+ // relative relocations regardless of whether or not we are executing from
+ // the same offset we were linked at. This is only possible if we are
+ // running from RAM.
+ adr x8, __reloc_base
+ adr x9, __reloc_start
+ adr x10, __reloc_end
+ bl _SetMemoryAttrtibutes
+ b ASM_PFX(ModuleEntryPoint)
+
+.section .text.reloc, "ax"
+_SetMemoryAttrtibutes:
+ mov x20, x0
+ mov x21, x1
+ mov x22, x2
+ mov x23, x3
+ mov x24, x11
+ mov x25, x12
+ mov x26, x13
+
+ // Set all of the memory as r/w
+ adr x11, __stmm_start
+ adr x13, __stmm_end
+ ldr x0, =0xC4000065
+ ldr x12, =0x1000
+ and x1, x11, #~0x0fff // Align to page
+ sub x11, x13, x11
+ add x11, x11, #0x0fff
+ and x11, x11, #~0x0fff // Roundup
+ udiv x11, x11, x12 // nr pages
+ mov x2, x11
+ ldr x3, =0x5 // Set perms to r/w
+ svc #0
+
+// reloc
+.Lreloc_loop:
+ cmp x9, x10
+ bhs .Lreloc_done
+
+ //
+ // AArch64 uses the ELF64 RELA format, which means each entry in the
+ // relocation table consists of
+ //
+ // UINT64 offset : the relative offset of the value that needs to
+ // be relocated
+ // UINT64 info : relocation type and symbol index (the latter is
+ // not used for R_AARCH64_RELATIVE relocations)
+ // UINT64 addend : value to be added to the value being relocated
+ //
+ ldp x11, x12, [x9], #24 // read offset into x11 and info into x12
+ cmp x12, #0x403 // check info == R_AARCH64_RELATIVE?
+ bne .Lreloc_loop // not a relative relocation? then skip
+ ldr x12, [x9, #-8] // read addend into x12
+ add x12, x12, x8 // add reloc base to addend to get relocated value
+ str x12, [x11, x8] // write relocated value at offset
+ b .Lreloc_loop
+
+.Lreloc_done:
+ mov x11, x24
+ mov x12, x25
+ mov x13, x26
+
+ adr x11, __stmm_start
+ adr x13, __reloc_end
+ // set memory per section
+ ldr x0, =0xC4000065
+ ldr x12, =0x1000
+ and x1, x11, #~0x0fff // Align to page
+ sub x11, x13, x11
+ add x11, x11, #0x0fff
+ and x11, x11, #~0x0fff // Roundup
+ udiv x11, x11, x12 // nr pages
+ mov x2, x11
+ ldr x3, =0x3 // Set perms to r/x
+ svc #0
+
+ // set memory per section
+ adr x11, __ro_start
+ adr x13, __ro_end
+ ldr x0, =0xC4000065
+ ldr x12, =0x1000
+ and x1, x11, #~0x0fff // Align to page
+ sub x11, x13, x11
+ add x11, x11, #0x0fff
+ and x11, x11, #~0x0fff // Roundup
+ udiv x11, x11, x12 // nr pages
+ mov x2, x11
+ ldr x3, =0x1 // Set perms to r/o
+ svc #0
+
+ mov x0, x20
+ mov x1, x21
+ mov x2, x22
+ mov x3, x23
+
+ ret
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPointRelocatable.c b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPointRelocatable.c
new file mode 100644
index 0000000000..6964f3802e
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPointRelocatable.c
@@ -0,0 +1,301 @@
+/** @file
+ Entry point to the Standalone MM Foundation when initialized during the SEC
+ phase on ARM platforms
+
+Copyright (c) 2017 - 2018, ARM Ltd. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <PiMm.h>
+
+#include <Library/AArch64/StandaloneMmCoreEntryPoint.h>
+
+#include <PiPei.h>
+#include <Guid/MmramMemoryReserve.h>
+#include <Guid/MpInformation.h>
+
+#include <Library/ArmMmuLib.h>
+#include <Library/ArmSvcLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SerialPortLib.h>
+
+#include <IndustryStandard/ArmStdSmc.h>
+#include <IndustryStandard/ArmMmSvc.h>
+
+#define SPM_MAJOR_VER_MASK 0xFFFF0000
+#define SPM_MINOR_VER_MASK 0x0000FFFF
+#define SPM_MAJOR_VER_SHIFT 16
+
+CONST UINT32 SPM_MAJOR_VER = 0;
+CONST UINT32 SPM_MINOR_VER = 1;
+
+CONST UINT8 BOOT_PAYLOAD_VERSION = 1;
+
+PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint = NULL;
+
+/**
+ Retrieve a pointer to and print the boot information passed by privileged
+ secure firmware
+
+ @param SharedBufAddress The pointer memory shared with privileged firmware
+
+**/
+EFI_SECURE_PARTITION_BOOT_INFO *
+GetAndPrintBootinformation (
+ IN VOID *SharedBufAddress
+)
+{
+ EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;
+ EFI_SECURE_PARTITION_CPU_INFO *PayloadCpuInfo;
+ UINTN Index;
+
+ PayloadBootInfo = (EFI_SECURE_PARTITION_BOOT_INFO *) SharedBufAddress;
+
+ if (PayloadBootInfo == NULL) {
+ DEBUG ((DEBUG_ERROR, "PayloadBootInfo NULL\n"));
+ return NULL;
+ }
+
+ if (PayloadBootInfo->Header.Version != BOOT_PAYLOAD_VERSION) {
+ DEBUG ((DEBUG_ERROR, "Boot Information Version Mismatch. Current=0x%x, Expected=0x%x.\n",
+ PayloadBootInfo->Header.Version, BOOT_PAYLOAD_VERSION));
+ return NULL;
+ }
+
+ DEBUG ((DEBUG_INFO, "NumSpMemRegions - 0x%x\n", PayloadBootInfo->NumSpMemRegions));
+ DEBUG ((DEBUG_INFO, "SpMemBase - 0x%lx\n", PayloadBootInfo->SpMemBase));
+ DEBUG ((DEBUG_INFO, "SpMemLimit - 0x%lx\n", PayloadBootInfo->SpMemLimit));
+ DEBUG ((DEBUG_INFO, "SpImageBase - 0x%lx\n", PayloadBootInfo->SpImageBase));
+ DEBUG ((DEBUG_INFO, "SpStackBase - 0x%lx\n", PayloadBootInfo->SpStackBase));
+ DEBUG ((DEBUG_INFO, "SpHeapBase - 0x%lx\n", PayloadBootInfo->SpHeapBase));
+ DEBUG ((DEBUG_INFO, "SpNsCommBufBase - 0x%lx\n", PayloadBootInfo->SpNsCommBufBase));
+ DEBUG ((DEBUG_INFO, "SpSharedBufBase - 0x%lx\n", PayloadBootInfo->SpSharedBufBase));
+
+ DEBUG ((DEBUG_INFO, "SpImageSize - 0x%x\n", PayloadBootInfo->SpImageSize));
+ DEBUG ((DEBUG_INFO, "SpPcpuStackSize - 0x%x\n", PayloadBootInfo->SpPcpuStackSize));
+ DEBUG ((DEBUG_INFO, "SpHeapSize - 0x%x\n", PayloadBootInfo->SpHeapSize));
+ DEBUG ((DEBUG_INFO, "SpNsCommBufSize - 0x%x\n", PayloadBootInfo->SpNsCommBufSize));
+ DEBUG ((DEBUG_INFO, "SpPcpuSharedBufSize - 0x%x\n", PayloadBootInfo->SpPcpuSharedBufSize));
+
+ DEBUG ((DEBUG_INFO, "NumCpus - 0x%x\n", PayloadBootInfo->NumCpus));
+ DEBUG ((DEBUG_INFO, "CpuInfo - 0x%p\n", PayloadBootInfo->CpuInfo));
+
+ PayloadCpuInfo = (EFI_SECURE_PARTITION_CPU_INFO *) PayloadBootInfo->CpuInfo;
+
+ if (PayloadCpuInfo == NULL) {
+ DEBUG ((DEBUG_ERROR, "PayloadCpuInfo NULL\n"));
+ return NULL;
+ }
+
+ for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) {
+ DEBUG ((DEBUG_INFO, "Mpidr - 0x%lx\n", PayloadCpuInfo[Index].Mpidr));
+ DEBUG ((DEBUG_INFO, "LinearId - 0x%x\n", PayloadCpuInfo[Index].LinearId));
+ DEBUG ((DEBUG_INFO, "Flags - 0x%x\n", PayloadCpuInfo[Index].Flags));
+ }
+
+ return PayloadBootInfo;
+}
+
+VOID
+EFIAPI
+DelegatedEventLoop (
+ IN ARM_SVC_ARGS *EventCompleteSvcArgs
+ )
+{
+ EFI_STATUS Status;
+ UINTN SvcStatus;
+
+ while (TRUE) {
+ ArmCallSvc (EventCompleteSvcArgs);
+
+ DEBUG ((DEBUG_INFO, "Received delegated event\n"));
+ DEBUG ((DEBUG_INFO, "X0 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg0));
+ DEBUG ((DEBUG_INFO, "X1 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg1));
+ DEBUG ((DEBUG_INFO, "X2 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg2));
+ DEBUG ((DEBUG_INFO, "X3 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg3));
+
+ Status = CpuDriverEntryPoint (
+ EventCompleteSvcArgs->Arg0,
+ EventCompleteSvcArgs->Arg3,
+ EventCompleteSvcArgs->Arg1
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed delegated event 0x%x, Status 0x%x\n",
+ EventCompleteSvcArgs->Arg0, Status));
+ }
+
+ switch (Status) {
+ case EFI_SUCCESS:
+ SvcStatus = ARM_SVC_SPM_RET_SUCCESS;
+ break;
+ case EFI_INVALID_PARAMETER:
+ SvcStatus = ARM_SVC_SPM_RET_INVALID_PARAMS;
+ break;
+ case EFI_ACCESS_DENIED:
+ SvcStatus = ARM_SVC_SPM_RET_DENIED;
+ break;
+ case EFI_OUT_OF_RESOURCES:
+ SvcStatus = ARM_SVC_SPM_RET_NO_MEMORY;
+ break;
+ case EFI_UNSUPPORTED:
+ SvcStatus = ARM_SVC_SPM_RET_NOT_SUPPORTED;
+ break;
+ default:
+ SvcStatus = ARM_SVC_SPM_RET_NOT_SUPPORTED;
+ break;
+ }
+
+ EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64;
+ EventCompleteSvcArgs->Arg1 = SvcStatus;
+ }
+}
+
+STATIC
+EFI_STATUS
+GetSpmVersion (VOID)
+{
+ EFI_STATUS Status;
+ UINT16 SpmMajorVersion;
+ UINT16 SpmMinorVersion;
+ UINT32 SpmVersion;
+ ARM_SVC_ARGS SpmVersionArgs;
+
+ SpmVersionArgs.Arg0 = ARM_SVC_ID_SPM_VERSION_AARCH32;
+
+ ArmCallSvc (&SpmVersionArgs);
+
+ SpmVersion = SpmVersionArgs.Arg0;
+
+ SpmMajorVersion = ((SpmVersion & SPM_MAJOR_VER_MASK) >> SPM_MAJOR_VER_SHIFT);
+ SpmMinorVersion = ((SpmVersion & SPM_MINOR_VER_MASK) >> 0);
+
+ // Different major revision values indicate possibly incompatible functions.
+ // For two revisions, A and B, for which the major revision values are
+ // identical, if the minor revision value of revision B is greater than
+ // the minor revision value of revision A, then every function in
+ // revision A must work in a compatible way with revision B.
+ // However, it is possible for revision B to have a higher
+ // function count than revision A.
+ if ((SpmMajorVersion == SPM_MAJOR_VER) &&
+ (SpmMinorVersion >= SPM_MINOR_VER))
+ {
+ DEBUG ((DEBUG_INFO, "SPM Version: Major=0x%x, Minor=0x%x\n",
+ SpmMajorVersion, SpmMinorVersion));
+ Status = EFI_SUCCESS;
+ }
+ else
+ {
+ DEBUG ((DEBUG_INFO, "Incompatible SPM Versions.\n Current Version: Major=0x%x, Minor=0x%x.\n Expected: Major=0x%x, Minor>=0x%x.\n",
+ SpmMajorVersion, SpmMinorVersion, SPM_MAJOR_VER, SPM_MINOR_VER));
+ Status = EFI_UNSUPPORTED;
+ }
+
+ return Status;
+}
+
+/**
+ The entry point of Standalone MM Foundation.
+
+ @param SharedBufAddress Pointer to the Buffer between SPM and SP.
+ @param cookie1.
+ @param cookie2.
+
+**/
+VOID
+EFIAPI
+ModuleEntryPoint (
+ IN VOID *SharedBufAddress,
+ IN UINT64 SharedBufSize,
+ IN UINT64 cookie1,
+ IN UINT64 cookie2
+ )
+{
+ //PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;
+ ARM_SVC_ARGS InitMmFoundationSvcArgs;
+ EFI_STATUS Status;
+ //UINT32 SectionHeaderOffset;
+ //UINT16 NumberOfSections;
+ VOID *HobStart;
+ VOID *TeData;
+ UINTN TeDataSize;
+
+ // Get Secure Partition Manager Version Information
+
+ Status = GetSpmVersion ();
+ if (EFI_ERROR (Status)) {
+ goto finish;
+ }
+
+ PayloadBootInfo = GetAndPrintBootinformation (SharedBufAddress);
+ if (PayloadBootInfo == NULL) {
+ Status = EFI_UNSUPPORTED;
+ goto finish;
+ }
+
+ // Locate PE/COFF File information for the Standalone MM core module
+ Status = LocateStandaloneMmCorePeCoffData (
+ (EFI_FIRMWARE_VOLUME_HEADER *) PayloadBootInfo->SpImageBase,
+ &TeData,
+ &TeDataSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto finish;
+ }
+
+#if 0
+ // Obtain the PE/COFF Section information for the Standalone MM core module
+ Status = GetStandaloneMmCorePeCoffSections (
+ TeData,
+ &ImageContext,
+ &SectionHeaderOffset,
+ &NumberOfSections
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto finish;
+ }
+
+ // Loading from RAM
+ ImageContext.ImageAddress = PayloadBootInfo->SpMemBase + 0x1000;
+ // Update the memory access permissions of individual sections in the
+ // Standalone MM core module
+ Status = UpdateMmFoundationPeCoffPermissions (
+ &ImageContext,
+ SectionHeaderOffset,
+ NumberOfSections,
+ ArmSetMemoryRegionNoExec,
+ ArmSetMemoryRegionReadOnly,
+ ArmClearMemoryRegionReadOnly
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto finish;
+ }
+#endif
+
+ //
+ // Create Hoblist based upon boot information passed by privileged software
+ //
+ HobStart = CreateHobListFromBootInfo (&CpuDriverEntryPoint, PayloadBootInfo);
+
+ //
+ // Call the MM Core entry point
+ //
+ ProcessModuleEntryPointList (HobStart);
+
+ DEBUG ((DEBUG_INFO, "Shared Cpu Driver EP 0x%lx\n", (UINT64) CpuDriverEntryPoint));
+
+finish:
+ ZeroMem (&InitMmFoundationSvcArgs, sizeof(InitMmFoundationSvcArgs));
+ InitMmFoundationSvcArgs.Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64;
+ InitMmFoundationSvcArgs.Arg1 = Status;
+ DelegatedEventLoop (&InitMmFoundationSvcArgs);
+}
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPointRelocatable.inf b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPointRelocatable.inf
new file mode 100644
index 0000000000..b8a6df5c59
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPointRelocatable.inf
@@ -0,0 +1,51 @@
+## @file
+# Module entry point library for DXE core.
+#
+# Copyright (c) 2017 - 2018, ARM Ltd. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = StandaloneMmCoreEntryPointRelocatable
+ FILE_GUID = C97AC593-109A-4C63-905C-675FDE2689E9
+ MODULE_TYPE = MM_CORE_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = StandaloneMmCoreEntryPointRelocatable|MM_CORE_STANDALONE
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only)
+#
+
+[Sources.AARCH64]
+ AArch64/StandaloneMmCoreEntryPointRelocatable.c
+ AArch64/SetPermissions.c
+ AArch64/CreateHobList.c
+ AArch64/ModuleEntryPoint.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
+
+[Packages.AARCH64]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+
+[LibraryClasses.AARCH64]
+ StandaloneMmMmuLib
+ ArmSvcLib
+
+[Guids]
+ gMpInformationHobGuid
+ gEfiMmPeiMmramMemoryReserveGuid
+ gEfiStandaloneMmNonSecureBufferGuid
+ gEfiArmTfCpuDriverEpDescriptorGuid