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