From nobody Tue Feb 10 17:30:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+106464+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+106464+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1687942154; cv=none; d=zohomail.com; s=zohoarc; b=lykIQHbdHzVxMPtAjh19WLb2ojiH7VayWGfZWPNZOxWX8/ebIdfCL2L/UmZz++z/zvPRSugjTeVk9aVctxkDzwyLHh8ZGh1Hj0qIiDtniIQm3imXViKiFQQaBdbIonQq7ZAQGJuTqH6MEjoFVxEnfQXLZj3tdH7OTGgXfOvVx8w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1687942154; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=Dm6eWPSGq625Gba3/WpnuVJHOZ+uOnEeWzXDfmt0HOk=; b=igKcyrJsFU0v3mJkHXqvAtGMO97SslW18ZMjjSZfT+cRSqk0jWw5I90hqCUvhghIC/bTHEn66VM5/6NHy62cw0fcyZ4Kc07yQykXuZ68wol3Tym63WaK1o9vOjAUOIA5dJeM2SsjtWOS5Uv7LX2qzNeqo30uLkBDC54OuaWgrZE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+106464+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1687942154976684.8397704477256; Wed, 28 Jun 2023 01:49:14 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id syfTYY1788612xwdphFcH3Ck; Wed, 28 Jun 2023 01:49:14 -0700 X-Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mx.groups.io with SMTP id smtpd.web11.11788.1687942151408549511 for ; Wed, 28 Jun 2023 01:49:12 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10754"; a="341373601" X-IronPort-AV: E=Sophos;i="6.01,165,1684825200"; d="scan'208";a="341373601" X-Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jun 2023 01:48:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10754"; a="890964619" X-IronPort-AV: E=Sophos;i="6.01,165,1684825200"; d="scan'208";a="890964619" X-Received: from shwdeopenlab705.ccr.corp.intel.com ([10.239.55.55]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jun 2023 01:48:08 -0700 From: "Yuanhao Xie" To: devel@edk2.groups.io Cc: Gerd Hoffmann , Eric Dong , Ray Ni , Rahul Kumar , Tom Lendacky , Yuanhao Xie Subject: [edk2-devel] [Patch V4 5/5] UefiCpuPkg: Eliminate the second INIT-SIPI-SIPI sequence. Date: Wed, 28 Jun 2023 16:47:24 +0800 Message-Id: <20230628084724.57574-6-yuanhao.xie@intel.com> In-Reply-To: <20230628084724.57574-1-yuanhao.xie@intel.com> References: <20230628084724.57574-1-yuanhao.xie@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,yuanhao.xie@intel.com X-Gm-Message-State: aOEMcbVctBKYFMvYK6oaguR2x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1687942154; bh=H0sNJK4qUskJFmXn9FQO9YsrXc+RmkuzeHFQf0nHxUE=; h=Cc:Date:From:Reply-To:Subject:To; b=BKAZMPy+DvYHAW6OaszReQcEpomW0Dg41zRIPnO2lq0NpZPWvXUFCLrL5BurBvu85Ls zKWEoi+oRDKwh3mUGBKS2U27ot2+rLlPwIjX8t4E6GHTFeIoFqGqFqM9uDUc8jKHedPnM G6rpeWlLsT0QEDbd8DpCkBqbsjyZouThL8Q= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1687942155475100017 Content-Type: text/plain; charset="utf-8" When both the PEI and DXE phases operate in the same execution mode(32-bit/64-bit), the BSP send a special start-up signal during the DXE phase to awaken the Application APs. To eliminate the need for the INIT-SIPI-SIPI sequence at the beginning of the DXE phase, the BSP call the SwitchApContext function to trigger the special start-up signal. By writing the specified StartupSignalValue to the designated StartupSignalAddress, the BSP wakes up the APs from mwait mode. Once the APs receive the MP_HAND_OFF_SIGNAL value, they are awakened and proceed to execute the SwitchContextPerAp procedure. They enter another while loop, transitioning their context from the PEI phase to the DXE phase. The original state transitions for an AP during the procedure are as follows: Idle ----> Ready ----> Busy ----> Idle [BSP] [AP] [AP] Instead of init-sipi-sipi sequence, we make use of a start-up signal to awaken the APs and transfer their context from PEI to DXE. Consequently, APs, rather than the BSP, to set their state to CpuStateReady. Cc: Gerd Hoffmann Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Cc: Tom Lendacky Signed-off-by: Yuanhao Xie --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 138 +++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++-- UefiCpuPkg/Library/MpInitLib/MpLib.h | 9 +++++++++ 2 files changed, 145 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpIn= itLib/MpLib.c index f904751b0d..737e03ffc5 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -680,7 +680,7 @@ PlaceAPInMwaitLoopOrRunLoop ( // Place AP in MWAIT-loop // AsmMonitor ((UINTN)ApStartupSignalBuffer, 0, 0); - if (*ApStartupSignalBuffer !=3D WAKEUP_AP_SIGNAL) { + if ((*ApStartupSignalBuffer !=3D WAKEUP_AP_SIGNAL) && (*ApStartupSig= nalBuffer !=3D MP_HAND_OFF_SIGNAL)) { // // Check AP start-up signal again. // If AP start-up signal is not set, place AP into @@ -701,7 +701,7 @@ PlaceAPInMwaitLoopOrRunLoop ( // If AP start-up signal is written, AP is waken up // otherwise place AP in loop again // - if (*ApStartupSignalBuffer =3D=3D WAKEUP_AP_SIGNAL) { + if ((*ApStartupSignalBuffer =3D=3D WAKEUP_AP_SIGNAL) || (*ApStartupSig= nalBuffer =3D=3D MP_HAND_OFF_SIGNAL)) { break; } } @@ -729,6 +729,7 @@ ApWakeupFunction ( UINT64 ApTopOfStack; UINTN CurrentApicMode; AP_STACK_DATA *ApStackData; + UINT32 OriginalValue; =20 // // AP's local APIC settings will be lost after received INIT IPI @@ -769,6 +770,15 @@ ApWakeupFunction ( // Clear AP start-up signal when AP waken up // ApStartupSignalBuffer =3D CpuMpData->CpuData[ProcessorNumber].Startu= pApSignal; + OriginalValue =3D InterlockedCompareExchange32 ( + (UINT32 *)ApStartupSignalBuffer, + MP_HAND_OFF_SIGNAL, + 0 + ); + if (OriginalValue =3D=3D MP_HAND_OFF_SIGNAL) { + SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateReady); + } + InterlockedCompareExchange32 ( (UINT32 *)ApStartupSignalBuffer, WAKEUP_AP_SIGNAL, @@ -887,6 +897,32 @@ ApWakeupFunction ( } } =20 +/** + This function serves as the entry point for APs when + they are awakened by the stores in the memory address + indicated by the MP_HANDOFF_INFO structure. + + @param[in] CpuMpData Pointer to PEI CPU MP Data +**/ +VOID +EFIAPI +DxeApEntryPoint ( + CPU_MP_DATA *CpuMpData + ) +{ + UINTN ProcessorNumber; + + GetProcessorNumber (CpuMpData, &ProcessorNumber); + InterlockedIncrement ((UINT32 *)&CpuMpData->FinishedCount); + RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALS= E); + PlaceAPInMwaitLoopOrRunLoop ( + CpuMpData->ApLoopMode, + CpuMpData->CpuData[ProcessorNumber].StartupApSignal, + CpuMpData->ApTargetCState + ); + ApWakeupFunction (CpuMpData, ProcessorNumber); +} + /** Wait for AP wakeup and write AP start-up signal till AP is waken up. =20 @@ -1457,6 +1493,32 @@ CalculateTimeout ( } } =20 +/** + Switch Context for each AP. + +**/ +VOID +EFIAPI +SwitchContextPerAp ( + VOID + ) +{ + UINTN ProcessorNumber; + CPU_MP_DATA *CpuMpData; + CPU_INFO_IN_HOB *CpuInfoInHob; + + CpuMpData =3D GetCpuMpData (); + CpuInfoInHob =3D (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob; + GetProcessorNumber (CpuMpData, &ProcessorNumber); + + SwitchStack ( + (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeApEntryPoint, + (VOID *)(UINTN)CpuMpData, + NULL, + (VOID *)((UINTN)CpuInfoInHob[ProcessorNumber].ApTopOfStack) + ); +} + /** Checks whether timeout expires. =20 @@ -1840,6 +1902,44 @@ GetBspNumber ( return BspNumber; } =20 +/** + This function is intended to be invoked by the BSP in order + to wake up the AP. The BSP accomplishes this by triggering a + start-up signal, which in turn causes any APs that are + currently in a loop on the PEI-prepared memory to awaken and + begin running the procedure called SwitchContextPerAp. + This procedure allows the AP to switch to another section of + memory and continue its loop there. + + @param[in] MpHandOff Pointer to MP hand-off data structure. +**/ +VOID +SwitchApContext ( + IN MP_HAND_OFF *MpHandOff + ) +{ + UINTN Index; + UINT32 BspNumber; + + BspNumber =3D GetBspNumber (MpHandOff); + + for (Index =3D 0; Index < MpHandOff->CpuCount; Index++) { + if (Index !=3D BspNumber) { + *(UINTN *)(UINTN)MpHandOff->Info[Index].StartupProcedureAddress =3D = (UINTN)SwitchContextPerAp; + *(UINT32 *)(UINTN)MpHandOff->Info[Index].StartupSignalAddress =3D = MpHandOff->StartupSignalValue; + } + } + + // + // Wait all APs waken up if this is not the 1st broadcast of SIPI + // + for (Index =3D 0; Index < MpHandOff->CpuCount; Index++) { + if (Index !=3D BspNumber) { + WaitApWakeup ((UINT32 *)(UINTN)(MpHandOff->Info[Index].StartupSignal= Address)); + } + } +} + /** Get pointer to MP_HAND_OFF GUIDed HOB. =20 @@ -2073,6 +2173,40 @@ MpInitLibInitialize ( CpuInfoInHob[Index].ApicId =3D MpHandOff->Info[Index].Apic= Id; CpuInfoInHob[Index].Health =3D MpHandOff->Info[Index].Heal= th; } + + DEBUG ((DEBUG_INFO, "MpHandOff->WaitLoopExecutionMode: %04d, sizeof (V= OID *): %04d\n", MpHandOff->WaitLoopExecutionMode, sizeof (VOID *))); + if (MpHandOff->WaitLoopExecutionMode =3D=3D sizeof (VOID *)) { + ASSERT (CpuMpData->ApLoopMode !=3D ApInHltLoop); + + CpuMpData->FinishedCount =3D 0; + CpuMpData->InitFlag =3D ApInitDone; + SaveCpuMpData (CpuMpData); + // + // In scenarios where both the PEI and DXE phases run in the same + // execution mode (32bit or 64bit), the BSP triggers + // a start-up signal during the DXE phase to wake up the APs. This c= auses any + // APs that are currently in a loop on the memory prepared during th= e PEI + // phase to awaken and run the SwitchContextPerAp procedure. This pr= ocedure + // enables the APs to switch to a different memory section and conti= nue their + // looping process there. + // + SwitchApContext (MpHandOff); + ASSERT (CpuMpData->FinishedCount =3D=3D (CpuMpData->CpuCount - 1)); + + // + // Set Apstate as Idle, otherwise Aps cannot be waken-up again. + // If any enabled AP is not idle, return EFI_NOT_READY during waken-= up. + // + for (Index =3D 0; Index < CpuMpData->CpuCount; Index++) { + SetApState (&CpuMpData->CpuData[Index], CpuStateIdle); + } + + // + // Initialize global data for MP support + // + InitMpGlobalData (CpuMpData); + return EFI_SUCCESS; + } } =20 if (!GetMicrocodePatchInfoFromHob ( diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpIn= itLib/MpLib.h index a7f36d323b..763db4963d 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -474,6 +474,15 @@ GetWakeupBuffer ( IN UINTN WakeupBufferSize ); =20 +/** + Switch Context for each AP. + +**/ +VOID +SwitchApContext ( + IN MP_HAND_OFF *MpHandOff + ); + /** Get available EfiBootServicesCode memory below 4GB by specified size. =20 --=20 2.36.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#106464): https://edk2.groups.io/g/devel/message/106464 Mute This Topic: https://groups.io/mt/99826559/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-