dbexec.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:11k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: dbexec - debugger control method execution
  4.  *              $Revision: 34 $
  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 "acdispat.h"
  27. #include "amlcode.h"
  28. #include "acnamesp.h"
  29. #include "acparser.h"
  30. #include "acevents.h"
  31. #include "acinterp.h"
  32. #include "acdebug.h"
  33. #include "actables.h"
  34. #ifdef ENABLE_DEBUGGER
  35. #define _COMPONENT          ACPI_DEBUGGER
  36.  MODULE_NAME         ("dbexec")
  37. db_method_info              acpi_gbl_db_method_info;
  38. /*******************************************************************************
  39.  *
  40.  * FUNCTION:    Acpi_db_execute_method
  41.  *
  42.  * PARAMETERS:  Info            - Valid info segment
  43.  *              Return_obj      - Where to put return object
  44.  *
  45.  * RETURN:      Status
  46.  *
  47.  * DESCRIPTION: Execute a control method.
  48.  *
  49.  ******************************************************************************/
  50. acpi_status
  51. acpi_db_execute_method (
  52. db_method_info          *info,
  53. acpi_buffer             *return_obj)
  54. {
  55. acpi_status             status;
  56. acpi_object_list        param_objects;
  57. acpi_object             params[MTH_NUM_ARGS];
  58. u32                     i;
  59. if (acpi_gbl_db_output_to_file && !acpi_dbg_level) {
  60. acpi_os_printf ("Warning: debug output is not enabled!n");
  61. }
  62. /* Are there arguments to the method? */
  63. if (info->args && info->args[0]) {
  64. for (i = 0; info->args[i] && i < MTH_NUM_ARGS; i++) {
  65. params[i].type              = ACPI_TYPE_INTEGER;
  66. params[i].integer.value     = STRTOUL (info->args[i], NULL, 16);
  67. }
  68. param_objects.pointer       = params;
  69. param_objects.count         = i;
  70. }
  71. else {
  72. /* Setup default parameters */
  73. params[0].type              = ACPI_TYPE_INTEGER;
  74. params[0].integer.value     = 0x01020304;
  75. params[1].type              = ACPI_TYPE_STRING;
  76. params[1].string.length     = 12;
  77. params[1].string.pointer    = "AML Debugger";
  78. param_objects.pointer       = params;
  79. param_objects.count         = 2;
  80. }
  81. /* Prepare for a return object of arbitrary size */
  82. return_obj->pointer          = acpi_gbl_db_buffer;
  83. return_obj->length           = ACPI_DEBUG_BUFFER_SIZE;
  84. /* Do the actual method execution */
  85. status = acpi_evaluate_object (NULL, info->pathname, &param_objects, return_obj);
  86. acpi_gbl_cm_single_step = FALSE;
  87. acpi_gbl_method_executing = FALSE;
  88. return (status);
  89. }
  90. /*******************************************************************************
  91.  *
  92.  * FUNCTION:    Acpi_db_execute_setup
  93.  *
  94.  * PARAMETERS:  Info            - Valid method info
  95.  *
  96.  * RETURN:      Status
  97.  *
  98.  * DESCRIPTION: Setup info segment prior to method execution
  99.  *
  100.  ******************************************************************************/
  101. void
  102. acpi_db_execute_setup (
  103. db_method_info          *info)
  104. {
  105. /* Catenate the current scope to the supplied name */
  106. info->pathname[0] = 0;
  107. if ((info->name[0] != '\') &&
  108. (info->name[0] != '/')) {
  109. STRCAT (info->pathname, acpi_gbl_db_scope_buf);
  110. }
  111. STRCAT (info->pathname, info->name);
  112. acpi_db_prep_namestring (info->pathname);
  113. acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT);
  114. acpi_os_printf ("Executing %sn", info->pathname);
  115. if (info->flags & EX_SINGLE_STEP) {
  116. acpi_gbl_cm_single_step = TRUE;
  117. acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
  118. }
  119. else {
  120. /* No single step, allow redirection to a file */
  121. acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT);
  122. }
  123. }
  124. /*******************************************************************************
  125.  *
  126.  * FUNCTION:    Acpi_db_get_outstanding_allocations
  127.  *
  128.  * PARAMETERS:  None
  129.  *
  130.  * RETURN:      Current global allocation count minus cache entries
  131.  *
  132.  * DESCRIPTION: Determine the current number of "outstanding" allocations --
  133.  *              those allocations that have not been freed and also are not
  134.  *              in one of the various object caches.
  135.  *
  136.  ******************************************************************************/
  137. u32
  138. acpi_db_get_outstanding_allocations (void)
  139. {
  140. u32                     i;
  141. u32                     outstanding = 0;
  142. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  143. for (i = ACPI_MEM_LIST_FIRST_CACHE_LIST; i < ACPI_NUM_MEM_LISTS; i++) {
  144. outstanding += (acpi_gbl_memory_lists[i].total_allocated -
  145.   acpi_gbl_memory_lists[i].total_freed -
  146.   acpi_gbl_memory_lists[i].cache_depth);
  147. }
  148. #endif
  149. return (outstanding);
  150. }
  151. /*******************************************************************************
  152.  *
  153.  * FUNCTION:    Acpi_db_execute
  154.  *
  155.  * PARAMETERS:  Name                - Name of method to execute
  156.  *              Args                - Parameters to the method
  157.  *              Flags               - single step/no single step
  158.  *
  159.  * RETURN:      Status
  160.  *
  161.  * DESCRIPTION: Execute a control method.  Name is relative to the current
  162.  *              scope.
  163.  *
  164.  ******************************************************************************/
  165. void
  166. acpi_db_execute (
  167. NATIVE_CHAR             *name,
  168. NATIVE_CHAR             **args,
  169. u32                     flags)
  170. {
  171. acpi_status             status;
  172. acpi_buffer             return_obj;
  173. #ifdef ACPI_DEBUG
  174. u32                     previous_allocations;
  175. u32                     allocations;
  176. /* Memory allocation tracking */
  177. previous_allocations = acpi_db_get_outstanding_allocations ();
  178. #endif
  179. acpi_gbl_db_method_info.name = name;
  180. acpi_gbl_db_method_info.args = args;
  181. acpi_gbl_db_method_info.flags = flags;
  182. acpi_db_execute_setup (&acpi_gbl_db_method_info);
  183. status = acpi_db_execute_method (&acpi_gbl_db_method_info, &return_obj);
  184. /*
  185.  * Allow any handlers in separate threads to complete.
  186.  * (Such as Notify handlers invoked from AML executed above).
  187.  */
  188. acpi_os_sleep (0, 10);
  189. #ifdef ACPI_DEBUG
  190. /* Memory allocation tracking */
  191. allocations = acpi_db_get_outstanding_allocations () - previous_allocations;
  192. acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT);
  193. if (allocations > 0) {
  194. acpi_os_printf ("Outstanding: %ld allocations after executionn",
  195.   allocations);
  196. }
  197. #endif
  198. if (ACPI_FAILURE (status)) {
  199. acpi_os_printf ("Execution of %s failed with status %sn",
  200. acpi_gbl_db_method_info.pathname, acpi_format_exception (status));
  201. }
  202. else {
  203. /* Display a return object, if any */
  204. if (return_obj.length) {
  205. acpi_os_printf ("Execution of %s returned object %p Buflen %Xn",
  206. acpi_gbl_db_method_info.pathname, return_obj.pointer, return_obj.length);
  207. acpi_db_dump_object (return_obj.pointer, 1);
  208. }
  209. }
  210. acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
  211. }
  212. /*******************************************************************************
  213.  *
  214.  * FUNCTION:    Acpi_db_method_thread
  215.  *
  216.  * PARAMETERS:  Context             - Execution info segment
  217.  *
  218.  * RETURN:      None
  219.  *
  220.  * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
  221.  *              simply dispatches it.
  222.  *
  223.  ******************************************************************************/
  224. void
  225. acpi_db_method_thread (
  226. void                    *context)
  227. {
  228. acpi_status             status;
  229. db_method_info          *info = context;
  230. u32                     i;
  231. acpi_buffer             return_obj;
  232. for (i = 0; i < info->num_loops; i++) {
  233. status = acpi_db_execute_method (info, &return_obj);
  234. if (ACPI_SUCCESS (status)) {
  235. if (return_obj.length) {
  236. acpi_os_printf ("Execution of %s returned object %p Buflen %Xn",
  237. info->pathname, return_obj.pointer, return_obj.length);
  238. acpi_db_dump_object (return_obj.pointer, 1);
  239. }
  240. }
  241. }
  242. /* Signal our completion */
  243. acpi_os_signal_semaphore (info->thread_gate, 1);
  244. }
  245. /*******************************************************************************
  246.  *
  247.  * FUNCTION:    Acpi_db_create_execution_threads
  248.  *
  249.  * PARAMETERS:  Num_threads_arg         - Number of threads to create
  250.  *              Num_loops_arg           - Loop count for the thread(s)
  251.  *              Method_name_arg         - Control method to execute
  252.  *
  253.  * RETURN:      None
  254.  *
  255.  * DESCRIPTION: Create threads to execute method(s)
  256.  *
  257.  ******************************************************************************/
  258. void
  259. acpi_db_create_execution_threads (
  260. NATIVE_CHAR             *num_threads_arg,
  261. NATIVE_CHAR             *num_loops_arg,
  262. NATIVE_CHAR             *method_name_arg)
  263. {
  264. acpi_status             status;
  265. u32                     num_threads;
  266. u32                     num_loops;
  267. u32                     i;
  268. acpi_handle             thread_gate;
  269. /* Get the arguments */
  270. num_threads = STRTOUL (num_threads_arg, NULL, 0);
  271. num_loops = STRTOUL (num_loops_arg, NULL, 0);
  272. if (!num_threads || !num_loops) {
  273. acpi_os_printf ("Bad argument: Threads %X, Loops %Xn", num_threads, num_loops);
  274. return;
  275. }
  276. /* Create the synchronization semaphore */
  277. status = acpi_os_create_semaphore (1, 0, &thread_gate);
  278. if (ACPI_FAILURE (status)) {
  279. acpi_os_printf ("Could not create semaphore, %sn", acpi_format_exception (status));
  280. return;
  281. }
  282. /* Setup the context to be passed to each thread */
  283. acpi_gbl_db_method_info.name = method_name_arg;
  284. acpi_gbl_db_method_info.args = NULL;
  285. acpi_gbl_db_method_info.flags = 0;
  286. acpi_gbl_db_method_info.num_loops = num_loops;
  287. acpi_gbl_db_method_info.thread_gate = thread_gate;
  288. acpi_db_execute_setup (&acpi_gbl_db_method_info);
  289. /* Create the threads */
  290. acpi_os_printf ("Creating %X threads to execute %X times eachn", num_threads, num_loops);
  291. for (i = 0; i < (num_threads); i++) {
  292. acpi_os_queue_for_execution (OSD_PRIORITY_MED, acpi_db_method_thread, &acpi_gbl_db_method_info);
  293. }
  294. /* Wait for all threads to complete */
  295. i = num_threads;
  296. while (i)   /* Brain damage for OSD implementations that only support wait of 1 unit */ {
  297. status = acpi_os_wait_semaphore (thread_gate, 1, WAIT_FOREVER);
  298. i--;
  299. }
  300. /* Cleanup and exit */
  301. acpi_os_delete_semaphore (thread_gate);
  302. acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT);
  303. acpi_os_printf ("All threads (%X) have completedn", num_threads);
  304. acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
  305. }
  306. #endif /* ENABLE_DEBUGGER */