aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2014-04-04 00:39:42 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-04-20 16:59:40 -0400
commit506f57dd6dfdb1d73cb77106706cd5b8953b453d (patch)
tree4c5b7085f22dcc0bd4e10267c55960b38ee1598c
parentc418ce19030f8cd9304b4e97c8e0dd580a81ace5 (diff)
ACPICA: acpidump: Add support to generate acpidump release.
The acpidump is initiated by Bob Moore and Chao Guan, fixed and completed by Lv Zheng. This patch is a generation of the commit that adds acpidump release automation into ACPICA release process. Lv Zheng. Note that this patch doesn't replace the kernel shipped acpidump with the new acpidump. The replacement is done by further patches. Original-by: Chao Guan <guanchao@mail.ustc.edu.cn> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/acpica/acapps.h170
-rw-r--r--tools/power/acpi/common/getopt.c239
-rw-r--r--tools/power/acpi/os_specific/service_layers/oslinuxtbl.c1275
-rw-r--r--tools/power/acpi/os_specific/service_layers/osunixdir.c204
-rw-r--r--tools/power/acpi/os_specific/service_layers/osunixmap.c151
-rw-r--r--tools/power/acpi/tools/acpidump/acpidump.h131
-rw-r--r--tools/power/acpi/tools/acpidump/apdump.c451
-rw-r--r--tools/power/acpi/tools/acpidump/apfiles.c228
-rw-r--r--tools/power/acpi/tools/acpidump/apmain.c340
9 files changed, 3189 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h
new file mode 100644
index 000000000000..8698ffba6f39
--- /dev/null
+++ b/drivers/acpi/acpica/acapps.h
@@ -0,0 +1,170 @@
1/******************************************************************************
2 *
3 * Module Name: acapps - common include for ACPI applications/tools
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, 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#ifndef _ACAPPS
45#define _ACAPPS
46
47/* Common info for tool signons */
48
49#define ACPICA_NAME "Intel ACPI Component Architecture"
50#define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2014 Intel Corporation"
51
52#if ACPI_MACHINE_WIDTH == 64
53#define ACPI_WIDTH "-64"
54
55#elif ACPI_MACHINE_WIDTH == 32
56#define ACPI_WIDTH "-32"
57
58#else
59#error unknown ACPI_MACHINE_WIDTH
60#define ACPI_WIDTH "-??"
61
62#endif
63
64/* Macros for signons and file headers */
65
66#define ACPI_COMMON_SIGNON(utility_name) \
67 "\n%s\n%s version %8.8X%s [%s]\n%s\n\n", \
68 ACPICA_NAME, \
69 utility_name, ((u32) ACPI_CA_VERSION), ACPI_WIDTH, __DATE__, \
70 ACPICA_COPYRIGHT
71
72#define ACPI_COMMON_HEADER(utility_name, prefix) \
73 "%s%s\n%s%s version %8.8X%s [%s]\n%s%s\n%s\n", \
74 prefix, ACPICA_NAME, \
75 prefix, utility_name, ((u32) ACPI_CA_VERSION), ACPI_WIDTH, __DATE__, \
76 prefix, ACPICA_COPYRIGHT, \
77 prefix
78
79/* Macros for usage messages */
80
81#define ACPI_USAGE_HEADER(usage) \
82 printf ("Usage: %s\nOptions:\n", usage);
83
84#define ACPI_OPTION(name, description) \
85 printf (" %-18s%s\n", name, description);
86
87#define FILE_SUFFIX_DISASSEMBLY "dsl"
88#define ACPI_TABLE_FILE_SUFFIX ".dat"
89
90/*
91 * getopt
92 */
93int acpi_getopt(int argc, char **argv, char *opts);
94
95int acpi_getopt_argument(int argc, char **argv);
96
97extern int acpi_gbl_optind;
98extern int acpi_gbl_opterr;
99extern int acpi_gbl_sub_opt_char;
100extern char *acpi_gbl_optarg;
101
102/*
103 * cmfsize - Common get file size function
104 */
105u32 cm_get_file_size(FILE * file);
106
107#ifndef ACPI_DUMP_APP
108/*
109 * adisasm
110 */
111acpi_status
112ad_aml_disassemble(u8 out_to_file,
113 char *filename, char *prefix, char **out_filename);
114
115void ad_print_statistics(void);
116
117acpi_status ad_find_dsdt(u8 **dsdt_ptr, u32 *dsdt_length);
118
119void ad_dump_tables(void);
120
121acpi_status ad_get_local_tables(void);
122
123acpi_status
124ad_parse_table(struct acpi_table_header *table,
125 acpi_owner_id * owner_id, u8 load_table, u8 external);
126
127acpi_status ad_display_tables(char *filename, struct acpi_table_header *table);
128
129acpi_status ad_display_statistics(void);
130
131/*
132 * adwalk
133 */
134void
135acpi_dm_cross_reference_namespace(union acpi_parse_object *parse_tree_root,
136 struct acpi_namespace_node *namespace_root,
137 acpi_owner_id owner_id);
138
139void acpi_dm_dump_tree(union acpi_parse_object *origin);
140
141void acpi_dm_find_orphan_methods(union acpi_parse_object *origin);
142
143void
144acpi_dm_finish_namespace_load(union acpi_parse_object *parse_tree_root,
145 struct acpi_namespace_node *namespace_root,
146 acpi_owner_id owner_id);
147
148void
149acpi_dm_convert_resource_indexes(union acpi_parse_object *parse_tree_root,
150 struct acpi_namespace_node *namespace_root);
151
152/*
153 * adfile
154 */
155acpi_status ad_initialize(void);
156
157char *fl_generate_filename(char *input_filename, char *suffix);
158
159acpi_status
160fl_split_input_pathname(char *input_path,
161 char **out_directory_path, char **out_filename);
162
163char *ad_generate_filename(char *prefix, char *table_id);
164
165void
166ad_write_table(struct acpi_table_header *table,
167 u32 length, char *table_name, char *oem_table_id);
168#endif
169
170#endif /* _ACAPPS */
diff --git a/tools/power/acpi/common/getopt.c b/tools/power/acpi/common/getopt.c
new file mode 100644
index 000000000000..a302f52e4fd3
--- /dev/null
+++ b/tools/power/acpi/common/getopt.c
@@ -0,0 +1,239 @@
1/******************************************************************************
2 *
3 * Module Name: getopt
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, 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/*
45 * ACPICA getopt() implementation
46 *
47 * Option strings:
48 * "f" - Option has no arguments
49 * "f:" - Option requires an argument
50 * "f^" - Option has optional single-char sub-options
51 * "f|" - Option has required single-char sub-options
52 */
53
54#include <stdio.h>
55#include <string.h>
56#include <acpi/acpi.h>
57#include "accommon.h"
58#include "acapps.h"
59
60#define ACPI_OPTION_ERROR(msg, badchar) \
61 if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
62
63int acpi_gbl_opterr = 1;
64int acpi_gbl_optind = 1;
65int acpi_gbl_sub_opt_char = 0;
66char *acpi_gbl_optarg;
67
68static int current_char_ptr = 1;
69
70/*******************************************************************************
71 *
72 * FUNCTION: acpi_getopt_argument
73 *
74 * PARAMETERS: argc, argv - from main
75 *
76 * RETURN: 0 if an argument was found, -1 otherwise. Sets acpi_gbl_Optarg
77 * to point to the next argument.
78 *
79 * DESCRIPTION: Get the next argument. Used to obtain arguments for the
80 * two-character options after the original call to acpi_getopt.
81 * Note: Either the argument starts at the next character after
82 * the option, or it is pointed to by the next argv entry.
83 * (After call to acpi_getopt, we need to backup to the previous
84 * argv entry).
85 *
86 ******************************************************************************/
87
88int acpi_getopt_argument(int argc, char **argv)
89{
90 acpi_gbl_optind--;
91 current_char_ptr++;
92
93 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
94 acpi_gbl_optarg =
95 &argv[acpi_gbl_optind++][(int)(current_char_ptr + 1)];
96 } else if (++acpi_gbl_optind >= argc) {
97 ACPI_OPTION_ERROR("Option requires an argument: -", 'v');
98
99 current_char_ptr = 1;
100 return (-1);
101 } else {
102 acpi_gbl_optarg = argv[acpi_gbl_optind++];
103 }
104
105 current_char_ptr = 1;
106 return (0);
107}
108
109/*******************************************************************************
110 *
111 * FUNCTION: acpi_getopt
112 *
113 * PARAMETERS: argc, argv - from main
114 * opts - options info list
115 *
116 * RETURN: Option character or EOF
117 *
118 * DESCRIPTION: Get the next option
119 *
120 ******************************************************************************/
121
122int acpi_getopt(int argc, char **argv, char *opts)
123{
124 int current_char;
125 char *opts_ptr;
126
127 if (current_char_ptr == 1) {
128 if (acpi_gbl_optind >= argc ||
129 argv[acpi_gbl_optind][0] != '-' ||
130 argv[acpi_gbl_optind][1] == '\0') {
131 return (EOF);
132 } else if (strcmp(argv[acpi_gbl_optind], "--") == 0) {
133 acpi_gbl_optind++;
134 return (EOF);
135 }
136 }
137
138 /* Get the option */
139
140 current_char = argv[acpi_gbl_optind][current_char_ptr];
141
142 /* Make sure that the option is legal */
143
144 if (current_char == ':' ||
145 (opts_ptr = strchr(opts, current_char)) == NULL) {
146 ACPI_OPTION_ERROR("Illegal option: -", current_char);
147
148 if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
149 acpi_gbl_optind++;
150 current_char_ptr = 1;
151 }
152
153 return ('?');
154 }
155
156 /* Option requires an argument? */
157
158 if (*++opts_ptr == ':') {
159 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
160 acpi_gbl_optarg =
161 &argv[acpi_gbl_optind++][(int)
162 (current_char_ptr + 1)];
163 } else if (++acpi_gbl_optind >= argc) {
164 ACPI_OPTION_ERROR("Option requires an argument: -",
165 current_char);
166
167 current_char_ptr = 1;
168 return ('?');
169 } else {
170 acpi_gbl_optarg = argv[acpi_gbl_optind++];
171 }
172
173 current_char_ptr = 1;
174 }
175
176 /* Option has an optional argument? */
177
178 else if (*opts_ptr == '+') {
179 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
180 acpi_gbl_optarg =
181 &argv[acpi_gbl_optind++][(int)
182 (current_char_ptr + 1)];
183 } else if (++acpi_gbl_optind >= argc) {
184 acpi_gbl_optarg = NULL;
185 } else {
186 acpi_gbl_optarg = argv[acpi_gbl_optind++];
187 }
188
189 current_char_ptr = 1;
190 }
191
192 /* Option has optional single-char arguments? */
193
194 else if (*opts_ptr == '^') {
195 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
196 acpi_gbl_optarg =
197 &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
198 } else {
199 acpi_gbl_optarg = "^";
200 }
201
202 acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
203 acpi_gbl_optind++;
204 current_char_ptr = 1;
205 }
206
207 /* Option has a required single-char argument? */
208
209 else if (*opts_ptr == '|') {
210 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
211 acpi_gbl_optarg =
212 &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
213 } else {
214 ACPI_OPTION_ERROR
215 ("Option requires a single-character suboption: -",
216 current_char);
217
218 current_char_ptr = 1;
219 return ('?');
220 }
221
222 acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
223 acpi_gbl_optind++;
224 current_char_ptr = 1;
225 }
226
227 /* Option with no arguments */
228
229 else {
230 if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
231 current_char_ptr = 1;
232 acpi_gbl_optind++;
233 }
234
235 acpi_gbl_optarg = NULL;
236 }
237
238 return (current_char);
239}
diff --git a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
new file mode 100644
index 000000000000..e975aa90016a
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
@@ -0,0 +1,1275 @@
1/******************************************************************************
2 *
3 * Module Name: oslinuxtbl - Linux OSL for obtaining ACPI tables
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, 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#define _COMPONENT ACPI_OS_SERVICES
47ACPI_MODULE_NAME("oslinuxtbl")
48
49#ifndef PATH_MAX
50#define PATH_MAX 256
51#endif
52/* List of information about obtained ACPI tables */
53typedef struct osl_table_info {
54 struct osl_table_info *next;
55 u32 instance;
56 char signature[ACPI_NAME_SIZE];
57
58} osl_table_info;
59
60/* Local prototypes */
61
62static acpi_status osl_table_initialize(void);
63
64static acpi_status
65osl_table_name_from_file(char *filename, char *signature, u32 *instance);
66
67static acpi_status osl_add_table_to_list(char *signature, u32 instance);
68
69static acpi_status
70osl_read_table_from_file(char *filename,
71 acpi_size file_offset,
72 char *signature, struct acpi_table_header **table);
73
74static acpi_status
75osl_map_table(acpi_size address,
76 char *signature, struct acpi_table_header **table);
77
78static void osl_unmap_table(struct acpi_table_header *table);
79
80static acpi_physical_address osl_find_rsdp_via_efi(void);
81
82static acpi_status osl_load_rsdp(void);
83
84static acpi_status osl_list_customized_tables(char *directory);
85
86static acpi_status
87osl_get_customized_table(char *pathname,
88 char *signature,
89 u32 instance,
90 struct acpi_table_header **table,
91 acpi_physical_address * address);
92
93static acpi_status osl_list_bios_tables(void);
94
95static acpi_status
96osl_get_bios_table(char *signature,
97 u32 instance,
98 struct acpi_table_header **table,
99 acpi_physical_address * address);
100
101static acpi_status osl_get_last_status(acpi_status default_status);
102
103/* File locations */
104
105#define DYNAMIC_TABLE_DIR "/sys/firmware/acpi/tables/dynamic"
106#define STATIC_TABLE_DIR "/sys/firmware/acpi/tables"
107#define EFI_SYSTAB "/sys/firmware/efi/systab"
108
109/* Should we get dynamically loaded SSDTs from DYNAMIC_TABLE_DIR? */
110
111u8 gbl_dump_dynamic_tables = TRUE;
112
113/* Initialization flags */
114
115u8 gbl_table_list_initialized = FALSE;
116
117/* Local copies of main ACPI tables */
118
119struct acpi_table_rsdp gbl_rsdp;
120struct acpi_table_fadt *gbl_fadt = NULL;
121struct acpi_table_rsdt *gbl_rsdt = NULL;
122struct acpi_table_xsdt *gbl_xsdt = NULL;
123
124/* Table addresses */
125
126acpi_physical_address gbl_fadt_address = 0;
127acpi_physical_address gbl_rsdp_address = 0;
128
129/* Revision of RSD PTR */
130
131u8 gbl_revision = 0;
132
133struct osl_table_info *gbl_table_list_head = NULL;
134u32 gbl_table_count = 0;
135
136/******************************************************************************
137 *
138 * FUNCTION: osl_get_last_status
139 *
140 * PARAMETERS: default_status - Default error status to return
141 *
142 * RETURN: Status; Converted from errno.
143 *
144 * DESCRIPTION: Get last errno and conver it to acpi_status.
145 *
146 *****************************************************************************/
147
148static acpi_status osl_get_last_status(acpi_status default_status)
149{
150
151 switch (errno) {
152 case EACCES:
153 case EPERM:
154
155 return (AE_ACCESS);
156
157 case ENOENT:
158
159 return (AE_NOT_FOUND);
160
161 case ENOMEM:
162
163 return (AE_NO_MEMORY);
164
165 default:
166
167 return (default_status);
168 }
169}
170
171/******************************************************************************
172 *
173 * FUNCTION: acpi_os_get_table_by_address
174 *
175 * PARAMETERS: address - Physical address of the ACPI table
176 * table - Where a pointer to the table is returned
177 *
178 * RETURN: Status; Table buffer is returned if AE_OK.
179 * AE_NOT_FOUND: A valid table was not found at the address
180 *
181 * DESCRIPTION: Get an ACPI table via a physical memory address.
182 *
183 *****************************************************************************/
184
185acpi_status
186acpi_os_get_table_by_address(acpi_physical_address address,
187 struct acpi_table_header ** table)
188{
189 u32 table_length;
190 struct acpi_table_header *mapped_table;
191 struct acpi_table_header *local_table = NULL;
192 acpi_status status = AE_OK;
193
194 /* Get main ACPI tables from memory on first invocation of this function */
195
196 status = osl_table_initialize();
197 if (ACPI_FAILURE(status)) {
198 return (status);
199 }
200
201 /* Map the table and validate it */
202
203 status = osl_map_table(address, NULL, &mapped_table);
204 if (ACPI_FAILURE(status)) {
205 return (status);
206 }
207
208 /* Copy table to local buffer and return it */
209
210 table_length = ap_get_table_length(mapped_table);
211 if (table_length == 0) {
212 status = AE_BAD_HEADER;
213 goto exit;
214 }
215
216 local_table = calloc(1, table_length);
217 if (!local_table) {
218 status = AE_NO_MEMORY;
219 goto exit;
220 }
221
222 ACPI_MEMCPY(local_table, mapped_table, table_length);
223
224exit:
225 osl_unmap_table(mapped_table);
226 *table = local_table;
227 return (status);
228}
229
230/******************************************************************************
231 *
232 * FUNCTION: acpi_os_get_table_by_name
233 *
234 * PARAMETERS: signature - ACPI Signature for desired table. Must be
235 * a null terminated 4-character string.
236 * instance - Multiple table support for SSDT/UEFI (0...n)
237 * Must be 0 for other tables.
238 * table - Where a pointer to the table is returned
239 * address - Where the table physical address is returned
240 *
241 * RETURN: Status; Table buffer and physical address returned if AE_OK.
242 * AE_LIMIT: Instance is beyond valid limit
243 * AE_NOT_FOUND: A table with the signature was not found
244 *
245 * NOTE: Assumes the input signature is uppercase.
246 *
247 *****************************************************************************/
248
249acpi_status
250acpi_os_get_table_by_name(char *signature,
251 u32 instance,
252 struct acpi_table_header ** table,
253 acpi_physical_address * address)
254{
255 acpi_status status;
256
257 /* Get main ACPI tables from memory on first invocation of this function */
258
259 status = osl_table_initialize();
260 if (ACPI_FAILURE(status)) {
261 return (status);
262 }
263
264 /* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */
265
266 if (!gbl_dump_customized_tables) {
267
268 /* Attempt to get the table from the memory */
269
270 status =
271 osl_get_bios_table(signature, instance, table, address);
272 } else {
273 /* Attempt to get the table from the static directory */
274
275 status = osl_get_customized_table(STATIC_TABLE_DIR, signature,
276 instance, table, address);
277 }
278
279 if (ACPI_FAILURE(status) && status == AE_LIMIT) {
280 if (gbl_dump_dynamic_tables) {
281
282 /* Attempt to get a dynamic table */
283
284 status =
285 osl_get_customized_table(DYNAMIC_TABLE_DIR,
286 signature, instance, table,
287 address);
288 }
289 }
290
291 return (status);
292}
293
294/******************************************************************************
295 *
296 * FUNCTION: osl_add_table_to_list
297 *
298 * PARAMETERS: signature - Table signature
299 * instance - Table instance
300 *
301 * RETURN: Status; Successfully added if AE_OK.
302 * AE_NO_MEMORY: Memory allocation error
303 *
304 * DESCRIPTION: Insert a table structure into OSL table list.
305 *
306 *****************************************************************************/
307
308static acpi_status osl_add_table_to_list(char *signature, u32 instance)
309{
310 struct osl_table_info *new_info;
311 struct osl_table_info *next;
312 u32 next_instance = 0;
313 u8 found = FALSE;
314
315 new_info = calloc(1, sizeof(struct osl_table_info));
316 if (!new_info) {
317 return (AE_NO_MEMORY);
318 }
319
320 ACPI_MOVE_NAME(new_info->signature, signature);
321
322 if (!gbl_table_list_head) {
323 gbl_table_list_head = new_info;
324 } else {
325 next = gbl_table_list_head;
326 while (1) {
327 if (ACPI_COMPARE_NAME(next->signature, signature)) {
328 if (next->instance == instance) {
329 found = TRUE;
330 }
331 if (next->instance >= next_instance) {
332 next_instance = next->instance + 1;
333 }
334 }
335
336 if (!next->next) {
337 break;
338 }
339 next = next->next;
340 }
341 next->next = new_info;
342 }
343
344 if (found) {
345 if (instance) {
346 fprintf(stderr,
347 "%4.4s: Warning unmatched table instance %d, expected %d\n",
348 signature, instance, next_instance);
349 }
350 instance = next_instance;
351 }
352
353 new_info->instance = instance;
354 gbl_table_count++;
355
356 return (AE_OK);
357}
358
359/******************************************************************************
360 *
361 * FUNCTION: acpi_os_get_table_by_index
362 *
363 * PARAMETERS: index - Which table to get
364 * table - Where a pointer to the table is returned
365 * instance - Where a pointer to the table instance no. is
366 * returned
367 * address - Where the table physical address is returned
368 *
369 * RETURN: Status; Table buffer and physical address returned if AE_OK.
370 * AE_LIMIT: Index is beyond valid limit
371 *
372 * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns
373 * AE_LIMIT when an invalid index is reached. Index is not
374 * necessarily an index into the RSDT/XSDT.
375 *
376 *****************************************************************************/
377
378acpi_status
379acpi_os_get_table_by_index(u32 index,
380 struct acpi_table_header ** table,
381 u32 *instance, acpi_physical_address * address)
382{
383 struct osl_table_info *info;
384 acpi_status status;
385 u32 i;
386
387 /* Get main ACPI tables from memory on first invocation of this function */
388
389 status = osl_table_initialize();
390 if (ACPI_FAILURE(status)) {
391 return (status);
392 }
393
394 /* Validate Index */
395
396 if (index >= gbl_table_count) {
397 return (AE_LIMIT);
398 }
399
400 /* Point to the table list entry specified by the Index argument */
401
402 info = gbl_table_list_head;
403 for (i = 0; i < index; i++) {
404 info = info->next;
405 }
406
407 /* Now we can just get the table via the signature */
408
409 status = acpi_os_get_table_by_name(info->signature, info->instance,
410 table, address);
411
412 if (ACPI_SUCCESS(status)) {
413 *instance = info->instance;
414 }
415 return (status);
416}
417
418/******************************************************************************
419 *
420 * FUNCTION: osl_find_rsdp_via_efi
421 *
422 * PARAMETERS: None
423 *
424 * RETURN: RSDP address if found
425 *
426 * DESCRIPTION: Find RSDP address via EFI.
427 *
428 *****************************************************************************/
429
430static acpi_physical_address osl_find_rsdp_via_efi(void)
431{
432 FILE *file;
433 char buffer[80];
434 unsigned long address = 0;
435
436 file = fopen(EFI_SYSTAB, "r");
437 if (file) {
438 while (fgets(buffer, 80, file)) {
439 if (sscanf(buffer, "ACPI20=0x%lx", &address) == 1) {
440 break;
441 }
442 }
443 fclose(file);
444 }
445
446 return ((acpi_physical_address) (address));
447}
448
449/******************************************************************************
450 *
451 * FUNCTION: osl_load_rsdp
452 *
453 * PARAMETERS: None
454 *
455 * RETURN: Status
456 *
457 * DESCRIPTION: Scan and load RSDP.
458 *
459 *****************************************************************************/
460
461static acpi_status osl_load_rsdp(void)
462{
463 struct acpi_table_header *mapped_table;
464 u8 *rsdp_address;
465 acpi_physical_address rsdp_base;
466 acpi_size rsdp_size;
467
468 /* Get RSDP from memory */
469
470 rsdp_size = sizeof(struct acpi_table_rsdp);
471 if (gbl_rsdp_base) {
472 rsdp_base = gbl_rsdp_base;
473 } else {
474 rsdp_base = osl_find_rsdp_via_efi();
475 }
476
477 if (!rsdp_base) {
478 rsdp_base = ACPI_HI_RSDP_WINDOW_BASE;
479 rsdp_size = ACPI_HI_RSDP_WINDOW_SIZE;
480 }
481
482 rsdp_address = acpi_os_map_memory(rsdp_base, rsdp_size);
483 if (!rsdp_address) {
484 return (osl_get_last_status(AE_BAD_ADDRESS));
485 }
486
487 /* Search low memory for the RSDP */
488
489 mapped_table = ACPI_CAST_PTR(struct acpi_table_header,
490 acpi_tb_scan_memory_for_rsdp(rsdp_address,
491 rsdp_size));
492 if (!mapped_table) {
493 acpi_os_unmap_memory(rsdp_address, rsdp_size);
494 return (AE_NOT_FOUND);
495 }
496
497 gbl_rsdp_address =
498 rsdp_base + (ACPI_CAST8(mapped_table) - rsdp_address);
499
500 ACPI_MEMCPY(&gbl_rsdp, mapped_table, sizeof(struct acpi_table_rsdp));
501 acpi_os_unmap_memory(rsdp_address, rsdp_size);
502
503 return (AE_OK);
504}
505
506/******************************************************************************
507 *
508 * FUNCTION: osl_table_initialize
509 *
510 * PARAMETERS: None
511 *
512 * RETURN: Status
513 *
514 * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to
515 * local variables. Main ACPI tables include RSDT, FADT, RSDT,
516 * and/or XSDT.
517 *
518 *****************************************************************************/
519
520static acpi_status osl_table_initialize(void)
521{
522 acpi_status status;
523 acpi_physical_address address;
524
525 if (gbl_table_list_initialized) {
526 return (AE_OK);
527 }
528
529 /* Get RSDP from memory */
530
531 status = osl_load_rsdp();
532 if (ACPI_FAILURE(status)) {
533 return (status);
534 }
535
536 /* Get XSDT from memory */
537
538 if (gbl_rsdp.revision) {
539 if (gbl_xsdt) {
540 free(gbl_xsdt);
541 gbl_xsdt = NULL;
542 }
543
544 gbl_revision = 2;
545 status = osl_get_bios_table(ACPI_SIG_XSDT, 0,
546 ACPI_CAST_PTR(struct
547 acpi_table_header *,
548 &gbl_xsdt), &address);
549 if (ACPI_FAILURE(status)) {
550 return (status);
551 }
552 }
553
554 /* Get RSDT from memory */
555
556 if (gbl_rsdp.rsdt_physical_address) {
557 if (gbl_rsdt) {
558 free(gbl_rsdt);
559 gbl_rsdt = NULL;
560 }
561
562 status = osl_get_bios_table(ACPI_SIG_RSDT, 0,
563 ACPI_CAST_PTR(struct
564 acpi_table_header *,
565 &gbl_rsdt), &address);
566 if (ACPI_FAILURE(status)) {
567 return (status);
568 }
569 }
570
571 /* Get FADT from memory */
572
573 if (gbl_fadt) {
574 free(gbl_fadt);
575 gbl_fadt = NULL;
576 }
577
578 status = osl_get_bios_table(ACPI_SIG_FADT, 0,
579 ACPI_CAST_PTR(struct acpi_table_header *,
580 &gbl_fadt),
581 &gbl_fadt_address);
582 if (ACPI_FAILURE(status)) {
583 return (status);
584 }
585
586 if (!gbl_dump_customized_tables) {
587
588 /* Add mandatory tables to global table list first */
589
590 status = osl_add_table_to_list(ACPI_RSDP_NAME, 0);
591 if (ACPI_FAILURE(status)) {
592 return (status);
593 }
594
595 status = osl_add_table_to_list(ACPI_SIG_RSDT, 0);
596 if (ACPI_FAILURE(status)) {
597 return (status);
598 }
599
600 if (gbl_revision == 2) {
601 status = osl_add_table_to_list(ACPI_SIG_XSDT, 0);
602 if (ACPI_FAILURE(status)) {
603 return (status);
604 }
605 }
606
607 status = osl_add_table_to_list(ACPI_SIG_DSDT, 0);
608 if (ACPI_FAILURE(status)) {
609 return (status);
610 }
611
612 status = osl_add_table_to_list(ACPI_SIG_FACS, 0);
613 if (ACPI_FAILURE(status)) {
614 return (status);
615 }
616
617 /* Add all tables found in the memory */
618
619 status = osl_list_bios_tables();
620 if (ACPI_FAILURE(status)) {
621 return (status);
622 }
623 } else {
624 /* Add all tables found in the static directory */
625
626 status = osl_list_customized_tables(STATIC_TABLE_DIR);
627 if (ACPI_FAILURE(status)) {
628 return (status);
629 }
630 }
631
632 if (gbl_dump_dynamic_tables) {
633
634 /* Add all dynamically loaded tables in the dynamic directory */
635
636 status = osl_list_customized_tables(DYNAMIC_TABLE_DIR);
637 if (ACPI_FAILURE(status)) {
638 return (status);
639 }
640 }
641
642 gbl_table_list_initialized = TRUE;
643 return (AE_OK);
644}
645
646/******************************************************************************
647 *
648 * FUNCTION: osl_list_bios_tables
649 *
650 * PARAMETERS: None
651 *
652 * RETURN: Status; Table list is initialized if AE_OK.
653 *
654 * DESCRIPTION: Add ACPI tables to the table list from memory.
655 *
656 * NOTE: This works on Linux as table customization does not modify the
657 * addresses stored in RSDP/RSDT/XSDT/FADT.
658 *
659 *****************************************************************************/
660
661static acpi_status osl_list_bios_tables(void)
662{
663 struct acpi_table_header *mapped_table = NULL;
664 u8 *table_data;
665 u8 number_of_tables;
666 u8 item_size;
667 acpi_physical_address table_address = 0;
668 acpi_status status = AE_OK;
669 u32 i;
670
671 if (gbl_revision) {
672 item_size = sizeof(u64);
673 table_data =
674 ACPI_CAST8(gbl_xsdt) + sizeof(struct acpi_table_header);
675 number_of_tables =
676 (u8)((gbl_xsdt->header.length -
677 sizeof(struct acpi_table_header))
678 / item_size);
679 } else { /* Use RSDT if XSDT is not available */
680
681 item_size = sizeof(u32);
682 table_data =
683 ACPI_CAST8(gbl_rsdt) + sizeof(struct acpi_table_header);
684 number_of_tables =
685 (u8)((gbl_rsdt->header.length -
686 sizeof(struct acpi_table_header))
687 / item_size);
688 }
689
690 /* Search RSDT/XSDT for the requested table */
691
692 for (i = 0; i < number_of_tables; ++i, table_data += item_size) {
693 if (gbl_revision) {
694 table_address =
695 (acpi_physical_address) (*ACPI_CAST64(table_data));
696 } else {
697 table_address =
698 (acpi_physical_address) (*ACPI_CAST32(table_data));
699 }
700
701 status = osl_map_table(table_address, NULL, &mapped_table);
702 if (ACPI_FAILURE(status)) {
703 return (status);
704 }
705
706 osl_add_table_to_list(mapped_table->signature, 0);
707 osl_unmap_table(mapped_table);
708 }
709
710 return (AE_OK);
711}
712
713/******************************************************************************
714 *
715 * FUNCTION: osl_get_bios_table
716 *
717 * PARAMETERS: signature - ACPI Signature for common table. Must be
718 * a null terminated 4-character string.
719 * instance - Multiple table support for SSDT/UEFI (0...n)
720 * Must be 0 for other tables.
721 * table - Where a pointer to the table is returned
722 * address - Where the table physical address is returned
723 *
724 * RETURN: Status; Table buffer and physical address returned if AE_OK.
725 * AE_LIMIT: Instance is beyond valid limit
726 * AE_NOT_FOUND: A table with the signature was not found
727 *
728 * DESCRIPTION: Get a BIOS provided ACPI table
729 *
730 * NOTE: Assumes the input signature is uppercase.
731 *
732 *****************************************************************************/
733
734static acpi_status
735osl_get_bios_table(char *signature,
736 u32 instance,
737 struct acpi_table_header **table,
738 acpi_physical_address * address)
739{
740 struct acpi_table_header *local_table = NULL;
741 struct acpi_table_header *mapped_table = NULL;
742 u8 *table_data;
743 u8 number_of_tables;
744 u8 item_size;
745 u32 current_instance = 0;
746 acpi_physical_address table_address = 0;
747 u32 table_length = 0;
748 acpi_status status = AE_OK;
749 u32 i;
750
751 /* Handle special tables whose addresses are not in RSDT/XSDT */
752
753 if (ACPI_COMPARE_NAME(signature, ACPI_RSDP_NAME) ||
754 ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT) ||
755 ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT) ||
756 ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT) ||
757 ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) {
758 /*
759 * Get the appropriate address, either 32-bit or 64-bit. Be very
760 * careful about the FADT length and validate table addresses.
761 * Note: The 64-bit addresses have priority.
762 */
763 if (ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT)) {
764 if ((gbl_fadt->header.length >= MIN_FADT_FOR_XDSDT) &&
765 gbl_fadt->Xdsdt) {
766 table_address =
767 (acpi_physical_address) gbl_fadt->Xdsdt;
768 } else
769 if ((gbl_fadt->header.length >= MIN_FADT_FOR_DSDT)
770 && gbl_fadt->dsdt) {
771 table_address =
772 (acpi_physical_address) gbl_fadt->dsdt;
773 }
774 } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) {
775 if ((gbl_fadt->header.length >= MIN_FADT_FOR_XFACS) &&
776 gbl_fadt->Xfacs) {
777 table_address =
778 (acpi_physical_address) gbl_fadt->Xfacs;
779 } else
780 if ((gbl_fadt->header.length >= MIN_FADT_FOR_FACS)
781 && gbl_fadt->facs) {
782 table_address =
783 (acpi_physical_address) gbl_fadt->facs;
784 }
785 } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT)) {
786 if (!gbl_revision) {
787 return (AE_BAD_SIGNATURE);
788 }
789 table_address =
790 (acpi_physical_address) gbl_rsdp.
791 xsdt_physical_address;
792 } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT)) {
793 table_address =
794 (acpi_physical_address) gbl_rsdp.
795 rsdt_physical_address;
796 } else {
797 table_address =
798 (acpi_physical_address) gbl_rsdp_address;
799 signature = ACPI_SIG_RSDP;
800 }
801
802 /* Now we can get the requested special table */
803
804 status = osl_map_table(table_address, signature, &mapped_table);
805 if (ACPI_FAILURE(status)) {
806 return (status);
807 }
808
809 table_length = ap_get_table_length(mapped_table);
810 } else { /* Case for a normal ACPI table */
811
812 if (gbl_revision) {
813 item_size = sizeof(u64);
814 table_data =
815 ACPI_CAST8(gbl_xsdt) +
816 sizeof(struct acpi_table_header);
817 number_of_tables =
818 (u8)((gbl_xsdt->header.length -
819 sizeof(struct acpi_table_header))
820 / item_size);
821 } else { /* Use RSDT if XSDT is not available */
822
823 item_size = sizeof(u32);
824 table_data =
825 ACPI_CAST8(gbl_rsdt) +
826 sizeof(struct acpi_table_header);
827 number_of_tables =
828 (u8)((gbl_rsdt->header.length -
829 sizeof(struct acpi_table_header))
830 / item_size);
831 }
832
833 /* Search RSDT/XSDT for the requested table */
834
835 for (i = 0; i < number_of_tables; ++i, table_data += item_size) {
836 if (gbl_revision) {
837 table_address =
838 (acpi_physical_address) (*ACPI_CAST64
839 (table_data));
840 } else {
841 table_address =
842 (acpi_physical_address) (*ACPI_CAST32
843 (table_data));
844 }
845
846 status =
847 osl_map_table(table_address, NULL, &mapped_table);
848 if (ACPI_FAILURE(status)) {
849 return (status);
850 }
851 table_length = mapped_table->length;
852
853 /* Does this table match the requested signature? */
854
855 if (!ACPI_COMPARE_NAME
856 (mapped_table->signature, signature)) {
857 osl_unmap_table(mapped_table);
858 mapped_table = NULL;
859 continue;
860 }
861
862 /* Match table instance (for SSDT/UEFI tables) */
863
864 if (current_instance != instance) {
865 osl_unmap_table(mapped_table);
866 mapped_table = NULL;
867 current_instance++;
868 continue;
869 }
870
871 break;
872 }
873 }
874
875 if (!mapped_table) {
876 return (AE_LIMIT);
877 }
878
879 if (table_length == 0) {
880 status = AE_BAD_HEADER;
881 goto exit;
882 }
883
884 /* Copy table to local buffer and return it */
885
886 local_table = calloc(1, table_length);
887 if (!local_table) {
888 status = AE_NO_MEMORY;
889 goto exit;
890 }
891
892 ACPI_MEMCPY(local_table, mapped_table, table_length);
893 *address = table_address;
894 *table = local_table;
895
896exit:
897 osl_unmap_table(mapped_table);
898 return (status);
899}
900
901/******************************************************************************
902 *
903 * FUNCTION: osl_list_customized_tables
904 *
905 * PARAMETERS: directory - Directory that contains the tables
906 *
907 * RETURN: Status; Table list is initialized if AE_OK.
908 *
909 * DESCRIPTION: Add ACPI tables to the table list from a directory.
910 *
911 *****************************************************************************/
912
913static acpi_status osl_list_customized_tables(char *directory)
914{
915 void *table_dir;
916 u32 instance;
917 char temp_name[ACPI_NAME_SIZE];
918 char *filename;
919 acpi_status status = AE_OK;
920
921 /* Open the requested directory */
922
923 table_dir = acpi_os_open_directory(directory, "*", REQUEST_FILE_ONLY);
924 if (!table_dir) {
925 return (osl_get_last_status(AE_NOT_FOUND));
926 }
927
928 /* Examine all entries in this directory */
929
930 while ((filename = acpi_os_get_next_filename(table_dir))) {
931
932 /* Extract table name and instance number */
933
934 status =
935 osl_table_name_from_file(filename, temp_name, &instance);
936
937 /* Ignore meaningless files */
938
939 if (ACPI_FAILURE(status)) {
940 continue;
941 }
942
943 /* Add new info node to global table list */
944
945 status = osl_add_table_to_list(temp_name, instance);
946 if (ACPI_FAILURE(status)) {
947 break;
948 }
949 }
950
951 acpi_os_close_directory(table_dir);
952 return (status);
953}
954
955/******************************************************************************
956 *
957 * FUNCTION: osl_map_table
958 *
959 * PARAMETERS: address - Address of the table in memory
960 * signature - Optional ACPI Signature for desired table.
961 * Null terminated 4-character string.
962 * table - Where a pointer to the mapped table is
963 * returned
964 *
965 * RETURN: Status; Mapped table is returned if AE_OK.
966 * AE_NOT_FOUND: A valid table was not found at the address
967 *
968 * DESCRIPTION: Map entire ACPI table into caller's address space.
969 *
970 *****************************************************************************/
971
972static acpi_status
973osl_map_table(acpi_size address,
974 char *signature, struct acpi_table_header **table)
975{
976 struct acpi_table_header *mapped_table;
977 u32 length;
978
979 if (!address) {
980 return (AE_BAD_ADDRESS);
981 }
982
983 /*
984 * Map the header so we can get the table length.
985 * Use sizeof (struct acpi_table_header) as:
986 * 1. it is bigger than 24 to include RSDP->Length
987 * 2. it is smaller than sizeof (struct acpi_table_rsdp)
988 */
989 mapped_table =
990 acpi_os_map_memory(address, sizeof(struct acpi_table_header));
991 if (!mapped_table) {
992 fprintf(stderr, "Could not map table header at 0x%8.8X%8.8X\n",
993 ACPI_FORMAT_UINT64(address));
994 return (osl_get_last_status(AE_BAD_ADDRESS));
995 }
996
997 /* If specified, signature must match */
998
999 if (signature && !ACPI_COMPARE_NAME(signature, mapped_table->signature)) {
1000 acpi_os_unmap_memory(mapped_table,
1001 sizeof(struct acpi_table_header));
1002 return (AE_BAD_SIGNATURE);
1003 }
1004
1005 /* Map the entire table */
1006
1007 length = ap_get_table_length(mapped_table);
1008 acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
1009 if (length == 0) {
1010 return (AE_BAD_HEADER);
1011 }
1012
1013 mapped_table = acpi_os_map_memory(address, length);
1014 if (!mapped_table) {
1015 fprintf(stderr,
1016 "Could not map table at 0x%8.8X%8.8X length %8.8X\n",
1017 ACPI_FORMAT_UINT64(address), length);
1018 return (osl_get_last_status(AE_INVALID_TABLE_LENGTH));
1019 }
1020
1021 (void)ap_is_valid_checksum(mapped_table);
1022
1023 *table = mapped_table;
1024 return (AE_OK);
1025}
1026
1027/******************************************************************************
1028 *
1029 * FUNCTION: osl_unmap_table
1030 *
1031 * PARAMETERS: table - A pointer to the mapped table
1032 *
1033 * RETURN: None
1034 *
1035 * DESCRIPTION: Unmap entire ACPI table.
1036 *
1037 *****************************************************************************/
1038
1039static void osl_unmap_table(struct acpi_table_header *table)
1040{
1041 if (table) {
1042 acpi_os_unmap_memory(table, ap_get_table_length(table));
1043 }
1044}
1045
1046/******************************************************************************
1047 *
1048 * FUNCTION: osl_table_name_from_file
1049 *
1050 * PARAMETERS: filename - File that contains the desired table
1051 * signature - Pointer to 4-character buffer to store
1052 * extracted table signature.
1053 * instance - Pointer to integer to store extracted
1054 * table instance number.
1055 *
1056 * RETURN: Status; Table name is extracted if AE_OK.
1057 *
1058 * DESCRIPTION: Extract table signature and instance number from a table file
1059 * name.
1060 *
1061 *****************************************************************************/
1062
1063static acpi_status
1064osl_table_name_from_file(char *filename, char *signature, u32 *instance)
1065{
1066
1067 /* Ignore meaningless files */
1068
1069 if (strlen(filename) < ACPI_NAME_SIZE) {
1070 return (AE_BAD_SIGNATURE);
1071 }
1072
1073 /* Extract instance number */
1074
1075 if (isdigit((int)filename[ACPI_NAME_SIZE])) {
1076 sscanf(&filename[ACPI_NAME_SIZE], "%d", instance);
1077 } else if (strlen(filename) != ACPI_NAME_SIZE) {
1078 return (AE_BAD_SIGNATURE);
1079 } else {
1080 *instance = 0;
1081 }
1082
1083 /* Extract signature */
1084
1085 ACPI_MOVE_NAME(signature, filename);
1086 return (AE_OK);
1087}
1088
1089/******************************************************************************
1090 *
1091 * FUNCTION: osl_read_table_from_file
1092 *
1093 * PARAMETERS: filename - File that contains the desired table
1094 * file_offset - Offset of the table in file
1095 * signature - Optional ACPI Signature for desired table.
1096 * A null terminated 4-character string.
1097 * table - Where a pointer to the table is returned
1098 *
1099 * RETURN: Status; Table buffer is returned if AE_OK.
1100 *
1101 * DESCRIPTION: Read a ACPI table from a file.
1102 *
1103 *****************************************************************************/
1104
1105static acpi_status
1106osl_read_table_from_file(char *filename,
1107 acpi_size file_offset,
1108 char *signature, struct acpi_table_header **table)
1109{
1110 FILE *table_file;
1111 struct acpi_table_header header;
1112 struct acpi_table_header *local_table = NULL;
1113 u32 table_length;
1114 s32 count;
1115 u32 total = 0;
1116 acpi_status status = AE_OK;
1117
1118 /* Open the file */
1119
1120 table_file = fopen(filename, "rb");
1121 if (table_file == NULL) {
1122 fprintf(stderr, "Could not open table file: %s\n", filename);
1123 return (osl_get_last_status(AE_NOT_FOUND));
1124 }
1125
1126 fseek(table_file, file_offset, SEEK_SET);
1127
1128 /* Read the Table header to get the table length */
1129
1130 count = fread(&header, 1, sizeof(struct acpi_table_header), table_file);
1131 if (count != sizeof(struct acpi_table_header)) {
1132 fprintf(stderr, "Could not read table header: %s\n", filename);
1133 status = AE_BAD_HEADER;
1134 goto exit;
1135 }
1136
1137 /* If signature is specified, it must match the table */
1138
1139 if (signature && !ACPI_COMPARE_NAME(signature, header.signature)) {
1140 fprintf(stderr,
1141 "Incorrect signature: Expecting %4.4s, found %4.4s\n",
1142 signature, header.signature);
1143 status = AE_BAD_SIGNATURE;
1144 goto exit;
1145 }
1146
1147 table_length = ap_get_table_length(&header);
1148 if (table_length == 0) {
1149 status = AE_BAD_HEADER;
1150 goto exit;
1151 }
1152
1153 /* Read the entire table into a local buffer */
1154
1155 local_table = calloc(1, table_length);
1156 if (!local_table) {
1157 fprintf(stderr,
1158 "%4.4s: Could not allocate buffer for table of length %X\n",
1159 header.signature, table_length);
1160 status = AE_NO_MEMORY;
1161 goto exit;
1162 }
1163
1164 fseek(table_file, file_offset, SEEK_SET);
1165
1166 while (!feof(table_file) && total < table_length) {
1167 count = fread(local_table + total, 1, table_length - total, table_file);
1168 if (count < 0) {
1169 fprintf(stderr, "%4.4s: Could not read table content\n",
1170 header.signature);
1171 status = AE_INVALID_TABLE_LENGTH;
1172 goto exit;
1173 }
1174
1175 total += count;
1176 }
1177
1178 /* Validate checksum */
1179
1180 (void)ap_is_valid_checksum(local_table);
1181
1182exit:
1183 fclose(table_file);
1184 *table = local_table;
1185 return (status);
1186}
1187
1188/******************************************************************************
1189 *
1190 * FUNCTION: osl_get_customized_table
1191 *
1192 * PARAMETERS: pathname - Directory to find Linux customized table
1193 * signature - ACPI Signature for desired table. Must be
1194 * a null terminated 4-character string.
1195 * instance - Multiple table support for SSDT/UEFI (0...n)
1196 * Must be 0 for other tables.
1197 * table - Where a pointer to the table is returned
1198 * address - Where the table physical address is returned
1199 *
1200 * RETURN: Status; Table buffer is returned if AE_OK.
1201 * AE_LIMIT: Instance is beyond valid limit
1202 * AE_NOT_FOUND: A table with the signature was not found
1203 *
1204 * DESCRIPTION: Get an OS customized table.
1205 *
1206 *****************************************************************************/
1207
1208static acpi_status
1209osl_get_customized_table(char *pathname,
1210 char *signature,
1211 u32 instance,
1212 struct acpi_table_header **table,
1213 acpi_physical_address * address)
1214{
1215 void *table_dir;
1216 u32 current_instance = 0;
1217 char temp_name[ACPI_NAME_SIZE];
1218 char table_filename[PATH_MAX];
1219 char *filename;
1220 acpi_status status;
1221
1222 /* Open the directory for customized tables */
1223
1224 table_dir = acpi_os_open_directory(pathname, "*", REQUEST_FILE_ONLY);
1225 if (!table_dir) {
1226 return (osl_get_last_status(AE_NOT_FOUND));
1227 }
1228
1229 /* Attempt to find the table in the directory */
1230
1231 while ((filename = acpi_os_get_next_filename(table_dir))) {
1232
1233 /* Ignore meaningless files */
1234
1235 if (!ACPI_COMPARE_NAME(filename, signature)) {
1236 continue;
1237 }
1238
1239 /* Extract table name and instance number */
1240
1241 status =
1242 osl_table_name_from_file(filename, temp_name,
1243 &current_instance);
1244
1245 /* Ignore meaningless files */
1246
1247 if (ACPI_FAILURE(status) || current_instance != instance) {
1248 continue;
1249 }
1250
1251 /* Create the table pathname */
1252
1253 if (instance != 0) {
1254 sprintf(table_filename, "%s/%4.4s%d", pathname,
1255 temp_name, instance);
1256 } else {
1257 sprintf(table_filename, "%s/%4.4s", pathname,
1258 temp_name);
1259 }
1260 break;
1261 }
1262
1263 acpi_os_close_directory(table_dir);
1264
1265 if (!filename) {
1266 return (AE_LIMIT);
1267 }
1268
1269 /* There is no physical address saved for customized tables, use zero */
1270
1271 *address = 0;
1272 status = osl_read_table_from_file(table_filename, 0, NULL, table);
1273
1274 return (status);
1275}
diff --git a/tools/power/acpi/os_specific/service_layers/osunixdir.c b/tools/power/acpi/os_specific/service_layers/osunixdir.c
new file mode 100644
index 000000000000..733f9e490fc4
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/osunixdir.c
@@ -0,0 +1,204 @@
1/******************************************************************************
2 *
3 * Module Name: osunixdir - Unix directory access interfaces
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, 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 <acpi/acpi.h>
45
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49#include <dirent.h>
50#include <fnmatch.h>
51#include <ctype.h>
52#include <sys/stat.h>
53
54/*
55 * Allocated structure returned from os_open_directory
56 */
57typedef struct external_find_info {
58 char *dir_pathname;
59 DIR *dir_ptr;
60 char temp_buffer[256];
61 char *wildcard_spec;
62 char requested_file_type;
63
64} external_find_info;
65
66/*******************************************************************************
67 *
68 * FUNCTION: acpi_os_open_directory
69 *
70 * PARAMETERS: dir_pathname - Full pathname to the directory
71 * wildcard_spec - string of the form "*.c", etc.
72 *
73 * RETURN: A directory "handle" to be used in subsequent search operations.
74 * NULL returned on failure.
75 *
76 * DESCRIPTION: Open a directory in preparation for a wildcard search
77 *
78 ******************************************************************************/
79
80void *acpi_os_open_directory(char *dir_pathname,
81 char *wildcard_spec, char requested_file_type)
82{
83 struct external_find_info *external_info;
84 DIR *dir;
85
86 /* Allocate the info struct that will be returned to the caller */
87
88 external_info = calloc(1, sizeof(struct external_find_info));
89 if (!external_info) {
90 return (NULL);
91 }
92
93 /* Get the directory stream */
94
95 dir = opendir(dir_pathname);
96 if (!dir) {
97 fprintf(stderr, "Cannot open directory - %s\n", dir_pathname);
98 free(external_info);
99 return (NULL);
100 }
101
102 /* Save the info in the return structure */
103
104 external_info->wildcard_spec = wildcard_spec;
105 external_info->requested_file_type = requested_file_type;
106 external_info->dir_pathname = dir_pathname;
107 external_info->dir_ptr = dir;
108 return (external_info);
109}
110
111/*******************************************************************************
112 *
113 * FUNCTION: acpi_os_get_next_filename
114 *
115 * PARAMETERS: dir_handle - Created via acpi_os_open_directory
116 *
117 * RETURN: Next filename matched. NULL if no more matches.
118 *
119 * DESCRIPTION: Get the next file in the directory that matches the wildcard
120 * specification.
121 *
122 ******************************************************************************/
123
124char *acpi_os_get_next_filename(void *dir_handle)
125{
126 struct external_find_info *external_info = dir_handle;
127 struct dirent *dir_entry;
128 char *temp_str;
129 int str_len;
130 struct stat temp_stat;
131 int err;
132
133 while ((dir_entry = readdir(external_info->dir_ptr))) {
134 if (!fnmatch
135 (external_info->wildcard_spec, dir_entry->d_name, 0)) {
136 if (dir_entry->d_name[0] == '.') {
137 continue;
138 }
139
140 str_len = strlen(dir_entry->d_name) +
141 strlen(external_info->dir_pathname) + 2;
142
143 temp_str = calloc(str_len, 1);
144 if (!temp_str) {
145 fprintf(stderr,
146 "Could not allocate buffer for temporary string\n");
147 return (NULL);
148 }
149
150 strcpy(temp_str, external_info->dir_pathname);
151 strcat(temp_str, "/");
152 strcat(temp_str, dir_entry->d_name);
153
154 err = stat(temp_str, &temp_stat);
155 if (err == -1) {
156 fprintf(stderr,
157 "Cannot stat file (should not happen) - %s\n",
158 temp_str);
159 free(temp_str);
160 return (NULL);
161 }
162
163 free(temp_str);
164
165 if ((S_ISDIR(temp_stat.st_mode)
166 && (external_info->requested_file_type ==
167 REQUEST_DIR_ONLY))
168 || ((!S_ISDIR(temp_stat.st_mode)
169 && external_info->requested_file_type ==
170 REQUEST_FILE_ONLY))) {
171
172 /* copy to a temp buffer because dir_entry struct is on the stack */
173
174 strcpy(external_info->temp_buffer,
175 dir_entry->d_name);
176 return (external_info->temp_buffer);
177 }
178 }
179 }
180
181 return (NULL);
182}
183
184/*******************************************************************************
185 *
186 * FUNCTION: acpi_os_close_directory
187 *
188 * PARAMETERS: dir_handle - Created via acpi_os_open_directory
189 *
190 * RETURN: None.
191 *
192 * DESCRIPTION: Close the open directory and cleanup.
193 *
194 ******************************************************************************/
195
196void acpi_os_close_directory(void *dir_handle)
197{
198 struct external_find_info *external_info = dir_handle;
199
200 /* Close the directory and free allocations */
201
202 closedir(external_info->dir_ptr);
203 free(dir_handle);
204}
diff --git a/tools/power/acpi/os_specific/service_layers/osunixmap.c b/tools/power/acpi/os_specific/service_layers/osunixmap.c
new file mode 100644
index 000000000000..99b47b6194a3
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/osunixmap.c
@@ -0,0 +1,151 @@
1/******************************************************************************
2 *
3 * Module Name: osunixmap - Unix OSL for file mappings
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, 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#include <unistd.h>
46#include <sys/mman.h>
47#ifdef _free_BSD
48#include <sys/param.h>
49#endif
50
51#define _COMPONENT ACPI_OS_SERVICES
52ACPI_MODULE_NAME("osunixmap")
53
54#ifndef O_BINARY
55#define O_BINARY 0
56#endif
57#ifdef _free_BSD
58#define MMAP_FLAGS MAP_SHARED
59#else
60#define MMAP_FLAGS MAP_PRIVATE
61#endif
62#define SYSTEM_MEMORY "/dev/mem"
63/*******************************************************************************
64 *
65 * FUNCTION: acpi_os_get_page_size
66 *
67 * PARAMETERS: None
68 *
69 * RETURN: Page size of the platform.
70 *
71 * DESCRIPTION: Obtain page size of the platform.
72 *
73 ******************************************************************************/
74static acpi_size acpi_os_get_page_size(void)
75{
76
77#ifdef PAGE_SIZE
78 return PAGE_SIZE;
79#else
80 return sysconf(_SC_PAGESIZE);
81#endif
82}
83
84/******************************************************************************
85 *
86 * FUNCTION: acpi_os_map_memory
87 *
88 * PARAMETERS: where - Physical address of memory to be mapped
89 * length - How much memory to map
90 *
91 * RETURN: Pointer to mapped memory. Null on error.
92 *
93 * DESCRIPTION: Map physical memory into local address space.
94 *
95 *****************************************************************************/
96
97void *acpi_os_map_memory(acpi_physical_address where, acpi_size length)
98{
99 u8 *mapped_memory;
100 acpi_physical_address offset;
101 acpi_size page_size;
102 int fd;
103
104 fd = open(SYSTEM_MEMORY, O_RDONLY | O_BINARY);
105 if (fd < 0) {
106 fprintf(stderr, "Cannot open %s\n", SYSTEM_MEMORY);
107 return (NULL);
108 }
109
110 /* Align the offset to use mmap */
111
112 page_size = acpi_os_get_page_size();
113 offset = where % page_size;
114
115 /* Map the table header to get the length of the full table */
116
117 mapped_memory = mmap(NULL, (length + offset), PROT_READ, MMAP_FLAGS,
118 fd, (where - offset));
119 if (mapped_memory == MAP_FAILED) {
120 fprintf(stderr, "Cannot map %s\n", SYSTEM_MEMORY);
121 close(fd);
122 return (NULL);
123 }
124
125 close(fd);
126 return (ACPI_CAST8(mapped_memory + offset));
127}
128
129/******************************************************************************
130 *
131 * FUNCTION: acpi_os_unmap_memory
132 *
133 * PARAMETERS: where - Logical address of memory to be unmapped
134 * length - How much memory to unmap
135 *
136 * RETURN: None.
137 *
138 * DESCRIPTION: Delete a previously created mapping. Where and Length must
139 * correspond to a previous mapping exactly.
140 *
141 *****************************************************************************/
142
143void acpi_os_unmap_memory(void *where, acpi_size length)
144{
145 acpi_physical_address offset;
146 acpi_size page_size;
147
148 page_size = acpi_os_get_page_size();
149 offset = (acpi_physical_address) where % page_size;
150 munmap((u8 *)where - offset, (length + offset));
151}
diff --git a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h
new file mode 100644
index 000000000000..3361b9e04d9c
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/acpidump.h
@@ -0,0 +1,131 @@
1/******************************************************************************
2 *
3 * Module Name: acpidump.h - Include file for acpi_dump utility
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, 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 <acpi/acpi.h>
45#include "accommon.h"
46#include "actables.h"
47
48#include <stdio.h>
49#include <fcntl.h>
50#include <errno.h>
51#include <sys/stat.h>
52
53/*
54 * Global variables. Defined in main.c only, externed in all other files
55 */
56#ifdef _DECLARE_GLOBALS
57#define EXTERN
58#define INIT_GLOBAL(a,b) a=b
59#else
60#define EXTERN extern
61#define INIT_GLOBAL(a,b) a
62#endif
63
64/* Globals */
65
66EXTERN u8 INIT_GLOBAL(gbl_summary_mode, FALSE);
67EXTERN u8 INIT_GLOBAL(gbl_verbose_mode, FALSE);
68EXTERN u8 INIT_GLOBAL(gbl_binary_mode, FALSE);
69EXTERN u8 INIT_GLOBAL(gbl_dump_customized_tables, FALSE);
70EXTERN FILE INIT_GLOBAL(*gbl_output_file, NULL);
71EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL);
72EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0);
73
74/* Globals required for use with ACPICA modules */
75
76#ifdef _DECLARE_GLOBALS
77u8 acpi_gbl_enable_interpreter_slack = FALSE;
78u8 acpi_gbl_integer_byte_width = 8;
79u32 acpi_dbg_level = 0;
80u32 acpi_dbg_layer = 0;
81#endif
82
83/* Action table used to defer requested options */
84
85struct ap_dump_action {
86 char *argument;
87 u32 to_be_done;
88};
89
90#define AP_MAX_ACTIONS 32
91
92#define AP_DUMP_ALL_TABLES 0
93#define AP_DUMP_TABLE_BY_ADDRESS 1
94#define AP_DUMP_TABLE_BY_NAME 2
95#define AP_DUMP_TABLE_BY_FILE 3
96
97#define AP_MAX_ACPI_FILES 256 /* Prevent infinite loops */
98
99/* Minimum FADT sizes for various table addresses */
100
101#define MIN_FADT_FOR_DSDT (ACPI_FADT_OFFSET (dsdt) + sizeof (u32))
102#define MIN_FADT_FOR_FACS (ACPI_FADT_OFFSET (facs) + sizeof (u32))
103#define MIN_FADT_FOR_XDSDT (ACPI_FADT_OFFSET (Xdsdt) + sizeof (u64))
104#define MIN_FADT_FOR_XFACS (ACPI_FADT_OFFSET (Xfacs) + sizeof (u64))
105
106/*
107 * apdump - Table get/dump routines
108 */
109int ap_dump_table_from_file(char *pathname);
110
111int ap_dump_table_by_name(char *signature);
112
113int ap_dump_table_by_address(char *ascii_address);
114
115int ap_dump_all_tables(void);
116
117u8 ap_is_valid_header(struct acpi_table_header *table);
118
119u8 ap_is_valid_checksum(struct acpi_table_header *table);
120
121u32 ap_get_table_length(struct acpi_table_header *table);
122
123/*
124 * apfiles - File I/O utilities
125 */
126int ap_open_output_file(char *pathname);
127
128int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance);
129
130struct acpi_table_header *ap_get_table_from_file(char *pathname,
131 u32 *file_size);
diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c
new file mode 100644
index 000000000000..3cac12378366
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/apdump.c
@@ -0,0 +1,451 @@
1/******************************************************************************
2 *
3 * Module Name: apdump - Dump routines for ACPI tables (acpidump)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, 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
48static int
49ap_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
64u8 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_acpi_name(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
102u8 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
138u32 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 (rsdp->length);
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
173static int
174ap_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 printf("%4.4s @ 0x%8.8X%8.8X\n", table->signature,
200 ACPI_FORMAT_UINT64(address));
201
202 acpi_ut_dump_buffer(ACPI_CAST_PTR(u8, table), table_length,
203 DB_BYTE_DISPLAY, 0);
204 printf("\n");
205 return (0);
206}
207
208/******************************************************************************
209 *
210 * FUNCTION: ap_dump_all_tables
211 *
212 * PARAMETERS: None
213 *
214 * RETURN: Status
215 *
216 * DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the
217 * tables that we can possibly get).
218 *
219 ******************************************************************************/
220
221int ap_dump_all_tables(void)
222{
223 struct acpi_table_header *table;
224 u32 instance = 0;
225 acpi_physical_address address;
226 acpi_status status;
227 int table_status;
228 u32 i;
229
230 /* Get and dump all available ACPI tables */
231
232 for (i = 0; i < AP_MAX_ACPI_FILES; i++) {
233 status =
234 acpi_os_get_table_by_index(i, &table, &instance, &address);
235 if (ACPI_FAILURE(status)) {
236
237 /* AE_LIMIT means that no more tables are available */
238
239 if (status == AE_LIMIT) {
240 return (0);
241 } else if (i == 0) {
242 fprintf(stderr,
243 "Could not get ACPI tables, %s\n",
244 acpi_format_exception(status));
245 return (-1);
246 } else {
247 fprintf(stderr,
248 "Could not get ACPI table at index %u, %s\n",
249 i, acpi_format_exception(status));
250 continue;
251 }
252 }
253
254 table_status = ap_dump_table_buffer(table, instance, address);
255 free(table);
256
257 if (table_status) {
258 break;
259 }
260 }
261
262 /* Something seriously bad happened if the loop terminates here */
263
264 return (-1);
265}
266
267/******************************************************************************
268 *
269 * FUNCTION: ap_dump_table_by_address
270 *
271 * PARAMETERS: ascii_address - Address for requested ACPI table
272 *
273 * RETURN: Status
274 *
275 * DESCRIPTION: Get an ACPI table via a physical address and dump it.
276 *
277 ******************************************************************************/
278
279int ap_dump_table_by_address(char *ascii_address)
280{
281 acpi_physical_address address;
282 struct acpi_table_header *table;
283 acpi_status status;
284 int table_status;
285 u64 long_address;
286
287 /* Convert argument to an integer physical address */
288
289 status = acpi_ut_strtoul64(ascii_address, 0, &long_address);
290 if (ACPI_FAILURE(status)) {
291 fprintf(stderr, "%s: Could not convert to a physical address\n",
292 ascii_address);
293 return (-1);
294 }
295
296 address = (acpi_physical_address) long_address;
297 status = acpi_os_get_table_by_address(address, &table);
298 if (ACPI_FAILURE(status)) {
299 fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n",
300 ACPI_FORMAT_UINT64(address),
301 acpi_format_exception(status));
302 return (-1);
303 }
304
305 table_status = ap_dump_table_buffer(table, 0, address);
306 free(table);
307 return (table_status);
308}
309
310/******************************************************************************
311 *
312 * FUNCTION: ap_dump_table_by_name
313 *
314 * PARAMETERS: signature - Requested ACPI table signature
315 *
316 * RETURN: Status
317 *
318 * DESCRIPTION: Get an ACPI table via a signature and dump it. Handles
319 * multiple tables with the same signature (SSDTs).
320 *
321 ******************************************************************************/
322
323int ap_dump_table_by_name(char *signature)
324{
325 char local_signature[ACPI_NAME_SIZE + 1];
326 u32 instance;
327 struct acpi_table_header *table;
328 acpi_physical_address address;
329 acpi_status status;
330 int table_status;
331
332 if (strlen(signature) != ACPI_NAME_SIZE) {
333 fprintf(stderr,
334 "Invalid table signature [%s]: must be exactly 4 characters\n",
335 signature);
336 return (-1);
337 }
338
339 /* Table signatures are expected to be uppercase */
340
341 strcpy(local_signature, signature);
342 acpi_ut_strupr(local_signature);
343
344 /* To be friendly, handle tables whose signatures do not match the name */
345
346 if (ACPI_COMPARE_NAME(local_signature, "FADT")) {
347 strcpy(local_signature, ACPI_SIG_FADT);
348 } else if (ACPI_COMPARE_NAME(local_signature, "MADT")) {
349 strcpy(local_signature, ACPI_SIG_MADT);
350 }
351
352 /* Dump all instances of this signature (to handle multiple SSDTs) */
353
354 for (instance = 0; instance < AP_MAX_ACPI_FILES; instance++) {
355 status = acpi_os_get_table_by_name(local_signature, instance,
356 &table, &address);
357 if (ACPI_FAILURE(status)) {
358
359 /* AE_LIMIT means that no more tables are available */
360
361 if (status == AE_LIMIT) {
362 return (0);
363 }
364
365 fprintf(stderr,
366 "Could not get ACPI table with signature [%s], %s\n",
367 local_signature, acpi_format_exception(status));
368 return (-1);
369 }
370
371 table_status = ap_dump_table_buffer(table, instance, address);
372 free(table);
373
374 if (table_status) {
375 break;
376 }
377 }
378
379 /* Something seriously bad happened if the loop terminates here */
380
381 return (-1);
382}
383
384/******************************************************************************
385 *
386 * FUNCTION: ap_dump_table_from_file
387 *
388 * PARAMETERS: pathname - File containing the binary ACPI table
389 *
390 * RETURN: Status
391 *
392 * DESCRIPTION: Dump an ACPI table from a binary file
393 *
394 ******************************************************************************/
395
396int ap_dump_table_from_file(char *pathname)
397{
398 struct acpi_table_header *table;
399 u32 file_size = 0;
400 int table_status = -1;
401
402 /* Get the entire ACPI table from the file */
403
404 table = ap_get_table_from_file(pathname, &file_size);
405 if (!table) {
406 return (-1);
407 }
408
409 /* File must be at least as long as the table length */
410
411 if (table->length > file_size) {
412 fprintf(stderr,
413 "Table length (0x%X) is too large for input file (0x%X) %s\n",
414 table->length, file_size, pathname);
415 goto exit;
416 }
417
418 if (gbl_verbose_mode) {
419 fprintf(stderr,
420 "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n",
421 pathname, table->signature, file_size, file_size);
422 }
423
424 table_status = ap_dump_table_buffer(table, 0, 0);
425
426exit:
427 free(table);
428 return (table_status);
429}
430
431/******************************************************************************
432 *
433 * FUNCTION: acpi_os* print functions
434 *
435 * DESCRIPTION: Used for linkage with ACPICA modules
436 *
437 ******************************************************************************/
438
439void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...)
440{
441 va_list args;
442
443 va_start(args, fmt);
444 vfprintf(stdout, fmt, args);
445 va_end(args);
446}
447
448void acpi_os_vprintf(const char *fmt, va_list args)
449{
450 vfprintf(stdout, fmt, args);
451}
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c
new file mode 100644
index 000000000000..4488accc010b
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/apfiles.c
@@ -0,0 +1,228 @@
1/******************************************************************************
2 *
3 * Module Name: apfiles - File-related functions for acpidump utility
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, 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#include "acapps.h"
46
47/******************************************************************************
48 *
49 * FUNCTION: ap_open_output_file
50 *
51 * PARAMETERS: pathname - Output filename
52 *
53 * RETURN: Open file handle
54 *
55 * DESCRIPTION: Open a text output file for acpidump. Checks if file already
56 * exists.
57 *
58 ******************************************************************************/
59
60int ap_open_output_file(char *pathname)
61{
62 struct stat stat_info;
63 FILE *file;
64
65 /* If file exists, prompt for overwrite */
66
67 if (!stat(pathname, &stat_info)) {
68 fprintf(stderr,
69 "Target path already exists, overwrite? [y|n] ");
70
71 if (getchar() != 'y') {
72 return (-1);
73 }
74 }
75
76 /* Point stdout to the file */
77
78 file = freopen(pathname, "w", stdout);
79 if (!file) {
80 perror("Could not open output file");
81 return (-1);
82 }
83
84 /* Save the file and path */
85
86 gbl_output_file = file;
87 gbl_output_filename = pathname;
88 return (0);
89}
90
91/******************************************************************************
92 *
93 * FUNCTION: ap_write_to_binary_file
94 *
95 * PARAMETERS: table - ACPI table to be written
96 * instance - ACPI table instance no. to be written
97 *
98 * RETURN: Status
99 *
100 * DESCRIPTION: Write an ACPI table to a binary file. Builds the output
101 * filename from the table signature.
102 *
103 ******************************************************************************/
104
105int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
106{
107 char filename[ACPI_NAME_SIZE + 16];
108 char instance_str[16];
109 FILE *file;
110 size_t actual;
111 u32 table_length;
112
113 /* Obtain table length */
114
115 table_length = ap_get_table_length(table);
116
117 /* Construct lower-case filename from the table local signature */
118
119 if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
120 ACPI_MOVE_NAME(filename, ACPI_RSDP_NAME);
121 } else {
122 ACPI_MOVE_NAME(filename, table->signature);
123 }
124 filename[0] = (char)ACPI_TOLOWER(filename[0]);
125 filename[1] = (char)ACPI_TOLOWER(filename[1]);
126 filename[2] = (char)ACPI_TOLOWER(filename[2]);
127 filename[3] = (char)ACPI_TOLOWER(filename[3]);
128 filename[ACPI_NAME_SIZE] = 0;
129
130 /* Handle multiple SSDts - create different filenames for each */
131
132 if (instance > 0) {
133 sprintf(instance_str, "%u", instance);
134 strcat(filename, instance_str);
135 }
136
137 strcat(filename, ACPI_TABLE_FILE_SUFFIX);
138
139 if (gbl_verbose_mode) {
140 fprintf(stderr,
141 "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
142 table->signature, filename, table->length,
143 table->length);
144 }
145
146 /* Open the file and dump the entire table in binary mode */
147
148 file = fopen(filename, "wb");
149 if (!file) {
150 perror("Could not open output file");
151 return (-1);
152 }
153
154 actual = fwrite(table, 1, table_length, file);
155 if (actual != table_length) {
156 perror("Error writing binary output file");
157 fclose(file);
158 return (-1);
159 }
160
161 fclose(file);
162 return (0);
163}
164
165/******************************************************************************
166 *
167 * FUNCTION: ap_get_table_from_file
168 *
169 * PARAMETERS: pathname - File containing the binary ACPI table
170 * out_file_size - Where the file size is returned
171 *
172 * RETURN: Buffer containing the ACPI table. NULL on error.
173 *
174 * DESCRIPTION: Open a file and read it entirely into a new buffer
175 *
176 ******************************************************************************/
177
178struct acpi_table_header *ap_get_table_from_file(char *pathname,
179 u32 *out_file_size)
180{
181 struct acpi_table_header *buffer = NULL;
182 FILE *file;
183 u32 file_size;
184 size_t actual;
185
186 /* Must use binary mode */
187
188 file = fopen(pathname, "rb");
189 if (!file) {
190 perror("Could not open input file");
191 return (NULL);
192 }
193
194 /* Need file size to allocate a buffer */
195
196 file_size = cm_get_file_size(file);
197 if (file_size == ACPI_UINT32_MAX) {
198 fprintf(stderr,
199 "Could not get input file size: %s\n", pathname);
200 goto cleanup;
201 }
202
203 /* Allocate a buffer for the entire file */
204
205 buffer = calloc(1, file_size);
206 if (!buffer) {
207 fprintf(stderr,
208 "Could not allocate file buffer of size: %u\n",
209 file_size);
210 goto cleanup;
211 }
212
213 /* Read the entire file */
214
215 actual = fread(buffer, 1, file_size, file);
216 if (actual != file_size) {
217 fprintf(stderr, "Could not read input file: %s\n", pathname);
218 free(buffer);
219 buffer = NULL;
220 goto cleanup;
221 }
222
223 *out_file_size = file_size;
224
225cleanup:
226 fclose(file);
227 return (buffer);
228}
diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c
new file mode 100644
index 000000000000..70d71ec687a5
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/apmain.c
@@ -0,0 +1,340 @@
1/******************************************************************************
2 *
3 * Module Name: apmain - Main module for the acpidump utility
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, 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
71static void ap_display_usage(void);
72
73static int ap_do_options(int argc, char **argv);
74
75static void ap_insert_action(char *argument, u32 to_be_done);
76
77/* Table for deferred actions from command line options */
78
79struct ap_dump_action action_table[AP_MAX_ACTIONS];
80u32 current_action = 0;
81
82#define AP_UTILITY_NAME "ACPI Binary Table Dump Utility"
83#define AP_SUPPORTED_OPTIONS "?a:bcf:hn:o:r:svz"
84
85/******************************************************************************
86 *
87 * FUNCTION: ap_display_usage
88 *
89 * DESCRIPTION: Usage message for the acpi_dump utility
90 *
91 ******************************************************************************/
92
93static 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("-c", "Dump customized tables");
100 ACPI_OPTION("-h -?", "This help message");
101 ACPI_OPTION("-o <File>", "Redirect output to file");
102 ACPI_OPTION("-r <Address>", "Dump tables from specified RSDP");
103 ACPI_OPTION("-s", "Print table summaries only");
104 ACPI_OPTION("-v", "Display version information");
105 ACPI_OPTION("-z", "Verbose mode");
106
107 printf("\nTable Options:\n");
108
109 ACPI_OPTION("-a <Address>", "Get table via a physical address");
110 ACPI_OPTION("-f <BinaryFile>", "Get table via a binary file");
111 ACPI_OPTION("-n <Signature>", "Get table via a name/signature");
112
113 printf("\n"
114 "Invocation without parameters dumps all available tables\n"
115 "Multiple mixed instances of -a, -f, and -n are supported\n\n");
116}
117
118/******************************************************************************
119 *
120 * FUNCTION: ap_insert_action
121 *
122 * PARAMETERS: argument - Pointer to the argument for this action
123 * to_be_done - What to do to process this action
124 *
125 * RETURN: None. Exits program if action table becomes full.
126 *
127 * DESCRIPTION: Add an action item to the action table
128 *
129 ******************************************************************************/
130
131static void ap_insert_action(char *argument, u32 to_be_done)
132{
133
134 /* Insert action and check for table overflow */
135
136 action_table[current_action].argument = argument;
137 action_table[current_action].to_be_done = to_be_done;
138
139 current_action++;
140 if (current_action > AP_MAX_ACTIONS) {
141 fprintf(stderr, "Too many table options (max %u)\n",
142 AP_MAX_ACTIONS);
143 exit(-1);
144 }
145}
146
147/******************************************************************************
148 *
149 * FUNCTION: ap_do_options
150 *
151 * PARAMETERS: argc/argv - Standard argc/argv
152 *
153 * RETURN: Status
154 *
155 * DESCRIPTION: Command line option processing. The main actions for getting
156 * and dumping tables are deferred via the action table.
157 *
158 *****************************************************************************/
159
160static int ap_do_options(int argc, char **argv)
161{
162 int j;
163 acpi_status status;
164
165 /* Command line options */
166
167 while ((j = acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != EOF)
168 switch (j) {
169 /*
170 * Global options
171 */
172 case 'b': /* Dump all input tables to binary files */
173
174 gbl_binary_mode = TRUE;
175 continue;
176
177 case 'c': /* Dump customized tables */
178
179 gbl_dump_customized_tables = TRUE;
180 continue;
181
182 case 'h':
183 case '?':
184
185 ap_display_usage();
186 exit(0);
187
188 case 'o': /* Redirect output to a single file */
189
190 if (ap_open_output_file(acpi_gbl_optarg)) {
191 exit(-1);
192 }
193 continue;
194
195 case 'r': /* Dump tables from specified RSDP */
196
197 status =
198 acpi_ut_strtoul64(acpi_gbl_optarg, 0,
199 &gbl_rsdp_base);
200 if (ACPI_FAILURE(status)) {
201 fprintf(stderr,
202 "%s: Could not convert to a physical address\n",
203 acpi_gbl_optarg);
204 exit(-1);
205 }
206 continue;
207
208 case 's': /* Print table summaries only */
209
210 gbl_summary_mode = TRUE;
211 continue;
212
213 case 'v': /* Revision/version */
214
215 printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
216 exit(0);
217
218 case 'z': /* Verbose mode */
219
220 gbl_verbose_mode = TRUE;
221 fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
222 continue;
223
224 /*
225 * Table options
226 */
227 case 'a': /* Get table by physical address */
228
229 ap_insert_action(acpi_gbl_optarg,
230 AP_DUMP_TABLE_BY_ADDRESS);
231 break;
232
233 case 'f': /* Get table from a file */
234
235 ap_insert_action(acpi_gbl_optarg,
236 AP_DUMP_TABLE_BY_FILE);
237 break;
238
239 case 'n': /* Get table by input name (signature) */
240
241 ap_insert_action(acpi_gbl_optarg,
242 AP_DUMP_TABLE_BY_NAME);
243 break;
244
245 default:
246
247 ap_display_usage();
248 exit(-1);
249 }
250
251 /* If there are no actions, this means "get/dump all tables" */
252
253 if (current_action == 0) {
254 ap_insert_action(NULL, AP_DUMP_ALL_TABLES);
255 }
256
257 return (0);
258}
259
260/******************************************************************************
261 *
262 * FUNCTION: main
263 *
264 * PARAMETERS: argc/argv - Standard argc/argv
265 *
266 * RETURN: Status
267 *
268 * DESCRIPTION: C main function for acpidump utility
269 *
270 ******************************************************************************/
271
272int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
273{
274 int status = 0;
275 struct ap_dump_action *action;
276 u32 file_size;
277 u32 i;
278
279 ACPI_DEBUG_INITIALIZE(); /* For debug version only */
280
281 /* Process command line options */
282
283 if (ap_do_options(argc, argv)) {
284 return (-1);
285 }
286
287 /* Get/dump ACPI table(s) as requested */
288
289 for (i = 0; i < current_action; i++) {
290 action = &action_table[i];
291 switch (action->to_be_done) {
292 case AP_DUMP_ALL_TABLES:
293
294 status = ap_dump_all_tables();
295 break;
296
297 case AP_DUMP_TABLE_BY_ADDRESS:
298
299 status = ap_dump_table_by_address(action->argument);
300 break;
301
302 case AP_DUMP_TABLE_BY_NAME:
303
304 status = ap_dump_table_by_name(action->argument);
305 break;
306
307 case AP_DUMP_TABLE_BY_FILE:
308
309 status = ap_dump_table_from_file(action->argument);
310 break;
311
312 default:
313
314 fprintf(stderr,
315 "Internal error, invalid action: 0x%X\n",
316 action->to_be_done);
317 return (-1);
318 }
319
320 if (status) {
321 return (status);
322 }
323 }
324
325 if (gbl_output_file) {
326 if (gbl_verbose_mode) {
327
328 /* Summary for the output file */
329
330 file_size = cm_get_file_size(gbl_output_file);
331 fprintf(stderr,
332 "Output file %s contains 0x%X (%u) bytes\n\n",
333 gbl_output_filename, file_size, file_size);
334 }
335
336 fclose(gbl_output_file);
337 }
338
339 return (status);
340}