public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Jeff Fan <jeff.fan@intel.com>
To: edk2-devel@lists.01.org
Cc: Feng Tian <feng.tian@intel.com>,
	Kinney, Michael D <michael.d.kinney@intel.com>,
	Ruiyu Ni <ruiyu.ni@intel.com>
Subject: [PATCH 2/6] UefiCpuPkg/MpInitLib: Sync BSP's local APIC timer settings to APs
Date: Mon, 26 Dec 2016 19:20:58 +0800	[thread overview]
Message-ID: <20161226112102.25512-3-jeff.fan@intel.com> (raw)
In-Reply-To: <20161226112102.25512-1-jeff.fan@intel.com>

If APs are waken up by INIT-SIPI-SIPI command, they will lose original local
APIC timer setting. As a result, the timer library instance based on local APIC
timer cannot work on APs function.

This fix is to save BSP's local APIC timer settings before waking up APs and
to sync to APs when APs wakeup by INIT-SIPI-SIPI command.

Setting BSP's current counter to AP's initial counter could make sure BSP and
APs have same counter value across BSP switching.

Cc: Feng Tian <feng.tian@intel.com>
Cc: Kinney, Michael D <michael.d.kinney@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
---
 UefiCpuPkg/Library/MpInitLib/MpLib.c | 55 +++++++++++++++++++++++++++++++++++-
 UefiCpuPkg/Library/MpInitLib/MpLib.h |  6 ++++
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index a21a980..e5842ef 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -110,6 +110,53 @@ SetApState (
 }
 
 /**
+  Save BSP's local APIC timer setting
+
+  @param[in] CpuMpData          Pointer to CPU MP Data
+**/
+VOID
+SaveLocalApicTimerSetting (
+  IN CPU_MP_DATA   *CpuMpData
+  )
+{
+  //
+  // Record the current local APIC timer setting of BSP
+  //
+  GetApicTimerState (
+    &CpuMpData->DivideValue,
+    &CpuMpData->PeriodicMode,
+    &CpuMpData->Vector
+    );
+  CpuMpData->CurrentTimerCount   = GetApicTimerCurrentCount ();
+  CpuMpData->TimerInterruptState = GetApicTimerInterruptState ();
+}
+
+/**
+  Sync local APIC timer setting from BSP to AP.
+
+  @param[in] CpuMpData          Pointer to CPU MP Data
+**/
+VOID
+SyncLocalApicTimerSetting (
+  IN CPU_MP_DATA   *CpuMpData
+  )
+{
+  //
+  // Sync local APIC timer setting from BSP to AP
+  //
+  InitializeApicTimer (
+    CpuMpData->DivideValue,
+    CpuMpData->CurrentTimerCount,
+    CpuMpData->PeriodicMode,
+    CpuMpData->Vector
+    );
+  //
+  // Disable AP's local APIC timer interrupt
+  //
+  DisableApicTimerInterrupt ();
+}
+
+/**
   Save the volatile registers required to be restored following INIT IPI.
 
   @param[out]  VolatileRegisters    Returns buffer saved the volatile resisters
@@ -488,7 +535,12 @@ ApWakeupFunction (
   //
   CpuMpData = ExchangeInfo->CpuMpData;
 
-  ProgramVirtualWireMode (); 
+  //
+  // AP's local APIC settings will be lost after received INIT IPI
+  // We need to re-initialize them at here
+  //
+  ProgramVirtualWireMode ();
+  SyncLocalApicTimerSetting (CpuMpData);
 
   while (TRUE) {
     if (CpuMpData->InitFlag == ApInitConfig) {
@@ -736,6 +788,7 @@ WakeUpAP (
     ResetVectorRequired = TRUE;
     AllocateResetVector (CpuMpData);
     FillExchangeInfoData (CpuMpData);
+    SaveLocalApicTimerSetting (CpuMpData);
   } else if (CpuMpData->ApLoopMode == ApInMwaitLoop) {
     //
     // Get AP target C-state each time when waking up AP,
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index b67ea9d..7a272d7 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -227,6 +227,12 @@ struct _CPU_MP_DATA {
   UINT16                         PmCodeSegment;
   CPU_AP_DATA                    *CpuData;
   volatile MP_CPU_EXCHANGE_INFO  *MpCpuExchangeInfo;
+
+  UINT32                         CurrentTimerCount;
+  UINTN                          DivideValue;
+  UINT8                          Vector;
+  BOOLEAN                        PeriodicMode;
+  BOOLEAN                        TimerInterruptState;
 };
 
 extern EFI_GUID mCpuInitMpLibHobGuid;
-- 
2.9.3.windows.2



  parent reply	other threads:[~2016-12-26 11:21 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-26 11:20 [PATCH 0/6] Support source debugging on DXE AP function Jeff Fan
2016-12-26 11:20 ` [PATCH 1/6] UefiCpuPkg/DxeMpInitLib: Support source debugging on " Jeff Fan
2016-12-26 11:20 ` Jeff Fan [this message]
2016-12-26 11:20 ` [PATCH 3/6] UefiCpuPkg/MpInitLib: Move save/restore interrupt to SwitchBSPWorker() Jeff Fan
2016-12-26 11:21 ` [PATCH 4/6] UefiCpuPkg/MpInitLib: Swap local APIC timer interrupt state Jeff Fan
2016-12-26 11:21 ` [PATCH 5/6] UefiCpuPkg/MpInitLib: Disable and restore system timer interrupt Jeff Fan
2016-12-26 11:21 ` [PATCH 6/6] UefiCpuPkg/MpInitLib: Set new AP to idle state after switching BSP Jeff Fan
2016-12-28  7:33 ` [PATCH 0/6] Support source debugging on DXE AP function Tian, Feng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161226112102.25512-3-jeff.fan@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox