]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/common/dmtable.c
Merge ACPICA 20130117.
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / common / dmtable.c
1 /******************************************************************************
2  *
3  * Module Name: dmtable - Support for ACPI tables that contain no AML code
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2013, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #include <contrib/dev/acpica/include/acpi.h>
45 #include <contrib/dev/acpica/include/accommon.h>
46 #include <contrib/dev/acpica/include/acdisasm.h>
47 #include <contrib/dev/acpica/include/actables.h>
48 #include <contrib/dev/acpica/compiler/aslcompiler.h>
49 #include <contrib/dev/acpica/compiler/dtcompiler.h>
50
51 /* This module used for application-level code only */
52
53 #define _COMPONENT          ACPI_CA_DISASSEMBLER
54         ACPI_MODULE_NAME    ("dmtable")
55
56 /* Local Prototypes */
57
58 static void
59 AcpiDmCheckAscii (
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
74 static 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
84 static 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
93 static 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
106 static 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
116 static 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
137 static 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
161 static 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
176 static const char           *AcpiDmHestNotifySubnames[] =
177 {
178     "Polled",
179     "External Interrupt",
180     "Local Interrupt",
181     "SCI",
182     "NMI",
183     "Unknown Notify Type"           /* Reserved */
184 };
185
186 static 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
204 static 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
212 static const char           *AcpiDmSlicSubnames[] =
213 {
214     "Public Key Structure",
215     "Windows Marker Structure",
216     "Unknown SubTable Type"         /* Reserved */
217 };
218
219 static 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
227 static 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
237 static 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
253 static 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
277 ACPI_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, DtCompileCsrt,  TemplateCsrt,   "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_TPM2, AcpiDmTableInfoTpm2,    NULL,           NULL,           TemplateTpm2,   "Trusted Platform Module hardware interface table"},
314     {ACPI_SIG_UEFI, AcpiDmTableInfoUefi,    NULL,           DtCompileUefi,  TemplateUefi,   "UEFI Boot Optimization Table"},
315     {ACPI_SIG_WAET, AcpiDmTableInfoWaet,    NULL,           NULL,           TemplateWaet,   "Windows ACPI Emulated Devices Table"},
316     {ACPI_SIG_WDAT, NULL,                   AcpiDmDumpWdat, DtCompileWdat,  TemplateWdat,   "Watchdog Action Table"},
317     {ACPI_SIG_WDDT, AcpiDmTableInfoWddt,    NULL,           NULL,           TemplateWddt,   "Watchdog Description Table"},
318     {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt,    NULL,           NULL,           TemplateWdrt,   "Watchdog Resource Table"},
319     {ACPI_SIG_XSDT, NULL,                   AcpiDmDumpXsdt, DtCompileXsdt,  TemplateXsdt,   "Extended System Description Table"},
320     {NULL,          NULL,                   NULL,           NULL,           NULL,           NULL}
321 };
322
323
324 /*******************************************************************************
325  *
326  * FUNCTION:    AcpiDmGenerateChecksum
327  *
328  * PARAMETERS:  Table               - Pointer to table to be checksummed
329  *              Length              - Length of the table
330  *              OriginalChecksum    - Value of the checksum field
331  *
332  * RETURN:      8 bit checksum of buffer
333  *
334  * DESCRIPTION: Computes an 8 bit checksum of the table.
335  *
336  ******************************************************************************/
337
338 UINT8
339 AcpiDmGenerateChecksum (
340     void                    *Table,
341     UINT32                  Length,
342     UINT8                   OriginalChecksum)
343 {
344     UINT8                   Checksum;
345
346
347     /* Sum the entire table as-is */
348
349     Checksum = AcpiTbChecksum ((UINT8 *) Table, Length);
350
351     /* Subtract off the existing checksum value in the table */
352
353     Checksum = (UINT8) (Checksum - OriginalChecksum);
354
355     /* Compute the final checksum */
356
357     Checksum = (UINT8) (0 - Checksum);
358     return (Checksum);
359 }
360
361
362 /*******************************************************************************
363  *
364  * FUNCTION:    AcpiDmGetTableData
365  *
366  * PARAMETERS:  Signature           - ACPI signature (4 chars) to match
367  *
368  * RETURN:      Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
369  *
370  * DESCRIPTION: Find a match in the global table of supported ACPI tables
371  *
372  ******************************************************************************/
373
374 ACPI_DMTABLE_DATA *
375 AcpiDmGetTableData (
376     char                    *Signature)
377 {
378     ACPI_DMTABLE_DATA       *TableData;
379
380
381     for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
382     {
383         if (ACPI_COMPARE_NAME (Signature, TableData->Signature))
384         {
385             return (TableData);
386         }
387     }
388
389     return (NULL);
390 }
391
392
393 /*******************************************************************************
394  *
395  * FUNCTION:    AcpiDmDumpDataTable
396  *
397  * PARAMETERS:  Table               - An ACPI table
398  *
399  * RETURN:      None.
400  *
401  * DESCRIPTION: Format the contents of an ACPI data table (any table other
402  *              than an SSDT or DSDT that does not contain executable AML code)
403  *
404  ******************************************************************************/
405
406 void
407 AcpiDmDumpDataTable (
408     ACPI_TABLE_HEADER       *Table)
409 {
410     ACPI_STATUS             Status;
411     ACPI_DMTABLE_DATA       *TableData;
412     UINT32                  Length;
413
414
415     /* Ignore tables that contain AML */
416
417     if (AcpiUtIsAmlTable (Table))
418     {
419         if (Gbl_VerboseTemplates)
420         {
421             /* Dump the raw table data */
422
423             Length = Table->Length;
424
425             AcpiOsPrintf ("\n/*\n%s: Length %d (0x%X)\n\n",
426                 ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
427             AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, Table),
428                 Length, DB_BYTE_DISPLAY, 0);
429             AcpiOsPrintf (" */\n");
430         }
431         return;
432     }
433
434     /*
435      * Handle tables that don't use the common ACPI table header structure.
436      * Currently, these are the FACS, RSDP, and S3PT.
437      */
438     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
439     {
440         Length = Table->Length;
441         AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
442     }
443     else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
444     {
445         Length = AcpiDmDumpRsdp (Table);
446     }
447     else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_S3PT))
448     {
449         Length = AcpiDmDumpS3pt (Table);
450     }
451     else
452     {
453         /*
454          * All other tables must use the common ACPI table header, dump it now
455          */
456         Length = Table->Length;
457         Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
458         if (ACPI_FAILURE (Status))
459         {
460             return;
461         }
462         AcpiOsPrintf ("\n");
463
464         /* Match signature and dispatch appropriately */
465
466         TableData = AcpiDmGetTableData (Table->Signature);
467         if (!TableData)
468         {
469             if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
470             {
471                 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
472                     Table->Signature);
473             }
474             else
475             {
476                 AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
477                     Table->Signature);
478             }
479         }
480         else if (TableData->TableHandler)
481         {
482             /* Complex table, has a handler */
483
484             TableData->TableHandler (Table);
485         }
486         else if (TableData->TableInfo)
487         {
488             /* Simple table, just walk the info table */
489
490             AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
491         }
492     }
493
494     if (!Gbl_DoTemplates || Gbl_VerboseTemplates)
495     {
496         /* Dump the raw table data */
497
498         AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
499             ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
500         AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, Table),
501             Length, DB_BYTE_DISPLAY, 0);
502     }
503 }
504
505
506 /*******************************************************************************
507  *
508  * FUNCTION:    AcpiDmLineHeader
509  *
510  * PARAMETERS:  Offset              - Current byte offset, from table start
511  *              ByteLength          - Length of the field in bytes, 0 for flags
512  *              Name                - Name of this field
513  *              Value               - Optional value, displayed on left of ':'
514  *
515  * RETURN:      None
516  *
517  * DESCRIPTION: Utility routines for formatting output lines. Displays the
518  *              current table offset in hex and decimal, the field length,
519  *              and the field name.
520  *
521  ******************************************************************************/
522
523 void
524 AcpiDmLineHeader (
525     UINT32                  Offset,
526     UINT32                  ByteLength,
527     char                    *Name)
528 {
529
530     /* Allow a null name for fields that span multiple lines (large buffers) */
531
532     if (!Name)
533     {
534         Name = "";
535     }
536
537     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
538     {
539         if (ByteLength)
540         {
541             AcpiOsPrintf ("[%.4d] %34s : ", ByteLength, Name);
542         }
543         else
544         {
545             if (*Name)
546             {
547                 AcpiOsPrintf ("%41s : ", Name);
548             }
549             else
550             {
551                 AcpiOsPrintf ("%41s   ", Name);
552             }
553         }
554     }
555     else /* Normal disassembler or verbose template */
556     {
557         if (ByteLength)
558         {
559             AcpiOsPrintf ("[%3.3Xh %4.4d% 4d] %28s : ",
560                 Offset, Offset, ByteLength, Name);
561         }
562         else
563         {
564             if (*Name)
565             {
566                 AcpiOsPrintf ("%44s : ", Name);
567             }
568             else
569             {
570                 AcpiOsPrintf ("%44s   ", Name);
571             }
572         }
573     }
574 }
575
576 void
577 AcpiDmLineHeader2 (
578     UINT32                  Offset,
579     UINT32                  ByteLength,
580     char                    *Name,
581     UINT32                  Value)
582 {
583
584     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
585     {
586         if (ByteLength)
587         {
588             AcpiOsPrintf ("[%.4d] %30s %3d : ",
589                 ByteLength, Name, Value);
590         }
591         else
592         {
593             AcpiOsPrintf ("%36s % 3d : ",
594                 Name, Value);
595         }
596     }
597     else /* Normal disassembler or verbose template */
598     {
599         if (ByteLength)
600         {
601             AcpiOsPrintf ("[%3.3Xh %4.4d %3d] %24s %3d : ",
602                 Offset, Offset, ByteLength, Name, Value);
603         }
604         else
605         {
606             AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s %3d : ",
607                 Offset, Offset, Name, Value);
608         }
609     }
610 }
611
612
613 /*******************************************************************************
614  *
615  * FUNCTION:    AcpiDmDumpTable
616  *
617  * PARAMETERS:  TableLength         - Length of the entire ACPI table
618  *              TableOffset         - Starting offset within the table for this
619  *                                    sub-descriptor (0 if main table)
620  *              Table               - The ACPI table
621  *              SubtableLength      - Length of this sub-descriptor
622  *              Info                - Info table for this ACPI table
623  *
624  * RETURN:      None
625  *
626  * DESCRIPTION: Display ACPI table contents by walking the Info table.
627  *
628  * Note: This function must remain in sync with DtGetFieldLength.
629  *
630  ******************************************************************************/
631
632 ACPI_STATUS
633 AcpiDmDumpTable (
634     UINT32                  TableLength,
635     UINT32                  TableOffset,
636     void                    *Table,
637     UINT32                  SubtableLength,
638     ACPI_DMTABLE_INFO       *Info)
639 {
640     UINT8                   *Target;
641     UINT32                  CurrentOffset;
642     UINT32                  ByteLength;
643     UINT8                   Temp8;
644     UINT16                  Temp16;
645     ACPI_DMTABLE_DATA       *TableData;
646     const char              *Name;
647     BOOLEAN                 LastOutputBlankLine = FALSE;
648     char                    RepairedName[8];
649
650
651     if (!Info)
652     {
653         AcpiOsPrintf ("Display not implemented\n");
654         return (AE_NOT_IMPLEMENTED);
655     }
656
657     /* Walk entire Info table; Null name terminates */
658
659     for (; Info->Name; Info++)
660     {
661         /*
662          * Target points to the field within the ACPI Table. CurrentOffset is
663          * the offset of the field from the start of the main table.
664          */
665         Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
666         CurrentOffset = TableOffset + Info->Offset;
667
668         /* Check for beyond EOT or beyond subtable end */
669
670         if ((CurrentOffset >= TableLength) ||
671             (SubtableLength && (Info->Offset >= SubtableLength)))
672         {
673             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
674             return (AE_BAD_DATA);
675         }
676
677         /* Generate the byte length for this field */
678
679         switch (Info->Opcode)
680         {
681         case ACPI_DMT_UINT8:
682         case ACPI_DMT_CHKSUM:
683         case ACPI_DMT_SPACEID:
684         case ACPI_DMT_ACCWIDTH:
685         case ACPI_DMT_IVRS:
686         case ACPI_DMT_MADT:
687         case ACPI_DMT_PMTT:
688         case ACPI_DMT_SRAT:
689         case ACPI_DMT_ASF:
690         case ACPI_DMT_HESTNTYP:
691         case ACPI_DMT_FADTPM:
692         case ACPI_DMT_EINJACT:
693         case ACPI_DMT_EINJINST:
694         case ACPI_DMT_ERSTACT:
695         case ACPI_DMT_ERSTINST:
696             ByteLength = 1;
697             break;
698         case ACPI_DMT_UINT16:
699         case ACPI_DMT_DMAR:
700         case ACPI_DMT_HEST:
701             ByteLength = 2;
702             break;
703         case ACPI_DMT_UINT24:
704             ByteLength = 3;
705             break;
706         case ACPI_DMT_UINT32:
707         case ACPI_DMT_NAME4:
708         case ACPI_DMT_SIG:
709         case ACPI_DMT_SLIC:
710             ByteLength = 4;
711             break;
712         case ACPI_DMT_UINT40:
713             ByteLength = 5;
714             break;
715         case ACPI_DMT_UINT48:
716         case ACPI_DMT_NAME6:
717             ByteLength = 6;
718             break;
719         case ACPI_DMT_UINT56:
720         case ACPI_DMT_BUF7:
721             ByteLength = 7;
722             break;
723         case ACPI_DMT_UINT64:
724         case ACPI_DMT_NAME8:
725             ByteLength = 8;
726             break;
727         case ACPI_DMT_BUF16:
728         case ACPI_DMT_UUID:
729             ByteLength = 16;
730             break;
731         case ACPI_DMT_BUF128:
732             ByteLength = 128;
733             break;
734         case ACPI_DMT_STRING:
735             ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
736             break;
737         case ACPI_DMT_GAS:
738             if (!LastOutputBlankLine)
739             {
740                 AcpiOsPrintf ("\n");
741                 LastOutputBlankLine = TRUE;
742             }
743             ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
744             break;
745         case ACPI_DMT_HESTNTFY:
746             if (!LastOutputBlankLine)
747             {
748                 AcpiOsPrintf ("\n");
749                 LastOutputBlankLine = TRUE;
750             }
751             ByteLength = sizeof (ACPI_HEST_NOTIFY);
752             break;
753         default:
754             ByteLength = 0;
755             break;
756         }
757
758         if (CurrentOffset + ByteLength > TableLength)
759         {
760             AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
761             return (AE_BAD_DATA);
762         }
763
764         if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
765         {
766             AcpiOsPrintf ("%s", Info->Name);
767             continue;
768         }
769
770         /* Start a new line and decode the opcode */
771
772         AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
773
774         switch (Info->Opcode)
775         {
776         /* Single-bit Flag fields. Note: Opcode is the bit position */
777
778         case ACPI_DMT_FLAG0:
779         case ACPI_DMT_FLAG1:
780         case ACPI_DMT_FLAG2:
781         case ACPI_DMT_FLAG3:
782         case ACPI_DMT_FLAG4:
783         case ACPI_DMT_FLAG5:
784         case ACPI_DMT_FLAG6:
785         case ACPI_DMT_FLAG7:
786
787             AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
788             break;
789
790         /* 2-bit Flag fields */
791
792         case ACPI_DMT_FLAGS0:
793
794             AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
795             break;
796
797         case ACPI_DMT_FLAGS1:
798
799             AcpiOsPrintf ("%1.1X\n", (*Target >> 1) & 0x03);
800             break;
801
802         case ACPI_DMT_FLAGS2:
803
804             AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
805             break;
806
807         case ACPI_DMT_FLAGS4:
808
809             AcpiOsPrintf ("%1.1X\n", (*Target >> 4) & 0x03);
810             break;
811
812         /* Integer Data Types */
813
814         case ACPI_DMT_UINT8:
815         case ACPI_DMT_UINT16:
816         case ACPI_DMT_UINT24:
817         case ACPI_DMT_UINT32:
818         case ACPI_DMT_UINT40:
819         case ACPI_DMT_UINT48:
820         case ACPI_DMT_UINT56:
821         case ACPI_DMT_UINT64:
822             /*
823              * Dump bytes - high byte first, low byte last.
824              * Note: All ACPI tables are little-endian.
825              */
826             for (Temp8 = (UINT8) ByteLength; Temp8 > 0; Temp8--)
827             {
828                 AcpiOsPrintf ("%2.2X", Target[Temp8 - 1]);
829             }
830             AcpiOsPrintf ("\n");
831             break;
832
833         case ACPI_DMT_BUF7:
834         case ACPI_DMT_BUF16:
835         case ACPI_DMT_BUF128:
836
837             /*
838              * Buffer: Size depends on the opcode and was set above.
839              * Each hex byte is separated with a space.
840              * Multiple lines are separated by line continuation char.
841              */
842             for (Temp16 = 0; Temp16 < ByteLength; Temp16++)
843             {
844                 AcpiOsPrintf ("%2.2X", Target[Temp16]);
845                 if ((UINT32) (Temp16 + 1) < ByteLength)
846                 {
847                     if ((Temp16 > 0) && (!((Temp16+1) % 16)))
848                     {
849                         AcpiOsPrintf (" \\\n"); /* Line continuation */
850                         AcpiDmLineHeader (0, 0, NULL);
851                     }
852                     else
853                     {
854                         AcpiOsPrintf (" ");
855                     }
856                 }
857             }
858             AcpiOsPrintf ("\n");
859             break;
860
861         case ACPI_DMT_UUID:
862
863             /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */
864
865             (void) AuConvertUuidToString ((char *) Target, MsgBuffer);
866
867             AcpiOsPrintf ("%s\n", MsgBuffer);
868             break;
869
870         case ACPI_DMT_STRING:
871
872             AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
873             break;
874
875         /* Fixed length ASCII name fields */
876
877         case ACPI_DMT_SIG:
878
879             AcpiDmCheckAscii (Target, RepairedName, 4);
880             AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
881             TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
882             if (TableData)
883             {
884                 AcpiOsPrintf (STRING_FORMAT, TableData->Name);
885             }
886             else
887             {
888                 AcpiOsPrintf ("\n");
889             }
890             break;
891
892         case ACPI_DMT_NAME4:
893
894             AcpiDmCheckAscii (Target, RepairedName, 4);
895             AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
896             break;
897
898         case ACPI_DMT_NAME6:
899
900             AcpiDmCheckAscii (Target, RepairedName, 6);
901             AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
902             break;
903
904         case ACPI_DMT_NAME8:
905
906             AcpiDmCheckAscii (Target, RepairedName, 8);
907             AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
908             break;
909
910         /* Special Data Types */
911
912         case ACPI_DMT_CHKSUM:
913
914             /* Checksum, display and validate */
915
916             AcpiOsPrintf ("%2.2X", *Target);
917             Temp8 = AcpiDmGenerateChecksum (Table,
918                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
919                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
920             if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
921             {
922                 AcpiOsPrintf (
923                     "     /* Incorrect checksum, should be %2.2X */", Temp8);
924             }
925             AcpiOsPrintf ("\n");
926             break;
927
928         case ACPI_DMT_SPACEID:
929
930             /* Address Space ID */
931
932             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiUtGetRegionName (*Target));
933             break;
934
935         case ACPI_DMT_ACCWIDTH:
936
937             /* Encoded Access Width */
938
939             Temp8 = *Target;
940             if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
941             {
942                 Temp8 = ACPI_GAS_WIDTH_RESERVED;
943             }
944
945             AcpiOsPrintf (UINT8_FORMAT, Temp8, AcpiDmGasAccessWidth[Temp8]);
946             break;
947
948         case ACPI_DMT_GAS:
949
950             /* Generic Address Structure */
951
952             AcpiOsPrintf (STRING_FORMAT, "Generic Address Structure");
953             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
954                 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
955             AcpiOsPrintf ("\n");
956             LastOutputBlankLine = TRUE;
957             break;
958
959         case ACPI_DMT_ASF:
960
961             /* ASF subtable types */
962
963             Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
964             if (Temp16 > ACPI_ASF_TYPE_RESERVED)
965             {
966                 Temp16 = ACPI_ASF_TYPE_RESERVED;
967             }
968
969             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmAsfSubnames[Temp16]);
970             break;
971
972         case ACPI_DMT_DMAR:
973
974             /* DMAR subtable types */
975
976             Temp16 = ACPI_GET16 (Target);
977             if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
978             {
979                 Temp16 = ACPI_DMAR_TYPE_RESERVED;
980             }
981
982             AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
983             break;
984
985         case ACPI_DMT_EINJACT:
986
987             /* EINJ Action types */
988
989             Temp8 = *Target;
990             if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
991             {
992                 Temp8 = ACPI_EINJ_ACTION_RESERVED;
993             }
994
995             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjActions[Temp8]);
996             break;
997
998         case ACPI_DMT_EINJINST:
999
1000             /* EINJ Instruction types */
1001
1002             Temp8 = *Target;
1003             if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
1004             {
1005                 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
1006             }
1007
1008             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjInstructions[Temp8]);
1009             break;
1010
1011         case ACPI_DMT_ERSTACT:
1012
1013             /* ERST Action types */
1014
1015             Temp8 = *Target;
1016             if (Temp8 > ACPI_ERST_ACTION_RESERVED)
1017             {
1018                 Temp8 = ACPI_ERST_ACTION_RESERVED;
1019             }
1020
1021             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstActions[Temp8]);
1022             break;
1023
1024         case ACPI_DMT_ERSTINST:
1025
1026             /* ERST Instruction types */
1027
1028             Temp8 = *Target;
1029             if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
1030             {
1031                 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
1032             }
1033
1034             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstInstructions[Temp8]);
1035             break;
1036
1037         case ACPI_DMT_HEST:
1038
1039             /* HEST subtable types */
1040
1041             Temp16 = ACPI_GET16 (Target);
1042             if (Temp16 > ACPI_HEST_TYPE_RESERVED)
1043             {
1044                 Temp16 = ACPI_HEST_TYPE_RESERVED;
1045             }
1046
1047             AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
1048             break;
1049
1050         case ACPI_DMT_HESTNTFY:
1051
1052             AcpiOsPrintf (STRING_FORMAT, "Hardware Error Notification Structure");
1053             AcpiDmDumpTable (TableLength, CurrentOffset, Target,
1054                 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
1055             AcpiOsPrintf ("\n");
1056             LastOutputBlankLine = TRUE;
1057             break;
1058
1059         case ACPI_DMT_HESTNTYP:
1060
1061             /* HEST Notify types */
1062
1063             Temp8 = *Target;
1064             if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
1065             {
1066                 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
1067             }
1068
1069             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmHestNotifySubnames[Temp8]);
1070             break;
1071
1072         case ACPI_DMT_MADT:
1073
1074             /* MADT subtable types */
1075
1076             Temp8 = *Target;
1077             if (Temp8 > ACPI_MADT_TYPE_RESERVED)
1078             {
1079                 Temp8 = ACPI_MADT_TYPE_RESERVED;
1080             }
1081
1082             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmMadtSubnames[Temp8]);
1083             break;
1084
1085         case ACPI_DMT_PMTT:
1086
1087             /* PMTT subtable types */
1088
1089             Temp8 = *Target;
1090             if (Temp8 > ACPI_PMTT_TYPE_RESERVED)
1091             {
1092                 Temp8 = ACPI_PMTT_TYPE_RESERVED;
1093             }
1094
1095             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmPmttSubnames[Temp8]);
1096             break;
1097
1098         case ACPI_DMT_SLIC:
1099
1100             /* SLIC subtable types */
1101
1102             Temp8 = *Target;
1103             if (Temp8 > ACPI_SLIC_TYPE_RESERVED)
1104             {
1105                 Temp8 = ACPI_SLIC_TYPE_RESERVED;
1106             }
1107
1108             AcpiOsPrintf (UINT32_FORMAT, *Target, AcpiDmSlicSubnames[Temp8]);
1109             break;
1110
1111         case ACPI_DMT_SRAT:
1112
1113             /* SRAT subtable types */
1114
1115             Temp8 = *Target;
1116             if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
1117             {
1118                 Temp8 = ACPI_SRAT_TYPE_RESERVED;
1119             }
1120
1121             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmSratSubnames[Temp8]);
1122             break;
1123
1124         case ACPI_DMT_FADTPM:
1125
1126             /* FADT Preferred PM Profile names */
1127
1128             Temp8 = *Target;
1129             if (Temp8 > ACPI_FADT_PM_RESERVED)
1130             {
1131                 Temp8 = ACPI_FADT_PM_RESERVED;
1132             }
1133
1134             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmFadtProfiles[Temp8]);
1135             break;
1136
1137         case ACPI_DMT_IVRS:
1138
1139             /* IVRS subtable types */
1140
1141             Temp8 = *Target;
1142             switch (Temp8)
1143             {
1144             case ACPI_IVRS_TYPE_HARDWARE:
1145                 Name = AcpiDmIvrsSubnames[0];
1146                 break;
1147
1148             case ACPI_IVRS_TYPE_MEMORY1:
1149             case ACPI_IVRS_TYPE_MEMORY2:
1150             case ACPI_IVRS_TYPE_MEMORY3:
1151                 Name = AcpiDmIvrsSubnames[1];
1152                 break;
1153
1154             default:
1155                 Name = AcpiDmIvrsSubnames[2];
1156                 break;
1157             }
1158
1159             AcpiOsPrintf (UINT8_FORMAT, *Target, Name);
1160             break;
1161
1162         case ACPI_DMT_EXIT:
1163             return (AE_OK);
1164
1165         default:
1166             ACPI_ERROR ((AE_INFO,
1167                 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1168             return (AE_SUPPORT);
1169         }
1170     }
1171
1172     if (TableOffset && !SubtableLength)
1173     {
1174         /* If this table is not the main table, subtable must have valid length */
1175
1176         AcpiOsPrintf ("Invalid zero length subtable\n");
1177         return (AE_BAD_DATA);
1178     }
1179
1180     return (AE_OK);
1181 }
1182
1183
1184 /*******************************************************************************
1185  *
1186  * FUNCTION:    AcpiDmCheckAscii
1187  *
1188  * PARAMETERS:  Name                - Ascii string
1189  *              Count               - Number of characters to check
1190  *
1191  * RETURN:      None
1192  *
1193  * DESCRIPTION: Ensure that the requested number of characters are printable
1194  *              Ascii characters. Sets non-printable and null chars to <space>.
1195  *
1196  ******************************************************************************/
1197
1198 static void
1199 AcpiDmCheckAscii (
1200     UINT8                   *Name,
1201     char                    *RepairedName,
1202     UINT32                  Count)
1203 {
1204     UINT32                  i;
1205
1206
1207     for (i = 0; i < Count; i++)
1208     {
1209         RepairedName[i] = (char) Name[i];
1210
1211         if (!Name[i])
1212         {
1213             return;
1214         }
1215         if (!isprint (Name[i]))
1216         {
1217             RepairedName[i] = ' ';
1218         }
1219     }
1220 }