From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 16CBA81909 for ; Mon, 26 Dec 2016 03:21:09 -0800 (PST) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga102.jf.intel.com with ESMTP; 26 Dec 2016 03:21:09 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,404,1477983600"; d="scan'208";a="916215816" Received: from jfan12-desk.ccr.corp.intel.com ([10.239.9.5]) by orsmga003.jf.intel.com with ESMTP; 26 Dec 2016 03:21:07 -0800 From: Jeff Fan To: edk2-devel@lists.01.org Cc: Feng Tian , Kinney, Michael D , Ruiyu Ni Date: Mon, 26 Dec 2016 19:20:58 +0800 Message-Id: <20161226112102.25512-3-jeff.fan@intel.com> X-Mailer: git-send-email 2.9.3.windows.2 In-Reply-To: <20161226112102.25512-1-jeff.fan@intel.com> References: <20161226112102.25512-1-jeff.fan@intel.com> Subject: [PATCH 2/6] UefiCpuPkg/MpInitLib: Sync BSP's local APIC timer settings to APs X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Dec 2016 11:21:09 -0000 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 Cc: Kinney, Michael D Cc: Ruiyu Ni Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan --- 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