]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/MpLib.c
UefiCpuPkg/MpInitLib: fix 32-bit build error
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / MpLib.c
index 8394572c6107156779f1b937c4366e5e9480d7e6..cdc03113e5998116ad78d7d89ad088a569ca6980 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   CPU MP Initialize Library common functions.\r
 \r
-  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -195,6 +195,10 @@ SaveVolatileRegisters (
     VolatileRegisters->Dr6 = AsmReadDr6 ();\r
     VolatileRegisters->Dr7 = AsmReadDr7 ();\r
   }\r
+\r
+  AsmReadGdtr (&VolatileRegisters->Gdtr);\r
+  AsmReadIdtr (&VolatileRegisters->Idtr);\r
+  VolatileRegisters->Tr = AsmReadTr ();\r
 }\r
 \r
 /**\r
@@ -211,6 +215,7 @@ RestoreVolatileRegisters (
   )\r
 {\r
   CPUID_VERSION_INFO_EDX        VersionInfoEdx;\r
+  IA32_TSS_DESCRIPTOR           *Tss;\r
 \r
   AsmWriteCr0 (VolatileRegisters->Cr0);\r
   AsmWriteCr3 (VolatileRegisters->Cr3);\r
@@ -231,6 +236,18 @@ RestoreVolatileRegisters (
       AsmWriteDr7 (VolatileRegisters->Dr7);\r
     }\r
   }\r
+\r
+  AsmWriteGdtr (&VolatileRegisters->Gdtr);\r
+  AsmWriteIdtr (&VolatileRegisters->Idtr);\r
+  if (VolatileRegisters->Tr != 0 &&\r
+      VolatileRegisters->Tr < VolatileRegisters->Gdtr.Limit) {\r
+    Tss = (IA32_TSS_DESCRIPTOR *)(VolatileRegisters->Gdtr.Base +\r
+                                  VolatileRegisters->Tr);\r
+    if (Tss->Bits.P == 1) {\r
+      Tss->Bits.Type &= 0xD;  // 1101 - Clear busy bit just in case\r
+      AsmWriteTr (VolatileRegisters->Tr);\r
+    }\r
+  }\r
 }\r
 \r
 /**\r
@@ -536,13 +553,13 @@ InitializeApData (
   This function will be called from AP reset code if BSP uses WakeUpAP.\r
 \r
   @param[in] ExchangeInfo     Pointer to the MP exchange info buffer\r
-  @param[in] NumApsExecuting  Number of current executing AP\r
+  @param[in] ApIndex          Number of current executing AP\r
 **/\r
 VOID\r
 EFIAPI\r
 ApWakeupFunction (\r
   IN MP_CPU_EXCHANGE_INFO      *ExchangeInfo,\r
-  IN UINTN                     NumApsExecuting\r
+  IN UINTN                     ApIndex\r
   )\r
 {\r
   CPU_MP_DATA                *CpuMpData;\r
@@ -565,6 +582,10 @@ ApWakeupFunction (
   // We need to re-initialize them at here\r
   //\r
   ProgramVirtualWireMode ();\r
+  //\r
+  // Mask the LINT0 and LINT1 so that AP doesn't enter the system timer interrupt handler.\r
+  //\r
+  DisableLvtInterrupts ();\r
   SyncLocalApicTimerSetting (CpuMpData);\r
 \r
   CurrentApicMode = GetApicMode ();\r
@@ -574,7 +595,7 @@ ApWakeupFunction (
       // Add CPU number\r
       //\r
       InterlockedIncrement ((UINT32 *) &CpuMpData->CpuCount);\r
-      ProcessorNumber = NumApsExecuting;\r
+      ProcessorNumber = ApIndex;\r
       //\r
       // This is first time AP wakeup, get BIST information from AP stack\r
       //\r
@@ -662,6 +683,7 @@ ApWakeupFunction (
     // AP finished executing C code\r
     //\r
     InterlockedIncrement ((UINT32 *) &CpuMpData->FinishedCount);\r
+    InterlockedDecrement ((UINT32 *) &CpuMpData->MpCpuExchangeInfo->NumApsExecuting);\r
 \r
     //\r
     // Place AP is specified loop mode\r
@@ -764,6 +786,7 @@ FillExchangeInfoData (
   ExchangeInfo->Cr3             = AsmReadCr3 ();\r
 \r
   ExchangeInfo->CFunction       = (UINTN) ApWakeupFunction;\r
+  ExchangeInfo->ApIndex         = 0;\r
   ExchangeInfo->NumApsExecuting = 0;\r
   ExchangeInfo->InitFlag        = (UINTN) CpuMpData->InitFlag;\r
   ExchangeInfo->CpuInfo         = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;\r
@@ -934,13 +957,24 @@ WakeUpAP (
     }\r
     if (CpuMpData->InitFlag == ApInitConfig) {\r
       //\r
-      // Wait for all potential APs waken up in one specified period\r
+      // Here support two methods to collect AP count through adjust\r
+      // PcdCpuApInitTimeOutInMicroSeconds values.\r
+      //\r
+      // one way is set a value to just let the first AP to start the\r
+      // initialization, then through the later while loop to wait all Aps\r
+      // finsh the initialization.\r
+      // The other way is set a value to let all APs finished the initialzation.\r
+      // In this case, the later while loop is useless.\r
       //\r
       TimedWaitForApFinish (\r
         CpuMpData,\r
         PcdGet32 (PcdCpuMaxLogicalProcessorNumber) - 1,\r
         PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds)\r
         );\r
+\r
+      while (CpuMpData->MpCpuExchangeInfo->NumApsExecuting != 0) {\r
+        CpuPause();\r
+      }\r
     } else {\r
       //\r
       // Wait all APs waken up if this is not the 1st broadcast of SIPI\r
@@ -1458,6 +1492,8 @@ MpInitLibInitialize (
   CpuMpData->SwitchBspFlag    = FALSE;\r
   CpuMpData->CpuData          = (CPU_AP_DATA *) (CpuMpData + 1);\r
   CpuMpData->CpuInfoInHob     = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);\r
+  CpuMpData->MicrocodePatchAddress    = PcdGet64 (PcdCpuMicrocodePatchAddress);\r
+  CpuMpData->MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);\r
   InitializeSpinLock(&CpuMpData->MpLock);\r
   //\r
   // Save BSP's Control registers to APs\r
@@ -1466,7 +1502,7 @@ MpInitLibInitialize (
   //\r
   // Set BSP basic information\r
   //\r
-  InitializeApData (CpuMpData, 0, 0, CpuMpData->Buffer);\r
+  InitializeApData (CpuMpData, 0, 0, CpuMpData->Buffer + ApStackSize);\r
   //\r
   // Save assembly code information\r
   //\r
@@ -1814,7 +1850,7 @@ EnableDisableApWorker (
   if (!EnableAP) {\r
     SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateDisabled);\r
   } else {\r
-    SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);\r
+    ResetProcessorToIdleState (ProcessorNumber);\r
   }\r
 \r
   if (HealthFlag != NULL) {\r