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