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