#include <Library/TimerLib.h>\r
#include <Library/PcdLib.h>\r
#include <Library/UefiCpuLib.h>\r
+#include <IndustryStandard/Tdx.h>\r
\r
//\r
// Library internal functions\r
//\r
\r
+/**\r
+ Some MSRs in TDX are accessed via TdCall.\r
+ Some are directly read/write from/to CPU.\r
+\r
+ @param MsrIndex Index of the MSR\r
+ @retval TRUE MSR accessed via TdCall.\r
+ @retval FALSE MSR accessed not via TdCall.\r
+\r
+**/\r
+BOOLEAN\r
+AccessMsrTdxCall (\r
+ IN UINT32 MsrIndex\r
+ )\r
+{\r
+ if (!TdIsEnabled ()) {\r
+ return FALSE;\r
+ }\r
+\r
+ switch (MsrIndex) {\r
+ case MSR_IA32_X2APIC_TPR:\r
+ case MSR_IA32_X2APIC_PPR:\r
+ case MSR_IA32_X2APIC_EOI:\r
+ case MSR_IA32_X2APIC_ISR0:\r
+ case MSR_IA32_X2APIC_ISR1:\r
+ case MSR_IA32_X2APIC_ISR2:\r
+ case MSR_IA32_X2APIC_ISR3:\r
+ case MSR_IA32_X2APIC_ISR4:\r
+ case MSR_IA32_X2APIC_ISR5:\r
+ case MSR_IA32_X2APIC_ISR6:\r
+ case MSR_IA32_X2APIC_ISR7:\r
+ case MSR_IA32_X2APIC_TMR0:\r
+ case MSR_IA32_X2APIC_TMR1:\r
+ case MSR_IA32_X2APIC_TMR2:\r
+ case MSR_IA32_X2APIC_TMR3:\r
+ case MSR_IA32_X2APIC_TMR4:\r
+ case MSR_IA32_X2APIC_TMR5:\r
+ case MSR_IA32_X2APIC_TMR6:\r
+ case MSR_IA32_X2APIC_TMR7:\r
+ case MSR_IA32_X2APIC_IRR0:\r
+ case MSR_IA32_X2APIC_IRR1:\r
+ case MSR_IA32_X2APIC_IRR2:\r
+ case MSR_IA32_X2APIC_IRR3:\r
+ case MSR_IA32_X2APIC_IRR4:\r
+ case MSR_IA32_X2APIC_IRR5:\r
+ case MSR_IA32_X2APIC_IRR6:\r
+ case MSR_IA32_X2APIC_IRR7:\r
+ return FALSE;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Read MSR value.\r
+\r
+ @param MsrIndex Index of the MSR to read\r
+ @retval 64-bit Value of MSR.\r
+\r
+**/\r
+UINT64\r
+LocalApicReadMsrReg64 (\r
+ IN UINT32 MsrIndex\r
+ )\r
+{\r
+ UINT64 Val;\r
+ UINT64 Status;\r
+\r
+ if (AccessMsrTdxCall (MsrIndex)) {\r
+ Status = TdVmCall (TDVMCALL_RDMSR, (UINT64)MsrIndex, 0, 0, 0, &Val);\r
+ if (Status != 0) {\r
+ TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0);\r
+ }\r
+ } else {\r
+ Val = AsmReadMsr64 (MsrIndex);\r
+ }\r
+\r
+ return Val;\r
+}\r
+\r
+/**\r
+ Write to MSR.\r
+\r
+ @param MsrIndex Index of the MSR to write to\r
+ @param Value Value to be written to the MSR\r
+\r
+ @return Value\r
+\r
+**/\r
+UINT64\r
+LocalApicWriteMsrReg64 (\r
+ IN UINT32 MsrIndex,\r
+ IN UINT64 Value\r
+ )\r
+{\r
+ UINT64 Status;\r
+\r
+ if (AccessMsrTdxCall (MsrIndex)) {\r
+ Status = TdVmCall (TDVMCALL_WRMSR, (UINT64)MsrIndex, Value, 0, 0, 0);\r
+ if (Status != 0) {\r
+ TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0);\r
+ }\r
+ } else {\r
+ AsmWriteMsr64 (MsrIndex, Value);\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+/**\r
+ Read MSR value.\r
+\r
+ @param MsrIndex Index of the MSR to read\r
+ @retval 32-bit Value of MSR.\r
+\r
+**/\r
+UINT32\r
+LocalApicReadMsrReg32 (\r
+ IN UINT32 MsrIndex\r
+ )\r
+{\r
+ return (UINT32)LocalApicReadMsrReg64 (MsrIndex);\r
+}\r
+\r
+/**\r
+ Write to MSR.\r
+\r
+ @param MsrIndex Index of the MSR to write to\r
+ @param Value Value to be written to the MSR\r
+\r
+ @return Value\r
+\r
+**/\r
+UINT32\r
+LocalApicWriteMsrReg32 (\r
+ IN UINT32 MsrIndex,\r
+ IN UINT32 Value\r
+ )\r
+{\r
+ return (UINT32)LocalApicWriteMsrReg64 (MsrIndex, Value);\r
+}\r
+\r
/**\r
Determine if the CPU supports the Local APIC Base Address MSR.\r
\r
return PcdGet32 (PcdCpuLocalApicBaseAddress);\r
}\r
\r
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
+ ApicBaseMsr.Uint64 = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);\r
\r
return (UINTN)(LShiftU64 ((UINT64)ApicBaseMsr.Bits.ApicBaseHi, 32)) +\r
(((UINTN)ApicBaseMsr.Bits.ApicBase) << 12);\r
return;\r
}\r
\r
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
+ ApicBaseMsr.Uint64 = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);\r
\r
ApicBaseMsr.Bits.ApicBase = (UINT32)(BaseAddress >> 12);\r
ApicBaseMsr.Bits.ApicBaseHi = (UINT32)(RShiftU64 ((UINT64)BaseAddress, 32));\r
\r
- AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);\r
+ LocalApicWriteMsrReg64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);\r
}\r
\r
/**\r
ASSERT (MmioOffset != XAPIC_ICR_HIGH_OFFSET);\r
\r
MsrIndex = (UINT32)(MmioOffset >> 4) + X2APIC_MSR_BASE_ADDRESS;\r
- return AsmReadMsr32 (MsrIndex);\r
+ return LocalApicReadMsrReg32 (MsrIndex);\r
}\r
}\r
\r
// Use memory fence here to force the serializing semantics to be consisent with xAPIC mode.\r
//\r
MemoryFence ();\r
- AsmWriteMsr32 (MsrIndex, Value);\r
+ LocalApicWriteMsrReg32 (MsrIndex, Value);\r
}\r
}\r
\r
return LOCAL_APIC_MODE_XAPIC;\r
}\r
\r
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
+ ApicBaseMsr.Uint64 = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);\r
//\r
// Local APIC should have been enabled\r
//\r
case LOCAL_APIC_MODE_XAPIC:\r
break;\r
case LOCAL_APIC_MODE_X2APIC:\r
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
+ ApicBaseMsr.Uint64 = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);\r
ApicBaseMsr.Bits.EXTD = 1;\r
- AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);\r
+ LocalApicWriteMsrReg64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);\r
break;\r
default:\r
ASSERT (FALSE);\r