summaryrefslogtreecommitdiff
path: root/Core/UefiCpuPkg
diff options
context:
space:
mode:
Diffstat (limited to 'Core/UefiCpuPkg')
-rw-r--r--Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeatures.h15
-rw-r--r--Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.c2
-rw-r--r--Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/X2Apic.c70
3 files changed, 77 insertions, 10 deletions
diff --git a/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeatures.h b/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeatures.h
index aa6d1122b1..9a7afed105 100644
--- a/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeatures.h
+++ b/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeatures.h
@@ -798,6 +798,21 @@ C1eInitialize (
);
/**
+ 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.
+**/
+VOID *
+EFIAPI
+X2ApicGetConfigData (
+ IN UINTN NumberOfProcessors
+ );
+
+/**
Detects if X2Apci feature supported on current processor.
Detect if X2Apci has been already enabled.
diff --git a/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.c b/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.c
index 3390aa8f2a..793a0956d3 100644
--- a/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.c
+++ b/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.c
@@ -211,7 +211,7 @@ CpuCommonFeaturesLibConstructor (
if (IsCpuFeatureSupported (CPU_FEATURE_X2APIC)) {
Status = RegisterCpuFeature (
"X2Apic",
- NULL,
+ X2ApicGetConfigData,
X2ApicSupport,
X2ApicInitialize,
CPU_FEATURE_X2APIC,
diff --git a/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/X2Apic.c b/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/X2Apic.c
index 9c2ad9ad31..b4a453c352 100644
--- a/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/X2Apic.c
+++ b/Core/UefiCpuPkg/Library/CpuCommonFeaturesLib/X2Apic.c
@@ -15,6 +15,28 @@
#include "CpuCommonFeatures.h"
/**
+ 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.
+**/
+VOID *
+EFIAPI
+X2ApicGetConfigData (
+ IN UINTN NumberOfProcessors
+ )
+{
+ BOOLEAN *ConfigData;
+
+ ConfigData = AllocateZeroPool (sizeof (BOOLEAN) * NumberOfProcessors);
+ ASSERT (ConfigData != NULL);
+ return ConfigData;
+}
+
+/**
Detects if X2Apci feature supported on current processor.
Detect if X2Apci has been already enabled.
@@ -40,7 +62,16 @@ X2ApicSupport (
IN VOID *ConfigData OPTIONAL
)
{
- return (GetApicMode () == LOCAL_APIC_MODE_X2APIC);
+ BOOLEAN *X2ApicEnabled;
+
+ ASSERT (ConfigData != NULL);
+ X2ApicEnabled = (BOOLEAN *) ConfigData;
+ //
+ // *ConfigData indicates if X2APIC enabled on current processor
+ //
+ X2ApicEnabled[ProcessorNumber] = (GetApicMode () == LOCAL_APIC_MODE_X2APIC) ? TRUE : FALSE;
+
+ return (CpuInfo->CpuIdVersionInfoEcx.Bits.x2APIC == 1);
}
/**
@@ -69,13 +100,34 @@ X2ApicInitialize (
IN BOOLEAN State
)
{
- PRE_SMM_CPU_REGISTER_TABLE_WRITE_FIELD (
- ProcessorNumber,
- Msr,
- MSR_IA32_APIC_BASE,
- MSR_IA32_APIC_BASE_REGISTER,
- Bits.EXTD,
- (State) ? 1 : 0
- );
+ BOOLEAN *X2ApicEnabled;
+
+ ASSERT (ConfigData != NULL);
+ X2ApicEnabled = (BOOLEAN *) ConfigData;
+ if (X2ApicEnabled[ProcessorNumber]) {
+ PRE_SMM_CPU_REGISTER_TABLE_WRITE_FIELD (
+ ProcessorNumber,
+ Msr,
+ MSR_IA32_APIC_BASE,
+ MSR_IA32_APIC_BASE_REGISTER,
+ Bits.EXTD,
+ 1
+ );
+ } else {
+ //
+ // Enable X2APIC mode only if X2APIC is not enabled,
+ // Needn't to disabe X2APIC mode again if X2APIC is not enabled
+ //
+ if (State) {
+ CPU_REGISTER_TABLE_WRITE_FIELD (
+ ProcessorNumber,
+ Msr,
+ MSR_IA32_APIC_BASE,
+ MSR_IA32_APIC_BASE_REGISTER,
+ Bits.EXTD,
+ 1
+ );
+ }
+ }
return RETURN_SUCCESS;
}