From 26146b77f6d54c44fbb984bacf8bf31683e8d477 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Wed, 5 Jun 2013 10:25:13 +0200 Subject: [PATCH 2/3] OvmfPkg/SmbiosPlatformDxe: install+patch default legacy type0 table (X86) Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek --- OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c | 5 +- OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h | 30 ++++ OvmfPkg/SmbiosPlatformDxe/QemuType0.c | 180 ++++++++++++++++++++++++ OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 1 + 4 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 OvmfPkg/SmbiosPlatformDxe/QemuType0.c diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c index 9c57558..ed75a01 100644 --- a/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c +++ b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c @@ -628,7 +628,10 @@ InstallDefaultTables ( IN OUT BUILD_CONTEXT *Context ) { - return EFI_SUCCESS; + EFI_STATUS Status; + + Status = InstallSmbiosType0 (Smbios, ProducerHandle, Context); + return Status; } diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h b/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h index 8613407..ca776b5 100644 --- a/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h +++ b/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h @@ -218,4 +218,34 @@ PatchSmbiosUnformatted ( IN UINT8 *TableBase ); + +/** + Install default (fallback) table for SMBIOS Type 0. + + In case QEMU has provided no Type 0 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 0 table has already been installed from the + SMBIOS firmware configuration blob. + @retval EFI_SUCCESS No Type 0 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 +InstallSmbiosType0 ( + IN EFI_SMBIOS_PROTOCOL *Smbios, + IN EFI_HANDLE ProducerHandle, + IN OUT BUILD_CONTEXT *Context + ); + #endif diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuType0.c b/OvmfPkg/SmbiosPlatformDxe/QemuType0.c new file mode 100644 index 0000000..9ec5d76 --- /dev/null +++ b/OvmfPkg/SmbiosPlatformDxe/QemuType0.c @@ -0,0 +1,180 @@ +/** @file + Install the default Type 0 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 0 SMBIOS table. +// +// All possible strings must be provided because Smbios->UpdateString() can +// only update existing strings, it can't introduce new ones. +// +#define OVMF_TYPE0_STRINGS \ + "EFI Development Kit II / OVMF\0" /* Vendor */ \ + "0.1\0" /* BiosVersion */ \ + "06/03/2013\0" /* BiosReleaseDate */ + + +// +// Type definition and contents of the default Type 0 SMBIOS table. +// +#pragma pack(1) +OVMF_SMBIOS (0); +#pragma pack() + +STATIC CONST OVMF_TYPE0 mOvmfType0 = { + { + // SMBIOS_STRUCTURE Hdr + { + EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type + sizeof (SMBIOS_TABLE_TYPE0) // UINT8 Length + }, + 1, // SMBIOS_TABLE_STRING Vendor + 2, // SMBIOS_TABLE_STRING BiosVersion + 0xE800,// UINT16 BiosSegment + 3, // SMBIOS_TABLE_STRING BiosReleaseDate + 0, // UINT8 BiosSize + { 0 }, // MISC_BIOS_CHARACTERISTICS BiosCharacteristics + { 0 }, // UINT8 BIOSCharacteristicsExtensionBytes[2] + 0, // UINT8 SystemBiosMajorRelease + 1, // UINT8 SystemBiosMinorRelease + 0xFF, // UINT8 EmbeddedControllerFirmwareMajorRelease + 0xFF // UINT8 EmbeddedControllerFirmwareMinorRelease + }, + OVMF_TYPE0_STRINGS +}; + + +/** + Install default (fallback) table for SMBIOS Type 0. + + In case QEMU has provided no Type 0 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 0 table has already been installed from the + SMBIOS firmware configuration blob. + @retval EFI_SUCCESS No Type 0 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 +InstallSmbiosType0 ( + IN EFI_SMBIOS_PROTOCOL *Smbios, + IN EFI_HANDLE ProducerHandle, + IN OUT BUILD_CONTEXT *Context + ) +{ + TABLE_CONTEXT *Table; + OVMF_TYPE0 OvmfType0; + MISC_BIOS_CHARACTERISTICS_EXTENSION *Ext; + EFI_STATUS Status; + EFI_SMBIOS_HANDLE SmbiosHandle; + + Table = &Context->Table[0]; + if (Table->Installed) { + return EFI_SUCCESS; + } + + CopyMem (&OvmfType0, &mOvmfType0, sizeof OvmfType0); + Ext = (VOID *) &OvmfType0.Base.BIOSCharacteristicsExtensionBytes[0]; + + OvmfType0.Base.BiosCharacteristics.BiosCharacteristicsNotSupported = 1; + Ext->SystemReserved.UefiSpecificationSupported = 1; + Ext->SystemReserved.VirtualMachineSupported = 1; + + // + // 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, 0, &OvmfType0, BiosSegment); + if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) { + return Status; + } + Status = PATCH_FORMATTED (Context, 0, &OvmfType0, BiosSize); + if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) { + return Status; + } + Status = PATCH_FORMATTED (Context, 0, &OvmfType0, BiosCharacteristics); + if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) { + return Status; + } + Status = PATCH_FORMATTED (Context, 0, &OvmfType0, + BIOSCharacteristicsExtensionBytes); + if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) { + return Status; + } + Status = PATCH_FORMATTED (Context, 0, &OvmfType0, SystemBiosMajorRelease); + if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) { + return Status; + } + Status = PATCH_FORMATTED (Context, 0, &OvmfType0, SystemBiosMinorRelease); + if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) { + return Status; + } + Status = PATCH_FORMATTED (Context, 0, &OvmfType0, + EmbeddedControllerFirmwareMajorRelease); + if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) { + return Status; + } + Status = PATCH_FORMATTED (Context, 0, &OvmfType0, + EmbeddedControllerFirmwareMinorRelease); + 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 *) &OvmfType0); + 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, 0, &OvmfType0, + Vendor); + if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) { + return Status; + } + Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 0, &OvmfType0, + BiosVersion); + if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) { + return Status; + } + Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 0, &OvmfType0, + BiosReleaseDate); + 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 8c9f43c..3483b9c 100644 --- a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf +++ b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf @@ -37,6 +37,7 @@ [Sources.IA32, Sources.X64] X86Xen.c QemuLegacy.c + QemuType0.c [Sources.ARM, Sources.AARCH64] ArmXen.c -- 1.8.3.1