Merge tag 'arc-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
[cascardo/linux.git] / tools / power / acpi / tools / acpidump / apdump.c
1 /******************************************************************************
2  *
3  * Module Name: apdump - Dump routines for ACPI tables (acpidump)
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2016, 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 "acpidump.h"
45
46 /* Local prototypes */
47
48 static int
49 ap_dump_table_buffer(struct acpi_table_header *table,
50                      u32 instance, acpi_physical_address address);
51
52 /******************************************************************************
53  *
54  * FUNCTION:    ap_is_valid_header
55  *
56  * PARAMETERS:  table               - Pointer to table to be validated
57  *
58  * RETURN:      TRUE if the header appears to be valid. FALSE otherwise
59  *
60  * DESCRIPTION: Check for a valid ACPI table header
61  *
62  ******************************************************************************/
63
64 u8 ap_is_valid_header(struct acpi_table_header *table)
65 {
66
67         if (!ACPI_VALIDATE_RSDP_SIG(table->signature)) {
68
69                 /* Make sure signature is all ASCII and a valid ACPI name */
70
71                 if (!acpi_ut_valid_nameseg(table->signature)) {
72                         fprintf(stderr,
73                                 "Table signature (0x%8.8X) is invalid\n",
74                                 *(u32 *)table->signature);
75                         return (FALSE);
76                 }
77
78                 /* Check for minimum table length */
79
80                 if (table->length < sizeof(struct acpi_table_header)) {
81                         fprintf(stderr, "Table length (0x%8.8X) is invalid\n",
82                                 table->length);
83                         return (FALSE);
84                 }
85         }
86
87         return (TRUE);
88 }
89
90 /******************************************************************************
91  *
92  * FUNCTION:    ap_is_valid_checksum
93  *
94  * PARAMETERS:  table               - Pointer to table to be validated
95  *
96  * RETURN:      TRUE if the checksum appears to be valid. FALSE otherwise.
97  *
98  * DESCRIPTION: Check for a valid ACPI table checksum.
99  *
100  ******************************************************************************/
101
102 u8 ap_is_valid_checksum(struct acpi_table_header *table)
103 {
104         acpi_status status;
105         struct acpi_table_rsdp *rsdp;
106
107         if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
108                 /*
109                  * Checksum for RSDP.
110                  * Note: Other checksums are computed during the table dump.
111                  */
112                 rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table);
113                 status = acpi_tb_validate_rsdp(rsdp);
114         } else {
115                 status = acpi_tb_verify_checksum(table, table->length);
116         }
117
118         if (ACPI_FAILURE(status)) {
119                 fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n",
120                         table->signature);
121         }
122
123         return (AE_OK);
124 }
125
126 /******************************************************************************
127  *
128  * FUNCTION:    ap_get_table_length
129  *
130  * PARAMETERS:  table               - Pointer to the table
131  *
132  * RETURN:      Table length
133  *
134  * DESCRIPTION: Obtain table length according to table signature.
135  *
136  ******************************************************************************/
137
138 u32 ap_get_table_length(struct acpi_table_header *table)
139 {
140         struct acpi_table_rsdp *rsdp;
141
142         /* Check if table is valid */
143
144         if (!ap_is_valid_header(table)) {
145                 return (0);
146         }
147
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));
151         }
152
153         /* Normal ACPI table */
154
155         return (table->length);
156 }
157
158 /******************************************************************************
159  *
160  * FUNCTION:    ap_dump_table_buffer
161  *
162  * PARAMETERS:  table               - ACPI table to be dumped
163  *              instance            - ACPI table instance no. to be dumped
164  *              address             - Physical address of the table
165  *
166  * RETURN:      None
167  *
168  * DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a
169  *              header that is compatible with the acpi_xtract utility.
170  *
171  ******************************************************************************/
172
173 static int
174 ap_dump_table_buffer(struct acpi_table_header *table,
175                      u32 instance, acpi_physical_address address)
176 {
177         u32 table_length;
178
179         table_length = ap_get_table_length(table);
180
181         /* Print only the header if requested */
182
183         if (gbl_summary_mode) {
184                 acpi_tb_print_table_header(address, table);
185                 return (0);
186         }
187
188         /* Dump to binary file if requested */
189
190         if (gbl_binary_mode) {
191                 return (ap_write_to_binary_file(table, instance));
192         }
193
194         /*
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.
198          */
199         fprintf(gbl_output_file, "%4.4s @ 0x%8.8X%8.8X\n",
200                 table->signature, ACPI_FORMAT_UINT64(address));
201
202         acpi_ut_dump_buffer_to_file(gbl_output_file,
203                                     ACPI_CAST_PTR(u8, table), table_length,
204                                     DB_BYTE_DISPLAY, 0);
205         fprintf(gbl_output_file, "\n");
206         return (0);
207 }
208
209 /******************************************************************************
210  *
211  * FUNCTION:    ap_dump_all_tables
212  *
213  * PARAMETERS:  None
214  *
215  * RETURN:      Status
216  *
217  * DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the
218  *              tables that we can possibly get).
219  *
220  ******************************************************************************/
221
222 int ap_dump_all_tables(void)
223 {
224         struct acpi_table_header *table;
225         u32 instance = 0;
226         acpi_physical_address address;
227         acpi_status status;
228         int table_status;
229         u32 i;
230
231         /* Get and dump all available ACPI tables */
232
233         for (i = 0; i < AP_MAX_ACPI_FILES; i++) {
234                 status =
235                     acpi_os_get_table_by_index(i, &table, &instance, &address);
236                 if (ACPI_FAILURE(status)) {
237
238                         /* AE_LIMIT means that no more tables are available */
239
240                         if (status == AE_LIMIT) {
241                                 return (0);
242                         } else if (i == 0) {
243                                 fprintf(stderr,
244                                         "Could not get ACPI tables, %s\n",
245                                         acpi_format_exception(status));
246                                 return (-1);
247                         } else {
248                                 fprintf(stderr,
249                                         "Could not get ACPI table at index %u, %s\n",
250                                         i, acpi_format_exception(status));
251                                 continue;
252                         }
253                 }
254
255                 table_status = ap_dump_table_buffer(table, instance, address);
256                 ACPI_FREE(table);
257
258                 if (table_status) {
259                         break;
260                 }
261         }
262
263         /* Something seriously bad happened if the loop terminates here */
264
265         return (-1);
266 }
267
268 /******************************************************************************
269  *
270  * FUNCTION:    ap_dump_table_by_address
271  *
272  * PARAMETERS:  ascii_address       - Address for requested ACPI table
273  *
274  * RETURN:      Status
275  *
276  * DESCRIPTION: Get an ACPI table via a physical address and dump it.
277  *
278  ******************************************************************************/
279
280 int ap_dump_table_by_address(char *ascii_address)
281 {
282         acpi_physical_address address;
283         struct acpi_table_header *table;
284         acpi_status status;
285         int table_status;
286         u64 long_address;
287
288         /* Convert argument to an integer physical address */
289
290         status = acpi_ut_strtoul64(ascii_address, ACPI_STRTOUL_64BIT,
291                                    &long_address);
292         if (ACPI_FAILURE(status)) {
293                 fprintf(stderr, "%s: Could not convert to a physical address\n",
294                         ascii_address);
295                 return (-1);
296         }
297
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));
304                 return (-1);
305         }
306
307         table_status = ap_dump_table_buffer(table, 0, address);
308         ACPI_FREE(table);
309         return (table_status);
310 }
311
312 /******************************************************************************
313  *
314  * FUNCTION:    ap_dump_table_by_name
315  *
316  * PARAMETERS:  signature           - Requested ACPI table signature
317  *
318  * RETURN:      Status
319  *
320  * DESCRIPTION: Get an ACPI table via a signature and dump it. Handles
321  *              multiple tables with the same signature (SSDTs).
322  *
323  ******************************************************************************/
324
325 int ap_dump_table_by_name(char *signature)
326 {
327         char local_signature[ACPI_NAME_SIZE + 1];
328         u32 instance;
329         struct acpi_table_header *table;
330         acpi_physical_address address;
331         acpi_status status;
332         int table_status;
333
334         if (strlen(signature) != ACPI_NAME_SIZE) {
335                 fprintf(stderr,
336                         "Invalid table signature [%s]: must be exactly 4 characters\n",
337                         signature);
338                 return (-1);
339         }
340
341         /* Table signatures are expected to be uppercase */
342
343         strcpy(local_signature, signature);
344         acpi_ut_strupr(local_signature);
345
346         /* To be friendly, handle tables whose signatures do not match the name */
347
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);
352         }
353
354         /* Dump all instances of this signature (to handle multiple SSDTs) */
355
356         for (instance = 0; instance < AP_MAX_ACPI_FILES; instance++) {
357                 status = acpi_os_get_table_by_name(local_signature, instance,
358                                                    &table, &address);
359                 if (ACPI_FAILURE(status)) {
360
361                         /* AE_LIMIT means that no more tables are available */
362
363                         if (status == AE_LIMIT) {
364                                 return (0);
365                         }
366
367                         fprintf(stderr,
368                                 "Could not get ACPI table with signature [%s], %s\n",
369                                 local_signature, acpi_format_exception(status));
370                         return (-1);
371                 }
372
373                 table_status = ap_dump_table_buffer(table, instance, address);
374                 ACPI_FREE(table);
375
376                 if (table_status) {
377                         break;
378                 }
379         }
380
381         /* Something seriously bad happened if the loop terminates here */
382
383         return (-1);
384 }
385
386 /******************************************************************************
387  *
388  * FUNCTION:    ap_dump_table_from_file
389  *
390  * PARAMETERS:  pathname            - File containing the binary ACPI table
391  *
392  * RETURN:      Status
393  *
394  * DESCRIPTION: Dump an ACPI table from a binary file
395  *
396  ******************************************************************************/
397
398 int ap_dump_table_from_file(char *pathname)
399 {
400         struct acpi_table_header *table;
401         u32 file_size = 0;
402         int table_status = -1;
403
404         /* Get the entire ACPI table from the file */
405
406         table = ap_get_table_from_file(pathname, &file_size);
407         if (!table) {
408                 return (-1);
409         }
410
411         if (!acpi_ut_valid_nameseg(table->signature)) {
412                 fprintf(stderr,
413                         "No valid ACPI signature was found in input file %s\n",
414                         pathname);
415         }
416
417         /* File must be at least as long as the table length */
418
419         if (table->length > file_size) {
420                 fprintf(stderr,
421                         "Table length (0x%X) is too large for input file (0x%X) %s\n",
422                         table->length, file_size, pathname);
423                 goto exit;
424         }
425
426         if (gbl_verbose_mode) {
427                 fprintf(stderr,
428                         "Input file:  %s contains table [%4.4s], 0x%X (%u) bytes\n",
429                         pathname, table->signature, file_size, file_size);
430         }
431
432         table_status = ap_dump_table_buffer(table, 0, 0);
433
434 exit:
435         ACPI_FREE(table);
436         return (table_status);
437 }