diff --git a/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h b/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h
new file mode 100644
index 0000000000..42eb3b28c1
--- /dev/null
+++ b/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h
@@ -0,0 +1,516 @@
+/** @file
+ Register CPU Features Library to register and manage CPU features.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __REGISTER_CPU_FEATURES_LIB_H__
+#define __REGISTER_CPU_FEATURES_LIB_H__
+
+#include
+#include
+#include
+
+///
+/// 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_XD 5
+#define CPU_FEATURE_FASTSTRINGS 6
+#define CPU_FEATURE_VMX 7
+#define CPU_FEATURE_SMX 8
+#define CPU_FEATURE_SENTER 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_AUTO_UNDEMOTION 19
+#define CPU_FEATURE_C3_AUTO_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_STRICK_COUNTER (32+8)
+#define CPU_FEATURE_APIC_TPR_UPDATE_MESSAGE (32+9)
+#define CPU_FEATURE_ENERGY_PERFORMANCE_BIAS (32+10)
+
+#define CPU_FEATURE_BEFORE_ALL BIT27
+#define CPU_FEATURE_AFTER_ALL BIT28
+#define CPU_FEATURE_BEFORE BIT29
+#define CPU_FEATURE_AFTER BIT30
+#define CPU_FEATURE_END MAX_UINT32
+/// @}
+
+///
+/// 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 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
+ );
+
+/**
+ Determines if a CPU feature is set in PcdCpuFeaturesCapability bit mask.
+
+ @param[in] Feature The bit number of the CPU feature to check in the PCD
+ PcdCpuFeaturesCapability.
+
+ @retval TRUE The CPU feature is set in PcdCpuFeaturesCapability.
+ @retval FALSE The CPU feature is not set in PcdCpuFeaturesCapability.
+
+ @note This service could be called by BSP only.
+**/
+BOOLEAN
+EFIAPI
+IsCpuFeatureCapability (
+ IN UINT32 Feature
+ );
+
+/**
+ Determines if a CPU feature is set in PcdCpuFeaturesUserConfiguration bit mask.
+
+ @param[in] Feature The bit number of the CPU feature to check in the PCD
+ PcdCpuFeaturesUserConfiguration.
+
+ @retval TRUE The CPU feature is set in PcdCpuFeaturesUserConfiguration.
+ @retval FALSE The CPU feature is not set in PcdCpuFeaturesUserConfiguration.
+
+ @note This service could be called by BSP only.
+**/
+BOOLEAN
+EFIAPI
+IsCpuFeatureUserConfiguration (
+ 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 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 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 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 ... 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 UINT32 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 UINT32 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 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 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 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/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index f7abe1cfd9..04c7c1ebc5 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -29,6 +29,11 @@
##
UefiCpuLib|Include/Library/UefiCpuLib.h
+ ## @libraryclass Defines some routines that are used to register/manage/program
+ ## CPU features.
+ ##
+ UefiCpuLib|Include/Library/RegisterCpuFeaturesLib.h
+
[LibraryClasses.IA32, LibraryClasses.X64]
## @libraryclass Provides functions to manage MTRR settings on IA32 and X64 CPUs.
##