Blob Blame History Raw
From 1b10131728dd1cff48ef1ce46820d89f21708852 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Wed, 5 Jun 2013 10:28:09 +0200
Subject: [PATCH 3/3] OvmfPkg/SmbiosPlatformDxe: install+patch default legacy
 type1 table (X86)

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c          |   5 +
 OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h  |  30 ++++
 OvmfPkg/SmbiosPlatformDxe/QemuType1.c           | 178 ++++++++++++++++++++++++
 OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf |   1 +
 4 files changed, 214 insertions(+)
 create mode 100644 OvmfPkg/SmbiosPlatformDxe/QemuType1.c

diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
index ed75a01..6507cc0 100644
--- a/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
+++ b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
@@ -631,6 +631,11 @@ InstallDefaultTables (
   EFI_STATUS Status;
 
   Status = InstallSmbiosType0 (Smbios, ProducerHandle, Context);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = InstallSmbiosType1 (Smbios, ProducerHandle, Context);
   return Status;
 }
 
diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h b/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
index ca776b5..4a2e824 100644
--- a/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
+++ b/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
@@ -248,4 +248,34 @@ InstallSmbiosType0 (
   IN OUT BUILD_CONTEXT       *Context
   );
 
+
+/**
+  Install default (fallback) table for SMBIOS Type 1.
+
+  In case QEMU has provided no Type 1 SMBIOS table in whole, prepare one here,
+  patch it with any referring saved patches, and install it.
+
+  @param[in]     Smbios          The EFI_SMBIOS_PROTOCOL instance used for
+                                 installing SMBIOS tables.
+  @param[in]     ProducerHandle  Passed on to Smbios->Add(), ProducerHandle
+                                 tracks the origin of installed SMBIOS tables.
+  @param[in,out] Context         The BUILD_CONTEXT object tracking installed
+                                 tables and saved patches.
+
+  @retval EFI_SUCCESS  A Type 1 table has already been installed from the
+                       SMBIOS firmware configuration blob.
+  @retval EFI_SUCCESS  No Type 1 table was installed previously, and installing
+                       the default here has succeeded.
+  @return              Error codes from the PATCH_FORMATTED() and
+                       PATCH_UNFORMATTED() macros, except EFI_NOT_FOUND, which
+                       is only an informative result of theirs.
+**/
+EFI_STATUS
+EFIAPI
+InstallSmbiosType1 (
+  IN     EFI_SMBIOS_PROTOCOL *Smbios,
+  IN     EFI_HANDLE          ProducerHandle,
+  IN OUT BUILD_CONTEXT       *Context
+  );
+
 #endif
diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuType1.c b/OvmfPkg/SmbiosPlatformDxe/QemuType1.c
new file mode 100644
index 0000000..ff48164
--- /dev/null
+++ b/OvmfPkg/SmbiosPlatformDxe/QemuType1.c
@@ -0,0 +1,178 @@
+/** @file
+  Install the default Type 1 SMBIOS table if QEMU doesn't provide one through
+  the firmware configuration interface.
+
+  Copyright (C) 2013, Red Hat, Inc.
+
+  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 "QemuLegacyInternal.h"
+
+
+//
+// Text strings (unformatted area) for the default Tpe 1 SMBIOS table.
+//
+// All possible strings must be provided because Smbios->UpdateString() can
+// only update existing strings, it can't introduce new ones.
+//
+#define OVMF_TYPE1_STRINGS                            \
+          "QEMU\0"                 /* Manufacturer */ \
+          "QEMU Virtual Machine\0" /* ProductName */  \
+          "n/a\0"                  /* Version */      \
+          "n/a\0"                  /* SerialNumber */ \
+          "n/a\0"                  /* SKUNumber */    \
+          "n/a\0"                  /* Family */
+
+
+//
+// Type definition and contents of the default Type 1 SMBIOS table.
+//
+#pragma pack(1)
+OVMF_SMBIOS (1);
+#pragma pack()
+
+STATIC CONST OVMF_TYPE1 mOvmfType1 = {
+  {
+    // SMBIOS_STRUCTURE Hdr
+    {
+      EFI_SMBIOS_TYPE_SYSTEM_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE1)         // UINT8 Length
+    },
+    1,                           // SMBIOS_TABLE_STRING Manufacturer
+    2,                           // SMBIOS_TABLE_STRING ProductName
+    3,                           // SMBIOS_TABLE_STRING Version
+    4,                           // SMBIOS_TABLE_STRING SerialNumber
+    { 0 },                       // GUID                Uuid
+    SystemWakeupTypePowerSwitch, // UINT8               WakeUpType
+    5,                           // SMBIOS_TABLE_STRING SKUNumber
+    6,                           // SMBIOS_TABLE_STRING Family
+  },
+  OVMF_TYPE1_STRINGS
+};
+
+
+/**
+  Install default (fallback) table for SMBIOS Type 1.
+
+  In case QEMU has provided no Type 1 SMBIOS table in whole, prepare one here,
+  patch it with any referring saved patches, and install it.
+
+  @param[in]     Smbios          The EFI_SMBIOS_PROTOCOL instance used for
+                                 installing SMBIOS tables.
+  @param[in]     ProducerHandle  Passed on to Smbios->Add(), ProducerHandle
+                                 tracks the origin of installed SMBIOS tables.
+  @param[in,out] Context         The BUILD_CONTEXT object tracking installed
+                                 tables and saved patches.
+
+  @retval EFI_SUCCESS  A Type 1 table has already been installed from the
+                       SMBIOS firmware configuration blob.
+  @retval EFI_SUCCESS  No Type 1 table was installed previously, and installing
+                       the default here has succeeded.
+  @return              Error codes from the PATCH_FORMATTED() and
+                       PATCH_UNFORMATTED() macros, except EFI_NOT_FOUND, which
+                       is only an informative result of theirs.
+**/
+EFI_STATUS
+EFIAPI
+InstallSmbiosType1 (
+  IN     EFI_SMBIOS_PROTOCOL *Smbios,
+  IN     EFI_HANDLE          ProducerHandle,
+  IN OUT BUILD_CONTEXT       *Context
+  )
+{
+  TABLE_CONTEXT     *Table;
+  OVMF_TYPE1        OvmfType1;
+  EFI_STATUS        Status;
+  EFI_SMBIOS_HANDLE SmbiosHandle;
+
+  Table = &Context->Table[1];
+  if (Table->Installed) {
+    return EFI_SUCCESS;
+  }
+
+  CopyMem (&OvmfType1, &mOvmfType1, sizeof OvmfType1);
+
+  QemuFwCfgSelectItem (QemuFwCfgItemSystemUuid);
+  OvmfType1.Base.Uuid.Data1 = SwapBytes32 (QemuFwCfgRead32 ());
+  OvmfType1.Base.Uuid.Data2 = SwapBytes16 (QemuFwCfgRead16 ());
+  OvmfType1.Base.Uuid.Data3 = SwapBytes16 (QemuFwCfgRead16 ());
+  QemuFwCfgReadBytes (sizeof OvmfType1.Base.Uuid.Data4,
+    &OvmfType1.Base.Uuid.Data4);
+
+  //
+  // Default contents ready. Formatted fields must be patched before installing
+  // the table, while strings in the unformatted area will be patched
+  // afterwards.
+  //
+  Status = PATCH_FORMATTED (Context, 1, &OvmfType1, Uuid);
+  switch (Status) {
+  case EFI_NOT_FOUND:
+    break;
+  case EFI_SUCCESS:
+    OvmfType1.Base.Uuid.Data1 = SwapBytes32 (OvmfType1.Base.Uuid.Data1);
+    OvmfType1.Base.Uuid.Data2 = SwapBytes16 (OvmfType1.Base.Uuid.Data2);
+    OvmfType1.Base.Uuid.Data3 = SwapBytes16 (OvmfType1.Base.Uuid.Data3);
+    break;
+  default:
+    return Status;
+  }
+
+  Status = PATCH_FORMATTED (Context, 1, &OvmfType1, WakeUpType);
+  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
+    return Status;
+  }
+
+  //
+  // Install SMBIOS table with patched formatted area and default strings.
+  //
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios->Add (Smbios, ProducerHandle, &SmbiosHandle,
+                     (EFI_SMBIOS_TABLE_HEADER *) &OvmfType1);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Smbios->Add(): %r\n", __FUNCTION__, Status));
+    return Status;
+  }
+  Table->Installed = TRUE;
+
+  //
+  // Patch strings in the unformatted area of the installed table.
+  //
+  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
+             Manufacturer);
+  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
+    return Status;
+  }
+  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
+             ProductName);
+  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
+    return Status;
+  }
+  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
+             Version);
+  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
+    return Status;
+  }
+  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
+             SerialNumber);
+  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
+    return Status;
+  }
+  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
+             SKUNumber);
+  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
+    return Status;
+  }
+  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
+             Family);
+  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
+    return Status;
+  }
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
index 3483b9c..1f7dfca 100644
--- a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+++ b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
@@ -38,6 +38,7 @@
   X86Xen.c
   QemuLegacy.c
   QemuType0.c
+  QemuType1.c
 
 [Sources.ARM, Sources.AARCH64]
   ArmXen.c
-- 
1.8.3.1