]> 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 f6229ca05c101ab2bf1ea4f8f7be03c1ab88d1ea..a4fd9aff845d654c4c0bb748500d1883aa76af28 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   ACPI Table Protocol Implementation\r
 \r
-  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
   Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -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
@@ -646,17 +647,29 @@ AddTableToList (
         AcpiTableInstance->Fadt3->FirmwareCtrl = 0;\r
       }\r
       if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {\r
-        AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\r
-        ZeroMem (&AcpiTableInstance->Fadt3->XDsdt, sizeof (UINT64));\r
+        AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\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
-        Buffer64                          = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
-        CopyMem (\r
-          &AcpiTableInstance->Fadt3->XDsdt,\r
-          &Buffer64,\r
-          sizeof (UINT64)\r
-          );\r
         AcpiTableInstance->Fadt3->Dsdt = 0;\r
+        Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
       }\r
+      CopyMem (&AcpiTableInstance->Fadt3->XDsdt, &Buffer64, sizeof (UINT64));\r
 \r
       //\r
       // RSDP OEM information is updated to match the FADT OEM information\r
@@ -850,14 +863,29 @@ AddTableToList (
       //\r
       if (AcpiTableInstance->Fadt3 != NULL) {\r
         if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {\r
-          AcpiTableInstance->Fadt3->Dsdt  = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\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 (\r
-          &AcpiTableInstance->Fadt3->XDsdt,\r
-          &Buffer64,\r
-          sizeof (UINT64)\r
-          );\r
+        CopyMem (&AcpiTableInstance->Fadt3->XDsdt, &Buffer64, sizeof (UINT64));\r
 \r
         //\r
         // Checksum FADT table\r
@@ -1132,7 +1160,7 @@ RemoveTableFromRsdt (
     //\r
     // Check if we have found the corresponding entry in both RSDT and XSDT\r
     //\r
-    if ((CurrentRsdtEntry == NULL || *CurrentRsdtEntry == (UINT32) (UINTN) Table->Table) &&\r
+    if (((Rsdt == NULL) || *CurrentRsdtEntry == (UINT32) (UINTN) Table->Table) &&\r
         ((Xsdt == NULL) || CurrentTablePointer64 == (UINT64) (UINTN) Table->Table)\r
         ) {\r
       //\r