MdePkg/BaseXApicX2ApicLib: Support IA32 processors without MSR_IA32_APIC_BASE_ADDRESS
Use Family from CPUID 01 to detect support for the Local APIC Base Address MSR (MSR_IA32_APIC_BASE_ADDRESS). If this MSR is not supported, then use Local APIC Base Address from the PCD PcdCpuLocalApicBaseAddress. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney <michael.d.kinney@intel.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17217 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -22,11 +22,39 @@
|
||||
#include <Library/LocalApicLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/TimerLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
//
|
||||
// Library internal functions
|
||||
//
|
||||
|
||||
/**
|
||||
Determine if the CPU supports the Local APIC Base Address MSR.
|
||||
|
||||
@retval TRUE The CPU supports the Local APIC Base Address MSR.
|
||||
@retval FALSE The CPU does not support the Local APIC Base Address MSR.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
LocalApicBaseAddressMsrSupported (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 RegEax;
|
||||
UINTN FamilyId;
|
||||
|
||||
AsmCpuid (1, &RegEax, NULL, NULL, NULL);
|
||||
FamilyId = BitFieldRead32 (RegEax, 8, 11);
|
||||
if (FamilyId == 0x04 || FamilyId == 0x05) {
|
||||
//
|
||||
// CPUs with a FamilyId of 0x04 or 0x05 do not support the
|
||||
// Local APIC Base Address MSR
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieve the base address of local APIC.
|
||||
|
||||
@@ -39,8 +67,16 @@ GetLocalApicBaseAddress (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
MSR_IA32_APIC_BASE ApicBaseMsr;
|
||||
|
||||
MSR_IA32_APIC_BASE ApicBaseMsr;
|
||||
|
||||
if (!LocalApicBaseAddressMsrSupported ()) {
|
||||
//
|
||||
// If CPU does not support Local APIC Base Address MSR, then retrieve
|
||||
// Local APIC Base Address from PCD
|
||||
//
|
||||
return PcdGet32 (PcdCpuLocalApicBaseAddress);
|
||||
}
|
||||
|
||||
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
|
||||
|
||||
return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +
|
||||
@@ -61,10 +97,17 @@ SetLocalApicBaseAddress (
|
||||
IN UINTN BaseAddress
|
||||
)
|
||||
{
|
||||
MSR_IA32_APIC_BASE ApicBaseMsr;
|
||||
MSR_IA32_APIC_BASE ApicBaseMsr;
|
||||
|
||||
ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
|
||||
|
||||
if (!LocalApicBaseAddressMsrSupported ()) {
|
||||
//
|
||||
// Ignore set request of the CPU does not support APIC Base Address MSR
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
|
||||
|
||||
ApicBaseMsr.Bits.ApicBaseLow = (UINT32) (BaseAddress >> 12);
|
||||
@@ -257,7 +300,14 @@ GetApicMode (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
MSR_IA32_APIC_BASE ApicBaseMsr;
|
||||
MSR_IA32_APIC_BASE ApicBaseMsr;
|
||||
|
||||
if (!LocalApicBaseAddressMsrSupported ()) {
|
||||
//
|
||||
// If CPU does not support APIC Base Address MSR, then return XAPIC mode
|
||||
//
|
||||
return LOCAL_APIC_MODE_XAPIC;
|
||||
}
|
||||
|
||||
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
|
||||
//
|
||||
@@ -288,8 +338,15 @@ SetApicMode (
|
||||
IN UINTN ApicMode
|
||||
)
|
||||
{
|
||||
UINTN CurrentMode;
|
||||
MSR_IA32_APIC_BASE ApicBaseMsr;
|
||||
UINTN CurrentMode;
|
||||
MSR_IA32_APIC_BASE ApicBaseMsr;
|
||||
|
||||
if (!LocalApicBaseAddressMsrSupported ()) {
|
||||
//
|
||||
// Ignore set request if the CPU does not support APIC Base Address MSR
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentMode = GetApicMode ();
|
||||
if (CurrentMode == LOCAL_APIC_MODE_XAPIC) {
|
||||
|
Reference in New Issue
Block a user