0001
0002
0003
0004
0005
0006
0007
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "amlcode.h"
0011 #include "acdebug.h"
0012 #include "acinterp.h"
0013 #include "acparser.h"
0014
0015 #define _COMPONENT ACPI_CA_DEBUGGER
0016 ACPI_MODULE_NAME("dbxface")
0017
0018
0019 static acpi_status
0020 acpi_db_start_command(struct acpi_walk_state *walk_state,
0021 union acpi_parse_object *op);
0022
0023 #ifdef ACPI_OBSOLETE_FUNCTIONS
0024 void acpi_db_method_end(struct acpi_walk_state *walk_state);
0025 #endif
0026
0027 #ifdef ACPI_DISASSEMBLER
0028 static union acpi_parse_object *acpi_db_get_display_op(struct acpi_walk_state
0029 *walk_state,
0030 union acpi_parse_object
0031 *op);
0032 #endif
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 static acpi_status
0048 acpi_db_start_command(struct acpi_walk_state *walk_state,
0049 union acpi_parse_object *op)
0050 {
0051 acpi_status status;
0052
0053
0054
0055
0056
0057
0058
0059 acpi_gbl_method_executing = TRUE;
0060 status = AE_CTRL_TRUE;
0061
0062 while (status == AE_CTRL_TRUE) {
0063
0064
0065
0066 status = acpi_os_notify_command_complete();
0067 if (ACPI_FAILURE(status)) {
0068 goto error_exit;
0069 }
0070
0071
0072
0073 status = acpi_os_wait_command_ready();
0074 if (ACPI_FAILURE(status)) {
0075 goto error_exit;
0076 }
0077
0078 status =
0079 acpi_db_command_dispatch(acpi_gbl_db_line_buf, walk_state,
0080 op);
0081 }
0082
0083
0084
0085 error_exit:
0086 if (ACPI_FAILURE(status) && status != AE_CTRL_TERMINATE) {
0087 ACPI_EXCEPTION((AE_INFO, status,
0088 "While parsing/handling command line"));
0089 }
0090 return (status);
0091 }
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 void acpi_db_signal_break_point(struct acpi_walk_state *walk_state)
0106 {
0107
0108 #ifndef ACPI_APPLICATION
0109 if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
0110 return;
0111 }
0112 #endif
0113
0114
0115
0116
0117
0118
0119 acpi_gbl_cm_single_step = TRUE;
0120 acpi_os_printf("**break** Executed AML BreakPoint opcode\n");
0121 }
0122
0123 #ifdef ACPI_DISASSEMBLER
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 static union acpi_parse_object *acpi_db_get_display_op(struct acpi_walk_state
0138 *walk_state,
0139 union acpi_parse_object
0140 *op)
0141 {
0142 union acpi_parse_object *display_op;
0143 union acpi_parse_object *parent_op;
0144
0145 display_op = op;
0146 parent_op = op->common.parent;
0147 if (parent_op) {
0148 if ((walk_state->control_state) &&
0149 (walk_state->control_state->common.state ==
0150 ACPI_CONTROL_PREDICATE_EXECUTING)) {
0151
0152
0153
0154
0155
0156 while (parent_op) {
0157 if ((parent_op->common.aml_opcode == AML_IF_OP)
0158 || (parent_op->common.aml_opcode ==
0159 AML_WHILE_OP)) {
0160 display_op = parent_op;
0161 break;
0162 }
0163 parent_op = parent_op->common.parent;
0164 }
0165 } else {
0166 while (parent_op) {
0167 if ((parent_op->common.aml_opcode == AML_IF_OP)
0168 || (parent_op->common.aml_opcode ==
0169 AML_ELSE_OP)
0170 || (parent_op->common.aml_opcode ==
0171 AML_SCOPE_OP)
0172 || (parent_op->common.aml_opcode ==
0173 AML_METHOD_OP)
0174 || (parent_op->common.aml_opcode ==
0175 AML_WHILE_OP)) {
0176 break;
0177 }
0178 display_op = parent_op;
0179 parent_op = parent_op->common.parent;
0180 }
0181 }
0182 }
0183 return display_op;
0184 }
0185 #endif
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 acpi_status
0202 acpi_db_single_step(struct acpi_walk_state *walk_state,
0203 union acpi_parse_object *op, u32 opcode_class)
0204 {
0205 union acpi_parse_object *next;
0206 acpi_status status = AE_OK;
0207 u32 original_debug_level;
0208 u32 aml_offset;
0209
0210 ACPI_FUNCTION_ENTRY();
0211
0212 #ifndef ACPI_APPLICATION
0213 if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
0214 return (AE_OK);
0215 }
0216 #endif
0217
0218
0219
0220 if (acpi_gbl_abort_method) {
0221 acpi_gbl_abort_method = FALSE;
0222 return (AE_ABORT_METHOD);
0223 }
0224
0225 aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml,
0226 walk_state->parser_state.aml_start);
0227
0228
0229
0230 if (walk_state->method_breakpoint &&
0231 (walk_state->method_breakpoint <= aml_offset)) {
0232
0233
0234
0235
0236 acpi_os_printf("***Break*** at AML offset %X\n", aml_offset);
0237 acpi_gbl_cm_single_step = TRUE;
0238 acpi_gbl_step_to_next_call = FALSE;
0239 walk_state->method_breakpoint = 0;
0240 }
0241
0242
0243
0244 else if (walk_state->user_breakpoint &&
0245 (walk_state->user_breakpoint == aml_offset)) {
0246 acpi_os_printf("***UserBreakpoint*** at AML offset %X\n",
0247 aml_offset);
0248 acpi_gbl_cm_single_step = TRUE;
0249 acpi_gbl_step_to_next_call = FALSE;
0250 walk_state->method_breakpoint = 0;
0251 }
0252
0253
0254
0255
0256
0257 if (op->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
0258 return (AE_OK);
0259 }
0260
0261 switch (opcode_class) {
0262 case AML_CLASS_UNKNOWN:
0263 case AML_CLASS_ARGUMENT:
0264
0265 return (AE_OK);
0266
0267 default:
0268
0269
0270 break;
0271 }
0272
0273
0274
0275
0276 if ((acpi_gbl_db_output_to_file) ||
0277 (acpi_gbl_cm_single_step) || (acpi_dbg_level & ACPI_LV_PARSE)) {
0278 if ((acpi_gbl_db_output_to_file) ||
0279 (acpi_dbg_level & ACPI_LV_PARSE)) {
0280 acpi_os_printf
0281 ("\nAML Debug: Next AML Opcode to execute:\n");
0282 }
0283
0284
0285
0286
0287
0288
0289 original_debug_level = acpi_dbg_level;
0290 acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
0291 next = op->common.next;
0292 op->common.next = NULL;
0293
0294
0295
0296 #ifdef ACPI_DISASSEMBLER
0297 acpi_dm_disassemble(walk_state,
0298 acpi_db_get_display_op(walk_state, op),
0299 ACPI_UINT32_MAX);
0300 #else
0301
0302
0303
0304
0305 acpi_os_printf("AML Opcode: %4.4X %s\n", op->common.aml_opcode,
0306 acpi_ps_get_opcode_name(op->common.aml_opcode));
0307 #endif
0308
0309 if ((op->common.aml_opcode == AML_IF_OP) ||
0310 (op->common.aml_opcode == AML_WHILE_OP)) {
0311 if (walk_state->control_state->common.value) {
0312 acpi_os_printf
0313 ("Predicate = [True], IF block was executed\n");
0314 } else {
0315 acpi_os_printf
0316 ("Predicate = [False], Skipping IF block\n");
0317 }
0318 } else if (op->common.aml_opcode == AML_ELSE_OP) {
0319 acpi_os_printf
0320 ("Predicate = [False], ELSE block was executed\n");
0321 }
0322
0323
0324
0325 op->common.next = next;
0326 acpi_os_printf("\n");
0327 if ((acpi_gbl_db_output_to_file) ||
0328 (acpi_dbg_level & ACPI_LV_PARSE)) {
0329 acpi_os_printf("\n");
0330 }
0331 acpi_dbg_level = original_debug_level;
0332 }
0333
0334
0335
0336 if (!acpi_gbl_cm_single_step) {
0337 return (AE_OK);
0338 }
0339
0340
0341
0342
0343
0344 if (acpi_gbl_step_to_next_call) {
0345 if (op->common.aml_opcode != AML_INT_METHODCALL_OP) {
0346
0347
0348
0349 return (AE_OK);
0350 }
0351
0352
0353
0354 acpi_gbl_step_to_next_call = FALSE;
0355 }
0356
0357
0358
0359
0360
0361 if (op->common.aml_opcode == AML_INT_METHODCALL_OP) {
0362
0363
0364
0365 acpi_gbl_cm_single_step = FALSE;
0366
0367
0368
0369
0370
0371 walk_state->method_breakpoint = 1;
0372 }
0373
0374 acpi_ex_exit_interpreter();
0375 status = acpi_db_start_command(walk_state, op);
0376 acpi_ex_enter_interpreter();
0377
0378
0379
0380 return (status);
0381 }
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395 acpi_status acpi_initialize_debugger(void)
0396 {
0397 acpi_status status;
0398
0399 ACPI_FUNCTION_TRACE(acpi_initialize_debugger);
0400
0401
0402
0403 acpi_gbl_db_buffer = NULL;
0404 acpi_gbl_db_filename = NULL;
0405 acpi_gbl_db_output_to_file = FALSE;
0406
0407 acpi_gbl_db_debug_level = ACPI_LV_VERBOSITY2;
0408 acpi_gbl_db_console_debug_level = ACPI_NORMAL_DEFAULT | ACPI_LV_TABLES;
0409 acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
0410
0411 acpi_gbl_db_opt_no_ini_methods = FALSE;
0412 acpi_gbl_db_opt_no_region_support = FALSE;
0413
0414 acpi_gbl_db_buffer = acpi_os_allocate(ACPI_DEBUG_BUFFER_SIZE);
0415 if (!acpi_gbl_db_buffer) {
0416 return_ACPI_STATUS(AE_NO_MEMORY);
0417 }
0418 memset(acpi_gbl_db_buffer, 0, ACPI_DEBUG_BUFFER_SIZE);
0419
0420
0421
0422 acpi_gbl_db_scope_buf[0] = AML_ROOT_PREFIX;
0423 acpi_gbl_db_scope_buf[1] = 0;
0424 acpi_gbl_db_scope_node = acpi_gbl_root_node;
0425
0426
0427
0428 acpi_gbl_db_terminate_loop = FALSE;
0429
0430
0431
0432
0433
0434
0435 if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
0436
0437
0438
0439 status = acpi_os_initialize_debugger();
0440 if (ACPI_FAILURE(status)) {
0441 acpi_os_printf("Could not get debugger mutex\n");
0442 return_ACPI_STATUS(status);
0443 }
0444
0445
0446
0447 acpi_gbl_db_threads_terminated = FALSE;
0448 status = acpi_os_execute(OSL_DEBUGGER_MAIN_THREAD,
0449 acpi_db_execute_thread, NULL);
0450 if (ACPI_FAILURE(status)) {
0451 ACPI_EXCEPTION((AE_INFO, status,
0452 "Could not start debugger thread"));
0453 acpi_gbl_db_threads_terminated = TRUE;
0454 return_ACPI_STATUS(status);
0455 }
0456 } else {
0457 acpi_gbl_db_thread_id = acpi_os_get_thread_id();
0458 }
0459
0460 return_ACPI_STATUS(AE_OK);
0461 }
0462
0463 ACPI_EXPORT_SYMBOL(acpi_initialize_debugger)
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476 void acpi_terminate_debugger(void)
0477 {
0478
0479
0480
0481 acpi_gbl_db_terminate_loop = TRUE;
0482
0483 if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
0484
0485
0486
0487 while (!acpi_gbl_db_threads_terminated) {
0488 acpi_os_sleep(100);
0489 }
0490
0491 acpi_os_terminate_debugger();
0492 }
0493
0494 if (acpi_gbl_db_buffer) {
0495 acpi_os_free(acpi_gbl_db_buffer);
0496 acpi_gbl_db_buffer = NULL;
0497 }
0498
0499
0500
0501 acpi_gbl_db_output_flags = ACPI_DB_DISABLE_OUTPUT;
0502 }
0503
0504 ACPI_EXPORT_SYMBOL(acpi_terminate_debugger)
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517 void acpi_set_debugger_thread_id(acpi_thread_id thread_id)
0518 {
0519 acpi_gbl_db_thread_id = thread_id;
0520 }
0521
0522 ACPI_EXPORT_SYMBOL(acpi_set_debugger_thread_id)