GNU Linux-libre 4.19.264-gnu1
[releases.git] / tools / power / acpi / tools / acpidump / apmain.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: apmain - Main module for the acpidump utility
5  *
6  * Copyright (C) 2000 - 2018, Intel Corp.
7  *
8  *****************************************************************************/
9
10 #define _DECLARE_GLOBALS
11 #include "acpidump.h"
12
13 /*
14  * acpidump - A portable utility for obtaining system ACPI tables and dumping
15  * them in an ASCII hex format suitable for binary extraction via acpixtract.
16  *
17  * Obtaining the system ACPI tables is an OS-specific operation.
18  *
19  * This utility can be ported to any host operating system by providing a
20  * module containing system-specific versions of these interfaces:
21  *
22  *      acpi_os_get_table_by_address
23  *      acpi_os_get_table_by_index
24  *      acpi_os_get_table_by_name
25  *
26  * See the ACPICA Reference Guide for the exact definitions of these
27  * interfaces. Also, see these ACPICA source code modules for example
28  * implementations:
29  *
30  *      source/os_specific/service_layers/oswintbl.c
31  *      source/os_specific/service_layers/oslinuxtbl.c
32  */
33
34 /* Local prototypes */
35
36 static void ap_display_usage(void);
37
38 static int ap_do_options(int argc, char **argv);
39
40 static int ap_insert_action(char *argument, u32 to_be_done);
41
42 /* Table for deferred actions from command line options */
43
44 struct ap_dump_action action_table[AP_MAX_ACTIONS];
45 u32 current_action = 0;
46
47 #define AP_UTILITY_NAME             "ACPI Binary Table Dump Utility"
48 #define AP_SUPPORTED_OPTIONS        "?a:bc:f:hn:o:r:sv^xz"
49
50 /******************************************************************************
51  *
52  * FUNCTION:    ap_display_usage
53  *
54  * DESCRIPTION: Usage message for the acpi_dump utility
55  *
56  ******************************************************************************/
57
58 static void ap_display_usage(void)
59 {
60
61         ACPI_USAGE_HEADER("acpidump [options]");
62
63         ACPI_OPTION("-b", "Dump tables to binary files");
64         ACPI_OPTION("-h -?", "This help message");
65         ACPI_OPTION("-o <File>", "Redirect output to file");
66         ACPI_OPTION("-r <Address>", "Dump tables from specified RSDP");
67         ACPI_OPTION("-s", "Print table summaries only");
68         ACPI_OPTION("-v", "Display version information");
69         ACPI_OPTION("-vd", "Display build date and time");
70         ACPI_OPTION("-z", "Verbose mode");
71
72         ACPI_USAGE_TEXT("\nTable Options:\n");
73
74         ACPI_OPTION("-a <Address>", "Get table via a physical address");
75         ACPI_OPTION("-c <on|off>", "Turning on/off customized table dumping");
76         ACPI_OPTION("-f <BinaryFile>", "Get table via a binary file");
77         ACPI_OPTION("-n <Signature>", "Get table via a name/signature");
78         ACPI_OPTION("-x", "Do not use but dump XSDT");
79         ACPI_OPTION("-x -x", "Do not use or dump XSDT");
80
81         ACPI_USAGE_TEXT("\n"
82                         "Invocation without parameters dumps all available tables\n"
83                         "Multiple mixed instances of -a, -f, and -n are supported\n\n");
84 }
85
86 /******************************************************************************
87  *
88  * FUNCTION:    ap_insert_action
89  *
90  * PARAMETERS:  argument            - Pointer to the argument for this action
91  *              to_be_done          - What to do to process this action
92  *
93  * RETURN:      Status
94  *
95  * DESCRIPTION: Add an action item to the action table
96  *
97  ******************************************************************************/
98
99 static int ap_insert_action(char *argument, u32 to_be_done)
100 {
101
102         /* Insert action and check for table overflow */
103
104         action_table[current_action].argument = argument;
105         action_table[current_action].to_be_done = to_be_done;
106
107         current_action++;
108         if (current_action > AP_MAX_ACTIONS) {
109                 fprintf(stderr, "Too many table options (max %d)\n",
110                         AP_MAX_ACTIONS);
111                 return (-1);
112         }
113
114         return (0);
115 }
116
117 /******************************************************************************
118  *
119  * FUNCTION:    ap_do_options
120  *
121  * PARAMETERS:  argc/argv           - Standard argc/argv
122  *
123  * RETURN:      Status
124  *
125  * DESCRIPTION: Command line option processing. The main actions for getting
126  *              and dumping tables are deferred via the action table.
127  *
128  *****************************************************************************/
129
130 static int ap_do_options(int argc, char **argv)
131 {
132         int j;
133         acpi_status status;
134
135         /* Command line options */
136
137         while ((j =
138                 acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != ACPI_OPT_END)
139                 switch (j) {
140                         /*
141                          * Global options
142                          */
143                 case 'b':       /* Dump all input tables to binary files */
144
145                         gbl_binary_mode = TRUE;
146                         continue;
147
148                 case 'c':       /* Dump customized tables */
149
150                         if (!strcmp(acpi_gbl_optarg, "on")) {
151                                 gbl_dump_customized_tables = TRUE;
152                         } else if (!strcmp(acpi_gbl_optarg, "off")) {
153                                 gbl_dump_customized_tables = FALSE;
154                         } else {
155                                 fprintf(stderr,
156                                         "%s: Cannot handle this switch, please use on|off\n",
157                                         acpi_gbl_optarg);
158                                 return (-1);
159                         }
160                         continue;
161
162                 case 'h':
163                 case '?':
164
165                         ap_display_usage();
166                         return (1);
167
168                 case 'o':       /* Redirect output to a single file */
169
170                         if (ap_open_output_file(acpi_gbl_optarg)) {
171                                 return (-1);
172                         }
173                         continue;
174
175                 case 'r':       /* Dump tables from specified RSDP */
176
177                         status =
178                             acpi_ut_strtoul64(acpi_gbl_optarg, &gbl_rsdp_base);
179                         if (ACPI_FAILURE(status)) {
180                                 fprintf(stderr,
181                                         "%s: Could not convert to a physical address\n",
182                                         acpi_gbl_optarg);
183                                 return (-1);
184                         }
185                         continue;
186
187                 case 's':       /* Print table summaries only */
188
189                         gbl_summary_mode = TRUE;
190                         continue;
191
192                 case 'x':       /* Do not use XSDT */
193
194                         if (!acpi_gbl_do_not_use_xsdt) {
195                                 acpi_gbl_do_not_use_xsdt = TRUE;
196                         } else {
197                                 gbl_do_not_dump_xsdt = TRUE;
198                         }
199                         continue;
200
201                 case 'v':       /* -v: (Version): signon already emitted, just exit */
202
203                         switch (acpi_gbl_optarg[0]) {
204                         case '^':       /* -v: (Version) */
205
206                                 fprintf(stderr,
207                                         ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
208                                 return (1);
209
210                         case 'd':
211
212                                 fprintf(stderr,
213                                         ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
214                                 printf(ACPI_COMMON_BUILD_TIME);
215                                 return (1);
216
217                         default:
218
219                                 printf("Unknown option: -v%s\n",
220                                        acpi_gbl_optarg);
221                                 return (-1);
222                         }
223                         break;
224
225                 case 'z':       /* Verbose mode */
226
227                         gbl_verbose_mode = TRUE;
228                         fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
229                         continue;
230
231                         /*
232                          * Table options
233                          */
234                 case 'a':       /* Get table by physical address */
235
236                         if (ap_insert_action
237                             (acpi_gbl_optarg, AP_DUMP_TABLE_BY_ADDRESS)) {
238                                 return (-1);
239                         }
240                         break;
241
242                 case 'f':       /* Get table from a file */
243
244                         if (ap_insert_action
245                             (acpi_gbl_optarg, AP_DUMP_TABLE_BY_FILE)) {
246                                 return (-1);
247                         }
248                         break;
249
250                 case 'n':       /* Get table by input name (signature) */
251
252                         if (ap_insert_action
253                             (acpi_gbl_optarg, AP_DUMP_TABLE_BY_NAME)) {
254                                 return (-1);
255                         }
256                         break;
257
258                 default:
259
260                         ap_display_usage();
261                         return (-1);
262                 }
263
264         /* If there are no actions, this means "get/dump all tables" */
265
266         if (current_action == 0) {
267                 if (ap_insert_action(NULL, AP_DUMP_ALL_TABLES)) {
268                         return (-1);
269                 }
270         }
271
272         return (0);
273 }
274
275 /******************************************************************************
276  *
277  * FUNCTION:    main
278  *
279  * PARAMETERS:  argc/argv           - Standard argc/argv
280  *
281  * RETURN:      Status
282  *
283  * DESCRIPTION: C main function for acpidump utility
284  *
285  ******************************************************************************/
286
287 #if !defined(_GNU_EFI) && !defined(_EDK2_EFI)
288 int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
289 #else
290 int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[])
291 #endif
292 {
293         int status = 0;
294         struct ap_dump_action *action;
295         u32 file_size;
296         u32 i;
297
298         ACPI_DEBUG_INITIALIZE();        /* For debug version only */
299         acpi_os_initialize();
300         gbl_output_file = ACPI_FILE_OUT;
301         acpi_gbl_integer_byte_width = 8;
302
303         /* Process command line options */
304
305         status = ap_do_options(argc, argv);
306         if (status > 0) {
307                 return (0);
308         }
309         if (status < 0) {
310                 return (status);
311         }
312
313         /* Get/dump ACPI table(s) as requested */
314
315         for (i = 0; i < current_action; i++) {
316                 action = &action_table[i];
317                 switch (action->to_be_done) {
318                 case AP_DUMP_ALL_TABLES:
319
320                         status = ap_dump_all_tables();
321                         break;
322
323                 case AP_DUMP_TABLE_BY_ADDRESS:
324
325                         status = ap_dump_table_by_address(action->argument);
326                         break;
327
328                 case AP_DUMP_TABLE_BY_NAME:
329
330                         status = ap_dump_table_by_name(action->argument);
331                         break;
332
333                 case AP_DUMP_TABLE_BY_FILE:
334
335                         status = ap_dump_table_from_file(action->argument);
336                         break;
337
338                 default:
339
340                         fprintf(stderr,
341                                 "Internal error, invalid action: 0x%X\n",
342                                 action->to_be_done);
343                         return (-1);
344                 }
345
346                 if (status) {
347                         return (status);
348                 }
349         }
350
351         if (gbl_output_filename) {
352                 if (gbl_verbose_mode) {
353
354                         /* Summary for the output file */
355
356                         file_size = cm_get_file_size(gbl_output_file);
357                         fprintf(stderr,
358                                 "Output file %s contains 0x%X (%u) bytes\n\n",
359                                 gbl_output_filename, file_size, file_size);
360                 }
361
362                 fclose(gbl_output_file);
363         }
364
365         return (status);
366 }