123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- /** @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
|