mirror of https://github.com/acidanthera/audk.git
MdePkg/BaseXApicLib: 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@17216 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
cd68e4a8de
commit
59d67246db
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
This local APIC library instance supports xAPIC mode only.
|
This local APIC library instance supports xAPIC mode only.
|
||||||
|
|
||||||
Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -21,11 +21,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.
|
||||||
|
|
||||||
|
@ -38,8 +66,16 @@ GetLocalApicBaseAddress (
|
||||||
VOID
|
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);
|
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
|
||||||
|
|
||||||
return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +
|
return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +
|
||||||
|
@ -60,10 +96,17 @@ SetLocalApicBaseAddress (
|
||||||
IN UINTN BaseAddress
|
IN UINTN BaseAddress
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
MSR_IA32_APIC_BASE ApicBaseMsr;
|
MSR_IA32_APIC_BASE ApicBaseMsr;
|
||||||
|
|
||||||
ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
|
ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
|
||||||
|
|
||||||
|
if (!LocalApicBaseAddressMsrSupported ()) {
|
||||||
|
//
|
||||||
|
// Ignore set request if 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);
|
||||||
|
@ -202,14 +245,19 @@ GetApicMode (
|
||||||
{
|
{
|
||||||
DEBUG_CODE (
|
DEBUG_CODE (
|
||||||
{
|
{
|
||||||
MSR_IA32_APIC_BASE ApicBaseMsr;
|
MSR_IA32_APIC_BASE ApicBaseMsr;
|
||||||
|
|
||||||
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
|
|
||||||
//
|
//
|
||||||
// Local APIC should have been enabled
|
// Check to see if the CPU supports the APIC Base Address MSR
|
||||||
//
|
//
|
||||||
ASSERT (ApicBaseMsr.Bits.En != 0);
|
if (LocalApicBaseAddressMsrSupported ()) {
|
||||||
ASSERT (ApicBaseMsr.Bits.Extd == 0);
|
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
|
||||||
|
//
|
||||||
|
// Local APIC should have been enabled
|
||||||
|
//
|
||||||
|
ASSERT (ApicBaseMsr.Bits.En != 0);
|
||||||
|
ASSERT (ApicBaseMsr.Bits.Extd == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return LOCAL_APIC_MODE_XAPIC;
|
return LOCAL_APIC_MODE_XAPIC;
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
MODULE_UNI_FILE = BaseXApicLib.uni
|
MODULE_UNI_FILE = BaseXApicLib.uni
|
||||||
FILE_GUID = D87CA0A8-1AC2-439b-90F8-EF4A2AC88DAF
|
FILE_GUID = D87CA0A8-1AC2-439b-90F8-EF4A2AC88DAF
|
||||||
MODULE_TYPE = BASE
|
MODULE_TYPE = BASE
|
||||||
VERSION_STRING = 1.0
|
VERSION_STRING = 1.1
|
||||||
LIBRARY_CLASS = LocalApicLib
|
LIBRARY_CLASS = LocalApicLib
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -42,6 +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