mirror of https://github.com/acidanthera/audk.git
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:
parent
59d67246db
commit
e9cd66d085
|
@ -22,11 +22,39 @@
|
||||||
#include <Library/LocalApicLib.h>
|
#include <Library/LocalApicLib.h>
|
||||||
#include <Library/IoLib.h>
|
#include <Library/IoLib.h>
|
||||||
#include <Library/TimerLib.h>
|
#include <Library/TimerLib.h>
|
||||||
|
#include <Library/PcdLib.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Library internal functions
|
// 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.
|
Retrieve the base address of local APIC.
|
||||||
|
|
||||||
|
@ -41,6 +69,14 @@ GetLocalApicBaseAddress (
|
||||||
{
|
{
|
||||||
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);
|
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
|
||||||
|
|
||||||
return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +
|
return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +
|
||||||
|
@ -65,6 +101,13 @@ SetLocalApicBaseAddress (
|
||||||
|
|
||||||
ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
|
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.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
|
||||||
|
|
||||||
ApicBaseMsr.Bits.ApicBaseLow = (UINT32) (BaseAddress >> 12);
|
ApicBaseMsr.Bits.ApicBaseLow = (UINT32) (BaseAddress >> 12);
|
||||||
|
@ -259,6 +302,13 @@ GetApicMode (
|
||||||
{
|
{
|
||||||
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);
|
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
|
||||||
//
|
//
|
||||||
// Local APIC should have been enabled
|
// Local APIC should have been enabled
|
||||||
|
@ -291,6 +341,13 @@ SetApicMode (
|
||||||
UINTN CurrentMode;
|
UINTN CurrentMode;
|
||||||
MSR_IA32_APIC_BASE ApicBaseMsr;
|
MSR_IA32_APIC_BASE ApicBaseMsr;
|
||||||
|
|
||||||
|
if (!LocalApicBaseAddressMsrSupported ()) {
|
||||||
|
//
|
||||||
|
// Ignore set request if the CPU does not support APIC Base Address MSR
|
||||||
|
//
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CurrentMode = GetApicMode ();
|
CurrentMode = GetApicMode ();
|
||||||
if (CurrentMode == LOCAL_APIC_MODE_XAPIC) {
|
if (CurrentMode == LOCAL_APIC_MODE_XAPIC) {
|
||||||
switch (ApicMode) {
|
switch (ApicMode) {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
MODULE_UNI_FILE = BaseXApicX2ApicLib.uni
|
MODULE_UNI_FILE = BaseXApicX2ApicLib.uni
|
||||||
FILE_GUID = 967B6E05-F10D-4c10-8BF7-365291CA143F
|
FILE_GUID = 967B6E05-F10D-4c10-8BF7-365291CA143F
|
||||||
MODULE_TYPE = BASE
|
MODULE_TYPE = BASE
|
||||||
VERSION_STRING = 1.0
|
VERSION_STRING = 1.1
|
||||||
LIBRARY_CLASS = LocalApicLib
|
LIBRARY_CLASS = LocalApicLib
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -42,7 +42,8 @@
|
||||||
DebugLib
|
DebugLib
|
||||||
TimerLib
|
TimerLib
|
||||||
IoLib
|
IoLib
|
||||||
|
PcdLib
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES
|
||||||
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress ## SOMETIMES_CONSUMES
|
||||||
|
|
Loading…
Reference in New Issue