BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4182 Removes SmmCpuFeaturesReadSaveStateRegister and SmmCpuFeaturesWirteSaveStateRegister function from SmmCpuFeaturesLib library. MmSaveStateLib library replaces the functionality of the above functions. Platform old/new need to use MmSaveStateLib library to read/write save state registers. Current implementation supports Intel and AMD. 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> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Signed-off-by: Abdul Lateef Attar <abdattar@amd.com> Reviewed-by: Abner Chang <abner.chang@amd.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			338 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			338 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
Library that provides CPU specific functions to support the PiSmmCpuDxeSmm module.
 | 
						|
 | 
						|
Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#ifndef __SMM_FEATURES_LIB_H__
 | 
						|
#define __SMM_FEATURES_LIB_H__
 | 
						|
 | 
						|
#include <Protocol/MpService.h>
 | 
						|
#include <Protocol/SmmCpu.h>
 | 
						|
#include <Register/Intel/SmramSaveStateMap.h>
 | 
						|
#include <CpuHotPlugData.h>
 | 
						|
 | 
						|
///
 | 
						|
/// Enumeration of SMM registers that are accessed using the library functions
 | 
						|
/// SmmCpuFeaturesIsSmmRegisterSupported (), SmmCpuFeaturesGetSmmRegister (),
 | 
						|
/// and SmmCpuFeaturesSetSmmRegister ().
 | 
						|
///
 | 
						|
typedef enum {
 | 
						|
  ///
 | 
						|
  /// Read-write register to provides access to MSR_SMM_FEATURE_CONTROL if the
 | 
						|
  /// CPU supports this MSR.
 | 
						|
  ///
 | 
						|
  SmmRegFeatureControl,
 | 
						|
  ///
 | 
						|
  /// Read-only register that returns a non-zero value if the CPU is able to
 | 
						|
  /// respond to SMIs.
 | 
						|
  ///
 | 
						|
  SmmRegSmmEnable,
 | 
						|
  ///
 | 
						|
  /// Read-only register that returns a non-zero value if the CPU is able to
 | 
						|
  /// respond to SMIs, but is busy with other actions that are causing a delay
 | 
						|
  /// in responding to an SMI.  This register abstracts access to MSR_SMM_DELAYED
 | 
						|
  /// if the CPU supports this MSR.
 | 
						|
  ///
 | 
						|
  SmmRegSmmDelayed,
 | 
						|
  ///
 | 
						|
  /// Read-only register that returns a non-zero value if the CPU is able to
 | 
						|
  /// respond to SMIs, but is busy with other actions that are blocking its
 | 
						|
  /// ability to respond to an SMI.  This register abstracts access to
 | 
						|
  /// MSR_SMM_BLOCKED if the CPU supports this MSR.
 | 
						|
  ///
 | 
						|
  SmmRegSmmBlocked
 | 
						|
} SMM_REG_NAME;
 | 
						|
 | 
						|
/**
 | 
						|
  Called during the very first SMI into System Management Mode to initialize
 | 
						|
  CPU features, including SMBASE, for the currently executing CPU.  Since this
 | 
						|
  is the first SMI, the SMRAM Save State Map is at the default address of
 | 
						|
  SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET.  The currently executing
 | 
						|
  CPU is specified by CpuIndex and CpuIndex can be used to access information
 | 
						|
  about the currently executing CPU in the ProcessorInfo array and the
 | 
						|
  HotPlugCpuData data structure.
 | 
						|
 | 
						|
  @param[in] CpuIndex        The index of the CPU to initialize.  The value
 | 
						|
                             must be between 0 and the NumberOfCpus field in
 | 
						|
                             the System Management System Table (SMST).
 | 
						|
  @param[in] IsMonarch       TRUE if the CpuIndex is the index of the CPU that
 | 
						|
                             was elected as monarch during System Management
 | 
						|
                             Mode initialization.
 | 
						|
                             FALSE if the CpuIndex is not the index of the CPU
 | 
						|
                             that was elected as monarch during System
 | 
						|
                             Management Mode initialization.
 | 
						|
  @param[in] ProcessorInfo   Pointer to an array of EFI_PROCESSOR_INFORMATION
 | 
						|
                             structures.  ProcessorInfo[CpuIndex] contains the
 | 
						|
                             information for the currently executing CPU.
 | 
						|
  @param[in] CpuHotPlugData  Pointer to the CPU_HOT_PLUG_DATA structure that
 | 
						|
                             contains the ApidId and SmBase arrays.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesInitializeProcessor (
 | 
						|
  IN UINTN                      CpuIndex,
 | 
						|
  IN BOOLEAN                    IsMonarch,
 | 
						|
  IN EFI_PROCESSOR_INFORMATION  *ProcessorInfo,
 | 
						|
  IN CPU_HOT_PLUG_DATA          *CpuHotPlugData
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  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] CpuIndex                 The index of the CPU to hook.  The value
 | 
						|
                                      must be between 0 and the NumberOfCpus
 | 
						|
                                      field in the System Management System Table
 | 
						|
                                      (SMST).
 | 
						|
  @param[in] CpuState                 Pointer to SMRAM Save State Map for the
 | 
						|
                                      currently executing CPU.
 | 
						|
  @param[in] NewInstructionPointer32  Instruction pointer to use if resuming to
 | 
						|
                                      32-bit execution mode from 64-bit SMM.
 | 
						|
  @param[in] NewInstructionPointer    Instruction pointer to use if resuming to
 | 
						|
                                      same execution mode as SMM.
 | 
						|
 | 
						|
  @retval 0    This function did modify the SMRAM save state.
 | 
						|
  @retval > 0  The original instruction pointer value from the SMRAM save state
 | 
						|
               before it was replaced.
 | 
						|
**/
 | 
						|
