From: "Laszlo Ersek" <lersek@redhat.com>
To: devel@edk2.groups.io, ray.ni@intel.com
Cc: Eric Dong <eric.dong@intel.com>, Rahul Kumar <rahul1.kumar@intel.com>
Subject: Re: [edk2-devel] [PATCH 1/4] UefiCpuPkg: Add MicrocodeLib for loading microcode
Date: Wed, 7 Apr 2021 15:05:21 +0200 [thread overview]
Message-ID: <da6d7e88-6af8-48e2-7770-ef41d9df335a@redhat.com> (raw)
In-Reply-To: <20210402055807.858-2-ray.ni@intel.com>
On 04/02/21 07:58, Ni, Ray wrote:
> Signed-off-by: Ray Ni <ray.ni@intel.com>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> ---
> UefiCpuPkg/Include/Library/MicrocodeLib.h | 120 +++++++
> .../Library/MicrocodeLib/MicrocodeLib.c | 322 ++++++++++++++++++
> .../Library/MicrocodeLib/MicrocodeLib.inf | 32 ++
> UefiCpuPkg/UefiCpuPkg.dec | 5 +-
> UefiCpuPkg/UefiCpuPkg.dsc | 1 +
> 5 files changed, 479 insertions(+), 1 deletion(-)
> create mode 100644 UefiCpuPkg/Include/Library/MicrocodeLib.h
> create mode 100644 UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.c
> create mode 100644 UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf
With the BZ ref added:
Acked-by: Laszlo Ersek <lersek@redhat.com>
Thanks
Laszlo
> diff --git a/UefiCpuPkg/Include/Library/MicrocodeLib.h b/UefiCpuPkg/Include/Library/MicrocodeLib.h
> new file mode 100644
> index 0000000000..2570c43cce
> --- /dev/null
> +++ b/UefiCpuPkg/Include/Library/MicrocodeLib.h
> @@ -0,0 +1,120 @@
> +/** @file
> + Public include file for Microcode library.
> +
> + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __MICROCODE_LIB_H__
> +#define __MICROCODE_LIB_H__
> +
> +#include <Register/Intel/Microcode.h>
> +#include <Ppi/ShadowMicrocode.h>
> +
> +/**
> + Get microcode update signature of currently loaded microcode update.
> +
> + @return Microcode signature.
> +**/
> +UINT32
> +EFIAPI
> +GetProcessorMicrocodeSignature (
> + VOID
> + );
> +
> +/**
> + Get the processor signature and platform ID for current processor.
> +
> + @param MicrocodeCpuId Return the processor signature and platform ID.
> +**/
> +VOID
> +EFIAPI
> +GetProcessorMicrocodeCpuId (
> + EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId
> + );
> +
> +/**
> + Return the total size of the microcode entry.
> +
> + Logic follows pseudo code in SDM as below:
> +
> + N = 512
> + If (Update.DataSize != 00000000H)
> + N = Update.TotalSize / 4
> +
> + If Microcode is NULL, then ASSERT.
> +
> + @param Microcode Pointer to the microcode entry.
> +
> + @return The microcode total size.
> +**/
> +UINT32
> +EFIAPI
> +GetMicrocodeLength (
> + IN CPU_MICROCODE_HEADER *Microcode
> + );
> +
> +/**
> + Load the microcode to the processor.
> +
> + If Microcode is NULL, then ASSERT.
> +
> + @param Microcode Pointer to the microcode entry.
> +**/
> +VOID
> +EFIAPI
> +LoadMicrocode (
> + IN CPU_MICROCODE_HEADER *Microcode
> + );
> +
> +/**
> + Detect whether specified processor can find matching microcode patch and load it.
> +
> + Microcode format is as below:
> + +----------------------------------------+-------------------------------------------------+
> + | CPU_MICROCODE_HEADER | |
> + +----------------------------------------+ V
> + | Update Data | CPU_MICROCODE_HEADER.Checksum
> + +----------------------------------------+-------+ ^
> + | CPU_MICROCODE_EXTENDED_TABLE_HEADER | | |
> + +----------------------------------------+ V |
> + | CPU_MICROCODE_EXTENDED_TABLE[0] | CPU_MICROCODE_EXTENDED_TABLE_HEADER.Checksum |
> + | CPU_MICROCODE_EXTENDED_TABLE[1] | ^ |
> + | ... | | |
> + +----------------------------------------+-------+-----------------------------------------+
> +
> + There may by multiple CPU_MICROCODE_EXTENDED_TABLE in this format.
> + The count of CPU_MICROCODE_EXTENDED_TABLE is indicated by ExtendedSignatureCount
> + of CPU_MICROCODE_EXTENDED_TABLE_HEADER structure.
> +
> + If Microcode is NULL, then ASSERT.
> +
> + @param Microcode Pointer to a microcode entry.
> + @param MicrocodeLength The total length of the microcode entry.
> + @param MinimumRevision The microcode whose revision <= MinimumRevision is treated as invalid.
> + Caller can supply value get from GetProcessorMicrocodeSignature() to check
> + whether the microcode is newer than loaded one.
> + Caller can supply 0 to treat any revision (except 0) microcode as valid.
> + @param MicrocodeCpuIds Pointer to an array of processor signature and platform ID that represents
> + a set of processors.
> + Caller can supply zero-element array to skip the processor signature and
> + platform ID check.
> + @param MicrocodeCpuIdCount The number of elements in MicrocodeCpuIds.
> + @param VerifyChecksum FALSE to skip all the checksum verifications.
> +
> + @retval TRUE The microcode is valid.
> + @retval FALSE The microcode is invalid.
> +**/
> +BOOLEAN
> +EFIAPI
> +IsValidMicrocode (
> + IN CPU_MICROCODE_HEADER *Microcode,
> + IN UINTN MicrocodeLength,
> + IN UINT32 MinimumRevision,
> + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds,
> + IN UINTN MicrocodeCpuIdCount,
> + IN BOOLEAN VerifyChecksum
> + );
> +
> +#endif
> \ No newline at end of file
> diff --git a/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.c b/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.c
> new file mode 100644
> index 0000000000..03a43fdae7
> --- /dev/null
> +++ b/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.c
> @@ -0,0 +1,322 @@
> +/** @file
> + Implementation of MicrocodeLib.
> +
> + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi/UefiBaseType.h>
> +#include <Register/Intel/Cpuid.h>
> +#include <Register/Intel/ArchitecturalMsr.h>
> +#include <Register/Intel/Microcode.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Ppi/ShadowMicrocode.h>
> +
> +/**
> + Get microcode update signature of currently loaded microcode update.
> +
> + @return Microcode signature.
> +**/
> +UINT32
> +EFIAPI
> +GetProcessorMicrocodeSignature (
> + VOID
> + )
> +{
> + MSR_IA32_BIOS_SIGN_ID_REGISTER BiosSignIdMsr;
> +
> + AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
> + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
> + BiosSignIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID);
> + return BiosSignIdMsr.Bits.MicrocodeUpdateSignature;
> +}
> +
> +/**
> + Get the processor signature and platform ID for current processor.
> +
> + @param MicrocodeCpuId Return the processor signature and platform ID.
> +**/
> +VOID
> +EFIAPI
> +GetProcessorMicrocodeCpuId (
> + EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId
> + )
> +{
> + MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr;
> +
> + ASSERT (MicrocodeCpuId != NULL);
> +
> + PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);
> + MicrocodeCpuId->PlatformId = (UINT8) PlatformIdMsr.Bits.PlatformId;
> + AsmCpuid (CPUID_VERSION_INFO, &MicrocodeCpuId->ProcessorSignature, NULL, NULL, NULL);
> +}
> +
> +/**
> + Return the total size of the microcode entry.
> +
> + Logic follows pseudo code in SDM as below:
> +
> + N = 512
> + If (Update.DataSize != 00000000H)
> + N = Update.TotalSize / 4
> +
> + If Microcode is NULL, then ASSERT.
> +
> + @param Microcode Pointer to the microcode entry.
> +
> + @return The microcode total size.
> +**/
> +UINT32
> +EFIAPI
> +GetMicrocodeLength (
> + IN CPU_MICROCODE_HEADER *Microcode
> + )
> +{
> + UINT32 TotalSize;
> +
> + ASSERT (Microcode != NULL);
> +
> + TotalSize = 2048;
> + if (Microcode->DataSize != 0) {
> + TotalSize = Microcode->TotalSize;
> + }
> + return TotalSize;
> +}
> +
> +/**
> + Load the microcode to the processor.
> +
> + If Microcode is NULL, then ASSERT.
> +
> + @param Microcode Pointer to the microcode entry.
> +**/
> +VOID
> +EFIAPI
> +LoadMicrocode (
> + IN CPU_MICROCODE_HEADER *Microcode
> + )
> +{
> + ASSERT (Microcode != NULL);
> +
> + AsmWriteMsr64 (MSR_IA32_BIOS_UPDT_TRIG, (UINT64) (UINTN) (Microcode + 1));
> +}
> +
> +/**
> + Determine if a microcode patch matchs the specific processor signature and flag.
> +
> + @param[in] ProcessorSignature The processor signature field value in a
> + microcode patch.
> + @param[in] ProcessorFlags The processor flags field value in a
> + microcode patch.
> + @param[in] MicrocodeCpuId A pointer to an array of EDKII_PEI_MICROCODE_CPU_ID
> + structures.
> + @param[in] MicrocodeCpuIdCount Number of elements in MicrocodeCpuId array.
> +
> + @retval TRUE The specified microcode patch matches to one of the MicrocodeCpuId.
> + @retval FALSE The specified microcode patch doesn't match to any of the MicrocodeCpuId.
> +**/
> +BOOLEAN
> +IsProcessorMatchedMicrocode (
> + IN UINT32 ProcessorSignature,
> + IN UINT32 ProcessorFlags,
> + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId,
> + IN UINTN MicrocodeCpuIdCount
> + )
> +{
> + UINTN Index;
> +
> + if (MicrocodeCpuIdCount == 0) {
> + return TRUE;
> + }
> +
> + for (Index = 0; Index < MicrocodeCpuIdCount; Index++) {
> + if ((ProcessorSignature == MicrocodeCpuId[Index].ProcessorSignature) &&
> + (ProcessorFlags & (1 << MicrocodeCpuId[Index].PlatformId)) != 0) {
> + return TRUE;
> + }
> + }
> +
> + return FALSE;
> +}
> +
> +/**
> + Detect whether specified processor can find matching microcode patch and load it.
> +
> + Microcode format is as below:
> + +----------------------------------------+-------------------------------------------------+
> + | CPU_MICROCODE_HEADER | |
> + +----------------------------------------+ V
> + | Update Data | CPU_MICROCODE_HEADER.Checksum
> + +----------------------------------------+-------+ ^
> + | CPU_MICROCODE_EXTENDED_TABLE_HEADER | | |
> + +----------------------------------------+ V |
> + | CPU_MICROCODE_EXTENDED_TABLE[0] | CPU_MICROCODE_EXTENDED_TABLE_HEADER.Checksum |
> + | CPU_MICROCODE_EXTENDED_TABLE[1] | ^ |
> + | ... | | |
> + +----------------------------------------+-------+-----------------------------------------+
> +
> + There may by multiple CPU_MICROCODE_EXTENDED_TABLE in this format.
> + The count of CPU_MICROCODE_EXTENDED_TABLE is indicated by ExtendedSignatureCount
> + of CPU_MICROCODE_EXTENDED_TABLE_HEADER structure.
> +
> + If Microcode is NULL, then ASSERT.
> +
> + @param Microcode Pointer to a microcode entry.
> + @param MicrocodeLength The total length of the microcode entry.
> + @param MinimumRevision The microcode whose revision <= MinimumRevision is treated as invalid.
> + Caller can supply value get from GetProcessorMicrocodeSignature() to check
> + whether the microcode is newer than loaded one.
> + Caller can supply 0 to treat any revision (except 0) microcode as valid.
> + @param MicrocodeCpuIds Pointer to an array of processor signature and platform ID that represents
> + a set of processors.
> + Caller can supply zero-element array to skip the processor signature and
> + platform ID check.
> + @param MicrocodeCpuIdCount The number of elements in MicrocodeCpuIds.
> + @param VerifyChecksum FALSE to skip all the checksum verifications.
> +
> + @retval TRUE The microcode is valid.
> + @retval FALSE The microcode is invalid.
> +**/
> +BOOLEAN
> +EFIAPI
> +IsValidMicrocode (
> + IN CPU_MICROCODE_HEADER *Microcode,
> + IN UINTN MicrocodeLength,
> + IN UINT32 MinimumRevision,
> + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds,
> + IN UINTN MicrocodeCpuIdCount,
> + IN BOOLEAN VerifyChecksum
> + )
> +{
> + UINTN Index;
> + UINT32 DataSize;
> + UINT32 TotalSize;
> + CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
> + CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
> + UINT32 ExtendedTableLength;
> + UINT32 Sum32;
> + BOOLEAN Match;
> +
> + ASSERT (Microcode != NULL);
> +
> + //
> + // It's invalid when:
> + // the input microcode buffer is so small that even cannot contain the header.
> + // the input microcode buffer is so large that exceeds MAX_ADDRESS.
> + //
> + if ((MicrocodeLength < sizeof (CPU_MICROCODE_HEADER)) || (MicrocodeLength > (MAX_ADDRESS - (UINTN) Microcode))) {
> + return FALSE;
> + }
> +
> + //
> + // Per SDM, HeaderVersion and LoaderRevision should both be 1.
> + //
> + if ((Microcode->HeaderVersion != 1) || (Microcode->LoaderRevision != 1)) {
> + return FALSE;
> + }
> +
> + //
> + // The microcode revision should be larger than the minimum revision.
> + //
> + if (Microcode->UpdateRevision <= MinimumRevision) {
> + return FALSE;
> + }
> +
> + DataSize = Microcode->DataSize;
> + if (DataSize == 0) {
> + DataSize = 2000;
> + }
> +
> + //
> + // Per SDM, DataSize should be multiple of DWORDs.
> + //
> + if ((DataSize % 4) != 0) {
> + return FALSE;
> + }
> +
> + TotalSize = GetMicrocodeLength (Microcode);
> +
> + //
> + // Check whether the whole microcode is within the buffer.
> + // TotalSize should be multiple of 1024.
> + //
> + if (((TotalSize % SIZE_1KB) != 0) || (TotalSize > MicrocodeLength)) {
> + return FALSE;
> + }
> +
> + //
> + // The summation of all DWORDs in microcode should be zero.
> + //
> + if (VerifyChecksum && (CalculateSum32 ((UINT32 *) Microcode, TotalSize) != 0)) {
> + return FALSE;
> + }
> +
> + Sum32 = Microcode->ProcessorSignature.Uint32 + Microcode->ProcessorFlags + Microcode->Checksum;
> +
> + //
> + // Check the processor signature and platform ID in the primary header.
> + //
> + Match = IsProcessorMatchedMicrocode (
> + Microcode->ProcessorSignature.Uint32,
> + Microcode->ProcessorFlags,
> + MicrocodeCpuIds,
> + MicrocodeCpuIdCount
> + );
> + if (Match) {
> + return TRUE;
> + }
> +
> + ExtendedTableLength = TotalSize - (DataSize + sizeof (CPU_MICROCODE_HEADER));
> + if ((ExtendedTableLength < sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER)) || ((ExtendedTableLength % 4) != 0)) {
> + return FALSE;
> + }
> + //
> + // Extended Table exist, check if the CPU in support list
> + //
> + ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINTN) (Microcode + 1) + DataSize);
> + if (ExtendedTableHeader->ExtendedSignatureCount > MAX_UINT32 / sizeof (CPU_MICROCODE_EXTENDED_TABLE)) {
> + return FALSE;
> + }
> + if (ExtendedTableHeader->ExtendedSignatureCount * sizeof (CPU_MICROCODE_EXTENDED_TABLE)
> + > ExtendedTableLength - sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER)) {
> + return FALSE;
> + }
> + //
> + // Check the extended table checksum
> + //
> + if (VerifyChecksum && (CalculateSum32 ((UINT32 *) ExtendedTableHeader, ExtendedTableLength) != 0)) {
> + return FALSE;
> + }
> +
> + ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1);
> + for (Index = 0; Index < ExtendedTableHeader->ExtendedSignatureCount; Index ++) {
> + if (VerifyChecksum &&
> + (ExtendedTable[Index].ProcessorSignature.Uint32 + ExtendedTable[Index].ProcessorFlag
> + + ExtendedTable[Index].Checksum != Sum32)) {
> + //
> + // The extended table entry is valid when the summation of Processor Signature, Processor Flags
> + // and Checksum equal to the coresponding summation from primary header. Because:
> + // CalculateSum32 (Header + Update Binary) == 0
> + // CalculateSum32 (Header + Update Binary)
> + // - (Header.ProcessorSignature + Header.ProcessorFlag + Header.Checksum)
> + // + (Extended.ProcessorSignature + Extended.ProcessorFlag + Extended.Checksum) == 0
> + // So,
> + // (Header.ProcessorSignature + Header.ProcessorFlag + Header.Checksum)
> + // == (Extended.ProcessorSignature + Extended.ProcessorFlag + Extended.Checksum)
> + //
> + continue;
> + }
> + Match = IsProcessorMatchedMicrocode (
> + ExtendedTable[Index].ProcessorSignature.Uint32,
> + ExtendedTable[Index].ProcessorFlag,
> + MicrocodeCpuIds,
> + MicrocodeCpuIdCount
> + );
> + if (Match) {
> + return TRUE;
> + }
> + }
> + return FALSE;
> +}
> diff --git a/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf b/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf
> new file mode 100644
> index 0000000000..c6f8f52e95
> --- /dev/null
> +++ b/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf
> @@ -0,0 +1,32 @@
> +## @file
> +# Library for microcode verification and load.
> +#
> +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010006
> + BASE_NAME = MicrocodeLib
> + FILE_GUID = EB8C72BC-8A48-4F80-996B-E52F68416D57
> + MODULE_TYPE = BASE
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = MicrocodeLib
> +
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[Sources.common]
> + MicrocodeLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
> index a639ce5412..62acb291f3 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dec
> +++ b/UefiCpuPkg/UefiCpuPkg.dec
> @@ -1,7 +1,7 @@
> ## @file UefiCpuPkg.dec
> # This Package provides UEFI compatible CPU modules and libraries.
> #
> -# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
> #
> # SPDX-License-Identifier: BSD-2-Clause-Patent
> #
> @@ -59,6 +59,9 @@ [LibraryClasses.IA32, LibraryClasses.X64]
> ## @libraryclass Provides function to get CPU cache information.
> CpuCacheInfoLib|Include/Library/CpuCacheInfoLib.h
>
> + ## @libraryclass Provides function for loading microcode.
> + MicrocodeLib|Include/Library/MicrocodeLib.h
> +
> [Guids]
> gUefiCpuPkgTokenSpaceGuid = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }}
> gMsegSmramGuid = { 0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }}
> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
> index 98c4c53465..b932cf63ec 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dsc
> +++ b/UefiCpuPkg/UefiCpuPkg.dsc
> @@ -60,6 +60,7 @@ [LibraryClasses]
> PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
> VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> + MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf
>
> [LibraryClasses.common.SEC]
> PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
>
next prev parent reply other threads:[~2021-04-07 13:05 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-02 5:58 [PATCH 0/4] UefiCpuPkg: Add MicrocodeLib for loading microcode Ni, Ray
2021-04-02 5:58 ` [PATCH 1/4] " Ni, Ray
2021-04-07 13:05 ` Laszlo Ersek [this message]
2021-04-08 2:19 ` Dong, Eric
2021-04-02 5:58 ` [PATCH 2/4] OvmfPkg: Add MicrocodeLib in DSC files Ni, Ray
2021-04-07 13:05 ` [edk2-devel] " Laszlo Ersek
2021-04-02 5:58 ` [PATCH 3/4] UefiPayloadPkg/UefiPayloadPkg.dsc: Consume MicrocodeLib Ni, Ray
2021-04-08 1:56 ` Ma, Maurice
2021-04-02 5:58 ` [PATCH 4/4] UefiCpuPkg/MpInitLib: Consume MicrocodeLib to remove duplicated code Ni, Ray
2021-04-07 13:08 ` [edk2-devel] " Laszlo Ersek
2021-04-08 14:24 ` Dong, Eric
2021-04-06 12:03 ` [edk2-devel] [PATCH 0/4] UefiCpuPkg: Add MicrocodeLib for loading microcode Laszlo Ersek
2021-04-07 2:43 ` Ni, Ray
2021-04-07 13:04 ` Laszlo Ersek
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=da6d7e88-6af8-48e2-7770-ef41d9df335a@redhat.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