summaryrefslogtreecommitdiff
path: root/OvmfPkg/AcpiPlatformDxe/Qemu.c
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2014-06-19 06:13:29 +0000
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2014-06-19 06:13:29 +0000
commita618eaa1f45d53073784460ec2c8d9c3d097b789 (patch)
tree773de2c5903544ff093cce15190552bff4da9ec2 /OvmfPkg/AcpiPlatformDxe/Qemu.c
parent374df8fc59622f78de0cefaf073c44076cc44f7e (diff)
downloadedk2-platforms-a618eaa1f45d53073784460ec2c8d9c3d097b789.tar.xz
OvmfPkg: AcpiPlatformDxe: don't rely on unstable QEMU interface
The fw_cfg file "etc/acpi/tables" is not a stable guest interface -- QEMU could rename it in the future, and/or introduce additional fw_cfg files with ACPI payload. Only the higher-level "etc/table-loader" file is considered stable, which contains a sequence of commands to assist firmware with reading QEMU ACPI tables from the FwCfg interface. Because edk2 provides publishing support for ACPI tables, OVMF only uses the Allocate command to find the names of FwCfg files to read and publish as ACPI tables. 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@15574 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'OvmfPkg/AcpiPlatformDxe/Qemu.c')
-rw-r--r--OvmfPkg/AcpiPlatformDxe/Qemu.c54
1 files changed, 49 insertions, 5 deletions
diff --git a/OvmfPkg/AcpiPlatformDxe/Qemu.c b/OvmfPkg/AcpiPlatformDxe/Qemu.c
index 5a96d76a1f..70f3ff6426 100644
--- a/OvmfPkg/AcpiPlatformDxe/Qemu.c
+++ b/OvmfPkg/AcpiPlatformDxe/Qemu.c
@@ -16,6 +16,7 @@
**/
#include "AcpiPlatform.h"
+#include "QemuLoader.h"
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/QemuFwCfgLib.h>
@@ -795,8 +796,7 @@ InstallQemuLinkedTables (
@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.
+ @retval EFI_PROTOCOL_ERROR Found invalid fw_cfg contents.
@return Status codes returned by
AcpiProtocol->InstallAcpiTable().
@@ -812,6 +812,10 @@ InstallAllQemuLinkedTables (
UINTN *InstalledKey;
INT32 Installed;
EFI_STATUS Status;
+ FIRMWARE_CONFIG_ITEM LoaderItem;
+ UINTN LoaderSize;
+ UINT8 *Loader;
+ QEMU_LOADER_ENTRY *Entry, *End;
InstalledKey = AllocatePool (INSTALLED_TABLES_MAX * sizeof *InstalledKey);
if (InstalledKey == NULL) {
@@ -819,10 +823,49 @@ InstallAllQemuLinkedTables (
}
Installed = 0;
- Status = InstallQemuLinkedTables ("etc/acpi/tables", AcpiProtocol,
- InstalledKey, &Installed);
+ Status = QemuFwCfgFindFile ("etc/table-loader", &LoaderItem, &LoaderSize);
+ if (EFI_ERROR (Status)) {
+ goto FreeInstalledKey;
+ }
+ if (LoaderSize % sizeof *Entry != 0) {
+ Status = EFI_PROTOCOL_ERROR;
+ goto FreeInstalledKey;
+ }
+
+ Loader = AllocatePool (LoaderSize);
+ if (Loader == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeInstalledKey;
+ }
+
+ QemuFwCfgSelectItem (LoaderItem);
+ QemuFwCfgReadBytes (LoaderSize, Loader);
+
+ Entry = (QEMU_LOADER_ENTRY *)Loader;
+ End = (QEMU_LOADER_ENTRY *)(Loader + LoaderSize);
+ while (Entry < End) {
+ if (Entry->Type == QemuLoaderCmdAllocate) {
+ QEMU_LOADER_ALLOCATE *Allocate;
+
+ Allocate = &Entry->Command.Allocate;
+ if (Allocate->File[sizeof Allocate->File - 1] != '\0') {
+ Status = EFI_PROTOCOL_ERROR;
+ break;
+ }
+
+ Status = InstallQemuLinkedTables ((CHAR8 *)Allocate->File, AcpiProtocol,
+ InstalledKey, &Installed);
+ if (EFI_ERROR (Status)) {
+ ASSERT (Status != EFI_INVALID_PARAMETER);
+ break;
+ }
+ }
+ ++Entry;
+ }
+
+ FreePool (Loader);
+
if (EFI_ERROR (Status)) {
- ASSERT (Status != EFI_INVALID_PARAMETER);
//
// Roll back partial installation.
//
@@ -834,6 +877,7 @@ InstallAllQemuLinkedTables (
DEBUG ((EFI_D_INFO, "%a: installed %d tables\n", __FUNCTION__, Installed));
}
+FreeInstalledKey:
FreePool (InstalledKey);
return Status;
}