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-06 11:30:40 +0300
commit13faaec9b11ead0e7b50180b91a8cff2c09eff44 (patch)
tree766f5de509c6f03c9543e02d0d0cf1336a5d3729
parent41a037733b32553b4f70e4733240867d6ca2d06c (diff)
StandaloneMmPkg: Relocatable version for StandAloneMMstmm_reloc_combined
With work currently being done in OP-TEE [1] and U-boot [2], we can compile StandAloneMM as a single binary [3] and load it from OP-TEE in an isolated partition that behahes similarly to SPM. By doing so we reuse existing code from EDK2 for the UEFI variable storage regardless of the firmware implementation. Another advantage is that OP-TEE combined with U-Boot's OP-TEE supplicant can use the RPMB partition of an eMMC and securely store EFI variables instead of solely relying on a secure world flash [4]. Since StMM can be compiled as a binary that runs on OP-TEE, we need to make it self-relocatable. OP-TEE load address can be arbitrary depending on memory layout or ASLR. We could keep the current StandAloneMM implemetation as-is and duplicate StandaloneMmCoreEntryPoint.c. Instead add another .inf file for the relocatable option and the relevant linker script, move the current entry point into asm and add a FeaturePcd for enabling/disabling the relocatable option. [1] https://github.com/apalos/optee_os/tree/stmm_upstream_03_clean [2] https://github.com/u-boot/u-boot/blob/master/lib/efi_loader/efi_variable_tee.c [3] https://git.linaro.org/people/ilias.apalodimas/edk2-platforms.git/tree/Platform/QemuVirt/PlatformStandaloneMm.dsc?h=stmm_reloc_combined [4] https://git.linaro.org/people/ilias.apalodimas/edk2-platforms.git/tree/Silicon/QemuVirt/Drivers/OpTeeRpmbFv/OpTeeRpmbFv.c?h=stmm_reloc_combined Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-rw-r--r--StandaloneMmPkg/Core/Scripts/StMM-PIE.lds54
-rw-r--r--StandaloneMmPkg/Core/StandaloneMmCore.inf3
-rw-r--r--StandaloneMmPkg/Core/StandaloneMmCoreRelocatable.inf80
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/ModuleEntryPoint.S103
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c7
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf4
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPointRelocatable.inf54
-rw-r--r--StandaloneMmPkg/StandaloneMmPkg.dec2
8 files changed, 306 insertions, 1 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/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf
index 7d590b49bd..fdd4b61b36 100644
--- a/StandaloneMmPkg/Core/StandaloneMmCore.inf
+++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf
@@ -74,3 +74,6 @@
gEfiEventLegacyBootGuid
gEfiEventExitBootServicesGuid
gEfiEventReadyToBootGuid
+
+[BuildOptions]
+ GCC:*_*_*_DLINK_FLAGS = -Wl,-T,$(MODULE_DIR)/Scripts/StMM-PIE.lds
diff --git a/StandaloneMmPkg/Core/StandaloneMmCoreRelocatable.inf b/StandaloneMmPkg/Core/StandaloneMmCoreRelocatable.inf
new file mode 100644
index 0000000000..69049080ef
--- /dev/null
+++ b/StandaloneMmPkg/Core/StandaloneMmCoreRelocatable.inf
@@ -0,0 +1,80 @@
+## @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>
+# Copyright (c) 2020, Linaro 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..90ff4579da
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/ModuleEntryPoint.S
@@ -0,0 +1,103 @@
+//
+// Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+// Copyright (c) 2015-2020, Linaro Limited. All rights reserved.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroIoLibV8.h>
+ASM_FUNC(_ModuleEntryPoint)
+ adr x8, FeaturePcdGet (PcdStMMReloc)
+ ldrb w9, [x8]
+ cmp x9, #0
+ // If PcdStMMReloc is set to TRUE, go ahead and fixup the relocations here
+ beq .Llaunch
+ adr x8, __reloc_base
+ adr x9, __reloc_start
+ adr x10, __reloc_end
+ bl ASM_PFX(_DoReloc)
+.Llaunch:
+ b ModuleEntryPoint
+
+.section .text.reloc, "ax"
+ASM_PFX(_DoReloc):
+ mov x20, x0
+ mov x21, x1
+ mov x22, x2
+ mov x23, x3
+
+ // Set all of the memory as r/w
+ adr x11, __stmm_start
+ adr x2, __stmm_end
+ ldr x0, =0xC4000065
+ and x1, x11, #~0x0fff // Align to page
+ sub x2, x2, x11
+ add x2, x2, #0xfff
+ lsr x2, x2, #12 // nr pages
+ ldr x3, =0x5 // Set perms to r/w
+ svc #0
+ // Prevent speculative execution beyond svc instruction
+ dsb nsh
+ isb
+
+.Lreloc_loop:
+ cmp x9, x10
+ bhs .Lreloc_done
+ //
+ // 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.
+ //
+ // 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:
+ // set memory per section
+ adr x11, __stmm_start
+ adr x2, __reloc_end
+ ldr x0, =0xC4000065
+ and x1, x11, #~0x0fff // Align to page
+ sub x2, x2, x11
+ add x2, x2, #0xfff
+ lsr x2, x2, #12 // nr pages
+ ldr x3, =0x3 // Set perms to r/x
+ svc #0
+ // Prevent speculative execution beyond svc instruction
+ dsb nsh
+ isb
+
+ adr x11, __ro_start
+ adr x2, __ro_end
+ ldr x0, =0xC4000065
+ and x1, x11, #~0x0fff // Align to page
+ sub x2, x2, x11
+ add x2, x2, #0xfff
+ lsr x2, x2, #12 // nr pages
+ ldr x3, =0x1 // Set perms to r/o
+ svc #0
+ // Prevent speculative execution beyond svc instruction
+ dsb nsh
+ isb
+
+ mov x0, x20
+ mov x1, x21
+ mov x2, x22
+ mov x3, x23
+
+ ret
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c
index 2072338511..57c3162ab5 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c
@@ -22,6 +22,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/HobLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
#include <Library/SerialPortLib.h>
#include <IndustryStandard/ArmStdSmc.h>
@@ -209,7 +210,7 @@ GetSpmVersion (VOID)
**/
VOID
EFIAPI
-_ModuleEntryPoint (
+ModuleEntryPoint (
IN VOID *SharedBufAddress,
IN UINT64 SharedBufSize,
IN UINT64 cookie1,
@@ -238,6 +239,9 @@ _ModuleEntryPoint (
goto finish;
}
+ if (FeaturePcdGet (PcdStMMReloc)) {
+ goto skip_remap;
+ }
// Locate PE/COFF File information for the Standalone MM core module
Status = LocateStandaloneMmCorePeCoffData (
(EFI_FIRMWARE_VOLUME_HEADER *) PayloadBootInfo->SpImageBase,
@@ -276,6 +280,7 @@ _ModuleEntryPoint (
goto finish;
}
+skip_remap:
//
// Create Hoblist based upon boot information passed by privileged software
//
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
index 891c292e92..6659219404 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
@@ -25,6 +25,7 @@
AArch64/StandaloneMmCoreEntryPoint.c
AArch64/SetPermissions.c
AArch64/CreateHobList.c
+ AArch64/ModuleEntryPoint.S
[Packages]
MdePkg/MdePkg.dec
@@ -48,3 +49,6 @@
gEfiMmPeiMmramMemoryReserveGuid
gEfiStandaloneMmNonSecureBufferGuid
gEfiArmTfCpuDriverEpDescriptorGuid
+
+[FeaturePcd]
+ gStandaloneMmPkgTokenSpaceGuid.PcdStMMReloc|FALSE
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPointRelocatable.inf b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPointRelocatable.inf
new file mode 100644
index 0000000000..10cdae1b40
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPointRelocatable.inf
@@ -0,0 +1,54 @@
+## @file
+# Module entry point library for DXE core.
+#
+# Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = StandaloneMmCoreEntryPoint
+ FILE_GUID = C97AC593-109A-4C63-905C-675FDE2689E8
+ MODULE_TYPE = MM_CORE_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = StandaloneMmCoreEntryPoint|MM_CORE_STANDALONE
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only)
+#
+
+[Sources.AARCH64]
+ AArch64/StandaloneMmCoreEntryPoint.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
+
+[FeaturePcd]
+ gStandaloneMmPkgTokenSpaceGuid.PcdStMMReloc|TRUE
diff --git a/StandaloneMmPkg/StandaloneMmPkg.dec b/StandaloneMmPkg/StandaloneMmPkg.dec
index 82cb62568b..cc572321a5 100644
--- a/StandaloneMmPkg/StandaloneMmPkg.dec
+++ b/StandaloneMmPkg/StandaloneMmPkg.dec
@@ -33,3 +33,5 @@
gEfiStandaloneMmNonSecureBufferGuid = { 0xf00497e3, 0xbfa2, 0x41a1, { 0x9d, 0x29, 0x54, 0xc2, 0xe9, 0x37, 0x21, 0xc5 }}
gEfiArmTfCpuDriverEpDescriptorGuid = { 0x6ecbd5a1, 0xc0f8, 0x4702, { 0x83, 0x01, 0x4f, 0xc2, 0xc5, 0x47, 0x0a, 0x51 }}
+[PcdsFeatureFlag]
+ gStandaloneMmPkgTokenSpaceGuid.PcdStMMReloc|FALSE|BOOLEAN|0x00000001