xref: /openbmc/linux/drivers/acpi/acpica/dbxface.c (revision ead5d1f4d877e92c051e1a1ade623d0d30e71619)
195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
299575102SLv Zheng /*******************************************************************************
399575102SLv Zheng  *
499575102SLv Zheng  * Module Name: dbxface - AML Debugger external interfaces
599575102SLv Zheng  *
699575102SLv Zheng  ******************************************************************************/
799575102SLv Zheng 
899575102SLv Zheng #include <acpi/acpi.h>
999575102SLv Zheng #include "accommon.h"
1099575102SLv Zheng #include "amlcode.h"
1199575102SLv Zheng #include "acdebug.h"
12069f9bf4SLv Zheng #include "acinterp.h"
13fb2ef998SBob Moore #include "acparser.h"
1499575102SLv Zheng 
1599575102SLv Zheng #define _COMPONENT          ACPI_CA_DEBUGGER
1699575102SLv Zheng ACPI_MODULE_NAME("dbxface")
1799575102SLv Zheng 
1899575102SLv Zheng /* Local prototypes */
1999575102SLv Zheng static acpi_status
2099575102SLv Zheng acpi_db_start_command(struct acpi_walk_state *walk_state,
2199575102SLv Zheng 		      union acpi_parse_object *op);
2299575102SLv Zheng 
2399575102SLv Zheng #ifdef ACPI_OBSOLETE_FUNCTIONS
2499575102SLv Zheng void acpi_db_method_end(struct acpi_walk_state *walk_state);
2599575102SLv Zheng #endif
2699575102SLv Zheng 
27c647eb98SErik Schmauss #ifdef ACPI_DISASSEMBLER
28c647eb98SErik Schmauss static union acpi_parse_object *acpi_db_get_display_op(struct acpi_walk_state
29c647eb98SErik Schmauss 						       *walk_state,
30c647eb98SErik Schmauss 						       union acpi_parse_object
31c647eb98SErik Schmauss 						       *op);
32c647eb98SErik Schmauss #endif
33c647eb98SErik Schmauss 
3499575102SLv Zheng /*******************************************************************************
3599575102SLv Zheng  *
3699575102SLv Zheng  * FUNCTION:    acpi_db_start_command
3799575102SLv Zheng  *
3899575102SLv Zheng  * PARAMETERS:  walk_state      - Current walk
3999575102SLv Zheng  *              op              - Current executing Op, from AML interpreter
4099575102SLv Zheng  *
4199575102SLv Zheng  * RETURN:      Status
4299575102SLv Zheng  *
4399575102SLv Zheng  * DESCRIPTION: Enter debugger command loop
4499575102SLv Zheng  *
4599575102SLv Zheng  ******************************************************************************/
4699575102SLv Zheng 
4799575102SLv Zheng static acpi_status
acpi_db_start_command(struct acpi_walk_state * walk_state,union acpi_parse_object * op)4899575102SLv Zheng acpi_db_start_command(struct acpi_walk_state *walk_state,
4999575102SLv Zheng 		      union acpi_parse_object *op)
5099575102SLv Zheng {
5199575102SLv Zheng 	acpi_status status;
5299575102SLv Zheng 
5399575102SLv Zheng 	/* TBD: [Investigate] are there namespace locking issues here? */
5499575102SLv Zheng 
5599575102SLv Zheng 	/* acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */
5699575102SLv Zheng 
5799575102SLv Zheng 	/* Go into the command loop and await next user command */
5899575102SLv Zheng 
5999575102SLv Zheng 	acpi_gbl_method_executing = TRUE;
6099575102SLv Zheng 	status = AE_CTRL_TRUE;
61f8d31489SLv Zheng 
6299575102SLv Zheng 	while (status == AE_CTRL_TRUE) {
6399575102SLv Zheng 
64f8d31489SLv Zheng 		/* Notify the completion of the command */
6599575102SLv Zheng 
66f8d31489SLv Zheng 		status = acpi_os_notify_command_complete();
6799575102SLv Zheng 		if (ACPI_FAILURE(status)) {
68f8d31489SLv Zheng 			goto error_exit;
6999575102SLv Zheng 		}
7099575102SLv Zheng 
71f8d31489SLv Zheng 		/* Wait the readiness of the command */
7299575102SLv Zheng 
73f8d31489SLv Zheng 		status = acpi_os_wait_command_ready();
7499575102SLv Zheng 		if (ACPI_FAILURE(status)) {
75f8d31489SLv Zheng 			goto error_exit;
7699575102SLv Zheng 		}
7799575102SLv Zheng 
7899575102SLv Zheng 		status =
7999575102SLv Zheng 		    acpi_db_command_dispatch(acpi_gbl_db_line_buf, walk_state,
8099575102SLv Zheng 					     op);
8199575102SLv Zheng 	}
8299575102SLv Zheng 
8399575102SLv Zheng 	/* acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */
8499575102SLv Zheng 
85f8d31489SLv Zheng error_exit:
86f8d31489SLv Zheng 	if (ACPI_FAILURE(status) && status != AE_CTRL_TERMINATE) {
87f8d31489SLv Zheng 		ACPI_EXCEPTION((AE_INFO, status,
88f8d31489SLv Zheng 				"While parsing/handling command line"));
89f8d31489SLv Zheng 	}
9099575102SLv Zheng 	return (status);
9199575102SLv Zheng }
9299575102SLv Zheng 
9399575102SLv Zheng /*******************************************************************************
9499575102SLv Zheng  *
958a2a2501SLv Zheng  * FUNCTION:    acpi_db_signal_break_point
968a2a2501SLv Zheng  *
978a2a2501SLv Zheng  * PARAMETERS:  walk_state      - Current walk
988a2a2501SLv Zheng  *
998a2a2501SLv Zheng  * RETURN:      Status
1008a2a2501SLv Zheng  *
1019ff5a21aSBob Moore  * DESCRIPTION: Called for AML_BREAKPOINT_OP
1028a2a2501SLv Zheng  *
1038a2a2501SLv Zheng  ******************************************************************************/
1048a2a2501SLv Zheng 
acpi_db_signal_break_point(struct acpi_walk_state * walk_state)1058a2a2501SLv Zheng void acpi_db_signal_break_point(struct acpi_walk_state *walk_state)
1068a2a2501SLv Zheng {
1078a2a2501SLv Zheng 
1088a2a2501SLv Zheng #ifndef ACPI_APPLICATION
1098a2a2501SLv Zheng 	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
1108a2a2501SLv Zheng 		return;
1118a2a2501SLv Zheng 	}
1128a2a2501SLv Zheng #endif
1138a2a2501SLv Zheng 
1148a2a2501SLv Zheng 	/*
1158a2a2501SLv Zheng 	 * Set the single-step flag. This will cause the debugger (if present)
1168a2a2501SLv Zheng 	 * to break to the console within the AML debugger at the start of the
1178a2a2501SLv Zheng 	 * next AML instruction.
1188a2a2501SLv Zheng 	 */
1198a2a2501SLv Zheng 	acpi_gbl_cm_single_step = TRUE;
1208a2a2501SLv Zheng 	acpi_os_printf("**break** Executed AML BreakPoint opcode\n");
1218a2a2501SLv Zheng }
1228a2a2501SLv Zheng 
123c647eb98SErik Schmauss #ifdef ACPI_DISASSEMBLER
124c647eb98SErik Schmauss /*******************************************************************************
125c647eb98SErik Schmauss  *
126c647eb98SErik Schmauss  * FUNCTION:    acpi_db_get_display_op
127c647eb98SErik Schmauss  *
128c647eb98SErik Schmauss  * PARAMETERS:  walk_state      - Current walk
129c647eb98SErik Schmauss  *              op              - Current executing op (from aml interpreter)
130c647eb98SErik Schmauss  *
131c647eb98SErik Schmauss  * RETURN:      Opcode to display
132c647eb98SErik Schmauss  *
133c647eb98SErik Schmauss  * DESCRIPTION: Find the opcode to display during single stepping
134c647eb98SErik Schmauss  *
135c647eb98SErik Schmauss  ******************************************************************************/
136c647eb98SErik Schmauss 
acpi_db_get_display_op(struct acpi_walk_state * walk_state,union acpi_parse_object * op)137c647eb98SErik Schmauss static union acpi_parse_object *acpi_db_get_display_op(struct acpi_walk_state
138c647eb98SErik Schmauss 						       *walk_state,
139c647eb98SErik Schmauss 						       union acpi_parse_object
140c647eb98SErik Schmauss 						       *op)
141c647eb98SErik Schmauss {
142c647eb98SErik Schmauss 	union acpi_parse_object *display_op;
143c647eb98SErik Schmauss 	union acpi_parse_object *parent_op;
144c647eb98SErik Schmauss 
145c647eb98SErik Schmauss 	display_op = op;
146c647eb98SErik Schmauss 	parent_op = op->common.parent;
147c647eb98SErik Schmauss 	if (parent_op) {
148c647eb98SErik Schmauss 		if ((walk_state->control_state) &&
149c647eb98SErik Schmauss 		    (walk_state->control_state->common.state ==
150c647eb98SErik Schmauss 		     ACPI_CONTROL_PREDICATE_EXECUTING)) {
151c647eb98SErik Schmauss 			/*
152c647eb98SErik Schmauss 			 * We are executing the predicate of an IF or WHILE statement
153c647eb98SErik Schmauss 			 * Search upwards for the containing IF or WHILE so that the
154c647eb98SErik Schmauss 			 * entire predicate can be displayed.
155c647eb98SErik Schmauss 			 */
156c647eb98SErik Schmauss 			while (parent_op) {
157c647eb98SErik Schmauss 				if ((parent_op->common.aml_opcode == AML_IF_OP)
158c647eb98SErik Schmauss 				    || (parent_op->common.aml_opcode ==
159c647eb98SErik Schmauss 					AML_WHILE_OP)) {
160c647eb98SErik Schmauss 					display_op = parent_op;
161c647eb98SErik Schmauss 					break;
162c647eb98SErik Schmauss 				}
163c647eb98SErik Schmauss 				parent_op = parent_op->common.parent;
164c647eb98SErik Schmauss 			}
165c647eb98SErik Schmauss 		} else {
166c647eb98SErik Schmauss 			while (parent_op) {
167c647eb98SErik Schmauss 				if ((parent_op->common.aml_opcode == AML_IF_OP)
168c647eb98SErik Schmauss 				    || (parent_op->common.aml_opcode ==
169c647eb98SErik Schmauss 					AML_ELSE_OP)
170c647eb98SErik Schmauss 				    || (parent_op->common.aml_opcode ==
171c647eb98SErik Schmauss 					AML_SCOPE_OP)
172c647eb98SErik Schmauss 				    || (parent_op->common.aml_opcode ==
173c647eb98SErik Schmauss 					AML_METHOD_OP)
174c647eb98SErik Schmauss 				    || (parent_op->common.aml_opcode ==
175c647eb98SErik Schmauss 					AML_WHILE_OP)) {
176c647eb98SErik Schmauss 					break;
177c647eb98SErik Schmauss 				}
178c647eb98SErik Schmauss 				display_op = parent_op;
179c647eb98SErik Schmauss 				parent_op = parent_op->common.parent;
180c647eb98SErik Schmauss 			}
181c647eb98SErik Schmauss 		}
182c647eb98SErik Schmauss 	}
183c647eb98SErik Schmauss 	return display_op;
184c647eb98SErik Schmauss }
185c647eb98SErik Schmauss #endif
186c647eb98SErik Schmauss 
1878a2a2501SLv Zheng /*******************************************************************************
1888a2a2501SLv Zheng  *
18999575102SLv Zheng  * FUNCTION:    acpi_db_single_step
19099575102SLv Zheng  *
19199575102SLv Zheng  * PARAMETERS:  walk_state      - Current walk
19299575102SLv Zheng  *              op              - Current executing op (from aml interpreter)
19399575102SLv Zheng  *              opcode_class    - Class of the current AML Opcode
19499575102SLv Zheng  *
19599575102SLv Zheng  * RETURN:      Status
19699575102SLv Zheng  *
19799575102SLv Zheng  * DESCRIPTION: Called just before execution of an AML opcode.
19899575102SLv Zheng  *
19999575102SLv Zheng  ******************************************************************************/
20099575102SLv Zheng 
20199575102SLv Zheng acpi_status
acpi_db_single_step(struct acpi_walk_state * walk_state,union acpi_parse_object * op,u32 opcode_class)20299575102SLv Zheng acpi_db_single_step(struct acpi_walk_state *walk_state,
20399575102SLv Zheng 		    union acpi_parse_object *op, u32 opcode_class)
20499575102SLv Zheng {
20599575102SLv Zheng 	union acpi_parse_object *next;
20699575102SLv Zheng 	acpi_status status = AE_OK;
20799575102SLv Zheng 	u32 original_debug_level;
20899575102SLv Zheng 	u32 aml_offset;
20999575102SLv Zheng 
21099575102SLv Zheng 	ACPI_FUNCTION_ENTRY();
21199575102SLv Zheng 
212f988f24eSLv Zheng #ifndef ACPI_APPLICATION
213f988f24eSLv Zheng 	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
214f988f24eSLv Zheng 		return (AE_OK);
215f988f24eSLv Zheng 	}
216f988f24eSLv Zheng #endif
217f988f24eSLv Zheng 
21899575102SLv Zheng 	/* Check the abort flag */
21999575102SLv Zheng 
22099575102SLv Zheng 	if (acpi_gbl_abort_method) {
22199575102SLv Zheng 		acpi_gbl_abort_method = FALSE;
22299575102SLv Zheng 		return (AE_ABORT_METHOD);
22399575102SLv Zheng 	}
22499575102SLv Zheng 
22599575102SLv Zheng 	aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml,
22699575102SLv Zheng 					walk_state->parser_state.aml_start);
22799575102SLv Zheng 
22899575102SLv Zheng 	/* Check for single-step breakpoint */
22999575102SLv Zheng 
23099575102SLv Zheng 	if (walk_state->method_breakpoint &&
23199575102SLv Zheng 	    (walk_state->method_breakpoint <= aml_offset)) {
23299575102SLv Zheng 
23399575102SLv Zheng 		/* Check if the breakpoint has been reached or passed */
23499575102SLv Zheng 		/* Hit the breakpoint, resume single step, reset breakpoint */
23599575102SLv Zheng 
23699575102SLv Zheng 		acpi_os_printf("***Break*** at AML offset %X\n", aml_offset);
23799575102SLv Zheng 		acpi_gbl_cm_single_step = TRUE;
23899575102SLv Zheng 		acpi_gbl_step_to_next_call = FALSE;
23999575102SLv Zheng 		walk_state->method_breakpoint = 0;
24099575102SLv Zheng 	}
24199575102SLv Zheng 
24299575102SLv Zheng 	/* Check for user breakpoint (Must be on exact Aml offset) */
24399575102SLv Zheng 
24499575102SLv Zheng 	else if (walk_state->user_breakpoint &&
24599575102SLv Zheng 		 (walk_state->user_breakpoint == aml_offset)) {
24699575102SLv Zheng 		acpi_os_printf("***UserBreakpoint*** at AML offset %X\n",
24799575102SLv Zheng 			       aml_offset);
24899575102SLv Zheng 		acpi_gbl_cm_single_step = TRUE;
24999575102SLv Zheng 		acpi_gbl_step_to_next_call = FALSE;
25099575102SLv Zheng 		walk_state->method_breakpoint = 0;
25199575102SLv Zheng 	}
25299575102SLv Zheng 
25399575102SLv Zheng 	/*
25499575102SLv Zheng 	 * Check if this is an opcode that we are interested in --
25599575102SLv Zheng 	 * namely, opcodes that have arguments
25699575102SLv Zheng 	 */
25799575102SLv Zheng 	if (op->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
25899575102SLv Zheng 		return (AE_OK);
25999575102SLv Zheng 	}
26099575102SLv Zheng 
26199575102SLv Zheng 	switch (opcode_class) {
26299575102SLv Zheng 	case AML_CLASS_UNKNOWN:
26399575102SLv Zheng 	case AML_CLASS_ARGUMENT:	/* constants, literals, etc. do nothing */
26499575102SLv Zheng 
26599575102SLv Zheng 		return (AE_OK);
26699575102SLv Zheng 
26799575102SLv Zheng 	default:
26899575102SLv Zheng 
26999575102SLv Zheng 		/* All other opcodes -- continue */
27099575102SLv Zheng 		break;
27199575102SLv Zheng 	}
27299575102SLv Zheng 
27399575102SLv Zheng 	/*
27499575102SLv Zheng 	 * Under certain debug conditions, display this opcode and its operands
27599575102SLv Zheng 	 */
27699575102SLv Zheng 	if ((acpi_gbl_db_output_to_file) ||
27799575102SLv Zheng 	    (acpi_gbl_cm_single_step) || (acpi_dbg_level & ACPI_LV_PARSE)) {
27899575102SLv Zheng 		if ((acpi_gbl_db_output_to_file) ||
27999575102SLv Zheng 		    (acpi_dbg_level & ACPI_LV_PARSE)) {
28099575102SLv Zheng 			acpi_os_printf
2811537f303SBob Moore 			    ("\nAML Debug: Next AML Opcode to execute:\n");
28299575102SLv Zheng 		}
28399575102SLv Zheng 
28499575102SLv Zheng 		/*
28599575102SLv Zheng 		 * Display this op (and only this op - zero out the NEXT field
28699575102SLv Zheng 		 * temporarily, and disable parser trace output for the duration of
28799575102SLv Zheng 		 * the display because we don't want the extraneous debug output)
28899575102SLv Zheng 		 */
28999575102SLv Zheng 		original_debug_level = acpi_dbg_level;
29099575102SLv Zheng 		acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
29199575102SLv Zheng 		next = op->common.next;
29299575102SLv Zheng 		op->common.next = NULL;
29399575102SLv Zheng 
294fb2ef998SBob Moore 		/* Now we can disassemble and display it */
29599575102SLv Zheng 
29699575102SLv Zheng #ifdef ACPI_DISASSEMBLER
297c647eb98SErik Schmauss 		acpi_dm_disassemble(walk_state,
298c647eb98SErik Schmauss 				    acpi_db_get_display_op(walk_state, op),
299c647eb98SErik Schmauss 				    ACPI_UINT32_MAX);
300fb2ef998SBob Moore #else
301fb2ef998SBob Moore 		/*
302fb2ef998SBob Moore 		 * The AML Disassembler is not configured - at least we can
303fb2ef998SBob Moore 		 * display the opcode value and name
304fb2ef998SBob Moore 		 */
305fb2ef998SBob Moore 		acpi_os_printf("AML Opcode: %4.4X %s\n", op->common.aml_opcode,
306fb2ef998SBob Moore 			       acpi_ps_get_opcode_name(op->common.aml_opcode));
30799575102SLv Zheng #endif
30899575102SLv Zheng 
30999575102SLv Zheng 		if ((op->common.aml_opcode == AML_IF_OP) ||
31099575102SLv Zheng 		    (op->common.aml_opcode == AML_WHILE_OP)) {
31199575102SLv Zheng 			if (walk_state->control_state->common.value) {
31299575102SLv Zheng 				acpi_os_printf
31399575102SLv Zheng 				    ("Predicate = [True], IF block was executed\n");
31499575102SLv Zheng 			} else {
31599575102SLv Zheng 				acpi_os_printf
31699575102SLv Zheng 				    ("Predicate = [False], Skipping IF block\n");
31799575102SLv Zheng 			}
31899575102SLv Zheng 		} else if (op->common.aml_opcode == AML_ELSE_OP) {
31999575102SLv Zheng 			acpi_os_printf
32099575102SLv Zheng 			    ("Predicate = [False], ELSE block was executed\n");
32199575102SLv Zheng 		}
32299575102SLv Zheng 
32399575102SLv Zheng 		/* Restore everything */
32499575102SLv Zheng 
32599575102SLv Zheng 		op->common.next = next;
32699575102SLv Zheng 		acpi_os_printf("\n");
32799575102SLv Zheng 		if ((acpi_gbl_db_output_to_file) ||
32899575102SLv Zheng 		    (acpi_dbg_level & ACPI_LV_PARSE)) {
32999575102SLv Zheng 			acpi_os_printf("\n");
33099575102SLv Zheng 		}
33199575102SLv Zheng 		acpi_dbg_level = original_debug_level;
33299575102SLv Zheng 	}
33399575102SLv Zheng 
33499575102SLv Zheng 	/* If we are not single stepping, just continue executing the method */
33599575102SLv Zheng 
33699575102SLv Zheng 	if (!acpi_gbl_cm_single_step) {
33799575102SLv Zheng 		return (AE_OK);
33899575102SLv Zheng 	}
33999575102SLv Zheng 
34099575102SLv Zheng 	/*
34199575102SLv Zheng 	 * If we are executing a step-to-call command,
34299575102SLv Zheng 	 * Check if this is a method call.
34399575102SLv Zheng 	 */
34499575102SLv Zheng 	if (acpi_gbl_step_to_next_call) {
34599575102SLv Zheng 		if (op->common.aml_opcode != AML_INT_METHODCALL_OP) {
34699575102SLv Zheng 
34799575102SLv Zheng 			/* Not a method call, just keep executing */
34899575102SLv Zheng 
34999575102SLv Zheng 			return (AE_OK);
35099575102SLv Zheng 		}
35199575102SLv Zheng 
35299575102SLv Zheng 		/* Found a method call, stop executing */
35399575102SLv Zheng 
35499575102SLv Zheng 		acpi_gbl_step_to_next_call = FALSE;
35599575102SLv Zheng 	}
35699575102SLv Zheng 
35799575102SLv Zheng 	/*
35899575102SLv Zheng 	 * If the next opcode is a method call, we will "step over" it
35999575102SLv Zheng 	 * by default.
36099575102SLv Zheng 	 */
36199575102SLv Zheng 	if (op->common.aml_opcode == AML_INT_METHODCALL_OP) {
36299575102SLv Zheng 
36399575102SLv Zheng 		/* Force no more single stepping while executing called method */
36499575102SLv Zheng 
36599575102SLv Zheng 		acpi_gbl_cm_single_step = FALSE;
36699575102SLv Zheng 
36799575102SLv Zheng 		/*
36899575102SLv Zheng 		 * Set the breakpoint on/before the call, it will stop execution
36999575102SLv Zheng 		 * as soon as we return
37099575102SLv Zheng 		 */
37199575102SLv Zheng 		walk_state->method_breakpoint = 1;	/* Must be non-zero! */
37299575102SLv Zheng 	}
37399575102SLv Zheng 
374069f9bf4SLv Zheng 	acpi_ex_exit_interpreter();
37599575102SLv Zheng 	status = acpi_db_start_command(walk_state, op);
376069f9bf4SLv Zheng 	acpi_ex_enter_interpreter();
37799575102SLv Zheng 
37899575102SLv Zheng 	/* User commands complete, continue execution of the interrupted method */
37999575102SLv Zheng 
38099575102SLv Zheng 	return (status);
38199575102SLv Zheng }
38299575102SLv Zheng 
38399575102SLv Zheng /*******************************************************************************
38499575102SLv Zheng  *
38599575102SLv Zheng  * FUNCTION:    acpi_initialize_debugger
38699575102SLv Zheng  *
38799575102SLv Zheng  * PARAMETERS:  None
38899575102SLv Zheng  *
38999575102SLv Zheng  * RETURN:      Status
39099575102SLv Zheng  *
39199575102SLv Zheng  * DESCRIPTION: Init and start debugger
39299575102SLv Zheng  *
39399575102SLv Zheng  ******************************************************************************/
39499575102SLv Zheng 
acpi_initialize_debugger(void)39599575102SLv Zheng acpi_status acpi_initialize_debugger(void)
39699575102SLv Zheng {
39799575102SLv Zheng 	acpi_status status;
39899575102SLv Zheng 
39999575102SLv Zheng 	ACPI_FUNCTION_TRACE(acpi_initialize_debugger);
40099575102SLv Zheng 
40199575102SLv Zheng 	/* Init globals */
40299575102SLv Zheng 
40399575102SLv Zheng 	acpi_gbl_db_buffer = NULL;
40499575102SLv Zheng 	acpi_gbl_db_filename = NULL;
40599575102SLv Zheng 	acpi_gbl_db_output_to_file = FALSE;
40699575102SLv Zheng 
40799575102SLv Zheng 	acpi_gbl_db_debug_level = ACPI_LV_VERBOSITY2;
40899575102SLv Zheng 	acpi_gbl_db_console_debug_level = ACPI_NORMAL_DEFAULT | ACPI_LV_TABLES;
40999575102SLv Zheng 	acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
41099575102SLv Zheng 
41199575102SLv Zheng 	acpi_gbl_db_opt_no_ini_methods = FALSE;
412*f2173c3eSErik Kaneda 	acpi_gbl_db_opt_no_region_support = FALSE;
41399575102SLv Zheng 
41499575102SLv Zheng 	acpi_gbl_db_buffer = acpi_os_allocate(ACPI_DEBUG_BUFFER_SIZE);
41599575102SLv Zheng 	if (!acpi_gbl_db_buffer) {
41699575102SLv Zheng 		return_ACPI_STATUS(AE_NO_MEMORY);
41799575102SLv Zheng 	}
41899575102SLv Zheng 	memset(acpi_gbl_db_buffer, 0, ACPI_DEBUG_BUFFER_SIZE);
41999575102SLv Zheng 
42099575102SLv Zheng 	/* Initial scope is the root */
42199575102SLv Zheng 
42299575102SLv Zheng 	acpi_gbl_db_scope_buf[0] = AML_ROOT_PREFIX;
42399575102SLv Zheng 	acpi_gbl_db_scope_buf[1] = 0;
42499575102SLv Zheng 	acpi_gbl_db_scope_node = acpi_gbl_root_node;
42599575102SLv Zheng 
426af08f9ccSLv Zheng 	/* Initialize user commands loop */
427af08f9ccSLv Zheng 
428af08f9ccSLv Zheng 	acpi_gbl_db_terminate_loop = FALSE;
429af08f9ccSLv Zheng 
43099575102SLv Zheng 	/*
43199575102SLv Zheng 	 * If configured for multi-thread support, the debug executor runs in
43299575102SLv Zheng 	 * a separate thread so that the front end can be in another address
43399575102SLv Zheng 	 * space, environment, or even another machine.
43499575102SLv Zheng 	 */
43599575102SLv Zheng 	if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
43699575102SLv Zheng 
43799575102SLv Zheng 		/* These were created with one unit, grab it */
43899575102SLv Zheng 
439703ecd22SLv Zheng 		status = acpi_os_initialize_debugger();
44099575102SLv Zheng 		if (ACPI_FAILURE(status)) {
44199575102SLv Zheng 			acpi_os_printf("Could not get debugger mutex\n");
44299575102SLv Zheng 			return_ACPI_STATUS(status);
44399575102SLv Zheng 		}
44499575102SLv Zheng 
44599575102SLv Zheng 		/* Create the debug execution thread to execute commands */
44699575102SLv Zheng 
447af08f9ccSLv Zheng 		acpi_gbl_db_threads_terminated = FALSE;
448f988f24eSLv Zheng 		status = acpi_os_execute(OSL_DEBUGGER_MAIN_THREAD,
44999575102SLv Zheng 					 acpi_db_execute_thread, NULL);
45099575102SLv Zheng 		if (ACPI_FAILURE(status)) {
45199575102SLv Zheng 			ACPI_EXCEPTION((AE_INFO, status,
45299575102SLv Zheng 					"Could not start debugger thread"));
453af08f9ccSLv Zheng 			acpi_gbl_db_threads_terminated = TRUE;
45499575102SLv Zheng 			return_ACPI_STATUS(status);
45599575102SLv Zheng 		}
456f988f24eSLv Zheng 	} else {
457f988f24eSLv Zheng 		acpi_gbl_db_thread_id = acpi_os_get_thread_id();
45899575102SLv Zheng 	}
45999575102SLv Zheng 
46099575102SLv Zheng 	return_ACPI_STATUS(AE_OK);
46199575102SLv Zheng }
46299575102SLv Zheng 
ACPI_EXPORT_SYMBOL(acpi_initialize_debugger)46399575102SLv Zheng ACPI_EXPORT_SYMBOL(acpi_initialize_debugger)
46499575102SLv Zheng 
46599575102SLv Zheng /*******************************************************************************
46699575102SLv Zheng  *
46799575102SLv Zheng  * FUNCTION:    acpi_terminate_debugger
46899575102SLv Zheng  *
46999575102SLv Zheng  * PARAMETERS:  None
47099575102SLv Zheng  *
47199575102SLv Zheng  * RETURN:      None
47299575102SLv Zheng  *
47399575102SLv Zheng  * DESCRIPTION: Stop debugger
47499575102SLv Zheng  *
47599575102SLv Zheng  ******************************************************************************/
47699575102SLv Zheng void acpi_terminate_debugger(void)
47799575102SLv Zheng {
47899575102SLv Zheng 
479af08f9ccSLv Zheng 	/* Terminate the AML Debugger */
480af08f9ccSLv Zheng 
481af08f9ccSLv Zheng 	acpi_gbl_db_terminate_loop = TRUE;
482af08f9ccSLv Zheng 
483af08f9ccSLv Zheng 	if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
484af08f9ccSLv Zheng 
485af08f9ccSLv Zheng 		/* Wait the AML Debugger threads */
486af08f9ccSLv Zheng 
487af08f9ccSLv Zheng 		while (!acpi_gbl_db_threads_terminated) {
488af08f9ccSLv Zheng 			acpi_os_sleep(100);
489af08f9ccSLv Zheng 		}
490f8d31489SLv Zheng 
491703ecd22SLv Zheng 		acpi_os_terminate_debugger();
492af08f9ccSLv Zheng 	}
493af08f9ccSLv Zheng 
49499575102SLv Zheng 	if (acpi_gbl_db_buffer) {
49599575102SLv Zheng 		acpi_os_free(acpi_gbl_db_buffer);
49699575102SLv Zheng 		acpi_gbl_db_buffer = NULL;
49799575102SLv Zheng 	}
49899575102SLv Zheng 
49999575102SLv Zheng 	/* Ensure that debug output is now disabled */
50099575102SLv Zheng 
50199575102SLv Zheng 	acpi_gbl_db_output_flags = ACPI_DB_DISABLE_OUTPUT;
50299575102SLv Zheng }
50399575102SLv Zheng 
ACPI_EXPORT_SYMBOL(acpi_terminate_debugger)50499575102SLv Zheng ACPI_EXPORT_SYMBOL(acpi_terminate_debugger)
505f988f24eSLv Zheng 
506f988f24eSLv Zheng /*******************************************************************************
507f988f24eSLv Zheng  *
508f988f24eSLv Zheng  * FUNCTION:    acpi_set_debugger_thread_id
509f988f24eSLv Zheng  *
510f988f24eSLv Zheng  * PARAMETERS:  thread_id       - Debugger thread ID
511f988f24eSLv Zheng  *
512f988f24eSLv Zheng  * RETURN:      None
513f988f24eSLv Zheng  *
514f988f24eSLv Zheng  * DESCRIPTION: Set debugger thread ID
515f988f24eSLv Zheng  *
516f988f24eSLv Zheng  ******************************************************************************/
517f988f24eSLv Zheng void acpi_set_debugger_thread_id(acpi_thread_id thread_id)
518f988f24eSLv Zheng {
519f988f24eSLv Zheng 	acpi_gbl_db_thread_id = thread_id;
520f988f24eSLv Zheng }
521f988f24eSLv Zheng 
522f988f24eSLv Zheng ACPI_EXPORT_SYMBOL(acpi_set_debugger_thread_id)
523