dbxface.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: dbxface - AML Debugger external interfaces
  4.  *              $Revision: 45 $
  5.  *
  6.  ******************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include "acpi.h"
  25. #include "acparser.h"
  26. #include "amlcode.h"
  27. #include "acnamesp.h"
  28. #include "acparser.h"
  29. #include "acevents.h"
  30. #include "acinterp.h"
  31. #include "acdebug.h"
  32. #ifdef ENABLE_DEBUGGER
  33. #define _COMPONENT          ACPI_DEBUGGER
  34.  MODULE_NAME         ("dbxface")
  35. /*******************************************************************************
  36.  *
  37.  * FUNCTION:    Acpi_db_single_step
  38.  *
  39.  * PARAMETERS:  Walk_state      - Current walk
  40.  *              Op              - Current executing op
  41.  *              Opcode_class    - Class of the current AML Opcode
  42.  *
  43.  * RETURN:      Status
  44.  *
  45.  * DESCRIPTION: Called just before execution of an AML opcode.
  46.  *
  47.  ******************************************************************************/
  48. acpi_status
  49. acpi_db_single_step (
  50. acpi_walk_state         *walk_state,
  51. acpi_parse_object       *op,
  52. u32                     opcode_class)
  53. {
  54. acpi_parse_object       *next;
  55. acpi_status             status = AE_OK;
  56. u32                     original_debug_level;
  57. acpi_parse_object       *display_op;
  58. FUNCTION_ENTRY ();
  59. /* Is there a breakpoint set? */
  60. if (walk_state->method_breakpoint) {
  61. /* Check if the breakpoint has been reached or passed */
  62. if (walk_state->method_breakpoint <= op->aml_offset) {
  63. /* Hit the breakpoint, resume single step, reset breakpoint */
  64. acpi_os_printf ("***Break*** at AML offset %Xn", op->aml_offset);
  65. acpi_gbl_cm_single_step = TRUE;
  66. acpi_gbl_step_to_next_call = FALSE;
  67. walk_state->method_breakpoint = 0;
  68. }
  69. }
  70. /*
  71.  * Check if this is an opcode that we are interested in --
  72.  * namely, opcodes that have arguments
  73.  */
  74. if (op->opcode == AML_INT_NAMEDFIELD_OP) {
  75. return (AE_OK);
  76. }
  77. switch (opcode_class) {
  78. case AML_CLASS_UNKNOWN:
  79. case AML_CLASS_ARGUMENT:    /* constants, literals, etc.  do nothing */
  80. return (AE_OK);
  81. break;
  82. }
  83. /*
  84.  * Under certain debug conditions, display this opcode and its operands
  85.  */
  86. if ((acpi_gbl_db_output_to_file)        ||
  87. (acpi_gbl_cm_single_step)           ||
  88. (acpi_dbg_level & ACPI_LV_PARSE)) {
  89. if ((acpi_gbl_db_output_to_file)    ||
  90. (acpi_dbg_level & ACPI_LV_PARSE)) {
  91. acpi_os_printf ("n[Aml_debug] Next AML Opcode to execute:n");
  92. }
  93. /*
  94.  * Display this op (and only this op - zero out the NEXT field temporarily,
  95.  * and disable parser trace output for the duration of the display because
  96.  * we don't want the extraneous debug output)
  97.  */
  98. original_debug_level = acpi_dbg_level;
  99. acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
  100. next = op->next;
  101. op->next = NULL;
  102. display_op = op;
  103. if (op->parent) {
  104. if ((op->parent->opcode == AML_IF_OP) ||
  105. (op->parent->opcode == AML_WHILE_OP)) {
  106. display_op = op->parent;
  107. }
  108. }
  109. /* Now we can display it */
  110. acpi_db_display_op (walk_state, display_op, ACPI_UINT32_MAX);
  111. if ((op->opcode == AML_IF_OP) ||
  112. (op->opcode == AML_WHILE_OP)) {
  113. if (walk_state->control_state->common.value) {
  114. acpi_os_printf ("Predicate was TRUE, executed blockn");
  115. }
  116. else {
  117. acpi_os_printf ("Predicate is FALSE, skipping blockn");
  118. }
  119. }
  120. else if (op->opcode == AML_ELSE_OP) {
  121. /* TBD */
  122. }
  123. /* Restore everything */
  124. op->next = next;
  125. acpi_os_printf ("n");
  126. acpi_dbg_level = original_debug_level;
  127. }
  128. /* If we are not single stepping, just continue executing the method */
  129. if (!acpi_gbl_cm_single_step) {
  130. return (AE_OK);
  131. }
  132. /*
  133.  * If we are executing a step-to-call command,
  134.  * Check if this is a method call.
  135.  */
  136. if (acpi_gbl_step_to_next_call) {
  137. if (op->opcode != AML_INT_METHODCALL_OP) {
  138. /* Not a method call, just keep executing */
  139. return (AE_OK);
  140. }
  141. /* Found a method call, stop executing */
  142. acpi_gbl_step_to_next_call = FALSE;
  143. }
  144. /*
  145.  * If the next opcode is a method call, we will "step over" it
  146.  * by default.
  147.  */
  148. if (op->opcode == AML_INT_METHODCALL_OP) {
  149. acpi_gbl_cm_single_step = FALSE; /* No more single step while executing called method */
  150. /* Set the breakpoint on the call, it will stop execution as soon as we return */
  151. /* TBD: [Future] don't kill the user breakpoint! */
  152. walk_state->method_breakpoint = /* Op->Aml_offset + */ 1; /* Must be non-zero! */
  153. }
  154. /* TBD: [Investigate] what are the namespace locking issues here */
  155. /* Acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */
  156. /* Go into the command loop and await next user command */
  157. acpi_gbl_method_executing = TRUE;
  158. status = AE_CTRL_TRUE;
  159. while (status == AE_CTRL_TRUE) {
  160. if (acpi_gbl_debugger_configuration == DEBUGGER_MULTI_THREADED) {
  161. /* Handshake with the front-end that gets user command lines */
  162. acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
  163. acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY);
  164. }
  165. else {
  166. /* Single threaded, we must get a command line ourselves */
  167. /* Force output to console until a command is entered */
  168. acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
  169. /* Different prompt if method is executing */
  170. if (!acpi_gbl_method_executing) {
  171. acpi_os_printf ("%1c ", DB_COMMAND_PROMPT);
  172. }
  173. else {
  174. acpi_os_printf ("%1c ", DB_EXECUTE_PROMPT);
  175. }
  176. /* Get the user input line */
  177. acpi_os_get_line (acpi_gbl_db_line_buf);
  178. }
  179. status = acpi_db_command_dispatch (acpi_gbl_db_line_buf, walk_state, op);
  180. }
  181. /* Acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */
  182. /* User commands complete, continue execution of the interrupted method */
  183. return (status);
  184. }
  185. /*******************************************************************************
  186.  *
  187.  * FUNCTION:    Acpi_db_initialize
  188.  *
  189.  * PARAMETERS:  None
  190.  *
  191.  * RETURN:      Status
  192.  *
  193.  * DESCRIPTION: Init and start debugger
  194.  *
  195.  ******************************************************************************/
  196. int
  197. acpi_db_initialize (void)
  198. {
  199. /* Init globals */
  200. acpi_gbl_db_buffer = acpi_os_callocate (ACPI_DEBUG_BUFFER_SIZE);
  201. /* Initial scope is the root */
  202. acpi_gbl_db_scope_buf [0] = '\';
  203. acpi_gbl_db_scope_buf [1] = 0;
  204. /*
  205.  * If configured for multi-thread support, the debug executor runs in
  206.  * a separate thread so that the front end can be in another address
  207.  * space, environment, or even another machine.
  208.  */
  209. if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
  210. /* These were created with one unit, grab it */
  211. acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
  212. acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY);
  213. /* Create the debug execution thread to execute commands */
  214. acpi_os_queue_for_execution (0, acpi_db_execute_thread, NULL);
  215. }
  216. if (!acpi_gbl_db_opt_verbose) {
  217. acpi_gbl_db_disasm_indent = " ";
  218. acpi_gbl_db_opt_disasm = TRUE;
  219. acpi_gbl_db_opt_stats = FALSE;
  220. }
  221. return (0);
  222. }
  223. /*******************************************************************************
  224.  *
  225.  * FUNCTION:    Acpi_db_terminate
  226.  *
  227.  * PARAMETERS:  None
  228.  *
  229.  * RETURN:      Status
  230.  *
  231.  * DESCRIPTION: Stop debugger
  232.  *
  233.  ******************************************************************************/
  234. void
  235. acpi_db_terminate (void)
  236. {
  237. if (acpi_gbl_db_table_ptr) {
  238. acpi_os_free (acpi_gbl_db_table_ptr);
  239. }
  240. if (acpi_gbl_db_buffer) {
  241. acpi_os_free (acpi_gbl_db_buffer);
  242. }
  243. }
  244. #endif /* ENABLE_DEBUGGER */