summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library')
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/CpuCacheInfoLib.h85
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/LocalApicLib.h457
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MicrocodeLib.h120
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MpInitLib.h381
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/MtrrLib.h364
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/PlatformSecLib.h64
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h611
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/SmmCpuFeaturesLib.h414
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/SmmCpuPlatformHookLib.h103
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/UefiCpuLib.h46
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Include/Library/VmgExitLib.h146
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