From nobody Sat Feb 7 06:35:11 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+52583+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+52583+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1577431958; cv=none; d=zohomail.com; s=zohoarc; b=KumJMqA3XHsXtTdMmXgerN7foWEo8L9e3xywOnb6xLjZcRNjAXsSiAFj8zXA/KOlCXclGmOhX9y/sCcC/D0IIUgE78A2k5IjzN6JmLmmGSiMOyJXr90chK93gGrb2y0jPGEAC5PiS4x6tm09KjEE6posCIp4XEw1UzeF2ahy2QE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577431958; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=Mj2HBWLzv+PH+ELf/zjJvUmy+dtFB6aBHN8HcaP9gnY=; b=iJE2K51Opmcmg7Gj098Wxn0NkczOCuXKa+sUExVC8/LgDKZKc4RaQKzGoTn2dWGyiDUrNw13vSVos7fYnvvgXTILnyx5ZVQH+uu1xmd0N4+im96VzHdJ0EMTrJfTND0g2g3YHm2cHs1Xo9GEkBDB0OK8NsUSxO8hM0WL8Btdjp8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+52583+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1577431958484591.0812990887805; Thu, 26 Dec 2019 23:32:38 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id ZEryYY1788612xIPhCznymn0; Thu, 26 Dec 2019 23:32:37 -0800 X-Received: from mga06.intel.com (mga06.intel.com []) by mx.groups.io with SMTP id smtpd.web12.29151.1577431953513368188 for ; Thu, 26 Dec 2019 23:32:36 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Dec 2019 23:32:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,362,1571727600"; d="scan'208";a="220445496" X-Received: from shwdeopenpsi014.ccr.corp.intel.com ([10.239.9.8]) by orsmga003.jf.intel.com with ESMTP; 26 Dec 2019 23:32:34 -0800 From: "Wu, Hao A" To: devel@edk2.groups.io Cc: Hao A Wu , Eric Dong , Ray Ni , Laszlo Ersek , Star Zeng , Siyuan Fu , Michael D Kinney Subject: [edk2-devel] [PATCH v4 2/6] UefiCpuPkg/MpInitLib: Reduce the size when loading microcode patches Date: Fri, 27 Dec 2019 15:32:25 +0800 Message-Id: <20191227073229.9416-3-hao.a.wu@intel.com> In-Reply-To: <20191227073229.9416-1-hao.a.wu@intel.com> References: <20191227073229.9416-1-hao.a.wu@intel.com> Precedence: Bulk List-Unsubscribe: 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,hao.a.wu@intel.com X-Gm-Message-State: ZI1GvXg8Lzth0C0OGDlIEhmLx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1577431957; bh=wZZleaNzmJF+nPk9H7DIPpwHw1eTWmZ1WuLYnONaSJ8=; h=Cc:Date:From:Reply-To:Subject:To; b=C7qMROWtPi1MvlUK5gG360Sznw6tJ+VWGSB/6qgZSWSDlYbtGQelGIr/05sklF0cmWh k1388yJ3sL8HPRkDrZggovhIv3VYT4E5Qh0G9Wn9ebXCwLH/HbAdU93Wv+7wu3peQVnEC 3k6ndSZOEP36VodW7AeMjofL9VCnoslcwjM= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D2429 This commit will attempt to reduce the copy size when loading the microcode patches data from flash into memory. Such optimization is done by a pre-process of the microcode patch headers (on flash). A microcode patch will be loaded into memory only when the below 3 criteria are met: A. With a microcode patch header (which means the data is not padding data between microcode patches); B. The 'ProcessorSignature' & 'ProcessorFlags' fields in the header match at least one processor within system; C. If the Extended Signature Table exists in a microcode patch, the 'ProcessorSignature' & 'ProcessorFlag' fields in the table entries match at least one processor within system. Criterion B and C will require all the processors to be woken up once to collect their CPUID and Platform ID information. Hence, this commit will move the copy, detect and apply of microcode patch on BSP and APs after all the processors have been woken up. Cc: Eric Dong Cc: Ray Ni Cc: Laszlo Ersek Cc: Star Zeng Cc: Siyuan Fu Cc: Michael D Kinney Signed-off-by: Hao A Wu --- UefiCpuPkg/Library/MpInitLib/MpLib.h | 24 ++ UefiCpuPkg/Library/MpInitLib/Microcode.c | 288 ++++++++++++++++++++ UefiCpuPkg/Library/MpInitLib/MpLib.c | 90 ++---- 3 files changed, 340 insertions(+), 62 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpIn= itLib/MpLib.h index 4440dc2701..56b0df664a 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -44,6 +44,20 @@ #define CPU_SWITCH_STATE_LOADED 2 =20 // +// Default maximum number of entries to store the microcode patches inform= ation +// +#define DEFAULT_MAX_MICROCODE_PATCH_NUM 8 + +// +// Data structure for microcode patch information +// +typedef struct { + UINTN Address; + UINTN Size; + UINTN AlignedSize; +} MICROCODE_PATCH_INFO; + +// // CPU exchange information for switch BSP // typedef struct { @@ -576,6 +590,16 @@ MicrocodeDetect ( ); =20 /** + Load the required microcode patches data into memory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +LoadMicrocodePatch ( + IN OUT CPU_MP_DATA *CpuMpData + ); + +/** Detect whether Mwait-monitor feature is supported. =20 @retval TRUE Mwait-monitor feature is supported. diff --git a/UefiCpuPkg/Library/MpInitLib/Microcode.c b/UefiCpuPkg/Library/= MpInitLib/Microcode.c index 199b1f23ce..62a104742a 100644 --- a/UefiCpuPkg/Library/MpInitLib/Microcode.c +++ b/UefiCpuPkg/Library/MpInitLib/Microcode.c @@ -331,3 +331,291 @@ Done: MicroData [0x%08x], Revision [0x%08x]\n", Eax.Uint32, ProcessorFlag= s, (UINTN) MicrocodeData, LatestRevision)); } } + +/** + Determine if a microcode patch will be loaded into memory. + + @param[in] CpuMpData The pointer to CPU MP Data structure. + @param[in] ProcessorSignature The processor signature field value + supported by a microcode patch. + @param[in] ProcessorFlags The prcessor flags field value support= ed by + a microcode patch. + + @retval TRUE The specified microcode patch will be loaded. + @retval FALSE The specified microcode patch will not be loaded. +**/ +BOOLEAN +IsMicrocodePatchNeedLoad ( + IN CPU_MP_DATA *CpuMpData, + IN UINT32 ProcessorSignature, + IN UINT32 ProcessorFlags + ) +{ + UINTN Index; + CPU_AP_DATA *CpuData; + + for (Index =3D 0; Index < CpuMpData->CpuCount; Index++) { + CpuData =3D &CpuMpData->CpuData[Index]; + if ((ProcessorSignature =3D=3D CpuData->ProcessorSignature) && + (ProcessorFlags & (1 << CpuData->PlatformId)) !=3D 0) { + return TRUE; + } + } + + return FALSE; +} + +/** + Actual worker function that loads the required microcode patches into me= mory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. + @param[in] Patches The pointer to an array of information= on + the microcode patches that will be loa= ded + into memory. + @param[in] PatchCount The number of microcode patches that w= ill + be loaded into memory. + @param[in] TotalLoadSize The total size of all the microcode pa= tches + to be loaded. +**/ +VOID +LoadMicrocodePatchWorker ( + IN OUT CPU_MP_DATA *CpuMpData, + IN MICROCODE_PATCH_INFO *Patches, + IN UINTN PatchCount, + IN UINTN TotalLoadSize + ) +{ + UINTN Index; + VOID *MicrocodePatchInRam; + UINT8 *Walker; + + ASSERT ((Patches !=3D NULL) && (PatchCount !=3D 0)); + + MicrocodePatchInRam =3D AllocatePages (EFI_SIZE_TO_PAGES (TotalLoadSize)= ); + if (MicrocodePatchInRam =3D=3D NULL) { + return; + } + + // + // Load all the required microcode patches into memory + // + for (Walker =3D MicrocodePatchInRam, Index =3D 0; Index < PatchCount; In= dex++) { + CopyMem ( + Walker, + (VOID *) Patches[Index].Address, + Patches[Index].Size + ); + + // + // Zero-fill the padding area + // Please note that AlignedSize will be no less than Size + // + ZeroMem ( + Walker + Patches[Index].Size, + Patches[Index].AlignedSize - Patches[Index].Size + ); + + Walker +=3D Patches[Index].AlignedSize; + } + + // + // Update the microcode patch related fields in CpuMpData + // + CpuMpData->MicrocodePatchAddress =3D (UINTN) MicrocodePatchInRam; + CpuMpData->MicrocodePatchRegionSize =3D TotalLoadSize; + + DEBUG (( + DEBUG_INFO, + "%a: Required microcode patches have been loaded at 0x%lx, with size 0= x%lx.\n", + __FUNCTION__, CpuMpData->MicrocodePatchAddress, CpuMpData->MicrocodePa= tchRegionSize + )); + + return; +} + +/** + Load the required microcode patches data into memory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +LoadMicrocodePatch ( + IN OUT CPU_MP_DATA *CpuMpData + ) +{ + CPU_MICROCODE_HEADER *MicrocodeEntryPoint; + UINTN MicrocodeEnd; + UINTN DataSize; + UINTN TotalSize; + CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader; + UINT32 ExtendedTableCount; + CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable; + MICROCODE_PATCH_INFO *PatchInfoBuffer; + UINTN MaxPatchNumber; + UINTN PatchCount; + UINTN TotalLoadSize; + UINTN Index; + BOOLEAN NeedLoad; + + // + // Initialize the microcode patch related fields in CpuMpData as the val= ues + // specified by the PCD pair. If the microcode patches are loaded into m= emory, + // these fields will be updated. + // + CpuMpData->MicrocodePatchAddress =3D PcdGet64 (PcdCpuMicrocodePatchAd= dress); + CpuMpData->MicrocodePatchRegionSize =3D PcdGet64 (PcdCpuMicrocodePatchRe= gionSize); + + MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) (UINTN) CpuMpData->M= icrocodePatchAddress; + MicrocodeEnd =3D (UINTN) MicrocodeEntryPoint + + (UINTN) CpuMpData->MicrocodePatchRegionSize; + if ((MicrocodeEntryPoint =3D=3D NULL) || ((UINTN) MicrocodeEntryPoint = =3D=3D MicrocodeEnd)) { + // + // There is no microcode patches + // + return; + } + + PatchCount =3D 0; + MaxPatchNumber =3D DEFAULT_MAX_MICROCODE_PATCH_NUM; + TotalLoadSize =3D 0; + PatchInfoBuffer =3D AllocatePool (MaxPatchNumber * sizeof (MICROCODE_PAT= CH_INFO)); + if (PatchInfoBuffer =3D=3D NULL) { + return; + } + + // + // Process the header of each microcode patch within the region. + // The purpose is to decide which microcode patch(es) will be loaded int= o memory. + // + do { + if (MicrocodeEntryPoint->HeaderVersion !=3D 0x1) { + // + // Padding data between the microcode patches, skip 1KB to check nex= t entry. + // + MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) (((UINTN) Microcode= EntryPoint) + SIZE_1KB); + continue; + } + + DataSize =3D MicrocodeEntryPoint->DataSize; + TotalSize =3D (DataSize =3D=3D 0) ? 2048 : MicrocodeEntryPoint->TotalS= ize; + if ( (UINTN)MicrocodeEntryPoint > (MAX_ADDRESS - TotalSize) || + ((UINTN)MicrocodeEntryPoint + TotalSize) > MicrocodeEnd || + (DataSize & 0x3) !=3D 0 || + (TotalSize & (SIZE_1KB - 1)) !=3D 0 || + TotalSize < DataSize + ) { + // + // Not a valid microcode header, skip 1KB to check next entry. + // + MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) (((UINTN) Microcode= EntryPoint) + SIZE_1KB); + continue; + } + + // + // Check the 'ProcessorSignature' and 'ProcessorFlags' of the microcode + // patch header with the CPUID and PlatformID of the processors within + // system to decide if it will be copied into memory + // + NeedLoad =3D IsMicrocodePatchNeedLoad ( + CpuMpData, + MicrocodeEntryPoint->ProcessorSignature.Uint32, + MicrocodeEntryPoint->ProcessorFlags + ); + + // + // If the Extended Signature Table exists, check if the processor is i= n the + // support list + // + if ((!NeedLoad) && (DataSize !=3D 0) && + (TotalSize - DataSize > sizeof (CPU_MICROCODE_HEADER) + + sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADE= R))) { + ExtendedTableHeader =3D (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UI= NT8 *) (MicrocodeEntryPoint) + + DataSize + sizeof (CPU_MICROCODE_HEADER)); + ExtendedTableCount =3D ExtendedTableHeader->ExtendedSignatureCount; + ExtendedTable =3D (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTa= bleHeader + 1); + + for (Index =3D 0; Index < ExtendedTableCount; Index ++) { + // + // Avoid access content beyond MicrocodeEnd + // + if ((UINTN) ExtendedTable > MicrocodeEnd - sizeof (CPU_MICROCODE_E= XTENDED_TABLE)) { + break; + } + + // + // Check the 'ProcessorSignature' and 'ProcessorFlag' of the Exten= ded + // Signature Table entry with the CPUID and PlatformID of the proc= essors + // within system to decide if it will be copied into memory + // + NeedLoad =3D IsMicrocodePatchNeedLoad ( + CpuMpData, + ExtendedTable->ProcessorSignature.Uint32, + ExtendedTable->ProcessorFlag + ); + if (NeedLoad) { + break; + } + ExtendedTable ++; + } + } + + if (NeedLoad) { + PatchCount++; + if (PatchCount >=3D MaxPatchNumber) { + // + // Current 'PatchInfoBuffer' cannot hold the information, double t= he size + // and allocate a new buffer. + // + if (MaxPatchNumber > MAX_UINTN / 2 / sizeof (MICROCODE_PATCH_INFO)= ) { + // + // Overflow check for MaxPatchNumber + // + goto OnExit; + } + + PatchInfoBuffer =3D ReallocatePool ( + MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO), + 2 * MaxPatchNumber * sizeof (MICROCODE_PATCH_I= NFO), + PatchInfoBuffer + ); + if (PatchInfoBuffer =3D=3D NULL) { + goto OnExit; + } + MaxPatchNumber =3D MaxPatchNumber * 2; + } + + // + // Store the information of this microcode patch + // + if (TotalSize > ALIGN_VALUE (TotalSize, SIZE_1KB) || + ALIGN_VALUE (TotalSize, SIZE_1KB) > MAX_UINTN - TotalLoadSize) { + goto OnExit; + } + PatchInfoBuffer[PatchCount - 1].Address =3D (UINTN) MicrocodeEnt= ryPoint; + PatchInfoBuffer[PatchCount - 1].Size =3D TotalSize; + PatchInfoBuffer[PatchCount - 1].AlignedSize =3D ALIGN_VALUE (TotalSi= ze, SIZE_1KB); + TotalLoadSize +=3D PatchInfoBuffer[PatchCount - 1].AlignedSize; + } + + // + // Process the next microcode patch + // + MicrocodeEntryPoint =3D (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEn= tryPoint) + TotalSize); + } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd)); + + if (PatchCount !=3D 0) { + DEBUG (( + DEBUG_INFO, + "%a: 0x%x microcode patches will be loaded into memory, with size 0x= %x.\n", + __FUNCTION__, PatchCount, TotalLoadSize + )); + + LoadMicrocodePatchWorker (CpuMpData, PatchInfoBuffer, PatchCount, Tota= lLoadSize); + } + +OnExit: + if (PatchInfoBuffer !=3D NULL) { + FreePool (PatchInfoBuffer); + } + return; +} diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpIn= itLib/MpLib.c index d5077e080e..c72bf3c9ee 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -628,10 +628,6 @@ ApWakeupFunction ( ApTopOfStack =3D CpuMpData->Buffer + (ProcessorNumber + 1) * CpuMpD= ata->CpuApStackSize; BistData =3D *(UINT32 *) ((UINTN) ApTopOfStack - sizeof (UINTN)); // - // Do some AP initialize sync - // - ApInitializeSync (CpuMpData); - // // CpuMpData->CpuData[0].VolatileRegisters is initialized based on B= SP environment, // to initialize AP in InitConfig path. // NOTE: IDTR.BASE stored in CpuMpData->CpuData[0].VolatileRegisters= points to a different IDT shared by all APs. @@ -1615,7 +1611,6 @@ MpInitLibInitialize ( UINTN ApResetVectorSize; UINTN BackupBufferAddr; UINTN ApIdtBase; - VOID *MicrocodePatchInRam; =20 OldCpuMpData =3D GetCpuMpDataFromGuidedHob (); if (OldCpuMpData =3D=3D NULL) { @@ -1683,39 +1678,7 @@ MpInitLibInitialize ( CpuMpData->SwitchBspFlag =3D FALSE; CpuMpData->CpuData =3D (CPU_AP_DATA *) (CpuMpData + 1); CpuMpData->CpuInfoInHob =3D (UINT64) (UINTN) (CpuMpData->CpuData + M= axLogicalProcessorNumber); - if (OldCpuMpData =3D=3D NULL) { - CpuMpData->MicrocodePatchRegionSize =3D PcdGet64 (PcdCpuMicrocodePatch= RegionSize); - // - // If platform has more than one CPU, relocate microcode to memory to = reduce - // loading microcode time. - // - MicrocodePatchInRam =3D NULL; - if (MaxLogicalProcessorNumber > 1) { - MicrocodePatchInRam =3D AllocatePages ( - EFI_SIZE_TO_PAGES ( - (UINTN)CpuMpData->MicrocodePatchRegionSize - ) - ); - } - if (MicrocodePatchInRam =3D=3D NULL) { - // - // there is only one processor, or no microcode patch is available, = or - // memory allocation failed - // - CpuMpData->MicrocodePatchAddress =3D PcdGet64 (PcdCpuMicrocodePatchA= ddress); - } else { - // - // there are multiple processors, and a microcode patch is available= , and - // memory allocation succeeded - // - CopyMem ( - MicrocodePatchInRam, - (VOID *)(UINTN)PcdGet64 (PcdCpuMicrocodePatchAddress), - (UINTN)CpuMpData->MicrocodePatchRegionSize - ); - CpuMpData->MicrocodePatchAddress =3D (UINTN)MicrocodePatchInRam; - } - }else { + if (OldCpuMpData !=3D NULL) { CpuMpData->MicrocodePatchRegionSize =3D OldCpuMpData->MicrocodePatchRe= gionSize; CpuMpData->MicrocodePatchAddress =3D OldCpuMpData->MicrocodePatchAd= dress; } @@ -1762,14 +1725,6 @@ MpInitLibInitialize ( (UINT32 *)(MonitorBuffer + MonitorFilterSize * Index); } // - // Load Microcode on BSP - // - MicrocodeDetect (CpuMpData, TRUE); - // - // Store BSP's MTRR setting - // - MtrrGetAllMtrrs (&CpuMpData->MtrrTable); - // // Enable the local APIC for Virtual Wire Mode. // ProgramVirtualWireMode (); @@ -1781,6 +1736,11 @@ MpInitLibInitialize ( // CollectProcessorCount (CpuMpData); } + + // + // Load required microcode patches data into memory + // + LoadMicrocodePatch (CpuMpData); } else { // // APs have been wakeup before, just get the CPU Information @@ -1788,7 +1748,6 @@ MpInitLibInitialize ( // CpuMpData->CpuCount =3D OldCpuMpData->CpuCount; CpuMpData->BspNumber =3D OldCpuMpData->BspNumber; - CpuMpData->InitFlag =3D ApInitReconfig; CpuMpData->CpuInfoInHob =3D OldCpuMpData->CpuInfoInHob; CpuInfoInHob =3D (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; for (Index =3D 0; Index < CpuMpData->CpuCount; Index++) { @@ -1797,21 +1756,28 @@ MpInitLibInitialize ( CpuMpData->CpuData[Index].ApFunction =3D 0; CopyMem (&CpuMpData->CpuData[Index].VolatileRegisters, &VolatileRegi= sters, sizeof (CPU_VOLATILE_REGISTERS)); } - if (MaxLogicalProcessorNumber > 1) { - // - // Wakeup APs to do some AP initialize sync - // - WakeUpAP (CpuMpData, TRUE, 0, ApInitializeSync, CpuMpData, TRUE); - // - // Wait for all APs finished initialization - // - while (CpuMpData->FinishedCount < (CpuMpData->CpuCount - 1)) { - CpuPause (); - } - CpuMpData->InitFlag =3D ApInitDone; - for (Index =3D 0; Index < CpuMpData->CpuCount; Index++) { - SetApState (&CpuMpData->CpuData[Index], CpuStateIdle); - } + } + + // + // Detect and apply Microcode on BSP + // + MicrocodeDetect (CpuMpData, TRUE); + // + // Store BSP's MTRR setting + // + MtrrGetAllMtrrs (&CpuMpData->MtrrTable); + + // + // Wakeup APs to do some AP initialize sync (Microcode & MTRR) + // + if (CpuMpData->CpuCount > 1) { + WakeUpAP (CpuMpData, TRUE, 0, ApInitializeSync, CpuMpData, TRUE); + while (CpuMpData->FinishedCount < (CpuMpData->CpuCount - 1)) { + CpuPause (); + } + + for (Index =3D 0; Index < CpuMpData->CpuCount; Index++) { + SetApState (&CpuMpData->CpuData[Index], CpuStateIdle); } } =20 --=20 2.12.0.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 (#52583): https://edk2.groups.io/g/devel/message/52583 Mute This Topic: https://groups.io/mt/69283205/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-