1/******************************************************************************
2 *
3 * Module Name: dmtbdump - Dump ACPI data tables that contain no AML code
4 *
5 *****************************************************************************/
6
7/******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2020, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************
115 *
116 * Alternatively, you may choose to be licensed under the terms of the
117 * following license:
118 *
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
121 * are met:
122 * 1. Redistributions of source code must retain the above copyright
123 *    notice, this list of conditions, and the following disclaimer,
124 *    without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 *    substantially similar to the "NO WARRANTY" disclaimer below
127 *    ("Disclaimer") and any redistribution must be conditioned upon
128 *    including a substantially similar Disclaimer requirement for further
129 *    binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 *    of any contributors may be used to endorse or promote products derived
132 *    from this software without specific prior written permission.
133 *
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145 *
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
149 *
150 *****************************************************************************/
151
152#include <contrib/dev/acpica/include/acpi.h>
153#include <contrib/dev/acpica/include/accommon.h>
154#include <contrib/dev/acpica/include/acdisasm.h>
155#include <contrib/dev/acpica/include/actables.h>
156
157/* This module used for application-level code only */
158
159#define _COMPONENT          ACPI_CA_DISASSEMBLER
160        ACPI_MODULE_NAME    ("dmtbdump")
161
162
163/* Local prototypes */
164
165static void
166AcpiDmValidateFadtLength (
167    UINT32                  Revision,
168    UINT32                  Length);
169
170
171/*******************************************************************************
172 *
173 * FUNCTION:    AcpiDmDumpBuffer
174 *
175 * PARAMETERS:  Table               - ACPI Table or subtable
176 *              BufferOffset        - Offset of buffer from Table above
177 *              Length              - Length of the buffer
178 *              AbsoluteOffset      - Offset of buffer in the main ACPI table
179 *              Header              - Name of the buffer field (printed on the
180 *                                    first line only.)
181 *
182 * RETURN:      None
183 *
184 * DESCRIPTION: Format the contents of an arbitrary length data buffer (in the
185 *              disassembler output format.)
186 *
187 ******************************************************************************/
188
189void
190AcpiDmDumpBuffer (
191    void                    *Table,
192    UINT32                  BufferOffset,
193    UINT32                  Length,
194    UINT32                  AbsoluteOffset,
195    char                    *Header)
196{
197    UINT8                   *Buffer;
198    UINT32                  i;
199
200
201    if (!Length)
202    {
203        return;
204    }
205
206    Buffer = ACPI_CAST_PTR (UINT8, Table) + BufferOffset;
207    i = 0;
208
209    while (i < Length)
210    {
211        if (!(i % 16))
212        {
213            /* Insert a backslash - line continuation character */
214
215            if (Length > 16)
216            {
217                AcpiOsPrintf ("\\\n    ");
218            }
219        }
220
221        AcpiOsPrintf ("%.02X ", *Buffer);
222        i++;
223        Buffer++;
224        AbsoluteOffset++;
225    }
226
227    AcpiOsPrintf ("\n");
228}
229
230
231/*******************************************************************************
232 *
233 * FUNCTION:    AcpiDmDumpUnicode
234 *
235 * PARAMETERS:  Table               - ACPI Table or subtable
236 *              BufferOffset        - Offset of buffer from Table above
237 *              ByteLength          - Length of the buffer
238 *
239 * RETURN:      None
240 *
241 * DESCRIPTION: Validate and dump the contents of a buffer that contains
242 *              unicode data. The output is a standard ASCII string. If it
243 *              appears that the data is not unicode, the buffer is dumped
244 *              as hex characters.
245 *
246 ******************************************************************************/
247
248void
249AcpiDmDumpUnicode (
250    void                    *Table,
251    UINT32                  BufferOffset,
252    UINT32                  ByteLength)
253{
254    UINT8                   *Buffer;
255    UINT32                  Length;
256    UINT32                  i;
257
258
259    Buffer = ((UINT8 *) Table) + BufferOffset;
260    Length = ByteLength - 2; /* Last two bytes are the null terminator */
261
262    /* Ensure all low bytes are entirely printable ASCII */
263
264    for (i = 0; i < Length; i += 2)
265    {
266        if (!isprint (Buffer[i]))
267        {
268            goto DumpRawBuffer;
269        }
270    }
271
272    /* Ensure all high bytes are zero */
273
274    for (i = 1; i < Length; i += 2)
275    {
276        if (Buffer[i])
277        {
278            goto DumpRawBuffer;
279        }
280    }
281
282    /* Dump the buffer as a normal string */
283
284    AcpiOsPrintf ("\"");
285    for (i = 0; i < Length; i += 2)
286    {
287        AcpiOsPrintf ("%c", Buffer[i]);
288    }
289
290    AcpiOsPrintf ("\"\n");
291    return;
292
293DumpRawBuffer:
294    AcpiDmDumpBuffer (Table, BufferOffset, ByteLength,
295        BufferOffset, NULL);
296    AcpiOsPrintf ("\n");
297}
298
299
300/*******************************************************************************
301 *
302 * FUNCTION:    AcpiDmDumpRsdp
303 *
304 * PARAMETERS:  Table               - A RSDP
305 *
306 * RETURN:      Length of the table (there is not always a length field,
307 *              use revision or length if available (ACPI 2.0+))
308 *
309 * DESCRIPTION: Format the contents of a RSDP
310 *
311 ******************************************************************************/
312
313UINT32
314AcpiDmDumpRsdp (
315    ACPI_TABLE_HEADER       *Table)
316{
317    ACPI_TABLE_RSDP         *Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table);
318    UINT32                  Length = sizeof (ACPI_RSDP_COMMON);
319    UINT8                   Checksum;
320    ACPI_STATUS             Status;
321
322
323    /* Dump the common ACPI 1.0 portion */
324
325    Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp1);
326    if (ACPI_FAILURE (Status))
327    {
328        return (Length);
329    }
330
331    /* Validate the first checksum */
332
333    Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_RSDP_COMMON),
334        Rsdp->Checksum);
335    if (Checksum != Rsdp->Checksum)
336    {
337        AcpiOsPrintf ("/* Incorrect Checksum above, should be 0x%2.2X */\n",
338            Checksum);
339    }
340
341    /* The RSDP for ACPI 2.0+ contains more data and has a Length field */
342
343    if (Rsdp->Revision > 0)
344    {
345        Length = Rsdp->Length;
346        Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp2);
347        if (ACPI_FAILURE (Status))
348        {
349            return (Length);
350        }
351
352        /* Validate the extended checksum over entire RSDP */
353
354        Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_TABLE_RSDP),
355            Rsdp->ExtendedChecksum);
356        if (Checksum != Rsdp->ExtendedChecksum)
357        {
358            AcpiOsPrintf (
359                "/* Incorrect Extended Checksum above, should be 0x%2.2X */\n",
360                Checksum);
361        }
362    }
363
364    return (Length);
365}
366
367
368/*******************************************************************************
369 *
370 * FUNCTION:    AcpiDmDumpRsdt
371 *
372 * PARAMETERS:  Table               - A RSDT
373 *
374 * RETURN:      None
375 *
376 * DESCRIPTION: Format the contents of a RSDT
377 *
378 ******************************************************************************/
379
380void
381AcpiDmDumpRsdt (
382    ACPI_TABLE_HEADER       *Table)
383{
384    UINT32                  *Array;
385    UINT32                  Entries;
386    UINT32                  Offset;
387    UINT32                  i;
388
389
390    /* Point to start of table pointer array */
391
392    Array = ACPI_CAST_PTR (ACPI_TABLE_RSDT, Table)->TableOffsetEntry;
393    Offset = sizeof (ACPI_TABLE_HEADER);
394
395    /* RSDT uses 32-bit pointers */
396
397    Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT32);
398
399    for (i = 0; i < Entries; i++)
400    {
401        AcpiDmLineHeader2 (Offset, sizeof (UINT32), "ACPI Table Address", i);
402        AcpiOsPrintf ("%8.8X\n", Array[i]);
403        Offset += sizeof (UINT32);
404    }
405}
406
407
408/*******************************************************************************
409 *
410 * FUNCTION:    AcpiDmDumpXsdt
411 *
412 * PARAMETERS:  Table               - A XSDT
413 *
414 * RETURN:      None
415 *
416 * DESCRIPTION: Format the contents of a XSDT
417 *
418 ******************************************************************************/
419
420void
421AcpiDmDumpXsdt (
422    ACPI_TABLE_HEADER       *Table)
423{
424    UINT64                  *Array;
425    UINT32                  Entries;
426    UINT32                  Offset;
427    UINT32                  i;
428
429
430    /* Point to start of table pointer array */
431
432    Array = ACPI_CAST_PTR (ACPI_TABLE_XSDT, Table)->TableOffsetEntry;
433    Offset = sizeof (ACPI_TABLE_HEADER);
434
435    /* XSDT uses 64-bit pointers */
436
437    Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT64);
438
439    for (i = 0; i < Entries; i++)
440    {
441        AcpiDmLineHeader2 (Offset, sizeof (UINT64), "ACPI Table Address", i);
442        AcpiOsPrintf ("%8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Array[i]));
443        Offset += sizeof (UINT64);
444    }
445}
446
447
448/*******************************************************************************
449 *
450 * FUNCTION:    AcpiDmDumpFadt
451 *
452 * PARAMETERS:  Table               - A FADT
453 *
454 * RETURN:      None
455 *
456 * DESCRIPTION: Format the contents of a FADT
457 *
458 * NOTE:        We cannot depend on the FADT version to indicate the actual
459 *              contents of the FADT because of BIOS bugs. The table length
460 *              is the only reliable indicator.
461 *
462 ******************************************************************************/
463
464void
465AcpiDmDumpFadt (
466    ACPI_TABLE_HEADER       *Table)
467{
468    ACPI_STATUS             Status;
469
470
471    /* Always dump the minimum FADT revision 1 fields (ACPI 1.0) */
472
473    Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
474        AcpiDmTableInfoFadt1);
475    if (ACPI_FAILURE (Status))
476    {
477        return;
478    }
479
480    /* Check for FADT revision 2 fields (ACPI 1.0B MS extensions) */
481
482    if ((Table->Length > ACPI_FADT_V1_SIZE) &&
483        (Table->Length <= ACPI_FADT_V2_SIZE))
484    {
485        Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
486            AcpiDmTableInfoFadt2);
487        if (ACPI_FAILURE (Status))
488        {
489            return;
490        }
491    }
492
493    /* Check for FADT revision 3/4 fields and up (ACPI 2.0+ extended data) */
494
495    else if (Table->Length > ACPI_FADT_V2_SIZE)
496    {
497        Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
498            AcpiDmTableInfoFadt3);
499        if (ACPI_FAILURE (Status))
500        {
501            return;
502        }
503
504        /* Check for FADT revision 5 fields and up (ACPI 5.0+) */
505
506        if (Table->Length > ACPI_FADT_V3_SIZE)
507        {
508            Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
509                AcpiDmTableInfoFadt5);
510            if (ACPI_FAILURE (Status))
511            {
512                return;
513            }
514        }
515
516        /* Check for FADT revision 6 fields and up (ACPI 6.0+) */
517
518        if (Table->Length > ACPI_FADT_V3_SIZE)
519        {
520            Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
521                AcpiDmTableInfoFadt6);
522            if (ACPI_FAILURE (Status))
523            {
524                return;
525            }
526        }
527    }
528
529    /* Validate various fields in the FADT, including length */
530
531    AcpiTbCreateLocalFadt (Table, Table->Length);
532
533    /* Validate FADT length against the revision */
534
535    AcpiDmValidateFadtLength (Table->Revision, Table->Length);
536}
537
538
539/*******************************************************************************
540 *
541 * FUNCTION:    AcpiDmValidateFadtLength
542 *
543 * PARAMETERS:  Revision            - FADT revision (Header->Revision)
544 *              Length              - FADT length (Header->Length
545 *
546 * RETURN:      None
547 *
548 * DESCRIPTION: Check the FADT revision against the expected table length for
549 *              that revision. Issue a warning if the length is not what was
550 *              expected. This seems to be such a common BIOS bug that the
551 *              FADT revision has been rendered virtually meaningless.
552 *
553 ******************************************************************************/
554
555static void
556AcpiDmValidateFadtLength (
557    UINT32                  Revision,
558    UINT32                  Length)
559{
560    UINT32                  ExpectedLength;
561
562
563    switch (Revision)
564    {
565    case 0:
566
567        AcpiOsPrintf ("// ACPI Warning: Invalid FADT revision: 0\n");
568        return;
569
570    case 1:
571
572        ExpectedLength = ACPI_FADT_V1_SIZE;
573        break;
574
575    case 2:
576
577        ExpectedLength = ACPI_FADT_V2_SIZE;
578        break;
579
580    case 3:
581    case 4:
582
583        ExpectedLength = ACPI_FADT_V3_SIZE;
584        break;
585
586    case 5:
587
588        ExpectedLength = ACPI_FADT_V5_SIZE;
589        break;
590
591    default:
592
593        return;
594    }
595
596    if (Length == ExpectedLength)
597    {
598        return;
599    }
600
601    AcpiOsPrintf (
602        "\n// ACPI Warning: FADT revision %X does not match length: "
603        "found %X expected %X\n",
604        Revision, Length, ExpectedLength);
605}
606