1/******************************************************************************
2 *
3 * Module Name: apmain - Main module for the acpidump utility
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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
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 *      AcpiOsGetTableByAddress
58 *      AcpiOsGetTableByIndex
59 *      AcpiOsGetTableByName
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
70/* Local prototypes */
71
72static void
73ApDisplayUsage (
74    void);
75
76static int
77ApDoOptions (
78    int                     argc,
79    char                    **argv);
80
81static int
82ApInsertAction (
83    char                    *Argument,
84    UINT32                  ToBeDone);
85
86
87/* Table for deferred actions from command line options */
88
89AP_DUMP_ACTION              ActionTable [AP_MAX_ACTIONS];
90UINT32                      CurrentAction = 0;
91
92
93#define AP_UTILITY_NAME             "ACPI Binary Table Dump Utility"
94#define AP_SUPPORTED_OPTIONS        "?a:bc:f:hn:o:r:sv^xz"
95
96
97/******************************************************************************
98 *
99 * FUNCTION:    ApDisplayUsage
100 *
101 * DESCRIPTION: Usage message for the AcpiDump utility
102 *
103 ******************************************************************************/
104
105static void
106ApDisplayUsage (
107    void)
108{
109
110    ACPI_USAGE_HEADER ("acpidump [options]");
111
112    ACPI_OPTION ("-b",                      "Dump tables to binary files");
113    ACPI_OPTION ("-h -?",                   "This help message");
114    ACPI_OPTION ("-o <File>",               "Redirect output to file");
115    ACPI_OPTION ("-r <Address>",            "Dump tables from specified RSDP");
116    ACPI_OPTION ("-s",                      "Print table summaries only");
117    ACPI_OPTION ("-v",                      "Display version information");
118    ACPI_OPTION ("-vd",                     "Display build date and time");
119    ACPI_OPTION ("-z",                      "Verbose mode");
120
121    ACPI_USAGE_TEXT ("\nTable Options:\n");
122
123    ACPI_OPTION ("-a <Address>",            "Get table via a physical address");
124    ACPI_OPTION ("-c <on|off>",             "Turning on/off customized table dumping");
125    ACPI_OPTION ("-f <BinaryFile>",         "Get table via a binary file");
126    ACPI_OPTION ("-n <Signature>",          "Get table via a name/signature");
127    ACPI_OPTION ("-x",                      "Use RSDT instead of XSDT");
128
129    ACPI_USAGE_TEXT (
130        "\n"
131        "Invocation without parameters dumps all available tables\n"
132        "Multiple mixed instances of -a, -f, and -n are supported\n\n");
133}
134
135
136/******************************************************************************
137 *
138 * FUNCTION:    ApInsertAction
139 *
140 * PARAMETERS:  Argument            - Pointer to the argument for this action
141 *              ToBeDone            - What to do to process this action
142 *
143 * RETURN:      Status
144 *
145 * DESCRIPTION: Add an action item to the action table
146 *
147 ******************************************************************************/
148
149static int
150ApInsertAction (
151    char                    *Argument,
152    UINT32                  ToBeDone)
153{
154
155    /* Insert action and check for table overflow */
156
157    ActionTable [CurrentAction].Argument = Argument;
158    ActionTable [CurrentAction].ToBeDone = ToBeDone;
159
160    CurrentAction++;
161    if (CurrentAction > AP_MAX_ACTIONS)
162    {
163        fprintf (stderr, "Too many table options (max %d)\n", AP_MAX_ACTIONS);
164        return (-1);
165    }
166
167    return (0);
168}
169
170
171/******************************************************************************
172 *
173 * FUNCTION:    ApDoOptions
174 *
175 * PARAMETERS:  argc/argv           - Standard argc/argv
176 *
177 * RETURN:      Status
178 *
179 * DESCRIPTION: Command line option processing. The main actions for getting
180 *              and dumping tables are deferred via the action table.
181 *
182 *****************************************************************************/
183
184static int
185ApDoOptions (
186    int                     argc,
187    char                    **argv)
188{
189    int                     j;
190    ACPI_STATUS             Status;
191
192
193    /* Command line options */
194
195    while ((j = AcpiGetopt (argc, argv, AP_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j)
196    {
197    /*
198     * Global options
199     */
200    case 'b':   /* Dump all input tables to binary files */
201
202        Gbl_BinaryMode = TRUE;
203        continue;
204
205    case 'c':   /* Dump customized tables */
206
207        if (!strcmp (AcpiGbl_Optarg, "on"))
208        {
209            Gbl_DumpCustomizedTables = TRUE;
210        }
211        else if (!strcmp (AcpiGbl_Optarg, "off"))
212        {
213            Gbl_DumpCustomizedTables = FALSE;
214        }
215        else
216        {
217            fprintf (stderr, "%s: Cannot handle this switch, please use on|off\n",
218                AcpiGbl_Optarg);
219            return (-1);
220        }
221        continue;
222
223    case 'h':
224    case '?':
225
226        ApDisplayUsage ();
227        return (1);
228
229    case 'o':   /* Redirect output to a single file */
230
231        if (ApOpenOutputFile (AcpiGbl_Optarg))
232        {
233            return (-1);
234        }
235        continue;
236
237    case 'r':   /* Dump tables from specified RSDP */
238
239        Status = AcpiUtStrtoul64 (AcpiGbl_Optarg, &Gbl_RsdpBase);
240        if (ACPI_FAILURE (Status))
241        {
242            fprintf (stderr, "%s: Could not convert to a physical address\n",
243                AcpiGbl_Optarg);
244            return (-1);
245        }
246        continue;
247
248    case 's':   /* Print table summaries only */
249
250        Gbl_SummaryMode = TRUE;
251        continue;
252
253    case 'x':   /* Do not use XSDT */
254
255        if (!AcpiGbl_DoNotUseXsdt)
256        {
257            AcpiGbl_DoNotUseXsdt = TRUE;
258        }
259        else
260        {
261            Gbl_DoNotDumpXsdt = TRUE;
262        }
263        continue;
264
265    case 'v': /* -v: (Version): signon already emitted, just exit */
266
267        switch (AcpiGbl_Optarg[0])
268        {
269        case '^':  /* -v: (Version) */
270
271            fprintf (stderr, ACPI_COMMON_SIGNON (AP_UTILITY_NAME));
272            return (1);
273
274        case 'd':
275
276            fprintf (stderr, ACPI_COMMON_SIGNON (AP_UTILITY_NAME));
277            printf (ACPI_COMMON_BUILD_TIME);
278            return (1);
279
280        default:
281
282            printf ("Unknown option: -v%s\n", AcpiGbl_Optarg);
283            return (-1);
284        }
285        break;
286
287    case 'z':   /* Verbose mode */
288
289        Gbl_VerboseMode = TRUE;
290        fprintf (stderr, ACPI_COMMON_SIGNON (AP_UTILITY_NAME));
291        continue;
292
293    /*
294     * Table options
295     */
296    case 'a':   /* Get table by physical address */
297
298        if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_ADDRESS))
299        {
300            return (-1);
301        }
302        break;
303
304    case 'f':   /* Get table from a file */
305
306        if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_FILE))
307        {
308            return (-1);
309        }
310        break;
311
312    case 'n':   /* Get table by input name (signature) */
313
314        if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_NAME))
315        {
316            return (-1);
317        }
318        break;
319
320    default:
321
322        ApDisplayUsage ();
323        return (-1);
324    }
325
326    /* If there are no actions, this means "get/dump all tables" */
327
328    if (CurrentAction == 0)
329    {
330        if (ApInsertAction (NULL, AP_DUMP_ALL_TABLES))
331        {
332            return (-1);
333        }
334    }
335
336    return (0);
337}
338
339
340/******************************************************************************
341 *
342 * FUNCTION:    main
343 *
344 * PARAMETERS:  argc/argv           - Standard argc/argv
345 *
346 * RETURN:      Status
347 *
348 * DESCRIPTION: C main function for acpidump utility
349 *
350 ******************************************************************************/
351
352#if !defined(_GNU_EFI) && !defined(_EDK2_EFI)
353int ACPI_SYSTEM_XFACE
354main (
355    int                     argc,
356    char                    *argv[])
357#else
358int ACPI_SYSTEM_XFACE
359acpi_main (
360    int                     argc,
361    char                    *argv[])
362#endif
363{
364    int                     Status = 0;
365    AP_DUMP_ACTION          *Action;
366    UINT32                  FileSize;
367    UINT32                  i;
368
369
370    ACPI_DEBUG_INITIALIZE (); /* For debug version only */
371    AcpiOsInitialize ();
372    Gbl_OutputFile = ACPI_FILE_OUT;
373    AcpiGbl_IntegerByteWidth = 8;
374
375    /* Process command line options */
376
377    Status = ApDoOptions (argc, argv);
378    if (Status > 0)
379    {
380        return (0);
381    }
382    if (Status < 0)
383    {
384        return (Status);
385    }
386
387    /* Get/dump ACPI table(s) as requested */
388
389    for (i = 0; i < CurrentAction; i++)
390    {
391        Action = &ActionTable[i];
392        switch (Action->ToBeDone)
393        {
394        case AP_DUMP_ALL_TABLES:
395
396            Status = ApDumpAllTables ();
397            break;
398
399        case AP_DUMP_TABLE_BY_ADDRESS:
400
401            Status = ApDumpTableByAddress (Action->Argument);
402            break;
403
404        case AP_DUMP_TABLE_BY_NAME:
405
406            Status = ApDumpTableByName (Action->Argument);
407            break;
408
409        case AP_DUMP_TABLE_BY_FILE:
410
411            Status = ApDumpTableFromFile (Action->Argument);
412            break;
413
414        default:
415
416            fprintf (stderr, "Internal error, invalid action: 0x%X\n",
417                Action->ToBeDone);
418            return (-1);
419        }
420
421        if (Status)
422        {
423            return (Status);
424        }
425    }
426
427    if (Gbl_OutputFilename)
428    {
429        if (Gbl_VerboseMode)
430        {
431            /* Summary for the output file */
432
433            FileSize = CmGetFileSize (Gbl_OutputFile);
434            fprintf (stderr, "Output file %s contains 0x%X (%u) bytes\n\n",
435                Gbl_OutputFilename, FileSize, FileSize);
436        }
437
438        fclose (Gbl_OutputFile);
439    }
440
441    return (Status);
442}
443