summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiaxin Wu <jiaxin.wu@intel.com>2024-04-10 13:05:46 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-05-08 01:53:58 +0000
commit47f212295f17ef2473b37e3e8cfbddd411ad85ea (patch)
treee7609ac790d90fae85316076bf903b86e8ed485d
parentc56ea95b2845d2846eda8ceb740586fe936627c9 (diff)
downloadedk2-47f212295f17ef2473b37e3e8cfbddd411ad85ea.tar.gz
edk2-47f212295f17ef2473b37e3e8cfbddd411ad85ea.tar.bz2
edk2-47f212295f17ef2473b37e3e8cfbddd411ad85ea.zip
UefiCpuPkg/SmmRelocationLib: Add library instance for AMD
Due to the definition difference of SMRAM Save State, SmmBase config in SMRAM Save State for AMD is also different. This patch provides the AmdSmmRelocationLib library instance to handle the SMRAM Save State difference. Cc: Abdul Lateef Attar <AbdulLateef.Attar@amd.com> Cc: Abner Chang <abner.chang@amd.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Zeng Star <star.zeng@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com> Acked-by: Ray Ni <ray.ni@intel.com> Reviewed-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
-rw-r--r--UefiCpuPkg/Library/SmmRelocationLib/AmdSmmRelocationLib.inf60
-rw-r--r--UefiCpuPkg/Library/SmmRelocationLib/AmdSmramSaveStateConfig.c125
-rw-r--r--UefiCpuPkg/UefiCpuPkg.dsc1
3 files changed, 186 insertions, 0 deletions
diff --git a/UefiCpuPkg/Library/SmmRelocationLib/AmdSmmRelocationLib.inf b/UefiCpuPkg/Library/SmmRelocationLib/AmdSmmRelocationLib.inf
new file mode 100644
index 0000000000..e69079fa02
--- /dev/null
+++ b/UefiCpuPkg/Library/SmmRelocationLib/AmdSmmRelocationLib.inf
@@ -0,0 +1,60 @@
+## @file
+# SMM Relocation Lib for each processor.
+#
+# This Lib produces the SMM_BASE_HOB in HOB database which tells
+# the PiSmmCpuDxeSmm driver (runs at a later phase) about the new
+# SMBASE for each processor. PiSmmCpuDxeSmm driver installs the
+# SMI handler at the SMM_BASE_HOB.SmBase[Index]+0x8000 for processor
+# Index.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmRelocationLib
+ FILE_GUID = 65C74DCD-0D09-494A-8BFF-A64226EB8054
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SmmRelocationLib
+
+[Sources]
+ InternalSmmRelocationLib.h
+ AmdSmramSaveStateConfig.c
+ SmmRelocationLib.c
+
+[Sources.Ia32]
+ Ia32/Semaphore.c
+ Ia32/SmmInit.nasm
+
+[Sources.X64]
+ X64/Semaphore.c
+ X64/SmmInit.nasm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ CpuExceptionHandlerLib
+ DebugLib
+ HobLib
+ LocalApicLib
+ MemoryAllocationLib
+ PcdLib
+ PeiServicesLib
+
+[Guids]
+ gSmmBaseHobGuid ## HOB ALWAYS_PRODUCED
+ gEfiSmmSmramMemoryGuid ## CONSUMES
+
+[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+
+[FeaturePcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugSupport ## CONSUMES
diff --git a/UefiCpuPkg/Library/SmmRelocationLib/AmdSmramSaveStateConfig.c b/UefiCpuPkg/Library/SmmRelocationLib/AmdSmramSaveStateConfig.c
new file mode 100644
index 0000000000..068ae60887
--- /dev/null
+++ b/UefiCpuPkg/Library/SmmRelocationLib/AmdSmramSaveStateConfig.c
@@ -0,0 +1,125 @@
+/** @file
+ Config SMRAM Save State for SmmBases Relocation.
+
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "InternalSmmRelocationLib.h"
+#include <Register/Amd/SmramSaveStateMap.h>
+
+#define EFER_ADDRESS 0XC0000080ul
+
+/**
+ Get the mode of the CPU at the time an SMI occurs
+
+ @retval EFI_MM_SAVE_STATE_REGISTER_LMA_32BIT 32 bit.
+ @retval EFI_MM_SAVE_STATE_REGISTER_LMA_64BIT 64 bit.
+
+**/
+UINT8
+GetMmSaveStateRegisterLma (
+ VOID
+ )
+{
+ UINT8 SmmSaveStateRegisterLma;
+ UINT32 LMAValue;
+
+ SmmSaveStateRegisterLma = (UINT8)EFI_MM_SAVE_STATE_REGISTER_LMA_32BIT;
+
+ LMAValue = (UINT32)AsmReadMsr64 (EFER_ADDRESS) & LMA;
+ if (LMAValue) {
+ SmmSaveStateRegisterLma = (UINT8)EFI_MM_SAVE_STATE_REGISTER_LMA_64BIT;
+ }
+
+ return SmmSaveStateRegisterLma;
+}
+
+/**
+ This function configures the SmBase on the currently executing CPU.
+
+ @param[in] SmBase The SmBase on the currently executing CPU.
+
+**/
+VOID
+EFIAPI
+ConfigureSmBase (
+ IN UINT64 SmBase
+ )
+{
+ AMD_SMRAM_SAVE_STATE_MAP *AmdCpuState;
+
+ AmdCpuState = (AMD_SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
+
+ AmdCpuState->x64.SMBASE = (UINT32)SmBase;
+}
+
+/**
+ This function updates the SMRAM save state on the currently executing CPU
+ to resume execution at a specific address after an RSM instruction. This
+ function must evaluate the SMRAM save state to determine the execution mode
+ the RSM instruction resumes and update the resume execution address with
+ either NewInstructionPointer32 or NewInstructionPoint. The auto HALT restart
+ flag in the SMRAM save state must always be cleared. This function returns
+ the value of the instruction pointer from the SMRAM save state that was
+ replaced. If this function returns 0, then the SMRAM save state was not
+ modified.
+
+ This function is called during the very first SMI on each CPU after
+ SmmCpuFeaturesInitializeProcessor() to set a flag in normal execution mode
+ to signal that the SMBASE of each CPU has been updated before the default
+ SMBASE address is used for the first SMI to the next CPU.
+
+ @param[in,out] CpuState Pointer to SMRAM Save State Map for the
+ currently executing CPU.
+ @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to
+ 32-bit mode from 64-bit SMM.
+ @param[in] NewInstructionPointer Instruction pointer to use if resuming to
+ same mode as SMM.
+
+ @retval The value of the original instruction pointer before it was hooked.
+
+**/
+UINT64
+EFIAPI
+HookReturnFromSmm (
+ IN OUT SMRAM_SAVE_STATE_MAP *CpuState,
+ IN UINT64 NewInstructionPointer32,
+ IN UINT64 NewInstructionPointer
+ )
+{
+ UINT64 OriginalInstructionPointer;
+ AMD_SMRAM_SAVE_STATE_MAP *AmdCpuState;
+
+ AmdCpuState = (AMD_SMRAM_SAVE_STATE_MAP *)CpuState;
+
+ if (GetMmSaveStateRegisterLma () == EFI_MM_SAVE_STATE_REGISTER_LMA_32BIT) {
+ OriginalInstructionPointer = (UINT64)AmdCpuState->x86._EIP;
+ AmdCpuState->x86._EIP = (UINT32)NewInstructionPointer;
+ //
+ // Clear the auto HALT restart flag so the RSM instruction returns
+ // program control to the instruction following the HLT instruction.
+ //
+ if ((AmdCpuState->x86.AutoHALTRestart & BIT0) != 0) {
+ AmdCpuState->x86.AutoHALTRestart &= ~BIT0;
+ }
+ } else {
+ OriginalInstructionPointer = AmdCpuState->x64._RIP;
+ if ((AmdCpuState->x64.EFER & LMA) == 0) {
+ AmdCpuState->x64._RIP = (UINT32)NewInstructionPointer32;
+ } else {
+ AmdCpuState->x64._RIP = (UINT32)NewInstructionPointer;
+ }
+
+ //
+ // Clear the auto HALT restart flag so the RSM instruction returns
+ // program control to the instruction following the HLT instruction.
+ //
+ if ((AmdCpuState->x64.AutoHALTRestart & BIT0) != 0) {
+ AmdCpuState->x64.AutoHALTRestart &= ~BIT0;
+ }
+ }
+
+ return OriginalInstructionPointer;
+}
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 8f67587e91..3d49f72588 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -202,6 +202,7 @@
UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf
UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.inf
UefiCpuPkg/Library/SmmRelocationLib/SmmRelocationLib.inf
+ UefiCpuPkg/Library/SmmRelocationLib/AmdSmmRelocationLib.inf
[Components.X64]
UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf