--- /dev/null
+/** @file\r
+ Find and extract QEMU SMBIOS data from fw_cfg.\r
+\r
+ Copyright (C) 2014, Gabriel L. Somlo <somlo@cmu.edu>\r
+\r
+ This program and the accompanying materials are licensed and made\r
+ available under the terms and conditions of the BSD License which\r
+ accompanies this distribution. The full text of the license may\r
+ be found at http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#include "SmbiosPlatformDxe.h"\r
+#include <Library/QemuFwCfgLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+/**\r
+ Locates and extracts the QEMU SMBIOS data if present in fw_cfg\r
+\r
+ @return Address of extracted QEMU SMBIOS data\r
+\r
+**/\r
+UINT8 *\r
+GetQemuSmbiosTables (\r
+ VOID\r
+ )\r
+{\r
+ SMBIOS_TABLE_ENTRY_POINT QemuAnchor;\r
+ FIRMWARE_CONFIG_ITEM Anchor, Tables;\r
+ UINTN AnchorSize, TablesSize;\r
+ UINT8 *QemuTables;\r
+\r
+ if (EFI_ERROR (QemuFwCfgFindFile (\r
+ "etc/smbios/smbios-anchor", &Anchor, &AnchorSize)) ||\r
+ EFI_ERROR (QemuFwCfgFindFile (\r
+ "etc/smbios/smbios-tables", &Tables, &TablesSize)) ||\r
+ AnchorSize != sizeof (QemuAnchor) ||\r
+ TablesSize == 0) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // We copy the entry point structure to perform some additional checks,\r
+ // but discard it upon return.\r
+ //\r
+ QemuFwCfgSelectItem (Anchor);\r
+ QemuFwCfgReadBytes (AnchorSize, &QemuAnchor);\r
+\r
+ if (AsciiStrnCmp ((CHAR8 *)QemuAnchor.AnchorString, "_SM_", 4) ||\r
+ AsciiStrnCmp ((CHAR8 *)QemuAnchor.IntermediateAnchorString, "_DMI_", 5) ||\r
+ TablesSize != QemuAnchor.TableLength) {\r
+ return NULL;\r
+ }\r
+\r
+ QemuTables = AllocatePool (TablesSize);\r
+ if (QemuTables == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ QemuFwCfgSelectItem (Tables);\r
+ QemuFwCfgReadBytes (TablesSize, QemuTables);\r
+\r
+ return QemuTables;\r
+}\r
Install all structures from the given SMBIOS structures block\r
\r
@param Smbios SMBIOS protocol\r
- @param EntryPointStructure SMBIOS entry point structures block\r
+ @param TableAddress SMBIOS tables starting address\r
\r
**/\r
EFI_STATUS\r
InstallAllStructures (\r
IN EFI_SMBIOS_PROTOCOL *Smbios,\r
- IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure\r
+ IN UINT8 *TableAddress\r
)\r
{\r
EFI_STATUS Status;\r
SMBIOS_STRUCTURE_POINTER SmbiosTable;\r
EFI_SMBIOS_HANDLE SmbiosHandle;\r
\r
- SmbiosTable.Raw = (UINT8*)(UINTN) EntryPointStructure->TableAddress;\r
+ SmbiosTable.Raw = TableAddress;\r
if (SmbiosTable.Raw == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
EFI_STATUS Status;\r
EFI_SMBIOS_PROTOCOL *Smbios;\r
SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure;\r
+ UINT8 *SmbiosTables;\r
\r
//\r
// Find the SMBIOS protocol\r
}\r
\r
//\r
- // Add Xen SMBIOS data if found\r
+ // Add Xen or QEMU SMBIOS data if found\r
//\r
EntryPointStructure = GetXenSmbiosTables ();\r
if (EntryPointStructure != NULL) {\r
- Status = InstallAllStructures (Smbios, EntryPointStructure);\r
+ SmbiosTables = (UINT8*)(UINTN)EntryPointStructure->TableAddress;\r
+ } else {\r
+ SmbiosTables = GetQemuSmbiosTables ();\r
+ }\r
+\r
+ if (SmbiosTables != NULL) {\r
+ Status = InstallAllStructures (Smbios, SmbiosTables);\r
+\r
+ //\r
+ // Free SmbiosTables if allocated by Qemu (i.e., NOT by Xen):\r
+ //\r
+ if (EntryPointStructure == NULL) {\r
+ FreePool (SmbiosTables);\r
+ }\r
}\r
\r
return Status;\r