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