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