Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/acpi/acpica/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 13 kB image not shown  

Quelle  dbxface.c   Sprache: C

 
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/*******************************************************************************
 *
 * Module Name: dbxface - AML Debugger external interfaces
 *
 ******************************************************************************/


#include <acpi/acpi.h>
#include "accommon.h"
#include "amlcode.h"
#include "acdebug.h"
#include "acinterp.h"
#include "acparser.h"

#define _COMPONENT          ACPI_CA_DEBUGGER
ACPI_MODULE_NAME("dbxface")

/* Local prototypes */
static acpi_status
acpi_db_start_command(struct acpi_walk_state *walk_state,
        union acpi_parse_object *op);

#ifdef ACPI_OBSOLETE_FUNCTIONS
void acpi_db_method_end(struct acpi_walk_state *walk_state);
#endif

#ifdef ACPI_DISASSEMBLER
static union acpi_parse_object *acpi_db_get_display_op(struct acpi_walk_state
             *walk_state,
             union acpi_parse_object
             *op);
#endif

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_start_command
 *
 * PARAMETERS:  walk_state      - Current walk
 *              op              - Current executing Op, from AML interpreter
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Enter debugger command loop
 *
 ******************************************************************************/


static acpi_status
acpi_db_start_command(struct acpi_walk_state *walk_state,
        union acpi_parse_object *op)
{
 acpi_status status;

 /* TBD: [Investigate] are there namespace locking issues here? */

 /* acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */

 /* Go into the command loop and await next user command */

 acpi_gbl_method_executing = TRUE;
 status = AE_CTRL_TRUE;

 while (status == AE_CTRL_TRUE) {

  /* Notify the completion of the command */

  status = acpi_os_notify_command_complete();
  if (ACPI_FAILURE(status)) {
   goto error_exit;
  }

  /* Wait the readiness of the command */

  status = acpi_os_wait_command_ready();
  if (ACPI_FAILURE(status)) {
   goto error_exit;
  }

  status =
      acpi_db_command_dispatch(acpi_gbl_db_line_buf, walk_state,
          op);
 }

 /* acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */

error_exit:
 if (ACPI_FAILURE(status) && status != AE_CTRL_TERMINATE) {
  ACPI_EXCEPTION((AE_INFO, status,
    "While parsing/handling command line"));
 }
 return (status);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_signal_break_point
 *
 * PARAMETERS:  walk_state      - Current walk
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Called for AML_BREAKPOINT_OP
 *
 ******************************************************************************/


void acpi_db_signal_break_point(struct acpi_walk_state *walk_state)
{

#ifndef ACPI_APPLICATION
 if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
  return;
 }
#endif

 /*
 * Set the single-step flag. This will cause the debugger (if present)
 * to break to the console within the AML debugger at the start of the
 * next AML instruction.
 */

 acpi_gbl_cm_single_step = TRUE;
 acpi_os_printf("**break** Executed AML BreakPoint opcode\n");
}

#ifdef ACPI_DISASSEMBLER
/*******************************************************************************
 *
 * FUNCTION:    acpi_db_get_display_op
 *
 * PARAMETERS:  walk_state      - Current walk
 *              op              - Current executing op (from aml interpreter)
 *
 * RETURN:      Opcode to display
 *
 * DESCRIPTION: Find the opcode to display during single stepping
 *
 ******************************************************************************/


static union acpi_parse_object *acpi_db_get_display_op(struct acpi_walk_state
             *walk_state,
             union acpi_parse_object
             *op)
{
 union acpi_parse_object *display_op;
 union acpi_parse_object *parent_op;

 display_op = op;
 parent_op = op->common.parent;
 if (parent_op) {
  if ((walk_state->control_state) &&
      (walk_state->control_state->common.state ==
       ACPI_CONTROL_PREDICATE_EXECUTING)) {
   /*
 * We are executing the predicate of an IF or WHILE statement
 * Search upwards for the containing IF or WHILE so that the
 * entire predicate can be displayed.
 */

   while (parent_op) {
    if ((parent_op->common.aml_opcode == AML_IF_OP)
        || (parent_op->common.aml_opcode ==
     AML_WHILE_OP)) {
     display_op = parent_op;
     break;
    }
    parent_op = parent_op->common.parent;
   }
  } else {
   while (parent_op) {
    if ((parent_op->common.aml_opcode == AML_IF_OP)
        || (parent_op->common.aml_opcode ==
     AML_ELSE_OP)
        || (parent_op->common.aml_opcode ==
     AML_SCOPE_OP)
        || (parent_op->common.aml_opcode ==
     AML_METHOD_OP)
        || (parent_op->common.aml_opcode ==
     AML_WHILE_OP)) {
     break;
    }
    display_op = parent_op;
    parent_op = parent_op->common.parent;
   }
  }
 }
 return display_op;
}
#endif

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_single_step
 *
 * PARAMETERS:  walk_state      - Current walk
 *              op              - Current executing op (from aml interpreter)
 *              opcode_class    - Class of the current AML Opcode
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Called just before execution of an AML opcode.
 *
 ******************************************************************************/


