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