REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the UefiCpuPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			415 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			415 lines
		
	
	
		
			16 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
 | |
|   );
 | |
| 
 | |
| /**
 | |
|   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_PARAMETER  Buffer is NULL.
 | |
|   @retval EFI_UNSUPPORTED       This function does not support reading Register.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| SmmCpuFeaturesReadSaveStateRegister (
 | |
|   IN  UINTN                        CpuIndex,
 | |
|   IN  EFI_SMM_SAVE_STATE_REGISTER  Register,
 | |
|   IN  UINTN                        Width,
 | |
|   OUT VOID                         *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_PARAMETER  Buffer is NULL.
 | |
|   @retval EFI_UNSUPPORTED       This function does not support writing Register.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| SmmCpuFeaturesWriteSaveStateRegister (
 | |
|   IN UINTN                        CpuIndex,
 | |
|   IN EFI_SMM_SAVE_STATE_REGISTER  Register,
 | |
|   IN UINTN                        Width,
 | |
|   IN CONST VOID                   *Buffer
 | |
|   );
 | |
| 
 | |
| /**
 | |
|   This function is hook point called after the gEfiSmmReadyToLockProtocolGuid
 | |
|   notification is completely processed.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| SmmCpuFeaturesCompleteSmmReadyToLock (
 | |
|   VOID
 | |
|   );
 | |
| 
 | |
| /**
 | |
|   This API provides a method for a CPU to allocate a specific region for storing page tables.
 | |
| 
 | |
|   This API can be called more once to allocate memory for page tables.
 | |
| 
 | |
|   Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
 | |
|   allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
 | |
|   is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
 | |
|   returned.
 | |
| 
 | |
|   This function can also return NULL if there is no preference on where the page tables are allocated in SMRAM.
 | |
| 
 | |
|   @param  Pages                 The number of 4 KB pages to allocate.
 | |
| 
 | |
|   @return A pointer to the allocated buffer for page tables.
 | |
|   @retval NULL      Fail to allocate a specific region for storing page tables,
 | |
|                     Or there is no preference on where the page tables are allocated in SMRAM.
 | |
| 
 | |
| **/
 | |
| VOID *
 | |
| EFIAPI
 | |
| SmmCpuFeaturesAllocatePageTableMemory (
 | |
|   IN UINTN  Pages
 | |
|   );
 | |
| 
 | |
| #endif
 |