From: "Chang, Abner" <abner.chang@amd.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>,
"Attar, AbdulLateef (Abdul Lateef)" <AbdulLateef.Attar@amd.com>
Cc: "Grimes, Paul" <Paul.Grimes@amd.com>,
"Kirkendall, Garrett" <Garrett.Kirkendall@amd.com>,
Eric Dong <eric.dong@intel.com>, Ray Ni <ray.ni@intel.com>,
Rahul Kumar <rahul1.kumar@intel.com>,
Gerd Hoffmann <kraxel@redhat.com>
Subject: Re: [edk2-devel] [PATCH v7 7/8] UefiCpuPkg: Implements SmmSmramSaveStateLib for Intel
Date: Mon, 10 Apr 2023 04:22:08 +0000 [thread overview]
Message-ID: <MN2PR12MB396603671D88E4F45F76AB22EA959@MN2PR12MB3966.namprd12.prod.outlook.com> (raw)
In-Reply-To: <b7af8aaa119585ad5183dc068bc458109ca4f883.1680847286.git.abdattar@amd.com>
[AMD Official Use Only - General]
Reviewed-by: Abner Chang <abner.chang@amd.com>
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Abdul
> Lateef Attar via groups.io
> Sent: Friday, April 7, 2023 2:58 PM
> To: devel@edk2.groups.io
> Cc: Attar, AbdulLateef (Abdul Lateef) <AbdulLateef.Attar@amd.com>;
> Grimes, Paul <Paul.Grimes@amd.com>; Kirkendall, Garrett
> <Garrett.Kirkendall@amd.com>; Chang, Abner <Abner.Chang@amd.com>;
> Eric Dong <eric.dong@intel.com>; Ray Ni <ray.ni@intel.com>; Rahul Kumar
> <rahul1.kumar@intel.com>; Gerd Hoffmann <kraxel@redhat.com>
> Subject: [edk2-devel] [PATCH v7 7/8] UefiCpuPkg: Implements
> SmmSmramSaveStateLib for Intel
>
> Caution: This message originated from an External Source. Use proper
> caution when opening attachments, clicking links, or responding.
>
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4182
>
> Implements SmmSmramSaveStateLib library interfaces to read and write
> save state registers for Intel processor family.
>
> Moves Intel and AMD common functionality to common area.
>
> Cc: Paul Grimes <paul.grimes@amd.com>
> Cc: Garrett Kirkendall <garrett.kirkendall@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>
> ---
> UefiCpuPkg/UefiCpuPkg.dsc | 4 +
> .../IntelSmmSmramSaveStateLib.inf | 28 ++
> .../SmmSmramSaveStateLib/SmramSaveState.h | 1 -
> .../SmmSmramSaveStateLib/AmdSmramSaveState.c | 32 --
> .../IntelSmramSaveState.c | 359 ++++++++++++++++++
> .../SmramSaveStateCommon.c | 116 +++++-
> 6 files changed, 503 insertions(+), 37 deletions(-) create mode 100644
> UefiCpuPkg/Library/SmmSmramSaveStateLib/IntelSmmSmramSaveStateLib.i
> nf
> create mode 100644
> UefiCpuPkg/Library/SmmSmramSaveStateLib/IntelSmramSaveState.c
>
> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index
> 043eb2dbc1b1..df555fdf32de 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dsc
> +++ b/UefiCpuPkg/UefiCpuPkg.dsc
> @@ -102,6 +102,7 @@ [LibraryClasses.common.DXE_SMM_DRIVER]
> HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
>
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/Smm
> CpuExceptionHandlerLib.inf
>
> SmmSmramSaveStateLib|UefiCpuPkg/Library/SmmSmramSaveStateLib/Am
> dSmmSmramSaveStateLib.inf
> +
> +
> SmmSmramSaveStateLib|UefiCpuPkg/Library/SmmSmramSaveStateLib/Intel
> SmmS
> + mramSaveStateLib.inf
>
> [LibraryClasses.common.MM_STANDALONE]
>
> MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/Stan
> daloneMmServicesTableLib.inf
> @@ -170,6 +171,7 @@ [Components.IA32, Components.X64]
> FILE_GUID = D1D74FE9-7A4E-41D3-A0B3-67F13AD34D94
> <LibraryClasses>
>
> SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFea
> turesLibStm.inf
> +
> +
> SmmSmramSaveStateLib|UefiCpuPkg/Library/SmmSmramSaveStateLib/Intel
> SmmS
> + mramSaveStateLib.inf
> }
> UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
> <Defines>
> @@ -177,6 +179,7 @@ [Components.IA32, Components.X64]
> <LibraryClasses>
>
> SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCp
> uFeaturesLib.inf
>
> SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull
> /SmmCpuPlatformHookLibNull.inf
> +
> +
> SmmSmramSaveStateLib|UefiCpuPkg/Library/SmmSmramSaveStateLib/Am
> dSmmSmr
> + amSaveStateLib.inf
> }
> UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
> UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
> @@ -194,6 +197,7 @@ [Components.IA32, Components.X64]
>
> UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultRep
> ortLib/UnitTestResultReportLibConOut.inf
> }
>
> UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLib.
> inf
> +
> UefiCpuPkg/Library/SmmSmramSaveStateLib/IntelSmmSmramSaveStateLib.i
> nf
> UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.inf
>
> [Components.X64]
> diff --git
> a/UefiCpuPkg/Library/SmmSmramSaveStateLib/IntelSmmSmramSaveStateLi
> b.inf
> b/UefiCpuPkg/Library/SmmSmramSaveStateLib/IntelSmmSmramSaveStateLi
> b.inf
> new file mode 100644
> index 000000000000..c9d438027b03
> --- /dev/null
> +++
> b/UefiCpuPkg/Library/SmmSmramSaveStateLib/IntelSmmSmramSaveStateLi
> b.
> +++ inf
> @@ -0,0 +1,28 @@
> +## @file
> +# SMM Smram save state service lib.
> +#
> +# This is SMM Smram save state service lib that provide service to read
> +and # save savestate area registers.
> +#
> +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights
> +reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> + INF_VERSION = 1.29
> + BASE_NAME = IntelSmmSmramSaveStateLib
> + FILE_GUID = 37E8137B-9F74-4250-8951-7A970A3C39C0
> + MODULE_TYPE = DXE_SMM_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = SmmSmramSaveStateLib
> +
> +[Sources]
> + SmramSaveState.h
> + SmramSaveStateCommon.c
> + IntelSmramSaveState.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> diff --git a/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h
> b/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h
> index 6c424e3e36e9..55d9d9f127c0 100644
> --- a/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h
> +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h
> @@ -90,7 +90,6 @@ SmramSaveStateGetRegisterIndex (
>
> **/
> EFI_STATUS
> -EFIAPI
> SmramSaveStateReadRegisterByIndex (
> IN UINTN CpuIndex,
> IN UINTN RegisterIndex,
> diff --git
> a/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveState.c
> b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveState.c
> index 8fc4466f473e..e0acd6182320 100644
> --- a/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveState.c
> +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveState.c
> @@ -11,21 +11,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> #include <Register/Amd/SmramSaveStateMap.h>
> #include <Library/BaseLib.h>
>
> -#define EFER_ADDRESS 0XC0000080ul
> #define SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX 1
>
> // Macro used to simplify the lookup table entries of type
> CPU_SMM_SAVE_STATE_LOOKUP_ENTRY #define SMM_CPU_OFFSET(Field)
> OFFSET_OF (AMD_SMRAM_SAVE_STATE_MAP, Field)
>
> -// Table used by SmramSaveStateGetRegisterIndex() to convert an
> EFI_SMM_SAVE_STATE_REGISTER -// value to an index into a table of type
> CPU_SMM_SAVE_STATE_LOOKUP_ENTRY -CONST
> CPU_SMM_SAVE_STATE_REGISTER_RANGE
> mSmmSmramCpuRegisterRanges[] = {
> - SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_GDTBASE,
> EFI_SMM_SAVE_STATE_REGISTER_LDTINFO),
> - SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_ES,
> EFI_SMM_SAVE_STATE_REGISTER_RIP),
> - SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_RFLAGS,
> EFI_SMM_SAVE_STATE_REGISTER_CR4),
> - { (EFI_SMM_SAVE_STATE_REGISTER)0,
> (EFI_SMM_SAVE_STATE_REGISTER)0, 0}
> -};
> -
> // Lookup table used to retrieve the widths and offsets associated with each
> // supported EFI_SMM_SAVE_STATE_REGISTER value CONST
> CPU_SMM_SAVE_STATE_LOOKUP_ENTRY mSmmSmramCpuWidthOffset[]
> = { @@ -294,25 +284,3 @@ SmramSaveStateWriteRegister (
>
> return EFI_SUCCESS;
> }
> -
> -/**
> - Returns LMA value of the Processor.
> -
> - @param[in] VOID
> -
> - @retval UINT8 returns LMA bit value.
> -**/
> -UINT8
> -SmramSaveStateGetRegisterLma (
> - VOID
> - )
> -{
> - UINT32 LMAValue;
> -
> - LMAValue = (UINT32)AsmReadMsr64 (EFER_ADDRESS) & LMA;
> - if (LMAValue) {
> - return EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;
> - }
> -
> - return EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT;
> -}
> diff --git
> a/UefiCpuPkg/Library/SmmSmramSaveStateLib/IntelSmramSaveState.c
> b/UefiCpuPkg/Library/SmmSmramSaveStateLib/IntelSmramSaveState.c
> new file mode 100644
> index 000000000000..ac6c43772f14
> --- /dev/null
> +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/IntelSmramSaveState.c
> @@ -0,0 +1,359 @@
> +/** @file
> +Provides services 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 "SmramSaveState.h"
> +#include <Register/Intel/SmramSaveStateMap.h>
> +#include <Register/Intel/Cpuid.h>
> +#include <Library/BaseLib.h>
> +
> +#define SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX 1
> +#define SMM_SAVE_STATE_REGISTER_IOMISC_INDEX 2
> +#define SMM_SAVE_STATE_REGISTER_IOMEMADDR_INDEX 3 #define
> +INTEL_SMM_SAVE_STATE_REGISTER_MAX_INDEX 4
> +
> +///
> +/// Macro used to simplify the lookup table entries of type
> +CPU_SMM_SAVE_STATE_LOOKUP_ENTRY /// #define
> SMM_CPU_OFFSET(Field)
> +OFFSET_OF (SMRAM_SAVE_STATE_MAP, Field)
> +
> +///
> +/// Lookup table used to retrieve the widths and offsets associated
> +with each /// supported EFI_SMM_SAVE_STATE_REGISTER value /// CONST
> +CPU_SMM_SAVE_STATE_LOOKUP_ENTRY mSmmSmramCpuWidthOffset[]
> = {
> + { 0, 0, 0, 0, 0, FALSE }, //
> Reserved
> +
> + //
> + // Internally defined CPU Save State Registers. Not defined in PI SMM CPU
> Protocol.
> + //
> + { 4, 4, SMM_CPU_OFFSET (x86.SMMRevId), SMM_CPU_OFFSET
> (x64.SMMRevId), 0, FALSE }, //
> SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX = 1
> + { 4, 4, SMM_CPU_OFFSET (x86.IOMisc), SMM_CPU_OFFSET (x64.IOMisc),
> 0, FALSE }, // SMM_SAVE_STATE_REGISTER_IOMISC_INDEX
> = 2
> + { 4, 8, SMM_CPU_OFFSET (x86.IOMemAddr), SMM_CPU_OFFSET
> (x64.IOMemAddr), SMM_CPU_OFFSET (x64.IOMemAddr) + 4, FALSE }, //
> SMM_SAVE_STATE_REGISTER_IOMEMADDR_INDEX = 3
> +
> + //
> + // CPU Save State registers defined in PI SMM CPU Protocol.
> + //
> + { 0, 8, 0, SMM_CPU_OFFSET (x64.GdtBaseLoDword),
> SMM_CPU_OFFSET (x64.GdtBaseHiDword), FALSE }, //
> EFI_SMM_SAVE_STATE_REGISTER_GDTBASE = 4
> + { 0, 8, 0, SMM_CPU_OFFSET (x64.IdtBaseLoDword),
> SMM_CPU_OFFSET (x64.IdtBaseHiDword), FALSE }, //
> EFI_SMM_SAVE_STATE_REGISTER_IDTBASE = 5
> + { 0, 8, 0, SMM_CPU_OFFSET (x64.LdtBaseLoDword),
> SMM_CPU_OFFSET (x64.LdtBaseHiDword), FALSE }, //
> EFI_SMM_SAVE_STATE_REGISTER_LDTBASE = 6
> + { 0, 0, 0, 0, 0, FALSE }, //
> EFI_SMM_SAVE_STATE_REGISTER_GDTLIMIT = 7
> + { 0, 0, 0, 0, 0, FALSE }, //
> EFI_SMM_SAVE_STATE_REGISTER_IDTLIMIT = 8
> + { 0, 0, 0, 0, 0, FALSE }, //
> EFI_SMM_SAVE_STATE_REGISTER_LDTLIMIT = 9
> + { 0, 0, 0, 0, 0, FALSE }, //
> EFI_SMM_SAVE_STATE_REGISTER_LDTINFO = 10
> +
> + { 4, 4, SMM_CPU_OFFSET (x86._ES), SMM_CPU_OFFSET (x64._ES),
> 0, FALSE }, // EFI_SMM_SAVE_STATE_REGISTER_ES = 20
> + { 4, 4, SMM_CPU_OFFSET (x86._CS), SMM_CPU_OFFSET (x64._CS),
> 0, FALSE }, // EFI_SMM_SAVE_STATE_REGISTER_CS = 21
> + { 4, 4, SMM_CPU_OFFSET (x86._SS), SMM_CPU_OFFSET (x64._SS),
> 0, FALSE }, // EFI_SMM_SAVE_STATE_REGISTER_SS = 22
> + { 4, 4, SMM_CPU_OFFSET (x86._DS), SMM_CPU_OFFSET (x64._DS),
> 0, FALSE }, // EFI_SMM_SAVE_STATE_REGISTER_DS = 23
> + { 4, 4, SMM_CPU_OFFSET (x86._FS), SMM_CPU_OFFSET (x64._FS),
> 0, FALSE }, // EFI_SMM_SAVE_STATE_REGISTER_FS = 24
> + { 4, 4, SMM_CPU_OFFSET (x86._GS), SMM_CPU_OFFSET (x64._GS),
> 0, FALSE }, // EFI_SMM_SAVE_STATE_REGISTER_GS = 25
> + { 0, 4, 0, SMM_CPU_OFFSET (x64._LDTR), 0,
> FALSE }, // EFI_SMM_SAVE_STATE_REGISTER_LDTR_SEL = 26
> + { 4, 4, SMM_CPU_OFFSET (x86._TR), SMM_CPU_OFFSET (x64._TR),
> 0, FALSE }, // EFI_SMM_SAVE_STATE_REGISTER_TR_SEL =
> 27
> + { 4, 8, SMM_CPU_OFFSET (x86._DR7), SMM_CPU_OFFSET (x64._DR7),
> SMM_CPU_OFFSET (x64._DR7) + 4, FALSE }, //
> EFI_SMM_SAVE_STATE_REGISTER_DR7 = 28
> + { 4, 8, SMM_CPU_OFFSET (x86._DR6), SMM_CPU_OFFSET (x64._DR6),
> SMM_CPU_OFFSET (x64._DR6) + 4, FALSE }, //
> EFI_SMM_SAVE_STATE_REGISTER_DR6 = 29
> + { 0, 8, 0, SMM_CPU_OFFSET (x64._R8),
> SMM_CPU_OFFSET (x64._R8) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_R8 = 30
> + { 0, 8, 0, SMM_CPU_OFFSET (x64._R9),
> SMM_CPU_OFFSET (x64._R9) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_R9 = 31
> + { 0, 8, 0, SMM_CPU_OFFSET (x64._R10),
> SMM_CPU_OFFSET (x64._R10) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_R10 = 32
> + { 0, 8, 0, SMM_CPU_OFFSET (x64._R11),
> SMM_CPU_OFFSET (x64._R11) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_R11 = 33
> + { 0, 8, 0, SMM_CPU_OFFSET (x64._R12),
> SMM_CPU_OFFSET (x64._R12) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_R12 = 34
> + { 0, 8, 0, SMM_CPU_OFFSET (x64._R13),
> SMM_CPU_OFFSET (x64._R13) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_R13 = 35
> + { 0, 8, 0, SMM_CPU_OFFSET (x64._R14),
> SMM_CPU_OFFSET (x64._R14) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_R14 = 36
> + { 0, 8, 0, SMM_CPU_OFFSET (x64._R15),
> SMM_CPU_OFFSET (x64._R15) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_R15 = 37
> + { 4, 8, SMM_CPU_OFFSET (x86._EAX), SMM_CPU_OFFSET (x64._RAX),
> SMM_CPU_OFFSET (x64._RAX) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_RAX = 38
> + { 4, 8, SMM_CPU_OFFSET (x86._EBX), SMM_CPU_OFFSET (x64._RBX),
> SMM_CPU_OFFSET (x64._RBX) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_RBX = 39
> + { 4, 8, SMM_CPU_OFFSET (x86._ECX), SMM_CPU_OFFSET (x64._RCX),
> SMM_CPU_OFFSET (x64._RCX) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_RCX = 40
> + { 4, 8, SMM_CPU_OFFSET (x86._EDX), SMM_CPU_OFFSET (x64._RDX),
> SMM_CPU_OFFSET (x64._RDX) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_RDX = 41
> + { 4, 8, SMM_CPU_OFFSET (x86._ESP), SMM_CPU_OFFSET (x64._RSP),
> SMM_CPU_OFFSET (x64._RSP) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_RSP = 42
> + { 4, 8, SMM_CPU_OFFSET (x86._EBP), SMM_CPU_OFFSET (x64._RBP),
> SMM_CPU_OFFSET (x64._RBP) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_RBP = 43
> + { 4, 8, SMM_CPU_OFFSET (x86._ESI), SMM_CPU_OFFSET (x64._RSI),
> SMM_CPU_OFFSET (x64._RSI) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_RSI = 44
> + { 4, 8, SMM_CPU_OFFSET (x86._EDI), SMM_CPU_OFFSET (x64._RDI),
> SMM_CPU_OFFSET (x64._RDI) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_RDI = 45
> + { 4, 8, SMM_CPU_OFFSET (x86._EIP), SMM_CPU_OFFSET (x64._RIP),
> SMM_CPU_OFFSET (x64._RIP) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_RIP = 46
> +
> + { 4, 8, SMM_CPU_OFFSET (x86._EFLAGS), SMM_CPU_OFFSET
> (x64._RFLAGS), SMM_CPU_OFFSET (x64._RFLAGS) + 4, TRUE }, //
> EFI_SMM_SAVE_STATE_REGISTER_RFLAGS = 51
> + { 4, 8, SMM_CPU_OFFSET (x86._CR0), SMM_CPU_OFFSET (x64._CR0),
> SMM_CPU_OFFSET (x64._CR0) + 4, FALSE }, //
> EFI_SMM_SAVE_STATE_REGISTER_CR0 = 52
> + { 4, 8, SMM_CPU_OFFSET (x86._CR3), SMM_CPU_OFFSET (x64._CR3),
> SMM_CPU_OFFSET (x64._CR3) + 4, FALSE }, //
> EFI_SMM_SAVE_STATE_REGISTER_CR3 = 53
> + { 0, 4, 0, SMM_CPU_OFFSET (x64._CR4), 0,
> FALSE }, // EFI_SMM_SAVE_STATE_REGISTER_CR4 = 54
> +};
> +
> +///
> +/// Structure used to build a lookup table for the IOMisc width
> +information /// typedef struct {
> + UINT8 Width;
> + EFI_SMM_SAVE_STATE_IO_WIDTH IoWidth;
> +} CPU_SMM_SAVE_STATE_IO_WIDTH;
> +
> +///
> +/// Lookup table for the IOMisc width information /// STATIC CONST
> +CPU_SMM_SAVE_STATE_IO_WIDTH mSmmCpuIoWidth[] = {
> + { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 0
> + { 1, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, //
> SMM_IO_LENGTH_BYTE =
> +1
> + { 2, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT16 }, //
> SMM_IO_LENGTH_WORD = 2
> + { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 3
> + { 4, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT32 }, //
> SMM_IO_LENGTH_DWORD = 4
> + { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 5
> + { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 6
> + { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 } // Undefined = 7
> +};
> +
> +///
> +/// Lookup table for the IOMisc type information /// STATIC CONST
> +EFI_SMM_SAVE_STATE_IO_TYPE mSmmCpuIoType[] = {
> + EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT, // SMM_IO_TYPE_OUT_DX
> = 0
> + EFI_SMM_SAVE_STATE_IO_TYPE_INPUT, // SMM_IO_TYPE_IN_DX
> = 1
> + EFI_SMM_SAVE_STATE_IO_TYPE_STRING, // SMM_IO_TYPE_OUTS
> = 2
> + EFI_SMM_SAVE_STATE_IO_TYPE_STRING, // SMM_IO_TYPE_INS =
> 3
> + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 4
> + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 5
> + EFI_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX, //
> SMM_IO_TYPE_REP_OUTS = 6
> + EFI_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX, //
> SMM_IO_TYPE_REP_INS = 7
> + EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT, //
> SMM_IO_TYPE_OUT_IMMEDIATE = 8
> + EFI_SMM_SAVE_STATE_IO_TYPE_INPUT, //
> SMM_IO_TYPE_OUT_IMMEDIATE = 9
> + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 10
> + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 11
> + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 12
> + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 13
> + (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 14
> + (EFI_SMM_SAVE_STATE_IO_TYPE)0 // Undefined = 15
> +};
> +
> +/**
> + Read an SMM Save State register on the target processor. If this
> +function
> + returns EFI_UNSUPPORTED, then the caller is responsible for reading
> +the
> + SMM Save Sate register.
> +
> + @param[in] CpuIndex The index of the CPU to read the SMM Save State.
> The
> + value must be between 0 and the NumberOfCpus field in
> + the System Management System Table (SMST).
> + @param[in] Register The SMM Save State register to read.
> + @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_INVALID_PARAMTER Buffer is NULL.
> + @retval EFI_UNSUPPORTED This function does not support reading
> Register.
> + @retval EFI_NOT_FOUND If desired Register not found.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmramSaveStateReadRegister (
> + IN UINTN CpuIndex,
> + IN EFI_SMM_SAVE_STATE_REGISTER Register,
> + IN UINTN Width,
> + OUT VOID *Buffer
> + )
> +{
> + UINT32 SmmRevId;
> + SMRAM_SAVE_STATE_IOMISC IoMisc;
> + EFI_SMM_SAVE_STATE_IO_INFO *IoInfo;
> +
> + //
> + // Check for special EFI_SMM_SAVE_STATE_REGISTER_LMA // if
> + (Register == EFI_SMM_SAVE_STATE_REGISTER_LMA) {
> + //
> + // Only byte access is supported for this register
> + //
> + if (Width != 1) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *(UINT8 *)Buffer = SmramSaveStateGetRegisterLma ();
> +
> + return EFI_SUCCESS;
> + }
> +
> + //
> + // Check for special EFI_SMM_SAVE_STATE_REGISTER_IO // if (Register
> + == EFI_SMM_SAVE_STATE_REGISTER_IO) {
> + //
> + // Get SMM Revision ID
> + //
> + SmramSaveStateReadRegisterByIndex (CpuIndex,
> + SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX, sizeof (SmmRevId),
> &SmmRevId);
> +
> + //
> + // See if the CPU supports the IOMisc register in the save state
> + //
> + if (SmmRevId < SMRAM_SAVE_STATE_MIN_REV_ID_IOMISC) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Get the IOMisc register value
> + //
> + SmramSaveStateReadRegisterByIndex (CpuIndex,
> + SMM_SAVE_STATE_REGISTER_IOMISC_INDEX, sizeof (IoMisc.Uint32),
> + &IoMisc.Uint32);
> +
> + //
> + // Check for the SMI_FLAG in IOMisc
> + //
> + if (IoMisc.Bits.SmiFlag == 0) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Only support IN/OUT, but not INS/OUTS/REP INS/REP OUTS.
> + //
> + if ((mSmmCpuIoType[IoMisc.Bits.Type] !=
> EFI_SMM_SAVE_STATE_IO_TYPE_INPUT) &&
> + (mSmmCpuIoType[IoMisc.Bits.Type] !=
> EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT))
> + {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Compute index for the I/O Length and I/O Type lookup tables
> + //
> + if ((mSmmCpuIoWidth[IoMisc.Bits.Length].Width == 0) ||
> (mSmmCpuIoType[IoMisc.Bits.Type] == 0)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Make sure the incoming buffer is large enough to hold IoInfo before
> accessing
> + //
> + if (Width < sizeof (EFI_SMM_SAVE_STATE_IO_INFO)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Zero the IoInfo structure that will be returned in Buffer
> + //
> + IoInfo = (EFI_SMM_SAVE_STATE_IO_INFO *)Buffer;
> + ZeroMem (IoInfo, sizeof (EFI_SMM_SAVE_STATE_IO_INFO));
> +
> + //
> + // Use lookup tables to help fill in all the fields of the IoInfo structure
> + //
> + IoInfo->IoPort = (UINT16)IoMisc.Bits.Port;
> + IoInfo->IoWidth = mSmmCpuIoWidth[IoMisc.Bits.Length].IoWidth;
> + IoInfo->IoType = mSmmCpuIoType[IoMisc.Bits.Type];
> + SmramSaveStateReadRegister (CpuIndex,
> EFI_SMM_SAVE_STATE_REGISTER_RAX,
> mSmmCpuIoWidth[IoMisc.Bits.Length].Width, &IoInfo->IoData);
> + return EFI_SUCCESS;
> + }
> +
> + //
> + // Convert Register to a register lookup table index
> + //
> + return SmramSaveStateReadRegisterByIndex (CpuIndex,
> +SmramSaveStateGetRegisterIndex (Register), Width, Buffer); }
> +
> +/**
> + Writes an SMM Save State register on the target processor. If this
> +function
> + returns EFI_UNSUPPORTED, then the caller is responsible for writing
> +the
> + SMM Save Sate register.
> +
> + @param[in] CpuIndex The index of the CPU to write the SMM Save State.
> The
> + value must be between 0 and the NumberOfCpus field in
> + the System Management System Table (SMST).
> + @param[in] Register The SMM Save State register to write.
> + @param[in] Width The number of bytes to write to the CPU save state.
> + @param[in] Buffer Upon entry, this holds the new CPU register value.
> +
> + @retval EFI_SUCCESS The register was written to Save State.
> + @retval EFI_INVALID_PARAMTER Buffer is NULL.
> + @retval EFI_UNSUPPORTED This function does not support writing
> Register.
> + @retval EFI_NOT_FOUND If desired Register not found.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmramSaveStateWriteRegister (
> + IN UINTN CpuIndex,
> + IN EFI_SMM_SAVE_STATE_REGISTER Register,
> + IN UINTN Width,
> + IN CONST VOID *Buffer
> + )
> +{
> + UINTN RegisterIndex;
> + SMRAM_SAVE_STATE_MAP *CpuSaveState;
> +
> + //
> + // Writes to EFI_SMM_SAVE_STATE_REGISTER_LMA are ignored // if
> + (Register == EFI_SMM_SAVE_STATE_REGISTER_LMA) {
> + return EFI_SUCCESS;
> + }
> +
> + //
> + // Writes to EFI_SMM_SAVE_STATE_REGISTER_IO are not supported // if
> + (Register == EFI_SMM_SAVE_STATE_REGISTER_IO) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Convert Register to a register lookup table index //
> + RegisterIndex = SmramSaveStateGetRegisterIndex (Register); if
> + (RegisterIndex == 0) {
> + return EFI_NOT_FOUND;
> + }
> +
> + CpuSaveState = gSmst->CpuSaveState[CpuIndex];
> +
> + //
> + // Do not write non-writable SaveState, because it will cause exception.
> + //
> + if (!mSmmSmramCpuWidthOffset[RegisterIndex].Writeable) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + //
> + // Check CPU mode
> + //
> + if (SmramSaveStateGetRegisterLma () ==
> EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {
> + //
> + // If 32-bit mode width is zero, then the specified register can not be
> accessed
> + //
> + if (mSmmSmramCpuWidthOffset[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 > mSmmSmramCpuWidthOffset[RegisterIndex].Width32) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Write SMM State register
> + //
> + ASSERT (CpuSaveState != NULL);
> + CopyMem ((UINT8 *)CpuSaveState +
> + mSmmSmramCpuWidthOffset[RegisterIndex].Offset32, Buffer, Width); }
> else {
> + //
> + // If 64-bit mode width is zero, then the specified register can not be
> accessed
> + //
> + if (mSmmSmramCpuWidthOffset[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 > mSmmSmramCpuWidthOffset[RegisterIndex].Width64) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Write at most 4 of the lower bytes of SMM State register
> + //
> + CopyMem ((UINT8 *)CpuSaveState +
> mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Lo, Buffer, MIN (4,
> Width));
> + if (Width > 4) {
> + //
> + // Write at most 4 of the upper bytes of SMM State register
> + //
> + CopyMem ((UINT8 *)CpuSaveState +
> mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Hi, (UINT8 *)Buffer +
> 4, Width - 4);
> + }
> + }
> +
> + return EFI_SUCCESS;
> +}
> diff --git
> a/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveStateCommon.c
> b/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveStateCommon.c
> index 98e89f9eec3f..53025e12cff9 100644
> ---
> a/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveStateCommon.c
> +++
> b/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveStateCommon.c
> @@ -9,9 +9,24 @@
> **/
>
> #include "SmramSaveState.h"
> +#include <Library/BaseLib.h>
> +#include <Library/CpuLib.h>
>
> -extern CONST CPU_SMM_SAVE_STATE_REGISTER_RANGE
> mSmmSmramCpuRegisterRanges[];
> -extern CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY
> mSmmSmramCpuWidthOffset[];
> +#define CPUID_VERSION_INFO 0x01
> +#define CPUID_EXTENDED_FUNCTION 0x80000000
> +#define CPUID_EXTENDED_CPU_SIG 0x80000001
> +#define EFER_ADDRESS 0XC0000080ul
> +
> +// Table used by SmramSaveStateGetRegisterIndex() to convert an
> +EFI_SMM_SAVE_STATE_REGISTER // value to an index into a table of type
> +CPU_SMM_SAVE_STATE_LOOKUP_ENTRY CONST
> CPU_SMM_SAVE_STATE_REGISTER_RANGE
> +mSmmSmramCpuRegisterRanges[] = {
> + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_GDTBASE,
> EFI_SMM_SAVE_STATE_REGISTER_LDTINFO),
> + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_ES,
> EFI_SMM_SAVE_STATE_REGISTER_RIP),
> + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_RFLAGS,
> EFI_SMM_SAVE_STATE_REGISTER_CR4),
> + { (EFI_SMM_SAVE_STATE_REGISTER)0,
> (EFI_SMM_SAVE_STATE_REGISTER)0, 0}
> +};
> +
> +extern CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY
> +mSmmSmramCpuWidthOffset[];
>
> /**
> Read information from the CPU save state.
> @@ -61,7 +76,6 @@ SmramSaveStateGetRegisterIndex (
>
> **/
> EFI_STATUS
> -EFIAPI
> SmramSaveStateReadRegisterByIndex (
> IN UINTN CpuIndex,
> IN UINTN RegisterIndex,
> @@ -112,7 +126,7 @@ SmramSaveStateReadRegisterByIndex (
> // Write lower 32-bits of return buffer
> //
> CopyMem (Buffer, (UINT8 *)gSmst->CpuSaveState[CpuIndex] +
> mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Lo, MIN (4, Width));
> - if (Width >= 4) {
> + if (Width > 4) {
> //
> // Write upper 32-bits of return buffer
> //
> @@ -122,3 +136,97 @@ SmramSaveStateReadRegisterByIndex (
>
> return EFI_SUCCESS;
> }
> +
> +/**
> + Returns LMA value of the Processor.
> +
> + @param[in] VOID
> +
> + @retval UINT8 returns LMA bit value.
> +**/
> +UINT8
> +IntelSmramSaveStateGetRegisterLma (
> + VOID
> + )
> +{
> + UINT32 RegEax;
> + UINT32 RegEdx;
> + UINTN FamilyId;
> + UINTN ModelId;
> + UINT8 SmmSaveStateRegisterLma;
> +
> + //
> + // Retrieve CPU Family
> + //
> + AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL); FamilyId
> =
> + (RegEax >> 8) & 0xf; ModelId = (RegEax >> 4) & 0xf; if ((FamilyId
> + == 0x06) || (FamilyId == 0x0f)) {
> + ModelId = ModelId | ((RegEax >> 12) & 0xf0); }
> +
> + RegEdx = 0;
> + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); if
> + (RegEax >= CPUID_EXTENDED_CPU_SIG) {
> + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx); }
> +
> + //
> + // Determine the mode of the CPU at the time an SMI occurs
> + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> + // Volume 3C, Section 34.4.1.1
> + //
> + SmmSaveStateRegisterLma =
> EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT;
> + if ((RegEdx & BIT29) != 0) {
> + SmmSaveStateRegisterLma =
> EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;
> + }
> +
> + if (FamilyId == 0x06) {
> + if ((ModelId == 0x17) || (ModelId == 0x0f) || (ModelId == 0x1c)) {
> + SmmSaveStateRegisterLma =
> EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;
> + }
> + }
> +
> + return SmmSaveStateRegisterLma;
> +}
> +
> +/**
> + Returns LMA value of the Processor.
> +
> + @param[in] VOID
> +
> + @retval UINT8 returns LMA bit value.
> +**/
> +UINT8
> +AmdSmramSaveStateGetRegisterLma (
> + VOID
> + )
> +{
> + UINT32 LMAValue;
> +
> + LMAValue = (UINT32)AsmReadMsr64 (EFER_ADDRESS) & LMA; if
> (LMAValue)
> + {
> + return EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;
> + }
> +
> + return EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT;
> +}
> +
> +/**
> + Returns LMA value of the Processor.
> +
> + @param[in] VOID
> +
> + @retval UINT8 returns LMA bit value.
> +**/
> +UINT8
> +SmramSaveStateGetRegisterLma (
> + VOID
> + )
> +{
> + if (StandardSignatureIsAuthenticAMD ()) {
> + return AmdSmramSaveStateGetRegisterLma ();
> + }
> +
> + return IntelSmramSaveStateGetRegisterLma (); }
> --
> 2.25.1
>
>
>
>
>
next prev parent reply other threads:[~2023-04-10 4:22 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-07 6:57 [PATCH v7 0/8] Adds AmdSmmCpuFeaturesLib and SmmSmramSaveStateLib Abdul Lateef Attar
2023-04-07 6:57 ` [PATCH v7 1/8] MdePkg: Adds AMD SMRAM save state map Abdul Lateef Attar
2023-04-07 6:57 ` [PATCH v7 2/8] UefiCpuPkg: Adds SmmSmramSaveStateLib library class Abdul Lateef Attar
2023-04-07 6:57 ` [PATCH v7 3/8] UefiCpuPkg: Implements " Abdul Lateef Attar
2023-04-07 6:57 ` [PATCH v7 4/8] UefiCpuPkg/SmmCpuFeaturesLib: Restructure arch-dependent code Abdul Lateef Attar
2023-04-07 6:57 ` [PATCH v7 5/8] UefiCpuPkg: Initial implementation of AMD's SmmCpuFeaturesLib Abdul Lateef Attar
2023-04-07 6:57 ` [PATCH v7 6/8] UefiCpuPkg: Implements SmmCpuFeaturesLib for AMD Family Abdul Lateef Attar
2023-04-10 3:20 ` Chang, Abner
2023-04-07 6:58 ` [PATCH v7 7/8] UefiCpuPkg: Implements SmmSmramSaveStateLib for Intel Abdul Lateef Attar
2023-04-10 4:22 ` Chang, Abner [this message]
2023-04-07 6:58 ` [PATCH v7 8/8] UefiCpuPkg: Uses SmmSmramSaveStateLib library Abdul Lateef Attar
2023-04-10 4:38 ` Chang, Abner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=MN2PR12MB396603671D88E4F45F76AB22EA959@MN2PR12MB3966.namprd12.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox