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