mirror of https://github.com/acidanthera/audk.git
217 lines
7.7 KiB
C
217 lines
7.7 KiB
C
/** @file
|
|
Implementation shared across all library instances.
|
|
|
|
Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
|
|
Copyright (c) Microsoft Corporation.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include <PiMm.h>
|
|
#include <Library/SmmCpuFeaturesLib.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/MtrrLib.h>
|
|
#include <Library/PcdLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/DebugLib.h>
|
|
|
|
#include "CpuFeaturesLib.h"
|
|
|
|
/**
|
|
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
|
|
)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
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
|
|
)
|
|
{
|
|
}
|
|
|
|
/**
|
|
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
|
|
)
|
|
{
|
|
if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName == SmmRegFeatureControl)) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
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
|
|
)
|
|
{
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
/**
|
|
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
|
|
)
|
|
{
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
/**
|
|
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
|
|
)
|
|
{
|
|
return NULL;
|
|
}
|