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