Locate QEMU SMBIOS data in fw_cfg and install it via the
SMBIOS protocol.

Starting with qemu-2.1, on pc/x86 machines of type >= 2.1, full
SMBIOS tables are generated and inserted into fw_cfg (i.e., no
per-field patching of locally generated structures is required).

Aside from new code to extract a SMBIOS blob from fw_cfg, this
patch utilizes the pre-existing (Xen) infrastructure to handle
final SMBIOS table creation.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Gabriel Somlo <so...@cmu.edu>
---
 OvmfPkg/SmbiosPlatformDxe/Qemu.c                | 87 +++++++++++++++++++++++++
 OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c   | 24 +++++--
 OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h   | 23 +++++++
 OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf |  3 +
 4 files changed, 132 insertions(+), 5 deletions(-)
 create mode 100644 OvmfPkg/SmbiosPlatformDxe/Qemu.c

diff --git a/OvmfPkg/SmbiosPlatformDxe/Qemu.c b/OvmfPkg/SmbiosPlatformDxe/Qemu.c
new file mode 100644
index 0000000..f18e2c1
--- /dev/null
+++ b/OvmfPkg/SmbiosPlatformDxe/Qemu.c
@@ -0,0 +1,87 @@
+/** @file
+  Find and extract QEMU SMBIOS data from fw_cfg.
+
+  Copyright (C) 2014, Gabriel L. Somlo <so...@cmu.edu>
+
+  This program and the accompanying materials are licensed and made
+  available under the terms and conditions of the BSD License which
+  accompanies this distribution.   The full text of the license may
+  be found at http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#include "SmbiosPlatformDxe.h"
+#include <Library/QemuFwCfgLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+//
+// fw_cfg file names for the SMBIOS entry point and tables
+//
+#define QEMU_ANCHOR "etc/smbios/smbios-anchor"
+#define QEMU_TABLES "etc/smbios/smbios-tables"
+
+/**
+  Locates and extracts the QEMU SMBIOS data if present in fw_cfg
+
+  @return                 Address of extracted QEMU SMBIOS data
+
+**/
+UINT8 *
+GetQemuSmbiosTables (
+  VOID
+  )
+{
+  SMBIOS_TABLE_ENTRY_POINT QemuAnchor;
+  FIRMWARE_CONFIG_ITEM     Anchor, Tables;
+  UINTN                    AnchorSz, TablesSz;
+  UINT8                    *QemuTables;
+
+  if (QemuFwCfgFindFile (QEMU_ANCHOR, &Anchor, &AnchorSz) != RETURN_SUCCESS ||
+      QemuFwCfgFindFile (QEMU_TABLES, &Tables, &TablesSz) != RETURN_SUCCESS ||
+      AnchorSz != sizeof (QemuAnchor) ||
+      TablesSz == 0) {
+    return NULL;
+  }
+
+  //
+  // We copy the entry point structure to perform some additional checks,
+  // but discard it upon return.
+  //
+  QemuFwCfgSelectItem (Anchor);
+  QemuFwCfgReadBytes (AnchorSz, &QemuAnchor);
+
+  if (AsciiStrnCmp ((CHAR8 *)QemuAnchor.AnchorString, "_SM_", 4) ||
+      AsciiStrnCmp ((CHAR8 *)QemuAnchor.IntermediateAnchorString, "_DMI_", 5) 
||
+      TablesSz != QemuAnchor.TableLength) {
+    return NULL;
+  }
+
+  QemuTables = AllocatePool (TablesSz);
+  if (QemuTables == NULL) {
+    return NULL;
+  }
+
+  QemuFwCfgSelectItem (Tables);
+  QemuFwCfgReadBytes (TablesSz, QemuTables);
+
+  return QemuTables;
+}
+
+/**
+  Frees the dynamically allocated portion of the extracted QEMU SMBIOS data
+
+  @param[in]  QemuTables  Address of QEMU SMBIOS data from 
GetQemuSmbiosTables()
+
+  It is the caller's responsibility to ensure QemuTables was allocated and
+  returned from GetQemuSmbiosTables().
+
+ **/
+VOID
+FreeQemuSmbiosTables (
+  IN UINT8 *QemuTables
+  )
+{
+  FreePool (QemuTables);
+}
diff --git a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c 
b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
index ac48fb7..9d3f515 100644
--- a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
+++ b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
@@ -84,20 +84,20 @@ SmbiosTableLength (
   Install all structures from the given SMBIOS structures block
 
   @param  Smbios               SMBIOS protocol
-  @param  EntryPointStructure  SMBIOS entry point structures block
+  @param  TableAddress         SMBIOS tables starting address
 
 **/
 EFI_STATUS
 InstallAllStructures (
   IN EFI_SMBIOS_PROTOCOL       *Smbios,
-  IN SMBIOS_TABLE_ENTRY_POINT  *EntryPointStructure
+  IN UINT8                     *TableAddress
   )
 {
   EFI_STATUS                Status;
   SMBIOS_STRUCTURE_POINTER  SmbiosTable;
   EFI_SMBIOS_HANDLE         SmbiosHandle;
 
-  SmbiosTable.Raw = (UINT8*)(UINTN) EntryPointStructure->TableAddress;
+  SmbiosTable.Raw = TableAddress;
   if (SmbiosTable.Raw == NULL) {
     return EFI_INVALID_PARAMETER;
   }
@@ -145,6 +145,7 @@ SmbiosTablePublishEntry (
   EFI_STATUS                Status;
   EFI_SMBIOS_PROTOCOL       *Smbios;
   SMBIOS_TABLE_ENTRY_POINT  *EntryPointStructure;
+  UINT8                     *SmbiosTables;
 
   //
   // Find the SMBIOS protocol
@@ -159,11 +160,24 @@ SmbiosTablePublishEntry (
   }
 
   //
-  // Add Xen SMBIOS data if found
+  // Add Xen or QEMU SMBIOS data if found
   //
   EntryPointStructure = GetXenSmbiosTables ();
   if (EntryPointStructure != NULL) {
-    Status = InstallAllStructures (Smbios, EntryPointStructure);
+    SmbiosTables = (UINT8*)(UINTN)EntryPointStructure->TableAddress;
+  } else {
+    SmbiosTables = GetQemuSmbiosTables ();
+  }
+
+  if (SmbiosTables != NULL) {
+    Status = InstallAllStructures (Smbios, SmbiosTables);
+
+    //
+    // Free SmbiosTables if allocated by Qemu (i.e., NOT by Xen):
+    //
+    if (EntryPointStructure == NULL) {
+      FreeQemuSmbiosTables (SmbiosTables);
+    }
   }
 
   return Status;
diff --git a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h 
b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
index bf99e43..8d37355 100644
--- a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
+++ b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
@@ -40,6 +40,29 @@ GetXenSmbiosTables (
 
 
 /**
+  Locates and extracts the QEMU SMBIOS table data if present in fw_cfg
+
+  @return             Address of extracted QEMU SMBIOS data
+
+**/
+UINT8 *
+GetQemuSmbiosTables (
+  VOID
+  );
+
+/**
+  Frees the dynamically allocated portion of the extracted QEMU SMBIOS data
+
+  @param[in]  QemuTables  Address of QEMU SMBIOS data from 
GetQemuSmbiosTables()
+
+**/
+VOID
+FreeQemuSmbiosTables (
+  IN UINT8 *QemuTables
+  );
+
+
+/**
   Validates the SMBIOS entry point structure
 
   @param  EntryPointStructure  SMBIOS entry point structure
diff --git a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf 
b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
index 7058284..6596392 100644
--- a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+++ b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
@@ -32,6 +32,7 @@
   SmbiosPlatformDxe.h
   SmbiosPlatformDxe.c
   Xen.c
+  Qemu.c
 
 [Packages]
   MdePkg/MdePkg.dec
@@ -45,6 +46,8 @@
   UefiDriverEntryPoint
   DebugLib
   HobLib
+  QemuFwCfgLib
+  MemoryAllocationLib
 
 [Protocols]
   gEfiSmbiosProtocolGuid                      # PROTOCOL ALWAYS_CONSUMED
-- 
1.9.0


------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to