1 /******************************************************************************
2  *
3  * Module Name: dmtable - Support for ACPI tables that contain no AML code
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2015, 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 const AH_TABLE *
57 AcpiAhGetTableInfo (
58     char                    *Signature);
59 
60 
61 /* Local Prototypes */
62 
63 static void
64 AcpiDmCheckAscii (
65     UINT8                   *Target,
66     char                    *RepairedName,
67     UINT32                  Count);
68 
69 
70 /* Common format strings for commented values */
71 
72 #define UINT8_FORMAT        "%2.2X [%s]\n"
73 #define UINT16_FORMAT       "%4.4X [%s]\n"
74 #define UINT32_FORMAT       "%8.8X [%s]\n"
75 #define STRING_FORMAT       "[%s]\n"
76 
77 /* These tables map a subtable type to a description string */
78 
79 static const char           *AcpiDmAsfSubnames[] =
80 {
81     "ASF Information",
82     "ASF Alerts",
83     "ASF Remote Control",
84     "ASF RMCP Boot Options",
85     "ASF Address",
86     "Unknown Subtable Type"         /* Reserved */
87 };
88 
89 static const char           *AcpiDmDmarSubnames[] =
90 {
91     "Hardware Unit Definition",
92     "Reserved Memory Region",
93     "Root Port ATS Capability",
94     "Remapping Hardware Static Affinity",
95     "ACPI Namespace Device Declaration",
96     "Unknown Subtable Type"         /* Reserved */
97 };
98 
99 static const char           *AcpiDmDmarScope[] =
100 {
101     "Reserved value",
102     "PCI Endpoint Device",
103     "PCI Bridge Device",
104     "IOAPIC Device",
105     "Message-capable HPET Device",
106     "Namespace Device",
107     "Unknown Scope Type"            /* Reserved */
108 };
109 
110 static const char           *AcpiDmEinjActions[] =
111 {
112     "Begin Operation",
113     "Get Trigger Table",
114     "Set Error Type",
115     "Get Error Type",
116     "End Operation",
117     "Execute Operation",
118     "Check Busy Status",
119     "Get Command Status",
120     "Set Error Type With Address",
121     "Unknown Action"
122 };
123 
124 static const char           *AcpiDmEinjInstructions[] =
125 {
126     "Read Register",
127     "Read Register Value",
128     "Write Register",
129     "Write Register Value",
130     "Noop",
131     "Flush Cacheline",
132     "Unknown Instruction"
133 };
134 
135 static const char           *AcpiDmErstActions[] =
136 {
137     "Begin Write Operation",
138     "Begin Read Operation",
139     "Begin Clear Operation",
140     "End Operation",
141     "Set Record Offset",
142     "Execute Operation",
143     "Check Busy Status",
144     "Get Command Status",
145     "Get Record Identifier",
146     "Set Record Identifier",
147     "Get Record Count",
148     "Begin Dummy Write",
149     "Unused/Unknown Action",
150     "Get Error Address Range",
151     "Get Error Address Length",
152     "Get Error Attributes",
153     "Unknown Action"
154 };
155 
156 static const char           *AcpiDmErstInstructions[] =
157 {
158     "Read Register",
159     "Read Register Value",
160     "Write Register",
161     "Write Register Value",
162     "Noop",
163     "Load Var1",
164     "Load Var2",
165     "Store Var1",
166     "Add",
167     "Subtract",
168     "Add Value",
169     "Subtract Value",
170     "Stall",
171     "Stall While True",
172     "Skip Next If True",
173     "GoTo",
174     "Set Source Address",
175     "Set Destination Address",
176     "Move Data",
177     "Unknown Instruction"
178 };
179 
180 static const char           *AcpiDmGtdtSubnames[] =
181 {
182     "Generic Timer Block",
183     "Generic Watchdog Timer",
184     "Unknown Subtable Type"         /* Reserved */
185 };
186 
187 static const char           *AcpiDmHestSubnames[] =
188 {
189     "IA-32 Machine Check Exception",
190     "IA-32 Corrected Machine Check",
191     "IA-32 Non-Maskable Interrupt",
192     "Unknown SubTable Type",        /* 3 - Reserved */
193     "Unknown SubTable Type",        /* 4 - Reserved */
194     "Unknown SubTable Type",        /* 5 - Reserved */
195     "PCI Express Root Port AER",
196     "PCI Express AER (AER Endpoint)",
197     "PCI Express/PCI-X Bridge AER",
198     "Generic Hardware Error Source",
199     "Unknown Subtable Type"         /* Reserved */
200 };
201 
202 static const char           *AcpiDmHestNotifySubnames[] =
203 {
204     "Polled",
205     "External Interrupt",
206     "Local Interrupt",
207     "SCI",
208     "NMI",
209     "CMCI",                         /* ACPI 5.0 */
210     "MCE",                          /* ACPI 5.0 */
211     "Unknown Notify Type"           /* Reserved */
212 };
213 
214 static const char           *AcpiDmMadtSubnames[] =
215 {
216     "Processor Local APIC",             /* ACPI_MADT_TYPE_LOCAL_APIC */
217     "I/O APIC",                         /* ACPI_MADT_TYPE_IO_APIC */
218     "Interrupt Source Override",        /* ACPI_MADT_TYPE_INTERRUPT_OVERRIDE */
219     "NMI Source",                       /* ACPI_MADT_TYPE_NMI_SOURCE */
220     "Local APIC NMI",                   /* ACPI_MADT_TYPE_LOCAL_APIC_NMI */
221     "Local APIC Address Override",      /* ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE */
222     "I/O SAPIC",                        /* ACPI_MADT_TYPE_IO_SAPIC */
223     "Local SAPIC",                      /* ACPI_MADT_TYPE_LOCAL_SAPIC */
224     "Platform Interrupt Sources",       /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */
225     "Processor Local x2APIC",           /* ACPI_MADT_TYPE_LOCAL_X2APIC */
226     "Local x2APIC NMI",                 /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */
227     "Generic Interrupt Controller",     /* ACPI_MADT_GENERIC_INTERRUPT */
228     "Generic Interrupt Distributor",    /* ACPI_MADT_GENERIC_DISTRIBUTOR */
229     "Generic MSI Frame",                /* ACPI_MADT_GENERIC_MSI_FRAME */
230     "Generic Interrupt Redistributor",  /* ACPI_MADT_GENERIC_REDISTRIBUTOR */
231     "Generic Interrupt Translator",     /* ACPI_MADT_GENERIC_TRANSLATOR */
232     "Unknown Subtable Type"             /* Reserved */
233 };
234 
235 static const char           *AcpiDmNfitSubnames[] =
236 {
237     "System Physical Address Range",    /* ACPI_NFIT_TYPE_SYSTEM_ADDRESS */
238     "Memory Range Map",                 /* ACPI_NFIT_TYPE_MEMORY_MAP */
239     "Interleave Info",                  /* ACPI_NFIT_TYPE_INTERLEAVE */
240     "SMBIOS Information",               /* ACPI_NFIT_TYPE_SMBIOS */
241     "NVDIMM Control Region",            /* ACPI_NFIT_TYPE_CONTROL_REGION */
242     "NVDIMM Block Data Window Region",  /* ACPI_NFIT_TYPE_DATA_REGION */
243     "Flush Hint Address",               /* ACPI_NFIT_TYPE_FLUSH_ADDRESS */
244     "Unknown Subtable Type"             /* Reserved */
245 };
246 
247 static const char           *AcpiDmPcctSubnames[] =
248 {
249     "Generic Communications Subspace",  /* ACPI_PCCT_TYPE_GENERIC_SUBSPACE */
250     "HW-Reduced Comm Subspace",         /* ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE */
251     "Unknown Subtable Type"             /* Reserved */
252 };
253 
254 static const char           *AcpiDmPmttSubnames[] =
255 {
256     "Socket",                       /* ACPI_PMTT_TYPE_SOCKET */
257     "Memory Controller",            /* ACPI_PMTT_TYPE_CONTROLLER */
258     "Physical Component (DIMM)",    /* ACPI_PMTT_TYPE_DIMM  */
259     "Unknown Subtable Type"         /* Reserved */
260 };
261 
262 static const char           *AcpiDmSratSubnames[] =
263 {
264     "Processor Local APIC/SAPIC Affinity",
265     "Memory Affinity",
266     "Processor Local x2APIC Affinity",
267     "GICC Affinity",
268     "Unknown Subtable Type"         /* Reserved */
269 };
270 
271 static const char           *AcpiDmIvrsSubnames[] =
272 {
273     "Hardware Definition Block",
274     "Memory Definition Block",
275     "Unknown Subtable Type"         /* Reserved */
276 };
277 
278 static const char           *AcpiDmLpitSubnames[] =
279 {
280     "Native C-state Idle Structure",
281     "Unknown Subtable Type"         /* Reserved */
282 };
283 
284 #define ACPI_FADT_PM_RESERVED       9
285 
286 static const char           *AcpiDmFadtProfiles[] =
287 {
288     "Unspecified",
289     "Desktop",
290     "Mobile",
291     "Workstation",
292     "Enterprise Server",
293     "SOHO Server",
294     "Appliance PC",
295     "Performance Server",
296     "Tablet",
297     "Unknown Profile Type"
298 };
299 
300 #define ACPI_GAS_WIDTH_RESERVED     5
301 
302 static const char           *AcpiDmGasAccessWidth[] =
303 {
304     "Undefined/Legacy",
305     "Byte Access:8",
306     "Word Access:16",
307     "DWord Access:32",
308     "QWord Access:64",
309     "Unknown Width Encoding"
310 };
311 
312 
313 /*******************************************************************************
314  *
315  * ACPI Table Data, indexed by signature.
316  *
317  * Each entry contains: Signature, Table Info, Handler, DtHandler,
318  *  Template, Description
319  *
320  * Simple tables have only a TableInfo structure, complex tables have a
321  * handler. This table must be NULL terminated. RSDP and FACS are
322  * special-cased elsewhere.
323  *
324  * Note: Any tables added here should be duplicated within AcpiSupportedTables
325  * in the file common/ahtable.c
326  *
327  ******************************************************************************/
328 
329 const ACPI_DMTABLE_DATA     AcpiDmTableData[] =
330 {
331     {ACPI_SIG_ASF,  NULL,                   AcpiDmDumpAsf,  DtCompileAsf,   TemplateAsf},
332     {ACPI_SIG_BERT, AcpiDmTableInfoBert,    NULL,           NULL,           TemplateBert},
333     {ACPI_SIG_BGRT, AcpiDmTableInfoBgrt,    NULL,           NULL,           TemplateBgrt},
334     {ACPI_SIG_BOOT, AcpiDmTableInfoBoot,    NULL,           NULL,           TemplateBoot},
335     {ACPI_SIG_CPEP, NULL,                   AcpiDmDumpCpep, DtCompileCpep,  TemplateCpep},
336     {ACPI_SIG_CSRT, NULL,                   AcpiDmDumpCsrt, DtCompileCsrt,  TemplateCsrt},
337     {ACPI_SIG_DBG2, AcpiDmTableInfoDbg2,    AcpiDmDumpDbg2, DtCompileDbg2,  TemplateDbg2},
338     {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp,    NULL,           NULL,           TemplateDbgp},
339     {ACPI_SIG_DMAR, NULL,                   AcpiDmDumpDmar, DtCompileDmar,  TemplateDmar},
340     {ACPI_SIG_DRTM, NULL,                   AcpiDmDumpDrtm, DtCompileDrtm,  TemplateDrtm},
341     {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt,    NULL,           NULL,           TemplateEcdt},
342     {ACPI_SIG_EINJ, NULL,                   AcpiDmDumpEinj, DtCompileEinj,  TemplateEinj},
343     {ACPI_SIG_ERST, NULL,                   AcpiDmDumpErst, DtCompileErst,  TemplateErst},
344     {ACPI_SIG_FADT, NULL,                   AcpiDmDumpFadt, DtCompileFadt,  TemplateFadt},
345     {ACPI_SIG_FPDT, NULL,                   AcpiDmDumpFpdt, DtCompileFpdt,  TemplateFpdt},
346     {ACPI_SIG_GTDT, NULL,                   AcpiDmDumpGtdt, DtCompileGtdt,  TemplateGtdt},
347     {ACPI_SIG_HEST, NULL,                   AcpiDmDumpHest, DtCompileHest,  TemplateHest},
348     {ACPI_SIG_HPET, AcpiDmTableInfoHpet,    NULL,           NULL,           TemplateHpet},
349     {ACPI_SIG_IORT, NULL,                   AcpiDmDumpIort, DtCompileIort,  TemplateIort},
350     {ACPI_SIG_IVRS, NULL,                   AcpiDmDumpIvrs, DtCompileIvrs,  TemplateIvrs},
351     {ACPI_SIG_LPIT, NULL,                   AcpiDmDumpLpit, DtCompileLpit,  TemplateLpit},
352     {ACPI_SIG_MADT, NULL,                   AcpiDmDumpMadt, DtCompileMadt,  TemplateMadt},
353     {ACPI_SIG_MCFG, NULL,                   AcpiDmDumpMcfg, DtCompileMcfg,  TemplateMcfg},
354     {ACPI_SIG_MCHI, AcpiDmTableInfoMchi,    NULL,           NULL,           TemplateMchi},
355     {ACPI_SIG_MPST, AcpiDmTableInfoMpst,    AcpiDmDumpMpst, DtCompileMpst,  TemplateMpst},
356     {ACPI_SIG_MSCT, NULL,                   AcpiDmDumpMsct, DtCompileMsct,  TemplateMsct},
357     {ACPI_SIG_MSDM, NULL,                   AcpiDmDumpSlic, DtCompileSlic,  TemplateMsdm},
358     {ACPI_SIG_MTMR, NULL,                   AcpiDmDumpMtmr, DtCompileMtmr,  TemplateMtmr},
359     {ACPI_SIG_NFIT, AcpiDmTableInfoNfit,    AcpiDmDumpNfit, DtCompileNfit,  TemplateNfit},
360     {ACPI_SIG_PCCT, AcpiDmTableInfoPcct,    AcpiDmDumpPcct, DtCompilePcct,  TemplatePcct},
361     {ACPI_SIG_PMTT, NULL,                   AcpiDmDumpPmtt, DtCompilePmtt,  TemplatePmtt},
362     {ACPI_SIG_RSDT, NULL,                   AcpiDmDumpRsdt, DtCompileRsdt,  TemplateRsdt},
363     {ACPI_SIG_S3PT, NULL,                   NULL,           NULL,           TemplateS3pt},
364     {ACPI_SIG_SBST, AcpiDmTableInfoSbst,    NULL,           NULL,           TemplateSbst},
365     {ACPI_SIG_SLIC, NULL,                   AcpiDmDumpSlic, DtCompileSlic,  TemplateSlic},
366     {ACPI_SIG_SLIT, NULL,                   AcpiDmDumpSlit, DtCompileSlit,  TemplateSlit},
367     {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr,    NULL,           NULL,           TemplateSpcr},
368     {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi,    NULL,           NULL,           TemplateSpmi},
369     {ACPI_SIG_SRAT, NULL,                   AcpiDmDumpSrat, DtCompileSrat,  TemplateSrat},
370     {ACPI_SIG_STAO, NULL,                   AcpiDmDumpStao, DtCompileStao,  TemplateStao},
371     {ACPI_SIG_TCPA, NULL,                   AcpiDmDumpTcpa, DtCompileTcpa,  TemplateTcpa},
372     {ACPI_SIG_TPM2, AcpiDmTableInfoTpm2,    NULL,           NULL,           TemplateTpm2},
373     {ACPI_SIG_UEFI, AcpiDmTableInfoUefi,    NULL,           DtCompileUefi,  TemplateUefi},
374     {ACPI_SIG_VRTC, AcpiDmTableInfoVrtc,    AcpiDmDumpVrtc, DtCompileVrtc,  TemplateVrtc},
375     {ACPI_SIG_WAET, AcpiDmTableInfoWaet,    NULL,           NULL,           TemplateWaet},
376     {ACPI_SIG_WDAT, NULL,                   AcpiDmDumpWdat, DtCompileWdat,  TemplateWdat},
377     {ACPI_SIG_WDDT, AcpiDmTableInfoWddt,    NULL,           NULL,           TemplateWddt},
378     {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt,    NULL,           NULL,           TemplateWdrt},
379     {ACPI_SIG_WPBT, NULL,                   AcpiDmDumpWpbt, DtCompileWpbt,  TemplateWpbt},
380     {ACPI_SIG_XENV, AcpiDmTableInfoXenv,    NULL,           NULL,           TemplateXenv},
381     {ACPI_SIG_XSDT, NULL,                   AcpiDmDumpXsdt, DtCompileXsdt,  TemplateXsdt},
382     {NULL,          NULL,                   NULL,           NULL,           NULL}
383 };
384 
385 
386 /*******************************************************************************
387  *
388  * FUNCTION:    AcpiDmGenerateChecksum
389  *
390  * PARAMETERS:  Table               - Pointer to table to be checksummed
391  *              Length              - Length of the table
392  *              OriginalChecksum    - Value of the checksum field
393  *
394  * RETURN:      8 bit checksum of buffer
395  *
396  * DESCRIPTION: Computes an 8 bit checksum of the table.
397  *
398  ******************************************************************************/
399 
400 UINT8
401 AcpiDmGenerateChecksum (
402     void                    *Table,
403     UINT32                  Length,
404     UINT8                   OriginalChecksum)
405 {
406     UINT8                   Checksum;
407 
408 
409     /* Sum the entire table as-is */
410 
411     Checksum = AcpiTbChecksum ((UINT8 *) Table, Length);
412 
413     /* Subtract off the existing checksum value in the table */
414 
415     Checksum = (UINT8) (Checksum - OriginalChecksum);
416 
417     /* Compute the final checksum */
418 
419     Checksum = (UINT8) (0 - Checksum);
420     return (Checksum);
421 }
422 
423 
424 /*******************************************************************************
425  *
426  * FUNCTION:    AcpiDmGetTableData
427  *
428  * PARAMETERS:  Signature           - ACPI signature (4 chars) to match
429  *
430  * RETURN:      Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
431  *
432  * DESCRIPTION: Find a match in the global table of supported ACPI tables
433  *
434  ******************************************************************************/
435 
436 const ACPI_DMTABLE_DATA *
437 AcpiDmGetTableData (
438     char                    *Signature)
439 {
440     const ACPI_DMTABLE_DATA *Info;
441 
442 
443     for (Info = AcpiDmTableData; Info->Signature; Info++)
444     {
445         if (ACPI_COMPARE_NAME (Signature, Info->Signature))
446         {
447             return (Info);
448         }
449     }
450 
451     return (NULL);
452 }
453 
454 
455 /*******************************************************************************
456  *
457  * FUNCTION:    AcpiDmDumpDataTable
458  *
459  * PARAMETERS:  Table               - An ACPI table
460  *
461  * RETURN:      None.
462  *
463  * DESCRIPTION: Format the contents of an ACPI data table (any table other
464  *              than an SSDT or DSDT that does not contain executable AML code)
465  *
466  ******************************************************************************/
467 
468 void
469 AcpiDmDumpDataTable (
470     ACPI_TABLE_HEADER       *Table)
471 {
472     ACPI_STATUS             Status;
473     const ACPI_DMTABLE_DATA *TableData;
474     UINT32                  Length;
475 
476 
477     /* Ignore tables that contain AML */
478 
479     if (AcpiUtIsAmlTable (Table))
480     {
481         if (Gbl_VerboseTemplates)
482         {
483             /* Dump the raw table data */
484 
485             Length = Table->Length;
486 
487             AcpiOsPrintf ("\n/*\n%s: Length %d (0x%X)\n\n",
488                 ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
489             AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, Table),
490                 Length, DB_BYTE_DISPLAY, 0);
491             AcpiOsPrintf (" */\n");
492         }
493         return;
494     }
495 
496     /*
497      * Handle tables that don't use the common ACPI table header structure.
498      * Currently, these are the FACS, RSDP, and S3PT.
499      */
500     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
501     {
502         Length = Table->Length;
503         Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
504         if (ACPI_FAILURE (Status))
505         {
506             return;
507         }
508     }
509     else if (ACPI_VALIDATE_RSDP_SIG (Table->Signature))
510     {
511         Length = AcpiDmDumpRsdp (Table);
512     }
513     else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_S3PT))
514     {
515         Length = AcpiDmDumpS3pt (Table);
516     }
517     else
518     {
519         /*
520          * All other tables must use the common ACPI table header, dump it now
521          */
522         Length = Table->Length;
523         Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
524         if (ACPI_FAILURE (Status))
525         {
526             return;
527         }
528         AcpiOsPrintf ("\n");
529 
530         /* Match signature and dispatch appropriately */
531 
532         TableData = AcpiDmGetTableData (Table->Signature);
533         if (!TableData)
534         {
535             if (!strncmp (Table->Signature, "OEM", 3))
536             {
537                 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
538                     Table->Signature);
539             }
540             else
541             {
542                 AcpiOsPrintf ("\n**** Unknown ACPI table signature [%4.4s]\n\n",
543                     Table->Signature);
544 
545                 fprintf (stderr, "Unknown ACPI table signature [%4.4s], ",
546                     Table->Signature);
547 
548                 if (!AcpiGbl_ForceAmlDisassembly)
549                 {
550                     fprintf (stderr, "decoding ACPI table header only\n");
551                 }
552                 else
553                 {
554                     fprintf (stderr, "assuming table contains valid AML code\n");
555                 }
556             }
557         }
558         else if (TableData->TableHandler)
559         {
560             /* Complex table, has a handler */
561 
562             TableData->TableHandler (Table);
563         }
564         else if (TableData->TableInfo)
565         {
566             /* Simple table, just walk the info table */
567 
568             Status = AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
569             if (ACPI_FAILURE (Status))
570             {
571                 return;
572             }
573         }
574     }
575 
576     if (!Gbl_DoTemplates || Gbl_VerboseTemplates)
577     {
578         /* Dump the raw table data */
579 
580         AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
581             ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
582         AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, Table),
583             Length, DB_BYTE_DISPLAY, 0);
584     }
585 }
586 
587 
588 /*******************************************************************************
589  *
590  * FUNCTION:    AcpiDmLineHeader
591  *
592  * PARAMETERS:  Offset              - Current byte offset, from table start
593  *              ByteLength          - Length of the field in bytes, 0 for flags
594  *              Name                - Name of this field
595  *
596  * RETURN:      None
597  *
598  * DESCRIPTION: Utility routines for formatting output lines. Displays the
599  *              current table offset in hex and decimal, the field length,
600  *              and the field name.
601  *
602  ******************************************************************************/
603 
604 void
605 AcpiDmLineHeader (
606     UINT32                  Offset,
607     UINT32                  ByteLength,
608     char                    *Name)
609 {
610 
611     /* Allow a null name for fields that span multiple lines (large buffers) */
612 
613     if (!Name)
614     {
615         Name = "";
616     }
617 
618     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
619     {
620         if (ByteLength)
621         {
622             AcpiOsPrintf ("[%.4d] %34s : ", ByteLength, Name);
623         }
624         else
625         {
626             if (*Name)
627             {
628                 AcpiOsPrintf ("%41s : ", Name);
629             }
630             else
631             {
632                 AcpiOsPrintf ("%41s   ", Name);
633             }
634         }
635     }
636     else /* Normal disassembler or verbose template */
637     {
638         if (ByteLength)
639         {
640             AcpiOsPrintf ("[%3.3Xh %4.4d% 4d] %28s : ",
641                 Offset, Offset, ByteLength, Name);
642         }
643         else
644         {
645             if (*Name)
646             {
647                 AcpiOsPrintf ("%44s : ", Name);
648             }
649             else
650             {
651                 AcpiOsPrintf ("%44s   ", Name);
652             }
653         }
654     }
655 }
656 
657 void
658 AcpiDmLineHeader2 (
659     UINT32                  Offset,
660     UINT32                  ByteLength,
661     char                    *Name,
662     UINT32                  Value)
663 {
664 
665     if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
666     {
667         if (ByteLength)
668         {
669             AcpiOsPrintf ("[%.4d] %30s %3d : ",
670                 ByteLength, Name, Value);
671         }
672         else
673         {
674             AcpiOsPrintf ("%36s % 3d : ",
675                 Name, Value);
676         }
677     }
678     else /* Normal disassembler or verbose template */
679     {
680         if (ByteLength)
681         {
682             AcpiOsPrintf ("[%3.3Xh %4.4d %3d] %24s %3d : ",
683                 Offset, Offset, ByteLength, Name, Value);
684         }
685         else
686         {
687             AcpiOsPrintf ("[%3.3Xh %4.4d   ] %24s %3d : ",
688                 Offset, Offset, Name, Value);
689         }
690     }
691 }
692 
693 
694 /*******************************************************************************
695  *
696  * FUNCTION:    AcpiDmDumpTable
697  *
698  * PARAMETERS:  TableLength         - Length of the entire ACPI table
699  *              TableOffset         - Starting offset within the table for this
700  *                                    sub-descriptor (0 if main table)
701  *              Table               - The ACPI table
702  *              SubtableLength      - Length of this sub-descriptor
703  *              Info                - Info table for this ACPI table
704  *
705  * RETURN:      Status
706  *
707  * DESCRIPTION: Display ACPI table contents by walking the Info table.
708  *
709  * Note: This function must remain in sync with DtGetFieldLength.
710  *
711  ******************************************************************************/
712 
713 ACPI_STATUS
714 AcpiDmDumpTable (
715     UINT32                  TableLength,
716     UINT32                  TableOffset,
717     void                    *Table,
718     UINT32                  SubtableLength,
719     ACPI_DMTABLE_INFO       *Info)
720 {
721     UINT8                   *Target;
722     UINT32                  CurrentOffset;
723     UINT32                  ByteLength;
724     UINT8                   Temp8;
725     UINT16                  Temp16;
726     UINT32                  Temp32;
727     UINT64                  Value;
728     const AH_TABLE          *TableData;
729     const char              *Name;
730     BOOLEAN                 LastOutputBlankLine = FALSE;
731     ACPI_STATUS             Status;
732     char                    RepairedName[8];
733 
734 
735     if (!Info)
736     {
737         AcpiOsPrintf ("Display not implemented\n");
738         return (AE_NOT_IMPLEMENTED);
739     }
740 
741     /* Walk entire Info table; Null name terminates */
742 
743     for (; Info->Name; Info++)
744     {
745         /*
746          * Target points to the field within the ACPI Table. CurrentOffset is
747          * the offset of the field from the start of the main table.
748          */
749         Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
750         CurrentOffset = TableOffset + Info->Offset;
751 
752         /* Check for beyond subtable end or (worse) beyond EOT */
753 
754         if (SubtableLength && (Info->Offset >= SubtableLength))
755         {
756             AcpiOsPrintf (
757                 "/**** ACPI subtable terminates early - "
758                 "may be older version (dump table) */\n");
759 
760             /* Move on to next subtable */
761 
762             return (AE_OK);
763         }
764 
765         if (CurrentOffset >= TableLength)
766         {
767             AcpiOsPrintf (
768                 "/**** ACPI table terminates "
769                 "in the middle of a data structure! (dump table) */\n");
770             return (AE_BAD_DATA);
771         }
772 
773         /* Generate the byte length for this field */
774 
775         switch (Info->Opcode)
776         {
777         case ACPI_DMT_UINT8:
778         case ACPI_DMT_CHKSUM:
779         case ACPI_DMT_SPACEID:
780         case ACPI_DMT_ACCWIDTH:
781         case ACPI_DMT_IVRS:
782         case ACPI_DMT_GTDT:
783         case ACPI_DMT_MADT:
784         case ACPI_DMT_PCCT:
785         case ACPI_DMT_PMTT:
786         case ACPI_DMT_SRAT:
787         case ACPI_DMT_ASF:
788         case ACPI_DMT_HESTNTYP:
789         case ACPI_DMT_FADTPM:
790         case ACPI_DMT_EINJACT:
791         case ACPI_DMT_EINJINST:
792         case ACPI_DMT_ERSTACT:
793         case ACPI_DMT_ERSTINST:
794         case ACPI_DMT_DMAR_SCOPE:
795 
796             ByteLength = 1;
797             break;
798 
799         case ACPI_DMT_UINT16:
800         case ACPI_DMT_DMAR:
801         case ACPI_DMT_HEST:
802         case ACPI_DMT_NFIT:
803 
804             ByteLength = 2;
805             break;
806 
807         case ACPI_DMT_UINT24:
808 
809             ByteLength = 3;
810             break;
811 
812         case ACPI_DMT_UINT32:
813         case ACPI_DMT_NAME4:
814         case ACPI_DMT_SIG:
815         case ACPI_DMT_LPIT:
816 
817             ByteLength = 4;
818             break;
819 
820         case ACPI_DMT_UINT40:
821 
822             ByteLength = 5;
823             break;
824 
825         case ACPI_DMT_UINT48:
826         case ACPI_DMT_NAME6:
827 
828             ByteLength = 6;
829             break;
830 
831         case ACPI_DMT_UINT56:
832         case ACPI_DMT_BUF7:
833 
834             ByteLength = 7;
835             break;
836 
837         case ACPI_DMT_UINT64:
838         case ACPI_DMT_NAME8:
839 
840             ByteLength = 8;
841             break;
842 
843         case ACPI_DMT_BUF10:
844 
845             ByteLength = 10;
846             break;
847 
848         case ACPI_DMT_BUF16:
849         case ACPI_DMT_UUID:
850 
851             ByteLength = 16;
852             break;
853 
854         case ACPI_DMT_BUF128:
855 
856             ByteLength = 128;
857             break;
858 
859         case ACPI_DMT_UNICODE:
860         case ACPI_DMT_BUFFER:
861         case ACPI_DMT_RAW_BUFFER:
862 
863             ByteLength = SubtableLength;
864             break;
865 
866         case ACPI_DMT_STRING:
867 
868             ByteLength = strlen (ACPI_CAST_PTR (char, Target)) + 1;
869             break;
870 
871         case ACPI_DMT_GAS:
872 
873             if (!LastOutputBlankLine)
874             {
875                 AcpiOsPrintf ("\n");
876                 LastOutputBlankLine = TRUE;
877             }
878 
879             ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
880             break;
881 
882         case ACPI_DMT_HESTNTFY:
883 
884             if (!LastOutputBlankLine)
885             {
886                 AcpiOsPrintf ("\n");
887                 LastOutputBlankLine = TRUE;
888             }
889 
890             ByteLength = sizeof (ACPI_HEST_NOTIFY);
891             break;
892 
893         case ACPI_DMT_IORTMEM:
894 
895             if (!LastOutputBlankLine)
896             {
897                 LastOutputBlankLine = FALSE;
898             }
899 
900             ByteLength = sizeof (ACPI_IORT_MEMORY_ACCESS);
901             break;
902 
903         default:
904 
905             ByteLength = 0;
906             break;
907         }
908 
909         /* Check if we are beyond a subtable, or (worse) beyond EOT */
910 
911         if (CurrentOffset + ByteLength > TableLength)
912         {
913             if (SubtableLength)
914             {
915                 AcpiOsPrintf (
916                     "/**** ACPI subtable terminates early - "
917                     "may be older version (dump table) */\n");
918 
919                 /* Move on to next subtable */
920 
921                 return (AE_OK);
922             }
923 
924             AcpiOsPrintf (
925                 "/**** ACPI table terminates "
926                 "in the middle of a data structure! */\n");
927             return (AE_BAD_DATA);
928         }
929 
930         if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
931         {
932             AcpiOsPrintf ("%s", Info->Name);
933             continue;
934         }
935 
936         /* Start a new line and decode the opcode */
937 
938         AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
939 
940         switch (Info->Opcode)
941         {
942         /* Single-bit Flag fields. Note: Opcode is the bit position */
943 
944         case ACPI_DMT_FLAG0:
945         case ACPI_DMT_FLAG1:
946         case ACPI_DMT_FLAG2:
947         case ACPI_DMT_FLAG3:
948         case ACPI_DMT_FLAG4:
949         case ACPI_DMT_FLAG5:
950         case ACPI_DMT_FLAG6:
951         case ACPI_DMT_FLAG7:
952 
953             AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
954             break;
955 
956         /* 2-bit Flag fields */
957 
958         case ACPI_DMT_FLAGS0:
959 
960             AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
961             break;
962 
963         case ACPI_DMT_FLAGS1:
964 
965             AcpiOsPrintf ("%1.1X\n", (*Target >> 1) & 0x03);
966             break;
967 
968         case ACPI_DMT_FLAGS2:
969 
970             AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
971             break;
972 
973         case ACPI_DMT_FLAGS4:
974 
975             AcpiOsPrintf ("%1.1X\n", (*Target >> 4) & 0x03);
976             break;
977 
978         /* Integer Data Types */
979 
980         case ACPI_DMT_UINT8:
981         case ACPI_DMT_UINT16:
982         case ACPI_DMT_UINT24:
983         case ACPI_DMT_UINT32:
984         case ACPI_DMT_UINT40:
985         case ACPI_DMT_UINT48:
986         case ACPI_DMT_UINT56:
987         case ACPI_DMT_UINT64:
988             /*
989              * Dump bytes - high byte first, low byte last.
990              * Note: All ACPI tables are little-endian.
991              */
992             Value = 0;
993             for (Temp8 = (UINT8) ByteLength; Temp8 > 0; Temp8--)
994             {
995                 AcpiOsPrintf ("%2.2X", Target[Temp8 - 1]);
996                 Value |= Target[Temp8 - 1];
997                 Value <<= 8;
998             }
999 
1000             if (!Value && (Info->Flags & DT_DESCRIBES_OPTIONAL))
1001             {
1002                 AcpiOsPrintf (" [Optional field not present]");
1003             }
1004 
1005             AcpiOsPrintf ("\n");
1006             break;
1007 
1008         case ACPI_DMT_BUF7:
1009         case ACPI_DMT_BUF10:
1010         case ACPI_DMT_BUF16:
1011         case ACPI_DMT_BUF128:
1012             /*
1013              * Buffer: Size depends on the opcode and was set above.
1014              * Each hex byte is separated with a space.
1015              * Multiple lines are separated by line continuation char.
1016              */
1017             for (Temp16 = 0; Temp16 < ByteLength; Temp16++)
1018             {
1019                 AcpiOsPrintf ("%2.2X", Target[Temp16]);
1020                 if ((UINT32) (Temp16 + 1) < ByteLength)
1021                 {
1022                     if ((Temp16 > 0) && (!((Temp16+1) % 16)))
1023                     {
1024                         AcpiOsPrintf (" \\\n"); /* Line continuation */
1025                         AcpiDmLineHeader (0, 0, NULL);
1026                     }
1027                     else
1028                     {
1029                         AcpiOsPrintf (" ");
1030                     }
1031                 }
1032             }
1033 
1034             AcpiOsPrintf ("\n");
1035             break;
1036 
1037         case ACPI_DMT_UUID:
1038 
1039             /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */
1040 
1041             (void) AuConvertUuidToString ((char *) Target, MsgBuffer);
1042 
1043             AcpiOsPrintf ("%s\n", MsgBuffer);
1044             break;
1045 
1046         case ACPI_DMT_STRING:
1047 
1048             AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
1049             break;
1050 
1051         /* Fixed length ASCII name fields */
1052 
1053         case ACPI_DMT_SIG:
1054 
1055             AcpiDmCheckAscii (Target, RepairedName, 4);
1056             AcpiOsPrintf ("\"%.4s\"    ", RepairedName);
1057 
1058             TableData = AcpiAhGetTableInfo (ACPI_CAST_PTR (char, Target));
1059             if (TableData)
1060             {
1061                 AcpiOsPrintf (STRING_FORMAT, TableData->Description);
1062             }
1063             else
1064             {
1065                 AcpiOsPrintf ("\n");
1066             }
1067             break;
1068 
1069         case ACPI_DMT_NAME4:
1070 
1071             AcpiDmCheckAscii (Target, RepairedName, 4);
1072             AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
1073             break;
1074 
1075         case ACPI_DMT_NAME6:
1076 
1077             AcpiDmCheckAscii (Target, RepairedName, 6);
1078             AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
1079             break;
1080 
1081         case ACPI_DMT_NAME8:
1082 
1083             AcpiDmCheckAscii (Target, RepairedName, 8);
1084             AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
1085             break;
1086 
1087         /* Special Data Types */
1088 
1089         case ACPI_DMT_CHKSUM:
1090 
1091             /* Checksum, display and validate */
1092 
1093             AcpiOsPrintf ("%2.2X", *Target);
1094             Temp8 = AcpiDmGenerateChecksum (Table,
1095                 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
1096                 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
1097 
1098             if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
1099             {
1100                 AcpiOsPrintf (
1101                     "     /* Incorrect checksum, should be %2.2X */", Temp8);
1102             }
1103 
1104             AcpiOsPrintf ("\n");
1105             break;
1106 
1107         case ACPI_DMT_SPACEID:
1108 
1109             /* Address Space ID */
1110 
1111             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiUtGetRegionName (*Target));
1112             break;
1113 
1114         case ACPI_DMT_ACCWIDTH:
1115 
1116             /* Encoded Access Width */
1117 
1118             Temp8 = *Target;
1119             if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
1120             {
1121                 Temp8 = ACPI_GAS_WIDTH_RESERVED;
1122             }
1123 
1124             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmGasAccessWidth[Temp8]);
1125             break;
1126 
1127         case ACPI_DMT_GAS:
1128 
1129             /* Generic Address Structure */
1130 
1131             AcpiOsPrintf (STRING_FORMAT, "Generic Address Structure");
1132             Status = AcpiDmDumpTable (TableLength, CurrentOffset, Target,
1133                 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
1134             if (ACPI_FAILURE (Status))
1135             {
1136                 return (Status);
1137             }
1138 
1139             AcpiOsPrintf ("\n");
1140             LastOutputBlankLine = TRUE;
1141             break;
1142 
1143         case ACPI_DMT_ASF:
1144 
1145             /* ASF subtable types */
1146 
1147             Temp16 = (UINT16) ((*Target) & 0x7F);  /* Top bit can be zero or one */
1148             if (Temp16 > ACPI_ASF_TYPE_RESERVED)
1149             {
1150                 Temp16 = ACPI_ASF_TYPE_RESERVED;
1151             }
1152 
1153             AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmAsfSubnames[Temp16]);
1154             break;
1155 
1156         case ACPI_DMT_DMAR:
1157 
1158             /* DMAR subtable types */
1159 
1160             Temp16 = ACPI_GET16 (Target);
1161             if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
1162             {
1163                 Temp16 = ACPI_DMAR_TYPE_RESERVED;
1164             }
1165 
1166             AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target),
1167                 AcpiDmDmarSubnames[Temp16]);
1168             break;
1169 
1170         case ACPI_DMT_DMAR_SCOPE:
1171 
1172             /* DMAR device scope types */
1173 
1174             Temp8 = *Target;
1175             if (Temp8 > ACPI_DMAR_SCOPE_TYPE_RESERVED)
1176             {
1177                 Temp8 = ACPI_DMAR_SCOPE_TYPE_RESERVED;
1178             }
1179 
1180             AcpiOsPrintf (UINT8_FORMAT, *Target,
1181                 AcpiDmDmarScope[Temp8]);
1182             break;
1183 
1184         case ACPI_DMT_EINJACT:
1185 
1186             /* EINJ Action types */
1187 
1188             Temp8 = *Target;
1189             if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
1190             {
1191                 Temp8 = ACPI_EINJ_ACTION_RESERVED;
1192             }
1193 
1194             AcpiOsPrintf (UINT8_FORMAT, *Target,
1195                 AcpiDmEinjActions[Temp8]);
1196             break;
1197 
1198         case ACPI_DMT_EINJINST:
1199 
1200             /* EINJ Instruction types */
1201 
1202             Temp8 = *Target;
1203             if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
1204             {
1205                 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
1206             }
1207 
1208             AcpiOsPrintf (UINT8_FORMAT, *Target,
1209                 AcpiDmEinjInstructions[Temp8]);
1210             break;
1211 
1212         case ACPI_DMT_ERSTACT:
1213 
1214             /* ERST Action types */
1215 
1216             Temp8 = *Target;
1217             if (Temp8 > ACPI_ERST_ACTION_RESERVED)
1218             {
1219                 Temp8 = ACPI_ERST_ACTION_RESERVED;
1220             }
1221 
1222             AcpiOsPrintf (UINT8_FORMAT, *Target,
1223                 AcpiDmErstActions[Temp8]);
1224             break;
1225 
1226         case ACPI_DMT_ERSTINST:
1227 
1228             /* ERST Instruction types */
1229 
1230             Temp8 = *Target;
1231             if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
1232             {
1233                 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
1234             }
1235 
1236             AcpiOsPrintf (UINT8_FORMAT, *Target,
1237                 AcpiDmErstInstructions[Temp8]);
1238             break;
1239 
1240         case ACPI_DMT_GTDT:
1241 
1242             /* GTDT subtable types */
1243 
1244             Temp8 = *Target;
1245             if (Temp8 > ACPI_GTDT_TYPE_RESERVED)
1246             {
1247                 Temp8 = ACPI_GTDT_TYPE_RESERVED;
1248             }
1249 
1250             AcpiOsPrintf (UINT8_FORMAT, *Target,
1251                 AcpiDmGtdtSubnames[Temp8]);
1252             break;
1253 
1254         case ACPI_DMT_HEST:
1255 
1256             /* HEST subtable types */
1257 
1258             Temp16 = ACPI_GET16 (Target);
1259             if (Temp16 > ACPI_HEST_TYPE_RESERVED)
1260             {
1261                 Temp16 = ACPI_HEST_TYPE_RESERVED;
1262             }
1263 
1264             AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target),
1265                 AcpiDmHestSubnames[Temp16]);
1266             break;
1267 
1268         case ACPI_DMT_HESTNTFY:
1269 
1270             AcpiOsPrintf (STRING_FORMAT,
1271                 "Hardware Error Notification Structure");
1272 
1273             Status = AcpiDmDumpTable (TableLength, CurrentOffset, Target,
1274                 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
1275             if (ACPI_FAILURE (Status))
1276             {
1277                 return (Status);
1278             }
1279 
1280             AcpiOsPrintf ("\n");
1281             LastOutputBlankLine = TRUE;
1282             break;
1283 
1284         case ACPI_DMT_HESTNTYP:
1285 
1286             /* HEST Notify types */
1287 
1288             Temp8 = *Target;
1289             if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
1290             {
1291                 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
1292             }
1293 
1294             AcpiOsPrintf (UINT8_FORMAT, *Target,
1295                 AcpiDmHestNotifySubnames[Temp8]);
1296             break;
1297 
1298         case ACPI_DMT_IORTMEM:
1299 
1300             AcpiOsPrintf (STRING_FORMAT,
1301                 "IORT Memory Access Properties");
1302 
1303             Status = AcpiDmDumpTable (TableLength, CurrentOffset, Target,
1304                 sizeof (ACPI_IORT_MEMORY_ACCESS), AcpiDmTableInfoIortAcc);
1305             if (ACPI_FAILURE (Status))
1306             {
1307                 return (Status);
1308             }
1309 
1310             LastOutputBlankLine = TRUE;
1311             break;
1312 
1313         case ACPI_DMT_MADT:
1314 
1315             /* MADT subtable types */
1316 
1317             Temp8 = *Target;
1318             if (Temp8 > ACPI_MADT_TYPE_RESERVED)
1319             {
1320                 Temp8 = ACPI_MADT_TYPE_RESERVED;
1321             }
1322 
1323             AcpiOsPrintf (UINT8_FORMAT, *Target,
1324                 AcpiDmMadtSubnames[Temp8]);
1325             break;
1326 
1327         case ACPI_DMT_NFIT:
1328 
1329             /* NFIT subtable types */
1330 
1331             Temp16 = ACPI_GET16 (Target);
1332             if (Temp16 > ACPI_NFIT_TYPE_RESERVED)
1333             {
1334                 Temp16 = ACPI_NFIT_TYPE_RESERVED;
1335             }
1336 
1337             AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target),
1338                 AcpiDmNfitSubnames[Temp16]);
1339             break;
1340 
1341         case ACPI_DMT_PCCT:
1342 
1343             /* PCCT subtable types */
1344 
1345             Temp8 = *Target;
1346             if (Temp8 > ACPI_PCCT_TYPE_RESERVED)
1347             {
1348                 Temp8 = ACPI_PCCT_TYPE_RESERVED;
1349             }
1350 
1351             AcpiOsPrintf (UINT8_FORMAT, *Target,
1352                 AcpiDmPcctSubnames[Temp8]);
1353             break;
1354 
1355         case ACPI_DMT_PMTT:
1356 
1357             /* PMTT subtable types */
1358 
1359             Temp8 = *Target;
1360             if (Temp8 > ACPI_PMTT_TYPE_RESERVED)
1361             {
1362                 Temp8 = ACPI_PMTT_TYPE_RESERVED;
1363             }
1364 
1365             AcpiOsPrintf (UINT8_FORMAT, *Target,
1366                 AcpiDmPmttSubnames[Temp8]);
1367             break;
1368 
1369         case ACPI_DMT_UNICODE:
1370 
1371             if (ByteLength == 0)
1372             {
1373                 AcpiOsPrintf ("/* Zero-length Data */\n");
1374                 break;
1375             }
1376 
1377             AcpiDmDumpUnicode (Table, CurrentOffset, ByteLength);
1378             break;
1379 
1380         case ACPI_DMT_RAW_BUFFER:
1381 
1382             if (ByteLength == 0)
1383             {
1384                 AcpiOsPrintf ("/* Zero-length Data */\n");
1385                 break;
1386             }
1387 
1388             AcpiDmDumpBuffer (Table, CurrentOffset, ByteLength,
1389                 CurrentOffset, NULL);
1390             break;
1391 
1392         case ACPI_DMT_SRAT:
1393 
1394             /* SRAT subtable types */
1395 
1396             Temp8 = *Target;
1397             if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
1398             {
1399                 Temp8 = ACPI_SRAT_TYPE_RESERVED;
1400             }
1401 
1402             AcpiOsPrintf (UINT8_FORMAT, *Target,
1403                 AcpiDmSratSubnames[Temp8]);
1404             break;
1405 
1406         case ACPI_DMT_FADTPM:
1407 
1408             /* FADT Preferred PM Profile names */
1409 
1410             Temp8 = *Target;
1411             if (Temp8 > ACPI_FADT_PM_RESERVED)
1412             {
1413                 Temp8 = ACPI_FADT_PM_RESERVED;
1414             }
1415 
1416             AcpiOsPrintf (UINT8_FORMAT, *Target,
1417                 AcpiDmFadtProfiles[Temp8]);
1418             break;
1419 
1420         case ACPI_DMT_IVRS:
1421 
1422             /* IVRS subtable types */
1423 
1424             Temp8 = *Target;
1425             switch (Temp8)
1426             {
1427             case ACPI_IVRS_TYPE_HARDWARE:
1428 
1429                 Name = AcpiDmIvrsSubnames[0];
1430                 break;
1431 
1432             case ACPI_IVRS_TYPE_MEMORY1:
1433             case ACPI_IVRS_TYPE_MEMORY2:
1434             case ACPI_IVRS_TYPE_MEMORY3:
1435 
1436                 Name = AcpiDmIvrsSubnames[1];
1437                 break;
1438 
1439             default:
1440 
1441                 Name = AcpiDmIvrsSubnames[2];
1442                 break;
1443             }
1444 
1445             AcpiOsPrintf (UINT8_FORMAT, *Target, Name);
1446             break;
1447 
1448         case ACPI_DMT_LPIT:
1449 
1450             /* LPIT subtable types */
1451 
1452             Temp32 = ACPI_GET32 (Target);
1453             if (Temp32 > ACPI_LPIT_TYPE_RESERVED)
1454             {
1455                 Temp32 = ACPI_LPIT_TYPE_RESERVED;
1456             }
1457 
1458             AcpiOsPrintf (UINT32_FORMAT, ACPI_GET32 (Target),
1459                 AcpiDmLpitSubnames[Temp32]);
1460             break;
1461 
1462         case ACPI_DMT_EXIT:
1463 
1464             return (AE_OK);
1465 
1466         default:
1467 
1468             ACPI_ERROR ((AE_INFO,
1469                 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1470             return (AE_SUPPORT);
1471         }
1472     }
1473 
1474     if (TableOffset && !SubtableLength)
1475     {
1476         /*
1477          * If this table is not the main table, the subtable must have a
1478          * valid length
1479          */
1480         AcpiOsPrintf ("Invalid zero length subtable\n");
1481         return (AE_BAD_DATA);
1482     }
1483 
1484     return (AE_OK);
1485 }
1486 
1487 
1488 /*******************************************************************************
1489  *
1490  * FUNCTION:    AcpiDmCheckAscii
1491  *
1492  * PARAMETERS:  Name                - Ascii string
1493  *              Count               - Number of characters to check
1494  *
1495  * RETURN:      None
1496  *
1497  * DESCRIPTION: Ensure that the requested number of characters are printable
1498  *              Ascii characters. Sets non-printable and null chars to <space>.
1499  *
1500  ******************************************************************************/
1501 
1502 static void
1503 AcpiDmCheckAscii (
1504     UINT8                   *Name,
1505     char                    *RepairedName,
1506     UINT32                  Count)
1507 {
1508     UINT32                  i;
1509 
1510 
1511     for (i = 0; i < Count; i++)
1512     {
1513         RepairedName[i] = (char) Name[i];
1514 
1515         if (!Name[i])
1516         {
1517             return;
1518         }
1519         if (!isprint (Name[i]))
1520         {
1521             RepairedName[i] = ' ';
1522         }
1523     }
1524 }
1525