summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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