summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/Library/MmSaveStateLib/MmSaveStateCommon.c
diff options
context:
space:
mode:
authorAbdul Lateef Attar <AbdulLateef.Attar@amd.com>2023-01-10 17:00:37 +0530
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-07-03 03:01:10 +0000
commit775b337c78a059d7897a80c3248f176730386fe1 (patch)
treef89398d6a89176ebfde5efb7e403388fe27be45c /UefiCpuPkg/Library/MmSaveStateLib/MmSaveStateCommon.c
parent4f3ddc6e154853f3422c1f1cd355bfff69c805fb (diff)
downloadedk2-775b337c78a059d7897a80c3248f176730386fe1.tar.gz
edk2-775b337c78a059d7897a80c3248f176730386fe1.tar.bz2
edk2-775b337c78a059d7897a80c3248f176730386fe1.zip
UefiCpuPkg: Implements MmSaveStateLib library instance
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4182 Implements MmSaveStateLib Library class for AMD cpu family. Cc: Paul Grimes <paul.grimes@amd.com> Cc: Abner Chang <abner.chang@amd.com> Cc: Eric Dong <eric.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Abdul Lateef Attar <abdattar@amd.com> Reviewed-by: Abner Chang <abner.chang@amd.com>
Diffstat (limited to 'UefiCpuPkg/Library/MmSaveStateLib/MmSaveStateCommon.c')
-rw-r--r--UefiCpuPkg/Library/MmSaveStateLib/MmSaveStateCommon.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/UefiCpuPkg/Library/MmSaveStateLib/MmSaveStateCommon.c b/UefiCpuPkg/Library/MmSaveStateLib/MmSaveStateCommon.c
new file mode 100644
index 0000000000..09c6c3f96f
--- /dev/null
+++ b/UefiCpuPkg/Library/MmSaveStateLib/MmSaveStateCommon.c
@@ -0,0 +1,132 @@
+/** @file
+ Provides common supporting function to access SMRAM Save State Map
+
+ Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MmSaveState.h"
+
+// Table used by MmSaveStateGetRegisterIndex() to convert an EFI_MM_SAVE_STATE_REGISTER
+// value to an index into a table of type CPU_MM_SAVE_STATE_LOOKUP_ENTRY
+CONST CPU_MM_SAVE_STATE_REGISTER_RANGE mCpuRegisterRanges[] = {
+ MM_REGISTER_RANGE (EFI_MM_SAVE_STATE_REGISTER_GDTBASE, EFI_MM_SAVE_STATE_REGISTER_LDTINFO),
+ MM_REGISTER_RANGE (EFI_MM_SAVE_STATE_REGISTER_ES, EFI_MM_SAVE_STATE_REGISTER_RIP),
+ MM_REGISTER_RANGE (EFI_MM_SAVE_STATE_REGISTER_RFLAGS, EFI_MM_SAVE_STATE_REGISTER_CR4),
+ { (EFI_MM_SAVE_STATE_REGISTER)0, (EFI_MM_SAVE_STATE_REGISTER)0, 0}
+};
+
+extern CONST CPU_MM_SAVE_STATE_LOOKUP_ENTRY mCpuWidthOffset[];
+
+/**
+ Read information from the CPU save state.
+
+ @param Register Specifies the CPU register to read form the save state.
+ @param RegOffset Offset for the next register index.
+
+ @retval 0 Register is not valid
+ @retval >0 Index into mCpuWidthOffset[] associated with Register
+
+**/
+UINTN
+MmSaveStateGetRegisterIndex (
+ IN EFI_MM_SAVE_STATE_REGISTER Register,
+ IN UINTN RegOffset
+ )
+{
+ UINTN Index;
+ UINTN Offset;
+
+ for (Index = 0, Offset = RegOffset; mCpuRegisterRanges[Index].Length != 0; Index++) {
+ if ((Register >= mCpuRegisterRanges[Index].Start) && (Register <= mCpuRegisterRanges[Index].End)) {
+ return Register - mCpuRegisterRanges[Index].Start + Offset;
+ }
+
+ Offset += mCpuRegisterRanges[Index].Length;
+ }
+
+ return 0;
+}
+
+/**
+ Read a CPU Save State register on the target processor.
+
+ This function abstracts the differences that whether the CPU Save State register is in the
+ IA32 CPU Save State Map or X64 CPU Save State Map.
+
+ This function supports reading a CPU Save State register in SMBase relocation handler.
+
+ @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
+ @param[in] RegisterIndex Index into mCpuWidthOffset[] look up table.
+ @param[in] Width The number of bytes to read from the CPU save state.
+ @param[out] Buffer Upon return, this holds the CPU register value read from the save state.
+
+ @retval EFI_SUCCESS The register was read from Save State.
+ @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
+ @retval EFI_INVALID_PARAMTER This or Buffer is NULL.
+
+**/
+EFI_STATUS
+MmSaveStateReadRegisterByIndex (
+ IN UINTN CpuIndex,
+ IN UINTN RegisterIndex,
+ IN UINTN Width,
+ OUT VOID *Buffer
+ )
+{
+ if (RegisterIndex == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (MmSaveStateGetRegisterLma () == EFI_MM_SAVE_STATE_REGISTER_LMA_32BIT) {
+ //
+ // If 32-bit mode width is zero, then the specified register can not be accessed
+ //
+ if (mCpuWidthOffset[RegisterIndex].Width32 == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // If Width is bigger than the 32-bit mode width, then the specified register can not be accessed
+ //
+ if (Width > mCpuWidthOffset[RegisterIndex].Width32) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Write return buffer
+ //
+ ASSERT (gSmst->CpuSaveState[CpuIndex] != NULL);
+ CopyMem (Buffer, (UINT8 *)gSmst->CpuSaveState[CpuIndex] + mCpuWidthOffset[RegisterIndex].Offset32, Width);
+ } else {
+ //
+ // If 64-bit mode width is zero, then the specified register can not be accessed
+ //
+ if (mCpuWidthOffset[RegisterIndex].Width64 == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // If Width is bigger than the 64-bit mode width, then the specified register can not be accessed
+ //
+ if (Width > mCpuWidthOffset[RegisterIndex].Width64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Write lower 32-bits of return buffer
+ //
+ CopyMem (Buffer, (UINT8 *)gSmst->CpuSaveState[CpuIndex] + mCpuWidthOffset[RegisterIndex].Offset64Lo, MIN (4, Width));
+ if (Width > 4) {
+ //
+ // Write upper 32-bits of return buffer
+ //
+ CopyMem ((UINT8 *)Buffer + 4, (UINT8 *)gSmst->CpuSaveState[CpuIndex] + mCpuWidthOffset[RegisterIndex].Offset64Hi, Width - 4);
+ }
+ }
+
+ return EFI_SUCCESS;
+}