]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / AcpiTableDxe / AcpiTableProtocol.c
index 7f95b9dc709d595a8802caac00711053bf46b54e..ad7baf8205b4826cc31a21f2972e2ae96ca5aef7 100644 (file)
@@ -1,15 +1,9 @@
 /** @file\r
   ACPI Table Protocol Implementation\r
 \r
-  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2018, 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
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -18,9 +12,9 @@
 //\r
 #include "AcpiTable.h"\r
 //\r
-// The maximum number of tables that pre-allocated. \r
+// The maximum number of tables that pre-allocated.\r
 //\r
-UINTN         mEfiAcpiMaxNumTables = EFI_ACPI_MAX_NUM_TABLES; \r
+UINTN         mEfiAcpiMaxNumTables = EFI_ACPI_MAX_NUM_TABLES;\r
 \r
 //\r
 // Allocation strategy to use for AllocatePages ().\r
@@ -196,7 +190,7 @@ PublishTables (
   @param  TableKey             Reurns a key to refer to the ACPI table.\r
 \r
   @return EFI_SUCCESS            The table was successfully inserted.\r
-  @return EFI_INVALID_PARAMETER  Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize \r
+  @return EFI_INVALID_PARAMETER  Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize\r
                                  and the size field embedded in the ACPI table pointed to by AcpiTableBuffer\r
                                  are not in sync.\r
   @return EFI_OUT_OF_RESOURCES   Insufficient resources exist to complete the request.\r
@@ -253,7 +247,7 @@ InstallAcpiTable (
                );\r
   }\r
   FreePool (AcpiTableBufferConst);\r
-  \r
+\r
   //\r
   // Add a new table successfully, notify registed callback\r
   //\r
@@ -290,24 +284,27 @@ UninstallAcpiTable (
 {\r
   EFI_ACPI_TABLE_INSTANCE   *AcpiTableInstance;\r
   EFI_STATUS                Status;\r
+  EFI_ACPI_TABLE_VERSION    Version;\r
 \r
   //\r
   // Get the instance of the ACPI table protocol\r
   //\r
   AcpiTableInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This);\r
 \r
+  Version = PcdGet32 (PcdAcpiExposedTableVersions);\r
+\r
   //\r
   // Uninstall the ACPI table\r
   //\r
   Status = RemoveTableFromList (\r
              AcpiTableInstance,\r
-             EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0,\r
+             Version,\r
              TableKey\r
              );\r
   if (!EFI_ERROR (Status)) {\r
     Status = PublishTables (\r
                AcpiTableInstance,\r
-               EFI_ACPI_TABLE_VERSION_1_0B | ACPI_TABLE_VERSION_GTE_2_0\r
+               Version\r
                );\r
   }\r
 \r
@@ -339,8 +336,8 @@ ReallocateAcpiTableBuffer (
   EFI_ACPI_TABLE_INSTANCE  TempPrivateData;\r
   EFI_STATUS               Status;\r
   UINT64                   CurrentData;\r
-   \r
-  CopyMem (&TempPrivateData, AcpiTableInstance, sizeof (EFI_ACPI_TABLE_INSTANCE)); \r
+\r
+  CopyMem (&TempPrivateData, AcpiTableInstance, sizeof (EFI_ACPI_TABLE_INSTANCE));\r
   //\r
   // Enlarge the max table number from mEfiAcpiMaxNumTables to mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES\r
   //\r
@@ -381,7 +378,7 @@ ReallocateAcpiTableBuffer (
 \r
   Pointer = (UINT8 *) (UINTN) PageAddress;\r
   ZeroMem (Pointer, TotalSize);\r
-  \r
+\r
   AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
   if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
     Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));\r
@@ -401,14 +398,14 @@ ReallocateAcpiTableBuffer (
   CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));\r
 \r
   //\r
-  // copy the original Rsdt1, Rsdt3 and Xsdt structure to new buffer \r
+  // copy the original Rsdt1, Rsdt3 and Xsdt structure to new buffer\r
   //\r
   if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
-    CopyMem (AcpiTableInstance->Rsdt1, TempPrivateData.Rsdt1, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32))); \r
-    CopyMem (AcpiTableInstance->Rsdt3, TempPrivateData.Rsdt3, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32))); \r
+    CopyMem (AcpiTableInstance->Rsdt1, TempPrivateData.Rsdt1, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32)));\r
+    CopyMem (AcpiTableInstance->Rsdt3, TempPrivateData.Rsdt3, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32)));\r
   }\r
   CopyMem (AcpiTableInstance->Xsdt, TempPrivateData.Xsdt, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT64)));\r
-  \r
+\r
   //\r
   // Calculate orignal ACPI table buffer size\r
   //\r
@@ -423,13 +420,14 @@ ReallocateAcpiTableBuffer (
   }\r
 \r
   gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)TempPrivateData.Rsdt1, EFI_SIZE_TO_PAGES (TotalSize));\r
-  \r
+\r
   //\r
   // Update the Max ACPI table number\r
-  // \r
+  //\r
   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
@@ -504,7 +502,7 @@ AddTableToList (
   //\r
   // Allocation memory type depends on the type of the table\r
   //\r
-  if ((CurrentTableSignature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) || \r
+  if ((CurrentTableSignature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||\r
       (CurrentTableSignature == EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE)) {\r
     //\r
     // Allocate memory for the FACS.  This structure must be aligned\r
@@ -630,7 +628,7 @@ AddTableToList (
 \r
       //\r
       // Update pointers in FADT.  If tables don't exist this will put NULL pointers there.\r
-      // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and \r
+      // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and\r
       // vice-versa.\r
       //\r
       if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {\r
@@ -646,17 +644,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
@@ -666,7 +676,7 @@ AddTableToList (
         &AcpiTableInstance->Fadt3->Header.OemId,\r
         6\r
         );\r
-      \r
+\r
       if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
         //\r
         // RSDT OEM information is updated to match FADT OEM information.\r
@@ -698,7 +708,7 @@ AddTableToList (
         sizeof (UINT64)\r
         );\r
       AcpiTableInstance->Xsdt->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;\r
-    }    \r
+    }\r
     //\r
     // Checksum the table\r
     //\r
@@ -766,7 +776,7 @@ AddTableToList (
       //\r
       if (AcpiTableInstance->Fadt3 != NULL) {\r
         //\r
-        // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and \r
+        // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and\r
         // vice-versa.\r
         //\r
         if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {\r
@@ -838,7 +848,7 @@ AddTableToList (
           );\r
       }\r
     }\r
-    \r
+\r
     if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {\r
       //\r
       // Save a pointer to the table\r
@@ -850,14 +860,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
@@ -869,7 +894,7 @@ AddTableToList (
           Checksum)\r
           );\r
       }\r
-    }        \r
+    }\r
     //\r
     // Checksum the table\r
     //\r
@@ -1019,7 +1044,7 @@ AddTableToList (
 \r
   @param  Handle      Table to find.\r
   @param  TableList   Table list to search\r
-  @param  Table       Pointer to table found. \r
+  @param  Table       Pointer to table found.\r
 \r
   @return EFI_SUCCESS    The function completed successfully.\r
   @return EFI_NOT_FOUND  No table found matching the handle specified.\r
@@ -1069,7 +1094,7 @@ FindTableByHandle (
   For Acpi 1.0 tables, pass in the Rsdt.\r
   For Acpi 2.0 tables, pass in both Rsdt and Xsdt.\r
 \r
-  @param  Table                 Pointer to table found. \r
+  @param  Table                 Pointer to table found.\r
   @param  NumberOfTableEntries  Current number of table entries in the RSDT/XSDT\r
   @param  Rsdt                  Pointer to the RSDT to remove from\r
   @param  Xsdt                  Pointer to the Xsdt to remove from\r
@@ -1289,7 +1314,7 @@ DeleteTable (
       // Remove this version from the table\r
       //\r
       Table->Version = Table->Version &~(Version & ACPI_TABLE_VERSION_GTE_2_0);\r
-      \r
+\r
       //\r
       // Remove from Rsdt and Xsdt.  We don't care about the return value\r
       // because it is acceptable for the table to not exist in Rsdt/Xsdt.\r
@@ -1303,7 +1328,7 @@ DeleteTable (
           AcpiTableInstance->Xsdt\r
           );\r
       }\r
-    }    \r
+    }\r
     //\r
     // Free the table, clean up any dependent tables and our private data pointers.\r
     //\r
@@ -1361,7 +1386,7 @@ DeleteTable (
             Checksum)\r
             );\r
         }\r
-      }    \r
+      }\r
       break;\r
 \r
     case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
@@ -1386,7 +1411,7 @@ DeleteTable (
         }\r
       }\r
 \r
-      \r
+\r
       if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {\r
         AcpiTableInstance->Dsdt3 = NULL;\r
 \r
@@ -1609,7 +1634,7 @@ ChecksumCommonTables (
     OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
     Checksum)\r
     );\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r