dmtable.c revision 239340
1272343Sngie/******************************************************************************
2272343Sngie *
3272343Sngie * Module Name: dmtable - Support for ACPI tables that contain no AML code
4272343Sngie *
5272343Sngie *****************************************************************************/
6272343Sngie
7272343Sngie/*
8272343Sngie * Copyright (C) 2000 - 2012, Intel Corp.
9272343Sngie * All rights reserved.
10272343Sngie *
11272343Sngie * Redistribution and use in source and binary forms, with or without
12272343Sngie * modification, are permitted provided that the following conditions
13272343Sngie * are met:
14272343Sngie * 1. Redistributions of source code must retain the above copyright
15272343Sngie *    notice, this list of conditions, and the following disclaimer,
16272343Sngie *    without modification.
17272343Sngie * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18272343Sngie *    substantially similar to the "NO WARRANTY" disclaimer below
19272343Sngie *    ("Disclaimer") and any redistribution must be conditioned upon
20272343Sngie *    including a substantially similar Disclaimer requirement for further
21272343Sngie *    binary redistribution.
22272343Sngie * 3. Neither the names of the above-listed copyright holders nor the names
23272343Sngie *    of any contributors may be used to endorse or promote products derived
24272343Sngie *    from this software without specific prior written permission.
25272343Sngie *
26272343Sngie * Alternatively, this software may be distributed under the terms of the
27272343Sngie * GNU General Public License ("GPL") version 2 as published by the Free
28272343Sngie * Software Foundation.
29272343Sngie *
30272343Sngie * NO WARRANTY
31272343Sngie * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32272343Sngie * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33272343Sngie * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34272343Sngie * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35272343Sngie * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36272343Sngie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37272343Sngie * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38272343Sngie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39272343Sngie * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40272343Sngie * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41272343Sngie * POSSIBILITY OF SUCH DAMAGES.
42272343Sngie */
43272343Sngie
44272343Sngie#include <contrib/dev/acpica/include/acpi.h>
45272343Sngie#include <contrib/dev/acpica/include/accommon.h>
46272343Sngie#include <contrib/dev/acpica/include/acdisasm.h>
47272343Sngie#include <contrib/dev/acpica/include/actables.h>
48272343Sngie#include <contrib/dev/acpica/compiler/aslcompiler.h>
49272343Sngie#include <contrib/dev/acpica/compiler/dtcompiler.h>
50272343Sngie
51272343Sngie/* This module used for application-level code only */
52272343Sngie
53272343Sngie#define _COMPONENT          ACPI_CA_DISASSEMBLER
54272343Sngie        ACPI_MODULE_NAME    ("dmtable")
55272343Sngie
56272343Sngie/* Local Prototypes */
57272343Sngie
58272343Sngiestatic void
59272343SngieAcpiDmCheckAscii (
60272343Sngie    UINT8                   *Target,
61272343Sngie    char                    *RepairedName,
62272343Sngie    UINT32                  Count);
63272343Sngie
64272343Sngie
65272343Sngie/* Common format strings for commented values */
66272343Sngie
67272343Sngie#define UINT8_FORMAT        "%2.2X [%s]\n"
68272343Sngie#define UINT16_FORMAT       "%4.4X [%s]\n"
69272343Sngie#define UINT32_FORMAT       "%8.8X [%s]\n"
70272343Sngie#define STRING_FORMAT       "[%s]\n"
71272343Sngie
72272343Sngie/* These tables map a subtable type to a description string */
73272343Sngie
74272343Sngiestatic const char           *AcpiDmAsfSubnames[] =
75272343Sngie{
76272343Sngie    "ASF Information",
77272343Sngie    "ASF Alerts",
78272343Sngie    "ASF Remote Control",
79272343Sngie    "ASF RMCP Boot Options",
80272343Sngie    "ASF Address",
81272343Sngie    "Unknown SubTable Type"         /* Reserved */
82272343Sngie};
83272343Sngie
84272343Sngiestatic const char           *AcpiDmDmarSubnames[] =
85272343Sngie{
86272343Sngie    "Hardware Unit Definition",
87272343Sngie    "Reserved Memory Region",
88272343Sngie    "Root Port ATS Capability",
89272343Sngie    "Remapping Hardware Static Affinity",
90272343Sngie    "Unknown SubTable Type"         /* Reserved */
91272343Sngie};
92272343Sngie
93272343Sngiestatic const char           *AcpiDmEinjActions[] =
94272343Sngie{
95272343Sngie    "Begin Operation",
96272343Sngie    "Get Trigger Table",
97272343Sngie    "Set Error Type",
98272343Sngie    "Get Error Type",
99272343Sngie    "End Operation",
100272343Sngie    "Execute Operation",
101272343Sngie    "Check Busy Status",
102272343Sngie    "Get Command Status",
103272343Sngie    "Unknown Action"
104272343Sngie};
105272343Sngie
106272343Sngiestatic const char           *AcpiDmEinjInstructions[] =
107272343Sngie{
108272343Sngie    "Read Register",
109272343Sngie    "Read Register Value",
110272343Sngie    "Write Register",
111272343Sngie    "Write Register Value",
112272343Sngie    "Noop",
113272343Sngie    "Unknown Instruction"
114272343Sngie};
115272343Sngie
116272343Sngiestatic const char           *AcpiDmErstActions[] =
117272343Sngie{
118272343Sngie    "Begin Write Operation",
119272343Sngie    "Begin Read Operation",
120272343Sngie    "Begin Clear Operation",
121272343Sngie    "End Operation",
122272343Sngie    "Set Record Offset",
123272343Sngie    "Execute Operation",
124272343Sngie    "Check Busy Status",
125272343Sngie    "Get Command Status",
126272343Sngie    "Get Record Identifier",
127272343Sngie    "Set Record Identifier",
128272343Sngie    "Get Record Count",
129272343Sngie    "Begin Dummy Write",
130272343Sngie    "Unused/Unknown Action",
131272343Sngie    "Get Error Address Range",
132272343Sngie    "Get Error Address Length",
133272343Sngie    "Get Error Attributes",
134272343Sngie    "Unknown Action"
135272343Sngie};
136272343Sngie
137272343Sngiestatic const char           *AcpiDmErstInstructions[] =
138272343Sngie{
139272343Sngie    "Read Register",
140272343Sngie    "Read Register Value",
141272343Sngie    "Write Register",
142272343Sngie    "Write Register Value",
143272343Sngie    "Noop",
144272343Sngie    "Load Var1",
145272343Sngie    "Load Var2",
146272343Sngie    "Store Var1",
147272343Sngie    "Add",
148272343Sngie    "Subtract",
149272343Sngie    "Add Value",
150272343Sngie    "Subtract Value",
151272343Sngie    "Stall",
152272343Sngie    "Stall While True",
153272343Sngie    "Skip Next If True",
154272343Sngie    "GoTo",
155272343Sngie    "Set Source Address",
156272343Sngie    "Set Destination Address",
157272343Sngie    "Move Data",
158272343Sngie    "Unknown Instruction"
159272343Sngie};
160272343Sngie
161272343Sngiestatic const char           *AcpiDmHestSubnames[] =
162272343Sngie{
163272343Sngie    "IA-32 Machine Check Exception",
164272343Sngie    "IA-32 Corrected Machine Check",
165272343Sngie    "IA-32 Non-Maskable Interrupt",
166272343Sngie    "Unknown SubTable Type",        /* 3 - Reserved */
167272343Sngie    "Unknown SubTable Type",        /* 4 - Reserved */
168272343Sngie    "Unknown SubTable Type",        /* 5 - Reserved */
169272343Sngie    "PCI Express Root Port AER",
170272343Sngie    "PCI Express AER (AER Endpoint)",
171272343Sngie    "PCI Express/PCI-X Bridge AER",
172272343Sngie    "Generic Hardware Error Source",
173272343Sngie    "Unknown SubTable Type"         /* Reserved */
174272343Sngie};
175272343Sngie
176272343Sngiestatic const char           *AcpiDmHestNotifySubnames[] =
177272343Sngie{
178272343Sngie    "Polled",
179272343Sngie    "External Interrupt",
180272343Sngie    "Local Interrupt",
181272343Sngie    "SCI",
182272343Sngie    "NMI",
183272343Sngie    "Unknown Notify Type"           /* Reserved */
184272343Sngie};
185272343Sngie
186272343Sngiestatic const char           *AcpiDmMadtSubnames[] =
187272343Sngie{
188272343Sngie    "Processor Local APIC",         /* ACPI_MADT_TYPE_LOCAL_APIC */
189272343Sngie    "I/O APIC",                     /* ACPI_MADT_TYPE_IO_APIC */
190272343Sngie    "Interrupt Source Override",    /* ACPI_MADT_TYPE_INTERRUPT_OVERRIDE */
191272343Sngie    "NMI Source",                   /* ACPI_MADT_TYPE_NMI_SOURCE */
192272343Sngie    "Local APIC NMI",               /* ACPI_MADT_TYPE_LOCAL_APIC_NMI */
193272343Sngie    "Local APIC Address Override",  /* ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE */
194272343Sngie    "I/O SAPIC",                    /* ACPI_MADT_TYPE_IO_SAPIC */
195272343Sngie    "Local SAPIC",                  /* ACPI_MADT_TYPE_LOCAL_SAPIC */
196272343Sngie    "Platform Interrupt Sources",   /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */
197272343Sngie    "Processor Local x2APIC",       /* ACPI_MADT_TYPE_LOCAL_X2APIC */
198272343Sngie    "Local x2APIC NMI",             /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */
199272343Sngie    "Generic Interrupt Controller", /* ACPI_MADT_GENERIC_INTERRUPT */
200272343Sngie    "Generic Interrupt Distributor",/* ACPI_MADT_GENERIC_DISTRIBUTOR */
201272343Sngie    "Unknown SubTable Type"         /* Reserved */
202272343Sngie};
203272343Sngie
204272343Sngiestatic const char           *AcpiDmPmttSubnames[] =
205272343Sngie{
206272343Sngie    "Socket",                       /* ACPI_PMTT_TYPE_SOCKET */
207272343Sngie    "Memory Controller",            /* ACPI_PMTT_TYPE_CONTROLLER */
208272343Sngie    "Physical Component (DIMM)",    /* ACPI_PMTT_TYPE_DIMM  */
209272343Sngie    "Unknown SubTable Type"         /* Reserved */
210272343Sngie};
211272343Sngie
212272343Sngiestatic const char           *AcpiDmSlicSubnames[] =
213272343Sngie{
214272343Sngie    "Public Key Structure",
215272343Sngie    "Windows Marker Structure",
216272343Sngie    "Unknown SubTable Type"         /* Reserved */
217272343Sngie};
218272343Sngie
219272343Sngiestatic const char           *AcpiDmSratSubnames[] =
220272343Sngie{
221272343Sngie    "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        return;
419    }
420
421    /*
422     * Handle tables that don't use the common ACPI table header structure.
423     * Currently, these are the FACS, RSDP, and S3PT.
424     */
425    if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
426    {
427        Length = Table->Length;
428        AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
429    }
430    else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
431    {
432        Length = AcpiDmDumpRsdp (Table);
433    }
434    else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_S3PT))
435    {
436        Length = AcpiDmDumpS3pt (Table);
437    }
438    else
439    {
440        /*
441         * All other tables must use the common ACPI table header, dump it now
442         */
443        Length = Table->Length;
444        Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
445        if (ACPI_FAILURE (Status))
446        {
447            return;
448        }
449        AcpiOsPrintf ("\n");
450
451        /* Match signature and dispatch appropriately */
452
453        TableData = AcpiDmGetTableData (Table->Signature);
454        if (!TableData)
455        {
456            if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
457            {
458                AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
459                    Table->Signature);
460            }
461            else
462            {
463                AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
464                    Table->Signature);
465            }
466        }
467        else if (TableData->TableHandler)
468        {
469            /* Complex table, has a handler */
470
471            TableData->TableHandler (Table);
472        }
473        else if (TableData->TableInfo)
474        {
475            /* Simple table, just walk the info table */
476
477            AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
478        }
479    }
480
481    if (!Gbl_DoTemplates || Gbl_VerboseTemplates)
482    {
483        /* Dump the raw table data */
484
485        AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
486            ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
487        AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY);
488    }
489}
490
491
492/*******************************************************************************
493 *
494 * FUNCTION:    AcpiDmLineHeader
495 *
496 * PARAMETERS:  Offset              - Current byte offset, from table start
497 *              ByteLength          - Length of the field in bytes, 0 for flags
498 *              Name                - Name of this field
499 *              Value               - Optional value, displayed on left of ':'
500 *
501 * RETURN:      None
502 *
503 * DESCRIPTION: Utility routines for formatting output lines. Displays the
504 *              current table offset in hex and decimal, the field length,
505 *              and the field name.
506 *
507 ******************************************************************************/
508
509void
510AcpiDmLineHeader (
511    UINT32                  Offset,
512    UINT32                  ByteLength,
513    char                    *Name)
514{
515
516    /* Allow a null name for fields that span multiple lines (large buffers) */
517
518    if (!Name)
519    {
520        Name = "";
521    }
522
523    if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
524    {
525        if (ByteLength)
526        {
527            AcpiOsPrintf ("[%.4d] %34s : ", ByteLength, Name);
528        }
529        else
530        {
531            if (*Name)
532            {
533                AcpiOsPrintf ("%41s : ", Name);
534            }
535            else
536            {
537                AcpiOsPrintf ("%41s   ", Name);
538            }
539        }
540    }
541    else /* Normal disassembler or verbose template */
542    {
543        if (ByteLength)
544        {
545            AcpiOsPrintf ("[%3.3Xh %4.4d% 4d] %28s : ",
546                Offset, Offset, ByteLength, Name);
547        }
548        else
549        {
550            if (*Name)
551            {
552                AcpiOsPrintf ("%44s : ", Name);
553            }
554            else
555            {
556                AcpiOsPrintf ("%44s   ", Name);
557            }
558        }
559    }
560}
561
562void
563AcpiDmLineHeader2 (
564    UINT32                  Offset,
565    UINT32                  ByteLength,
566    char                    *Name,
567    UINT32                  Value)
568{
569
570    if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
571    {
572        if (ByteLength)
573        {
574            AcpiOsPrintf ("[%.4d] %30s %3d : ",
575                ByteLength, Name, Value);
576        }
577        else
578        {
579            AcpiOsPrintf ("%36s % 3d : ",
580                Name, Value);
581        }
582    }
583    else /* Normal disassembler or verbose template */
584    {
585        if (ByteLength)
586        {
587            AcpiOsPrintf ("[%3.3Xh %4.4d %3d] %24s %3d : ",
588                Offset, Offset, ByteLength, Name, Value);
589        }
590        else
591        {
592            AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s %3d : ",
593                Offset, Offset, Name, Value);
594        }
595    }
596}
597
598
599/*******************************************************************************
600 *
601 * FUNCTION:    AcpiDmDumpTable
602 *
603 * PARAMETERS:  TableLength         - Length of the entire ACPI table
604 *              TableOffset         - Starting offset within the table for this
605 *                                    sub-descriptor (0 if main table)
606 *              Table               - The ACPI table
607 *              SubtableLength      - Length of this sub-descriptor
608 *              Info                - Info table for this ACPI table
609 *
610 * RETURN:      None
611 *
612 * DESCRIPTION: Display ACPI table contents by walking the Info table.
613 *
614 * Note: This function must remain in sync with DtGetFieldLength.
615 *
616 ******************************************************************************/
617
618ACPI_STATUS
619AcpiDmDumpTable (
620    UINT32                  TableLength,
621    UINT32                  TableOffset,
622    void                    *Table,
623    UINT32                  SubtableLength,
624    ACPI_DMTABLE_INFO       *Info)
625{
626    UINT8                   *Target;
627    UINT32                  CurrentOffset;
628    UINT32                  ByteLength;
629    UINT8                   Temp8;
630    UINT16                  Temp16;
631    ACPI_DMTABLE_DATA       *TableData;
632    const char              *Name;
633    BOOLEAN                 LastOutputBlankLine = FALSE;
634    char                    RepairedName[8];
635
636
637    if (!Info)
638    {
639        AcpiOsPrintf ("Display not implemented\n");
640        return (AE_NOT_IMPLEMENTED);
641    }
642
643    /* Walk entire Info table; Null name terminates */
644
645    for (; Info->Name; Info++)
646    {
647        /*
648         * Target points to the field within the ACPI Table. CurrentOffset is
649         * the offset of the field from the start of the main table.
650         */
651        Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
652        CurrentOffset = TableOffset + Info->Offset;
653
654        /* Check for beyond EOT or beyond subtable end */
655
656        if ((CurrentOffset >= TableLength) ||
657            (SubtableLength && (Info->Offset >= SubtableLength)))
658        {
659            AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
660            return (AE_BAD_DATA);
661        }
662
663        /* Generate the byte length for this field */
664
665        switch (Info->Opcode)
666        {
667        case ACPI_DMT_UINT8:
668        case ACPI_DMT_CHKSUM:
669        case ACPI_DMT_SPACEID:
670        case ACPI_DMT_ACCWIDTH:
671        case ACPI_DMT_IVRS:
672        case ACPI_DMT_MADT:
673        case ACPI_DMT_PMTT:
674        case ACPI_DMT_SRAT:
675        case ACPI_DMT_ASF:
676        case ACPI_DMT_HESTNTYP:
677        case ACPI_DMT_FADTPM:
678        case ACPI_DMT_EINJACT:
679        case ACPI_DMT_EINJINST:
680        case ACPI_DMT_ERSTACT:
681        case ACPI_DMT_ERSTINST:
682            ByteLength = 1;
683            break;
684        case ACPI_DMT_UINT16:
685        case ACPI_DMT_DMAR:
686        case ACPI_DMT_HEST:
687            ByteLength = 2;
688            break;
689        case ACPI_DMT_UINT24:
690            ByteLength = 3;
691            break;
692        case ACPI_DMT_UINT32:
693        case ACPI_DMT_NAME4:
694        case ACPI_DMT_SIG:
695        case ACPI_DMT_SLIC:
696            ByteLength = 4;
697            break;
698        case ACPI_DMT_UINT40:
699            ByteLength = 5;
700            break;
701        case ACPI_DMT_UINT48:
702        case ACPI_DMT_NAME6:
703            ByteLength = 6;
704            break;
705        case ACPI_DMT_UINT56:
706        case ACPI_DMT_BUF7:
707            ByteLength = 7;
708            break;
709        case ACPI_DMT_UINT64:
710        case ACPI_DMT_NAME8:
711            ByteLength = 8;
712            break;
713        case ACPI_DMT_BUF16:
714        case ACPI_DMT_UUID:
715            ByteLength = 16;
716            break;
717        case ACPI_DMT_BUF128:
718            ByteLength = 128;
719            break;
720        case ACPI_DMT_STRING:
721            ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
722            break;
723        case ACPI_DMT_GAS:
724            if (!LastOutputBlankLine)
725            {
726                AcpiOsPrintf ("\n");
727                LastOutputBlankLine = TRUE;
728            }
729            ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
730            break;
731        case ACPI_DMT_HESTNTFY:
732            if (!LastOutputBlankLine)
733            {
734                AcpiOsPrintf ("\n");
735                LastOutputBlankLine = TRUE;
736            }
737            ByteLength = sizeof (ACPI_HEST_NOTIFY);
738            break;
739        default:
740            ByteLength = 0;
741            break;
742        }
743
744        if (CurrentOffset + ByteLength > TableLength)
745        {
746            AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
747            return (AE_BAD_DATA);
748        }
749
750        if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
751        {
752            AcpiOsPrintf ("%s", Info->Name);
753            continue;
754        }
755
756        /* Start a new line and decode the opcode */
757
758        AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
759
760        switch (Info->Opcode)
761        {
762        /* Single-bit Flag fields. Note: Opcode is the bit position */
763
764        case ACPI_DMT_FLAG0:
765        case ACPI_DMT_FLAG1:
766        case ACPI_DMT_FLAG2:
767        case ACPI_DMT_FLAG3:
768        case ACPI_DMT_FLAG4:
769        case ACPI_DMT_FLAG5:
770        case ACPI_DMT_FLAG6:
771        case ACPI_DMT_FLAG7:
772
773            AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
774            break;
775
776        /* 2-bit Flag fields */
777
778        case ACPI_DMT_FLAGS0:
779
780            AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
781            break;
782
783        case ACPI_DMT_FLAGS1:
784
785            AcpiOsPrintf ("%1.1X\n", (*Target >> 1) & 0x03);
786            break;
787
788        case ACPI_DMT_FLAGS2:
789
790            AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
791            break;
792
793        case ACPI_DMT_FLAGS4:
794
795            AcpiOsPrintf ("%1.1X\n", (*Target >> 4) & 0x03);
796            break;
797
798        /* Integer Data Types */
799
800        case ACPI_DMT_UINT8:
801        case ACPI_DMT_UINT16:
802        case ACPI_DMT_UINT24:
803        case ACPI_DMT_UINT32:
804        case ACPI_DMT_UINT40:
805        case ACPI_DMT_UINT48:
806        case ACPI_DMT_UINT56:
807        case ACPI_DMT_UINT64:
808            /*
809             * Dump bytes - high byte first, low byte last.
810             * Note: All ACPI tables are little-endian.
811             */
812            for (Temp8 = (UINT8) ByteLength; Temp8 > 0; Temp8--)
813            {
814                AcpiOsPrintf ("%2.2X", Target[Temp8 - 1]);
815            }
816            AcpiOsPrintf ("\n");
817            break;
818
819        case ACPI_DMT_BUF7:
820        case ACPI_DMT_BUF16:
821        case ACPI_DMT_BUF128:
822
823            /*
824             * Buffer: Size depends on the opcode and was set above.
825             * Each hex byte is separated with a space.
826             * Multiple lines are separated by line continuation char.
827             */
828            for (Temp16 = 0; Temp16 < ByteLength; Temp16++)
829            {
830                AcpiOsPrintf ("%2.2X", Target[Temp16]);
831                if ((UINT32) (Temp16 + 1) < ByteLength)
832                {
833                    if ((Temp16 > 0) && (!((Temp16+1) % 16)))
834                    {
835                        AcpiOsPrintf (" \\\n"); /* Line continuation */
836                        AcpiDmLineHeader (0, 0, NULL);
837                    }
838                    else
839                    {
840                        AcpiOsPrintf (" ");
841                    }
842                }
843            }
844            AcpiOsPrintf ("\n");
845            break;
846
847        case ACPI_DMT_UUID:
848
849            /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */
850
851            (void) AuConvertUuidToString ((char *) Target, MsgBuffer);
852
853            AcpiOsPrintf ("%s\n", MsgBuffer);
854            break;
855
856        case ACPI_DMT_STRING:
857
858            AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
859            break;
860
861        /* Fixed length ASCII name fields */
862
863        case ACPI_DMT_SIG:
864
865            AcpiDmCheckAscii (Target, RepairedName, 4);
866            AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
867            TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
868            if (TableData)
869            {
870                AcpiOsPrintf (STRING_FORMAT, TableData->Name);
871            }
872            else
873            {
874                AcpiOsPrintf ("\n");
875            }
876            break;
877
878        case ACPI_DMT_NAME4:
879
880            AcpiDmCheckAscii (Target, RepairedName, 4);
881            AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
882            break;
883
884        case ACPI_DMT_NAME6:
885
886            AcpiDmCheckAscii (Target, RepairedName, 6);
887            AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
888            break;
889
890        case ACPI_DMT_NAME8:
891
892            AcpiDmCheckAscii (Target, RepairedName, 8);
893            AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
894            break;
895
896        /* Special Data Types */
897
898        case ACPI_DMT_CHKSUM:
899
900            /* Checksum, display and validate */
901
902            AcpiOsPrintf ("%2.2X", *Target);
903            Temp8 = AcpiDmGenerateChecksum (Table,
904                        ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
905                        ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
906            if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
907            {
908                AcpiOsPrintf (
909                    "     /* Incorrect checksum, should be %2.2X */", Temp8);
910            }
911            AcpiOsPrintf ("\n");
912            break;
913
914        case ACPI_DMT_SPACEID:
915
916            /* Address Space ID */
917
918            AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiUtGetRegionName (*Target));
919            break;
920
921        case ACPI_DMT_ACCWIDTH:
922
923            /* Encoded Access Width */
924
925            Temp8 = *Target;
926            if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
927            {
928                Temp8 = ACPI_GAS_WIDTH_RESERVED;
929            }
930
931            AcpiOsPrintf (UINT8_FORMAT, Temp8, AcpiDmGasAccessWidth[Temp8]);
932            break;
933
934        case ACPI_DMT_GAS:
935
936            /* Generic Address Structure */
937
938            AcpiOsPrintf (STRING_FORMAT, "Generic Address Structure");
939            AcpiDmDumpTable (TableLength, CurrentOffset, Target,
940                sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
941            AcpiOsPrintf ("\n");
942            LastOutputBlankLine = TRUE;
943            break;
944
945        case ACPI_DMT_ASF:
946
947            /* ASF subtable types */
948
949            Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
950            if (Temp16 > ACPI_ASF_TYPE_RESERVED)
951            {
952                Temp16 = ACPI_ASF_TYPE_RESERVED;
953            }
954
955            AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmAsfSubnames[Temp16]);
956            break;
957
958        case ACPI_DMT_DMAR:
959
960            /* DMAR subtable types */
961
962            Temp16 = ACPI_GET16 (Target);
963            if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
964            {
965                Temp16 = ACPI_DMAR_TYPE_RESERVED;
966            }
967
968            AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
969            break;
970
971        case ACPI_DMT_EINJACT:
972
973            /* EINJ Action types */
974
975            Temp8 = *Target;
976            if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
977            {
978                Temp8 = ACPI_EINJ_ACTION_RESERVED;
979            }
980
981            AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjActions[Temp8]);
982            break;
983
984        case ACPI_DMT_EINJINST:
985
986            /* EINJ Instruction types */
987
988            Temp8 = *Target;
989            if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
990            {
991                Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
992            }
993
994            AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjInstructions[Temp8]);
995            break;
996
997        case ACPI_DMT_ERSTACT:
998
999            /* ERST Action types */
1000
1001            Temp8 = *Target;
1002            if (Temp8 > ACPI_ERST_ACTION_RESERVED)
1003            {
1004                Temp8 = ACPI_ERST_ACTION_RESERVED;
1005            }
1006
1007            AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstActions[Temp8]);
1008            break;
1009
1010        case ACPI_DMT_ERSTINST:
1011
1012            /* ERST Instruction types */
1013
1014            Temp8 = *Target;
1015            if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
1016            {
1017                Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
1018            }
1019
1020            AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstInstructions[Temp8]);
1021            break;
1022
1023        case ACPI_DMT_HEST:
1024
1025            /* HEST subtable types */
1026
1027            Temp16 = ACPI_GET16 (Target);
1028            if (Temp16 > ACPI_HEST_TYPE_RESERVED)
1029            {
1030                Temp16 = ACPI_HEST_TYPE_RESERVED;
1031            }
1032
1033            AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
1034            break;
1035
1036        case ACPI_DMT_HESTNTFY:
1037
1038            AcpiOsPrintf (STRING_FORMAT, "Hardware Error Notification Structure");
1039            AcpiDmDumpTable (TableLength, CurrentOffset, Target,
1040                sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
1041            AcpiOsPrintf ("\n");
1042            LastOutputBlankLine = TRUE;
1043            break;
1044
1045        case ACPI_DMT_HESTNTYP:
1046
1047            /* HEST Notify types */
1048
1049            Temp8 = *Target;
1050            if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
1051            {
1052                Temp8 = ACPI_HEST_NOTIFY_RESERVED;
1053            }
1054
1055            AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmHestNotifySubnames[Temp8]);
1056            break;
1057
1058        case ACPI_DMT_MADT:
1059
1060            /* MADT subtable types */
1061
1062            Temp8 = *Target;
1063            if (Temp8 > ACPI_MADT_TYPE_RESERVED)
1064            {
1065                Temp8 = ACPI_MADT_TYPE_RESERVED;
1066            }
1067
1068            AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmMadtSubnames[Temp8]);
1069            break;
1070
1071        case ACPI_DMT_PMTT:
1072
1073            /* PMTT subtable types */
1074
1075            Temp8 = *Target;
1076            if (Temp8 > ACPI_PMTT_TYPE_RESERVED)
1077            {
1078                Temp8 = ACPI_PMTT_TYPE_RESERVED;
1079            }
1080
1081            AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmPmttSubnames[Temp8]);
1082            break;
1083
1084        case ACPI_DMT_SLIC:
1085
1086            /* SLIC subtable types */
1087
1088            Temp8 = *Target;
1089            if (Temp8 > ACPI_SLIC_TYPE_RESERVED)
1090            {
1091                Temp8 = ACPI_SLIC_TYPE_RESERVED;
1092            }
1093
1094            AcpiOsPrintf (UINT32_FORMAT, *Target, AcpiDmSlicSubnames[Temp8]);
1095            break;
1096
1097        case ACPI_DMT_SRAT:
1098
1099            /* SRAT subtable types */
1100
1101            Temp8 = *Target;
1102            if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
1103            {
1104                Temp8 = ACPI_SRAT_TYPE_RESERVED;
1105            }
1106
1107            AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmSratSubnames[Temp8]);
1108            break;
1109
1110        case ACPI_DMT_FADTPM:
1111
1112            /* FADT Preferred PM Profile names */
1113
1114            Temp8 = *Target;
1115            if (Temp8 > ACPI_FADT_PM_RESERVED)
1116            {
1117                Temp8 = ACPI_FADT_PM_RESERVED;
1118            }
1119
1120            AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmFadtProfiles[Temp8]);
1121            break;
1122
1123        case ACPI_DMT_IVRS:
1124
1125            /* IVRS subtable types */
1126
1127            Temp8 = *Target;
1128            switch (Temp8)
1129            {
1130            case ACPI_IVRS_TYPE_HARDWARE:
1131                Name = AcpiDmIvrsSubnames[0];
1132                break;
1133
1134            case ACPI_IVRS_TYPE_MEMORY1:
1135            case ACPI_IVRS_TYPE_MEMORY2:
1136            case ACPI_IVRS_TYPE_MEMORY3:
1137                Name = AcpiDmIvrsSubnames[1];
1138                break;
1139
1140            default:
1141                Name = AcpiDmIvrsSubnames[2];
1142                break;
1143            }
1144
1145            AcpiOsPrintf (UINT8_FORMAT, *Target, Name);
1146            break;
1147
1148        case ACPI_DMT_EXIT:
1149            return (AE_OK);
1150
1151        default:
1152            ACPI_ERROR ((AE_INFO,
1153                "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1154            return (AE_SUPPORT);
1155        }
1156    }
1157
1158    if (TableOffset && !SubtableLength)
1159    {
1160        /* If this table is not the main table, subtable must have valid length */
1161
1162        AcpiOsPrintf ("Invalid zero length subtable\n");
1163        return (AE_BAD_DATA);
1164    }
1165
1166    return (AE_OK);
1167}
1168
1169
1170/*******************************************************************************
1171 *
1172 * FUNCTION:    AcpiDmCheckAscii
1173 *
1174 * PARAMETERS:  Name                - Ascii string
1175 *              Count               - Number of characters to check
1176 *
1177 * RETURN:      None
1178 *
1179 * DESCRIPTION: Ensure that the requested number of characters are printable
1180 *              Ascii characters. Sets non-printable and null chars to <space>.
1181 *
1182 ******************************************************************************/
1183
1184static void
1185AcpiDmCheckAscii (
1186    UINT8                   *Name,
1187    char                    *RepairedName,
1188    UINT32                  Count)
1189{
1190    UINT32                  i;
1191
1192
1193    for (i = 0; i < Count; i++)
1194    {
1195        RepairedName[i] = (char) Name[i];
1196
1197        if (!Name[i])
1198        {
1199            return;
1200        }
1201        if (!isprint (Name[i]))
1202        {
1203            RepairedName[i] = ' ';
1204        }
1205    }
1206}
1207