public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [PATCH] IntelFsp2Pkg: Optional Plugin for FSP SecCore/PeiCore Rebasing
@ 2024-04-03  8:12 Zhiguang Liu
  2024-04-09  5:20 ` Ni, Ray
  0 siblings, 1 reply; 2+ messages in thread
From: Zhiguang Liu @ 2024-04-03  8:12 UTC (permalink / raw)
  To: devel
  Cc: Zhiguang Liu, Chasel Chiu, Nate DeSimone, Duggapu Chinni B,
	Star Zeng, Ted Kuo, Ashraf Ali S, Susovan Mohapatra, Ray Ni

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
'AsmGetFspSecEntry', 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>     PreFspSecS:_ModuleEntryPoint - [0x0000]
PreFspSecS:SecCoreRelativeOff   PreFspSecS:AsmGetFspSecCore
                                   - Fsp24SecCoreS:BASE
PreFspSecS:PeiCoreRelativeOff   PreFspSecS:AsmGetFspPeiCore
                                   - PeiCore:BASE
PreFspSecS:SecEntryRelativeOff  PreFspSecS:AsmGetFspSecEntry
                                  - Fsp24SecCoreS:FspSiliconInitApi

Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Duggapu Chinni B <chinni.b.duggapu@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Ted Kuo <ted.kuo@intel.com>
Cc: Ashraf Ali S <ashraf.ali.s@intel.com>
Cc: Susovan Mohapatra <susovan.mohapatra@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
---
 IntelFsp2Pkg/IntelFsp2Pkg.dsc                 |   5 +
 IntelFsp2Pkg/PreFspSec/PreFspSec.c            | 115 ++++++++++++++++++
 IntelFsp2Pkg/PreFspSec/PreFspSec.inf          |  61 ++++++++++
 .../PreFspSec/X64/PreFspSecCommon.nasm        |  69 +++++++++++
 4 files changed, 250 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..d5fd028afc
--- /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 interface gets SecCore image base
+
+  @return   SecCore image base, or zero if no patch in nasm code
+
+**/
+UINTN
+EFIAPI
+AsmGetFspSecCore (
+  VOID
+  );
+
+/**
+  This interface gets PeiCore image base
+
+  @return   PeiCore image base, or zero if no patch in nasm code
+
+**/
+UINTN
+EFIAPI
+AsmGetFspPeiCore (
+  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
+FspPatchSecAndPeiCore (
+  VOID
+  )
+{
+  UINT64      SecCoreImageBase;
+  UINT64      PeiCoreImageBase;
+  EFI_STATUS  Status;
+
+  //
+  // Get SecCore image, and rebase it
+  //
+  SecCoreImageBase = AsmGetFspSecCore ();
+  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 = AsmGetFspPeiCore ();
+  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..51a0b337a1
--- /dev/null
+++ b/IntelFsp2Pkg/PreFspSec/PreFspSec.inf
@@ -0,0 +1,61 @@
+## @file
+#  Optional Plugin for FSP SecCore/PeiCore Rebasing
+#
+#  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 'AsmGetFspSecEntry', 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:AsmGetFspSecCore - Fsp24SecCoreS:BASE
+#  PreFspSec:PeiCoreRelativeOff    PreFspSec:AsmGetFspPeiCore - PeiCore:BASE
+#  PreFspSec:SecEntryRelativeOff   PreFspSec:AsmGetFspSecEntry - 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..f1e166de36
--- /dev/null
+++ b/IntelFsp2Pkg/PreFspSec/X64/PreFspSecCommon.nasm
@@ -0,0 +1,69 @@
+;; @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(FspPatchSecAndPeiCore)
+
+;----------------------------------------------------------------------------
+; _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(FspPatchSecAndPeiCore)
+  POPA_64
+  call   ASM_PFX(AsmGetFspSecEntry)
+  jmp    rax
+
+global ASM_PFX(AsmGetFspSecCore)
+ASM_PFX(AsmGetFspSecCore):
+   lea   rax, [ASM_PFX(AsmGetFspSecCore)]
+   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               ; After exchange, rcx is the value be subtract by the patched value
+                                  ; rax == rcx means patched value is zero
+   CMPXCHG rcx, rdx               ; if (rcx == rax) {rcx = rdx} else {rax = rcx}
+   mov     rax, rcx
+   ret
+
+global ASM_PFX(AsmGetFspPeiCore)
+ASM_PFX(AsmGetFspPeiCore):
+   lea   rax, [ASM_PFX(AsmGetFspPeiCore)]
+   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               ; After exchange, rcx is the value be subtract by the patched value
+                                  ; rax == rcx means patched value is zero
+   CMPXCHG rcx, rdx               ; if (rcx == rax) {rcx = rdx} else {rax = rcx}
+   mov     rax, rcx
+   ret
+
+global ASM_PFX(AsmGetFspSecEntry)
+ASM_PFX(AsmGetFspSecEntry):
+   lea   rax, [ASM_PFX(AsmGetFspSecEntry)]
+   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 (#117357): https://edk2.groups.io/g/devel/message/117357
Mute This Topic: https://groups.io/mt/105304660/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [edk2-devel] [PATCH] IntelFsp2Pkg: Optional Plugin for FSP SecCore/PeiCore Rebasing
  2024-04-03  8:12 [edk2-devel] [PATCH] IntelFsp2Pkg: Optional Plugin for FSP SecCore/PeiCore Rebasing Zhiguang Liu
@ 2024-04-09  5:20 ` Ni, Ray
  0 siblings, 0 replies; 2+ messages in thread
