dbexec.c revision 100966
184865Sobrien/******************************************************************************* 284865Sobrien * 384865Sobrien * Module Name: dbexec - debugger control method execution 484865Sobrien * $Revision: 42 $ 584865Sobrien * 684865Sobrien ******************************************************************************/ 784865Sobrien 884865Sobrien/****************************************************************************** 984865Sobrien * 1084865Sobrien * 1. Copyright Notice 1184865Sobrien * 1284865Sobrien * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. 1384865Sobrien * All rights reserved. 1484865Sobrien * 1584865Sobrien * 2. License 1684865Sobrien * 1784865Sobrien * 2.1. This is your license from Intel Corp. under its intellectual property 1884865Sobrien * rights. You may have additional license terms from the party that provided 1984865Sobrien * you this software, covering your right to use that party's intellectual 2084865Sobrien * property rights. 2184865Sobrien * 2284865Sobrien * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2384865Sobrien * copy of the source code appearing in this file ("Covered Code") an 2484865Sobrien * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2584865Sobrien * base code distributed originally by Intel ("Original Intel Code") to copy, 2684865Sobrien * make derivatives, distribute, use and display any portion of the Covered 2784865Sobrien * Code in any form, with the right to sublicense such rights; and 2884865Sobrien * 2984865Sobrien * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3084865Sobrien * license (with the right to sublicense), under only those claims of Intel 3184865Sobrien * patents that are infringed by the Original Intel Code, to make, use, sell, 3284865Sobrien * offer to sell, and import the Covered Code and derivative works thereof 3384865Sobrien * solely to the minimum extent necessary to exercise the above copyright 3484865Sobrien * license, and in no event shall the patent license extend to any additions 3584865Sobrien * to or modifications of the Original Intel Code. No other license or right 3684865Sobrien * is granted directly or by implication, estoppel or otherwise; 3784865Sobrien * 3884865Sobrien * The above copyright and patent license is granted only if the following 3984865Sobrien * conditions are met: 4084865Sobrien * 4184865Sobrien * 3. Conditions 4284865Sobrien * 4384865Sobrien * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4484865Sobrien * Redistribution of source code of any substantial portion of the Covered 4584865Sobrien * Code or modification with rights to further distribute source must include 4684865Sobrien * the above Copyright Notice, the above License, this list of Conditions, 4784865Sobrien * and the following Disclaimer and Export Compliance provision. In addition, 4884865Sobrien * Licensee must cause all Covered Code to which Licensee contributes to 4984865Sobrien * contain a file documenting the changes Licensee made to create that Covered 5084865Sobrien * Code and the date of any change. Licensee must include in that file the 5184865Sobrien * documentation of any changes made by any predecessor Licensee. Licensee 5284865Sobrien * must include a prominent statement that the modification is derived, 5384865Sobrien * directly or indirectly, from Original Intel Code. 5484865Sobrien * 5584865Sobrien * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5684865Sobrien * Redistribution of source code of any substantial portion of the Covered 5784865Sobrien * Code or modification without rights to further distribute source must 5884865Sobrien * include the following Disclaimer and Export Compliance provision in the 5984865Sobrien * documentation and/or other materials provided with distribution. In 6084865Sobrien * addition, Licensee may not authorize further sublicense of source of any 6184865Sobrien * portion of the Covered Code, and must include terms to the effect that the 6284865Sobrien * license from Licensee to its licensee is limited to the intellectual 6384865Sobrien * property embodied in the software Licensee provides to its licensee, and 6484865Sobrien * not to intellectual property embodied in modifications its licensee may 6584865Sobrien * make. 6684865Sobrien * 6784865Sobrien * 3.3. Redistribution of Executable. Redistribution in executable form of any 6884865Sobrien * substantial portion of the Covered Code or modification must reproduce the 6984865Sobrien * above Copyright Notice, and the following Disclaimer and Export Compliance 7084865Sobrien * provision in the documentation and/or other materials provided with the 7184865Sobrien * distribution. 7284865Sobrien * 7384865Sobrien * 3.4. Intel retains all right, title, and interest in and to the Original 7484865Sobrien * Intel Code. 7584865Sobrien * 7684865Sobrien * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7784865Sobrien * Intel shall be used in advertising or otherwise to promote the sale, use or 7884865Sobrien * other dealings in products derived from or relating to the Covered Code 7984865Sobrien * without prior written authorization from Intel. 8084865Sobrien * 8184865Sobrien * 4. Disclaimer and Export Compliance 8284865Sobrien * 8384865Sobrien * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8484865Sobrien * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8584865Sobrien * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8684865Sobrien * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8784865Sobrien * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8884865Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8984865Sobrien * PARTICULAR PURPOSE. 9084865Sobrien * 9184865Sobrien * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9284865Sobrien * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9384865Sobrien * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9484865Sobrien * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9584865Sobrien * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9684865Sobrien * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9784865Sobrien * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9884865Sobrien * LIMITED REMEDY. 9984865Sobrien * 10084865Sobrien * 4.3. Licensee shall not export, either directly or indirectly, any of this 10184865Sobrien * software or system incorporating such software without first obtaining any 10284865Sobrien * required license or other approval from the U. S. Department of Commerce or 10384865Sobrien * any other agency or department of the United States Government. In the 10484865Sobrien * event Licensee exports any such software from the United States or 10584865Sobrien * re-exports any such software from a foreign destination, Licensee shall 10684865Sobrien * ensure that the distribution and export/re-export of the software is in 10784865Sobrien * compliance with all laws, regulations, orders, or other restrictions of the 10884865Sobrien * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10984865Sobrien * any of its subsidiaries will export/re-export any technical data, process, 11084865Sobrien * software, or service, directly or indirectly, to any country for which the 11184865Sobrien * United States government or any agency thereof requires an export license, 11284865Sobrien * other governmental approval, or letter of assurance, without first obtaining 11384865Sobrien * such license, approval or letter. 11484865Sobrien * 11584865Sobrien *****************************************************************************/ 11684865Sobrien 11784865Sobrien 11884865Sobrien#include "acpi.h" 11984865Sobrien#include "acdebug.h" 12084865Sobrien 12184865Sobrien#ifdef ENABLE_DEBUGGER 12284865Sobrien 12384865Sobrien#define _COMPONENT ACPI_DEBUGGER 12484865Sobrien ACPI_MODULE_NAME ("dbexec") 12584865Sobrien 12684865Sobrien 12784865Sobrienstatic ACPI_DB_METHOD_INFO AcpiGbl_DbMethodInfo; 12884865Sobrien 12984865Sobrien 13084865Sobrien/******************************************************************************* 13184865Sobrien * 13284865Sobrien * FUNCTION: AcpiDbExecuteMethod 13384865Sobrien * 13484865Sobrien * PARAMETERS: Info - Valid info segment 13584865Sobrien * ReturnObj - Where to put return object 13684865Sobrien * 13784865Sobrien * RETURN: Status 13884865Sobrien * 13984865Sobrien * DESCRIPTION: Execute a control method. 14084865Sobrien * 14184865Sobrien ******************************************************************************/ 14284865Sobrien 14384865SobrienACPI_STATUS 14484865SobrienAcpiDbExecuteMethod ( 14584865Sobrien ACPI_DB_METHOD_INFO *Info, 14684865Sobrien ACPI_BUFFER *ReturnObj) 14784865Sobrien{ 14884865Sobrien ACPI_STATUS Status; 14984865Sobrien ACPI_OBJECT_LIST ParamObjects; 15084865Sobrien ACPI_OBJECT Params[MTH_NUM_ARGS]; 15184865Sobrien UINT32 i; 15284865Sobrien 15384865Sobrien 15484865Sobrien if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel) 15584865Sobrien { 15684865Sobrien AcpiOsPrintf ("Warning: debug output is not enabled!\n"); 15784865Sobrien } 15884865Sobrien 15984865Sobrien /* Are there arguments to the method? */ 16084865Sobrien 16184865Sobrien if (Info->Args && Info->Args[0]) 16284865Sobrien { 16384865Sobrien for (i = 0; Info->Args[i] && i < MTH_NUM_ARGS; i++) 16484865Sobrien { 16584865Sobrien Params[i].Type = ACPI_TYPE_INTEGER; 16684865Sobrien Params[i].Integer.Value = ACPI_STRTOUL (Info->Args[i], NULL, 16); 16784865Sobrien } 16884865Sobrien 16984865Sobrien ParamObjects.Pointer = Params; 17084865Sobrien ParamObjects.Count = i; 17184865Sobrien } 17284865Sobrien else 17384865Sobrien { 17484865Sobrien /* Setup default parameters */ 17584865Sobrien 17684865Sobrien Params[0].Type = ACPI_TYPE_INTEGER; 17784865Sobrien Params[0].Integer.Value = 0x01020304; 17884865Sobrien 17984865Sobrien Params[1].Type = ACPI_TYPE_STRING; 18084865Sobrien Params[1].String.Length = 12; 18184865Sobrien Params[1].String.Pointer = "AML Debugger"; 18284865Sobrien 18384865Sobrien ParamObjects.Pointer = Params; 18484865Sobrien ParamObjects.Count = 2; 18584865Sobrien } 18684865Sobrien 18784865Sobrien /* Prepare for a return object of arbitrary size */ 18884865Sobrien 18984865Sobrien ReturnObj->Pointer = AcpiGbl_DbBuffer; 19084865Sobrien ReturnObj->Length = ACPI_DEBUG_BUFFER_SIZE; 19184865Sobrien 19284865Sobrien /* Do the actual method execution */ 19384865Sobrien 19484865Sobrien Status = AcpiEvaluateObject (NULL, Info->Pathname, &ParamObjects, ReturnObj); 19584865Sobrien 19684865Sobrien AcpiGbl_CmSingleStep = FALSE; 19784865Sobrien AcpiGbl_MethodExecuting = FALSE; 19884865Sobrien 19984865Sobrien return (Status); 20084865Sobrien} 20184865Sobrien 20284865Sobrien 20384865Sobrien/******************************************************************************* 20484865Sobrien * 20584865Sobrien * FUNCTION: AcpiDbExecuteSetup 20684865Sobrien * 20784865Sobrien * PARAMETERS: Info - Valid method info 20884865Sobrien * 20984865Sobrien * RETURN: Status 21084865Sobrien * 21184865Sobrien * DESCRIPTION: Setup info segment prior to method execution 21284865Sobrien * 21384865Sobrien ******************************************************************************/ 21484865Sobrien 21584865Sobrienvoid 21684865SobrienAcpiDbExecuteSetup ( 21784865Sobrien ACPI_DB_METHOD_INFO *Info) 21884865Sobrien{ 21984865Sobrien 22084865Sobrien /* Catenate the current scope to the supplied name */ 22184865Sobrien 22284865Sobrien Info->Pathname[0] = 0; 22384865Sobrien if ((Info->Name[0] != '\\') && 22484865Sobrien (Info->Name[0] != '/')) 22584865Sobrien { 22684865Sobrien ACPI_STRCAT (Info->Pathname, AcpiGbl_DbScopeBuf); 22784865Sobrien } 22884865Sobrien 22984865Sobrien ACPI_STRCAT (Info->Pathname, Info->Name); 23084865Sobrien AcpiDbPrepNamestring (Info->Pathname); 23184865Sobrien 23284865Sobrien AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 23384865Sobrien AcpiOsPrintf ("Executing %s\n", Info->Pathname); 23484865Sobrien 23584865Sobrien if (Info->Flags & EX_SINGLE_STEP) 23684865Sobrien { 23784865Sobrien AcpiGbl_CmSingleStep = TRUE; 23884865Sobrien AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 239 } 240 241 else 242 { 243 /* No single step, allow redirection to a file */ 244 245 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 246 } 247} 248 249 250/******************************************************************************* 251 * 252 * FUNCTION: AcpiDbGetOutstandingAllocations 253 * 254 * PARAMETERS: None 255 * 256 * RETURN: Current global allocation count minus cache entries 257 * 258 * DESCRIPTION: Determine the current number of "outstanding" allocations -- 259 * those allocations that have not been freed and also are not 260 * in one of the various object caches. 261 * 262 ******************************************************************************/ 263 264UINT32 265AcpiDbGetOutstandingAllocations ( 266 void) 267{ 268 UINT32 Outstanding = 0; 269 270#ifdef ACPI_DBG_TRACK_ALLOCATIONS 271 UINT32 i; 272 273 274 for (i = ACPI_MEM_LIST_FIRST_CACHE_LIST; i < ACPI_NUM_MEM_LISTS; i++) 275 { 276 Outstanding += (AcpiGbl_MemoryLists[i].TotalAllocated - 277 AcpiGbl_MemoryLists[i].TotalFreed - 278 AcpiGbl_MemoryLists[i].CacheDepth); 279 } 280#endif 281 282 return (Outstanding); 283} 284 285 286/******************************************************************************* 287 * 288 * FUNCTION: AcpiDbExecute 289 * 290 * PARAMETERS: Name - Name of method to execute 291 * Args - Parameters to the method 292 * Flags - single step/no single step 293 * 294 * RETURN: Status 295 * 296 * DESCRIPTION: Execute a control method. Name is relative to the current 297 * scope. 298 * 299 ******************************************************************************/ 300 301void 302AcpiDbExecute ( 303 NATIVE_CHAR *Name, 304 NATIVE_CHAR **Args, 305 UINT32 Flags) 306{ 307 ACPI_STATUS Status; 308 ACPI_BUFFER ReturnObj; 309 310 311#ifdef ACPI_DEBUG 312 UINT32 PreviousAllocations; 313 UINT32 Allocations; 314 315 316 /* Memory allocation tracking */ 317 318 PreviousAllocations = AcpiDbGetOutstandingAllocations (); 319#endif 320 321 AcpiGbl_DbMethodInfo.Name = Name; 322 AcpiGbl_DbMethodInfo.Args = Args; 323 AcpiGbl_DbMethodInfo.Flags = Flags; 324 325 ReturnObj.Pointer = NULL; 326 ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 327 328 AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 329 Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj); 330 331 /* 332 * Allow any handlers in separate threads to complete. 333 * (Such as Notify handlers invoked from AML executed above). 334 */ 335 AcpiOsSleep (0, 10); 336 337 338#ifdef ACPI_DEBUG 339 340 /* Memory allocation tracking */ 341 342 Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations; 343 344 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 345 346 if (Allocations > 0) 347 { 348 AcpiOsPrintf ("Outstanding: %ld allocations after execution\n", 349 Allocations); 350 } 351#endif 352 353 if (ACPI_FAILURE (Status)) 354 { 355 AcpiOsPrintf ("Execution of %s failed with status %s\n", 356 AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status)); 357 } 358 359 else 360 { 361 /* Display a return object, if any */ 362 363 if (ReturnObj.Length) 364 { 365 AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 366 AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, ReturnObj.Length); 367 AcpiDbDumpObject (ReturnObj.Pointer, 1); 368 } 369 else 370 { 371 AcpiOsPrintf ("No return object from execution of %s\n", 372 AcpiGbl_DbMethodInfo.Pathname); 373 } 374 } 375 376 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 377} 378 379 380/******************************************************************************* 381 * 382 * FUNCTION: AcpiDbMethodThread 383 * 384 * PARAMETERS: Context - Execution info segment 385 * 386 * RETURN: None 387 * 388 * DESCRIPTION: Debugger execute thread. Waits for a command line, then 389 * simply dispatches it. 390 * 391 ******************************************************************************/ 392 393void ACPI_SYSTEM_XFACE 394AcpiDbMethodThread ( 395 void *Context) 396{ 397 ACPI_STATUS Status; 398 ACPI_DB_METHOD_INFO *Info = Context; 399 UINT32 i; 400 ACPI_BUFFER ReturnObj; 401 402 403 for (i = 0; i < Info->NumLoops; i++) 404 { 405 Status = AcpiDbExecuteMethod (Info, &ReturnObj); 406 if (ACPI_SUCCESS (Status)) 407 { 408 if (ReturnObj.Length) 409 { 410 AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 411 Info->Pathname, ReturnObj.Pointer, ReturnObj.Length); 412 AcpiDbDumpObject (ReturnObj.Pointer, 1); 413 } 414 } 415 } 416 417 /* Signal our completion */ 418 419 Status = AcpiOsSignalSemaphore (Info->ThreadGate, 1); 420 if (ACPI_FAILURE (Status)) 421 { 422 AcpiOsPrintf ("Could not signal debugger semaphore\n"); 423 } 424} 425 426 427/******************************************************************************* 428 * 429 * FUNCTION: AcpiDbCreateExecutionThreads 430 * 431 * PARAMETERS: NumThreadsArg - Number of threads to create 432 * NumLoopsArg - Loop count for the thread(s) 433 * MethodNameArg - Control method to execute 434 * 435 * RETURN: None 436 * 437 * DESCRIPTION: Create threads to execute method(s) 438 * 439 ******************************************************************************/ 440 441void 442AcpiDbCreateExecutionThreads ( 443 NATIVE_CHAR *NumThreadsArg, 444 NATIVE_CHAR *NumLoopsArg, 445 NATIVE_CHAR *MethodNameArg) 446{ 447 ACPI_STATUS Status; 448 UINT32 NumThreads; 449 UINT32 NumLoops; 450 UINT32 i; 451 ACPI_HANDLE ThreadGate; 452 453 454 /* Get the arguments */ 455 456 NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0); 457 NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0); 458 459 if (!NumThreads || !NumLoops) 460 { 461 AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", NumThreads, NumLoops); 462 return; 463 } 464 465 /* Create the synchronization semaphore */ 466 467 Status = AcpiOsCreateSemaphore (1, 0, &ThreadGate); 468 if (ACPI_FAILURE (Status)) 469 { 470 AcpiOsPrintf ("Could not create semaphore, %s\n", AcpiFormatException (Status)); 471 return; 472 } 473 474 /* Setup the context to be passed to each thread */ 475 476 AcpiGbl_DbMethodInfo.Name = MethodNameArg; 477 AcpiGbl_DbMethodInfo.Args = NULL; 478 AcpiGbl_DbMethodInfo.Flags = 0; 479 AcpiGbl_DbMethodInfo.NumLoops = NumLoops; 480 AcpiGbl_DbMethodInfo.ThreadGate = ThreadGate; 481 482 AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 483 484 /* Create the threads */ 485 486 AcpiOsPrintf ("Creating %X threads to execute %X times each\n", NumThreads, NumLoops); 487 488 for (i = 0; i < (NumThreads); i++) 489 { 490 Status = AcpiOsQueueForExecution (OSD_PRIORITY_MED, AcpiDbMethodThread, &AcpiGbl_DbMethodInfo); 491 if (ACPI_FAILURE (Status)) 492 { 493 break; 494 } 495 } 496 497 /* Wait for all threads to complete */ 498 499 i = NumThreads; 500 while (i) /* Brain damage for OSD implementations that only support wait of 1 unit */ 501 { 502 Status = AcpiOsWaitSemaphore (ThreadGate, 1, WAIT_FOREVER); 503 i--; 504 } 505 506 /* Cleanup and exit */ 507 508 (void) AcpiOsDeleteSemaphore (ThreadGate); 509 510 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 511 AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); 512 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 513} 514 515 516#endif /* ENABLE_DEBUGGER */ 517 518 519