dmtable.c revision 220663
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/* 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
74static 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
84static 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
93static 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
106static 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
116static 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
137static 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
161static 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
176static const char           *AcpiDmHestNotifySubnames[] =
177{
178    "Polled",
179    "External Interrupt",
180    "Local Interrupt",
181    "SCI",
182    "NMI",
183    "Unknown Notify Type"           /* Reserved */
184};
185
186static 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
202static const char           *AcpiDmSlicSubnames[] =
203{
204    "Public Key Structure",
205    "Windows Marker Structure",
206    "Unknown SubTable Type"         /* Reserved */
207};
208
209static 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
217static 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
227static 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
242static 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
266ACPI_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
317UINT8
318AcpiDmGenerateChecksum (
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
353ACPI_DMTABLE_DATA *
354AcpiDmGetTableData (
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
385void
386AcpiDmDumpDataTable (
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
485void
486AcpiDmLineHeader (
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
538void
539AcpiDmLineHeader2 (
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
594ACPI_STATUS
595AcpiDmDumpTable (
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
1143static void
1144AcpiDmCheckAscii (
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}
1166