summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kinney <michael.d.kinney@intel.com>2015-04-27 19:48:00 +0000
committermdkinney <mdkinney@Edk2>2015-04-27 19:48:00 +0000
commite9cd66d0859f63ec6aab2b1ac863fe72b65fe474 (patch)
tree6be85b236d37335bdada00b5d2b4271420fc8aec
parent59d67246dbbe3f0fe29bc46c65f8ea4a6828cb2a (diff)
downloadedk2-e9cd66d0859f63ec6aab2b1ac863fe72b65fe474.tar.gz
edk2-e9cd66d0859f63ec6aab2b1ac863fe72b65fe474.tar.bz2
edk2-e9cd66d0859f63ec6aab2b1ac863fe72b65fe474.zip
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
-rw-r--r--UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c69
-rw-r--r--UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf7
2 files changed, 67 insertions, 9 deletions
diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
index bf318e06e4..8c6e8d7415 100644
--- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
+++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
@@ -22,12 +22,40 @@
#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.
@return 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) {
diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
index 1e0e98433d..53e186858f 100644
--- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
+++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
@@ -21,7 +21,7 @@
MODULE_UNI_FILE = BaseXApicX2ApicLib.uni
FILE_GUID = 967B6E05-F10D-4c10-8BF7-365291CA143F
MODULE_TYPE = BASE
- VERSION_STRING = 1.0
+ VERSION_STRING = 1.1
LIBRARY_CLASS = LocalApicLib
#
@@ -42,7 +42,8 @@
DebugLib
TimerLib
IoLib
+ PcdLib
[Pcd]
- gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES
-
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress ## SOMETIMES_CONSUMES