]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c
EdkCompatibilityPkg: Fix typos in comments
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / MpServicesOnFrameworkMpServicesThunk / MpServicesOnFrameworkMpServicesThunk.c
index 3ff503758d84916819d7a347ea6ed4dfd1778e59..73c89a10f026e4763d9040d80509fdd06593b34f 100644 (file)
@@ -22,7 +22,6 @@ EFI_HANDLE                          mHandle = NULL;
 MP_SYSTEM_DATA                      mMPSystemData;\r
 EFI_PHYSICAL_ADDRESS                mStartupVector;\r
 MP_CPU_EXCHANGE_INFO                *mExchangeInfo;\r
-VOID                                *mStackStartAddress;\r
 BOOLEAN                             mStopCheckAPsStatus = FALSE;\r
 UINTN                               mNumberOfProcessors;\r
 EFI_GENERIC_MEMORY_TEST_PROTOCOL    *mGenMemoryTest;\r
@@ -532,6 +531,12 @@ SwitchBSP (
   CPU_DATA_BLOCK        *CpuData;\r
   UINTN                 CallerNumber;\r
   UINTN                 BspNumber;\r
+  UINTN                 ApicBase;\r
+  UINT32                CurrentTimerValue;\r
+  UINT32                CurrentTimerRegister;\r
+  UINT32                CurrentTimerDivide;\r
+  UINT64                CurrentTscValue;\r
+  BOOLEAN               OldInterruptState;\r
 \r
   //\r
   // Check whether caller processor is BSP\r
@@ -572,6 +577,28 @@ SwitchBSP (
     return EFI_NOT_READY;\r
   }\r
 \r
+  //\r
+  // Save and disable interrupt.\r
+  //\r
+  OldInterruptState = SaveAndDisableInterrupts ();\r
+       \r
+  //\r
+  // Record the current local APIC timer setting of BSP\r
+  //\r
+  ApicBase = (UINTN)AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE, 12, 35) << 12;\r
+  CurrentTimerValue     = MmioRead32 (ApicBase + APIC_REGISTER_TIMER_COUNT);\r
+  CurrentTimerRegister  = MmioRead32 (ApicBase + APIC_REGISTER_LVT_TIMER);\r
+  CurrentTimerDivide    = MmioRead32 (ApicBase + APIC_REGISTER_TIMER_DIVIDE);\r
+  //\r
+  // Set mask bit (BIT 16) of LVT Timer Register to disable its interrupt\r
+  //\r
+  MmioBitFieldWrite32 (ApicBase + APIC_REGISTER_LVT_TIMER, 16, 16, 1);\r
+\r
+  //\r
+  // Record the current TSC value\r
+  //\r
+  CurrentTscValue = AsmReadTsc ();\r
+  \r
   Status = mFrameworkMpService->SwitchBSP (\r
                                   mFrameworkMpService,\r
                                   ProcessorNumber,\r
@@ -579,6 +606,23 @@ SwitchBSP (
                                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  //\r
+  // Restore TSC value\r
+  //\r
+  AsmWriteMsr64 (MSR_IA32_TIME_STAMP_COUNTER, CurrentTscValue);\r
+\r
+  //\r
+  // Restore local APIC timer setting to new BSP\r
+  //\r
+  MmioWrite32 (ApicBase + APIC_REGISTER_TIMER_DIVIDE, CurrentTimerDivide);\r
+  MmioWrite32 (ApicBase + APIC_REGISTER_TIMER_INIT_COUNT, CurrentTimerValue);\r
+  MmioWrite32 (ApicBase + APIC_REGISTER_LVT_TIMER, CurrentTimerRegister);\r
+\r
+  //\r
+  // Restore interrupt state.\r
+  //\r
+  SetInterruptState (OldInterruptState);\r
+  \r
   ChangeCpuState (BspNumber, EnableOldBSP);\r
 \r
   return EFI_SUCCESS;\r
@@ -703,7 +747,7 @@ WhoAmI (
 /**\r
   Checks APs' status periodically.\r
 \r
-  This function is triggerred by timer perodically to check the\r
+  This function is triggered by timer periodically to check the\r
   state of APs for StartupAllAPs() and StartupThisAP() executed\r
   in non-blocking mode.\r
 \r
@@ -1075,70 +1119,6 @@ GetNextWaitingProcessorNumber (
   return EFI_NOT_FOUND;\r
 }\r
 \r
-/**\r
-  Programs Local APIC registers for virtual wire mode.\r
-\r
-  This function programs Local APIC registers for virtual wire mode.\r
-\r
-  @param  Bsp  Indicates whether the programmed processor is going to be BSP\r
-\r
-**/\r
-VOID\r
-ProgramVirtualWireMode (\r
-  BOOLEAN                       Bsp\r
-  )\r
-{\r
-  UINTN                 ApicBase;\r
-  UINT32                Value;\r
-\r
-  ApicBase = (UINTN)AsmMsrBitFieldRead64 (27, 12, 35) << 12;\r
-\r
-  //\r
-  // Program the Spurious Vector entry\r
-  // Set bit 8 (APIC Software Enable/Disable) to enable local APIC,\r
-  // and set Spurious Vector as 0x0F.\r
-  //\r
-  MmioBitFieldWrite32 (ApicBase + APIC_REGISTER_SPURIOUS_VECTOR_OFFSET, 0, 9, 0x10F);\r
-\r
-  //\r
-  // Program the LINT0 vector entry as ExtInt\r
-  // Set bits 8..10 to 7 as ExtInt Delivery Mode,\r
-  // and clear bits for Delivery Status, Interrupt Input Pin Polarity, Remote IRR,\r
-  // Trigger Mode, and Mask\r
-  //\r
-  if (!Bsp) {\r
-    DisableInterrupts ();\r
-  }\r
-  Value = MmioRead32 (ApicBase + APIC_REGISTER_LINT0_VECTOR_OFFSET);\r
-  Value = BitFieldWrite32 (Value, 8, 10, 7);\r
-  Value = BitFieldWrite32 (Value, 12, 16, 0);\r
-  if (!Bsp) {\r
-    //\r
-    // For APs, LINT0 is masked\r
-    //\r
-    Value = BitFieldWrite32 (Value, 16, 16, 1);\r
-  }\r
-  MmioWrite32 (ApicBase + APIC_REGISTER_LINT0_VECTOR_OFFSET, Value);\r
-\r
-  //\r
-  // Program the LINT1 vector entry as NMI\r
-  // Set bits 8..10 to 4 as NMI Delivery Mode,\r
-  // and clear bits for Delivery Status, Interrupt Input Pin Polarity, Remote IRR,\r
-  // Trigger Mode.\r
-  // For BSP clear Mask bit, and for AP set mask bit.\r
-  //\r
-  Value = MmioRead32 (ApicBase + APIC_REGISTER_LINT1_VECTOR_OFFSET);\r
-  Value = BitFieldWrite32 (Value, 8, 10, 4);\r
-  Value = BitFieldWrite32 (Value, 12, 16, 0);\r
-  if (!Bsp) {\r
-    //\r
-    // For APs, LINT1 is masked\r
-    //\r
-    Value = BitFieldWrite32 (Value, 16, 16, 1);\r
-  }\r
-  MmioWrite32 (ApicBase + APIC_REGISTER_LINT1_VECTOR_OFFSET, Value);\r
-}\r
-\r
 \r
 /**\r
   Wrapper function for all procedures assigned to AP.\r
@@ -1157,7 +1137,16 @@ ApProcWrapper (
   UINTN                 ProcessorNumber;\r
   CPU_DATA_BLOCK        *CpuData;\r
 \r
-  ProgramVirtualWireMode (FALSE);\r
+  //\r
+  // Program virtual wire mode for AP, since it will be lost after AP wake up\r
+  //\r
+  ProgramVirtualWireMode ();\r
+  DisableLvtInterrupts ();\r
+\r
+  //\r
+  // Initialize Debug Agent to support source level debug on AP code.\r
+  //\r
+  InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_AP, NULL, NULL);\r
 \r
   WhoAmI (&mMpService, &ProcessorNumber);\r
   CpuData = &mMPSystemData.CpuData[ProcessorNumber];\r
@@ -1196,78 +1185,6 @@ ApProcWrapper (
   ReleaseSpinLock (&CpuData->CpuDataLock);\r
 }\r
 \r
-/**\r
-  Sends INIT-SIPI-SIPI to AP.\r
-\r
-  This function sends INIT-SIPI-SIPI to AP, and assign procedure specified by ApFunction.\r
-\r
-  @param  Broadcast   If TRUE, broadcase IPI to all APs; otherwise, send to specified AP.\r
-  @param  ApicID      The Local APIC ID of the specified AP. If Broadcast is TRUE, it is ignored.\r
-  @param  ApFunction  The procedure for AP to work on.\r
-\r
-**/\r
-VOID\r
-SendInitSipiSipi (\r
-  IN BOOLEAN            Broadcast,\r
-  IN UINT32             ApicID,\r
-  IN VOID               *ApFunction\r
-  )\r
-{\r
-  UINTN                 ApicBase;\r
-  UINT32                ICRLow;\r
-  UINT32                ICRHigh;\r
-\r
-  UINT32                VectorNumber;\r
-  UINT32                DeliveryMode;\r
-\r
-  mExchangeInfo->ApFunction = ApFunction;\r
-  mExchangeInfo->StackStart = mStackStartAddress;\r
-\r
-  if (Broadcast) {\r
-    ICRHigh = 0;\r
-    ICRLow  = BROADCAST_MODE_ALL_EXCLUDING_SELF_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;\r
-  } else {\r
-    ICRHigh = ApicID << 24;\r
-    ICRLow  = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;\r
-  }\r
-\r
-  VectorNumber = 0;\r
-  DeliveryMode = DELIVERY_MODE_INIT;\r
-  ICRLow      |= VectorNumber | (DeliveryMode << 8);\r
-\r
-  ApicBase = 0xfee00000;\r
-\r
-  //\r
-  // Write Interrupt Command Registers to send INIT IPI.\r
-  //\r
-  MmioWrite32 (ApicBase + APIC_REGISTER_ICR_HIGH_OFFSET, ICRHigh);\r
-  MmioWrite32 (ApicBase + APIC_REGISTER_ICR_LOW_OFFSET, ICRLow);\r
-\r
-  MicroSecondDelay (10);\r
-\r
-  VectorNumber = (UINT32) RShiftU64 (mStartupVector, 12);\r
-  DeliveryMode = DELIVERY_MODE_SIPI;\r
-  if (Broadcast) {\r
-    ICRLow = BROADCAST_MODE_ALL_EXCLUDING_SELF_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;\r
-  } else {\r
-    ICRLow = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;\r
-  }\r
-\r
-  ICRLow |= VectorNumber | (DeliveryMode << 8);\r
-\r
-  //\r
-  // Write Interrupt Command Register to send first SIPI IPI.\r
-  //\r
-  MmioWrite32 (ApicBase + APIC_REGISTER_ICR_LOW_OFFSET, ICRLow);\r
-\r
-  MicroSecondDelay (200);\r
-\r
-  //\r
-  // Write Interrupt Command Register to send second SIPI IPI.\r
-  //\r
-  MmioWrite32 (ApicBase + APIC_REGISTER_ICR_LOW_OFFSET, ICRLow);\r
-}\r
-\r
 /**\r
   Function to wake up a specified AP and assign procedure to it.\r
 \r
@@ -1304,10 +1221,11 @@ WakeUpAp (
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  mExchangeInfo->ApFunction = (VOID *) (UINTN) ApProcWrapper;\r
+  mExchangeInfo->ProcessorNumber[ProcessorInfoBuffer.ProcessorId] = (UINT32) ProcessorNumber;\r
   SendInitSipiSipi (\r
-    FALSE,\r
     (UINT32) ProcessorInfoBuffer.ProcessorId,\r
-    (VOID *) (UINTN) ApProcWrapper\r
+    (UINT32) (UINTN) mStartupVector\r
     );\r
 }\r
 \r
@@ -1336,10 +1254,11 @@ ResetProcessorToIdleState (
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  mExchangeInfo->ApFunction = NULL;\r
+  mExchangeInfo->ProcessorNumber[ProcessorInfoBuffer.ProcessorId] = (UINT32) ProcessorNumber;\r
   SendInitSipiSipi (\r
-    FALSE,\r
     (UINT32) ProcessorInfoBuffer.ProcessorId,\r
-    NULL\r
+    (UINT32) (UINTN) mStartupVector\r
     );\r
 \r
   CpuData = &mMPSystemData.CpuData[ProcessorNumber];\r
@@ -1548,7 +1467,7 @@ PrepareAPStartupVector (
 \r
   ZeroMem ((VOID *) mExchangeInfo, sizeof (MP_CPU_EXCHANGE_INFO));\r
 \r
-  mStackStartAddress = AllocatePages (EFI_SIZE_TO_PAGES (MAX_CPU_NUMBER * AP_STACK_SIZE));\r
+  mExchangeInfo->StackStart  = AllocatePages (EFI_SIZE_TO_PAGES (mNumberOfProcessors * AP_STACK_SIZE));\r
   mExchangeInfo->StackSize  = AP_STACK_SIZE;\r
 \r
   AsmReadGdtr (&GdtrForBSP);\r
@@ -1658,8 +1577,6 @@ InitializeMpServicesProtocol (
 {\r
   EFI_STATUS Status;\r
 \r
-  PrepareMemoryForConfiguration ();\r
-\r
   //\r
   // Locates Framework version MP Services Protocol\r
   //\r
@@ -1681,6 +1598,8 @@ InitializeMpServicesProtocol (
   ASSERT_EFI_ERROR (Status);\r
   ASSERT (mNumberOfProcessors < MAX_CPU_NUMBER);\r
 \r
+  PrepareMemoryForConfiguration ();\r
+\r
   //\r
   // Create timer event to check AP state for non-blocking execution.\r
   //\r