/** @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
mEfiAcpiMaxNumTables = NewMaxTableNumber;\r
return EFI_SUCCESS;\r
}\r
+\r
+/**\r
+ Determine whether the FADT table passed in as parameter requires mutual\r
+ exclusion between the DSDT and X_DSDT fields. (That is, whether there exists\r
+ an explicit requirement that at most one of those fields is permitted to be\r
+ nonzero.)\r
+\r
+ @param[in] Fadt The EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE object to\r
+ check.\r
+\r
+ @retval TRUE Fadt requires mutual exclusion between DSDT and X_DSDT.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+RequireDsdtXDsdtExclusion (\r
+ IN EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt\r
+ )\r
+{\r
+ //\r
+ // Mantis ticket #1393 was addressed in ACPI 5.1 Errata B. Unfortunately, we\r
+ // can't tell apart 5.1 Errata A and 5.1 Errata B just from looking at the\r
+ // FADT table. Therefore let's require exclusion for table versions >= 5.1.\r
+ //\r
+ // While this needlessly covers 5.1 and 5.1A too, it is safer to require\r
+ // DSDT<->X_DSDT exclusion for lax (5.1, 5.1A) versions of the spec than to\r
+ // permit DSDT<->X_DSDT duplication for strict (5.1B) versions of the spec.\r
+ //\r
+ // The same applies to 6.0 vs. 6.0A. While 6.0 does not require the\r
+ // exclusion, 6.0A and 6.1 do. Since we cannot distinguish 6.0 from 6.0A\r
+ // based on just the FADT, we lump 6.0 in with the rest of >= 5.1.\r
+ //\r
+ if ((Fadt->Header.Revision < 5) ||\r
+ ((Fadt->Header.Revision == 5) &&\r
+ (((EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE *)Fadt)->MinorVersion == 0))) {\r
+ //\r
+ // version <= 5.0\r
+ //\r
+ return FALSE;\r
+ }\r
+ //\r
+ // version >= 5.1\r
+ //\r
+ return TRUE;\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
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
+ if (RequireDsdtXDsdtExclusion (AcpiTableInstance->Fadt3)) {\r
+ Buffer64 = 0;\r
+ } else {\r
+ Buffer64 = AcpiTableInstance->Fadt3->Dsdt;\r
+ }\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
//\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
+ if (RequireDsdtXDsdtExclusion (AcpiTableInstance->Fadt3)) {\r
+ Buffer64 = 0;\r
+ } else {\r
+ Buffer64 = AcpiTableInstance->Fadt3->Dsdt;\r
+ }\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
//\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