dmtable.c revision 1.1.1.1
1/******************************************************************************
2 *
3 * Module Name: dmtable - Support for ACPI tables that contain no AML code
4 *
5 *****************************************************************************/
6
7/******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights.  You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code.  No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision.  In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change.  Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee.  Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution.  In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government.  In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************/
115
116#include "acpi.h"
117#include "accommon.h"
118#include "acdisasm.h"
119#include "actables.h"
120#include "dtcompiler.h"
121
122/* This module used for application-level code only */
123
124#define _COMPONENT          ACPI_CA_DISASSEMBLER
125        ACPI_MODULE_NAME    ("dmtable")
126
127/* Local Prototypes */
128
129static void
130AcpiDmCheckAscii (
131    UINT8                   *Target,
132    char                    *RepairedName,
133    UINT32                  Count);
134
135UINT8
136AcpiTbGenerateChecksum (
137    ACPI_TABLE_HEADER       *Table);
138
139
140/* These tables map a subtable type to a description string */
141
142static const char           *AcpiDmAsfSubnames[] =
143{
144    "ASF Information",
145    "ASF Alerts",
146    "ASF Remote Control",
147    "ASF RMCP Boot Options",
148    "ASF Address",
149    "Unknown SubTable Type"         /* Reserved */
150};
151
152static const char           *AcpiDmDmarSubnames[] =
153{
154    "Hardware Unit Definition",
155    "Reserved Memory Region",
156    "Root Port ATS Capability",
157    "Remapping Hardware Static Affinity",
158    "Unknown SubTable Type"         /* Reserved */
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           *AcpiDmSratSubnames[] =
203{
204    "Processor Local APIC/SAPIC Affinity",
205    "Memory Affinity",
206    "Processor Local x2APIC Affinity",
207    "Unknown SubTable Type"         /* Reserved */
208};
209
210static const char           *AcpiDmIvrsSubnames[] =
211{
212    "Hardware Definition Block",
213    "Memory Definition Block",
214    "Unknown SubTable Type"         /* Reserved */
215};
216
217
218#define ACPI_FADT_PM_RESERVED       8
219
220static const char           *AcpiDmFadtProfiles[] =
221{
222    "Unspecified",
223    "Desktop",
224    "Mobile",
225    "Workstation",
226    "Enterprise Server",
227    "SOHO Server",
228    "Appliance PC",
229    "Performance Server",
230    "Unknown Profile Type"
231};
232
233/*******************************************************************************
234 *
235 * ACPI Table Data, indexed by signature.
236 *
237 * Each entry contains: Signature, Table Info, Handler, Description
238 *
239 * Simple tables have only a TableInfo structure, complex tables have a handler.
240 * This table must be NULL terminated. RSDP and FACS are special-cased
241 * elsewhere.
242 *
243 ******************************************************************************/
244
245static ACPI_DMTABLE_DATA    AcpiDmTableData[] =
246{
247    {ACPI_SIG_ASF,  NULL,                   AcpiDmDumpAsf,  DtCompileAsf,   "Alert Standard Format table"},
248    {ACPI_SIG_BOOT, AcpiDmTableInfoBoot,    NULL,           NULL,           "Simple Boot Flag Table"},
249    {ACPI_SIG_BERT, AcpiDmTableInfoBert,    NULL,           NULL,           "Boot Error Record Table"},
250    {ACPI_SIG_CPEP, NULL,                   AcpiDmDumpCpep, DtCompileCpep,  "Corrected Platform Error Polling table"},
251    {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp,    NULL,           NULL,           "Debug Port table"},
252    {ACPI_SIG_DMAR, NULL,                   AcpiDmDumpDmar, DtCompileDmar,  "DMA Remapping table"},
253    {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt,    NULL,           NULL,           "Embedded Controller Boot Resources Table"},
254    {ACPI_SIG_EINJ, NULL,                   AcpiDmDumpEinj, DtCompileEinj,  "Error Injection table"},
255    {ACPI_SIG_ERST, NULL,                   AcpiDmDumpErst, DtCompileErst,  "Error Record Serialization Table"},
256    {ACPI_SIG_FADT, NULL,                   AcpiDmDumpFadt, DtCompileFadt,  "Fixed ACPI Description Table"},
257    {ACPI_SIG_HEST, NULL,                   AcpiDmDumpHest, DtCompileHest,  "Hardware Error Source Table"},
258    {ACPI_SIG_HPET, AcpiDmTableInfoHpet,    NULL,           NULL,           "High Precision Event Timer table"},
259    {ACPI_SIG_IVRS, NULL,                   AcpiDmDumpIvrs, DtCompileIvrs,  "I/O Virtualization Reporting Structure"},
260    {ACPI_SIG_MADT, NULL,                   AcpiDmDumpMadt, DtCompileMadt,  "Multiple APIC Description Table"},
261    {ACPI_SIG_MCFG, NULL,                   AcpiDmDumpMcfg, DtCompileMcfg,  "Memory Mapped Configuration table"},
262    {ACPI_SIG_MCHI, AcpiDmTableInfoMchi,    NULL,           NULL,           "Management Controller Host Interface table"},
263    {ACPI_SIG_MSCT, NULL,                   AcpiDmDumpMsct, DtCompileMsct,  "Maximum System Characteristics Table"},
264    {ACPI_SIG_RSDT, NULL,                   AcpiDmDumpRsdt, DtCompileRsdt,  "Root System Description Table"},
265    {ACPI_SIG_SBST, AcpiDmTableInfoSbst,    NULL,           NULL,           "Smart Battery Specification Table"},
266    {ACPI_SIG_SLIC, AcpiDmTableInfoSlic,    NULL,           NULL,           "Software Licensing Description Table"},
267    {ACPI_SIG_SLIT, NULL,                   AcpiDmDumpSlit, DtCompileSlit,  "System Locality Information Table"},
268    {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr,    NULL,           NULL,           "Serial Port Console Redirection table"},
269    {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi,    NULL,           NULL,           "Server Platform Management Interface table"},
270    {ACPI_SIG_SRAT, NULL,                   AcpiDmDumpSrat, DtCompileSrat,  "System Resource Affinity Table"},
271    {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa,    NULL,           NULL,           "Trusted Computing Platform Alliance table"},
272    {ACPI_SIG_UEFI, AcpiDmTableInfoUefi,    NULL,           NULL,           "UEFI Boot Optimization Table"},
273    {ACPI_SIG_WAET, AcpiDmTableInfoWaet,    NULL,           NULL,           "Windows ACPI Emulated Devices Table"},
274    {ACPI_SIG_WDAT, NULL,                   AcpiDmDumpWdat, DtCompileWdat,  "Watchdog Action Table"},
275    {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt,    NULL,           NULL,           "Watchdog Resource Table"},
276    {ACPI_SIG_XSDT, NULL,                   AcpiDmDumpXsdt, DtCompileXsdt,  "Extended System Description Table"},
277    {NULL,          NULL,                   NULL,           NULL,           NULL}
278};
279
280
281/*******************************************************************************
282 *
283 * FUNCTION:    AcpiTbGenerateChecksum
284 *
285 * PARAMETERS:  Table               - Pointer to a valid ACPI table (with a
286 *                                    standard ACPI header)
287 *
288 * RETURN:      8 bit checksum of buffer
289 *
290 * DESCRIPTION: Computes an 8 bit checksum of the table.
291 *
292 ******************************************************************************/
293
294UINT8
295AcpiTbGenerateChecksum (
296    ACPI_TABLE_HEADER       *Table)
297{
298    UINT8                   Checksum;
299
300
301    /* Sum the entire table as-is */
302
303    Checksum = AcpiTbChecksum ((UINT8 *) Table, Table->Length);
304
305    /* Subtract off the existing checksum value in the table */
306
307    Checksum = (UINT8) (Checksum - Table->Checksum);
308
309    /* Compute the final checksum */
310
311    Checksum = (UINT8) (0 - Checksum);
312    return (Checksum);
313}
314
315
316/*******************************************************************************
317 *
318 * FUNCTION:    AcpiDmGetTableData
319 *
320 * PARAMETERS:  Signature           - ACPI signature (4 chars) to match
321 *
322 * RETURN:      Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
323 *
324 * DESCRIPTION: Find a match in the global table of supported ACPI tables
325 *
326 ******************************************************************************/
327
328ACPI_DMTABLE_DATA *
329AcpiDmGetTableData (
330    char                    *Signature)
331{
332    ACPI_DMTABLE_DATA       *TableData;
333
334
335    for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
336    {
337        if (ACPI_COMPARE_NAME (Signature, TableData->Signature))
338        {
339            return (TableData);
340        }
341    }
342
343    return (NULL);
344}
345
346
347/*******************************************************************************
348 *
349 * FUNCTION:    AcpiDmDumpDataTable
350 *
351 * PARAMETERS:  Table               - An ACPI table
352 *
353 * RETURN:      None.
354 *
355 * DESCRIPTION: Format the contents of an ACPI data table (any table other
356 *              than an SSDT or DSDT that does not contain executable AML code)
357 *
358 ******************************************************************************/
359
360void
361AcpiDmDumpDataTable (
362    ACPI_TABLE_HEADER       *Table)
363{
364    ACPI_STATUS             Status;
365    ACPI_DMTABLE_DATA       *TableData;
366    UINT32                  Length;
367
368
369    /* Ignore tables that contain AML */
370
371    if (AcpiUtIsAmlTable (Table))
372    {
373        return;
374    }
375
376    /*
377     * Handle tables that don't use the common ACPI table header structure.
378     * Currently, these are the FACS and RSDP.
379     */
380    if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
381    {
382        Length = Table->Length;
383        AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
384    }
385    else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
386    {
387        Length = AcpiDmDumpRsdp (Table);
388    }
389    else
390    {
391        /*
392         * All other tables must use the common ACPI table header, dump it now
393         */
394        Length = Table->Length;
395        Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
396        if (ACPI_FAILURE (Status))
397        {
398            return;
399        }
400        AcpiOsPrintf ("\n");
401
402        /* Match signature and dispatch appropriately */
403
404        TableData = AcpiDmGetTableData (Table->Signature);
405        if (!TableData)
406        {
407            if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
408            {
409                AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
410                    Table->Signature);
411            }
412            else
413            {
414                AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
415                    Table->Signature);
416            }
417        }
418        else if (TableData->TableHandler)
419        {
420            /* Complex table, has a handler */
421
422            TableData->TableHandler (Table);
423        }
424        else if (TableData->TableInfo)
425        {
426            /* Simple table, just walk the info table */
427
428            AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
429        }
430    }
431
432    /* Always dump the raw table data */
433
434    AcpiOsPrintf ("\nRaw Table Data\n\n");
435    AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY);
436}
437
438
439/*******************************************************************************
440 *
441 * FUNCTION:    AcpiDmLineHeader
442 *
443 * PARAMETERS:  Offset              - Current byte offset, from table start
444 *              ByteLength          - Length of the field in bytes, 0 for flags
445 *              Name                - Name of this field
446 *              Value               - Optional value, displayed on left of ':'
447 *
448 * RETURN:      None
449 *
450 * DESCRIPTION: Utility routines for formatting output lines. Displays the
451 *              current table offset in hex and decimal, the field length,
452 *              and the field name.
453 *
454 ******************************************************************************/
455
456void
457AcpiDmLineHeader (
458    UINT32                  Offset,
459    UINT32                  ByteLength,
460    char                    *Name)
461{
462
463    if (ByteLength)
464    {
465        AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %28s : ",
466            Offset, Offset, ByteLength, Name);
467    }
468    else
469    {
470        AcpiOsPrintf ("%43s : ",
471            Name);
472    }
473}
474
475void
476AcpiDmLineHeader2 (
477    UINT32                  Offset,
478    UINT32                  ByteLength,
479    char                    *Name,
480    UINT32                  Value)
481{
482
483    if (ByteLength)
484    {
485        AcpiOsPrintf ("[%3.3Xh %4.4d% 3d] %24s % 3d : ",
486            Offset, Offset, ByteLength, Name, Value);
487    }
488    else
489    {
490        AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s % 3d : ",
491            Offset, Offset, Name, Value);
492    }
493}
494
495
496/*******************************************************************************
497 *
498 * FUNCTION:    AcpiDmDumpTable
499 *
500 * PARAMETERS:  TableLength         - Length of the entire ACPI table
501 *              TableOffset         - Starting offset within the table for this
502 *                                    sub-descriptor (0 if main table)
503 *              Table               - The ACPI table
504 *              SubtableLength      - Length of this sub-descriptor
505 *              Info                - Info table for this ACPI table
506 *
507 * RETURN:      None
508 *
509 * DESCRIPTION: Display ACPI table contents by walking the Info table.
510 *
511 ******************************************************************************/
512
513ACPI_STATUS
514AcpiDmDumpTable (
515    UINT32                  TableLength,
516    UINT32                  TableOffset,
517    void                    *Table,
518    UINT32                  SubtableLength,
519    ACPI_DMTABLE_INFO       *Info)
520{
521    UINT8                   *Target;
522    UINT32                  CurrentOffset;
523    UINT32                  ByteLength;
524    UINT8                   Temp8;
525    UINT16                  Temp16;
526    ACPI_DMTABLE_DATA       *TableData;
527    const char              *Name;
528    BOOLEAN                 LastOutputBlankLine = FALSE;
529    char                    RepairedName[8];
530
531
532    if (!Info)
533    {
534        AcpiOsPrintf ("Display not implemented\n");
535        return (AE_NOT_IMPLEMENTED);
536    }
537
538    /* Walk entire Info table; Null name terminates */
539
540    for (; Info->Name; Info++)
541    {
542        /*
543         * Target points to the field within the ACPI Table. CurrentOffset is
544         * the offset of the field from the start of the main table.
545         */
546        Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
547        CurrentOffset = TableOffset + Info->Offset;
548
549        /* Check for beyond EOT or beyond subtable end */
550
551        if ((CurrentOffset >= TableLength) ||
552            (SubtableLength && (Info->Offset >= SubtableLength)))
553        {
554            AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
555            return (AE_BAD_DATA);
556        }
557
558        /* Generate the byte length for this field */
559
560        switch (Info->Opcode)
561        {
562        case ACPI_DMT_UINT8:
563        case ACPI_DMT_CHKSUM:
564        case ACPI_DMT_SPACEID:
565        case ACPI_DMT_IVRS:
566        case ACPI_DMT_MADT:
567        case ACPI_DMT_SRAT:
568        case ACPI_DMT_ASF:
569        case ACPI_DMT_HESTNTYP:
570        case ACPI_DMT_FADTPM:
571            ByteLength = 1;
572            break;
573        case ACPI_DMT_UINT16:
574        case ACPI_DMT_DMAR:
575        case ACPI_DMT_HEST:
576            ByteLength = 2;
577            break;
578        case ACPI_DMT_UINT24:
579            ByteLength = 3;
580            break;
581        case ACPI_DMT_UINT32:
582        case ACPI_DMT_NAME4:
583        case ACPI_DMT_SIG:
584            ByteLength = 4;
585            break;
586        case ACPI_DMT_NAME6:
587            ByteLength = 6;
588            break;
589        case ACPI_DMT_UINT56:
590            ByteLength = 7;
591            break;
592        case ACPI_DMT_UINT64:
593        case ACPI_DMT_NAME8:
594            ByteLength = 8;
595            break;
596        case ACPI_DMT_BUF16:
597            ByteLength = 16;
598            break;
599        case ACPI_DMT_STRING:
600            ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
601            break;
602        case ACPI_DMT_GAS:
603            if (!LastOutputBlankLine)
604            {
605                AcpiOsPrintf ("\n");
606                LastOutputBlankLine = TRUE;
607            }
608            ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
609            break;
610        case ACPI_DMT_HESTNTFY:
611            if (!LastOutputBlankLine)
612            {
613                AcpiOsPrintf ("\n");
614                LastOutputBlankLine = TRUE;
615            }
616            ByteLength = sizeof (ACPI_HEST_NOTIFY);
617            break;
618        default:
619            ByteLength = 0;
620            break;
621        }
622
623        if (CurrentOffset + ByteLength > TableLength)
624        {
625            AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
626            return (AE_BAD_DATA);
627        }
628
629        /* Start a new line and decode the opcode */
630
631        AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
632
633        switch (Info->Opcode)
634        {
635        /* Single-bit Flag fields. Note: Opcode is the bit position */
636
637        case ACPI_DMT_FLAG0:
638        case ACPI_DMT_FLAG1:
639        case ACPI_DMT_FLAG2:
640        case ACPI_DMT_FLAG3:
641        case ACPI_DMT_FLAG4:
642        case ACPI_DMT_FLAG5:
643        case ACPI_DMT_FLAG6:
644        case ACPI_DMT_FLAG7:
645
646            AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
647            break;
648
649        /* 2-bit Flag fields */
650
651        case ACPI_DMT_FLAGS0:
652
653            AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
654            break;
655
656        case ACPI_DMT_FLAGS2:
657
658            AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
659            break;
660
661        /* Standard Data Types */
662
663        case ACPI_DMT_UINT8:
664
665            AcpiOsPrintf ("%2.2X\n", *Target);
666            break;
667
668        case ACPI_DMT_UINT16:
669
670            AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target));
671            break;
672
673        case ACPI_DMT_UINT24:
674
675            AcpiOsPrintf ("%2.2X%2.2X%2.2X\n",
676                *Target, *(Target + 1), *(Target + 2));
677            break;
678
679        case ACPI_DMT_UINT32:
680
681            AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target));
682            break;
683
684        case ACPI_DMT_UINT56:
685
686            for (Temp8 = 0; Temp8 < 7; Temp8++)
687            {
688                AcpiOsPrintf ("%2.2X", Target[Temp8]);
689            }
690            AcpiOsPrintf ("\n");
691            break;
692
693        case ACPI_DMT_UINT64:
694
695            AcpiOsPrintf ("%8.8X%8.8X\n",
696                ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
697            break;
698
699        case ACPI_DMT_BUF16:
700
701            /* Buffer of length 16 */
702
703            for (Temp8 = 0; Temp8 < 16; Temp8++)
704            {
705                AcpiOsPrintf ("%2.2X,", Target[Temp8]);
706            }
707            AcpiOsPrintf ("\n");
708            break;
709
710        case ACPI_DMT_STRING:
711
712            AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
713            break;
714
715        /* Fixed length ASCII name fields */
716
717        case ACPI_DMT_SIG:
718
719            AcpiDmCheckAscii (Target, RepairedName, 4);
720            AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
721            TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
722            if (TableData)
723            {
724                AcpiOsPrintf ("/* %s */", TableData->Name);
725            }
726            AcpiOsPrintf ("\n");
727            break;
728
729        case ACPI_DMT_NAME4:
730
731            AcpiDmCheckAscii (Target, RepairedName, 4);
732            AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
733            break;
734
735        case ACPI_DMT_NAME6:
736
737            AcpiDmCheckAscii (Target, RepairedName, 6);
738            AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
739            break;
740
741        case ACPI_DMT_NAME8:
742
743            AcpiDmCheckAscii (Target, RepairedName, 8);
744            AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
745            break;
746
747        /* Special Data Types */
748
749        case ACPI_DMT_CHKSUM:
750
751            /* Checksum, display and validate */
752
753            AcpiOsPrintf ("%2.2X", *Target);
754            Temp8 = AcpiTbGenerateChecksum (Table);
755            if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
756            {
757                AcpiOsPrintf (
758                    "     /* Incorrect checksum, should be %2.2X */", Temp8);
759            }
760            AcpiOsPrintf ("\n");
761            break;
762
763        case ACPI_DMT_SPACEID:
764
765            /* Address Space ID */
766
767            AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target));
768            break;
769
770        case ACPI_DMT_GAS:
771
772            /* Generic Address Structure */
773
774            AcpiOsPrintf ("<Generic Address Structure>\n");
775            AcpiDmDumpTable (TableLength, CurrentOffset, Target,
776                sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
777            AcpiOsPrintf ("\n");
778            LastOutputBlankLine = TRUE;
779            break;
780
781        case ACPI_DMT_ASF:
782
783            /* ASF subtable types */
784
785            Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
786            if (Temp16 > ACPI_ASF_TYPE_RESERVED)
787            {
788                Temp16 = ACPI_ASF_TYPE_RESERVED;
789            }
790
791            AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmAsfSubnames[Temp16]);
792            break;
793
794        case ACPI_DMT_DMAR:
795
796            /* DMAR subtable types */
797
798            Temp16 = ACPI_GET16 (Target);
799            if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
800            {
801                Temp16 = ACPI_DMAR_TYPE_RESERVED;
802            }
803
804            AcpiOsPrintf ("%4.4X <%s>\n", ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
805            break;
806
807        case ACPI_DMT_HEST:
808
809            /* HEST subtable types */
810
811            Temp16 = ACPI_GET16 (Target);
812            if (Temp16 > ACPI_HEST_TYPE_RESERVED)
813            {
814                Temp16 = ACPI_HEST_TYPE_RESERVED;
815            }
816
817            AcpiOsPrintf ("%4.4X (%s)\n", ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
818            break;
819
820        case ACPI_DMT_HESTNTFY:
821
822            AcpiOsPrintf ("<Hardware Error Notification Structure>\n");
823            AcpiDmDumpTable (TableLength, CurrentOffset, Target,
824                sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
825            AcpiOsPrintf ("\n");
826            LastOutputBlankLine = TRUE;
827            break;
828
829        case ACPI_DMT_HESTNTYP:
830
831            /* HEST Notify types */
832
833            Temp8 = *Target;
834            if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
835            {
836                Temp8 = ACPI_HEST_NOTIFY_RESERVED;
837            }
838
839            AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmHestNotifySubnames[Temp8]);
840            break;
841
842
843        case ACPI_DMT_MADT:
844
845            /* MADT subtable types */
846
847            Temp8 = *Target;
848            if (Temp8 > ACPI_MADT_TYPE_RESERVED)
849            {
850                Temp8 = ACPI_MADT_TYPE_RESERVED;
851            }
852
853            AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmMadtSubnames[Temp8]);
854            break;
855
856        case ACPI_DMT_SRAT:
857
858            /* SRAT subtable types */
859
860            Temp8 = *Target;
861            if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
862            {
863                Temp8 = ACPI_SRAT_TYPE_RESERVED;
864            }
865
866            AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmSratSubnames[Temp8]);
867            break;
868
869        case ACPI_DMT_FADTPM:
870
871            /* FADT Preferred PM Profile names */
872
873            Temp8 = *Target;
874            if (Temp8 > ACPI_FADT_PM_RESERVED)
875            {
876                Temp8 = ACPI_FADT_PM_RESERVED;
877            }
878
879            AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmFadtProfiles[Temp8]);
880            break;
881
882        case ACPI_DMT_IVRS:
883
884            /* IVRS subtable types */
885
886            Temp8 = *Target;
887            switch (Temp8)
888            {
889            case ACPI_IVRS_TYPE_HARDWARE:
890                Name = AcpiDmIvrsSubnames[0];
891                break;
892
893            case ACPI_IVRS_TYPE_MEMORY1:
894            case ACPI_IVRS_TYPE_MEMORY2:
895            case ACPI_IVRS_TYPE_MEMORY3:
896                Name = AcpiDmIvrsSubnames[1];
897                break;
898
899            default:
900                Name = AcpiDmIvrsSubnames[2];
901                break;
902            }
903
904            AcpiOsPrintf ("%2.2X <%s>\n", *Target, Name);
905            break;
906
907        case ACPI_DMT_EXIT:
908            return (AE_OK);
909
910        default:
911            ACPI_ERROR ((AE_INFO,
912                "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
913            return (AE_SUPPORT);
914        }
915    }
916
917    if (TableOffset && !SubtableLength)
918    {
919        /* If this table is not the main table, subtable must have valid length */
920
921        AcpiOsPrintf ("Invalid zero length subtable\n");
922        return (AE_BAD_DATA);
923    }
924
925    return (AE_OK);
926}
927
928
929/*******************************************************************************
930 *
931 * FUNCTION:    AcpiDmCheckAscii
932 *
933 * PARAMETERS:  Name                - Ascii string
934 *              Count               - Number of characters to check
935 *
936 * RETURN:      None
937 *
938 * DESCRIPTION: Ensure that the requested number of characters are printable
939 *              Ascii characters. Sets non-printable and null chars to <space>.
940 *
941 ******************************************************************************/
942
943static void
944AcpiDmCheckAscii (
945    UINT8                   *Name,
946    char                    *RepairedName,
947    UINT32                  Count)
948{
949    UINT32                  i;
950
951
952    for (i = 0; i < Count; i++)
953    {
954        RepairedName[i] = (char) Name[i];
955
956        if (!Name[i])
957        {
958            return;
959        }
960        if (!isprint (Name[i]))
961        {
962            RepairedName[i] = ' ';
963        }
964    }
965}
966