]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: AcpiPlatformDxe: exclude RSD PTR from QEMU's fw_cfg payload
authorLaszlo Ersek <lersek@redhat.com>
Thu, 19 Jun 2014 06:13:22 +0000 (06:13 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 19 Jun 2014 06:13:22 +0000 (06:13 +0000)
In one of the next patches we'll start scanning all fw_cfg files that QEMU
advertises as carrying ACPI tables, not just "etc/acpi/tables".

The RSD PTR table is known to occur in the "etc/acpi/rsdp" fw_cfg file.
Since edk2 handles RSD PTR automatically, similarly to RSDT and XSDT,
let's exclude RSD PTR too from the manually installed 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@15573 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/AcpiPlatformDxe/Qemu.c

index df912c20f80fb0815c8eefe51144922e6fa6f574..5a96d76a1f44df8951ebfb8d9182e85c5aaddbe5 100644 (file)
@@ -516,6 +516,80 @@ QemuInstallAcpiTable (
 }\r
 \r
 \r
+/**\r
+  Check if an array of bytes starts with an RSD PTR structure.\r
+\r
+  Checksum is ignored.\r
+\r
+  @param[in] Buffer     The array to check.\r
+\r
+  @param[in] Size       Number of bytes in Buffer.\r
+\r
+  @param[out] RsdpSize  If the function returns EFI_SUCCESS, this parameter\r
+                        contains the size of the detected RSD PTR structure.\r
+\r
+  @retval  EFI_SUCCESS         RSD PTR structure detected at the beginning of\r
+                               Buffer, and its advertised size does not exceed\r
+                               Size.\r
+\r
+  @retval  EFI_PROTOCOL_ERROR  RSD PTR structure detected at the beginning of\r
+                               Buffer, but it has inconsistent size.\r
+\r
+  @retval  EFI_NOT_FOUND       RSD PTR structure not found.\r
+\r
+**/\r
+\r
+STATIC\r
+EFI_STATUS\r
+CheckRsdp (\r
+  IN  CONST VOID *Buffer,\r
+  IN  UINTN      Size,\r
+  OUT UINTN      *RsdpSize\r
+  )\r
+{\r
+  CONST UINT64                                       *Signature;\r
+  CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp1;\r
+  CONST EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp2;\r
+\r
+  if (Size < sizeof *Signature) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  Signature = Buffer;\r
+\r
+  if (*Signature != EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Signature found -- from this point on we can only report\r
+  // EFI_PROTOCOL_ERROR or EFI_SUCCESS.\r
+  //\r
+  if (Size < sizeof *Rsdp1) {\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
+  Rsdp1 = Buffer;\r
+\r
+  if (Rsdp1->Reserved == 0) {\r
+    //\r
+    // ACPI 1.0 doesn't include the Length field\r
+    //\r
+    *RsdpSize = sizeof *Rsdp1;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (Size < sizeof *Rsdp2) {\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
+  Rsdp2 = Buffer;\r
+\r
+  if (Size < Rsdp2->Length || Rsdp2->Length < sizeof *Rsdp2) {\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
+\r
+  *RsdpSize = Rsdp2->Length;\r
+  return EFI_SUCCESS;\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
@@ -602,9 +676,39 @@ InstallQemuLinkedTables (
   Processed = 0;\r
   while (Processed < TablesFileSize) {\r
     UINTN                       Remaining;\r
+    UINTN                       RsdpSize;\r
     EFI_ACPI_DESCRIPTION_HEADER *Probe;\r
 \r
     Remaining = TablesFileSize - Processed;\r
+\r
+    //\r
+    // See if we're looking at an RSD PTR structure.\r
+    //\r
+    RsdpSize = 0;\r
+    Status = CheckRsdp (Tables + Processed, Remaining, &RsdpSize);\r
+    if (Status == EFI_PROTOCOL_ERROR) {\r
+      //\r
+      // RSD PTR found but its size is inconsistent; abort processing. (Note\r
+      // that "RSD PTR found" excludes the NUL-padding case by definition.)\r
+      //\r
+      break;\r
+    }\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Consistent RSD PTR found, skip it.\r
+      //\r
+      DEBUG ((EFI_D_VERBOSE, "%a: \"%a\" offset 0x%016Lx: RSD PTR "\r
+        "Length=0x%08x\n", __FUNCTION__, FwCfgFile, (UINT64)Processed,\r
+        (UINT32)RsdpSize));\r
+      Processed += RsdpSize;\r
+      continue;\r
+    }\r
+    ASSERT (Status == EFI_NOT_FOUND);\r
+\r
+    //\r
+    // What we're looking at is not an RSD PTR structure; attempt to parse it\r
+    // as an ACPI table.\r
+    //\r
     if (Remaining < sizeof *Probe) {\r
       Status = EFI_PROTOCOL_ERROR;\r
       break;\r