]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/contrib/dev/acpica/common/dmtable.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / contrib / dev / acpica / common / dmtable.c
1 /******************************************************************************
2  *
3  * Module Name: dmtable - Support for ACPI tables that contain no AML code
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2011, Intel Corp.
9  * All rights reserved.
10  *
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.
25  *
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.
29  *
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.
42  */
43
44 #include <contrib/dev/acpica/include/acpi.h>
45 #include <contrib/dev/acpica/include/accommon.h>
46 #include <contrib/dev/acpica/include/acdisasm.h>
47 #include <contrib/dev/acpica/include/actables.h>
48 #include <contrib/dev/acpica/compiler/aslcompiler.h>
49 #include <contrib/dev/acpica/compiler/dtcompiler.h>
50
51 /* This module used for application-level code only */
52
53 #define _COMPONENT          ACPI_CA_DISASSEMBLER
54         ACPI_MODULE_NAME    ("dmtable")
55
56 /* Local Prototypes */
57
58 static void
59 AcpiDmCheckAscii (
60     UINT8                   *Target,
61     char                    *RepairedName,
62     UINT32                  Count);
63
64
65 /* Common format strings for commented values */
66
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"
71
72 /* These tables map a subtable type to a description string */
73
74 static const char           *AcpiDmAsfSubnames[] =
75 {
76     "ASF Information",
77     "ASF Alerts",
78     "ASF Remote Control",
79     "ASF RMCP Boot Options",
80     "ASF Address",
81     "Unknown SubTable Type"         /* Reserved */
82 };
83
84 static const char           *AcpiDmDmarSubnames[] =
85 {
86     "Hardware Unit Definition",
87     "Reserved Memory Region",
88     "Root Port ATS Capability",
89     "Remapping Hardware Static Affinity",
90     "Unknown SubTable Type"         /* Reserved */
91 };
92
93 static const char           *AcpiDmEinjActions[] =
94 {
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     "Unknown Action"
104 };
105
106 static const char           *AcpiDmEinjInstructions[] =
107 {
108     "Read Register",
109     "Read Register Value",
110     "Write Register",
111     "Write Register Value",
112     "Noop",
113     "Unknown Instruction"
114 };
115
116 static const char           *AcpiDmErstActions[] =
117 {
118     "Begin Write Operation",
119     "Begin Read Operation",
120     "Begin Clear Operation",
121     "End Operation",
122     "Set Record Offset",
123     "Execute Operation",
124     "Check Busy Status",
125     "Get Command Status",
126     "Get Record Identifier",
127     "Set Record Identifier",
128     "Get Record Count",
129     "Begin Dummy Write",
130     "Unused/Unknown Action",
131     "Get Error Address Range",
132     "Get Error Address Length",
133     "Get Error Attributes",
134     "Unknown Action"
135 };
136
137 static const char           *AcpiDmErstInstructions[] =
138 {
139     "Read Register",
140     "Read Register Value",
141     "Write Register",
142     "Write Register Value",
143     "Noop",
144     "Load Var1",
145     "Load Var2",
146     "Store Var1",
147     "Add",
148     "Subtract",
149     "Add Value",
150     "Subtract Value",
151     "Stall",
152     "Stall While True",
153     "Skip Next If True",
154     "GoTo",
155     "Set Source Address",
156     "Set Destination Address",
157     "Move Data",
158     "Unknown Instruction"
159 };
160
161 static const char           *AcpiDmHestSubnames[] =
162 {
163     "IA-32 Machine Check Exception",
164     "IA-32 Corrected Machine Check",
165     "IA-32 Non-Maskable Interrupt",
166     "Unknown SubTable Type",        /* 3 - Reserved */
167     "Unknown SubTable Type",        /* 4 - Reserved */
168     "Unknown SubTable Type",        /* 5 - Reserved */
169     "PCI Express Root Port AER",
170     "PCI Express AER (AER Endpoint)",
171     "PCI Express/PCI-X Bridge AER",
172     "Generic Hardware Error Source",
173     "Unknown SubTable Type"         /* Reserved */
174 };
175
176 static const char           *AcpiDmHestNotifySubnames[] =
177 {
178     "Polled",
179     "External Interrupt",
180     "Local Interrupt",
181     "SCI",
182     "NMI",
183     "Unknown Notify Type"           /* Reserved */
184 };
185
186 static const char           *AcpiDmMadtSubnames[] =
187 {
188     "Processor Local APIC",         /* ACPI_MADT_TYPE_LOCAL_APIC */
189     "I/O APIC",                     /* ACPI_MADT_TYPE_IO_APIC */
190     "Interrupt Source Override",    /* ACPI_MADT_TYPE_INTERRUPT_OVERRIDE */
191     "NMI Source",                   /* ACPI_MADT_TYPE_NMI_SOURCE */
192     "Local APIC NMI",               /* ACPI_MADT_TYPE_LOCAL_APIC_NMI */
193     "Local APIC Address Override",  /* ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE */
194     "I/O SAPIC",                    /* ACPI_MADT_TYPE_IO_SAPIC */
195     "Local SAPIC",                  /* ACPI_MADT_TYPE_LOCAL_SAPIC */
196     "Platform Interrupt Sources",   /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */
197     "Processor Local x2APIC",       /* ACPI_MADT_TYPE_LOCAL_X2APIC */
198     "Local x2APIC NMI",             /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */
199     "Unknown SubTable Type"         /* Reserved */
200 };
201
202 static const char           *AcpiDmSlicSubnames[] =
203 {
204     "Public Key Structure",
205     "Windows Marker Structure",
206     "Unknown SubTable Type"         /* Reserved */
207 };
208
209 static const char           *AcpiDmSratSubnames[] =
210 {
211     "Processor Local APIC/SAPIC Affinity",
212     "Memory Affinity",
213     "Processor Local x2APIC Affinity",
214     "Unknown SubTable Type"         /* Reserved */
215 };
216
217 static const char           *AcpiDmIvrsSubnames[] =
218 {
219     "Hardware Definition Block",
220     "Memory Definition Block",
221     "Unknown SubTable Type"         /* Reserved */
222 };
223
224
225 #define ACPI_FADT_PM_RESERVED       8
226
227 static const char           *AcpiDmFadtProfiles[] =
228 {
229     "Unspecified",
230     "Desktop",
231     "Mobile",
232     "Workstation",
233     "Enterprise Server",
234     "SOHO Server",
235     "Appliance PC",
236     "Performance Server",
237     "Unknown Profile Type"
238 };
239
240 #define ACPI_GAS_WIDTH_RESERVED     5
241
242 static const char           *AcpiDmGasAccessWidth[] =
243 {
244     "Undefined/Legacy",
245     "Byte Access:8",
246     "Word Access:16",
247     "DWord Access:32",
248     "QWord Access:64",
249     "Unknown Width Encoding"
250 };
251
252
253 /*******************************************************************************
254  *
255  * ACPI Table Data, indexed by signature.
256  *
257  * Each entry contains: Signature, Table Info, Handler, DtHandler,
258  *  Template, Description
259  *
260  * Simple tables have only a TableInfo structure, complex tables have a
261  * handler. This table must be NULL terminated. RSDP and FACS are
262  * special-cased elsewhere.
263  *
264  ******************************************************************************/
265
266 ACPI_DMTABLE_DATA    AcpiDmTableData[] =
267 {
268     {ACPI_SIG_ASF,  NULL,                   AcpiDmDumpAsf,  DtCompileAsf,   TemplateAsf,    "Alert Standard Format table"},
269     {ACPI_SIG_BOOT, AcpiDmTableInfoBoot,    NULL,           NULL,           TemplateBoot,   "Simple Boot Flag Table"},
270     {ACPI_SIG_BERT, AcpiDmTableInfoBert,    NULL,           NULL,           TemplateBert,   "Boot Error Record Table"},
271     {ACPI_SIG_CPEP, NULL,                   AcpiDmDumpCpep, DtCompileCpep,  TemplateCpep,   "Corrected Platform Error Polling table"},
272     {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp,    NULL,           NULL,           TemplateDbgp,   "Debug Port table"},
273     {ACPI_SIG_DMAR, NULL,                   AcpiDmDumpDmar, DtCompileDmar,  TemplateDmar,   "DMA Remapping table"},
274     {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt,    NULL,           NULL,           TemplateEcdt,   "Embedded Controller Boot Resources Table"},
275     {ACPI_SIG_EINJ, NULL,                   AcpiDmDumpEinj, DtCompileEinj,  TemplateEinj,   "Error Injection table"},
276     {ACPI_SIG_ERST, NULL,                   AcpiDmDumpErst, DtCompileErst,  TemplateErst,   "Error Record Serialization Table"},
277     {ACPI_SIG_FADT, NULL,                   AcpiDmDumpFadt, DtCompileFadt,  TemplateFadt,   "Fixed ACPI Description Table"},
278     {ACPI_SIG_HEST, NULL,                   AcpiDmDumpHest, DtCompileHest,  TemplateHest,   "Hardware Error Source Table"},
279     {ACPI_SIG_HPET, AcpiDmTableInfoHpet,    NULL,           NULL,           TemplateHpet,   "High Precision Event Timer table"},
280     {ACPI_SIG_IVRS, NULL,                   AcpiDmDumpIvrs, DtCompileIvrs,  TemplateIvrs,   "I/O Virtualization Reporting Structure"},
281     {ACPI_SIG_MADT, NULL,                   AcpiDmDumpMadt, DtCompileMadt,  TemplateMadt,   "Multiple APIC Description Table"},
282     {ACPI_SIG_MCFG, NULL,                   AcpiDmDumpMcfg, DtCompileMcfg,  TemplateMcfg,   "Memory Mapped Configuration table"},
283     {ACPI_SIG_MCHI, AcpiDmTableInfoMchi,    NULL,           NULL,           TemplateMchi,   "Management Controller Host Interface table"},
284     {ACPI_SIG_MSCT, NULL,                   AcpiDmDumpMsct, DtCompileMsct,  TemplateMsct,   "Maximum System Characteristics Table"},
285     {ACPI_SIG_RSDT, NULL,                   AcpiDmDumpRsdt, DtCompileRsdt,  TemplateRsdt,   "Root System Description Table"},
286     {ACPI_SIG_SBST, AcpiDmTableInfoSbst,    NULL,           NULL,           TemplateSbst,   "Smart Battery Specification Table"},
287     {ACPI_SIG_SLIC, NULL,                   AcpiDmDumpSlic, DtCompileSlic,  TemplateSlic,   "Software Licensing Description Table"},
288     {ACPI_SIG_SLIT, NULL,                   AcpiDmDumpSlit, DtCompileSlit,  TemplateSlit,   "System Locality Information Table"},
289     {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr,    NULL,           NULL,           TemplateSpcr,   "Serial Port Console Redirection table"},
290     {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi,    NULL,           NULL,           TemplateSpmi,   "Server Platform Management Interface table"},
291     {ACPI_SIG_SRAT, NULL,                   AcpiDmDumpSrat, DtCompileSrat,  TemplateSrat,   "System Resource Affinity Table"},
292     {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa,    NULL,           NULL,           TemplateTcpa,   "Trusted Computing Platform Alliance table"},
293     {ACPI_SIG_UEFI, AcpiDmTableInfoUefi,    NULL,           DtCompileUefi,  TemplateUefi,   "UEFI Boot Optimization Table"},
294     {ACPI_SIG_WAET, AcpiDmTableInfoWaet,    NULL,           NULL,           TemplateWaet,   "Windows ACPI Emulated Devices Table"},
295     {ACPI_SIG_WDAT, NULL,                   AcpiDmDumpWdat, DtCompileWdat,  TemplateWdat,   "Watchdog Action Table"},
296     {ACPI_SIG_WDDT, AcpiDmTableInfoWddt,    NULL,           NULL,           TemplateWddt,   "Watchdog Description Table"},
297     {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt,    NULL,           NULL,           TemplateWdrt,   "Watchdog Resource Table"},
298     {ACPI_SIG_XSDT, NULL,                   AcpiDmDumpXsdt, DtCompileXsdt,  TemplateXsdt,   "Extended System Description Table"},
299     {NULL,          NULL,                   NULL,           NULL,           NULL,           NULL}
300 };
301
302
303 /*******************************************************************************
304  *
305  * FUNCTION:    AcpiDmGenerateChecksum
306  *
307  * PARAMETERS:  Table               - Pointer to table to be checksummed
308  *              Length              - Length of the table
309  *              OriginalChecksum    - Value of the checksum field
310  *
311  * RETURN:      8 bit checksum of buffer
312  *
313  * DESCRIPTION: Computes an 8 bit checksum of the table.
314  *
315  ******************************************************************************/
316
317 UINT8
318 AcpiDmGenerateChecksum (
319     void                    *Table,
320     UINT32                  Length,
321     UINT8                   OriginalChecksum)
322 {
323     UINT8                   Checksum;
324
325
326     /* Sum the entire table as-is */
327
328     Checksum = AcpiTbChecksum ((UINT8 *) Table, Length);
329
330     /* Subtract off the existing checksum value in the table */
331
332     Checksum = (UINT8) (Checksum - OriginalChecksum);
333
334     /* Compute the final checksum */
335
336     Checksum = (UINT8) (0 - Checksum);
337     return (Checksum);
338 }
339
340
341 /*******************************************************************************
342  *
343  * FUNCTION:    AcpiDmGetTableData
344  *
345  * PARAMETERS:  Signature           - ACPI signature (4 chars) to match
346  *
347  * RETURN:      Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
348  *
349  * DESCRIPTION: Find a match in the global table of supported ACPI tables
350  *
351  ******************************************************************************/
352
353 ACPI_DMTABLE_DATA *
354 AcpiDmGetTableData (
355     char                    *Signature)
356 {
357     ACPI_DMTABLE_DATA       *TableData;
358
359
360     for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
361     {
362         if (ACPI_COMPARE_NAME (Signature, TableData->Signature))
363         {
364             return (TableData);
365         }
366     }
367
368     return (NULL);
369 }
370
371
372 /*******************************************************************************
373  *
374  * FUNCTION:    AcpiDmDumpDataTable
375  *
376  * PARAMETERS:  Table               - An ACPI table
377  *
378  * RETURN:      None.
379  *
380  * DESCRIPTION: Format the contents of an ACPI data table (any table other
381  *              than an SSDT or DSDT that does not contain executable AML code)
382  *
383  ******************************************************************************/
384
385 void
386 AcpiDmDumpDataTable (
387     ACPI_TABLE_HEADER       *Table)
388 {
389     ACPI_STATUS             Status;
390     ACPI_DMTABLE_DATA       *TableData;
391     UINT32                  Length;
392
393
394     /* Ignore tables that contain AML */
395
396     if (AcpiUtIsAmlTable (Table))
397     {
398         return;
399     }
400
401     /*
402      * Handle tables that don't use the common ACPI table header structure.
403      * Currently, these are the FACS and RSDP.
404      */
405     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
406     {
407         Length = Table->Length;
408         AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
409     }
410     else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
411     {
412         Length = AcpiDmDumpRsdp (Table);
413     }
414     else
415     {
416         /*
417          * All other tables must use the common ACPI table header, dump it now
418          */
419         Length = Table->Length;
420         Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
421         if (ACPI_FAILURE (Status))
422         {
423             return;
424         }
425         AcpiOsPrintf ("\n");
426
427         /* Match signature and dispatch appropriately */
428
429         TableData = AcpiDmGetTableData (Table->Signature);
430         if (!TableData)
431         {
432             if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
433             {
434                 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
435                     Table->Signature);
436             }
437             else
438             {
439                 AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
440                     Table->Signature);
441             }
442         }
443         else if (TableData->TableHandler)
444         {
445             /* Complex table, has a handler */
446
447             TableData->TableHandler (Table);
448         }
449         else if (TableData->TableInfo)
450         {
451             /* Simple table, just walk the info table */
452
453             AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
454         }
455     }
456
457     if (!Gbl_DoTemplates || Gbl_VerboseTemplates)
458     {
459         /* Dump the raw table data */
460
461         AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
462             ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
463         AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY);
464     }
465 }
466
467
468 /*******************************************************************************
469  *
470  * FUNCTION:    AcpiDmLineHeader
471  *
472  * PARAMETERS:  Offset              - Current byte offset, from table start
473  *              ByteLength          - Length of the field in bytes, 0 for flags
474  *              Name                - Name of this field
475  *              Value               - Optional value, displayed on left of ':'
476  *
477  * RETURN:      None
478  *
479  * DESCRIPTION: Utility routines for formatting output lines. Displays the
480  *              current table offset in hex and decimal, the field length,
481  *              and the field name.
482  *
483  ******************************************************************************/
484
485 void
486 AcpiDmLineHeader (
487     UINT32                  Offset,
488     UINT32                  ByteLength,
489     char                    *Name)
490 {
491
492     /* Allow a null name for fields that span multiple lines (large buffers) */
493
494     if (!Name)
495     {
496         Name = "";
497     }
498
499     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
500     {
501         if (ByteLength)
502         {
503             AcpiOsPrintf ("[%.4d] %34s : ", ByteLength, Name);
504         }
505         else
506         {
507             if (*Name)
508             {
509                 AcpiOsPrintf ("%41s : ", Name);
510             }
511             else
512             {
513                 AcpiOsPrintf ("%41s   ", Name);
514             }
515         }
516     }
517     else /* Normal disassembler or verbose template */
518     {
519         if (ByteLength)
520         {
521             AcpiOsPrintf ("[%3.3Xh %4.4d% 4d] %28s : ",
522                 Offset, Offset, ByteLength, Name);
523         }
524         else
525         {
526             if (*Name)
527             {
528                 AcpiOsPrintf ("%44s : ", Name);
529             }
530             else
531             {
532                 AcpiOsPrintf ("%44s   ", Name);
533             }
534         }
535     }
536 }
537
538 void
539 AcpiDmLineHeader2 (
540     UINT32                  Offset,
541     UINT32                  ByteLength,
542     char                    *Name,
543     UINT32                  Value)
544 {
545
546     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
547     {
548         if (ByteLength)
549         {
550             AcpiOsPrintf ("[%.4d] %30s %3d : ",
551                 ByteLength, Name, Value);
552         }
553         else
554         {
555             AcpiOsPrintf ("%36s % 3d : ",
556                 Name, Value);
557         }
558     }
559     else /* Normal disassembler or verbose template */
560     {
561         if (ByteLength)
562         {
563             AcpiOsPrintf ("[%3.3Xh %4.4d %3d] %24s %3d : ",
564                 Offset, Offset, ByteLength, Name, Value);
565         }
566         else
567         {
568             AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s %3d : ",
569                 Offset, Offset, Name, Value);
570         }
571     }
572 }
573
574
575 /*******************************************************************************
576  *
577  * FUNCTION:    AcpiDmDumpTable
578  *
579  * PARAMETERS:  TableLength         - Length of the entire ACPI table
580  *              TableOffset         - Starting offset within the table for this
581  *                                    sub-descriptor (0 if main table)
582  *              Table               - The ACPI table
583  *              SubtableLength      - Length of this sub-descriptor
584  *              Info                - Info table for this ACPI table
585  *
586  * RETURN:      None
587  *
588  * DESCRIPTION: Display ACPI table contents by walking the Info table.
589  *
590  * Note: This function must remain in sync with DtGetFieldLength.
591  *
592  ******************************************************************************/
593
594 ACPI_STATUS
595 AcpiDmDumpTable (
596     UINT32                  TableLength,
597     UINT32                  TableOffset,
598     void                    *Table,
599     UINT32                  SubtableLength,
600     ACPI_DMTABLE_INFO       *Info)
601 {
602     UINT8                   *Target;
603     UINT32                  CurrentOffset;
604     UINT32                  ByteLength;
605     UINT8                   Temp8;
606     UINT16                  Temp16;
607     ACPI_DMTABLE_DATA       *TableData;
608     const char              *Name;
609     BOOLEAN                 LastOutputBlankLine = FALSE;
610     char                    RepairedName[8];
611
612
613     if (!Info)
614     {
615         AcpiOsPrintf ("Display not implemented\n");
616         return (AE_NOT_IMPLEMENTED);
617     }
618
619     /* Walk entire Info table; Null name terminates */
620
621     for (; Info->Name; Info++)
622     {
623         /*
624          * Target points to the field within the ACPI Table. CurrentOffset is
625          * the offset of the field from the start of the main table.
626          */
627         Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
628         CurrentOffset = TableOffset + Info->Offset;
629
630         /* Check for beyond EOT or beyond subtable end */
631
632         if ((CurrentOffset >= TableLength) ||
633             (SubtableLength && (Info->Offset >= SubtableLength)))
634         {
635             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
636             return (AE_BAD_DATA);
637         }
638
639         /* Generate the byte length for this field */
640
641         switch (Info->Opcode)
642         {
643         case ACPI_DMT_UINT8:
644         case ACPI_DMT_CHKSUM:
645         case ACPI_DMT_SPACEID:
646         case ACPI_DMT_ACCWIDTH:
647         case ACPI_DMT_IVRS:
648         case ACPI_DMT_MADT:
649         case ACPI_DMT_SRAT:
650         case ACPI_DMT_ASF:
651         case ACPI_DMT_HESTNTYP:
652         case ACPI_DMT_FADTPM:
653         case ACPI_DMT_EINJACT:
654         case ACPI_DMT_EINJINST:
655         case ACPI_DMT_ERSTACT:
656         case ACPI_DMT_ERSTINST:
657             ByteLength = 1;
658             break;
659         case ACPI_DMT_UINT16:
660         case ACPI_DMT_DMAR:
661         case ACPI_DMT_HEST:
662             ByteLength = 2;
663             break;
664         case ACPI_DMT_UINT24:
665             ByteLength = 3;
666             break;
667         case ACPI_DMT_UINT32:
668         case ACPI_DMT_NAME4:
669         case ACPI_DMT_SIG:
670         case ACPI_DMT_SLIC:
671             ByteLength = 4;
672             break;
673         case ACPI_DMT_NAME6:
674             ByteLength = 6;
675             break;
676         case ACPI_DMT_UINT56:
677         case ACPI_DMT_BUF7:
678             ByteLength = 7;
679             break;
680         case ACPI_DMT_UINT64:
681         case ACPI_DMT_NAME8:
682             ByteLength = 8;
683             break;
684         case ACPI_DMT_BUF16:
685         case ACPI_DMT_UUID:
686             ByteLength = 16;
687             break;
688         case ACPI_DMT_BUF128:
689             ByteLength = 128;
690             break;
691         case ACPI_DMT_STRING:
692             ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
693             break;
694         case ACPI_DMT_GAS:
695             if (!LastOutputBlankLine)
696             {
697                 AcpiOsPrintf ("\n");
698                 LastOutputBlankLine = TRUE;
699             }
700             ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
701             break;
702         case ACPI_DMT_HESTNTFY:
703             if (!LastOutputBlankLine)
704             {
705                 AcpiOsPrintf ("\n");
706                 LastOutputBlankLine = TRUE;
707             }
708             ByteLength = sizeof (ACPI_HEST_NOTIFY);
709             break;
710         default:
711             ByteLength = 0;
712             break;
713         }
714
715         if (CurrentOffset + ByteLength > TableLength)
716         {
717             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
718             return (AE_BAD_DATA);
719         }
720
721         /* Start a new line and decode the opcode */
722
723         AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
724
725         switch (Info->Opcode)
726         {
727         /* Single-bit Flag fields. Note: Opcode is the bit position */
728
729         case ACPI_DMT_FLAG0:
730         case ACPI_DMT_FLAG1:
731         case ACPI_DMT_FLAG2:
732         case ACPI_DMT_FLAG3:
733         case ACPI_DMT_FLAG4:
734         case ACPI_DMT_FLAG5:
735         case ACPI_DMT_FLAG6:
736         case ACPI_DMT_FLAG7:
737
738             AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
739             break;
740
741         /* 2-bit Flag fields */
742
743         case ACPI_DMT_FLAGS0:
744
745             AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
746             break;
747
748         case ACPI_DMT_FLAGS2:
749
750             AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
751             break;
752
753         /* Standard Data Types */
754
755         case ACPI_DMT_UINT8:
756
757             AcpiOsPrintf ("%2.2X\n", *Target);
758             break;
759
760         case ACPI_DMT_UINT16:
761
762             AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target));
763             break;
764
765         case ACPI_DMT_UINT24:
766
767             AcpiOsPrintf ("%2.2X%2.2X%2.2X\n",
768                 *Target, *(Target + 1), *(Target + 2));
769             break;
770
771         case ACPI_DMT_UINT32:
772
773             AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target));
774             break;
775
776         case ACPI_DMT_UINT56:
777
778             for (Temp8 = 0; Temp8 < 7; Temp8++)
779             {
780                 AcpiOsPrintf ("%2.2X", Target[Temp8]);
781             }
782             AcpiOsPrintf ("\n");
783             break;
784
785         case ACPI_DMT_UINT64:
786
787             AcpiOsPrintf ("%8.8X%8.8X\n",
788                 ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
789             break;
790
791         case ACPI_DMT_BUF7:
792         case ACPI_DMT_BUF16:
793         case ACPI_DMT_BUF128:
794
795             /*
796              * Buffer: Size depends on the opcode and was set above.
797              * Each hex byte is separated with a space.
798              * Multiple lines are separated by line continuation char.
799              */
800             for (Temp16 = 0; Temp16 < ByteLength; Temp16++)
801             {
802                 AcpiOsPrintf ("%2.2X", Target[Temp16]);
803                 if ((UINT32) (Temp16 + 1) < ByteLength)
804                 {
805                     if ((Temp16 > 0) && (!((Temp16+1) % 16)))
806                     {
807                         AcpiOsPrintf (" \\\n"); /* Line continuation */
808                         AcpiDmLineHeader (0, 0, NULL);
809                     }
810                     else
811                     {
812                         AcpiOsPrintf (" ");
813                     }
814                 }
815             }
816             AcpiOsPrintf ("\n");
817             break;
818
819         case ACPI_DMT_UUID:
820
821             /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */
822
823             (void) AuConvertUuidToString ((char *) Target, MsgBuffer);
824
825             AcpiOsPrintf ("%s\n", MsgBuffer);
826             break;
827
828         case ACPI_DMT_STRING:
829
830             AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
831             break;
832
833         /* Fixed length ASCII name fields */
834
835         case ACPI_DMT_SIG:
836
837             AcpiDmCheckAscii (Target, RepairedName, 4);
838             AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
839             TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
840             if (TableData)
841             {
842                 AcpiOsPrintf (STRING_FORMAT, TableData->Name);
843             }
844             else
845             {
846                 AcpiOsPrintf ("\n");
847             }
848             break;
849
850         case ACPI_DMT_NAME4:
851
852             AcpiDmCheckAscii (Target, RepairedName, 4);
853             AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
854             break;
855
856         case ACPI_DMT_NAME6:
857
858             AcpiDmCheckAscii (Target, RepairedName, 6);
859             AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
860             break;
861
862         case ACPI_DMT_NAME8:
863
864             AcpiDmCheckAscii (Target, RepairedName, 8);
865             AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
866             break;
867
868         /* Special Data Types */
869
870         case ACPI_DMT_CHKSUM:
871
872             /* Checksum, display and validate */
873
874             AcpiOsPrintf ("%2.2X", *Target);
875             Temp8 = AcpiDmGenerateChecksum (Table,
876                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
877                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
878             if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
879             {
880                 AcpiOsPrintf (
881                     "     /* Incorrect checksum, should be %2.2X */", Temp8);
882             }
883             AcpiOsPrintf ("\n");
884             break;
885
886         case ACPI_DMT_SPACEID:
887
888             /* Address Space ID */
889
890             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiUtGetRegionName (*Target));
891             break;
892
893         case ACPI_DMT_ACCWIDTH:
894
895             /* Encoded Access Width */
896
897             Temp8 = *Target;
898             if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
899             {
900                 Temp8 = ACPI_GAS_WIDTH_RESERVED;
901             }
902
903             AcpiOsPrintf (UINT8_FORMAT, Temp8, AcpiDmGasAccessWidth[Temp8]);
904             break;
905
906         case ACPI_DMT_GAS:
907
908             /* Generic Address Structure */
909
910             AcpiOsPrintf (STRING_FORMAT, "Generic Address Structure");
911             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
912                 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
913             AcpiOsPrintf ("\n");
914             LastOutputBlankLine = TRUE;
915             break;
916
917         case ACPI_DMT_ASF:
918
919             /* ASF subtable types */
920
921             Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
922             if (Temp16 > ACPI_ASF_TYPE_RESERVED)
923             {
924                 Temp16 = ACPI_ASF_TYPE_RESERVED;
925             }
926
927             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmAsfSubnames[Temp16]);
928             break;
929
930         case ACPI_DMT_DMAR:
931
932             /* DMAR subtable types */
933
934             Temp16 = ACPI_GET16 (Target);
935             if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
936             {
937                 Temp16 = ACPI_DMAR_TYPE_RESERVED;
938             }
939
940             AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
941             break;
942
943         case ACPI_DMT_EINJACT:
944
945             /* EINJ Action types */
946
947             Temp8 = *Target;
948             if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
949             {
950                 Temp8 = ACPI_EINJ_ACTION_RESERVED;
951             }
952
953             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjActions[Temp8]);
954             break;
955
956         case ACPI_DMT_EINJINST:
957
958             /* EINJ Instruction types */
959
960             Temp8 = *Target;
961             if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
962             {
963                 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
964             }
965
966             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjInstructions[Temp8]);
967             break;
968
969         case ACPI_DMT_ERSTACT:
970
971             /* ERST Action types */
972
973             Temp8 = *Target;
974             if (Temp8 > ACPI_ERST_ACTION_RESERVED)
975             {
976                 Temp8 = ACPI_ERST_ACTION_RESERVED;
977             }
978
979             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstActions[Temp8]);
980             break;
981
982         case ACPI_DMT_ERSTINST:
983
984             /* ERST Instruction types */
985
986             Temp8 = *Target;
987             if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
988             {
989                 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
990             }
991
992             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstInstructions[Temp8]);
993             break;
994
995         case ACPI_DMT_HEST:
996
997             /* HEST subtable types */
998
999             Temp16 = ACPI_GET16 (Target);
1000             if (Temp16 > ACPI_HEST_TYPE_RESERVED)
1001             {
1002                 Temp16 = ACPI_HEST_TYPE_RESERVED;
1003             }
1004
1005             AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
1006             break;
1007
1008         case ACPI_DMT_HESTNTFY:
1009
1010             AcpiOsPrintf (STRING_FORMAT, "Hardware Error Notification Structure");
1011             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
1012                 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
1013             AcpiOsPrintf ("\n");
1014             LastOutputBlankLine = TRUE;
1015             break;
1016
1017         case ACPI_DMT_HESTNTYP:
1018
1019             /* HEST Notify types */
1020
1021             Temp8 = *Target;
1022             if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
1023             {
1024                 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
1025             }
1026
1027             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmHestNotifySubnames[Temp8]);
1028             break;
1029
1030         case ACPI_DMT_MADT:
1031
1032             /* MADT subtable types */
1033
1034             Temp8 = *Target;
1035             if (Temp8 > ACPI_MADT_TYPE_RESERVED)
1036             {
1037                 Temp8 = ACPI_MADT_TYPE_RESERVED;
1038             }
1039
1040             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmMadtSubnames[Temp8]);
1041             break;
1042
1043         case ACPI_DMT_SLIC:
1044
1045             /* SLIC subtable types */
1046
1047             Temp8 = *Target;
1048             if (Temp8 > ACPI_SLIC_TYPE_RESERVED)
1049             {
1050                 Temp8 = ACPI_SLIC_TYPE_RESERVED;
1051             }
1052
1053             AcpiOsPrintf (UINT32_FORMAT, *Target, AcpiDmSlicSubnames[Temp8]);
1054             break;
1055
1056         case ACPI_DMT_SRAT:
1057
1058             /* SRAT subtable types */
1059
1060             Temp8 = *Target;
1061             if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
1062             {
1063                 Temp8 = ACPI_SRAT_TYPE_RESERVED;
1064             }
1065
1066             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmSratSubnames[Temp8]);
1067             break;
1068
1069         case ACPI_DMT_FADTPM:
1070
1071             /* FADT Preferred PM Profile names */
1072
1073             Temp8 = *Target;
1074             if (Temp8 > ACPI_FADT_PM_RESERVED)
1075             {
1076                 Temp8 = ACPI_FADT_PM_RESERVED;
1077             }
1078
1079             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmFadtProfiles[Temp8]);
1080             break;
1081
1082         case ACPI_DMT_IVRS:
1083
1084             /* IVRS subtable types */
1085
1086             Temp8 = *Target;
1087             switch (Temp8)
1088             {
1089             case ACPI_IVRS_TYPE_HARDWARE:
1090                 Name = AcpiDmIvrsSubnames[0];
1091                 break;
1092
1093             case ACPI_IVRS_TYPE_MEMORY1:
1094             case ACPI_IVRS_TYPE_MEMORY2:
1095             case ACPI_IVRS_TYPE_MEMORY3:
1096                 Name = AcpiDmIvrsSubnames[1];
1097                 break;
1098
1099             default:
1100                 Name = AcpiDmIvrsSubnames[2];
1101                 break;
1102             }
1103
1104             AcpiOsPrintf (UINT8_FORMAT, *Target, Name);
1105             break;
1106
1107         case ACPI_DMT_EXIT:
1108             return (AE_OK);
1109
1110         default:
1111             ACPI_ERROR ((AE_INFO,
1112                 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1113             return (AE_SUPPORT);
1114         }
1115     }
1116
1117     if (TableOffset && !SubtableLength)
1118     {
1119         /* If this table is not the main table, subtable must have valid length */
1120
1121         AcpiOsPrintf ("Invalid zero length subtable\n");
1122         return (AE_BAD_DATA);
1123     }
1124
1125     return (AE_OK);
1126 }
1127
1128
1129 /*******************************************************************************
1130  *
1131  * FUNCTION:    AcpiDmCheckAscii
1132  *
1133  * PARAMETERS:  Name                - Ascii string
1134  *              Count               - Number of characters to check
1135  *
1136  * RETURN:      None
1137  *
1138  * DESCRIPTION: Ensure that the requested number of characters are printable
1139  *              Ascii characters. Sets non-printable and null chars to <space>.
1140  *
1141  ******************************************************************************/
1142
1143 static void
1144 AcpiDmCheckAscii (
1145     UINT8                   *Name,
1146     char                    *RepairedName,
1147     UINT32                  Count)
1148 {
1149     UINT32                  i;
1150
1151
1152     for (i = 0; i < Count; i++)
1153     {
1154         RepairedName[i] = (char) Name[i];
1155
1156         if (!Name[i])
1157         {
1158             return;
1159         }
1160         if (!isprint (Name[i]))
1161         {
1162             RepairedName[i] = ' ';
1163         }
1164     }
1165 }