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