Skip to content

Commit

Permalink
acpidump: Add DSDT/FACS instance support for Linux and EFI
Browse files Browse the repository at this point in the history
ACPI spec allows to configure different 32-bit/64-bit table addresses for
DSDT and FACS. And for FACS, it's meaningful to dump both of them as they
are used to support different suspend protocols.

While:
1. on Linux, only 1 instance is supported for DSDT/FACS; and
2. on EFI, the code in OslGetTable() is buggy with special table instances,
   causing endless file dump for such tables (reported by Shao Ming in link
   #2).

This patch adds DSDT/FACS instance support for Linux/EFI but doesn't cover
BSD as BSD acpidump needs a full refresh. Fixed by Lv Zheng.

Link: https://bugs.acpica.org/show_bug.cgi?id=1407 [#1]
Link: acpica#285  [#2]
Reported-by: Shao Ming <smbest163@163.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
  • Loading branch information
Lv Zheng committed Jul 13, 2017
1 parent 01b8f5a commit 343fc31
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 50 deletions.
90 changes: 67 additions & 23 deletions source/os_specific/efi/osefitbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ OslListTables (

/* Skip NULL entries in RSDT/XSDT */

if (!TableAddress)
if (TableAddress == 0)
{
continue;
}
Expand Down Expand Up @@ -835,7 +835,8 @@ OslGetTable (
UINT8 NumberOfTables;
UINT8 ItemSize;
UINT32 CurrentInstance = 0;
ACPI_PHYSICAL_ADDRESS TableAddress = 0;
ACPI_PHYSICAL_ADDRESS TableAddress;
ACPI_PHYSICAL_ADDRESS FirstTableAddress = 0;
UINT32 TableLength = 0;
ACPI_STATUS Status = AE_OK;
UINT32 i;
Expand All @@ -849,35 +850,46 @@ OslGetTable (
ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) ||
ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
{

FindNextInstance:

TableAddress = 0;

/*
* Get the appropriate address, either 32-bit or 64-bit. Be very
* careful about the FADT length and validate table addresses.
* Note: The 64-bit addresses have priority.
*/
if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
{
if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) &&
Gbl_Fadt->XDsdt)
if (CurrentInstance < 2)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt;
}
else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) &&
Gbl_Fadt->Dsdt)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt;
if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) &&
Gbl_Fadt->XDsdt && CurrentInstance == 0)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt;
}
else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) &&
Gbl_Fadt->Dsdt != FirstTableAddress)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt;
}
}
}
else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
{
if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) &&
Gbl_Fadt->XFacs)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs;
}
else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) &&
Gbl_Fadt->Facs)
if (CurrentInstance < 2)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs;
if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) &&
Gbl_Fadt->XFacs && CurrentInstance == 0)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs;
}
else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) &&
Gbl_Fadt->Facs != FirstTableAddress)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs;
}
}
}
else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_XSDT))
Expand All @@ -886,16 +898,32 @@ OslGetTable (
{
return (AE_BAD_SIGNATURE);
}
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.XsdtPhysicalAddress;
if (CurrentInstance == 0)
{
TableAddress =
(ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.XsdtPhysicalAddress;
}
}
else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDT))
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.RsdtPhysicalAddress;
if (CurrentInstance == 0)
{
TableAddress =
(ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.RsdtPhysicalAddress;
}
}
else
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_RsdpAddress;
Signature = ACPI_SIG_RSDP;
if (CurrentInstance == 0)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_RsdpAddress;
Signature = ACPI_SIG_RSDP;
}
}

if (TableAddress == 0)
{
goto ExitFindTable;
}

/* Now we can get the requested special table */
Expand All @@ -907,6 +935,20 @@ OslGetTable (
}

TableLength = ApGetTableLength (MappedTable);
if (FirstTableAddress == 0)
{
FirstTableAddress = TableAddress;
}

/* Match table instance */

