]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
MdeModulePkg/AcpiTableDxe: Not make FADT.{DSDT,X_DSDT} mutual exclusion
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / AcpiTableDxe / AcpiTableProtocol.c
index 7795ff7269cab1341874c9ca795315efc0b5a170..a4fd9aff845d654c4c0bb748500d1883aa76af28 100644 (file)
@@ -430,6 +430,7 @@ ReallocateAcpiTableBuffer (
   mEfiAcpiMaxNumTables = NewMaxTableNumber;\r
   return EFI_SUCCESS;\r
 }\r
+\r
 /**\r
   This function adds an ACPI table to the table list.  It will detect FACS and\r
   allocate the correct type of memory and properly align the table.\r
@@ -647,12 +648,28 @@ AddTableToList (
       }\r
       if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {\r
         AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\r
-        ZeroMem (&AcpiTableInstance->Fadt3->XDsdt, sizeof (UINT64));\r
+        //\r
+        // Comment block "the caller installs the tables in "DSDT, FADT" order"\r
+        // The below comments are also in "the caller installs the tables in "FADT, DSDT" order" comment block.\r
+        //\r
+        // The ACPI specification, up to and including revision 5.1 Errata A,\r
+        // allows the DSDT and X_DSDT fields to be both set in the FADT.\r
+        // (Obviously, this only makes sense if the DSDT address is representable in 4 bytes.)\r
+        // Starting with 5.1 Errata B, specifically for Mantis 1393 <https://mantis.uefi.org/mantis/view.php?id=1393>,\r
+        // the spec requires at most one of DSDT and X_DSDT fields to be set to a nonzero value,\r
+        // but strangely an exception is 6.0 that has no this requirement.\r
+        //\r
+        // Here we do not make the DSDT and X_DSDT fields mutual exclusion conditionally\r
+        // by checking FADT revision, but always set both DSDT and X_DSDT fields in the FADT\r
+        // to have better compatibility as some OS may have assumption to only consume X_DSDT\r
+        // field even the DSDT address is < 4G.\r
+        //\r
+        Buffer64 = AcpiTableInstance->Fadt3->Dsdt;\r
       } else {\r
         AcpiTableInstance->Fadt3->Dsdt = 0;\r
         Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
-        CopyMem (&AcpiTableInstance->Fadt3->XDsdt, &Buffer64, sizeof (UINT64));\r
       }\r
+      CopyMem (&AcpiTableInstance->Fadt3->XDsdt, &Buffer64, sizeof (UINT64));\r
 \r
       //\r
       // RSDP OEM information is updated to match the FADT OEM information\r
@@ -847,8 +864,27 @@ AddTableToList (
       if (AcpiTableInstance->Fadt3 != NULL) {\r
         if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {\r
           AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\r
+          //\r
+          // Comment block "the caller installs the tables in "FADT, DSDT" order"\r
+          // The below comments are also in "the caller installs the tables in "DSDT, FADT" order" comment block.\r
+          //\r
+          // The ACPI specification, up to and including revision 5.1 Errata A,\r
+          // allows the DSDT and X_DSDT fields to be both set in the FADT.\r
+          // (Obviously, this only makes sense if the DSDT address is representable in 4 bytes.)\r
+          // Starting with 5.1 Errata B, specifically for Mantis 1393 <https://mantis.uefi.org/mantis/view.php?id=1393>,\r
+          // the spec requires at most one of DSDT and X_DSDT fields to be set to a nonzero value,\r
+          // but strangely an exception is 6.0 that has no this requirement.\r
+          //\r
+          // Here we do not make the DSDT and X_DSDT fields mutual exclusion conditionally\r
+          // by checking FADT revision, but always set both DSDT and X_DSDT fields in the FADT\r
+          // to have better compatibility as some OS may have assumption to only consume X_DSDT\r
+          // field even the DSDT address is < 4G.\r
+          //\r
+          Buffer64 = AcpiTableInstance->Fadt3->Dsdt;\r
+        } else {\r
+          AcpiTableInstance->Fadt3->Dsdt = 0;\r
+          Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
         }\r
-        Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
         CopyMem (&AcpiTableInstance->Fadt3->XDsdt, &Buffer64, sizeof (UINT64));\r
 \r
         //\r