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