if (CurrentInstance != Instance)
{
OslUnmapTable (MappedTable);
MappedTable = NULL;
CurrentInstance++;
goto FindNextInstance;
}
}
else /* Case for a normal ACPI table */
{
Expand Down Expand Up @@ -944,7 +986,7 @@ OslGetTable (

/* Skip NULL entries in RSDT/XSDT */

if (!TableAddress)
if (TableAddress == 0)
{
continue;
}
Expand Down Expand Up @@ -979,6 +1021,8 @@ OslGetTable (
}
}

ExitFindTable:

if (!MappedTable)
{
return (AE_LIMIT);
Expand Down
93 changes: 66 additions & 27 deletions source/os_specific/service_layers/oslinuxtbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,7 @@ OslListBiosTables (

/* Skip NULL entries in RSDT/XSDT */

if (!TableAddress)
if (TableAddress == 0)
{
continue;
}
Expand Down Expand Up @@ -1041,7 +1041,8 @@ OslGetBiosTable (
UINT8 NumberOfTables;
UINT8 ItemSize;
UINT32 CurrentInstance = 0;
ACPI_PHYSICAL_ADDRESS TableAddress = 0;
ACPI_PHYSICAL_ADDRESS TableAddress;
ACPI_PHYSICAL_ADDRESS FirstTableAddress = 0;
UINT32 TableLength = 0;
ACPI_STATUS Status = AE_OK;
UINT32 i;
Expand All @@ -1055,10 +1056,10 @@ OslGetBiosTable (
ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) ||
ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
{
if (Instance > 0)
{
return (AE_LIMIT);
}

FindNextInstance:

TableAddress = 0;

/*
* Get the appropriate address, either 32-bit or 64-bit. Be very
Expand All @@ -1067,28 +1068,34 @@ OslGetBiosTable (
*/
if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
{
if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) &&
Gbl_Fadt->XDsdt)
if (CurrentInstance < 2)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt;
}
else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) &&
Gbl_Fadt->Dsdt)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt;
if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) &&
Gbl_Fadt->XDsdt && CurrentInstance == 0)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt;
}
else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) &&
Gbl_Fadt->Dsdt != FirstTableAddress)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt;
}
}
}
else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
{
if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) &&
Gbl_Fadt->XFacs)
if (CurrentInstance < 2)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs;
}
else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) &&
Gbl_Fadt->Facs)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs;
if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) &&
Gbl_Fadt->XFacs && CurrentInstance == 0)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs;
}
else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) &&
Gbl_Fadt->Facs != FirstTableAddress)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs;
}
}
}
else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_XSDT))
Expand All @@ -1097,16 +1104,32 @@ OslGetBiosTable (
{
return (AE_BAD_SIGNATURE);
}
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.XsdtPhysicalAddress;
if (CurrentInstance == 0)
{
TableAddress =
(ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.XsdtPhysicalAddress;
}
}
else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDT))
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.RsdtPhysicalAddress;
if (CurrentInstance == 0)
{
TableAddress =
(ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.RsdtPhysicalAddress;
}
}
else
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_RsdpAddress;
Signature = ACPI_SIG_RSDP;
if (CurrentInstance == 0)
{
TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_RsdpAddress;
Signature = ACPI_SIG_RSDP;
}
}

if (TableAddress == 0)
{
goto ExitFindTable;
}

/* Now we can get the requested special table */
Expand All @@ -1118,6 +1141,20 @@ OslGetBiosTable (
}

TableLength = ApGetTableLength (MappedTable);
if (FirstTableAddress == 0)
{
FirstTableAddress = TableAddress;
}

/* Match table instance */

if (CurrentInstance != Instance)
{
OslUnmapTable (MappedTable);
MappedTable = NULL;
CurrentInstance++;
goto FindNextInstance;
}
}
else /* Case for a normal ACPI table */
{
Expand Down Expand Up @@ -1155,7 +1192,7 @@ OslGetBiosTable (

/* Skip NULL entries in RSDT/XSDT */

if (!TableAddress)
if (TableAddress == 0)
{
continue;
}
Expand Down Expand Up @@ -1190,6 +1227,8 @@ OslGetBiosTable (
}
}

ExitFindTable:

if (!MappedTable)
{
return (AE_LIMIT);
Expand Down

0 comments on commit 343fc31

Please sign in to comment.