Fixed compatibility of output.
[AROS.git] / arch / all-pc / acpica / source / common / dmtable.c
blob255c3c28f9da63931fa62fb2e5903833211dd3f0
1 /******************************************************************************
3 * Module Name: dmtable - Support for ACPI tables that contain no AML code
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2013, Intel Corp.
9 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acdisasm.h"
47 #include "actables.h"
48 #include "aslcompiler.h"
49 #include "dtcompiler.h"
51 /* This module used for application-level code only */
53 #define _COMPONENT ACPI_CA_DISASSEMBLER
54 ACPI_MODULE_NAME ("dmtable")
56 /* Local Prototypes */
58 static void
59 AcpiDmCheckAscii (
60 UINT8 *Target,
61 char *RepairedName,
62 UINT32 Count);
65 /* Common format strings for commented values */
67 #define UINT8_FORMAT "%2.2X [%s]\n"
68 #define UINT16_FORMAT "%4.4X [%s]\n"
69 #define UINT32_FORMAT "%8.8X [%s]\n"
70 #define STRING_FORMAT "[%s]\n"
72 /* These tables map a subtable type to a description string */
74 static const char *AcpiDmAsfSubnames[] =
76 "ASF Information",
77 "ASF Alerts",
78 "ASF Remote Control",
79 "ASF RMCP Boot Options",
80 "ASF Address",
81 "Unknown SubTable Type" /* Reserved */
84 static const char *AcpiDmDmarSubnames[] =
86 "Hardware Unit Definition",
87 "Reserved Memory Region",
88 "Root Port ATS Capability",
89 "Remapping Hardware Static Affinity",
90 "Unknown SubTable Type" /* Reserved */
93 static const char *AcpiDmEinjActions[] =
95 "Begin Operation",
96 "Get Trigger Table",
97 "Set Error Type",
98 "Get Error Type",
99 "End Operation",
100 "Execute Operation",
101 "Check Busy Status",
102 "Get Command Status",
103 "Set Error Type With Address",
104 "Unknown Action"
107 static const char *AcpiDmEinjInstructions[] =
109 "Read Register",
110 "Read Register Value",
111 "Write Register",
112 "Write Register Value",
113 "Noop",
114 "Flush Cacheline",
115 "Unknown Instruction"
118 static const char *AcpiDmErstActions[] =
120 "Begin Write Operation",
121 "Begin Read Operation",
122 "Begin Clear Operation",
123 "End Operation",
124 "Set Record Offset",
125 "Execute Operation",
126 "Check Busy Status",
127 "Get Command Status",
128 "Get Record Identifier",
129 "Set Record Identifier",
130 "Get Record Count",
131 "Begin Dummy Write",
132 "Unused/Unknown Action",
133 "Get Error Address Range",
134 "Get Error Address Length",
135 "Get Error Attributes",
136 "Unknown Action"
139 static const char *AcpiDmErstInstructions[] =
141 "Read Register",
142 "Read Register Value",
143 "Write Register",
144 "Write Register Value",
145 "Noop",
146 "Load Var1",
147 "Load Var2",
148 "Store Var1",
149 "Add",
150 "Subtract",
151 "Add Value",
152 "Subtract Value",
153 "Stall",
154 "Stall While True",
155 "Skip Next If True",
156 "GoTo",
157 "Set Source Address",
158 "Set Destination Address",
159 "Move Data",
160 "Unknown Instruction"
163 static const char *AcpiDmHestSubnames[] =
165 "IA-32 Machine Check Exception",
166 "IA-32 Corrected Machine Check",
167 "IA-32 Non-Maskable Interrupt",
168 "Unknown SubTable Type", /* 3 - Reserved */
169 "Unknown SubTable Type", /* 4 - Reserved */
170 "Unknown SubTable Type", /* 5 - Reserved */
171 "PCI Express Root Port AER",
172 "PCI Express AER (AER Endpoint)",
173 "PCI Express/PCI-X Bridge AER",
174 "Generic Hardware Error Source",
175 "Unknown SubTable Type" /* Reserved */
178 static const char *AcpiDmHestNotifySubnames[] =
180 "Polled",
181 "External Interrupt",
182 "Local Interrupt",
183 "SCI",
184 "NMI",
185 "CMCI", /* ACPI 5.0 */
186 "MCE", /* ACPI 5.0 */
187 "Unknown Notify Type" /* Reserved */
190 static const char *AcpiDmMadtSubnames[] =
192 "Processor Local APIC", /* ACPI_MADT_TYPE_LOCAL_APIC */
193 "I/O APIC", /* ACPI_MADT_TYPE_IO_APIC */
194 "Interrupt Source Override", /* ACPI_MADT_TYPE_INTERRUPT_OVERRIDE */
195 "NMI Source", /* ACPI_MADT_TYPE_NMI_SOURCE */
196 "Local APIC NMI", /* ACPI_MADT_TYPE_LOCAL_APIC_NMI */
197 "Local APIC Address Override", /* ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE */
198 "I/O SAPIC", /* ACPI_MADT_TYPE_IO_SAPIC */
199 "Local SAPIC", /* ACPI_MADT_TYPE_LOCAL_SAPIC */
200 "Platform Interrupt Sources", /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */
201 "Processor Local x2APIC", /* ACPI_MADT_TYPE_LOCAL_X2APIC */
202 "Local x2APIC NMI", /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */
203 "Generic Interrupt Controller", /* ACPI_MADT_GENERIC_INTERRUPT */
204 "Generic Interrupt Distributor",/* ACPI_MADT_GENERIC_DISTRIBUTOR */
205 "Unknown SubTable Type" /* Reserved */
208 static const char *AcpiDmPmttSubnames[] =
210 "Socket", /* ACPI_PMTT_TYPE_SOCKET */
211 "Memory Controller", /* ACPI_PMTT_TYPE_CONTROLLER */
212 "Physical Component (DIMM)", /* ACPI_PMTT_TYPE_DIMM */
213 "Unknown SubTable Type" /* Reserved */
216 static const char *AcpiDmSlicSubnames[] =
218 "Public Key Structure",
219 "Windows Marker Structure",
220 "Unknown SubTable Type" /* Reserved */
223 static const char *AcpiDmSratSubnames[] =
225 "Processor Local APIC/SAPIC Affinity",
226 "Memory Affinity",
227 "Processor Local x2APIC Affinity",
228 "Unknown SubTable Type" /* Reserved */
231 static const char *AcpiDmIvrsSubnames[] =
233 "Hardware Definition Block",
234 "Memory Definition Block",
235 "Unknown SubTable Type" /* Reserved */
239 #define ACPI_FADT_PM_RESERVED 9
241 static const char *AcpiDmFadtProfiles[] =
243 "Unspecified",
244 "Desktop",
245 "Mobile",
246 "Workstation",
247 "Enterprise Server",
248 "SOHO Server",
249 "Appliance PC",
250 "Performance Server",
251 "Tablet",
252 "Unknown Profile Type"
255 #define ACPI_GAS_WIDTH_RESERVED 5
257 static const char *AcpiDmGasAccessWidth[] =
259 "Undefined/Legacy",
260 "Byte Access:8",
261 "Word Access:16",
262 "DWord Access:32",
263 "QWord Access:64",
264 "Unknown Width Encoding"
268 /*******************************************************************************
270 * ACPI Table Data, indexed by signature.
272 * Each entry contains: Signature, Table Info, Handler, DtHandler,
273 * Template, Description
275 * Simple tables have only a TableInfo structure, complex tables have a
276 * handler. This table must be NULL terminated. RSDP and FACS are
277 * special-cased elsewhere.
279 ******************************************************************************/
281 ACPI_DMTABLE_DATA AcpiDmTableData[] =
283 {ACPI_SIG_ASF, NULL, AcpiDmDumpAsf, DtCompileAsf, TemplateAsf, "Alert Standard Format table"},
284 {ACPI_SIG_BERT, AcpiDmTableInfoBert, NULL, NULL, TemplateBert, "Boot Error Record Table"},
285 {ACPI_SIG_BGRT, AcpiDmTableInfoBgrt, NULL, NULL, TemplateBgrt, "Boot Graphics Resource Table"},
286 {ACPI_SIG_BOOT, AcpiDmTableInfoBoot, NULL, NULL, TemplateBoot, "Simple Boot Flag Table"},
287 {ACPI_SIG_CPEP, NULL, AcpiDmDumpCpep, DtCompileCpep, TemplateCpep, "Corrected Platform Error Polling table"},
288 {ACPI_SIG_CSRT, NULL, AcpiDmDumpCsrt, DtCompileCsrt, TemplateCsrt, "Core System Resource Table"},
289 {ACPI_SIG_DBG2, NULL, AcpiDmDumpDbg2, NULL, NULL, "Debug Port table type 2"},
290 {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp, NULL, NULL, TemplateDbgp, "Debug Port table"},
291 {ACPI_SIG_DMAR, NULL, AcpiDmDumpDmar, DtCompileDmar, TemplateDmar, "DMA Remapping table"},
292 {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt, NULL, NULL, TemplateEcdt, "Embedded Controller Boot Resources Table"},
293 {ACPI_SIG_EINJ, NULL, AcpiDmDumpEinj, DtCompileEinj, TemplateEinj, "Error Injection table"},
294 {ACPI_SIG_ERST, NULL, AcpiDmDumpErst, DtCompileErst, TemplateErst, "Error Record Serialization Table"},
295 {ACPI_SIG_FADT, NULL, AcpiDmDumpFadt, DtCompileFadt, TemplateFadt, "Fixed ACPI Description Table (FADT)"},
296 {ACPI_SIG_FPDT, NULL, AcpiDmDumpFpdt, DtCompileFpdt, TemplateFpdt, "Firmware Performance Data Table"},
297 {ACPI_SIG_GTDT, AcpiDmTableInfoGtdt, NULL, NULL, TemplateGtdt, "Generic Timer Description Table"},
298 {ACPI_SIG_HEST, NULL, AcpiDmDumpHest, DtCompileHest, TemplateHest, "Hardware Error Source Table"},
299 {ACPI_SIG_HPET, AcpiDmTableInfoHpet, NULL, NULL, TemplateHpet, "High Precision Event Timer table"},
300 {ACPI_SIG_IVRS, NULL, AcpiDmDumpIvrs, DtCompileIvrs, TemplateIvrs, "I/O Virtualization Reporting Structure"},
301 {ACPI_SIG_MADT, NULL, AcpiDmDumpMadt, DtCompileMadt, TemplateMadt, "Multiple APIC Description Table (MADT)"},
302 {ACPI_SIG_MCFG, NULL, AcpiDmDumpMcfg, DtCompileMcfg, TemplateMcfg, "Memory Mapped Configuration table"},
303 {ACPI_SIG_MCHI, AcpiDmTableInfoMchi, NULL, NULL, TemplateMchi, "Management Controller Host Interface table"},
304 {ACPI_SIG_MPST, AcpiDmTableInfoMpst, AcpiDmDumpMpst, DtCompileMpst, TemplateMpst, "Memory Power State Table"},
305 {ACPI_SIG_MSCT, NULL, AcpiDmDumpMsct, DtCompileMsct, TemplateMsct, "Maximum System Characteristics Table"},
306 {ACPI_SIG_MTMR, NULL, AcpiDmDumpMtmr, DtCompileMtmr, TemplateMtmr, "MID Timer Table"},
307 {ACPI_SIG_PCCT, NULL, AcpiDmDumpPcct, NULL, NULL, "Platform Communications Channel Table"},
308 {ACPI_SIG_PMTT, NULL, AcpiDmDumpPmtt, DtCompilePmtt, TemplatePmtt, "Platform Memory Topology Table"},
309 {ACPI_SIG_RSDT, NULL, AcpiDmDumpRsdt, DtCompileRsdt, TemplateRsdt, "Root System Description Table"},
310 {ACPI_SIG_S3PT, NULL, NULL, NULL, TemplateS3pt, "S3 Performance Table"},
311 {ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, NULL, TemplateSbst, "Smart Battery Specification Table"},
312 {ACPI_SIG_SLIC, NULL, AcpiDmDumpSlic, DtCompileSlic, TemplateSlic, "Software Licensing Description Table"},
313 {ACPI_SIG_SLIT, NULL, AcpiDmDumpSlit, DtCompileSlit, TemplateSlit, "System Locality Information Table"},
314 {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr, NULL, NULL, TemplateSpcr, "Serial Port Console Redirection table"},
315 {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi, NULL, NULL, TemplateSpmi, "Server Platform Management Interface table"},
316 {ACPI_SIG_SRAT, NULL, AcpiDmDumpSrat, DtCompileSrat, TemplateSrat, "System Resource Affinity Table"},
317 {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa, NULL, NULL, TemplateTcpa, "Trusted Computing Platform Alliance table"},
318 {ACPI_SIG_TPM2, AcpiDmTableInfoTpm2, NULL, NULL, TemplateTpm2, "Trusted Platform Module hardware interface table"},
319 {ACPI_SIG_UEFI, AcpiDmTableInfoUefi, NULL, DtCompileUefi, TemplateUefi, "UEFI Boot Optimization Table"},
320 {ACPI_SIG_VRTC, AcpiDmTableInfoVrtc, AcpiDmDumpVrtc, DtCompileVrtc, TemplateVrtc, "Virtual Real-Time Clock Table"},
321 {ACPI_SIG_WAET, AcpiDmTableInfoWaet, NULL, NULL, TemplateWaet, "Windows ACPI Emulated Devices Table"},
322 {ACPI_SIG_WDAT, NULL, AcpiDmDumpWdat, DtCompileWdat, TemplateWdat, "Watchdog Action Table"},
323 {ACPI_SIG_WDDT, AcpiDmTableInfoWddt, NULL, NULL, TemplateWddt, "Watchdog Description Table"},
324 {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt, NULL, NULL, TemplateWdrt, "Watchdog Resource Table"},
325 {ACPI_SIG_XSDT, NULL, AcpiDmDumpXsdt, DtCompileXsdt, TemplateXsdt, "Extended System Description Table"},
326 {NULL, NULL, NULL, NULL, NULL, NULL}
330 /*******************************************************************************
332 * FUNCTION: AcpiDmGenerateChecksum
334 * PARAMETERS: Table - Pointer to table to be checksummed
335 * Length - Length of the table
336 * OriginalChecksum - Value of the checksum field
338 * RETURN: 8 bit checksum of buffer
340 * DESCRIPTION: Computes an 8 bit checksum of the table.
342 ******************************************************************************/
344 UINT8
345 AcpiDmGenerateChecksum (
346 void *Table,
347 UINT32 Length,
348 UINT8 OriginalChecksum)
350 UINT8 Checksum;
353 /* Sum the entire table as-is */
355 Checksum = AcpiTbChecksum ((UINT8 *) Table, Length);
357 /* Subtract off the existing checksum value in the table */
359 Checksum = (UINT8) (Checksum - OriginalChecksum);
361 /* Compute the final checksum */
363 Checksum = (UINT8) (0 - Checksum);
364 return (Checksum);
368 /*******************************************************************************
370 * FUNCTION: AcpiDmGetTableData
372 * PARAMETERS: Signature - ACPI signature (4 chars) to match
374 * RETURN: Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
376 * DESCRIPTION: Find a match in the global table of supported ACPI tables
378 ******************************************************************************/
380 ACPI_DMTABLE_DATA *
381 AcpiDmGetTableData (
382 char *Signature)
384 ACPI_DMTABLE_DATA *TableData;
387 for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
389 if (ACPI_COMPARE_NAME (Signature, TableData->Signature))
391 return (TableData);
395 return (NULL);
399 /*******************************************************************************
401 * FUNCTION: AcpiDmDumpDataTable
403 * PARAMETERS: Table - An ACPI table
405 * RETURN: None.
407 * DESCRIPTION: Format the contents of an ACPI data table (any table other
408 * than an SSDT or DSDT that does not contain executable AML code)
410 ******************************************************************************/
412 void
413 AcpiDmDumpDataTable (
414 ACPI_TABLE_HEADER *Table)
416 ACPI_STATUS Status;
417 ACPI_DMTABLE_DATA *TableData;
418 UINT32 Length;
421 /* Ignore tables that contain AML */
423 if (AcpiUtIsAmlTable (Table))
425 if (Gbl_VerboseTemplates)
427 /* Dump the raw table data */
429 Length = Table->Length;
431 AcpiOsPrintf ("\n/*\n%s: Length %d (0x%X)\n\n",
432 ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
433 AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, Table),
434 Length, DB_BYTE_DISPLAY, 0);
435 AcpiOsPrintf (" */\n");
437 return;
441 * Handle tables that don't use the common ACPI table header structure.
442 * Currently, these are the FACS, RSDP, and S3PT.
444 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
446 Length = Table->Length;
447 AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
449 else if (ACPI_VALIDATE_RSDP_SIG (Table->Signature))
451 Length = AcpiDmDumpRsdp (Table);
453 else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_S3PT))
455 Length = AcpiDmDumpS3pt (Table);
457 else
460 * All other tables must use the common ACPI table header, dump it now
462 Length = Table->Length;
463 Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
464 if (ACPI_FAILURE (Status))
466 return;
468 AcpiOsPrintf ("\n");
470 /* Match signature and dispatch appropriately */
472 TableData = AcpiDmGetTableData (Table->Signature);
473 if (!TableData)
475 if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
477 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
478 Table->Signature);
480 else
482 AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
483 Table->Signature);
484 fprintf (stderr, "Unknown ACPI table signature [%4.4s], decoding header only\n",
485 Table->Signature);
488 else if (TableData->TableHandler)
490 /* Complex table, has a handler */
492 TableData->TableHandler (Table);
494 else if (TableData->TableInfo)
496 /* Simple table, just walk the info table */
498 AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
502 if (!Gbl_DoTemplates || Gbl_VerboseTemplates)
504 /* Dump the raw table data */
506 AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
507 ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
508 AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, Table),
509 Length, DB_BYTE_DISPLAY, 0);
514 /*******************************************************************************
516 * FUNCTION: AcpiDmLineHeader
518 * PARAMETERS: Offset - Current byte offset, from table start
519 * ByteLength - Length of the field in bytes, 0 for flags
520 * Name - Name of this field
521 * Value - Optional value, displayed on left of ':'
523 * RETURN: None
525 * DESCRIPTION: Utility routines for formatting output lines. Displays the
526 * current table offset in hex and decimal, the field length,
527 * and the field name.
529 ******************************************************************************/
531 void
532 AcpiDmLineHeader (
533 UINT32 Offset,
534 UINT32 ByteLength,
535 char *Name)
538 /* Allow a null name for fields that span multiple lines (large buffers) */
540 if (!Name)
542 Name = "";
545 if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
547 if (ByteLength)
549 AcpiOsPrintf ("[%.4d] %34s : ", ByteLength, Name);
551 else
553 if (*Name)
555 AcpiOsPrintf ("%41s : ", Name);
557 else
559 AcpiOsPrintf ("%41s ", Name);
563 else /* Normal disassembler or verbose template */
565 if (ByteLength)
567 AcpiOsPrintf ("[%3.3Xh %4.4d% 4d] %28s : ",
568 Offset, Offset, ByteLength, Name);
570 else
572 if (*Name)
574 AcpiOsPrintf ("%44s : ", Name);
576 else
578 AcpiOsPrintf ("%44s ", Name);
584 void
585 AcpiDmLineHeader2 (
586 UINT32 Offset,
587 UINT32 ByteLength,
588 char *Name,
589 UINT32 Value)
592 if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
594 if (ByteLength)
596 AcpiOsPrintf ("[%.4d] %30s %3d : ",
597 ByteLength, Name, Value);
599 else
601 AcpiOsPrintf ("%36s % 3d : ",
602 Name, Value);
605 else /* Normal disassembler or verbose template */
607 if (ByteLength)
609 AcpiOsPrintf ("[%3.3Xh %4.4d %3d] %24s %3d : ",
610 Offset, Offset, ByteLength, Name, Value);
612 else
614 AcpiOsPrintf ("[%3.3Xh %4.4d ] %24s %3d : ",
615 Offset, Offset, Name, Value);
621 /*******************************************************************************
623 * FUNCTION: AcpiDmDumpTable
625 * PARAMETERS: TableLength - Length of the entire ACPI table
626 * TableOffset - Starting offset within the table for this
627 * sub-descriptor (0 if main table)
628 * Table - The ACPI table
629 * SubtableLength - Length of this sub-descriptor
630 * Info - Info table for this ACPI table
632 * RETURN: None
634 * DESCRIPTION: Display ACPI table contents by walking the Info table.
636 * Note: This function must remain in sync with DtGetFieldLength.
638 ******************************************************************************/
640 ACPI_STATUS
641 AcpiDmDumpTable (
642 UINT32 TableLength,
643 UINT32 TableOffset,
644 void *Table,
645 UINT32 SubtableLength,
646 ACPI_DMTABLE_INFO *Info)
648 UINT8 *Target;
649 UINT32 CurrentOffset;
650 UINT32 ByteLength;
651 UINT8 Temp8;
652 UINT16 Temp16;
653 ACPI_DMTABLE_DATA *TableData;
654 const char *Name;
655 BOOLEAN LastOutputBlankLine = FALSE;
656 char RepairedName[8];
659 if (!Info)
661 AcpiOsPrintf ("Display not implemented\n");
662 return (AE_NOT_IMPLEMENTED);
665 /* Walk entire Info table; Null name terminates */
667 for (; Info->Name; Info++)
670 * Target points to the field within the ACPI Table. CurrentOffset is
671 * the offset of the field from the start of the main table.
673 Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
674 CurrentOffset = TableOffset + Info->Offset;
676 /* Check for beyond EOT or beyond subtable end */
678 if ((CurrentOffset >= TableLength) ||
679 (SubtableLength && (Info->Offset >= SubtableLength)))
681 AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
682 return (AE_BAD_DATA);
685 /* Generate the byte length for this field */
687 switch (Info->Opcode)
689 case ACPI_DMT_UINT8:
690 case ACPI_DMT_CHKSUM:
691 case ACPI_DMT_SPACEID:
692 case ACPI_DMT_ACCWIDTH:
693 case ACPI_DMT_IVRS:
694 case ACPI_DMT_MADT:
695 case ACPI_DMT_PMTT:
696 case ACPI_DMT_SRAT:
697 case ACPI_DMT_ASF:
698 case ACPI_DMT_HESTNTYP:
699 case ACPI_DMT_FADTPM:
700 case ACPI_DMT_EINJACT:
701 case ACPI_DMT_EINJINST:
702 case ACPI_DMT_ERSTACT:
703 case ACPI_DMT_ERSTINST:
705 ByteLength = 1;
706 break;
708 case ACPI_DMT_UINT16:
709 case ACPI_DMT_DMAR:
710 case ACPI_DMT_HEST:
712 ByteLength = 2;
713 break;
715 case ACPI_DMT_UINT24:
717 ByteLength = 3;
718 break;
720 case ACPI_DMT_UINT32:
721 case ACPI_DMT_NAME4:
722 case ACPI_DMT_SIG:
723 case ACPI_DMT_SLIC:
725 ByteLength = 4;
726 break;
728 case ACPI_DMT_UINT40:
730 ByteLength = 5;
731 break;
733 case ACPI_DMT_UINT48:
734 case ACPI_DMT_NAME6:
736 ByteLength = 6;
737 break;
739 case ACPI_DMT_UINT56:
740 case ACPI_DMT_BUF7:
742 ByteLength = 7;
743 break;
745 case ACPI_DMT_UINT64:
746 case ACPI_DMT_NAME8:
748 ByteLength = 8;
749 break;
751 case ACPI_DMT_BUF10:
753 ByteLength = 10;
754 break;
756 case ACPI_DMT_BUF16:
757 case ACPI_DMT_UUID:
759 ByteLength = 16;
760 break;
762 case ACPI_DMT_BUF128:
764 ByteLength = 128;
765 break;
767 case ACPI_DMT_STRING:
769 ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
770 break;
772 case ACPI_DMT_GAS:
774 if (!LastOutputBlankLine)
776 AcpiOsPrintf ("\n");
777 LastOutputBlankLine = TRUE;
779 ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
780 break;
782 case ACPI_DMT_HESTNTFY:
784 if (!LastOutputBlankLine)
786 AcpiOsPrintf ("\n");
787 LastOutputBlankLine = TRUE;
789 ByteLength = sizeof (ACPI_HEST_NOTIFY);
790 break;
792 default:
794 ByteLength = 0;
795 break;
798 if (CurrentOffset + ByteLength > TableLength)
800 AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
801 return (AE_BAD_DATA);
804 if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
806 AcpiOsPrintf ("%s", Info->Name);
807 continue;
810 /* Start a new line and decode the opcode */
812 AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
814 switch (Info->Opcode)
816 /* Single-bit Flag fields. Note: Opcode is the bit position */
818 case ACPI_DMT_FLAG0:
819 case ACPI_DMT_FLAG1:
820 case ACPI_DMT_FLAG2:
821 case ACPI_DMT_FLAG3:
822 case ACPI_DMT_FLAG4:
823 case ACPI_DMT_FLAG5:
824 case ACPI_DMT_FLAG6:
825 case ACPI_DMT_FLAG7:
827 AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
828 break;
830 /* 2-bit Flag fields */
832 case ACPI_DMT_FLAGS0:
834 AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
835 break;
837 case ACPI_DMT_FLAGS1:
839 AcpiOsPrintf ("%1.1X\n", (*Target >> 1) & 0x03);
840 break;
842 case ACPI_DMT_FLAGS2:
844 AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
845 break;
847 case ACPI_DMT_FLAGS4:
849 AcpiOsPrintf ("%1.1X\n", (*Target >> 4) & 0x03);
850 break;
852 /* Integer Data Types */
854 case ACPI_DMT_UINT8:
855 case ACPI_DMT_UINT16:
856 case ACPI_DMT_UINT24:
857 case ACPI_DMT_UINT32:
858 case ACPI_DMT_UINT40:
859 case ACPI_DMT_UINT48:
860 case ACPI_DMT_UINT56:
861 case ACPI_DMT_UINT64:
863 * Dump bytes - high byte first, low byte last.
864 * Note: All ACPI tables are little-endian.
866 for (Temp8 = (UINT8) ByteLength; Temp8 > 0; Temp8--)
868 AcpiOsPrintf ("%2.2X", Target[Temp8 - 1]);
870 AcpiOsPrintf ("\n");
871 break;
873 case ACPI_DMT_BUF7:
874 case ACPI_DMT_BUF10:
875 case ACPI_DMT_BUF16:
876 case ACPI_DMT_BUF128:
878 * Buffer: Size depends on the opcode and was set above.
879 * Each hex byte is separated with a space.
880 * Multiple lines are separated by line continuation char.
882 for (Temp16 = 0; Temp16 < ByteLength; Temp16++)
884 AcpiOsPrintf ("%2.2X", Target[Temp16]);
885 if ((UINT32) (Temp16 + 1) < ByteLength)
887 if ((Temp16 > 0) && (!((Temp16+1) % 16)))
889 AcpiOsPrintf (" \\\n"); /* Line continuation */
890 AcpiDmLineHeader (0, 0, NULL);
892 else
894 AcpiOsPrintf (" ");
898 AcpiOsPrintf ("\n");
899 break;
901 case ACPI_DMT_UUID:
903 /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */
905 (void) AuConvertUuidToString ((char *) Target, MsgBuffer);
907 AcpiOsPrintf ("%s\n", MsgBuffer);
908 break;
910 case ACPI_DMT_STRING:
912 AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
913 break;
915 /* Fixed length ASCII name fields */
917 case ACPI_DMT_SIG:
919 AcpiDmCheckAscii (Target, RepairedName, 4);
920 AcpiOsPrintf ("\"%.4s\" ", RepairedName);
921 TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
922 if (TableData)
924 AcpiOsPrintf (STRING_FORMAT, TableData->Name);
926 else
928 AcpiOsPrintf ("\n");
930 break;
932 case ACPI_DMT_NAME4:
934 AcpiDmCheckAscii (Target, RepairedName, 4);
935 AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
936 break;
938 case ACPI_DMT_NAME6:
940 AcpiDmCheckAscii (Target, RepairedName, 6);
941 AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
942 break;
944 case ACPI_DMT_NAME8:
946 AcpiDmCheckAscii (Target, RepairedName, 8);
947 AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
948 break;
950 /* Special Data Types */
952 case ACPI_DMT_CHKSUM:
954 /* Checksum, display and validate */
956 AcpiOsPrintf ("%2.2X", *Target);
957 Temp8 = AcpiDmGenerateChecksum (Table,
958 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
959 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
960 if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
962 AcpiOsPrintf (
963 " /* Incorrect checksum, should be %2.2X */", Temp8);
965 AcpiOsPrintf ("\n");
966 break;
968 case ACPI_DMT_SPACEID:
970 /* Address Space ID */
972 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiUtGetRegionName (*Target));
973 break;
975 case ACPI_DMT_ACCWIDTH:
977 /* Encoded Access Width */
979 Temp8 = *Target;
980 if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
982 Temp8 = ACPI_GAS_WIDTH_RESERVED;
985 AcpiOsPrintf (UINT8_FORMAT, Temp8, AcpiDmGasAccessWidth[Temp8]);
986 break;
988 case ACPI_DMT_GAS:
990 /* Generic Address Structure */
992 AcpiOsPrintf (STRING_FORMAT, "Generic Address Structure");
993 AcpiDmDumpTable (TableLength, CurrentOffset, Target,
994 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
995 AcpiOsPrintf ("\n");
996 LastOutputBlankLine = TRUE;
997 break;
999 case ACPI_DMT_ASF:
1001 /* ASF subtable types */
1003 Temp16 = (UINT16) ((*Target) & 0x7F); /* Top bit can be zero or one */
1004 if (Temp16 > ACPI_ASF_TYPE_RESERVED)
1006 Temp16 = ACPI_ASF_TYPE_RESERVED;
1009 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmAsfSubnames[Temp16]);
1010 break;
1012 case ACPI_DMT_DMAR:
1014 /* DMAR subtable types */
1016 Temp16 = ACPI_GET16 (Target);
1017 if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
1019 Temp16 = ACPI_DMAR_TYPE_RESERVED;
1022 AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
1023 break;
1025 case ACPI_DMT_EINJACT:
1027 /* EINJ Action types */
1029 Temp8 = *Target;
1030 if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
1032 Temp8 = ACPI_EINJ_ACTION_RESERVED;
1035 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjActions[Temp8]);
1036 break;
1038 case ACPI_DMT_EINJINST:
1040 /* EINJ Instruction types */
1042 Temp8 = *Target;
1043 if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
1045 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
1048 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjInstructions[Temp8]);
1049 break;
1051 case ACPI_DMT_ERSTACT:
1053 /* ERST Action types */
1055 Temp8 = *Target;
1056 if (Temp8 > ACPI_ERST_ACTION_RESERVED)
1058 Temp8 = ACPI_ERST_ACTION_RESERVED;
1061 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstActions[Temp8]);
1062 break;
1064 case ACPI_DMT_ERSTINST:
1066 /* ERST Instruction types */
1068 Temp8 = *Target;
1069 if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
1071 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
1074 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstInstructions[Temp8]);
1075 break;
1077 case ACPI_DMT_HEST:
1079 /* HEST subtable types */
1081 Temp16 = ACPI_GET16 (Target);
1082 if (Temp16 > ACPI_HEST_TYPE_RESERVED)
1084 Temp16 = ACPI_HEST_TYPE_RESERVED;
1087 AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
1088 break;
1090 case ACPI_DMT_HESTNTFY:
1092 AcpiOsPrintf (STRING_FORMAT, "Hardware Error Notification Structure");
1093 AcpiDmDumpTable (TableLength, CurrentOffset, Target,
1094 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
1095 AcpiOsPrintf ("\n");
1096 LastOutputBlankLine = TRUE;
1097 break;
1099 case ACPI_DMT_HESTNTYP:
1101 /* HEST Notify types */
1103 Temp8 = *Target;
1104 if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
1106 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
1109 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmHestNotifySubnames[Temp8]);
1110 break;
1112 case ACPI_DMT_MADT:
1114 /* MADT subtable types */
1116 Temp8 = *Target;
1117 if (Temp8 > ACPI_MADT_TYPE_RESERVED)
1119 Temp8 = ACPI_MADT_TYPE_RESERVED;
1122 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmMadtSubnames[Temp8]);
1123 break;
1125 case ACPI_DMT_PMTT:
1127 /* PMTT subtable types */
1129 Temp8 = *Target;
1130 if (Temp8 > ACPI_PMTT_TYPE_RESERVED)
1132 Temp8 = ACPI_PMTT_TYPE_RESERVED;
1135 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmPmttSubnames[Temp8]);
1136 break;
1138 case ACPI_DMT_SLIC:
1140 /* SLIC subtable types */
1142 Temp8 = *Target;
1143 if (Temp8 > ACPI_SLIC_TYPE_RESERVED)
1145 Temp8 = ACPI_SLIC_TYPE_RESERVED;
1148 AcpiOsPrintf (UINT32_FORMAT, *Target, AcpiDmSlicSubnames[Temp8]);
1149 break;
1151 case ACPI_DMT_SRAT:
1153 /* SRAT subtable types */
1155 Temp8 = *Target;
1156 if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
1158 Temp8 = ACPI_SRAT_TYPE_RESERVED;
1161 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmSratSubnames[Temp8]);
1162 break;
1164 case ACPI_DMT_FADTPM:
1166 /* FADT Preferred PM Profile names */
1168 Temp8 = *Target;
1169 if (Temp8 > ACPI_FADT_PM_RESERVED)
1171 Temp8 = ACPI_FADT_PM_RESERVED;
1174 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmFadtProfiles[Temp8]);
1175 break;
1177 case ACPI_DMT_IVRS:
1179 /* IVRS subtable types */
1181 Temp8 = *Target;
1182 switch (Temp8)
1184 case ACPI_IVRS_TYPE_HARDWARE:
1186 Name = AcpiDmIvrsSubnames[0];
1187 break;
1189 case ACPI_IVRS_TYPE_MEMORY1:
1190 case ACPI_IVRS_TYPE_MEMORY2:
1191 case ACPI_IVRS_TYPE_MEMORY3:
1193 Name = AcpiDmIvrsSubnames[1];
1194 break;
1196 default:
1198 Name = AcpiDmIvrsSubnames[2];
1199 break;
1202 AcpiOsPrintf (UINT8_FORMAT, *Target, Name);
1203 break;
1205 case ACPI_DMT_EXIT:
1207 return (AE_OK);
1209 default:
1211 ACPI_ERROR ((AE_INFO,
1212 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1213 return (AE_SUPPORT);
1217 if (TableOffset && !SubtableLength)
1219 /* If this table is not the main table, subtable must have valid length */
1221 AcpiOsPrintf ("Invalid zero length subtable\n");
1222 return (AE_BAD_DATA);
1225 return (AE_OK);
1229 /*******************************************************************************
1231 * FUNCTION: AcpiDmCheckAscii
1233 * PARAMETERS: Name - Ascii string
1234 * Count - Number of characters to check
1236 * RETURN: None
1238 * DESCRIPTION: Ensure that the requested number of characters are printable
1239 * Ascii characters. Sets non-printable and null chars to <space>.
1241 ******************************************************************************/
1243 static void
1244 AcpiDmCheckAscii (
1245 UINT8 *Name,
1246 char *RepairedName,
1247 UINT32 Count)
1249 UINT32 i;
1252 for (i = 0; i < Count; i++)
1254 RepairedName[i] = (char) Name[i];
1256 if (!Name[i])
1258 return;
1260 if (!isprint (Name[i]))
1262 RepairedName[i] = ' ';