OvmfPkg: AcpiPlatformDxe: pass FwCfgFile to InstallQemuLinkedTables()

Split InstallQemuLinkedTables() in two:
- the function now takes the name of the fw_cfg file (from which ACPI
  tables are to be extracted) as a parameter,

- the new function InstallAllQemuLinkedTables() calls the former with
  fw_cfg file names, and cumulatively tracks the ACPI tables installed by
  all invocations of the former.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-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@15572 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Laszlo Ersek 2014-06-19 06:13:12 +00:00 committed by jljusten
parent 6a904296e4
commit 2d1fe95066
3 changed files with 116 additions and 51 deletions

View File

@ -257,7 +257,7 @@ AcpiPlatformEntryPoint (
if (XenDetected ()) { if (XenDetected ()) {
Status = InstallXenTables (AcpiTable); Status = InstallXenTables (AcpiTable);
} else { } else {
Status = InstallQemuLinkedTables (AcpiTable); Status = InstallAllQemuLinkedTables (AcpiTable);
} }
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {

View File

@ -63,7 +63,7 @@ InstallXenTables (
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
InstallQemuLinkedTables ( InstallAllQemuLinkedTables (
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
); );
#endif #endif

View File

@ -3,7 +3,7 @@
Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR> Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (C) 2012, Red Hat, Inc. Copyright (C) 2012-2014, Red Hat, Inc.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
@ -516,50 +516,78 @@ QemuInstallAcpiTable (
} }
/**
Download the ACPI table data file from QEMU and interpret it.
@param[in] AcpiProtocol The ACPI table protocol used to install tables.
@retval EFI_UNSUPPORTED Firmware configuration is unavailable.
@retval EFI_NOT_FOUND The host doesn't export the required fw_cfg
files.
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.
@retval EFI_PROTOCOL_ERROR Found truncated or invalid ACPI table header
in the fw_cfg contents.
@return Status codes returned by
AcpiProtocol->InstallAcpiTable().
**/
// //
// We'll be saving the keys of installed tables so that we can roll them back // We'll be saving the keys of installed tables so that we can roll them back
// in case of failure. 128 tables should be enough for anyone (TM). // in case of failure. 128 tables should be enough for anyone (TM).
// //
#define INSTALLED_TABLES_MAX 128 #define INSTALLED_TABLES_MAX 128
/**
Download one ACPI table data file from QEMU and interpret it.
@param[in] FwCfgFile The NUL-terminated name of the fw_cfg file to
download and interpret.
@param[in] AcpiProtocol The ACPI table protocol used to install tables.
@param[in,out] InstalledKey On input, an array of INSTALLED_TABLES_MAX UINTN
elements, allocated by the caller. On output,
the function will have stored (appended) the
AcpiProtocol-internal keys of the ACPI tables
that the function has installed from the fw_cfg
file. The array reflects installed tables even
if the function returns with an error.
@param[in,out] NumInstalled On input, the number of entries already used in
InstalledKey; it must be in [0,
INSTALLED_TABLES_MAX] inclusive. On output, the
parameter is updated to the new cumulative count
of the keys stored in InstalledKey; the value
reflects installed tables even if the function
returns with an error.
@retval EFI_INVALID_PARAMETER NumInstalled is outside the allowed range on
input.
@retval EFI_UNSUPPORTED Firmware configuration is unavailable.
@retval EFI_NOT_FOUND The host doesn't export the requested fw_cfg
file.
@retval EFI_OUT_OF_RESOURCES Memory allocation failed, or no more room in
InstalledKey.
@retval EFI_PROTOCOL_ERROR Found truncated or invalid ACPI table header
in the fw_cfg contents.
@return Status codes returned by
AcpiProtocol->InstallAcpiTable().
**/
STATIC
EFI_STATUS EFI_STATUS
EFIAPI
InstallQemuLinkedTables ( InstallQemuLinkedTables (
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol IN CONST CHAR8 *FwCfgFile,
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
IN OUT UINTN InstalledKey[INSTALLED_TABLES_MAX],
IN OUT INT32 *NumInstalled
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
FIRMWARE_CONFIG_ITEM TablesFile; FIRMWARE_CONFIG_ITEM TablesFile;
UINTN TablesFileSize; UINTN TablesFileSize;
UINT8 *Tables; UINT8 *Tables;
UINTN *InstalledKey;
UINTN Processed; UINTN Processed;
INT32 Installed;
Status = QemuFwCfgFindFile ("etc/acpi/tables", &TablesFile, &TablesFileSize); if (*NumInstalled < 0 || *NumInstalled > INSTALLED_TABLES_MAX) {
return EFI_INVALID_PARAMETER;
}
Status = QemuFwCfgFindFile (FwCfgFile, &TablesFile, &TablesFileSize);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "%a: \"etc/acpi/tables\" interface unavailable: %r\n", DEBUG ((EFI_D_ERROR, "%a: \"%a\" unavailable: %r\n", __FUNCTION__,
__FUNCTION__, Status)); FwCfgFile, Status));
return Status; return Status;
} }
@ -571,14 +599,7 @@ InstallQemuLinkedTables (
QemuFwCfgSelectItem (TablesFile); QemuFwCfgSelectItem (TablesFile);
QemuFwCfgReadBytes (TablesFileSize, Tables); QemuFwCfgReadBytes (TablesFileSize, Tables);
InstalledKey = AllocatePool (INSTALLED_TABLES_MAX * sizeof *InstalledKey);
if (InstalledKey == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto FreeTables;
}
Processed = 0; Processed = 0;
Installed = 0;
while (Processed < TablesFileSize) { while (Processed < TablesFileSize) {
UINTN Remaining; UINTN Remaining;
EFI_ACPI_DESCRIPTION_HEADER *Probe; EFI_ACPI_DESCRIPTION_HEADER *Probe;
@ -595,9 +616,9 @@ InstallQemuLinkedTables (
break; break;
} }
DEBUG ((EFI_D_VERBOSE, "%a: offset 0x%016Lx:" DEBUG ((EFI_D_VERBOSE, "%a: \"%a\" offset 0x%016Lx:"
" Signature=\"%-4.4a\" Length=0x%08x\n", " Signature=\"%-4.4a\" Length=0x%08x\n",
__FUNCTION__, (UINT64) Processed, __FUNCTION__, FwCfgFile, (UINT64) Processed,
(CONST CHAR8 *) &Probe->Signature, Probe->Length)); (CONST CHAR8 *) &Probe->Signature, Probe->Length));
// //
@ -607,7 +628,7 @@ InstallQemuLinkedTables (
EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE && EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
Probe->Signature != Probe->Signature !=
EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) { EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
if (Installed == INSTALLED_TABLES_MAX) { if (*NumInstalled == INSTALLED_TABLES_MAX) {
DEBUG ((EFI_D_ERROR, "%a: can't install more than %d tables\n", DEBUG ((EFI_D_ERROR, "%a: can't install more than %d tables\n",
__FUNCTION__, INSTALLED_TABLES_MAX)); __FUNCTION__, INSTALLED_TABLES_MAX));
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
@ -615,16 +636,16 @@ InstallQemuLinkedTables (
} }
Status = AcpiProtocol->InstallAcpiTable (AcpiProtocol, Probe, Status = AcpiProtocol->InstallAcpiTable (AcpiProtocol, Probe,
Probe->Length, &InstalledKey[Installed]); Probe->Length, &InstalledKey[*NumInstalled]);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, DEBUG ((EFI_D_ERROR,
"%a: failed to install table \"%-4.4a\" at offset 0x%Lx: %r\n", "%a: failed to install table \"%-4.4a\" at \"%a\" offset 0x%Lx: "
__FUNCTION__, (CONST CHAR8 *) &Probe->Signature, (UINT64) Processed, "%r\n", __FUNCTION__, (CONST CHAR8 *)&Probe->Signature, FwCfgFile,
Status)); (UINT64) Processed, Status));
break; break;
} }
++Installed; ++*NumInstalled;
} }
Processed += Probe->Length; Processed += Probe->Length;
@ -642,16 +663,62 @@ InstallQemuLinkedTables (
} }
if (Processed < TablesFileSize) { if (Processed < TablesFileSize) {
DEBUG ((EFI_D_ERROR, "%a: truncated or invalid ACPI table header at " DEBUG ((EFI_D_ERROR, "%a: truncated or invalid ACPI table header at "
"offset 0x%Lx\n", __FUNCTION__, (UINT64) ErrorLocation)); "\"%a\" offset 0x%Lx\n", __FUNCTION__, FwCfgFile,
(UINT64)ErrorLocation));
} }
} }
if (Processed == TablesFileSize) { if (Processed == TablesFileSize) {
DEBUG ((EFI_D_INFO, "%a: installed %d tables\n", __FUNCTION__, Installed));
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
} else { } else {
ASSERT (EFI_ERROR (Status)); ASSERT (EFI_ERROR (Status));
}
FreePool (Tables);
return Status;
}
/**
Download all ACPI table data files from QEMU and interpret them.
@param[in] AcpiProtocol The ACPI table protocol used to install tables.
@retval EFI_UNSUPPORTED Firmware configuration is unavailable.
@retval EFI_NOT_FOUND The host doesn't export the required fw_cfg
files.
@retval EFI_OUT_OF_RESOURCES Memory allocation failed, or more than
INSTALLED_TABLES_MAX tables found.
@retval EFI_PROTOCOL_ERROR Found truncated or invalid ACPI table header
in the fw_cfg contents.
@return Status codes returned by
AcpiProtocol->InstallAcpiTable().
**/
EFI_STATUS
EFIAPI
InstallAllQemuLinkedTables (
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
)
{
UINTN *InstalledKey;
INT32 Installed;
EFI_STATUS Status;
InstalledKey = AllocatePool (INSTALLED_TABLES_MAX * sizeof *InstalledKey);
if (InstalledKey == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Installed = 0;
Status = InstallQemuLinkedTables ("etc/acpi/tables", AcpiProtocol,
InstalledKey, &Installed);
if (EFI_ERROR (Status)) {
ASSERT (Status != EFI_INVALID_PARAMETER);
// //
// Roll back partial installation. // Roll back partial installation.
// //
@ -659,12 +726,10 @@ InstallQemuLinkedTables (
--Installed; --Installed;
AcpiProtocol->UninstallAcpiTable (AcpiProtocol, InstalledKey[Installed]); AcpiProtocol->UninstallAcpiTable (AcpiProtocol, InstalledKey[Installed]);
} }
} else {
DEBUG ((EFI_D_INFO, "%a: installed %d tables\n", __FUNCTION__, Installed));
} }
FreePool (InstalledKey); FreePool (InstalledKey);
FreeTables:
FreePool (Tables);
return Status; return Status;
} }