1 /******************************************************************************
2  *
3  * Module Name: apmain - Main module for the acpidump utility
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 #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, ACPI_ANY_BASE,
213 					      ACPI_MAX64_BYTE_WIDTH,
214 					      &gbl_rsdp_base);
215 			if (ACPI_FAILURE(status)) {
216 				acpi_log_error
217 				    ("%s: Could not convert to a physical address\n",
218 				     acpi_gbl_optarg);
219 				return (-1);
220 			}
221 			continue;
222 
223 		case 's':	/* Print table summaries only */
224 
225 			gbl_summary_mode = TRUE;
226 			continue;
227 
228 		case 'x':	/* Do not use XSDT */
229 
230 			if (!acpi_gbl_do_not_use_xsdt) {
231 				acpi_gbl_do_not_use_xsdt = TRUE;
232 			} else {
233 				gbl_do_not_dump_xsdt = TRUE;
234 			}
235 			continue;
236 
237 		case 'v':	/* Revision/version */
238 
239 			acpi_os_printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
240 			return (1);
241 
242 		case 'z':	/* Verbose mode */
243 
244 			gbl_verbose_mode = TRUE;
245 			acpi_log_error(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
246 			continue;
247 
248 			/*
249 			 * Table options
250 			 */
251 		case 'a':	/* Get table by physical address */
252 
253 			if (ap_insert_action
254 			    (acpi_gbl_optarg, AP_DUMP_TABLE_BY_ADDRESS)) {
255 				return (-1);
256 			}
257 			break;
258 
259 		case 'f':	/* Get table from a file */
260 
261 			if (ap_insert_action
262 			    (acpi_gbl_optarg, AP_DUMP_TABLE_BY_FILE)) {
263 				return (-1);
264 			}
265 			break;
266 
267 		case 'n':	/* Get table by input name (signature) */
268 
269 			if (ap_insert_action
270 			    (acpi_gbl_optarg, AP_DUMP_TABLE_BY_NAME)) {
271 				return (-1);
272 			}
273 			break;
274 
275 		default:
276 
277 			ap_display_usage();
278 			return (-1);
279 		}
280 
281 	/* If there are no actions, this means "get/dump all tables" */
282 
283 	if (current_action == 0) {
284 		if (ap_insert_action(NULL, AP_DUMP_ALL_TABLES)) {
285 			return (-1);
286 		}
287 	}
288 
289 	return (0);
290 }
291 
292 /******************************************************************************
293  *
294  * FUNCTION:    main
295  *
296  * PARAMETERS:  argc/argv           - Standard argc/argv
297  *
298  * RETURN:      Status
299  *
300  * DESCRIPTION: C main function for acpidump utility
301  *
302  ******************************************************************************/
303 
304 #ifndef _GNU_EFI
305 int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
306 #else
307 int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[])
308 #endif
309 {
310 	int status = 0;
311 	struct ap_dump_action *action;
312 	u32 file_size;
313 	u32 i;
314 
315 	ACPI_DEBUG_INITIALIZE();	/* For debug version only */
316 	acpi_os_initialize();
317 	gbl_output_file = ACPI_FILE_OUT;
318 
319 	/* Process command line options */
320 
321 	status = ap_do_options(argc, argv);
322 	if (status > 0) {
323 		return (0);
324 	}
325 	if (status < 0) {
326 		return (status);
327 	}
328 
329 	/* Get/dump ACPI table(s) as requested */
330 
331 	for (i = 0; i < current_action; i++) {
332 		action = &action_table[i];
333 		switch (action->to_be_done) {
334 		case AP_DUMP_ALL_TABLES:
335 
336 			status = ap_dump_all_tables();
337 			break;
338 
339 		case AP_DUMP_TABLE_BY_ADDRESS:
340 
341 			status = ap_dump_table_by_address(action->argument);
342 			break;
343 
344 		case AP_DUMP_TABLE_BY_NAME:
345 
346 			status = ap_dump_table_by_name(action->argument);
347 			break;
348 
349 		case AP_DUMP_TABLE_BY_FILE:
350 
351 			status = ap_dump_table_from_file(action->argument);
352 			break;
353 
354 		default:
355 
356 			acpi_log_error("Internal error, invalid action: 0x%X\n",
357 				       action->to_be_done);
358 			return (-1);
359 		}
360 
361 		if (status) {
362 			return (status);
363 		}
364 	}
365 
366 	if (gbl_output_filename) {
367 		if (gbl_verbose_mode) {
368 
369 			/* Summary for the output file */
370 
371 			file_size = cm_get_file_size(gbl_output_file);
372 			acpi_log_error
373 			    ("Output file %s contains 0x%X (%u) bytes\n\n",
374 			     gbl_output_filename, file_size, file_size);
375 		}
376 
377 		acpi_os_close_file(gbl_output_file);
378 	}
379 
380 	return (status);
381 }
382