acpi_status
acpi_db_single_step(struct acpi_walk_state *walk_state,
      union acpi_parse_object *op, u32 opcode_class)
{
 union acpi_parse_object *next;
 acpi_status status = AE_OK;
 u32 original_debug_level;
 u32 aml_offset;

 ACPI_FUNCTION_ENTRY();

#ifndef ACPI_APPLICATION
 if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
  return (AE_OK);
 }
#endif

 /* Check the abort flag */

 if (acpi_gbl_abort_method) {
  acpi_gbl_abort_method = FALSE;
  return (AE_ABORT_METHOD);
 }

 aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml,
     walk_state->parser_state.aml_start);

 /* Check for single-step breakpoint */

 if (walk_state->method_breakpoint &&
     (walk_state->method_breakpoint <= aml_offset)) {

  /* Check if the breakpoint has been reached or passed */
  /* Hit the breakpoint, resume single step, reset breakpoint */

  acpi_os_printf("***Break*** at AML offset %X\n", aml_offset);
  acpi_gbl_cm_single_step = TRUE;
  acpi_gbl_step_to_next_call = FALSE;
  walk_state->method_breakpoint = 0;
 }

 /* Check for user breakpoint (Must be on exact Aml offset) */

 else if (walk_state->user_breakpoint &&
   (walk_state->user_breakpoint == aml_offset)) {
  acpi_os_printf("***UserBreakpoint*** at AML offset %X\n",
          aml_offset);
  acpi_gbl_cm_single_step = TRUE;
  acpi_gbl_step_to_next_call = FALSE;
  walk_state->method_breakpoint = 0;
 }

 /*
 * Check if this is an opcode that we are interested in --
 * namely, opcodes that have arguments
 */

 if (op->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
  return (AE_OK);
 }

 switch (opcode_class) {
 case AML_CLASS_UNKNOWN:
 case AML_CLASS_ARGUMENT: /* constants, literals, etc. do nothing */

  return (AE_OK);

 default:

  /* All other opcodes -- continue */
  break;
 }

 /*
 * Under certain debug conditions, display this opcode and its operands
 */

 if ((acpi_gbl_db_output_to_file) ||
     (acpi_gbl_cm_single_step) || (acpi_dbg_level & ACPI_LV_PARSE)) {
  if ((acpi_gbl_db_output_to_file) ||
      (acpi_dbg_level & ACPI_LV_PARSE)) {
   acpi_os_printf
       ("\nAML Debug: Next AML Opcode to execute:\n");
  }

  /*
 * Display this op (and only this op - zero out the NEXT field
 * temporarily, and disable parser trace output for the duration of
 * the display because we don't want the extraneous debug output)
 */

  original_debug_level = acpi_dbg_level;
  acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
  next = op->common.next;
  op->common.next = NULL;

  /* Now we can disassemble and display it */

#ifdef ACPI_DISASSEMBLER
  acpi_dm_disassemble(walk_state,
        acpi_db_get_display_op(walk_state, op),
        ACPI_UINT32_MAX);
#else
  /*
 * The AML Disassembler is not configured - at least we can
 * display the opcode value and name
 */

  acpi_os_printf("AML Opcode: %4.4X %s\n", op->common.aml_opcode,
          acpi_ps_get_opcode_name(op->common.aml_opcode));
#endif

  if ((op->common.aml_opcode == AML_IF_OP) ||
      (op->common.aml_opcode == AML_WHILE_OP)) {
   if (walk_state->control_state->common.value) {
    acpi_os_printf
        ("Predicate = [True], IF block was executed\n");
   } else {
    acpi_os_printf
        ("Predicate = [False], Skipping IF block\n");
   }
  } else if (op->common.aml_opcode == AML_ELSE_OP) {
   acpi_os_printf
       ("Predicate = [False], ELSE block was executed\n");
  }

  /* Restore everything */

  op->common.next = next;
  acpi_os_printf("\n");
  if ((acpi_gbl_db_output_to_file) ||
      (acpi_dbg_level & ACPI_LV_PARSE)) {
   acpi_os_printf("\n");
  }
  acpi_dbg_level = original_debug_level;
 }

 /* If we are not single stepping, just continue executing the method */

 if (!acpi_gbl_cm_single_step) {
  return (AE_OK);
 }

 /*
 * If we are executing a step-to-call command,
 * Check if this is a method call.
 */

 if (acpi_gbl_step_to_next_call) {
  if (op->common.aml_opcode != AML_INT_METHODCALL_OP) {

   /* Not a method call, just keep executing */

   return (AE_OK);
  }

  /* Found a method call, stop executing */

  acpi_gbl_step_to_next_call = FALSE;
 }

 /*
 * If the next opcode is a method call, we will "step over" it
 * by default.
 */

 if (op->common.aml_opcode == AML_INT_METHODCALL_OP) {

  /* Force no more single stepping while executing called method */

  acpi_gbl_cm_single_step = FALSE;

  /*
 * Set the breakpoint on/before the call, it will stop execution
 * as soon as we return
 */

  walk_state->method_breakpoint = 1; /* Must be non-zero! */
 }

 acpi_ex_exit_interpreter();
 status = acpi_db_start_command(walk_state, op);
 acpi_ex_enter_interpreter();

 /* User commands complete, continue execution of the interrupted method */

 return (status);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_initialize_debugger
 *
 * PARAMETERS:  None
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Init and start debugger
 *
 ******************************************************************************/


