From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga04.intel.com (mga04.intel.com []) by mx.groups.io with SMTP id smtpd.web09.6160.1622799753888231527 for ; Fri, 04 Jun 2021 02:42:39 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: zhiguang.liu@intel.com) IronPort-SDR: h7bxnpxQqQc5F0MmwFBj/BCEztS+/FHmrHuljCfCSSQs8PMRH/FjsIlgSNDnuESeYA5ttVyuTV PoO7Si06jmmg== X-IronPort-AV: E=McAfee;i="6200,9189,10004"; a="202401934" X-IronPort-AV: E=Sophos;i="5.83,248,1616482800"; d="scan'208";a="202401934" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jun 2021 02:42:39 -0700 IronPort-SDR: Ty8RV9U6OYFdakgzr99FhP83rqj3JgnOiQTurz17G31cINcOnT5ZI0a5Wf32SKErMQoAknn5JV hsOBAw284bzw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,248,1616482800"; d="scan'208";a="448203592" Received: from fieedk002.ccr.corp.intel.com ([10.239.158.144]) by fmsmga008.fm.intel.com with ESMTP; 04 Jun 2021 02:42:37 -0700 From: "Zhiguang Liu" To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Dandan Bi , Star Zeng , Zhichao Gao , Patrick Rudolph Subject: [Patch V3 5/9] MdeModulePkg/Universal/SmbiosDxe: Scan for existing tables Date: Fri, 4 Jun 2021 17:42:23 +0800 Message-Id: <20210604094227.1890-6-zhiguang.liu@intel.com> X-Mailer: git-send-email 2.30.0.windows.2 In-Reply-To: <20210604094227.1890-1-zhiguang.liu@intel.com> References: <20210604094227.1890-1-zhiguang.liu@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable V1: The default EfiSmbiosProtocol operates on an empty SMBIOS table. The SMBIOS tables are provided by the bootloader on UefiPayloadPkg. Scan for existing tables in SmbiosDxe and load them if they seem valid. This fixes the settings menu not showing any hardware information, instead only "0 MB RAM" was displayed. Tests showed that the OS can still see the SMBIOS tables. V2: SmbiosDxe will get the SMBIOS from a guid Hob. Aslo will keep the SmbiosHandle if it is available. Cc: Jian J Wang Cc: Hao A Wu Cc: Dandan Bi Cc: Star Zeng Cc: Zhichao Gao Signed-off-by: Patrick Rudolph Signed-off-by: Zhiguang Liu --- MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c | 320 +++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h | 4 +++- MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf | 5 ++++- 3 files changed, 325 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c b/MdeModulePkg/Un= iversal/SmbiosDxe/SmbiosDxe.c index 3cdb0b1ed7..3579c4d890 100644 --- a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c +++ b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c @@ -2,7 +2,7 @@ This code produces the Smbios protocol. It also responsible for construc= ting=0D SMBIOS table into system table.=0D =0D -Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
=0D +Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.
=0D SPDX-License-Identifier: BSD-2-Clause-Patent=0D =0D **/=0D @@ -148,6 +148,31 @@ SMBIOS_TABLE_3_0_ENTRY_POINT Smbios30EntryPointStructu= reData =3D { //=0D 0=0D };=0D +=0D +/**=0D + Validates a SMBIOS table entry point.=0D +=0D + @param TableEntry The SmBios table entry to validate.=0D + @param TableAddress On exit, point to the smbios table addres.=0D + @param TableMaximumSize On exit, point to the maximum size of the table= .=0D +=0D + @retval TRUE SMBIOS table entry point is valid.=0D + @retval FALSE SMBIOS table entry point is malformed.=0D +=0D +**/=0D +typedef=0D +BOOLEAN=0D +(* IS_SMBIOS_TABLE_VALID) (=0D + IN VOID *TableEntry,=0D + OUT VOID **TableAddress,=0D + OUT UINTN *TableMaximumSize=0D + );=0D +typedef struct {=0D + EFI_GUID *Guid;=0D + IS_SMBIOS_TABLE_VALID IsValid;=0D +} IS_SMBIOS_TABLE_VALID_ENTRY;=0D +=0D +=0D /**=0D =0D Get the full size of SMBIOS structure including optional strings that fo= llow the formatted structure.=0D @@ -1408,6 +1433,296 @@ SmbiosTableConstruction ( }=0D }=0D =0D +/**=0D + Validates a SMBIOS 2.0 table entry point.=0D +=0D + @param TableEntry The SmBios table entry to validate.=0D + @param TableAddress On exit, point to the smbios table addres.=0D + @param TableMaximumSize On exit, point to the maximum size of the table= .=0D +=0D + @retval TRUE SMBIOS table entry point is valid.=0D + @retval FALSE SMBIOS table entry point is malformed.=0D +=0D +**/=0D +STATIC=0D +BOOLEAN=0D +IsValidSmbios20Table (=0D + IN VOID *TableEntry,=0D + OUT VOID **TableAddress,=0D + OUT UINTN *TableMaximumSize=0D + )=0D +{=0D + UINT8 Checksum;=0D + SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;=0D + SmbiosTable =3D (SMBIOS_TABLE_ENTRY_POINT *) TableEntry;=0D +=0D + if (CompareMem (SmbiosTable->AnchorString, "_SM_", 4) !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + if (CompareMem (SmbiosTable->IntermediateAnchorString, "_DMI_", 5) !=3D = 0) {=0D + return FALSE;=0D + }=0D +=0D + //=0D + // The actual value of the EntryPointLength should be 1Fh.=0D + // However, it was incorrectly stated in version 2.1 of smbios specifica= tion.=0D + // Therefore, 0x1F and 0x1E are both accepted.=0D + //=0D + if (SmbiosTable->EntryPointLength !=3D 0x1E && SmbiosTable->EntryPointLe= ngth !=3D sizeof (SMBIOS_TABLE_ENTRY_POINT)) {=0D + return FALSE;=0D + }=0D +=0D + //=0D + // MajorVersion should not be less than 2.=0D + //=0D + if (SmbiosTable->MajorVersion < 2) {=0D + return FALSE;=0D + }=0D +=0D + //=0D + // The whole struct check sum should be zero=0D + //=0D + Checksum =3D CalculateSum8 (=0D + (UINT8 *) SmbiosTable,=0D + SmbiosTable->EntryPointLength=0D + );=0D + if (Checksum !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + //=0D + // The Intermediate Entry Point Structure check sum should be zero.=0D + //=0D + Checksum =3D CalculateSum8 (=0D + (UINT8 *) SmbiosTable + OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT= , IntermediateAnchorString),=0D + SmbiosTable->EntryPointLength - OFFSET_OF (SMBIOS_TABLE_ENT= RY_POINT, IntermediateAnchorString)=0D + );=0D + if (Checksum !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + *TableAddress =3D (VOID *) (UINTN) SmbiosTable->TableAddress;=0D + *TableMaximumSize =3D SmbiosTable->TableLength;=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Validates a SMBIOS 3.0 table entry point.=0D +=0D + @param TableEntry The SmBios table entry to validate.=0D + @param TableAddress On exit, point to the smbios table addres.=0D + @param TableMaximumSize On exit, point to the maximum size of the table= .=0D +=0D + @retval TRUE SMBIOS table entry point is valid.=0D + @retval FALSE SMBIOS table entry point is malformed.=0D +=0D +**/=0D +STATIC=0D +BOOLEAN=0D +IsValidSmbios30Table (=0D + IN VOID *TableEntry,=0D + OUT VOID **TableAddress,=0D + OUT UINTN *TableMaximumSize=0D + )=0D +{=0D + UINT8 Checksum;=0D + SMBIOS_TABLE_3_0_ENTRY_POINT *SmbiosTable;=0D + SmbiosTable =3D (SMBIOS_TABLE_3_0_ENTRY_POINT *) TableEntry;=0D +=0D + if (CompareMem (SmbiosTable->AnchorString, "_SM3_", 5) !=3D 0) {=0D + return FALSE;=0D + }=0D + if (SmbiosTable->EntryPointLength < sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT= )) {=0D + return FALSE;=0D + }=0D + if (SmbiosTable->MajorVersion < 3) {=0D + return FALSE;=0D + }=0D +=0D + //=0D + // The whole struct check sum should be zero=0D + //=0D + Checksum =3D CalculateSum8 (=0D + (UINT8 *) SmbiosTable,=0D + SmbiosTable->EntryPointLength=0D + );=0D + if (Checksum !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + *TableAddress =3D (VOID *) (UINTN) SmbiosTable->TableAddress;=0D + *TableMaximumSize =3D SmbiosTable->TableMaximumSize;=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Parse an existing SMBIOS table and insert it using SmbiosAdd.=0D +=0D + @param ImageHandle The EFI_HANDLE to this driver.=0D + @param Smbios The SMBIOS table to parse.=0D + @param Length The length of the SMBIOS table.=0D +=0D + @retval EFI_SUCCESS SMBIOS table was parsed and installed.=0D + @retval EFI_OUT_OF_RESOURCES Record was not added due to lack of system= resources.=0D + @retval EFI_INVALID_PARAMETER Smbios is not a correct smbios table=0D +=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +ParseAndAddExistingSmbiosTable (=0D + IN EFI_HANDLE ImageHandle,=0D + IN SMBIOS_STRUCTURE_POINTER Smbios,=0D + IN UINTN Length=0D + )=0D +{=0D + EFI_STATUS Status;=0D + CHAR8 *String;=0D + EFI_SMBIOS_HANDLE SmbiosHandle;=0D + SMBIOS_STRUCTURE_POINTER SmbiosEnd;=0D +=0D + SmbiosEnd.Raw =3D Smbios.Raw + Length;=0D +=0D + if (Smbios.Raw >=3D SmbiosEnd.Raw || Smbios.Raw =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + do {=0D + //=0D + // Make sure not to access memory beyond SmbiosEnd=0D + //=0D + if (Smbios.Raw + sizeof (SMBIOS_STRUCTURE) > SmbiosEnd.Raw ||=0D + Smbios.Raw + sizeof (SMBIOS_STRUCTURE) < Smbios.Raw) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D + //=0D + // Check for end marker=0D + //=0D + if (Smbios.Hdr->Type =3D=3D SMBIOS_TYPE_END_OF_TABLE) {=0D + break;=0D + }=0D + //=0D + // Make sure not to access memory beyond SmbiosEnd=0D + // Each structure shall be terminated by a double-null (0000h).=0D + //=0D + if (Smbios.Raw + Smbios.Hdr->Length + 2 * sizeof (UINT8) > SmbiosEnd.R= aw ||=0D + Smbios.Raw + Smbios.Hdr->Length + 2 * sizeof (UINT8) < Smbios.Raw) {= =0D + return EFI_INVALID_PARAMETER;=0D + }=0D + //=0D + // Install the table=0D + //=0D + SmbiosHandle =3D Smbios.Hdr->Handle;=0D + Status =3D SmbiosAdd (=0D + &mPrivateData.Smbios,=0D + ImageHandle,=0D + &SmbiosHandle,=0D + Smbios.Hdr=0D + );=0D +=0D + ASSERT_EFI_ERROR (Status);=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + //=0D + // Go to the next SMBIOS structure. Each SMBIOS structure may include = 2 parts:=0D + // 1. Formatted section; 2. Unformatted string section. So, 2 steps ar= e needed=0D + // to skip one SMBIOS structure.=0D + //=0D +=0D + //=0D + // Step 1: Skip over formatted section.=0D + //=0D + String =3D (CHAR8 *) (Smbios.Raw + Smbios.Hdr->Length);=0D +=0D + //=0D + // Step 2: Skip over unformatted string section.=0D + //=0D + do {=0D + //=0D + // Each string is terminated with a NULL(00h) BYTE and the sets of s= trings=0D + // is terminated with an additional NULL(00h) BYTE.=0D + //=0D + for ( ; *String !=3D 0; String++) {=0D + if ((UINTN) String >=3D (UINTN) SmbiosEnd.Raw - sizeof (UINT8)) {= =0D + return EFI_INVALID_PARAMETER;=0D + }=0D + }=0D +=0D + if (*(UINT8 *) ++String =3D=3D 0) {=0D + //=0D + // Pointer to the next SMBIOS structure.=0D + //=0D + Smbios.Raw =3D (UINT8 *) ++String;=0D + break;=0D + }=0D + } while (TRUE);=0D + } while (Smbios.Raw < SmbiosEnd.Raw);=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +=0D +IS_SMBIOS_TABLE_VALID_ENTRY mIsSmbiosTableValid[] =3D {=0D + {&gPldSmbios3TableGuid, IsValidSmbios30Table },=0D + {&gPldSmbiosTableGuid, IsValidSmbios20Table }=0D +};=0D +=0D +/**=0D + Retrieve SMBIOS from Hob.=0D + @param ImageHandle Module's image handle=0D +=0D + @retval EFI_SUCCESS Smbios from Hob is installed.=0D + @return EFI_NOT_FOUND Not found Smbios from Hob.=0D + @retval Other No Smbios from Hob is installed.=0D +=0D +**/=0D +EFI_STATUS=0D +RetrieveSmbiosFromHob (=0D + IN EFI_HANDLE ImageHandle=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINTN Index;=0D + SMBIOS_STRUCTURE_POINTER Smbios;=0D + EFI_HOB_GUID_TYPE *GuidHob;=0D + PLD_SMBIOS_TABLE *SmBiosTableAdress;=0D + PLD_GENERIC_HEADER *GenericHeader;=0D + VOID *TableAddress;=0D + UINTN TableMaximumSize;=0D +=0D + Status =3D EFI_NOT_FOUND;=0D +=0D + for (Index =3D 0; Index < ARRAY_SIZE (mIsSmbiosTableValid); Index++) {=0D + GuidHob =3D GetFirstGuidHob (mIsSmbiosTableValid[Index].Guid);=0D + if (GuidHob =3D=3D NULL) {=0D + continue;=0D + }=0D + GenericHeader =3D (PLD_GENERIC_HEADER *) GET_GUID_HOB_DATA (GuidHob);= =0D + if ((sizeof (PLD_GENERIC_HEADER) <=3D GET_GUID_HOB_DATA_SIZE (GuidHob)= ) && (GenericHeader->Length <=3D GET_GUID_HOB_DATA_SIZE (GuidHob))) {=0D + if (GenericHeader->Revision =3D=3D PLD_SMBIOS_TABLE_REVISION) {=0D + //=0D + // PLD_SMBIOS_TABLE structure is used when Revision equals to PLD_= SMBIOS_TABLE_REVISION=0D + //=0D + SmBiosTableAdress =3D (PLD_SMBIOS_TABLE *) GET_GUID_HOB_DATA (Guid= Hob);=0D + if (GenericHeader->Length >=3D PLD_SIZEOF_THROUGH_FIELD (PLD_SMBIO= S_TABLE, SmBiosEntryPoint)) {=0D + if (mIsSmbiosTableValid[Index].IsValid ((VOID *) (UINTN )SmBiosT= ableAdress->SmBiosEntryPoint, &TableAddress, &TableMaximumSize)) {=0D + Smbios.Raw =3D TableAddress;=0D + Status =3D ParseAndAddExistingSmbiosTable (ImageHandle, Smbios= , TableMaximumSize);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "RetrieveSmbiosFromHob: Failed to parse= preinstalled tables from gPldSmbios3TableGuid Guid Hob\n"));=0D + Status =3D EFI_UNSUPPORTED;=0D + } else {=0D + return EFI_SUCCESS;=0D + }=0D + }=0D + }=0D + }=0D + }=0D + }=0D + return Status;=0D +}=0D +=0D /**=0D =0D Driver to produce Smbios protocol and pre-allocate 1 page for the final = SMBIOS table.=0D @@ -1451,5 +1766,6 @@ SmbiosDriverEntryPoint ( &mPrivateData.Smbios=0D );=0D =0D - return Status;=0D + RetrieveSmbiosFromHob (ImageHandle);=0D + return EFI_SUCCESS;=0D }=0D diff --git a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h b/MdeModulePkg/Un= iversal/SmbiosDxe/SmbiosDxe.h index f97c85ae40..a260cf695e 100644 --- a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h +++ b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h @@ -1,7 +1,7 @@ /** @file=0D This code supports the implementation of the Smbios protocol=0D =0D -Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
=0D +Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.
=0D SPDX-License-Identifier: BSD-2-Clause-Patent=0D =0D **/=0D @@ -24,6 +24,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include =0D #include =0D #include =0D +#include =0D +#include =0D =0D #define SMBIOS_INSTANCE_SIGNATURE SIGNATURE_32 ('S', 'B', 'i', 's')=0D typedef struct {=0D diff --git a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf b/MdeModulePkg/= Universal/SmbiosDxe/SmbiosDxe.inf index f6c036e1dc..63f468936d 100644 --- a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf +++ b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf @@ -1,7 +1,7 @@ ## @file=0D # This driver initializes and installs the SMBIOS protocol, constructs SMB= IOS table into system configuration table.=0D #=0D -# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
=0D +# Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.
=0D #=0D # SPDX-License-Identifier: BSD-2-Clause-Patent=0D #=0D @@ -41,6 +41,7 @@ UefiDriverEntryPoint=0D DebugLib=0D PcdLib=0D + HobLib=0D =0D [Protocols]=0D gEfiSmbiosProtocolGuid ## PRODUCES=0D @@ -48,6 +49,8 @@ [Guids]=0D gEfiSmbiosTableGuid ## SOMETIMES_PRODUCES = ## SystemTable=0D gEfiSmbios3TableGuid ## SOMETIMES_PRODUCES = ## SystemTable=0D + gPldSmbios3TableGuid ## CONSUMES = ## HOB=0D + gPldSmbiosTableGuid ## SOMETIMES_CONSUMES = ## HOB=0D =0D [Pcd]=0D gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion ## CONSUMES=0D --=20 2.30.0.windows.2