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