acpi_status acpi_initialize_debugger(void)
{
 acpi_status status;

 ACPI_FUNCTION_TRACE(acpi_initialize_debugger);

 /* Init globals */

 acpi_gbl_db_buffer = NULL;
 acpi_gbl_db_filename = NULL;
 acpi_gbl_db_output_to_file = FALSE;

 acpi_gbl_db_debug_level = ACPI_LV_VERBOSITY2;
 acpi_gbl_db_console_debug_level = ACPI_NORMAL_DEFAULT | ACPI_LV_TABLES;
 acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;

 acpi_gbl_db_opt_no_ini_methods = FALSE;
 acpi_gbl_db_opt_no_region_support = FALSE;

 acpi_gbl_db_buffer = acpi_os_allocate(ACPI_DEBUG_BUFFER_SIZE);
 if (!acpi_gbl_db_buffer) {
  return_ACPI_STATUS(AE_NO_MEMORY);
 }
 memset(acpi_gbl_db_buffer, 0, ACPI_DEBUG_BUFFER_SIZE);

 /* Initial scope is the root */

 acpi_gbl_db_scope_buf[0] = AML_ROOT_PREFIX;
 acpi_gbl_db_scope_buf[1] = 0;
 acpi_gbl_db_scope_node = acpi_gbl_root_node;

 /* Initialize user commands loop */

 acpi_gbl_db_terminate_loop = FALSE;

 /*
 * If configured for multi-thread support, the debug executor runs in
 * a separate thread so that the front end can be in another address
 * space, environment, or even another machine.
 */

 if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {

  /* These were created with one unit, grab it */

  status = acpi_os_initialize_debugger();
  if (ACPI_FAILURE(status)) {
   acpi_os_printf("Could not get debugger mutex\n");
   return_ACPI_STATUS(status);
  }

  /* Create the debug execution thread to execute commands */

  acpi_gbl_db_threads_terminated = FALSE;
  status = acpi_os_execute(OSL_DEBUGGER_MAIN_THREAD,
      acpi_db_execute_thread, NULL);
  if (ACPI_FAILURE(status)) {
   ACPI_EXCEPTION((AE_INFO, status,
     "Could not start debugger thread"));
   acpi_gbl_db_threads_terminated = TRUE;
   return_ACPI_STATUS(status);
  }
 } else {
  acpi_gbl_db_thread_id = acpi_os_get_thread_id();
 }

 return_ACPI_STATUS(AE_OK);
}

ACPI_EXPORT_SYMBOL(acpi_initialize_debugger)

/*******************************************************************************
 *
 * FUNCTION:    acpi_terminate_debugger
 *
 * PARAMETERS:  None
 *
 * RETURN:      None
 *
 * DESCRIPTION: Stop debugger
 *
 ******************************************************************************/

void acpi_terminate_debugger(void)
{

 /* Terminate the AML Debugger */

 acpi_gbl_db_terminate_loop = TRUE;

 if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {

  /* Wait the AML Debugger threads */

  while (!acpi_gbl_db_threads_terminated) {
   acpi_os_sleep(100);
  }

  acpi_os_terminate_debugger();
 }

 if (acpi_gbl_db_buffer) {
  acpi_os_free(acpi_gbl_db_buffer);
  acpi_gbl_db_buffer = NULL;
 }

 /* Ensure that debug output is now disabled */

 acpi_gbl_db_output_flags = ACPI_DB_DISABLE_OUTPUT;
}

ACPI_EXPORT_SYMBOL(acpi_terminate_debugger)

/*******************************************************************************
 *
 * FUNCTION:    acpi_set_debugger_thread_id
 *
 * PARAMETERS:  thread_id       - Debugger thread ID
 *
 * RETURN:      None
 *
 * DESCRIPTION: Set debugger thread ID
 *
 ******************************************************************************/

void acpi_set_debugger_thread_id(acpi_thread_id thread_id)
{
 acpi_gbl_db_thread_id = thread_id;
}

ACPI_EXPORT_SYMBOL(acpi_set_debugger_thread_id)

Messung V0.5
C=93 H=95 G=93

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.