diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library')
11 files changed, 2791 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/CpuCacheInfoLib.h b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/CpuCacheInfoLib.h new file mode 100644 index 00000000..67b0fb40 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/CpuCacheInfoLib.h @@ -0,0 +1,85 @@ +/** @file + Header file for CPU Cache info Library. + + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _CPU_CACHE_INFO_LIB_H_ +#define _CPU_CACHE_INFO_LIB_H_ + +typedef struct { + // + // Package number. + // + UINT32 Package; + // + // Core type of logical processor. + // Value = CPUID.1Ah:EAX[31:24] + // + UINT8 CoreType; + // + // Level of the cache that this package's this type of logical processor corresponds to. + // Value = CPUID.04h:EAX[07:05] + // + UINT8 CacheLevel : 3; + // + // Type of the cache that this package's this type of logical processor corresponds to. + // Value = CPUID.04h:EAX[04:00] + // + UINT8 CacheType : 5; + // + // Ways of associativity. + // Value = CPUID.04h:EBX[31:22] + // + UINT16 CacheWays : 10; + // + // Fully associative cache. + // Value = CPUID.04h:EAX[09] + // + UINT16 FullyAssociativeCache : 1; + // + // Direct mapped cache. + // Value = CPUID.04h:EDX[02] + // + UINT16 DirectMappedCache : 1; + UINT16 Reserved : 4; + // + // Size of single cache that this package's this type of logical processor corresponds to. + // Value = (CPUID.04h:EBX[31:22] + 1) * (CPUID.04h:EBX[21:12] + 1) * + // (CPUID.04h:EBX[11:00] + 1) * (CPUID.04h:ECX[31:00] + 1) + // + UINT32 CacheSizeinKB; + // + // Number of the cache that this package's this type of logical processor corresponds to. + // Have subtracted the number of caches that are shared. + // + UINT16 CacheCount; +} CPU_CACHE_INFO; + +/** + Get CpuCacheInfo data array. + + @param[in, out] CpuCacheInfo Pointer to the CpuCacheInfo array. + @param[in, out] CpuCacheInfoCount As input, point to the length of response CpuCacheInfo array. + As output, point to the actual length of response CpuCacheInfo array. + + @retval EFI_SUCCESS Function completed successfully. + @retval EFI_INVALID_PARAMETER CpuCacheInfoCount is NULL. + @retval EFI_INVALID_PARAMETER CpuCacheInfo is NULL while CpuCacheInfoCount contains the value + greater than zero. + @retval EFI_UNSUPPORTED Processor does not support CPUID_CACHE_PARAMS Leaf. + @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated. + @retval EFI_BUFFER_TOO_SMALL CpuCacheInfoCount is too small to hold the response CpuCacheInfo + array. CpuCacheInfoCount has been updated with the length needed + to complete the request. +**/ +EFI_STATUS +EFIAPI +GetCpuCacheInfo ( + IN OUT CPU_CACHE_INFO *CpuCacheInfo, + IN OUT UINTN *CpuCacheInfoCount + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/LocalApicLib.h b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/LocalApicLib.h new file mode 100644 index 00000000..41dc66c1 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/LocalApicLib.h @@ -0,0 +1,457 @@ +/** @file + Public include file for Local APIC library. + + Local APIC library assumes local APIC is enabled. It does not + handles cases where local APIC is disabled. + + Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __LOCAL_APIC_LIB_H__ +#define __LOCAL_APIC_LIB_H__ + +#define LOCAL_APIC_MODE_XAPIC 0x1 ///< xAPIC mode. +#define LOCAL_APIC_MODE_X2APIC 0x2 ///< x2APIC mode. + +/** + Retrieve the base address of local APIC. + + @return The base address of local APIC. + +**/ +UINTN +EFIAPI +GetLocalApicBaseAddress ( + VOID + ); + +/** + Set the base address of local APIC. + + If BaseAddress is not aligned on a 4KB boundary, then ASSERT(). + + @param[in] BaseAddress Local APIC base address to be set. + +**/ +VOID +EFIAPI +SetLocalApicBaseAddress ( + IN UINTN BaseAddress + ); + +/** + Get the current local APIC mode. + + If local APIC is disabled, then ASSERT. + + @retval LOCAL_APIC_MODE_XAPIC current APIC mode is xAPIC. + @retval LOCAL_APIC_MODE_X2APIC current APIC mode is x2APIC. +**/ +UINTN +EFIAPI +GetApicMode ( + VOID + ); + +/** + Set the current local APIC mode. + + If the specified local APIC mode is not valid, then ASSERT. + If the specified local APIC mode can't be set as current, then ASSERT. + + @param ApicMode APIC mode to be set. + + @note This API must not be called from an interrupt handler or SMI handler. + It may result in unpredictable behavior. +**/ +VOID +EFIAPI +SetApicMode ( + IN UINTN ApicMode + ); + +/** + Get the initial local APIC ID of the executing processor assigned by hardware upon power on or reset. + + In xAPIC mode, the initial local APIC ID may be different from current APIC ID. + In x2APIC mode, the local APIC ID can't be changed and there is no concept of initial APIC ID. In this case, + the 32-bit local APIC ID is returned as initial APIC ID. + + @return 32-bit initial local APIC ID of the executing processor. +**/ +UINT32 +EFIAPI +GetInitialApicId ( + VOID + ); + +/** + Get the local APIC ID of the executing processor. + + @return 32-bit local APIC ID of the executing processor. +**/ +UINT32 +EFIAPI +GetApicId ( + VOID + ); + +/** + Get the value of the local APIC version register. + + @return the value of the local APIC version register. +**/ +UINT32 +EFIAPI +GetApicVersion ( + VOID + ); + +/** + Send a Fixed IPI to a specified target processor. + + This function returns after the IPI has been accepted by the target processor. + + @param ApicId The local APIC ID of the target processor. + @param Vector The vector number of the interrupt being sent. +**/ +VOID +EFIAPI +SendFixedIpi ( + IN UINT32 ApicId, + IN UINT8 Vector + ); + +/** + Send a Fixed IPI to all processors excluding self. + + This function returns after the IPI has been accepted by the target processors. + + @param Vector The vector number of the interrupt being sent. +**/ +VOID +EFIAPI +SendFixedIpiAllExcludingSelf ( + IN UINT8 Vector + ); + +/** + Send a SMI IPI to a specified target processor. + + This function returns after the IPI has been accepted by the target processor. + + @param ApicId Specify the local APIC ID of the target processor. +**/ +VOID +EFIAPI +SendSmiIpi ( + IN UINT32 ApicId + ); + +/** + Send a SMI IPI to all processors excluding self. + + This function returns after the IPI has been accepted by the target processors. +**/ +VOID +EFIAPI +SendSmiIpiAllExcludingSelf ( + VOID + ); + +/** + Send an INIT IPI to a specified target processor. + + This function returns after the IPI has been accepted by the target processor. + + @param ApicId Specify the local APIC ID of the target processor. +**/ +VOID +EFIAPI +SendInitIpi ( + IN UINT32 ApicId + ); + +/** + Send an INIT IPI to all processors excluding self. + + This function returns after the IPI has been accepted by the target processors. +**/ +VOID +EFIAPI +SendInitIpiAllExcludingSelf ( + VOID + ); + +/** + Send an INIT-Start-up-Start-up IPI sequence to a specified target processor. + + This function returns after the IPI has been accepted by the target processor. + + if StartupRoutine >= 1M, then ASSERT. + if StartupRoutine is not multiple of 4K, then ASSERT. + + @param ApicId Specify the local APIC ID of the target processor. + @param StartupRoutine Points to a start-up routine which is below 1M physical + address and 4K aligned. +**/ +VOID +EFIAPI +SendInitSipiSipi ( + IN UINT32 ApicId, + IN UINT32 StartupRoutine + ); + +/** + Send an INIT-Start-up-Start-up IPI sequence to all processors excluding self. + + This function returns after the IPI has been accepted by the target processors. + + if StartupRoutine >= 1M, then ASSERT. + if StartupRoutine is not multiple of 4K, then ASSERT. + + @param StartupRoutine Points to a start-up routine which is below 1M physical + address and 4K aligned. +**/ +VOID +EFIAPI +SendInitSipiSipiAllExcludingSelf ( + IN UINT32 StartupRoutine + ); + +/** + Initialize the state of the SoftwareEnable bit in the Local APIC + Spurious Interrupt Vector register. + + @param Enable If TRUE, then set SoftwareEnable to 1 + If FALSE, then set SoftwareEnable to 0. + +**/ +VOID +EFIAPI +InitializeLocalApicSoftwareEnable ( + IN BOOLEAN Enable + ); + +/** + Programming Virtual Wire Mode. + + This function programs the local APIC for virtual wire mode following + the example described in chapter A.3 of the MP 1.4 spec. + + IOxAPIC is not involved in this type of virtual wire mode. +**/ +VOID +EFIAPI +ProgramVirtualWireMode ( + VOID + ); + +/** + Disable LINT0 & LINT1 interrupts. + + This function sets the mask flag in the LVT LINT0 & LINT1 registers. +**/ +VOID +EFIAPI +DisableLvtInterrupts ( + VOID + ); + +/** + Read the initial count value from the init-count register. + + @return The initial count value read from the init-count register. +**/ +UINT32 +EFIAPI +GetApicTimerInitCount ( + VOID + ); + +/** + Read the current count value from the current-count register. + + @return The current count value read from the current-count register. +**/ +UINT32 +EFIAPI +GetApicTimerCurrentCount ( + VOID + ); + +/** + Initialize the local APIC timer. + + The local APIC timer is initialized and enabled. + + @param DivideValue The divide value for the DCR. It is one of 1,2,4,8,16,32,64,128. + If it is 0, then use the current divide value in the DCR. + @param InitCount The initial count value. + @param PeriodicMode If TRUE, timer mode is peridoic. Othewise, timer mode is one-shot. + @param Vector The timer interrupt vector number. +**/ +VOID +EFIAPI +InitializeApicTimer ( + IN UINTN DivideValue, + IN UINT32 InitCount, + IN BOOLEAN PeriodicMode, + IN UINT8 Vector + ); + +/** + Get the state of the local APIC timer. + + @param DivideValue Return the divide value for the DCR. It is one of 1,2,4,8,16,32,64,128. + @param PeriodicMode Return the timer mode. If TRUE, timer mode is peridoic. Othewise, timer mode is one-shot. + @param Vector Return the timer interrupt vector number. +**/ +VOID +EFIAPI +GetApicTimerState ( + OUT UINTN *DivideValue OPTIONAL, + OUT BOOLEAN *PeriodicMode OPTIONAL, + OUT UINT8 *Vector OPTIONAL + ); + +/** + Enable the local APIC timer interrupt. +**/ +VOID +EFIAPI +EnableApicTimerInterrupt ( + VOID + ); + +/** + Disable the local APIC timer interrupt. +**/ +VOID +EFIAPI +DisableApicTimerInterrupt ( + VOID + ); + +/** + Get the local APIC timer interrupt state. + + @retval TRUE The local APIC timer interrupt is enabled. + @retval FALSE The local APIC timer interrupt is disabled. +**/ +BOOLEAN +EFIAPI +GetApicTimerInterruptState ( + VOID + ); + +/** + Send EOI to the local APIC. +**/ +VOID +EFIAPI +SendApicEoi ( + VOID + ); + +/** + Get the 32-bit address that a device should use to send a Message Signaled + Interrupt (MSI) to the Local APIC of the currently executing processor. + + @return 32-bit address used to send an MSI to the Local APIC. +**/ +UINT32 +EFIAPI +GetApicMsiAddress ( + VOID + ); + +/** + Get the 64-bit data value that a device should use to send a Message Signaled + Interrupt (MSI) to the Local APIC of the currently executing processor. + + If Vector is not in range 0x10..0xFE, then ASSERT(). + If DeliveryMode is not supported, then ASSERT(). + + @param Vector The 8-bit interrupt vector associated with the MSI. + Must be in the range 0x10..0xFE + @param DeliveryMode A 3-bit value that specifies how the recept of the MSI + is handled. The only supported values are: + 0: LOCAL_APIC_DELIVERY_MODE_FIXED + 1: LOCAL_APIC_DELIVERY_MODE_LOWEST_PRIORITY + 2: LOCAL_APIC_DELIVERY_MODE_SMI + 4: LOCAL_APIC_DELIVERY_MODE_NMI + 5: LOCAL_APIC_DELIVERY_MODE_INIT + 7: LOCAL_APIC_DELIVERY_MODE_EXTINT + + @param LevelTriggered TRUE specifies a level triggered interrupt. + FALSE specifies an edge triggered interrupt. + @param AssertionLevel Ignored if LevelTriggered is FALSE. + TRUE specifies a level triggered interrupt that active + when the interrupt line is asserted. + FALSE specifies a level triggered interrupt that active + when the interrupt line is deasserted. + + @return 64-bit data value used to send an MSI to the Local APIC. +**/ +UINT64 +EFIAPI +GetApicMsiValue ( + IN UINT8 Vector, + IN UINTN DeliveryMode, + IN BOOLEAN LevelTriggered, + IN BOOLEAN AssertionLevel + ); + +/** + Get Package ID/Core ID/Thread ID of a processor. + + The algorithm assumes the target system has symmetry across physical + package boundaries with respect to the number of logical processors + per package, number of cores per package. + + @param[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +EFIAPI +GetProcessorLocationByApicId ( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ); + +/** + Get Package ID/Module ID/Tile ID/Die ID/Core ID/Thread ID of a processor. + + The algorithm assumes the target system has symmetry across physical + package boundaries with respect to the number of threads per core, number of + cores per module, number of modules per tile, number of tiles per die, number + of dies per package. + + @param[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Die Returns the processor die ID. + @param[out] Tile Returns the processor tile ID. + @param[out] Module Returns the processor module ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +EFIAPI +GetProcessorLocation2ByApicId ( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Die OPTIONAL, + OUT UINT32 *Tile OPTIONAL, + OUT UINT32 *Module OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ); +#endif + diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MicrocodeLib.h b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MicrocodeLib.h new file mode 100644 index 00000000..c23fe5bd --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MicrocodeLib.h @@ -0,0 +1,120 @@ +/** @file + Public include file for Microcode library. + + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MICROCODE_LIB_H_ +#define MICROCODE_LIB_H_ + +#include <Register/Intel/Microcode.h> +#include <Ppi/ShadowMicrocode.h> + +/** + Get microcode update signature of currently loaded microcode update. + + @return Microcode signature. +**/ +UINT32 +EFIAPI +GetProcessorMicrocodeSignature ( + VOID + ); + +/** + Get the processor signature and platform ID for current processor. + + @param MicrocodeCpuId Return the processor signature and platform ID. +**/ +VOID +EFIAPI +GetProcessorMicrocodeCpuId ( + EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId + ); + +/** + Return the total size of the microcode entry. + + Logic follows pseudo code in SDM as below: + + N = 512 + If (Update.DataSize != 00000000H) + N = Update.TotalSize / 4 + + If Microcode is NULL, then ASSERT. + + @param Microcode Pointer to the microcode entry. + + @return The microcode total size. +**/ +UINT32 +EFIAPI +GetMicrocodeLength ( + IN CPU_MICROCODE_HEADER *Microcode + ); + +/** + Load the microcode to the processor. + + If Microcode is NULL, then ASSERT. + + @param Microcode Pointer to the microcode entry. +**/ +VOID +EFIAPI +LoadMicrocode ( + IN CPU_MICROCODE_HEADER *Microcode + ); + +/** + Detect whether specified processor can find matching microcode patch and load it. + + Microcode format is as below: + +----------------------------------------+-------------------------------------------------+ + | CPU_MICROCODE_HEADER | | + +----------------------------------------+ V + | Update Data | CPU_MICROCODE_HEADER.Checksum + +----------------------------------------+-------+ ^ + | CPU_MICROCODE_EXTENDED_TABLE_HEADER | | | + +----------------------------------------+ V | + | CPU_MICROCODE_EXTENDED_TABLE[0] | CPU_MICROCODE_EXTENDED_TABLE_HEADER.Checksum | + | CPU_MICROCODE_EXTENDED_TABLE[1] | ^ | + | ... | | | + +----------------------------------------+-------+-----------------------------------------+ + + There may by multiple CPU_MICROCODE_EXTENDED_TABLE in this format. + The count of CPU_MICROCODE_EXTENDED_TABLE is indicated by ExtendedSignatureCount + of CPU_MICROCODE_EXTENDED_TABLE_HEADER structure. + + If Microcode is NULL, then ASSERT. + + @param Microcode Pointer to a microcode entry. + @param MicrocodeLength The total length of the microcode entry. + @param MinimumRevision The microcode whose revision <= MinimumRevision is treated as invalid. + Caller can supply value get from GetProcessorMicrocodeSignature() to check + whether the microcode is newer than loaded one. + Caller can supply 0 to treat any revision (except 0) microcode as valid. + @param MicrocodeCpuIds Pointer to an array of processor signature and platform ID that represents + a set of processors. + Caller can supply zero-element array to skip the processor signature and + platform ID check. + @param MicrocodeCpuIdCount The number of elements in MicrocodeCpuIds. + @param VerifyChecksum FALSE to skip all the checksum verifications. + + @retval TRUE The microcode is valid. + @retval FALSE The microcode is invalid. +**/ +BOOLEAN +EFIAPI +IsValidMicrocode ( + IN CPU_MICROCODE_HEADER *Microcode, + IN UINTN MicrocodeLength, + IN UINT32 MinimumRevision, + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds, + IN UINTN MicrocodeCpuIdCount, + IN BOOLEAN VerifyChecksum + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MpInitLib.h b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MpInitLib.h new file mode 100644 index 00000000..a4bc74ee --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MpInitLib.h @@ -0,0 +1,381 @@ +/** @file + Multiple-Processor initialization Library. + + Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __MP_INIT_LIB_H__ +#define __MP_INIT_LIB_H__ + +#include <Ppi/SecPlatformInformation.h> +#include <Protocol/MpService.h> + +/** + MP Initialize Library initialization. + + This service will allocate AP reset vector and wakeup all APs to do APs + initialization. + + This service must be invoked before all other MP Initialize Library + service are invoked. + + @retval EFI_SUCCESS MP initialization succeeds. + @retval Others MP initialization fails. + +**/ +EFI_STATUS +EFIAPI +MpInitLibInitialize ( + VOID + ); + +/** + Retrieves the number of logical processor in the platform and the number of + those logical processors that are enabled on this boot. This service may only + be called from the BSP. + + @param[out] NumberOfProcessors Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors + is NULL. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibGetNumberOfProcessors ( + OUT UINTN *NumberOfProcessors, OPTIONAL + OUT UINTN *NumberOfEnabledProcessors OPTIONAL + ); + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + @param[out] HealthData Return processor health data. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibGetProcessorInfo ( + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer, + OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL + ); + +/** + This service executes a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] SingleThread If TRUE, then all the enabled APs execute + the function specified by Procedure one by + one, in ascending order of processor handle + number. If FALSE, then all the enabled APs + execute the function specified by Procedure + simultaneously. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until all APs finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on all the enabled + APs, and go on executing immediately. If + all return from Procedure, or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + all APs return from Procedure, then Procedure + on the failed APs is terminated. All enabled + APs are available for next function assigned + by MpInitLibStartupAllAPs() or + MPInitLibStartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise, + if all APs finish successfully, then its + content is set to NULL. If not all APs + finish before timeout expires, then its + content is set to address of the buffer + holding handle numbers of the failed APs. + The buffer is allocated by MP Initialization + library, and it's the caller's responsibility to + free the buffer with FreePool() service. + In blocking mode, it is ready for consumption + when the call returns. In non-blocking mode, + it is ready when WaitEvent is signaled. The + list of failed CPU is terminated by + END_OF_CPU_LIST. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not + supported. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + all enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupAllAPs ( + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL + ); + +/** + This service lets the caller get one enabled AP to execute a caller-provided + function. + + @param[in] Procedure A pointer to the function to be run on the + designated AP of the system. See type + EFI_AP_PROCEDURE. + @param[in] ProcessorNumber The handle number of the AP. The range is + from 0 to the total number of logical + processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until this AP finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on this AP, + and go on executing immediately. If this AP + return from Procedure or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + this AP to finish this Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + this AP returns from Procedure, then Procedure + on the AP is terminated. The + AP is available for next function assigned + by MpInitLibStartupAllAPs() or + MpInitLibStartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure on the + specified AP. + @param[out] Finished If NULL, this parameter is ignored. In + blocking mode, this parameter is ignored. + In non-blocking mode, if AP returns from + Procedure before the timeout expires, its + content is set to TRUE. Otherwise, the + value is set to FALSE. The caller can + determine if the AP returned from Procedure + by evaluating this value. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before + the timeout expires. + @retval EFI_SUCCESS In non-blocking mode, the function has been + dispatched to specified AP. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not + supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + the specified AP has finished. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupThisAP ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL + ); + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + @param[in] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an + enabled AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to + this service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or + a disabled AP. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibSwitchBSP ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ); + +/** + This service lets the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for + enabled, FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies + the new health status of the AP. This flag + corresponds to StatusFlag defined in + EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only + the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter + is ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed + prior to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibEnableDisableAP ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ); + +/** + This return the handle number for the calling processor. This service may be + called from the BSP and APs. + + @param[out] ProcessorNumber Pointer to the handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + MpInitLibGetNumberOfProcessors(). + + @retval EFI_SUCCESS The current processor handle number was returned + in ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + +**/ +EFI_STATUS +EFIAPI +MpInitLibWhoAmI ( + OUT UINTN *ProcessorNumber + ); + +/** + This service executes a caller provided function on all enabled CPUs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. TimeoutInMicroseconds is ignored + for BSP. + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + + @retval EFI_SUCCESS In blocking mode, all CPUs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled CPUs. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_NOT_READY MP Initialize Library is not initialized. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + all enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +EFI_STATUS +EFIAPI +MpInitLibStartupAllCPUs ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MtrrLib.h b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MtrrLib.h new file mode 100644 index 00000000..02c046a9 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MtrrLib.h @@ -0,0 +1,364 @@ +/** @file + MTRR setting library + + Copyright (c) 2008 - 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _MTRR_LIB_H_ +#define _MTRR_LIB_H_ + +// +// According to IA32 SDM, MTRRs number and MSR offset are always consistent +// for IA32 processor family +// + +// +// The semantics of below macro is MAX_MTRR_NUMBER_OF_VARIABLE_MTRR, the real number can be read out from MTRR_CAP register. +// +#define MTRR_NUMBER_OF_VARIABLE_MTRR 32 +// +// Firmware need reserve 2 MTRR for OS +// Note: It is replaced by PCD PcdCpuNumberOfReservedVariableMtrrs +// +#define RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER 2 + +#define MTRR_NUMBER_OF_FIXED_MTRR 11 + +// +// Structure to describe a fixed MTRR +// +typedef struct { + UINT32 Msr; + UINT32 BaseAddress; + UINT32 Length; +} FIXED_MTRR; + +// +// Structure to describe a variable MTRR +// +typedef struct { + UINT64 BaseAddress; + UINT64 Length; + UINT64 Type; + UINT32 Msr; + BOOLEAN Valid; + BOOLEAN Used; +} VARIABLE_MTRR; + +// +// Structure to hold base and mask pair for variable MTRR register +// +typedef struct _MTRR_VARIABLE_SETTING_ { + UINT64 Base; + UINT64 Mask; +} MTRR_VARIABLE_SETTING; + +// +// Array for variable MTRRs +// +typedef struct _MTRR_VARIABLE_SETTINGS_ { + MTRR_VARIABLE_SETTING Mtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; +} MTRR_VARIABLE_SETTINGS; + +// +// Array for fixed MTRRs +// +typedef struct _MTRR_FIXED_SETTINGS_ { + UINT64 Mtrr[MTRR_NUMBER_OF_FIXED_MTRR]; +} MTRR_FIXED_SETTINGS; + +// +// Structure to hold all MTRRs +// +typedef struct _MTRR_SETTINGS_ { + MTRR_FIXED_SETTINGS Fixed; + MTRR_VARIABLE_SETTINGS Variables; + UINT64 MtrrDefType; +} MTRR_SETTINGS; + +// +// Memory cache types +// +typedef enum { + CacheUncacheable = 0, + CacheWriteCombining = 1, + CacheWriteThrough = 4, + CacheWriteProtected = 5, + CacheWriteBack = 6, + CacheInvalid = 7 +} MTRR_MEMORY_CACHE_TYPE; + +#define MTRR_CACHE_UNCACHEABLE 0 +#define MTRR_CACHE_WRITE_COMBINING 1 +#define MTRR_CACHE_WRITE_THROUGH 4 +#define MTRR_CACHE_WRITE_PROTECTED 5 +#define MTRR_CACHE_WRITE_BACK 6 +#define MTRR_CACHE_INVALID_TYPE 7 + +typedef struct { + UINT64 BaseAddress; + UINT64 Length; + MTRR_MEMORY_CACHE_TYPE Type; +} MTRR_MEMORY_RANGE; + +/** + Returns the variable MTRR count for the CPU. + + @return Variable MTRR count + +**/ +UINT32 +EFIAPI +GetVariableMtrrCount ( + VOID + ); + +/** + Returns the firmware usable variable MTRR count for the CPU. + + @return Firmware usable variable MTRR count + +**/ +UINT32 +EFIAPI +GetFirmwareVariableMtrrCount ( + VOID + ); + +/** + This function attempts to set the attributes for a memory range. + + @param[in] BaseAddress The physical address that is the start + address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attribute The bit mask of attributes to set for the + memory region. + + @retval RETURN_SUCCESS The attributes were set for the memory + region. + @retval RETURN_INVALID_PARAMETER Length is zero. + @retval RETURN_UNSUPPORTED The processor does not support one or + more bytes of the memory resource range + specified by BaseAddress and Length. + @retval RETURN_UNSUPPORTED The bit mask of attributes is not support + for the memory resource range specified + by BaseAddress and Length. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource + range specified by BaseAddress and Length + cannot be modified. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to + modify the attributes of the memory + resource range. + Multiple memory range attributes setting by calling this API multiple + times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean + the number of CPU MTRRs are too small to set such memory attributes. + Pass the multiple memory range attributes to one call of + MtrrSetMemoryAttributesInMtrrSettings() may succeed. + @retval RETURN_BUFFER_TOO_SMALL The fixed internal scratch buffer is too small for MTRR calculation. + Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify + external scratch buffer. +**/ +RETURN_STATUS +EFIAPI +MtrrSetMemoryAttribute ( + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Attribute + ); + + +/** + This function will get the memory cache type of the specific address. + This function is mainly for debugging purposes. + + @param[in] Address The specific address + + @return The memory cache type of the specific address + +**/ +MTRR_MEMORY_CACHE_TYPE +EFIAPI +MtrrGetMemoryAttribute ( + IN PHYSICAL_ADDRESS Address + ); + + +/** + This function gets the content in fixed MTRRs + + @param[out] FixedSettings A buffer to hold fixed MTRRs content. + + @return The pointer of FixedSettings + +**/ +MTRR_FIXED_SETTINGS* +EFIAPI +MtrrGetFixedMtrr ( + OUT MTRR_FIXED_SETTINGS *FixedSettings + ); + + +/** + This function gets the content in all MTRRs (variable and fixed) + + @param[out] MtrrSetting A buffer to hold all MTRRs content. + + @return The pointer of MtrrSetting + +**/ +MTRR_SETTINGS * +EFIAPI +MtrrGetAllMtrrs ( + OUT MTRR_SETTINGS *MtrrSetting + ); + + +/** + This function sets all MTRRs (variable and fixed) + + @param[in] MtrrSetting A buffer to hold all MTRRs content. + + @return The pointer of MtrrSetting + +**/ +MTRR_SETTINGS * +EFIAPI +MtrrSetAllMtrrs ( + IN MTRR_SETTINGS *MtrrSetting + ); + + +/** + Get the attribute of variable MTRRs. + + This function shadows the content of variable MTRRs into + an internal array: VariableMtrr + + @param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR + @param[in] MtrrValidAddressMask The valid address mask for MTRR since the base address in + MTRR must align to 4K, so valid address mask equal to + MtrrValidBitsMask & 0xfffffffffffff000ULL + @param[out] VariableMtrr The array to shadow variable MTRRs content + + @return The return value of this parameter indicates the number of + MTRRs which has been used. +**/ +UINT32 +EFIAPI +MtrrGetMemoryAttributeInVariableMtrr ( + IN UINT64 MtrrValidBitsMask, + IN UINT64 MtrrValidAddressMask, + OUT VARIABLE_MTRR *VariableMtrr + ); + + +/** + This function prints all MTRRs for debugging. +**/ +VOID +EFIAPI +MtrrDebugPrintAllMtrrs ( + VOID + ); + +/** + Checks if MTRR is supported. + + @retval TRUE MTRR is supported. + @retval FALSE MTRR is not supported. + +**/ +BOOLEAN +EFIAPI +IsMtrrSupported ( + VOID + ); + +/** + Returns the default MTRR cache type for the system. + + @return The default MTRR cache type. + +**/ +MTRR_MEMORY_CACHE_TYPE +EFIAPI +MtrrGetDefaultMemoryType ( + VOID + ); + +/** + This function attempts to set the attributes into MTRR setting buffer for a memory range. + + @param[in, out] MtrrSetting MTRR setting buffer to be set. + @param[in] BaseAddress The physical address that is the start address + of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attribute The bit mask of attributes to set for the + memory region. + + @retval RETURN_SUCCESS The attributes were set for the memory region. + @retval RETURN_INVALID_PARAMETER Length is zero. + @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the + memory resource range specified by BaseAddress and Length. + @retval RETURN_UNSUPPORTED The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + Multiple memory range attributes setting by calling this API multiple + times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean + the number of CPU MTRRs are too small to set such memory attributes. + Pass the multiple memory range attributes to one call of + MtrrSetMemoryAttributesInMtrrSettings() may succeed. + @retval RETURN_BUFFER_TOO_SMALL The fixed internal scratch buffer is too small for MTRR calculation. + Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify + external scratch buffer. +**/ +RETURN_STATUS +EFIAPI +MtrrSetMemoryAttributeInMtrrSettings ( + IN OUT MTRR_SETTINGS *MtrrSetting, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Attribute + ); + +/** + This function attempts to set the attributes into MTRR setting buffer for multiple memory ranges. + + @param[in, out] MtrrSetting MTRR setting buffer to be set. + @param[in] Scratch A temporary scratch buffer that is used to perform the calculation. + @param[in, out] ScratchSize Pointer to the size in bytes of the scratch buffer. + It may be updated to the actual required size when the calculation + needs more scratch buffer. + @param[in] Ranges Pointer to an array of MTRR_MEMORY_RANGE. + When range overlap happens, the last one takes higher priority. + When the function returns, either all the attributes are set successfully, + or none of them is set. + @param[in] RangeCount Count of MTRR_MEMORY_RANGE. + + @retval RETURN_SUCCESS The attributes were set for all the memory ranges. + @retval RETURN_INVALID_PARAMETER Length in any range is zero. + @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the + memory resource range specified by BaseAddress and Length in any range. + @retval RETURN_UNSUPPORTED The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length in any range. + @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource ranges. + @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval RETURN_BUFFER_TOO_SMALL The scratch buffer is too small for MTRR calculation. +**/ +RETURN_STATUS +EFIAPI +MtrrSetMemoryAttributesInMtrrSettings ( + IN OUT MTRR_SETTINGS *MtrrSetting, + IN VOID *Scratch, + IN OUT UINTN *ScratchSize, + IN CONST MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCount + ); +#endif // _MTRR_LIB_H_ diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/PlatformSecLib.h b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/PlatformSecLib.h new file mode 100644 index 00000000..bc418143 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/PlatformSecLib.h @@ -0,0 +1,64 @@ +/** @file +This library class defines interface for platform to perform platform +specific initialization in SEC phase. + +Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PLATFORM_SEC_LIB_H__ +#define __PLATFORM_SEC_LIB_H__ + +/** + A developer supplied function to perform platform specific operations. + + It's a developer supplied function to perform any operations appropriate to a + given platform. It's invoked just before passing control to PEI core by SEC + core. Platform developer may modify the SecCoreData passed to PEI Core. + It returns a platform specific PPI list that platform wishes to pass to PEI core. + The Generic SEC core module will merge this list to join the final list passed to + PEI core. + + @param SecCoreData The same parameter as passing to PEI core. It + could be overridden by this function. + + @return The platform specific PPI list to be passed to PEI core or + NULL if there is no need of such platform specific PPI list. + +**/ +EFI_PEI_PPI_DESCRIPTOR * +EFIAPI +SecPlatformMain ( + IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData + ); + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param PeiServices Pointer to the PEI Services Table. + @param StructureSize Pointer to the variable describing size of the input buffer. + @param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ); + +/** + This interface disables temporary memory in SEC Phase. +**/ +VOID +EFIAPI +SecPlatformDisableTemporaryMemory ( + VOID + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h new file mode 100644 index 00000000..4c1b14c3 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h @@ -0,0 +1,611 @@ +/** @file + Register CPU Features Library to register and manage CPU features. + + Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __REGISTER_CPU_FEATURES_LIB_H__ +#define __REGISTER_CPU_FEATURES_LIB_H__ + +#include <AcpiCpuData.h> +#include <Register/Intel/Cpuid.h> +#include <Protocol/MpService.h> + +/// +/// Defines used to identify a CPU feature. The lower 16-bits are used to +/// identify a unique CPU feature and the value represents a bit number in +/// a bit mask. The upper 16-bits are bit mask values that are used as +/// modifiers of a CPU feature. When used in a list, the define value +/// CPU_FEATURE_END is used to terminate a list of CPU feature values. +/// @{ +#define CPU_FEATURE_AESNI 0 +#define CPU_FEATURE_TURBO_MODE 1 +#define CPU_FEATURE_MWAIT 2 +#define CPU_FEATURE_ACPI 3 +#define CPU_FEATURE_EIST 4 +#define CPU_FEATURE_RESERVED_5 5 +#define CPU_FEATURE_FASTSTRINGS 6 +#define CPU_FEATURE_VMX 7 +#define CPU_FEATURE_SMX 8 +#define CPU_FEATURE_LMCE 9 +#define CPU_FEATURE_LOCK_FEATURE_CONTROL_REGISTER 10 +#define CPU_FEATURE_LIMIT_CPUID_MAX_VAL 11 +#define CPU_FEATURE_MCE 12 +#define CPU_FEATURE_MCA 13 +#define CPU_FEATURE_MCG_CTL 14 +#define CPU_FEATURE_PENDING_BREAK 15 +#define CPU_FEATURE_C1E 16 +#define CPU_FEATURE_C1_AUTO_DEMOTION 17 +#define CPU_FEATURE_C3_AUTO_DEMOTION 18 +#define CPU_FEATURE_C1_UNDEMOTION 19 +#define CPU_FEATURE_C3_UNDEMOTION 20 +#define CPU_FEATURE_C_STATE 21 +#define CPU_FEATURE_TM 22 +#define CPU_FEATURE_TM2 23 +#define CPU_FEATURE_X2APIC 24 +#define CPU_FEATURE_RESERVED_25 25 +#define CPU_FEATURE_RESERVED_26 26 +#define CPU_FEATURE_RESERVED_27 27 +#define CPU_FEATURE_RESERVED_28 28 +#define CPU_FEATURE_RESERVED_29 29 +#define CPU_FEATURE_RESERVED_30 30 +#define CPU_FEATURE_RESERVED_31 31 + +#define CPU_FEATURE_L2_PREFETCHER (32+0) +#define CPU_FEATURE_L1_DATA_PREFETCHER (32+1) +#define CPU_FEATURE_HARDWARE_PREFETCHER (32+2) +#define CPU_FEATURE_ADJACENT_CACHE_LINE_PREFETCH (32+3) +#define CPU_FEATURE_DCU_PREFETCHER (32+4) +#define CPU_FEATURE_IP_PREFETCHER (32+5) +#define CPU_FEATURE_MLC_STREAMER_PREFETCHER (32+6) +#define CPU_FEATURE_MLC_SPATIAL_PREFETCHER (32+7) +#define CPU_FEATURE_THREE_STRIKE_COUNTER (32+8) +#define CPU_FEATURE_APIC_TPR_UPDATE_MESSAGE (32+9) +#define CPU_FEATURE_ENERGY_PERFORMANCE_BIAS (32+10) +#define CPU_FEATURE_PPIN (32+11) +#define CPU_FEATURE_PROC_TRACE (32+12) + +#define CPU_FEATURE_BEFORE_ALL BIT23 +#define CPU_FEATURE_AFTER_ALL BIT24 +#define CPU_FEATURE_THREAD_BEFORE BIT25 +#define CPU_FEATURE_THREAD_AFTER BIT26 +#define CPU_FEATURE_CORE_BEFORE BIT27 +#define CPU_FEATURE_CORE_AFTER BIT28 +#define CPU_FEATURE_PACKAGE_BEFORE BIT29 +#define CPU_FEATURE_PACKAGE_AFTER BIT30 +#define CPU_FEATURE_END MAX_UINT32 +/// @} + +/// +/// The bit field to indicate whether the processor is the first in its parent scope. +/// +typedef struct { + // + // Set to 1 when current processor is the first thread in the core it resides in. + // + UINT32 Thread : 1; + // + // Set to 1 when current processor is a thread of the first core in the module it resides in. + // + UINT32 Core : 1; + // + // Set to 1 when current processor is a thread of the first module in the tile it resides in. + // + UINT32 Module : 1; + // + // Set to 1 when current processor is a thread of the first tile in the die it resides in. + // + UINT32 Tile : 1; + // + // Set to 1 when current processor is a thread of the first die in the package it resides in. + // + UINT32 Die : 1; + // + // Set to 1 when current processor is a thread of the first package in the system. + // + UINT32 Package : 1; + UINT32 Reserved : 26; +} REGISTER_CPU_FEATURE_FIRST_PROCESSOR; + +/// +/// CPU Information passed into the SupportFunc and InitializeFunc of the +/// RegisterCpuFeature() library function. This structure contains information +/// that is commonly used during CPU feature detection and initialization. +/// +typedef struct { + /// + /// The package that the CPU resides + /// + EFI_PROCESSOR_INFORMATION ProcessorInfo; + + /// + /// The bit flag indicating whether the CPU is the first Thread/Core/Module/Tile/Die/Package in its parent scope. + /// + REGISTER_CPU_FEATURE_FIRST_PROCESSOR First; + /// + /// The Display Family of the CPU computed from CPUID leaf CPUID_VERSION_INFO + /// + UINT32 DisplayFamily; + /// + /// The Display Model of the CPU computed from CPUID leaf CPUID_VERSION_INFO + /// + UINT32 DisplayModel; + /// + /// The Stepping ID of the CPU computed from CPUID leaf CPUID_VERSION_INFO + /// + UINT32 SteppingId; + /// + /// The Processor Type of the CPU computed from CPUID leaf CPUID_VERSION_INFO + /// + UINT32 ProcessorType; + /// + /// Bit field structured returned in ECX from CPUID leaf CPUID_VERSION_INFO + /// + CPUID_VERSION_INFO_ECX CpuIdVersionInfoEcx; + /// + /// Bit field structured returned in EDX from CPUID leaf CPUID_VERSION_INFO + /// + CPUID_VERSION_INFO_EDX CpuIdVersionInfoEdx; +} REGISTER_CPU_FEATURE_INFORMATION; + +/** + Determines if a CPU feature is enabled in PcdCpuFeaturesSupport bit mask. + If a CPU feature is disabled in PcdCpuFeaturesSupport then all the code/data + associated with that feature should be optimized away if compiler + optimizations are enabled. + + @param[in] Feature The bit number of the CPU feature to check in the PCD + PcdCpuFeaturesSupport. + + @retval TRUE The CPU feature is set in PcdCpuFeaturesSupport. + @retval FALSE The CPU feature is not set in PcdCpuFeaturesSupport. + + @note This service could be called by BSP only. +**/ +BOOLEAN +EFIAPI +IsCpuFeatureSupported ( + IN UINT32 Feature + ); + +/** + Determines if a CPU feature is set in PcdCpuFeaturesSetting bit mask. + + @param[in] Feature The bit number of the CPU feature to check in the PCD + PcdCpuFeaturesSetting. + + @retval TRUE The CPU feature is set in PcdCpuFeaturesSetting. + @retval FALSE The CPU feature is not set in PcdCpuFeaturesSetting. + + @note This service could be called by BSP only. +**/ +BOOLEAN +EFIAPI +IsCpuFeatureInSetting ( + IN UINT32 Feature + ); + +/** + Prepares for the data used by CPU feature detection and initialization. + + @param[in] NumberOfProcessors The number of CPUs in the platform. + + @return Pointer to a buffer of CPU related configuration data. + + @note This service could be called by BSP only. +**/ +typedef +VOID * +(EFIAPI *CPU_FEATURE_GET_CONFIG_DATA)( + IN UINTN NumberOfProcessors + ); + +/** + Detects if CPU feature supported on current processor. + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + + @retval TRUE CPU feature is supported. + @retval FALSE CPU feature is not supported. + + @note This service could be called by BSP/APs. +**/ +typedef +BOOLEAN +(EFIAPI *CPU_FEATURE_SUPPORT)( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ); + +/** + Initializes CPU feature to specific state. + + This service does not initialize hardware and only produces entries in the + Register Table for specified processor. Hardware initialization on BSP/APs + will be done in CpuFeaturesInitialize(). + + @param[in] ProcessorNumber The index of the CPU executing this function. + @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION + structure for the CPU executing this function. + @param[in] ConfigData A pointer to the configuration buffer returned + by CPU_FEATURE_GET_CONFIG_DATA. NULL if + CPU_FEATURE_GET_CONFIG_DATA was not provided in + RegisterCpuFeature(). + @param[in] State If TRUE, then the CPU feature must be enabled. + If FALSE, then the CPU feature must be disabled. + + @retval RETURN_SUCCESS CPU feature is initialized. + + @note This service could be called by BSP only. +**/ +typedef +RETURN_STATUS +(EFIAPI *CPU_FEATURE_INITIALIZE)( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ); + +/** + Registers a CPU Feature. + + @param[in] FeatureName A Null-terminated Ascii string indicates CPU feature + name. + @param[in] GetConfigDataFunc CPU feature get configuration data function. This + is an optional parameter that may be NULL. If NULL, + then the most recently registered function for the + CPU feature is used. If no functions are registered + for a CPU feature, then the CPU configuration data + for the registered feature is NULL. + @param[in] SupportFunc CPU feature support function. This is an optional + parameter that may be NULL. If NULL, then the most + recently registered function for the CPU feature is + used. If no functions are registered for a CPU + feature, then the CPU feature is assumed to be + supported by all CPUs. + @param[in] InitializeFunc CPU feature initialize function. This is an optional + parameter that may be NULL. If NULL, then the most + recently registered function for the CPU feature is + used. If no functions are registered for a CPU + feature, then the CPU feature initialization is + skipped. + @param[in] ... Variable argument list of UINT32 CPU feature value. + Values with no modifiers are the features provided + by the registered functions. + Values with CPU_FEATURE_BEFORE modifier are features + that must be initialized after the features provided + by the registered functions are used. + Values with CPU_FEATURE_AFTER modifier are features + that must be initialized before the features provided + by the registered functions are used. + The last argument in this variable argument list must + always be CPU_FEATURE_END. + + @retval RETURN_SUCCESS The CPU feature was successfully registered. + @retval RETURN_OUT_OF_RESOURCES There are not enough resources to register + the CPU feature. + @retval RETURN_UNSUPPORTED Registration of the CPU feature is not + supported due to a circular dependency between + BEFORE and AFTER features. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +RegisterCpuFeature ( + IN CHAR8 *FeatureName, OPTIONAL + IN CPU_FEATURE_GET_CONFIG_DATA GetConfigDataFunc, OPTIONAL + IN CPU_FEATURE_SUPPORT SupportFunc, OPTIONAL + IN CPU_FEATURE_INITIALIZE InitializeFunc, OPTIONAL + ... + ); + +/** + Performs CPU features detection. + + This service will invoke MP service to check CPU features' + capabilities on BSP/APs. + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuFeaturesDetect ( + VOID + ); + +/** + Performs CPU features Initialization. + + This service will invoke MP service to perform CPU features + initialization on BSP/APs per user configuration. + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuFeaturesInitialize ( + VOID + ); + +/** + Switches to assigned BSP after CPU features initialization. + + @param[in] ProcessorNumber The index of the CPU executing this function. + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +SwitchBspAfterFeaturesInitialize ( + IN UINTN ProcessorNumber + ); + +/** + Adds an entry in specified register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValueMask Mask of bits in register to write + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuRegisterTableWrite ( + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT64 ValueMask, + IN UINT64 Value + ); + +/** + Adds an entry in specified register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValueMask Mask of bits in register to write + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuRegisterTableTestThenWrite ( + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT64 ValueMask, + IN UINT64 Value + ); + +/** + Adds an entry in specified Pre-SMM register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValueMask Mask of bits in register to write + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +PreSmmCpuRegisterTableWrite ( + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT64 ValueMask, + IN UINT64 Value + ); + +/** + Adds a 32-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_WRITE32(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT32, Value); \ + } while(FALSE); + +/** + Adds a 32-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_TEST_THEN_WRITE32(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, MAX_UINT32, Value); \ + } while(FALSE); + +/** + Adds a 64-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_WRITE64(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT64, Value); \ + } while(FALSE); + +/** + Adds a 64-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_TEST_THEN_WRITE64(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, MAX_UINT64, Value); \ + } while(FALSE); + +/** + Adds a bit field write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, bit field section, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program. + @param[in] Index Index of the register to program. + @param[in] Type The data type name of a register structure. + @param[in] Field The bit fiel name in register structure to write. + @param[in] Value Value to write to the bit field. + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_WRITE_FIELD(ProcessorNumber, RegisterType, Index, Type, Field, Value) \ + do { \ + UINT64 ValueMask; \ + ValueMask = MAX_UINT64; \ + ((Type *)(&ValueMask))->Field = 0; \ + CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, ~ValueMask, Value); \ + } while(FALSE); + +/** + Adds a bit field write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, bit field section, and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program. + @param[in] Index Index of the register to program. + @param[in] Type The data type name of a register structure. + @param[in] Field The bit fiel name in register structure to write. + @param[in] Value Value to write to the bit field. + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD(ProcessorNumber, RegisterType, Index, Type, Field, Value) \ + do { \ + UINT64 ValueMask; \ + ValueMask = MAX_UINT64; \ + ((Type *)(&ValueMask))->Field = 0; \ + CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, ~ValueMask, Value); \ + } while(FALSE); + +/** + Adds a 32-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define PRE_SMM_CPU_REGISTER_TABLE_WRITE32(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + PreSmmCpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT32, Value); \ + } while(FALSE); + +/** + Adds a 64-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define PRE_SMM_CPU_REGISTER_TABLE_WRITE64(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + PreSmmCpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT64, Value); \ + } while(FALSE); + +/** + Adds a bit field write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, bit field section, and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program. + @param[in] Index Index of the register to program. + @param[in] Type The data type name of a register structure. + @param[in] Field The bit fiel name in register structure to write. + @param[in] Value Value to write to the bit field. + + @note This service could be called by BSP only. +**/ +#define PRE_SMM_CPU_REGISTER_TABLE_WRITE_FIELD(ProcessorNumber, RegisterType, Index, Type, Field, Value) \ + do { \ + UINT64 ValueMask; \ + ValueMask = MAX_UINT64; \ + ((Type *)(&ValueMask))->Field = 0; \ + PreSmmCpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, ~ValueMask, Value); \ + } while(FALSE); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/SmmCpuFeaturesLib.h b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/SmmCpuFeaturesLib.h new file mode 100644 index 00000000..d6d3e825 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/SmmCpuFeaturesLib.h @@ -0,0 +1,414 @@ +/** @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 diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/SmmCpuPlatformHookLib.h b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/SmmCpuPlatformHookLib.h new file mode 100644 index 00000000..d5b49cc5 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/SmmCpuPlatformHookLib.h @@ -0,0 +1,103 @@ +/** @file + Public include file for the SMM CPU Platform Hook Library. + + Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SMM_CPU_PLATFORM_HOOK_LIB_H__ +#define __SMM_CPU_PLATFORM_HOOK_LIB_H__ + +/// +/// SMM Page Size Type +/// +typedef enum { + SmmPageSize4K, + SmmPageSize2M, + SmmPageSize1G, + MaxSmmPageSizeType +} SMM_PAGE_SIZE_TYPE; + +/** + Checks if platform produces a valid SMI. + + This function checks if platform produces a valid SMI. This function is + called at SMM entry to detect if this is a spurious SMI. This function + must be implemented in an MP safe way because it is called by multiple CPU + threads. + + @retval TRUE There is a valid SMI + @retval FALSE There is no valid SMI + +**/ +BOOLEAN +EFIAPI +PlatformValidSmi ( + VOID + ); + +/** + Clears platform top level SMI status bit. + + This function clears platform top level SMI status bit. + + @retval TRUE The platform top level SMI status is cleared. + @retval FALSE The platform top level SMI status cannot be cleared. + +**/ +BOOLEAN +EFIAPI +ClearTopLevelSmiStatus ( + VOID + ); + +/** + Performs platform specific way of SMM BSP election. + + This function performs platform specific way of SMM BSP election. + + @param IsBsp Output parameter. TRUE: the CPU this function executes + on is elected to be the SMM BSP. FALSE: the CPU this + function executes on is to be SMM AP. + + @retval EFI_SUCCESS The function executes successfully. + @retval EFI_NOT_READY The function does not determine whether this CPU should be + BSP or AP. This may occur if hardware init sequence to + enable the determination is yet to be done, or the function + chooses not to do BSP election and will let SMM CPU driver to + use its default BSP election process. + @retval EFI_DEVICE_ERROR The function cannot determine whether this CPU should be + BSP or AP due to hardware error. + +**/ +EFI_STATUS +EFIAPI +PlatformSmmBspElection ( + OUT BOOLEAN *IsBsp + ); + +/** + Get platform page table attribute . + + This function gets page table attribute of platform. + + @param Address Input parameter. Obtain the page table entries attribute on this address. + @param PageSize Output parameter. The size of the page. + @param NumOfPages Output parameter. Number of page. + @param PageAttribute Output parameter. Paging Attributes (WB, UC, etc). + + @retval EFI_SUCCESS The platform page table attribute from the address is determined. + @retval EFI_UNSUPPORTED The platform does not support getting page table attribute for the address. + +**/ +EFI_STATUS +EFIAPI +GetPlatformPageTableAttribute ( + IN UINT64 Address, + OUT SMM_PAGE_SIZE_TYPE *PageSize, + OUT UINTN *NumOfPages, + OUT UINTN *PageAttribute + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/UefiCpuLib.h b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/UefiCpuLib.h new file mode 100644 index 00000000..fb8dd8cd --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/UefiCpuLib.h @@ -0,0 +1,46 @@ +/** @file + Public header file for UEFI CPU library class. + + This library class defines some routines that are generic for IA32 family CPU + to be UEFI specification compliant. + + Copyright (c) 2009, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2020, AMD Inc. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __UEFI_CPU_LIB_H__ +#define __UEFI_CPU_LIB_H__ + + + +/** + Initializes floating point units for requirement of UEFI specification. + + This function initializes floating-point control word to 0x027F (all exceptions + masked,double-precision, round-to-nearest) and multimedia-extensions control word + (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero + for masked underflow). + +**/ +VOID +EFIAPI +InitializeFloatingPointUnits ( + VOID + ); + +/** + Determine if the standard CPU signature is "AuthenticAMD". + + @retval TRUE The CPU signature matches. + @retval FALSE The CPU signature does not match. + +**/ +BOOLEAN +EFIAPI +StandardSignatureIsAuthenticAMD ( + VOID + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/VmgExitLib.h b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/VmgExitLib.h new file mode 100644 index 00000000..6df1682f --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/VmgExitLib.h @@ -0,0 +1,146 @@ +/** @file + Public header file for the VMGEXIT Support library class. + + This library class defines some routines used when invoking the VMGEXIT + instruction in support of SEV-ES and to handle #VC exceptions. + + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __VMG_EXIT_LIB_H__ +#define __VMG_EXIT_LIB_H__ + +#include <Protocol/DebugSupport.h> +#include <Register/Amd/Ghcb.h> + + +/** + Perform VMGEXIT. + + Sets the necessary fields of the GHCB, invokes the VMGEXIT instruction and + then handles the return actions. + + @param[in, out] Ghcb A pointer to the GHCB + @param[in] ExitCode VMGEXIT code to be assigned to the SwExitCode + field of the GHCB. + @param[in] ExitInfo1 VMGEXIT information to be assigned to the + SwExitInfo1 field of the GHCB. + @param[in] ExitInfo2 VMGEXIT information to be assigned to the + SwExitInfo2 field of the GHCB. + + @retval 0 VMGEXIT succeeded. + @return Exception number to be propagated, VMGEXIT + processing did not succeed. + +**/ +UINT64 +EFIAPI +VmgExit ( + IN OUT GHCB *Ghcb, + IN UINT64 ExitCode, + IN UINT64 ExitInfo1, + IN UINT64 ExitInfo2 + ); + +/** + Perform pre-VMGEXIT initialization/preparation. + + Performs the necessary steps in preparation for invoking VMGEXIT. Must be + called before setting any fields within the GHCB. + + @param[in, out] Ghcb A pointer to the GHCB + @param[in, out] InterruptState A pointer to hold the current interrupt + state, used for restoring in VmgDone () + +**/ +VOID +EFIAPI +VmgInit ( + IN OUT GHCB *Ghcb, + IN OUT BOOLEAN *InterruptState + ); + +/** + Perform post-VMGEXIT cleanup. + + Performs the necessary steps to cleanup after invoking VMGEXIT. Must be + called after obtaining needed fields within the GHCB. + + @param[in, out] Ghcb A pointer to the GHCB + @param[in] InterruptState An indicator to conditionally (re)enable + interrupts + +**/ +VOID +EFIAPI +VmgDone ( + IN OUT GHCB *Ghcb, + IN BOOLEAN InterruptState + ); + +/** + Marks a specified offset as valid in the GHCB. + + The ValidBitmap area represents the areas of the GHCB that have been marked + valid. Set the bit in ValidBitmap for the input offset. + + @param[in, out] Ghcb A pointer to the GHCB + @param[in] Offset Qword offset in the GHCB to mark valid + +**/ +VOID +EFIAPI +VmgSetOffsetValid ( + IN OUT GHCB *Ghcb, + IN GHCB_REGISTER Offset + ); + +/** + Checks if a specified offset is valid in the GHCB. + + The ValidBitmap area represents the areas of the GHCB that have been marked + valid. Return whether the bit in the ValidBitmap is set for the input offset. + + @param[in] Ghcb A pointer to the GHCB + @param[in] Offset Qword offset in the GHCB to mark valid + + @retval TRUE Offset is marked valid in the GHCB + @retval FALSE Offset is not marked valid in the GHCB + +**/ +BOOLEAN +EFIAPI +VmgIsOffsetValid ( + IN GHCB *Ghcb, + IN GHCB_REGISTER Offset + ); + +/** + Handle a #VC exception. + + Performs the necessary processing to handle a #VC exception. + + The base library function returns an error equal to VC_EXCEPTION, + to be propagated to the standard exception handling stack. + + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be set + as value to use on error. + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT + + @retval EFI_SUCCESS Exception handled + @retval EFI_UNSUPPORTED #VC not supported, (new) exception value to + propagate provided + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception value to + propagate provided + +**/ +EFI_STATUS +EFIAPI +VmgExitHandleVc ( + IN OUT EFI_EXCEPTION_TYPE *ExceptionType, + IN OUT EFI_SYSTEM_CONTEXT SystemContext + ); + +#endif |