aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-04-28 06:12:57 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-04-28 06:12:57 -0400
commitfd0c940522c5c5b281b7a4fe3497fabf74bd8911 (patch)
tree9905a60f65d2eb051cb05a95a1052fb35c24c37c
parent6273f00e6ecbd60494a979033b7e5271a29a0436 (diff)
parent35476c75efa04a5fdb01074e54135dcc126c25f7 (diff)
Merge back earlier ACPICA material.
-rw-r--r--Documentation/kernel-parameters.txt10
-rw-r--r--drivers/acpi/acpica/Makefile1
-rw-r--r--drivers/acpi/acpica/acapps.h170
-rw-r--r--drivers/acpi/acpica/acglobal.h9
-rw-r--r--drivers/acpi/acpica/aclocal.h8
-rw-r--r--drivers/acpi/acpica/actables.h60
-rw-r--r--drivers/acpi/acpica/acutils.h10
-rw-r--r--drivers/acpi/acpica/evmisc.c3
-rw-r--r--drivers/acpi/acpica/evsci.c2
-rw-r--r--drivers/acpi/acpica/evxface.c61
-rw-r--r--drivers/acpi/acpica/exconfig.c82
-rw-r--r--drivers/acpi/acpica/exdump.c4
-rw-r--r--drivers/acpi/acpica/tbdata.c723
-rw-r--r--drivers/acpi/acpica/tbfadt.c10
-rw-r--r--drivers/acpi/acpica/tbfind.c4
-rw-r--r--drivers/acpi/acpica/tbinstal.c837
-rw-r--r--drivers/acpi/acpica/tbutils.c171
-rw-r--r--drivers/acpi/acpica/tbxface.c18
-rw-r--r--drivers/acpi/acpica/tbxfload.c87
-rw-r--r--drivers/acpi/acpica/utdecode.c74
-rw-r--r--drivers/acpi/acpica/utstring.c2
-rw-r--r--drivers/acpi/osl.c11
-rw-r--r--include/acpi/acpixf.h7
-rw-r--r--include/acpi/actbl.h11
-rw-r--r--include/acpi/platform/acgcc.h11
-rw-r--r--include/acpi/platform/aclinux.h5
-rw-r--r--tools/power/acpi/Makefile26
-rw-r--r--tools/power/acpi/common/cmfsize.c101
-rw-r--r--tools/power/acpi/common/getopt.c239
-rw-r--r--tools/power/acpi/man/acpidump.885
-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.c559
-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
38 files changed, 4780 insertions, 1401 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 43842177b771..60a278948652 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -237,7 +237,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
237 This feature is enabled by default. 237 This feature is enabled by default.
238 This option allows to turn off the feature. 238 This option allows to turn off the feature.
239 239
240 acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT 240 acpi_no_static_ssdt [HW,ACPI]
241 Disable installation of static SSDTs at early boot time
242 By default, SSDTs contained in the RSDT/XSDT will be
243 installed automatically and they will appear under
244 /sys/firmware/acpi/tables.
245 This option turns off this feature.
246 Note that specifying this option does not affect
247 dynamic table installation which will install SSDT
248 tables to /sys/firmware/acpi/tables/dynamic.
241 249
242 acpica_no_return_repair [HW, ACPI] 250 acpica_no_return_repair [HW, ACPI]
243 Disable AML predefined validation mechanism 251 Disable AML predefined validation mechanism
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index b7ed86a20427..8bb43f06e11f 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -135,6 +135,7 @@ acpi-y += \
135 rsxface.o 135 rsxface.o
136 136
137acpi-y += \ 137acpi-y += \
138 tbdata.o \
138 tbfadt.o \ 139 tbfadt.o \
139 tbfind.o \ 140 tbfind.o \
140 tbinstal.o \ 141 tbinstal.o \
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/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 49bbc71fad54..1f602907dfab 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -103,8 +103,8 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_auto_serialize_methods, TRUE);
103 103
104/* 104/*
105 * Create the predefined _OSI method in the namespace? Default is TRUE 105 * Create the predefined _OSI method in the namespace? Default is TRUE
106 * because ACPI CA is fully compatible with other ACPI implementations. 106 * because ACPICA is fully compatible with other ACPI implementations.
107 * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. 107 * Changing this will revert ACPICA (and machine ASL) to pre-OSI behavior.
108 */ 108 */
109ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE); 109ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE);
110 110
@@ -160,10 +160,10 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_truncate_io_addresses, FALSE);
160ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_auto_repair, FALSE); 160ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_auto_repair, FALSE);
161 161
162/* 162/*
163 * Optionally do not load any SSDTs from the RSDT/XSDT during initialization. 163 * Optionally do not install any SSDTs from the RSDT/XSDT during initialization.
164 * This can be useful for debugging ACPI problems on some machines. 164 * This can be useful for debugging ACPI problems on some machines.
165 */ 165 */
166ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_ssdt_table_load, FALSE); 166ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_ssdt_table_install, FALSE);
167 167
168/* 168/*
169 * We keep track of the latest version of Windows that has been requested by 169 * We keep track of the latest version of Windows that has been requested by
@@ -509,5 +509,6 @@ ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL);
509 ****************************************************************************/ 509 ****************************************************************************/
510 510
511extern const struct ah_predefined_name asl_predefined_info[]; 511extern const struct ah_predefined_name asl_predefined_info[];
512extern const struct ah_device_id asl_device_ids[];
512 513
513#endif /* __ACGLOBAL_H__ */ 514#endif /* __ACGLOBAL_H__ */
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 52a21dafb540..f68cb602dc23 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -733,7 +733,8 @@ union acpi_parse_value {
733#define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ 733#define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */
734#define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ 734#define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */
735#define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ 735#define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */
736#define ACPI_DASM_IGNORE 0x09 /* Not used at this time */ 736#define ACPI_DASM_HID_STRING 0x09 /* String is a _HID or _CID */
737#define ACPI_DASM_IGNORE 0x0A /* Not used at this time */
737 738
738/* 739/*
739 * Generic operation (for example: If, While, Store) 740 * Generic operation (for example: If, While, Store)
@@ -1147,4 +1148,9 @@ struct ah_predefined_name {
1147#endif 1148#endif
1148}; 1149};
1149 1150
1151struct ah_device_id {
1152 char *name;
1153 char *description;
1154};
1155
1150#endif /* __ACLOCAL_H__ */ 1156#endif /* __ACLOCAL_H__ */
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index 5fa4b2027697..bda9a7eb50c1 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -54,6 +54,26 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp);
54u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); 54u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length);
55 55
56/* 56/*
57 * tbdata - table data structure management
58 */
59acpi_status acpi_tb_get_next_root_index(u32 *table_index);
60
61void
62acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
63 acpi_physical_address address,
64 u8 flags, struct acpi_table_header *table);
65
66acpi_status
67acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc,
68 acpi_physical_address address, u8 flags);
69
70void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc);
71
72u8 acpi_tb_is_table_loaded(u32 table_index);
73
74void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded);
75
76/*
57 * tbfadt - FADT parse/convert/validate 77 * tbfadt - FADT parse/convert/validate
58 */ 78 */
59void acpi_tb_parse_fadt(u32 table_index); 79void acpi_tb_parse_fadt(u32 table_index);
@@ -72,22 +92,35 @@ acpi_tb_find_table(char *signature,
72 */ 92 */
73acpi_status acpi_tb_resize_root_table_list(void); 93acpi_status acpi_tb_resize_root_table_list(void);
74 94
75acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); 95acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc);
76 96
77struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header 97void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc);
78 *table_header,
79 struct acpi_table_desc
80 *table_desc);
81 98
82acpi_status 99acpi_status
83acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index); 100acpi_tb_verify_table(struct acpi_table_desc *table_desc, char *signature);
101
102void acpi_tb_override_table(struct acpi_table_desc *old_table_desc);
103
104acpi_status
105acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
106 struct acpi_table_header **table_ptr,
107 u32 *table_length, u8 *table_flags);
108
109void
110acpi_tb_release_table(struct acpi_table_header *table,
111 u32 table_length, u8 table_flags);
112
113acpi_status
114acpi_tb_install_standard_table(acpi_physical_address address,
115 u8 flags,
116 u8 reload, u8 override, u32 *table_index);
84 117
85acpi_status 118acpi_status
86acpi_tb_store_table(acpi_physical_address address, 119acpi_tb_store_table(acpi_physical_address address,
87 struct acpi_table_header *table, 120 struct acpi_table_header *table,
88 u32 length, u8 flags, u32 *table_index); 121 u32 length, u8 flags, u32 *table_index);
89 122
90void acpi_tb_delete_table(struct acpi_table_desc *table_desc); 123void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc);
91 124
92void acpi_tb_terminate(void); 125void acpi_tb_terminate(void);
93 126
@@ -99,10 +132,6 @@ acpi_status acpi_tb_release_owner_id(u32 table_index);
99 132
100acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id); 133acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id);
101 134
102u8 acpi_tb_is_table_loaded(u32 table_index);
103
104void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded);
105
106/* 135/*
107 * tbutils - table manager utilities 136 * tbutils - table manager utilities
108 */ 137 */
@@ -124,8 +153,13 @@ void acpi_tb_check_dsdt_header(void);
124struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index); 153struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index);
125 154
126void 155void
127acpi_tb_install_table(acpi_physical_address address, 156acpi_tb_install_table_with_override(u32 table_index,
128 char *signature, u32 table_index); 157 struct acpi_table_desc *new_table_desc,
158 u8 override);
159
160acpi_status
161acpi_tb_install_fixed_table(acpi_physical_address address,
162 char *signature, u32 table_index);
129 163
130acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); 164acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
131 165
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
index ceeec0b7ccb1..1e256c5bda20 100644
--- a/drivers/acpi/acpica/acutils.h
+++ b/drivers/acpi/acpica/acutils.h
@@ -176,8 +176,7 @@ acpi_status acpi_ut_init_globals(void);
176 176
177char *acpi_ut_get_mutex_name(u32 mutex_id); 177char *acpi_ut_get_mutex_name(u32 mutex_id);
178 178
179const char *acpi_ut_get_notify_name(u32 notify_value); 179const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type);
180
181#endif 180#endif
182 181
183char *acpi_ut_get_type_name(acpi_object_type type); 182char *acpi_ut_get_type_name(acpi_object_type type);
@@ -737,4 +736,11 @@ acpi_ut_method_error(const char *module_name,
737 struct acpi_namespace_node *node, 736 struct acpi_namespace_node *node,
738 const char *path, acpi_status lookup_status); 737 const char *path, acpi_status lookup_status);
739 738
739/*
740 * Utility functions for ACPI names and IDs
741 */
742const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg);
743
744const struct ah_device_id *acpi_ah_match_hardware_id(char *hid);
745
740#endif /* _ACUTILS_H */ 746#endif /* _ACUTILS_H */
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c
index 5d594eb2e5ec..24ea3424981b 100644
--- a/drivers/acpi/acpica/evmisc.c
+++ b/drivers/acpi/acpica/evmisc.c
@@ -167,7 +167,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
167 "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", 167 "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
168 acpi_ut_get_node_name(node), 168 acpi_ut_get_node_name(node),
169 acpi_ut_get_type_name(node->type), notify_value, 169 acpi_ut_get_type_name(node->type), notify_value,
170 acpi_ut_get_notify_name(notify_value), node)); 170 acpi_ut_get_notify_name(notify_value, ACPI_TYPE_ANY),
171 node));
171 172
172 status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, 173 status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
173 info); 174 info);
diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c
index 4d8a709c1fc4..29630e303829 100644
--- a/drivers/acpi/acpica/evsci.c
+++ b/drivers/acpi/acpica/evsci.c
@@ -117,7 +117,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)
117 ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler); 117 ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler);
118 118
119 /* 119 /*
120 * We are guaranteed by the ACPI CA initialization/shutdown code that 120 * We are guaranteed by the ACPICA initialization/shutdown code that
121 * if this interrupt handler is installed, ACPI is enabled. 121 * if this interrupt handler is installed, ACPI is enabled.
122 */ 122 */
123 123
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index a734b27da061..11e5803b8b41 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -239,7 +239,7 @@ acpi_remove_notify_handler(acpi_handle device,
239 union acpi_operand_object *obj_desc; 239 union acpi_operand_object *obj_desc;
240 union acpi_operand_object *handler_obj; 240 union acpi_operand_object *handler_obj;
241 union acpi_operand_object *previous_handler_obj; 241 union acpi_operand_object *previous_handler_obj;
242 acpi_status status; 242 acpi_status status = AE_OK;
243 u32 i; 243 u32 i;
244 244
245 ACPI_FUNCTION_TRACE(acpi_remove_notify_handler); 245 ACPI_FUNCTION_TRACE(acpi_remove_notify_handler);
@@ -251,20 +251,17 @@ acpi_remove_notify_handler(acpi_handle device,
251 return_ACPI_STATUS(AE_BAD_PARAMETER); 251 return_ACPI_STATUS(AE_BAD_PARAMETER);
252 } 252 }
253 253
254 /* Make sure all deferred notify tasks are completed */
255
256 acpi_os_wait_events_complete();
257
258 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
259 if (ACPI_FAILURE(status)) {
260 return_ACPI_STATUS(status);
261 }
262
263 /* Root Object. Global handlers are removed here */ 254 /* Root Object. Global handlers are removed here */
264 255
265 if (device == ACPI_ROOT_OBJECT) { 256 if (device == ACPI_ROOT_OBJECT) {
266 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { 257 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
267 if (handler_type & (i + 1)) { 258 if (handler_type & (i + 1)) {
259 status =
260 acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
261 if (ACPI_FAILURE(status)) {
262 return_ACPI_STATUS(status);
263 }
264
268 if (!acpi_gbl_global_notify[i].handler || 265 if (!acpi_gbl_global_notify[i].handler ||
269 (acpi_gbl_global_notify[i].handler != 266 (acpi_gbl_global_notify[i].handler !=
270 handler)) { 267 handler)) {
@@ -277,31 +274,40 @@ acpi_remove_notify_handler(acpi_handle device,
277 274
278 acpi_gbl_global_notify[i].handler = NULL; 275 acpi_gbl_global_notify[i].handler = NULL;
279 acpi_gbl_global_notify[i].context = NULL; 276 acpi_gbl_global_notify[i].context = NULL;
277
278 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
279
280 /* Make sure all deferred notify tasks are completed */
281
282 acpi_os_wait_events_complete();
280 } 283 }
281 } 284 }
282 285
283 goto unlock_and_exit; 286 return_ACPI_STATUS(AE_OK);
284 } 287 }
285 288
286 /* All other objects: Are Notifies allowed on this object? */ 289 /* All other objects: Are Notifies allowed on this object? */
287 290
288 if (!acpi_ev_is_notify_object(node)) { 291 if (!acpi_ev_is_notify_object(node)) {
289 status = AE_TYPE; 292 return_ACPI_STATUS(AE_TYPE);
290 goto unlock_and_exit;
291 } 293 }
292 294
293 /* Must have an existing internal object */ 295 /* Must have an existing internal object */
294 296
295 obj_desc = acpi_ns_get_attached_object(node); 297 obj_desc = acpi_ns_get_attached_object(node);
296 if (!obj_desc) { 298 if (!obj_desc) {
297 status = AE_NOT_EXIST; 299 return_ACPI_STATUS(AE_NOT_EXIST);
298 goto unlock_and_exit;
299 } 300 }
300 301
301 /* Internal object exists. Find the handler and remove it */ 302 /* Internal object exists. Find the handler and remove it */
302 303
303 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { 304 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
304 if (handler_type & (i + 1)) { 305 if (handler_type & (i + 1)) {
306 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
307 if (ACPI_FAILURE(status)) {
308 return_ACPI_STATUS(status);
309 }
310
305 handler_obj = obj_desc->common_notify.notify_list[i]; 311 handler_obj = obj_desc->common_notify.notify_list[i];
306 previous_handler_obj = NULL; 312 previous_handler_obj = NULL;
307 313
@@ -329,10 +335,17 @@ acpi_remove_notify_handler(acpi_handle device,
329 handler_obj->notify.next[i]; 335 handler_obj->notify.next[i];
330 } 336 }
331 337
338 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
339
340 /* Make sure all deferred notify tasks are completed */
341
342 acpi_os_wait_events_complete();
332 acpi_ut_remove_reference(handler_obj); 343 acpi_ut_remove_reference(handler_obj);
333 } 344 }
334 } 345 }
335 346
347 return_ACPI_STATUS(status);
348
336unlock_and_exit: 349unlock_and_exit:
337 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 350 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
338 return_ACPI_STATUS(status); 351 return_ACPI_STATUS(status);
@@ -457,6 +470,8 @@ exit:
457 return_ACPI_STATUS(status); 470 return_ACPI_STATUS(status);
458} 471}
459 472
473ACPI_EXPORT_SYMBOL(acpi_install_sci_handler)
474
460/******************************************************************************* 475/*******************************************************************************
461 * 476 *
462 * FUNCTION: acpi_remove_sci_handler 477 * FUNCTION: acpi_remove_sci_handler
@@ -468,7 +483,6 @@ exit:
468 * DESCRIPTION: Remove a handler for a System Control Interrupt. 483 * DESCRIPTION: Remove a handler for a System Control Interrupt.
469 * 484 *
470 ******************************************************************************/ 485 ******************************************************************************/
471
472acpi_status acpi_remove_sci_handler(acpi_sci_handler address) 486acpi_status acpi_remove_sci_handler(acpi_sci_handler address)
473{ 487{
474 struct acpi_sci_handler_info *prev_sci_handler; 488 struct acpi_sci_handler_info *prev_sci_handler;
@@ -522,6 +536,8 @@ unlock_and_exit:
522 return_ACPI_STATUS(status); 536 return_ACPI_STATUS(status);
523} 537}
524 538
539ACPI_EXPORT_SYMBOL(acpi_remove_sci_handler)
540
525/******************************************************************************* 541/*******************************************************************************
526 * 542 *
527 * FUNCTION: acpi_install_global_event_handler 543 * FUNCTION: acpi_install_global_event_handler
@@ -537,7 +553,6 @@ unlock_and_exit:
537 * Can be used to update event counters, etc. 553 * Can be used to update event counters, etc.
538 * 554 *
539 ******************************************************************************/ 555 ******************************************************************************/
540
541acpi_status 556acpi_status
542acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) 557acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context)
543{ 558{
@@ -840,10 +855,6 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
840 return_ACPI_STATUS(AE_BAD_PARAMETER); 855 return_ACPI_STATUS(AE_BAD_PARAMETER);
841 } 856 }
842 857
843 /* Make sure all deferred GPE tasks are completed */
844
845 acpi_os_wait_events_complete();
846
847 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 858 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
848 if (ACPI_FAILURE(status)) { 859 if (ACPI_FAILURE(status)) {
849 return_ACPI_STATUS(status); 860 return_ACPI_STATUS(status);
@@ -895,9 +906,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
895 (void)acpi_ev_add_gpe_reference(gpe_event_info); 906 (void)acpi_ev_add_gpe_reference(gpe_event_info);
896 } 907 }
897 908
909 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
910 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
911
912 /* Make sure all deferred GPE tasks are completed */
913
914 acpi_os_wait_events_complete();
915
898 /* Now we can free the handler object */ 916 /* Now we can free the handler object */
899 917
900 ACPI_FREE(handler); 918 ACPI_FREE(handler);
919 return_ACPI_STATUS(status);
901 920
902unlock_and_exit: 921unlock_and_exit:
903 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 922 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 8ba1464efd11..7d2949420db7 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -343,16 +343,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
343 struct acpi_walk_state *walk_state) 343 struct acpi_walk_state *walk_state)
344{ 344{
345 union acpi_operand_object *ddb_handle; 345 union acpi_operand_object *ddb_handle;
346 struct acpi_table_header *table_header;
346 struct acpi_table_header *table; 347 struct acpi_table_header *table;
347 struct acpi_table_desc table_desc;
348 u32 table_index; 348 u32 table_index;
349 acpi_status status; 349 acpi_status status;
350 u32 length; 350 u32 length;
351 351
352 ACPI_FUNCTION_TRACE(ex_load_op); 352 ACPI_FUNCTION_TRACE(ex_load_op);
353 353
354 ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
355
356 /* Source Object can be either an op_region or a Buffer/Field */ 354 /* Source Object can be either an op_region or a Buffer/Field */
357 355
358 switch (obj_desc->common.type) { 356 switch (obj_desc->common.type) {
@@ -380,17 +378,17 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
380 378
381 /* Get the table header first so we can get the table length */ 379 /* Get the table header first so we can get the table length */
382 380
383 table = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); 381 table_header = ACPI_ALLOCATE(sizeof(struct acpi_table_header));
384 if (!table) { 382 if (!table_header) {
385 return_ACPI_STATUS(AE_NO_MEMORY); 383 return_ACPI_STATUS(AE_NO_MEMORY);
386 } 384 }
387 385
388 status = 386 status =
389 acpi_ex_region_read(obj_desc, 387 acpi_ex_region_read(obj_desc,
390 sizeof(struct acpi_table_header), 388 sizeof(struct acpi_table_header),
391 ACPI_CAST_PTR(u8, table)); 389 ACPI_CAST_PTR(u8, table_header));
392 length = table->length; 390 length = table_header->length;
393 ACPI_FREE(table); 391 ACPI_FREE(table_header);
394 392
395 if (ACPI_FAILURE(status)) { 393 if (ACPI_FAILURE(status)) {
396 return_ACPI_STATUS(status); 394 return_ACPI_STATUS(status);
@@ -420,22 +418,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
420 418
421 /* Allocate a buffer for the table */ 419 /* Allocate a buffer for the table */
422 420
423 table_desc.pointer = ACPI_ALLOCATE(length); 421 table = ACPI_ALLOCATE(length);
424 if (!table_desc.pointer) { 422 if (!table) {
425 return_ACPI_STATUS(AE_NO_MEMORY); 423 return_ACPI_STATUS(AE_NO_MEMORY);
426 } 424 }
427 425
428 /* Read the entire table */ 426 /* Read the entire table */
429 427
430 status = acpi_ex_region_read(obj_desc, length, 428 status = acpi_ex_region_read(obj_desc, length,
431 ACPI_CAST_PTR(u8, 429 ACPI_CAST_PTR(u8, table));
432 table_desc.pointer));
433 if (ACPI_FAILURE(status)) { 430 if (ACPI_FAILURE(status)) {
434 ACPI_FREE(table_desc.pointer); 431 ACPI_FREE(table);
435 return_ACPI_STATUS(status); 432 return_ACPI_STATUS(status);
436 } 433 }
437
438 table_desc.address = obj_desc->region.address;
439 break; 434 break;
440 435
441 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ 436 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */
@@ -452,10 +447,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
452 447
453 /* Get the actual table length from the table header */ 448 /* Get the actual table length from the table header */
454 449
455 table = 450 table_header =
456 ACPI_CAST_PTR(struct acpi_table_header, 451 ACPI_CAST_PTR(struct acpi_table_header,
457 obj_desc->buffer.pointer); 452 obj_desc->buffer.pointer);
458 length = table->length; 453 length = table_header->length;
459 454
460 /* Table cannot extend beyond the buffer */ 455 /* Table cannot extend beyond the buffer */
461 456
@@ -470,13 +465,12 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
470 * Copy the table from the buffer because the buffer could be modified 465 * Copy the table from the buffer because the buffer could be modified
471 * or even deleted in the future 466 * or even deleted in the future
472 */ 467 */
473 table_desc.pointer = ACPI_ALLOCATE(length); 468 table = ACPI_ALLOCATE(length);
474 if (!table_desc.pointer) { 469 if (!table) {
475 return_ACPI_STATUS(AE_NO_MEMORY); 470 return_ACPI_STATUS(AE_NO_MEMORY);
476 } 471 }
477 472
478 ACPI_MEMCPY(table_desc.pointer, table, length); 473 ACPI_MEMCPY(table, table_header, length);
479 table_desc.address = ACPI_TO_INTEGER(table_desc.pointer);
480 break; 474 break;
481 475
482 default: 476 default:
@@ -484,27 +478,32 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
484 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 478 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
485 } 479 }
486 480
487 /* Validate table checksum (will not get validated in tb_add_table) */ 481 /* Install the new table into the local data structures */
488
489 status = acpi_tb_verify_checksum(table_desc.pointer, length);
490 if (ACPI_FAILURE(status)) {
491 ACPI_FREE(table_desc.pointer);
492 return_ACPI_STATUS(status);
493 }
494
495 /* Complete the table descriptor */
496 482
497 table_desc.length = length; 483 ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:"));
498 table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; 484 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
499 485
500 /* Install the new table into the local data structures */ 486 status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table),
487 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
488 TRUE, TRUE, &table_index);
501 489
502 status = acpi_tb_add_table(&table_desc, &table_index); 490 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
503 if (ACPI_FAILURE(status)) { 491 if (ACPI_FAILURE(status)) {
504 492
505 /* Delete allocated table buffer */ 493 /* Delete allocated table buffer */
506 494
507 acpi_tb_delete_table(&table_desc); 495 ACPI_FREE(table);
496 return_ACPI_STATUS(status);
497 }
498
499 /*
500 * Note: Now table is "INSTALLED", it must be validated before
501 * loading.
502 */
503 status =
504 acpi_tb_validate_table(&acpi_gbl_root_table_list.
505 tables[table_index]);
506 if (ACPI_FAILURE(status)) {
508 return_ACPI_STATUS(status); 507 return_ACPI_STATUS(status);
509 } 508 }
510 509
@@ -536,9 +535,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
536 return_ACPI_STATUS(status); 535 return_ACPI_STATUS(status);
537 } 536 }
538 537
539 ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:"));
540 acpi_tb_print_table_header(0, table_desc.pointer);
541
542 /* Remove the reference by added by acpi_ex_store above */ 538 /* Remove the reference by added by acpi_ex_store above */
543 539
544 acpi_ut_remove_reference(ddb_handle); 540 acpi_ut_remove_reference(ddb_handle);
@@ -546,8 +542,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
546 /* Invoke table handler if present */ 542 /* Invoke table handler if present */
547 543
548 if (acpi_gbl_table_handler) { 544 if (acpi_gbl_table_handler) {
549 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, 545 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
550 table_desc.pointer,
551 acpi_gbl_table_handler_context); 546 acpi_gbl_table_handler_context);
552 } 547 }
553 548
@@ -576,6 +571,13 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
576 ACPI_FUNCTION_TRACE(ex_unload_table); 571 ACPI_FUNCTION_TRACE(ex_unload_table);
577 572
578 /* 573 /*
574 * Temporarily emit a warning so that the ASL for the machine can be
575 * hopefully obtained. This is to say that the Unload() operator is
576 * extremely rare if not completely unused.
577 */
578 ACPI_WARNING((AE_INFO, "Received request to unload an ACPI table"));
579
580 /*
579 * Validate the handle 581 * Validate the handle
580 * Although the handle is partially validated in acpi_ex_reconfiguration() 582 * Although the handle is partially validated in acpi_ex_reconfiguration()
581 * when it calls acpi_ex_resolve_operands(), the handle is more completely 583 * when it calls acpi_ex_resolve_operands(), the handle is more completely
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
index 973fdae00f94..925202acc3e4 100644
--- a/drivers/acpi/acpica/exdump.c
+++ b/drivers/acpi/acpica/exdump.c
@@ -134,9 +134,11 @@ static struct acpi_exdump_info acpi_ex_dump_method[9] = {
134 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"} 134 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"}
135}; 135};
136 136
137static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { 137static struct acpi_exdump_info acpi_ex_dump_mutex[6] = {
138 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, 138 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL},
139 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, 139 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"},
140 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.original_sync_level),
141 "Original Sync Level"},
140 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, 142 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"},
141 {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), 143 {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth),
142 "Acquire Depth"}, 144 "Acquire Depth"},
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
new file mode 100644
index 000000000000..cbe29944dc97
--- /dev/null
+++ b/drivers/acpi/acpica/tbdata.c
@@ -0,0 +1,723 @@
1/******************************************************************************
2 *
3 * Module Name: tbdata - Table manager data structure functions
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 "acnamesp.h"
47#include "actables.h"
48
49#define _COMPONENT ACPI_TABLES
50ACPI_MODULE_NAME("tbdata")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_tb_init_table_descriptor
55 *
56 * PARAMETERS: table_desc - Table descriptor
57 * address - Physical address of the table
58 * flags - Allocation flags of the table
59 * table - Pointer to the table
60 *
61 * RETURN: None
62 *
63 * DESCRIPTION: Initialize a new table descriptor
64 *
65 ******************************************************************************/
66void
67acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
68 acpi_physical_address address,
69 u8 flags, struct acpi_table_header *table)
70{
71
72 /*
73 * Initialize the table descriptor. Set the pointer to NULL, since the
74 * table is not fully mapped at this time.
75 */
76 ACPI_MEMSET(table_desc, 0, sizeof(struct acpi_table_desc));
77 table_desc->address = address;
78 table_desc->length = table->length;
79 table_desc->flags = flags;
80 ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
81}
82
83/*******************************************************************************
84 *
85 * FUNCTION: acpi_tb_acquire_table
86 *
87 * PARAMETERS: table_desc - Table descriptor
88 * table_ptr - Where table is returned
89 * table_length - Where table length is returned
90 * table_flags - Where table allocation flags are returned
91 *
92 * RETURN: Status
93 *
94 * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
95 * maintained in the acpi_gbl_root_table_list.
96 *
97 ******************************************************************************/
98
99acpi_status
100acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
101 struct acpi_table_header **table_ptr,
102 u32 *table_length, u8 *table_flags)
103{
104 struct acpi_table_header *table = NULL;
105
106 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
107 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
108
109 table =
110 acpi_os_map_memory(table_desc->address, table_desc->length);
111 break;
112
113 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
114 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
115
116 table =
117 ACPI_CAST_PTR(struct acpi_table_header,
118 table_desc->address);
119 break;
120
121 default:
122
123 break;
124 }
125
126 /* Table is not valid yet */
127
128 if (!table) {
129 return (AE_NO_MEMORY);
130 }
131
132 /* Fill the return values */
133
134 *table_ptr = table;
135 *table_length = table_desc->length;
136 *table_flags = table_desc->flags;
137 return (AE_OK);
138}
139
140/*******************************************************************************
141 *
142 * FUNCTION: acpi_tb_release_table
143 *
144 * PARAMETERS: table - Pointer for the table
145 * table_length - Length for the table
146 * table_flags - Allocation flags for the table
147 *
148 * RETURN: None
149 *
150 * DESCRIPTION: Release a table. The inverse of acpi_tb_acquire_table().
151 *
152 ******************************************************************************/
153
154void
155acpi_tb_release_table(struct acpi_table_header *table,
156 u32 table_length, u8 table_flags)
157{
158
159 switch (table_flags & ACPI_TABLE_ORIGIN_MASK) {
160 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
161
162 acpi_os_unmap_memory(table, table_length);
163 break;
164
165 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
166 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
167 default:
168
169 break;
170 }
171}
172
173/*******************************************************************************
174 *
175 * FUNCTION: acpi_tb_acquire_temp_table
176 *
177 * PARAMETERS: table_desc - Table descriptor to be acquired
178 * address - Address of the table
179 * flags - Allocation flags of the table
180 *
181 * RETURN: Status
182 *
183 * DESCRIPTION: This function validates the table header to obtain the length
184 * of a table and fills the table descriptor to make its state as
185 * "INSTALLED". Such a table descriptor is only used for verified
186 * installation.
187 *
188 ******************************************************************************/
189
190acpi_status
191acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc,
192 acpi_physical_address address, u8 flags)
193{
194 struct acpi_table_header *table_header;
195
196 switch (flags & ACPI_TABLE_ORIGIN_MASK) {
197 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
198
199 /* Get the length of the full table from the header */
200
201 table_header =
202 acpi_os_map_memory(address,
203 sizeof(struct acpi_table_header));
204 if (!table_header) {
205 return (AE_NO_MEMORY);
206 }
207
208 acpi_tb_init_table_descriptor(table_desc, address, flags,
209 table_header);
210 acpi_os_unmap_memory(table_header,
211 sizeof(struct acpi_table_header));
212 return (AE_OK);
213
214 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
215 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
216
217 table_header = ACPI_CAST_PTR(struct acpi_table_header, address);
218 if (!table_header) {
219 return (AE_NO_MEMORY);
220 }
221
222 acpi_tb_init_table_descriptor(table_desc, address, flags,
223 table_header);
224 return (AE_OK);
225
226 default:
227
228 break;
229 }
230
231 /* Table is not valid yet */
232
233 return (AE_NO_MEMORY);
234}
235
236/*******************************************************************************
237 *
238 * FUNCTION: acpi_tb_release_temp_table
239 *
240 * PARAMETERS: table_desc - Table descriptor to be released
241 *
242 * RETURN: Status
243 *
244 * DESCRIPTION: The inverse of acpi_tb_acquire_temp_table().
245 *
246 *****************************************************************************/
247
248void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc)
249{
250
251 /*
252 * Note that the .Address is maintained by the callers of
253 * acpi_tb_acquire_temp_table(), thus do not invoke acpi_tb_uninstall_table()
254 * where .Address will be freed.
255 */
256 acpi_tb_invalidate_table(table_desc);
257}
258
259/******************************************************************************
260 *
261 * FUNCTION: acpi_tb_validate_table
262 *
263 * PARAMETERS: table_desc - Table descriptor
264 *
265 * RETURN: Status
266 *
267 * DESCRIPTION: This function is called to validate the table, the returned
268 * table descriptor is in "VALIDATED" state.
269 *
270 *****************************************************************************/
271
272acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc)
273{
274 acpi_status status = AE_OK;
275
276 ACPI_FUNCTION_TRACE(tb_validate_table);
277
278 /* Validate the table if necessary */
279
280 if (!table_desc->pointer) {
281 status = acpi_tb_acquire_table(table_desc, &table_desc->pointer,
282 &table_desc->length,
283 &table_desc->flags);
284 if (!table_desc->pointer) {
285 status = AE_NO_MEMORY;
286 }
287 }
288
289 return_ACPI_STATUS(status);
290}
291
292/*******************************************************************************
293 *
294 * FUNCTION: acpi_tb_invalidate_table
295 *
296 * PARAMETERS: table_desc - Table descriptor
297 *
298 * RETURN: None
299 *
300 * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
301 * acpi_tb_validate_table().
302 *
303 ******************************************************************************/
304
305void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
306{
307
308 ACPI_FUNCTION_TRACE(tb_invalidate_table);
309
310 /* Table must be validated */
311
312 if (!table_desc->pointer) {
313 return_VOID;
314 }
315
316 acpi_tb_release_table(table_desc->pointer, table_desc->length,
317 table_desc->flags);
318 table_desc->pointer = NULL;
319
320 return_VOID;
321}
322
323/******************************************************************************
324 *
325 * FUNCTION: acpi_tb_verify_table
326 *
327 * PARAMETERS: table_desc - Table descriptor
328 * signature - Table signature to verify
329 *
330 * RETURN: Status
331 *
332 * DESCRIPTION: This function is called to validate and verify the table, the
333 * returned table descriptor is in "VALIDATED" state.
334 *
335 *****************************************************************************/
336
337acpi_status
338acpi_tb_verify_table(struct acpi_table_desc *table_desc, char *signature)
339{
340 acpi_status status = AE_OK;
341
342 ACPI_FUNCTION_TRACE(tb_verify_table);
343
344 /* Validate the table */
345
346 status = acpi_tb_validate_table(table_desc);
347 if (ACPI_FAILURE(status)) {
348 return_ACPI_STATUS(AE_NO_MEMORY);
349 }
350
351 /* If a particular signature is expected (DSDT/FACS), it must match */
352
353 if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) {
354 ACPI_BIOS_ERROR((AE_INFO,
355 "Invalid signature 0x%X for ACPI table, expected [%s]",
356 table_desc->signature.integer, signature));
357 status = AE_BAD_SIGNATURE;
358 goto invalidate_and_exit;
359 }
360
361 /* Verify the checksum */
362
363 status =
364 acpi_tb_verify_checksum(table_desc->pointer, table_desc->length);
365 if (ACPI_FAILURE(status)) {
366 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
367 "%4.4s " ACPI_PRINTF_UINT
368 " Attempted table install failed",
369 acpi_ut_valid_acpi_name(table_desc->signature.
370 ascii) ? table_desc->
371 signature.ascii : "????",
372 ACPI_FORMAT_TO_UINT(table_desc->address)));
373 goto invalidate_and_exit;
374 }
375
376 return_ACPI_STATUS(AE_OK);
377
378invalidate_and_exit:
379 acpi_tb_invalidate_table(table_desc);
380 return_ACPI_STATUS(status);
381}
382
383/*******************************************************************************
384 *
385 * FUNCTION: acpi_tb_resize_root_table_list
386 *
387 * PARAMETERS: None
388 *
389 * RETURN: Status
390 *
391 * DESCRIPTION: Expand the size of global table array
392 *
393 ******************************************************************************/
394
395acpi_status acpi_tb_resize_root_table_list(void)
396{
397 struct acpi_table_desc *tables;
398 u32 table_count;
399
400 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
401
402 /* allow_resize flag is a parameter to acpi_initialize_tables */
403
404 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
405 ACPI_ERROR((AE_INFO,
406 "Resize of Root Table Array is not allowed"));
407 return_ACPI_STATUS(AE_SUPPORT);
408 }
409
410 /* Increase the Table Array size */
411
412 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
413 table_count = acpi_gbl_root_table_list.max_table_count;
414 } else {
415 table_count = acpi_gbl_root_table_list.current_table_count;
416 }
417
418 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count +
419 ACPI_ROOT_TABLE_SIZE_INCREMENT) *
420 sizeof(struct acpi_table_desc));
421 if (!tables) {
422 ACPI_ERROR((AE_INFO,
423 "Could not allocate new root table array"));
424 return_ACPI_STATUS(AE_NO_MEMORY);
425 }
426
427 /* Copy and free the previous table array */
428
429 if (acpi_gbl_root_table_list.tables) {
430 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
431 (acpi_size) table_count *
432 sizeof(struct acpi_table_desc));
433
434 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
435 ACPI_FREE(acpi_gbl_root_table_list.tables);
436 }
437 }
438
439 acpi_gbl_root_table_list.tables = tables;
440 acpi_gbl_root_table_list.max_table_count =
441 table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
442 acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
443
444 return_ACPI_STATUS(AE_OK);
445}
446
447/*******************************************************************************
448 *
449 * FUNCTION: acpi_tb_get_next_root_index
450 *
451 * PARAMETERS: table_index - Where table index is returned
452 *
453 * RETURN: Status and table index.
454 *
455 * DESCRIPTION: Allocate a new ACPI table entry to the global table list
456 *
457 ******************************************************************************/
458
459acpi_status acpi_tb_get_next_root_index(u32 *table_index)
460{
461 acpi_status status;
462
463 /* Ensure that there is room for the table in the Root Table List */
464
465 if (acpi_gbl_root_table_list.current_table_count >=
466 acpi_gbl_root_table_list.max_table_count) {
467 status = acpi_tb_resize_root_table_list();
468 if (ACPI_FAILURE(status)) {
469 return (status);
470 }
471 }
472
473 *table_index = acpi_gbl_root_table_list.current_table_count;
474 acpi_gbl_root_table_list.current_table_count++;
475 return (AE_OK);
476}
477
478/*******************************************************************************
479 *
480 * FUNCTION: acpi_tb_terminate
481 *
482 * PARAMETERS: None
483 *
484 * RETURN: None
485 *
486 * DESCRIPTION: Delete all internal ACPI tables
487 *
488 ******************************************************************************/
489
490void acpi_tb_terminate(void)
491{
492 u32 i;
493
494 ACPI_FUNCTION_TRACE(tb_terminate);
495
496 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
497
498 /* Delete the individual tables */
499
500 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
501 acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]);
502 }
503
504 /*
505 * Delete the root table array if allocated locally. Array cannot be
506 * mapped, so we don't need to check for that flag.
507 */
508 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
509 ACPI_FREE(acpi_gbl_root_table_list.tables);
510 }
511
512 acpi_gbl_root_table_list.tables = NULL;
513 acpi_gbl_root_table_list.flags = 0;
514 acpi_gbl_root_table_list.current_table_count = 0;
515
516 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
517
518 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
519 return_VOID;
520}
521
522/*******************************************************************************
523 *
524 * FUNCTION: acpi_tb_delete_namespace_by_owner
525 *
526 * PARAMETERS: table_index - Table index
527 *
528 * RETURN: Status
529 *
530 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
531 *
532 ******************************************************************************/
533
534acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
535{
536 acpi_owner_id owner_id;
537 acpi_status status;
538
539 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
540
541 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
542 if (ACPI_FAILURE(status)) {
543 return_ACPI_STATUS(status);
544 }
545
546 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
547
548 /* The table index does not exist */
549
550 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
551 return_ACPI_STATUS(AE_NOT_EXIST);
552 }
553
554 /* Get the owner ID for this table, used to delete namespace nodes */
555
556 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
557 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
558
559 /*
560 * Need to acquire the namespace writer lock to prevent interference
561 * with any concurrent namespace walks. The interpreter must be
562 * released during the deletion since the acquisition of the deletion
563 * lock may block, and also since the execution of a namespace walk
564 * must be allowed to use the interpreter.
565 */
566 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
567 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
568
569 acpi_ns_delete_namespace_by_owner(owner_id);
570 if (ACPI_FAILURE(status)) {
571 return_ACPI_STATUS(status);
572 }
573
574 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
575
576 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
577 return_ACPI_STATUS(status);
578}
579
580/*******************************************************************************
581 *
582 * FUNCTION: acpi_tb_allocate_owner_id
583 *
584 * PARAMETERS: table_index - Table index
585 *
586 * RETURN: Status
587 *
588 * DESCRIPTION: Allocates owner_id in table_desc
589 *
590 ******************************************************************************/
591
592acpi_status acpi_tb_allocate_owner_id(u32 table_index)
593{
594 acpi_status status = AE_BAD_PARAMETER;
595
596 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
597
598 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
599 if (table_index < acpi_gbl_root_table_list.current_table_count) {
600 status =
601 acpi_ut_allocate_owner_id(&
602 (acpi_gbl_root_table_list.
603 tables[table_index].owner_id));
604 }
605
606 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
607 return_ACPI_STATUS(status);
608}
609
610/*******************************************************************************
611 *
612 * FUNCTION: acpi_tb_release_owner_id
613 *
614 * PARAMETERS: table_index - Table index
615 *
616 * RETURN: Status
617 *
618 * DESCRIPTION: Releases owner_id in table_desc
619 *
620 ******************************************************************************/
621
622acpi_status acpi_tb_release_owner_id(u32 table_index)
623{
624 acpi_status status = AE_BAD_PARAMETER;
625
626 ACPI_FUNCTION_TRACE(tb_release_owner_id);
627
628 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
629 if (table_index < acpi_gbl_root_table_list.current_table_count) {
630 acpi_ut_release_owner_id(&
631 (acpi_gbl_root_table_list.
632 tables[table_index].owner_id));
633 status = AE_OK;
634 }
635
636 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
637 return_ACPI_STATUS(status);
638}
639
640/*******************************************************************************
641 *
642 * FUNCTION: acpi_tb_get_owner_id
643 *
644 * PARAMETERS: table_index - Table index
645 * owner_id - Where the table owner_id is returned
646 *
647 * RETURN: Status
648 *
649 * DESCRIPTION: returns owner_id for the ACPI table
650 *
651 ******************************************************************************/
652
653acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id)
654{
655 acpi_status status = AE_BAD_PARAMETER;
656
657 ACPI_FUNCTION_TRACE(tb_get_owner_id);
658
659 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
660 if (table_index < acpi_gbl_root_table_list.current_table_count) {
661 *owner_id =
662 acpi_gbl_root_table_list.tables[table_index].owner_id;
663 status = AE_OK;
664 }
665
666 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
667 return_ACPI_STATUS(status);
668}
669
670/*******************************************************************************
671 *
672 * FUNCTION: acpi_tb_is_table_loaded
673 *
674 * PARAMETERS: table_index - Index into the root table
675 *
676 * RETURN: Table Loaded Flag
677 *
678 ******************************************************************************/
679
680u8 acpi_tb_is_table_loaded(u32 table_index)
681{
682 u8 is_loaded = FALSE;
683
684 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
685 if (table_index < acpi_gbl_root_table_list.current_table_count) {
686 is_loaded = (u8)
687 (acpi_gbl_root_table_list.tables[table_index].flags &
688 ACPI_TABLE_IS_LOADED);
689 }
690
691 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
692 return (is_loaded);
693}
694
695/*******************************************************************************
696 *
697 * FUNCTION: acpi_tb_set_table_loaded_flag
698 *
699 * PARAMETERS: table_index - Table index
700 * is_loaded - TRUE if table is loaded, FALSE otherwise
701 *
702 * RETURN: None
703 *
704 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
705 *
706 ******************************************************************************/
707
708void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
709{
710
711 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
712 if (table_index < acpi_gbl_root_table_list.current_table_count) {
713 if (is_loaded) {
714 acpi_gbl_root_table_list.tables[table_index].flags |=
715 ACPI_TABLE_IS_LOADED;
716 } else {
717 acpi_gbl_root_table_list.tables[table_index].flags &=
718 ~ACPI_TABLE_IS_LOADED;
719 }
720 }
721
722 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
723}
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index ec14588254d4..a37af164b8c8 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -332,15 +332,15 @@ void acpi_tb_parse_fadt(u32 table_index)
332 332
333 /* Obtain the DSDT and FACS tables via their addresses within the FADT */ 333 /* Obtain the DSDT and FACS tables via their addresses within the FADT */
334 334
335 acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, 335 acpi_tb_install_fixed_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
336 ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); 336 ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
337 337
338 /* If Hardware Reduced flag is set, there is no FACS */ 338 /* If Hardware Reduced flag is set, there is no FACS */
339 339
340 if (!acpi_gbl_reduced_hardware) { 340 if (!acpi_gbl_reduced_hardware) {
341 acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT. 341 acpi_tb_install_fixed_table((acpi_physical_address)
342 Xfacs, ACPI_SIG_FACS, 342 acpi_gbl_FADT.Xfacs, ACPI_SIG_FACS,
343 ACPI_TABLE_INDEX_FACS); 343 ACPI_TABLE_INDEX_FACS);
344 } 344 }
345} 345}
346 346
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c
index c12003947bd5..cb947700206c 100644
--- a/drivers/acpi/acpica/tbfind.c
+++ b/drivers/acpi/acpica/tbfind.c
@@ -99,8 +99,8 @@ acpi_tb_find_table(char *signature,
99 /* Table is not currently mapped, map it */ 99 /* Table is not currently mapped, map it */
100 100
101 status = 101 status =
102 acpi_tb_verify_table(&acpi_gbl_root_table_list. 102 acpi_tb_validate_table(&acpi_gbl_root_table_list.
103 tables[i]); 103 tables[i]);
104 if (ACPI_FAILURE(status)) { 104 if (ACPI_FAILURE(status)) {
105 return_ACPI_STATUS(status); 105 return_ACPI_STATUS(status);
106 } 106 }
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index e3040947e9a0..d4d6029fef44 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -43,688 +43,483 @@
43 43
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include "accommon.h" 45#include "accommon.h"
46#include "acnamesp.h"
47#include "actables.h" 46#include "actables.h"
48 47
49#define _COMPONENT ACPI_TABLES 48#define _COMPONENT ACPI_TABLES
50ACPI_MODULE_NAME("tbinstal") 49ACPI_MODULE_NAME("tbinstal")
51 50
52/****************************************************************************** 51/* Local prototypes */
52static u8
53acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
54
55/*******************************************************************************
53 * 56 *
54 * FUNCTION: acpi_tb_verify_table 57 * FUNCTION: acpi_tb_compare_tables
55 * 58 *
56 * PARAMETERS: table_desc - table 59 * PARAMETERS: table_desc - Table 1 descriptor to be compared
60 * table_index - Index of table 2 to be compared
57 * 61 *
58 * RETURN: Status 62 * RETURN: TRUE if both tables are identical.
59 * 63 *
60 * DESCRIPTION: this function is called to verify and map table 64 * DESCRIPTION: This function compares a table with another table that has
65 * already been installed in the root table list.
61 * 66 *
62 *****************************************************************************/ 67 ******************************************************************************/
63acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) 68
69static u8
70acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
64{ 71{
65 acpi_status status = AE_OK; 72 acpi_status status = AE_OK;
73 u8 is_identical;
74 struct acpi_table_header *table;
75 u32 table_length;
76 u8 table_flags;
66 77
67 ACPI_FUNCTION_TRACE(tb_verify_table); 78 status =
68 79 acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
69 /* Map the table if necessary */ 80 &table, &table_length, &table_flags);
70 81 if (ACPI_FAILURE(status)) {
71 if (!table_desc->pointer) { 82 return (FALSE);
72 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
73 ACPI_TABLE_ORIGIN_MAPPED) {
74 table_desc->pointer =
75 acpi_os_map_memory(table_desc->address,
76 table_desc->length);
77 }
78 if (!table_desc->pointer) {
79 return_ACPI_STATUS(AE_NO_MEMORY);
80 }
81 } 83 }
82 84
83 /* Always calculate checksum, ignore bad checksum if requested */ 85 /*
86 * Check for a table match on the entire table length,
87 * not just the header.
88 */
89 is_identical = (u8)((table_desc->length != table_length ||
90 ACPI_MEMCMP(table_desc->pointer, table,
91 table_length)) ? FALSE : TRUE);
84 92
85 status = 93 /* Release the acquired table */
86 acpi_tb_verify_checksum(table_desc->pointer, table_desc->length);
87 94
88 return_ACPI_STATUS(status); 95 acpi_tb_release_table(table, table_length, table_flags);
96 return (is_identical);
89} 97}
90 98
91/******************************************************************************* 99/*******************************************************************************
92 * 100 *
93 * FUNCTION: acpi_tb_add_table 101 * FUNCTION: acpi_tb_install_table_with_override
94 * 102 *
95 * PARAMETERS: table_desc - Table descriptor 103 * PARAMETERS: table_index - Index into root table array
96 * table_index - Where the table index is returned 104 * new_table_desc - New table descriptor to install
105 * override - Whether override should be performed
97 * 106 *
98 * RETURN: Status 107 * RETURN: None
99 * 108 *
100 * DESCRIPTION: This function is called to add an ACPI table. It is used to 109 * DESCRIPTION: Install an ACPI table into the global data structure. The
101 * dynamically load tables via the Load and load_table AML 110 * table override mechanism is called to allow the host
102 * operators. 111 * OS to replace any table before it is installed in the root
112 * table array.
103 * 113 *
104 ******************************************************************************/ 114 ******************************************************************************/
105 115
106acpi_status 116void
107acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) 117acpi_tb_install_table_with_override(u32 table_index,
118 struct acpi_table_desc *new_table_desc,
119 u8 override)
108{ 120{
109 u32 i;
110 acpi_status status = AE_OK;
111 121
112 ACPI_FUNCTION_TRACE(tb_add_table); 122 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
113 123 return;
114 if (!table_desc->pointer) {
115 status = acpi_tb_verify_table(table_desc);
116 if (ACPI_FAILURE(status) || !table_desc->pointer) {
117 return_ACPI_STATUS(status);
118 }
119 } 124 }
120 125
121 /* 126 /*
122 * Validate the incoming table signature. 127 * ACPI Table Override:
123 * 128 *
124 * 1) Originally, we checked the table signature for "SSDT" or "PSDT". 129 * Before we install the table, let the host OS override it with a new
125 * 2) We added support for OEMx tables, signature "OEM". 130 * one if desired. Any table within the RSDT/XSDT can be replaced,
126 * 3) Valid tables were encountered with a null signature, so we just 131 * including the DSDT which is pointed to by the FADT.
127 * gave up on validating the signature, (05/2008).
128 * 4) We encountered non-AML tables such as the MADT, which caused
129 * interpreter errors and kernel faults. So now, we once again allow
130 * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
131 */ 132 */
132 if ((table_desc->pointer->signature[0] != 0x00) && 133 if (override) {
133 (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)) 134 acpi_tb_override_table(new_table_desc);
134 && (ACPI_STRNCMP(table_desc->pointer->signature, "OEM", 3))) {
135 ACPI_BIOS_ERROR((AE_INFO,
136 "Table has invalid signature [%4.4s] (0x%8.8X), "
137 "must be SSDT or OEMx",
138 acpi_ut_valid_acpi_name(table_desc->pointer->
139 signature) ?
140 table_desc->pointer->signature : "????",
141 *(u32 *)table_desc->pointer->signature));
142
143 return_ACPI_STATUS(AE_BAD_SIGNATURE);
144 } 135 }
145 136
146 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 137 acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.
138 tables[table_index],
139 new_table_desc->address,
140 new_table_desc->flags,
141 new_table_desc->pointer);
147 142
148 /* Check if table is already registered */ 143 acpi_tb_print_table_header(new_table_desc->address,
144 new_table_desc->pointer);
149 145
150 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { 146 /* Set the global integer width (based upon revision of the DSDT) */
151 if (!acpi_gbl_root_table_list.tables[i].pointer) {
152 status =
153 acpi_tb_verify_table(&acpi_gbl_root_table_list.
154 tables[i]);
155 if (ACPI_FAILURE(status)
156 || !acpi_gbl_root_table_list.tables[i].pointer) {
157 continue;
158 }
159 }
160 147
161 /* 148 if (table_index == ACPI_TABLE_INDEX_DSDT) {
162 * Check for a table match on the entire table length, 149 acpi_ut_set_integer_width(new_table_desc->pointer->revision);
163 * not just the header.
164 */
165 if (table_desc->length !=
166 acpi_gbl_root_table_list.tables[i].length) {
167 continue;
168 }
169
170 if (ACPI_MEMCMP(table_desc->pointer,
171 acpi_gbl_root_table_list.tables[i].pointer,
172 acpi_gbl_root_table_list.tables[i].length)) {
173 continue;
174 }
175
176 /*
177 * Note: the current mechanism does not unregister a table if it is
178 * dynamically unloaded. The related namespace entries are deleted,
179 * but the table remains in the root table list.
180 *
181 * The assumption here is that the number of different tables that
182 * will be loaded is actually small, and there is minimal overhead
183 * in just keeping the table in case it is needed again.
184 *
185 * If this assumption changes in the future (perhaps on large
186 * machines with many table load/unload operations), tables will
187 * need to be unregistered when they are unloaded, and slots in the
188 * root table list should be reused when empty.
189 */
190
191 /*
192 * Table is already registered.
193 * We can delete the table that was passed as a parameter.
194 */
195 acpi_tb_delete_table(table_desc);
196 *table_index = i;
197
198 if (acpi_gbl_root_table_list.tables[i].
199 flags & ACPI_TABLE_IS_LOADED) {
200
201 /* Table is still loaded, this is an error */
202
203 status = AE_ALREADY_EXISTS;
204 goto release;
205 } else {
206 /* Table was unloaded, allow it to be reloaded */
207
208 table_desc->pointer =
209 acpi_gbl_root_table_list.tables[i].pointer;
210 table_desc->address =
211 acpi_gbl_root_table_list.tables[i].address;
212 status = AE_OK;
213 goto print_header;
214 }
215 } 150 }
216
217 /*
218 * ACPI Table Override:
219 * Allow the host to override dynamically loaded tables.
220 * NOTE: the table is fully mapped at this point, and the mapping will
221 * be deleted by tb_table_override if the table is actually overridden.
222 */
223 (void)acpi_tb_table_override(table_desc->pointer, table_desc);
224
225 /* Add the table to the global root table list */
226
227 status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
228 table_desc->length, table_desc->flags,
229 table_index);
230 if (ACPI_FAILURE(status)) {
231 goto release;
232 }
233
234print_header:
235 acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
236
237release:
238 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
239 return_ACPI_STATUS(status);
240} 151}
241 152
242/******************************************************************************* 153/*******************************************************************************
243 * 154 *
244 * FUNCTION: acpi_tb_table_override 155 * FUNCTION: acpi_tb_install_fixed_table
245 * 156 *
246 * PARAMETERS: table_header - Header for the original table 157 * PARAMETERS: address - Physical address of DSDT or FACS
247 * table_desc - Table descriptor initialized for the 158 * signature - Table signature, NULL if no need to
248 * original table. May or may not be mapped. 159 * match
160 * table_index - Index into root table array
249 * 161 *
250 * RETURN: Pointer to the entire new table. NULL if table not overridden. 162 * RETURN: Status
251 * If overridden, installs the new table within the input table
252 * descriptor.
253 * 163 *
254 * DESCRIPTION: Attempt table override by calling the OSL override functions. 164 * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data
255 * Note: If the table is overridden, then the entire new table 165 * structure.
256 * is mapped and returned by this function.
257 * 166 *
258 ******************************************************************************/ 167 ******************************************************************************/
259 168
260struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header 169acpi_status
261 *table_header, 170acpi_tb_install_fixed_table(acpi_physical_address address,
262 struct acpi_table_desc 171 char *signature, u32 table_index)
263 *table_desc)
264{ 172{
173 struct acpi_table_desc new_table_desc;
265 acpi_status status; 174 acpi_status status;
266 struct acpi_table_header *new_table = NULL;
267 acpi_physical_address new_address = 0;
268 u32 new_table_length = 0;
269 u8 new_flags;
270 char *override_type;
271 175
272 /* (1) Attempt logical override (returns a logical address) */ 176 ACPI_FUNCTION_TRACE(tb_install_fixed_table);
273 177
274 status = acpi_os_table_override(table_header, &new_table); 178 if (!address) {
275 if (ACPI_SUCCESS(status) && new_table) { 179 ACPI_ERROR((AE_INFO,
276 new_address = ACPI_PTR_TO_PHYSADDR(new_table); 180 "Null physical address for ACPI table [%s]",
277 new_table_length = new_table->length; 181 signature));
278 new_flags = ACPI_TABLE_ORIGIN_OVERRIDE; 182 return (AE_NO_MEMORY);
279 override_type = "Logical";
280 goto finish_override;
281 } 183 }
282 184
283 /* (2) Attempt physical override (returns a physical address) */ 185 /* Fill a table descriptor for validation */
284 186
285 status = acpi_os_physical_table_override(table_header, 187 status = acpi_tb_acquire_temp_table(&new_table_desc, address,
286 &new_address, 188 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
287 &new_table_length); 189 if (ACPI_FAILURE(status)) {
288 if (ACPI_SUCCESS(status) && new_address && new_table_length) { 190 ACPI_ERROR((AE_INFO, "Could not acquire table length at %p",
289 191 ACPI_CAST_PTR(void, address)));
290 /* Map the entire new table */ 192 return_ACPI_STATUS(status);
291
292 new_table = acpi_os_map_memory(new_address, new_table_length);
293 if (!new_table) {
294 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
295 "%4.4s " ACPI_PRINTF_UINT
296 " Attempted physical table override failed",
297 table_header->signature,
298 ACPI_FORMAT_TO_UINT(table_desc->
299 address)));
300 return (NULL);
301 }
302
303 override_type = "Physical";
304 new_flags = ACPI_TABLE_ORIGIN_MAPPED;
305 goto finish_override;
306 } 193 }
307 194
308 return (NULL); /* There was no override */ 195 /* Validate and verify a table before installation */
309
310finish_override:
311
312 ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT
313 " %s table override, new table: " ACPI_PRINTF_UINT,
314 table_header->signature,
315 ACPI_FORMAT_TO_UINT(table_desc->address),
316 override_type, ACPI_FORMAT_TO_UINT(new_table)));
317 196
318 /* We can now unmap/delete the original table (if fully mapped) */ 197 status = acpi_tb_verify_table(&new_table_desc, signature);
198 if (ACPI_FAILURE(status)) {
199 goto release_and_exit;
200 }
319 201
320 acpi_tb_delete_table(table_desc); 202 acpi_tb_install_table_with_override(table_index, &new_table_desc, TRUE);
321 203
322 /* Setup descriptor for the new table */ 204release_and_exit:
323 205
324 table_desc->address = new_address; 206 /* Release the temporary table descriptor */
325 table_desc->pointer = new_table;
326 table_desc->length = new_table_length;
327 table_desc->flags = new_flags;
328 207
329 return (new_table); 208 acpi_tb_release_temp_table(&new_table_desc);
209 return_ACPI_STATUS(status);
330} 210}
331 211
332/******************************************************************************* 212/*******************************************************************************
333 * 213 *
334 * FUNCTION: acpi_tb_resize_root_table_list 214 * FUNCTION: acpi_tb_install_standard_table
335 * 215 *
336 * PARAMETERS: None 216 * PARAMETERS: address - Address of the table (might be a virtual
217 * address depending on the table_flags)
218 * flags - Flags for the table
219 * reload - Whether reload should be performed
220 * override - Whether override should be performed
221 * table_index - Where the table index is returned
337 * 222 *
338 * RETURN: Status 223 * RETURN: Status
339 * 224 *
340 * DESCRIPTION: Expand the size of global table array 225 * DESCRIPTION: This function is called to install an ACPI table that is
226 * neither DSDT nor FACS (a "standard" table.)
227 * When this function is called by "Load" or "LoadTable" opcodes,
228 * or by acpi_load_table() API, the "Reload" parameter is set.
229 * After sucessfully returning from this function, table is
230 * "INSTALLED" but not "VALIDATED".
341 * 231 *
342 ******************************************************************************/ 232 ******************************************************************************/
343 233
344acpi_status acpi_tb_resize_root_table_list(void) 234acpi_status
235acpi_tb_install_standard_table(acpi_physical_address address,
236 u8 flags,
237 u8 reload, u8 override, u32 *table_index)
345{ 238{
346 struct acpi_table_desc *tables; 239 u32 i;
347 u32 table_count; 240 acpi_status status = AE_OK;
348 241 struct acpi_table_desc new_table_desc;
349 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
350
351 /* allow_resize flag is a parameter to acpi_initialize_tables */
352 242
353 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { 243 ACPI_FUNCTION_TRACE(tb_install_standard_table);
354 ACPI_ERROR((AE_INFO,
355 "Resize of Root Table Array is not allowed"));
356 return_ACPI_STATUS(AE_SUPPORT);
357 }
358 244
359 /* Increase the Table Array size */ 245 /* Acquire a temporary table descriptor for validation */
360 246
361 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 247 status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags);
362 table_count = acpi_gbl_root_table_list.max_table_count; 248 if (ACPI_FAILURE(status)) {
363 } else { 249 ACPI_ERROR((AE_INFO, "Could not acquire table length at %p",
364 table_count = acpi_gbl_root_table_list.current_table_count; 250 ACPI_CAST_PTR(void, address)));
251 return_ACPI_STATUS(status);
365 } 252 }
366 253
367 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + 254 /*
368 ACPI_ROOT_TABLE_SIZE_INCREMENT) * 255 * Optionally do not load any SSDTs from the RSDT/XSDT. This can
369 sizeof(struct acpi_table_desc)); 256 * be useful for debugging ACPI problems on some machines.
370 if (!tables) { 257 */
371 ACPI_ERROR((AE_INFO, 258 if (!reload &&
372 "Could not allocate new root table array")); 259 acpi_gbl_disable_ssdt_table_install &&
373 return_ACPI_STATUS(AE_NO_MEMORY); 260 ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) {
261 ACPI_INFO((AE_INFO, "Ignoring installation of %4.4s at %p",
262 new_table_desc.signature.ascii, ACPI_CAST_PTR(void,
263 address)));
264 goto release_and_exit;
374 } 265 }
375 266
376 /* Copy and free the previous table array */ 267 /* Validate and verify a table before installation */
377
378 if (acpi_gbl_root_table_list.tables) {
379 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
380 (acpi_size) table_count *
381 sizeof(struct acpi_table_desc));
382 268
383 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 269 status = acpi_tb_verify_table(&new_table_desc, NULL);
384 ACPI_FREE(acpi_gbl_root_table_list.tables); 270 if (ACPI_FAILURE(status)) {
385 } 271 goto release_and_exit;
386 } 272 }
387 273
388 acpi_gbl_root_table_list.tables = tables; 274 if (reload) {
389 acpi_gbl_root_table_list.max_table_count = 275 /*
390 table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; 276 * Validate the incoming table signature.
391 acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; 277 *
392 278 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
393 return_ACPI_STATUS(AE_OK); 279 * 2) We added support for OEMx tables, signature "OEM".
394} 280 * 3) Valid tables were encountered with a null signature, so we just
395 281 * gave up on validating the signature, (05/2008).
396/******************************************************************************* 282 * 4) We encountered non-AML tables such as the MADT, which caused
397 * 283 * interpreter errors and kernel faults. So now, we once again allow
398 * FUNCTION: acpi_tb_store_table 284 * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
399 * 285 */
400 * PARAMETERS: address - Table address 286 if ((new_table_desc.signature.ascii[0] != 0x00) &&
401 * table - Table header 287 (!ACPI_COMPARE_NAME
402 * length - Table length 288 (&new_table_desc.signature, ACPI_SIG_SSDT))
403 * flags - flags 289 && (ACPI_STRNCMP(new_table_desc.signature.ascii, "OEM", 3)))
404 * 290 {
405 * RETURN: Status and table index. 291 ACPI_BIOS_ERROR((AE_INFO,
406 * 292 "Table has invalid signature [%4.4s] (0x%8.8X), "
407 * DESCRIPTION: Add an ACPI table to the global table list 293 "must be SSDT or OEMx",
408 * 294 acpi_ut_valid_acpi_name(new_table_desc.
409 ******************************************************************************/ 295 signature.
296 ascii) ?
297 new_table_desc.signature.
298 ascii : "????",
299 new_table_desc.signature.integer));
300
301 status = AE_BAD_SIGNATURE;
302 goto release_and_exit;
303 }
410 304
411acpi_status 305 /* Check if table is already registered */
412acpi_tb_store_table(acpi_physical_address address,
413 struct acpi_table_header *table,
414 u32 length, u8 flags, u32 *table_index)
415{
416 acpi_status status;
417 struct acpi_table_desc *new_table;
418 306
419 /* Ensure that there is room for the table in the Root Table List */ 307 for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
308 ++i) {
309 /*
310 * Check for a table match on the entire table length,
311 * not just the header.
312 */
313 if (!acpi_tb_compare_tables(&new_table_desc, i)) {
314 continue;
315 }
420 316
421 if (acpi_gbl_root_table_list.current_table_count >= 317 /*
422 acpi_gbl_root_table_list.max_table_count) { 318 * Note: the current mechanism does not unregister a table if it is
423 status = acpi_tb_resize_root_table_list(); 319 * dynamically unloaded. The related namespace entries are deleted,
424 if (ACPI_FAILURE(status)) { 320 * but the table remains in the root table list.
425 return (status); 321 *
322 * The assumption here is that the number of different tables that
323 * will be loaded is actually small, and there is minimal overhead
324 * in just keeping the table in case it is needed again.
325 *
326 * If this assumption changes in the future (perhaps on large
327 * machines with many table load/unload operations), tables will
328 * need to be unregistered when they are unloaded, and slots in the
329 * root table list should be reused when empty.
330 */
331 if (acpi_gbl_root_table_list.tables[i].
332 flags & ACPI_TABLE_IS_LOADED) {
333
334 /* Table is still loaded, this is an error */
335
336 status = AE_ALREADY_EXISTS;
337 goto release_and_exit;
338 } else {
339 /*
340 * Table was unloaded, allow it to be reloaded.
341 * As we are going to return AE_OK to the caller, we should
342 * take the responsibility of freeing the input descriptor.
343 * Refill the input descriptor to ensure
344 * acpi_tb_install_table_with_override() can be called again to
345 * indicate the re-installation.
346 */
347 acpi_tb_uninstall_table(&new_table_desc);
348 *table_index = i;
349 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
350 return_ACPI_STATUS(AE_OK);
351 }
426 } 352 }
427 } 353 }
428 354
429 new_table = 355 /* Add the table to the global root table list */
430 &acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.
431 current_table_count];
432
433 /* Initialize added table */
434
435 new_table->address = address;
436 new_table->pointer = table;
437 new_table->length = length;
438 new_table->owner_id = 0;
439 new_table->flags = flags;
440
441 ACPI_MOVE_32_TO_32(&new_table->signature, table->signature);
442
443 *table_index = acpi_gbl_root_table_list.current_table_count;
444 acpi_gbl_root_table_list.current_table_count++;
445 return (AE_OK);
446}
447
448/*******************************************************************************
449 *
450 * FUNCTION: acpi_tb_delete_table
451 *
452 * PARAMETERS: table_index - Table index
453 *
454 * RETURN: None
455 *
456 * DESCRIPTION: Delete one internal ACPI table
457 *
458 ******************************************************************************/
459 356
460void acpi_tb_delete_table(struct acpi_table_desc *table_desc) 357 status = acpi_tb_get_next_root_index(&i);
461{ 358 if (ACPI_FAILURE(status)) {
462 /* Table must be mapped or allocated */ 359 goto release_and_exit;
463 if (!table_desc->pointer) {
464 return;
465 } 360 }
466 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
467 case ACPI_TABLE_ORIGIN_MAPPED:
468
469 acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
470 break;
471
472 case ACPI_TABLE_ORIGIN_ALLOCATED:
473 361
474 ACPI_FREE(table_desc->pointer); 362 *table_index = i;
475 break; 363 acpi_tb_install_table_with_override(i, &new_table_desc, override);
476 364
477 /* Not mapped or allocated, there is nothing we can do */ 365release_and_exit:
478 366
479 default: 367 /* Release the temporary table descriptor */
480 368
481 return; 369 acpi_tb_release_temp_table(&new_table_desc);
482 } 370 return_ACPI_STATUS(status);
483
484 table_desc->pointer = NULL;
485} 371}
486 372
487/******************************************************************************* 373/*******************************************************************************
488 * 374 *
489 * FUNCTION: acpi_tb_terminate 375 * FUNCTION: acpi_tb_override_table
490 * 376 *
491 * PARAMETERS: None 377 * PARAMETERS: old_table_desc - Validated table descriptor to be
378 * overridden
492 * 379 *
493 * RETURN: None 380 * RETURN: None
494 * 381 *
495 * DESCRIPTION: Delete all internal ACPI tables 382 * DESCRIPTION: Attempt table override by calling the OSL override functions.
383 * Note: If the table is overridden, then the entire new table
384 * is acquired and returned by this function.
385 * Before/after invocation, the table descriptor is in a state
386 * that is "VALIDATED".
496 * 387 *
497 ******************************************************************************/ 388 ******************************************************************************/
498 389
499void acpi_tb_terminate(void) 390void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
500{ 391{
501 u32 i; 392 acpi_status status;
502 393 char *override_type;
503 ACPI_FUNCTION_TRACE(tb_terminate); 394 struct acpi_table_desc new_table_desc;
504 395 struct acpi_table_header *table;
505 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 396 acpi_physical_address address;
506 397 u32 length;
507 /* Delete the individual tables */
508 398
509 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { 399 /* (1) Attempt logical override (returns a logical address) */
510 acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]);
511 }
512 400
513 /* 401 status = acpi_os_table_override(old_table_desc->pointer, &table);
514 * Delete the root table array if allocated locally. Array cannot be 402 if (ACPI_SUCCESS(status) && table) {
515 * mapped, so we don't need to check for that flag. 403 acpi_tb_acquire_temp_table(&new_table_desc,
516 */ 404 ACPI_PTR_TO_PHYSADDR(table),
517 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 405 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL);
518 ACPI_FREE(acpi_gbl_root_table_list.tables); 406 override_type = "Logical";
407 goto finish_override;
519 } 408 }
520 409
521 acpi_gbl_root_table_list.tables = NULL; 410 /* (2) Attempt physical override (returns a physical address) */
522 acpi_gbl_root_table_list.flags = 0;
523 acpi_gbl_root_table_list.current_table_count = 0;
524 411
525 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); 412 status = acpi_os_physical_table_override(old_table_desc->pointer,
526 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 413 &address, &length);
414 if (ACPI_SUCCESS(status) && address && length) {
415 acpi_tb_acquire_temp_table(&new_table_desc, address,
416 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
417 override_type = "Physical";
418 goto finish_override;
419 }
527 420
528 return_VOID; 421 return; /* There was no override */
529}
530 422
531/******************************************************************************* 423finish_override:
532 *
533 * FUNCTION: acpi_tb_delete_namespace_by_owner
534 *
535 * PARAMETERS: table_index - Table index
536 *
537 * RETURN: Status
538 *
539 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
540 *
541 ******************************************************************************/
542
543acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
544{
545 acpi_owner_id owner_id;
546 acpi_status status;
547 424
548 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); 425 /* Validate and verify a table before overriding */
549 426
550 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 427 status = acpi_tb_verify_table(&new_table_desc, NULL);
551 if (ACPI_FAILURE(status)) { 428 if (ACPI_FAILURE(status)) {
552 return_ACPI_STATUS(status); 429 return;
553 } 430 }
554 431
555 if (table_index >= acpi_gbl_root_table_list.current_table_count) { 432 ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT
556 433 " %s table override, new table: " ACPI_PRINTF_UINT,
557 /* The table index does not exist */ 434 old_table_desc->signature.ascii,
558 435 ACPI_FORMAT_TO_UINT(old_table_desc->address),
559 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 436 override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address)));
560 return_ACPI_STATUS(AE_NOT_EXIST);
561 }
562 437
563 /* Get the owner ID for this table, used to delete namespace nodes */ 438 /* We can now uninstall the original table */
564 439
565 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; 440 acpi_tb_uninstall_table(old_table_desc);
566 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
567 441
568 /* 442 /*
569 * Need to acquire the namespace writer lock to prevent interference 443 * Replace the original table descriptor and keep its state as
570 * with any concurrent namespace walks. The interpreter must be 444 * "VALIDATED".
571 * released during the deletion since the acquisition of the deletion
572 * lock may block, and also since the execution of a namespace walk
573 * must be allowed to use the interpreter.
574 */ 445 */
575 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); 446 acpi_tb_init_table_descriptor(old_table_desc, new_table_desc.address,
576 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); 447 new_table_desc.flags,
448 new_table_desc.pointer);
449 acpi_tb_validate_table(old_table_desc);
577 450
578 acpi_ns_delete_namespace_by_owner(owner_id); 451 /* Release the temporary table descriptor */
579 if (ACPI_FAILURE(status)) {
580 return_ACPI_STATUS(status);
581 }
582 452
583 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); 453 acpi_tb_release_temp_table(&new_table_desc);
584
585 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
586 return_ACPI_STATUS(status);
587} 454}
588 455
589/******************************************************************************* 456/*******************************************************************************
590 * 457 *
591 * FUNCTION: acpi_tb_allocate_owner_id 458 * FUNCTION: acpi_tb_store_table
592 * 459 *
593 * PARAMETERS: table_index - Table index 460 * PARAMETERS: address - Table address
461 * table - Table header
462 * length - Table length
463 * flags - Install flags
464 * table_index - Where the table index is returned
594 * 465 *
595 * RETURN: Status 466 * RETURN: Status and table index.
596 * 467 *
597 * DESCRIPTION: Allocates owner_id in table_desc 468 * DESCRIPTION: Add an ACPI table to the global table list
598 * 469 *
599 ******************************************************************************/ 470 ******************************************************************************/
600 471
601acpi_status acpi_tb_allocate_owner_id(u32 table_index) 472acpi_status
473acpi_tb_store_table(acpi_physical_address address,
474 struct acpi_table_header * table,
475 u32 length, u8 flags, u32 *table_index)
602{ 476{
603 acpi_status status = AE_BAD_PARAMETER; 477 acpi_status status;
604 478 struct acpi_table_desc *table_desc;
605 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
606 479
607 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 480 status = acpi_tb_get_next_root_index(table_index);
608 if (table_index < acpi_gbl_root_table_list.current_table_count) { 481 if (ACPI_FAILURE(status)) {
609 status = acpi_ut_allocate_owner_id 482 return (status);
610 (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
611 } 483 }
612 484
613 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 485 /* Initialize added table */
614 return_ACPI_STATUS(status);
615}
616
617/*******************************************************************************
618 *
619 * FUNCTION: acpi_tb_release_owner_id
620 *
621 * PARAMETERS: table_index - Table index
622 *
623 * RETURN: Status
624 *
625 * DESCRIPTION: Releases owner_id in table_desc
626 *
627 ******************************************************************************/
628
629acpi_status acpi_tb_release_owner_id(u32 table_index)
630{
631 acpi_status status = AE_BAD_PARAMETER;
632
633 ACPI_FUNCTION_TRACE(tb_release_owner_id);
634
635 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
636 if (table_index < acpi_gbl_root_table_list.current_table_count) {
637 acpi_ut_release_owner_id(&
638 (acpi_gbl_root_table_list.
639 tables[table_index].owner_id));
640 status = AE_OK;
641 }
642 486
643 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 487 table_desc = &acpi_gbl_root_table_list.tables[*table_index];
644 return_ACPI_STATUS(status); 488 acpi_tb_init_table_descriptor(table_desc, address, flags, table);
489 table_desc->pointer = table;
490 return (AE_OK);
645} 491}
646 492
647/******************************************************************************* 493/*******************************************************************************
648 * 494 *
649 * FUNCTION: acpi_tb_get_owner_id 495 * FUNCTION: acpi_tb_uninstall_table
650 * 496 *
651 * PARAMETERS: table_index - Table index 497 * PARAMETERS: table_desc - Table descriptor
652 * owner_id - Where the table owner_id is returned
653 * 498 *
654 * RETURN: Status 499 * RETURN: None
655 * 500 *
656 * DESCRIPTION: returns owner_id for the ACPI table 501 * DESCRIPTION: Delete one internal ACPI table
657 * 502 *
658 ******************************************************************************/ 503 ******************************************************************************/
659 504
660acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id) 505void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
661{ 506{
662 acpi_status status = AE_BAD_PARAMETER;
663
664 ACPI_FUNCTION_TRACE(tb_get_owner_id);
665 507
666 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 508 ACPI_FUNCTION_TRACE(tb_uninstall_table);
667 if (table_index < acpi_gbl_root_table_list.current_table_count) {
668 *owner_id =
669 acpi_gbl_root_table_list.tables[table_index].owner_id;
670 status = AE_OK;
671 }
672 509
673 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 510 /* Table must be installed */
674 return_ACPI_STATUS(status);
675}
676
677/*******************************************************************************
678 *
679 * FUNCTION: acpi_tb_is_table_loaded
680 *
681 * PARAMETERS: table_index - Table index
682 *
683 * RETURN: Table Loaded Flag
684 *
685 ******************************************************************************/
686 511
687u8 acpi_tb_is_table_loaded(u32 table_index) 512 if (!table_desc->address) {
688{ 513 return_VOID;
689 u8 is_loaded = FALSE;
690
691 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
692 if (table_index < acpi_gbl_root_table_list.current_table_count) {
693 is_loaded = (u8)
694 (acpi_gbl_root_table_list.tables[table_index].flags &
695 ACPI_TABLE_IS_LOADED);
696 } 514 }
697 515
698 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 516 acpi_tb_invalidate_table(table_desc);
699 return (is_loaded);
700}
701
702/*******************************************************************************
703 *
704 * FUNCTION: acpi_tb_set_table_loaded_flag
705 *
706 * PARAMETERS: table_index - Table index
707 * is_loaded - TRUE if table is loaded, FALSE otherwise
708 *
709 * RETURN: None
710 *
711 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
712 *
713 ******************************************************************************/
714
715void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
716{
717 517
718 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 518 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
719 if (table_index < acpi_gbl_root_table_list.current_table_count) { 519 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) {
720 if (is_loaded) { 520 ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address));
721 acpi_gbl_root_table_list.tables[table_index].flags |=
722 ACPI_TABLE_IS_LOADED;
723 } else {
724 acpi_gbl_root_table_list.tables[table_index].flags &=
725 ~ACPI_TABLE_IS_LOADED;
726 }
727 } 521 }
728 522
729 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 523 table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
524 return_VOID;
730} 525}
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index a4702eee91a8..6c31d77cece0 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -178,9 +178,13 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
178 } 178 }
179 179
180 ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); 180 ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length);
181 acpi_tb_delete_table(table_desc); 181 acpi_tb_uninstall_table(table_desc);
182 table_desc->pointer = new_table; 182
183 table_desc->flags = ACPI_TABLE_ORIGIN_ALLOCATED; 183 acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.
184 tables[ACPI_TABLE_INDEX_DSDT],
185 ACPI_PTR_TO_PHYSADDR(new_table),
186 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
187 new_table);
184 188
185 ACPI_INFO((AE_INFO, 189 ACPI_INFO((AE_INFO,
186 "Forced DSDT copy: length 0x%05X copied locally, original unmapped", 190 "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
@@ -191,116 +195,6 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
191 195
192/******************************************************************************* 196/*******************************************************************************
193 * 197 *
194 * FUNCTION: acpi_tb_install_table
195 *
196 * PARAMETERS: address - Physical address of DSDT or FACS
197 * signature - Table signature, NULL if no need to
198 * match
199 * table_index - Index into root table array
200 *
201 * RETURN: None
202 *
203 * DESCRIPTION: Install an ACPI table into the global data structure. The
204 * table override mechanism is called to allow the host
205 * OS to replace any table before it is installed in the root
206 * table array.
207 *
208 ******************************************************************************/
209
210void
211acpi_tb_install_table(acpi_physical_address address,
212 char *signature, u32 table_index)
213{
214 struct acpi_table_header *table;
215 struct acpi_table_header *final_table;
216 struct acpi_table_desc *table_desc;
217
218 if (!address) {
219 ACPI_ERROR((AE_INFO,
220 "Null physical address for ACPI table [%s]",
221 signature));
222 return;
223 }
224
225 /* Map just the table header */
226
227 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
228 if (!table) {
229 ACPI_ERROR((AE_INFO,
230 "Could not map memory for table [%s] at %p",
231 signature, ACPI_CAST_PTR(void, address)));
232 return;
233 }
234
235 /* If a particular signature is expected (DSDT/FACS), it must match */
236
237 if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
238 ACPI_BIOS_ERROR((AE_INFO,
239 "Invalid signature 0x%X for ACPI table, expected [%s]",
240 *ACPI_CAST_PTR(u32, table->signature),
241 signature));
242 goto unmap_and_exit;
243 }
244
245 /*
246 * Initialize the table entry. Set the pointer to NULL, since the
247 * table is not fully mapped at this time.
248 */
249 table_desc = &acpi_gbl_root_table_list.tables[table_index];
250
251 table_desc->address = address;
252 table_desc->pointer = NULL;
253 table_desc->length = table->length;
254 table_desc->flags = ACPI_TABLE_ORIGIN_MAPPED;
255 ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
256
257 /*
258 * ACPI Table Override:
259 *
260 * Before we install the table, let the host OS override it with a new
261 * one if desired. Any table within the RSDT/XSDT can be replaced,
262 * including the DSDT which is pointed to by the FADT.
263 *
264 * NOTE: If the table is overridden, then final_table will contain a
265 * mapped pointer to the full new table. If the table is not overridden,
266 * or if there has been a physical override, then the table will be
267 * fully mapped later (in verify table). In any case, we must
268 * unmap the header that was mapped above.
269 */
270 final_table = acpi_tb_table_override(table, table_desc);
271 if (!final_table) {
272 final_table = table; /* There was no override */
273 }
274
275 acpi_tb_print_table_header(table_desc->address, final_table);
276
277 /* Set the global integer width (based upon revision of the DSDT) */
278
279 if (table_index == ACPI_TABLE_INDEX_DSDT) {
280 acpi_ut_set_integer_width(final_table->revision);
281 }
282
283 /*
284 * If we have a physical override during this early loading of the ACPI
285 * tables, unmap the table for now. It will be mapped again later when
286 * it is actually used. This supports very early loading of ACPI tables,
287 * before virtual memory is fully initialized and running within the
288 * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE
289 * flag set and will not be deleted below.
290 */
291 if (final_table != table) {
292 acpi_tb_delete_table(table_desc);
293 }
294
295unmap_and_exit:
296
297 /* Always unmap the table header that we mapped above */
298
299 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
300}
301
302/*******************************************************************************
303 *
304 * FUNCTION: acpi_tb_get_root_table_entry 198 * FUNCTION: acpi_tb_get_root_table_entry
305 * 199 *
306 * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry 200 * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry
@@ -464,6 +358,7 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
464 u32 length; 358 u32 length;
465 u8 *table_entry; 359 u8 *table_entry;
466 acpi_status status; 360 acpi_status status;
361 u32 table_index;
467 362
468 ACPI_FUNCTION_TRACE(tb_parse_root_table); 363 ACPI_FUNCTION_TRACE(tb_parse_root_table);
469 364
@@ -573,31 +468,24 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
573 /* Initialize the root table array from the RSDT/XSDT */ 468 /* Initialize the root table array from the RSDT/XSDT */
574 469
575 for (i = 0; i < table_count; i++) { 470 for (i = 0; i < table_count; i++) {
576 if (acpi_gbl_root_table_list.current_table_count >=
577 acpi_gbl_root_table_list.max_table_count) {
578
579 /* There is no more room in the root table array, attempt resize */
580
581 status = acpi_tb_resize_root_table_list();
582 if (ACPI_FAILURE(status)) {
583 ACPI_WARNING((AE_INFO,
584 "Truncating %u table entries!",
585 (unsigned) (table_count -
586 (acpi_gbl_root_table_list.
587 current_table_count -
588 2))));
589 break;
590 }
591 }
592 471
593 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ 472 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
594 473
595 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. 474 status =
596 current_table_count].address = 475 acpi_tb_install_standard_table(acpi_tb_get_root_table_entry
597 acpi_tb_get_root_table_entry(table_entry, table_entry_size); 476 (table_entry,
477 table_entry_size),
478 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
479 FALSE, TRUE, &table_index);
480
481 if (ACPI_SUCCESS(status) &&
482 ACPI_COMPARE_NAME(&acpi_gbl_root_table_list.
483 tables[table_index].signature,
484 ACPI_SIG_FADT)) {
485 acpi_tb_parse_fadt(table_index);
486 }
598 487
599 table_entry += table_entry_size; 488 table_entry += table_entry_size;
600 acpi_gbl_root_table_list.current_table_count++;
601 } 489 }
602 490
603 /* 491 /*
@@ -606,22 +494,5 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
606 */ 494 */
607 acpi_os_unmap_memory(table, length); 495 acpi_os_unmap_memory(table, length);
608 496
609 /*
610 * Complete the initialization of the root table array by examining
611 * the header of each table
612 */
613 for (i = 2; i < acpi_gbl_root_table_list.current_table_count; i++) {
614 acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
615 address, NULL, i);
616
617 /* Special case for FADT - validate it then get the DSDT and FACS */
618
619 if (ACPI_COMPARE_NAME
620 (&acpi_gbl_root_table_list.tables[i].signature,
621 ACPI_SIG_FADT)) {
622 acpi_tb_parse_fadt(i);
623 }
624 }
625
626 return_ACPI_STATUS(AE_OK); 497 return_ACPI_STATUS(AE_OK);
627} 498}
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index a1593159d9ea..6482b0ded652 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -206,8 +206,8 @@ acpi_status
206acpi_get_table_header(char *signature, 206acpi_get_table_header(char *signature,
207 u32 instance, struct acpi_table_header *out_table_header) 207 u32 instance, struct acpi_table_header *out_table_header)
208{ 208{
209 u32 i; 209 u32 i;
210 u32 j; 210 u32 j;
211 struct acpi_table_header *header; 211 struct acpi_table_header *header;
212 212
213 /* Parameter validation */ 213 /* Parameter validation */
@@ -233,7 +233,7 @@ acpi_get_table_header(char *signature,
233 if (!acpi_gbl_root_table_list.tables[i].pointer) { 233 if (!acpi_gbl_root_table_list.tables[i].pointer) {
234 if ((acpi_gbl_root_table_list.tables[i].flags & 234 if ((acpi_gbl_root_table_list.tables[i].flags &
235 ACPI_TABLE_ORIGIN_MASK) == 235 ACPI_TABLE_ORIGIN_MASK) ==
236 ACPI_TABLE_ORIGIN_MAPPED) { 236 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL) {
237 header = 237 header =
238 acpi_os_map_memory(acpi_gbl_root_table_list. 238 acpi_os_map_memory(acpi_gbl_root_table_list.
239 tables[i].address, 239 tables[i].address,
@@ -321,8 +321,8 @@ acpi_get_table_with_size(char *signature,
321 u32 instance, struct acpi_table_header **out_table, 321 u32 instance, struct acpi_table_header **out_table,
322 acpi_size *tbl_size) 322 acpi_size *tbl_size)
323{ 323{
324 u32 i; 324 u32 i;
325 u32 j; 325 u32 j;
326 acpi_status status; 326 acpi_status status;
327 327
328 /* Parameter validation */ 328 /* Parameter validation */
@@ -346,7 +346,7 @@ acpi_get_table_with_size(char *signature,
346 } 346 }
347 347
348 status = 348 status =
349 acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); 349 acpi_tb_validate_table(&acpi_gbl_root_table_list.tables[i]);
350 if (ACPI_SUCCESS(status)) { 350 if (ACPI_SUCCESS(status)) {
351 *out_table = acpi_gbl_root_table_list.tables[i].pointer; 351 *out_table = acpi_gbl_root_table_list.tables[i].pointer;
352 *tbl_size = acpi_gbl_root_table_list.tables[i].length; 352 *tbl_size = acpi_gbl_root_table_list.tables[i].length;
@@ -390,7 +390,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table)
390 * 390 *
391 ******************************************************************************/ 391 ******************************************************************************/
392acpi_status 392acpi_status
393acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) 393acpi_get_table_by_index(u32 table_index, struct acpi_table_header ** table)
394{ 394{
395 acpi_status status; 395 acpi_status status;
396 396
@@ -416,8 +416,8 @@ acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table)
416 /* Table is not mapped, map it */ 416 /* Table is not mapped, map it */
417 417
418 status = 418 status =
419 acpi_tb_verify_table(&acpi_gbl_root_table_list. 419 acpi_tb_validate_table(&acpi_gbl_root_table_list.
420 tables[table_index]); 420 tables[table_index]);
421 if (ACPI_FAILURE(status)) { 421 if (ACPI_FAILURE(status)) {
422 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 422 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
423 return_ACPI_STATUS(status); 423 return_ACPI_STATUS(status);
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
index 0909420fc776..ab5308b81aa8 100644
--- a/drivers/acpi/acpica/tbxfload.c
+++ b/drivers/acpi/acpica/tbxfload.c
@@ -117,7 +117,7 @@ static acpi_status acpi_tb_load_namespace(void)
117 tables[ACPI_TABLE_INDEX_DSDT].signature), 117 tables[ACPI_TABLE_INDEX_DSDT].signature),
118 ACPI_SIG_DSDT) 118 ACPI_SIG_DSDT)
119 || 119 ||
120 ACPI_FAILURE(acpi_tb_verify_table 120 ACPI_FAILURE(acpi_tb_validate_table
121 (&acpi_gbl_root_table_list. 121 (&acpi_gbl_root_table_list.
122 tables[ACPI_TABLE_INDEX_DSDT]))) { 122 tables[ACPI_TABLE_INDEX_DSDT]))) {
123 status = AE_NO_ACPI_TABLES; 123 status = AE_NO_ACPI_TABLES;
@@ -128,7 +128,7 @@ static acpi_status acpi_tb_load_namespace(void)
128 * Save the DSDT pointer for simple access. This is the mapped memory 128 * Save the DSDT pointer for simple access. This is the mapped memory
129 * address. We must take care here because the address of the .Tables 129 * address. We must take care here because the address of the .Tables
130 * array can change dynamically as tables are loaded at run-time. Note: 130 * array can change dynamically as tables are loaded at run-time. Note:
131 * .Pointer field is not validated until after call to acpi_tb_verify_table. 131 * .Pointer field is not validated until after call to acpi_tb_validate_table.
132 */ 132 */
133 acpi_gbl_DSDT = 133 acpi_gbl_DSDT =
134 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; 134 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer;
@@ -174,24 +174,11 @@ static acpi_status acpi_tb_load_namespace(void)
174 (acpi_gbl_root_table_list.tables[i]. 174 (acpi_gbl_root_table_list.tables[i].
175 signature), ACPI_SIG_PSDT)) 175 signature), ACPI_SIG_PSDT))
176 || 176 ||
177 ACPI_FAILURE(acpi_tb_verify_table 177 ACPI_FAILURE(acpi_tb_validate_table
178 (&acpi_gbl_root_table_list.tables[i]))) { 178 (&acpi_gbl_root_table_list.tables[i]))) {
179 continue; 179 continue;
180 } 180 }
181 181
182 /*
183 * Optionally do not load any SSDTs from the RSDT/XSDT. This can
184 * be useful for debugging ACPI problems on some machines.
185 */
186 if (acpi_gbl_disable_ssdt_table_load) {
187 ACPI_INFO((AE_INFO, "Ignoring %4.4s at %p",
188 acpi_gbl_root_table_list.tables[i].signature.
189 ascii, ACPI_CAST_PTR(void,
190 acpi_gbl_root_table_list.
191 tables[i].address)));
192 continue;
193 }
194
195 /* Ignore errors while loading tables, get as many as possible */ 182 /* Ignore errors while loading tables, get as many as possible */
196 183
197 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 184 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
@@ -208,6 +195,45 @@ unlock_and_exit:
208 195
209/******************************************************************************* 196/*******************************************************************************
210 * 197 *
198 * FUNCTION: acpi_install_table
199 *
200 * PARAMETERS: address - Address of the ACPI table to be installed.
201 * physical - Whether the address is a physical table
202 * address or not
203 *
204 * RETURN: Status
205 *
206 * DESCRIPTION: Dynamically install an ACPI table.
207 * Note: This function should only be invoked after
208 * acpi_initialize_tables() and before acpi_load_tables().
209 *
210 ******************************************************************************/
211
212acpi_status __init
213acpi_install_table(acpi_physical_address address, u8 physical)
214{
215 acpi_status status;
216 u8 flags;
217 u32 table_index;
218
219 ACPI_FUNCTION_TRACE(acpi_install_table);
220
221 if (physical) {
222 flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
223 } else {
224 flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
225 }
226
227 status = acpi_tb_install_standard_table(address, flags,
228 FALSE, FALSE, &table_index);
229
230 return_ACPI_STATUS(status);
231}
232
233ACPI_EXPORT_SYMBOL_INIT(acpi_install_table)
234
235/*******************************************************************************
236 *
211 * FUNCTION: acpi_load_table 237 * FUNCTION: acpi_load_table
212 * 238 *
213 * PARAMETERS: table - Pointer to a buffer containing the ACPI 239 * PARAMETERS: table - Pointer to a buffer containing the ACPI
@@ -222,11 +248,9 @@ unlock_and_exit:
222 * to ensure that the table is not deleted or unmapped. 248 * to ensure that the table is not deleted or unmapped.
223 * 249 *
224 ******************************************************************************/ 250 ******************************************************************************/
225
226acpi_status acpi_load_table(struct acpi_table_header *table) 251acpi_status acpi_load_table(struct acpi_table_header *table)
227{ 252{
228 acpi_status status; 253 acpi_status status;
229 struct acpi_table_desc table_desc;
230 u32 table_index; 254 u32 table_index;
231 255
232 ACPI_FUNCTION_TRACE(acpi_load_table); 256 ACPI_FUNCTION_TRACE(acpi_load_table);
@@ -237,14 +261,6 @@ acpi_status acpi_load_table(struct acpi_table_header *table)
237 return_ACPI_STATUS(AE_BAD_PARAMETER); 261 return_ACPI_STATUS(AE_BAD_PARAMETER);
238 } 262 }
239 263
240 /* Init local table descriptor */
241
242 ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
243 table_desc.address = ACPI_PTR_TO_PHYSADDR(table);
244 table_desc.pointer = table;
245 table_desc.length = table->length;
246 table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN;
247
248 /* Must acquire the interpreter lock during this operation */ 264 /* Must acquire the interpreter lock during this operation */
249 265
250 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); 266 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
@@ -255,7 +271,24 @@ acpi_status acpi_load_table(struct acpi_table_header *table)
255 /* Install the table and load it into the namespace */ 271 /* Install the table and load it into the namespace */
256 272
257 ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); 273 ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
258 status = acpi_tb_add_table(&table_desc, &table_index); 274 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
275
276 status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table),
277 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
278 TRUE, FALSE, &table_index);
279
280 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
281 if (ACPI_FAILURE(status)) {
282 goto unlock_and_exit;
283 }
284
285 /*
286 * Note: Now table is "INSTALLED", it must be validated before
287 * using.
288 */
289 status =
290 acpi_tb_validate_table(&acpi_gbl_root_table_list.
291 tables[table_index]);
259 if (ACPI_FAILURE(status)) { 292 if (ACPI_FAILURE(status)) {
260 goto unlock_and_exit; 293 goto unlock_and_exit;
261 } 294 }
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c
index fbfa9eca011f..90ec37c473c6 100644
--- a/drivers/acpi/acpica/utdecode.c
+++ b/drivers/acpi/acpica/utdecode.c
@@ -462,7 +462,7 @@ char *acpi_ut_get_mutex_name(u32 mutex_id)
462 462
463/* Names for Notify() values, used for debug output */ 463/* Names for Notify() values, used for debug output */
464 464
465static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = { 465static const char *acpi_gbl_generic_notify[ACPI_NOTIFY_MAX + 1] = {
466 /* 00 */ "Bus Check", 466 /* 00 */ "Bus Check",
467 /* 01 */ "Device Check", 467 /* 01 */ "Device Check",
468 /* 02 */ "Device Wake", 468 /* 02 */ "Device Wake",
@@ -473,23 +473,75 @@ static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = {
473 /* 07 */ "Power Fault", 473 /* 07 */ "Power Fault",
474 /* 08 */ "Capabilities Check", 474 /* 08 */ "Capabilities Check",
475 /* 09 */ "Device PLD Check", 475 /* 09 */ "Device PLD Check",
476 /* 10 */ "Reserved", 476 /* 0A */ "Reserved",
477 /* 11 */ "System Locality Update", 477 /* 0B */ "System Locality Update",
478 /* 12 */ "Shutdown Request" 478 /* 0C */ "Shutdown Request"
479}; 479};
480 480
481const char *acpi_ut_get_notify_name(u32 notify_value) 481static const char *acpi_gbl_device_notify[4] = {
482 /* 80 */ "Status Change",
483 /* 81 */ "Information Change",
484 /* 82 */ "Device-Specific Change",
485 /* 83 */ "Device-Specific Change"
486};
487
488static const char *acpi_gbl_processor_notify[4] = {
489 /* 80 */ "Performance Capability Change",
490 /* 81 */ "C-State Change",
491 /* 82 */ "Throttling Capability Change",
492 /* 83 */ "Device-Specific Change"
493};
494
495static const char *acpi_gbl_thermal_notify[4] = {
496 /* 80 */ "Thermal Status Change",
497 /* 81 */ "Thermal Trip Point Change",
498 /* 82 */ "Thermal Device List Change",
499 /* 83 */ "Thermal Relationship Change"
500};
501
502const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type)
482{ 503{
483 504
505 /* 00 - 0C are common to all object types */
506
484 if (notify_value <= ACPI_NOTIFY_MAX) { 507 if (notify_value <= ACPI_NOTIFY_MAX) {
485 return (acpi_gbl_notify_value_names[notify_value]); 508 return (acpi_gbl_generic_notify[notify_value]);
486 } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { 509 }
510
511 /* 0D - 7F are reserved */
512
513 if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
487 return ("Reserved"); 514 return ("Reserved");
488 } else if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) {
489 return ("Device Specific");
490 } else {
491 return ("Hardware Specific");
492 } 515 }
516
517 /* 80 - 83 are per-object-type */
518
519 if (notify_value <= 0x83) {
520 switch (type) {
521 case ACPI_TYPE_ANY:
522 case ACPI_TYPE_DEVICE:
523 return (acpi_gbl_device_notify[notify_value - 0x80]);
524
525 case ACPI_TYPE_PROCESSOR:
526 return (acpi_gbl_processor_notify[notify_value - 0x80]);
527
528 case ACPI_TYPE_THERMAL:
529 return (acpi_gbl_thermal_notify[notify_value - 0x80]);
530
531 default:
532 return ("Target object type does not support notifies");
533 }
534 }
535
536 /* 84 - BF are device-specific */
537
538 if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) {
539 return ("Device-Specific");
540 }
541
542 /* C0 and above are hardware-specific */
543
544 return ("Hardware-Specific");
493} 545}
494#endif 546#endif
495 547
diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c
index 77219336c7e0..6dc54b3c28b0 100644
--- a/drivers/acpi/acpica/utstring.c
+++ b/drivers/acpi/acpica/utstring.c
@@ -353,7 +353,7 @@ void acpi_ut_print_string(char *string, u16 max_length)
353 } 353 }
354 354
355 acpi_os_printf("\""); 355 acpi_os_printf("\"");
356 for (i = 0; string[i] && (i < max_length); i++) { 356 for (i = 0; (i < max_length) && string[i]; i++) {
357 357
358 /* Escape sequences */ 358 /* Escape sequences */
359 359
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 6776c599816f..9aeae41e22fb 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1770,16 +1770,15 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
1770} 1770}
1771#endif 1771#endif
1772 1772
1773static int __init acpi_no_auto_ssdt_setup(char *s) 1773static int __init acpi_no_static_ssdt_setup(char *s)
1774{ 1774{
1775 printk(KERN_NOTICE PREFIX "SSDT auto-load disabled\n"); 1775 acpi_gbl_disable_ssdt_table_install = TRUE;
1776 pr_info("ACPI: static SSDT installation disabled\n");
1776 1777
1777 acpi_gbl_disable_ssdt_table_load = TRUE; 1778 return 0;
1778
1779 return 1;
1780} 1779}
1781 1780
1782__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup); 1781early_param("acpi_no_static_ssdt", acpi_no_static_ssdt_setup);
1783 1782
1784static int __init acpi_disable_return_repair(char *s) 1783static int __init acpi_disable_return_repair(char *s)
1785{ 1784{
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 44f5e9749601..913d0765adbe 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -46,7 +46,7 @@
46 46
47/* Current ACPICA subsystem version in YYYYMMDD format */ 47/* Current ACPICA subsystem version in YYYYMMDD format */
48 48
49#define ACPI_CA_VERSION 0x20140214 49#define ACPI_CA_VERSION 0x20140325
50 50
51#include <acpi/acconfig.h> 51#include <acpi/acconfig.h>
52#include <acpi/actypes.h> 52#include <acpi/actypes.h>
@@ -75,7 +75,7 @@ extern u8 acpi_gbl_auto_serialize_methods;
75extern u8 acpi_gbl_copy_dsdt_locally; 75extern u8 acpi_gbl_copy_dsdt_locally;
76extern u8 acpi_gbl_create_osi_method; 76extern u8 acpi_gbl_create_osi_method;
77extern u8 acpi_gbl_disable_auto_repair; 77extern u8 acpi_gbl_disable_auto_repair;
78extern u8 acpi_gbl_disable_ssdt_table_load; 78extern u8 acpi_gbl_disable_ssdt_table_install;
79extern u8 acpi_gbl_do_not_use_xsdt; 79extern u8 acpi_gbl_do_not_use_xsdt;
80extern u8 acpi_gbl_enable_aml_debug_object; 80extern u8 acpi_gbl_enable_aml_debug_object;
81extern u8 acpi_gbl_enable_interpreter_slack; 81extern u8 acpi_gbl_enable_interpreter_slack;
@@ -164,6 +164,9 @@ acpi_decode_pld_buffer(u8 *in_buffer,
164/* 164/*
165 * ACPI table load/unload interfaces 165 * ACPI table load/unload interfaces
166 */ 166 */
167acpi_status __init
168acpi_install_table(acpi_physical_address address, u8 physical);
169
167acpi_status acpi_load_table(struct acpi_table_header *table); 170acpi_status acpi_load_table(struct acpi_table_header *table);
168 171
169acpi_status acpi_unload_parent_table(acpi_handle object); 172acpi_status acpi_unload_parent_table(acpi_handle object);
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index 3b30e36b53b5..1cc7ef13c01a 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -367,12 +367,11 @@ struct acpi_table_desc {
367 367
368/* Masks for Flags field above */ 368/* Masks for Flags field above */
369 369
370#define ACPI_TABLE_ORIGIN_UNKNOWN (0) 370#define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL (0) /* Virtual address, external maintained */
371#define ACPI_TABLE_ORIGIN_MAPPED (1) 371#define ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL (1) /* Physical address, internally mapped */
372#define ACPI_TABLE_ORIGIN_ALLOCATED (2) 372#define ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL (2) /* Virtual address, internallly allocated */
373#define ACPI_TABLE_ORIGIN_OVERRIDE (4) 373#define ACPI_TABLE_ORIGIN_MASK (3)
374#define ACPI_TABLE_ORIGIN_MASK (7) 374#define ACPI_TABLE_IS_LOADED (8)
375#define ACPI_TABLE_IS_LOADED (8)
376 375
377/* 376/*
378 * Get the remaining ACPI tables 377 * Get the remaining ACPI tables
diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h
index a476b9118b49..384875da3713 100644
--- a/include/acpi/platform/acgcc.h
+++ b/include/acpi/platform/acgcc.h
@@ -64,4 +64,15 @@
64 */ 64 */
65#define ACPI_UNUSED_VAR __attribute__ ((unused)) 65#define ACPI_UNUSED_VAR __attribute__ ((unused))
66 66
67/*
68 * Some versions of gcc implement strchr() with a buggy macro. So,
69 * undef it here. Prevents error messages of this form (usually from the
70 * file getopt.c):
71 *
72 * error: logical '&&' with non-zero constant will always evaluate as true
73 */
74#ifdef strchr
75#undef strchr
76#endif
77
67#endif /* __ACGCC_H__ */ 78#endif /* __ACGCC_H__ */
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index 93c55ed7c53d..f2429094b9b9 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -91,7 +91,7 @@
91#include <ctype.h> 91#include <ctype.h>
92#include <unistd.h> 92#include <unistd.h>
93 93
94/* Disable kernel specific declarators */ 94/* Define/disable kernel-specific declarators */
95 95
96#ifndef __init 96#ifndef __init
97#define __init 97#define __init
@@ -106,7 +106,8 @@
106#define ACPI_FLUSH_CPU_CACHE() 106#define ACPI_FLUSH_CPU_CACHE()
107#define ACPI_CAST_PTHREAD_T(pthread) ((acpi_thread_id) (pthread)) 107#define ACPI_CAST_PTHREAD_T(pthread) ((acpi_thread_id) (pthread))
108 108
109#if defined(__ia64__) || defined(__x86_64__) || defined(__aarch64__) 109#if defined(__ia64__) || defined(__x86_64__) ||\
110 defined(__aarch64__) || defined(__PPC64__)
110#define ACPI_MACHINE_WIDTH 64 111#define ACPI_MACHINE_WIDTH 64
111#define COMPILER_DEPENDENT_INT64 long 112#define COMPILER_DEPENDENT_INT64 long
112#define COMPILER_DEPENDENT_UINT64 unsigned long 113#define COMPILER_DEPENDENT_UINT64 unsigned long
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile
index d9186a2fdf06..98625fa2baf1 100644
--- a/tools/power/acpi/Makefile
+++ b/tools/power/acpi/Makefile
@@ -68,7 +68,8 @@ WARNINGS += $(call cc-supports,-Wstrict-prototypes)
68WARNINGS += $(call cc-supports,-Wdeclaration-after-statement) 68WARNINGS += $(call cc-supports,-Wdeclaration-after-statement)
69 69
70KERNEL_INCLUDE := ../../../include 70KERNEL_INCLUDE := ../../../include
71CFLAGS += -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE) 71ACPICA_INCLUDE := ../../../drivers/acpi/acpica
72CFLAGS += -D_LINUX -I$(KERNEL_INCLUDE) -I$(ACPICA_INCLUDE)
72CFLAGS += $(WARNINGS) 73CFLAGS += $(WARNINGS)
73 74
74ifeq ($(strip $(V)),false) 75ifeq ($(strip $(V)),false)
@@ -101,10 +102,29 @@ endif
101# --- ACPIDUMP BEGIN --- 102# --- ACPIDUMP BEGIN ---
102 103
103vpath %.c \ 104vpath %.c \
104 tools/acpidump 105 ../../../drivers/acpi/acpica\
106 tools/acpidump\
107 common\
108 os_specific/service_layers
109
110CFLAGS += -DACPI_DUMP_APP -Itools/acpidump
105 111
106DUMP_OBJS = \ 112DUMP_OBJS = \
107 acpidump.o 113 apdump.o\
114 apfiles.o\
115 apmain.o\
116 osunixdir.o\
117 osunixmap.o\
118 tbprint.o\
119 tbxfroot.o\
120 utbuffer.o\
121 utexcep.o\
122 utmath.o\
123 utstring.o\
124 utxferror.o\
125 oslinuxtbl.o\
126 cmfsize.o\
127 getopt.o
108 128
109DUMP_OBJS := $(addprefix $(OUTPUT)tools/acpidump/,$(DUMP_OBJS)) 129DUMP_OBJS := $(addprefix $(OUTPUT)tools/acpidump/,$(DUMP_OBJS))
110 130
diff --git a/tools/power/acpi/common/cmfsize.c b/tools/power/acpi/common/cmfsize.c
new file mode 100644
index 000000000000..5140e5edae1f
--- /dev/null
+++ b/tools/power/acpi/common/cmfsize.c
@@ -0,0 +1,101 @@
1/******************************************************************************
2 *
3 * Module Name: cfsize - Common get file size function
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 "acapps.h"
47#include <stdio.h>
48
49#define _COMPONENT ACPI_TOOLS
50ACPI_MODULE_NAME("cmfsize")
51
52/*******************************************************************************
53 *
54 * FUNCTION: cm_get_file_size
55 *
56 * PARAMETERS: file - Open file descriptor
57 *
58 * RETURN: File Size. On error, -1 (ACPI_UINT32_MAX)
59 *
60 * DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open.
61 * Does not disturb the current file pointer. Uses perror for
62 * error messages.
63 *
64 ******************************************************************************/
65u32 cm_get_file_size(FILE * file)
66{
67 long file_size;
68 long current_offset;
69
70 /* Save the current file pointer, seek to EOF to obtain file size */
71
72 current_offset = ftell(file);
73 if (current_offset < 0) {
74 goto offset_error;
75 }
76
77 if (fseek(file, 0, SEEK_END)) {
78 goto seek_error;
79 }
80
81 file_size = ftell(file);
82 if (file_size < 0) {
83 goto offset_error;
84 }
85
86 /* Restore original file pointer */
87
88 if (fseek(file, current_offset, SEEK_SET)) {
89 goto seek_error;
90 }
91
92 return ((u32)file_size);
93
94offset_error:
95 perror("Could not get file offset");
96 return (ACPI_UINT32_MAX);
97
98seek_error:
99 perror("Could not seek file");
100 return (ACPI_UINT32_MAX);
101}
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/man/acpidump.8 b/tools/power/acpi/man/acpidump.8
index adfa99166e5e..38f095d86b52 100644
--- a/tools/power/acpi/man/acpidump.8
+++ b/tools/power/acpi/man/acpidump.8
@@ -1,18 +1,64 @@
1.TH ACPIDUMP 8 1.TH ACPIDUMP 8
2.SH NAME 2.SH NAME
3acpidump \- Dump system's ACPI tables to an ASCII file. 3acpidump \- dump a system's ACPI tables to an ASCII file
4
4.SH SYNOPSIS 5.SH SYNOPSIS
5.ft B 6.B acpidump
6.B acpidump > acpidump.out 7.RI [ options ]
8.br
9
7.SH DESCRIPTION 10.SH DESCRIPTION
8\fBacpidump \fP dumps the systems ACPI tables to an ASCII file 11.B acpidump
9appropriate for attaching to a bug report. 12dumps the systems ACPI tables to an ASCII file appropriate for
13attaching to a bug report.
10 14
11Subsequently, they can be processed by utilities in the ACPICA package. 15Subsequently, they can be processed by utilities in the ACPICA package.
12.SS Options 16
13no options worth worrying about. 17.SH OPTIONS
14.PP 18acpidump options are as follow:
15.SH EXAMPLE 19.TP
20.B Options
21.TP
22.B \-b
23Dump tables to binary files
24.TP
25.B \-c
26Dump customized tables
27.TP
28.B \-h \-?
29This help message
30.TP
31.B \-o <File>
32Redirect output to file
33.TP
34.B \-r <Address>
35Dump tables from specified RSDP
36.TP
37.B \-s
38Print table summaries only
39.TP
40.B \-v
41Display version information
42.TP
43.B \-z
44Verbose mode
45.TP
46.B Table Options
47.TP
48.B \-a <Address>
49Get table via a physical address
50.TP
51.B \-f <BinaryFile>
52Get table via a binary file
53.TP
54.B \-n <Signature>
55Get table via a name/signature
56.TP
57Invocation without parameters dumps all available tables
58.TP
59Multiple mixed instances of -a, -f, and -n are supported
60
61.SH EXAMPLES
16 62
17.nf 63.nf
18# acpidump > acpidump.out 64# acpidump > acpidump.out
@@ -50,10 +96,25 @@ ACPICA: https://acpica.org/
50.ta 96.ta
51.nf 97.nf
52/dev/mem 98/dev/mem
99/sys/firmware/acpi/tables/*
53/sys/firmware/acpi/tables/dynamic/* 100/sys/firmware/acpi/tables/dynamic/*
101/sys/firmware/efi/systab
54.fi 102.fi
55 103
56.PP
57.SH AUTHOR 104.SH AUTHOR
58.nf 105.TP
59Written by Len Brown <len.brown@intel.com> 106Original by:
107 Len Brown <len.brown@intel.com>
108.TP
109Written by:
110 Chao Guan <chao.guan@intel.com>
111.TP
112Updated by:
113 Bob Moore <robert.moore@intel.com>
114 Lv Zheng <lv.zheng@intel.com>
115
116.SH SEE ALSO
117\&\fIacpixtract\fR\|(8), \fIiasl\fR\|(8).
118
119.SH COPYRIGHT
120COPYRIGHT (c) 2013, Intel Corporation.
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.c b/tools/power/acpi/tools/acpidump/acpidump.c
deleted file mode 100644
index a84553a0e0df..000000000000
--- a/tools/power/acpi/tools/acpidump/acpidump.c
+++ /dev/null
@@ -1,559 +0,0 @@
1/*
2 * (c) Alexey Starikovskiy, Intel, 2005-2006.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions, and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * substantially similar to the "NO WARRANTY" disclaimer below
13 * ("Disclaimer") and any redistribution must be conditioned upon
14 * including a substantially similar Disclaimer requirement for further
15 * binary redistribution.
16 * 3. Neither the names of the above-listed copyright holders nor the names
17 * of any contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * NO WARRANTY
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
34 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGES.
36 */
37
38#ifdef DEFINE_ALTERNATE_TYPES
39/* hack to enable building old application with new headers -lenb */
40#define acpi_fadt_descriptor acpi_table_fadt
41#define acpi_rsdp_descriptor acpi_table_rsdp
42#define DSDT_SIG ACPI_SIG_DSDT
43#define FACS_SIG ACPI_SIG_FACS
44#define FADT_SIG ACPI_SIG_FADT
45#define xfirmware_ctrl Xfacs
46#define firmware_ctrl facs
47
48typedef int s32;
49typedef unsigned char u8;
50typedef unsigned short u16;
51typedef unsigned int u32;
52typedef unsigned long long u64;
53typedef long long s64;
54#endif
55
56#include <sys/mman.h>
57#include <sys/types.h>
58#include <sys/stat.h>
59#include <fcntl.h>
60#include <stdio.h>
61#include <string.h>
62#include <unistd.h>
63#include <getopt.h>
64
65#include <dirent.h>
66
67#include <acpi/acconfig.h>
68#include <acpi/platform/acenv.h>
69#include <acpi/actypes.h>
70#include <acpi/actbl.h>
71
72static inline u8 checksum(u8 * buffer, u32 length)
73{
74 u8 sum = 0, *i = buffer;
75 buffer += length;
76 for (; i < buffer; sum += *(i++));
77 return sum;
78}
79
80static unsigned long psz, addr, length;
81static int print, connect, skip;
82static u8 select_sig[4];
83
84static unsigned long read_efi_systab( void )
85{
86 char buffer[80];
87 unsigned long addr;
88 FILE *f = fopen("/sys/firmware/efi/systab", "r");
89 if (f) {
90 while (fgets(buffer, 80, f)) {
91 if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1)
92 return addr;
93 }
94 fclose(f);
95 }
96 return 0;
97}
98
99static u8 *acpi_map_memory(unsigned long where, unsigned length)
100{
101 unsigned long offset;
102 u8 *there;
103 int fd = open("/dev/mem", O_RDONLY);
104 if (fd < 0) {
105 fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n");
106 exit(1);
107 }
108 offset = where % psz;
109 there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE,
110 fd, where - offset);
111 close(fd);
112 if (there == MAP_FAILED) return 0;
113 return (there + offset);
114}
115
116static void acpi_unmap_memory(u8 * there, unsigned length)
117{
118 unsigned long offset = (unsigned long)there % psz;
119 munmap(there - offset, length + offset);
120}
121
122static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig)
123{
124 unsigned size;
125 struct acpi_table_header *tbl = (struct acpi_table_header *)
126 acpi_map_memory(where, sizeof(struct acpi_table_header));
127 if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0;
128 size = tbl->length;
129 acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header));
130 return (struct acpi_table_header *)acpi_map_memory(where, size);
131}
132
133static void acpi_unmap_table(struct acpi_table_header *tbl)
134{
135 acpi_unmap_memory((u8 *)tbl, tbl->length);
136}
137
138static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length)
139{
140 struct acpi_rsdp_descriptor *rsdp;
141 u8 *i, *end = begin + length;
142 /* Search from given start address for the requested length */
143 for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) {
144 /* The signature and checksum must both be correct */
145 if (memcmp((char *)i, "RSD PTR ", 8)) continue;
146 rsdp = (struct acpi_rsdp_descriptor *)i;
147 /* Signature matches, check the appropriate checksum */
148 if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ?
149 ACPI_RSDP_CHECKSUM_LENGTH :
150 ACPI_RSDP_XCHECKSUM_LENGTH))
151 /* Checksum valid, we have found a valid RSDP */
152 return rsdp;
153 }
154 /* Searched entire block, no RSDP was found */
155 return 0;
156}
157
158/*
159 * Output data
160 */
161static void acpi_show_data(int fd, u8 * data, int size)
162{
163 char buffer[256];
164 int len;
165 int i, remain = size;
166 while (remain > 0) {
167 len = snprintf(buffer, 256, " %04x:", size - remain);
168 for (i = 0; i < 16 && i < remain; i++) {
169 len +=
170 snprintf(&buffer[len], 256 - len, " %02x", data[i]);
171 }
172 for (; i < 16; i++) {
173 len += snprintf(&buffer[len], 256 - len, " ");
174 }
175 len += snprintf(&buffer[len], 256 - len, " ");
176 for (i = 0; i < 16 && i < remain; i++) {
177 buffer[len++] = (isprint(data[i])) ? data[i] : '.';
178 }
179 buffer[len++] = '\n';
180 write(fd, buffer, len);
181 data += 16;
182 remain -= 16;
183 }
184}
185
186/*
187 * Output ACPI table
188 */
189static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr)
190{
191 char buff[80];
192 int len = snprintf(buff, 80, "%.4s @ %p\n", table->signature, (void *)addr);
193 write(fd, buff, len);
194 acpi_show_data(fd, (u8 *) table, table->length);
195 buff[0] = '\n';
196 write(fd, buff, 1);
197}
198
199static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr)
200{
201 static int select_done = 0;
202 if (!select_sig[0]) {
203 if (print) {
204 acpi_show_table(fd, tbl, addr);
205 } else {
206 write(fd, tbl, tbl->length);
207 }
208 } else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) {
209 if (skip > 0) {
210 --skip;
211 return;
212 }
213 if (print) {
214 acpi_show_table(fd, tbl, addr);
215 } else {
216 write(fd, tbl, tbl->length);
217 }
218 select_done = 1;
219 }
220}
221
222static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) {
223 struct acpi_fadt_descriptor x;
224 unsigned long addr;
225 size_t len = sizeof(struct acpi_fadt_descriptor);
226 if (len > tbl->length) len = tbl->length;
227 memcpy(&x, tbl, len);
228 x.header.length = len;
229 if (checksum((u8 *)tbl, len)) {
230 fprintf(stderr, "Wrong checksum for FADT!\n");
231 }
232 if (x.header.length >= 148 && x.Xdsdt) {
233 addr = (unsigned long)x.Xdsdt;
234 if (connect) {
235 x.Xdsdt = lseek(fd, 0, SEEK_CUR);
236 }
237 } else if (x.header.length >= 44 && x.dsdt) {
238 addr = (unsigned long)x.dsdt;
239 if (connect) {
240 x.dsdt = lseek(fd, 0, SEEK_CUR);
241 }
242 } else {
243 fprintf(stderr, "No DSDT in FADT!\n");
244 goto no_dsdt;
245 }
246 tbl = acpi_map_table(addr, DSDT_SIG);
247 if (!tbl) goto no_dsdt;
248 if (checksum((u8 *)tbl, tbl->length))
249 fprintf(stderr, "Wrong checksum for DSDT!\n");
250 write_table(fd, tbl, addr);
251 acpi_unmap_table(tbl);
252no_dsdt:
253 if (x.header.length >= 140 && x.xfirmware_ctrl) {
254 addr = (unsigned long)x.xfirmware_ctrl;
255 if (connect) {
256 x.xfirmware_ctrl = lseek(fd, 0, SEEK_CUR);
257 }
258 } else if (x.header.length >= 40 && x.firmware_ctrl) {
259 addr = (unsigned long)x.firmware_ctrl;
260 if (connect) {
261 x.firmware_ctrl = lseek(fd, 0, SEEK_CUR);
262 }
263 } else {
264 fprintf(stderr, "No FACS in FADT!\n");
265 goto no_facs;
266 }
267 tbl = acpi_map_table(addr, FACS_SIG);
268 if (!tbl) goto no_facs;
269 /* do not checksum FACS */
270 write_table(fd, tbl, addr);
271 acpi_unmap_table(tbl);
272no_facs:
273 write_table(fd, (struct acpi_table_header *)&x, xaddr);
274}
275
276static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp)
277{
278 struct acpi_table_header *sdt, *tbl = 0;
279 int xsdt = 1, i, num;
280 char *offset;
281 unsigned long addr;
282 if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
283 tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT");
284 }
285 if (!tbl && rsdp->rsdt_physical_address) {
286 xsdt = 0;
287 tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT");
288 }
289 if (!tbl) return 0;
290 sdt = malloc(tbl->length);
291 memcpy(sdt, tbl, tbl->length);
292 acpi_unmap_table(tbl);
293 if (checksum((u8 *)sdt, sdt->length))
294 fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT");
295 num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32));
296 offset = (char *)sdt + sizeof(struct acpi_table_header);
297 for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) {
298 addr = (xsdt) ? (unsigned long)(*(u64 *)offset):
299 (unsigned long)(*(u32 *)offset);
300 if (!addr) continue;
301 tbl = acpi_map_table(addr, 0);
302 if (!tbl) continue;
303 if (!memcmp(tbl->signature, FADT_SIG, 4)) {
304 acpi_dump_FADT(fd, tbl, addr);
305 } else {
306 if (checksum((u8 *)tbl, tbl->length))
307 fprintf(stderr, "Wrong checksum for generic table!\n");
308 write_table(fd, tbl, addr);
309 }
310 acpi_unmap_table(tbl);
311 if (connect) {
312 if (xsdt)
313 (*(u64*)offset) = lseek(fd, 0, SEEK_CUR);
314 else
315 (*(u32*)offset) = lseek(fd, 0, SEEK_CUR);
316 }
317 }
318 if (xsdt) {
319 addr = (unsigned long)rsdp->xsdt_physical_address;
320 if (connect) {
321 rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR);
322 }
323 } else {
324 addr = (unsigned long)rsdp->rsdt_physical_address;
325 if (connect) {
326 rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR);
327 }
328 }
329 write_table(fd, sdt, addr);
330 free (sdt);
331 return 1;
332}
333
334#define DYNAMIC_SSDT "/sys/firmware/acpi/tables/dynamic"
335
336static void acpi_dump_dynamic_SSDT(int fd)
337{
338 struct stat file_stat;
339 char filename[256], *ptr;
340 DIR *tabledir;
341 struct dirent *entry;
342 FILE *fp;
343 int count, readcount, length;
344 struct acpi_table_header table_header, *ptable;
345
346 if (stat(DYNAMIC_SSDT, &file_stat) == -1) {
347 /* The directory doesn't exist */
348 return;
349 }
350 tabledir = opendir(DYNAMIC_SSDT);
351 if(!tabledir){
352 /*can't open the directory */
353 return;
354 }
355
356 while ((entry = readdir(tabledir)) != 0){
357 /* skip the file of . /.. */
358 if (entry->d_name[0] == '.')
359 continue;
360
361 sprintf(filename, "%s/%s", DYNAMIC_SSDT, entry->d_name);
362 fp = fopen(filename, "r");
363 if (fp == NULL) {
364 fprintf(stderr, "Can't open the file of %s\n",
365 filename);
366 continue;
367 }
368 /* Read the Table header to parse the table length */
369 count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
370 if (count < sizeof(table_header)) {
371 /* the length is lessn than ACPI table header. skip it */
372 fclose(fp);
373 continue;
374 }
375 length = table_header.length;
376 ptr = malloc(table_header.length);
377 fseek(fp, 0, SEEK_SET);
378 readcount = 0;
379 while(!feof(fp) && readcount < length) {
380 count = fread(ptr + readcount, 1, 256, fp);
381 readcount += count;
382 }
383 fclose(fp);
384 ptable = (struct acpi_table_header *) ptr;
385 if (checksum((u8 *) ptable, ptable->length))
386 fprintf(stderr, "Wrong checksum "
387 "for dynamic SSDT table!\n");
388 write_table(fd, ptable, 0);
389 free(ptr);
390 }
391 closedir(tabledir);
392 return;
393}
394
395static void usage(const char *progname)
396{
397 puts("Usage:");
398 printf("%s [--addr 0x1234][--table DSDT][--output filename]"
399 "[--binary][--length 0x456][--help]\n", progname);
400 puts("\t--addr 0x1234 or -a 0x1234 -- look for tables at this physical address");
401 puts("\t--table DSDT or -t DSDT -- only dump table with DSDT signature");
402 puts("\t--output filename or -o filename -- redirect output from stdin to filename");
403 puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format");
404 puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory"
405 "\n\t\tregion without trying to understand it's contents");
406 puts("\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one");
407 puts("\t--help or -h -- this help message");
408 exit(0);
409}
410
411static struct option long_options[] = {
412 {"addr", 1, 0, 0},
413 {"table", 1, 0, 0},
414 {"output", 1, 0, 0},
415 {"binary", 0, 0, 0},
416 {"length", 1, 0, 0},
417 {"skip", 1, 0, 0},
418 {"help", 0, 0, 0},
419 {0, 0, 0, 0}
420};
421int main(int argc, char **argv)
422{
423 int option_index, c, fd;
424 u8 *raw;
425 struct acpi_rsdp_descriptor rsdpx, *x = 0;
426 char *filename = 0;
427 char buff[80];
428 memset(select_sig, 0, 4);
429 print = 1;
430 connect = 0;
431 addr = length = 0;
432 skip = 0;
433 while (1) {
434 option_index = 0;
435 c = getopt_long(argc, argv, "a:t:o:bl:s:h",
436 long_options, &option_index);
437 if (c == -1)
438 break;
439
440 switch (c) {
441 case 0:
442 switch (option_index) {
443 case 0:
444 addr = strtoul(optarg, (char **)NULL, 16);
445 break;
446 case 1:
447 memcpy(select_sig, optarg, 4);
448 break;
449 case 2:
450 filename = optarg;
451 break;
452 case 3:
453 print = 0;
454 break;
455 case 4:
456 length = strtoul(optarg, (char **)NULL, 16);
457 break;
458 case 5:
459 skip = strtoul(optarg, (char **)NULL, 10);
460 break;
461 case 6:
462 usage(argv[0]);
463 exit(0);
464 }
465 break;
466 case 'a':
467 addr = strtoul(optarg, (char **)NULL, 16);
468 break;
469 case 't':
470 memcpy(select_sig, optarg, 4);
471 break;
472 case 'o':
473 filename = optarg;
474 break;
475 case 'b':
476 print = 0;
477 break;
478 case 'l':
479 length = strtoul(optarg, (char **)NULL, 16);
480 break;
481 case 's':
482 skip = strtoul(optarg, (char **)NULL, 10);
483 break;
484 case 'h':
485 usage(argv[0]);
486 exit(0);
487 default:
488 printf("Unknown option!\n");
489 usage(argv[0]);
490 exit(0);
491 }
492 }
493
494 fd = STDOUT_FILENO;
495 if (filename) {
496 fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
497 if (fd < 0)
498 return fd;
499 }
500
501 if (!select_sig[0] && !print) {
502 connect = 1;
503 }
504
505 psz = sysconf(_SC_PAGESIZE);
506 if (length && addr) {
507 /* We know length and address, it means we just want a memory dump */
508 if (!(raw = acpi_map_memory(addr, length)))
509 goto not_found;
510 write(fd, raw, length);
511 acpi_unmap_memory(raw, length);
512 close(fd);
513 return 0;
514 }
515
516 length = sizeof(struct acpi_rsdp_descriptor);
517 if (!addr) {
518 addr = read_efi_systab();
519 if (!addr) {
520 addr = ACPI_HI_RSDP_WINDOW_BASE;
521 length = ACPI_HI_RSDP_WINDOW_SIZE;
522 }
523 }
524
525 if (!(raw = acpi_map_memory(addr, length)) ||
526 !(x = acpi_scan_for_rsdp(raw, length)))
527 goto not_found;
528
529 /* Find RSDP and print all found tables */
530 memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor));
531 acpi_unmap_memory(raw, length);
532 if (connect) {
533 lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET);
534 }
535 if (!acpi_dump_SDT(fd, &rsdpx))
536 goto not_found;
537 if (connect) {
538 lseek(fd, 0, SEEK_SET);
539 write(fd, x, (rsdpx.revision < 2) ?
540 ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
541 } else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) {
542 addr += (long)x - (long)raw;
543 length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr);
544 write(fd, buff, length);
545 acpi_show_data(fd, (u8 *) & rsdpx, (rsdpx.revision < 2) ?
546 ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
547 buff[0] = '\n';
548 write(fd, buff, 1);
549 }
550 acpi_dump_dynamic_SSDT(fd);
551 close(fd);
552 return 0;
553not_found:
554 close(fd);
555 fprintf(stderr, "ACPI tables were not found. If you know location "
556 "of RSD PTR table (from dmesg, etc), "
557 "supply it with either --addr or -a option\n");
558 return 1;
559}
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}