summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Moore <Robert.Moore@intel.com>2022-08-12 13:49:37 -0700
committerRobert Moore <Robert.Moore@intel.com>2022-08-12 13:49:37 -0700
commitcd6a30897593f6052abf0b9a791671dcf07b9596 (patch)
tree656b08029190781f61cf520f6df7a591170c3548
parent3284ae19f31b126fe09e899bdf52dcdaa8f8c463 (diff)
downloadacpica-cd6a30897593f6052abf0b9a791671dcf07b9596.tar.gz
iASL: Update for PHAT table support.
Includes changes for both the data table compiler and the disassembler. Now handles Version Data Records and Health Data Records properly.
-rw-r--r--source/common/dmtbdump2.c97
-rw-r--r--source/compiler/dttable2.c142
2 files changed, 213 insertions, 26 deletions
diff --git a/source/common/dmtbdump2.c b/source/common/dmtbdump2.c
index c50a6a247..2f99911d2 100644
--- a/source/common/dmtbdump2.c
+++ b/source/common/dmtbdump2.c
@@ -149,6 +149,7 @@
*
*****************************************************************************/
+#include <wchar.h>
#include "acpi.h"
#include "accommon.h"
#include "acdisasm.h"
@@ -2104,9 +2105,12 @@ AcpiDmDumpPhat (
UINT32 RecordCount;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_PHAT);
+ UINT32 OriginalOffset;
UINT32 SubtableLength;
UINT32 PathLength;
UINT32 VendorLength;
+ UINT16 RecordType;
+ const wchar_t *WideString;
Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table, sizeof (ACPI_TABLE_PHAT));
@@ -2116,13 +2120,16 @@ AcpiDmDumpPhat (
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, 0, Subtable,
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
sizeof (ACPI_PHAT_HEADER), AcpiDmTableInfoPhatHdr);
if (ACPI_FAILURE (Status))
{
return;
}
+ DbgPrint (ASL_DEBUG_OUTPUT, "\n/* %u, Subtable->Type %X */\n",
+ __LINE__, Subtable->Type);
+
switch (Subtable->Type)
{
case ACPI_PHAT_TYPE_FW_VERSION_DATA:
@@ -2139,35 +2146,68 @@ AcpiDmDumpPhat (
default:
- AcpiOsPrintf ("\n**** Unknown PHAT subtable type 0x%X\n\n",
+ DbgPrint (ASL_DEBUG_OUTPUT, "\n**** Unknown PHAT subtable type 0x%X\n\n",
Subtable->Type);
return;
}
- Status = AcpiDmDumpTable (Length, 0, Subtable,
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
SubtableLength, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
}
+ Offset += SubtableLength;
+ OriginalOffset = Offset;
switch (Subtable->Type)
{
case ACPI_PHAT_TYPE_FW_VERSION_DATA:
VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA, Subtable);
RecordCount = VersionData->ElementCount;
- while (RecordCount)
+ RecordType = *ACPI_CAST_PTR (UINT8, Subtable);
+
+ /*
+ * Skip past a zero-valued block (not part of the ACPI PHAT specification).
+ * First, check for a zero length record and a zero element count
+ */
+ if (!VersionData->Header.Length && !VersionData->ElementCount)
{
- Status = AcpiDmDumpTable (Length, Offset,
- ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_VERSION_DATA)),
+ while (RecordType == 0)
+ {
+ Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table, Offset);
+ RecordType = *ACPI_CAST_PTR (UINT8, Subtable);
+ RecordCount = VersionData->ElementCount;
+ Offset += 1;
+ }
+
+ Offset -= 1;
+ AcpiOsPrintf ("\n/* Warning: Block of zeros found above starting at Offset %X Length %X */\n"
+ "/* (not compliant to PHAT specification -- ignoring block) */\n",
+ OriginalOffset - 12, Offset - OriginalOffset + 12);
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "/* %u, RecordCount: %X, Offset %X, SubtableLength %X */\n",
+ __LINE__, RecordCount, Offset, SubtableLength);
+
+ /* Emit each of the version elements */
+
+ while (RecordCount && VersionData->Header.Length)
+ {
+ AcpiOsPrintf ("\n/* Version Element #%Xh Offset %Xh */\n\n",
+ VersionData->ElementCount - RecordCount + 1, Offset);
+
+ Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table, Offset);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
sizeof (ACPI_PHAT_VERSION_ELEMENT), AcpiDmTableInfoPhat0a);
if (ACPI_FAILURE (Status))
{
return;
}
+ Offset += sizeof (ACPI_PHAT_VERSION_ELEMENT);
RecordCount--;
}
@@ -2175,24 +2215,48 @@ AcpiDmDumpPhat (
case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
- /* account for the null terminator */
+ /*
+ * Get the length of the Device Path (UEFI wide string).
+ * Include the wide null terminator (+2),
+ */
+ WideString = ACPI_ADD_PTR (wchar_t, Subtable,
+ sizeof (ACPI_PHAT_HEALTH_DATA));
+
+ PathLength = (wcslen (WideString) * 2) + 2;
+ DbgPrint (ASL_DEBUG_OUTPUT, "/* %u, PathLength %X, Offset %X, Table->Length %X */\n",
+ __LINE__, PathLength, Offset, Length);
- PathLength = strlen (ACPI_ADD_PTR (char, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA))) + 1;
Status = AcpiDmDumpTable (Length, Offset,
ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA)),
PathLength, AcpiDmTableInfoPhat1a);
+ Offset += PathLength;
if (ACPI_FAILURE (Status))
{
return;
}
- /* Get vendor data - data length is the remaining subtable length */
+ /* Get Device-Specific Data - length of which is the remaining subtable length. */
VendorLength =
Subtable->Length - sizeof (ACPI_PHAT_HEALTH_DATA) - PathLength;
- Status = AcpiDmDumpTable (Length, 0,
- ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA) + PathLength),
- VendorLength, AcpiDmTableInfoPhat1b);
+ DbgPrint (ASL_DEBUG_OUTPUT, "%u, Subtable->Length %X, VendorLength %X, Offset %X PathLength: %X\n",
+ __LINE__, Subtable->Length, VendorLength, Offset, PathLength);
+
+ if (VendorLength)
+ {
+ /* Point past the Device Path, Compile the Device-Specific Data */
+
+ Status = AcpiDmDumpTable (Length, Offset,
+ ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA) + PathLength),
+ VendorLength, AcpiDmTableInfoPhat1b);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ Offset += VendorLength;
+ }
+
if (ACPI_FAILURE (Status))
{
return;
@@ -2208,9 +2272,12 @@ AcpiDmDumpPhat (
/* Next subtable */
- Offset += Subtable->Length;
- Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable,
- Subtable->Length);
+ DbgPrint (ASL_DEBUG_OUTPUT, "/* %u, Bottom of main loop: Offset %X, "
+ "Subtable->Length %X, Table->Length %X */\n",
+ __LINE__, Offset, Subtable->Length, Table->Length);
+
+ Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table,
+ Offset);
}
}
diff --git a/source/compiler/dttable2.c b/source/compiler/dttable2.c
index 1798a963e..75d272d3a 100644
--- a/source/compiler/dttable2.c
+++ b/source/compiler/dttable2.c
@@ -1369,19 +1369,30 @@ DtCompilePhat (
ACPI_PHAT_HEADER *PhatHeader;
ACPI_DMTABLE_INFO *Info;
ACPI_PHAT_VERSION_DATA *VersionData;
+ UINT32 DeviceDataLength;
UINT32 RecordCount;
+ DT_FIELD *DataOffsetField;
+ DT_FIELD *DevicePathField;
+ UINT32 TableOffset = 0;
+ UINT32 DataOffsetValue;
+ UINT32 i;
- /* The table consist of subtables */
+ /* The table consists of subtables */
while (*PFieldList)
{
+ /* Compile the common subtable header */
+
Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
+ TableOffset += Subtable->Length;
+ DbgPrint (ASL_DEBUG_OUTPUT, "0 Subtable->Length: %X\n", Subtable->Length);
+
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
DtPushSubtable (Subtable);
@@ -1392,12 +1403,66 @@ DtCompilePhat (
{
case ACPI_PHAT_TYPE_FW_VERSION_DATA:
+ /* Compile the middle portion of the Firmware Version Data */
+
Info = AcpiDmTableInfoPhat0;
PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA);
+ DataOffsetField = NULL;
break;
case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
+ DbgPrint (ASL_DEBUG_OUTPUT, "1 Offset: %X, Name: \"%s\" Length: %X\n",
+ (*PFieldList)->TableOffset, (*PFieldList)->Name, Subtable->Length);
+
+ DataOffsetField = *PFieldList;
+
+ /* Walk the field list to get to the "Device-specific data Offset" field */
+
+ TableOffset = sizeof (ACPI_PHAT_HEALTH_DATA);
+ for (i = 0; i < 3; i++)
+ {
+ DataOffsetField = DataOffsetField->Next;
+ DbgPrint (ASL_DEBUG_OUTPUT, "2 Offset: %X, Name: \"%s\" Length: %X Value: %s:\n",
+ TableOffset, DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
+ }
+
+ /* Convert DataOffsetField->Value (a char * string) to an integer value */
+
+ sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
+
+ /*
+ * Get the next field (Device Path):
+ * DataOffsetField points to "Device-Specific Offset", next field is
+ * "Device Path".
+ */
+ DevicePathField = DataOffsetField->Next;
+
+ /* Compute the size of the input ASCII string as a unicode string (*2 + 2) */
+
+ DevicePathField->StringLength = (strlen ((const char *) DevicePathField->Value) * 2) + 2;
+ TableOffset += DevicePathField->StringLength;
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "3 Offset: %X, Length: %X devicepathLength: %X\n",
+ TableOffset, Subtable->Length, DevicePathField->StringLength);
+
+ /* Set the DataOffsetField to the current TableOffset */
+ /* Must set the DataOffsetField here (not later) */
+
+ if (DataOffsetValue != 0)
+ {
+ snprintf (DataOffsetField->Value, Subtable->Length, "%X", TableOffset);
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "4 Offset: %X, Length: %X\n", TableOffset, Subtable->Length);
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "5 TableOffset: %X, DataOffsetField->StringLength: "
+ "%X DevicePathField Length: %X DevicePathField->Value: %s, DataOffsetField->Value: %s DataOffsetField->ByteOffset %X\n",
+ TableOffset, DataOffsetField->StringLength, DevicePathField->StringLength,
+ DevicePathField->Value, DataOffsetField->Value, DataOffsetField->ByteOffset);
+
+ /* Compile the middle portion of the Health Data Record */
+
Info = AcpiDmTableInfoPhat1;
PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA);
break;
@@ -1406,16 +1471,19 @@ DtCompilePhat (
DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
return (AE_ERROR);
-
- break;
}
+ /* Compile either the Version Data or the Health Data */
+
Status = DtCompileTable (PFieldList, Info, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
+ DbgPrint (ASL_DEBUG_OUTPUT, "6 Offset: %X, Name: \"%s\" SubtableLength: %X\n",
+ TableOffset /* - StartTableOffset*/, (*PFieldList)->Name, Subtable->Length);
+
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
@@ -1427,6 +1495,8 @@ DtCompilePhat (
(Subtable->Buffer - sizeof (ACPI_PHAT_HEADER)));
RecordCount = VersionData->ElementCount;
+ /* Compile all of the Version Elements */
+
while (RecordCount)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a,
@@ -1435,17 +1505,29 @@ DtCompilePhat (
{
return (Status);
}
+
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
+ TableOffset += Subtable->Length;
RecordCount--;
PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT);
}
+
+ DtPopSubtable ();
break;
case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
- /* Compile device path */
+ /* Compile the Device Path */
+
+ DeviceDataLength = Subtable->Length;
+ TableOffset += Subtable->Length;
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "7 Device Path Length: %X FieldName: \"%s\" FieldLength: "
+ "%s FieldValue: %s SubtableLength: %X TableOffset: %X\n", DeviceDataLength,
+ (*PFieldList)->Name, DataOffsetField->Value, (*PFieldList)->Value,
+ Subtable->Length, TableOffset);
Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable);
if (ACPI_FAILURE (Status))
@@ -1455,20 +1537,58 @@ DtCompilePhat (
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
+ /* *PFieldList will be null if previous field was at the end-of-ParseTree (EOF) */
+
+ if (!*PFieldList)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT, "8 Exit on end-of-ParseTree\n");
+ return (AE_OK);
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "9 Device Data Length: %X FieldName: \"%s"
+ " TableOffset: %X FieldLength: %X Field Value: %s SubtableLength: %X\n",
+ DeviceDataLength, (*PFieldList)->Name, TableOffset,
+ (*PFieldList)->StringLength, (*PFieldList)->Value, Subtable->Length);
+
PhatHeader->Length += (UINT16) Subtable->Length;
- /* Compile vendor specific data */
+ /* Convert DataOffsetField->Value (a hex char * string) to an integer value */
- Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable);
- if (ACPI_FAILURE (Status))
+ sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "10 Device-Specific Offset: %X Table Offset: %X\n",
+ DataOffsetValue, TableOffset);
+ if (DataOffsetValue != 0)
{
- return (Status);
+ /* Compile Device-Specific Data - only if the Data Offset is non-zero */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "11 Subtable: %p Table Offset: %X\n",
+ Subtable, TableOffset);
+ if (Subtable)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT, "12 Device Specific Offset: "
+ "%X FieldName \"%s\" SubtableLength %X\n",
+ DeviceDataLength, DataOffsetField->Name, Subtable->Length);
+
+ DeviceDataLength += Subtable->Length;
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ PhatHeader->Length += (UINT16) Subtable->Length;
+ }
}
- ParentTable = DtPeekSubtable ();
- DtInsertSubtable (ParentTable, Subtable);
- PhatHeader->Length += (UINT16) Subtable->Length;
+ DtPopSubtable ();
+ DbgPrint (ASL_DEBUG_OUTPUT, "13 FieldName: \"%s\" FieldLength: %X Field Value: %s\n",
+ DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
break;
default: