Reviewed-by: Ray Ni <[email protected]>
Thanks,
Ray
________________________________
From: Liu, Zhiguang <[email protected]>
Sent: Wednesday, April 10, 2024 15:08
To: [email protected] <[email protected]>
Cc: Liu, Zhiguang <[email protected]>; Chiu, Chasel
<[email protected]>; Desimone, Nathaniel L
<[email protected]>; Duggapu, Chinni B
<[email protected]>; Zeng, Star <[email protected]>; Kuo, Ted
<[email protected]>; S, Ashraf Ali <[email protected]>; Susovan Mohapatra
<[email protected]>; Ni, Ray <[email protected]>
Subject: [PATCH v2] IntelFsp2Pkg: Optional Plugin for FSP SecCore/PeiCore
Rebasing
Note this plugin only applies to 64-bit PSP
This optional plugin is designed to execute before the FSP SecCore to
rebase SecCore and PeiCore during runtime. If the FSP binary requires
rebasing at runtime, this module should be included within the FSP
binary. Additionally, specific patches must be applied to ensure proper
functionality. In the absence of this module, manual patching of API
offsets within the FSP header is necessary. To illustrate, let's
consider a scenario within FSP-S where 'FspSiliconInitEntry' is the
initial API to be executed post-rebase. Rather than directly inputting
the 'FspSiliconInit' offset into the 'FspSiliconInitEntryOffset' field
of the FSP header, the entry point of this module should be used.
Furthermore, the 'FspSiliconInit' offset should be placed into
'AsmGetFspOriginalEntry', which signifies the address to which this
module will jump.
It is also essential to patch the image bases of SecCore and PeiCore
to enable the rebasing functionality of this module.
The following is an example of how to apply the necessary patches:
Patch Address Patch Value
<FspSiliconInitEntryOffset> PreFspSec:_ModuleEntryPoint - [0x0000]
PreFspSec:SecCoreRelativeOff PreFspSec:AsmGetFspSecCoreImageBase
- Fsp24SecCoreS:BASE
PreFspSec:PeiCoreRelativeOff PreFspSec:AsmGetFspPeiCoreImageBase
- PeiCore:BASE
PreFspSec:SecEntryRelativeOff PreFspSec:AsmGetFspOriginalEntry
- Fsp24SecCoreS:FspSiliconInitApi
Cc: Chasel Chiu <[email protected]>
Cc: Nate DeSimone <[email protected]>
Cc: Duggapu Chinni B <[email protected]>
Cc: Star Zeng <[email protected]>
Cc: Ted Kuo <[email protected]>
Cc: Ashraf Ali S <[email protected]>
Cc: Susovan Mohapatra <[email protected]>
Cc: Ray Ni <[email protected]>
Signed-off-by: Zhiguang Liu <[email protected]>
---
IntelFsp2Pkg/IntelFsp2Pkg.dsc | 5 +
IntelFsp2Pkg/PreFspSec/PreFspSec.c | 115 ++++++++++++++++++
IntelFsp2Pkg/PreFspSec/PreFspSec.inf | 62 ++++++++++
.../PreFspSec/X64/PreFspSecCommon.nasm | 94 ++++++++++++++
4 files changed, 276 insertions(+)
create mode 100644 IntelFsp2Pkg/PreFspSec/PreFspSec.c
create mode 100644 IntelFsp2Pkg/PreFspSec/PreFspSec.inf
create mode 100644 IntelFsp2Pkg/PreFspSec/X64/PreFspSecCommon.nasm
diff --git a/IntelFsp2Pkg/IntelFsp2Pkg.dsc b/IntelFsp2Pkg/IntelFsp2Pkg.dsc
index f236a7010b..a2cc29c940 100644
--- a/IntelFsp2Pkg/IntelFsp2Pkg.dsc
+++ b/IntelFsp2Pkg/IntelFsp2Pkg.dsc
@@ -33,6 +33,8 @@
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
DebugDeviceLib|IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
# FSP override
DebugLib|IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf
@@ -75,6 +77,9 @@
IntelFsp2Pkg/FspSecCore/Fsp24SecCoreS.inf
IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf
+[Components.X64]
+ IntelFsp2Pkg/PreFspSec/PreFspSec.inf
+
[PcdsFixedAtBuild.common]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046
diff --git a/IntelFsp2Pkg/PreFspSec/PreFspSec.c
b/IntelFsp2Pkg/PreFspSec/PreFspSec.c
new file mode 100644
index 0000000000..b3b52b8064
--- /dev/null
+++ b/IntelFsp2Pkg/PreFspSec/PreFspSec.c
@@ -0,0 +1,115 @@
+/** @file
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include "Guid/FspHeaderFile.h"
+#include <Library/PeCoffLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+
+/**
+ This fuction gets SecCore image base
+
+ @return SecCore image base, or zero if no patch in nasm code
+
+**/
+UINTN
+EFIAPI
+AsmGetFspSecCoreImageBase (
+ VOID
+ );
+
+/**
+ This fuction gets PeiCore image base
+
+ @return PeiCore image base, or zero if no patch in nasm code
+
+**/
+UINTN
+EFIAPI
+AsmGetFspPeiCoreImageBase (
+ VOID
+ );
+
+/**
+ Relocate Pe/Te Image
+
+ @param[in] ImageBaseAddress Image base address
+
+ @retval EFI_SUCCESS Image is relocated successfully
+ @retval Others Image is not relocated successfully
+**/
+EFI_STATUS
+RelocatePeTeImage (
+ UINT64 ImageBaseAddress
+ )
+{
+ RETURN_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ ZeroMem (&ImageContext, sizeof (ImageContext));
+
+ ImageContext.Handle = (VOID *)ImageBaseAddress;
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)ImageBaseAddress;
+
+ //
+ // rebase the image
+ //
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/**
+ This function will patch the Sec Core and Pei Core in current FSP.
+**/
+VOID
+EFIAPI
+FspRelocateSecAndPeiCore (
+ VOID
+ )
+{
+ UINT64 SecCoreImageBase;
+ UINT64 PeiCoreImageBase;
+ EFI_STATUS Status;
+
+ //
+ // Get SecCore image, and rebase it
+ //
+ SecCoreImageBase = AsmGetFspSecCoreImageBase ();
+ if (SecCoreImageBase != 0) {
+ Status = RelocatePeTeImage (SecCoreImageBase);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Sec Core is relocated successfully\n"));
+ } else {
+ DEBUG ((DEBUG_WARN, "Sec Core is not relocated. May have issue
later\n"));
+ }
+ }
+
+ //
+ // Get PeiCore image, and rebase it
+ //
+ PeiCoreImageBase = AsmGetFspPeiCoreImageBase ();
+ if (PeiCoreImageBase != 0) {
+ Status = RelocatePeTeImage (PeiCoreImageBase);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Pei Core is relocated successfully\n"));
+ } else {
+ DEBUG ((DEBUG_INFO, "Pei Core is not relocated. May have issue
later\n"));
+ }
+ }
+}
diff --git a/IntelFsp2Pkg/PreFspSec/PreFspSec.inf
b/IntelFsp2Pkg/PreFspSec/PreFspSec.inf
new file mode 100644
index 0000000000..1f19ef85eb
--- /dev/null
+++ b/IntelFsp2Pkg/PreFspSec/PreFspSec.inf
@@ -0,0 +1,62 @@
+## @file
+# Optional Plugin for FSP SecCore/PeiCore Rebasing.
+# Note this plugin only applies to 64-bit PSP
+#
+# This optional plugin is designed to execute before the FSP SecCore to rebase
+# SecCore and PeiCore during runtime. If the FSP binary requires rebasing at
runtime,
+# this module should be included within the FSP binary.
+# Additionally, specific patches must be applied to ensure proper
functionality.
+#
+# In the absence of this module, manual patching of API offsets within the
FSP header
+# is necessary. To illustrate, let's consider a scenario within FSP-S where
+# 'FspSiliconInitEntry' is the initial API to be executed post-rebase.
+# Rather than directly inputting the 'FspSiliconInit' offset into the
+# 'FspSiliconInitEntryOffset' field of the FSP header, the entry point of
this module
+# should be used. Furthermore, the 'FspSiliconInit' offset should be placed
+# into 'AsmGetFspOriginalEntry', which signifies the address to which this
module will jump.
+# It is also essential to patch the image bases of SecCore and PeiCore to
enable the
+# rebasing functionality of this module.
+# The following is an example of how to apply the necessary patches:
+# Patch Address Patch Value
+# <FspSiliconInitEntryOffset> PreFspSec:_ModuleEntryPoint - [0x0000]
+# PreFspSec:SecCoreRelativeOff PreFspSec:AsmGetFspSecCoreImageBase -
Fsp24SecCoreS:BASE
+# PreFspSec:PeiCoreRelativeOff PreFspSec:AsmGetFspPeiCoreImageBase -
PeiCore:BASE
+# PreFspSec:SecEntryRelativeOff PreFspSec:AsmGetFspOriginalEntry -
Fsp24SecCoreS:FspSiliconInitApi
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PreFspSec
+ FILE_GUID = ef13ad51-2bab-4333-bd96-e01c79f2d313
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the
build tools.
+#
+# VALID_ARCHITECTURES = X64
+#
+
+[Sources]
+ PreFspSec.c
+
+[Sources.X64]
+
+ X64/PreFspSecCommon.nasm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ BaseLib
+ CpuLib
+ PeCoffLib
diff --git a/IntelFsp2Pkg/PreFspSec/X64/PreFspSecCommon.nasm
b/IntelFsp2Pkg/PreFspSec/X64/PreFspSecCommon.nasm
new file mode 100644
index 0000000000..f1386edb3f
--- /dev/null
+++ b/IntelFsp2Pkg/PreFspSec/X64/PreFspSecCommon.nasm
@@ -0,0 +1,94 @@
+;; @file
+; Run before FSP SecCore to rebase SecCore and PeiCore
+;
+; Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+ DEFAULT REL
+ SECTION .text
+
+%include "PushPopRegsNasm.inc"
+
+;
+; Following functions will be provided in C
+;
+extern ASM_PFX(FspRelocateSecAndPeiCore)
+
+;----------------------------------------------------------------------------
+; _ModuleEntryPoint API
+;
+; This is the PreFspSec entry point to rebase and resume the FSP execution
+; Only rax register is modified.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ PUSHA_64
+ call ASM_PFX(FspRelocateSecAndPeiCore)
+ POPA_64
+ call ASM_PFX(AsmGetFspOriginalEntry)
+ jmp rax
+
+
+;----------------------------------------------------------------------------
+; This fuction gets SecCore image base
+;
+; UINTN
+; EFIAPI
+; AsmGetFspSecCoreImageBase (
+; VOID
+; )
+;----------------------------------------------------------------------------
+global ASM_PFX(AsmGetFspSecCoreImageBase )
+ASM_PFX(AsmGetFspSecCoreImageBase ):
+ lea rax, [ASM_PFX(AsmGetFspSecCoreImageBase )]
+ mov rcx, rax
+ xor rdx, rdx
+ DB 0x48, 0x2d ; sub rax, 0x????????
+global ASM_PFX(SecCoreRelativeOff)
+ASM_PFX(SecCoreRelativeOff):
+ DD 0 ; This value can be patched by the build
script if need to rebase SecCore
+ xchg rax, rcx ; Before exchange, RAX = SecCore image base
at runtime, RCX = AsmGetFspSecCoreImageBase runtime address
+ ; After exchange, RCX = SecCore image base
at runtime, RAX = AsmGetFspSecCoreImageBase runtime address.
+ ; If SecCoreRelativeOff is not patched, RCX
= RAX = AsmGetFspSecCoreImageBase runtime address. This happens when there is
no SecCore in the binary.
+ CMPXCHG rcx, rdx ; if (rcx == rax) {rcx = rdx} else {rax =
rcx}
+ mov rax, rcx
+ ret
+
+;----------------------------------------------------------------------------
+; This fuction gets PeiCore Image Base
+;
+; UINTN
+; EFIAPI
+; AsmGetFspPeiCoreImageBase (
+; VOID
+; )
+;----------------------------------------------------------------------------
+global ASM_PFX(AsmGetFspPeiCoreImageBase)
+ASM_PFX(AsmGetFspPeiCoreImageBase):
+ lea rax, [ASM_PFX(AsmGetFspPeiCoreImageBase)]
+ mov rcx, rax
+ xor rdx, rdx
+ DB 0x48, 0x2d ; sub rax, 0x????????
+global ASM_PFX(PeiCoreRelativeOff)
+ASM_PFX(PeiCoreRelativeOff):
+ DD 0 ; This value can be patched by the build
script if need to rebase PeiCore
+ xchg rax, rcx ; Before exchange, RAX = PeiCore image base
at runtime, RCX = AsmGetFspPeiCoreImageBase runtime address
+ ; After exchange, RCX = PeiCore image base
at runtime, RAX = AsmGetFspPeiCoreImageBase runtime address.
+ ; If PeiCoreRelativeOff is not patched, RCX
= RAX = AsmGetFspPeiCoreImageBase runtime address. This happens when there is
no SecCore in the binary.
+ CMPXCHG rcx, rdx ; if (rcx == rax) {rcx = rdx} else {rax =
rcx}
+ mov rax, rcx
+ ret
+
+;----------------------------------------------------------------------------
+; This fuction gets Fsp Original entry
+; Only Rax register is used
+;----------------------------------------------------------------------------
+global ASM_PFX(AsmGetFspOriginalEntry)
+ASM_PFX(AsmGetFspOriginalEntry):
+ lea rax, [ASM_PFX(AsmGetFspOriginalEntry)]
+ DB 0x48, 0x2d ; sub rax, 0x????????
+global ASM_PFX(SecEntryRelativeOff)
+ASM_PFX(SecEntryRelativeOff):
+ DD 0x12345678 ; This value must be patched by the build
script
+ ret
--
2.31.1.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117579): https://edk2.groups.io/g/devel/message/117579
Mute This Topic: https://groups.io/mt/105437669/21656
Group Owner: [email protected]
Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-