162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
262306a36Sopenharmony_ci/*******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Module Name: dbxface - AML Debugger external interfaces
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci ******************************************************************************/
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <acpi/acpi.h>
962306a36Sopenharmony_ci#include "accommon.h"
1062306a36Sopenharmony_ci#include "amlcode.h"
1162306a36Sopenharmony_ci#include "acdebug.h"
1262306a36Sopenharmony_ci#include "acinterp.h"
1362306a36Sopenharmony_ci#include "acparser.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define _COMPONENT          ACPI_CA_DEBUGGER
1662306a36Sopenharmony_ciACPI_MODULE_NAME("dbxface")
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* Local prototypes */
1962306a36Sopenharmony_cistatic acpi_status
2062306a36Sopenharmony_ciacpi_db_start_command(struct acpi_walk_state *walk_state,
2162306a36Sopenharmony_ci		      union acpi_parse_object *op);
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#ifdef ACPI_OBSOLETE_FUNCTIONS
2462306a36Sopenharmony_civoid acpi_db_method_end(struct acpi_walk_state *walk_state);
2562306a36Sopenharmony_ci#endif
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#ifdef ACPI_DISASSEMBLER
2862306a36Sopenharmony_cistatic union acpi_parse_object *acpi_db_get_display_op(struct acpi_walk_state
2962306a36Sopenharmony_ci						       *walk_state,
3062306a36Sopenharmony_ci						       union acpi_parse_object
3162306a36Sopenharmony_ci						       *op);
3262306a36Sopenharmony_ci#endif
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci/*******************************************************************************
3562306a36Sopenharmony_ci *
3662306a36Sopenharmony_ci * FUNCTION:    acpi_db_start_command
3762306a36Sopenharmony_ci *
3862306a36Sopenharmony_ci * PARAMETERS:  walk_state      - Current walk
3962306a36Sopenharmony_ci *              op              - Current executing Op, from AML interpreter
4062306a36Sopenharmony_ci *
4162306a36Sopenharmony_ci * RETURN:      Status
4262306a36Sopenharmony_ci *
4362306a36Sopenharmony_ci * DESCRIPTION: Enter debugger command loop
4462306a36Sopenharmony_ci *
4562306a36Sopenharmony_ci ******************************************************************************/
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic acpi_status
4862306a36Sopenharmony_ciacpi_db_start_command(struct acpi_walk_state *walk_state,
4962306a36Sopenharmony_ci		      union acpi_parse_object *op)
5062306a36Sopenharmony_ci{
5162306a36Sopenharmony_ci	acpi_status status;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	/* TBD: [Investigate] are there namespace locking issues here? */
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	/* acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	/* Go into the command loop and await next user command */
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	acpi_gbl_method_executing = TRUE;
6062306a36Sopenharmony_ci	status = AE_CTRL_TRUE;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	while (status == AE_CTRL_TRUE) {
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci		/* Notify the completion of the command */
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci		status = acpi_os_notify_command_complete();
6762306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
6862306a36Sopenharmony_ci			goto error_exit;
6962306a36Sopenharmony_ci		}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci		/* Wait the readiness of the command */
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci		status = acpi_os_wait_command_ready();
7462306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
7562306a36Sopenharmony_ci			goto error_exit;
7662306a36Sopenharmony_ci		}
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci		status =
7962306a36Sopenharmony_ci		    acpi_db_command_dispatch(acpi_gbl_db_line_buf, walk_state,
8062306a36Sopenharmony_ci					     op);
8162306a36Sopenharmony_ci	}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	/* acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cierror_exit:
8662306a36Sopenharmony_ci	if (ACPI_FAILURE(status) && status != AE_CTRL_TERMINATE) {
8762306a36Sopenharmony_ci		ACPI_EXCEPTION((AE_INFO, status,
8862306a36Sopenharmony_ci				"While parsing/handling command line"));
8962306a36Sopenharmony_ci	}
9062306a36Sopenharmony_ci	return (status);
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci/*******************************************************************************
9462306a36Sopenharmony_ci *
9562306a36Sopenharmony_ci * FUNCTION:    acpi_db_signal_break_point
9662306a36Sopenharmony_ci *
9762306a36Sopenharmony_ci * PARAMETERS:  walk_state      - Current walk
9862306a36Sopenharmony_ci *
9962306a36Sopenharmony_ci * RETURN:      Status
10062306a36Sopenharmony_ci *
10162306a36Sopenharmony_ci * DESCRIPTION: Called for AML_BREAKPOINT_OP
10262306a36Sopenharmony_ci *
10362306a36Sopenharmony_ci ******************************************************************************/
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_civoid acpi_db_signal_break_point(struct acpi_walk_state *walk_state)
10662306a36Sopenharmony_ci{
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci#ifndef ACPI_APPLICATION
10962306a36Sopenharmony_ci	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
11062306a36Sopenharmony_ci		return;
11162306a36Sopenharmony_ci	}
11262306a36Sopenharmony_ci#endif
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	/*
11562306a36Sopenharmony_ci	 * Set the single-step flag. This will cause the debugger (if present)
11662306a36Sopenharmony_ci	 * to break to the console within the AML debugger at the start of the
11762306a36Sopenharmony_ci	 * next AML instruction.
11862306a36Sopenharmony_ci	 */
11962306a36Sopenharmony_ci	acpi_gbl_cm_single_step = TRUE;
12062306a36Sopenharmony_ci	acpi_os_printf("**break** Executed AML BreakPoint opcode\n");
12162306a36Sopenharmony_ci}
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci#ifdef ACPI_DISASSEMBLER
12462306a36Sopenharmony_ci/*******************************************************************************
12562306a36Sopenharmony_ci *
12662306a36Sopenharmony_ci * FUNCTION:    acpi_db_get_display_op
12762306a36Sopenharmony_ci *
12862306a36Sopenharmony_ci * PARAMETERS:  walk_state      - Current walk
12962306a36Sopenharmony_ci *              op              - Current executing op (from aml interpreter)
13062306a36Sopenharmony_ci *
13162306a36Sopenharmony_ci * RETURN:      Opcode to display
13262306a36Sopenharmony_ci *
13362306a36Sopenharmony_ci * DESCRIPTION: Find the opcode to display during single stepping
13462306a36Sopenharmony_ci *
13562306a36Sopenharmony_ci ******************************************************************************/
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cistatic union acpi_parse_object *acpi_db_get_display_op(struct acpi_walk_state
13862306a36Sopenharmony_ci						       *walk_state,
13962306a36Sopenharmony_ci						       union acpi_parse_object
14062306a36Sopenharmony_ci						       *op)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	union acpi_parse_object *display_op;
14362306a36Sopenharmony_ci	union acpi_parse_object *parent_op;
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci	display_op = op;
14662306a36Sopenharmony_ci	parent_op = op->common.parent;
14762306a36Sopenharmony_ci	if (parent_op) {
14862306a36Sopenharmony_ci		if ((walk_state->control_state) &&
14962306a36Sopenharmony_ci		    (walk_state->control_state->common.state ==
15062306a36Sopenharmony_ci		     ACPI_CONTROL_PREDICATE_EXECUTING)) {
15162306a36Sopenharmony_ci			/*
15262306a36Sopenharmony_ci			 * We are executing the predicate of an IF or WHILE statement
15362306a36Sopenharmony_ci			 * Search upwards for the containing IF or WHILE so that the
15462306a36Sopenharmony_ci			 * entire predicate can be displayed.
15562306a36Sopenharmony_ci			 */
15662306a36Sopenharmony_ci			while (parent_op) {
15762306a36Sopenharmony_ci				if ((parent_op->common.aml_opcode == AML_IF_OP)
15862306a36Sopenharmony_ci				    || (parent_op->common.aml_opcode ==
15962306a36Sopenharmony_ci					AML_WHILE_OP)) {
16062306a36Sopenharmony_ci					display_op = parent_op;
16162306a36Sopenharmony_ci					break;
16262306a36Sopenharmony_ci				}
16362306a36Sopenharmony_ci				parent_op = parent_op->common.parent;
16462306a36Sopenharmony_ci			}
16562306a36Sopenharmony_ci		} else {
16662306a36Sopenharmony_ci			while (parent_op) {
16762306a36Sopenharmony_ci				if ((parent_op->common.aml_opcode == AML_IF_OP)
16862306a36Sopenharmony_ci				    || (parent_op->common.aml_opcode ==
16962306a36Sopenharmony_ci					AML_ELSE_OP)
17062306a36Sopenharmony_ci				    || (parent_op->common.aml_opcode ==
17162306a36Sopenharmony_ci					AML_SCOPE_OP)
17262306a36Sopenharmony_ci				    || (parent_op->common.aml_opcode ==
17362306a36Sopenharmony_ci					AML_METHOD_OP)
17462306a36Sopenharmony_ci				    || (parent_op->common.aml_opcode ==
17562306a36Sopenharmony_ci					AML_WHILE_OP)) {
17662306a36Sopenharmony_ci					break;
17762306a36Sopenharmony_ci				}
17862306a36Sopenharmony_ci				display_op = parent_op;
17962306a36Sopenharmony_ci				parent_op = parent_op->common.parent;
18062306a36Sopenharmony_ci			}
18162306a36Sopenharmony_ci		}
18262306a36Sopenharmony_ci	}
18362306a36Sopenharmony_ci	return display_op;
18462306a36Sopenharmony_ci}
18562306a36Sopenharmony_ci#endif
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci/*******************************************************************************
18862306a36Sopenharmony_ci *
18962306a36Sopenharmony_ci * FUNCTION:    acpi_db_single_step
19062306a36Sopenharmony_ci *
19162306a36Sopenharmony_ci * PARAMETERS:  walk_state      - Current walk
19262306a36Sopenharmony_ci *              op              - Current executing op (from aml interpreter)
19362306a36Sopenharmony_ci *              opcode_class    - Class of the current AML Opcode
19462306a36Sopenharmony_ci *
19562306a36Sopenharmony_ci * RETURN:      Status
19662306a36Sopenharmony_ci *
19762306a36Sopenharmony_ci * DESCRIPTION: Called just before execution of an AML opcode.
19862306a36Sopenharmony_ci *
19962306a36Sopenharmony_ci ******************************************************************************/
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ciacpi_status
20262306a36Sopenharmony_ciacpi_db_single_step(struct acpi_walk_state *walk_state,
20362306a36Sopenharmony_ci		    union acpi_parse_object *op, u32 opcode_class)
20462306a36Sopenharmony_ci{
20562306a36Sopenharmony_ci	union acpi_parse_object *next;
20662306a36Sopenharmony_ci	acpi_status status = AE_OK;
20762306a36Sopenharmony_ci	u32 original_debug_level;
20862306a36Sopenharmony_ci	u32 aml_offset;
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	ACPI_FUNCTION_ENTRY();
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci#ifndef ACPI_APPLICATION
21362306a36Sopenharmony_ci	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
21462306a36Sopenharmony_ci		return (AE_OK);
21562306a36Sopenharmony_ci	}
21662306a36Sopenharmony_ci#endif
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	/* Check the abort flag */
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	if (acpi_gbl_abort_method) {
22162306a36Sopenharmony_ci		acpi_gbl_abort_method = FALSE;
22262306a36Sopenharmony_ci		return (AE_ABORT_METHOD);
22362306a36Sopenharmony_ci	}
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml,
22662306a36Sopenharmony_ci					walk_state->parser_state.aml_start);
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	/* Check for single-step breakpoint */
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	if (walk_state->method_breakpoint &&
23162306a36Sopenharmony_ci	    (walk_state->method_breakpoint <= aml_offset)) {
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci		/* Check if the breakpoint has been reached or passed */
23462306a36Sopenharmony_ci		/* Hit the breakpoint, resume single step, reset breakpoint */
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci		acpi_os_printf("***Break*** at AML offset %X\n", aml_offset);
23762306a36Sopenharmony_ci		acpi_gbl_cm_single_step = TRUE;
23862306a36Sopenharmony_ci		acpi_gbl_step_to_next_call = FALSE;
23962306a36Sopenharmony_ci		walk_state->method_breakpoint = 0;
24062306a36Sopenharmony_ci	}
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci	/* Check for user breakpoint (Must be on exact Aml offset) */
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	else if (walk_state->user_breakpoint &&
24562306a36Sopenharmony_ci		 (walk_state->user_breakpoint == aml_offset)) {
24662306a36Sopenharmony_ci		acpi_os_printf("***UserBreakpoint*** at AML offset %X\n",
24762306a36Sopenharmony_ci			       aml_offset);
24862306a36Sopenharmony_ci		acpi_gbl_cm_single_step = TRUE;
24962306a36Sopenharmony_ci		acpi_gbl_step_to_next_call = FALSE;
25062306a36Sopenharmony_ci		walk_state->method_breakpoint = 0;
25162306a36Sopenharmony_ci	}
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	/*
25462306a36Sopenharmony_ci	 * Check if this is an opcode that we are interested in --
25562306a36Sopenharmony_ci	 * namely, opcodes that have arguments
25662306a36Sopenharmony_ci	 */
25762306a36Sopenharmony_ci	if (op->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
25862306a36Sopenharmony_ci		return (AE_OK);
25962306a36Sopenharmony_ci	}
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	switch (opcode_class) {
26262306a36Sopenharmony_ci	case AML_CLASS_UNKNOWN:
26362306a36Sopenharmony_ci	case AML_CLASS_ARGUMENT:	/* constants, literals, etc. do nothing */
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci		return (AE_OK);
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	default:
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci		/* All other opcodes -- continue */
27062306a36Sopenharmony_ci		break;
27162306a36Sopenharmony_ci	}
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	/*
27462306a36Sopenharmony_ci	 * Under certain debug conditions, display this opcode and its operands
27562306a36Sopenharmony_ci	 */
27662306a36Sopenharmony_ci	if ((acpi_gbl_db_output_to_file) ||
27762306a36Sopenharmony_ci	    (acpi_gbl_cm_single_step) || (acpi_dbg_level & ACPI_LV_PARSE)) {
27862306a36Sopenharmony_ci		if ((acpi_gbl_db_output_to_file) ||
27962306a36Sopenharmony_ci		    (acpi_dbg_level & ACPI_LV_PARSE)) {
28062306a36Sopenharmony_ci			acpi_os_printf
28162306a36Sopenharmony_ci			    ("\nAML Debug: Next AML Opcode to execute:\n");
28262306a36Sopenharmony_ci		}
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci		/*
28562306a36Sopenharmony_ci		 * Display this op (and only this op - zero out the NEXT field
28662306a36Sopenharmony_ci		 * temporarily, and disable parser trace output for the duration of
28762306a36Sopenharmony_ci		 * the display because we don't want the extraneous debug output)
28862306a36Sopenharmony_ci		 */
28962306a36Sopenharmony_ci		original_debug_level = acpi_dbg_level;
29062306a36Sopenharmony_ci		acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
29162306a36Sopenharmony_ci		next = op->common.next;
29262306a36Sopenharmony_ci		op->common.next = NULL;
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci		/* Now we can disassemble and display it */
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci#ifdef ACPI_DISASSEMBLER
29762306a36Sopenharmony_ci		acpi_dm_disassemble(walk_state,
29862306a36Sopenharmony_ci				    acpi_db_get_display_op(walk_state, op),
29962306a36Sopenharmony_ci				    ACPI_UINT32_MAX);
30062306a36Sopenharmony_ci#else
30162306a36Sopenharmony_ci		/*
30262306a36Sopenharmony_ci		 * The AML Disassembler is not configured - at least we can
30362306a36Sopenharmony_ci		 * display the opcode value and name
30462306a36Sopenharmony_ci		 */
30562306a36Sopenharmony_ci		acpi_os_printf("AML Opcode: %4.4X %s\n", op->common.aml_opcode,
30662306a36Sopenharmony_ci			       acpi_ps_get_opcode_name(op->common.aml_opcode));
30762306a36Sopenharmony_ci#endif
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci		if ((op->common.aml_opcode == AML_IF_OP) ||
31062306a36Sopenharmony_ci		    (op->common.aml_opcode == AML_WHILE_OP)) {
31162306a36Sopenharmony_ci			if (walk_state->control_state->common.value) {
31262306a36Sopenharmony_ci				acpi_os_printf
31362306a36Sopenharmony_ci				    ("Predicate = [True], IF block was executed\n");
31462306a36Sopenharmony_ci			} else {
31562306a36Sopenharmony_ci				acpi_os_printf
31662306a36Sopenharmony_ci				    ("Predicate = [False], Skipping IF block\n");
31762306a36Sopenharmony_ci			}
31862306a36Sopenharmony_ci		} else if (op->common.aml_opcode == AML_ELSE_OP) {
31962306a36Sopenharmony_ci			acpi_os_printf
32062306a36Sopenharmony_ci			    ("Predicate = [False], ELSE block was executed\n");
32162306a36Sopenharmony_ci		}
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci		/* Restore everything */
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci		op->common.next = next;
32662306a36Sopenharmony_ci		acpi_os_printf("\n");
32762306a36Sopenharmony_ci		if ((acpi_gbl_db_output_to_file) ||
32862306a36Sopenharmony_ci		    (acpi_dbg_level & ACPI_LV_PARSE)) {
32962306a36Sopenharmony_ci			acpi_os_printf("\n");
33062306a36Sopenharmony_ci		}
33162306a36Sopenharmony_ci		acpi_dbg_level = original_debug_level;
33262306a36Sopenharmony_ci	}
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	/* If we are not single stepping, just continue executing the method */
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	if (!acpi_gbl_cm_single_step) {
33762306a36Sopenharmony_ci		return (AE_OK);
33862306a36Sopenharmony_ci	}
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	/*
34162306a36Sopenharmony_ci	 * If we are executing a step-to-call command,
34262306a36Sopenharmony_ci	 * Check if this is a method call.
34362306a36Sopenharmony_ci	 */
34462306a36Sopenharmony_ci	if (acpi_gbl_step_to_next_call) {
34562306a36Sopenharmony_ci		if (op->common.aml_opcode != AML_INT_METHODCALL_OP) {
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci			/* Not a method call, just keep executing */
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci			return (AE_OK);
35062306a36Sopenharmony_ci		}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci		/* Found a method call, stop executing */
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci		acpi_gbl_step_to_next_call = FALSE;
35562306a36Sopenharmony_ci	}
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci	/*
35862306a36Sopenharmony_ci	 * If the next opcode is a method call, we will "step over" it
35962306a36Sopenharmony_ci	 * by default.
36062306a36Sopenharmony_ci	 */
36162306a36Sopenharmony_ci	if (op->common.aml_opcode == AML_INT_METHODCALL_OP) {
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci		/* Force no more single stepping while executing called method */
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci		acpi_gbl_cm_single_step = FALSE;
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci		/*
36862306a36Sopenharmony_ci		 * Set the breakpoint on/before the call, it will stop execution
36962306a36Sopenharmony_ci		 * as soon as we return
37062306a36Sopenharmony_ci		 */
37162306a36Sopenharmony_ci		walk_state->method_breakpoint = 1;	/* Must be non-zero! */
37262306a36Sopenharmony_ci	}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	acpi_ex_exit_interpreter();
37562306a36Sopenharmony_ci	status = acpi_db_start_command(walk_state, op);
37662306a36Sopenharmony_ci	acpi_ex_enter_interpreter();
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci	/* User commands complete, continue execution of the interrupted method */
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci	return (status);
38162306a36Sopenharmony_ci}
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci/*******************************************************************************
38462306a36Sopenharmony_ci *
38562306a36Sopenharmony_ci * FUNCTION:    acpi_initialize_debugger
38662306a36Sopenharmony_ci *
38762306a36Sopenharmony_ci * PARAMETERS:  None
38862306a36Sopenharmony_ci *
38962306a36Sopenharmony_ci * RETURN:      Status
39062306a36Sopenharmony_ci *
39162306a36Sopenharmony_ci * DESCRIPTION: Init and start debugger
39262306a36Sopenharmony_ci *
39362306a36Sopenharmony_ci ******************************************************************************/
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ciacpi_status acpi_initialize_debugger(void)
39662306a36Sopenharmony_ci{
39762306a36Sopenharmony_ci	acpi_status status;
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(acpi_initialize_debugger);
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	/* Init globals */
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci	acpi_gbl_db_buffer = NULL;
40462306a36Sopenharmony_ci	acpi_gbl_db_filename = NULL;
40562306a36Sopenharmony_ci	acpi_gbl_db_output_to_file = FALSE;
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci	acpi_gbl_db_debug_level = ACPI_LV_VERBOSITY2;
40862306a36Sopenharmony_ci	acpi_gbl_db_console_debug_level = ACPI_NORMAL_DEFAULT | ACPI_LV_TABLES;
40962306a36Sopenharmony_ci	acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	acpi_gbl_db_opt_no_ini_methods = FALSE;
41262306a36Sopenharmony_ci	acpi_gbl_db_opt_no_region_support = FALSE;
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci	acpi_gbl_db_buffer = acpi_os_allocate(ACPI_DEBUG_BUFFER_SIZE);
41562306a36Sopenharmony_ci	if (!acpi_gbl_db_buffer) {
41662306a36Sopenharmony_ci		return_ACPI_STATUS(AE_NO_MEMORY);
41762306a36Sopenharmony_ci	}
41862306a36Sopenharmony_ci	memset(acpi_gbl_db_buffer, 0, ACPI_DEBUG_BUFFER_SIZE);
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci	/* Initial scope is the root */
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	acpi_gbl_db_scope_buf[0] = AML_ROOT_PREFIX;
42362306a36Sopenharmony_ci	acpi_gbl_db_scope_buf[1] = 0;
42462306a36Sopenharmony_ci	acpi_gbl_db_scope_node = acpi_gbl_root_node;
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	/* Initialize user commands loop */
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci	acpi_gbl_db_terminate_loop = FALSE;
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci	/*
43162306a36Sopenharmony_ci	 * If configured for multi-thread support, the debug executor runs in
43262306a36Sopenharmony_ci	 * a separate thread so that the front end can be in another address
43362306a36Sopenharmony_ci	 * space, environment, or even another machine.
43462306a36Sopenharmony_ci	 */
43562306a36Sopenharmony_ci	if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci		/* These were created with one unit, grab it */
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci		status = acpi_os_initialize_debugger();
44062306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
44162306a36Sopenharmony_ci			acpi_os_printf("Could not get debugger mutex\n");
44262306a36Sopenharmony_ci			return_ACPI_STATUS(status);
44362306a36Sopenharmony_ci		}
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci		/* Create the debug execution thread to execute commands */
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci		acpi_gbl_db_threads_terminated = FALSE;
44862306a36Sopenharmony_ci		status = acpi_os_execute(OSL_DEBUGGER_MAIN_THREAD,
44962306a36Sopenharmony_ci					 acpi_db_execute_thread, NULL);
45062306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
45162306a36Sopenharmony_ci			ACPI_EXCEPTION((AE_INFO, status,
45262306a36Sopenharmony_ci					"Could not start debugger thread"));
45362306a36Sopenharmony_ci			acpi_gbl_db_threads_terminated = TRUE;
45462306a36Sopenharmony_ci			return_ACPI_STATUS(status);
45562306a36Sopenharmony_ci		}
45662306a36Sopenharmony_ci	} else {
45762306a36Sopenharmony_ci		acpi_gbl_db_thread_id = acpi_os_get_thread_id();
45862306a36Sopenharmony_ci	}
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci	return_ACPI_STATUS(AE_OK);
46162306a36Sopenharmony_ci}
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_initialize_debugger)
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci/*******************************************************************************
46662306a36Sopenharmony_ci *
46762306a36Sopenharmony_ci * FUNCTION:    acpi_terminate_debugger
46862306a36Sopenharmony_ci *
46962306a36Sopenharmony_ci * PARAMETERS:  None
47062306a36Sopenharmony_ci *
47162306a36Sopenharmony_ci * RETURN:      None
47262306a36Sopenharmony_ci *
47362306a36Sopenharmony_ci * DESCRIPTION: Stop debugger
47462306a36Sopenharmony_ci *
47562306a36Sopenharmony_ci ******************************************************************************/
47662306a36Sopenharmony_civoid acpi_terminate_debugger(void)
47762306a36Sopenharmony_ci{
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	/* Terminate the AML Debugger */
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci	acpi_gbl_db_terminate_loop = TRUE;
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci	if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci		/* Wait the AML Debugger threads */
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci		while (!acpi_gbl_db_threads_terminated) {
48862306a36Sopenharmony_ci			acpi_os_sleep(100);
48962306a36Sopenharmony_ci		}
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci		acpi_os_terminate_debugger();
49262306a36Sopenharmony_ci	}
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci	if (acpi_gbl_db_buffer) {
49562306a36Sopenharmony_ci		acpi_os_free(acpi_gbl_db_buffer);
49662306a36Sopenharmony_ci		acpi_gbl_db_buffer = NULL;
49762306a36Sopenharmony_ci	}
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci	/* Ensure that debug output is now disabled */
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci	acpi_gbl_db_output_flags = ACPI_DB_DISABLE_OUTPUT;
50262306a36Sopenharmony_ci}
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_terminate_debugger)
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci/*******************************************************************************
50762306a36Sopenharmony_ci *
50862306a36Sopenharmony_ci * FUNCTION:    acpi_set_debugger_thread_id
50962306a36Sopenharmony_ci *
51062306a36Sopenharmony_ci * PARAMETERS:  thread_id       - Debugger thread ID
51162306a36Sopenharmony_ci *
51262306a36Sopenharmony_ci * RETURN:      None
51362306a36Sopenharmony_ci *
51462306a36Sopenharmony_ci * DESCRIPTION: Set debugger thread ID
51562306a36Sopenharmony_ci *
51662306a36Sopenharmony_ci ******************************************************************************/
51762306a36Sopenharmony_civoid acpi_set_debugger_thread_id(acpi_thread_id thread_id)
51862306a36Sopenharmony_ci{
51962306a36Sopenharmony_ci	acpi_gbl_db_thread_id = thread_id;
52062306a36Sopenharmony_ci}
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_set_debugger_thread_id)
523