dmtable.c revision 1.1.1.3 1 /******************************************************************************
2 *
3 * Module Name: dmtable - Support for ACPI tables that contain no AML code
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acdisasm.h"
47 #include "actables.h"
48 #include "aslcompiler.h"
49 #include "dtcompiler.h"
50
51 /* This module used for application-level code only */
52
53 #define _COMPONENT ACPI_CA_DISASSEMBLER
54 ACPI_MODULE_NAME ("dmtable")
55
56 /* Local Prototypes */
57
58 static void
59 AcpiDmCheckAscii (
60 UINT8 *Target,
61 char *RepairedName,
62 UINT32 Count);
63
64
65 /* Common format strings for commented values */
66
67 #define UINT8_FORMAT "%2.2X [%s]\n"
68 #define UINT16_FORMAT "%4.4X [%s]\n"
69 #define UINT32_FORMAT "%8.8X [%s]\n"
70 #define STRING_FORMAT "[%s]\n"
71
72 /* These tables map a subtable type to a description string */
73
74 static const char *AcpiDmAsfSubnames[] =
75 {
76 "ASF Information",
77 "ASF Alerts",
78 "ASF Remote Control",
79 "ASF RMCP Boot Options",
80 "ASF Address",
81 "Unknown SubTable Type" /* Reserved */
82 };
83
84 static const char *AcpiDmDmarSubnames[] =
85 {
86 "Hardware Unit Definition",
87 "Reserved Memory Region",
88 "Root Port ATS Capability",
89 "Remapping Hardware Static Affinity",
90 "Unknown SubTable Type" /* Reserved */
91 };
92
93 static const char *AcpiDmEinjActions[] =
94 {
95 "Begin Operation",
96 "Get Trigger Table",
97 "Set Error Type",
98 "Get Error Type",
99 "End Operation",
100 "Execute Operation",
101 "Check Busy Status",
102 "Get Command Status",
103 "Unknown Action"
104 };
105
106 static const char *AcpiDmEinjInstructions[] =
107 {
108 "Read Register",
109 "Read Register Value",
110 "Write Register",
111 "Write Register Value",
112 "Noop",
113 "Unknown Instruction"
114 };
115
116 static const char *AcpiDmErstActions[] =
117 {
118 "Begin Write Operation",
119 "Begin Read Operation",
120 "Begin Clear Operation",
121 "End Operation",
122 "Set Record Offset",
123 "Execute Operation",
124 "Check Busy Status",
125 "Get Command Status",
126 "Get Record Identifier",
127 "Set Record Identifier",
128 "Get Record Count",
129 "Begin Dummy Write",
130 "Unused/Unknown Action",
131 "Get Error Address Range",
132 "Get Error Address Length",
133 "Get Error Attributes",
134 "Unknown Action"
135 };
136
137 static const char *AcpiDmErstInstructions[] =
138 {
139 "Read Register",
140 "Read Register Value",
141 "Write Register",
142 "Write Register Value",
143 "Noop",
144 "Load Var1",
145 "Load Var2",
146 "Store Var1",
147 "Add",
148 "Subtract",
149 "Add Value",
150 "Subtract Value",
151 "Stall",
152 "Stall While True",
153 "Skip Next If True",
154 "GoTo",
155 "Set Source Address",
156 "Set Destination Address",
157 "Move Data",
158 "Unknown Instruction"
159 };
160
161 static const char *AcpiDmHestSubnames[] =
162 {
163 "IA-32 Machine Check Exception",
164 "IA-32 Corrected Machine Check",
165 "IA-32 Non-Maskable Interrupt",
166 "Unknown SubTable Type", /* 3 - Reserved */
167 "Unknown SubTable Type", /* 4 - Reserved */
168 "Unknown SubTable Type", /* 5 - Reserved */
169 "PCI Express Root Port AER",
170 "PCI Express AER (AER Endpoint)",
171 "PCI Express/PCI-X Bridge AER",
172 "Generic Hardware Error Source",
173 "Unknown SubTable Type" /* Reserved */
174 };
175
176 static const char *AcpiDmHestNotifySubnames[] =
177 {
178 "Polled",
179 "External Interrupt",
180 "Local Interrupt",
181 "SCI",
182 "NMI",
183 "Unknown Notify Type" /* Reserved */
184 };
185
186 static const char *AcpiDmMadtSubnames[] =
187 {
188 "Processor Local APIC", /* ACPI_MADT_TYPE_LOCAL_APIC */
189 "I/O APIC", /* ACPI_MADT_TYPE_IO_APIC */
190 "Interrupt Source Override", /* ACPI_MADT_TYPE_INTERRUPT_OVERRIDE */
191 "NMI Source", /* ACPI_MADT_TYPE_NMI_SOURCE */
192 "Local APIC NMI", /* ACPI_MADT_TYPE_LOCAL_APIC_NMI */
193 "Local APIC Address Override", /* ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE */
194 "I/O SAPIC", /* ACPI_MADT_TYPE_IO_SAPIC */
195 "Local SAPIC", /* ACPI_MADT_TYPE_LOCAL_SAPIC */
196 "Platform Interrupt Sources", /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */
197 "Processor Local x2APIC", /* ACPI_MADT_TYPE_LOCAL_X2APIC */
198 "Local x2APIC NMI", /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */
199 "Unknown SubTable Type" /* Reserved */
200 };
201
202 static const char *AcpiDmSlicSubnames[] =
203 {
204 "Public Key Structure",
205 "Windows Marker Structure",
206 "Unknown SubTable Type" /* Reserved */
207 };
208
209 static const char *AcpiDmSratSubnames[] =
210 {
211 "Processor Local APIC/SAPIC Affinity",
212 "Memory Affinity",
213 "Processor Local x2APIC Affinity",
214 "Unknown SubTable Type" /* Reserved */
215 };
216
217 static const char *AcpiDmIvrsSubnames[] =
218 {
219 "Hardware Definition Block",
220 "Memory Definition Block",
221 "Unknown SubTable Type" /* Reserved */
222 };
223
224
225 #define ACPI_FADT_PM_RESERVED 8
226
227 static const char *AcpiDmFadtProfiles[] =
228 {
229 "Unspecified",
230 "Desktop",
231 "Mobile",
232 "Workstation",
233 "Enterprise Server",
234 "SOHO Server",
235 "Appliance PC",
236 "Performance Server",
237 "Unknown Profile Type"
238 };
239
240 #define ACPI_GAS_WIDTH_RESERVED 5
241
242 static const char *AcpiDmGasAccessWidth[] =
243 {
244 "Undefined/Legacy",
245 "Byte Access:8",
246 "Word Access:16",
247 "DWord Access:32",
248 "QWord Access:64",
249 "Unknown Width Encoding"
250 };
251
252
253 /*******************************************************************************
254 *
255 * ACPI Table Data, indexed by signature.
256 *
257 * Each entry contains: Signature, Table Info, Handler, DtHandler,
258 * Template, Description
259 *
260 * Simple tables have only a TableInfo structure, complex tables have a
261 * handler. This table must be NULL terminated. RSDP and FACS are
262 * special-cased elsewhere.
263 *
264 ******************************************************************************/
265
266 ACPI_DMTABLE_DATA AcpiDmTableData[] =
267 {
268 {ACPI_SIG_ASF, NULL, AcpiDmDumpAsf, DtCompileAsf, TemplateAsf, "Alert Standard Format table"},
269 {ACPI_SIG_BOOT, AcpiDmTableInfoBoot, NULL, NULL, TemplateBoot, "Simple Boot Flag Table"},
270 {ACPI_SIG_BERT, AcpiDmTableInfoBert, NULL, NULL, TemplateBert, "Boot Error Record Table"},
271 {ACPI_SIG_CPEP, NULL, AcpiDmDumpCpep, DtCompileCpep, TemplateCpep, "Corrected Platform Error Polling table"},
272 {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp, NULL, NULL, TemplateDbgp, "Debug Port table"},
273 {ACPI_SIG_DMAR, NULL, AcpiDmDumpDmar, DtCompileDmar, TemplateDmar, "DMA Remapping table"},
274 {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt, NULL, NULL, TemplateEcdt, "Embedded Controller Boot Resources Table"},
275 {ACPI_SIG_EINJ, NULL, AcpiDmDumpEinj, DtCompileEinj, TemplateEinj, "Error Injection table"},
276 {ACPI_SIG_ERST, NULL, AcpiDmDumpErst, DtCompileErst, TemplateErst, "Error Record Serialization Table"},
277 {ACPI_SIG_FADT, NULL, AcpiDmDumpFadt, DtCompileFadt, TemplateFadt, "Fixed ACPI Description Table"},
278 {ACPI_SIG_HEST, NULL, AcpiDmDumpHest, DtCompileHest, TemplateHest, "Hardware Error Source Table"},
279 {ACPI_SIG_HPET, AcpiDmTableInfoHpet, NULL, NULL, TemplateHpet, "High Precision Event Timer table"},
280 {ACPI_SIG_IVRS, NULL, AcpiDmDumpIvrs, DtCompileIvrs, TemplateIvrs, "I/O Virtualization Reporting Structure"},
281 {ACPI_SIG_MADT, NULL, AcpiDmDumpMadt, DtCompileMadt, TemplateMadt, "Multiple APIC Description Table"},
282 {ACPI_SIG_MCFG, NULL, AcpiDmDumpMcfg, DtCompileMcfg, TemplateMcfg, "Memory Mapped Configuration table"},
283 {ACPI_SIG_MCHI, AcpiDmTableInfoMchi, NULL, NULL, TemplateMchi, "Management Controller Host Interface table"},
284 {ACPI_SIG_MSCT, NULL, AcpiDmDumpMsct, DtCompileMsct, TemplateMsct, "Maximum System Characteristics Table"},
285 {ACPI_SIG_RSDT, NULL, AcpiDmDumpRsdt, DtCompileRsdt, TemplateRsdt, "Root System Description Table"},
286 {ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, NULL, TemplateSbst, "Smart Battery Specification Table"},
287 {ACPI_SIG_SLIC, NULL, AcpiDmDumpSlic, DtCompileSlic, TemplateSlic, "Software Licensing Description Table"},
288 {ACPI_SIG_SLIT, NULL, AcpiDmDumpSlit, DtCompileSlit, TemplateSlit, "System Locality Information Table"},
289 {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr, NULL, NULL, TemplateSpcr, "Serial Port Console Redirection table"},
290 {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi, NULL, NULL, TemplateSpmi, "Server Platform Management Interface table"},
291 {ACPI_SIG_SRAT, NULL, AcpiDmDumpSrat, DtCompileSrat, TemplateSrat, "System Resource Affinity Table"},
292 {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa, NULL, NULL, TemplateTcpa, "Trusted Computing Platform Alliance table"},
293 {ACPI_SIG_UEFI, AcpiDmTableInfoUefi, NULL, DtCompileUefi, TemplateUefi, "UEFI Boot Optimization Table"},
294 {ACPI_SIG_WAET, AcpiDmTableInfoWaet, NULL, NULL, TemplateWaet, "Windows ACPI Emulated Devices Table"},
295 {ACPI_SIG_WDAT, NULL, AcpiDmDumpWdat, DtCompileWdat, TemplateWdat, "Watchdog Action Table"},
296 {ACPI_SIG_WDDT, AcpiDmTableInfoWddt, NULL, NULL, TemplateWddt, "Watchdog Description Table"},
297 {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt, NULL, NULL, TemplateWdrt, "Watchdog Resource Table"},
298 {ACPI_SIG_XSDT, NULL, AcpiDmDumpXsdt, DtCompileXsdt, TemplateXsdt, "Extended System Description Table"},
299 {NULL, NULL, NULL, NULL, NULL, NULL}
300 };
301
302
303 /*******************************************************************************
304 *
305 * FUNCTION: AcpiDmGenerateChecksum
306 *
307 * PARAMETERS: Table - Pointer to table to be checksummed
308 * Length - Length of the table
309 * OriginalChecksum - Value of the checksum field
310 *
311 * RETURN: 8 bit checksum of buffer
312 *
313 * DESCRIPTION: Computes an 8 bit checksum of the table.
314 *
315 ******************************************************************************/
316
317 UINT8
318 AcpiDmGenerateChecksum (
319 void *Table,
320 UINT32 Length,
321 UINT8 OriginalChecksum)
322 {
323 UINT8 Checksum;
324
325
326 /* Sum the entire table as-is */
327
328 Checksum = AcpiTbChecksum ((UINT8 *) Table, Length);
329
330 /* Subtract off the existing checksum value in the table */
331
332 Checksum = (UINT8) (Checksum - OriginalChecksum);
333
334 /* Compute the final checksum */
335
336 Checksum = (UINT8) (0 - Checksum);
337 return (Checksum);
338 }
339
340
341 /*******************************************************************************
342 *
343 * FUNCTION: AcpiDmGetTableData
344 *
345 * PARAMETERS: Signature - ACPI signature (4 chars) to match
346 *
347 * RETURN: Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found.
348 *
349 * DESCRIPTION: Find a match in the global table of supported ACPI tables
350 *
351 ******************************************************************************/
352
353 ACPI_DMTABLE_DATA *
354 AcpiDmGetTableData (
355 char *Signature)
356 {
357 ACPI_DMTABLE_DATA *TableData;
358
359
360 for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
361 {
362 if (ACPI_COMPARE_NAME (Signature, TableData->Signature))
363 {
364 return (TableData);
365 }
366 }
367
368 return (NULL);
369 }
370
371
372 /*******************************************************************************
373 *
374 * FUNCTION: AcpiDmDumpDataTable
375 *
376 * PARAMETERS: Table - An ACPI table
377 *
378 * RETURN: None.
379 *
380 * DESCRIPTION: Format the contents of an ACPI data table (any table other
381 * than an SSDT or DSDT that does not contain executable AML code)
382 *
383 ******************************************************************************/
384
385 void
386 AcpiDmDumpDataTable (
387 ACPI_TABLE_HEADER *Table)
388 {
389 ACPI_STATUS Status;
390 ACPI_DMTABLE_DATA *TableData;
391 UINT32 Length;
392
393
394 /* Ignore tables that contain AML */
395
396 if (AcpiUtIsAmlTable (Table))
397 {
398 return;
399 }
400
401 /*
402 * Handle tables that don't use the common ACPI table header structure.
403 * Currently, these are the FACS and RSDP.
404 */
405 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
406 {
407 Length = Table->Length;
408 AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
409 }
410 else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
411 {
412 Length = AcpiDmDumpRsdp (Table);
413 }
414 else
415 {
416 /*
417 * All other tables must use the common ACPI table header, dump it now
418 */
419 Length = Table->Length;
420 Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader);
421 if (ACPI_FAILURE (Status))
422 {
423 return;
424 }
425 AcpiOsPrintf ("\n");
426
427 /* Match signature and dispatch appropriately */
428
429 TableData = AcpiDmGetTableData (Table->Signature);
430 if (!TableData)
431 {
432 if (!ACPI_STRNCMP (Table->Signature, "OEM", 3))
433 {
434 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n",
435 Table->Signature);
436 }
437 else
438 {
439 AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n",
440 Table->Signature);
441 }
442 }
443 else if (TableData->TableHandler)
444 {
445 /* Complex table, has a handler */
446
447 TableData->TableHandler (Table);
448 }
449 else if (TableData->TableInfo)
450 {
451 /* Simple table, just walk the info table */
452
453 AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo);
454 }
455 }
456
457 if (!Gbl_DoTemplates || Gbl_VerboseTemplates)
458 {
459 /* Dump the raw table data */
460
461 AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
462 ACPI_RAW_TABLE_DATA_HEADER, Length, Length);
463 AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY);
464 }
465 }
466
467
468 /*******************************************************************************
469 *
470 * FUNCTION: AcpiDmLineHeader
471 *
472 * PARAMETERS: Offset - Current byte offset, from table start
473 * ByteLength - Length of the field in bytes, 0 for flags
474 * Name - Name of this field
475 * Value - Optional value, displayed on left of ':'
476 *
477 * RETURN: None
478 *
479 * DESCRIPTION: Utility routines for formatting output lines. Displays the
480 * current table offset in hex and decimal, the field length,
481 * and the field name.
482 *
483 ******************************************************************************/
484
485 void
486 AcpiDmLineHeader (
487 UINT32 Offset,
488 UINT32 ByteLength,
489 char *Name)
490 {
491
492 /* Allow a null name for fields that span multiple lines (large buffers) */
493
494 if (!Name)
495 {
496 Name = "";
497 }
498
499 if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
500 {
501 if (ByteLength)
502 {
503 AcpiOsPrintf ("[%.4d] %34s : ", ByteLength, Name);
504 }
505 else
506 {
507 if (*Name)
508 {
509 AcpiOsPrintf ("%41s : ", Name);
510 }
511 else
512 {
513 AcpiOsPrintf ("%41s ", Name);
514 }
515 }
516 }
517 else /* Normal disassembler or verbose template */
518 {
519 if (ByteLength)
520 {
521 AcpiOsPrintf ("[%3.3Xh %4.4d% 4d] %28s : ",
522 Offset, Offset, ByteLength, Name);
523 }
524 else
525 {
526 if (*Name)
527 {
528 AcpiOsPrintf ("%44s : ", Name);
529 }
530 else
531 {
532 AcpiOsPrintf ("%44s ", Name);
533 }
534 }
535 }
536 }
537
538 void
539 AcpiDmLineHeader2 (
540 UINT32 Offset,
541 UINT32 ByteLength,
542 char *Name,
543 UINT32 Value)
544 {
545
546 if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */
547 {
548 if (ByteLength)
549 {
550 AcpiOsPrintf ("[%.4d] %30s %3d : ",
551 ByteLength, Name, Value);
552 }
553 else
554 {
555 AcpiOsPrintf ("%36s % 3d : ",
556 Name, Value);
557 }
558 }
559 else /* Normal disassembler or verbose template */
560 {
561 if (ByteLength)
562 {
563 AcpiOsPrintf ("[%3.3Xh %4.4d %3d] %24s %3d : ",
564 Offset, Offset, ByteLength, Name, Value);
565 }
566 else
567 {
568 AcpiOsPrintf ("[%3.3Xh %4.4d ] %24s %3d : ",
569 Offset, Offset, Name, Value);
570 }
571 }
572 }
573
574
575 /*******************************************************************************
576 *
577 * FUNCTION: AcpiDmDumpTable
578 *
579 * PARAMETERS: TableLength - Length of the entire ACPI table
580 * TableOffset - Starting offset within the table for this
581 * sub-descriptor (0 if main table)
582 * Table - The ACPI table
583 * SubtableLength - Length of this sub-descriptor
584 * Info - Info table for this ACPI table
585 *
586 * RETURN: None
587 *
588 * DESCRIPTION: Display ACPI table contents by walking the Info table.
589 *
590 * Note: This function must remain in sync with DtGetFieldLength.
591 *
592 ******************************************************************************/
593
594 ACPI_STATUS
595 AcpiDmDumpTable (
596 UINT32 TableLength,
597 UINT32 TableOffset,
598 void *Table,
599 UINT32 SubtableLength,
600 ACPI_DMTABLE_INFO *Info)
601 {
602 UINT8 *Target;
603 UINT32 CurrentOffset;
604 UINT32 ByteLength;
605 UINT8 Temp8;
606 UINT16 Temp16;
607 ACPI_DMTABLE_DATA *TableData;
608 const char *Name;
609 BOOLEAN LastOutputBlankLine = FALSE;
610 char RepairedName[8];
611
612
613 if (!Info)
614 {
615 AcpiOsPrintf ("Display not implemented\n");
616 return (AE_NOT_IMPLEMENTED);
617 }
618
619 /* Walk entire Info table; Null name terminates */
620
621 for (; Info->Name; Info++)
622 {
623 /*
624 * Target points to the field within the ACPI Table. CurrentOffset is
625 * the offset of the field from the start of the main table.
626 */
627 Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset);
628 CurrentOffset = TableOffset + Info->Offset;
629
630 /* Check for beyond EOT or beyond subtable end */
631
632 if ((CurrentOffset >= TableLength) ||
633 (SubtableLength && (Info->Offset >= SubtableLength)))
634 {
635 AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
636 return (AE_BAD_DATA);
637 }
638
639 /* Generate the byte length for this field */
640
641 switch (Info->Opcode)
642 {
643 case ACPI_DMT_UINT8:
644 case ACPI_DMT_CHKSUM:
645 case ACPI_DMT_SPACEID:
646 case ACPI_DMT_ACCWIDTH:
647 case ACPI_DMT_IVRS:
648 case ACPI_DMT_MADT:
649 case ACPI_DMT_SRAT:
650 case ACPI_DMT_ASF:
651 case ACPI_DMT_HESTNTYP:
652 case ACPI_DMT_FADTPM:
653 case ACPI_DMT_EINJACT:
654 case ACPI_DMT_EINJINST:
655 case ACPI_DMT_ERSTACT:
656 case ACPI_DMT_ERSTINST:
657 ByteLength = 1;
658 break;
659 case ACPI_DMT_UINT16:
660 case ACPI_DMT_DMAR:
661 case ACPI_DMT_HEST:
662 ByteLength = 2;
663 break;
664 case ACPI_DMT_UINT24:
665 ByteLength = 3;
666 break;
667 case ACPI_DMT_UINT32:
668 case ACPI_DMT_NAME4:
669 case ACPI_DMT_SIG:
670 case ACPI_DMT_SLIC:
671 ByteLength = 4;
672 break;
673 case ACPI_DMT_NAME6:
674 ByteLength = 6;
675 break;
676 case ACPI_DMT_UINT56:
677 case ACPI_DMT_BUF7:
678 ByteLength = 7;
679 break;
680 case ACPI_DMT_UINT64:
681 case ACPI_DMT_NAME8:
682 ByteLength = 8;
683 break;
684 case ACPI_DMT_BUF16:
685 case ACPI_DMT_UUID:
686 ByteLength = 16;
687 break;
688 case ACPI_DMT_BUF128:
689 ByteLength = 128;
690 break;
691 case ACPI_DMT_STRING:
692 ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1;
693 break;
694 case ACPI_DMT_GAS:
695 if (!LastOutputBlankLine)
696 {
697 AcpiOsPrintf ("\n");
698 LastOutputBlankLine = TRUE;
699 }
700 ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
701 break;
702 case ACPI_DMT_HESTNTFY:
703 if (!LastOutputBlankLine)
704 {
705 AcpiOsPrintf ("\n");
706 LastOutputBlankLine = TRUE;
707 }
708 ByteLength = sizeof (ACPI_HEST_NOTIFY);
709 break;
710 default:
711 ByteLength = 0;
712 break;
713 }
714
715 if (CurrentOffset + ByteLength > TableLength)
716 {
717 AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n");
718 return (AE_BAD_DATA);
719 }
720
721 /* Start a new line and decode the opcode */
722
723 AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name);
724
725 switch (Info->Opcode)
726 {
727 /* Single-bit Flag fields. Note: Opcode is the bit position */
728
729 case ACPI_DMT_FLAG0:
730 case ACPI_DMT_FLAG1:
731 case ACPI_DMT_FLAG2:
732 case ACPI_DMT_FLAG3:
733 case ACPI_DMT_FLAG4:
734 case ACPI_DMT_FLAG5:
735 case ACPI_DMT_FLAG6:
736 case ACPI_DMT_FLAG7:
737
738 AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01);
739 break;
740
741 /* 2-bit Flag fields */
742
743 case ACPI_DMT_FLAGS0:
744
745 AcpiOsPrintf ("%1.1X\n", *Target & 0x03);
746 break;
747
748 case ACPI_DMT_FLAGS2:
749
750 AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03);
751 break;
752
753 /* Standard Data Types */
754
755 case ACPI_DMT_UINT8:
756
757 AcpiOsPrintf ("%2.2X\n", *Target);
758 break;
759
760 case ACPI_DMT_UINT16:
761
762 AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target));
763 break;
764
765 case ACPI_DMT_UINT24:
766
767 AcpiOsPrintf ("%2.2X%2.2X%2.2X\n",
768 *Target, *(Target + 1), *(Target + 2));
769 break;
770
771 case ACPI_DMT_UINT32:
772
773 AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target));
774 break;
775
776 case ACPI_DMT_UINT56:
777
778 for (Temp8 = 0; Temp8 < 7; Temp8++)
779 {
780 AcpiOsPrintf ("%2.2X", Target[Temp8]);
781 }
782 AcpiOsPrintf ("\n");
783 break;
784
785 case ACPI_DMT_UINT64:
786
787 AcpiOsPrintf ("%8.8X%8.8X\n",
788 ACPI_FORMAT_UINT64 (ACPI_GET64 (Target)));
789 break;
790
791 case ACPI_DMT_BUF7:
792 case ACPI_DMT_BUF16:
793 case ACPI_DMT_BUF128:
794
795 /*
796 * Buffer: Size depends on the opcode and was set above.
797 * Each hex byte is separated with a space.
798 * Multiple lines are separated by line continuation char.
799 */
800 for (Temp16 = 0; Temp16 < ByteLength; Temp16++)
801 {
802 AcpiOsPrintf ("%2.2X", Target[Temp16]);
803 if ((UINT32) (Temp16 + 1) < ByteLength)
804 {
805 if ((Temp16 > 0) && (!((Temp16+1) % 16)))
806 {
807 AcpiOsPrintf (" \\\n"); /* Line continuation */
808 AcpiDmLineHeader (0, 0, NULL);
809 }
810 else
811 {
812 AcpiOsPrintf (" ");
813 }
814 }
815 }
816 AcpiOsPrintf ("\n");
817 break;
818
819 case ACPI_DMT_UUID:
820
821 /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */
822
823 (void) AuConvertUuidToString ((char *) Target, MsgBuffer);
824
825 AcpiOsPrintf ("%s\n", MsgBuffer);
826 break;
827
828 case ACPI_DMT_STRING:
829
830 AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target));
831 break;
832
833 /* Fixed length ASCII name fields */
834
835 case ACPI_DMT_SIG:
836
837 AcpiDmCheckAscii (Target, RepairedName, 4);
838 AcpiOsPrintf ("\"%.4s\" ", RepairedName);
839 TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target));
840 if (TableData)
841 {
842 AcpiOsPrintf (STRING_FORMAT, TableData->Name);
843 }
844 else
845 {
846 AcpiOsPrintf ("\n");
847 }
848 break;
849
850 case ACPI_DMT_NAME4:
851
852 AcpiDmCheckAscii (Target, RepairedName, 4);
853 AcpiOsPrintf ("\"%.4s\"\n", RepairedName);
854 break;
855
856 case ACPI_DMT_NAME6:
857
858 AcpiDmCheckAscii (Target, RepairedName, 6);
859 AcpiOsPrintf ("\"%.6s\"\n", RepairedName);
860 break;
861
862 case ACPI_DMT_NAME8:
863
864 AcpiDmCheckAscii (Target, RepairedName, 8);
865 AcpiOsPrintf ("\"%.8s\"\n", RepairedName);
866 break;
867
868 /* Special Data Types */
869
870 case ACPI_DMT_CHKSUM:
871
872 /* Checksum, display and validate */
873
874 AcpiOsPrintf ("%2.2X", *Target);
875 Temp8 = AcpiDmGenerateChecksum (Table,
876 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length,
877 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum);
878 if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum)
879 {
880 AcpiOsPrintf (
881 " /* Incorrect checksum, should be %2.2X */", Temp8);
882 }
883 AcpiOsPrintf ("\n");
884 break;
885
886 case ACPI_DMT_SPACEID:
887
888 /* Address Space ID */
889
890 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiUtGetRegionName (*Target));
891 break;
892
893 case ACPI_DMT_ACCWIDTH:
894
895 /* Encoded Access Width */
896
897 Temp8 = *Target;
898 if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
899 {
900 Temp8 = ACPI_GAS_WIDTH_RESERVED;
901 }
902
903 AcpiOsPrintf (UINT8_FORMAT, Temp8, AcpiDmGasAccessWidth[Temp8]);
904 break;
905
906 case ACPI_DMT_GAS:
907
908 /* Generic Address Structure */
909
910 AcpiOsPrintf (STRING_FORMAT, "Generic Address Structure");
911 AcpiDmDumpTable (TableLength, CurrentOffset, Target,
912 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas);
913 AcpiOsPrintf ("\n");
914 LastOutputBlankLine = TRUE;
915 break;
916
917 case ACPI_DMT_ASF:
918
919 /* ASF subtable types */
920
921 Temp16 = (UINT16) ((*Target) & 0x7F); /* Top bit can be zero or one */
922 if (Temp16 > ACPI_ASF_TYPE_RESERVED)
923 {
924 Temp16 = ACPI_ASF_TYPE_RESERVED;
925 }
926
927 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmAsfSubnames[Temp16]);
928 break;
929
930 case ACPI_DMT_DMAR:
931
932 /* DMAR subtable types */
933
934 Temp16 = ACPI_GET16 (Target);
935 if (Temp16 > ACPI_DMAR_TYPE_RESERVED)
936 {
937 Temp16 = ACPI_DMAR_TYPE_RESERVED;
938 }
939
940 AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]);
941 break;
942
943 case ACPI_DMT_EINJACT:
944
945 /* EINJ Action types */
946
947 Temp8 = *Target;
948 if (Temp8 > ACPI_EINJ_ACTION_RESERVED)
949 {
950 Temp8 = ACPI_EINJ_ACTION_RESERVED;
951 }
952
953 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjActions[Temp8]);
954 break;
955
956 case ACPI_DMT_EINJINST:
957
958 /* EINJ Instruction types */
959
960 Temp8 = *Target;
961 if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED)
962 {
963 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED;
964 }
965
966 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjInstructions[Temp8]);
967 break;
968
969 case ACPI_DMT_ERSTACT:
970
971 /* ERST Action types */
972
973 Temp8 = *Target;
974 if (Temp8 > ACPI_ERST_ACTION_RESERVED)
975 {
976 Temp8 = ACPI_ERST_ACTION_RESERVED;
977 }
978
979 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstActions[Temp8]);
980 break;
981
982 case ACPI_DMT_ERSTINST:
983
984 /* ERST Instruction types */
985
986 Temp8 = *Target;
987 if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED)
988 {
989 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED;
990 }
991
992 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstInstructions[Temp8]);
993 break;
994
995 case ACPI_DMT_HEST:
996
997 /* HEST subtable types */
998
999 Temp16 = ACPI_GET16 (Target);
1000 if (Temp16 > ACPI_HEST_TYPE_RESERVED)
1001 {
1002 Temp16 = ACPI_HEST_TYPE_RESERVED;
1003 }
1004
1005 AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]);
1006 break;
1007
1008 case ACPI_DMT_HESTNTFY:
1009
1010 AcpiOsPrintf (STRING_FORMAT, "Hardware Error Notification Structure");
1011 AcpiDmDumpTable (TableLength, CurrentOffset, Target,
1012 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify);
1013 AcpiOsPrintf ("\n");
1014 LastOutputBlankLine = TRUE;
1015 break;
1016
1017 case ACPI_DMT_HESTNTYP:
1018
1019 /* HEST Notify types */
1020
1021 Temp8 = *Target;
1022 if (Temp8 > ACPI_HEST_NOTIFY_RESERVED)
1023 {
1024 Temp8 = ACPI_HEST_NOTIFY_RESERVED;
1025 }
1026
1027 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmHestNotifySubnames[Temp8]);
1028 break;
1029
1030 case ACPI_DMT_MADT:
1031
1032 /* MADT subtable types */
1033
1034 Temp8 = *Target;
1035 if (Temp8 > ACPI_MADT_TYPE_RESERVED)
1036 {
1037 Temp8 = ACPI_MADT_TYPE_RESERVED;
1038 }
1039
1040 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmMadtSubnames[Temp8]);
1041 break;
1042
1043 case ACPI_DMT_SLIC:
1044
1045 /* SLIC subtable types */
1046
1047 Temp8 = *Target;
1048 if (Temp8 > ACPI_SLIC_TYPE_RESERVED)
1049 {
1050 Temp8 = ACPI_SLIC_TYPE_RESERVED;
1051 }
1052
1053 AcpiOsPrintf (UINT32_FORMAT, *Target, AcpiDmSlicSubnames[Temp8]);
1054 break;
1055
1056 case ACPI_DMT_SRAT:
1057
1058 /* SRAT subtable types */
1059
1060 Temp8 = *Target;
1061 if (Temp8 > ACPI_SRAT_TYPE_RESERVED)
1062 {
1063 Temp8 = ACPI_SRAT_TYPE_RESERVED;
1064 }
1065
1066 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmSratSubnames[Temp8]);
1067 break;
1068
1069 case ACPI_DMT_FADTPM:
1070
1071 /* FADT Preferred PM Profile names */
1072
1073 Temp8 = *Target;
1074 if (Temp8 > ACPI_FADT_PM_RESERVED)
1075 {
1076 Temp8 = ACPI_FADT_PM_RESERVED;
1077 }
1078
1079 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmFadtProfiles[Temp8]);
1080 break;
1081
1082 case ACPI_DMT_IVRS:
1083
1084 /* IVRS subtable types */
1085
1086 Temp8 = *Target;
1087 switch (Temp8)
1088 {
1089 case ACPI_IVRS_TYPE_HARDWARE:
1090 Name = AcpiDmIvrsSubnames[0];
1091 break;
1092
1093 case ACPI_IVRS_TYPE_MEMORY1:
1094 case ACPI_IVRS_TYPE_MEMORY2:
1095 case ACPI_IVRS_TYPE_MEMORY3:
1096 Name = AcpiDmIvrsSubnames[1];
1097 break;
1098
1099 default:
1100 Name = AcpiDmIvrsSubnames[2];
1101 break;
1102 }
1103
1104 AcpiOsPrintf (UINT8_FORMAT, *Target, Name);
1105 break;
1106
1107 case ACPI_DMT_EXIT:
1108 return (AE_OK);
1109
1110 default:
1111 ACPI_ERROR ((AE_INFO,
1112 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode));
1113 return (AE_SUPPORT);
1114 }
1115 }
1116
1117 if (TableOffset && !SubtableLength)
1118 {
1119 /* If this table is not the main table, subtable must have valid length */
1120
1121 AcpiOsPrintf ("Invalid zero length subtable\n");
1122 return (AE_BAD_DATA);
1123 }
1124
1125 return (AE_OK);
1126 }
1127
1128
1129 /*******************************************************************************
1130 *
1131 * FUNCTION: AcpiDmCheckAscii
1132 *
1133 * PARAMETERS: Name - Ascii string
1134 * Count - Number of characters to check
1135 *
1136 * RETURN: None
1137 *
1138 * DESCRIPTION: Ensure that the requested number of characters are printable
1139 * Ascii characters. Sets non-printable and null chars to <space>.
1140 *
1141 ******************************************************************************/
1142
1143 static void
1144 AcpiDmCheckAscii (
1145 UINT8 *Name,
1146 char *RepairedName,
1147 UINT32 Count)
1148 {
1149 UINT32 i;
1150
1151
1152 for (i = 0; i < Count; i++)
1153 {
1154 RepairedName[i] = (char) Name[i];
1155
1156 if (!Name[i])
1157 {
1158 return;
1159 }
1160 if (!isprint (Name[i]))
1161 {
1162 RepairedName[i] = ' ';
1163 }
1164 }
1165 }
1166