<div dir="ltr"><div dir="ltr"><br></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, May 24, 2021 at 9:13 AM Zhiguang Liu <<a href="mailto:zhiguang.liu@intel.com">zhiguang.liu@intel.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">V1:<br>
The default EfiSmbiosProtocol operates on an empty SMBIOS table.<br>
The SMBIOS tables are provided by the bootloader on UefiPayloadPkg.<br>
Scan for existing tables in SmbiosDxe and load them if they seem valid.<br>
<br>
This fixes the settings menu not showing any hardware information, instead<br>
only "0 MB RAM" was displayed.<br>
<br>
Tests showed that the OS can still see the SMBIOS tables.<br>
<br>
V2:<br>
SmbiosDxe will get the SMBIOS from a guid Hob.<br>
Aslo will keep the SmbiosHandle if it is available.<br>
<br>
Cc: Jian J Wang <<a href="mailto:jian.j.wang@intel.com" target="_blank">jian.j.wang@intel.com</a>><br>
Cc: Hao A Wu <<a href="mailto:hao.a.wu@intel.com" target="_blank">hao.a.wu@intel.com</a>><br>
Cc: Dandan Bi <<a href="mailto:dandan.bi@intel.com" target="_blank">dandan.bi@intel.com</a>><br>
Cc: Star Zeng <<a href="mailto:star.zeng@intel.com" target="_blank">star.zeng@intel.com</a>><br>
Cc: Zhichao Gao <<a href="mailto:zhichao.gao@intel.com" target="_blank">zhichao.gao@intel.com</a>><br>
Signed-off-by: Patrick Rudolph <<a href="mailto:patrick.rudolph@9elements.com" target="_blank">patrick.rudolph@9elements.com</a>><br>
Signed-off-by: Zhiguang Liu <<a href="mailto:zhiguang.liu@intel.com" target="_blank">zhiguang.liu@intel.com</a>><br>
---<br>
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c | 299 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--<br>
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h | 4 +++-<br>
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf | 5 ++++-<br>
3 files changed, 304 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c<br>
index 3cdb0b1ed7..d2aa15d43f 100644<br>
--- a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c<br>
+++ b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c<br>
@@ -2,7 +2,7 @@<br>
This code produces the Smbios protocol. It also responsible for constructing<br>
SMBIOS table into system table.<br>
<br>
-Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR><br>
+Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR><br>
SPDX-License-Identifier: BSD-2-Clause-Patent<br>
<br>
**/<br>
@@ -1408,6 +1408,300 @@ SmbiosTableConstruction (<br>
}<br>
}<br>
<br>
+/**<br>
+ Validates a SMBIOS 2.0 table entry point.<br>
+<br>
+ @param SmbiosTable The SMBIOS_TABLE_ENTRY_POINT to validate.<br>
+<br>
+ @retval TRUE SMBIOS table entry point is valid.<br>
+ @retval FALSE SMBIOS table entry point is malformed.<br>
+<br>
+**/<br>
+STATIC<br>
+BOOLEAN<br>
+IsValidSmbios20Table (<br>
+ IN SMBIOS_TABLE_ENTRY_POINT *SmbiosTable<br>
+ )<br>
+{<br>
+ UINT8 Checksum;<br>
+<br>
+ if (CompareMem (SmbiosTable->AnchorString, "_SM_", 4) != 0) {<br>
+ return FALSE;<br>
+ }<br>
+<br>
+ //<br>
+ // The actual value of the EntryPointLength should be 1Fh.<br>
+ // However, it was incorrectly stated in version 2.1 of smbios specification.<br>
+ // Therefore, 0x1F and 0x1E are both accepted.<br>
+ //<br>
+ if (SmbiosTable->EntryPointLength != 0x1E || SmbiosTable->EntryPointLength != sizeof (SMBIOS_TABLE_ENTRY_POINT)) {<br>
+ return FALSE;<br>
+ }<br>
+<br></blockquote><div><br></div><div>This is not correct, it should be <br></div><div><br></div><div> if (SmbiosTable->EntryPointLength != 0x1E && SmbiosTable->EntryPointLength != sizeof (SMBIOS_TABLE_ENTRY_POINT)) {</div><div><br></div><div>otherwise the table wouldn't be recognized as valid.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ //<br>
+ // MajorVersion should be 2.<br>
+ //<br>
+ if (SmbiosTable->MajorVersion != 2) {<br>
+ return FALSE;<br>
+ }<br>
+<br>
+ //<br>
+ // The whole struct check sum should be zero<br>
+ //<br>
+ Checksum = CalculateSum8 (<br>
+ (UINT8 *) SmbiosTable,<br>
+ SmbiosTable->EntryPointLength<br>
+ );<br>
+ if (Checksum != 0) {<br>
+ return FALSE;<br>
+ }<br>
+<br>
+ //<br>
+ // The Intermediate Entry Point Structure check sum should be zero.<br>
+ //<br>
+ Checksum = CalculateSum8 (<br>
+ (UINT8 *) SmbiosTable + OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString),<br>
+ SmbiosTable->EntryPointLength - OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString)<br>
+ );<br>
+ return (BOOLEAN) (Checksum == 0);<br>
+}<br>
+<br>
+/**<br>
+ Validates a SMBIOS 3.0 table entry point.<br>
+<br>
+ @param SmbiosTable The SMBIOS_TABLE_3_0_ENTRY_POINT to validate.<br>
+<br>
+ @retval TRUE SMBIOS table entry point is valid.<br>
+ @retval FALSE SMBIOS table entry point is malformed.<br>
+<br>
+**/<br>
+STATIC<br>
+BOOLEAN<br>
+IsValidSmbios30Table (<br>
+ IN SMBIOS_TABLE_3_0_ENTRY_POINT *SmbiosTable<br>
+ )<br>
+{<br>
+ UINT8 Checksum;<br>
+<br>
+ if (CompareMem (SmbiosTable->AnchorString, "_SM3_", 5) != 0) {<br>
+ return FALSE;<br>
+ }<br>
+ if (SmbiosTable->EntryPointLength < sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT)) {<br>
+ return FALSE;<br>
+ }<br>
+ if (SmbiosTable->MajorVersion < 3) {<br>
+ return FALSE;<br>
+ }<br>
+<br>
+ //<br>
+ // The whole struct check sum should be zero<br>
+ //<br>
+ Checksum = CalculateSum8 (<br>
+ (UINT8 *) SmbiosTable,<br>
+ SmbiosTable->EntryPointLength<br>
+ );<br>
+ if (Checksum != 0) {<br>
+ return FALSE;<br>
+ }<br>
+ return TRUE;<br>
+}<br>
+<br>
+/**<br>
+ Parse an existing SMBIOS table and insert it using SmbiosAdd.<br>
+<br>
+ @param ImageHandle The EFI_HANDLE to this driver.<br>
+ @param Smbios The SMBIOS table to parse.<br>
+ @param Length The length of the SMBIOS table.<br>
+<br>
+ @retval EFI_SUCCESS SMBIOS table was parsed and installed.<br>
+ @retval EFI_OUT_OF_RESOURCES Record was not added due to lack of system resources.<br>
+ @retval EFI_INVALID_PARAMETER Smbios is not a correct smbios table<br>
+<br>
+**/<br>
+STATIC<br>
+EFI_STATUS<br>
+ParseAndAddExistingSmbiosTable (<br>
+ IN EFI_HANDLE ImageHandle,<br>
+ IN SMBIOS_STRUCTURE_POINTER Smbios,<br>
+ IN UINTN Length<br>
+ )<br>
+{<br>
+ EFI_STATUS Status;<br>
+ CHAR8 *String;<br>
+ EFI_SMBIOS_HANDLE SmbiosHandle;<br>
+ SMBIOS_STRUCTURE_POINTER SmbiosEnd;<br>
+<br>
+ SmbiosEnd.Raw = Smbios.Raw + Length;<br>
+<br>
+ if (Smbios.Raw >= SmbiosEnd.Raw || Smbios.Raw == NULL) {<br>
+ return EFI_INVALID_PARAMETER;<br>
+ }<br>
+<br>
+ do {<br>
+ //<br>
+ // Make sure not to access memory beyond SmbiosEnd<br>
+ //<br>
+ if (Smbios.Raw + sizeof (SMBIOS_STRUCTURE) > SmbiosEnd.Raw ||<br>
+ Smbios.Raw + sizeof (SMBIOS_STRUCTURE) < Smbios.Raw) {<br>
+ return EFI_INVALID_PARAMETER;<br>
+ }<br>
+ //<br>
+ // Check for end marker<br>
+ //<br>
+ if (Smbios.Hdr->Type == SMBIOS_TYPE_END_OF_TABLE) {<br>
+ break;<br>
+ }<br>
+ //<br>
+ // Make sure not to access memory beyond SmbiosEnd<br>
+ // Each structure shall be terminated by a double-null (0000h).<br>
+ //<br>
+ if (Smbios.Raw + Smbios.Hdr->Length + 2 * sizeof (UINT8) > SmbiosEnd.Raw ||<br>
+ Smbios.Raw + Smbios.Hdr->Length + 2 * sizeof (UINT8) < Smbios.Raw) {<br>
+ return EFI_INVALID_PARAMETER;<br>
+ }<br>
+ //<br>
+ // Install the table<br>
+ //<br>
+ SmbiosHandle = Smbios.Hdr->Handle;<br>
+ Status = SmbiosAdd (<br>
+ &mPrivateData.Smbios,<br>
+ ImageHandle,<br>
+ &SmbiosHandle,<br>
+ Smbios.Hdr<br>
+ );<br>
+<br>
+ ASSERT_EFI_ERROR (Status);<br>
+ if (EFI_ERROR (Status)) {<br>
+ return Status;<br>
+ }<br>
+ //<br>
+ // Go to the next SMBIOS structure. Each SMBIOS structure may include 2 parts:<br>
+ // 1. Formatted section; 2. Unformatted string section. So, 2 steps are needed<br>
+ // to skip one SMBIOS structure.<br>
+ //<br>
+<br>
+ //<br>
+ // Step 1: Skip over formatted section.<br>
+ //<br>
+ String = (CHAR8 *) (Smbios.Raw + Smbios.Hdr->Length);<br>
+<br>
+ //<br>
+ // Step 2: Skip over unformatted string section.<br>
+ //<br>
+ do {<br>
+ //<br>
+ // Each string is terminated with a NULL(00h) BYTE and the sets of strings<br>
+ // is terminated with an additional NULL(00h) BYTE.<br>
+ //<br>
+ for ( ; *String != 0; String++) {<br>
+ if ((UINTN) String >= (UINTN) SmbiosEnd.Raw - sizeof (UINT8)) {<br>
+ return EFI_INVALID_PARAMETER;<br>
+ }<br>
+ }<br>
+<br>
+ if (*(UINT8 *) ++String == 0) {<br>
+ //<br>
+ // Pointer to the next SMBIOS structure.<br>
+ //<br>
+ Smbios.Raw = (UINT8 *) ++String;<br>
+ break;<br>
+ }<br>
+ } while (TRUE);<br>
+ } while (Smbios.Raw < SmbiosEnd.Raw);<br>
+<br>
+ return EFI_SUCCESS;<br>
+}<br>
+<br>
+<br>
+/**<br>
+ Retrieve SMBIOS from Hob.<br>
+ @param ImageHandle Module's image handle<br>
+<br>
+ @retval EFI_SUCCESS Smbios from Hob is installed.<br>
+ @return EFI_NOT_FOUND Not found Smbios from Hob.<br>
+ @retval Other No Smbios from Hob is installed.<br>
+<br>
+**/<br>
+EFI_STATUS<br>
+EFIAPI<br>
+RetrieveSmbiosFromHob (<br>
+ IN EFI_HANDLE ImageHandle<br>
+ )<br>
+{<br>
+ EFI_STATUS Status;<br>
+ SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;<br>
+ SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios30Table;<br>
+ SMBIOS_STRUCTURE_POINTER Smbios;<br>
+ EFI_HOB_GUID_TYPE *GuidHob;<br>
+ PLD_SMBIOS_TABLE *SmBiosTableAdress;<br>
+ PLD_GENERIC_HEADER *GenericHeader;<br>
+<br>
+ Status = EFI_NOT_FOUND;<br>
+ //<br>
+ // Scan for existing SMBIOS tables from gPldSmbios3TableGuid Guid Hob<br>
+ //<br>
+ GuidHob = GetFirstGuidHob (&gPldSmbios3TableGuid);<br>
+ if (GuidHob != NULL) {<br>
+ GenericHeader = (PLD_GENERIC_HEADER *) GET_GUID_HOB_DATA (GuidHob);<br>
+ if ((sizeof (PLD_GENERIC_HEADER) <= GET_GUID_HOB_DATA_SIZE (GuidHob)) && (GenericHeader->Length <= GET_GUID_HOB_DATA_SIZE (GuidHob))) {<br>
+ if (GenericHeader->Revision == PLD_SMBIOS_TABLE_REVISION) {<br>
+ //<br>
+ // PLD_SMBIOS_TABLE structure is used when Revision equals to PLD_SMBIOS_TABLE_REVISION<br>
+ //<br>
+ SmBiosTableAdress = (PLD_SMBIOS_TABLE *) GET_GUID_HOB_DATA (GuidHob);<br>
+ if (GenericHeader->Length >= PLD_SIZEOF_THROUGH_FIELD (PLD_SMBIOS_TABLE, SmBiosEntryPoint)) {<br>
+ Smbios30Table = (SMBIOS_TABLE_3_0_ENTRY_POINT *) (UINTN) SmBiosTableAdress->SmBiosEntryPoint;<br>
+ if (IsValidSmbios30Table (Smbios30Table)) {<br>
+ Smbios.Raw = (UINT8 *) (UINTN) Smbios30Table->TableAddress;<br>
+ Status = ParseAndAddExistingSmbiosTable (ImageHandle, Smbios, Smbios30Table->TableMaximumSize);<br>
+ if (EFI_ERROR (Status)) {<br>
+ DEBUG ((DEBUG_ERROR, "RetrieveSmbiosFromHob: Failed to parse preinstalled tables from gPldSmbios3TableGuid Guid Hob\n"));<br>
+ Status = EFI_UNSUPPORTED;<br>
+ } else {<br>
+ return EFI_SUCCESS;<br>
+ }<br>
+ }<br>
+ }<br>
+ } else {<br>
+ Status = EFI_UNSUPPORTED;<br>
+ }<br>
+ }<br>
+ }<br>
+<br>
+ //<br>
+ // Scan for existing SMBIOS tables from gPldSmbiosTableGuid Guid Hob,<br>
+ // if gPldSmbios3TableGuid Hob doesn't exist or parsing gPldSmbios3TableGuid failed<br>
+ //<br>
+ GuidHob = GetFirstGuidHob (&gPldSmbiosTableGuid);<br>
+ <br>
+ if (GuidHob != NULL) {<br>
+ GenericHeader = (PLD_GENERIC_HEADER *) GET_GUID_HOB_DATA (GuidHob);<br>
+ if ((sizeof (PLD_GENERIC_HEADER) <= GET_GUID_HOB_DATA_SIZE (GuidHob)) && (GenericHeader->Length <= GET_GUID_HOB_DATA_SIZE (GuidHob))) {<br>
+ if (GenericHeader->Revision == PLD_SMBIOS_TABLE_REVISION) {<br>
+ //<br>
+ // PLD_SMBIOS_TABLE structure is used when Revision equals to PLD_SMBIOS_TABLE_REVISION<br>
+ //<br>
+ SmBiosTableAdress = (PLD_SMBIOS_TABLE *) GET_GUID_HOB_DATA (GuidHob);<br>
+ if (GenericHeader->Length >= PLD_SIZEOF_THROUGH_FIELD (PLD_SMBIOS_TABLE, SmBiosEntryPoint)) {<br>
+ SmbiosTable = (SMBIOS_TABLE_ENTRY_POINT *) (UINTN) SmBiosTableAdress->SmBiosEntryPoint;<br>
+ if (IsValidSmbios20Table (SmbiosTable)) {<br>
+ Smbios.Raw = (UINT8 *) (UINTN) SmbiosTable->TableAddress;<br>
+ Status = ParseAndAddExistingSmbiosTable (ImageHandle, Smbios, SmbiosTable->TableLength);<br>
+ if (EFI_ERROR (Status)) {<br>
+ DEBUG ((DEBUG_ERROR, "RetrieveSmbiosFromHob: Failed to parse preinstalled tables from gPldSmbiosTableGuid Guid Hob\n"));<br>
+ Status = EFI_UNSUPPORTED;<br>
+ }<br>
+ return EFI_SUCCESS;<br>
+ }<br>
+ }<br>
+ } else {<br>
+ Status = EFI_UNSUPPORTED;<br>
+ }<br>
+ }<br>
+ }<br>
+ return Status;<br>
+}<br>
+<br>
/**<br>
<br>
Driver to produce Smbios protocol and pre-allocate 1 page for the final SMBIOS table.<br>
@@ -1451,5 +1745,6 @@ SmbiosDriverEntryPoint (<br>
&mPrivateData.Smbios<br>
);<br>
<br>
- return Status;<br>
+ RetrieveSmbiosFromHob (ImageHandle);<br>
+ return EFI_SUCCESS;<br>
}<br>
diff --git a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h<br>
index f97c85ae40..a260cf695e 100644<br>
--- a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h<br>
+++ b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h<br>
@@ -1,7 +1,7 @@<br>
/** @file<br>
This code supports the implementation of the Smbios protocol<br>
<br>
-Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR><br>
+Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR><br>
SPDX-License-Identifier: BSD-2-Clause-Patent<br>
<br>
**/<br>
@@ -24,6 +24,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent<br>
#include <Library/MemoryAllocationLib.h><br>
#include <Library/UefiBootServicesTableLib.h><br>
#include <Library/PcdLib.h><br>
+#include <Library/HobLib.h><br>
+#include <UniversalPayload/SmbiosTable.h><br>
<br>
#define SMBIOS_INSTANCE_SIGNATURE SIGNATURE_32 ('S', 'B', 'i', 's')<br>
typedef struct {<br>
diff --git a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf<br>
index f6c036e1dc..3286575098 100644<br>
--- a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf<br>
+++ b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf<br>
@@ -1,7 +1,7 @@<br>
## @file<br>
# This driver initializes and installs the SMBIOS protocol, constructs SMBIOS table into system configuration table.<br>
#<br>
-# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR><br>
+# Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR><br>
#<br>
# SPDX-License-Identifier: BSD-2-Clause-Patent<br>
#<br>
@@ -41,6 +41,7 @@<br>
UefiDriverEntryPoint<br>
DebugLib<br>
PcdLib<br>
+ HobLib<br>
<br>
[Protocols]<br>
gEfiSmbiosProtocolGuid ## PRODUCES<br>
@@ -48,6 +49,8 @@<br>
[Guids]<br>
gEfiSmbiosTableGuid ## SOMETIMES_PRODUCES ## SystemTable<br>
gEfiSmbios3TableGuid ## SOMETIMES_PRODUCES ## SystemTable<br>
+ gPldSmbios3TableGuid<br>
+ gPldSmbiosTableGuid<br>
<br>
[Pcd]<br>
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion ## CONSUMES<br>
-- <br>
2.30.0.windows.2<br>
<br>
<br>
<br>
------------<br>
Groups.io Links: You receive all messages sent to this group.<br>
View/Reply Online (#75489): <a href="https://edk2.groups.io/g/devel/message/75489" rel="noreferrer" target="_blank">https://edk2.groups.io/g/devel/message/75489</a><br>
Mute This Topic: <a href="https://groups.io/mt/83045509/2917327" rel="noreferrer" target="_blank">https://groups.io/mt/83045509/2917327</a><br>
Group Owner: <a href="mailto:devel%2Bowner@edk2.groups.io" target="_blank">devel+owner@edk2.groups.io</a><br>
Unsubscribe: <a href="https://edk2.groups.io/g/devel/unsub" rel="noreferrer" target="_blank">https://edk2.groups.io/g/devel/unsub</a> [<a href="mailto:patrick.rudolph@9elements.com" target="_blank">patrick.rudolph@9elements.com</a>]<br>
------------<br>
<br>
<br>
</blockquote></div></div>
<div width="1" style="color:white;clear:both">_._,_._,_</div> <hr> Groups.io Links:<p> You receive all messages sent to this group. <p> <a target="_blank" href="https://edk2.groups.io/g/devel/message/75661">View/Reply Online (#75661)</a> | | <a target="_blank" href="https://groups.io/mt/83045509/1813853">Mute This Topic</a> | <a href="https://edk2.groups.io/g/devel/post">New Topic</a><br> <a href="https://edk2.groups.io/g/devel/editsub/1813853">Your Subscription</a> | <a href="mailto:devel+owner@edk2.groups.io">Contact Group Owner</a> | <a href="https://edk2.groups.io/g/devel/unsub">Unsubscribe</a> [edk2-devel-archive@redhat.com]<br> <div width="1" style="color:white;clear:both">_._,_._,_</div>