diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-11-01 18:50:26 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-11-01 18:50:26 -0500 |
commit | 5b9ddd0d7427c16e5d8779e77ba89c2bc5a7324c (patch) | |
tree | 1ec257a715f035e7f250fdadd68aa30171b3dfad | |
parent | ba210f5de42f4604730ffaea96bfb6e591740bde (diff) | |
parent | b31968828352ecae41d47aaa703e16c1ba06bfd8 (diff) |
Merge branch 'acpica'
* acpica:
ACPICA: Update version to 20150930
ACPICA: Debugger: Fix dead lock issue ocurred in single stepping mode
ACPI: Enable build of AML interpreter debugger
ACPICA: Debugger: Add thread ID support so that single step mode can only apply to the debugger thread
ACPICA: Debugger: Fix "terminate" command by cleaning up subsystem shutdown logic
ACPICA: Debugger: Fix "quit/exit" command by cleaning up user commands termination logic
ACPICA: Linuxize: Export debugger files to Linux
ACPICA: iASL: General cleanup of the file suffix #defines
ACPICA: Improve typechecking, both compile-time and runtime
ACPICA: Update NFIT table to rename a flags field
ACPICA: Debugger: Update mutexes used for multithreaded debugger
ACPICA: Update exception code for "file not found" error
ACPICA: iASL: Add symbolic operator support for Index() operator
ACPICA: Remove unnecessary conditional compilation
55 files changed, 9982 insertions, 137 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 5d1015c26ff4..706c2e95503f 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -57,6 +57,15 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT | |||
57 | config ACPI_CCA_REQUIRED | 57 | config ACPI_CCA_REQUIRED |
58 | bool | 58 | bool |
59 | 59 | ||
60 | config ACPI_DEBUGGER | ||
61 | bool "In-kernel debugger (EXPERIMENTAL)" | ||
62 | select ACPI_DEBUG | ||
63 | help | ||
64 | Enable in-kernel debugging facilities: statistics, internal | ||
65 | object dump, single step control method execution. | ||
66 | This is still under development, currently enabling this only | ||
67 | results in the compilation of the ACPICA debugger files. | ||
68 | |||
60 | config ACPI_SLEEP | 69 | config ACPI_SLEEP |
61 | bool | 70 | bool |
62 | depends on SUSPEND || HIBERNATION | 71 | depends on SUSPEND || HIBERNATION |
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index fedcc16b56cc..885936f79542 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -123,7 +123,6 @@ acpi-y += \ | |||
123 | rsaddr.o \ | 123 | rsaddr.o \ |
124 | rscalc.o \ | 124 | rscalc.o \ |
125 | rscreate.o \ | 125 | rscreate.o \ |
126 | rsdump.o \ | ||
127 | rsdumpinfo.o \ | 126 | rsdumpinfo.o \ |
128 | rsinfo.o \ | 127 | rsinfo.o \ |
129 | rsio.o \ | 128 | rsio.o \ |
@@ -178,7 +177,24 @@ acpi-y += \ | |||
178 | utxferror.o \ | 177 | utxferror.o \ |
179 | utxfmutex.o | 178 | utxfmutex.o |
180 | 179 | ||
180 | acpi-$(CONFIG_ACPI_DEBUGGER) += \ | ||
181 | dbcmds.o \ | ||
182 | dbconvert.o \ | ||
183 | dbdisply.o \ | ||
184 | dbexec.o \ | ||
185 | dbhistry.o \ | ||
186 | dbinput.o \ | ||
187 | dbmethod.o \ | ||
188 | dbnames.o \ | ||
189 | dbobject.o \ | ||
190 | dbstats.o \ | ||
191 | dbutils.o \ | ||
192 | dbxface.o \ | ||
193 | rsdump.o \ | ||
194 | |||
181 | acpi-$(ACPI_FUTURE_USAGE) += \ | 195 | acpi-$(ACPI_FUTURE_USAGE) += \ |
196 | dbfileio.o \ | ||
197 | dbtest.o \ | ||
182 | utcache.o \ | 198 | utcache.o \ |
183 | utfileio.o \ | 199 | utfileio.o \ |
184 | utprint.o \ | 200 | utprint.o \ |
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h index e9f0833e818d..e4cc48fbf4ee 100644 --- a/drivers/acpi/acpica/acapps.h +++ b/drivers/acpi/acpica/acapps.h | |||
@@ -88,7 +88,7 @@ | |||
88 | acpi_os_printf (" %-18s%s\n", name, description); | 88 | acpi_os_printf (" %-18s%s\n", name, description); |
89 | 89 | ||
90 | #define FILE_SUFFIX_DISASSEMBLY "dsl" | 90 | #define FILE_SUFFIX_DISASSEMBLY "dsl" |
91 | #define ACPI_TABLE_FILE_SUFFIX ".dat" | 91 | #define FILE_SUFFIX_BINARY_TABLE ".dat" /* Needs the dot */ |
92 | 92 | ||
93 | /* | 93 | /* |
94 | * getopt | 94 | * getopt |
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index eb2e926d8218..c928ba494c40 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h | |||
@@ -44,6 +44,12 @@ | |||
44 | #ifndef __ACDEBUG_H__ | 44 | #ifndef __ACDEBUG_H__ |
45 | #define __ACDEBUG_H__ | 45 | #define __ACDEBUG_H__ |
46 | 46 | ||
47 | /* The debugger is used in conjunction with the disassembler most of time */ | ||
48 | |||
49 | #ifdef ACPI_DISASSEMBLER | ||
50 | #include "acdisasm.h" | ||
51 | #endif | ||
52 | |||
47 | #define ACPI_DEBUG_BUFFER_SIZE 0x4000 /* 16K buffer for return objects */ | 53 | #define ACPI_DEBUG_BUFFER_SIZE 0x4000 /* 16K buffer for return objects */ |
48 | 54 | ||
49 | struct acpi_db_command_info { | 55 | struct acpi_db_command_info { |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 4dde37c3d8fc..faa97604d878 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -325,9 +325,9 @@ ACPI_GLOBAL(struct acpi_external_file *, acpi_gbl_external_file_list); | |||
325 | 325 | ||
326 | #ifdef ACPI_DEBUGGER | 326 | #ifdef ACPI_DEBUGGER |
327 | 327 | ||
328 | ACPI_INIT_GLOBAL(u8, acpi_gbl_db_terminate_threads, FALSE); | ||
329 | ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE); | 328 | ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE); |
330 | ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE); | 329 | ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE); |
330 | ACPI_INIT_GLOBAL(acpi_thread_id, acpi_gbl_db_thread_id, ACPI_INVALID_THREAD_ID); | ||
331 | 331 | ||
332 | ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_ini_methods); | 332 | ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_ini_methods); |
333 | ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_region_support); | 333 | ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_region_support); |
@@ -337,6 +337,8 @@ ACPI_GLOBAL(char *, acpi_gbl_db_filename); | |||
337 | ACPI_GLOBAL(u32, acpi_gbl_db_debug_level); | 337 | ACPI_GLOBAL(u32, acpi_gbl_db_debug_level); |
338 | ACPI_GLOBAL(u32, acpi_gbl_db_console_debug_level); | 338 | ACPI_GLOBAL(u32, acpi_gbl_db_console_debug_level); |
339 | ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_db_scope_node); | 339 | ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_db_scope_node); |
340 | ACPI_GLOBAL(u8, acpi_gbl_db_terminate_loop); | ||
341 | ACPI_GLOBAL(u8, acpi_gbl_db_threads_terminated); | ||
340 | 342 | ||
341 | ACPI_GLOBAL(char *, acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]); | 343 | ACPI_GLOBAL(char *, acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]); |
342 | ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]); | 344 | ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]); |
@@ -358,6 +360,9 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc); | |||
358 | ACPI_GLOBAL(u32, acpi_gbl_num_nodes); | 360 | ACPI_GLOBAL(u32, acpi_gbl_num_nodes); |
359 | ACPI_GLOBAL(u32, acpi_gbl_num_objects); | 361 | ACPI_GLOBAL(u32, acpi_gbl_num_objects); |
360 | 362 | ||
363 | ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_ready); | ||
364 | ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_complete); | ||
365 | |||
361 | #endif /* ACPI_DEBUGGER */ | 366 | #endif /* ACPI_DEBUGGER */ |
362 | 367 | ||
363 | /***************************************************************************** | 368 | /***************************************************************************** |
diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index e820ed8f173f..e9e936e78154 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h | |||
@@ -397,12 +397,10 @@ void | |||
397 | acpi_ex_dump_operands(union acpi_operand_object **operands, | 397 | acpi_ex_dump_operands(union acpi_operand_object **operands, |
398 | const char *opcode_name, u32 num_opcodes); | 398 | const char *opcode_name, u32 num_opcodes); |
399 | 399 | ||
400 | #ifdef ACPI_FUTURE_USAGE | ||
401 | void | 400 | void |
402 | acpi_ex_dump_object_descriptor(union acpi_operand_object *object, u32 flags); | 401 | acpi_ex_dump_object_descriptor(union acpi_operand_object *object, u32 flags); |
403 | 402 | ||
404 | void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags); | 403 | void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags); |
405 | #endif /* ACPI_FUTURE_USAGE */ | ||
406 | 404 | ||
407 | /* | 405 | /* |
408 | * exnames - AML namestring support | 406 | * exnames - AML namestring support |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 6f708267ad8c..e1dd784d8515 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -83,10 +83,8 @@ union acpi_parse_object; | |||
83 | #define ACPI_MTX_EVENTS 3 /* Data for ACPI events */ | 83 | #define ACPI_MTX_EVENTS 3 /* Data for ACPI events */ |
84 | #define ACPI_MTX_CACHES 4 /* Internal caches, general purposes */ | 84 | #define ACPI_MTX_CACHES 4 /* Internal caches, general purposes */ |
85 | #define ACPI_MTX_MEMORY 5 /* Debug memory tracking lists */ | 85 | #define ACPI_MTX_MEMORY 5 /* Debug memory tracking lists */ |
86 | #define ACPI_MTX_DEBUG_CMD_COMPLETE 6 /* AML debugger */ | ||
87 | #define ACPI_MTX_DEBUG_CMD_READY 7 /* AML debugger */ | ||
88 | 86 | ||
89 | #define ACPI_MAX_MUTEX 7 | 87 | #define ACPI_MAX_MUTEX 5 |
90 | #define ACPI_NUM_MUTEX ACPI_MAX_MUTEX+1 | 88 | #define ACPI_NUM_MUTEX ACPI_MAX_MUTEX+1 |
91 | 89 | ||
92 | /* Lock structure for reader/writer interfaces */ | 90 | /* Lock structure for reader/writer interfaces */ |
@@ -111,6 +109,14 @@ struct acpi_rw_lock { | |||
111 | 109 | ||
112 | #define ACPI_MUTEX_NOT_ACQUIRED (acpi_thread_id) 0 | 110 | #define ACPI_MUTEX_NOT_ACQUIRED (acpi_thread_id) 0 |
113 | 111 | ||
112 | /* This Thread ID means an invalid thread ID */ | ||
113 | |||
114 | #ifdef ACPI_OS_INVALID_THREAD_ID | ||
115 | #define ACPI_INVALID_THREAD_ID ACPI_OS_INVALID_THREAD_ID | ||
116 | #else | ||
117 | #define ACPI_INVALID_THREAD_ID ((acpi_thread_id) 0xFFFFFFFF) | ||
118 | #endif | ||
119 | |||
114 | /* Table for the global mutexes */ | 120 | /* Table for the global mutexes */ |
115 | 121 | ||
116 | struct acpi_mutex_info { | 122 | struct acpi_mutex_info { |
@@ -287,13 +293,17 @@ acpi_status(*acpi_internal_method) (struct acpi_walk_state * walk_state); | |||
287 | #define ACPI_BTYPE_BUFFER_FIELD 0x00002000 | 293 | #define ACPI_BTYPE_BUFFER_FIELD 0x00002000 |
288 | #define ACPI_BTYPE_DDB_HANDLE 0x00004000 | 294 | #define ACPI_BTYPE_DDB_HANDLE 0x00004000 |
289 | #define ACPI_BTYPE_DEBUG_OBJECT 0x00008000 | 295 | #define ACPI_BTYPE_DEBUG_OBJECT 0x00008000 |
290 | #define ACPI_BTYPE_REFERENCE 0x00010000 | 296 | #define ACPI_BTYPE_REFERENCE_OBJECT 0x00010000 /* From Index(), ref_of(), etc (type6_opcodes) */ |
291 | #define ACPI_BTYPE_RESOURCE 0x00020000 | 297 | #define ACPI_BTYPE_RESOURCE 0x00020000 |
298 | #define ACPI_BTYPE_NAMED_REFERENCE 0x00040000 /* Generic unresolved Name or Namepath */ | ||
292 | 299 | ||
293 | #define ACPI_BTYPE_COMPUTE_DATA (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER) | 300 | #define ACPI_BTYPE_COMPUTE_DATA (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER) |
294 | 301 | ||
295 | #define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_PACKAGE) | 302 | #define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_PACKAGE) |
296 | #define ACPI_BTYPE_DATA_REFERENCE (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE) | 303 | |
304 | /* Used by Copy, de_ref_of, Store, Printf, Fprintf */ | ||
305 | |||
306 | #define ACPI_BTYPE_DATA_REFERENCE (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE_OBJECT | ACPI_BTYPE_DDB_HANDLE) | ||
297 | #define ACPI_BTYPE_DEVICE_OBJECTS (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR) | 307 | #define ACPI_BTYPE_DEVICE_OBJECTS (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR) |
298 | #define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001FFFF /* ARG or LOCAL */ | 308 | #define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001FFFF /* ARG or LOCAL */ |
299 | #define ACPI_BTYPE_ALL_OBJECTS 0x0000FFFF | 309 | #define ACPI_BTYPE_ALL_OBJECTS 0x0000FFFF |
@@ -848,7 +858,7 @@ struct acpi_parse_state { | |||
848 | #define ACPI_PARSEOP_PARAMLIST 0x02 | 858 | #define ACPI_PARSEOP_PARAMLIST 0x02 |
849 | #define ACPI_PARSEOP_EMPTY_TERMLIST 0x04 | 859 | #define ACPI_PARSEOP_EMPTY_TERMLIST 0x04 |
850 | #define ACPI_PARSEOP_PREDEF_CHECKED 0x08 | 860 | #define ACPI_PARSEOP_PREDEF_CHECKED 0x08 |
851 | #define ACPI_PARSEOP_SPECIAL 0x10 | 861 | #define ACPI_PARSEOP_CLOSING_PAREN 0x10 |
852 | #define ACPI_PARSEOP_COMPOUND 0x20 | 862 | #define ACPI_PARSEOP_COMPOUND 0x20 |
853 | #define ACPI_PARSEOP_ASSIGNMENT 0x40 | 863 | #define ACPI_PARSEOP_ASSIGNMENT 0x40 |
854 | 864 | ||
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index ea0d9076d408..5d261c942a0d 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -193,9 +193,7 @@ acpi_ns_convert_to_resource(union acpi_operand_object *original_object, | |||
193 | /* | 193 | /* |
194 | * nsdump - Namespace dump/print utilities | 194 | * nsdump - Namespace dump/print utilities |
195 | */ | 195 | */ |
196 | #ifdef ACPI_FUTURE_USAGE | ||
197 | void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth); | 196 | void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth); |
198 | #endif /* ACPI_FUTURE_USAGE */ | ||
199 | 197 | ||
200 | void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level); | 198 | void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level); |
201 | 199 | ||
@@ -208,7 +206,6 @@ acpi_status | |||
208 | acpi_ns_dump_one_object(acpi_handle obj_handle, | 206 | acpi_ns_dump_one_object(acpi_handle obj_handle, |
209 | u32 level, void *context, void **return_value); | 207 | u32 level, void *context, void **return_value); |
210 | 208 | ||
211 | #ifdef ACPI_FUTURE_USAGE | ||
212 | void | 209 | void |
213 | acpi_ns_dump_objects(acpi_object_type type, | 210 | acpi_ns_dump_objects(acpi_object_type type, |
214 | u8 display_type, | 211 | u8 display_type, |
@@ -220,7 +217,6 @@ acpi_ns_dump_object_paths(acpi_object_type type, | |||
220 | u8 display_type, | 217 | u8 display_type, |
221 | u32 max_depth, | 218 | u32 max_depth, |
222 | acpi_owner_id owner_id, acpi_handle start_handle); | 219 | acpi_owner_id owner_id, acpi_handle start_handle); |
223 | #endif /* ACPI_FUTURE_USAGE */ | ||
224 | 220 | ||
225 | /* | 221 | /* |
226 | * nseval - Namespace evaluation functions | 222 | * nseval - Namespace evaluation functions |
diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h index fd85ad05a24a..f9acf92fa0bc 100644 --- a/drivers/acpi/acpica/acopcode.h +++ b/drivers/acpi/acpica/acopcode.h | |||
@@ -211,7 +211,7 @@ | |||
211 | #define ARGI_ARG4 ARG_NONE | 211 | #define ARGI_ARG4 ARG_NONE |
212 | #define ARGI_ARG5 ARG_NONE | 212 | #define ARGI_ARG5 ARG_NONE |
213 | #define ARGI_ARG6 ARG_NONE | 213 | #define ARGI_ARG6 ARG_NONE |
214 | #define ARGI_BANK_FIELD_OP ARGI_INVALID_OPCODE | 214 | #define ARGI_BANK_FIELD_OP ARGI_LIST1 (ARGI_INTEGER) |
215 | #define ARGI_BIT_AND_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) | 215 | #define ARGI_BIT_AND_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) |
216 | #define ARGI_BIT_NAND_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) | 216 | #define ARGI_BIT_NAND_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) |
217 | #define ARGI_BIT_NOR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) | 217 | #define ARGI_BIT_NOR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) |
@@ -307,7 +307,7 @@ | |||
307 | #define ARGI_SLEEP_OP ARGI_LIST1 (ARGI_INTEGER) | 307 | #define ARGI_SLEEP_OP ARGI_LIST1 (ARGI_INTEGER) |
308 | #define ARGI_STALL_OP ARGI_LIST1 (ARGI_INTEGER) | 308 | #define ARGI_STALL_OP ARGI_LIST1 (ARGI_INTEGER) |
309 | #define ARGI_STATICSTRING_OP ARGI_INVALID_OPCODE | 309 | #define ARGI_STATICSTRING_OP ARGI_INVALID_OPCODE |
310 | #define ARGI_STORE_OP ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_TARGETREF) | 310 | #define ARGI_STORE_OP ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_STORE_TARGET) |
311 | #define ARGI_STRING_OP ARGI_INVALID_OPCODE | 311 | #define ARGI_STRING_OP ARGI_INVALID_OPCODE |
312 | #define ARGI_SUBTRACT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) | 312 | #define ARGI_SUBTRACT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) |
313 | #define ARGI_THERMAL_ZONE_OP ARGI_INVALID_OPCODE | 313 | #define ARGI_THERMAL_ZONE_OP ARGI_INVALID_OPCODE |
diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index 6021ccfb0b1c..8fc8c7cea879 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h | |||
@@ -194,10 +194,8 @@ union acpi_parse_object *acpi_ps_find(union acpi_parse_object *scope, | |||
194 | 194 | ||
195 | union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn); | 195 | union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn); |
196 | 196 | ||
197 | #ifdef ACPI_FUTURE_USAGE | ||
198 | union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin, | 197 | union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin, |
199 | union acpi_parse_object *op); | 198 | union acpi_parse_object *op); |
200 | #endif /* ACPI_FUTURE_USAGE */ | ||
201 | 199 | ||
202 | /* | 200 | /* |
203 | * pswalk - parse tree walk routines | 201 | * pswalk - parse tree walk routines |
@@ -235,9 +233,7 @@ void acpi_ps_free_op(union acpi_parse_object *op); | |||
235 | 233 | ||
236 | u8 acpi_ps_is_leading_char(u32 c); | 234 | u8 acpi_ps_is_leading_char(u32 c); |
237 | 235 | ||
238 | #ifdef ACPI_FUTURE_USAGE | ||
239 | u32 acpi_ps_get_name(union acpi_parse_object *op); | 236 | u32 acpi_ps_get_name(union acpi_parse_object *op); |
240 | #endif /* ACPI_FUTURE_USAGE */ | ||
241 | 237 | ||
242 | void acpi_ps_set_name(union acpi_parse_object *op, u32 name); | 238 | void acpi_ps_set_name(union acpi_parse_object *op, u32 name); |
243 | 239 | ||
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index fb2aa5066f3f..8b8fef6cc32d 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -635,9 +635,7 @@ void | |||
635 | acpi_ut_free_and_track(void *address, | 635 | acpi_ut_free_and_track(void *address, |
636 | u32 component, const char *module, u32 line); | 636 | u32 component, const char *module, u32 line); |
637 | 637 | ||
638 | #ifdef ACPI_FUTURE_USAGE | ||
639 | void acpi_ut_dump_allocation_info(void); | 638 | void acpi_ut_dump_allocation_info(void); |
640 | #endif /* ACPI_FUTURE_USAGE */ | ||
641 | 639 | ||
642 | void acpi_ut_dump_allocations(u32 component, const char *module); | 640 | void acpi_ut_dump_allocations(u32 component, const char *module); |
643 | 641 | ||
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index be9fd009cb28..883f20cfa698 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h | |||
@@ -277,14 +277,15 @@ | |||
277 | #define ARGI_TARGETREF 0x0F /* Target, subject to implicit conversion */ | 277 | #define ARGI_TARGETREF 0x0F /* Target, subject to implicit conversion */ |
278 | #define ARGI_FIXED_TARGET 0x10 /* Target, no implicit conversion */ | 278 | #define ARGI_FIXED_TARGET 0x10 /* Target, no implicit conversion */ |
279 | #define ARGI_SIMPLE_TARGET 0x11 /* Name, Local, Arg -- no implicit conversion */ | 279 | #define ARGI_SIMPLE_TARGET 0x11 /* Name, Local, Arg -- no implicit conversion */ |
280 | #define ARGI_STORE_TARGET 0x12 /* Target for store is TARGETREF + package objects */ | ||
280 | 281 | ||
281 | /* Multiple/complex types */ | 282 | /* Multiple/complex types */ |
282 | 283 | ||
283 | #define ARGI_DATAOBJECT 0x12 /* Buffer, String, package or reference to a node - Used only by size_of operator */ | 284 | #define ARGI_DATAOBJECT 0x13 /* Buffer, String, package or reference to a node - Used only by size_of operator */ |
284 | #define ARGI_COMPLEXOBJ 0x13 /* Buffer, String, or package (Used by INDEX op only) */ | 285 | #define ARGI_COMPLEXOBJ 0x14 /* Buffer, String, or package (Used by INDEX op only) */ |
285 | #define ARGI_REF_OR_STRING 0x14 /* Reference or String (Used by DEREFOF op only) */ | 286 | #define ARGI_REF_OR_STRING 0x15 /* Reference or String (Used by DEREFOF op only) */ |
286 | #define ARGI_REGION_OR_BUFFER 0x15 /* Used by LOAD op only */ | 287 | #define ARGI_REGION_OR_BUFFER 0x16 /* Used by LOAD op only */ |
287 | #define ARGI_DATAREFOBJ 0x16 | 288 | #define ARGI_DATAREFOBJ 0x17 |
288 | 289 | ||
289 | /* Note: types above can expand to 0x1F maximum */ | 290 | /* Note: types above can expand to 0x1F maximum */ |
290 | 291 | ||
diff --git a/drivers/acpi/acpica/dbcmds.c b/drivers/acpi/acpica/dbcmds.c new file mode 100644 index 000000000000..30414b3d7fdd --- /dev/null +++ b/drivers/acpi/acpica/dbcmds.c | |||
@@ -0,0 +1,1187 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbcmds - Miscellaneous debug commands and output routines | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acevents.h" | ||
47 | #include "acdebug.h" | ||
48 | #include "acnamesp.h" | ||
49 | #include "acresrc.h" | ||
50 | #include "actables.h" | ||
51 | |||
52 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
53 | ACPI_MODULE_NAME("dbcmds") | ||
54 | |||
55 | /* Local prototypes */ | ||
56 | static void | ||
57 | acpi_dm_compare_aml_resources(u8 *aml1_buffer, | ||
58 | acpi_rsdesc_size aml1_buffer_length, | ||
59 | u8 *aml2_buffer, | ||
60 | acpi_rsdesc_size aml2_buffer_length); | ||
61 | |||
62 | static acpi_status | ||
63 | acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name); | ||
64 | |||
65 | static acpi_status | ||
66 | acpi_db_resource_callback(struct acpi_resource *resource, void *context); | ||
67 | |||
68 | static acpi_status | ||
69 | acpi_db_device_resources(acpi_handle obj_handle, | ||
70 | u32 nesting_level, void *context, void **return_value); | ||
71 | |||
72 | static void acpi_db_do_one_sleep_state(u8 sleep_state); | ||
73 | |||
74 | static char *acpi_db_trace_method_name = NULL; | ||
75 | |||
76 | /******************************************************************************* | ||
77 | * | ||
78 | * FUNCTION: acpi_db_convert_to_node | ||
79 | * | ||
80 | * PARAMETERS: in_string - String to convert | ||
81 | * | ||
82 | * RETURN: Pointer to a NS node | ||
83 | * | ||
84 | * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or | ||
85 | * alphanumeric strings. | ||
86 | * | ||
87 | ******************************************************************************/ | ||
88 | |||
89 | struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string) | ||
90 | { | ||
91 | struct acpi_namespace_node *node; | ||
92 | acpi_size address; | ||
93 | |||
94 | if ((*in_string >= 0x30) && (*in_string <= 0x39)) { | ||
95 | |||
96 | /* Numeric argument, convert */ | ||
97 | |||
98 | address = strtoul(in_string, NULL, 16); | ||
99 | node = ACPI_TO_POINTER(address); | ||
100 | if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) { | ||
101 | acpi_os_printf("Address %p is invalid", node); | ||
102 | return (NULL); | ||
103 | } | ||
104 | |||
105 | /* Make sure pointer is valid NS node */ | ||
106 | |||
107 | if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { | ||
108 | acpi_os_printf | ||
109 | ("Address %p is not a valid namespace node [%s]\n", | ||
110 | node, acpi_ut_get_descriptor_name(node)); | ||
111 | return (NULL); | ||
112 | } | ||
113 | } else { | ||
114 | /* | ||
115 | * Alpha argument: The parameter is a name string that must be | ||
116 | * resolved to a Namespace object. | ||
117 | */ | ||
118 | node = acpi_db_local_ns_lookup(in_string); | ||
119 | if (!node) { | ||
120 | acpi_os_printf | ||
121 | ("Could not find [%s] in namespace, defaulting to root node\n", | ||
122 | in_string); | ||
123 | node = acpi_gbl_root_node; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | return (node); | ||
128 | } | ||
129 | |||
130 | /******************************************************************************* | ||
131 | * | ||
132 | * FUNCTION: acpi_db_sleep | ||
133 | * | ||
134 | * PARAMETERS: object_arg - Desired sleep state (0-5). NULL means | ||
135 | * invoke all possible sleep states. | ||
136 | * | ||
137 | * RETURN: Status | ||
138 | * | ||
139 | * DESCRIPTION: Simulate sleep/wake sequences | ||
140 | * | ||
141 | ******************************************************************************/ | ||
142 | |||
143 | acpi_status acpi_db_sleep(char *object_arg) | ||
144 | { | ||
145 | u8 sleep_state; | ||
146 | u32 i; | ||
147 | |||
148 | ACPI_FUNCTION_TRACE(acpi_db_sleep); | ||
149 | |||
150 | /* Null input (no arguments) means to invoke all sleep states */ | ||
151 | |||
152 | if (!object_arg) { | ||
153 | acpi_os_printf("Invoking all possible sleep states, 0-%d\n", | ||
154 | ACPI_S_STATES_MAX); | ||
155 | |||
156 | for (i = 0; i <= ACPI_S_STATES_MAX; i++) { | ||
157 | acpi_db_do_one_sleep_state((u8)i); | ||
158 | } | ||
159 | |||
160 | return_ACPI_STATUS(AE_OK); | ||
161 | } | ||
162 | |||
163 | /* Convert argument to binary and invoke the sleep state */ | ||
164 | |||
165 | sleep_state = (u8)strtoul(object_arg, NULL, 0); | ||
166 | acpi_db_do_one_sleep_state(sleep_state); | ||
167 | return_ACPI_STATUS(AE_OK); | ||
168 | } | ||
169 | |||
170 | /******************************************************************************* | ||
171 | * | ||
172 | * FUNCTION: acpi_db_do_one_sleep_state | ||
173 | * | ||
174 | * PARAMETERS: sleep_state - Desired sleep state (0-5) | ||
175 | * | ||
176 | * RETURN: None | ||
177 | * | ||
178 | * DESCRIPTION: Simulate a sleep/wake sequence | ||
179 | * | ||
180 | ******************************************************************************/ | ||
181 | |||
182 | static void acpi_db_do_one_sleep_state(u8 sleep_state) | ||
183 | { | ||
184 | acpi_status status; | ||
185 | u8 sleep_type_a; | ||
186 | u8 sleep_type_b; | ||
187 | |||
188 | /* Validate parameter */ | ||
189 | |||
190 | if (sleep_state > ACPI_S_STATES_MAX) { | ||
191 | acpi_os_printf("Sleep state %d out of range (%d max)\n", | ||
192 | sleep_state, ACPI_S_STATES_MAX); | ||
193 | return; | ||
194 | } | ||
195 | |||
196 | acpi_os_printf("\n---- Invoking sleep state S%d (%s):\n", | ||
197 | sleep_state, acpi_gbl_sleep_state_names[sleep_state]); | ||
198 | |||
199 | /* Get the values for the sleep type registers (for display only) */ | ||
200 | |||
201 | status = | ||
202 | acpi_get_sleep_type_data(sleep_state, &sleep_type_a, &sleep_type_b); | ||
203 | if (ACPI_FAILURE(status)) { | ||
204 | acpi_os_printf("Could not evaluate [%s] method, %s\n", | ||
205 | acpi_gbl_sleep_state_names[sleep_state], | ||
206 | acpi_format_exception(status)); | ||
207 | return; | ||
208 | } | ||
209 | |||
210 | acpi_os_printf | ||
211 | ("Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n", | ||
212 | sleep_state, sleep_type_a, sleep_type_b); | ||
213 | |||
214 | /* Invoke the various sleep/wake interfaces */ | ||
215 | |||
216 | acpi_os_printf("**** Sleep: Prepare to sleep (S%d) ****\n", | ||
217 | sleep_state); | ||
218 | status = acpi_enter_sleep_state_prep(sleep_state); | ||
219 | if (ACPI_FAILURE(status)) { | ||
220 | goto error_exit; | ||
221 | } | ||
222 | |||
223 | acpi_os_printf("**** Sleep: Going to sleep (S%d) ****\n", sleep_state); | ||
224 | status = acpi_enter_sleep_state(sleep_state); | ||
225 | if (ACPI_FAILURE(status)) { | ||
226 | goto error_exit; | ||
227 | } | ||
228 | |||
229 | acpi_os_printf("**** Wake: Prepare to return from sleep (S%d) ****\n", | ||
230 | sleep_state); | ||
231 | status = acpi_leave_sleep_state_prep(sleep_state); | ||
232 | if (ACPI_FAILURE(status)) { | ||
233 | goto error_exit; | ||
234 | } | ||
235 | |||
236 | acpi_os_printf("**** Wake: Return from sleep (S%d) ****\n", | ||
237 | sleep_state); | ||
238 | status = acpi_leave_sleep_state(sleep_state); | ||
239 | if (ACPI_FAILURE(status)) { | ||
240 | goto error_exit; | ||
241 | } | ||
242 | |||
243 | return; | ||
244 | |||
245 | error_exit: | ||
246 | ACPI_EXCEPTION((AE_INFO, status, "During invocation of sleep state S%d", | ||
247 | sleep_state)); | ||
248 | } | ||
249 | |||
250 | /******************************************************************************* | ||
251 | * | ||
252 | * FUNCTION: acpi_db_display_locks | ||
253 | * | ||
254 | * PARAMETERS: None | ||
255 | * | ||
256 | * RETURN: None | ||
257 | * | ||
258 | * DESCRIPTION: Display information about internal mutexes. | ||
259 | * | ||
260 | ******************************************************************************/ | ||
261 | |||
262 | void acpi_db_display_locks(void) | ||
263 | { | ||
264 | u32 i; | ||
265 | |||
266 | for (i = 0; i < ACPI_MAX_MUTEX; i++) { | ||
267 | acpi_os_printf("%26s : %s\n", acpi_ut_get_mutex_name(i), | ||
268 | acpi_gbl_mutex_info[i].thread_id == | ||
269 | ACPI_MUTEX_NOT_ACQUIRED ? "Locked" : "Unlocked"); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | /******************************************************************************* | ||
274 | * | ||
275 | * FUNCTION: acpi_db_display_table_info | ||
276 | * | ||
277 | * PARAMETERS: table_arg - Name of table to be displayed | ||
278 | * | ||
279 | * RETURN: None | ||
280 | * | ||
281 | * DESCRIPTION: Display information about loaded tables. Current | ||
282 | * implementation displays all loaded tables. | ||
283 | * | ||
284 | ******************************************************************************/ | ||
285 | |||
286 | void acpi_db_display_table_info(char *table_arg) | ||
287 | { | ||
288 | u32 i; | ||
289 | struct acpi_table_desc *table_desc; | ||
290 | acpi_status status; | ||
291 | |||
292 | /* Header */ | ||
293 | |||
294 | acpi_os_printf("Idx ID Status Type " | ||
295 | "TableHeader (Sig, Address, Length, Misc)\n"); | ||
296 | |||
297 | /* Walk the entire root table list */ | ||
298 | |||
299 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { | ||
300 | table_desc = &acpi_gbl_root_table_list.tables[i]; | ||
301 | |||
302 | /* Index and Table ID */ | ||
303 | |||
304 | acpi_os_printf("%3u %.2u ", i, table_desc->owner_id); | ||
305 | |||
306 | /* Decode the table flags */ | ||
307 | |||
308 | if (!(table_desc->flags & ACPI_TABLE_IS_LOADED)) { | ||
309 | acpi_os_printf("NotLoaded "); | ||
310 | } else { | ||
311 | acpi_os_printf(" Loaded "); | ||
312 | } | ||
313 | |||
314 | switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { | ||
315 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: | ||
316 | |||
317 | acpi_os_printf("External/virtual "); | ||
318 | break; | ||
319 | |||
320 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: | ||
321 | |||
322 | acpi_os_printf("Internal/physical "); | ||
323 | break; | ||
324 | |||
325 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: | ||
326 | |||
327 | acpi_os_printf("Internal/virtual "); | ||
328 | break; | ||
329 | |||
330 | default: | ||
331 | |||
332 | acpi_os_printf("INVALID TYPE "); | ||
333 | break; | ||
334 | } | ||
335 | |||
336 | /* Make sure that the table is mapped */ | ||
337 | |||
338 | status = acpi_tb_validate_table(table_desc); | ||
339 | if (ACPI_FAILURE(status)) { | ||
340 | return; | ||
341 | } | ||
342 | |||
343 | /* Dump the table header */ | ||
344 | |||
345 | if (table_desc->pointer) { | ||
346 | acpi_tb_print_table_header(table_desc->address, | ||
347 | table_desc->pointer); | ||
348 | } else { | ||
349 | /* If the pointer is null, the table has been unloaded */ | ||
350 | |||
351 | ACPI_INFO((AE_INFO, "%4.4s - Table has been unloaded", | ||
352 | table_desc->signature.ascii)); | ||
353 | } | ||
354 | } | ||
355 | } | ||
356 | |||
357 | /******************************************************************************* | ||
358 | * | ||
359 | * FUNCTION: acpi_db_unload_acpi_table | ||
360 | * | ||
361 | * PARAMETERS: object_name - Namespace pathname for an object that | ||
362 | * is owned by the table to be unloaded | ||
363 | * | ||
364 | * RETURN: None | ||
365 | * | ||
366 | * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned | ||
367 | * by the table. | ||
368 | * | ||
369 | ******************************************************************************/ | ||
370 | |||
371 | void acpi_db_unload_acpi_table(char *object_name) | ||
372 | { | ||
373 | struct acpi_namespace_node *node; | ||
374 | acpi_status status; | ||
375 | |||
376 | /* Translate name to an Named object */ | ||
377 | |||
378 | node = acpi_db_convert_to_node(object_name); | ||
379 | if (!node) { | ||
380 | return; | ||
381 | } | ||
382 | |||
383 | status = acpi_unload_parent_table(ACPI_CAST_PTR(acpi_handle, node)); | ||
384 | if (ACPI_SUCCESS(status)) { | ||
385 | acpi_os_printf("Parent of [%s] (%p) unloaded and uninstalled\n", | ||
386 | object_name, node); | ||
387 | } else { | ||
388 | acpi_os_printf("%s, while unloading parent table of [%s]\n", | ||
389 | acpi_format_exception(status), object_name); | ||
390 | } | ||
391 | } | ||
392 | |||
393 | /******************************************************************************* | ||
394 | * | ||
395 | * FUNCTION: acpi_db_send_notify | ||
396 | * | ||
397 | * PARAMETERS: name - Name of ACPI object where to send notify | ||
398 | * value - Value of the notify to send. | ||
399 | * | ||
400 | * RETURN: None | ||
401 | * | ||
402 | * DESCRIPTION: Send an ACPI notification. The value specified is sent to the | ||
403 | * named object as an ACPI notify. | ||
404 | * | ||
405 | ******************************************************************************/ | ||
406 | |||
407 | void acpi_db_send_notify(char *name, u32 value) | ||
408 | { | ||
409 | struct acpi_namespace_node *node; | ||
410 | acpi_status status; | ||
411 | |||
412 | /* Translate name to an Named object */ | ||
413 | |||
414 | node = acpi_db_convert_to_node(name); | ||
415 | if (!node) { | ||
416 | return; | ||
417 | } | ||
418 | |||
419 | /* Dispatch the notify if legal */ | ||
420 | |||
421 | if (acpi_ev_is_notify_object(node)) { | ||
422 | status = acpi_ev_queue_notify_request(node, value); | ||
423 | if (ACPI_FAILURE(status)) { | ||
424 | acpi_os_printf("Could not queue notify\n"); | ||
425 | } | ||
426 | } else { | ||
427 | acpi_os_printf("Named object [%4.4s] Type %s, " | ||
428 | "must be Device/Thermal/Processor type\n", | ||
429 | acpi_ut_get_node_name(node), | ||
430 | acpi_ut_get_type_name(node->type)); | ||
431 | } | ||
432 | } | ||
433 | |||
434 | /******************************************************************************* | ||
435 | * | ||
436 | * FUNCTION: acpi_db_display_interfaces | ||
437 | * | ||
438 | * PARAMETERS: action_arg - Null, "install", or "remove" | ||
439 | * interface_name_arg - Name for install/remove options | ||
440 | * | ||
441 | * RETURN: None | ||
442 | * | ||
443 | * DESCRIPTION: Display or modify the global _OSI interface list | ||
444 | * | ||
445 | ******************************************************************************/ | ||
446 | |||
447 | void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg) | ||
448 | { | ||
449 | struct acpi_interface_info *next_interface; | ||
450 | char *sub_string; | ||
451 | acpi_status status; | ||
452 | |||
453 | /* If no arguments, just display current interface list */ | ||
454 | |||
455 | if (!action_arg) { | ||
456 | (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, | ||
457 | ACPI_WAIT_FOREVER); | ||
458 | |||
459 | next_interface = acpi_gbl_supported_interfaces; | ||
460 | while (next_interface) { | ||
461 | if (!(next_interface->flags & ACPI_OSI_INVALID)) { | ||
462 | acpi_os_printf("%s\n", next_interface->name); | ||
463 | } | ||
464 | |||
465 | next_interface = next_interface->next; | ||
466 | } | ||
467 | |||
468 | acpi_os_release_mutex(acpi_gbl_osi_mutex); | ||
469 | return; | ||
470 | } | ||
471 | |||
472 | /* If action_arg exists, so must interface_name_arg */ | ||
473 | |||
474 | if (!interface_name_arg) { | ||
475 | acpi_os_printf("Missing Interface Name argument\n"); | ||
476 | return; | ||
477 | } | ||
478 | |||
479 | /* Uppercase the action for match below */ | ||
480 | |||
481 | acpi_ut_strupr(action_arg); | ||
482 | |||
483 | /* install - install an interface */ | ||
484 | |||
485 | sub_string = strstr("INSTALL", action_arg); | ||
486 | if (sub_string) { | ||
487 | status = acpi_install_interface(interface_name_arg); | ||
488 | if (ACPI_FAILURE(status)) { | ||
489 | acpi_os_printf("%s, while installing \"%s\"\n", | ||
490 | acpi_format_exception(status), | ||
491 | interface_name_arg); | ||
492 | } | ||
493 | return; | ||
494 | } | ||
495 | |||
496 | /* remove - remove an interface */ | ||
497 | |||
498 | sub_string = strstr("REMOVE", action_arg); | ||
499 | if (sub_string) { | ||
500 | status = acpi_remove_interface(interface_name_arg); | ||
501 | if (ACPI_FAILURE(status)) { | ||
502 | acpi_os_printf("%s, while removing \"%s\"\n", | ||
503 | acpi_format_exception(status), | ||
504 | interface_name_arg); | ||
505 | } | ||
506 | return; | ||
507 | } | ||
508 | |||
509 | /* Invalid action_arg */ | ||
510 | |||
511 | acpi_os_printf("Invalid action argument: %s\n", action_arg); | ||
512 | return; | ||
513 | } | ||
514 | |||
515 | /******************************************************************************* | ||
516 | * | ||
517 | * FUNCTION: acpi_db_display_template | ||
518 | * | ||
519 | * PARAMETERS: buffer_arg - Buffer name or address | ||
520 | * | ||
521 | * RETURN: None | ||
522 | * | ||
523 | * DESCRIPTION: Dump a buffer that contains a resource template | ||
524 | * | ||
525 | ******************************************************************************/ | ||
526 | |||
527 | void acpi_db_display_template(char *buffer_arg) | ||
528 | { | ||
529 | struct acpi_namespace_node *node; | ||
530 | acpi_status status; | ||
531 | struct acpi_buffer return_buffer; | ||
532 | |||
533 | /* Translate buffer_arg to an Named object */ | ||
534 | |||
535 | node = acpi_db_convert_to_node(buffer_arg); | ||
536 | if (!node || (node == acpi_gbl_root_node)) { | ||
537 | acpi_os_printf("Invalid argument: %s\n", buffer_arg); | ||
538 | return; | ||
539 | } | ||
540 | |||
541 | /* We must have a buffer object */ | ||
542 | |||
543 | if (node->type != ACPI_TYPE_BUFFER) { | ||
544 | acpi_os_printf | ||
545 | ("Not a Buffer object, cannot be a template: %s\n", | ||
546 | buffer_arg); | ||
547 | return; | ||
548 | } | ||
549 | |||
550 | return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | ||
551 | return_buffer.pointer = acpi_gbl_db_buffer; | ||
552 | |||
553 | /* Attempt to convert the raw buffer to a resource list */ | ||
554 | |||
555 | status = acpi_rs_create_resource_list(node->object, &return_buffer); | ||
556 | |||
557 | acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); | ||
558 | acpi_dbg_level |= ACPI_LV_RESOURCES; | ||
559 | |||
560 | if (ACPI_FAILURE(status)) { | ||
561 | acpi_os_printf | ||
562 | ("Could not convert Buffer to a resource list: %s, %s\n", | ||
563 | buffer_arg, acpi_format_exception(status)); | ||
564 | goto dump_buffer; | ||
565 | } | ||
566 | |||
567 | /* Now we can dump the resource list */ | ||
568 | |||
569 | acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource, | ||
570 | return_buffer.pointer)); | ||
571 | |||
572 | dump_buffer: | ||
573 | acpi_os_printf("\nRaw data buffer:\n"); | ||
574 | acpi_ut_debug_dump_buffer((u8 *)node->object->buffer.pointer, | ||
575 | node->object->buffer.length, | ||
576 | DB_BYTE_DISPLAY, ACPI_UINT32_MAX); | ||
577 | |||
578 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
579 | return; | ||
580 | } | ||
581 | |||
582 | /******************************************************************************* | ||
583 | * | ||
584 | * FUNCTION: acpi_dm_compare_aml_resources | ||
585 | * | ||
586 | * PARAMETERS: aml1_buffer - Contains first resource list | ||
587 | * aml1_buffer_length - Length of first resource list | ||
588 | * aml2_buffer - Contains second resource list | ||
589 | * aml2_buffer_length - Length of second resource list | ||
590 | * | ||
591 | * RETURN: None | ||
592 | * | ||
593 | * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in | ||
594 | * order to isolate a miscompare to an individual resource) | ||
595 | * | ||
596 | ******************************************************************************/ | ||
597 | |||
598 | static void | ||
599 | acpi_dm_compare_aml_resources(u8 *aml1_buffer, | ||
600 | acpi_rsdesc_size aml1_buffer_length, | ||
601 | u8 *aml2_buffer, | ||
602 | acpi_rsdesc_size aml2_buffer_length) | ||
603 | { | ||
604 | u8 *aml1; | ||
605 | u8 *aml2; | ||
606 | u8 *aml1_end; | ||
607 | u8 *aml2_end; | ||
608 | acpi_rsdesc_size aml1_length; | ||
609 | acpi_rsdesc_size aml2_length; | ||
610 | acpi_rsdesc_size offset = 0; | ||
611 | u8 resource_type; | ||
612 | u32 count = 0; | ||
613 | u32 i; | ||
614 | |||
615 | /* Compare overall buffer sizes (may be different due to size rounding) */ | ||
616 | |||
617 | if (aml1_buffer_length != aml2_buffer_length) { | ||
618 | acpi_os_printf("**** Buffer length mismatch in converted " | ||
619 | "AML: Original %X, New %X ****\n", | ||
620 | aml1_buffer_length, aml2_buffer_length); | ||
621 | } | ||
622 | |||
623 | aml1 = aml1_buffer; | ||
624 | aml2 = aml2_buffer; | ||
625 | aml1_end = aml1_buffer + aml1_buffer_length; | ||
626 | aml2_end = aml2_buffer + aml2_buffer_length; | ||
627 | |||
628 | /* Walk the descriptor lists, comparing each descriptor */ | ||
629 | |||
630 | while ((aml1 < aml1_end) && (aml2 < aml2_end)) { | ||
631 | |||
632 | /* Get the lengths of each descriptor */ | ||
633 | |||
634 | aml1_length = acpi_ut_get_descriptor_length(aml1); | ||
635 | aml2_length = acpi_ut_get_descriptor_length(aml2); | ||
636 | resource_type = acpi_ut_get_resource_type(aml1); | ||
637 | |||
638 | /* Check for descriptor length match */ | ||
639 | |||
640 | if (aml1_length != aml2_length) { | ||
641 | acpi_os_printf | ||
642 | ("**** Length mismatch in descriptor [%.2X] type %2.2X, " | ||
643 | "Offset %8.8X Len1 %X, Len2 %X ****\n", count, | ||
644 | resource_type, offset, aml1_length, aml2_length); | ||
645 | } | ||
646 | |||
647 | /* Check for descriptor byte match */ | ||
648 | |||
649 | else if (memcmp(aml1, aml2, aml1_length)) { | ||
650 | acpi_os_printf | ||
651 | ("**** Data mismatch in descriptor [%.2X] type %2.2X, " | ||
652 | "Offset %8.8X ****\n", count, resource_type, | ||
653 | offset); | ||
654 | |||
655 | for (i = 0; i < aml1_length; i++) { | ||
656 | if (aml1[i] != aml2[i]) { | ||
657 | acpi_os_printf | ||
658 | ("Mismatch at byte offset %.2X: is %2.2X, " | ||
659 | "should be %2.2X\n", i, aml2[i], | ||
660 | aml1[i]); | ||
661 | } | ||
662 | } | ||
663 | } | ||
664 | |||
665 | /* Exit on end_tag descriptor */ | ||
666 | |||
667 | if (resource_type == ACPI_RESOURCE_NAME_END_TAG) { | ||
668 | return; | ||
669 | } | ||
670 | |||
671 | /* Point to next descriptor in each buffer */ | ||
672 | |||
673 | count++; | ||
674 | offset += aml1_length; | ||
675 | aml1 += aml1_length; | ||
676 | aml2 += aml2_length; | ||
677 | } | ||
678 | } | ||
679 | |||
680 | /******************************************************************************* | ||
681 | * | ||
682 | * FUNCTION: acpi_dm_test_resource_conversion | ||
683 | * | ||
684 | * PARAMETERS: node - Parent device node | ||
685 | * name - resource method name (_CRS) | ||
686 | * | ||
687 | * RETURN: Status | ||
688 | * | ||
689 | * DESCRIPTION: Compare the original AML with a conversion of the AML to | ||
690 | * internal resource list, then back to AML. | ||
691 | * | ||
692 | ******************************************************************************/ | ||
693 | |||
694 | static acpi_status | ||
695 | acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name) | ||
696 | { | ||
697 | acpi_status status; | ||
698 | struct acpi_buffer return_buffer; | ||
699 | struct acpi_buffer resource_buffer; | ||
700 | struct acpi_buffer new_aml; | ||
701 | union acpi_object *original_aml; | ||
702 | |||
703 | acpi_os_printf("Resource Conversion Comparison:\n"); | ||
704 | |||
705 | new_aml.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
706 | return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
707 | resource_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
708 | |||
709 | /* Get the original _CRS AML resource template */ | ||
710 | |||
711 | status = acpi_evaluate_object(node, name, NULL, &return_buffer); | ||
712 | if (ACPI_FAILURE(status)) { | ||
713 | acpi_os_printf("Could not obtain %s: %s\n", | ||
714 | name, acpi_format_exception(status)); | ||
715 | return (status); | ||
716 | } | ||
717 | |||
718 | /* Get the AML resource template, converted to internal resource structs */ | ||
719 | |||
720 | status = acpi_get_current_resources(node, &resource_buffer); | ||
721 | if (ACPI_FAILURE(status)) { | ||
722 | acpi_os_printf("AcpiGetCurrentResources failed: %s\n", | ||
723 | acpi_format_exception(status)); | ||
724 | goto exit1; | ||
725 | } | ||
726 | |||
727 | /* Convert internal resource list to external AML resource template */ | ||
728 | |||
729 | status = acpi_rs_create_aml_resources(&resource_buffer, &new_aml); | ||
730 | if (ACPI_FAILURE(status)) { | ||
731 | acpi_os_printf("AcpiRsCreateAmlResources failed: %s\n", | ||
732 | acpi_format_exception(status)); | ||
733 | goto exit2; | ||
734 | } | ||
735 | |||
736 | /* Compare original AML to the newly created AML resource list */ | ||
737 | |||
738 | original_aml = return_buffer.pointer; | ||
739 | |||
740 | acpi_dm_compare_aml_resources(original_aml->buffer.pointer, | ||
741 | (acpi_rsdesc_size) original_aml->buffer. | ||
742 | length, new_aml.pointer, | ||
743 | (acpi_rsdesc_size) new_aml.length); | ||
744 | |||
745 | /* Cleanup and exit */ | ||
746 | |||
747 | ACPI_FREE(new_aml.pointer); | ||
748 | exit2: | ||
749 | ACPI_FREE(resource_buffer.pointer); | ||
750 | exit1: | ||
751 | ACPI_FREE(return_buffer.pointer); | ||
752 | return (status); | ||
753 | } | ||
754 | |||
755 | /******************************************************************************* | ||
756 | * | ||
757 | * FUNCTION: acpi_db_resource_callback | ||
758 | * | ||
759 | * PARAMETERS: acpi_walk_resource_callback | ||
760 | * | ||
761 | * RETURN: Status | ||
762 | * | ||
763 | * DESCRIPTION: Simple callback to exercise acpi_walk_resources and | ||
764 | * acpi_walk_resource_buffer. | ||
765 | * | ||
766 | ******************************************************************************/ | ||
767 | |||
768 | static acpi_status | ||
769 | acpi_db_resource_callback(struct acpi_resource *resource, void *context) | ||
770 | { | ||
771 | |||
772 | return (AE_OK); | ||
773 | } | ||
774 | |||
775 | /******************************************************************************* | ||
776 | * | ||
777 | * FUNCTION: acpi_db_device_resources | ||
778 | * | ||
779 | * PARAMETERS: acpi_walk_callback | ||
780 | * | ||
781 | * RETURN: Status | ||
782 | * | ||
783 | * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object. | ||
784 | * | ||
785 | ******************************************************************************/ | ||
786 | |||
787 | static acpi_status | ||
788 | acpi_db_device_resources(acpi_handle obj_handle, | ||
789 | u32 nesting_level, void *context, void **return_value) | ||
790 | { | ||
791 | struct acpi_namespace_node *node; | ||
792 | struct acpi_namespace_node *prt_node = NULL; | ||
793 | struct acpi_namespace_node *crs_node = NULL; | ||
794 | struct acpi_namespace_node *prs_node = NULL; | ||
795 | struct acpi_namespace_node *aei_node = NULL; | ||
796 | char *parent_path; | ||
797 | struct acpi_buffer return_buffer; | ||
798 | acpi_status status; | ||
799 | |||
800 | node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); | ||
801 | parent_path = acpi_ns_get_external_pathname(node); | ||
802 | if (!parent_path) { | ||
803 | return (AE_NO_MEMORY); | ||
804 | } | ||
805 | |||
806 | /* Get handles to the resource methods for this device */ | ||
807 | |||
808 | (void)acpi_get_handle(node, METHOD_NAME__PRT, | ||
809 | ACPI_CAST_PTR(acpi_handle, &prt_node)); | ||
810 | (void)acpi_get_handle(node, METHOD_NAME__CRS, | ||
811 | ACPI_CAST_PTR(acpi_handle, &crs_node)); | ||
812 | (void)acpi_get_handle(node, METHOD_NAME__PRS, | ||
813 | ACPI_CAST_PTR(acpi_handle, &prs_node)); | ||
814 | (void)acpi_get_handle(node, METHOD_NAME__AEI, | ||
815 | ACPI_CAST_PTR(acpi_handle, &aei_node)); | ||
816 | |||
817 | if (!prt_node && !crs_node && !prs_node && !aei_node) { | ||
818 | goto cleanup; /* Nothing to do */ | ||
819 | } | ||
820 | |||
821 | acpi_os_printf("\nDevice: %s\n", parent_path); | ||
822 | |||
823 | /* Prepare for a return object of arbitrary size */ | ||
824 | |||
825 | return_buffer.pointer = acpi_gbl_db_buffer; | ||
826 | return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | ||
827 | |||
828 | /* _PRT */ | ||
829 | |||
830 | if (prt_node) { | ||
831 | acpi_os_printf("Evaluating _PRT\n"); | ||
832 | |||
833 | status = | ||
834 | acpi_evaluate_object(prt_node, NULL, NULL, &return_buffer); | ||
835 | if (ACPI_FAILURE(status)) { | ||
836 | acpi_os_printf("Could not evaluate _PRT: %s\n", | ||
837 | acpi_format_exception(status)); | ||
838 | goto get_crs; | ||
839 | } | ||
840 | |||
841 | return_buffer.pointer = acpi_gbl_db_buffer; | ||
842 | return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | ||
843 | |||
844 | status = acpi_get_irq_routing_table(node, &return_buffer); | ||
845 | if (ACPI_FAILURE(status)) { | ||
846 | acpi_os_printf("GetIrqRoutingTable failed: %s\n", | ||
847 | acpi_format_exception(status)); | ||
848 | goto get_crs; | ||
849 | } | ||
850 | |||
851 | acpi_rs_dump_irq_list(ACPI_CAST_PTR(u8, acpi_gbl_db_buffer)); | ||
852 | } | ||
853 | |||
854 | /* _CRS */ | ||
855 | |||
856 | get_crs: | ||
857 | if (crs_node) { | ||
858 | acpi_os_printf("Evaluating _CRS\n"); | ||
859 | |||
860 | return_buffer.pointer = acpi_gbl_db_buffer; | ||
861 | return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | ||
862 | |||
863 | status = | ||
864 | acpi_evaluate_object(crs_node, NULL, NULL, &return_buffer); | ||
865 | if (ACPI_FAILURE(status)) { | ||
866 | acpi_os_printf("Could not evaluate _CRS: %s\n", | ||
867 | acpi_format_exception(status)); | ||
868 | goto get_prs; | ||
869 | } | ||
870 | |||
871 | /* This code exercises the acpi_walk_resources interface */ | ||
872 | |||
873 | status = acpi_walk_resources(node, METHOD_NAME__CRS, | ||
874 | acpi_db_resource_callback, NULL); | ||
875 | if (ACPI_FAILURE(status)) { | ||
876 | acpi_os_printf("AcpiWalkResources failed: %s\n", | ||
877 | acpi_format_exception(status)); | ||
878 | goto get_prs; | ||
879 | } | ||
880 | |||
881 | /* Get the _CRS resource list (test ALLOCATE buffer) */ | ||
882 | |||
883 | return_buffer.pointer = NULL; | ||
884 | return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
885 | |||
886 | status = acpi_get_current_resources(node, &return_buffer); | ||
887 | if (ACPI_FAILURE(status)) { | ||
888 | acpi_os_printf("AcpiGetCurrentResources failed: %s\n", | ||
889 | acpi_format_exception(status)); | ||
890 | goto get_prs; | ||
891 | } | ||
892 | |||
893 | /* This code exercises the acpi_walk_resource_buffer interface */ | ||
894 | |||
895 | status = acpi_walk_resource_buffer(&return_buffer, | ||
896 | acpi_db_resource_callback, | ||
897 | NULL); | ||
898 | if (ACPI_FAILURE(status)) { | ||
899 | acpi_os_printf("AcpiWalkResourceBuffer failed: %s\n", | ||
900 | acpi_format_exception(status)); | ||
901 | goto end_crs; | ||
902 | } | ||
903 | |||
904 | /* Dump the _CRS resource list */ | ||
905 | |||
906 | acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource, | ||
907 | return_buffer. | ||
908 | pointer)); | ||
909 | |||
910 | /* | ||
911 | * Perform comparison of original AML to newly created AML. This | ||
912 | * tests both the AML->Resource conversion and the Resource->AML | ||
913 | * conversion. | ||
914 | */ | ||
915 | (void)acpi_dm_test_resource_conversion(node, METHOD_NAME__CRS); | ||
916 | |||
917 | /* Execute _SRS with the resource list */ | ||
918 | |||
919 | acpi_os_printf("Evaluating _SRS\n"); | ||
920 | |||
921 | status = acpi_set_current_resources(node, &return_buffer); | ||
922 | if (ACPI_FAILURE(status)) { | ||
923 | acpi_os_printf("AcpiSetCurrentResources failed: %s\n", | ||
924 | acpi_format_exception(status)); | ||
925 | goto end_crs; | ||
926 | } | ||
927 | |||
928 | end_crs: | ||
929 | ACPI_FREE(return_buffer.pointer); | ||
930 | } | ||
931 | |||
932 | /* _PRS */ | ||
933 | |||
934 | get_prs: | ||
935 | if (prs_node) { | ||
936 | acpi_os_printf("Evaluating _PRS\n"); | ||
937 | |||
938 | return_buffer.pointer = acpi_gbl_db_buffer; | ||
939 | return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | ||
940 | |||
941 | status = | ||
942 | acpi_evaluate_object(prs_node, NULL, NULL, &return_buffer); | ||
943 | if (ACPI_FAILURE(status)) { | ||
944 | acpi_os_printf("Could not evaluate _PRS: %s\n", | ||
945 | acpi_format_exception(status)); | ||
946 | goto get_aei; | ||
947 | } | ||
948 | |||
949 | return_buffer.pointer = acpi_gbl_db_buffer; | ||
950 | return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | ||
951 | |||
952 | status = acpi_get_possible_resources(node, &return_buffer); | ||
953 | if (ACPI_FAILURE(status)) { | ||
954 | acpi_os_printf("AcpiGetPossibleResources failed: %s\n", | ||
955 | acpi_format_exception(status)); | ||
956 | goto get_aei; | ||
957 | } | ||
958 | |||
959 | acpi_rs_dump_resource_list(ACPI_CAST_PTR | ||
960 | (struct acpi_resource, | ||
961 | acpi_gbl_db_buffer)); | ||
962 | } | ||
963 | |||
964 | /* _AEI */ | ||
965 | |||
966 | get_aei: | ||
967 | if (aei_node) { | ||
968 | acpi_os_printf("Evaluating _AEI\n"); | ||
969 | |||
970 | return_buffer.pointer = acpi_gbl_db_buffer; | ||
971 | return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | ||
972 | |||
973 | status = | ||
974 | acpi_evaluate_object(aei_node, NULL, NULL, &return_buffer); | ||
975 | if (ACPI_FAILURE(status)) { | ||
976 | acpi_os_printf("Could not evaluate _AEI: %s\n", | ||
977 | acpi_format_exception(status)); | ||
978 | goto cleanup; | ||
979 | } | ||
980 | |||
981 | return_buffer.pointer = acpi_gbl_db_buffer; | ||
982 | return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | ||
983 | |||
984 | status = acpi_get_event_resources(node, &return_buffer); | ||
985 | if (ACPI_FAILURE(status)) { | ||
986 | acpi_os_printf("AcpiGetEventResources failed: %s\n", | ||
987 | acpi_format_exception(status)); | ||
988 | goto cleanup; | ||
989 | } | ||
990 | |||
991 | acpi_rs_dump_resource_list(ACPI_CAST_PTR | ||
992 | (struct acpi_resource, | ||
993 | acpi_gbl_db_buffer)); | ||
994 | } | ||
995 | |||
996 | cleanup: | ||
997 | ACPI_FREE(parent_path); | ||
998 | return (AE_OK); | ||
999 | } | ||
1000 | |||
1001 | /******************************************************************************* | ||
1002 | * | ||
1003 | * FUNCTION: acpi_db_display_resources | ||
1004 | * | ||
1005 | * PARAMETERS: object_arg - String object name or object pointer. | ||
1006 | * NULL or "*" means "display resources for | ||
1007 | * all devices" | ||
1008 | * | ||
1009 | * RETURN: None | ||
1010 | * | ||
1011 | * DESCRIPTION: Display the resource objects associated with a device. | ||
1012 | * | ||
1013 | ******************************************************************************/ | ||
1014 | |||
1015 | void acpi_db_display_resources(char *object_arg) | ||
1016 | { | ||
1017 | struct acpi_namespace_node *node; | ||
1018 | |||
1019 | acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); | ||
1020 | acpi_dbg_level |= ACPI_LV_RESOURCES; | ||
1021 | |||
1022 | /* Asterisk means "display resources for all devices" */ | ||
1023 | |||
1024 | if (!object_arg || (!strcmp(object_arg, "*"))) { | ||
1025 | (void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
1026 | ACPI_UINT32_MAX, | ||
1027 | acpi_db_device_resources, NULL, NULL, | ||
1028 | NULL); | ||
1029 | } else { | ||
1030 | /* Convert string to object pointer */ | ||
1031 | |||
1032 | node = acpi_db_convert_to_node(object_arg); | ||
1033 | if (node) { | ||
1034 | if (node->type != ACPI_TYPE_DEVICE) { | ||
1035 | acpi_os_printf | ||
1036 | ("%4.4s: Name is not a device object (%s)\n", | ||
1037 | node->name.ascii, | ||
1038 | acpi_ut_get_type_name(node->type)); | ||
1039 | } else { | ||
1040 | (void)acpi_db_device_resources(node, 0, NULL, | ||
1041 | NULL); | ||
1042 | } | ||
1043 | } | ||
1044 | } | ||
1045 | |||
1046 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
1047 | } | ||
1048 | |||
1049 | #if (!ACPI_REDUCED_HARDWARE) | ||
1050 | /******************************************************************************* | ||
1051 | * | ||
1052 | * FUNCTION: acpi_db_generate_gpe | ||
1053 | * | ||
1054 | * PARAMETERS: gpe_arg - Raw GPE number, ascii string | ||
1055 | * block_arg - GPE block number, ascii string | ||
1056 | * 0 or 1 for FADT GPE blocks | ||
1057 | * | ||
1058 | * RETURN: None | ||
1059 | * | ||
1060 | * DESCRIPTION: Simulate firing of a GPE | ||
1061 | * | ||
1062 | ******************************************************************************/ | ||
1063 | |||
1064 | void acpi_db_generate_gpe(char *gpe_arg, char *block_arg) | ||
1065 | { | ||
1066 | u32 block_number = 0; | ||
1067 | u32 gpe_number; | ||
1068 | struct acpi_gpe_event_info *gpe_event_info; | ||
1069 | |||
1070 | gpe_number = strtoul(gpe_arg, NULL, 0); | ||
1071 | |||
1072 | /* | ||
1073 | * If no block arg, or block arg == 0 or 1, use the FADT-defined | ||
1074 | * GPE blocks. | ||
1075 | */ | ||
1076 | if (block_arg) { | ||
1077 | block_number = strtoul(block_arg, NULL, 0); | ||
1078 | if (block_number == 1) { | ||
1079 | block_number = 0; | ||
1080 | } | ||
1081 | } | ||
1082 | |||
1083 | gpe_event_info = | ||
1084 | acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number), | ||
1085 | gpe_number); | ||
1086 | if (!gpe_event_info) { | ||
1087 | acpi_os_printf("Invalid GPE\n"); | ||
1088 | return; | ||
1089 | } | ||
1090 | |||
1091 | (void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number); | ||
1092 | } | ||
1093 | |||
1094 | /******************************************************************************* | ||
1095 | * | ||
1096 | * FUNCTION: acpi_db_generate_sci | ||
1097 | * | ||
1098 | * PARAMETERS: None | ||
1099 | * | ||
1100 | * RETURN: None | ||
1101 | * | ||
1102 | * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch. | ||
1103 | * | ||
1104 | ******************************************************************************/ | ||
1105 | |||
1106 | void acpi_db_generate_sci(void) | ||
1107 | { | ||
1108 | acpi_ev_sci_dispatch(); | ||
1109 | } | ||
1110 | |||
1111 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
1112 | |||
1113 | /******************************************************************************* | ||
1114 | * | ||
1115 | * FUNCTION: acpi_db_trace | ||
1116 | * | ||
1117 | * PARAMETERS: enable_arg - ENABLE/AML to enable tracer | ||
1118 | * DISABLE to disable tracer | ||
1119 | * method_arg - Method to trace | ||
1120 | * once_arg - Whether trace once | ||
1121 | * | ||
1122 | * RETURN: None | ||
1123 | * | ||
1124 | * DESCRIPTION: Control method tracing facility | ||
1125 | * | ||
1126 | ******************************************************************************/ | ||
1127 | |||
1128 | void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg) | ||
1129 | { | ||
1130 | u32 debug_level = 0; | ||
1131 | u32 debug_layer = 0; | ||
1132 | u32 flags = 0; | ||
1133 | |||
1134 | if (enable_arg) { | ||
1135 | acpi_ut_strupr(enable_arg); | ||
1136 | } | ||
1137 | |||
1138 | if (once_arg) { | ||
1139 | acpi_ut_strupr(once_arg); | ||
1140 | } | ||
1141 | |||
1142 | if (method_arg) { | ||
1143 | if (acpi_db_trace_method_name) { | ||
1144 | ACPI_FREE(acpi_db_trace_method_name); | ||
1145 | acpi_db_trace_method_name = NULL; | ||
1146 | } | ||
1147 | |||
1148 | acpi_db_trace_method_name = | ||
1149 | ACPI_ALLOCATE(strlen(method_arg) + 1); | ||
1150 | if (!acpi_db_trace_method_name) { | ||
1151 | acpi_os_printf("Failed to allocate method name (%s)\n", | ||
1152 | method_arg); | ||
1153 | return; | ||
1154 | } | ||
1155 | |||
1156 | strcpy(acpi_db_trace_method_name, method_arg); | ||
1157 | } | ||
1158 | |||
1159 | if (!strcmp(enable_arg, "ENABLE") || | ||
1160 | !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) { | ||
1161 | if (!strcmp(enable_arg, "ENABLE")) { | ||
1162 | |||
1163 | /* Inherit current console settings */ | ||
1164 | |||
1165 | debug_level = acpi_gbl_db_console_debug_level; | ||
1166 | debug_layer = acpi_dbg_layer; | ||
1167 | } else { | ||
1168 | /* Restrict console output to trace points only */ | ||
1169 | |||
1170 | debug_level = ACPI_LV_TRACE_POINT; | ||
1171 | debug_layer = ACPI_EXECUTER; | ||
1172 | } | ||
1173 | |||
1174 | flags = ACPI_TRACE_ENABLED; | ||
1175 | |||
1176 | if (!strcmp(enable_arg, "OPCODE")) { | ||
1177 | flags |= ACPI_TRACE_OPCODE; | ||
1178 | } | ||
1179 | |||
1180 | if (once_arg && !strcmp(once_arg, "ONCE")) { | ||
1181 | flags |= ACPI_TRACE_ONESHOT; | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | (void)acpi_debug_trace(acpi_db_trace_method_name, | ||
1186 | debug_level, debug_layer, flags); | ||
1187 | } | ||
diff --git a/drivers/acpi/acpica/dbconvert.c b/drivers/acpi/acpica/dbconvert.c new file mode 100644 index 000000000000..a71632ca8a81 --- /dev/null +++ b/drivers/acpi/acpica/dbconvert.c | |||
@@ -0,0 +1,484 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbconvert - debugger miscellaneous conversion routines | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acdebug.h" | ||
47 | |||
48 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
49 | ACPI_MODULE_NAME("dbconvert") | ||
50 | |||
51 | #define DB_DEFAULT_PKG_ELEMENTS 33 | ||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_db_hex_char_to_value | ||
55 | * | ||
56 | * PARAMETERS: hex_char - Ascii Hex digit, 0-9|a-f|A-F | ||
57 | * return_value - Where the converted value is returned | ||
58 | * | ||
59 | * RETURN: Status | ||
60 | * | ||
61 | * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16). | ||
62 | * | ||
63 | ******************************************************************************/ | ||
64 | acpi_status acpi_db_hex_char_to_value(int hex_char, u8 *return_value) | ||
65 | { | ||
66 | u8 value; | ||
67 | |||
68 | /* Digit must be ascii [0-9a-fA-F] */ | ||
69 | |||
70 | if (!isxdigit(hex_char)) { | ||
71 | return (AE_BAD_HEX_CONSTANT); | ||
72 | } | ||
73 | |||
74 | if (hex_char <= 0x39) { | ||
75 | value = (u8)(hex_char - 0x30); | ||
76 | } else { | ||
77 | value = (u8)(toupper(hex_char) - 0x37); | ||
78 | } | ||
79 | |||
80 | *return_value = value; | ||
81 | return (AE_OK); | ||
82 | } | ||
83 | |||
84 | /******************************************************************************* | ||
85 | * | ||
86 | * FUNCTION: acpi_db_hex_byte_to_binary | ||
87 | * | ||
88 | * PARAMETERS: hex_byte - Double hex digit (0x00 - 0xFF) in format: | ||
89 | * hi_byte then lo_byte. | ||
90 | * return_value - Where the converted value is returned | ||
91 | * | ||
92 | * RETURN: Status | ||
93 | * | ||
94 | * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255). | ||
95 | * | ||
96 | ******************************************************************************/ | ||
97 | |||
98 | static acpi_status acpi_db_hex_byte_to_binary(char *hex_byte, u8 *return_value) | ||
99 | { | ||
100 | u8 local0; | ||
101 | u8 local1; | ||
102 | acpi_status status; | ||
103 | |||
104 | /* High byte */ | ||
105 | |||
106 | status = acpi_db_hex_char_to_value(hex_byte[0], &local0); | ||
107 | if (ACPI_FAILURE(status)) { | ||
108 | return (status); | ||
109 | } | ||
110 | |||
111 | /* Low byte */ | ||
112 | |||
113 | status = acpi_db_hex_char_to_value(hex_byte[1], &local1); | ||
114 | if (ACPI_FAILURE(status)) { | ||
115 | return (status); | ||
116 | } | ||
117 | |||
118 | *return_value = (u8)((local0 << 4) | local1); | ||
119 | return (AE_OK); | ||
120 | } | ||
121 | |||
122 | /******************************************************************************* | ||
123 | * | ||
124 | * FUNCTION: acpi_db_convert_to_buffer | ||
125 | * | ||
126 | * PARAMETERS: string - Input string to be converted | ||
127 | * object - Where the buffer object is returned | ||
128 | * | ||
129 | * RETURN: Status | ||
130 | * | ||
131 | * DESCRIPTION: Convert a string to a buffer object. String is treated a list | ||
132 | * of buffer elements, each separated by a space or comma. | ||
133 | * | ||
134 | ******************************************************************************/ | ||
135 | |||
136 | static acpi_status | ||
137 | acpi_db_convert_to_buffer(char *string, union acpi_object *object) | ||
138 | { | ||
139 | u32 i; | ||
140 | u32 j; | ||
141 | u32 length; | ||
142 | u8 *buffer; | ||
143 | acpi_status status; | ||
144 | |||
145 | /* Generate the final buffer length */ | ||
146 | |||
147 | for (i = 0, length = 0; string[i];) { | ||
148 | i += 2; | ||
149 | length++; | ||
150 | |||
151 | while (string[i] && ((string[i] == ',') || (string[i] == ' '))) { | ||
152 | i++; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | buffer = ACPI_ALLOCATE(length); | ||
157 | if (!buffer) { | ||
158 | return (AE_NO_MEMORY); | ||
159 | } | ||
160 | |||
161 | /* Convert the command line bytes to the buffer */ | ||
162 | |||
163 | for (i = 0, j = 0; string[i];) { | ||
164 | status = acpi_db_hex_byte_to_binary(&string[i], &buffer[j]); | ||
165 | if (ACPI_FAILURE(status)) { | ||
166 | ACPI_FREE(buffer); | ||
167 | return (status); | ||
168 | } | ||
169 | |||
170 | j++; | ||
171 | i += 2; | ||
172 | while (string[i] && ((string[i] == ',') || (string[i] == ' '))) { | ||
173 | i++; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | object->type = ACPI_TYPE_BUFFER; | ||
178 | object->buffer.pointer = buffer; | ||
179 | object->buffer.length = length; | ||
180 | return (AE_OK); | ||
181 | } | ||
182 | |||
183 | /******************************************************************************* | ||
184 | * | ||
185 | * FUNCTION: acpi_db_convert_to_package | ||
186 | * | ||
187 | * PARAMETERS: string - Input string to be converted | ||
188 | * object - Where the package object is returned | ||
189 | * | ||
190 | * RETURN: Status | ||
191 | * | ||
192 | * DESCRIPTION: Convert a string to a package object. Handles nested packages | ||
193 | * via recursion with acpi_db_convert_to_object. | ||
194 | * | ||
195 | ******************************************************************************/ | ||
196 | |||
197 | acpi_status acpi_db_convert_to_package(char *string, union acpi_object * object) | ||
198 | { | ||
199 | char *this; | ||
200 | char *next; | ||
201 | u32 i; | ||
202 | acpi_object_type type; | ||
203 | union acpi_object *elements; | ||
204 | acpi_status status; | ||
205 | |||
206 | elements = | ||
207 | ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS * | ||
208 | sizeof(union acpi_object)); | ||
209 | |||
210 | this = string; | ||
211 | for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) { | ||
212 | this = acpi_db_get_next_token(this, &next, &type); | ||
213 | if (!this) { | ||
214 | break; | ||
215 | } | ||
216 | |||
217 | /* Recursive call to convert each package element */ | ||
218 | |||
219 | status = acpi_db_convert_to_object(type, this, &elements[i]); | ||
220 | if (ACPI_FAILURE(status)) { | ||
221 | acpi_db_delete_objects(i + 1, elements); | ||
222 | ACPI_FREE(elements); | ||
223 | return (status); | ||
224 | } | ||
225 | |||
226 | this = next; | ||
227 | } | ||
228 | |||
229 | object->type = ACPI_TYPE_PACKAGE; | ||
230 | object->package.count = i; | ||
231 | object->package.elements = elements; | ||
232 | return (AE_OK); | ||
233 | } | ||
234 | |||
235 | /******************************************************************************* | ||
236 | * | ||
237 | * FUNCTION: acpi_db_convert_to_object | ||
238 | * | ||
239 | * PARAMETERS: type - Object type as determined by parser | ||
240 | * string - Input string to be converted | ||
241 | * object - Where the new object is returned | ||
242 | * | ||
243 | * RETURN: Status | ||
244 | * | ||
245 | * DESCRIPTION: Convert a typed and tokenized string to an union acpi_object. Typing: | ||
246 | * 1) String objects were surrounded by quotes. | ||
247 | * 2) Buffer objects were surrounded by parentheses. | ||
248 | * 3) Package objects were surrounded by brackets "[]". | ||
249 | * 4) All standalone tokens are treated as integers. | ||
250 | * | ||
251 | ******************************************************************************/ | ||
252 | |||
253 | acpi_status | ||
254 | acpi_db_convert_to_object(acpi_object_type type, | ||
255 | char *string, union acpi_object * object) | ||
256 | { | ||
257 | acpi_status status = AE_OK; | ||
258 | |||
259 | switch (type) { | ||
260 | case ACPI_TYPE_STRING: | ||
261 | |||
262 | object->type = ACPI_TYPE_STRING; | ||
263 | object->string.pointer = string; | ||
264 | object->string.length = (u32)strlen(string); | ||
265 | break; | ||
266 | |||
267 | case ACPI_TYPE_BUFFER: | ||
268 | |||
269 | status = acpi_db_convert_to_buffer(string, object); | ||
270 | break; | ||
271 | |||
272 | case ACPI_TYPE_PACKAGE: | ||
273 | |||
274 | status = acpi_db_convert_to_package(string, object); | ||
275 | break; | ||
276 | |||
277 | default: | ||
278 | |||
279 | object->type = ACPI_TYPE_INTEGER; | ||
280 | status = acpi_ut_strtoul64(string, 16, &object->integer.value); | ||
281 | break; | ||
282 | } | ||
283 | |||
284 | return (status); | ||
285 | } | ||
286 | |||
287 | /******************************************************************************* | ||
288 | * | ||
289 | * FUNCTION: acpi_db_encode_pld_buffer | ||
290 | * | ||
291 | * PARAMETERS: pld_info - _PLD buffer struct (Using local struct) | ||
292 | * | ||
293 | * RETURN: Encode _PLD buffer suitable for return value from _PLD | ||
294 | * | ||
295 | * DESCRIPTION: Bit-packs a _PLD buffer struct. Used to test the _PLD macros | ||
296 | * | ||
297 | ******************************************************************************/ | ||
298 | |||
299 | u8 *acpi_db_encode_pld_buffer(struct acpi_pld_info *pld_info) | ||
300 | { | ||
301 | u32 *buffer; | ||
302 | u32 dword; | ||
303 | |||
304 | buffer = ACPI_ALLOCATE_ZEROED(ACPI_PLD_BUFFER_SIZE); | ||
305 | if (!buffer) { | ||
306 | return (NULL); | ||
307 | } | ||
308 | |||
309 | /* First 32 bits */ | ||
310 | |||
311 | dword = 0; | ||
312 | ACPI_PLD_SET_REVISION(&dword, pld_info->revision); | ||
313 | ACPI_PLD_SET_IGNORE_COLOR(&dword, pld_info->ignore_color); | ||
314 | ACPI_PLD_SET_RED(&dword, pld_info->red); | ||
315 | ACPI_PLD_SET_GREEN(&dword, pld_info->green); | ||
316 | ACPI_PLD_SET_BLUE(&dword, pld_info->blue); | ||
317 | ACPI_MOVE_32_TO_32(&buffer[0], &dword); | ||
318 | |||
319 | /* Second 32 bits */ | ||
320 | |||
321 | dword = 0; | ||
322 | ACPI_PLD_SET_WIDTH(&dword, pld_info->width); | ||
323 | ACPI_PLD_SET_HEIGHT(&dword, pld_info->height); | ||
324 | ACPI_MOVE_32_TO_32(&buffer[1], &dword); | ||
325 | |||
326 | /* Third 32 bits */ | ||
327 | |||
328 | dword = 0; | ||
329 | ACPI_PLD_SET_USER_VISIBLE(&dword, pld_info->user_visible); | ||
330 | ACPI_PLD_SET_DOCK(&dword, pld_info->dock); | ||
331 | ACPI_PLD_SET_LID(&dword, pld_info->lid); | ||
332 | ACPI_PLD_SET_PANEL(&dword, pld_info->panel); | ||
333 | ACPI_PLD_SET_VERTICAL(&dword, pld_info->vertical_position); | ||
334 | ACPI_PLD_SET_HORIZONTAL(&dword, pld_info->horizontal_position); | ||
335 | ACPI_PLD_SET_SHAPE(&dword, pld_info->shape); | ||
336 | ACPI_PLD_SET_ORIENTATION(&dword, pld_info->group_orientation); | ||
337 | ACPI_PLD_SET_TOKEN(&dword, pld_info->group_token); | ||
338 | ACPI_PLD_SET_POSITION(&dword, pld_info->group_position); | ||
339 | ACPI_PLD_SET_BAY(&dword, pld_info->bay); | ||
340 | ACPI_MOVE_32_TO_32(&buffer[2], &dword); | ||
341 | |||
342 | /* Fourth 32 bits */ | ||
343 | |||
344 | dword = 0; | ||
345 | ACPI_PLD_SET_EJECTABLE(&dword, pld_info->ejectable); | ||
346 | ACPI_PLD_SET_OSPM_EJECT(&dword, pld_info->ospm_eject_required); | ||
347 | ACPI_PLD_SET_CABINET(&dword, pld_info->cabinet_number); | ||
348 | ACPI_PLD_SET_CARD_CAGE(&dword, pld_info->card_cage_number); | ||
349 | ACPI_PLD_SET_REFERENCE(&dword, pld_info->reference); | ||
350 | ACPI_PLD_SET_ROTATION(&dword, pld_info->rotation); | ||
351 | ACPI_PLD_SET_ORDER(&dword, pld_info->order); | ||
352 | ACPI_MOVE_32_TO_32(&buffer[3], &dword); | ||
353 | |||
354 | if (pld_info->revision >= 2) { | ||
355 | |||
356 | /* Fifth 32 bits */ | ||
357 | |||
358 | dword = 0; | ||
359 | ACPI_PLD_SET_VERT_OFFSET(&dword, pld_info->vertical_offset); | ||
360 | ACPI_PLD_SET_HORIZ_OFFSET(&dword, pld_info->horizontal_offset); | ||
361 | ACPI_MOVE_32_TO_32(&buffer[4], &dword); | ||
362 | } | ||
363 | |||
364 | return (ACPI_CAST_PTR(u8, buffer)); | ||
365 | } | ||
366 | |||
367 | /******************************************************************************* | ||
368 | * | ||
369 | * FUNCTION: acpi_db_dump_pld_buffer | ||
370 | * | ||
371 | * PARAMETERS: obj_desc - Object returned from _PLD method | ||
372 | * | ||
373 | * RETURN: None. | ||
374 | * | ||
375 | * DESCRIPTION: Dumps formatted contents of a _PLD return buffer. | ||
376 | * | ||
377 | ******************************************************************************/ | ||
378 | |||
379 | #define ACPI_PLD_OUTPUT "%20s : %-6X\n" | ||
380 | |||
381 | void acpi_db_dump_pld_buffer(union acpi_object *obj_desc) | ||
382 | { | ||
383 | union acpi_object *buffer_desc; | ||
384 | struct acpi_pld_info *pld_info; | ||
385 | u8 *new_buffer; | ||
386 | acpi_status status; | ||
387 | |||
388 | /* Object must be of type Package with at least one Buffer element */ | ||
389 | |||
390 | if (obj_desc->type != ACPI_TYPE_PACKAGE) { | ||
391 | return; | ||
392 | } | ||
393 | |||
394 | buffer_desc = &obj_desc->package.elements[0]; | ||
395 | if (buffer_desc->type != ACPI_TYPE_BUFFER) { | ||
396 | return; | ||
397 | } | ||
398 | |||
399 | /* Convert _PLD buffer to local _PLD struct */ | ||
400 | |||
401 | status = acpi_decode_pld_buffer(buffer_desc->buffer.pointer, | ||
402 | buffer_desc->buffer.length, &pld_info); | ||
403 | if (ACPI_FAILURE(status)) { | ||
404 | return; | ||
405 | } | ||
406 | |||
407 | /* Encode local _PLD struct back to a _PLD buffer */ | ||
408 | |||
409 | new_buffer = acpi_db_encode_pld_buffer(pld_info); | ||
410 | if (!new_buffer) { | ||
411 | return; | ||
412 | } | ||
413 | |||
414 | /* The two bit-packed buffers should match */ | ||
415 | |||
416 | if (memcmp(new_buffer, buffer_desc->buffer.pointer, | ||
417 | buffer_desc->buffer.length)) { | ||
418 | acpi_os_printf | ||
419 | ("Converted _PLD buffer does not compare. New:\n"); | ||
420 | |||
421 | acpi_ut_dump_buffer(new_buffer, | ||
422 | buffer_desc->buffer.length, DB_BYTE_DISPLAY, | ||
423 | 0); | ||
424 | } | ||
425 | |||
426 | /* First 32-bit dword */ | ||
427 | |||
428 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Revision", pld_info->revision); | ||
429 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_IgnoreColor", | ||
430 | pld_info->ignore_color); | ||
431 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Red", pld_info->red); | ||
432 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Green", pld_info->green); | ||
433 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Blue", pld_info->blue); | ||
434 | |||
435 | /* Second 32-bit dword */ | ||
436 | |||
437 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Width", pld_info->width); | ||
438 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Height", pld_info->height); | ||
439 | |||
440 | /* Third 32-bit dword */ | ||
441 | |||
442 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_UserVisible", | ||
443 | pld_info->user_visible); | ||
444 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Dock", pld_info->dock); | ||
445 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Lid", pld_info->lid); | ||
446 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Panel", pld_info->panel); | ||
447 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalPosition", | ||
448 | pld_info->vertical_position); | ||
449 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalPosition", | ||
450 | pld_info->horizontal_position); | ||
451 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Shape", pld_info->shape); | ||
452 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupOrientation", | ||
453 | pld_info->group_orientation); | ||
454 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupToken", | ||
455 | pld_info->group_token); | ||
456 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupPosition", | ||
457 | pld_info->group_position); | ||
458 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Bay", pld_info->bay); | ||
459 | |||
460 | /* Fourth 32-bit dword */ | ||
461 | |||
462 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Ejectable", pld_info->ejectable); | ||
463 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_EjectRequired", | ||
464 | pld_info->ospm_eject_required); | ||
465 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CabinetNumber", | ||
466 | pld_info->cabinet_number); | ||
467 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CardCageNumber", | ||
468 | pld_info->card_cage_number); | ||
469 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Reference", pld_info->reference); | ||
470 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Rotation", pld_info->rotation); | ||
471 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Order", pld_info->order); | ||
472 | |||
473 | /* Fifth 32-bit dword */ | ||
474 | |||
475 | if (buffer_desc->buffer.length > 16) { | ||
476 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalOffset", | ||
477 | pld_info->vertical_offset); | ||
478 | acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalOffset", | ||
479 | pld_info->horizontal_offset); | ||
480 | } | ||
481 | |||
482 | ACPI_FREE(pld_info); | ||
483 | ACPI_FREE(new_buffer); | ||
484 | } | ||
diff --git a/drivers/acpi/acpica/dbdisply.c b/drivers/acpi/acpica/dbdisply.c new file mode 100644 index 000000000000..672977ec7c7d --- /dev/null +++ b/drivers/acpi/acpica/dbdisply.c | |||
@@ -0,0 +1,1108 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbdisply - debug display commands | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "amlcode.h" | ||
47 | #include "acdispat.h" | ||
48 | #include "acnamesp.h" | ||
49 | #include "acparser.h" | ||
50 | #include "acinterp.h" | ||
51 | #include "acdebug.h" | ||
52 | |||
53 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
54 | ACPI_MODULE_NAME("dbdisply") | ||
55 | |||
56 | /* Local prototypes */ | ||
57 | static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op); | ||
58 | |||
59 | static void *acpi_db_get_pointer(void *target); | ||
60 | |||
61 | static acpi_status | ||
62 | acpi_db_display_non_root_handlers(acpi_handle obj_handle, | ||
63 | u32 nesting_level, | ||
64 | void *context, void **return_value); | ||
65 | |||
66 | /* | ||
67 | * System handler information. | ||
68 | * Used for Handlers command, in acpi_db_display_handlers. | ||
69 | */ | ||
70 | #define ACPI_PREDEFINED_PREFIX "%25s (%.2X) : " | ||
71 | #define ACPI_HANDLER_NAME_STRING "%30s : " | ||
72 | #define ACPI_HANDLER_PRESENT_STRING "%-9s (%p)\n" | ||
73 | #define ACPI_HANDLER_PRESENT_STRING2 "%-9s (%p)" | ||
74 | #define ACPI_HANDLER_NOT_PRESENT_STRING "%-9s\n" | ||
75 | |||
76 | /* All predefined Address Space IDs */ | ||
77 | |||
78 | static acpi_adr_space_type acpi_gbl_space_id_list[] = { | ||
79 | ACPI_ADR_SPACE_SYSTEM_MEMORY, | ||
80 | ACPI_ADR_SPACE_SYSTEM_IO, | ||
81 | ACPI_ADR_SPACE_PCI_CONFIG, | ||
82 | ACPI_ADR_SPACE_EC, | ||
83 | ACPI_ADR_SPACE_SMBUS, | ||
84 | ACPI_ADR_SPACE_CMOS, | ||
85 | ACPI_ADR_SPACE_PCI_BAR_TARGET, | ||
86 | ACPI_ADR_SPACE_IPMI, | ||
87 | ACPI_ADR_SPACE_GPIO, | ||
88 | ACPI_ADR_SPACE_GSBUS, | ||
89 | ACPI_ADR_SPACE_DATA_TABLE, | ||
90 | ACPI_ADR_SPACE_FIXED_HARDWARE | ||
91 | }; | ||
92 | |||
93 | /* Global handler information */ | ||
94 | |||
95 | typedef struct acpi_handler_info { | ||
96 | void *handler; | ||
97 | char *name; | ||
98 | |||
99 | } acpi_handler_info; | ||
100 | |||
101 | static struct acpi_handler_info acpi_gbl_handler_list[] = { | ||
102 | {&acpi_gbl_global_notify[0].handler, "System Notifications"}, | ||
103 | {&acpi_gbl_global_notify[1].handler, "Device Notifications"}, | ||
104 | {&acpi_gbl_table_handler, "ACPI Table Events"}, | ||
105 | {&acpi_gbl_exception_handler, "Control Method Exceptions"}, | ||
106 | {&acpi_gbl_interface_handler, "OSI Invocations"} | ||
107 | }; | ||
108 | |||
109 | /******************************************************************************* | ||
110 | * | ||
111 | * FUNCTION: acpi_db_get_pointer | ||
112 | * | ||
113 | * PARAMETERS: target - Pointer to string to be converted | ||
114 | * | ||
115 | * RETURN: Converted pointer | ||
116 | * | ||
117 | * DESCRIPTION: Convert an ascii pointer value to a real value | ||
118 | * | ||
119 | ******************************************************************************/ | ||
120 | |||
121 | static void *acpi_db_get_pointer(void *target) | ||
122 | { | ||
123 | void *obj_ptr; | ||
124 | acpi_size address; | ||
125 | |||
126 | address = strtoul(target, NULL, 16); | ||
127 | obj_ptr = ACPI_TO_POINTER(address); | ||
128 | return (obj_ptr); | ||
129 | } | ||
130 | |||
131 | /******************************************************************************* | ||
132 | * | ||
133 | * FUNCTION: acpi_db_dump_parser_descriptor | ||
134 | * | ||
135 | * PARAMETERS: op - A parser Op descriptor | ||
136 | * | ||
137 | * RETURN: None | ||
138 | * | ||
139 | * DESCRIPTION: Display a formatted parser object | ||
140 | * | ||
141 | ******************************************************************************/ | ||
142 | |||
143 | static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op) | ||
144 | { | ||
145 | const struct acpi_opcode_info *info; | ||
146 | |||
147 | info = acpi_ps_get_opcode_info(op->common.aml_opcode); | ||
148 | |||
149 | acpi_os_printf("Parser Op Descriptor:\n"); | ||
150 | acpi_os_printf("%20.20s : %4.4X\n", "Opcode", op->common.aml_opcode); | ||
151 | |||
152 | ACPI_DEBUG_ONLY_MEMBERS(acpi_os_printf("%20.20s : %s\n", "Opcode Name", | ||
153 | info->name)); | ||
154 | |||
155 | acpi_os_printf("%20.20s : %p\n", "Value/ArgList", op->common.value.arg); | ||
156 | acpi_os_printf("%20.20s : %p\n", "Parent", op->common.parent); | ||
157 | acpi_os_printf("%20.20s : %p\n", "NextOp", op->common.next); | ||
158 | } | ||
159 | |||
160 | /******************************************************************************* | ||
161 | * | ||
162 | * FUNCTION: acpi_db_decode_and_display_object | ||
163 | * | ||
164 | * PARAMETERS: target - String with object to be displayed. Names | ||
165 | * and hex pointers are supported. | ||
166 | * output_type - Byte, Word, Dword, or Qword (B|W|D|Q) | ||
167 | * | ||
168 | * RETURN: None | ||
169 | * | ||
170 | * DESCRIPTION: Display a formatted ACPI object | ||
171 | * | ||
172 | ******************************************************************************/ | ||
173 | |||
174 | void acpi_db_decode_and_display_object(char *target, char *output_type) | ||
175 | { | ||
176 | void *obj_ptr; | ||
177 | struct acpi_namespace_node *node; | ||
178 | union acpi_operand_object *obj_desc; | ||
179 | u32 display = DB_BYTE_DISPLAY; | ||
180 | char buffer[80]; | ||
181 | struct acpi_buffer ret_buf; | ||
182 | acpi_status status; | ||
183 | u32 size; | ||
184 | |||
185 | if (!target) { | ||
186 | return; | ||
187 | } | ||
188 | |||
189 | /* Decode the output type */ | ||
190 | |||
191 | if (output_type) { | ||
192 | acpi_ut_strupr(output_type); | ||
193 | if (output_type[0] == 'W') { | ||
194 | display = DB_WORD_DISPLAY; | ||
195 | } else if (output_type[0] == 'D') { | ||
196 | display = DB_DWORD_DISPLAY; | ||
197 | } else if (output_type[0] == 'Q') { | ||
198 | display = DB_QWORD_DISPLAY; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | ret_buf.length = sizeof(buffer); | ||
203 | ret_buf.pointer = buffer; | ||
204 | |||
205 | /* Differentiate between a number and a name */ | ||
206 | |||
207 | if ((target[0] >= 0x30) && (target[0] <= 0x39)) { | ||
208 | obj_ptr = acpi_db_get_pointer(target); | ||
209 | if (!acpi_os_readable(obj_ptr, 16)) { | ||
210 | acpi_os_printf | ||
211 | ("Address %p is invalid in this address space\n", | ||
212 | obj_ptr); | ||
213 | return; | ||
214 | } | ||
215 | |||
216 | /* Decode the object type */ | ||
217 | |||
218 | switch (ACPI_GET_DESCRIPTOR_TYPE(obj_ptr)) { | ||
219 | case ACPI_DESC_TYPE_NAMED: | ||
220 | |||
221 | /* This is a namespace Node */ | ||
222 | |||
223 | if (!acpi_os_readable | ||
224 | (obj_ptr, sizeof(struct acpi_namespace_node))) { | ||
225 | acpi_os_printf | ||
226 | ("Cannot read entire Named object at address %p\n", | ||
227 | obj_ptr); | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | node = obj_ptr; | ||
232 | goto dump_node; | ||
233 | |||
234 | case ACPI_DESC_TYPE_OPERAND: | ||
235 | |||
236 | /* This is a ACPI OPERAND OBJECT */ | ||
237 | |||
238 | if (!acpi_os_readable | ||
239 | (obj_ptr, sizeof(union acpi_operand_object))) { | ||
240 | acpi_os_printf | ||
241 | ("Cannot read entire ACPI object at address %p\n", | ||
242 | obj_ptr); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | acpi_ut_debug_dump_buffer(obj_ptr, | ||
247 | sizeof(union | ||
248 | acpi_operand_object), | ||
249 | display, ACPI_UINT32_MAX); | ||
250 | acpi_ex_dump_object_descriptor(obj_ptr, 1); | ||
251 | break; | ||
252 | |||
253 | case ACPI_DESC_TYPE_PARSER: | ||
254 | |||
255 | /* This is a Parser Op object */ | ||
256 | |||
257 | if (!acpi_os_readable | ||
258 | (obj_ptr, sizeof(union acpi_parse_object))) { | ||
259 | acpi_os_printf | ||
260 | ("Cannot read entire Parser object at address %p\n", | ||
261 | obj_ptr); | ||
262 | return; | ||
263 | } | ||
264 | |||
265 | acpi_ut_debug_dump_buffer(obj_ptr, | ||
266 | sizeof(union | ||
267 | acpi_parse_object), | ||
268 | display, ACPI_UINT32_MAX); | ||
269 | acpi_db_dump_parser_descriptor((union acpi_parse_object | ||
270 | *)obj_ptr); | ||
271 | break; | ||
272 | |||
273 | default: | ||
274 | |||
275 | /* Is not a recognizeable object */ | ||
276 | |||
277 | acpi_os_printf | ||
278 | ("Not a known ACPI internal object, descriptor type %2.2X\n", | ||
279 | ACPI_GET_DESCRIPTOR_TYPE(obj_ptr)); | ||
280 | |||
281 | size = 16; | ||
282 | if (acpi_os_readable(obj_ptr, 64)) { | ||
283 | size = 64; | ||
284 | } | ||
285 | |||
286 | /* Just dump some memory */ | ||
287 | |||
288 | acpi_ut_debug_dump_buffer(obj_ptr, size, display, | ||
289 | ACPI_UINT32_MAX); | ||
290 | break; | ||
291 | } | ||
292 | |||
293 | return; | ||
294 | } | ||
295 | |||
296 | /* The parameter is a name string that must be resolved to a Named obj */ | ||
297 | |||
298 | node = acpi_db_local_ns_lookup(target); | ||
299 | if (!node) { | ||
300 | return; | ||
301 | } | ||
302 | |||
303 | dump_node: | ||
304 | /* Now dump the NS node */ | ||
305 | |||
306 | status = acpi_get_name(node, ACPI_FULL_PATHNAME_NO_TRAILING, &ret_buf); | ||
307 | if (ACPI_FAILURE(status)) { | ||
308 | acpi_os_printf("Could not convert name to pathname\n"); | ||
309 | } | ||
310 | |||
311 | else { | ||
312 | acpi_os_printf("Object (%p) Pathname: %s\n", | ||
313 | node, (char *)ret_buf.pointer); | ||
314 | } | ||
315 | |||
316 | if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) { | ||
317 | acpi_os_printf("Invalid Named object at address %p\n", node); | ||
318 | return; | ||
319 | } | ||
320 | |||
321 | acpi_ut_debug_dump_buffer((void *)node, | ||
322 | sizeof(struct acpi_namespace_node), display, | ||
323 | ACPI_UINT32_MAX); | ||
324 | acpi_ex_dump_namespace_node(node, 1); | ||
325 | |||
326 | obj_desc = acpi_ns_get_attached_object(node); | ||
327 | if (obj_desc) { | ||
328 | acpi_os_printf("\nAttached Object (%p):\n", obj_desc); | ||
329 | if (!acpi_os_readable | ||
330 | (obj_desc, sizeof(union acpi_operand_object))) { | ||
331 | acpi_os_printf | ||
332 | ("Invalid internal ACPI Object at address %p\n", | ||
333 | obj_desc); | ||
334 | return; | ||
335 | } | ||
336 | |||
337 | acpi_ut_debug_dump_buffer((void *)obj_desc, | ||
338 | sizeof(union acpi_operand_object), | ||
339 | display, ACPI_UINT32_MAX); | ||
340 | acpi_ex_dump_object_descriptor(obj_desc, 1); | ||
341 | } | ||
342 | } | ||
343 | |||
344 | /******************************************************************************* | ||
345 | * | ||
346 | * FUNCTION: acpi_db_display_method_info | ||
347 | * | ||
348 | * PARAMETERS: start_op - Root of the control method parse tree | ||
349 | * | ||
350 | * RETURN: None | ||
351 | * | ||
352 | * DESCRIPTION: Display information about the current method | ||
353 | * | ||
354 | ******************************************************************************/ | ||
355 | |||
356 | void acpi_db_display_method_info(union acpi_parse_object *start_op) | ||
357 | { | ||
358 | struct acpi_walk_state *walk_state; | ||
359 | union acpi_operand_object *obj_desc; | ||
360 | struct acpi_namespace_node *node; | ||
361 | union acpi_parse_object *root_op; | ||
362 | union acpi_parse_object *op; | ||
363 | const struct acpi_opcode_info *op_info; | ||
364 | u32 num_ops = 0; | ||
365 | u32 num_operands = 0; | ||
366 | u32 num_operators = 0; | ||
367 | u32 num_remaining_ops = 0; | ||
368 | u32 num_remaining_operands = 0; | ||
369 | u32 num_remaining_operators = 0; | ||
370 | u8 count_remaining = FALSE; | ||
371 | |||
372 | walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); | ||
373 | if (!walk_state) { | ||
374 | acpi_os_printf("There is no method currently executing\n"); | ||
375 | return; | ||
376 | } | ||
377 | |||
378 | obj_desc = walk_state->method_desc; | ||
379 | node = walk_state->method_node; | ||
380 | |||
381 | acpi_os_printf("Currently executing control method is [%4.4s]\n", | ||
382 | acpi_ut_get_node_name(node)); | ||
383 | acpi_os_printf("%X Arguments, SyncLevel = %X\n", | ||
384 | (u32)obj_desc->method.param_count, | ||
385 | (u32)obj_desc->method.sync_level); | ||
386 | |||
387 | root_op = start_op; | ||
388 | while (root_op->common.parent) { | ||
389 | root_op = root_op->common.parent; | ||
390 | } | ||
391 | |||
392 | op = root_op; | ||
393 | |||
394 | while (op) { | ||
395 | if (op == start_op) { | ||
396 | count_remaining = TRUE; | ||
397 | } | ||
398 | |||
399 | num_ops++; | ||
400 | if (count_remaining) { | ||
401 | num_remaining_ops++; | ||
402 | } | ||
403 | |||
404 | /* Decode the opcode */ | ||
405 | |||
406 | op_info = acpi_ps_get_opcode_info(op->common.aml_opcode); | ||
407 | switch (op_info->class) { | ||
408 | case AML_CLASS_ARGUMENT: | ||
409 | |||
410 | if (count_remaining) { | ||
411 | num_remaining_operands++; | ||
412 | } | ||
413 | |||
414 | num_operands++; | ||
415 | break; | ||
416 | |||
417 | case AML_CLASS_UNKNOWN: | ||
418 | |||
419 | /* Bad opcode or ASCII character */ | ||
420 | |||
421 | continue; | ||
422 | |||
423 | default: | ||
424 | |||
425 | if (count_remaining) { | ||
426 | num_remaining_operators++; | ||
427 | } | ||
428 | |||
429 | num_operators++; | ||
430 | break; | ||
431 | } | ||
432 | |||
433 | op = acpi_ps_get_depth_next(start_op, op); | ||
434 | } | ||
435 | |||
436 | acpi_os_printf | ||
437 | ("Method contains: %X AML Opcodes - %X Operators, %X Operands\n", | ||
438 | num_ops, num_operators, num_operands); | ||
439 | |||
440 | acpi_os_printf | ||
441 | ("Remaining to execute: %X AML Opcodes - %X Operators, %X Operands\n", | ||
442 | num_remaining_ops, num_remaining_operators, | ||
443 | num_remaining_operands); | ||
444 | } | ||
445 | |||
446 | /******************************************************************************* | ||
447 | * | ||
448 | * FUNCTION: acpi_db_display_locals | ||
449 | * | ||
450 | * PARAMETERS: None | ||
451 | * | ||
452 | * RETURN: None | ||
453 | * | ||
454 | * DESCRIPTION: Display all locals for the currently running control method | ||
455 | * | ||
456 | ******************************************************************************/ | ||
457 | |||
458 | void acpi_db_display_locals(void) | ||
459 | { | ||
460 | struct acpi_walk_state *walk_state; | ||
461 | |||
462 | walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); | ||
463 | if (!walk_state) { | ||
464 | acpi_os_printf("There is no method currently executing\n"); | ||
465 | return; | ||
466 | } | ||
467 | |||
468 | acpi_db_decode_locals(walk_state); | ||
469 | } | ||
470 | |||
471 | /******************************************************************************* | ||
472 | * | ||
473 | * FUNCTION: acpi_db_display_arguments | ||
474 | * | ||
475 | * PARAMETERS: None | ||
476 | * | ||
477 | * RETURN: None | ||
478 | * | ||
479 | * DESCRIPTION: Display all arguments for the currently running control method | ||
480 | * | ||
481 | ******************************************************************************/ | ||
482 | |||
483 | void acpi_db_display_arguments(void) | ||
484 | { | ||
485 | struct acpi_walk_state *walk_state; | ||
486 | |||
487 | walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); | ||
488 | if (!walk_state) { | ||
489 | acpi_os_printf("There is no method currently executing\n"); | ||
490 | return; | ||
491 | } | ||
492 | |||
493 | acpi_db_decode_arguments(walk_state); | ||
494 | } | ||
495 | |||
496 | /******************************************************************************* | ||
497 | * | ||
498 | * FUNCTION: acpi_db_display_results | ||
499 | * | ||
500 | * PARAMETERS: None | ||
501 | * | ||
502 | * RETURN: None | ||
503 | * | ||
504 | * DESCRIPTION: Display current contents of a method result stack | ||
505 | * | ||
506 | ******************************************************************************/ | ||
507 | |||
508 | void acpi_db_display_results(void) | ||
509 | { | ||
510 | u32 i; | ||
511 | struct acpi_walk_state *walk_state; | ||
512 | union acpi_operand_object *obj_desc; | ||
513 | u32 result_count = 0; | ||
514 | struct acpi_namespace_node *node; | ||
515 | union acpi_generic_state *frame; | ||
516 | u32 index; /* Index onto current frame */ | ||
517 | |||
518 | walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); | ||
519 | if (!walk_state) { | ||
520 | acpi_os_printf("There is no method currently executing\n"); | ||
521 | return; | ||
522 | } | ||
523 | |||
524 | obj_desc = walk_state->method_desc; | ||
525 | node = walk_state->method_node; | ||
526 | |||
527 | if (walk_state->results) { | ||
528 | result_count = walk_state->result_count; | ||
529 | } | ||
530 | |||
531 | acpi_os_printf("Method [%4.4s] has %X stacked result objects\n", | ||
532 | acpi_ut_get_node_name(node), result_count); | ||
533 | |||
534 | /* From the top element of result stack */ | ||
535 | |||
536 | frame = walk_state->results; | ||
537 | index = (result_count - 1) % ACPI_RESULTS_FRAME_OBJ_NUM; | ||
538 | |||
539 | for (i = 0; i < result_count; i++) { | ||
540 | obj_desc = frame->results.obj_desc[index]; | ||
541 | acpi_os_printf("Result%u: ", i); | ||
542 | acpi_db_display_internal_object(obj_desc, walk_state); | ||
543 | |||
544 | if (index == 0) { | ||
545 | frame = frame->results.next; | ||
546 | index = ACPI_RESULTS_FRAME_OBJ_NUM; | ||
547 | } | ||
548 | |||
549 | index--; | ||
550 | } | ||
551 | } | ||
552 | |||
553 | /******************************************************************************* | ||
554 | * | ||
555 | * FUNCTION: acpi_db_display_calling_tree | ||
556 | * | ||
557 | * PARAMETERS: None | ||
558 | * | ||
559 | * RETURN: None | ||
560 | * | ||
561 | * DESCRIPTION: Display current calling tree of nested control methods | ||
562 | * | ||
563 | ******************************************************************************/ | ||
564 | |||
565 | void acpi_db_display_calling_tree(void) | ||
566 | { | ||
567 | struct acpi_walk_state *walk_state; | ||
568 | struct acpi_namespace_node *node; | ||
569 | |||
570 | walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); | ||
571 | if (!walk_state) { | ||
572 | acpi_os_printf("There is no method currently executing\n"); | ||
573 | return; | ||
574 | } | ||
575 | |||
576 | node = walk_state->method_node; | ||
577 | acpi_os_printf("Current Control Method Call Tree\n"); | ||
578 | |||
579 | while (walk_state) { | ||
580 | node = walk_state->method_node; | ||
581 | acpi_os_printf(" [%4.4s]\n", acpi_ut_get_node_name(node)); | ||
582 | |||
583 | walk_state = walk_state->next; | ||
584 | } | ||
585 | } | ||
586 | |||
587 | /******************************************************************************* | ||
588 | * | ||
589 | * FUNCTION: acpi_db_display_object_type | ||
590 | * | ||
591 | * PARAMETERS: name - User entered NS node handle or name | ||
592 | * | ||
593 | * RETURN: None | ||
594 | * | ||
595 | * DESCRIPTION: Display type of an arbitrary NS node | ||
596 | * | ||
597 | ******************************************************************************/ | ||
598 | |||
599 | void acpi_db_display_object_type(char *name) | ||
600 | { | ||
601 | struct acpi_namespace_node *node; | ||
602 | struct acpi_device_info *info; | ||
603 | acpi_status status; | ||
604 | u32 i; | ||
605 | |||
606 | node = acpi_db_convert_to_node(name); | ||
607 | if (!node) { | ||
608 | return; | ||
609 | } | ||
610 | |||
611 | status = acpi_get_object_info(ACPI_CAST_PTR(acpi_handle, node), &info); | ||
612 | if (ACPI_FAILURE(status)) { | ||
613 | acpi_os_printf("Could not get object info, %s\n", | ||
614 | acpi_format_exception(status)); | ||
615 | return; | ||
616 | } | ||
617 | |||
618 | if (info->valid & ACPI_VALID_ADR) { | ||
619 | acpi_os_printf("ADR: %8.8X%8.8X, STA: %8.8X, Flags: %X\n", | ||
620 | ACPI_FORMAT_UINT64(info->address), | ||
621 | info->current_status, info->flags); | ||
622 | } | ||
623 | if (info->valid & ACPI_VALID_SXDS) { | ||
624 | acpi_os_printf("S1D-%2.2X S2D-%2.2X S3D-%2.2X S4D-%2.2X\n", | ||
625 | info->highest_dstates[0], | ||
626 | info->highest_dstates[1], | ||
627 | info->highest_dstates[2], | ||
628 | info->highest_dstates[3]); | ||
629 | } | ||
630 | if (info->valid & ACPI_VALID_SXWS) { | ||
631 | acpi_os_printf | ||
632 | ("S0W-%2.2X S1W-%2.2X S2W-%2.2X S3W-%2.2X S4W-%2.2X\n", | ||
633 | info->lowest_dstates[0], info->lowest_dstates[1], | ||
634 | info->lowest_dstates[2], info->lowest_dstates[3], | ||
635 | info->lowest_dstates[4]); | ||
636 | } | ||
637 | |||
638 | if (info->valid & ACPI_VALID_HID) { | ||
639 | acpi_os_printf("HID: %s\n", info->hardware_id.string); | ||
640 | } | ||
641 | |||
642 | if (info->valid & ACPI_VALID_UID) { | ||
643 | acpi_os_printf("UID: %s\n", info->unique_id.string); | ||
644 | } | ||
645 | |||
646 | if (info->valid & ACPI_VALID_SUB) { | ||
647 | acpi_os_printf("SUB: %s\n", info->subsystem_id.string); | ||
648 | } | ||
649 | |||
650 | if (info->valid & ACPI_VALID_CID) { | ||
651 | for (i = 0; i < info->compatible_id_list.count; i++) { | ||
652 | acpi_os_printf("CID %u: %s\n", i, | ||
653 | info->compatible_id_list.ids[i].string); | ||
654 | } | ||
655 | } | ||
656 | |||
657 | ACPI_FREE(info); | ||
658 | } | ||
659 | |||
660 | /******************************************************************************* | ||
661 | * | ||
662 | * FUNCTION: acpi_db_display_result_object | ||
663 | * | ||
664 | * PARAMETERS: obj_desc - Object to be displayed | ||
665 | * walk_state - Current walk state | ||
666 | * | ||
667 | * RETURN: None | ||
668 | * | ||
669 | * DESCRIPTION: Display the result of an AML opcode | ||
670 | * | ||
671 | * Note: Curently only displays the result object if we are single stepping. | ||
672 | * However, this output may be useful in other contexts and could be enabled | ||
673 | * to do so if needed. | ||
674 | * | ||
675 | ******************************************************************************/ | ||
676 | |||
677 | void | ||
678 | acpi_db_display_result_object(union acpi_operand_object *obj_desc, | ||
679 | struct acpi_walk_state *walk_state) | ||
680 | { | ||
681 | |||
682 | /* Only display if single stepping */ | ||
683 | |||
684 | if (!acpi_gbl_cm_single_step) { | ||
685 | return; | ||
686 | } | ||
687 | |||
688 | acpi_os_printf("ResultObj: "); | ||
689 | acpi_db_display_internal_object(obj_desc, walk_state); | ||
690 | acpi_os_printf("\n"); | ||
691 | } | ||
692 | |||
693 | /******************************************************************************* | ||
694 | * | ||
695 | * FUNCTION: acpi_db_display_argument_object | ||
696 | * | ||
697 | * PARAMETERS: obj_desc - Object to be displayed | ||
698 | * walk_state - Current walk state | ||
699 | * | ||
700 | * RETURN: None | ||
701 | * | ||
702 | * DESCRIPTION: Display the result of an AML opcode | ||
703 | * | ||
704 | ******************************************************************************/ | ||
705 | |||
706 | void | ||
707 | acpi_db_display_argument_object(union acpi_operand_object *obj_desc, | ||
708 | struct acpi_walk_state *walk_state) | ||
709 | { | ||
710 | |||
711 | if (!acpi_gbl_cm_single_step) { | ||
712 | return; | ||
713 | } | ||
714 | |||
715 | acpi_os_printf("ArgObj: "); | ||
716 | acpi_db_display_internal_object(obj_desc, walk_state); | ||
717 | } | ||
718 | |||
719 | #if (!ACPI_REDUCED_HARDWARE) | ||
720 | /******************************************************************************* | ||
721 | * | ||
722 | * FUNCTION: acpi_db_display_gpes | ||
723 | * | ||
724 | * PARAMETERS: None | ||
725 | * | ||
726 | * RETURN: None | ||
727 | * | ||
728 | * DESCRIPTION: Display the current GPE structures | ||
729 | * | ||
730 | ******************************************************************************/ | ||
731 | |||
732 | void acpi_db_display_gpes(void) | ||
733 | { | ||
734 | struct acpi_gpe_block_info *gpe_block; | ||
735 | struct acpi_gpe_xrupt_info *gpe_xrupt_info; | ||
736 | struct acpi_gpe_event_info *gpe_event_info; | ||
737 | struct acpi_gpe_register_info *gpe_register_info; | ||
738 | char *gpe_type; | ||
739 | struct acpi_gpe_notify_info *notify; | ||
740 | u32 gpe_index; | ||
741 | u32 block = 0; | ||
742 | u32 i; | ||
743 | u32 j; | ||
744 | u32 count; | ||
745 | char buffer[80]; | ||
746 | struct acpi_buffer ret_buf; | ||
747 | acpi_status status; | ||
748 | |||
749 | ret_buf.length = sizeof(buffer); | ||
750 | ret_buf.pointer = buffer; | ||
751 | |||
752 | block = 0; | ||
753 | |||
754 | /* Walk the GPE lists */ | ||
755 | |||
756 | gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; | ||
757 | while (gpe_xrupt_info) { | ||
758 | gpe_block = gpe_xrupt_info->gpe_block_list_head; | ||
759 | while (gpe_block) { | ||
760 | status = acpi_get_name(gpe_block->node, | ||
761 | ACPI_FULL_PATHNAME_NO_TRAILING, | ||
762 | &ret_buf); | ||
763 | if (ACPI_FAILURE(status)) { | ||
764 | acpi_os_printf | ||
765 | ("Could not convert name to pathname\n"); | ||
766 | } | ||
767 | |||
768 | if (gpe_block->node == acpi_gbl_fadt_gpe_device) { | ||
769 | gpe_type = "FADT-defined GPE block"; | ||
770 | } else { | ||
771 | gpe_type = "GPE Block Device"; | ||
772 | } | ||
773 | |||
774 | acpi_os_printf | ||
775 | ("\nBlock %u - Info %p DeviceNode %p [%s] - %s\n", | ||
776 | block, gpe_block, gpe_block->node, buffer, | ||
777 | gpe_type); | ||
778 | |||
779 | acpi_os_printf(" Registers: %u (%u GPEs)\n", | ||
780 | gpe_block->register_count, | ||
781 | gpe_block->gpe_count); | ||
782 | |||
783 | acpi_os_printf | ||
784 | (" GPE range: 0x%X to 0x%X on interrupt %u\n", | ||
785 | gpe_block->block_base_number, | ||
786 | gpe_block->block_base_number + | ||
787 | (gpe_block->gpe_count - 1), | ||
788 | gpe_xrupt_info->interrupt_number); | ||
789 | |||
790 | acpi_os_printf | ||
791 | (" RegisterInfo: %p Status %8.8X%8.8X Enable %8.8X%8.8X\n", | ||
792 | gpe_block->register_info, | ||
793 | ACPI_FORMAT_UINT64(gpe_block->register_info-> | ||
794 | status_address.address), | ||
795 | ACPI_FORMAT_UINT64(gpe_block->register_info-> | ||
796 | enable_address.address)); | ||
797 | |||
798 | acpi_os_printf(" EventInfo: %p\n", | ||
799 | gpe_block->event_info); | ||
800 | |||
801 | /* Examine each GPE Register within the block */ | ||
802 | |||
803 | for (i = 0; i < gpe_block->register_count; i++) { | ||
804 | gpe_register_info = | ||
805 | &gpe_block->register_info[i]; | ||
806 | |||
807 | acpi_os_printf(" Reg %u: (GPE %.2X-%.2X) " | ||
808 | "RunEnable %2.2X WakeEnable %2.2X" | ||
809 | " Status %8.8X%8.8X Enable %8.8X%8.8X\n", | ||
810 | i, | ||
811 | gpe_register_info-> | ||
812 | base_gpe_number, | ||
813 | gpe_register_info-> | ||
814 | base_gpe_number + | ||
815 | (ACPI_GPE_REGISTER_WIDTH - 1), | ||
816 | gpe_register_info-> | ||
817 | enable_for_run, | ||
818 | gpe_register_info-> | ||
819 | enable_for_wake, | ||
820 | ACPI_FORMAT_UINT64 | ||
821 | (gpe_register_info-> | ||
822 | status_address.address), | ||
823 | ACPI_FORMAT_UINT64 | ||
824 | (gpe_register_info-> | ||
825 | enable_address.address)); | ||
826 | |||
827 | /* Now look at the individual GPEs in this byte register */ | ||
828 | |||
829 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { | ||
830 | gpe_index = | ||
831 | (i * ACPI_GPE_REGISTER_WIDTH) + j; | ||
832 | gpe_event_info = | ||
833 | &gpe_block->event_info[gpe_index]; | ||
834 | |||
835 | if (ACPI_GPE_DISPATCH_TYPE | ||
836 | (gpe_event_info->flags) == | ||
837 | ACPI_GPE_DISPATCH_NONE) { | ||
838 | |||
839 | /* This GPE is not used (no method or handler), ignore it */ | ||
840 | |||
841 | continue; | ||
842 | } | ||
843 | |||
844 | acpi_os_printf | ||
845 | (" GPE %.2X: %p RunRefs %2.2X Flags %2.2X (", | ||
846 | gpe_block->block_base_number + | ||
847 | gpe_index, gpe_event_info, | ||
848 | gpe_event_info->runtime_count, | ||
849 | gpe_event_info->flags); | ||
850 | |||
851 | /* Decode the flags byte */ | ||
852 | |||
853 | if (gpe_event_info-> | ||
854 | flags & ACPI_GPE_LEVEL_TRIGGERED) { | ||
855 | acpi_os_printf("Level, "); | ||
856 | } else { | ||
857 | acpi_os_printf("Edge, "); | ||
858 | } | ||
859 | |||
860 | if (gpe_event_info-> | ||
861 | flags & ACPI_GPE_CAN_WAKE) { | ||
862 | acpi_os_printf("CanWake, "); | ||
863 | } else { | ||
864 | acpi_os_printf("RunOnly, "); | ||
865 | } | ||
866 | |||
867 | switch (ACPI_GPE_DISPATCH_TYPE | ||
868 | (gpe_event_info->flags)) { | ||
869 | case ACPI_GPE_DISPATCH_NONE: | ||
870 | |||
871 | acpi_os_printf("NotUsed"); | ||
872 | break; | ||
873 | |||
874 | case ACPI_GPE_DISPATCH_METHOD: | ||
875 | |||
876 | acpi_os_printf("Method"); | ||
877 | break; | ||
878 | |||
879 | case ACPI_GPE_DISPATCH_HANDLER: | ||
880 | |||
881 | acpi_os_printf("Handler"); | ||
882 | break; | ||
883 | |||
884 | case ACPI_GPE_DISPATCH_NOTIFY: | ||
885 | |||
886 | count = 0; | ||
887 | notify = | ||
888 | gpe_event_info->dispatch. | ||
889 | notify_list; | ||
890 | while (notify) { | ||
891 | count++; | ||
892 | notify = notify->next; | ||
893 | } | ||
894 | |||
895 | acpi_os_printf | ||
896 | ("Implicit Notify on %u devices", | ||
897 | count); | ||
898 | break; | ||
899 | |||
900 | case ACPI_GPE_DISPATCH_RAW_HANDLER: | ||
901 | |||
902 | acpi_os_printf("RawHandler"); | ||
903 | break; | ||
904 | |||
905 | default: | ||
906 | |||
907 | acpi_os_printf("UNKNOWN: %X", | ||
908 | ACPI_GPE_DISPATCH_TYPE | ||
909 | (gpe_event_info-> | ||
910 | flags)); | ||
911 | break; | ||
912 | } | ||
913 | |||
914 | acpi_os_printf(")\n"); | ||
915 | } | ||
916 | } | ||
917 | |||
918 | block++; | ||
919 | gpe_block = gpe_block->next; | ||
920 | } | ||
921 | |||
922 | gpe_xrupt_info = gpe_xrupt_info->next; | ||
923 | } | ||
924 | } | ||
925 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
926 | |||
927 | /******************************************************************************* | ||
928 | * | ||
929 | * FUNCTION: acpi_db_display_handlers | ||
930 | * | ||
931 | * PARAMETERS: None | ||
932 | * | ||
933 | * RETURN: None | ||
934 | * | ||
935 | * DESCRIPTION: Display the currently installed global handlers | ||
936 | * | ||
937 | ******************************************************************************/ | ||
938 | |||
939 | void acpi_db_display_handlers(void) | ||
940 | { | ||
941 | union acpi_operand_object *obj_desc; | ||
942 | union acpi_operand_object *handler_obj; | ||
943 | acpi_adr_space_type space_id; | ||
944 | u32 i; | ||
945 | |||
946 | /* Operation region handlers */ | ||
947 | |||
948 | acpi_os_printf("\nOperation Region Handlers at the namespace root:\n"); | ||
949 | |||
950 | obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node); | ||
951 | if (obj_desc) { | ||
952 | for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_space_id_list); i++) { | ||
953 | space_id = acpi_gbl_space_id_list[i]; | ||
954 | handler_obj = obj_desc->device.handler; | ||
955 | |||
956 | acpi_os_printf(ACPI_PREDEFINED_PREFIX, | ||
957 | acpi_ut_get_region_name((u8)space_id), | ||
958 | space_id); | ||
959 | |||
960 | while (handler_obj) { | ||
961 | if (acpi_gbl_space_id_list[i] == | ||
962 | handler_obj->address_space.space_id) { | ||
963 | acpi_os_printf | ||
964 | (ACPI_HANDLER_PRESENT_STRING, | ||
965 | (handler_obj->address_space. | ||
966 | handler_flags & | ||
967 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) | ||
968 | ? "Default" : "User", | ||
969 | handler_obj->address_space. | ||
970 | handler); | ||
971 | |||
972 | goto found_handler; | ||
973 | } | ||
974 | |||
975 | handler_obj = handler_obj->address_space.next; | ||
976 | } | ||
977 | |||
978 | /* There is no handler for this space_id */ | ||
979 | |||
980 | acpi_os_printf("None\n"); | ||
981 | |||
982 | found_handler: ; | ||
983 | } | ||
984 | |||
985 | /* Find all handlers for user-defined space_IDs */ | ||
986 | |||
987 | handler_obj = obj_desc->device.handler; | ||
988 | while (handler_obj) { | ||
989 | if (handler_obj->address_space.space_id >= | ||
990 | ACPI_USER_REGION_BEGIN) { | ||
991 | acpi_os_printf(ACPI_PREDEFINED_PREFIX, | ||
992 | "User-defined ID", | ||
993 | handler_obj->address_space. | ||
994 | space_id); | ||
995 | acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, | ||
996 | (handler_obj->address_space. | ||
997 | handler_flags & | ||
998 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) | ||
999 | ? "Default" : "User", | ||
1000 | handler_obj->address_space. | ||
1001 | handler); | ||
1002 | } | ||
1003 | |||
1004 | handler_obj = handler_obj->address_space.next; | ||
1005 | } | ||
1006 | } | ||
1007 | #if (!ACPI_REDUCED_HARDWARE) | ||
1008 | |||
1009 | /* Fixed event handlers */ | ||
1010 | |||
1011 | acpi_os_printf("\nFixed Event Handlers:\n"); | ||
1012 | |||
1013 | for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { | ||
1014 | acpi_os_printf(ACPI_PREDEFINED_PREFIX, | ||
1015 | acpi_ut_get_event_name(i), i); | ||
1016 | if (acpi_gbl_fixed_event_handlers[i].handler) { | ||
1017 | acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User", | ||
1018 | acpi_gbl_fixed_event_handlers[i]. | ||
1019 | handler); | ||
1020 | } else { | ||
1021 | acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None"); | ||
1022 | } | ||
1023 | } | ||
1024 | |||
1025 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
1026 | |||
1027 | /* Miscellaneous global handlers */ | ||
1028 | |||
1029 | acpi_os_printf("\nMiscellaneous Global Handlers:\n"); | ||
1030 | |||
1031 | for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_handler_list); i++) { | ||
1032 | acpi_os_printf(ACPI_HANDLER_NAME_STRING, | ||
1033 | acpi_gbl_handler_list[i].name); | ||
1034 | |||
1035 | if (acpi_gbl_handler_list[i].handler) { | ||
1036 | acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User", | ||
1037 | acpi_gbl_handler_list[i].handler); | ||
1038 | } else { | ||
1039 | acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None"); | ||
1040 | } | ||
1041 | } | ||
1042 | |||
1043 | /* Other handlers that are installed throughout the namespace */ | ||
1044 | |||
1045 | acpi_os_printf("\nOperation Region Handlers for specific devices:\n"); | ||
1046 | |||
1047 | (void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
1048 | ACPI_UINT32_MAX, | ||
1049 | acpi_db_display_non_root_handlers, NULL, NULL, | ||
1050 | NULL); | ||
1051 | } | ||
1052 | |||
1053 | /******************************************************************************* | ||
1054 | * | ||
1055 | * FUNCTION: acpi_db_display_non_root_handlers | ||
1056 | * | ||
1057 | * PARAMETERS: acpi_walk_callback | ||
1058 | * | ||
1059 | * RETURN: Status | ||
1060 | * | ||
1061 | * DESCRIPTION: Display information about all handlers installed for a | ||
1062 | * device object. | ||
1063 | * | ||
1064 | ******************************************************************************/ | ||
1065 | |||
1066 | static acpi_status | ||
1067 | acpi_db_display_non_root_handlers(acpi_handle obj_handle, | ||
1068 | u32 nesting_level, | ||
1069 | void *context, void **return_value) | ||
1070 | { | ||
1071 | struct acpi_namespace_node *node = | ||
1072 | ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); | ||
1073 | union acpi_operand_object *obj_desc; | ||
1074 | union acpi_operand_object *handler_obj; | ||
1075 | char *pathname; | ||
1076 | |||
1077 | obj_desc = acpi_ns_get_attached_object(node); | ||
1078 | if (!obj_desc) { | ||
1079 | return (AE_OK); | ||
1080 | } | ||
1081 | |||
1082 | pathname = acpi_ns_get_external_pathname(node); | ||
1083 | if (!pathname) { | ||
1084 | return (AE_OK); | ||
1085 | } | ||
1086 | |||
1087 | /* Display all handlers associated with this device */ | ||
1088 | |||
1089 | handler_obj = obj_desc->device.handler; | ||
1090 | while (handler_obj) { | ||
1091 | acpi_os_printf(ACPI_PREDEFINED_PREFIX, | ||
1092 | acpi_ut_get_region_name((u8)handler_obj-> | ||
1093 | address_space.space_id), | ||
1094 | handler_obj->address_space.space_id); | ||
1095 | |||
1096 | acpi_os_printf(ACPI_HANDLER_PRESENT_STRING2, | ||
1097 | (handler_obj->address_space.handler_flags & | ||
1098 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default" | ||
1099 | : "User", handler_obj->address_space.handler); | ||
1100 | |||
1101 | acpi_os_printf(" Device Name: %s (%p)\n", pathname, node); | ||
1102 | |||
1103 | handler_obj = handler_obj->address_space.next; | ||
1104 | } | ||
1105 | |||
1106 | ACPI_FREE(pathname); | ||
1107 | return (AE_OK); | ||
1108 | } | ||
diff --git a/drivers/acpi/acpica/dbexec.c b/drivers/acpi/acpica/dbexec.c new file mode 100644 index 000000000000..d713e2df65b9 --- /dev/null +++ b/drivers/acpi/acpica/dbexec.c | |||
@@ -0,0 +1,764 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbexec - debugger control method execution | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acdebug.h" | ||
47 | #include "acnamesp.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
50 | ACPI_MODULE_NAME("dbexec") | ||
51 | |||
52 | static struct acpi_db_method_info acpi_gbl_db_method_info; | ||
53 | |||
54 | /* Local prototypes */ | ||
55 | |||
56 | static acpi_status | ||
57 | acpi_db_execute_method(struct acpi_db_method_info *info, | ||
58 | struct acpi_buffer *return_obj); | ||
59 | |||
60 | static acpi_status acpi_db_execute_setup(struct acpi_db_method_info *info); | ||
61 | |||
62 | static u32 acpi_db_get_outstanding_allocations(void); | ||
63 | |||
64 | static void ACPI_SYSTEM_XFACE acpi_db_method_thread(void *context); | ||
65 | |||
66 | static acpi_status | ||
67 | acpi_db_execution_walk(acpi_handle obj_handle, | ||
68 | u32 nesting_level, void *context, void **return_value); | ||
69 | |||
70 | /******************************************************************************* | ||
71 | * | ||
72 | * FUNCTION: acpi_db_delete_objects | ||
73 | * | ||
74 | * PARAMETERS: count - Count of objects in the list | ||
75 | * objects - Array of ACPI_OBJECTs to be deleted | ||
76 | * | ||
77 | * RETURN: None | ||
78 | * | ||
79 | * DESCRIPTION: Delete a list of ACPI_OBJECTS. Handles packages and nested | ||
80 | * packages via recursion. | ||
81 | * | ||
82 | ******************************************************************************/ | ||
83 | |||
84 | void acpi_db_delete_objects(u32 count, union acpi_object *objects) | ||
85 | { | ||
86 | u32 i; | ||
87 | |||
88 | for (i = 0; i < count; i++) { | ||
89 | switch (objects[i].type) { | ||
90 | case ACPI_TYPE_BUFFER: | ||
91 | |||
92 | ACPI_FREE(objects[i].buffer.pointer); | ||
93 | break; | ||
94 | |||
95 | case ACPI_TYPE_PACKAGE: | ||
96 | |||
97 | /* Recursive call to delete package elements */ | ||
98 | |||
99 | acpi_db_delete_objects(objects[i].package.count, | ||
100 | objects[i].package.elements); | ||
101 | |||
102 | /* Free the elements array */ | ||
103 | |||
104 | ACPI_FREE(objects[i].package.elements); | ||
105 | break; | ||
106 | |||
107 | default: | ||
108 | |||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | |||
114 | /******************************************************************************* | ||
115 | * | ||
116 | * FUNCTION: acpi_db_execute_method | ||
117 | * | ||
118 | * PARAMETERS: info - Valid info segment | ||
119 | * return_obj - Where to put return object | ||
120 | * | ||
121 | * RETURN: Status | ||
122 | * | ||
123 | * DESCRIPTION: Execute a control method. | ||
124 | * | ||
125 | ******************************************************************************/ | ||
126 | |||
127 | static acpi_status | ||
128 | acpi_db_execute_method(struct acpi_db_method_info *info, | ||
129 | struct acpi_buffer *return_obj) | ||
130 | { | ||
131 | acpi_status status; | ||
132 | struct acpi_object_list param_objects; | ||
133 | union acpi_object params[ACPI_DEBUGGER_MAX_ARGS + 1]; | ||
134 | u32 i; | ||
135 | |||
136 | ACPI_FUNCTION_TRACE(db_execute_method); | ||
137 | |||
138 | if (acpi_gbl_db_output_to_file && !acpi_dbg_level) { | ||
139 | acpi_os_printf("Warning: debug output is not enabled!\n"); | ||
140 | } | ||
141 | |||
142 | param_objects.count = 0; | ||
143 | param_objects.pointer = NULL; | ||
144 | |||
145 | /* Pass through any command-line arguments */ | ||
146 | |||
147 | if (info->args && info->args[0]) { | ||
148 | |||
149 | /* Get arguments passed on the command line */ | ||
150 | |||
151 | for (i = 0; (info->args[i] && *(info->args[i])); i++) { | ||
152 | |||
153 | /* Convert input string (token) to an actual union acpi_object */ | ||
154 | |||
155 | status = acpi_db_convert_to_object(info->types[i], | ||
156 | info->args[i], | ||
157 | ¶ms[i]); | ||
158 | if (ACPI_FAILURE(status)) { | ||
159 | ACPI_EXCEPTION((AE_INFO, status, | ||
160 | "While parsing method arguments")); | ||
161 | goto cleanup; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | param_objects.count = i; | ||
166 | param_objects.pointer = params; | ||
167 | } | ||
168 | |||
169 | /* Prepare for a return object of arbitrary size */ | ||
170 | |||
171 | return_obj->pointer = acpi_gbl_db_buffer; | ||
172 | return_obj->length = ACPI_DEBUG_BUFFER_SIZE; | ||
173 | |||
174 | /* Do the actual method execution */ | ||
175 | |||
176 | acpi_gbl_method_executing = TRUE; | ||
177 | status = acpi_evaluate_object(NULL, info->pathname, | ||
178 | ¶m_objects, return_obj); | ||
179 | |||
180 | acpi_gbl_cm_single_step = FALSE; | ||
181 | acpi_gbl_method_executing = FALSE; | ||
182 | |||
183 | if (ACPI_FAILURE(status)) { | ||
184 | ACPI_EXCEPTION((AE_INFO, status, | ||
185 | "while executing %s from debugger", | ||
186 | info->pathname)); | ||
187 | |||
188 | if (status == AE_BUFFER_OVERFLOW) { | ||
189 | ACPI_ERROR((AE_INFO, | ||
190 | "Possible overflow of internal debugger " | ||
191 | "buffer (size 0x%X needed 0x%X)", | ||
192 | ACPI_DEBUG_BUFFER_SIZE, | ||
193 | (u32)return_obj->length)); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | cleanup: | ||
198 | acpi_db_delete_objects(param_objects.count, params); | ||
199 | return_ACPI_STATUS(status); | ||
200 | } | ||
201 | |||
202 | /******************************************************************************* | ||
203 | * | ||
204 | * FUNCTION: acpi_db_execute_setup | ||
205 | * | ||
206 | * PARAMETERS: info - Valid method info | ||
207 | * | ||
208 | * RETURN: None | ||
209 | * | ||
210 | * DESCRIPTION: Setup info segment prior to method execution | ||
211 | * | ||
212 | ******************************************************************************/ | ||
213 | |||
214 | static acpi_status acpi_db_execute_setup(struct acpi_db_method_info *info) | ||
215 | { | ||
216 | acpi_status status; | ||
217 | |||
218 | ACPI_FUNCTION_NAME(db_execute_setup); | ||
219 | |||
220 | /* Catenate the current scope to the supplied name */ | ||
221 | |||
222 | info->pathname[0] = 0; | ||
223 | if ((info->name[0] != '\\') && (info->name[0] != '/')) { | ||
224 | if (acpi_ut_safe_strcat(info->pathname, sizeof(info->pathname), | ||
225 | acpi_gbl_db_scope_buf)) { | ||
226 | status = AE_BUFFER_OVERFLOW; | ||
227 | goto error_exit; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | if (acpi_ut_safe_strcat(info->pathname, sizeof(info->pathname), | ||
232 | info->name)) { | ||
233 | status = AE_BUFFER_OVERFLOW; | ||
234 | goto error_exit; | ||
235 | } | ||
236 | |||
237 | acpi_db_prep_namestring(info->pathname); | ||
238 | |||
239 | acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); | ||
240 | acpi_os_printf("Evaluating %s\n", info->pathname); | ||
241 | |||
242 | if (info->flags & EX_SINGLE_STEP) { | ||
243 | acpi_gbl_cm_single_step = TRUE; | ||
244 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
245 | } | ||
246 | |||
247 | else { | ||
248 | /* No single step, allow redirection to a file */ | ||
249 | |||
250 | acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); | ||
251 | } | ||
252 | |||
253 | return (AE_OK); | ||
254 | |||
255 | error_exit: | ||
256 | |||
257 | ACPI_EXCEPTION((AE_INFO, status, "During setup for method execution")); | ||
258 | return (status); | ||
259 | } | ||
260 | |||
261 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
262 | u32 acpi_db_get_cache_info(struct acpi_memory_list *cache) | ||
263 | { | ||
264 | |||
265 | return (cache->total_allocated - cache->total_freed - | ||
266 | cache->current_depth); | ||
267 | } | ||
268 | #endif | ||
269 | |||
270 | /******************************************************************************* | ||
271 | * | ||
272 | * FUNCTION: acpi_db_get_outstanding_allocations | ||
273 | * | ||
274 | * PARAMETERS: None | ||
275 | * | ||
276 | * RETURN: Current global allocation count minus cache entries | ||
277 | * | ||
278 | * DESCRIPTION: Determine the current number of "outstanding" allocations -- | ||
279 | * those allocations that have not been freed and also are not | ||
280 | * in one of the various object caches. | ||
281 | * | ||
282 | ******************************************************************************/ | ||
283 | |||
284 | static u32 acpi_db_get_outstanding_allocations(void) | ||
285 | { | ||
286 | u32 outstanding = 0; | ||
287 | |||
288 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
289 | |||
290 | outstanding += acpi_db_get_cache_info(acpi_gbl_state_cache); | ||
291 | outstanding += acpi_db_get_cache_info(acpi_gbl_ps_node_cache); | ||
292 | outstanding += acpi_db_get_cache_info(acpi_gbl_ps_node_ext_cache); | ||
293 | outstanding += acpi_db_get_cache_info(acpi_gbl_operand_cache); | ||
294 | #endif | ||
295 | |||
296 | return (outstanding); | ||
297 | } | ||
298 | |||
299 | /******************************************************************************* | ||
300 | * | ||
301 | * FUNCTION: acpi_db_execution_walk | ||
302 | * | ||
303 | * PARAMETERS: WALK_CALLBACK | ||
304 | * | ||
305 | * RETURN: Status | ||
306 | * | ||
307 | * DESCRIPTION: Execute a control method. Name is relative to the current | ||
308 | * scope. | ||
309 | * | ||
310 | ******************************************************************************/ | ||
311 | |||
312 | static acpi_status | ||
313 | acpi_db_execution_walk(acpi_handle obj_handle, | ||
314 | u32 nesting_level, void *context, void **return_value) | ||
315 | { | ||
316 | union acpi_operand_object *obj_desc; | ||
317 | struct acpi_namespace_node *node = | ||
318 | (struct acpi_namespace_node *)obj_handle; | ||
319 | struct acpi_buffer return_obj; | ||
320 | acpi_status status; | ||
321 | |||
322 | obj_desc = acpi_ns_get_attached_object(node); | ||
323 | if (obj_desc->method.param_count) { | ||
324 | return (AE_OK); | ||
325 | } | ||
326 | |||
327 | return_obj.pointer = NULL; | ||
328 | return_obj.length = ACPI_ALLOCATE_BUFFER; | ||
329 | |||
330 | acpi_ns_print_node_pathname(node, "Evaluating"); | ||
331 | |||
332 | /* Do the actual method execution */ | ||
333 | |||
334 | acpi_os_printf("\n"); | ||
335 | acpi_gbl_method_executing = TRUE; | ||
336 | |||
337 | status = acpi_evaluate_object(node, NULL, NULL, &return_obj); | ||
338 | |||
339 | acpi_os_printf("Evaluation of [%4.4s] returned %s\n", | ||
340 | acpi_ut_get_node_name(node), | ||
341 | acpi_format_exception(status)); | ||
342 | |||
343 | acpi_gbl_method_executing = FALSE; | ||
344 | return (AE_OK); | ||
345 | } | ||
346 | |||
347 | /******************************************************************************* | ||
348 | * | ||
349 | * FUNCTION: acpi_db_execute | ||
350 | * | ||
351 | * PARAMETERS: name - Name of method to execute | ||
352 | * args - Parameters to the method | ||
353 | * Types - | ||
354 | * flags - single step/no single step | ||
355 | * | ||
356 | * RETURN: None | ||
357 | * | ||
358 | * DESCRIPTION: Execute a control method. Name is relative to the current | ||
359 | * scope. | ||
360 | * | ||
361 | ******************************************************************************/ | ||
362 | |||
363 | void | ||
364 | acpi_db_execute(char *name, char **args, acpi_object_type * types, u32 flags) | ||
365 | { | ||
366 | acpi_status status; | ||
367 | struct acpi_buffer return_obj; | ||
368 | char *name_string; | ||
369 | |||
370 | #ifdef ACPI_DEBUG_OUTPUT | ||
371 | u32 previous_allocations; | ||
372 | u32 allocations; | ||
373 | #endif | ||
374 | |||
375 | /* | ||
376 | * Allow one execution to be performed by debugger or single step | ||
377 | * execution will be dead locked by the interpreter mutexes. | ||
378 | */ | ||
379 | if (acpi_gbl_method_executing) { | ||
380 | acpi_os_printf("Only one debugger execution is allowed.\n"); | ||
381 | return; | ||
382 | } | ||
383 | #ifdef ACPI_DEBUG_OUTPUT | ||
384 | /* Memory allocation tracking */ | ||
385 | |||
386 | previous_allocations = acpi_db_get_outstanding_allocations(); | ||
387 | #endif | ||
388 | |||
389 | if (*name == '*') { | ||
390 | (void)acpi_walk_namespace(ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT, | ||
391 | ACPI_UINT32_MAX, | ||
392 | acpi_db_execution_walk, NULL, NULL, | ||
393 | NULL); | ||
394 | return; | ||
395 | } else { | ||
396 | name_string = ACPI_ALLOCATE(strlen(name) + 1); | ||
397 | if (!name_string) { | ||
398 | return; | ||
399 | } | ||
400 | |||
401 | memset(&acpi_gbl_db_method_info, 0, | ||
402 | sizeof(struct acpi_db_method_info)); | ||
403 | |||
404 | strcpy(name_string, name); | ||
405 | acpi_ut_strupr(name_string); | ||
406 | acpi_gbl_db_method_info.name = name_string; | ||
407 | acpi_gbl_db_method_info.args = args; | ||
408 | acpi_gbl_db_method_info.types = types; | ||
409 | acpi_gbl_db_method_info.flags = flags; | ||
410 | |||
411 | return_obj.pointer = NULL; | ||
412 | return_obj.length = ACPI_ALLOCATE_BUFFER; | ||
413 | |||
414 | status = acpi_db_execute_setup(&acpi_gbl_db_method_info); | ||
415 | if (ACPI_FAILURE(status)) { | ||
416 | ACPI_FREE(name_string); | ||
417 | return; | ||
418 | } | ||
419 | |||
420 | /* Get the NS node, determines existence also */ | ||
421 | |||
422 | status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname, | ||
423 | &acpi_gbl_db_method_info.method); | ||
424 | if (ACPI_SUCCESS(status)) { | ||
425 | status = | ||
426 | acpi_db_execute_method(&acpi_gbl_db_method_info, | ||
427 | &return_obj); | ||
428 | } | ||
429 | ACPI_FREE(name_string); | ||
430 | } | ||
431 | |||
432 | /* | ||
433 | * Allow any handlers in separate threads to complete. | ||
434 | * (Such as Notify handlers invoked from AML executed above). | ||
435 | */ | ||
436 | acpi_os_sleep((u64)10); | ||
437 | |||
438 | #ifdef ACPI_DEBUG_OUTPUT | ||
439 | |||
440 | /* Memory allocation tracking */ | ||
441 | |||
442 | allocations = | ||
443 | acpi_db_get_outstanding_allocations() - previous_allocations; | ||
444 | |||
445 | acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); | ||
446 | |||
447 | if (allocations > 0) { | ||
448 | acpi_os_printf | ||
449 | ("0x%X Outstanding allocations after evaluation of %s\n", | ||
450 | allocations, acpi_gbl_db_method_info.pathname); | ||
451 | } | ||
452 | #endif | ||
453 | |||
454 | if (ACPI_FAILURE(status)) { | ||
455 | acpi_os_printf("Evaluation of %s failed with status %s\n", | ||
456 | acpi_gbl_db_method_info.pathname, | ||
457 | acpi_format_exception(status)); | ||
458 | } else { | ||
459 | /* Display a return object, if any */ | ||
460 | |||
461 | if (return_obj.length) { | ||
462 | acpi_os_printf("Evaluation of %s returned object %p, " | ||
463 | "external buffer length %X\n", | ||
464 | acpi_gbl_db_method_info.pathname, | ||
465 | return_obj.pointer, | ||
466 | (u32)return_obj.length); | ||
467 | |||
468 | acpi_db_dump_external_object(return_obj.pointer, 1); | ||
469 | |||
470 | /* Dump a _PLD buffer if present */ | ||
471 | |||
472 | if (ACPI_COMPARE_NAME | ||
473 | ((ACPI_CAST_PTR | ||
474 | (struct acpi_namespace_node, | ||
475 | acpi_gbl_db_method_info.method)->name.ascii), | ||
476 | METHOD_NAME__PLD)) { | ||
477 | acpi_db_dump_pld_buffer(return_obj.pointer); | ||
478 | } | ||
479 | } else { | ||
480 | acpi_os_printf | ||
481 | ("No object was returned from evaluation of %s\n", | ||
482 | acpi_gbl_db_method_info.pathname); | ||
483 | } | ||
484 | } | ||
485 | |||
486 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
487 | } | ||
488 | |||
489 | /******************************************************************************* | ||
490 | * | ||
491 | * FUNCTION: acpi_db_method_thread | ||
492 | * | ||
493 | * PARAMETERS: context - Execution info segment | ||
494 | * | ||
495 | * RETURN: None | ||
496 | * | ||
497 | * DESCRIPTION: Debugger execute thread. Waits for a command line, then | ||
498 | * simply dispatches it. | ||
499 | * | ||
500 | ******************************************************************************/ | ||
501 | |||
502 | static void ACPI_SYSTEM_XFACE acpi_db_method_thread(void *context) | ||
503 | { | ||
504 | acpi_status status; | ||
505 | struct acpi_db_method_info *info = context; | ||
506 | struct acpi_db_method_info local_info; | ||
507 | u32 i; | ||
508 | u8 allow; | ||
509 | struct acpi_buffer return_obj; | ||
510 | |||
511 | /* | ||
512 | * acpi_gbl_db_method_info.Arguments will be passed as method arguments. | ||
513 | * Prevent acpi_gbl_db_method_info from being modified by multiple threads | ||
514 | * concurrently. | ||
515 | * | ||
516 | * Note: The arguments we are passing are used by the ASL test suite | ||
517 | * (aslts). Do not change them without updating the tests. | ||
518 | */ | ||
519 | (void)acpi_os_wait_semaphore(info->info_gate, 1, ACPI_WAIT_FOREVER); | ||
520 | |||
521 | if (info->init_args) { | ||
522 | acpi_db_uint32_to_hex_string(info->num_created, | ||
523 | info->index_of_thread_str); | ||
524 | acpi_db_uint32_to_hex_string((u32)acpi_os_get_thread_id(), | ||
525 | info->id_of_thread_str); | ||
526 | } | ||
527 | |||
528 | if (info->threads && (info->num_created < info->num_threads)) { | ||
529 | info->threads[info->num_created++] = acpi_os_get_thread_id(); | ||
530 | } | ||
531 | |||
532 | local_info = *info; | ||
533 | local_info.args = local_info.arguments; | ||
534 | local_info.arguments[0] = local_info.num_threads_str; | ||
535 | local_info.arguments[1] = local_info.id_of_thread_str; | ||
536 | local_info.arguments[2] = local_info.index_of_thread_str; | ||
537 | local_info.arguments[3] = NULL; | ||
538 | |||
539 | local_info.types = local_info.arg_types; | ||
540 | |||
541 | (void)acpi_os_signal_semaphore(info->info_gate, 1); | ||
542 | |||
543 | for (i = 0; i < info->num_loops; i++) { | ||
544 | status = acpi_db_execute_method(&local_info, &return_obj); | ||
545 | if (ACPI_FAILURE(status)) { | ||
546 | acpi_os_printf | ||
547 | ("%s During evaluation of %s at iteration %X\n", | ||
548 | acpi_format_exception(status), info->pathname, i); | ||
549 | if (status == AE_ABORT_METHOD) { | ||
550 | break; | ||
551 | } | ||
552 | } | ||
553 | #if 0 | ||
554 | if ((i % 100) == 0) { | ||
555 | acpi_os_printf("%u loops, Thread 0x%x\n", | ||
556 | i, acpi_os_get_thread_id()); | ||
557 | } | ||
558 | |||
559 | if (return_obj.length) { | ||
560 | acpi_os_printf | ||
561 | ("Evaluation of %s returned object %p Buflen %X\n", | ||
562 | info->pathname, return_obj.pointer, | ||
563 | (u32)return_obj.length); | ||
564 | acpi_db_dump_external_object(return_obj.pointer, 1); | ||
565 | } | ||
566 | #endif | ||
567 | } | ||
568 | |||
569 | /* Signal our completion */ | ||
570 | |||
571 | allow = 0; | ||
572 | (void)acpi_os_wait_semaphore(info->thread_complete_gate, | ||
573 | 1, ACPI_WAIT_FOREVER); | ||
574 | info->num_completed++; | ||
575 | |||
576 | if (info->num_completed == info->num_threads) { | ||
577 | |||
578 | /* Do signal for main thread once only */ | ||
579 | allow = 1; | ||
580 | } | ||
581 | |||
582 | (void)acpi_os_signal_semaphore(info->thread_complete_gate, 1); | ||
583 | |||
584 | if (allow) { | ||
585 | status = acpi_os_signal_semaphore(info->main_thread_gate, 1); | ||
586 | if (ACPI_FAILURE(status)) { | ||
587 | acpi_os_printf | ||
588 | ("Could not signal debugger thread sync semaphore, %s\n", | ||
589 | acpi_format_exception(status)); | ||
590 | } | ||
591 | } | ||
592 | } | ||
593 | |||
594 | /******************************************************************************* | ||
595 | * | ||
596 | * FUNCTION: acpi_db_create_execution_threads | ||
597 | * | ||
598 | * PARAMETERS: num_threads_arg - Number of threads to create | ||
599 | * num_loops_arg - Loop count for the thread(s) | ||
600 | * method_name_arg - Control method to execute | ||
601 | * | ||
602 | * RETURN: None | ||
603 | * | ||
604 | * DESCRIPTION: Create threads to execute method(s) | ||
605 | * | ||
606 | ******************************************************************************/ | ||
607 | |||
608 | void | ||
609 | acpi_db_create_execution_threads(char *num_threads_arg, | ||
610 | char *num_loops_arg, char *method_name_arg) | ||
611 | { | ||
612 | acpi_status status; | ||
613 | u32 num_threads; | ||
614 | u32 num_loops; | ||
615 | u32 i; | ||
616 | u32 size; | ||
617 | acpi_mutex main_thread_gate; | ||
618 | acpi_mutex thread_complete_gate; | ||
619 | acpi_mutex info_gate; | ||
620 | |||
621 | /* Get the arguments */ | ||
622 | |||
623 | num_threads = strtoul(num_threads_arg, NULL, 0); | ||
624 | num_loops = strtoul(num_loops_arg, NULL, 0); | ||
625 | |||
626 | if (!num_threads || !num_loops) { | ||
627 | acpi_os_printf("Bad argument: Threads %X, Loops %X\n", | ||
628 | num_threads, num_loops); | ||
629 | return; | ||
630 | } | ||
631 | |||
632 | /* | ||
633 | * Create the semaphore for synchronization of | ||
634 | * the created threads with the main thread. | ||
635 | */ | ||
636 | status = acpi_os_create_semaphore(1, 0, &main_thread_gate); | ||
637 | if (ACPI_FAILURE(status)) { | ||
638 | acpi_os_printf("Could not create semaphore for " | ||
639 | "synchronization with the main thread, %s\n", | ||
640 | acpi_format_exception(status)); | ||
641 | return; | ||
642 | } | ||
643 | |||
644 | /* | ||
645 | * Create the semaphore for synchronization | ||
646 | * between the created threads. | ||
647 | */ | ||
648 | status = acpi_os_create_semaphore(1, 1, &thread_complete_gate); | ||
649 | if (ACPI_FAILURE(status)) { | ||
650 | acpi_os_printf("Could not create semaphore for " | ||
651 | "synchronization between the created threads, %s\n", | ||
652 | acpi_format_exception(status)); | ||
653 | |||
654 | (void)acpi_os_delete_semaphore(main_thread_gate); | ||
655 | return; | ||
656 | } | ||
657 | |||
658 | status = acpi_os_create_semaphore(1, 1, &info_gate); | ||
659 | if (ACPI_FAILURE(status)) { | ||
660 | acpi_os_printf("Could not create semaphore for " | ||
661 | "synchronization of AcpiGbl_DbMethodInfo, %s\n", | ||
662 | acpi_format_exception(status)); | ||
663 | |||
664 | (void)acpi_os_delete_semaphore(thread_complete_gate); | ||
665 | (void)acpi_os_delete_semaphore(main_thread_gate); | ||
666 | return; | ||
667 | } | ||
668 | |||
669 | memset(&acpi_gbl_db_method_info, 0, sizeof(struct acpi_db_method_info)); | ||
670 | |||
671 | /* Array to store IDs of threads */ | ||
672 | |||
673 | acpi_gbl_db_method_info.num_threads = num_threads; | ||
674 | size = sizeof(acpi_thread_id) * acpi_gbl_db_method_info.num_threads; | ||
675 | |||
676 | acpi_gbl_db_method_info.threads = acpi_os_allocate(size); | ||
677 | if (acpi_gbl_db_method_info.threads == NULL) { | ||
678 | acpi_os_printf("No memory for thread IDs array\n"); | ||
679 | (void)acpi_os_delete_semaphore(main_thread_gate); | ||
680 | (void)acpi_os_delete_semaphore(thread_complete_gate); | ||
681 | (void)acpi_os_delete_semaphore(info_gate); | ||
682 | return; | ||
683 | } | ||
684 | memset(acpi_gbl_db_method_info.threads, 0, size); | ||
685 | |||
686 | /* Setup the context to be passed to each thread */ | ||
687 | |||
688 | acpi_gbl_db_method_info.name = method_name_arg; | ||
689 | acpi_gbl_db_method_info.flags = 0; | ||
690 | acpi_gbl_db_method_info.num_loops = num_loops; | ||
691 | acpi_gbl_db_method_info.main_thread_gate = main_thread_gate; | ||
692 | acpi_gbl_db_method_info.thread_complete_gate = thread_complete_gate; | ||
693 | acpi_gbl_db_method_info.info_gate = info_gate; | ||
694 | |||
695 | /* Init arguments to be passed to method */ | ||
696 | |||
697 | acpi_gbl_db_method_info.init_args = 1; | ||
698 | acpi_gbl_db_method_info.args = acpi_gbl_db_method_info.arguments; | ||
699 | acpi_gbl_db_method_info.arguments[0] = | ||
700 | acpi_gbl_db_method_info.num_threads_str; | ||
701 | acpi_gbl_db_method_info.arguments[1] = | ||
702 | acpi_gbl_db_method_info.id_of_thread_str; | ||
703 | acpi_gbl_db_method_info.arguments[2] = | ||
704 | acpi_gbl_db_method_info.index_of_thread_str; | ||
705 | acpi_gbl_db_method_info.arguments[3] = NULL; | ||
706 | |||
707 | acpi_gbl_db_method_info.types = acpi_gbl_db_method_info.arg_types; | ||
708 | acpi_gbl_db_method_info.arg_types[0] = ACPI_TYPE_INTEGER; | ||
709 | acpi_gbl_db_method_info.arg_types[1] = ACPI_TYPE_INTEGER; | ||
710 | acpi_gbl_db_method_info.arg_types[2] = ACPI_TYPE_INTEGER; | ||
711 | |||
712 | acpi_db_uint32_to_hex_string(num_threads, | ||
713 | acpi_gbl_db_method_info.num_threads_str); | ||
714 | |||
715 | status = acpi_db_execute_setup(&acpi_gbl_db_method_info); | ||
716 | if (ACPI_FAILURE(status)) { | ||
717 | goto cleanup_and_exit; | ||
718 | } | ||
719 | |||
720 | /* Get the NS node, determines existence also */ | ||
721 | |||
722 | status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname, | ||
723 | &acpi_gbl_db_method_info.method); | ||
724 | if (ACPI_FAILURE(status)) { | ||
725 | acpi_os_printf("%s Could not get handle for %s\n", | ||
726 | acpi_format_exception(status), | ||
727 | acpi_gbl_db_method_info.pathname); | ||
728 | goto cleanup_and_exit; | ||
729 | } | ||
730 | |||
731 | /* Create the threads */ | ||
732 | |||
733 | acpi_os_printf("Creating %X threads to execute %X times each\n", | ||
734 | num_threads, num_loops); | ||
735 | |||
736 | for (i = 0; i < (num_threads); i++) { | ||
737 | status = | ||
738 | acpi_os_execute(OSL_DEBUGGER_EXEC_THREAD, | ||
739 | acpi_db_method_thread, | ||
740 | &acpi_gbl_db_method_info); | ||
741 | if (ACPI_FAILURE(status)) { | ||
742 | break; | ||
743 | } | ||
744 | } | ||
745 | |||
746 | /* Wait for all threads to complete */ | ||
747 | |||
748 | (void)acpi_os_wait_semaphore(main_thread_gate, 1, ACPI_WAIT_FOREVER); | ||
749 | |||
750 | acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); | ||
751 | acpi_os_printf("All threads (%X) have completed\n", num_threads); | ||
752 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
753 | |||
754 | cleanup_and_exit: | ||
755 | |||
756 | /* Cleanup and exit */ | ||
757 | |||
758 | (void)acpi_os_delete_semaphore(main_thread_gate); | ||
759 | (void)acpi_os_delete_semaphore(thread_complete_gate); | ||
760 | (void)acpi_os_delete_semaphore(info_gate); | ||
761 | |||
762 | acpi_os_free(acpi_gbl_db_method_info.threads); | ||
763 | acpi_gbl_db_method_info.threads = NULL; | ||
764 | } | ||
diff --git a/drivers/acpi/acpica/dbfileio.c b/drivers/acpi/acpica/dbfileio.c new file mode 100644 index 000000000000..d0e6b20ce82a --- /dev/null +++ b/drivers/acpi/acpica/dbfileio.c | |||
@@ -0,0 +1,256 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbfileio - Debugger file I/O commands. These can't usually | ||
4 | * be used when running the debugger in Ring 0 (Kernel mode) | ||
5 | * | ||
6 | ******************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include "accommon.h" | ||
47 | #include "acdebug.h" | ||
48 | #include "actables.h" | ||
49 | |||
50 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
51 | ACPI_MODULE_NAME("dbfileio") | ||
52 | |||
53 | #ifdef ACPI_DEBUGGER | ||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_db_close_debug_file | ||
57 | * | ||
58 | * PARAMETERS: None | ||
59 | * | ||
60 | * RETURN: None | ||
61 | * | ||
62 | * DESCRIPTION: If open, close the current debug output file | ||
63 | * | ||
64 | ******************************************************************************/ | ||
65 | void acpi_db_close_debug_file(void) | ||
66 | { | ||
67 | |||
68 | #ifdef ACPI_APPLICATION | ||
69 | |||
70 | if (acpi_gbl_debug_file) { | ||
71 | fclose(acpi_gbl_debug_file); | ||
72 | acpi_gbl_debug_file = NULL; | ||
73 | acpi_gbl_db_output_to_file = FALSE; | ||
74 | acpi_os_printf("Debug output file %s closed\n", | ||
75 | acpi_gbl_db_debug_filename); | ||
76 | } | ||
77 | #endif | ||
78 | } | ||
79 | |||
80 | /******************************************************************************* | ||
81 | * | ||
82 | * FUNCTION: acpi_db_open_debug_file | ||
83 | * | ||
84 | * PARAMETERS: name - Filename to open | ||
85 | * | ||
86 | * RETURN: None | ||
87 | * | ||
88 | * DESCRIPTION: Open a file where debug output will be directed. | ||
89 | * | ||
90 | ******************************************************************************/ | ||
91 | |||
92 | void acpi_db_open_debug_file(char *name) | ||
93 | { | ||
94 | |||
95 | #ifdef ACPI_APPLICATION | ||
96 | |||
97 | acpi_db_close_debug_file(); | ||
98 | acpi_gbl_debug_file = fopen(name, "w+"); | ||
99 | if (!acpi_gbl_debug_file) { | ||
100 | acpi_os_printf("Could not open debug file %s\n", name); | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | acpi_os_printf("Debug output file %s opened\n", name); | ||
105 | strncpy(acpi_gbl_db_debug_filename, name, | ||
106 | sizeof(acpi_gbl_db_debug_filename)); | ||
107 | acpi_gbl_db_output_to_file = TRUE; | ||
108 | |||
109 | #endif | ||
110 | } | ||
111 | #endif | ||
112 | |||
113 | #ifdef ACPI_APPLICATION | ||
114 | #include "acapps.h" | ||
115 | |||
116 | /******************************************************************************* | ||
117 | * | ||
118 | * FUNCTION: ae_local_load_table | ||
119 | * | ||
120 | * PARAMETERS: table - pointer to a buffer containing the entire | ||
121 | * table to be loaded | ||
122 | * | ||
123 | * RETURN: Status | ||
124 | * | ||
125 | * DESCRIPTION: This function is called to load a table from the caller's | ||
126 | * buffer. The buffer must contain an entire ACPI Table including | ||
127 | * a valid header. The header fields will be verified, and if it | ||
128 | * is determined that the table is invalid, the call will fail. | ||
129 | * | ||
130 | ******************************************************************************/ | ||
131 | |||
132 | static acpi_status ae_local_load_table(struct acpi_table_header *table) | ||
133 | { | ||
134 | acpi_status status = AE_OK; | ||
135 | |||
136 | ACPI_FUNCTION_TRACE(ae_local_load_table); | ||
137 | |||
138 | #if 0 | ||
139 | /* struct acpi_table_desc table_info; */ | ||
140 | |||
141 | if (!table) { | ||
142 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
143 | } | ||
144 | |||
145 | table_info.pointer = table; | ||
146 | status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL); | ||
147 | if (ACPI_FAILURE(status)) { | ||
148 | return_ACPI_STATUS(status); | ||
149 | } | ||
150 | |||
151 | /* Install the new table into the local data structures */ | ||
152 | |||
153 | status = acpi_tb_init_table_descriptor(&table_info); | ||
154 | if (ACPI_FAILURE(status)) { | ||
155 | if (status == AE_ALREADY_EXISTS) { | ||
156 | |||
157 | /* Table already exists, no error */ | ||
158 | |||
159 | status = AE_OK; | ||
160 | } | ||
161 | |||
162 | /* Free table allocated by acpi_tb_get_table */ | ||
163 | |||
164 | acpi_tb_delete_single_table(&table_info); | ||
165 | return_ACPI_STATUS(status); | ||
166 | } | ||
167 | #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) | ||
168 | |||
169 | status = | ||
170 | acpi_ns_load_table(table_info.installed_desc, acpi_gbl_root_node); | ||
171 | if (ACPI_FAILURE(status)) { | ||
172 | |||
173 | /* Uninstall table and free the buffer */ | ||
174 | |||
175 | acpi_tb_delete_tables_by_type(ACPI_TABLE_ID_DSDT); | ||
176 | return_ACPI_STATUS(status); | ||
177 | } | ||
178 | #endif | ||
179 | #endif | ||
180 | |||
181 | return_ACPI_STATUS(status); | ||
182 | } | ||
183 | #endif | ||
184 | |||
185 | /******************************************************************************* | ||
186 | * | ||
187 | * FUNCTION: acpi_db_get_table_from_file | ||
188 | * | ||
189 | * PARAMETERS: filename - File where table is located | ||
190 | * return_table - Where a pointer to the table is returned | ||
191 | * | ||
192 | * RETURN: Status | ||
193 | * | ||
194 | * DESCRIPTION: Load an ACPI table from a file | ||
195 | * | ||
196 | ******************************************************************************/ | ||
197 | |||
198 | acpi_status | ||
199 | acpi_db_get_table_from_file(char *filename, | ||
200 | struct acpi_table_header **return_table, | ||
201 | u8 must_be_aml_file) | ||
202 | { | ||
203 | #ifdef ACPI_APPLICATION | ||
204 | acpi_status status; | ||
205 | struct acpi_table_header *table; | ||
206 | u8 is_aml_table = TRUE; | ||
207 | |||
208 | status = acpi_ut_read_table_from_file(filename, &table); | ||
209 | if (ACPI_FAILURE(status)) { | ||
210 | return (status); | ||
211 | } | ||
212 | |||
213 | if (must_be_aml_file) { | ||
214 | is_aml_table = acpi_ut_is_aml_table(table); | ||
215 | if (!is_aml_table) { | ||
216 | ACPI_EXCEPTION((AE_INFO, AE_OK, | ||
217 | "Input for -e is not an AML table: " | ||
218 | "\"%4.4s\" (must be DSDT/SSDT)", | ||
219 | table->signature)); | ||
220 | return (AE_TYPE); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | if (is_aml_table) { | ||
225 | |||
226 | /* Attempt to recognize and install the table */ | ||
227 | |||
228 | status = ae_local_load_table(table); | ||
229 | if (ACPI_FAILURE(status)) { | ||
230 | if (status == AE_ALREADY_EXISTS) { | ||
231 | acpi_os_printf | ||
232 | ("Table %4.4s is already installed\n", | ||
233 | table->signature); | ||
234 | } else { | ||
235 | acpi_os_printf("Could not install table, %s\n", | ||
236 | acpi_format_exception(status)); | ||
237 | } | ||
238 | |||
239 | return (status); | ||
240 | } | ||
241 | |||
242 | acpi_tb_print_table_header(0, table); | ||
243 | |||
244 | fprintf(stderr, | ||
245 | "Acpi table [%4.4s] successfully installed and loaded\n", | ||
246 | table->signature); | ||
247 | } | ||
248 | |||
249 | acpi_gbl_acpi_hardware_present = FALSE; | ||
250 | if (return_table) { | ||
251 | *return_table = table; | ||
252 | } | ||
253 | |||
254 | #endif /* ACPI_APPLICATION */ | ||
255 | return (AE_OK); | ||
256 | } | ||
diff --git a/drivers/acpi/acpica/dbhistry.c b/drivers/acpi/acpica/dbhistry.c new file mode 100644 index 000000000000..9c66a9eadd38 --- /dev/null +++ b/drivers/acpi/acpica/dbhistry.c | |||
@@ -0,0 +1,239 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: dbhistry - debugger HISTORY command | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acdebug.h" | ||
47 | |||
48 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
49 | ACPI_MODULE_NAME("dbhistry") | ||
50 | |||
51 | #define HI_NO_HISTORY 0 | ||
52 | #define HI_RECORD_HISTORY 1 | ||
53 | #define HISTORY_SIZE 40 | ||
54 | typedef struct history_info { | ||
55 | char *command; | ||
56 | u32 cmd_num; | ||
57 | |||
58 | } HISTORY_INFO; | ||
59 | |||
60 | static HISTORY_INFO acpi_gbl_history_buffer[HISTORY_SIZE]; | ||
61 | static u16 acpi_gbl_lo_history = 0; | ||
62 | static u16 acpi_gbl_num_history = 0; | ||
63 | static u16 acpi_gbl_next_history_index = 0; | ||
64 | u32 acpi_gbl_next_cmd_num = 1; | ||
65 | |||
66 | /******************************************************************************* | ||
67 | * | ||
68 | * FUNCTION: acpi_db_add_to_history | ||
69 | * | ||
70 | * PARAMETERS: command_line - Command to add | ||
71 | * | ||
72 | * RETURN: None | ||
73 | * | ||
74 | * DESCRIPTION: Add a command line to the history buffer. | ||
75 | * | ||
76 | ******************************************************************************/ | ||
77 | |||
78 | void acpi_db_add_to_history(char *command_line) | ||
79 | { | ||
80 | u16 cmd_len; | ||
81 | u16 buffer_len; | ||
82 | |||
83 | /* Put command into the next available slot */ | ||
84 | |||
85 | cmd_len = (u16)strlen(command_line); | ||
86 | if (!cmd_len) { | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | if (acpi_gbl_history_buffer[acpi_gbl_next_history_index].command != | ||
91 | NULL) { | ||
92 | buffer_len = | ||
93 | (u16) | ||
94 | strlen(acpi_gbl_history_buffer[acpi_gbl_next_history_index]. | ||
95 | command); | ||
96 | |||
97 | if (cmd_len > buffer_len) { | ||
98 | acpi_os_free(acpi_gbl_history_buffer | ||
99 | [acpi_gbl_next_history_index].command); | ||
100 | acpi_gbl_history_buffer[acpi_gbl_next_history_index]. | ||
101 | command = acpi_os_allocate(cmd_len + 1); | ||
102 | } | ||
103 | } else { | ||
104 | acpi_gbl_history_buffer[acpi_gbl_next_history_index].command = | ||
105 | acpi_os_allocate(cmd_len + 1); | ||
106 | } | ||
107 | |||
108 | strcpy(acpi_gbl_history_buffer[acpi_gbl_next_history_index].command, | ||
109 | command_line); | ||
110 | |||
111 | acpi_gbl_history_buffer[acpi_gbl_next_history_index].cmd_num = | ||
112 | acpi_gbl_next_cmd_num; | ||
113 | |||
114 | /* Adjust indexes */ | ||
115 | |||
116 | if ((acpi_gbl_num_history == HISTORY_SIZE) && | ||
117 | (acpi_gbl_next_history_index == acpi_gbl_lo_history)) { | ||
118 | acpi_gbl_lo_history++; | ||
119 | if (acpi_gbl_lo_history >= HISTORY_SIZE) { | ||
120 | acpi_gbl_lo_history = 0; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | acpi_gbl_next_history_index++; | ||
125 | if (acpi_gbl_next_history_index >= HISTORY_SIZE) { | ||
126 | acpi_gbl_next_history_index = 0; | ||
127 | } | ||
128 | |||
129 | acpi_gbl_next_cmd_num++; | ||
130 | if (acpi_gbl_num_history < HISTORY_SIZE) { | ||
131 | acpi_gbl_num_history++; | ||
132 | } | ||
133 | } | ||
134 | |||
135 | /******************************************************************************* | ||
136 | * | ||
137 | * FUNCTION: acpi_db_display_history | ||
138 | * | ||
139 | * PARAMETERS: None | ||
140 | * | ||
141 | * RETURN: None | ||
142 | * | ||
143 | * DESCRIPTION: Display the contents of the history buffer | ||
144 | * | ||
145 | ******************************************************************************/ | ||
146 | |||
147 | void acpi_db_display_history(void) | ||
148 | { | ||
149 | u32 i; | ||
150 | u16 history_index; | ||
151 | |||
152 | history_index = acpi_gbl_lo_history; | ||
153 | |||
154 | /* Dump entire history buffer */ | ||
155 | |||
156 | for (i = 0; i < acpi_gbl_num_history; i++) { | ||
157 | if (acpi_gbl_history_buffer[history_index].command) { | ||
158 | acpi_os_printf("%3ld %s\n", | ||
159 | acpi_gbl_history_buffer[history_index]. | ||
160 | cmd_num, | ||
161 | acpi_gbl_history_buffer[history_index]. | ||
162 | command); | ||
163 | } | ||
164 | |||
165 | history_index++; | ||
166 | if (history_index >= HISTORY_SIZE) { | ||
167 | history_index = 0; | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | |||
172 | /******************************************************************************* | ||
173 | * | ||
174 | * FUNCTION: acpi_db_get_from_history | ||
175 | * | ||
176 | * PARAMETERS: command_num_arg - String containing the number of the | ||
177 | * command to be retrieved | ||
178 | * | ||
179 | * RETURN: Pointer to the retrieved command. Null on error. | ||
180 | * | ||
181 | * DESCRIPTION: Get a command from the history buffer | ||
182 | * | ||
183 | ******************************************************************************/ | ||
184 | |||
185 | char *acpi_db_get_from_history(char *command_num_arg) | ||
186 | { | ||
187 | u32 cmd_num; | ||
188 | |||
189 | if (command_num_arg == NULL) { | ||
190 | cmd_num = acpi_gbl_next_cmd_num - 1; | ||
191 | } | ||
192 | |||
193 | else { | ||
194 | cmd_num = strtoul(command_num_arg, NULL, 0); | ||
195 | } | ||
196 | |||
197 | return (acpi_db_get_history_by_index(cmd_num)); | ||
198 | } | ||
199 | |||
200 | /******************************************************************************* | ||
201 | * | ||
202 | * FUNCTION: acpi_db_get_history_by_index | ||
203 | * | ||
204 | * PARAMETERS: cmd_num - Index of the desired history entry. | ||
205 | * Values are 0...(acpi_gbl_next_cmd_num - 1) | ||
206 | * | ||
207 | * RETURN: Pointer to the retrieved command. Null on error. | ||
208 | * | ||
209 | * DESCRIPTION: Get a command from the history buffer | ||
210 | * | ||
211 | ******************************************************************************/ | ||
212 | |||
213 | char *acpi_db_get_history_by_index(u32 cmd_num) | ||
214 | { | ||
215 | u32 i; | ||
216 | u16 history_index; | ||
217 | |||
218 | /* Search history buffer */ | ||
219 | |||
220 | history_index = acpi_gbl_lo_history; | ||
221 | for (i = 0; i < acpi_gbl_num_history; i++) { | ||
222 | if (acpi_gbl_history_buffer[history_index].cmd_num == cmd_num) { | ||
223 | |||
224 | /* Found the command, return it */ | ||
225 | |||
226 | return (acpi_gbl_history_buffer[history_index].command); | ||
227 | } | ||
228 | |||
229 | /* History buffer is circular */ | ||
230 | |||
231 | history_index++; | ||
232 | if (history_index >= HISTORY_SIZE) { | ||
233 | history_index = 0; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | acpi_os_printf("Invalid history number: %u\n", history_index); | ||
238 | return (NULL); | ||
239 | } | ||
diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c new file mode 100644 index 000000000000..0480254437f1 --- /dev/null +++ b/drivers/acpi/acpica/dbinput.c | |||
@@ -0,0 +1,1267 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbinput - user front-end to the AML debugger | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acdebug.h" | ||
47 | |||
48 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
49 | ACPI_MODULE_NAME("dbinput") | ||
50 | |||
51 | /* Local prototypes */ | ||
52 | static u32 acpi_db_get_line(char *input_buffer); | ||
53 | |||
54 | static u32 acpi_db_match_command(char *user_command); | ||
55 | |||
56 | static void acpi_db_single_thread(void); | ||
57 | |||
58 | static void acpi_db_display_command_info(char *command, u8 display_all); | ||
59 | |||
60 | static void acpi_db_display_help(char *command); | ||
61 | |||
62 | static u8 | ||
63 | acpi_db_match_command_help(char *command, | ||
64 | const struct acpi_db_command_help *help); | ||
65 | |||
66 | /* | ||
67 | * Top-level debugger commands. | ||
68 | * | ||
69 | * This list of commands must match the string table below it | ||
70 | */ | ||
71 | enum acpi_ex_debugger_commands { | ||
72 | CMD_NOT_FOUND = 0, | ||
73 | CMD_NULL, | ||
74 | CMD_ALLOCATIONS, | ||
75 | CMD_ARGS, | ||
76 | CMD_ARGUMENTS, | ||
77 | CMD_BREAKPOINT, | ||
78 | CMD_BUSINFO, | ||
79 | CMD_CALL, | ||
80 | CMD_DEBUG, | ||
81 | CMD_DISASSEMBLE, | ||
82 | CMD_DISASM, | ||
83 | CMD_DUMP, | ||
84 | CMD_EVALUATE, | ||
85 | CMD_EXECUTE, | ||
86 | CMD_EXIT, | ||
87 | CMD_FIND, | ||
88 | CMD_GO, | ||
89 | CMD_HANDLERS, | ||
90 | CMD_HELP, | ||
91 | CMD_HELP2, | ||
92 | CMD_HISTORY, | ||
93 | CMD_HISTORY_EXE, | ||
94 | CMD_HISTORY_LAST, | ||
95 | CMD_INFORMATION, | ||
96 | CMD_INTEGRITY, | ||
97 | CMD_INTO, | ||
98 | CMD_LEVEL, | ||
99 | CMD_LIST, | ||
100 | CMD_LOCALS, | ||
101 | CMD_LOCKS, | ||
102 | CMD_METHODS, | ||
103 | CMD_NAMESPACE, | ||
104 | CMD_NOTIFY, | ||
105 | CMD_OBJECTS, | ||
106 | CMD_OSI, | ||
107 | CMD_OWNER, | ||
108 | CMD_PATHS, | ||
109 | CMD_PREDEFINED, | ||
110 | CMD_PREFIX, | ||
111 | CMD_QUIT, | ||
112 | CMD_REFERENCES, | ||
113 | CMD_RESOURCES, | ||
114 | CMD_RESULTS, | ||
115 | CMD_SET, | ||
116 | CMD_STATS, | ||
117 | CMD_STOP, | ||
118 | CMD_TABLES, | ||
119 | CMD_TEMPLATE, | ||
120 | CMD_TRACE, | ||
121 | CMD_TREE, | ||
122 | CMD_TYPE, | ||
123 | #ifdef ACPI_APPLICATION | ||
124 | CMD_ENABLEACPI, | ||
125 | CMD_EVENT, | ||
126 | CMD_GPE, | ||
127 | CMD_GPES, | ||
128 | CMD_SCI, | ||
129 | CMD_SLEEP, | ||
130 | |||
131 | CMD_CLOSE, | ||
132 | CMD_LOAD, | ||
133 | CMD_OPEN, | ||
134 | CMD_UNLOAD, | ||
135 | |||
136 | CMD_TERMINATE, | ||
137 | CMD_THREADS, | ||
138 | |||
139 | CMD_TEST, | ||
140 | #endif | ||
141 | }; | ||
142 | |||
143 | #define CMD_FIRST_VALID 2 | ||
144 | |||
145 | /* Second parameter is the required argument count */ | ||
146 | |||
147 | static const struct acpi_db_command_info acpi_gbl_db_commands[] = { | ||
148 | {"<NOT FOUND>", 0}, | ||
149 | {"<NULL>", 0}, | ||
150 | {"ALLOCATIONS", 0}, | ||
151 | {"ARGS", 0}, | ||
152 | {"ARGUMENTS", 0}, | ||
153 | {"BREAKPOINT", 1}, | ||
154 | {"BUSINFO", 0}, | ||
155 | {"CALL", 0}, | ||
156 | {"DEBUG", 1}, | ||
157 | {"DISASSEMBLE", 1}, | ||
158 | {"DISASM", 1}, | ||
159 | {"DUMP", 1}, | ||
160 | {"EVALUATE", 1}, | ||
161 | {"EXECUTE", 1}, | ||
162 | {"EXIT", 0}, | ||
163 | {"FIND", 1}, | ||
164 | {"GO", 0}, | ||
165 | {"HANDLERS", 0}, | ||
166 | {"HELP", 0}, | ||
167 | {"?", 0}, | ||
168 | {"HISTORY", 0}, | ||
169 | {"!", 1}, | ||
170 | {"!!", 0}, | ||
171 | {"INFORMATION", 0}, | ||
172 | {"INTEGRITY", 0}, | ||
173 | {"INTO", 0}, | ||
174 | {"LEVEL", 0}, | ||
175 | {"LIST", 0}, | ||
176 | {"LOCALS", 0}, | ||
177 | {"LOCKS", 0}, | ||
178 | {"METHODS", 0}, | ||
179 | {"NAMESPACE", 0}, | ||
180 | {"NOTIFY", 2}, | ||
181 | {"OBJECTS", 0}, | ||
182 | {"OSI", 0}, | ||
183 | {"OWNER", 1}, | ||
184 | {"PATHS", 0}, | ||
185 | {"PREDEFINED", 0}, | ||
186 | {"PREFIX", 0}, | ||
187 | {"QUIT", 0}, | ||
188 | {"REFERENCES", 1}, | ||
189 | {"RESOURCES", 0}, | ||
190 | {"RESULTS", 0}, | ||
191 | {"SET", 3}, | ||
192 | {"STATS", 1}, | ||
193 | {"STOP", 0}, | ||
194 | {"TABLES", 0}, | ||
195 | {"TEMPLATE", 1}, | ||
196 | {"TRACE", 1}, | ||
197 | {"TREE", 0}, | ||
198 | {"TYPE", 1}, | ||
199 | #ifdef ACPI_APPLICATION | ||
200 | {"ENABLEACPI", 0}, | ||
201 | {"EVENT", 1}, | ||
202 | {"GPE", 1}, | ||
203 | {"GPES", 0}, | ||
204 | {"SCI", 0}, | ||
205 | {"SLEEP", 0}, | ||
206 | |||
207 | {"CLOSE", 0}, | ||
208 | {"LOAD", 1}, | ||
209 | {"OPEN", 1}, | ||
210 | {"UNLOAD", 1}, | ||
211 | |||
212 | {"TERMINATE", 0}, | ||
213 | {"THREADS", 3}, | ||
214 | |||
215 | {"TEST", 1}, | ||
216 | #endif | ||
217 | {NULL, 0} | ||
218 | }; | ||
219 | |||
220 | /* | ||
221 | * Help for all debugger commands. First argument is the number of lines | ||
222 | * of help to output for the command. | ||
223 | */ | ||
224 | static const struct acpi_db_command_help acpi_gbl_db_command_help[] = { | ||
225 | {0, "\nGeneral-Purpose Commands:", "\n"}, | ||
226 | {1, " Allocations", "Display list of current memory allocations\n"}, | ||
227 | {2, " Dump <Address>|<Namepath>", "\n"}, | ||
228 | {0, " [Byte|Word|Dword|Qword]", | ||
229 | "Display ACPI objects or memory\n"}, | ||
230 | {1, " Handlers", "Info about global handlers\n"}, | ||
231 | {1, " Help [Command]", "This help screen or individual command\n"}, | ||
232 | {1, " History", "Display command history buffer\n"}, | ||
233 | {1, " Level <DebugLevel>] [console]", | ||
234 | "Get/Set debug level for file or console\n"}, | ||
235 | {1, " Locks", "Current status of internal mutexes\n"}, | ||
236 | {1, " Osi [Install|Remove <name>]", | ||
237 | "Display or modify global _OSI list\n"}, | ||
238 | {1, " Quit or Exit", "Exit this command\n"}, | ||
239 | {8, " Stats <SubCommand>", | ||
240 | "Display namespace and memory statistics\n"}, | ||
241 | {1, " Allocations", "Display list of current memory allocations\n"}, | ||
242 | {1, " Memory", "Dump internal memory lists\n"}, | ||
243 | {1, " Misc", "Namespace search and mutex stats\n"}, | ||
244 | {1, " Objects", "Summary of namespace objects\n"}, | ||
245 | {1, " Sizes", "Sizes for each of the internal objects\n"}, | ||
246 | {1, " Stack", "Display CPU stack usage\n"}, | ||
247 | {1, " Tables", "Info about current ACPI table(s)\n"}, | ||
248 | {1, " Tables", "Display info about loaded ACPI tables\n"}, | ||
249 | {1, " ! <CommandNumber>", "Execute command from history buffer\n"}, | ||
250 | {1, " !!", "Execute last command again\n"}, | ||
251 | |||
252 | {0, "\nNamespace Access Commands:", "\n"}, | ||
253 | {1, " Businfo", "Display system bus info\n"}, | ||
254 | {1, " Disassemble <Method>", "Disassemble a control method\n"}, | ||
255 | {1, " Find <AcpiName> (? is wildcard)", | ||
256 | "Find ACPI name(s) with wildcards\n"}, | ||
257 | {1, " Integrity", "Validate namespace integrity\n"}, | ||
258 | {1, " Methods", "Display list of loaded control methods\n"}, | ||
259 | {1, " Namespace [Object] [Depth]", | ||
260 | "Display loaded namespace tree/subtree\n"}, | ||
261 | {1, " Notify <Object> <Value>", "Send a notification on Object\n"}, | ||
262 | {1, " Objects [ObjectType]", | ||
263 | "Display summary of all objects or just given type\n"}, | ||
264 | {1, " Owner <OwnerId> [Depth]", | ||
265 | "Display loaded namespace by object owner\n"}, | ||
266 | {1, " Paths", "Display full pathnames of namespace objects\n"}, | ||
267 | {1, " Predefined", "Check all predefined names\n"}, | ||
268 | {1, " Prefix [<Namepath>]", "Set or Get current execution prefix\n"}, | ||
269 | {1, " References <Addr>", "Find all references to object at addr\n"}, | ||
270 | {1, " Resources [DeviceName]", | ||
271 | "Display Device resources (no arg = all devices)\n"}, | ||
272 | {1, " Set N <NamedObject> <Value>", "Set value for named integer\n"}, | ||
273 | {1, " Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"}, | ||
274 | {1, " Type <Object>", "Display object type\n"}, | ||
275 | |||
276 | {0, "\nControl Method Execution Commands:", "\n"}, | ||
277 | {1, " Arguments (or Args)", "Display method arguments\n"}, | ||
278 | {1, " Breakpoint <AmlOffset>", "Set an AML execution breakpoint\n"}, | ||
279 | {1, " Call", "Run to next control method invocation\n"}, | ||
280 | {1, " Debug <Namepath> [Arguments]", "Single Step a control method\n"}, | ||
281 | {6, " Evaluate", "Synonym for Execute\n"}, | ||
282 | {5, " Execute <Namepath> [Arguments]", "Execute control method\n"}, | ||
283 | {1, " Hex Integer", "Integer method argument\n"}, | ||
284 | {1, " \"Ascii String\"", "String method argument\n"}, | ||
285 | {1, " (Hex Byte List)", "Buffer method argument\n"}, | ||
286 | {1, " [Package Element List]", "Package method argument\n"}, | ||
287 | {1, " Go", "Allow method to run to completion\n"}, | ||
288 | {1, " Information", "Display info about the current method\n"}, | ||
289 | {1, " Into", "Step into (not over) a method call\n"}, | ||
290 | {1, " List [# of Aml Opcodes]", "Display method ASL statements\n"}, | ||
291 | {1, " Locals", "Display method local variables\n"}, | ||
292 | {1, " Results", "Display method result stack\n"}, | ||
293 | {1, " Set <A|L> <#> <Value>", "Set method data (Arguments/Locals)\n"}, | ||
294 | {1, " Stop", "Terminate control method\n"}, | ||
295 | {5, " Trace <State> [<Namepath>] [Once]", | ||
296 | "Trace control method execution\n"}, | ||
297 | {1, " Enable", "Enable all messages\n"}, | ||
298 | {1, " Disable", "Disable tracing\n"}, | ||
299 | {1, " Method", "Enable method execution messages\n"}, | ||
300 | {1, " Opcode", "Enable opcode execution messages\n"}, | ||
301 | {1, " Tree", "Display control method calling tree\n"}, | ||
302 | {1, " <Enter>", "Single step next AML opcode (over calls)\n"}, | ||
303 | |||
304 | #ifdef ACPI_APPLICATION | ||
305 | {0, "\nHardware Simulation Commands:", "\n"}, | ||
306 | {1, " EnableAcpi", "Enable ACPI (hardware) mode\n"}, | ||
307 | {1, " Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"}, | ||
308 | {1, " Gpe <GpeNum> [GpeBlockDevice]", "Simulate a GPE\n"}, | ||
309 | {1, " Gpes", "Display info on all GPE devices\n"}, | ||
310 | {1, " Sci", "Generate an SCI\n"}, | ||
311 | {1, " Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"}, | ||
312 | |||
313 | {0, "\nFile I/O Commands:", "\n"}, | ||
314 | {1, " Close", "Close debug output file\n"}, | ||
315 | {1, " Load <Input Filename>", "Load ACPI table from a file\n"}, | ||
316 | {1, " Open <Output Filename>", "Open a file for debug output\n"}, | ||
317 | {1, " Unload <Namepath>", | ||
318 | "Unload an ACPI table via namespace object\n"}, | ||
319 | |||
320 | {0, "\nUser Space Commands:", "\n"}, | ||
321 | {1, " Terminate", "Delete namespace and all internal objects\n"}, | ||
322 | {1, " Thread <Threads><Loops><NamePath>", | ||
323 | "Spawn threads to execute method(s)\n"}, | ||
324 | |||
325 | {0, "\nDebug Test Commands:", "\n"}, | ||
326 | {3, " Test <TestName>", "Invoke a debug test\n"}, | ||
327 | {1, " Objects", "Read/write/compare all namespace data objects\n"}, | ||
328 | {1, " Predefined", | ||
329 | "Execute all ACPI predefined names (_STA, etc.)\n"}, | ||
330 | #endif | ||
331 | {0, NULL, NULL} | ||
332 | }; | ||
333 | |||
334 | /******************************************************************************* | ||
335 | * | ||
336 | * FUNCTION: acpi_db_match_command_help | ||
337 | * | ||
338 | * PARAMETERS: command - Command string to match | ||
339 | * help - Help table entry to attempt match | ||
340 | * | ||
341 | * RETURN: TRUE if command matched, FALSE otherwise | ||
342 | * | ||
343 | * DESCRIPTION: Attempt to match a command in the help table in order to | ||
344 | * print help information for a single command. | ||
345 | * | ||
346 | ******************************************************************************/ | ||
347 | |||
348 | static u8 | ||
349 | acpi_db_match_command_help(char *command, | ||
350 | const struct acpi_db_command_help *help) | ||
351 | { | ||
352 | char *invocation = help->invocation; | ||
353 | u32 line_count; | ||
354 | |||
355 | /* Valid commands in the help table begin with a couple of spaces */ | ||
356 | |||
357 | if (*invocation != ' ') { | ||
358 | return (FALSE); | ||
359 | } | ||
360 | |||
361 | while (*invocation == ' ') { | ||
362 | invocation++; | ||
363 | } | ||
364 | |||
365 | /* Match command name (full command or substring) */ | ||
366 | |||
367 | while ((*command) && (*invocation) && (*invocation != ' ')) { | ||
368 | if (tolower((int)*command) != tolower((int)*invocation)) { | ||
369 | return (FALSE); | ||
370 | } | ||
371 | |||
372 | invocation++; | ||
373 | command++; | ||
374 | } | ||
375 | |||
376 | /* Print the appropriate number of help lines */ | ||
377 | |||
378 | line_count = help->line_count; | ||
379 | while (line_count) { | ||
380 | acpi_os_printf("%-38s : %s", help->invocation, | ||
381 | help->description); | ||
382 | help++; | ||
383 | line_count--; | ||
384 | } | ||
385 | |||
386 | return (TRUE); | ||
387 | } | ||
388 | |||
389 | /******************************************************************************* | ||
390 | * | ||
391 | * FUNCTION: acpi_db_display_command_info | ||
392 | * | ||
393 | * PARAMETERS: command - Command string to match | ||
394 | * display_all - Display all matching commands, or just | ||
395 | * the first one (substring match) | ||
396 | * | ||
397 | * RETURN: None | ||
398 | * | ||
399 | * DESCRIPTION: Display help information for a Debugger command. | ||
400 | * | ||
401 | ******************************************************************************/ | ||
402 | |||
403 | static void acpi_db_display_command_info(char *command, u8 display_all) | ||
404 | { | ||
405 | const struct acpi_db_command_help *next; | ||
406 | u8 matched; | ||
407 | |||
408 | next = acpi_gbl_db_command_help; | ||
409 | while (next->invocation) { | ||
410 | matched = acpi_db_match_command_help(command, next); | ||
411 | if (!display_all && matched) { | ||
412 | return; | ||
413 | } | ||
414 | |||
415 | next++; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | /******************************************************************************* | ||
420 | * | ||
421 | * FUNCTION: acpi_db_display_help | ||
422 | * | ||
423 | * PARAMETERS: command - Optional command string to display help. | ||
424 | * if not specified, all debugger command | ||
425 | * help strings are displayed | ||
426 | * | ||
427 | * RETURN: None | ||
428 | * | ||
429 | * DESCRIPTION: Display help for a single debugger command, or all of them. | ||
430 | * | ||
431 | ******************************************************************************/ | ||
432 | |||
433 | static void acpi_db_display_help(char *command) | ||
434 | { | ||
435 | const struct acpi_db_command_help *next = acpi_gbl_db_command_help; | ||
436 | |||
437 | if (!command) { | ||
438 | |||
439 | /* No argument to help, display help for all commands */ | ||
440 | |||
441 | while (next->invocation) { | ||
442 | acpi_os_printf("%-38s%s", next->invocation, | ||
443 | next->description); | ||
444 | next++; | ||
445 | } | ||
446 | } else { | ||
447 | /* Display help for all commands that match the subtring */ | ||
448 | |||
449 | acpi_db_display_command_info(command, TRUE); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | /******************************************************************************* | ||
454 | * | ||
455 | * FUNCTION: acpi_db_get_next_token | ||
456 | * | ||
457 | * PARAMETERS: string - Command buffer | ||
458 | * next - Return value, end of next token | ||
459 | * | ||
460 | * RETURN: Pointer to the start of the next token. | ||
461 | * | ||
462 | * DESCRIPTION: Command line parsing. Get the next token on the command line | ||
463 | * | ||
464 | ******************************************************************************/ | ||
465 | |||
466 | char *acpi_db_get_next_token(char *string, | ||
467 | char **next, acpi_object_type * return_type) | ||
468 | { | ||
469 | char *start; | ||
470 | u32 depth; | ||
471 | acpi_object_type type = ACPI_TYPE_INTEGER; | ||
472 | |||
473 | /* At end of buffer? */ | ||
474 | |||
475 | if (!string || !(*string)) { | ||
476 | return (NULL); | ||
477 | } | ||
478 | |||
479 | /* Remove any spaces at the beginning */ | ||
480 | |||
481 | if (*string == ' ') { | ||
482 | while (*string && (*string == ' ')) { | ||
483 | string++; | ||
484 | } | ||
485 | |||
486 | if (!(*string)) { | ||
487 | return (NULL); | ||
488 | } | ||
489 | } | ||
490 | |||
491 | switch (*string) { | ||
492 | case '"': | ||
493 | |||
494 | /* This is a quoted string, scan until closing quote */ | ||
495 | |||
496 | string++; | ||
497 | start = string; | ||
498 | type = ACPI_TYPE_STRING; | ||
499 | |||
500 | /* Find end of string */ | ||
501 | |||
502 | while (*string && (*string != '"')) { | ||
503 | string++; | ||
504 | } | ||
505 | break; | ||
506 | |||
507 | case '(': | ||
508 | |||
509 | /* This is the start of a buffer, scan until closing paren */ | ||
510 | |||
511 | string++; | ||
512 | start = string; | ||
513 | type = ACPI_TYPE_BUFFER; | ||
514 | |||
515 | /* Find end of buffer */ | ||
516 | |||
517 | while (*string && (*string != ')')) { | ||
518 | string++; | ||
519 | } | ||
520 | break; | ||
521 | |||
522 | case '[': | ||
523 | |||
524 | /* This is the start of a package, scan until closing bracket */ | ||
525 | |||
526 | string++; | ||
527 | depth = 1; | ||
528 | start = string; | ||
529 | type = ACPI_TYPE_PACKAGE; | ||
530 | |||
531 | /* Find end of package (closing bracket) */ | ||
532 | |||
533 | while (*string) { | ||
534 | |||
535 | /* Handle String package elements */ | ||
536 | |||
537 | if (*string == '"') { | ||
538 | /* Find end of string */ | ||
539 | |||
540 | string++; | ||
541 | while (*string && (*string != '"')) { | ||
542 | string++; | ||
543 | } | ||
544 | if (!(*string)) { | ||
545 | break; | ||
546 | } | ||
547 | } else if (*string == '[') { | ||
548 | depth++; /* A nested package declaration */ | ||
549 | } else if (*string == ']') { | ||
550 | depth--; | ||
551 | if (depth == 0) { /* Found final package closing bracket */ | ||
552 | break; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | string++; | ||
557 | } | ||
558 | break; | ||
559 | |||
560 | default: | ||
561 | |||
562 | start = string; | ||
563 | |||
564 | /* Find end of token */ | ||
565 | |||
566 | while (*string && (*string != ' ')) { | ||
567 | string++; | ||
568 | } | ||
569 | break; | ||
570 | } | ||
571 | |||
572 | if (!(*string)) { | ||
573 | *next = NULL; | ||
574 | } else { | ||
575 | *string = 0; | ||
576 | *next = string + 1; | ||
577 | } | ||
578 | |||
579 | *return_type = type; | ||
580 | return (start); | ||
581 | } | ||
582 | |||
583 | /******************************************************************************* | ||
584 | * | ||
585 | * FUNCTION: acpi_db_get_line | ||
586 | * | ||
587 | * PARAMETERS: input_buffer - Command line buffer | ||
588 | * | ||
589 | * RETURN: Count of arguments to the command | ||
590 | * | ||
591 | * DESCRIPTION: Get the next command line from the user. Gets entire line | ||
592 | * up to the next newline | ||
593 | * | ||
594 | ******************************************************************************/ | ||
595 | |||
596 | static u32 acpi_db_get_line(char *input_buffer) | ||
597 | { | ||
598 | u32 i; | ||
599 | u32 count; | ||
600 | char *next; | ||
601 | char *this; | ||
602 | |||
603 | if (acpi_ut_safe_strcpy | ||
604 | (acpi_gbl_db_parsed_buf, sizeof(acpi_gbl_db_parsed_buf), | ||
605 | input_buffer)) { | ||
606 | acpi_os_printf | ||
607 | ("Buffer overflow while parsing input line (max %u characters)\n", | ||
608 | sizeof(acpi_gbl_db_parsed_buf)); | ||
609 | return (0); | ||
610 | } | ||
611 | |||
612 | this = acpi_gbl_db_parsed_buf; | ||
613 | for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++) { | ||
614 | acpi_gbl_db_args[i] = acpi_db_get_next_token(this, &next, | ||
615 | &acpi_gbl_db_arg_types | ||
616 | [i]); | ||
617 | if (!acpi_gbl_db_args[i]) { | ||
618 | break; | ||
619 | } | ||
620 | |||
621 | this = next; | ||
622 | } | ||
623 | |||
624 | /* Uppercase the actual command */ | ||
625 | |||
626 | if (acpi_gbl_db_args[0]) { | ||
627 | acpi_ut_strupr(acpi_gbl_db_args[0]); | ||
628 | } | ||
629 | |||
630 | count = i; | ||
631 | if (count) { | ||
632 | count--; /* Number of args only */ | ||
633 | } | ||
634 | |||
635 | return (count); | ||
636 | } | ||
637 | |||
638 | /******************************************************************************* | ||
639 | * | ||
640 | * FUNCTION: acpi_db_match_command | ||
641 | * | ||
642 | * PARAMETERS: user_command - User command line | ||
643 | * | ||
644 | * RETURN: Index into command array, -1 if not found | ||
645 | * | ||
646 | * DESCRIPTION: Search command array for a command match | ||
647 | * | ||
648 | ******************************************************************************/ | ||
649 | |||
650 | static u32 acpi_db_match_command(char *user_command) | ||
651 | { | ||
652 | u32 i; | ||
653 | |||
654 | if (!user_command || user_command[0] == 0) { | ||
655 | return (CMD_NULL); | ||
656 | } | ||
657 | |||
658 | for (i = CMD_FIRST_VALID; acpi_gbl_db_commands[i].name; i++) { | ||
659 | if (strstr(acpi_gbl_db_commands[i].name, user_command) == | ||
660 | acpi_gbl_db_commands[i].name) { | ||
661 | return (i); | ||
662 | } | ||
663 | } | ||
664 | |||
665 | /* Command not recognized */ | ||
666 | |||
667 | return (CMD_NOT_FOUND); | ||
668 | } | ||
669 | |||
670 | /******************************************************************************* | ||
671 | * | ||
672 | * FUNCTION: acpi_db_command_dispatch | ||
673 | * | ||
674 | * PARAMETERS: input_buffer - Command line buffer | ||
675 | * walk_state - Current walk | ||
676 | * op - Current (executing) parse op | ||
677 | * | ||
678 | * RETURN: Status | ||
679 | * | ||
680 | * DESCRIPTION: Command dispatcher. | ||
681 | * | ||
682 | ******************************************************************************/ | ||
683 | |||
684 | acpi_status | ||
685 | acpi_db_command_dispatch(char *input_buffer, | ||
686 | struct acpi_walk_state * walk_state, | ||
687 | union acpi_parse_object * op) | ||
688 | { | ||
689 | u32 temp; | ||
690 | u32 command_index; | ||
691 | u32 param_count; | ||
692 | char *command_line; | ||
693 | acpi_status status = AE_CTRL_TRUE; | ||
694 | |||
695 | /* If acpi_terminate has been called, terminate this thread */ | ||
696 | |||
697 | if (acpi_gbl_db_terminate_loop) { | ||
698 | return (AE_CTRL_TERMINATE); | ||
699 | } | ||
700 | |||
701 | /* Find command and add to the history buffer */ | ||
702 | |||
703 | param_count = acpi_db_get_line(input_buffer); | ||
704 | command_index = acpi_db_match_command(acpi_gbl_db_args[0]); | ||
705 | temp = 0; | ||
706 | |||
707 | /* | ||
708 | * We don't want to add the !! command to the history buffer. It | ||
709 | * would cause an infinite loop because it would always be the | ||
710 | * previous command. | ||
711 | */ | ||
712 | if (command_index != CMD_HISTORY_LAST) { | ||
713 | acpi_db_add_to_history(input_buffer); | ||
714 | } | ||
715 | |||
716 | /* Verify that we have the minimum number of params */ | ||
717 | |||
718 | if (param_count < acpi_gbl_db_commands[command_index].min_args) { | ||
719 | acpi_os_printf | ||
720 | ("%u parameters entered, [%s] requires %u parameters\n", | ||
721 | param_count, acpi_gbl_db_commands[command_index].name, | ||
722 | acpi_gbl_db_commands[command_index].min_args); | ||
723 | |||
724 | acpi_db_display_command_info(acpi_gbl_db_commands | ||
725 | [command_index].name, FALSE); | ||
726 | return (AE_CTRL_TRUE); | ||
727 | } | ||
728 | |||
729 | /* Decode and dispatch the command */ | ||
730 | |||
731 | switch (command_index) { | ||
732 | case CMD_NULL: | ||
733 | |||
734 | if (op) { | ||
735 | return (AE_OK); | ||
736 | } | ||
737 | break; | ||
738 | |||
739 | case CMD_ALLOCATIONS: | ||
740 | |||
741 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
742 | acpi_ut_dump_allocations((u32)-1, NULL); | ||
743 | #endif | ||
744 | break; | ||
745 | |||
746 | case CMD_ARGS: | ||
747 | case CMD_ARGUMENTS: | ||
748 | |||
749 | acpi_db_display_arguments(); | ||
750 | break; | ||
751 | |||
752 | case CMD_BREAKPOINT: | ||
753 | |||
754 | acpi_db_set_method_breakpoint(acpi_gbl_db_args[1], walk_state, | ||
755 | op); | ||
756 | break; | ||
757 | |||
758 | case CMD_BUSINFO: | ||
759 | |||
760 | acpi_db_get_bus_info(); | ||
761 | break; | ||
762 | |||
763 | case CMD_CALL: | ||
764 | |||
765 | acpi_db_set_method_call_breakpoint(op); | ||
766 | status = AE_OK; | ||
767 | break; | ||
768 | |||
769 | case CMD_DEBUG: | ||
770 | |||
771 | acpi_db_execute(acpi_gbl_db_args[1], | ||
772 | &acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2], | ||
773 | EX_SINGLE_STEP); | ||
774 | break; | ||
775 | |||
776 | case CMD_DISASSEMBLE: | ||
777 | case CMD_DISASM: | ||
778 | |||
779 | (void)acpi_db_disassemble_method(acpi_gbl_db_args[1]); | ||
780 | break; | ||
781 | |||
782 | case CMD_DUMP: | ||
783 | |||
784 | acpi_db_decode_and_display_object(acpi_gbl_db_args[1], | ||
785 | acpi_gbl_db_args[2]); | ||
786 | break; | ||
787 | |||
788 | case CMD_EVALUATE: | ||
789 | case CMD_EXECUTE: | ||
790 | |||
791 | acpi_db_execute(acpi_gbl_db_args[1], | ||
792 | &acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2], | ||
793 | EX_NO_SINGLE_STEP); | ||
794 | break; | ||
795 | |||
796 | case CMD_FIND: | ||
797 | |||
798 | status = acpi_db_find_name_in_namespace(acpi_gbl_db_args[1]); | ||
799 | break; | ||
800 | |||
801 | case CMD_GO: | ||
802 | |||
803 | acpi_gbl_cm_single_step = FALSE; | ||
804 | return (AE_OK); | ||
805 | |||
806 | case CMD_HANDLERS: | ||
807 | |||
808 | acpi_db_display_handlers(); | ||
809 | break; | ||
810 | |||
811 | case CMD_HELP: | ||
812 | case CMD_HELP2: | ||
813 | |||
814 | acpi_db_display_help(acpi_gbl_db_args[1]); | ||
815 | break; | ||
816 | |||
817 | case CMD_HISTORY: | ||
818 | |||
819 | acpi_db_display_history(); | ||
820 | break; | ||
821 | |||
822 | case CMD_HISTORY_EXE: /* ! command */ | ||
823 | |||
824 | command_line = acpi_db_get_from_history(acpi_gbl_db_args[1]); | ||
825 | if (!command_line) { | ||
826 | return (AE_CTRL_TRUE); | ||
827 | } | ||
828 | |||
829 | status = acpi_db_command_dispatch(command_line, walk_state, op); | ||
830 | return (status); | ||
831 | |||
832 | case CMD_HISTORY_LAST: /* !! command */ | ||
833 | |||
834 | command_line = acpi_db_get_from_history(NULL); | ||
835 | if (!command_line) { | ||
836 | return (AE_CTRL_TRUE); | ||
837 | } | ||
838 | |||
839 | status = acpi_db_command_dispatch(command_line, walk_state, op); | ||
840 | return (status); | ||
841 | |||
842 | case CMD_INFORMATION: | ||
843 | |||
844 | acpi_db_display_method_info(op); | ||
845 | break; | ||
846 | |||
847 | case CMD_INTEGRITY: | ||
848 | |||
849 | acpi_db_check_integrity(); | ||
850 | break; | ||
851 | |||
852 | case CMD_INTO: | ||
853 | |||
854 | if (op) { | ||
855 | acpi_gbl_cm_single_step = TRUE; | ||
856 | return (AE_OK); | ||
857 | } | ||
858 | break; | ||
859 | |||
860 | case CMD_LEVEL: | ||
861 | |||
862 | if (param_count == 0) { | ||
863 | acpi_os_printf | ||
864 | ("Current debug level for file output is: %8.8lX\n", | ||
865 | acpi_gbl_db_debug_level); | ||
866 | acpi_os_printf | ||
867 | ("Current debug level for console output is: %8.8lX\n", | ||
868 | acpi_gbl_db_console_debug_level); | ||
869 | } else if (param_count == 2) { | ||
870 | temp = acpi_gbl_db_console_debug_level; | ||
871 | acpi_gbl_db_console_debug_level = | ||
872 | strtoul(acpi_gbl_db_args[1], NULL, 16); | ||
873 | acpi_os_printf | ||
874 | ("Debug Level for console output was %8.8lX, now %8.8lX\n", | ||
875 | temp, acpi_gbl_db_console_debug_level); | ||
876 | } else { | ||
877 | temp = acpi_gbl_db_debug_level; | ||
878 | acpi_gbl_db_debug_level = | ||
879 | strtoul(acpi_gbl_db_args[1], NULL, 16); | ||
880 | acpi_os_printf | ||
881 | ("Debug Level for file output was %8.8lX, now %8.8lX\n", | ||
882 | temp, acpi_gbl_db_debug_level); | ||
883 | } | ||
884 | break; | ||
885 | |||
886 | case CMD_LIST: | ||
887 | |||
888 | acpi_db_disassemble_aml(acpi_gbl_db_args[1], op); | ||
889 | break; | ||
890 | |||
891 | case CMD_LOCKS: | ||
892 | |||
893 | acpi_db_display_locks(); | ||
894 | break; | ||
895 | |||
896 | case CMD_LOCALS: | ||
897 | |||
898 | acpi_db_display_locals(); | ||
899 | break; | ||
900 | |||
901 | case CMD_METHODS: | ||
902 | |||
903 | status = acpi_db_display_objects("METHOD", acpi_gbl_db_args[1]); | ||
904 | break; | ||
905 | |||
906 | case CMD_NAMESPACE: | ||
907 | |||
908 | acpi_db_dump_namespace(acpi_gbl_db_args[1], | ||
909 | acpi_gbl_db_args[2]); | ||
910 | break; | ||
911 | |||
912 | case CMD_NOTIFY: | ||
913 | |||
914 | temp = strtoul(acpi_gbl_db_args[2], NULL, 0); | ||
915 | acpi_db_send_notify(acpi_gbl_db_args[1], temp); | ||
916 | break; | ||
917 | |||
918 | case CMD_OBJECTS: | ||
919 | |||
920 | acpi_ut_strupr(acpi_gbl_db_args[1]); | ||
921 | status = | ||
922 | acpi_db_display_objects(acpi_gbl_db_args[1], | ||
923 | acpi_gbl_db_args[2]); | ||
924 | break; | ||
925 | |||
926 | case CMD_OSI: | ||
927 | |||
928 | acpi_db_display_interfaces(acpi_gbl_db_args[1], | ||
929 | acpi_gbl_db_args[2]); | ||
930 | break; | ||
931 | |||
932 | case CMD_OWNER: | ||
933 | |||
934 | acpi_db_dump_namespace_by_owner(acpi_gbl_db_args[1], | ||
935 | acpi_gbl_db_args[2]); | ||
936 | break; | ||
937 | |||
938 | case CMD_PATHS: | ||
939 | |||
940 | acpi_db_dump_namespace_paths(); | ||
941 | break; | ||
942 | |||
943 | case CMD_PREFIX: | ||
944 | |||
945 | acpi_db_set_scope(acpi_gbl_db_args[1]); | ||
946 | break; | ||
947 | |||
948 | case CMD_REFERENCES: | ||
949 | |||
950 | acpi_db_find_references(acpi_gbl_db_args[1]); | ||
951 | break; | ||
952 | |||
953 | case CMD_RESOURCES: | ||
954 | |||
955 | acpi_db_display_resources(acpi_gbl_db_args[1]); | ||
956 | break; | ||
957 | |||
958 | case CMD_RESULTS: | ||
959 | |||
960 | acpi_db_display_results(); | ||
961 | break; | ||
962 | |||
963 | case CMD_SET: | ||
964 | |||
965 | acpi_db_set_method_data(acpi_gbl_db_args[1], | ||
966 | acpi_gbl_db_args[2], | ||
967 | acpi_gbl_db_args[3]); | ||
968 | break; | ||
969 | |||
970 | case CMD_STATS: | ||
971 | |||
972 | status = acpi_db_display_statistics(acpi_gbl_db_args[1]); | ||
973 | break; | ||
974 | |||
975 | case CMD_STOP: | ||
976 | |||
977 | return (AE_NOT_IMPLEMENTED); | ||
978 | |||
979 | case CMD_TABLES: | ||
980 | |||
981 | acpi_db_display_table_info(acpi_gbl_db_args[1]); | ||
982 | break; | ||
983 | |||
984 | case CMD_TEMPLATE: | ||
985 | |||
986 | acpi_db_display_template(acpi_gbl_db_args[1]); | ||
987 | break; | ||
988 | |||
989 | case CMD_TRACE: | ||
990 | |||
991 | acpi_db_trace(acpi_gbl_db_args[1], acpi_gbl_db_args[2], | ||
992 | acpi_gbl_db_args[3]); | ||
993 | break; | ||
994 | |||
995 | case CMD_TREE: | ||
996 | |||
997 | acpi_db_display_calling_tree(); | ||
998 | break; | ||
999 | |||
1000 | case CMD_TYPE: | ||
1001 | |||
1002 | acpi_db_display_object_type(acpi_gbl_db_args[1]); | ||
1003 | break; | ||
1004 | |||
1005 | #ifdef ACPI_APPLICATION | ||
1006 | |||
1007 | /* Hardware simulation commands. */ | ||
1008 | |||
1009 | case CMD_ENABLEACPI: | ||
1010 | #if (!ACPI_REDUCED_HARDWARE) | ||
1011 | |||
1012 | status = acpi_enable(); | ||
1013 | if (ACPI_FAILURE(status)) { | ||
1014 | acpi_os_printf("AcpiEnable failed (Status=%X)\n", | ||
1015 | status); | ||
1016 | return (status); | ||
1017 | } | ||
1018 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
1019 | break; | ||
1020 | |||
1021 | case CMD_EVENT: | ||
1022 | |||
1023 | acpi_os_printf("Event command not implemented\n"); | ||
1024 | break; | ||
1025 | |||
1026 | case CMD_GPE: | ||
1027 | |||
1028 | acpi_db_generate_gpe(acpi_gbl_db_args[1], acpi_gbl_db_args[2]); | ||
1029 | break; | ||
1030 | |||
1031 | case CMD_GPES: | ||
1032 | |||
1033 | acpi_db_display_gpes(); | ||
1034 | break; | ||
1035 | |||
1036 | case CMD_SCI: | ||
1037 | |||
1038 | acpi_db_generate_sci(); | ||
1039 | break; | ||
1040 | |||
1041 | case CMD_SLEEP: | ||
1042 | |||
1043 | status = acpi_db_sleep(acpi_gbl_db_args[1]); | ||
1044 | break; | ||
1045 | |||
1046 | /* File I/O commands. */ | ||
1047 | |||
1048 | case CMD_CLOSE: | ||
1049 | |||
1050 | acpi_db_close_debug_file(); | ||
1051 | break; | ||
1052 | |||
1053 | case CMD_LOAD: | ||
1054 | |||
1055 | status = | ||
1056 | acpi_db_get_table_from_file(acpi_gbl_db_args[1], NULL, | ||
1057 | FALSE); | ||
1058 | break; | ||
1059 | |||
1060 | case CMD_OPEN: | ||
1061 | |||
1062 | acpi_db_open_debug_file(acpi_gbl_db_args[1]); | ||
1063 | break; | ||
1064 | |||
1065 | /* User space commands. */ | ||
1066 | |||
1067 | case CMD_TERMINATE: | ||
1068 | |||
1069 | acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); | ||
1070 | acpi_ut_subsystem_shutdown(); | ||
1071 | |||
1072 | /* | ||
1073 | * TBD: [Restructure] Need some way to re-initialize without | ||
1074 | * re-creating the semaphores! | ||
1075 | */ | ||
1076 | |||
1077 | acpi_gbl_db_terminate_loop = TRUE; | ||
1078 | /* acpi_initialize (NULL); */ | ||
1079 | break; | ||
1080 | |||
1081 | case CMD_THREADS: | ||
1082 | |||
1083 | acpi_db_create_execution_threads(acpi_gbl_db_args[1], | ||
1084 | acpi_gbl_db_args[2], | ||
1085 | acpi_gbl_db_args[3]); | ||
1086 | break; | ||
1087 | |||
1088 | /* Debug test commands. */ | ||
1089 | |||
1090 | case CMD_PREDEFINED: | ||
1091 | |||
1092 | acpi_db_check_predefined_names(); | ||
1093 | break; | ||
1094 | |||
1095 | case CMD_TEST: | ||
1096 | |||
1097 | acpi_db_execute_test(acpi_gbl_db_args[1]); | ||
1098 | break; | ||
1099 | |||
1100 | case CMD_UNLOAD: | ||
1101 | |||
1102 | acpi_db_unload_acpi_table(acpi_gbl_db_args[1]); | ||
1103 | break; | ||
1104 | #endif | ||
1105 | |||
1106 | case CMD_EXIT: | ||
1107 | case CMD_QUIT: | ||
1108 | |||
1109 | if (op) { | ||
1110 | acpi_os_printf("Method execution terminated\n"); | ||
1111 | return (AE_CTRL_TERMINATE); | ||
1112 | } | ||
1113 | |||
1114 | if (!acpi_gbl_db_output_to_file) { | ||
1115 | acpi_dbg_level = ACPI_DEBUG_DEFAULT; | ||
1116 | } | ||
1117 | #ifdef ACPI_APPLICATION | ||
1118 | acpi_db_close_debug_file(); | ||
1119 | #endif | ||
1120 | acpi_gbl_db_terminate_loop = TRUE; | ||
1121 | return (AE_CTRL_TERMINATE); | ||
1122 | |||
1123 | case CMD_NOT_FOUND: | ||
1124 | default: | ||
1125 | |||
1126 | acpi_os_printf("%s: unknown command\n", acpi_gbl_db_args[0]); | ||
1127 | return (AE_CTRL_TRUE); | ||
1128 | } | ||
1129 | |||
1130 | if (ACPI_SUCCESS(status)) { | ||
1131 | status = AE_CTRL_TRUE; | ||
1132 | } | ||
1133 | |||
1134 | return (status); | ||
1135 | } | ||
1136 | |||
1137 | /******************************************************************************* | ||
1138 | * | ||
1139 | * FUNCTION: acpi_db_execute_thread | ||
1140 | * | ||
1141 | * PARAMETERS: context - Not used | ||
1142 | * | ||
1143 | * RETURN: None | ||
1144 | * | ||
1145 | * DESCRIPTION: Debugger execute thread. Waits for a command line, then | ||
1146 | * simply dispatches it. | ||
1147 | * | ||
1148 | ******************************************************************************/ | ||
1149 | |||
1150 | void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context) | ||
1151 | { | ||
1152 | acpi_status status = AE_OK; | ||
1153 | acpi_status Mstatus; | ||
1154 | |||
1155 | while (status != AE_CTRL_TERMINATE && !acpi_gbl_db_terminate_loop) { | ||
1156 | acpi_gbl_method_executing = FALSE; | ||
1157 | acpi_gbl_step_to_next_call = FALSE; | ||
1158 | |||
1159 | Mstatus = acpi_os_acquire_mutex(acpi_gbl_db_command_ready, | ||
1160 | ACPI_WAIT_FOREVER); | ||
1161 | if (ACPI_FAILURE(Mstatus)) { | ||
1162 | return; | ||
1163 | } | ||
1164 | |||
1165 | status = | ||
1166 | acpi_db_command_dispatch(acpi_gbl_db_line_buf, NULL, NULL); | ||
1167 | |||
1168 | acpi_os_release_mutex(acpi_gbl_db_command_complete); | ||
1169 | } | ||
1170 | acpi_gbl_db_threads_terminated = TRUE; | ||
1171 | } | ||
1172 | |||
1173 | /******************************************************************************* | ||
1174 | * | ||
1175 | * FUNCTION: acpi_db_single_thread | ||
1176 | * | ||
1177 | * PARAMETERS: None | ||
1178 | * | ||
1179 | * RETURN: None | ||
1180 | * | ||
1181 | * DESCRIPTION: Debugger execute thread. Waits for a command line, then | ||
1182 | * simply dispatches it. | ||
1183 | * | ||
1184 | ******************************************************************************/ | ||
1185 | |||
1186 | static void acpi_db_single_thread(void) | ||
1187 | { | ||
1188 | |||
1189 | acpi_gbl_method_executing = FALSE; | ||
1190 | acpi_gbl_step_to_next_call = FALSE; | ||
1191 | |||
1192 | (void)acpi_db_command_dispatch(acpi_gbl_db_line_buf, NULL, NULL); | ||
1193 | } | ||
1194 | |||
1195 | /******************************************************************************* | ||
1196 | * | ||
1197 | * FUNCTION: acpi_db_user_commands | ||
1198 | * | ||
1199 | * PARAMETERS: prompt - User prompt (depends on mode) | ||
1200 | * op - Current executing parse op | ||
1201 | * | ||
1202 | * RETURN: None | ||
1203 | * | ||
1204 | * DESCRIPTION: Command line execution for the AML debugger. Commands are | ||
1205 | * matched and dispatched here. | ||
1206 | * | ||
1207 | ******************************************************************************/ | ||
1208 | |||
1209 | acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op) | ||
1210 | { | ||
1211 | acpi_status status = AE_OK; | ||
1212 | |||
1213 | acpi_os_printf("\n"); | ||
1214 | |||
1215 | /* TBD: [Restructure] Need a separate command line buffer for step mode */ | ||
1216 | |||
1217 | while (!acpi_gbl_db_terminate_loop) { | ||
1218 | |||
1219 | /* Force output to console until a command is entered */ | ||
1220 | |||
1221 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
1222 | |||
1223 | /* Different prompt if method is executing */ | ||
1224 | |||
1225 | if (!acpi_gbl_method_executing) { | ||
1226 | acpi_os_printf("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); | ||
1227 | } else { | ||
1228 | acpi_os_printf("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); | ||
1229 | } | ||
1230 | |||
1231 | /* Get the user input line */ | ||
1232 | |||
1233 | status = acpi_os_get_line(acpi_gbl_db_line_buf, | ||
1234 | ACPI_DB_LINE_BUFFER_SIZE, NULL); | ||
1235 | if (ACPI_FAILURE(status)) { | ||
1236 | ACPI_EXCEPTION((AE_INFO, status, | ||
1237 | "While parsing command line")); | ||
1238 | return (status); | ||
1239 | } | ||
1240 | |||
1241 | /* Check for single or multithreaded debug */ | ||
1242 | |||
1243 | if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) { | ||
1244 | /* | ||
1245 | * Signal the debug thread that we have a command to execute, | ||
1246 | * and wait for the command to complete. | ||
1247 | */ | ||
1248 | acpi_os_release_mutex(acpi_gbl_db_command_ready); | ||
1249 | if (ACPI_FAILURE(status)) { | ||
1250 | return (status); | ||
1251 | } | ||
1252 | |||
1253 | status = | ||
1254 | acpi_os_acquire_mutex(acpi_gbl_db_command_complete, | ||
1255 | ACPI_WAIT_FOREVER); | ||
1256 | if (ACPI_FAILURE(status)) { | ||
1257 | return (status); | ||
1258 | } | ||
1259 | } else { | ||
1260 | /* Just call to the command line interpreter */ | ||
1261 | |||
1262 | acpi_db_single_thread(); | ||
1263 | } | ||
1264 | } | ||
1265 | |||
1266 | return (status); | ||
1267 | } | ||
diff --git a/drivers/acpi/acpica/dbmethod.c b/drivers/acpi/acpica/dbmethod.c new file mode 100644 index 000000000000..01e5a71147fd --- /dev/null +++ b/drivers/acpi/acpica/dbmethod.c | |||
@@ -0,0 +1,369 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbmethod - Debug commands for control methods | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acdispat.h" | ||
47 | #include "acnamesp.h" | ||
48 | #include "acdebug.h" | ||
49 | #include "acparser.h" | ||
50 | #include "acpredef.h" | ||
51 | |||
52 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
53 | ACPI_MODULE_NAME("dbmethod") | ||
54 | |||
55 | /******************************************************************************* | ||
56 | * | ||
57 | * FUNCTION: acpi_db_set_method_breakpoint | ||
58 | * | ||
59 | * PARAMETERS: location - AML offset of breakpoint | ||
60 | * walk_state - Current walk info | ||
61 | * op - Current Op (from parse walk) | ||
62 | * | ||
63 | * RETURN: None | ||
64 | * | ||
65 | * DESCRIPTION: Set a breakpoint in a control method at the specified | ||
66 | * AML offset | ||
67 | * | ||
68 | ******************************************************************************/ | ||
69 | void | ||
70 | acpi_db_set_method_breakpoint(char *location, | ||
71 | struct acpi_walk_state *walk_state, | ||
72 | union acpi_parse_object *op) | ||
73 | { | ||
74 | u32 address; | ||
75 | u32 aml_offset; | ||
76 | |||
77 | if (!op) { | ||
78 | acpi_os_printf("There is no method currently executing\n"); | ||
79 | return; | ||
80 | } | ||
81 | |||
82 | /* Get and verify the breakpoint address */ | ||
83 | |||
84 | address = strtoul(location, NULL, 16); | ||
85 | aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml, | ||
86 | walk_state->parser_state.aml_start); | ||
87 | if (address <= aml_offset) { | ||
88 | acpi_os_printf("Breakpoint %X is beyond current address %X\n", | ||
89 | address, aml_offset); | ||
90 | } | ||
91 | |||
92 | /* Save breakpoint in current walk */ | ||
93 | |||
94 | walk_state->user_breakpoint = address; | ||
95 | acpi_os_printf("Breakpoint set at AML offset %X\n", address); | ||
96 | } | ||
97 | |||
98 | /******************************************************************************* | ||
99 | * | ||
100 | * FUNCTION: acpi_db_set_method_call_breakpoint | ||
101 | * | ||
102 | * PARAMETERS: op - Current Op (from parse walk) | ||
103 | * | ||
104 | * RETURN: None | ||
105 | * | ||
106 | * DESCRIPTION: Set a breakpoint in a control method at the specified | ||
107 | * AML offset | ||
108 | * | ||
109 | ******************************************************************************/ | ||
110 | |||
111 | void acpi_db_set_method_call_breakpoint(union acpi_parse_object *op) | ||
112 | { | ||
113 | |||
114 | if (!op) { | ||
115 | acpi_os_printf("There is no method currently executing\n"); | ||
116 | return; | ||
117 | } | ||
118 | |||
119 | acpi_gbl_step_to_next_call = TRUE; | ||
120 | } | ||
121 | |||
122 | /******************************************************************************* | ||
123 | * | ||
124 | * FUNCTION: acpi_db_set_method_data | ||
125 | * | ||
126 | * PARAMETERS: type_arg - L for local, A for argument | ||
127 | * index_arg - which one | ||
128 | * value_arg - Value to set. | ||
129 | * | ||
130 | * RETURN: None | ||
131 | * | ||
132 | * DESCRIPTION: Set a local or argument for the running control method. | ||
133 | * NOTE: only object supported is Number. | ||
134 | * | ||
135 | ******************************************************************************/ | ||
136 | |||
137 | void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg) | ||
138 | { | ||
139 | char type; | ||
140 | u32 index; | ||
141 | u32 value; | ||
142 | struct acpi_walk_state *walk_state; | ||
143 | union acpi_operand_object *obj_desc; | ||
144 | acpi_status status; | ||
145 | struct acpi_namespace_node *node; | ||
146 | |||
147 | /* Validate type_arg */ | ||
148 | |||
149 | acpi_ut_strupr(type_arg); | ||
150 | type = type_arg[0]; | ||
151 | if ((type != 'L') && (type != 'A') && (type != 'N')) { | ||
152 | acpi_os_printf("Invalid SET operand: %s\n", type_arg); | ||
153 | return; | ||
154 | } | ||
155 | |||
156 | value = strtoul(value_arg, NULL, 16); | ||
157 | |||
158 | if (type == 'N') { | ||
159 | node = acpi_db_convert_to_node(index_arg); | ||
160 | if (!node) { | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | if (node->type != ACPI_TYPE_INTEGER) { | ||
165 | acpi_os_printf("Can only set Integer nodes\n"); | ||
166 | return; | ||
167 | } | ||
168 | obj_desc = node->object; | ||
169 | obj_desc->integer.value = value; | ||
170 | return; | ||
171 | } | ||
172 | |||
173 | /* Get the index and value */ | ||
174 | |||
175 | index = strtoul(index_arg, NULL, 16); | ||
176 | |||
177 | walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); | ||
178 | if (!walk_state) { | ||
179 | acpi_os_printf("There is no method currently executing\n"); | ||
180 | return; | ||
181 | } | ||
182 | |||
183 | /* Create and initialize the new object */ | ||
184 | |||
185 | obj_desc = acpi_ut_create_integer_object((u64)value); | ||
186 | if (!obj_desc) { | ||
187 | acpi_os_printf("Could not create an internal object\n"); | ||
188 | return; | ||
189 | } | ||
190 | |||
191 | /* Store the new object into the target */ | ||
192 | |||
193 | switch (type) { | ||
194 | case 'A': | ||
195 | |||
196 | /* Set a method argument */ | ||
197 | |||
198 | if (index > ACPI_METHOD_MAX_ARG) { | ||
199 | acpi_os_printf("Arg%u - Invalid argument name\n", | ||
200 | index); | ||
201 | goto cleanup; | ||
202 | } | ||
203 | |||
204 | status = acpi_ds_store_object_to_local(ACPI_REFCLASS_ARG, | ||
205 | index, obj_desc, | ||
206 | walk_state); | ||
207 | if (ACPI_FAILURE(status)) { | ||
208 | goto cleanup; | ||
209 | } | ||
210 | |||
211 | obj_desc = walk_state->arguments[index].object; | ||
212 | |||
213 | acpi_os_printf("Arg%u: ", index); | ||
214 | acpi_db_display_internal_object(obj_desc, walk_state); | ||
215 | break; | ||
216 | |||
217 | case 'L': | ||
218 | |||
219 | /* Set a method local */ | ||
220 | |||
221 | if (index > ACPI_METHOD_MAX_LOCAL) { | ||
222 | acpi_os_printf | ||
223 | ("Local%u - Invalid local variable name\n", index); | ||
224 | goto cleanup; | ||
225 | } | ||
226 | |||
227 | status = acpi_ds_store_object_to_local(ACPI_REFCLASS_LOCAL, | ||
228 | index, obj_desc, | ||
229 | walk_state); | ||
230 | if (ACPI_FAILURE(status)) { | ||
231 | goto cleanup; | ||
232 | } | ||
233 | |||
234 | obj_desc = walk_state->local_variables[index].object; | ||
235 | |||
236 | acpi_os_printf("Local%u: ", index); | ||
237 | acpi_db_display_internal_object(obj_desc, walk_state); | ||
238 | break; | ||
239 | |||
240 | default: | ||
241 | |||
242 | break; | ||
243 | } | ||
244 | |||
245 | cleanup: | ||
246 | acpi_ut_remove_reference(obj_desc); | ||
247 | } | ||
248 | |||
249 | /******************************************************************************* | ||
250 | * | ||
251 | * FUNCTION: acpi_db_disassemble_aml | ||
252 | * | ||
253 | * PARAMETERS: statements - Number of statements to disassemble | ||
254 | * op - Current Op (from parse walk) | ||
255 | * | ||
256 | * RETURN: None | ||
257 | * | ||
258 | * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number | ||
259 | * of statements specified. | ||
260 | * | ||
261 | ******************************************************************************/ | ||
262 | |||
263 | void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op) | ||
264 | { | ||
265 | u32 num_statements = 8; | ||
266 | |||
267 | if (!op) { | ||
268 | acpi_os_printf("There is no method currently executing\n"); | ||
269 | return; | ||
270 | } | ||
271 | |||
272 | if (statements) { | ||
273 | num_statements = strtoul(statements, NULL, 0); | ||
274 | } | ||
275 | #ifdef ACPI_DISASSEMBLER | ||
276 | acpi_dm_disassemble(NULL, op, num_statements); | ||
277 | #endif | ||
278 | } | ||
279 | |||
280 | /******************************************************************************* | ||
281 | * | ||
282 | * FUNCTION: acpi_db_disassemble_method | ||
283 | * | ||
284 | * PARAMETERS: name - Name of control method | ||
285 | * | ||
286 | * RETURN: None | ||
287 | * | ||
288 | * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number | ||
289 | * of statements specified. | ||
290 | * | ||
291 | ******************************************************************************/ | ||
292 | |||
293 | acpi_status acpi_db_disassemble_method(char *name) | ||
294 | { | ||
295 | acpi_status status; | ||
296 | union acpi_parse_object *op; | ||
297 | struct acpi_walk_state *walk_state; | ||
298 | union acpi_operand_object *obj_desc; | ||
299 | struct acpi_namespace_node *method; | ||
300 | |||
301 | method = acpi_db_convert_to_node(name); | ||
302 | if (!method) { | ||
303 | return (AE_BAD_PARAMETER); | ||
304 | } | ||
305 | |||
306 | if (method->type != ACPI_TYPE_METHOD) { | ||
307 | ACPI_ERROR((AE_INFO, "%s (%s): Object must be a control method", | ||
308 | name, acpi_ut_get_type_name(method->type))); | ||
309 | return (AE_BAD_PARAMETER); | ||
310 | } | ||
311 | |||
312 | obj_desc = method->object; | ||
313 | |||
314 | op = acpi_ps_create_scope_op(obj_desc->method.aml_start); | ||
315 | if (!op) { | ||
316 | return (AE_NO_MEMORY); | ||
317 | } | ||
318 | |||
319 | /* Create and initialize a new walk state */ | ||
320 | |||
321 | walk_state = acpi_ds_create_walk_state(0, op, NULL, NULL); | ||
322 | if (!walk_state) { | ||
323 | return (AE_NO_MEMORY); | ||
324 | } | ||
325 | |||
326 | status = acpi_ds_init_aml_walk(walk_state, op, NULL, | ||
327 | obj_desc->method.aml_start, | ||
328 | obj_desc->method.aml_length, NULL, | ||
329 | ACPI_IMODE_LOAD_PASS1); | ||
330 | if (ACPI_FAILURE(status)) { | ||
331 | return (status); | ||
332 | } | ||
333 | |||
334 | status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id); | ||
335 | walk_state->owner_id = obj_desc->method.owner_id; | ||
336 | |||
337 | /* Push start scope on scope stack and make it current */ | ||
338 | |||
339 | status = acpi_ds_scope_stack_push(method, method->type, walk_state); | ||
340 | if (ACPI_FAILURE(status)) { | ||
341 | return (status); | ||
342 | } | ||
343 | |||
344 | /* Parse the entire method AML including deferred operators */ | ||
345 | |||
346 | walk_state->parse_flags &= ~ACPI_PARSE_DELETE_TREE; | ||
347 | walk_state->parse_flags |= ACPI_PARSE_DISASSEMBLE; | ||
348 | |||
349 | status = acpi_ps_parse_aml(walk_state); | ||
350 | |||
351 | #ifdef ACPI_DISASSEMBLER | ||
352 | (void)acpi_dm_parse_deferred_ops(op); | ||
353 | |||
354 | /* Now we can disassemble the method */ | ||
355 | |||
356 | acpi_gbl_dm_opt_verbose = FALSE; | ||
357 | acpi_dm_disassemble(NULL, op, 0); | ||
358 | acpi_gbl_dm_opt_verbose = TRUE; | ||
359 | #endif | ||
360 | |||
361 | acpi_ps_delete_parse_tree(op); | ||
362 | |||
363 | /* Method cleanup */ | ||
364 | |||
365 | acpi_ns_delete_namespace_subtree(method); | ||
366 | acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id); | ||
367 | acpi_ut_release_owner_id(&obj_desc->method.owner_id); | ||
368 | return (AE_OK); | ||
369 | } | ||
diff --git a/drivers/acpi/acpica/dbnames.c b/drivers/acpi/acpica/dbnames.c new file mode 100644 index 000000000000..04ff1ebfda58 --- /dev/null +++ b/drivers/acpi/acpica/dbnames.c | |||
@@ -0,0 +1,947 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbnames - Debugger commands for the acpi namespace | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acnamesp.h" | ||
47 | #include "acdebug.h" | ||
48 | #include "acpredef.h" | ||
49 | |||
50 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
51 | ACPI_MODULE_NAME("dbnames") | ||
52 | |||
53 | /* Local prototypes */ | ||
54 | static acpi_status | ||
55 | acpi_db_walk_and_match_name(acpi_handle obj_handle, | ||
56 | u32 nesting_level, | ||
57 | void *context, void **return_value); | ||
58 | |||
59 | static acpi_status | ||
60 | acpi_db_walk_for_predefined_names(acpi_handle obj_handle, | ||
61 | u32 nesting_level, | ||
62 | void *context, void **return_value); | ||
63 | |||
64 | static acpi_status | ||
65 | acpi_db_walk_for_specific_objects(acpi_handle obj_handle, | ||
66 | u32 nesting_level, | ||
67 | void *context, void **return_value); | ||
68 | |||
69 | static acpi_status | ||
70 | acpi_db_walk_for_object_counts(acpi_handle obj_handle, | ||
71 | u32 nesting_level, | ||
72 | void *context, void **return_value); | ||
73 | |||
74 | static acpi_status | ||
75 | acpi_db_integrity_walk(acpi_handle obj_handle, | ||
76 | u32 nesting_level, void *context, void **return_value); | ||
77 | |||
78 | static acpi_status | ||
79 | acpi_db_walk_for_references(acpi_handle obj_handle, | ||
80 | u32 nesting_level, | ||
81 | void *context, void **return_value); | ||
82 | |||
83 | static acpi_status | ||
84 | acpi_db_bus_walk(acpi_handle obj_handle, | ||
85 | u32 nesting_level, void *context, void **return_value); | ||
86 | |||
87 | /* | ||
88 | * Arguments for the Objects command | ||
89 | * These object types map directly to the ACPI_TYPES | ||
90 | */ | ||
91 | static struct acpi_db_argument_info acpi_db_object_types[] = { | ||
92 | {"ANY"}, | ||
93 | {"INTEGERS"}, | ||
94 | {"STRINGS"}, | ||
95 | {"BUFFERS"}, | ||
96 | {"PACKAGES"}, | ||
97 | {"FIELDS"}, | ||
98 | {"DEVICES"}, | ||
99 | {"EVENTS"}, | ||
100 | {"METHODS"}, | ||
101 | {"MUTEXES"}, | ||
102 | {"REGIONS"}, | ||
103 | {"POWERRESOURCES"}, | ||
104 | {"PROCESSORS"}, | ||
105 | {"THERMALZONES"}, | ||
106 | {"BUFFERFIELDS"}, | ||
107 | {"DDBHANDLES"}, | ||
108 | {"DEBUG"}, | ||
109 | {"REGIONFIELDS"}, | ||
110 | {"BANKFIELDS"}, | ||
111 | {"INDEXFIELDS"}, | ||
112 | {"REFERENCES"}, | ||
113 | {"ALIASES"}, | ||
114 | {"METHODALIASES"}, | ||
115 | {"NOTIFY"}, | ||
116 | {"ADDRESSHANDLER"}, | ||
117 | {"RESOURCE"}, | ||
118 | {"RESOURCEFIELD"}, | ||
119 | {"SCOPES"}, | ||
120 | {NULL} /* Must be null terminated */ | ||
121 | }; | ||
122 | |||
123 | /******************************************************************************* | ||
124 | * | ||
125 | * FUNCTION: acpi_db_set_scope | ||
126 | * | ||
127 | * PARAMETERS: name - New scope path | ||
128 | * | ||
129 | * RETURN: Status | ||
130 | * | ||
131 | * DESCRIPTION: Set the "current scope" as maintained by this utility. | ||
132 | * The scope is used as a prefix to ACPI paths. | ||
133 | * | ||
134 | ******************************************************************************/ | ||
135 | |||
136 | void acpi_db_set_scope(char *name) | ||
137 | { | ||
138 | acpi_status status; | ||
139 | struct acpi_namespace_node *node; | ||
140 | |||
141 | if (!name || name[0] == 0) { | ||
142 | acpi_os_printf("Current scope: %s\n", acpi_gbl_db_scope_buf); | ||
143 | return; | ||
144 | } | ||
145 | |||
146 | acpi_db_prep_namestring(name); | ||
147 | |||
148 | if (ACPI_IS_ROOT_PREFIX(name[0])) { | ||
149 | |||
150 | /* Validate new scope from the root */ | ||
151 | |||
152 | status = acpi_ns_get_node(acpi_gbl_root_node, name, | ||
153 | ACPI_NS_NO_UPSEARCH, &node); | ||
154 | if (ACPI_FAILURE(status)) { | ||
155 | goto error_exit; | ||
156 | } | ||
157 | |||
158 | acpi_gbl_db_scope_buf[0] = 0; | ||
159 | } else { | ||
160 | /* Validate new scope relative to old scope */ | ||
161 | |||
162 | status = acpi_ns_get_node(acpi_gbl_db_scope_node, name, | ||
163 | ACPI_NS_NO_UPSEARCH, &node); | ||
164 | if (ACPI_FAILURE(status)) { | ||
165 | goto error_exit; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | /* Build the final pathname */ | ||
170 | |||
171 | if (acpi_ut_safe_strcat | ||
172 | (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), name)) { | ||
173 | status = AE_BUFFER_OVERFLOW; | ||
174 | goto error_exit; | ||
175 | } | ||
176 | |||
177 | if (acpi_ut_safe_strcat | ||
178 | (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), "\\")) { | ||
179 | status = AE_BUFFER_OVERFLOW; | ||
180 | goto error_exit; | ||
181 | } | ||
182 | |||
183 | acpi_gbl_db_scope_node = node; | ||
184 | acpi_os_printf("New scope: %s\n", acpi_gbl_db_scope_buf); | ||
185 | return; | ||
186 | |||
187 | error_exit: | ||
188 | |||
189 | acpi_os_printf("Could not attach scope: %s, %s\n", | ||
190 | name, acpi_format_exception(status)); | ||
191 | } | ||
192 | |||
193 | /******************************************************************************* | ||
194 | * | ||
195 | * FUNCTION: acpi_db_dump_namespace | ||
196 | * | ||
197 | * PARAMETERS: start_arg - Node to begin namespace dump | ||
198 | * depth_arg - Maximum tree depth to be dumped | ||
199 | * | ||
200 | * RETURN: None | ||
201 | * | ||
202 | * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed | ||
203 | * with type and other information. | ||
204 | * | ||
205 | ******************************************************************************/ | ||
206 | |||
207 | void acpi_db_dump_namespace(char *start_arg, char *depth_arg) | ||
208 | { | ||
209 | acpi_handle subtree_entry = acpi_gbl_root_node; | ||
210 | u32 max_depth = ACPI_UINT32_MAX; | ||
211 | |||
212 | /* No argument given, just start at the root and dump entire namespace */ | ||
213 | |||
214 | if (start_arg) { | ||
215 | subtree_entry = acpi_db_convert_to_node(start_arg); | ||
216 | if (!subtree_entry) { | ||
217 | return; | ||
218 | } | ||
219 | |||
220 | /* Now we can check for the depth argument */ | ||
221 | |||
222 | if (depth_arg) { | ||
223 | max_depth = strtoul(depth_arg, NULL, 0); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); | ||
228 | acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n", | ||
229 | ((struct acpi_namespace_node *)subtree_entry)->name. | ||
230 | ascii, subtree_entry); | ||
231 | |||
232 | /* Display the subtree */ | ||
233 | |||
234 | acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); | ||
235 | acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth, | ||
236 | ACPI_OWNER_ID_MAX, subtree_entry); | ||
237 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
238 | } | ||
239 | |||
240 | /******************************************************************************* | ||
241 | * | ||
242 | * FUNCTION: acpi_db_dump_namespace_paths | ||
243 | * | ||
244 | * PARAMETERS: None | ||
245 | * | ||
246 | * RETURN: None | ||
247 | * | ||
248 | * DESCRIPTION: Dump entire namespace with full object pathnames and object | ||
249 | * type information. Alternative to "namespace" command. | ||
250 | * | ||
251 | ******************************************************************************/ | ||
252 | |||
253 | void acpi_db_dump_namespace_paths(void) | ||
254 | { | ||
255 | |||
256 | acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); | ||
257 | acpi_os_printf("ACPI Namespace (from root):\n"); | ||
258 | |||
259 | /* Display the entire namespace */ | ||
260 | |||
261 | acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); | ||
262 | acpi_ns_dump_object_paths(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, | ||
263 | ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX, | ||
264 | acpi_gbl_root_node); | ||
265 | |||
266 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
267 | } | ||
268 | |||
269 | /******************************************************************************* | ||
270 | * | ||
271 | * FUNCTION: acpi_db_dump_namespace_by_owner | ||
272 | * | ||
273 | * PARAMETERS: owner_arg - Owner ID whose nodes will be displayed | ||
274 | * depth_arg - Maximum tree depth to be dumped | ||
275 | * | ||
276 | * RETURN: None | ||
277 | * | ||
278 | * DESCRIPTION: Dump elements of the namespace that are owned by the owner_id. | ||
279 | * | ||
280 | ******************************************************************************/ | ||
281 | |||
282 | void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg) | ||
283 | { | ||
284 | acpi_handle subtree_entry = acpi_gbl_root_node; | ||
285 | u32 max_depth = ACPI_UINT32_MAX; | ||
286 | acpi_owner_id owner_id; | ||
287 | |||
288 | owner_id = (acpi_owner_id) strtoul(owner_arg, NULL, 0); | ||
289 | |||
290 | /* Now we can check for the depth argument */ | ||
291 | |||
292 | if (depth_arg) { | ||
293 | max_depth = strtoul(depth_arg, NULL, 0); | ||
294 | } | ||
295 | |||
296 | acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); | ||
297 | acpi_os_printf("ACPI Namespace by owner %X:\n", owner_id); | ||
298 | |||
299 | /* Display the subtree */ | ||
300 | |||
301 | acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); | ||
302 | acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth, | ||
303 | owner_id, subtree_entry); | ||
304 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
305 | } | ||
306 | |||
307 | /******************************************************************************* | ||
308 | * | ||
309 | * FUNCTION: acpi_db_walk_and_match_name | ||
310 | * | ||
311 | * PARAMETERS: Callback from walk_namespace | ||
312 | * | ||
313 | * RETURN: Status | ||
314 | * | ||
315 | * DESCRIPTION: Find a particular name/names within the namespace. Wildcards | ||
316 | * are supported -- '?' matches any character. | ||
317 | * | ||
318 | ******************************************************************************/ | ||
319 | |||
320 | static acpi_status | ||
321 | acpi_db_walk_and_match_name(acpi_handle obj_handle, | ||
322 | u32 nesting_level, | ||
323 | void *context, void **return_value) | ||
324 | { | ||
325 | acpi_status status; | ||
326 | char *requested_name = (char *)context; | ||
327 | u32 i; | ||
328 | struct acpi_buffer buffer; | ||
329 | struct acpi_walk_info info; | ||
330 | |||
331 | /* Check for a name match */ | ||
332 | |||
333 | for (i = 0; i < 4; i++) { | ||
334 | |||
335 | /* Wildcard support */ | ||
336 | |||
337 | if ((requested_name[i] != '?') && | ||
338 | (requested_name[i] != ((struct acpi_namespace_node *) | ||
339 | obj_handle)->name.ascii[i])) { | ||
340 | |||
341 | /* No match, just exit */ | ||
342 | |||
343 | return (AE_OK); | ||
344 | } | ||
345 | } | ||
346 | |||
347 | /* Get the full pathname to this object */ | ||
348 | |||
349 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
350 | status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE); | ||
351 | if (ACPI_FAILURE(status)) { | ||
352 | acpi_os_printf("Could Not get pathname for object %p\n", | ||
353 | obj_handle); | ||
354 | } else { | ||
355 | info.owner_id = ACPI_OWNER_ID_MAX; | ||
356 | info.debug_level = ACPI_UINT32_MAX; | ||
357 | info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; | ||
358 | |||
359 | acpi_os_printf("%32s", (char *)buffer.pointer); | ||
360 | (void)acpi_ns_dump_one_object(obj_handle, nesting_level, &info, | ||
361 | NULL); | ||
362 | ACPI_FREE(buffer.pointer); | ||
363 | } | ||
364 | |||
365 | return (AE_OK); | ||
366 | } | ||
367 | |||
368 | /******************************************************************************* | ||
369 | * | ||
370 | * FUNCTION: acpi_db_find_name_in_namespace | ||
371 | * | ||
372 | * PARAMETERS: name_arg - The 4-character ACPI name to find. | ||
373 | * wildcards are supported. | ||
374 | * | ||
375 | * RETURN: None | ||
376 | * | ||
377 | * DESCRIPTION: Search the namespace for a given name (with wildcards) | ||
378 | * | ||
379 | ******************************************************************************/ | ||
380 | |||
381 | acpi_status acpi_db_find_name_in_namespace(char *name_arg) | ||
382 | { | ||
383 | char acpi_name[5] = "____"; | ||
384 | char *acpi_name_ptr = acpi_name; | ||
385 | |||
386 | if (strlen(name_arg) > ACPI_NAME_SIZE) { | ||
387 | acpi_os_printf("Name must be no longer than 4 characters\n"); | ||
388 | return (AE_OK); | ||
389 | } | ||
390 | |||
391 | /* Pad out name with underscores as necessary to create a 4-char name */ | ||
392 | |||
393 | acpi_ut_strupr(name_arg); | ||
394 | while (*name_arg) { | ||
395 | *acpi_name_ptr = *name_arg; | ||
396 | acpi_name_ptr++; | ||
397 | name_arg++; | ||
398 | } | ||
399 | |||
400 | /* Walk the namespace from the root */ | ||
401 | |||
402 | (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
403 | ACPI_UINT32_MAX, acpi_db_walk_and_match_name, | ||
404 | NULL, acpi_name, NULL); | ||
405 | |||
406 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
407 | return (AE_OK); | ||
408 | } | ||
409 | |||
410 | /******************************************************************************* | ||
411 | * | ||
412 | * FUNCTION: acpi_db_walk_for_predefined_names | ||
413 | * | ||
414 | * PARAMETERS: Callback from walk_namespace | ||
415 | * | ||
416 | * RETURN: Status | ||
417 | * | ||
418 | * DESCRIPTION: Detect and display predefined ACPI names (names that start with | ||
419 | * an underscore) | ||
420 | * | ||
421 | ******************************************************************************/ | ||
422 | |||
423 | static acpi_status | ||
424 | acpi_db_walk_for_predefined_names(acpi_handle obj_handle, | ||
425 | u32 nesting_level, | ||
426 | void *context, void **return_value) | ||
427 | { | ||
428 | struct acpi_namespace_node *node = | ||
429 | (struct acpi_namespace_node *)obj_handle; | ||
430 | u32 *count = (u32 *)context; | ||
431 | const union acpi_predefined_info *predefined; | ||
432 | const union acpi_predefined_info *package = NULL; | ||
433 | char *pathname; | ||
434 | char string_buffer[48]; | ||
435 | |||
436 | predefined = acpi_ut_match_predefined_method(node->name.ascii); | ||
437 | if (!predefined) { | ||
438 | return (AE_OK); | ||
439 | } | ||
440 | |||
441 | pathname = acpi_ns_get_external_pathname(node); | ||
442 | if (!pathname) { | ||
443 | return (AE_OK); | ||
444 | } | ||
445 | |||
446 | /* If method returns a package, the info is in the next table entry */ | ||
447 | |||
448 | if (predefined->info.expected_btypes & ACPI_RTYPE_PACKAGE) { | ||
449 | package = predefined + 1; | ||
450 | } | ||
451 | |||
452 | acpi_ut_get_expected_return_types(string_buffer, | ||
453 | predefined->info.expected_btypes); | ||
454 | |||
455 | acpi_os_printf("%-32s Arguments %X, Return Types: %s", pathname, | ||
456 | METHOD_GET_ARG_COUNT(predefined->info.argument_list), | ||
457 | string_buffer); | ||
458 | |||
459 | if (package) { | ||
460 | acpi_os_printf(" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)", | ||
461 | package->ret_info.type, | ||
462 | package->ret_info.object_type1, | ||
463 | package->ret_info.count1); | ||
464 | } | ||
465 | |||
466 | acpi_os_printf("\n"); | ||
467 | |||
468 | /* Check that the declared argument count matches the ACPI spec */ | ||
469 | |||
470 | acpi_ns_check_acpi_compliance(pathname, node, predefined); | ||
471 | |||
472 | ACPI_FREE(pathname); | ||
473 | (*count)++; | ||
474 | return (AE_OK); | ||
475 | } | ||
476 | |||
477 | /******************************************************************************* | ||
478 | * | ||
479 | * FUNCTION: acpi_db_check_predefined_names | ||
480 | * | ||
481 | * PARAMETERS: None | ||
482 | * | ||
483 | * RETURN: None | ||
484 | * | ||
485 | * DESCRIPTION: Validate all predefined names in the namespace | ||
486 | * | ||
487 | ******************************************************************************/ | ||
488 | |||
489 | void acpi_db_check_predefined_names(void) | ||
490 | { | ||
491 | u32 count = 0; | ||
492 | |||
493 | /* Search all nodes in namespace */ | ||
494 | |||
495 | (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
496 | ACPI_UINT32_MAX, | ||
497 | acpi_db_walk_for_predefined_names, NULL, | ||
498 | (void *)&count, NULL); | ||
499 | |||
500 | acpi_os_printf("Found %u predefined names in the namespace\n", count); | ||
501 | } | ||
502 | |||
503 | /******************************************************************************* | ||
504 | * | ||
505 | * FUNCTION: acpi_db_walk_for_object_counts | ||
506 | * | ||
507 | * PARAMETERS: Callback from walk_namespace | ||
508 | * | ||
509 | * RETURN: Status | ||
510 | * | ||
511 | * DESCRIPTION: Display short info about objects in the namespace | ||
512 | * | ||
513 | ******************************************************************************/ | ||
514 | |||
515 | static acpi_status | ||
516 | acpi_db_walk_for_object_counts(acpi_handle obj_handle, | ||
517 | u32 nesting_level, | ||
518 | void *context, void **return_value) | ||
519 | { | ||
520 | struct acpi_object_info *info = (struct acpi_object_info *)context; | ||
521 | struct acpi_namespace_node *node = | ||
522 | (struct acpi_namespace_node *)obj_handle; | ||
523 | |||
524 | if (node->type > ACPI_TYPE_NS_NODE_MAX) { | ||
525 | acpi_os_printf("[%4.4s]: Unknown object type %X\n", | ||
526 | node->name.ascii, node->type); | ||
527 | } else { | ||
528 | info->types[node->type]++; | ||
529 | } | ||
530 | |||
531 | return (AE_OK); | ||
532 | } | ||
533 | |||
534 | /******************************************************************************* | ||
535 | * | ||
536 | * FUNCTION: acpi_db_walk_for_specific_objects | ||
537 | * | ||
538 | * PARAMETERS: Callback from walk_namespace | ||
539 | * | ||
540 | * RETURN: Status | ||
541 | * | ||
542 | * DESCRIPTION: Display short info about objects in the namespace | ||
543 | * | ||
544 | ******************************************************************************/ | ||
545 | |||
546 | static acpi_status | ||
547 | acpi_db_walk_for_specific_objects(acpi_handle obj_handle, | ||
548 | u32 nesting_level, | ||
549 | void *context, void **return_value) | ||
550 | { | ||
551 | struct acpi_walk_info *info = (struct acpi_walk_info *)context; | ||
552 | struct acpi_buffer buffer; | ||
553 | acpi_status status; | ||
554 | |||
555 | info->count++; | ||
556 | |||
557 | /* Get and display the full pathname to this object */ | ||
558 | |||
559 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
560 | status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE); | ||
561 | if (ACPI_FAILURE(status)) { | ||
562 | acpi_os_printf("Could Not get pathname for object %p\n", | ||
563 | obj_handle); | ||
564 | return (AE_OK); | ||
565 | } | ||
566 | |||
567 | acpi_os_printf("%32s", (char *)buffer.pointer); | ||
568 | ACPI_FREE(buffer.pointer); | ||
569 | |||
570 | /* Dump short info about the object */ | ||
571 | |||
572 | (void)acpi_ns_dump_one_object(obj_handle, nesting_level, info, NULL); | ||
573 | return (AE_OK); | ||
574 | } | ||
575 | |||
576 | /******************************************************************************* | ||
577 | * | ||
578 | * FUNCTION: acpi_db_display_objects | ||
579 | * | ||
580 | * PARAMETERS: obj_type_arg - Type of object to display | ||
581 | * display_count_arg - Max depth to display | ||
582 | * | ||
583 | * RETURN: None | ||
584 | * | ||
585 | * DESCRIPTION: Display objects in the namespace of the requested type | ||
586 | * | ||
587 | ******************************************************************************/ | ||
588 | |||
589 | acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg) | ||
590 | { | ||
591 | struct acpi_walk_info info; | ||
592 | acpi_object_type type; | ||
593 | struct acpi_object_info *object_info; | ||
594 | u32 i; | ||
595 | u32 total_objects = 0; | ||
596 | |||
597 | /* No argument means display summary/count of all object types */ | ||
598 | |||
599 | if (!obj_type_arg) { | ||
600 | object_info = | ||
601 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info)); | ||
602 | |||
603 | /* Walk the namespace from the root */ | ||
604 | |||
605 | (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
606 | ACPI_UINT32_MAX, | ||
607 | acpi_db_walk_for_object_counts, NULL, | ||
608 | (void *)object_info, NULL); | ||
609 | |||
610 | acpi_os_printf("\nSummary of namespace objects:\n\n"); | ||
611 | |||
612 | for (i = 0; i < ACPI_TOTAL_TYPES; i++) { | ||
613 | acpi_os_printf("%8u %s\n", object_info->types[i], | ||
614 | acpi_ut_get_type_name(i)); | ||
615 | |||
616 | total_objects += object_info->types[i]; | ||
617 | } | ||
618 | |||
619 | acpi_os_printf("\n%8u Total namespace objects\n\n", | ||
620 | total_objects); | ||
621 | |||
622 | ACPI_FREE(object_info); | ||
623 | return (AE_OK); | ||
624 | } | ||
625 | |||
626 | /* Get the object type */ | ||
627 | |||
628 | type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types); | ||
629 | if (type == ACPI_TYPE_NOT_FOUND) { | ||
630 | acpi_os_printf("Invalid or unsupported argument\n"); | ||
631 | return (AE_OK); | ||
632 | } | ||
633 | |||
634 | acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); | ||
635 | acpi_os_printf | ||
636 | ("Objects of type [%s] defined in the current ACPI Namespace:\n", | ||
637 | acpi_ut_get_type_name(type)); | ||
638 | |||
639 | acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); | ||
640 | |||
641 | info.count = 0; | ||
642 | info.owner_id = ACPI_OWNER_ID_MAX; | ||
643 | info.debug_level = ACPI_UINT32_MAX; | ||
644 | info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; | ||
645 | |||
646 | /* Walk the namespace from the root */ | ||
647 | |||
648 | (void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, | ||
649 | acpi_db_walk_for_specific_objects, NULL, | ||
650 | (void *)&info, NULL); | ||
651 | |||
652 | acpi_os_printf | ||
653 | ("\nFound %u objects of type [%s] in the current ACPI Namespace\n", | ||
654 | info.count, acpi_ut_get_type_name(type)); | ||
655 | |||
656 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
657 | return (AE_OK); | ||
658 | } | ||
659 | |||
660 | /******************************************************************************* | ||
661 | * | ||
662 | * FUNCTION: acpi_db_integrity_walk | ||
663 | * | ||
664 | * PARAMETERS: Callback from walk_namespace | ||
665 | * | ||
666 | * RETURN: Status | ||
667 | * | ||
668 | * DESCRIPTION: Examine one NS node for valid values. | ||
669 | * | ||
670 | ******************************************************************************/ | ||
671 | |||
672 | static acpi_status | ||
673 | acpi_db_integrity_walk(acpi_handle obj_handle, | ||
674 | u32 nesting_level, void *context, void **return_value) | ||
675 | { | ||
676 | struct acpi_integrity_info *info = | ||
677 | (struct acpi_integrity_info *)context; | ||
678 | struct acpi_namespace_node *node = | ||
679 | (struct acpi_namespace_node *)obj_handle; | ||
680 | union acpi_operand_object *object; | ||
681 | u8 alias = TRUE; | ||
682 | |||
683 | info->nodes++; | ||
684 | |||
685 | /* Verify the NS node, and dereference aliases */ | ||
686 | |||
687 | while (alias) { | ||
688 | if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { | ||
689 | acpi_os_printf | ||
690 | ("Invalid Descriptor Type for Node %p [%s] - " | ||
691 | "is %2.2X should be %2.2X\n", node, | ||
692 | acpi_ut_get_descriptor_name(node), | ||
693 | ACPI_GET_DESCRIPTOR_TYPE(node), | ||
694 | ACPI_DESC_TYPE_NAMED); | ||
695 | return (AE_OK); | ||
696 | } | ||
697 | |||
698 | if ((node->type == ACPI_TYPE_LOCAL_ALIAS) || | ||
699 | (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) { | ||
700 | node = (struct acpi_namespace_node *)node->object; | ||
701 | } else { | ||
702 | alias = FALSE; | ||
703 | } | ||
704 | } | ||
705 | |||
706 | if (node->type > ACPI_TYPE_LOCAL_MAX) { | ||
707 | acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n", | ||
708 | node, node->type); | ||
709 | return (AE_OK); | ||
710 | } | ||
711 | |||
712 | if (!acpi_ut_valid_acpi_name(node->name.ascii)) { | ||
713 | acpi_os_printf("Invalid AcpiName for Node %p\n", node); | ||
714 | return (AE_OK); | ||
715 | } | ||
716 | |||
717 | object = acpi_ns_get_attached_object(node); | ||
718 | if (object) { | ||
719 | info->objects++; | ||
720 | if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) { | ||
721 | acpi_os_printf | ||
722 | ("Invalid Descriptor Type for Object %p [%s]\n", | ||
723 | object, acpi_ut_get_descriptor_name(object)); | ||
724 | } | ||
725 | } | ||
726 | |||
727 | return (AE_OK); | ||
728 | } | ||
729 | |||
730 | /******************************************************************************* | ||
731 | * | ||
732 | * FUNCTION: acpi_db_check_integrity | ||
733 | * | ||
734 | * PARAMETERS: None | ||
735 | * | ||
736 | * RETURN: None | ||
737 | * | ||
738 | * DESCRIPTION: Check entire namespace for data structure integrity | ||
739 | * | ||
740 | ******************************************************************************/ | ||
741 | |||
742 | void acpi_db_check_integrity(void) | ||
743 | { | ||
744 | struct acpi_integrity_info info = { 0, 0 }; | ||
745 | |||
746 | /* Search all nodes in namespace */ | ||
747 | |||
748 | (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
749 | ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL, | ||
750 | (void *)&info, NULL); | ||
751 | |||
752 | acpi_os_printf("Verified %u namespace nodes with %u Objects\n", | ||
753 | info.nodes, info.objects); | ||
754 | } | ||
755 | |||
756 | /******************************************************************************* | ||
757 | * | ||
758 | * FUNCTION: acpi_db_walk_for_references | ||
759 | * | ||
760 | * PARAMETERS: Callback from walk_namespace | ||
761 | * | ||
762 | * RETURN: Status | ||
763 | * | ||
764 | * DESCRIPTION: Check if this namespace object refers to the target object | ||
765 | * that is passed in as the context value. | ||
766 | * | ||
767 | * Note: Currently doesn't check subobjects within the Node's object | ||
768 | * | ||
769 | ******************************************************************************/ | ||
770 | |||
771 | static acpi_status | ||
772 | acpi_db_walk_for_references(acpi_handle obj_handle, | ||
773 | u32 nesting_level, | ||
774 | void *context, void **return_value) | ||
775 | { | ||
776 | union acpi_operand_object *obj_desc = | ||
777 | (union acpi_operand_object *)context; | ||
778 | struct acpi_namespace_node *node = | ||
779 | (struct acpi_namespace_node *)obj_handle; | ||
780 | |||
781 | /* Check for match against the namespace node itself */ | ||
782 | |||
783 | if (node == (void *)obj_desc) { | ||
784 | acpi_os_printf("Object is a Node [%4.4s]\n", | ||
785 | acpi_ut_get_node_name(node)); | ||
786 | } | ||
787 | |||
788 | /* Check for match against the object attached to the node */ | ||
789 | |||
790 | if (acpi_ns_get_attached_object(node) == obj_desc) { | ||
791 | acpi_os_printf("Reference at Node->Object %p [%4.4s]\n", | ||
792 | node, acpi_ut_get_node_name(node)); | ||
793 | } | ||
794 | |||
795 | return (AE_OK); | ||
796 | } | ||
797 | |||
798 | /******************************************************************************* | ||
799 | * | ||
800 | * FUNCTION: acpi_db_find_references | ||
801 | * | ||
802 | * PARAMETERS: object_arg - String with hex value of the object | ||
803 | * | ||
804 | * RETURN: None | ||
805 | * | ||
806 | * DESCRIPTION: Search namespace for all references to the input object | ||
807 | * | ||
808 | ******************************************************************************/ | ||
809 | |||
810 | void acpi_db_find_references(char *object_arg) | ||
811 | { | ||
812 | union acpi_operand_object *obj_desc; | ||
813 | acpi_size address; | ||
814 | |||
815 | /* Convert string to object pointer */ | ||
816 | |||
817 | address = strtoul(object_arg, NULL, 16); | ||
818 | obj_desc = ACPI_TO_POINTER(address); | ||
819 | |||
820 | /* Search all nodes in namespace */ | ||
821 | |||
822 | (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
823 | ACPI_UINT32_MAX, acpi_db_walk_for_references, | ||
824 | NULL, (void *)obj_desc, NULL); | ||
825 | } | ||
826 | |||
827 | /******************************************************************************* | ||
828 | * | ||
829 | * FUNCTION: acpi_db_bus_walk | ||
830 | * | ||
831 | * PARAMETERS: Callback from walk_namespace | ||
832 | * | ||
833 | * RETURN: Status | ||
834 | * | ||
835 | * DESCRIPTION: Display info about device objects that have a corresponding | ||
836 | * _PRT method. | ||
837 | * | ||
838 | ******************************************************************************/ | ||
839 | |||
840 | static acpi_status | ||
841 | acpi_db_bus_walk(acpi_handle obj_handle, | ||
842 | u32 nesting_level, void *context, void **return_value) | ||
843 | { | ||
844 | struct acpi_namespace_node *node = | ||
845 | (struct acpi_namespace_node *)obj_handle; | ||
846 | acpi_status status; | ||
847 | struct acpi_buffer buffer; | ||
848 | struct acpi_namespace_node *temp_node; | ||
849 | struct acpi_device_info *info; | ||
850 | u32 i; | ||
851 | |||
852 | if ((node->type != ACPI_TYPE_DEVICE) && | ||
853 | (node->type != ACPI_TYPE_PROCESSOR)) { | ||
854 | return (AE_OK); | ||
855 | } | ||
856 | |||
857 | /* Exit if there is no _PRT under this device */ | ||
858 | |||
859 | status = acpi_get_handle(node, METHOD_NAME__PRT, | ||
860 | ACPI_CAST_PTR(acpi_handle, &temp_node)); | ||
861 | if (ACPI_FAILURE(status)) { | ||
862 | return (AE_OK); | ||
863 | } | ||
864 | |||
865 | /* Get the full path to this device object */ | ||
866 | |||
867 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
868 | status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE); | ||
869 | if (ACPI_FAILURE(status)) { | ||
870 | acpi_os_printf("Could Not get pathname for object %p\n", | ||
871 | obj_handle); | ||
872 | return (AE_OK); | ||
873 | } | ||
874 | |||
875 | status = acpi_get_object_info(obj_handle, &info); | ||
876 | if (ACPI_FAILURE(status)) { | ||
877 | return (AE_OK); | ||
878 | } | ||
879 | |||
880 | /* Display the full path */ | ||
881 | |||
882 | acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type); | ||
883 | ACPI_FREE(buffer.pointer); | ||
884 | |||
885 | if (info->flags & ACPI_PCI_ROOT_BRIDGE) { | ||
886 | acpi_os_printf(" - Is PCI Root Bridge"); | ||
887 | } | ||
888 | acpi_os_printf("\n"); | ||
889 | |||
890 | /* _PRT info */ | ||
891 | |||
892 | acpi_os_printf("_PRT: %p\n", temp_node); | ||
893 | |||
894 | /* Dump _ADR, _HID, _UID, _CID */ | ||
895 | |||
896 | if (info->valid & ACPI_VALID_ADR) { | ||
897 | acpi_os_printf("_ADR: %8.8X%8.8X\n", | ||
898 | ACPI_FORMAT_UINT64(info->address)); | ||
899 | } else { | ||
900 | acpi_os_printf("_ADR: <Not Present>\n"); | ||
901 | } | ||
902 | |||
903 | if (info->valid & ACPI_VALID_HID) { | ||
904 | acpi_os_printf("_HID: %s\n", info->hardware_id.string); | ||
905 | } else { | ||
906 | acpi_os_printf("_HID: <Not Present>\n"); | ||
907 | } | ||
908 | |||
909 | if (info->valid & ACPI_VALID_UID) { | ||
910 | acpi_os_printf("_UID: %s\n", info->unique_id.string); | ||
911 | } else { | ||
912 | acpi_os_printf("_UID: <Not Present>\n"); | ||
913 | } | ||
914 | |||
915 | if (info->valid & ACPI_VALID_CID) { | ||
916 | for (i = 0; i < info->compatible_id_list.count; i++) { | ||
917 | acpi_os_printf("_CID: %s\n", | ||
918 | info->compatible_id_list.ids[i].string); | ||
919 | } | ||
920 | } else { | ||
921 | acpi_os_printf("_CID: <Not Present>\n"); | ||
922 | } | ||
923 | |||
924 | ACPI_FREE(info); | ||
925 | return (AE_OK); | ||
926 | } | ||
927 | |||
928 | /******************************************************************************* | ||
929 | * | ||
930 | * FUNCTION: acpi_db_get_bus_info | ||
931 | * | ||
932 | * PARAMETERS: None | ||
933 | * | ||
934 | * RETURN: None | ||
935 | * | ||
936 | * DESCRIPTION: Display info about system busses. | ||
937 | * | ||
938 | ******************************************************************************/ | ||
939 | |||
940 | void acpi_db_get_bus_info(void) | ||
941 | { | ||
942 | /* Search all nodes in namespace */ | ||
943 | |||
944 | (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
945 | ACPI_UINT32_MAX, acpi_db_bus_walk, NULL, NULL, | ||
946 | NULL); | ||
947 | } | ||
diff --git a/drivers/acpi/acpica/dbobject.c b/drivers/acpi/acpica/dbobject.c new file mode 100644 index 000000000000..116f6db8c2ed --- /dev/null +++ b/drivers/acpi/acpica/dbobject.c | |||
@@ -0,0 +1,533 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbobject - ACPI object decode and display | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acnamesp.h" | ||
47 | #include "acdebug.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
50 | ACPI_MODULE_NAME("dbobject") | ||
51 | |||
52 | /* Local prototypes */ | ||
53 | static void acpi_db_decode_node(struct acpi_namespace_node *node); | ||
54 | |||
55 | /******************************************************************************* | ||
56 | * | ||
57 | * FUNCTION: acpi_db_dump_method_info | ||
58 | * | ||
59 | * PARAMETERS: status - Method execution status | ||
60 | * walk_state - Current state of the parse tree walk | ||
61 | * | ||
62 | * RETURN: None | ||
63 | * | ||
64 | * DESCRIPTION: Called when a method has been aborted because of an error. | ||
65 | * Dumps the method execution stack, and the method locals/args, | ||
66 | * and disassembles the AML opcode that failed. | ||
67 | * | ||
68 | ******************************************************************************/ | ||
69 | |||
70 | void | ||
71 | acpi_db_dump_method_info(acpi_status status, struct acpi_walk_state *walk_state) | ||
72 | { | ||
73 | struct acpi_thread_state *thread; | ||
74 | |||
75 | /* Ignore control codes, they are not errors */ | ||
76 | |||
77 | if ((status & AE_CODE_MASK) == AE_CODE_CONTROL) { | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | /* We may be executing a deferred opcode */ | ||
82 | |||
83 | if (walk_state->deferred_node) { | ||
84 | acpi_os_printf("Executing subtree for Buffer/Package/Region\n"); | ||
85 | return; | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * If there is no Thread, we are not actually executing a method. | ||
90 | * This can happen when the iASL compiler calls the interpreter | ||
91 | * to perform constant folding. | ||
92 | */ | ||
93 | thread = walk_state->thread; | ||
94 | if (!thread) { | ||
95 | return; | ||
96 | } | ||
97 | |||
98 | /* Display the method locals and arguments */ | ||
99 | |||
100 | acpi_os_printf("\n"); | ||
101 | acpi_db_decode_locals(walk_state); | ||
102 | acpi_os_printf("\n"); | ||
103 | acpi_db_decode_arguments(walk_state); | ||
104 | acpi_os_printf("\n"); | ||
105 | } | ||
106 | |||
107 | /******************************************************************************* | ||
108 | * | ||
109 | * FUNCTION: acpi_db_decode_internal_object | ||
110 | * | ||
111 | * PARAMETERS: obj_desc - Object to be displayed | ||
112 | * | ||
113 | * RETURN: None | ||
114 | * | ||
115 | * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers. | ||
116 | * | ||
117 | ******************************************************************************/ | ||
118 | |||
119 | void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc) | ||
120 | { | ||
121 | u32 i; | ||
122 | |||
123 | if (!obj_desc) { | ||
124 | acpi_os_printf(" Uninitialized"); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) { | ||
129 | acpi_os_printf(" %p [%s]", obj_desc, | ||
130 | acpi_ut_get_descriptor_name(obj_desc)); | ||
131 | return; | ||
132 | } | ||
133 | |||
134 | acpi_os_printf(" %s", acpi_ut_get_object_type_name(obj_desc)); | ||
135 | |||
136 | switch (obj_desc->common.type) { | ||
137 | case ACPI_TYPE_INTEGER: | ||
138 | |||
139 | acpi_os_printf(" %8.8X%8.8X", | ||
140 | ACPI_FORMAT_UINT64(obj_desc->integer.value)); | ||
141 | break; | ||
142 | |||
143 | case ACPI_TYPE_STRING: | ||
144 | |||
145 | acpi_os_printf("(%u) \"%.24s", | ||
146 | obj_desc->string.length, | ||
147 | obj_desc->string.pointer); | ||
148 | |||
149 | if (obj_desc->string.length > 24) { | ||
150 | acpi_os_printf("..."); | ||
151 | } else { | ||
152 | acpi_os_printf("\""); | ||
153 | } | ||
154 | break; | ||
155 | |||
156 | case ACPI_TYPE_BUFFER: | ||
157 | |||
158 | acpi_os_printf("(%u)", obj_desc->buffer.length); | ||
159 | for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) { | ||
160 | acpi_os_printf(" %2.2X", obj_desc->buffer.pointer[i]); | ||
161 | } | ||
162 | break; | ||
163 | |||
164 | default: | ||
165 | |||
166 | acpi_os_printf(" %p", obj_desc); | ||
167 | break; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | /******************************************************************************* | ||
172 | * | ||
173 | * FUNCTION: acpi_db_decode_node | ||
174 | * | ||
175 | * PARAMETERS: node - Object to be displayed | ||
176 | * | ||
177 | * RETURN: None | ||
178 | * | ||
179 | * DESCRIPTION: Short display of a namespace node | ||
180 | * | ||
181 | ******************************************************************************/ | ||
182 | |||
183 | static void acpi_db_decode_node(struct acpi_namespace_node *node) | ||
184 | { | ||
185 | |||
186 | acpi_os_printf("<Node> Name %4.4s", | ||
187 | acpi_ut_get_node_name(node)); | ||
188 | |||
189 | if (node->flags & ANOBJ_METHOD_ARG) { | ||
190 | acpi_os_printf(" [Method Arg]"); | ||
191 | } | ||
192 | if (node->flags & ANOBJ_METHOD_LOCAL) { | ||
193 | acpi_os_printf(" [Method Local]"); | ||
194 | } | ||
195 | |||
196 | switch (node->type) { | ||
197 | |||
198 | /* These types have no attached object */ | ||
199 | |||
200 | case ACPI_TYPE_DEVICE: | ||
201 | |||
202 | acpi_os_printf(" Device"); | ||
203 | break; | ||
204 | |||
205 | case ACPI_TYPE_THERMAL: | ||
206 | |||
207 | acpi_os_printf(" Thermal Zone"); | ||
208 | break; | ||
209 | |||
210 | default: | ||
211 | |||
212 | acpi_db_decode_internal_object(acpi_ns_get_attached_object | ||
213 | (node)); | ||
214 | break; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | /******************************************************************************* | ||
219 | * | ||
220 | * FUNCTION: acpi_db_display_internal_object | ||
221 | * | ||
222 | * PARAMETERS: obj_desc - Object to be displayed | ||
223 | * walk_state - Current walk state | ||
224 | * | ||
225 | * RETURN: None | ||
226 | * | ||
227 | * DESCRIPTION: Short display of an internal object | ||
228 | * | ||
229 | ******************************************************************************/ | ||
230 | |||
231 | void | ||
232 | acpi_db_display_internal_object(union acpi_operand_object *obj_desc, | ||
233 | struct acpi_walk_state *walk_state) | ||
234 | { | ||
235 | u8 type; | ||
236 | |||
237 | acpi_os_printf("%p ", obj_desc); | ||
238 | |||
239 | if (!obj_desc) { | ||
240 | acpi_os_printf("<Null Object>\n"); | ||
241 | return; | ||
242 | } | ||
243 | |||
244 | /* Decode the object type */ | ||
245 | |||
246 | switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) { | ||
247 | case ACPI_DESC_TYPE_PARSER: | ||
248 | |||
249 | acpi_os_printf("<Parser> "); | ||
250 | break; | ||
251 | |||
252 | case ACPI_DESC_TYPE_NAMED: | ||
253 | |||
254 | acpi_db_decode_node((struct acpi_namespace_node *)obj_desc); | ||
255 | break; | ||
256 | |||
257 | case ACPI_DESC_TYPE_OPERAND: | ||
258 | |||
259 | type = obj_desc->common.type; | ||
260 | if (type > ACPI_TYPE_LOCAL_MAX) { | ||
261 | acpi_os_printf(" Type %X [Invalid Type]", (u32)type); | ||
262 | return; | ||
263 | } | ||
264 | |||
265 | /* Decode the ACPI object type */ | ||
266 | |||
267 | switch (obj_desc->common.type) { | ||
268 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
269 | |||
270 | acpi_os_printf("[%s] ", | ||
271 | acpi_ut_get_reference_name(obj_desc)); | ||
272 | |||
273 | /* Decode the refererence */ | ||
274 | |||
275 | switch (obj_desc->reference.class) { | ||
276 | case ACPI_REFCLASS_LOCAL: | ||
277 | |||
278 | acpi_os_printf("%X ", | ||
279 | obj_desc->reference.value); | ||
280 | if (walk_state) { | ||
281 | obj_desc = walk_state->local_variables | ||
282 | [obj_desc->reference.value].object; | ||
283 | acpi_os_printf("%p", obj_desc); | ||
284 | acpi_db_decode_internal_object | ||
285 | (obj_desc); | ||
286 | } | ||
287 | break; | ||
288 | |||
289 | case ACPI_REFCLASS_ARG: | ||
290 | |||
291 | acpi_os_printf("%X ", | ||
292 | obj_desc->reference.value); | ||
293 | if (walk_state) { | ||
294 | obj_desc = walk_state->arguments | ||
295 | [obj_desc->reference.value].object; | ||
296 | acpi_os_printf("%p", obj_desc); | ||
297 | acpi_db_decode_internal_object | ||
298 | (obj_desc); | ||
299 | } | ||
300 | break; | ||
301 | |||
302 | case ACPI_REFCLASS_INDEX: | ||
303 | |||
304 | switch (obj_desc->reference.target_type) { | ||
305 | case ACPI_TYPE_BUFFER_FIELD: | ||
306 | |||
307 | acpi_os_printf("%p", | ||
308 | obj_desc->reference. | ||
309 | object); | ||
310 | acpi_db_decode_internal_object | ||
311 | (obj_desc->reference.object); | ||
312 | break; | ||
313 | |||
314 | case ACPI_TYPE_PACKAGE: | ||
315 | |||
316 | acpi_os_printf("%p", | ||
317 | obj_desc->reference. | ||
318 | where); | ||
319 | if (!obj_desc->reference.where) { | ||
320 | acpi_os_printf | ||
321 | (" Uninitialized WHERE pointer"); | ||
322 | } else { | ||
323 | acpi_db_decode_internal_object(* | ||
324 | (obj_desc-> | ||
325 | reference. | ||
326 | where)); | ||
327 | } | ||
328 | break; | ||
329 | |||
330 | default: | ||
331 | |||
332 | acpi_os_printf | ||
333 | ("Unknown index target type"); | ||
334 | break; | ||
335 | } | ||
336 | break; | ||
337 | |||
338 | case ACPI_REFCLASS_REFOF: | ||
339 | |||
340 | if (!obj_desc->reference.object) { | ||
341 | acpi_os_printf | ||
342 | ("Uninitialized reference subobject pointer"); | ||
343 | break; | ||
344 | } | ||
345 | |||
346 | /* Reference can be to a Node or an Operand object */ | ||
347 | |||
348 | switch (ACPI_GET_DESCRIPTOR_TYPE | ||
349 | (obj_desc->reference.object)) { | ||
350 | case ACPI_DESC_TYPE_NAMED: | ||
351 | |||
352 | acpi_db_decode_node(obj_desc->reference. | ||
353 | object); | ||
354 | break; | ||
355 | |||
356 | case ACPI_DESC_TYPE_OPERAND: | ||
357 | |||
358 | acpi_db_decode_internal_object | ||
359 | (obj_desc->reference.object); | ||
360 | break; | ||
361 | |||
362 | default: | ||
363 | break; | ||
364 | } | ||
365 | break; | ||
366 | |||
367 | case ACPI_REFCLASS_NAME: | ||
368 | |||
369 | acpi_db_decode_node(obj_desc->reference.node); | ||
370 | break; | ||
371 | |||
372 | case ACPI_REFCLASS_DEBUG: | ||
373 | case ACPI_REFCLASS_TABLE: | ||
374 | |||
375 | acpi_os_printf("\n"); | ||
376 | break; | ||
377 | |||
378 | default: /* Unknown reference class */ | ||
379 | |||
380 | acpi_os_printf("%2.2X\n", | ||
381 | obj_desc->reference.class); | ||
382 | break; | ||
383 | } | ||
384 | break; | ||
385 | |||
386 | default: | ||
387 | |||
388 | acpi_os_printf("<Obj> "); | ||
389 | acpi_db_decode_internal_object(obj_desc); | ||
390 | break; | ||
391 | } | ||
392 | break; | ||
393 | |||
394 | default: | ||
395 | |||
396 | acpi_os_printf("<Not a valid ACPI Object Descriptor> [%s]", | ||
397 | acpi_ut_get_descriptor_name(obj_desc)); | ||
398 | break; | ||
399 | } | ||
400 | |||
401 | acpi_os_printf("\n"); | ||
402 | } | ||
403 | |||
404 | /******************************************************************************* | ||
405 | * | ||
406 | * FUNCTION: acpi_db_decode_locals | ||
407 | * | ||
408 | * PARAMETERS: walk_state - State for current method | ||
409 | * | ||
410 | * RETURN: None | ||
411 | * | ||
412 | * DESCRIPTION: Display all locals for the currently running control method | ||
413 | * | ||
414 | ******************************************************************************/ | ||
415 | |||
416 | void acpi_db_decode_locals(struct acpi_walk_state *walk_state) | ||
417 | { | ||
418 | u32 i; | ||
419 | union acpi_operand_object *obj_desc; | ||
420 | struct acpi_namespace_node *node; | ||
421 | u8 display_locals = FALSE; | ||
422 | |||
423 | obj_desc = walk_state->method_desc; | ||
424 | node = walk_state->method_node; | ||
425 | |||
426 | if (!node) { | ||
427 | acpi_os_printf | ||
428 | ("No method node (Executing subtree for buffer or opregion)\n"); | ||
429 | return; | ||
430 | } | ||
431 | |||
432 | if (node->type != ACPI_TYPE_METHOD) { | ||
433 | acpi_os_printf("Executing subtree for Buffer/Package/Region\n"); | ||
434 | return; | ||
435 | } | ||
436 | |||
437 | /* Are any locals actually set? */ | ||
438 | |||
439 | for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) { | ||
440 | obj_desc = walk_state->local_variables[i].object; | ||
441 | if (obj_desc) { | ||
442 | display_locals = TRUE; | ||
443 | break; | ||
444 | } | ||
445 | } | ||
446 | |||
447 | /* If any are set, only display the ones that are set */ | ||
448 | |||
449 | if (display_locals) { | ||
450 | acpi_os_printf | ||
451 | ("\nInitialized Local Variables for method [%4.4s]:\n", | ||
452 | acpi_ut_get_node_name(node)); | ||
453 | |||
454 | for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) { | ||
455 | obj_desc = walk_state->local_variables[i].object; | ||
456 | if (obj_desc) { | ||
457 | acpi_os_printf(" Local%X: ", i); | ||
458 | acpi_db_display_internal_object(obj_desc, | ||
459 | walk_state); | ||
460 | } | ||
461 | } | ||
462 | } else { | ||
463 | acpi_os_printf | ||
464 | ("No Local Variables are initialized for method [%4.4s]\n", | ||
465 | acpi_ut_get_node_name(node)); | ||
466 | } | ||
467 | } | ||
468 | |||
469 | /******************************************************************************* | ||
470 | * | ||
471 | * FUNCTION: acpi_db_decode_arguments | ||
472 | * | ||
473 | * PARAMETERS: walk_state - State for current method | ||
474 | * | ||
475 | * RETURN: None | ||
476 | * | ||
477 | * DESCRIPTION: Display all arguments for the currently running control method | ||
478 | * | ||
479 | ******************************************************************************/ | ||
480 | |||
481 | void acpi_db_decode_arguments(struct acpi_walk_state *walk_state) | ||
482 | { | ||
483 | u32 i; | ||
484 | union acpi_operand_object *obj_desc; | ||
485 | struct acpi_namespace_node *node; | ||
486 | u8 display_args = FALSE; | ||
487 | |||
488 | node = walk_state->method_node; | ||
489 | obj_desc = walk_state->method_desc; | ||
490 | |||
491 | if (!node) { | ||
492 | acpi_os_printf | ||
493 | ("No method node (Executing subtree for buffer or opregion)\n"); | ||
494 | return; | ||
495 | } | ||
496 | |||
497 | if (node->type != ACPI_TYPE_METHOD) { | ||
498 | acpi_os_printf("Executing subtree for Buffer/Package/Region\n"); | ||
499 | return; | ||
500 | } | ||
501 | |||
502 | /* Are any arguments actually set? */ | ||
503 | |||
504 | for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) { | ||
505 | obj_desc = walk_state->arguments[i].object; | ||
506 | if (obj_desc) { | ||
507 | display_args = TRUE; | ||
508 | break; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | /* If any are set, only display the ones that are set */ | ||
513 | |||
514 | if (display_args) { | ||
515 | acpi_os_printf("Initialized Arguments for Method [%4.4s]: " | ||
516 | "(%X arguments defined for method invocation)\n", | ||
517 | acpi_ut_get_node_name(node), | ||
518 | obj_desc->method.param_count); | ||
519 | |||
520 | for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) { | ||
521 | obj_desc = walk_state->arguments[i].object; | ||
522 | if (obj_desc) { | ||
523 | acpi_os_printf(" Arg%u: ", i); | ||
524 | acpi_db_display_internal_object(obj_desc, | ||
525 | walk_state); | ||
526 | } | ||
527 | } | ||
528 | } else { | ||
529 | acpi_os_printf | ||
530 | ("No Arguments are initialized for method [%4.4s]\n", | ||
531 | acpi_ut_get_node_name(node)); | ||
532 | } | ||
533 | } | ||
diff --git a/drivers/acpi/acpica/dbstats.c b/drivers/acpi/acpica/dbstats.c new file mode 100644 index 000000000000..4ba0a20811eb --- /dev/null +++ b/drivers/acpi/acpica/dbstats.c | |||
@@ -0,0 +1,546 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbstats - Generation and display of ACPI table statistics | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acdebug.h" | ||
47 | #include "acnamesp.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
50 | ACPI_MODULE_NAME("dbstats") | ||
51 | |||
52 | /* Local prototypes */ | ||
53 | static void acpi_db_count_namespace_objects(void); | ||
54 | |||
55 | static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc); | ||
56 | |||
57 | static acpi_status | ||
58 | acpi_db_classify_one_object(acpi_handle obj_handle, | ||
59 | u32 nesting_level, | ||
60 | void *context, void **return_value); | ||
61 | |||
62 | #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE | ||
63 | static void acpi_db_list_info(struct acpi_memory_list *list); | ||
64 | #endif | ||
65 | |||
66 | /* | ||
67 | * Statistics subcommands | ||
68 | */ | ||
69 | static struct acpi_db_argument_info acpi_db_stat_types[] = { | ||
70 | {"ALLOCATIONS"}, | ||
71 | {"OBJECTS"}, | ||
72 | {"MEMORY"}, | ||
73 | {"MISC"}, | ||
74 | {"TABLES"}, | ||
75 | {"SIZES"}, | ||
76 | {"STACK"}, | ||
77 | {NULL} /* Must be null terminated */ | ||
78 | }; | ||
79 | |||
80 | #define CMD_STAT_ALLOCATIONS 0 | ||
81 | #define CMD_STAT_OBJECTS 1 | ||
82 | #define CMD_STAT_MEMORY 2 | ||
83 | #define CMD_STAT_MISC 3 | ||
84 | #define CMD_STAT_TABLES 4 | ||
85 | #define CMD_STAT_SIZES 5 | ||
86 | #define CMD_STAT_STACK 6 | ||
87 | |||
88 | #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE | ||
89 | /******************************************************************************* | ||
90 | * | ||
91 | * FUNCTION: acpi_db_list_info | ||
92 | * | ||
93 | * PARAMETERS: list - Memory list/cache to be displayed | ||
94 | * | ||
95 | * RETURN: None | ||
96 | * | ||
97 | * DESCRIPTION: Display information about the input memory list or cache. | ||
98 | * | ||
99 | ******************************************************************************/ | ||
100 | |||
101 | static void acpi_db_list_info(struct acpi_memory_list *list) | ||
102 | { | ||
103 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
104 | u32 outstanding; | ||
105 | #endif | ||
106 | |||
107 | acpi_os_printf("\n%s\n", list->list_name); | ||
108 | |||
109 | /* max_depth > 0 indicates a cache object */ | ||
110 | |||
111 | if (list->max_depth > 0) { | ||
112 | acpi_os_printf | ||
113 | (" Cache: [Depth MaxD Avail Size] " | ||
114 | "%8.2X %8.2X %8.2X %8.2X\n", list->current_depth, | ||
115 | list->max_depth, list->max_depth - list->current_depth, | ||
116 | (list->current_depth * list->object_size)); | ||
117 | } | ||
118 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
119 | if (list->max_depth > 0) { | ||
120 | acpi_os_printf | ||
121 | (" Cache: [Requests Hits Misses ObjSize] " | ||
122 | "%8.2X %8.2X %8.2X %8.2X\n", list->requests, list->hits, | ||
123 | list->requests - list->hits, list->object_size); | ||
124 | } | ||
125 | |||
126 | outstanding = acpi_db_get_cache_info(list); | ||
127 | |||
128 | if (list->object_size) { | ||
129 | acpi_os_printf | ||
130 | (" Mem: [Alloc Free Max CurSize Outstanding] " | ||
131 | "%8.2X %8.2X %8.2X %8.2X %8.2X\n", list->total_allocated, | ||
132 | list->total_freed, list->max_occupied, | ||
133 | outstanding * list->object_size, outstanding); | ||
134 | } else { | ||
135 | acpi_os_printf | ||
136 | (" Mem: [Alloc Free Max CurSize Outstanding Total] " | ||
137 | "%8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n", | ||
138 | list->total_allocated, list->total_freed, | ||
139 | list->max_occupied, list->current_total_size, outstanding, | ||
140 | list->total_size); | ||
141 | } | ||
142 | #endif | ||
143 | } | ||
144 | #endif | ||
145 | |||
146 | /******************************************************************************* | ||
147 | * | ||
148 | * FUNCTION: acpi_db_enumerate_object | ||
149 | * | ||
150 | * PARAMETERS: obj_desc - Object to be counted | ||
151 | * | ||
152 | * RETURN: None | ||
153 | * | ||
154 | * DESCRIPTION: Add this object to the global counts, by object type. | ||
155 | * Limited recursion handles subobjects and packages, and this | ||
156 | * is probably acceptable within the AML debugger only. | ||
157 | * | ||
158 | ******************************************************************************/ | ||
159 | |||
160 | static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc) | ||
161 | { | ||
162 | u32 i; | ||
163 | |||
164 | if (!obj_desc) { | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | /* Enumerate this object first */ | ||
169 | |||
170 | acpi_gbl_num_objects++; | ||
171 | |||
172 | if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) { | ||
173 | acpi_gbl_obj_type_count_misc++; | ||
174 | } else { | ||
175 | acpi_gbl_obj_type_count[obj_desc->common.type]++; | ||
176 | } | ||
177 | |||
178 | /* Count the sub-objects */ | ||
179 | |||
180 | switch (obj_desc->common.type) { | ||
181 | case ACPI_TYPE_PACKAGE: | ||
182 | |||
183 | for (i = 0; i < obj_desc->package.count; i++) { | ||
184 | acpi_db_enumerate_object(obj_desc->package.elements[i]); | ||
185 | } | ||
186 | break; | ||
187 | |||
188 | case ACPI_TYPE_DEVICE: | ||
189 | |||
190 | acpi_db_enumerate_object(obj_desc->device.notify_list[0]); | ||
191 | acpi_db_enumerate_object(obj_desc->device.notify_list[1]); | ||
192 | acpi_db_enumerate_object(obj_desc->device.handler); | ||
193 | break; | ||
194 | |||
195 | case ACPI_TYPE_BUFFER_FIELD: | ||
196 | |||
197 | if (acpi_ns_get_secondary_object(obj_desc)) { | ||
198 | acpi_gbl_obj_type_count[ACPI_TYPE_BUFFER_FIELD]++; | ||
199 | } | ||
200 | break; | ||
201 | |||
202 | case ACPI_TYPE_REGION: | ||
203 | |||
204 | acpi_gbl_obj_type_count[ACPI_TYPE_LOCAL_REGION_FIELD]++; | ||
205 | acpi_db_enumerate_object(obj_desc->region.handler); | ||
206 | break; | ||
207 | |||
208 | case ACPI_TYPE_POWER: | ||
209 | |||
210 | acpi_db_enumerate_object(obj_desc->power_resource. | ||
211 | notify_list[0]); | ||
212 | acpi_db_enumerate_object(obj_desc->power_resource. | ||
213 | notify_list[1]); | ||
214 | break; | ||
215 | |||
216 | case ACPI_TYPE_PROCESSOR: | ||
217 | |||
218 | acpi_db_enumerate_object(obj_desc->processor.notify_list[0]); | ||
219 | acpi_db_enumerate_object(obj_desc->processor.notify_list[1]); | ||
220 | acpi_db_enumerate_object(obj_desc->processor.handler); | ||
221 | break; | ||
222 | |||
223 | case ACPI_TYPE_THERMAL: | ||
224 | |||
225 | acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[0]); | ||
226 | acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[1]); | ||
227 | acpi_db_enumerate_object(obj_desc->thermal_zone.handler); | ||
228 | break; | ||
229 | |||
230 | default: | ||
231 | |||
232 | break; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | /******************************************************************************* | ||
237 | * | ||
238 | * FUNCTION: acpi_db_classify_one_object | ||
239 | * | ||
240 | * PARAMETERS: Callback for walk_namespace | ||
241 | * | ||
242 | * RETURN: Status | ||
243 | * | ||
244 | * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and | ||
245 | * the parent namespace node. | ||
246 | * | ||
247 | ******************************************************************************/ | ||
248 | |||
249 | static acpi_status | ||
250 | acpi_db_classify_one_object(acpi_handle obj_handle, | ||
251 | u32 nesting_level, | ||
252 | void *context, void **return_value) | ||
253 | { | ||
254 | struct acpi_namespace_node *node; | ||
255 | union acpi_operand_object *obj_desc; | ||
256 | u32 type; | ||
257 | |||
258 | acpi_gbl_num_nodes++; | ||
259 | |||
260 | node = (struct acpi_namespace_node *)obj_handle; | ||
261 | obj_desc = acpi_ns_get_attached_object(node); | ||
262 | |||
263 | acpi_db_enumerate_object(obj_desc); | ||
264 | |||
265 | type = node->type; | ||
266 | if (type > ACPI_TYPE_NS_NODE_MAX) { | ||
267 | acpi_gbl_node_type_count_misc++; | ||
268 | } else { | ||
269 | acpi_gbl_node_type_count[type]++; | ||
270 | } | ||
271 | |||
272 | return (AE_OK); | ||
273 | |||
274 | #ifdef ACPI_FUTURE_IMPLEMENTATION | ||
275 | |||
276 | /* TBD: These need to be counted during the initial parsing phase */ | ||
277 | |||
278 | if (acpi_ps_is_named_op(op->opcode)) { | ||
279 | num_nodes++; | ||
280 | } | ||
281 | |||
282 | if (is_method) { | ||
283 | num_method_elements++; | ||
284 | } | ||
285 | |||
286 | num_grammar_elements++; | ||
287 | op = acpi_ps_get_depth_next(root, op); | ||
288 | |||
289 | size_of_parse_tree = (num_grammar_elements - num_method_elements) * | ||
290 | (u32)sizeof(union acpi_parse_object); | ||
291 | size_of_method_trees = | ||
292 | num_method_elements * (u32)sizeof(union acpi_parse_object); | ||
293 | size_of_node_entries = | ||
294 | num_nodes * (u32)sizeof(struct acpi_namespace_node); | ||
295 | size_of_acpi_objects = | ||
296 | num_nodes * (u32)sizeof(union acpi_operand_object); | ||
297 | #endif | ||
298 | } | ||
299 | |||
300 | /******************************************************************************* | ||
301 | * | ||
302 | * FUNCTION: acpi_db_count_namespace_objects | ||
303 | * | ||
304 | * PARAMETERS: None | ||
305 | * | ||
306 | * RETURN: None | ||
307 | * | ||
308 | * DESCRIPTION: Count and classify the entire namespace, including all | ||
309 | * namespace nodes and attached objects. | ||
310 | * | ||
311 | ******************************************************************************/ | ||
312 | |||
313 | static void acpi_db_count_namespace_objects(void) | ||
314 | { | ||
315 | u32 i; | ||
316 | |||
317 | acpi_gbl_num_nodes = 0; | ||
318 | acpi_gbl_num_objects = 0; | ||
319 | |||
320 | acpi_gbl_obj_type_count_misc = 0; | ||
321 | for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX - 1); i++) { | ||
322 | acpi_gbl_obj_type_count[i] = 0; | ||
323 | acpi_gbl_node_type_count[i] = 0; | ||
324 | } | ||
325 | |||
326 | (void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
327 | ACPI_UINT32_MAX, FALSE, | ||
328 | acpi_db_classify_one_object, NULL, NULL, | ||
329 | NULL); | ||
330 | } | ||
331 | |||
332 | /******************************************************************************* | ||
333 | * | ||
334 | * FUNCTION: acpi_db_display_statistics | ||
335 | * | ||
336 | * PARAMETERS: type_arg - Subcommand | ||
337 | * | ||
338 | * RETURN: Status | ||
339 | * | ||
340 | * DESCRIPTION: Display various statistics | ||
341 | * | ||
342 | ******************************************************************************/ | ||
343 | |||
344 | acpi_status acpi_db_display_statistics(char *type_arg) | ||
345 | { | ||
346 | u32 i; | ||
347 | u32 temp; | ||
348 | |||
349 | acpi_ut_strupr(type_arg); | ||
350 | temp = acpi_db_match_argument(type_arg, acpi_db_stat_types); | ||
351 | if (temp == ACPI_TYPE_NOT_FOUND) { | ||
352 | acpi_os_printf("Invalid or unsupported argument\n"); | ||
353 | return (AE_OK); | ||
354 | } | ||
355 | |||
356 | switch (temp) { | ||
357 | case CMD_STAT_ALLOCATIONS: | ||
358 | |||
359 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
360 | acpi_ut_dump_allocation_info(); | ||
361 | #endif | ||
362 | break; | ||
363 | |||
364 | case CMD_STAT_TABLES: | ||
365 | |||
366 | acpi_os_printf("ACPI Table Information (not implemented):\n\n"); | ||
367 | break; | ||
368 | |||
369 | case CMD_STAT_OBJECTS: | ||
370 | |||
371 | acpi_db_count_namespace_objects(); | ||
372 | |||
373 | acpi_os_printf | ||
374 | ("\nObjects defined in the current namespace:\n\n"); | ||
375 | |||
376 | acpi_os_printf("%16.16s %10.10s %10.10s\n", | ||
377 | "ACPI_TYPE", "NODES", "OBJECTS"); | ||
378 | |||
379 | for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++) { | ||
380 | acpi_os_printf("%16.16s % 10ld% 10ld\n", | ||
381 | acpi_ut_get_type_name(i), | ||
382 | acpi_gbl_node_type_count[i], | ||
383 | acpi_gbl_obj_type_count[i]); | ||
384 | } | ||
385 | acpi_os_printf("%16.16s % 10ld% 10ld\n", "Misc/Unknown", | ||
386 | acpi_gbl_node_type_count_misc, | ||
387 | acpi_gbl_obj_type_count_misc); | ||
388 | |||
389 | acpi_os_printf("%16.16s % 10ld% 10ld\n", "TOTALS:", | ||
390 | acpi_gbl_num_nodes, acpi_gbl_num_objects); | ||
391 | break; | ||
392 | |||
393 | case CMD_STAT_MEMORY: | ||
394 | |||
395 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
396 | acpi_os_printf | ||
397 | ("\n----Object Statistics (all in hex)---------\n"); | ||
398 | |||
399 | acpi_db_list_info(acpi_gbl_global_list); | ||
400 | acpi_db_list_info(acpi_gbl_ns_node_list); | ||
401 | #endif | ||
402 | |||
403 | #ifdef ACPI_USE_LOCAL_CACHE | ||
404 | acpi_os_printf | ||
405 | ("\n----Cache Statistics (all in hex)---------\n"); | ||
406 | acpi_db_list_info(acpi_gbl_operand_cache); | ||
407 | acpi_db_list_info(acpi_gbl_ps_node_cache); | ||
408 | acpi_db_list_info(acpi_gbl_ps_node_ext_cache); | ||
409 | acpi_db_list_info(acpi_gbl_state_cache); | ||
410 | #endif | ||
411 | |||
412 | break; | ||
413 | |||
414 | case CMD_STAT_MISC: | ||
415 | |||
416 | acpi_os_printf("\nMiscellaneous Statistics:\n\n"); | ||
417 | acpi_os_printf("Calls to AcpiPsFind:.. ........% 7ld\n", | ||
418 | acpi_gbl_ps_find_count); | ||
419 | acpi_os_printf("Calls to AcpiNsLookup:..........% 7ld\n", | ||
420 | acpi_gbl_ns_lookup_count); | ||
421 | |||
422 | acpi_os_printf("\n"); | ||
423 | |||
424 | acpi_os_printf("Mutex usage:\n\n"); | ||
425 | for (i = 0; i < ACPI_NUM_MUTEX; i++) { | ||
426 | acpi_os_printf("%-28s: % 7ld\n", | ||
427 | acpi_ut_get_mutex_name(i), | ||
428 | acpi_gbl_mutex_info[i].use_count); | ||
429 | } | ||
430 | break; | ||
431 | |||
432 | case CMD_STAT_SIZES: | ||
433 | |||
434 | acpi_os_printf("\nInternal object sizes:\n\n"); | ||
435 | |||
436 | acpi_os_printf("Common %3d\n", | ||
437 | sizeof(struct acpi_object_common)); | ||
438 | acpi_os_printf("Number %3d\n", | ||
439 | sizeof(struct acpi_object_integer)); | ||
440 | acpi_os_printf("String %3d\n", | ||
441 | sizeof(struct acpi_object_string)); | ||
442 | acpi_os_printf("Buffer %3d\n", | ||
443 | sizeof(struct acpi_object_buffer)); | ||
444 | acpi_os_printf("Package %3d\n", | ||
445 | sizeof(struct acpi_object_package)); | ||
446 | acpi_os_printf("BufferField %3d\n", | ||
447 | sizeof(struct acpi_object_buffer_field)); | ||
448 | acpi_os_printf("Device %3d\n", | ||
449 | sizeof(struct acpi_object_device)); | ||
450 | acpi_os_printf("Event %3d\n", | ||
451 | sizeof(struct acpi_object_event)); | ||
452 | acpi_os_printf("Method %3d\n", | ||
453 | sizeof(struct acpi_object_method)); | ||
454 | acpi_os_printf("Mutex %3d\n", | ||
455 | sizeof(struct acpi_object_mutex)); | ||
456 | acpi_os_printf("Region %3d\n", | ||
457 | sizeof(struct acpi_object_region)); | ||
458 | acpi_os_printf("PowerResource %3d\n", | ||
459 | sizeof(struct acpi_object_power_resource)); | ||
460 | acpi_os_printf("Processor %3d\n", | ||
461 | sizeof(struct acpi_object_processor)); | ||
462 | acpi_os_printf("ThermalZone %3d\n", | ||
463 | sizeof(struct acpi_object_thermal_zone)); | ||
464 | acpi_os_printf("RegionField %3d\n", | ||
465 | sizeof(struct acpi_object_region_field)); | ||
466 | acpi_os_printf("BankField %3d\n", | ||
467 | sizeof(struct acpi_object_bank_field)); | ||
468 | acpi_os_printf("IndexField %3d\n", | ||
469 | sizeof(struct acpi_object_index_field)); | ||
470 | acpi_os_printf("Reference %3d\n", | ||
471 | sizeof(struct acpi_object_reference)); | ||
472 | acpi_os_printf("Notify %3d\n", | ||
473 | sizeof(struct acpi_object_notify_handler)); | ||
474 | acpi_os_printf("AddressSpace %3d\n", | ||
475 | sizeof(struct acpi_object_addr_handler)); | ||
476 | acpi_os_printf("Extra %3d\n", | ||
477 | sizeof(struct acpi_object_extra)); | ||
478 | acpi_os_printf("Data %3d\n", | ||
479 | sizeof(struct acpi_object_data)); | ||
480 | |||
481 | acpi_os_printf("\n"); | ||
482 | |||
483 | acpi_os_printf("ParseObject %3d\n", | ||
484 | sizeof(struct acpi_parse_obj_common)); | ||
485 | acpi_os_printf("ParseObjectNamed %3d\n", | ||
486 | sizeof(struct acpi_parse_obj_named)); | ||
487 | acpi_os_printf("ParseObjectAsl %3d\n", | ||
488 | sizeof(struct acpi_parse_obj_asl)); | ||
489 | acpi_os_printf("OperandObject %3d\n", | ||
490 | sizeof(union acpi_operand_object)); | ||
491 | acpi_os_printf("NamespaceNode %3d\n", | ||
492 | sizeof(struct acpi_namespace_node)); | ||
493 | acpi_os_printf("AcpiObject %3d\n", | ||
494 | sizeof(union acpi_object)); | ||
495 | |||
496 | acpi_os_printf("\n"); | ||
497 | |||
498 | acpi_os_printf("Generic State %3d\n", | ||
499 | sizeof(union acpi_generic_state)); | ||
500 | acpi_os_printf("Common State %3d\n", | ||
501 | sizeof(struct acpi_common_state)); | ||
502 | acpi_os_printf("Control State %3d\n", | ||
503 | sizeof(struct acpi_control_state)); | ||
504 | acpi_os_printf("Update State %3d\n", | ||
505 | sizeof(struct acpi_update_state)); | ||
506 | acpi_os_printf("Scope State %3d\n", | ||
507 | sizeof(struct acpi_scope_state)); | ||
508 | acpi_os_printf("Parse Scope %3d\n", | ||
509 | sizeof(struct acpi_pscope_state)); | ||
510 | acpi_os_printf("Package State %3d\n", | ||
511 | sizeof(struct acpi_pkg_state)); | ||
512 | acpi_os_printf("Thread State %3d\n", | ||
513 | sizeof(struct acpi_thread_state)); | ||
514 | acpi_os_printf("Result Values %3d\n", | ||
515 | sizeof(struct acpi_result_values)); | ||
516 | acpi_os_printf("Notify Info %3d\n", | ||
517 | sizeof(struct acpi_notify_info)); | ||
518 | break; | ||
519 | |||
520 | case CMD_STAT_STACK: | ||
521 | #if defined(ACPI_DEBUG_OUTPUT) | ||
522 | |||
523 | temp = | ||
524 | (u32)ACPI_PTR_DIFF(acpi_gbl_entry_stack_pointer, | ||
525 | acpi_gbl_lowest_stack_pointer); | ||
526 | |||
527 | acpi_os_printf("\nSubsystem Stack Usage:\n\n"); | ||
528 | acpi_os_printf("Entry Stack Pointer %p\n", | ||
529 | acpi_gbl_entry_stack_pointer); | ||
530 | acpi_os_printf("Lowest Stack Pointer %p\n", | ||
531 | acpi_gbl_lowest_stack_pointer); | ||
532 | acpi_os_printf("Stack Use %X (%u)\n", temp, | ||
533 | temp); | ||
534 | acpi_os_printf("Deepest Procedure Nesting %u\n", | ||
535 | acpi_gbl_deepest_nesting); | ||
536 | #endif | ||
537 | break; | ||
538 | |||
539 | default: | ||
540 | |||
541 | break; | ||
542 | } | ||
543 | |||
544 | acpi_os_printf("\n"); | ||
545 | return (AE_OK); | ||
546 | } | ||
diff --git a/drivers/acpi/acpica/dbtest.c b/drivers/acpi/acpica/dbtest.c new file mode 100644 index 000000000000..10ea8bf9b810 --- /dev/null +++ b/drivers/acpi/acpica/dbtest.c | |||
@@ -0,0 +1,1057 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbtest - Various debug-related tests | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acdebug.h" | ||
47 | #include "acnamesp.h" | ||
48 | #include "acpredef.h" | ||
49 | |||
50 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
51 | ACPI_MODULE_NAME("dbtest") | ||
52 | |||
53 | /* Local prototypes */ | ||
54 | static void acpi_db_test_all_objects(void); | ||
55 | |||
56 | static acpi_status | ||
57 | acpi_db_test_one_object(acpi_handle obj_handle, | ||
58 | u32 nesting_level, void *context, void **return_value); | ||
59 | |||
60 | static acpi_status | ||
61 | acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length); | ||
62 | |||
63 | static acpi_status | ||
64 | acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length); | ||
65 | |||
66 | static acpi_status | ||
67 | acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length); | ||
68 | |||
69 | static acpi_status | ||
70 | acpi_db_read_from_object(struct acpi_namespace_node *node, | ||
71 | acpi_object_type expected_type, | ||
72 | union acpi_object **value); | ||
73 | |||
74 | static acpi_status | ||
75 | acpi_db_write_to_object(struct acpi_namespace_node *node, | ||
76 | union acpi_object *value); | ||
77 | |||
78 | static void acpi_db_evaluate_all_predefined_names(char *count_arg); | ||
79 | |||
80 | static acpi_status | ||
81 | acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle, | ||
82 | u32 nesting_level, | ||
83 | void *context, void **return_value); | ||
84 | |||
85 | /* | ||
86 | * Test subcommands | ||
87 | */ | ||
88 | static struct acpi_db_argument_info acpi_db_test_types[] = { | ||
89 | {"OBJECTS"}, | ||
90 | {"PREDEFINED"}, | ||
91 | {NULL} /* Must be null terminated */ | ||
92 | }; | ||
93 | |||
94 | #define CMD_TEST_OBJECTS 0 | ||
95 | #define CMD_TEST_PREDEFINED 1 | ||
96 | |||
97 | #define BUFFER_FILL_VALUE 0xFF | ||
98 | |||
99 | /* | ||
100 | * Support for the special debugger read/write control methods. | ||
101 | * These methods are installed into the current namespace and are | ||
102 | * used to read and write the various namespace objects. The point | ||
103 | * is to force the AML interpreter do all of the work. | ||
104 | */ | ||
105 | #define ACPI_DB_READ_METHOD "\\_T98" | ||
106 | #define ACPI_DB_WRITE_METHOD "\\_T99" | ||
107 | |||
108 | static acpi_handle read_handle = NULL; | ||
109 | static acpi_handle write_handle = NULL; | ||
110 | |||
111 | /* ASL Definitions of the debugger read/write control methods */ | ||
112 | |||
113 | #if 0 | ||
114 | definition_block("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001) | ||
115 | { | ||
116 | method(_T98, 1, not_serialized) { /* Read */ | ||
117 | return (de_ref_of(arg0)) | ||
118 | } | ||
119 | } | ||
120 | |||
121 | definition_block("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001) | ||
122 | { | ||
123 | method(_T99, 2, not_serialized) { /* Write */ | ||
124 | store(arg1, arg0) | ||
125 | } | ||
126 | } | ||
127 | #endif | ||
128 | |||
129 | static unsigned char read_method_code[] = { | ||
130 | 0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000 "SSDT...." */ | ||
131 | 0x02, 0xC9, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008 "..Intel." */ | ||
132 | 0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010 "DEBUG..." */ | ||
133 | 0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018 "....INTL" */ | ||
134 | 0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020 "... .._T" */ | ||
135 | 0x39, 0x38, 0x01, 0xA4, 0x83, 0x68 /* 00000028 "98...h" */ | ||
136 | }; | ||
137 | |||
138 | static unsigned char write_method_code[] = { | ||
139 | 0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000 "SSDT...." */ | ||
140 | 0x02, 0x15, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008 "..Intel." */ | ||
141 | 0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010 "DEBUG..." */ | ||
142 | 0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018 "....INTL" */ | ||
143 | 0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020 "... .._T" */ | ||
144 | 0x39, 0x39, 0x02, 0x70, 0x69, 0x68 /* 00000028 "99.pih" */ | ||
145 | }; | ||
146 | |||
147 | /******************************************************************************* | ||
148 | * | ||
149 | * FUNCTION: acpi_db_execute_test | ||
150 | * | ||
151 | * PARAMETERS: type_arg - Subcommand | ||
152 | * | ||
153 | * RETURN: None | ||
154 | * | ||
155 | * DESCRIPTION: Execute various debug tests. | ||
156 | * | ||
157 | * Note: Code is prepared for future expansion of the TEST command. | ||
158 | * | ||
159 | ******************************************************************************/ | ||
160 | |||
161 | void acpi_db_execute_test(char *type_arg) | ||
162 | { | ||
163 | u32 temp; | ||
164 | |||
165 | acpi_ut_strupr(type_arg); | ||
166 | temp = acpi_db_match_argument(type_arg, acpi_db_test_types); | ||
167 | if (temp == ACPI_TYPE_NOT_FOUND) { | ||
168 | acpi_os_printf("Invalid or unsupported argument\n"); | ||
169 | return; | ||
170 | } | ||
171 | |||
172 | switch (temp) { | ||
173 | case CMD_TEST_OBJECTS: | ||
174 | |||
175 | acpi_db_test_all_objects(); | ||
176 | break; | ||
177 | |||
178 | case CMD_TEST_PREDEFINED: | ||
179 | |||
180 | acpi_db_evaluate_all_predefined_names(NULL); | ||
181 | break; | ||
182 | |||
183 | default: | ||
184 | break; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | /******************************************************************************* | ||
189 | * | ||
190 | * FUNCTION: acpi_db_test_all_objects | ||
191 | * | ||
192 | * PARAMETERS: None | ||
193 | * | ||
194 | * RETURN: None | ||
195 | * | ||
196 | * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the | ||
197 | * namespace by reading/writing/comparing all data objects such | ||
198 | * as integers, strings, buffers, fields, buffer fields, etc. | ||
199 | * | ||
200 | ******************************************************************************/ | ||
201 | |||
202 | static void acpi_db_test_all_objects(void) | ||
203 | { | ||
204 | acpi_status status; | ||
205 | |||
206 | /* Install the debugger read-object control method if necessary */ | ||
207 | |||
208 | if (!read_handle) { | ||
209 | status = acpi_install_method(read_method_code); | ||
210 | if (ACPI_FAILURE(status)) { | ||
211 | acpi_os_printf | ||
212 | ("%s, Could not install debugger read method\n", | ||
213 | acpi_format_exception(status)); | ||
214 | return; | ||
215 | } | ||
216 | |||
217 | status = | ||
218 | acpi_get_handle(NULL, ACPI_DB_READ_METHOD, &read_handle); | ||
219 | if (ACPI_FAILURE(status)) { | ||
220 | acpi_os_printf | ||
221 | ("Could not obtain handle for debug method %s\n", | ||
222 | ACPI_DB_READ_METHOD); | ||
223 | return; | ||
224 | } | ||
225 | } | ||
226 | |||
227 | /* Install the debugger write-object control method if necessary */ | ||
228 | |||
229 | if (!write_handle) { | ||
230 | status = acpi_install_method(write_method_code); | ||
231 | if (ACPI_FAILURE(status)) { | ||
232 | acpi_os_printf | ||
233 | ("%s, Could not install debugger write method\n", | ||
234 | acpi_format_exception(status)); | ||
235 | return; | ||
236 | } | ||
237 | |||
238 | status = | ||
239 | acpi_get_handle(NULL, ACPI_DB_WRITE_METHOD, &write_handle); | ||
240 | if (ACPI_FAILURE(status)) { | ||
241 | acpi_os_printf | ||
242 | ("Could not obtain handle for debug method %s\n", | ||
243 | ACPI_DB_WRITE_METHOD); | ||
244 | return; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | /* Walk the entire namespace, testing each supported named data object */ | ||
249 | |||
250 | (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
251 | ACPI_UINT32_MAX, acpi_db_test_one_object, | ||
252 | NULL, NULL, NULL); | ||
253 | } | ||
254 | |||
255 | /******************************************************************************* | ||
256 | * | ||
257 | * FUNCTION: acpi_db_test_one_object | ||
258 | * | ||
259 | * PARAMETERS: acpi_walk_callback | ||
260 | * | ||
261 | * RETURN: Status | ||
262 | * | ||
263 | * DESCRIPTION: Test one namespace object. Supported types are Integer, | ||
264 | * String, Buffer, buffer_field, and field_unit. All other object | ||
265 | * types are simply ignored. | ||
266 | * | ||
267 | * Note: Support for Packages is not implemented. | ||
268 | * | ||
269 | ******************************************************************************/ | ||
270 | |||
271 | static acpi_status | ||
272 | acpi_db_test_one_object(acpi_handle obj_handle, | ||
273 | u32 nesting_level, void *context, void **return_value) | ||
274 | { | ||
275 | struct acpi_namespace_node *node; | ||
276 | union acpi_operand_object *obj_desc; | ||
277 | union acpi_operand_object *region_obj; | ||
278 | acpi_object_type local_type; | ||
279 | u32 bit_length = 0; | ||
280 | u32 byte_length = 0; | ||
281 | acpi_status status = AE_OK; | ||
282 | |||
283 | node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); | ||
284 | obj_desc = node->object; | ||
285 | |||
286 | /* | ||
287 | * For the supported types, get the actual bit length or | ||
288 | * byte length. Map the type to one of Integer/String/Buffer. | ||
289 | */ | ||
290 | switch (node->type) { | ||
291 | case ACPI_TYPE_INTEGER: | ||
292 | |||
293 | /* Integer width is either 32 or 64 */ | ||
294 | |||
295 | local_type = ACPI_TYPE_INTEGER; | ||
296 | bit_length = acpi_gbl_integer_bit_width; | ||
297 | break; | ||
298 | |||
299 | case ACPI_TYPE_STRING: | ||
300 | |||
301 | local_type = ACPI_TYPE_STRING; | ||
302 | byte_length = obj_desc->string.length; | ||
303 | break; | ||
304 | |||
305 | case ACPI_TYPE_BUFFER: | ||
306 | |||
307 | local_type = ACPI_TYPE_BUFFER; | ||
308 | byte_length = obj_desc->buffer.length; | ||
309 | bit_length = byte_length * 8; | ||
310 | break; | ||
311 | |||
312 | case ACPI_TYPE_FIELD_UNIT: | ||
313 | case ACPI_TYPE_BUFFER_FIELD: | ||
314 | case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
315 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | ||
316 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
317 | |||
318 | local_type = ACPI_TYPE_INTEGER; | ||
319 | if (obj_desc) { | ||
320 | /* | ||
321 | * Returned object will be a Buffer if the field length | ||
322 | * is larger than the size of an Integer (32 or 64 bits | ||
323 | * depending on the DSDT version). | ||
324 | */ | ||
325 | bit_length = obj_desc->common_field.bit_length; | ||
326 | byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length); | ||
327 | if (bit_length > acpi_gbl_integer_bit_width) { | ||
328 | local_type = ACPI_TYPE_BUFFER; | ||
329 | } | ||
330 | } | ||
331 | break; | ||
332 | |||
333 | default: | ||
334 | |||
335 | /* Ignore all other types */ | ||
336 | |||
337 | return (AE_OK); | ||
338 | } | ||
339 | |||
340 | /* Emit the common prefix: Type:Name */ | ||
341 | |||
342 | acpi_os_printf("%14s: %4.4s", | ||
343 | acpi_ut_get_type_name(node->type), node->name.ascii); | ||
344 | if (!obj_desc) { | ||
345 | acpi_os_printf(" Ignoring, no attached object\n"); | ||
346 | return (AE_OK); | ||
347 | } | ||
348 | |||
349 | /* | ||
350 | * Check for unsupported region types. Note: acpi_exec simulates | ||
351 | * access to system_memory, system_IO, PCI_Config, and EC. | ||
352 | */ | ||
353 | switch (node->type) { | ||
354 | case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
355 | |||
356 | region_obj = obj_desc->field.region_obj; | ||
357 | switch (region_obj->region.space_id) { | ||
358 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | ||
359 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
360 | case ACPI_ADR_SPACE_PCI_CONFIG: | ||
361 | case ACPI_ADR_SPACE_EC: | ||
362 | |||
363 | break; | ||
364 | |||
365 | default: | ||
366 | |||
367 | acpi_os_printf | ||
368 | (" %s space is not supported [%4.4s]\n", | ||
369 | acpi_ut_get_region_name(region_obj->region. | ||
370 | space_id), | ||
371 | region_obj->region.node->name.ascii); | ||
372 | return (AE_OK); | ||
373 | } | ||
374 | break; | ||
375 | |||
376 | default: | ||
377 | break; | ||
378 | } | ||
379 | |||
380 | /* At this point, we have resolved the object to one of the major types */ | ||
381 | |||
382 | switch (local_type) { | ||
383 | case ACPI_TYPE_INTEGER: | ||
384 | |||
385 | status = acpi_db_test_integer_type(node, bit_length); | ||
386 | break; | ||
387 | |||
388 | case ACPI_TYPE_STRING: | ||
389 | |||
390 | status = acpi_db_test_string_type(node, byte_length); | ||
391 | break; | ||
392 | |||
393 | case ACPI_TYPE_BUFFER: | ||
394 | |||
395 | status = acpi_db_test_buffer_type(node, bit_length); | ||
396 | break; | ||
397 | |||
398 | default: | ||
399 | |||
400 | acpi_os_printf(" Ignoring, type not implemented (%2.2X)", | ||
401 | local_type); | ||
402 | break; | ||
403 | } | ||
404 | |||
405 | switch (node->type) { | ||
406 | case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
407 | |||
408 | region_obj = obj_desc->field.region_obj; | ||
409 | acpi_os_printf(" (%s)", | ||
410 | acpi_ut_get_region_name(region_obj->region. | ||
411 | space_id)); | ||
412 | break; | ||
413 | |||
414 | default: | ||
415 | break; | ||
416 | } | ||
417 | |||
418 | acpi_os_printf("\n"); | ||
419 | return (status); | ||
420 | } | ||
421 | |||
422 | /******************************************************************************* | ||
423 | * | ||
424 | * FUNCTION: acpi_db_test_integer_type | ||
425 | * | ||
426 | * PARAMETERS: node - Parent NS node for the object | ||
427 | * bit_length - Actual length of the object. Used for | ||
428 | * support of arbitrary length field_unit | ||
429 | * and buffer_field objects. | ||
430 | * | ||
431 | * RETURN: Status | ||
432 | * | ||
433 | * DESCRIPTION: Test read/write for an Integer-valued object. Performs a | ||
434 | * write/read/compare of an arbitrary new value, then performs | ||
435 | * a write/read/compare of the original value. | ||
436 | * | ||
437 | ******************************************************************************/ | ||
438 | |||
439 | static acpi_status | ||
440 | acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length) | ||
441 | { | ||
442 | union acpi_object *temp1 = NULL; | ||
443 | union acpi_object *temp2 = NULL; | ||
444 | union acpi_object *temp3 = NULL; | ||
445 | union acpi_object write_value; | ||
446 | u64 value_to_write; | ||
447 | acpi_status status; | ||
448 | |||
449 | if (bit_length > 64) { | ||
450 | acpi_os_printf(" Invalid length for an Integer: %u", | ||
451 | bit_length); | ||
452 | return (AE_OK); | ||
453 | } | ||
454 | |||
455 | /* Read the original value */ | ||
456 | |||
457 | status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp1); | ||
458 | if (ACPI_FAILURE(status)) { | ||
459 | return (status); | ||
460 | } | ||
461 | |||
462 | acpi_os_printf(" (%4.4X/%3.3X) %8.8X%8.8X", | ||
463 | bit_length, ACPI_ROUND_BITS_UP_TO_BYTES(bit_length), | ||
464 | ACPI_FORMAT_UINT64(temp1->integer.value)); | ||
465 | |||
466 | value_to_write = ACPI_UINT64_MAX >> (64 - bit_length); | ||
467 | if (temp1->integer.value == value_to_write) { | ||
468 | value_to_write = 0; | ||
469 | } | ||
470 | |||
471 | /* Write a new value */ | ||
472 | |||
473 | write_value.type = ACPI_TYPE_INTEGER; | ||
474 | write_value.integer.value = value_to_write; | ||
475 | status = acpi_db_write_to_object(node, &write_value); | ||
476 | if (ACPI_FAILURE(status)) { | ||
477 | goto exit; | ||
478 | } | ||
479 | |||
480 | /* Ensure that we can read back the new value */ | ||
481 | |||
482 | status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp2); | ||
483 | if (ACPI_FAILURE(status)) { | ||
484 | goto exit; | ||
485 | } | ||
486 | |||
487 | if (temp2->integer.value != value_to_write) { | ||
488 | acpi_os_printf(" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X", | ||
489 | ACPI_FORMAT_UINT64(temp2->integer.value), | ||
490 | ACPI_FORMAT_UINT64(value_to_write)); | ||
491 | } | ||
492 | |||
493 | /* Write back the original value */ | ||
494 | |||
495 | write_value.integer.value = temp1->integer.value; | ||
496 | status = acpi_db_write_to_object(node, &write_value); | ||
497 | if (ACPI_FAILURE(status)) { | ||
498 | goto exit; | ||
499 | } | ||
500 | |||
501 | /* Ensure that we can read back the original value */ | ||
502 | |||
503 | status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp3); | ||
504 | if (ACPI_FAILURE(status)) { | ||
505 | goto exit; | ||
506 | } | ||
507 | |||
508 | if (temp3->integer.value != temp1->integer.value) { | ||
509 | acpi_os_printf(" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X", | ||
510 | ACPI_FORMAT_UINT64(temp3->integer.value), | ||
511 | ACPI_FORMAT_UINT64(temp1->integer.value)); | ||
512 | } | ||
513 | |||
514 | exit: | ||
515 | if (temp1) { | ||
516 | acpi_os_free(temp1); | ||
517 | } | ||
518 | if (temp2) { | ||
519 | acpi_os_free(temp2); | ||
520 | } | ||
521 | if (temp3) { | ||
522 | acpi_os_free(temp3); | ||
523 | } | ||
524 | return (AE_OK); | ||
525 | } | ||
526 | |||
527 | /******************************************************************************* | ||
528 | * | ||
529 | * FUNCTION: acpi_db_test_buffer_type | ||
530 | * | ||
531 | * PARAMETERS: node - Parent NS node for the object | ||
532 | * bit_length - Actual length of the object. | ||
533 | * | ||
534 | * RETURN: Status | ||
535 | * | ||
536 | * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a | ||
537 | * write/read/compare of an arbitrary new value, then performs | ||
538 | * a write/read/compare of the original value. | ||
539 | * | ||
540 | ******************************************************************************/ | ||
541 | |||
542 | static acpi_status | ||
543 | acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length) | ||
544 | { | ||
545 | union acpi_object *temp1 = NULL; | ||
546 | union acpi_object *temp2 = NULL; | ||
547 | union acpi_object *temp3 = NULL; | ||
548 | u8 *buffer; | ||
549 | union acpi_object write_value; | ||
550 | acpi_status status; | ||
551 | u32 byte_length; | ||
552 | u32 i; | ||
553 | u8 extra_bits; | ||
554 | |||
555 | byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length); | ||
556 | if (byte_length == 0) { | ||
557 | acpi_os_printf(" Ignoring zero length buffer"); | ||
558 | return (AE_OK); | ||
559 | } | ||
560 | |||
561 | /* Allocate a local buffer */ | ||
562 | |||
563 | buffer = ACPI_ALLOCATE_ZEROED(byte_length); | ||
564 | if (!buffer) { | ||
565 | return (AE_NO_MEMORY); | ||
566 | } | ||
567 | |||
568 | /* Read the original value */ | ||
569 | |||
570 | status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp1); | ||
571 | if (ACPI_FAILURE(status)) { | ||
572 | goto exit; | ||
573 | } | ||
574 | |||
575 | /* Emit a few bytes of the buffer */ | ||
576 | |||
577 | acpi_os_printf(" (%4.4X/%3.3X)", bit_length, temp1->buffer.length); | ||
578 | for (i = 0; ((i < 4) && (i < byte_length)); i++) { | ||
579 | acpi_os_printf(" %2.2X", temp1->buffer.pointer[i]); | ||
580 | } | ||
581 | acpi_os_printf("... "); | ||
582 | |||
583 | /* | ||
584 | * Write a new value. | ||
585 | * | ||
586 | * Handle possible extra bits at the end of the buffer. Can | ||
587 | * happen for field_units larger than an integer, but the bit | ||
588 | * count is not an integral number of bytes. Zero out the | ||
589 | * unused bits. | ||
590 | */ | ||
591 | memset(buffer, BUFFER_FILL_VALUE, byte_length); | ||
592 | extra_bits = bit_length % 8; | ||
593 | if (extra_bits) { | ||
594 | buffer[byte_length - 1] = ACPI_MASK_BITS_ABOVE(extra_bits); | ||
595 | } | ||
596 | |||
597 | write_value.type = ACPI_TYPE_BUFFER; | ||
598 | write_value.buffer.length = byte_length; | ||
599 | write_value.buffer.pointer = buffer; | ||
600 | |||
601 | status = acpi_db_write_to_object(node, &write_value); | ||
602 | if (ACPI_FAILURE(status)) { | ||
603 | goto exit; | ||
604 | } | ||
605 | |||
606 | /* Ensure that we can read back the new value */ | ||
607 | |||
608 | status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp2); | ||
609 | if (ACPI_FAILURE(status)) { | ||
610 | goto exit; | ||
611 | } | ||
612 | |||
613 | if (memcmp(temp2->buffer.pointer, buffer, byte_length)) { | ||
614 | acpi_os_printf(" MISMATCH 2: New buffer value"); | ||
615 | } | ||
616 | |||
617 | /* Write back the original value */ | ||
618 | |||
619 | write_value.buffer.length = byte_length; | ||
620 | write_value.buffer.pointer = temp1->buffer.pointer; | ||
621 | |||
622 | status = acpi_db_write_to_object(node, &write_value); | ||
623 | if (ACPI_FAILURE(status)) { | ||
624 | goto exit; | ||
625 | } | ||
626 | |||
627 | /* Ensure that we can read back the original value */ | ||
628 | |||
629 | status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp3); | ||
630 | if (ACPI_FAILURE(status)) { | ||
631 | goto exit; | ||
632 | } | ||
633 | |||
634 | if (memcmp(temp1->buffer.pointer, temp3->buffer.pointer, byte_length)) { | ||
635 | acpi_os_printf(" MISMATCH 3: While restoring original buffer"); | ||
636 | } | ||
637 | |||
638 | exit: | ||
639 | ACPI_FREE(buffer); | ||
640 | if (temp1) { | ||
641 | acpi_os_free(temp1); | ||
642 | } | ||
643 | if (temp2) { | ||
644 | acpi_os_free(temp2); | ||
645 | } | ||
646 | if (temp3) { | ||
647 | acpi_os_free(temp3); | ||
648 | } | ||
649 | return (status); | ||
650 | } | ||
651 | |||
652 | /******************************************************************************* | ||
653 | * | ||
654 | * FUNCTION: acpi_db_test_string_type | ||
655 | * | ||
656 | * PARAMETERS: node - Parent NS node for the object | ||
657 | * byte_length - Actual length of the object. | ||
658 | * | ||
659 | * RETURN: Status | ||
660 | * | ||
661 | * DESCRIPTION: Test read/write for an String-valued object. Performs a | ||
662 | * write/read/compare of an arbitrary new value, then performs | ||
663 | * a write/read/compare of the original value. | ||
664 | * | ||
665 | ******************************************************************************/ | ||
666 | |||
667 | static acpi_status | ||
668 | acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length) | ||
669 | { | ||
670 | union acpi_object *temp1 = NULL; | ||
671 | union acpi_object *temp2 = NULL; | ||
672 | union acpi_object *temp3 = NULL; | ||
673 | char *value_to_write = "Test String from AML Debugger"; | ||
674 | union acpi_object write_value; | ||
675 | acpi_status status; | ||
676 | |||
677 | /* Read the original value */ | ||
678 | |||
679 | status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp1); | ||
680 | if (ACPI_FAILURE(status)) { | ||
681 | return (status); | ||
682 | } | ||
683 | |||
684 | acpi_os_printf(" (%4.4X/%3.3X) \"%s\"", (temp1->string.length * 8), | ||
685 | temp1->string.length, temp1->string.pointer); | ||
686 | |||
687 | /* Write a new value */ | ||
688 | |||
689 | write_value.type = ACPI_TYPE_STRING; | ||
690 | write_value.string.length = strlen(value_to_write); | ||
691 | write_value.string.pointer = value_to_write; | ||
692 | |||
693 | status = acpi_db_write_to_object(node, &write_value); | ||
694 | if (ACPI_FAILURE(status)) { | ||
695 | goto exit; | ||
696 | } | ||
697 | |||
698 | /* Ensure that we can read back the new value */ | ||
699 | |||
700 | status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp2); | ||
701 | if (ACPI_FAILURE(status)) { | ||
702 | goto exit; | ||
703 | } | ||
704 | |||
705 | if (strcmp(temp2->string.pointer, value_to_write)) { | ||
706 | acpi_os_printf(" MISMATCH 2: %s, expecting %s", | ||
707 | temp2->string.pointer, value_to_write); | ||
708 | } | ||
709 | |||
710 | /* Write back the original value */ | ||
711 | |||
712 | write_value.string.length = strlen(temp1->string.pointer); | ||
713 | write_value.string.pointer = temp1->string.pointer; | ||
714 | |||
715 | status = acpi_db_write_to_object(node, &write_value); | ||
716 | if (ACPI_FAILURE(status)) { | ||
717 | goto exit; | ||
718 | } | ||
719 | |||
720 | /* Ensure that we can read back the original value */ | ||
721 | |||
722 | status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp3); | ||
723 | if (ACPI_FAILURE(status)) { | ||
724 | goto exit; | ||
725 | } | ||
726 | |||
727 | if (strcmp(temp1->string.pointer, temp3->string.pointer)) { | ||
728 | acpi_os_printf(" MISMATCH 3: %s, expecting %s", | ||
729 | temp3->string.pointer, temp1->string.pointer); | ||
730 | } | ||
731 | |||
732 | exit: | ||
733 | if (temp1) { | ||
734 | acpi_os_free(temp1); | ||
735 | } | ||
736 | if (temp2) { | ||
737 | acpi_os_free(temp2); | ||
738 | } | ||
739 | if (temp3) { | ||
740 | acpi_os_free(temp3); | ||
741 | } | ||
742 | return (status); | ||
743 | } | ||
744 | |||
745 | /******************************************************************************* | ||
746 | * | ||
747 | * FUNCTION: acpi_db_read_from_object | ||
748 | * | ||
749 | * PARAMETERS: node - Parent NS node for the object | ||
750 | * expected_type - Object type expected from the read | ||
751 | * value - Where the value read is returned | ||
752 | * | ||
753 | * RETURN: Status | ||
754 | * | ||
755 | * DESCRIPTION: Performs a read from the specified object by invoking the | ||
756 | * special debugger control method that reads the object. Thus, | ||
757 | * the AML interpreter is doing all of the work, increasing the | ||
758 | * validity of the test. | ||
759 | * | ||
760 | ******************************************************************************/ | ||
761 | |||
762 | static acpi_status | ||
763 | acpi_db_read_from_object(struct acpi_namespace_node *node, | ||
764 | acpi_object_type expected_type, | ||
765 | union acpi_object **value) | ||
766 | { | ||
767 | union acpi_object *ret_value; | ||
768 | struct acpi_object_list param_objects; | ||
769 | union acpi_object params[2]; | ||
770 | struct acpi_buffer return_obj; | ||
771 | acpi_status status; | ||
772 | |||
773 | params[0].type = ACPI_TYPE_LOCAL_REFERENCE; | ||
774 | params[0].reference.actual_type = node->type; | ||
775 | params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node); | ||
776 | |||
777 | param_objects.count = 1; | ||
778 | param_objects.pointer = params; | ||
779 | |||
780 | return_obj.length = ACPI_ALLOCATE_BUFFER; | ||
781 | |||
782 | acpi_gbl_method_executing = TRUE; | ||
783 | status = acpi_evaluate_object(read_handle, NULL, | ||
784 | ¶m_objects, &return_obj); | ||
785 | acpi_gbl_method_executing = FALSE; | ||
786 | |||
787 | if (ACPI_FAILURE(status)) { | ||
788 | acpi_os_printf("Could not read from object, %s", | ||
789 | acpi_format_exception(status)); | ||
790 | return (status); | ||
791 | } | ||
792 | |||
793 | ret_value = (union acpi_object *)return_obj.pointer; | ||
794 | |||
795 | switch (ret_value->type) { | ||
796 | case ACPI_TYPE_INTEGER: | ||
797 | case ACPI_TYPE_BUFFER: | ||
798 | case ACPI_TYPE_STRING: | ||
799 | /* | ||
800 | * Did we receive the type we wanted? Most important for the | ||
801 | * Integer/Buffer case (when a field is larger than an Integer, | ||
802 | * it should return a Buffer). | ||
803 | */ | ||
804 | if (ret_value->type != expected_type) { | ||
805 | acpi_os_printf | ||
806 | (" Type mismatch: Expected %s, Received %s", | ||
807 | acpi_ut_get_type_name(expected_type), | ||
808 | acpi_ut_get_type_name(ret_value->type)); | ||
809 | |||
810 | return (AE_TYPE); | ||
811 | } | ||
812 | |||
813 | *value = ret_value; | ||
814 | break; | ||
815 | |||
816 | default: | ||
817 | |||
818 | acpi_os_printf(" Unsupported return object type, %s", | ||
819 | acpi_ut_get_type_name(ret_value->type)); | ||
820 | |||
821 | acpi_os_free(return_obj.pointer); | ||
822 | return (AE_TYPE); | ||
823 | } | ||
824 | |||
825 | return (status); | ||
826 | } | ||
827 | |||
828 | /******************************************************************************* | ||
829 | * | ||
830 | * FUNCTION: acpi_db_write_to_object | ||
831 | * | ||
832 | * PARAMETERS: node - Parent NS node for the object | ||
833 | * value - Value to be written | ||
834 | * | ||
835 | * RETURN: Status | ||
836 | * | ||
837 | * DESCRIPTION: Performs a write to the specified object by invoking the | ||
838 | * special debugger control method that writes the object. Thus, | ||
839 | * the AML interpreter is doing all of the work, increasing the | ||
840 | * validity of the test. | ||
841 | * | ||
842 | ******************************************************************************/ | ||
843 | |||
844 | static acpi_status | ||
845 | acpi_db_write_to_object(struct acpi_namespace_node *node, | ||
846 | union acpi_object *value) | ||
847 | { | ||
848 | struct acpi_object_list param_objects; | ||
849 | union acpi_object params[2]; | ||
850 | acpi_status status; | ||
851 | |||
852 | params[0].type = ACPI_TYPE_LOCAL_REFERENCE; | ||
853 | params[0].reference.actual_type = node->type; | ||
854 | params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node); | ||
855 | |||
856 | /* Copy the incoming user parameter */ | ||
857 | |||
858 | memcpy(¶ms[1], value, sizeof(union acpi_object)); | ||
859 | |||
860 | param_objects.count = 2; | ||
861 | param_objects.pointer = params; | ||
862 | |||
863 | acpi_gbl_method_executing = TRUE; | ||
864 | status = acpi_evaluate_object(write_handle, NULL, ¶m_objects, NULL); | ||
865 | acpi_gbl_method_executing = FALSE; | ||
866 | |||
867 | if (ACPI_FAILURE(status)) { | ||
868 | acpi_os_printf("Could not write to object, %s", | ||
869 | acpi_format_exception(status)); | ||
870 | } | ||
871 | |||
872 | return (status); | ||
873 | } | ||
874 | |||
875 | /******************************************************************************* | ||
876 | * | ||
877 | * FUNCTION: acpi_db_evaluate_all_predefined_names | ||
878 | * | ||
879 | * PARAMETERS: count_arg - Max number of methods to execute | ||
880 | * | ||
881 | * RETURN: None | ||
882 | * | ||
883 | * DESCRIPTION: Namespace batch execution. Execute predefined names in the | ||
884 | * namespace, up to the max count, if specified. | ||
885 | * | ||
886 | ******************************************************************************/ | ||
887 | |||
888 | static void acpi_db_evaluate_all_predefined_names(char *count_arg) | ||
889 | { | ||
890 | struct acpi_db_execute_walk info; | ||
891 | |||
892 | info.count = 0; | ||
893 | info.max_count = ACPI_UINT32_MAX; | ||
894 | |||
895 | if (count_arg) { | ||
896 | info.max_count = strtoul(count_arg, NULL, 0); | ||
897 | } | ||
898 | |||
899 | /* Search all nodes in namespace */ | ||
900 | |||
901 | (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
902 | ACPI_UINT32_MAX, | ||
903 | acpi_db_evaluate_one_predefined_name, NULL, | ||
904 | (void *)&info, NULL); | ||
905 | |||
906 | acpi_os_printf("Evaluated %u predefined names in the namespace\n", | ||
907 | info.count); | ||
908 | } | ||
909 | |||
910 | /******************************************************************************* | ||
911 | * | ||
912 | * FUNCTION: acpi_db_evaluate_one_predefined_name | ||
913 | * | ||
914 | * PARAMETERS: Callback from walk_namespace | ||
915 | * | ||
916 | * RETURN: Status | ||
917 | * | ||
918 | * DESCRIPTION: Batch execution module. Currently only executes predefined | ||
919 | * ACPI names. | ||
920 | * | ||
921 | ******************************************************************************/ | ||
922 | |||
923 | static acpi_status | ||
924 | acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle, | ||
925 | u32 nesting_level, | ||
926 | void *context, void **return_value) | ||
927 | { | ||
928 | struct acpi_namespace_node *node = | ||
929 | (struct acpi_namespace_node *)obj_handle; | ||
930 | struct acpi_db_execute_walk *info = | ||
931 | (struct acpi_db_execute_walk *)context; | ||
932 | char *pathname; | ||
933 | const union acpi_predefined_info *predefined; | ||
934 | struct acpi_device_info *obj_info; | ||
935 | struct acpi_object_list param_objects; | ||
936 | union acpi_object params[ACPI_METHOD_NUM_ARGS]; | ||
937 | union acpi_object *this_param; | ||
938 | struct acpi_buffer return_obj; | ||
939 | acpi_status status; | ||
940 | u16 arg_type_list; | ||
941 | u8 arg_count; | ||
942 | u8 arg_type; | ||
943 | u32 i; | ||
944 | |||
945 | /* The name must be a predefined ACPI name */ | ||
946 | |||
947 | predefined = acpi_ut_match_predefined_method(node->name.ascii); | ||
948 | if (!predefined) { | ||
949 | return (AE_OK); | ||
950 | } | ||
951 | |||
952 | if (node->type == ACPI_TYPE_LOCAL_SCOPE) { | ||
953 | return (AE_OK); | ||
954 | } | ||
955 | |||
956 | pathname = acpi_ns_get_external_pathname(node); | ||
957 | if (!pathname) { | ||
958 | return (AE_OK); | ||
959 | } | ||
960 | |||
961 | /* Get the object info for number of method parameters */ | ||
962 | |||
963 | status = acpi_get_object_info(obj_handle, &obj_info); | ||
964 | if (ACPI_FAILURE(status)) { | ||
965 | ACPI_FREE(pathname); | ||
966 | return (status); | ||
967 | } | ||
968 | |||
969 | param_objects.count = 0; | ||
970 | param_objects.pointer = NULL; | ||
971 | |||
972 | if (obj_info->type == ACPI_TYPE_METHOD) { | ||
973 | |||
974 | /* Setup default parameters (with proper types) */ | ||
975 | |||
976 | arg_type_list = predefined->info.argument_list; | ||
977 | arg_count = METHOD_GET_ARG_COUNT(arg_type_list); | ||
978 | |||
979 | /* | ||
980 | * Setup the ACPI-required number of arguments, regardless of what | ||
981 | * the actual method defines. If there is a difference, then the | ||
982 | * method is wrong and a warning will be issued during execution. | ||
983 | */ | ||
984 | this_param = params; | ||
985 | for (i = 0; i < arg_count; i++) { | ||
986 | arg_type = METHOD_GET_NEXT_TYPE(arg_type_list); | ||
987 | this_param->type = arg_type; | ||
988 | |||
989 | switch (arg_type) { | ||
990 | case ACPI_TYPE_INTEGER: | ||
991 | |||
992 | this_param->integer.value = 1; | ||
993 | break; | ||
994 | |||
995 | case ACPI_TYPE_STRING: | ||
996 | |||
997 | this_param->string.pointer = | ||
998 | "This is the default argument string"; | ||
999 | this_param->string.length = | ||
1000 | strlen(this_param->string.pointer); | ||
1001 | break; | ||
1002 | |||
1003 | case ACPI_TYPE_BUFFER: | ||
1004 | |||
1005 | this_param->buffer.pointer = (u8 *)params; /* just a garbage buffer */ | ||
1006 | this_param->buffer.length = 48; | ||
1007 | break; | ||
1008 | |||
1009 | case ACPI_TYPE_PACKAGE: | ||
1010 | |||
1011 | this_param->package.elements = NULL; | ||
1012 | this_param->package.count = 0; | ||
1013 | break; | ||
1014 | |||
1015 | default: | ||
1016 | |||
1017 | acpi_os_printf | ||
1018 | ("%s: Unsupported argument type: %u\n", | ||
1019 | pathname, arg_type); | ||
1020 | break; | ||
1021 | } | ||
1022 | |||
1023 | this_param++; | ||
1024 | } | ||
1025 | |||
1026 | param_objects.count = arg_count; | ||
1027 | param_objects.pointer = params; | ||
1028 | } | ||
1029 | |||
1030 | ACPI_FREE(obj_info); | ||
1031 | return_obj.pointer = NULL; | ||
1032 | return_obj.length = ACPI_ALLOCATE_BUFFER; | ||
1033 | |||
1034 | /* Do the actual method execution */ | ||
1035 | |||
1036 | acpi_gbl_method_executing = TRUE; | ||
1037 | |||
1038 | status = acpi_evaluate_object(node, NULL, ¶m_objects, &return_obj); | ||
1039 | |||
1040 | acpi_os_printf("%-32s returned %s\n", | ||
1041 | pathname, acpi_format_exception(status)); | ||
1042 | acpi_gbl_method_executing = FALSE; | ||
1043 | ACPI_FREE(pathname); | ||
1044 | |||
1045 | /* Ignore status from method execution */ | ||
1046 | |||
1047 | status = AE_OK; | ||
1048 | |||
1049 | /* Update count, check if we have executed enough methods */ | ||
1050 | |||
1051 | info->count++; | ||
1052 | if (info->count >= info->max_count) { | ||
1053 | status = AE_CTRL_TERMINATE; | ||
1054 | } | ||
1055 | |||
1056 | return (status); | ||
1057 | } | ||
diff --git a/drivers/acpi/acpica/dbutils.c b/drivers/acpi/acpica/dbutils.c new file mode 100644 index 000000000000..86790e080139 --- /dev/null +++ b/drivers/acpi/acpica/dbutils.c | |||
@@ -0,0 +1,457 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbutils - AML debugger utilities | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acnamesp.h" | ||
47 | #include "acdebug.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
50 | ACPI_MODULE_NAME("dbutils") | ||
51 | |||
52 | /* Local prototypes */ | ||
53 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
54 | acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root); | ||
55 | |||
56 | void acpi_db_dump_buffer(u32 address); | ||
57 | #endif | ||
58 | |||
59 | static char *gbl_hex_to_ascii = "0123456789ABCDEF"; | ||
60 | |||
61 | /******************************************************************************* | ||
62 | * | ||
63 | * FUNCTION: acpi_db_match_argument | ||
64 | * | ||
65 | * PARAMETERS: user_argument - User command line | ||
66 | * arguments - Array of commands to match against | ||
67 | * | ||
68 | * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found | ||
69 | * | ||
70 | * DESCRIPTION: Search command array for a command match | ||
71 | * | ||
72 | ******************************************************************************/ | ||
73 | |||
74 | acpi_object_type | ||
75 | acpi_db_match_argument(char *user_argument, | ||
76 | struct acpi_db_argument_info *arguments) | ||
77 | { | ||
78 | u32 i; | ||
79 | |||
80 | if (!user_argument || user_argument[0] == 0) { | ||
81 | return (ACPI_TYPE_NOT_FOUND); | ||
82 | } | ||
83 | |||
84 | for (i = 0; arguments[i].name; i++) { | ||
85 | if (strstr(arguments[i].name, user_argument) == | ||
86 | arguments[i].name) { | ||
87 | return (i); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | /* Argument not recognized */ | ||
92 | |||
93 | return (ACPI_TYPE_NOT_FOUND); | ||
94 | } | ||
95 | |||
96 | /******************************************************************************* | ||
97 | * | ||
98 | * FUNCTION: acpi_db_set_output_destination | ||
99 | * | ||
100 | * PARAMETERS: output_flags - Current flags word | ||
101 | * | ||
102 | * RETURN: None | ||
103 | * | ||
104 | * DESCRIPTION: Set the current destination for debugger output. Also sets | ||
105 | * the debug output level accordingly. | ||
106 | * | ||
107 | ******************************************************************************/ | ||
108 | |||
109 | void acpi_db_set_output_destination(u32 output_flags) | ||
110 | { | ||
111 | |||
112 | acpi_gbl_db_output_flags = (u8)output_flags; | ||
113 | |||
114 | if ((output_flags & ACPI_DB_REDIRECTABLE_OUTPUT) && | ||
115 | acpi_gbl_db_output_to_file) { | ||
116 | acpi_dbg_level = acpi_gbl_db_debug_level; | ||
117 | } else { | ||
118 | acpi_dbg_level = acpi_gbl_db_console_debug_level; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | /******************************************************************************* | ||
123 | * | ||
124 | * FUNCTION: acpi_db_dump_external_object | ||
125 | * | ||
126 | * PARAMETERS: obj_desc - External ACPI object to dump | ||
127 | * level - Nesting level. | ||
128 | * | ||
129 | * RETURN: None | ||
130 | * | ||
131 | * DESCRIPTION: Dump the contents of an ACPI external object | ||
132 | * | ||
133 | ******************************************************************************/ | ||
134 | |||
135 | void acpi_db_dump_external_object(union acpi_object *obj_desc, u32 level) | ||
136 | { | ||
137 | u32 i; | ||
138 | |||
139 | if (!obj_desc) { | ||
140 | acpi_os_printf("[Null Object]\n"); | ||
141 | return; | ||
142 | } | ||
143 | |||
144 | for (i = 0; i < level; i++) { | ||
145 | acpi_os_printf(" "); | ||
146 | } | ||
147 | |||
148 | switch (obj_desc->type) { | ||
149 | case ACPI_TYPE_ANY: | ||
150 | |||
151 | acpi_os_printf("[Null Object] (Type=0)\n"); | ||
152 | break; | ||
153 | |||
154 | case ACPI_TYPE_INTEGER: | ||
155 | |||
156 | acpi_os_printf("[Integer] = %8.8X%8.8X\n", | ||
157 | ACPI_FORMAT_UINT64(obj_desc->integer.value)); | ||
158 | break; | ||
159 | |||
160 | case ACPI_TYPE_STRING: | ||
161 | |||
162 | acpi_os_printf("[String] Length %.2X = ", | ||
163 | obj_desc->string.length); | ||
164 | acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX); | ||
165 | acpi_os_printf("\n"); | ||
166 | break; | ||
167 | |||
168 | case ACPI_TYPE_BUFFER: | ||
169 | |||
170 | acpi_os_printf("[Buffer] Length %.2X = ", | ||
171 | obj_desc->buffer.length); | ||
172 | if (obj_desc->buffer.length) { | ||
173 | if (obj_desc->buffer.length > 16) { | ||
174 | acpi_os_printf("\n"); | ||
175 | } | ||
176 | acpi_ut_debug_dump_buffer(ACPI_CAST_PTR | ||
177 | (u8, | ||
178 | obj_desc->buffer.pointer), | ||
179 | obj_desc->buffer.length, | ||
180 | DB_BYTE_DISPLAY, _COMPONENT); | ||
181 | } else { | ||
182 | acpi_os_printf("\n"); | ||
183 | } | ||
184 | break; | ||
185 | |||
186 | case ACPI_TYPE_PACKAGE: | ||
187 | |||
188 | acpi_os_printf("[Package] Contains %u Elements:\n", | ||
189 | obj_desc->package.count); | ||
190 | |||
191 | for (i = 0; i < obj_desc->package.count; i++) { | ||
192 | acpi_db_dump_external_object(&obj_desc->package. | ||
193 | elements[i], level + 1); | ||
194 | } | ||
195 | break; | ||
196 | |||
197 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
198 | |||
199 | acpi_os_printf("[Object Reference] = "); | ||
200 | acpi_db_display_internal_object(obj_desc->reference.handle, | ||
201 | NULL); | ||
202 | break; | ||
203 | |||
204 | case ACPI_TYPE_PROCESSOR: | ||
205 | |||
206 | acpi_os_printf("[Processor]\n"); | ||
207 | break; | ||
208 | |||
209 | case ACPI_TYPE_POWER: | ||
210 | |||
211 | acpi_os_printf("[Power Resource]\n"); | ||
212 | break; | ||
213 | |||
214 | default: | ||
215 | |||
216 | acpi_os_printf("[Unknown Type] %X\n", obj_desc->type); | ||
217 | break; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /******************************************************************************* | ||
222 | * | ||
223 | * FUNCTION: acpi_db_prep_namestring | ||
224 | * | ||
225 | * PARAMETERS: name - String to prepare | ||
226 | * | ||
227 | * RETURN: None | ||
228 | * | ||
229 | * DESCRIPTION: Translate all forward slashes and dots to backslashes. | ||
230 | * | ||
231 | ******************************************************************************/ | ||
232 | |||
233 | void acpi_db_prep_namestring(char *name) | ||
234 | { | ||
235 | |||
236 | if (!name) { | ||
237 | return; | ||
238 | } | ||
239 | |||
240 | acpi_ut_strupr(name); | ||
241 | |||
242 | /* Convert a leading forward slash to a backslash */ | ||
243 | |||
244 | if (*name == '/') { | ||
245 | *name = '\\'; | ||
246 | } | ||
247 | |||
248 | /* Ignore a leading backslash, this is the root prefix */ | ||
249 | |||
250 | if (ACPI_IS_ROOT_PREFIX(*name)) { | ||
251 | name++; | ||
252 | } | ||
253 | |||
254 | /* Convert all slash path separators to dots */ | ||
255 | |||
256 | while (*name) { | ||
257 | if ((*name == '/') || (*name == '\\')) { | ||
258 | *name = '.'; | ||
259 | } | ||
260 | |||
261 | name++; | ||
262 | } | ||
263 | } | ||
264 | |||
265 | /******************************************************************************* | ||
266 | * | ||
267 | * FUNCTION: acpi_db_local_ns_lookup | ||
268 | * | ||
269 | * PARAMETERS: name - Name to lookup | ||
270 | * | ||
271 | * RETURN: Pointer to a namespace node, null on failure | ||
272 | * | ||
273 | * DESCRIPTION: Lookup a name in the ACPI namespace | ||
274 | * | ||
275 | * Note: Currently begins search from the root. Could be enhanced to use | ||
276 | * the current prefix (scope) node as the search beginning point. | ||
277 | * | ||
278 | ******************************************************************************/ | ||
279 | |||
280 | struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name) | ||
281 | { | ||
282 | char *internal_path; | ||
283 | acpi_status status; | ||
284 | struct acpi_namespace_node *node = NULL; | ||
285 | |||
286 | acpi_db_prep_namestring(name); | ||
287 | |||
288 | /* Build an internal namestring */ | ||
289 | |||
290 | status = acpi_ns_internalize_name(name, &internal_path); | ||
291 | if (ACPI_FAILURE(status)) { | ||
292 | acpi_os_printf("Invalid namestring: %s\n", name); | ||
293 | return (NULL); | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * Lookup the name. | ||
298 | * (Uses root node as the search starting point) | ||
299 | */ | ||
300 | status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY, | ||
301 | ACPI_IMODE_EXECUTE, | ||
302 | ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, | ||
303 | NULL, &node); | ||
304 | if (ACPI_FAILURE(status)) { | ||
305 | acpi_os_printf("Could not locate name: %s, %s\n", | ||
306 | name, acpi_format_exception(status)); | ||
307 | } | ||
308 | |||
309 | ACPI_FREE(internal_path); | ||
310 | return (node); | ||
311 | } | ||
312 | |||
313 | /******************************************************************************* | ||
314 | * | ||
315 | * FUNCTION: acpi_db_uint32_to_hex_string | ||
316 | * | ||
317 | * PARAMETERS: value - The value to be converted to string | ||
318 | * buffer - Buffer for result (not less than 11 bytes) | ||
319 | * | ||
320 | * RETURN: None | ||
321 | * | ||
322 | * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image | ||
323 | * | ||
324 | * NOTE: It is the caller's responsibility to ensure that the length of buffer | ||
325 | * is sufficient. | ||
326 | * | ||
327 | ******************************************************************************/ | ||
328 | |||
329 | void acpi_db_uint32_to_hex_string(u32 value, char *buffer) | ||
330 | { | ||
331 | int i; | ||
332 | |||
333 | if (value == 0) { | ||
334 | strcpy(buffer, "0"); | ||
335 | return; | ||
336 | } | ||
337 | |||
338 | buffer[8] = '\0'; | ||
339 | |||
340 | for (i = 7; i >= 0; i--) { | ||
341 | buffer[i] = gbl_hex_to_ascii[value & 0x0F]; | ||
342 | value = value >> 4; | ||
343 | } | ||
344 | } | ||
345 | |||
346 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
347 | /******************************************************************************* | ||
348 | * | ||
349 | * FUNCTION: acpi_db_second_pass_parse | ||
350 | * | ||
351 | * PARAMETERS: root - Root of the parse tree | ||
352 | * | ||
353 | * RETURN: Status | ||
354 | * | ||
355 | * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until | ||
356 | * second pass to parse the control methods | ||
357 | * | ||
358 | ******************************************************************************/ | ||
359 | |||
360 | acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root) | ||
361 | { | ||
362 | union acpi_parse_object *op = root; | ||
363 | union acpi_parse_object *method; | ||
364 | union acpi_parse_object *search_op; | ||
365 | union acpi_parse_object *start_op; | ||
366 | acpi_status status = AE_OK; | ||
367 | u32 base_aml_offset; | ||
368 | struct acpi_walk_state *walk_state; | ||
369 | |||
370 | ACPI_FUNCTION_ENTRY(); | ||
371 | |||
372 | acpi_os_printf("Pass two parse ....\n"); | ||
373 | |||
374 | while (op) { | ||
375 | if (op->common.aml_opcode == AML_METHOD_OP) { | ||
376 | method = op; | ||
377 | |||
378 | /* Create a new walk state for the parse */ | ||
379 | |||
380 | walk_state = | ||
381 | acpi_ds_create_walk_state(0, NULL, NULL, NULL); | ||
382 | if (!walk_state) { | ||
383 | return (AE_NO_MEMORY); | ||
384 | } | ||
385 | |||
386 | /* Init the Walk State */ | ||
387 | |||
388 | walk_state->parser_state.aml = | ||
389 | walk_state->parser_state.aml_start = | ||
390 | method->named.data; | ||
391 | walk_state->parser_state.aml_end = | ||
392 | walk_state->parser_state.pkg_end = | ||
393 | method->named.data + method->named.length; | ||
394 | walk_state->parser_state.start_scope = op; | ||
395 | |||
396 | walk_state->descending_callback = | ||
397 | acpi_ds_load1_begin_op; | ||
398 | walk_state->ascending_callback = acpi_ds_load1_end_op; | ||
399 | |||
400 | /* Perform the AML parse */ | ||
401 | |||
402 | status = acpi_ps_parse_aml(walk_state); | ||
403 | |||
404 | base_aml_offset = | ||
405 | (method->common.value.arg)->common.aml_offset + 1; | ||
406 | start_op = (method->common.value.arg)->common.next; | ||
407 | search_op = start_op; | ||
408 | |||
409 | while (search_op) { | ||
410 | search_op->common.aml_offset += base_aml_offset; | ||
411 | search_op = | ||
412 | acpi_ps_get_depth_next(start_op, search_op); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | if (op->common.aml_opcode == AML_REGION_OP) { | ||
417 | |||
418 | /* TBD: [Investigate] this isn't quite the right thing to do! */ | ||
419 | /* | ||
420 | * | ||
421 | * Method = (ACPI_DEFERRED_OP *) Op; | ||
422 | * Status = acpi_ps_parse_aml (Op, Method->Body, Method->body_length); | ||
423 | */ | ||
424 | } | ||
425 | |||
426 | if (ACPI_FAILURE(status)) { | ||
427 | break; | ||
428 | } | ||
429 | |||
430 | op = acpi_ps_get_depth_next(root, op); | ||
431 | } | ||
432 | |||
433 | return (status); | ||
434 | } | ||
435 | |||
436 | /******************************************************************************* | ||
437 | * | ||
438 | * FUNCTION: acpi_db_dump_buffer | ||
439 | * | ||
440 | * PARAMETERS: address - Pointer to the buffer | ||
441 | * | ||
442 | * RETURN: None | ||
443 | * | ||
444 | * DESCRIPTION: Print a portion of a buffer | ||
445 | * | ||
446 | ******************************************************************************/ | ||
447 | |||
448 | void acpi_db_dump_buffer(u32 address) | ||
449 | { | ||
450 | |||
451 | acpi_os_printf("\nLocation %X:\n", address); | ||
452 | |||
453 | acpi_dbg_level |= ACPI_LV_TABLES; | ||
454 | acpi_ut_debug_dump_buffer(ACPI_TO_POINTER(address), 64, DB_BYTE_DISPLAY, | ||
455 | ACPI_UINT32_MAX); | ||
456 | } | ||
457 | #endif | ||
diff --git a/drivers/acpi/acpica/dbxface.c b/drivers/acpi/acpica/dbxface.c new file mode 100644 index 000000000000..342298a6e10f --- /dev/null +++ b/drivers/acpi/acpica/dbxface.c | |||
@@ -0,0 +1,513 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: dbxface - AML Debugger external interfaces | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2015, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "amlcode.h" | ||
47 | #include "acdebug.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_CA_DEBUGGER | ||
50 | ACPI_MODULE_NAME("dbxface") | ||
51 | |||
52 | /* Local prototypes */ | ||
53 | static acpi_status | ||
54 | acpi_db_start_command(struct acpi_walk_state *walk_state, | ||
55 | union acpi_parse_object *op); | ||
56 | |||
57 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
58 | void acpi_db_method_end(struct acpi_walk_state *walk_state); | ||
59 | #endif | ||
60 | |||
61 | /******************************************************************************* | ||
62 | * | ||
63 | * FUNCTION: acpi_db_start_command | ||
64 | * | ||
65 | * PARAMETERS: walk_state - Current walk | ||
66 | * op - Current executing Op, from AML interpreter | ||
67 | * | ||
68 | * RETURN: Status | ||
69 | * | ||
70 | * DESCRIPTION: Enter debugger command loop | ||
71 | * | ||
72 | ******************************************************************************/ | ||
73 | |||
74 | static acpi_status | ||
75 | acpi_db_start_command(struct acpi_walk_state *walk_state, | ||
76 | union acpi_parse_object *op) | ||
77 | { | ||
78 | acpi_status status; | ||
79 | |||
80 | /* TBD: [Investigate] are there namespace locking issues here? */ | ||
81 | |||
82 | /* acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */ | ||
83 | |||
84 | /* Go into the command loop and await next user command */ | ||
85 | |||
86 | acpi_gbl_method_executing = TRUE; | ||
87 | status = AE_CTRL_TRUE; | ||
88 | while (status == AE_CTRL_TRUE) { | ||
89 | if (acpi_gbl_debugger_configuration == DEBUGGER_MULTI_THREADED) { | ||
90 | |||
91 | /* Handshake with the front-end that gets user command lines */ | ||
92 | |||
93 | acpi_os_release_mutex(acpi_gbl_db_command_complete); | ||
94 | |||
95 | status = | ||
96 | acpi_os_acquire_mutex(acpi_gbl_db_command_ready, | ||
97 | ACPI_WAIT_FOREVER); | ||
98 | if (ACPI_FAILURE(status)) { | ||
99 | return (status); | ||
100 | } | ||
101 | } else { | ||
102 | /* Single threaded, we must get a command line ourselves */ | ||
103 | |||
104 | /* Force output to console until a command is entered */ | ||
105 | |||
106 | acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | ||
107 | |||
108 | /* Different prompt if method is executing */ | ||
109 | |||
110 | if (!acpi_gbl_method_executing) { | ||
111 | acpi_os_printf("%1c ", | ||
112 | ACPI_DEBUGGER_COMMAND_PROMPT); | ||
113 | } else { | ||
114 | acpi_os_printf("%1c ", | ||
115 | ACPI_DEBUGGER_EXECUTE_PROMPT); | ||
116 | } | ||
117 | |||
118 | /* Get the user input line */ | ||
119 | |||
120 | status = acpi_os_get_line(acpi_gbl_db_line_buf, | ||
121 | ACPI_DB_LINE_BUFFER_SIZE, | ||
122 | NULL); | ||
123 | if (ACPI_FAILURE(status)) { | ||
124 | ACPI_EXCEPTION((AE_INFO, status, | ||
125 | "While parsing command line")); | ||
126 | return (status); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | status = | ||
131 | acpi_db_command_dispatch(acpi_gbl_db_line_buf, walk_state, | ||
132 | op); | ||
133 | } | ||
134 | |||
135 | /* acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */ | ||
136 | |||
137 | return (status); | ||
138 | } | ||
139 | |||
140 | /******************************************************************************* | ||
141 | * | ||
142 | * FUNCTION: acpi_db_single_step | ||
143 | * | ||
144 | * PARAMETERS: walk_state - Current walk | ||
145 | * op - Current executing op (from aml interpreter) | ||
146 | * opcode_class - Class of the current AML Opcode | ||
147 | * | ||
148 | * RETURN: Status | ||
149 | * | ||
150 | * DESCRIPTION: Called just before execution of an AML opcode. | ||
151 | * | ||
152 | ******************************************************************************/ | ||
153 | |||
154 | acpi_status | ||
155 | acpi_db_single_step(struct acpi_walk_state * walk_state, | ||
156 | union acpi_parse_object * op, u32 opcode_class) | ||
157 | { | ||
158 | union acpi_parse_object *next; | ||
159 | acpi_status status = AE_OK; | ||
160 | u32 original_debug_level; | ||
161 | union acpi_parse_object *display_op; | ||
162 | union acpi_parse_object *parent_op; | ||
163 | u32 aml_offset; | ||
164 | |||
165 | ACPI_FUNCTION_ENTRY(); | ||
166 | |||
167 | #ifndef ACPI_APPLICATION | ||
168 | if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) { | ||
169 | return (AE_OK); | ||
170 | } | ||
171 | #endif | ||
172 | |||
173 | /* Check the abort flag */ | ||
174 | |||
175 | if (acpi_gbl_abort_method) { | ||
176 | acpi_gbl_abort_method = FALSE; | ||
177 | return (AE_ABORT_METHOD); | ||
178 | } | ||
179 | |||
180 | aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml, | ||
181 | walk_state->parser_state.aml_start); | ||
182 | |||
183 | /* Check for single-step breakpoint */ | ||
184 | |||
185 | if (walk_state->method_breakpoint && | ||
186 | (walk_state->method_breakpoint <= aml_offset)) { | ||
187 | |||
188 | /* Check if the breakpoint has been reached or passed */ | ||
189 | /* Hit the breakpoint, resume single step, reset breakpoint */ | ||
190 | |||
191 | acpi_os_printf("***Break*** at AML offset %X\n", aml_offset); | ||
192 | acpi_gbl_cm_single_step = TRUE; | ||
193 | acpi_gbl_step_to_next_call = FALSE; | ||
194 | walk_state->method_breakpoint = 0; | ||
195 | } | ||
196 | |||
197 | /* Check for user breakpoint (Must be on exact Aml offset) */ | ||
198 | |||
199 | else if (walk_state->user_breakpoint && | ||
200 | (walk_state->user_breakpoint == aml_offset)) { | ||
201 | acpi_os_printf("***UserBreakpoint*** at AML offset %X\n", | ||
202 | aml_offset); | ||
203 | acpi_gbl_cm_single_step = TRUE; | ||
204 | acpi_gbl_step_to_next_call = FALSE; | ||
205 | walk_state->method_breakpoint = 0; | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * Check if this is an opcode that we are interested in -- | ||
210 | * namely, opcodes that have arguments | ||
211 | */ | ||
212 | if (op->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { | ||
213 | return (AE_OK); | ||
214 | } | ||
215 | |||
216 | switch (opcode_class) { | ||
217 | case AML_CLASS_UNKNOWN: | ||
218 | case AML_CLASS_ARGUMENT: /* constants, literals, etc. do nothing */ | ||
219 | |||
220 | return (AE_OK); | ||
221 | |||
222 | default: | ||
223 | |||
224 | /* All other opcodes -- continue */ | ||
225 | break; | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * Under certain debug conditions, display this opcode and its operands | ||
230 | */ | ||
231 | if ((acpi_gbl_db_output_to_file) || | ||
232 | (acpi_gbl_cm_single_step) || (acpi_dbg_level & ACPI_LV_PARSE)) { | ||
233 | if ((acpi_gbl_db_output_to_file) || | ||
234 | (acpi_dbg_level & ACPI_LV_PARSE)) { | ||
235 | acpi_os_printf | ||
236 | ("\n[AmlDebug] Next AML Opcode to execute:\n"); | ||
237 | } | ||
238 | |||
239 | /* | ||
240 | * Display this op (and only this op - zero out the NEXT field | ||
241 | * temporarily, and disable parser trace output for the duration of | ||
242 | * the display because we don't want the extraneous debug output) | ||
243 | */ | ||
244 | original_debug_level = acpi_dbg_level; | ||
245 | acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS); | ||
246 | next = op->common.next; | ||
247 | op->common.next = NULL; | ||
248 | |||
249 | display_op = op; | ||
250 | parent_op = op->common.parent; | ||
251 | if (parent_op) { | ||
252 | if ((walk_state->control_state) && | ||
253 | (walk_state->control_state->common.state == | ||
254 | ACPI_CONTROL_PREDICATE_EXECUTING)) { | ||
255 | /* | ||
256 | * We are executing the predicate of an IF or WHILE statement | ||
257 | * Search upwards for the containing IF or WHILE so that the | ||
258 | * entire predicate can be displayed. | ||
259 | */ | ||
260 | while (parent_op) { | ||
261 | if ((parent_op->common.aml_opcode == | ||
262 | AML_IF_OP) | ||
263 | || (parent_op->common.aml_opcode == | ||
264 | AML_WHILE_OP)) { | ||
265 | display_op = parent_op; | ||
266 | break; | ||
267 | } | ||
268 | parent_op = parent_op->common.parent; | ||
269 | } | ||
270 | } else { | ||
271 | while (parent_op) { | ||
272 | if ((parent_op->common.aml_opcode == | ||
273 | AML_IF_OP) | ||
274 | || (parent_op->common.aml_opcode == | ||
275 | AML_ELSE_OP) | ||
276 | || (parent_op->common.aml_opcode == | ||
277 | AML_SCOPE_OP) | ||
278 | || (parent_op->common.aml_opcode == | ||
279 | AML_METHOD_OP) | ||
280 | || (parent_op->common.aml_opcode == | ||
281 | AML_WHILE_OP)) { | ||
282 | break; | ||
283 | } | ||
284 | display_op = parent_op; | ||
285 | parent_op = parent_op->common.parent; | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | |||
290 | /* Now we can display it */ | ||
291 | |||
292 | #ifdef ACPI_DISASSEMBLER | ||
293 | acpi_dm_disassemble(walk_state, display_op, ACPI_UINT32_MAX); | ||
294 | #endif | ||
295 | |||
296 | if ((op->common.aml_opcode == AML_IF_OP) || | ||
297 | (op->common.aml_opcode == AML_WHILE_OP)) { | ||
298 | if (walk_state->control_state->common.value) { | ||
299 | acpi_os_printf | ||
300 | ("Predicate = [True], IF block was executed\n"); | ||
301 | } else { | ||
302 | acpi_os_printf | ||
303 | ("Predicate = [False], Skipping IF block\n"); | ||
304 | } | ||
305 | } else if (op->common.aml_opcode == AML_ELSE_OP) { | ||
306 | acpi_os_printf | ||
307 | ("Predicate = [False], ELSE block was executed\n"); | ||
308 | } | ||
309 | |||
310 | /* Restore everything */ | ||
311 | |||
312 | op->common.next = next; | ||
313 | acpi_os_printf("\n"); | ||
314 | if ((acpi_gbl_db_output_to_file) || | ||
315 | (acpi_dbg_level & ACPI_LV_PARSE)) { | ||
316 | acpi_os_printf("\n"); | ||
317 | } | ||
318 | acpi_dbg_level = original_debug_level; | ||
319 | } | ||
320 | |||
321 | /* If we are not single stepping, just continue executing the method */ | ||
322 | |||
323 | if (!acpi_gbl_cm_single_step) { | ||
324 | return (AE_OK); | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | * If we are executing a step-to-call command, | ||
329 | * Check if this is a method call. | ||
330 | */ | ||
331 | if (acpi_gbl_step_to_next_call) { | ||
332 | if (op->common.aml_opcode != AML_INT_METHODCALL_OP) { | ||
333 | |||
334 | /* Not a method call, just keep executing */ | ||
335 | |||
336 | return (AE_OK); | ||
337 | } | ||
338 | |||
339 | /* Found a method call, stop executing */ | ||
340 | |||
341 | acpi_gbl_step_to_next_call = FALSE; | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * If the next opcode is a method call, we will "step over" it | ||
346 | * by default. | ||
347 | */ | ||
348 | if (op->common.aml_opcode == AML_INT_METHODCALL_OP) { | ||
349 | |||
350 | /* Force no more single stepping while executing called method */ | ||
351 | |||
352 | acpi_gbl_cm_single_step = FALSE; | ||
353 | |||
354 | /* | ||
355 | * Set the breakpoint on/before the call, it will stop execution | ||
356 | * as soon as we return | ||
357 | */ | ||
358 | walk_state->method_breakpoint = 1; /* Must be non-zero! */ | ||
359 | } | ||
360 | |||
361 | status = acpi_db_start_command(walk_state, op); | ||
362 | |||
363 | /* User commands complete, continue execution of the interrupted method */ | ||
364 | |||
365 | return (status); | ||
366 | } | ||
367 | |||
368 | /******************************************************************************* | ||
369 | * | ||
370 | * FUNCTION: acpi_initialize_debugger | ||
371 | * | ||
372 | * PARAMETERS: None | ||
373 | * | ||
374 | * RETURN: Status | ||
375 | * | ||
376 | * DESCRIPTION: Init and start debugger | ||
377 | * | ||
378 | ******************************************************************************/ | ||
379 | |||
380 | acpi_status acpi_initialize_debugger(void) | ||
381 | { | ||
382 | acpi_status status; | ||
383 | |||
384 | ACPI_FUNCTION_TRACE(acpi_initialize_debugger); | ||
385 | |||
386 | /* Init globals */ | ||
387 | |||
388 | acpi_gbl_db_buffer = NULL; | ||
389 | acpi_gbl_db_filename = NULL; | ||
390 | acpi_gbl_db_output_to_file = FALSE; | ||
391 | |||
392 | acpi_gbl_db_debug_level = ACPI_LV_VERBOSITY2; | ||
393 | acpi_gbl_db_console_debug_level = ACPI_NORMAL_DEFAULT | ACPI_LV_TABLES; | ||
394 | acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; | ||
395 | |||
396 | acpi_gbl_db_opt_no_ini_methods = FALSE; | ||
397 | |||
398 | acpi_gbl_db_buffer = acpi_os_allocate(ACPI_DEBUG_BUFFER_SIZE); | ||
399 | if (!acpi_gbl_db_buffer) { | ||
400 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
401 | } | ||
402 | memset(acpi_gbl_db_buffer, 0, ACPI_DEBUG_BUFFER_SIZE); | ||
403 | |||
404 | /* Initial scope is the root */ | ||
405 | |||
406 | acpi_gbl_db_scope_buf[0] = AML_ROOT_PREFIX; | ||
407 | acpi_gbl_db_scope_buf[1] = 0; | ||
408 | acpi_gbl_db_scope_node = acpi_gbl_root_node; | ||
409 | |||
410 | /* Initialize user commands loop */ | ||
411 | |||
412 | acpi_gbl_db_terminate_loop = FALSE; | ||
413 | |||
414 | /* | ||
415 | * If configured for multi-thread support, the debug executor runs in | ||
416 | * a separate thread so that the front end can be in another address | ||
417 | * space, environment, or even another machine. | ||
418 | */ | ||
419 | if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) { | ||
420 | |||
421 | /* These were created with one unit, grab it */ | ||
422 | |||
423 | status = acpi_os_acquire_mutex(acpi_gbl_db_command_complete, | ||
424 | ACPI_WAIT_FOREVER); | ||
425 | if (ACPI_FAILURE(status)) { | ||
426 | acpi_os_printf("Could not get debugger mutex\n"); | ||
427 | return_ACPI_STATUS(status); | ||
428 | } | ||
429 | |||
430 | status = acpi_os_acquire_mutex(acpi_gbl_db_command_ready, | ||
431 | ACPI_WAIT_FOREVER); | ||
432 | if (ACPI_FAILURE(status)) { | ||
433 | acpi_os_printf("Could not get debugger mutex\n"); | ||
434 | return_ACPI_STATUS(status); | ||
435 | } | ||
436 | |||
437 | /* Create the debug execution thread to execute commands */ | ||
438 | |||
439 | acpi_gbl_db_threads_terminated = FALSE; | ||
440 | status = acpi_os_execute(OSL_DEBUGGER_MAIN_THREAD, | ||
441 | acpi_db_execute_thread, NULL); | ||
442 | if (ACPI_FAILURE(status)) { | ||
443 | ACPI_EXCEPTION((AE_INFO, status, | ||
444 | "Could not start debugger thread")); | ||
445 | acpi_gbl_db_threads_terminated = TRUE; | ||
446 | return_ACPI_STATUS(status); | ||
447 | } | ||
448 | } else { | ||
449 | acpi_gbl_db_thread_id = acpi_os_get_thread_id(); | ||
450 | } | ||
451 | |||
452 | return_ACPI_STATUS(AE_OK); | ||
453 | } | ||
454 | |||
455 | ACPI_EXPORT_SYMBOL(acpi_initialize_debugger) | ||
456 | |||
457 | /******************************************************************************* | ||
458 | * | ||
459 | * FUNCTION: acpi_terminate_debugger | ||
460 | * | ||
461 | * PARAMETERS: None | ||
462 | * | ||
463 | * RETURN: None | ||
464 | * | ||
465 | * DESCRIPTION: Stop debugger | ||
466 | * | ||
467 | ******************************************************************************/ | ||
468 | void acpi_terminate_debugger(void) | ||
469 | { | ||
470 | |||
471 | /* Terminate the AML Debugger */ | ||
472 | |||
473 | acpi_gbl_db_terminate_loop = TRUE; | ||
474 | |||
475 | if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) { | ||
476 | acpi_os_release_mutex(acpi_gbl_db_command_ready); | ||
477 | |||
478 | /* Wait the AML Debugger threads */ | ||
479 | |||
480 | while (!acpi_gbl_db_threads_terminated) { | ||
481 | acpi_os_sleep(100); | ||
482 | } | ||
483 | } | ||
484 | |||
485 | if (acpi_gbl_db_buffer) { | ||
486 | acpi_os_free(acpi_gbl_db_buffer); | ||
487 | acpi_gbl_db_buffer = NULL; | ||
488 | } | ||
489 | |||
490 | /* Ensure that debug output is now disabled */ | ||
491 | |||
492 | acpi_gbl_db_output_flags = ACPI_DB_DISABLE_OUTPUT; | ||
493 | } | ||
494 | |||
495 | ACPI_EXPORT_SYMBOL(acpi_terminate_debugger) | ||
496 | |||
497 | /******************************************************************************* | ||
498 | * | ||
499 | * FUNCTION: acpi_set_debugger_thread_id | ||
500 | * | ||
501 | * PARAMETERS: thread_id - Debugger thread ID | ||
502 | * | ||
503 | * RETURN: None | ||
504 | * | ||
505 | * DESCRIPTION: Set debugger thread ID | ||
506 | * | ||
507 | ******************************************************************************/ | ||
508 | void acpi_set_debugger_thread_id(acpi_thread_id thread_id) | ||
509 | { | ||
510 | acpi_gbl_db_thread_id = thread_id; | ||
511 | } | ||
512 | |||
513 | ACPI_EXPORT_SYMBOL(acpi_set_debugger_thread_id) | ||
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 81f2d9e87fad..07d22bfbaa00 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -405,7 +405,7 @@ cleanup: | |||
405 | } | 405 | } |
406 | 406 | ||
407 | ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) | 407 | ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) |
408 | #endif /* ACPI_FUTURE_USAGE */ | 408 | #endif |
409 | 409 | ||
410 | #if (!ACPI_REDUCED_HARDWARE) | 410 | #if (!ACPI_REDUCED_HARDWARE) |
411 | /******************************************************************************* | 411 | /******************************************************************************* |
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index 075d654c837f..1e4c5b6dc0b0 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c | |||
@@ -618,6 +618,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, | |||
618 | break; | 618 | break; |
619 | 619 | ||
620 | case ARGI_TARGETREF: | 620 | case ARGI_TARGETREF: |
621 | case ARGI_STORE_TARGET: | ||
621 | 622 | ||
622 | switch (destination_type) { | 623 | switch (destination_type) { |
623 | case ACPI_TYPE_INTEGER: | 624 | case ACPI_TYPE_INTEGER: |
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index 7b109128b035..a1afe1a1e7c2 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c | |||
@@ -209,7 +209,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
209 | * (i.e., dereference the package index) | 209 | * (i.e., dereference the package index) |
210 | * Delete the ref object, increment the returned object | 210 | * Delete the ref object, increment the returned object |
211 | */ | 211 | */ |
212 | acpi_ut_remove_reference(stack_desc); | ||
213 | acpi_ut_add_reference(obj_desc); | 212 | acpi_ut_add_reference(obj_desc); |
214 | *stack_ptr = obj_desc; | 213 | *stack_ptr = obj_desc; |
215 | } else { | 214 | } else { |
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index d2964af9ad4d..424442d50b5e 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c | |||
@@ -307,6 +307,8 @@ acpi_ex_resolve_operands(u16 opcode, | |||
307 | case ARGI_TARGETREF: /* Allows implicit conversion rules before store */ | 307 | case ARGI_TARGETREF: /* Allows implicit conversion rules before store */ |
308 | case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */ | 308 | case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */ |
309 | case ARGI_SIMPLE_TARGET: /* Name, Local, or arg - no implicit conversion */ | 309 | case ARGI_SIMPLE_TARGET: /* Name, Local, or arg - no implicit conversion */ |
310 | case ARGI_STORE_TARGET: | ||
311 | |||
310 | /* | 312 | /* |
311 | * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE | 313 | * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE |
312 | * A Namespace Node is OK as-is | 314 | * A Namespace Node is OK as-is |
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index a7eee2400ce0..c076e9100d66 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c | |||
@@ -137,7 +137,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, | |||
137 | /* Destination is not a Reference object */ | 137 | /* Destination is not a Reference object */ |
138 | 138 | ||
139 | ACPI_ERROR((AE_INFO, | 139 | ACPI_ERROR((AE_INFO, |
140 | "Target is not a Reference or Constant object - %s [%p]", | 140 | "Target is not a Reference or Constant object - [%s] %p", |
141 | acpi_ut_get_object_type_name(dest_desc), | 141 | acpi_ut_get_object_type_name(dest_desc), |
142 | dest_desc)); | 142 | dest_desc)); |
143 | 143 | ||
@@ -189,7 +189,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, | |||
189 | * displayed and otherwise has no effect -- see ACPI Specification | 189 | * displayed and otherwise has no effect -- see ACPI Specification |
190 | */ | 190 | */ |
191 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 191 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
192 | "**** Write to Debug Object: Object %p %s ****:\n\n", | 192 | "**** Write to Debug Object: Object %p [%s] ****:\n\n", |
193 | source_desc, | 193 | source_desc, |
194 | acpi_ut_get_object_type_name(source_desc))); | 194 | acpi_ut_get_object_type_name(source_desc))); |
195 | 195 | ||
@@ -341,7 +341,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, | |||
341 | /* All other types are invalid */ | 341 | /* All other types are invalid */ |
342 | 342 | ||
343 | ACPI_ERROR((AE_INFO, | 343 | ACPI_ERROR((AE_INFO, |
344 | "Source must be Integer/Buffer/String type, not %s", | 344 | "Source must be type [Integer/Buffer/String], found [%s]", |
345 | acpi_ut_get_object_type_name(source_desc))); | 345 | acpi_ut_get_object_type_name(source_desc))); |
346 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 346 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
347 | } | 347 | } |
@@ -352,8 +352,9 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, | |||
352 | break; | 352 | break; |
353 | 353 | ||
354 | default: | 354 | default: |
355 | ACPI_ERROR((AE_INFO, "Target is not a Package or BufferField")); | 355 | ACPI_ERROR((AE_INFO, |
356 | status = AE_AML_OPERAND_TYPE; | 356 | "Target is not of type [Package/BufferField]")); |
357 | status = AE_AML_TARGET_TYPE; | ||
357 | break; | 358 | break; |
358 | } | 359 | } |
359 | 360 | ||
@@ -373,20 +374,20 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, | |||
373 | * | 374 | * |
374 | * DESCRIPTION: Store the object to the named object. | 375 | * DESCRIPTION: Store the object to the named object. |
375 | * | 376 | * |
376 | * The Assignment of an object to a named object is handled here | 377 | * The assignment of an object to a named object is handled here. |
377 | * The value passed in will replace the current value (if any) | 378 | * The value passed in will replace the current value (if any) |
378 | * with the input value. | 379 | * with the input value. |
379 | * | 380 | * |
380 | * When storing into an object the data is converted to the | 381 | * When storing into an object the data is converted to the |
381 | * target object type then stored in the object. This means | 382 | * target object type then stored in the object. This means |
382 | * that the target object type (for an initialized target) will | 383 | * that the target object type (for an initialized target) will |
383 | * not be changed by a store operation. A copy_object can change | 384 | * not be changed by a store operation. A copy_object can change |
384 | * the target type, however. | 385 | * the target type, however. |
385 | * | 386 | * |
386 | * The implicit_conversion flag is set to NO/FALSE only when | 387 | * The implicit_conversion flag is set to NO/FALSE only when |
387 | * storing to an arg_x -- as per the rules of the ACPI spec. | 388 | * storing to an arg_x -- as per the rules of the ACPI spec. |
388 | * | 389 | * |
389 | * Assumes parameters are already validated. | 390 | * Assumes parameters are already validated. |
390 | * | 391 | * |
391 | ******************************************************************************/ | 392 | ******************************************************************************/ |
392 | 393 | ||
@@ -408,11 +409,75 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, | |||
408 | target_type = acpi_ns_get_type(node); | 409 | target_type = acpi_ns_get_type(node); |
409 | target_desc = acpi_ns_get_attached_object(node); | 410 | target_desc = acpi_ns_get_attached_object(node); |
410 | 411 | ||
411 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n", | 412 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n", |
412 | source_desc, | 413 | source_desc, |
413 | acpi_ut_get_object_type_name(source_desc), node, | 414 | acpi_ut_get_object_type_name(source_desc), node, |
414 | acpi_ut_get_type_name(target_type))); | 415 | acpi_ut_get_type_name(target_type))); |
415 | 416 | ||
417 | /* Only limited target types possible for everything except copy_object */ | ||
418 | |||
419 | if (walk_state->opcode != AML_COPY_OP) { | ||
420 | /* | ||
421 | * Only copy_object allows all object types to be overwritten. For | ||
422 | * target_ref(s), there are restrictions on the object types that | ||
423 | * are allowed. | ||
424 | * | ||
425 | * Allowable operations/typing for Store: | ||
426 | * | ||
427 | * 1) Simple Store | ||
428 | * Integer --> Integer (Named/Local/Arg) | ||
429 | * String --> String (Named/Local/Arg) | ||
430 | * Buffer --> Buffer (Named/Local/Arg) | ||
431 | * Package --> Package (Named/Local/Arg) | ||
432 | * | ||
433 | * 2) Store with implicit conversion | ||
434 | * Integer --> String or Buffer (Named) | ||
435 | * String --> Integer or Buffer (Named) | ||
436 | * Buffer --> Integer or String (Named) | ||
437 | */ | ||
438 | switch (target_type) { | ||
439 | case ACPI_TYPE_PACKAGE: | ||
440 | /* | ||
441 | * Here, can only store a package to an existing package. | ||
442 | * Storing a package to a Local/Arg is OK, and handled | ||
443 | * elsewhere. | ||
444 | */ | ||
445 | if (walk_state->opcode == AML_STORE_OP) { | ||
446 | if (source_desc->common.type != | ||
447 | ACPI_TYPE_PACKAGE) { | ||
448 | ACPI_ERROR((AE_INFO, | ||
449 | "Cannot assign type [%s] to [Package] " | ||
450 | "(source must be type Pkg)", | ||
451 | acpi_ut_get_object_type_name | ||
452 | (source_desc))); | ||
453 | |||
454 | return_ACPI_STATUS(AE_AML_TARGET_TYPE); | ||
455 | } | ||
456 | break; | ||
457 | } | ||
458 | |||
459 | /* Fallthrough */ | ||
460 | |||
461 | case ACPI_TYPE_DEVICE: | ||
462 | case ACPI_TYPE_EVENT: | ||
463 | case ACPI_TYPE_MUTEX: | ||
464 | case ACPI_TYPE_REGION: | ||
465 | case ACPI_TYPE_POWER: | ||
466 | case ACPI_TYPE_PROCESSOR: | ||
467 | case ACPI_TYPE_THERMAL: | ||
468 | |||
469 | ACPI_ERROR((AE_INFO, | ||
470 | "Target must be [Buffer/Integer/String/Reference], found [%s] (%4.4s)", | ||
471 | acpi_ut_get_type_name(node->type), | ||
472 | node->name.ascii)); | ||
473 | |||
474 | return_ACPI_STATUS(AE_AML_TARGET_TYPE); | ||
475 | |||
476 | default: | ||
477 | break; | ||
478 | } | ||
479 | } | ||
480 | |||
416 | /* | 481 | /* |
417 | * Resolve the source object to an actual value | 482 | * Resolve the source object to an actual value |
418 | * (If it is a reference object) | 483 | * (If it is a reference object) |
@@ -425,13 +490,13 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, | |||
425 | /* Do the actual store operation */ | 490 | /* Do the actual store operation */ |
426 | 491 | ||
427 | switch (target_type) { | 492 | switch (target_type) { |
428 | case ACPI_TYPE_INTEGER: | ||
429 | case ACPI_TYPE_STRING: | ||
430 | case ACPI_TYPE_BUFFER: | ||
431 | /* | 493 | /* |
432 | * The simple data types all support implicit source operand | 494 | * The simple data types all support implicit source operand |
433 | * conversion before the store. | 495 | * conversion before the store. |
434 | */ | 496 | */ |
497 | case ACPI_TYPE_INTEGER: | ||
498 | case ACPI_TYPE_STRING: | ||
499 | case ACPI_TYPE_BUFFER: | ||
435 | 500 | ||
436 | if ((walk_state->opcode == AML_COPY_OP) || !implicit_conversion) { | 501 | if ((walk_state->opcode == AML_COPY_OP) || !implicit_conversion) { |
437 | /* | 502 | /* |
@@ -467,7 +532,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, | |||
467 | new_desc->common.type); | 532 | new_desc->common.type); |
468 | 533 | ||
469 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 534 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
470 | "Store %s into %s via Convert/Attach\n", | 535 | "Store type [%s] into [%s] via Convert/Attach\n", |
471 | acpi_ut_get_object_type_name | 536 | acpi_ut_get_object_type_name |
472 | (source_desc), | 537 | (source_desc), |
473 | acpi_ut_get_object_type_name | 538 | acpi_ut_get_object_type_name |
@@ -491,15 +556,12 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, | |||
491 | 556 | ||
492 | default: | 557 | default: |
493 | /* | 558 | /* |
494 | * No conversions for all other types. Directly store a copy of | 559 | * copy_object operator: No conversions for all other types. |
495 | * the source object. This is the ACPI spec-defined behavior for | 560 | * Instead, directly store a copy of the source object. |
496 | * the copy_object operator. | ||
497 | * | 561 | * |
498 | * NOTE: For the Store operator, this is a departure from the | 562 | * This is the ACPI spec-defined behavior for the copy_object |
499 | * ACPI spec, which states "If conversion is impossible, abort | 563 | * operator. (Note, for this default case, all normal |
500 | * the running control method". Instead, this code implements | 564 | * Store/Target operations exited above with an error). |
501 | * "If conversion is impossible, treat the Store operation as | ||
502 | * a CopyObject". | ||
503 | */ | 565 | */ |
504 | status = acpi_ex_store_direct_to_node(source_desc, node, | 566 | status = acpi_ex_store_direct_to_node(source_desc, node, |
505 | walk_state); | 567 | walk_state); |
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c index 3101607b4efe..d1841defa669 100644 --- a/drivers/acpi/acpica/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c | |||
@@ -122,9 +122,10 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, | |||
122 | /* Conversion successful but still not a valid type */ | 122 | /* Conversion successful but still not a valid type */ |
123 | 123 | ||
124 | ACPI_ERROR((AE_INFO, | 124 | ACPI_ERROR((AE_INFO, |
125 | "Cannot assign type %s to %s (must be type Int/Str/Buf)", | 125 | "Cannot assign type [%s] to [%s] (must be type Int/Str/Buf)", |
126 | acpi_ut_get_object_type_name(source_desc), | 126 | acpi_ut_get_object_type_name(source_desc), |
127 | acpi_ut_get_type_name(target_type))); | 127 | acpi_ut_get_type_name(target_type))); |
128 | |||
128 | status = AE_AML_OPERAND_TYPE; | 129 | status = AE_AML_OPERAND_TYPE; |
129 | } | 130 | } |
130 | break; | 131 | break; |
@@ -275,7 +276,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc, | |||
275 | /* | 276 | /* |
276 | * All other types come here. | 277 | * All other types come here. |
277 | */ | 278 | */ |
278 | ACPI_WARNING((AE_INFO, "Store into type %s not implemented", | 279 | ACPI_WARNING((AE_INFO, "Store into type [%s] not implemented", |
279 | acpi_ut_get_object_type_name(dest_desc))); | 280 | acpi_ut_get_object_type_name(dest_desc))); |
280 | 281 | ||
281 | status = AE_NOT_IMPLEMENTED; | 282 | status = AE_NOT_IMPLEMENTED; |
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 0f1daba640e7..37aa5c45ca4b 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c | |||
@@ -60,7 +60,6 @@ acpi_ns_dump_one_device(acpi_handle obj_handle, | |||
60 | 60 | ||
61 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | 61 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) |
62 | 62 | ||
63 | #ifdef ACPI_FUTURE_USAGE | ||
64 | static acpi_status | 63 | static acpi_status |
65 | acpi_ns_dump_one_object_path(acpi_handle obj_handle, | 64 | acpi_ns_dump_one_object_path(acpi_handle obj_handle, |
66 | u32 level, void *context, void **return_value); | 65 | u32 level, void *context, void **return_value); |
@@ -68,7 +67,6 @@ acpi_ns_dump_one_object_path(acpi_handle obj_handle, | |||
68 | static acpi_status | 67 | static acpi_status |
69 | acpi_ns_get_max_depth(acpi_handle obj_handle, | 68 | acpi_ns_get_max_depth(acpi_handle obj_handle, |
70 | u32 level, void *context, void **return_value); | 69 | u32 level, void *context, void **return_value); |
71 | #endif /* ACPI_FUTURE_USAGE */ | ||
72 | 70 | ||
73 | /******************************************************************************* | 71 | /******************************************************************************* |
74 | * | 72 | * |
@@ -625,7 +623,6 @@ cleanup: | |||
625 | return (AE_OK); | 623 | return (AE_OK); |
626 | } | 624 | } |
627 | 625 | ||
628 | #ifdef ACPI_FUTURE_USAGE | ||
629 | /******************************************************************************* | 626 | /******************************************************************************* |
630 | * | 627 | * |
631 | * FUNCTION: acpi_ns_dump_objects | 628 | * FUNCTION: acpi_ns_dump_objects |
@@ -680,9 +677,7 @@ acpi_ns_dump_objects(acpi_object_type type, | |||
680 | 677 | ||
681 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 678 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
682 | } | 679 | } |
683 | #endif /* ACPI_FUTURE_USAGE */ | ||
684 | 680 | ||
685 | #ifdef ACPI_FUTURE_USAGE | ||
686 | /******************************************************************************* | 681 | /******************************************************************************* |
687 | * | 682 | * |
688 | * FUNCTION: acpi_ns_dump_one_object_path, acpi_ns_get_max_depth | 683 | * FUNCTION: acpi_ns_dump_one_object_path, acpi_ns_get_max_depth |
@@ -810,7 +805,6 @@ acpi_ns_dump_object_paths(acpi_object_type type, | |||
810 | 805 | ||
811 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 806 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
812 | } | 807 | } |
813 | #endif /* ACPI_FUTURE_USAGE */ | ||
814 | 808 | ||
815 | /******************************************************************************* | 809 | /******************************************************************************* |
816 | * | 810 | * |
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 0eb54315b4be..0c20980bbcf3 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -226,7 +226,7 @@ acpi_ns_check_object_type(struct acpi_evaluate_info *info, | |||
226 | { | 226 | { |
227 | union acpi_operand_object *return_object = *return_object_ptr; | 227 | union acpi_operand_object *return_object = *return_object_ptr; |
228 | acpi_status status = AE_OK; | 228 | acpi_status status = AE_OK; |
229 | char type_buffer[48]; /* Room for 5 types */ | 229 | char type_buffer[96]; /* Room for 10 types */ |
230 | 230 | ||
231 | /* A Namespace node should not get here, but make sure */ | 231 | /* A Namespace node should not get here, but make sure */ |
232 | 232 | ||
diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c index 89984f30addc..cf2f2faf4f92 100644 --- a/drivers/acpi/acpica/pstree.c +++ b/drivers/acpi/acpica/pstree.c | |||
@@ -183,7 +183,6 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg) | |||
183 | } | 183 | } |
184 | } | 184 | } |
185 | 185 | ||
186 | #ifdef ACPI_FUTURE_USAGE | ||
187 | /******************************************************************************* | 186 | /******************************************************************************* |
188 | * | 187 | * |
189 | * FUNCTION: acpi_ps_get_depth_next | 188 | * FUNCTION: acpi_ps_get_depth_next |
@@ -317,4 +316,3 @@ union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op) | |||
317 | return (child); | 316 | return (child); |
318 | } | 317 | } |
319 | #endif | 318 | #endif |
320 | #endif /* ACPI_FUTURE_USAGE */ | ||
diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c index 183cc1efbc51..71d2877cd2ce 100644 --- a/drivers/acpi/acpica/psutils.c +++ b/drivers/acpi/acpica/psutils.c | |||
@@ -205,7 +205,6 @@ u8 acpi_ps_is_leading_char(u32 c) | |||
205 | /* | 205 | /* |
206 | * Get op's name (4-byte name segment) or 0 if unnamed | 206 | * Get op's name (4-byte name segment) or 0 if unnamed |
207 | */ | 207 | */ |
208 | #ifdef ACPI_FUTURE_USAGE | ||
209 | u32 acpi_ps_get_name(union acpi_parse_object * op) | 208 | u32 acpi_ps_get_name(union acpi_parse_object * op) |
210 | { | 209 | { |
211 | 210 | ||
@@ -219,7 +218,6 @@ u32 acpi_ps_get_name(union acpi_parse_object * op) | |||
219 | 218 | ||
220 | return (op->named.name); | 219 | return (op->named.name); |
221 | } | 220 | } |
222 | #endif /* ACPI_FUTURE_USAGE */ | ||
223 | 221 | ||
224 | /* | 222 | /* |
225 | * Set op's name | 223 | * Set op's name |
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index c428bb33204e..2a09288e7c57 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c | |||
@@ -51,7 +51,6 @@ ACPI_MODULE_NAME("rsdump") | |||
51 | /* | 51 | /* |
52 | * All functions in this module are used by the AML Debugger only | 52 | * All functions in this module are used by the AML Debugger only |
53 | */ | 53 | */ |
54 | #if defined(ACPI_DEBUGGER) | ||
55 | /* Local prototypes */ | 54 | /* Local prototypes */ |
56 | static void acpi_rs_out_string(char *title, char *value); | 55 | static void acpi_rs_out_string(char *title, char *value); |
57 | 56 | ||
@@ -565,5 +564,3 @@ static void acpi_rs_dump_word_list(u16 length, u16 *data) | |||
565 | acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]); | 564 | acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]); |
566 | } | 565 | } |
567 | } | 566 | } |
568 | |||
569 | #endif | ||
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index 52b024df0052..9486992edbb8 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c | |||
@@ -564,7 +564,6 @@ acpi_rs_get_crs_method_data(struct acpi_namespace_node *node, | |||
564 | * | 564 | * |
565 | ******************************************************************************/ | 565 | ******************************************************************************/ |
566 | 566 | ||
567 | #ifdef ACPI_FUTURE_USAGE | ||
568 | acpi_status | 567 | acpi_status |
569 | acpi_rs_get_prs_method_data(struct acpi_namespace_node *node, | 568 | acpi_rs_get_prs_method_data(struct acpi_namespace_node *node, |
570 | struct acpi_buffer *ret_buffer) | 569 | struct acpi_buffer *ret_buffer) |
@@ -596,7 +595,6 @@ acpi_rs_get_prs_method_data(struct acpi_namespace_node *node, | |||
596 | acpi_ut_remove_reference(obj_desc); | 595 | acpi_ut_remove_reference(obj_desc); |
597 | return_ACPI_STATUS(status); | 596 | return_ACPI_STATUS(status); |
598 | } | 597 | } |
599 | #endif /* ACPI_FUTURE_USAGE */ | ||
600 | 598 | ||
601 | /******************************************************************************* | 599 | /******************************************************************************* |
602 | * | 600 | * |
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index de51f836ef68..1e8cd5723326 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c | |||
@@ -220,7 +220,7 @@ acpi_get_current_resources(acpi_handle device_handle, | |||
220 | } | 220 | } |
221 | 221 | ||
222 | ACPI_EXPORT_SYMBOL(acpi_get_current_resources) | 222 | ACPI_EXPORT_SYMBOL(acpi_get_current_resources) |
223 | #ifdef ACPI_FUTURE_USAGE | 223 | |
224 | /******************************************************************************* | 224 | /******************************************************************************* |
225 | * | 225 | * |
226 | * FUNCTION: acpi_get_possible_resources | 226 | * FUNCTION: acpi_get_possible_resources |
@@ -262,7 +262,7 @@ acpi_get_possible_resources(acpi_handle device_handle, | |||
262 | } | 262 | } |
263 | 263 | ||
264 | ACPI_EXPORT_SYMBOL(acpi_get_possible_resources) | 264 | ACPI_EXPORT_SYMBOL(acpi_get_possible_resources) |
265 | #endif /* ACPI_FUTURE_USAGE */ | 265 | |
266 | /******************************************************************************* | 266 | /******************************************************************************* |
267 | * | 267 | * |
268 | * FUNCTION: acpi_set_current_resources | 268 | * FUNCTION: acpi_set_current_resources |
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index 988e23b7795c..ecaaaffc0788 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c | |||
@@ -232,12 +232,27 @@ char *acpi_ut_get_type_name(acpi_object_type type) | |||
232 | 232 | ||
233 | char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc) | 233 | char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc) |
234 | { | 234 | { |
235 | ACPI_FUNCTION_TRACE(ut_get_object_type_name); | ||
235 | 236 | ||
236 | if (!obj_desc) { | 237 | if (!obj_desc) { |
237 | return ("[NULL Object Descriptor]"); | 238 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n")); |
239 | return_PTR("[NULL Object Descriptor]"); | ||
238 | } | 240 | } |
239 | 241 | ||
240 | return (acpi_ut_get_type_name(obj_desc->common.type)); | 242 | /* These descriptor types share a common area */ |
243 | |||
244 | if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) && | ||
245 | (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_NAMED)) { | ||
246 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
247 | "Invalid object descriptor type: 0x%2.2X [%s] (%p)\n", | ||
248 | ACPI_GET_DESCRIPTOR_TYPE(obj_desc), | ||
249 | acpi_ut_get_descriptor_name(obj_desc), | ||
250 | obj_desc)); | ||
251 | |||
252 | return_PTR("Invalid object"); | ||
253 | } | ||
254 | |||
255 | return_PTR(acpi_ut_get_type_name(obj_desc->common.type)); | ||
241 | } | 256 | } |
242 | 257 | ||
243 | /******************************************************************************* | 258 | /******************************************************************************* |
@@ -407,8 +422,6 @@ static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = { | |||
407 | "ACPI_MTX_Events", | 422 | "ACPI_MTX_Events", |
408 | "ACPI_MTX_Caches", | 423 | "ACPI_MTX_Caches", |
409 | "ACPI_MTX_Memory", | 424 | "ACPI_MTX_Memory", |
410 | "ACPI_MTX_CommandComplete", | ||
411 | "ACPI_MTX_CommandReady" | ||
412 | }; | 425 | }; |
413 | 426 | ||
414 | char *acpi_ut_get_mutex_name(u32 mutex_id) | 427 | char *acpi_ut_get_mutex_name(u32 mutex_id) |
diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c index 75a94f52b4be..d435b7b7eb94 100644 --- a/drivers/acpi/acpica/utfileio.c +++ b/drivers/acpi/acpica/utfileio.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "actables.h" | 46 | #include "actables.h" |
47 | #include "acapps.h" | 47 | #include "acapps.h" |
48 | #include "errno.h" | ||
48 | 49 | ||
49 | #ifdef ACPI_ASL_COMPILER | 50 | #ifdef ACPI_ASL_COMPILER |
50 | #include "aslcompiler.h" | 51 | #include "aslcompiler.h" |
@@ -301,6 +302,11 @@ acpi_ut_read_table_from_file(char *filename, struct acpi_table_header ** table) | |||
301 | file = fopen(filename, "rb"); | 302 | file = fopen(filename, "rb"); |
302 | if (!file) { | 303 | if (!file) { |
303 | perror("Could not open input file"); | 304 | perror("Could not open input file"); |
305 | |||
306 | if (errno == ENOENT) { | ||
307 | return (AE_NOT_EXIST); | ||
308 | } | ||
309 | |||
304 | return (status); | 310 | return (status); |
305 | } | 311 | } |
306 | 312 | ||
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index 28ab3a1d5ec1..ccd0745f011e 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c | |||
@@ -241,8 +241,6 @@ acpi_status acpi_ut_init_globals(void) | |||
241 | acpi_gbl_disable_mem_tracking = FALSE; | 241 | acpi_gbl_disable_mem_tracking = FALSE; |
242 | #endif | 242 | #endif |
243 | 243 | ||
244 | ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE); | ||
245 | |||
246 | return_ACPI_STATUS(AE_OK); | 244 | return_ACPI_STATUS(AE_OK); |
247 | } | 245 | } |
248 | 246 | ||
@@ -284,6 +282,19 @@ void acpi_ut_subsystem_shutdown(void) | |||
284 | { | 282 | { |
285 | ACPI_FUNCTION_TRACE(ut_subsystem_shutdown); | 283 | ACPI_FUNCTION_TRACE(ut_subsystem_shutdown); |
286 | 284 | ||
285 | /* Just exit if subsystem is already shutdown */ | ||
286 | |||
287 | if (acpi_gbl_shutdown) { | ||
288 | ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated")); | ||
289 | return_VOID; | ||
290 | } | ||
291 | |||
292 | /* Subsystem appears active, go ahead and shut it down */ | ||
293 | |||
294 | acpi_gbl_shutdown = TRUE; | ||
295 | acpi_gbl_startup_flags = 0; | ||
296 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); | ||
297 | |||
287 | #ifndef ACPI_ASL_COMPILER | 298 | #ifndef ACPI_ASL_COMPILER |
288 | 299 | ||
289 | /* Close the acpi_event Handling */ | 300 | /* Close the acpi_event Handling */ |
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 37b8b58fcd56..ce406e39b669 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
@@ -108,6 +108,21 @@ acpi_status acpi_ut_mutex_initialize(void) | |||
108 | /* Create the reader/writer lock for namespace access */ | 108 | /* Create the reader/writer lock for namespace access */ |
109 | 109 | ||
110 | status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock); | 110 | status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock); |
111 | if (ACPI_FAILURE(status)) { | ||
112 | return_ACPI_STATUS(status); | ||
113 | } | ||
114 | #ifdef ACPI_DEBUGGER | ||
115 | |||
116 | /* Debugger Support */ | ||
117 | |||
118 | status = acpi_os_create_mutex(&acpi_gbl_db_command_ready); | ||
119 | if (ACPI_FAILURE(status)) { | ||
120 | return_ACPI_STATUS(status); | ||
121 | } | ||
122 | |||
123 | status = acpi_os_create_mutex(&acpi_gbl_db_command_complete); | ||
124 | #endif | ||
125 | |||
111 | return_ACPI_STATUS(status); | 126 | return_ACPI_STATUS(status); |
112 | } | 127 | } |
113 | 128 | ||
@@ -147,6 +162,12 @@ void acpi_ut_mutex_terminate(void) | |||
147 | /* Delete the reader/writer lock */ | 162 | /* Delete the reader/writer lock */ |
148 | 163 | ||
149 | acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock); | 164 | acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock); |
165 | |||
166 | #ifdef ACPI_DEBUGGER | ||
167 | acpi_os_delete_mutex(acpi_gbl_db_command_ready); | ||
168 | acpi_os_delete_mutex(acpi_gbl_db_command_complete); | ||
169 | #endif | ||
170 | |||
150 | return_VOID; | 171 | return_VOID; |
151 | } | 172 | } |
152 | 173 | ||
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 4f332815db00..f9c8f9ce1f0f 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -67,23 +67,6 @@ acpi_status __init acpi_terminate(void) | |||
67 | 67 | ||
68 | ACPI_FUNCTION_TRACE(acpi_terminate); | 68 | ACPI_FUNCTION_TRACE(acpi_terminate); |
69 | 69 | ||
70 | /* Just exit if subsystem is already shutdown */ | ||
71 | |||
72 | if (acpi_gbl_shutdown) { | ||
73 | ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated")); | ||
74 | return_ACPI_STATUS(AE_OK); | ||
75 | } | ||
76 | |||
77 | /* Subsystem appears active, go ahead and shut it down */ | ||
78 | |||
79 | acpi_gbl_shutdown = TRUE; | ||
80 | acpi_gbl_startup_flags = 0; | ||
81 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); | ||
82 | |||
83 | /* Terminate the AML Debugger if present */ | ||
84 | |||
85 | ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); | ||
86 | |||
87 | /* Shutdown and free all resources */ | 70 | /* Shutdown and free all resources */ |
88 | 71 | ||
89 | acpi_ut_subsystem_shutdown(); | 72 | acpi_ut_subsystem_shutdown(); |
@@ -270,7 +253,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function) | |||
270 | } | 253 | } |
271 | 254 | ||
272 | ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) | 255 | ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) |
273 | #endif /* ACPI_FUTURE_USAGE */ | 256 | #endif |
274 | 257 | ||
275 | /***************************************************************************** | 258 | /***************************************************************************** |
276 | * | 259 | * |
diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c index c1b8d03e262e..bc18aa213bb1 100644 --- a/drivers/acpi/nfit.c +++ b/drivers/acpi/nfit.c | |||
@@ -706,7 +706,7 @@ static ssize_t flags_show(struct device *dev, | |||
706 | flags & ACPI_NFIT_MEM_SAVE_FAILED ? "save_fail " : "", | 706 | flags & ACPI_NFIT_MEM_SAVE_FAILED ? "save_fail " : "", |
707 | flags & ACPI_NFIT_MEM_RESTORE_FAILED ? "restore_fail " : "", | 707 | flags & ACPI_NFIT_MEM_RESTORE_FAILED ? "restore_fail " : "", |
708 | flags & ACPI_NFIT_MEM_FLUSH_FAILED ? "flush_fail " : "", | 708 | flags & ACPI_NFIT_MEM_FLUSH_FAILED ? "flush_fail " : "", |
709 | flags & ACPI_NFIT_MEM_ARMED ? "not_armed " : "", | 709 | flags & ACPI_NFIT_MEM_NOT_ARMED ? "not_armed " : "", |
710 | flags & ACPI_NFIT_MEM_HEALTH_OBSERVED ? "smart_event " : ""); | 710 | flags & ACPI_NFIT_MEM_HEALTH_OBSERVED ? "smart_event " : ""); |
711 | } | 711 | } |
712 | static DEVICE_ATTR_RO(flags); | 712 | static DEVICE_ATTR_RO(flags); |
@@ -815,7 +815,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc) | |||
815 | flags |= NDD_ALIASING; | 815 | flags |= NDD_ALIASING; |
816 | 816 | ||
817 | mem_flags = __to_nfit_memdev(nfit_mem)->flags; | 817 | mem_flags = __to_nfit_memdev(nfit_mem)->flags; |
818 | if (mem_flags & ACPI_NFIT_MEM_ARMED) | 818 | if (mem_flags & ACPI_NFIT_MEM_NOT_ARMED) |
819 | flags |= NDD_UNARMED; | 819 | flags |= NDD_UNARMED; |
820 | 820 | ||
821 | rc = acpi_nfit_add_dimm(acpi_desc, nfit_mem, device_handle); | 821 | rc = acpi_nfit_add_dimm(acpi_desc, nfit_mem, device_handle); |
@@ -839,7 +839,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc) | |||
839 | mem_flags & ACPI_NFIT_MEM_SAVE_FAILED ? " save_fail" : "", | 839 | mem_flags & ACPI_NFIT_MEM_SAVE_FAILED ? " save_fail" : "", |
840 | mem_flags & ACPI_NFIT_MEM_RESTORE_FAILED ? " restore_fail":"", | 840 | mem_flags & ACPI_NFIT_MEM_RESTORE_FAILED ? " restore_fail":"", |
841 | mem_flags & ACPI_NFIT_MEM_FLUSH_FAILED ? " flush_fail" : "", | 841 | mem_flags & ACPI_NFIT_MEM_FLUSH_FAILED ? " flush_fail" : "", |
842 | mem_flags & ACPI_NFIT_MEM_ARMED ? " not_armed" : ""); | 842 | mem_flags & ACPI_NFIT_MEM_NOT_ARMED ? " not_armed" : ""); |
843 | 843 | ||
844 | } | 844 | } |
845 | 845 | ||
diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit.h index 7e740156b9c2..329a1eba0c16 100644 --- a/drivers/acpi/nfit.h +++ b/drivers/acpi/nfit.h | |||
@@ -24,7 +24,7 @@ | |||
24 | #define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66" | 24 | #define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66" |
25 | #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \ | 25 | #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \ |
26 | | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \ | 26 | | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \ |
27 | | ACPI_NFIT_MEM_ARMED) | 27 | | ACPI_NFIT_MEM_NOT_ARMED) |
28 | 28 | ||
29 | enum nfit_uuids { | 29 | enum nfit_uuids { |
30 | NFIT_SPA_VOLATILE, | 30 | NFIT_SPA_VOLATILE, |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 739a4a6b3b9b..327291586f84 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -66,8 +66,6 @@ struct acpi_os_dpc { | |||
66 | /* stuff for debugger support */ | 66 | /* stuff for debugger support */ |
67 | int acpi_in_debugger; | 67 | int acpi_in_debugger; |
68 | EXPORT_SYMBOL(acpi_in_debugger); | 68 | EXPORT_SYMBOL(acpi_in_debugger); |
69 | |||
70 | extern char line_buf[80]; | ||
71 | #endif /*ENABLE_DEBUGGER */ | 69 | #endif /*ENABLE_DEBUGGER */ |
72 | 70 | ||
73 | static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl, | 71 | static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl, |
@@ -1345,15 +1343,13 @@ acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) | |||
1345 | return AE_OK; | 1343 | return AE_OK; |
1346 | } | 1344 | } |
1347 | 1345 | ||
1348 | #ifdef ACPI_FUTURE_USAGE | 1346 | acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read) |
1349 | u32 acpi_os_get_line(char *buffer) | ||
1350 | { | 1347 | { |
1351 | |||
1352 | #ifdef ENABLE_DEBUGGER | 1348 | #ifdef ENABLE_DEBUGGER |
1353 | if (acpi_in_debugger) { | 1349 | if (acpi_in_debugger) { |
1354 | u32 chars; | 1350 | u32 chars; |
1355 | 1351 | ||
1356 | kdb_read(buffer, sizeof(line_buf)); | 1352 | kdb_read(buffer, buffer_length); |
1357 | 1353 | ||
1358 | /* remove the CR kdb includes */ | 1354 | /* remove the CR kdb includes */ |
1359 | chars = strlen(buffer) - 1; | 1355 | chars = strlen(buffer) - 1; |
@@ -1361,9 +1357,8 @@ u32 acpi_os_get_line(char *buffer) | |||
1361 | } | 1357 | } |
1362 | #endif | 1358 | #endif |
1363 | 1359 | ||
1364 | return 0; | 1360 | return AE_OK; |
1365 | } | 1361 | } |
1366 | #endif /* ACPI_FUTURE_USAGE */ | ||
1367 | 1362 | ||
1368 | acpi_status acpi_os_signal(u32 function, void *info) | 1363 | acpi_status acpi_os_signal(u32 function, void *info) |
1369 | { | 1364 | { |
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 9f20eb4acaa6..204f5819d464 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h | |||
@@ -193,8 +193,9 @@ struct acpi_exception_info { | |||
193 | #define AE_AML_ILLEGAL_ADDRESS EXCEP_AML (0x0020) | 193 | #define AE_AML_ILLEGAL_ADDRESS EXCEP_AML (0x0020) |
194 | #define AE_AML_INFINITE_LOOP EXCEP_AML (0x0021) | 194 | #define AE_AML_INFINITE_LOOP EXCEP_AML (0x0021) |
195 | #define AE_AML_UNINITIALIZED_NODE EXCEP_AML (0x0022) | 195 | #define AE_AML_UNINITIALIZED_NODE EXCEP_AML (0x0022) |
196 | #define AE_AML_TARGET_TYPE EXCEP_AML (0x0023) | ||
196 | 197 | ||
197 | #define AE_CODE_AML_MAX 0x0022 | 198 | #define AE_CODE_AML_MAX 0x0023 |
198 | 199 | ||
199 | /* | 200 | /* |
200 | * Internal exceptions used for control | 201 | * Internal exceptions used for control |
@@ -358,7 +359,9 @@ static const struct acpi_exception_info acpi_gbl_exception_names_aml[] = { | |||
358 | EXCEP_TXT("AE_AML_INFINITE_LOOP", | 359 | EXCEP_TXT("AE_AML_INFINITE_LOOP", |
359 | "An apparent infinite AML While loop, method was aborted"), | 360 | "An apparent infinite AML While loop, method was aborted"), |
360 | EXCEP_TXT("AE_AML_UNINITIALIZED_NODE", | 361 | EXCEP_TXT("AE_AML_UNINITIALIZED_NODE", |
361 | "A namespace node is uninitialized or unresolved") | 362 | "A namespace node is uninitialized or unresolved"), |
363 | EXCEP_TXT("AE_AML_TARGET_TYPE", | ||
364 | "A target operand of an incorrect type was encountered") | ||
362 | }; | 365 | }; |
363 | 366 | ||
364 | static const struct acpi_exception_info acpi_gbl_exception_names_ctrl[] = { | 367 | static const struct acpi_exception_info acpi_gbl_exception_names_ctrl[] = { |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index a54ad1cc990c..fbc2baf2b9dc 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -55,7 +55,8 @@ typedef enum { | |||
55 | OSL_GLOBAL_LOCK_HANDLER, | 55 | OSL_GLOBAL_LOCK_HANDLER, |
56 | OSL_NOTIFY_HANDLER, | 56 | OSL_NOTIFY_HANDLER, |
57 | OSL_GPE_HANDLER, | 57 | OSL_GPE_HANDLER, |
58 | OSL_DEBUGGER_THREAD, | 58 | OSL_DEBUGGER_MAIN_THREAD, |
59 | OSL_DEBUGGER_EXEC_THREAD, | ||
59 | OSL_EC_POLL_HANDLER, | 60 | OSL_EC_POLL_HANDLER, |
60 | OSL_EC_BURST_HANDLER | 61 | OSL_EC_BURST_HANDLER |
61 | } acpi_execute_type; | 62 | } acpi_execute_type; |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index c33eeabde160..3aaaa8630735 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 0x20150818 | 49 | #define ACPI_CA_VERSION 0x20150930 |
50 | 50 | ||
51 | #include <acpi/acconfig.h> | 51 | #include <acpi/acconfig.h> |
52 | #include <acpi/actypes.h> | 52 | #include <acpi/actypes.h> |
@@ -393,15 +393,11 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_terminate(void)) | |||
393 | */ | 393 | */ |
394 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable(void)) | 394 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable(void)) |
395 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable(void)) | 395 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable(void)) |
396 | #ifdef ACPI_FUTURE_USAGE | ||
397 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_subsystem_status(void)) | 396 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_subsystem_status(void)) |
398 | #endif | ||
399 | 397 | ||
400 | #ifdef ACPI_FUTURE_USAGE | ||
401 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | 398 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
402 | acpi_get_system_info(struct acpi_buffer | 399 | acpi_get_system_info(struct acpi_buffer |
403 | *ret_buffer)) | 400 | *ret_buffer)) |
404 | #endif | ||
405 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | 401 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
406 | acpi_get_statistics(struct acpi_statistics *stats)) | 402 | acpi_get_statistics(struct acpi_statistics *stats)) |
407 | ACPI_EXTERNAL_RETURN_PTR(const char | 403 | ACPI_EXTERNAL_RETURN_PTR(const char |
@@ -625,11 +621,9 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status | |||
625 | space_id, | 621 | space_id, |
626 | acpi_adr_space_handler | 622 | acpi_adr_space_handler |
627 | handler)) | 623 | handler)) |
628 | #ifdef ACPI_FUTURE_USAGE | ||
629 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | 624 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
630 | acpi_install_exception_handler | 625 | acpi_install_exception_handler |
631 | (acpi_exception_handler handler)) | 626 | (acpi_exception_handler handler)) |
632 | #endif | ||
633 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | 627 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
634 | acpi_install_interface_handler | 628 | acpi_install_interface_handler |
635 | (acpi_interface_handler handler)) | 629 | (acpi_interface_handler handler)) |
@@ -750,12 +744,10 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status | |||
750 | acpi_get_current_resources(acpi_handle device, | 744 | acpi_get_current_resources(acpi_handle device, |
751 | struct acpi_buffer | 745 | struct acpi_buffer |
752 | *ret_buffer)) | 746 | *ret_buffer)) |
753 | #ifdef ACPI_FUTURE_USAGE | ||
754 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | 747 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
755 | acpi_get_possible_resources(acpi_handle device, | 748 | acpi_get_possible_resources(acpi_handle device, |
756 | struct acpi_buffer | 749 | struct acpi_buffer |
757 | *ret_buffer)) | 750 | *ret_buffer)) |
758 | #endif | ||
759 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | 751 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
760 | acpi_get_event_resources(acpi_handle device_handle, | 752 | acpi_get_event_resources(acpi_handle device_handle, |
761 | struct acpi_buffer | 753 | struct acpi_buffer |
@@ -844,7 +836,6 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
844 | /* | 836 | /* |
845 | * ACPI Timer interfaces | 837 | * ACPI Timer interfaces |
846 | */ | 838 | */ |
847 | #ifdef ACPI_FUTURE_USAGE | ||
848 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 839 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
849 | acpi_get_timer_resolution(u32 *resolution)) | 840 | acpi_get_timer_resolution(u32 *resolution)) |
850 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_get_timer(u32 *ticks)) | 841 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_get_timer(u32 *ticks)) |
@@ -853,7 +844,6 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
853 | acpi_get_timer_duration(u32 start_ticks, | 844 | acpi_get_timer_duration(u32 start_ticks, |
854 | u32 end_ticks, | 845 | u32 end_ticks, |
855 | u32 *time_elapsed)) | 846 | u32 *time_elapsed)) |
856 | #endif /* ACPI_FUTURE_USAGE */ | ||
857 | 847 | ||
858 | /* | 848 | /* |
859 | * Error/Warning output | 849 | * Error/Warning output |
@@ -939,4 +929,6 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status | |||
939 | void **data, | 929 | void **data, |
940 | void (*callback)(void *))) | 930 | void (*callback)(void *))) |
941 | 931 | ||
932 | void acpi_set_debugger_thread_id(acpi_thread_id thread_id); | ||
933 | |||
942 | #endif /* __ACXFACE_H__ */ | 934 | #endif /* __ACXFACE_H__ */ |
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index fcd570999f35..1bb979e3e3f5 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h | |||
@@ -1012,7 +1012,7 @@ struct acpi_nfit_memory_map { | |||
1012 | #define ACPI_NFIT_MEM_SAVE_FAILED (1) /* 00: Last SAVE to Memory Device failed */ | 1012 | #define ACPI_NFIT_MEM_SAVE_FAILED (1) /* 00: Last SAVE to Memory Device failed */ |
1013 | #define ACPI_NFIT_MEM_RESTORE_FAILED (1<<1) /* 01: Last RESTORE from Memory Device failed */ | 1013 | #define ACPI_NFIT_MEM_RESTORE_FAILED (1<<1) /* 01: Last RESTORE from Memory Device failed */ |
1014 | #define ACPI_NFIT_MEM_FLUSH_FAILED (1<<2) /* 02: Platform flush failed */ | 1014 | #define ACPI_NFIT_MEM_FLUSH_FAILED (1<<2) /* 02: Platform flush failed */ |
1015 | #define ACPI_NFIT_MEM_ARMED (1<<3) /* 03: Memory Device observed to be not armed */ | 1015 | #define ACPI_NFIT_MEM_NOT_ARMED (1<<3) /* 03: Memory Device is not armed */ |
1016 | #define ACPI_NFIT_MEM_HEALTH_OBSERVED (1<<4) /* 04: Memory Device observed SMART/health events */ | 1016 | #define ACPI_NFIT_MEM_HEALTH_OBSERVED (1<<4) /* 04: Memory Device observed SMART/health events */ |
1017 | #define ACPI_NFIT_MEM_HEALTH_ENABLED (1<<5) /* 05: SMART/health events enabled */ | 1017 | #define ACPI_NFIT_MEM_HEALTH_ENABLED (1<<5) /* 05: SMART/health events enabled */ |
1018 | 1018 | ||
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index ec00e2bb029e..056f245ad038 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h | |||
@@ -142,7 +142,7 @@ | |||
142 | 142 | ||
143 | #ifdef ACPI_LIBRARY | 143 | #ifdef ACPI_LIBRARY |
144 | #define ACPI_USE_LOCAL_CACHE | 144 | #define ACPI_USE_LOCAL_CACHE |
145 | #define ACPI_FUTURE_USAGE | 145 | #define ACPI_FULL_DEBUG |
146 | #endif | 146 | #endif |
147 | 147 | ||
148 | /* Common for all ACPICA applications */ | 148 | /* Common for all ACPICA applications */ |
@@ -304,11 +304,11 @@ | |||
304 | * multi-threaded if ACPI_APPLICATION is not set. | 304 | * multi-threaded if ACPI_APPLICATION is not set. |
305 | */ | 305 | */ |
306 | #ifndef DEBUGGER_THREADING | 306 | #ifndef DEBUGGER_THREADING |
307 | #ifdef ACPI_APPLICATION | 307 | #if !defined (ACPI_APPLICATION) || defined (ACPI_EXEC_APP) |
308 | #define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED | 308 | #define DEBUGGER_THREADING DEBUGGER_MULTI_THREADED |
309 | 309 | ||
310 | #else | 310 | #else |
311 | #define DEBUGGER_THREADING DEBUGGER_MULTI_THREADED | 311 | #define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED |
312 | #endif | 312 | #endif |
313 | #endif /* !DEBUGGER_THREADING */ | 313 | #endif /* !DEBUGGER_THREADING */ |
314 | 314 | ||
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 74ba46c8157a..323e5daece54 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
@@ -63,12 +63,16 @@ | |||
63 | 63 | ||
64 | #define ACPI_USE_SYSTEM_INTTYPES | 64 | #define ACPI_USE_SYSTEM_INTTYPES |
65 | 65 | ||
66 | /* Compile for reduced hardware mode only with this kernel config */ | 66 | /* Kernel specific ACPICA configuration */ |
67 | 67 | ||
68 | #ifdef CONFIG_ACPI_REDUCED_HARDWARE_ONLY | 68 | #ifdef CONFIG_ACPI_REDUCED_HARDWARE_ONLY |
69 | #define ACPI_REDUCED_HARDWARE 1 | 69 | #define ACPI_REDUCED_HARDWARE 1 |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | #ifdef CONFIG_ACPI_DEBUGGER | ||
73 | #define ACPI_DEBUGGER | ||
74 | #endif | ||
75 | |||
72 | #include <linux/string.h> | 76 | #include <linux/string.h> |
73 | #include <linux/kernel.h> | 77 | #include <linux/kernel.h> |
74 | #include <linux/ctype.h> | 78 | #include <linux/ctype.h> |
@@ -151,7 +155,6 @@ | |||
151 | * OSL interfaces used by utilities | 155 | * OSL interfaces used by utilities |
152 | */ | 156 | */ |
153 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_redirect_output | 157 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_redirect_output |
154 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_line | ||
155 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_name | 158 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_name |
156 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_index | 159 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_index |
157 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_address | 160 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_address |
diff --git a/include/acpi/platform/aclinuxex.h b/include/acpi/platform/aclinuxex.h index acedc3f026de..fd6d70fe1219 100644 --- a/include/acpi/platform/aclinuxex.h +++ b/include/acpi/platform/aclinuxex.h | |||
@@ -124,6 +124,11 @@ static inline acpi_thread_id acpi_os_get_thread_id(void) | |||
124 | lock ? AE_OK : AE_NO_MEMORY; \ | 124 | lock ? AE_OK : AE_NO_MEMORY; \ |
125 | }) | 125 | }) |
126 | 126 | ||
127 | static inline u8 acpi_os_readable(void *pointer, acpi_size length) | ||
128 | { | ||
129 | return TRUE; | ||
130 | } | ||
131 | |||
127 | /* | 132 | /* |
128 | * OSL interfaces added by Linux | 133 | * OSL interfaces added by Linux |
129 | */ | 134 | */ |
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c index a37f9702b2a9..a1c62de42a3b 100644 --- a/tools/power/acpi/tools/acpidump/apfiles.c +++ b/tools/power/acpi/tools/acpidump/apfiles.c | |||
@@ -150,7 +150,7 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance) | |||
150 | strcat(filename, instance_str); | 150 | strcat(filename, instance_str); |
151 | } | 151 | } |
152 | 152 | ||
153 | strcat(filename, ACPI_TABLE_FILE_SUFFIX); | 153 | strcat(filename, FILE_SUFFIX_BINARY_TABLE); |
154 | 154 | ||
155 | if (gbl_verbose_mode) { | 155 | if (gbl_verbose_mode) { |
156 | acpi_log_error | 156 | acpi_log_error |