OvmfPkg/SMBIOS: Add QEMU support to OVMF SMBIOS driver

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 infrastructure (already used by
Xen) to handle final SMBIOS table creation.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15542 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Gabriel Somlo 2014-05-20 16:33:19 +00:00 committed by jljusten
parent 6b23d767f6
commit a145e28dec
4 changed files with 101 additions and 5 deletions

View File

@ -0,0 +1,66 @@
/** @file
Find and extract QEMU SMBIOS data from fw_cfg.
Copyright (C) 2014, Gabriel L. Somlo <somlo@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>
/**
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 AnchorSize, TablesSize;
UINT8 *QemuTables;
if (EFI_ERROR (QemuFwCfgFindFile (
"etc/smbios/smbios-anchor", &Anchor, &AnchorSize)) ||
EFI_ERROR (QemuFwCfgFindFile (
"etc/smbios/smbios-tables", &Tables, &TablesSize)) ||
AnchorSize != sizeof (QemuAnchor) ||
TablesSize == 0) {
return NULL;
}
//
// We copy the entry point structure to perform some additional checks,
// but discard it upon return.
//
QemuFwCfgSelectItem (Anchor);
QemuFwCfgReadBytes (AnchorSize, &QemuAnchor);
if (AsciiStrnCmp ((CHAR8 *)QemuAnchor.AnchorString, "_SM_", 4) ||
AsciiStrnCmp ((CHAR8 *)QemuAnchor.IntermediateAnchorString, "_DMI_", 5) ||
TablesSize != QemuAnchor.TableLength) {
return NULL;
}
QemuTables = AllocatePool (TablesSize);
if (QemuTables == NULL) {
return NULL;
}
QemuFwCfgSelectItem (Tables);
QemuFwCfgReadBytes (TablesSize, QemuTables);
return QemuTables;
}

View File

@ -84,20 +84,20 @@ SmbiosTableLength (
Install all structures from the given SMBIOS structures block Install all structures from the given SMBIOS structures block
@param Smbios SMBIOS protocol @param Smbios SMBIOS protocol
@param EntryPointStructure SMBIOS entry point structures block @param TableAddress SMBIOS tables starting address
**/ **/
EFI_STATUS EFI_STATUS
InstallAllStructures ( InstallAllStructures (
IN EFI_SMBIOS_PROTOCOL *Smbios, IN EFI_SMBIOS_PROTOCOL *Smbios,
IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure IN UINT8 *TableAddress
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
SMBIOS_STRUCTURE_POINTER SmbiosTable; SMBIOS_STRUCTURE_POINTER SmbiosTable;
EFI_SMBIOS_HANDLE SmbiosHandle; EFI_SMBIOS_HANDLE SmbiosHandle;
SmbiosTable.Raw = (UINT8*)(UINTN) EntryPointStructure->TableAddress; SmbiosTable.Raw = TableAddress;
if (SmbiosTable.Raw == NULL) { if (SmbiosTable.Raw == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
@ -145,6 +145,7 @@ SmbiosTablePublishEntry (
EFI_STATUS Status; EFI_STATUS Status;
EFI_SMBIOS_PROTOCOL *Smbios; EFI_SMBIOS_PROTOCOL *Smbios;
SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure; SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure;
UINT8 *SmbiosTables;
// //
// Find the SMBIOS protocol // 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 (); EntryPointStructure = GetXenSmbiosTables ();
if (EntryPointStructure != NULL) { 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) {
FreePool (SmbiosTables);
}
} }
return Status; return Status;

View File

@ -25,6 +25,7 @@
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h> #include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
/** /**
@ -39,6 +40,18 @@ GetXenSmbiosTables (
); );
/**
Locates and extracts the QEMU SMBIOS table data if present in fw_cfg
@return Address of extracted QEMU SMBIOS data
**/
UINT8 *
GetQemuSmbiosTables (
VOID
);
/** /**
Validates the SMBIOS entry point structure Validates the SMBIOS entry point structure

View File

@ -32,6 +32,7 @@
SmbiosPlatformDxe.h SmbiosPlatformDxe.h
SmbiosPlatformDxe.c SmbiosPlatformDxe.c
Xen.c Xen.c
Qemu.c
[Packages] [Packages]
MdePkg/MdePkg.dec MdePkg/MdePkg.dec
@ -45,6 +46,8 @@
UefiDriverEntryPoint UefiDriverEntryPoint
DebugLib DebugLib
HobLib HobLib
QemuFwCfgLib
MemoryAllocationLib
[Protocols] [Protocols]
gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED