#include <Library/LocalApicLib.h>\r
#include <Library/IoLib.h>\r
#include <Library/TimerLib.h>\r
+#include <Library/PcdLib.h>\r
\r
//\r
// Library internal functions\r
//\r
\r
+/**\r
+ Determine if the CPU supports the Local APIC Base Address MSR.\r
+\r
+ @retval TRUE The CPU supports the Local APIC Base Address MSR.\r
+ @retval FALSE The CPU does not support the Local APIC Base Address MSR.\r
+\r
+**/\r
+BOOLEAN\r
+LocalApicBaseAddressMsrSupported (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 RegEax;\r
+ UINTN FamilyId;\r
+ \r
+ AsmCpuid (1, &RegEax, NULL, NULL, NULL);\r
+ FamilyId = BitFieldRead32 (RegEax, 8, 11);\r
+ if (FamilyId == 0x04 || FamilyId == 0x05) {\r
+ //\r
+ // CPUs with a FamilyId of 0x04 or 0x05 do not support the \r
+ // Local APIC Base Address MSR\r
+ //\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
/**\r
Retrieve the base address of local APIC.\r
\r
VOID\r
)\r
{\r
- MSR_IA32_APIC_BASE ApicBaseMsr;\r
- \r
+ MSR_IA32_APIC_BASE ApicBaseMsr;\r
+\r
+ if (!LocalApicBaseAddressMsrSupported ()) {\r
+ //\r
+ // If CPU does not support Local APIC Base Address MSR, then retrieve\r
+ // Local APIC Base Address from PCD\r
+ //\r
+ return PcdGet32 (PcdCpuLocalApicBaseAddress);\r
+ }\r
+\r
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);\r
\r
return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +\r
IN UINTN BaseAddress\r
)\r
{\r
- MSR_IA32_APIC_BASE ApicBaseMsr;\r
+ MSR_IA32_APIC_BASE ApicBaseMsr;\r
\r
ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);\r
\r
+ if (!LocalApicBaseAddressMsrSupported ()) {\r
+ //\r
+ // Ignore set request of the CPU does not support APIC Base Address MSR\r
+ //\r
+ return;\r
+ }\r
+\r
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);\r
\r
ApicBaseMsr.Bits.ApicBaseLow = (UINT32) (BaseAddress >> 12);\r
VOID\r
)\r
{\r
- MSR_IA32_APIC_BASE ApicBaseMsr;\r
+ MSR_IA32_APIC_BASE ApicBaseMsr;\r
+\r
+ if (!LocalApicBaseAddressMsrSupported ()) {\r
+ //\r
+ // If CPU does not support APIC Base Address MSR, then return XAPIC mode\r
+ //\r
+ return LOCAL_APIC_MODE_XAPIC;\r
+ }\r
\r
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);\r
//\r
IN UINTN ApicMode\r
)\r
{\r
- UINTN CurrentMode;\r
- MSR_IA32_APIC_BASE ApicBaseMsr;\r
+ UINTN CurrentMode;\r
+ MSR_IA32_APIC_BASE ApicBaseMsr;\r
+\r
+ if (!LocalApicBaseAddressMsrSupported ()) {\r
+ //\r
+ // Ignore set request if the CPU does not support APIC Base Address MSR\r
+ //\r
+ return;\r
+ }\r
\r
CurrentMode = GetApicMode ();\r
if (CurrentMode == LOCAL_APIC_MODE_XAPIC) {\r