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