From: Ni, Ray @ 2024-04-09  5:20 UTC (permalink / raw)
  To: Liu, Zhiguang, devel@edk2.groups.io
  Cc: Chiu, Chasel, Desimone, Nathaniel L, Duggapu, Chinni B,
	Zeng, Star, Kuo, Ted, S, Ashraf Ali, Susovan Mohapatra

[-- Attachment #1: Type: text/plain, Size: 5645 bytes --]



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
'AsmGetFspSecEntry', 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>     PreFspSecS:_ModuleEntryPoint - [0x0000]
PreFspSecS:SecCoreRelativeOff   PreFspSecS:AsmGetFspSecCore
                                   - Fsp24SecCoreS:BASE
PreFspSecS:PeiCoreRelativeOff   PreFspSecS:AsmGetFspPeiCore
                                   - PeiCore:BASE
PreFspSecS:SecEntryRelativeOff  PreFspSecS:AsmGetFspSecEntry
                                  - Fsp24SecCoreS:FspSiliconInitApi


[Ray.1] Can you emphasize this optional plug-in only applies to 64bit FSP?



+/**
+  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
+FspPatchSecAndPeiCore (

[Ray.2] Can you rename it as "Fsp*Relocate*SecAndPeiCore"?
It's to align with "RelocatePeTeImage".

+;
+;----------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+  PUSHA_64
+  call   ASM_PFX(FspPatchSecAndPeiCore)
+  POPA_64
+  call   ASM_PFX(AsmGetFspSecEntry)
+  jmp    rax
+
+global ASM_PFX(AsmGetFspSecCore)

[Ray.3] rename as AsmGetFspSecCoreImageBase and add function header.

+ASM_PFX(AsmGetFspSecCore):
+   lea   rax, [ASM_PFX(AsmGetFspSecCore)]
+   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

[Ray.4] ; RAX = SecCore image base at runtime, RCX = AsmGetFspSecCore runtime address

+   xchg    rax, rcx               ; After exchange, rcx is the value be subtract by the patched value
+                                  ; rax == rcx means patched value is zero
[Ray.5] ; RCX = SecCore image base at runtime, RAX = AsmGetFspSecCore runtime address.
; If SecCoreRelativeOff is not patched, RCX = RAX = AsmGetFspSecCore runtime address. This happens when there is no SecCore in the binary.


+   CMPXCHG rcx, rdx               ; if (rcx == rax) {rcx = rdx (0) } else {rax = rcx (SecCore image base at runtime)}
+   mov     rax, rcx
+   ret
+
+global ASM_PFX(AsmGetFspPeiCore)
+ASM_PFX(AsmGetFspPeiCore):
+   lea   rax, [ASM_PFX(AsmGetFspPeiCore)]
+   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               ; After exchange, rcx is the value be subtract by the patched value
+                                  ; rax == rcx means patched value is zero
+   CMPXCHG rcx, rdx               ; if (rcx == rax) {rcx = rdx} else {rax = rcx}
+   mov     rax, rcx
+   ret
+



[Ray.6] rename it as AsmGetFspOriginalEntry.
+global ASM_PFX(AsmGetFspSecEntry)
+ASM_PFX(AsmGetFspSecEntry):
+   lea   rax, [ASM_PFX(AsmGetFspSecEntry)]
+   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 (#117528): https://edk2.groups.io/g/devel/message/117528
Mute This Topic: https://groups.io/mt/105304660/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



[-- Attachment #2: Type: text/html, Size: 13657 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-04-09  5:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-03  8:12 [edk2-devel] [PATCH] IntelFsp2Pkg: Optional Plugin for FSP SecCore/PeiCore Rebasing Zhiguang Liu
2024-04-09  5:20 ` Ni, Ray

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox