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