UINT64
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesHookReturnFromSmm (
 | 
						|
  IN UINTN                 CpuIndex,
 | 
						|
  IN SMRAM_SAVE_STATE_MAP  *CpuState,
 | 
						|
  IN UINT64                NewInstructionPointer32,
 | 
						|
  IN UINT64                NewInstructionPointer
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Hook point in normal execution mode that allows the one CPU that was elected
 | 
						|
  as monarch during System Management Mode initialization to perform additional
 | 
						|
  initialization actions immediately after all of the CPUs have processed their
 | 
						|
  first SMI and called SmmCpuFeaturesInitializeProcessor() relocating SMBASE
 | 
						|
  into a buffer in SMRAM and called SmmCpuFeaturesHookReturnFromSmm().
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesSmmRelocationComplete (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Return the size, in bytes, of a custom SMI Handler in bytes.  If 0 is
 | 
						|
  returned, then a custom SMI handler is not provided by this library,
 | 
						|
  and the default SMI handler must be used.
 | 
						|
 | 
						|
  @retval 0    Use the default SMI handler.
 | 
						|
  @retval > 0  Use the SMI handler installed by SmmCpuFeaturesInstallSmiHandler()
 | 
						|
               The caller is required to allocate enough SMRAM for each CPU to
 | 
						|
               support the size of the custom SMI handler.
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesGetSmiHandlerSize (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Install a custom SMI handler for the CPU specified by CpuIndex.  This function
 | 
						|
  is only called if SmmCpuFeaturesGetSmiHandlerSize() returns a size is greater
 | 
						|
  than zero and is called by the CPU that was elected as monarch during System
 | 
						|
  Management Mode initialization.
 | 
						|
 | 
						|
    //
 | 
						|
    // Append Shadow Stack after normal stack
 | 
						|
    //
 | 
						|
    // |= SmiStack
 | 
						|
    // +--------------------------------------------------+---------------------------------------------------------------+
 | 
						|
    // | Known Good Stack | Guard Page |    SMM Stack     | Known Good Shadow Stack | Guard Page |    SMM Shadow Stack    |
 | 
						|
    // +--------------------------------------------------+---------------------------------------------------------------+
 | 
						|
    // |                               |PcdCpuSmmStackSize|                                      |PcdCpuSmmShadowStackSize|
 | 
						|
    // |<-------------------- StackSize ----------------->|<------------------------- ShadowStackSize ------------------->|
 | 
						|
    // |                                                                                                                  |
 | 
						|
    // |<-------------------------------------------- Processor N ------------------------------------------------------->|
 | 
						|
    // | low address (bottom)                                                                          high address (top) |
 | 
						|
    //
 | 
						|
 | 
						|
  @param[in] CpuIndex   The index of the CPU to install the custom SMI handler.
 | 
						|
                        The value must be between 0 and the NumberOfCpus field
 | 
						|
                        in the System Management System Table (SMST).
 | 
						|
  @param[in] SmBase     The SMBASE address for the CPU specified by CpuIndex.
 | 
						|
  @param[in] SmiStack   The bottom of stack to use when an SMI is processed by the
 | 
						|
                        the CPU specified by CpuIndex.
 | 
						|
  @param[in] StackSize  The size, in bytes, if the stack used when an SMI is
 | 
						|
                        processed by the CPU specified by CpuIndex.
 | 
						|
                        StackSize should be PcdCpuSmmStackSize, with 2 more pages
 | 
						|
                        if PcdCpuSmmStackGuard is true.
 | 
						|
                        If ShadowStack is enabled, the shadow stack is allocated
 | 
						|
                        after the normal Stack. The size is PcdCpuSmmShadowStackSize.
 | 
						|
                        with 2 more pages if PcdCpuSmmStackGuard is true.
 | 
						|
  @param[in] GdtBase    The base address of the GDT to use when an SMI is
 | 
						|
                        processed by the CPU specified by CpuIndex.
 | 
						|
  @param[in] GdtSize    The size, in bytes, of the GDT used when an SMI is
 | 
						|
                        processed by the CPU specified by CpuIndex.
 | 
						|
  @param[in] IdtBase    The base address of the IDT to use when an SMI is
 | 
						|
                        processed by the CPU specified by CpuIndex.
 | 
						|
  @param[in] IdtSize    The size, in bytes, of the IDT used when an SMI is
 | 
						|
                        processed by the CPU specified by CpuIndex.
 | 
						|
  @param[in] Cr3        The base address of the page tables to use when an SMI
 | 
						|
                        is processed by the CPU specified by CpuIndex.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesInstallSmiHandler (
 | 
						|
  IN UINTN   CpuIndex,
 | 
						|
  IN UINT32  SmBase,
 | 
						|
  IN VOID    *SmiStack,
 | 
						|
  IN UINTN   StackSize,
 | 
						|
  IN UINTN   GdtBase,
 | 
						|
  IN UINTN   GdtSize,
 | 
						|
  IN UINTN   IdtBase,
 | 
						|
  IN UINTN   IdtSize,
 | 
						|
  IN UINT32  Cr3
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Determines if MTRR registers must be configured to set SMRAM cache-ability
 | 
						|
  when executing in System Management Mode.
 | 
						|
 | 
						|
  @retval TRUE   MTRR registers must be configured to set SMRAM cache-ability.
 | 
						|
  @retval FALSE  MTRR registers do not need to be configured to set SMRAM
 | 
						|
                 cache-ability.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesNeedConfigureMtrrs (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Disable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs()
 | 
						|
  returns TRUE.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesDisableSmrr (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Enable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs()
 | 
						|
  returns TRUE.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesReenableSmrr (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Processor specific hook point each time a CPU enters System Management Mode.
 | 
						|
 | 
						|
  @param[in] CpuIndex  The index of the CPU that has entered SMM.  The value
 | 
						|
                       must be between 0 and the NumberOfCpus field in the
 | 
						|
                       System Management System Table (SMST).
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesRendezvousEntry (
 | 
						|
  IN UINTN  CpuIndex
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Processor specific hook point each time a CPU exits System Management Mode.
 | 
						|
 | 
						|
  @param[in] CpuIndex  The index of the CPU that is exiting SMM.  The value must
 | 
						|
                       be between 0 and the NumberOfCpus field in the System
 | 
						|
                       Management System Table (SMST).
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesRendezvousExit (
 | 
						|
  IN UINTN  CpuIndex
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Check to see if an SMM register is supported by a specified CPU.
 | 
						|
 | 
						|
  @param[in] CpuIndex  The index of the CPU to check for SMM register support.
 | 
						|
                       The value must be between 0 and the NumberOfCpus field
 | 
						|
                       in the System Management System Table (SMST).
 | 
						|
  @param[in] RegName   Identifies the SMM register to check for support.
 | 
						|
 | 
						|
  @retval TRUE   The SMM register specified by RegName is supported by the CPU
 | 
						|
                 specified by CpuIndex.
 | 
						|
  @retval FALSE  The SMM register specified by RegName is not supported by the
 | 
						|
                 CPU specified by CpuIndex.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesIsSmmRegisterSupported (
 | 
						|
  IN UINTN         CpuIndex,
 | 
						|
  IN SMM_REG_NAME  RegName
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Returns the current value of the SMM register for the specified CPU.
 | 
						|
  If the SMM register is not supported, then 0 is returned.
 | 
						|
 | 
						|
  @param[in] CpuIndex  The index of the CPU to read the SMM register.  The
 | 
						|
                       value must be between 0 and the NumberOfCpus field in
 | 
						|
                       the System Management System Table (SMST).
 | 
						|
  @param[in] RegName   Identifies the SMM register to read.
 | 
						|
 | 
						|
  @return  The value of the SMM register specified by RegName from the CPU
 | 
						|
           specified by CpuIndex.
 | 
						|
**/
 | 
						|
UINT64
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesGetSmmRegister (
 | 
						|
  IN UINTN         CpuIndex,
 | 
						|
  IN SMM_REG_NAME  RegName
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Sets the value of an SMM register on a specified CPU.
 | 
						|
  If the SMM register is not supported, then no action is performed.
 | 
						|
 | 
						|
  @param[in] CpuIndex  The index of the CPU to write the SMM register.  The
 | 
						|
                       value must be between 0 and the NumberOfCpus field in
 | 
						|
                       the System Management System Table (SMST).
 | 
						|
  @param[in] RegName   Identifies the SMM register to write.
 | 
						|
                       registers are read-only.
 | 
						|
  @param[in] Value     The value to write to the SMM register.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesSetSmmRegister (
 | 
						|
  IN UINTN         CpuIndex,
 | 
						|
  IN SMM_REG_NAME  RegName,
 | 
						|
  IN UINT64        Value
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  This function is hook point called after the gEfiSmmReadyToLockProtocolGuid
 | 
						|
  notification is completely processed.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SmmCpuFeaturesCompleteSmmReadyToLock (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
#endif
 |