1 /******************************************************************************
3 * Module Name: apdump - Dump routines for ACPI tables (acpidump)
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2017, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
46 /* Local prototypes */
49 ap_dump_table_buffer(struct acpi_table_header
*table
,
50 u32 instance
, acpi_physical_address address
);
52 /******************************************************************************
54 * FUNCTION: ap_is_valid_header
56 * PARAMETERS: table - Pointer to table to be validated
58 * RETURN: TRUE if the header appears to be valid. FALSE otherwise
60 * DESCRIPTION: Check for a valid ACPI table header
62 ******************************************************************************/
64 u8
ap_is_valid_header(struct acpi_table_header
*table
)
67 if (!ACPI_VALIDATE_RSDP_SIG(table
->signature
)) {
69 /* Make sure signature is all ASCII and a valid ACPI name */
71 if (!acpi_ut_valid_nameseg(table
->signature
)) {
73 "Table signature (0x%8.8X) is invalid\n",
74 *(u32
*)table
->signature
);
78 /* Check for minimum table length */
80 if (table
->length
< sizeof(struct acpi_table_header
)) {
81 fprintf(stderr
, "Table length (0x%8.8X) is invalid\n",
90 /******************************************************************************
92 * FUNCTION: ap_is_valid_checksum
94 * PARAMETERS: table - Pointer to table to be validated
96 * RETURN: TRUE if the checksum appears to be valid. FALSE otherwise.
98 * DESCRIPTION: Check for a valid ACPI table checksum.
100 ******************************************************************************/
102 u8
ap_is_valid_checksum(struct acpi_table_header
*table
)
105 struct acpi_table_rsdp
*rsdp
;
107 if (ACPI_VALIDATE_RSDP_SIG(table
->signature
)) {
110 * Note: Other checksums are computed during the table dump.
112 rsdp
= ACPI_CAST_PTR(struct acpi_table_rsdp
, table
);
113 status
= acpi_tb_validate_rsdp(rsdp
);
115 status
= acpi_tb_verify_checksum(table
, table
->length
);
118 if (ACPI_FAILURE(status
)) {
119 fprintf(stderr
, "%4.4s: Warning: wrong checksum in table\n",
126 /******************************************************************************
128 * FUNCTION: ap_get_table_length
130 * PARAMETERS: table - Pointer to the table
132 * RETURN: Table length
134 * DESCRIPTION: Obtain table length according to table signature.
136 ******************************************************************************/
138 u32
ap_get_table_length(struct acpi_table_header
*table
)
140 struct acpi_table_rsdp
*rsdp
;
142 /* Check if table is valid */
144 if (!ap_is_valid_header(table
)) {
148 if (ACPI_VALIDATE_RSDP_SIG(table
->signature
)) {
149 rsdp
= ACPI_CAST_PTR(struct acpi_table_rsdp
, table
);
150 return (acpi_tb_get_rsdp_length(rsdp
));
153 /* Normal ACPI table */
155 return (table
->length
);
158 /******************************************************************************
160 * FUNCTION: ap_dump_table_buffer
162 * PARAMETERS: table - ACPI table to be dumped
163 * instance - ACPI table instance no. to be dumped
164 * address - Physical address of the table
168 * DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a
169 * header that is compatible with the acpi_xtract utility.
171 ******************************************************************************/
174 ap_dump_table_buffer(struct acpi_table_header
*table
,
175 u32 instance
, acpi_physical_address address
)
179 table_length
= ap_get_table_length(table
);
181 /* Print only the header if requested */
183 if (gbl_summary_mode
) {
184 acpi_tb_print_table_header(address
, table
);
188 /* Dump to binary file if requested */
190 if (gbl_binary_mode
) {
191 return (ap_write_to_binary_file(table
, instance
));
195 * Dump the table with header for use with acpixtract utility.
196 * Note: simplest to just always emit a 64-bit address. acpi_xtract
197 * utility can handle this.
199 fprintf(gbl_output_file
, "%4.4s @ 0x%8.8X%8.8X\n",
200 table
->signature
, ACPI_FORMAT_UINT64(address
));
202 acpi_ut_dump_buffer_to_file(gbl_output_file
,
203 ACPI_CAST_PTR(u8
, table
), table_length
,
205 fprintf(gbl_output_file
, "\n");
209 /******************************************************************************
211 * FUNCTION: ap_dump_all_tables
217 * DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the
218 * tables that we can possibly get).
220 ******************************************************************************/
222 int ap_dump_all_tables(void)
224 struct acpi_table_header
*table
;
226 acpi_physical_address address
;
231 /* Get and dump all available ACPI tables */
233 for (i
= 0; i
< AP_MAX_ACPI_FILES
; i
++) {
235 acpi_os_get_table_by_index(i
, &table
, &instance
, &address
);
236 if (ACPI_FAILURE(status
)) {
238 /* AE_LIMIT means that no more tables are available */
240 if (status
== AE_LIMIT
) {
244 "Could not get ACPI tables, %s\n",
245 acpi_format_exception(status
));
249 "Could not get ACPI table at index %u, %s\n",
250 i
, acpi_format_exception(status
));
255 table_status
= ap_dump_table_buffer(table
, instance
, address
);
263 /* Something seriously bad happened if the loop terminates here */
268 /******************************************************************************
270 * FUNCTION: ap_dump_table_by_address
272 * PARAMETERS: ascii_address - Address for requested ACPI table
276 * DESCRIPTION: Get an ACPI table via a physical address and dump it.
278 ******************************************************************************/
280 int ap_dump_table_by_address(char *ascii_address
)
282 acpi_physical_address address
;
283 struct acpi_table_header
*table
;
288 /* Convert argument to an integer physical address */
290 status
= acpi_ut_strtoul64(ascii_address
, ACPI_STRTOUL_64BIT
,
292 if (ACPI_FAILURE(status
)) {
293 fprintf(stderr
, "%s: Could not convert to a physical address\n",
298 address
= (acpi_physical_address
)long_address
;
299 status
= acpi_os_get_table_by_address(address
, &table
);
300 if (ACPI_FAILURE(status
)) {
301 fprintf(stderr
, "Could not get table at 0x%8.8X%8.8X, %s\n",
302 ACPI_FORMAT_UINT64(address
),
303 acpi_format_exception(status
));
307 table_status
= ap_dump_table_buffer(table
, 0, address
);
309 return (table_status
);
312 /******************************************************************************
314 * FUNCTION: ap_dump_table_by_name
316 * PARAMETERS: signature - Requested ACPI table signature
320 * DESCRIPTION: Get an ACPI table via a signature and dump it. Handles
321 * multiple tables with the same signature (SSDTs).
323 ******************************************************************************/
325 int ap_dump_table_by_name(char *signature
)
327 char local_signature
[ACPI_NAME_SIZE
+ 1];
329 struct acpi_table_header
*table
;
330 acpi_physical_address address
;
334 if (strlen(signature
) != ACPI_NAME_SIZE
) {
336 "Invalid table signature [%s]: must be exactly 4 characters\n",
341 /* Table signatures are expected to be uppercase */
343 strcpy(local_signature
, signature
);
344 acpi_ut_strupr(local_signature
);
346 /* To be friendly, handle tables whose signatures do not match the name */
348 if (ACPI_COMPARE_NAME(local_signature
, "FADT")) {
349 strcpy(local_signature
, ACPI_SIG_FADT
);
350 } else if (ACPI_COMPARE_NAME(local_signature
, "MADT")) {
351 strcpy(local_signature
, ACPI_SIG_MADT
);
354 /* Dump all instances of this signature (to handle multiple SSDTs) */
356 for (instance
= 0; instance
< AP_MAX_ACPI_FILES
; instance
++) {
357 status
= acpi_os_get_table_by_name(local_signature
, instance
,
359 if (ACPI_FAILURE(status
)) {
361 /* AE_LIMIT means that no more tables are available */
363 if (status
== AE_LIMIT
) {
368 "Could not get ACPI table with signature [%s], %s\n",
369 local_signature
, acpi_format_exception(status
));
373 table_status
= ap_dump_table_buffer(table
, instance
, address
);
381 /* Something seriously bad happened if the loop terminates here */
386 /******************************************************************************
388 * FUNCTION: ap_dump_table_from_file
390 * PARAMETERS: pathname - File containing the binary ACPI table
394 * DESCRIPTION: Dump an ACPI table from a binary file
396 ******************************************************************************/
398 int ap_dump_table_from_file(char *pathname
)
400 struct acpi_table_header
*table
;
402 int table_status
= -1;
404 /* Get the entire ACPI table from the file */
406 table
= ap_get_table_from_file(pathname
, &file_size
);
411 if (!acpi_ut_valid_nameseg(table
->signature
)) {
413 "No valid ACPI signature was found in input file %s\n",
417 /* File must be at least as long as the table length */
419 if (table
->length
> file_size
) {
421 "Table length (0x%X) is too large for input file (0x%X) %s\n",
422 table
->length
, file_size
, pathname
);
426 if (gbl_verbose_mode
) {
428 "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n",
429 pathname
, table
->signature
, file_size
, file_size
);
432 table_status
= ap_dump_table_buffer(table
, 0, 0);
436 return (table_status
);