1*3446Smrj /******************************************************************************* 2*3446Smrj * 3*3446Smrj * Module Name: dbexec - debugger control method execution 4*3446Smrj * $Revision: 1.77 $ 5*3446Smrj * 6*3446Smrj ******************************************************************************/ 7*3446Smrj 8*3446Smrj /****************************************************************************** 9*3446Smrj * 10*3446Smrj * 1. Copyright Notice 11*3446Smrj * 12*3446Smrj * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp. 13*3446Smrj * All rights reserved. 14*3446Smrj * 15*3446Smrj * 2. License 16*3446Smrj * 17*3446Smrj * 2.1. This is your license from Intel Corp. under its intellectual property 18*3446Smrj * rights. You may have additional license terms from the party that provided 19*3446Smrj * you this software, covering your right to use that party's intellectual 20*3446Smrj * property rights. 21*3446Smrj * 22*3446Smrj * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23*3446Smrj * copy of the source code appearing in this file ("Covered Code") an 24*3446Smrj * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25*3446Smrj * base code distributed originally by Intel ("Original Intel Code") to copy, 26*3446Smrj * make derivatives, distribute, use and display any portion of the Covered 27*3446Smrj * Code in any form, with the right to sublicense such rights; and 28*3446Smrj * 29*3446Smrj * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30*3446Smrj * license (with the right to sublicense), under only those claims of Intel 31*3446Smrj * patents that are infringed by the Original Intel Code, to make, use, sell, 32*3446Smrj * offer to sell, and import the Covered Code and derivative works thereof 33*3446Smrj * solely to the minimum extent necessary to exercise the above copyright 34*3446Smrj * license, and in no event shall the patent license extend to any additions 35*3446Smrj * to or modifications of the Original Intel Code. No other license or right 36*3446Smrj * is granted directly or by implication, estoppel or otherwise; 37*3446Smrj * 38*3446Smrj * The above copyright and patent license is granted only if the following 39*3446Smrj * conditions are met: 40*3446Smrj * 41*3446Smrj * 3. Conditions 42*3446Smrj * 43*3446Smrj * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44*3446Smrj * Redistribution of source code of any substantial portion of the Covered 45*3446Smrj * Code or modification with rights to further distribute source must include 46*3446Smrj * the above Copyright Notice, the above License, this list of Conditions, 47*3446Smrj * and the following Disclaimer and Export Compliance provision. In addition, 48*3446Smrj * Licensee must cause all Covered Code to which Licensee contributes to 49*3446Smrj * contain a file documenting the changes Licensee made to create that Covered 50*3446Smrj * Code and the date of any change. Licensee must include in that file the 51*3446Smrj * documentation of any changes made by any predecessor Licensee. Licensee 52*3446Smrj * must include a prominent statement that the modification is derived, 53*3446Smrj * directly or indirectly, from Original Intel Code. 54*3446Smrj * 55*3446Smrj * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56*3446Smrj * Redistribution of source code of any substantial portion of the Covered 57*3446Smrj * Code or modification without rights to further distribute source must 58*3446Smrj * include the following Disclaimer and Export Compliance provision in the 59*3446Smrj * documentation and/or other materials provided with distribution. In 60*3446Smrj * addition, Licensee may not authorize further sublicense of source of any 61*3446Smrj * portion of the Covered Code, and must include terms to the effect that the 62*3446Smrj * license from Licensee to its licensee is limited to the intellectual 63*3446Smrj * property embodied in the software Licensee provides to its licensee, and 64*3446Smrj * not to intellectual property embodied in modifications its licensee may 65*3446Smrj * make. 66*3446Smrj * 67*3446Smrj * 3.3. Redistribution of Executable. Redistribution in executable form of any 68*3446Smrj * substantial portion of the Covered Code or modification must reproduce the 69*3446Smrj * above Copyright Notice, and the following Disclaimer and Export Compliance 70*3446Smrj * provision in the documentation and/or other materials provided with the 71*3446Smrj * distribution. 72*3446Smrj * 73*3446Smrj * 3.4. Intel retains all right, title, and interest in and to the Original 74*3446Smrj * Intel Code. 75*3446Smrj * 76*3446Smrj * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77*3446Smrj * Intel shall be used in advertising or otherwise to promote the sale, use or 78*3446Smrj * other dealings in products derived from or relating to the Covered Code 79*3446Smrj * without prior written authorization from Intel. 80*3446Smrj * 81*3446Smrj * 4. Disclaimer and Export Compliance 82*3446Smrj * 83*3446Smrj * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84*3446Smrj * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85*3446Smrj * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86*3446Smrj * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87*3446Smrj * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88*3446Smrj * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89*3446Smrj * PARTICULAR PURPOSE. 90*3446Smrj * 91*3446Smrj * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92*3446Smrj * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93*3446Smrj * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94*3446Smrj * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95*3446Smrj * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96*3446Smrj * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97*3446Smrj * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98*3446Smrj * LIMITED REMEDY. 99*3446Smrj * 100*3446Smrj * 4.3. Licensee shall not export, either directly or indirectly, any of this 101*3446Smrj * software or system incorporating such software without first obtaining any 102*3446Smrj * required license or other approval from the U. S. Department of Commerce or 103*3446Smrj * any other agency or department of the United States Government. In the 104*3446Smrj * event Licensee exports any such software from the United States or 105*3446Smrj * re-exports any such software from a foreign destination, Licensee shall 106*3446Smrj * ensure that the distribution and export/re-export of the software is in 107*3446Smrj * compliance with all laws, regulations, orders, or other restrictions of the 108*3446Smrj * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109*3446Smrj * any of its subsidiaries will export/re-export any technical data, process, 110*3446Smrj * software, or service, directly or indirectly, to any country for which the 111*3446Smrj * United States government or any agency thereof requires an export license, 112*3446Smrj * other governmental approval, or letter of assurance, without first obtaining 113*3446Smrj * such license, approval or letter. 114*3446Smrj * 115*3446Smrj *****************************************************************************/ 116*3446Smrj 117*3446Smrj 118*3446Smrj #include "acpi.h" 119*3446Smrj #include "acdebug.h" 120*3446Smrj #include "acnamesp.h" 121*3446Smrj 122*3446Smrj #ifdef ACPI_DEBUGGER 123*3446Smrj 124*3446Smrj #define _COMPONENT ACPI_CA_DEBUGGER 125*3446Smrj ACPI_MODULE_NAME ("dbexec") 126*3446Smrj 127*3446Smrj 128*3446Smrj static ACPI_DB_METHOD_INFO AcpiGbl_DbMethodInfo; 129*3446Smrj 130*3446Smrj /* Local prototypes */ 131*3446Smrj 132*3446Smrj static ACPI_STATUS 133*3446Smrj AcpiDbExecuteMethod ( 134*3446Smrj ACPI_DB_METHOD_INFO *Info, 135*3446Smrj ACPI_BUFFER *ReturnObj); 136*3446Smrj 137*3446Smrj static void 138*3446Smrj AcpiDbExecuteSetup ( 139*3446Smrj ACPI_DB_METHOD_INFO *Info); 140*3446Smrj 141*3446Smrj static UINT32 142*3446Smrj AcpiDbGetOutstandingAllocations ( 143*3446Smrj void); 144*3446Smrj 145*3446Smrj static void ACPI_SYSTEM_XFACE 146*3446Smrj AcpiDbMethodThread ( 147*3446Smrj void *Context); 148*3446Smrj 149*3446Smrj static ACPI_STATUS 150*3446Smrj AcpiDbExecutionWalk ( 151*3446Smrj ACPI_HANDLE ObjHandle, 152*3446Smrj UINT32 NestingLevel, 153*3446Smrj void *Context, 154*3446Smrj void **ReturnValue); 155*3446Smrj 156*3446Smrj #ifdef ACPI_DBG_TRACK_ALLOCATIONS 157*3446Smrj static UINT32 158*3446Smrj AcpiDbGetCacheInfo ( 159*3446Smrj ACPI_MEMORY_LIST *Cache); 160*3446Smrj #endif 161*3446Smrj 162*3446Smrj 163*3446Smrj /******************************************************************************* 164*3446Smrj * 165*3446Smrj * FUNCTION: AcpiDbExecuteMethod 166*3446Smrj * 167*3446Smrj * PARAMETERS: Info - Valid info segment 168*3446Smrj * ReturnObj - Where to put return object 169*3446Smrj * 170*3446Smrj * RETURN: Status 171*3446Smrj * 172*3446Smrj * DESCRIPTION: Execute a control method. 173*3446Smrj * 174*3446Smrj ******************************************************************************/ 175*3446Smrj 176*3446Smrj static ACPI_STATUS 177*3446Smrj AcpiDbExecuteMethod ( 178*3446Smrj ACPI_DB_METHOD_INFO *Info, 179*3446Smrj ACPI_BUFFER *ReturnObj) 180*3446Smrj { 181*3446Smrj ACPI_STATUS Status; 182*3446Smrj ACPI_OBJECT_LIST ParamObjects; 183*3446Smrj ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; 184*3446Smrj UINT32 i; 185*3446Smrj 186*3446Smrj 187*3446Smrj if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel) 188*3446Smrj { 189*3446Smrj AcpiOsPrintf ("Warning: debug output is not enabled!\n"); 190*3446Smrj } 191*3446Smrj 192*3446Smrj /* Are there arguments to the method? */ 193*3446Smrj 194*3446Smrj if (Info->Args && Info->Args[0]) 195*3446Smrj { 196*3446Smrj for (i = 0; Info->Args[i] && i < ACPI_METHOD_NUM_ARGS; i++) 197*3446Smrj { 198*3446Smrj Params[i].Type = ACPI_TYPE_INTEGER; 199*3446Smrj Params[i].Integer.Value = ACPI_STRTOUL (Info->Args[i], NULL, 16); 200*3446Smrj } 201*3446Smrj 202*3446Smrj ParamObjects.Pointer = Params; 203*3446Smrj ParamObjects.Count = i; 204*3446Smrj } 205*3446Smrj else 206*3446Smrj { 207*3446Smrj /* Setup default parameters */ 208*3446Smrj 209*3446Smrj Params[0].Type = ACPI_TYPE_INTEGER; 210*3446Smrj Params[0].Integer.Value = 0x01020304; 211*3446Smrj 212*3446Smrj Params[1].Type = ACPI_TYPE_STRING; 213*3446Smrj Params[1].String.Length = 12; 214*3446Smrj Params[1].String.Pointer = "AML Debugger"; 215*3446Smrj 216*3446Smrj ParamObjects.Pointer = Params; 217*3446Smrj ParamObjects.Count = 2; 218*3446Smrj } 219*3446Smrj 220*3446Smrj /* Prepare for a return object of arbitrary size */ 221*3446Smrj 222*3446Smrj ReturnObj->Pointer = AcpiGbl_DbBuffer; 223*3446Smrj ReturnObj->Length = ACPI_DEBUG_BUFFER_SIZE; 224*3446Smrj 225*3446Smrj /* Do the actual method execution */ 226*3446Smrj 227*3446Smrj AcpiGbl_MethodExecuting = TRUE; 228*3446Smrj Status = AcpiEvaluateObject (NULL, 229*3446Smrj Info->Pathname, &ParamObjects, ReturnObj); 230*3446Smrj 231*3446Smrj AcpiGbl_CmSingleStep = FALSE; 232*3446Smrj AcpiGbl_MethodExecuting = FALSE; 233*3446Smrj 234*3446Smrj return (Status); 235*3446Smrj } 236*3446Smrj 237*3446Smrj 238*3446Smrj /******************************************************************************* 239*3446Smrj * 240*3446Smrj * FUNCTION: AcpiDbExecuteSetup 241*3446Smrj * 242*3446Smrj * PARAMETERS: Info - Valid method info 243*3446Smrj * 244*3446Smrj * RETURN: None 245*3446Smrj * 246*3446Smrj * DESCRIPTION: Setup info segment prior to method execution 247*3446Smrj * 248*3446Smrj ******************************************************************************/ 249*3446Smrj 250*3446Smrj static void 251*3446Smrj AcpiDbExecuteSetup ( 252*3446Smrj ACPI_DB_METHOD_INFO *Info) 253*3446Smrj { 254*3446Smrj 255*3446Smrj /* Catenate the current scope to the supplied name */ 256*3446Smrj 257*3446Smrj Info->Pathname[0] = 0; 258*3446Smrj if ((Info->Name[0] != '\\') && 259*3446Smrj (Info->Name[0] != '/')) 260*3446Smrj { 261*3446Smrj ACPI_STRCAT (Info->Pathname, AcpiGbl_DbScopeBuf); 262*3446Smrj } 263*3446Smrj 264*3446Smrj ACPI_STRCAT (Info->Pathname, Info->Name); 265*3446Smrj AcpiDbPrepNamestring (Info->Pathname); 266*3446Smrj 267*3446Smrj AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 268*3446Smrj AcpiOsPrintf ("Executing %s\n", Info->Pathname); 269*3446Smrj 270*3446Smrj if (Info->Flags & EX_SINGLE_STEP) 271*3446Smrj { 272*3446Smrj AcpiGbl_CmSingleStep = TRUE; 273*3446Smrj AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 274*3446Smrj } 275*3446Smrj 276*3446Smrj else 277*3446Smrj { 278*3446Smrj /* No single step, allow redirection to a file */ 279*3446Smrj 280*3446Smrj AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 281*3446Smrj } 282*3446Smrj } 283*3446Smrj 284*3446Smrj 285*3446Smrj #ifdef ACPI_DBG_TRACK_ALLOCATIONS 286*3446Smrj static UINT32 287*3446Smrj AcpiDbGetCacheInfo ( 288*3446Smrj ACPI_MEMORY_LIST *Cache) 289*3446Smrj { 290*3446Smrj 291*3446Smrj return (Cache->TotalAllocated - Cache->TotalFreed - Cache->CurrentDepth); 292*3446Smrj } 293*3446Smrj #endif 294*3446Smrj 295*3446Smrj /******************************************************************************* 296*3446Smrj * 297*3446Smrj * FUNCTION: AcpiDbGetOutstandingAllocations 298*3446Smrj * 299*3446Smrj * PARAMETERS: None 300*3446Smrj * 301*3446Smrj * RETURN: Current global allocation count minus cache entries 302*3446Smrj * 303*3446Smrj * DESCRIPTION: Determine the current number of "outstanding" allocations -- 304*3446Smrj * those allocations that have not been freed and also are not 305*3446Smrj * in one of the various object caches. 306*3446Smrj * 307*3446Smrj ******************************************************************************/ 308*3446Smrj 309*3446Smrj static UINT32 310*3446Smrj AcpiDbGetOutstandingAllocations ( 311*3446Smrj void) 312*3446Smrj { 313*3446Smrj UINT32 Outstanding = 0; 314*3446Smrj 315*3446Smrj #ifdef ACPI_DBG_TRACK_ALLOCATIONS 316*3446Smrj 317*3446Smrj Outstanding += AcpiDbGetCacheInfo (AcpiGbl_StateCache); 318*3446Smrj Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeCache); 319*3446Smrj Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeExtCache); 320*3446Smrj Outstanding += AcpiDbGetCacheInfo (AcpiGbl_OperandCache); 321*3446Smrj #endif 322*3446Smrj 323*3446Smrj return (Outstanding); 324*3446Smrj } 325*3446Smrj 326*3446Smrj 327*3446Smrj /******************************************************************************* 328*3446Smrj * 329*3446Smrj * FUNCTION: AcpiDbExecutionWalk 330*3446Smrj * 331*3446Smrj * PARAMETERS: WALK_CALLBACK 332*3446Smrj * 333*3446Smrj * RETURN: Status 334*3446Smrj * 335*3446Smrj * DESCRIPTION: Execute a control method. Name is relative to the current 336*3446Smrj * scope. 337*3446Smrj * 338*3446Smrj ******************************************************************************/ 339*3446Smrj 340*3446Smrj static ACPI_STATUS 341*3446Smrj AcpiDbExecutionWalk ( 342*3446Smrj ACPI_HANDLE ObjHandle, 343*3446Smrj UINT32 NestingLevel, 344*3446Smrj void *Context, 345*3446Smrj void **ReturnValue) 346*3446Smrj { 347*3446Smrj ACPI_OPERAND_OBJECT *ObjDesc; 348*3446Smrj ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 349*3446Smrj ACPI_BUFFER ReturnObj; 350*3446Smrj ACPI_STATUS Status; 351*3446Smrj 352*3446Smrj 353*3446Smrj ObjDesc = AcpiNsGetAttachedObject (Node); 354*3446Smrj if (ObjDesc->Method.ParamCount) 355*3446Smrj { 356*3446Smrj return (AE_OK); 357*3446Smrj } 358*3446Smrj 359*3446Smrj ReturnObj.Pointer = NULL; 360*3446Smrj ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 361*3446Smrj 362*3446Smrj AcpiNsPrintNodePathname (Node, "Execute"); 363*3446Smrj 364*3446Smrj /* Do the actual method execution */ 365*3446Smrj 366*3446Smrj AcpiOsPrintf ("\n"); 367*3446Smrj AcpiGbl_MethodExecuting = TRUE; 368*3446Smrj 369*3446Smrj Status = AcpiEvaluateObject (Node, NULL, NULL, &ReturnObj); 370*3446Smrj 371*3446Smrj AcpiOsPrintf ("[%4.4s] returned %s\n", AcpiUtGetNodeName (Node), 372*3446Smrj AcpiFormatException (Status)); 373*3446Smrj AcpiGbl_MethodExecuting = FALSE; 374*3446Smrj 375*3446Smrj return (AE_OK); 376*3446Smrj } 377*3446Smrj 378*3446Smrj 379*3446Smrj /******************************************************************************* 380*3446Smrj * 381*3446Smrj * FUNCTION: AcpiDbExecute 382*3446Smrj * 383*3446Smrj * PARAMETERS: Name - Name of method to execute 384*3446Smrj * Args - Parameters to the method 385*3446Smrj * Flags - single step/no single step 386*3446Smrj * 387*3446Smrj * RETURN: None 388*3446Smrj * 389*3446Smrj * DESCRIPTION: Execute a control method. Name is relative to the current 390*3446Smrj * scope. 391*3446Smrj * 392*3446Smrj ******************************************************************************/ 393*3446Smrj 394*3446Smrj void 395*3446Smrj AcpiDbExecute ( 396*3446Smrj char *Name, 397*3446Smrj char **Args, 398*3446Smrj UINT32 Flags) 399*3446Smrj { 400*3446Smrj ACPI_STATUS Status; 401*3446Smrj ACPI_BUFFER ReturnObj; 402*3446Smrj char *NameString; 403*3446Smrj 404*3446Smrj 405*3446Smrj #ifdef ACPI_DEBUG_OUTPUT 406*3446Smrj UINT32 PreviousAllocations; 407*3446Smrj UINT32 Allocations; 408*3446Smrj 409*3446Smrj 410*3446Smrj /* Memory allocation tracking */ 411*3446Smrj 412*3446Smrj PreviousAllocations = AcpiDbGetOutstandingAllocations (); 413*3446Smrj #endif 414*3446Smrj 415*3446Smrj if (*Name == '*') 416*3446Smrj { 417*3446Smrj (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT, 418*3446Smrj ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL); 419*3446Smrj return; 420*3446Smrj } 421*3446Smrj else 422*3446Smrj { 423*3446Smrj NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1); 424*3446Smrj if (!NameString) 425*3446Smrj { 426*3446Smrj return; 427*3446Smrj } 428*3446Smrj 429*3446Smrj ACPI_STRCPY (NameString, Name); 430*3446Smrj AcpiUtStrupr (NameString); 431*3446Smrj AcpiGbl_DbMethodInfo.Name = NameString; 432*3446Smrj AcpiGbl_DbMethodInfo.Args = Args; 433*3446Smrj AcpiGbl_DbMethodInfo.Flags = Flags; 434*3446Smrj 435*3446Smrj ReturnObj.Pointer = NULL; 436*3446Smrj ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 437*3446Smrj 438*3446Smrj AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 439*3446Smrj Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj); 440*3446Smrj ACPI_FREE (NameString); 441*3446Smrj } 442*3446Smrj 443*3446Smrj /* 444*3446Smrj * Allow any handlers in separate threads to complete. 445*3446Smrj * (Such as Notify handlers invoked from AML executed above). 446*3446Smrj */ 447*3446Smrj AcpiOsSleep ((ACPI_INTEGER) 10); 448*3446Smrj 449*3446Smrj 450*3446Smrj #ifdef ACPI_DEBUG_OUTPUT 451*3446Smrj 452*3446Smrj /* Memory allocation tracking */ 453*3446Smrj 454*3446Smrj Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations; 455*3446Smrj 456*3446Smrj AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 457*3446Smrj 458*3446Smrj if (Allocations > 0) 459*3446Smrj { 460*3446Smrj AcpiOsPrintf ("Outstanding: 0x%X allocations after execution\n", 461*3446Smrj Allocations); 462*3446Smrj } 463*3446Smrj #endif 464*3446Smrj 465*3446Smrj if (ACPI_FAILURE (Status)) 466*3446Smrj { 467*3446Smrj AcpiOsPrintf ("Execution of %s failed with status %s\n", 468*3446Smrj AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status)); 469*3446Smrj } 470*3446Smrj else 471*3446Smrj { 472*3446Smrj /* Display a return object, if any */ 473*3446Smrj 474*3446Smrj if (ReturnObj.Length) 475*3446Smrj { 476*3446Smrj AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 477*3446Smrj AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, 478*3446Smrj (UINT32) ReturnObj.Length); 479*3446Smrj AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); 480*3446Smrj } 481*3446Smrj else 482*3446Smrj { 483*3446Smrj AcpiOsPrintf ("No return object from execution of %s\n", 484*3446Smrj AcpiGbl_DbMethodInfo.Pathname); 485*3446Smrj } 486*3446Smrj } 487*3446Smrj 488*3446Smrj AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 489*3446Smrj } 490*3446Smrj 491*3446Smrj 492*3446Smrj /******************************************************************************* 493*3446Smrj * 494*3446Smrj * FUNCTION: AcpiDbMethodThread 495*3446Smrj * 496*3446Smrj * PARAMETERS: Context - Execution info segment 497*3446Smrj * 498*3446Smrj * RETURN: None 499*3446Smrj * 500*3446Smrj * DESCRIPTION: Debugger execute thread. Waits for a command line, then 501*3446Smrj * simply dispatches it. 502*3446Smrj * 503*3446Smrj ******************************************************************************/ 504*3446Smrj 505*3446Smrj static void ACPI_SYSTEM_XFACE 506*3446Smrj AcpiDbMethodThread ( 507*3446Smrj void *Context) 508*3446Smrj { 509*3446Smrj ACPI_STATUS Status; 510*3446Smrj ACPI_DB_METHOD_INFO *Info = Context; 511*3446Smrj UINT32 i; 512*3446Smrj ACPI_BUFFER ReturnObj; 513*3446Smrj 514*3446Smrj 515*3446Smrj for (i = 0; i < Info->NumLoops; i++) 516*3446Smrj { 517*3446Smrj Status = AcpiDbExecuteMethod (Info, &ReturnObj); 518*3446Smrj if (ACPI_FAILURE (Status)) 519*3446Smrj { 520*3446Smrj AcpiOsPrintf ("%s During execution of %s at iteration %X\n", 521*3446Smrj AcpiFormatException (Status), Info->Pathname, i); 522*3446Smrj if (Status == AE_ABORT_METHOD) 523*3446Smrj { 524*3446Smrj break; 525*3446Smrj } 526*3446Smrj } 527*3446Smrj 528*3446Smrj if ((i % 100) == 0) 529*3446Smrj { 530*3446Smrj AcpiOsPrintf ("%d executions\n", i); 531*3446Smrj } 532*3446Smrj 533*3446Smrj #if 0 534*3446Smrj if (ReturnObj.Length) 535*3446Smrj { 536*3446Smrj AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 537*3446Smrj Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length); 538*3446Smrj AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); 539*3446Smrj } 540*3446Smrj #endif 541*3446Smrj } 542*3446Smrj 543*3446Smrj /* Signal our completion */ 544*3446Smrj 545*3446Smrj Status = AcpiOsSignalSemaphore (Info->ThreadGate, 1); 546*3446Smrj if (ACPI_FAILURE (Status)) 547*3446Smrj { 548*3446Smrj AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n", 549*3446Smrj AcpiFormatException (Status)); 550*3446Smrj } 551*3446Smrj } 552*3446Smrj 553*3446Smrj 554*3446Smrj /******************************************************************************* 555*3446Smrj * 556*3446Smrj * FUNCTION: AcpiDbCreateExecutionThreads 557*3446Smrj * 558*3446Smrj * PARAMETERS: NumThreadsArg - Number of threads to create 559*3446Smrj * NumLoopsArg - Loop count for the thread(s) 560*3446Smrj * MethodNameArg - Control method to execute 561*3446Smrj * 562*3446Smrj * RETURN: None 563*3446Smrj * 564*3446Smrj * DESCRIPTION: Create threads to execute method(s) 565*3446Smrj * 566*3446Smrj ******************************************************************************/ 567*3446Smrj 568*3446Smrj void 569*3446Smrj AcpiDbCreateExecutionThreads ( 570*3446Smrj char *NumThreadsArg, 571*3446Smrj char *NumLoopsArg, 572*3446Smrj char *MethodNameArg) 573*3446Smrj { 574*3446Smrj ACPI_STATUS Status; 575*3446Smrj UINT32 NumThreads; 576*3446Smrj UINT32 NumLoops; 577*3446Smrj UINT32 i; 578*3446Smrj ACPI_MUTEX ThreadGate; 579*3446Smrj 580*3446Smrj 581*3446Smrj /* Get the arguments */ 582*3446Smrj 583*3446Smrj NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0); 584*3446Smrj NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0); 585*3446Smrj 586*3446Smrj if (!NumThreads || !NumLoops) 587*3446Smrj { 588*3446Smrj AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", 589*3446Smrj NumThreads, NumLoops); 590*3446Smrj return; 591*3446Smrj } 592*3446Smrj 593*3446Smrj /* Create the synchronization semaphore */ 594*3446Smrj 595*3446Smrj Status = AcpiOsCreateSemaphore (1, 0, &ThreadGate); 596*3446Smrj if (ACPI_FAILURE (Status)) 597*3446Smrj { 598*3446Smrj AcpiOsPrintf ("Could not create semaphore, %s\n", 599*3446Smrj AcpiFormatException (Status)); 600*3446Smrj return; 601*3446Smrj } 602*3446Smrj 603*3446Smrj /* Setup the context to be passed to each thread */ 604*3446Smrj 605*3446Smrj AcpiGbl_DbMethodInfo.Name = MethodNameArg; 606*3446Smrj AcpiGbl_DbMethodInfo.Args = NULL; 607*3446Smrj AcpiGbl_DbMethodInfo.Flags = 0; 608*3446Smrj AcpiGbl_DbMethodInfo.NumLoops = NumLoops; 609*3446Smrj AcpiGbl_DbMethodInfo.ThreadGate = ThreadGate; 610*3446Smrj 611*3446Smrj AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 612*3446Smrj 613*3446Smrj /* Create the threads */ 614*3446Smrj 615*3446Smrj AcpiOsPrintf ("Creating %X threads to execute %X times each\n", 616*3446Smrj NumThreads, NumLoops); 617*3446Smrj 618*3446Smrj for (i = 0; i < (NumThreads); i++) 619*3446Smrj { 620*3446Smrj Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread, 621*3446Smrj &AcpiGbl_DbMethodInfo); 622*3446Smrj if (ACPI_FAILURE (Status)) 623*3446Smrj { 624*3446Smrj break; 625*3446Smrj } 626*3446Smrj } 627*3446Smrj 628*3446Smrj /* Wait for all threads to complete */ 629*3446Smrj 630*3446Smrj i = NumThreads; 631*3446Smrj while (i) /* Brain damage for host OSs that only support wait of 1 unit */ 632*3446Smrj { 633*3446Smrj Status = AcpiOsWaitSemaphore (ThreadGate, 1, ACPI_WAIT_FOREVER); 634*3446Smrj i--; 635*3446Smrj } 636*3446Smrj 637*3446Smrj /* Cleanup and exit */ 638*3446Smrj 639*3446Smrj (void) AcpiOsDeleteSemaphore (ThreadGate); 640*3446Smrj 641*3446Smrj AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 642*3446Smrj AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); 643*3446Smrj AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 644*3446Smrj } 645*3446Smrj 646*3446Smrj #endif /* ACPI_DEBUGGER */ 647*3446Smrj 648*3446Smrj 649