]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/MpLib.c
UefiCpuPkg/MpInitLib: Add CPU_VOLATILE_REGISTERS & worker functions
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / MpLib.c
index 70e5eb1b411a843eb6369819ee350531dffbb258..0832228d71cab1216e548eabbd208c2ac6c6bdd6 100644 (file)
@@ -46,6 +46,73 @@ SetApState (
   ReleaseSpinLock (&CpuData->ApLock);\r
 }\r
 \r
+/**\r
+  Save the volatile registers required to be restored following INIT IPI.\r
+\r
+  @param[out]  VolatileRegisters    Returns buffer saved the volatile resisters\r
+**/\r
+VOID\r
+SaveVolatileRegisters (\r
+  OUT CPU_VOLATILE_REGISTERS    *VolatileRegisters\r
+  )\r
+{\r
+  CPUID_VERSION_INFO_EDX        VersionInfoEdx;\r
+\r
+  VolatileRegisters->Cr0 = AsmReadCr0 ();\r
+  VolatileRegisters->Cr3 = AsmReadCr3 ();\r
+  VolatileRegisters->Cr4 = AsmReadCr4 ();\r
+\r
+  AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);\r
+  if (VersionInfoEdx.Bits.DE != 0) {\r
+    //\r
+    // If processor supports Debugging Extensions feature\r
+    // by CPUID.[EAX=01H]:EDX.BIT2\r
+    //\r
+    VolatileRegisters->Dr0 = AsmReadDr0 ();\r
+    VolatileRegisters->Dr1 = AsmReadDr1 ();\r
+    VolatileRegisters->Dr2 = AsmReadDr2 ();\r
+    VolatileRegisters->Dr3 = AsmReadDr3 ();\r
+    VolatileRegisters->Dr6 = AsmReadDr6 ();\r
+    VolatileRegisters->Dr7 = AsmReadDr7 ();\r
+  }\r
+}\r
+\r
+/**\r
+  Restore the volatile registers following INIT IPI.\r
+\r
+  @param[in]  VolatileRegisters   Pointer to volatile resisters\r
+  @param[in]  IsRestoreDr         TRUE:  Restore DRx if supported\r
+                                  FALSE: Do not restore DRx\r
+**/\r
+VOID\r
+RestoreVolatileRegisters (\r
+  IN CPU_VOLATILE_REGISTERS    *VolatileRegisters,\r
+  IN BOOLEAN                   IsRestoreDr\r
+  )\r
+{\r
+  CPUID_VERSION_INFO_EDX        VersionInfoEdx;\r
+\r
+  AsmWriteCr0 (VolatileRegisters->Cr0);\r
+  AsmWriteCr3 (VolatileRegisters->Cr3);\r
+  AsmWriteCr4 (VolatileRegisters->Cr4);\r
+\r
+  if (IsRestoreDr) {\r
+    AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);\r
+    if (VersionInfoEdx.Bits.DE != 0) {\r
+      //\r
+      // If processor supports Debugging Extensions feature\r
+      // by CPUID.[EAX=01H]:EDX.BIT2\r
+      //\r
+      AsmWriteDr0 (VolatileRegisters->Dr0);\r
+      AsmWriteDr1 (VolatileRegisters->Dr1);\r
+      AsmWriteDr2 (VolatileRegisters->Dr2);\r
+      AsmWriteDr3 (VolatileRegisters->Dr3);\r
+      AsmWriteDr6 (VolatileRegisters->Dr6);\r
+      AsmWriteDr7 (VolatileRegisters->Dr7);\r
+    }\r
+  }\r
+}\r
+\r
 /**\r
   Detect whether Mwait-monitor feature is supported.\r
 \r
@@ -204,6 +271,10 @@ MpInitLibInitialize (
   CpuMpData->CpuInfoInHob     = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);\r
   InitializeSpinLock(&CpuMpData->MpLock);\r
   //\r
+  // Save BSP's Control registers to APs\r
+  //\r
+  SaveVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters);\r
+  //\r
   // Set BSP basic information\r
   //\r
   InitializeApData (CpuMpData, 0, 0);\r