13446Smrj /******************************************************************************* 23446Smrj * 33446Smrj * Module Name: dbexec - debugger control method execution 4*7851SDana.Myers@Sun.COM * $Revision: 1.83 $ 53446Smrj * 63446Smrj ******************************************************************************/ 73446Smrj 83446Smrj /****************************************************************************** 93446Smrj * 103446Smrj * 1. Copyright Notice 113446Smrj * 12*7851SDana.Myers@Sun.COM * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 133446Smrj * All rights reserved. 143446Smrj * 153446Smrj * 2. License 163446Smrj * 173446Smrj * 2.1. This is your license from Intel Corp. under its intellectual property 183446Smrj * rights. You may have additional license terms from the party that provided 193446Smrj * you this software, covering your right to use that party's intellectual 203446Smrj * property rights. 213446Smrj * 223446Smrj * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 233446Smrj * copy of the source code appearing in this file ("Covered Code") an 243446Smrj * irrevocable, perpetual, worldwide license under Intel's copyrights in the 253446Smrj * base code distributed originally by Intel ("Original Intel Code") to copy, 263446Smrj * make derivatives, distribute, use and display any portion of the Covered 273446Smrj * Code in any form, with the right to sublicense such rights; and 283446Smrj * 293446Smrj * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 303446Smrj * license (with the right to sublicense), under only those claims of Intel 313446Smrj * patents that are infringed by the Original Intel Code, to make, use, sell, 323446Smrj * offer to sell, and import the Covered Code and derivative works thereof 333446Smrj * solely to the minimum extent necessary to exercise the above copyright 343446Smrj * license, and in no event shall the patent license extend to any additions 353446Smrj * to or modifications of the Original Intel Code. No other license or right 363446Smrj * is granted directly or by implication, estoppel or otherwise; 373446Smrj * 383446Smrj * The above copyright and patent license is granted only if the following 393446Smrj * conditions are met: 403446Smrj * 413446Smrj * 3. Conditions 423446Smrj * 433446Smrj * 3.1. Redistribution of Source with Rights to Further Distribute Source. 443446Smrj * Redistribution of source code of any substantial portion of the Covered 453446Smrj * Code or modification with rights to further distribute source must include 463446Smrj * the above Copyright Notice, the above License, this list of Conditions, 473446Smrj * and the following Disclaimer and Export Compliance provision. In addition, 483446Smrj * Licensee must cause all Covered Code to which Licensee contributes to 493446Smrj * contain a file documenting the changes Licensee made to create that Covered 503446Smrj * Code and the date of any change. Licensee must include in that file the 513446Smrj * documentation of any changes made by any predecessor Licensee. Licensee 523446Smrj * must include a prominent statement that the modification is derived, 533446Smrj * directly or indirectly, from Original Intel Code. 543446Smrj * 553446Smrj * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 563446Smrj * Redistribution of source code of any substantial portion of the Covered 573446Smrj * Code or modification without rights to further distribute source must 583446Smrj * include the following Disclaimer and Export Compliance provision in the 593446Smrj * documentation and/or other materials provided with distribution. In 603446Smrj * addition, Licensee may not authorize further sublicense of source of any 613446Smrj * portion of the Covered Code, and must include terms to the effect that the 623446Smrj * license from Licensee to its licensee is limited to the intellectual 633446Smrj * property embodied in the software Licensee provides to its licensee, and 643446Smrj * not to intellectual property embodied in modifications its licensee may 653446Smrj * make. 663446Smrj * 673446Smrj * 3.3. Redistribution of Executable. Redistribution in executable form of any 683446Smrj * substantial portion of the Covered Code or modification must reproduce the 693446Smrj * above Copyright Notice, and the following Disclaimer and Export Compliance 703446Smrj * provision in the documentation and/or other materials provided with the 713446Smrj * distribution. 723446Smrj * 733446Smrj * 3.4. Intel retains all right, title, and interest in and to the Original 743446Smrj * Intel Code. 753446Smrj * 763446Smrj * 3.5. Neither the name Intel nor any other trademark owned or controlled by 773446Smrj * Intel shall be used in advertising or otherwise to promote the sale, use or 783446Smrj * other dealings in products derived from or relating to the Covered Code 793446Smrj * without prior written authorization from Intel. 803446Smrj * 813446Smrj * 4. Disclaimer and Export Compliance 823446Smrj * 833446Smrj * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 843446Smrj * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 853446Smrj * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 863446Smrj * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 873446Smrj * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 883446Smrj * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 893446Smrj * PARTICULAR PURPOSE. 903446Smrj * 913446Smrj * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 923446Smrj * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 933446Smrj * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 943446Smrj * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 953446Smrj * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 963446Smrj * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 973446Smrj * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 983446Smrj * LIMITED REMEDY. 993446Smrj * 1003446Smrj * 4.3. Licensee shall not export, either directly or indirectly, any of this 1013446Smrj * software or system incorporating such software without first obtaining any 1023446Smrj * required license or other approval from the U. S. Department of Commerce or 1033446Smrj * any other agency or department of the United States Government. In the 1043446Smrj * event Licensee exports any such software from the United States or 1053446Smrj * re-exports any such software from a foreign destination, Licensee shall 1063446Smrj * ensure that the distribution and export/re-export of the software is in 1073446Smrj * compliance with all laws, regulations, orders, or other restrictions of the 1083446Smrj * U.S. Export Administration Regulations. Licensee agrees that neither it nor 1093446Smrj * any of its subsidiaries will export/re-export any technical data, process, 1103446Smrj * software, or service, directly or indirectly, to any country for which the 1113446Smrj * United States government or any agency thereof requires an export license, 1123446Smrj * other governmental approval, or letter of assurance, without first obtaining 1133446Smrj * such license, approval or letter. 1143446Smrj * 1153446Smrj *****************************************************************************/ 1163446Smrj 1173446Smrj 1183446Smrj #include "acpi.h" 1193446Smrj #include "acdebug.h" 1203446Smrj #include "acnamesp.h" 1213446Smrj 1223446Smrj #ifdef ACPI_DEBUGGER 1233446Smrj 1243446Smrj #define _COMPONENT ACPI_CA_DEBUGGER 1253446Smrj ACPI_MODULE_NAME ("dbexec") 1263446Smrj 1273446Smrj 1283446Smrj static ACPI_DB_METHOD_INFO AcpiGbl_DbMethodInfo; 1293446Smrj 1303446Smrj /* Local prototypes */ 1313446Smrj 1323446Smrj static ACPI_STATUS 1333446Smrj AcpiDbExecuteMethod ( 1343446Smrj ACPI_DB_METHOD_INFO *Info, 1353446Smrj ACPI_BUFFER *ReturnObj); 1363446Smrj 1373446Smrj static void 1383446Smrj AcpiDbExecuteSetup ( 1393446Smrj ACPI_DB_METHOD_INFO *Info); 1403446Smrj 1413446Smrj static UINT32 1423446Smrj AcpiDbGetOutstandingAllocations ( 1433446Smrj void); 1443446Smrj 1453446Smrj static void ACPI_SYSTEM_XFACE 1463446Smrj AcpiDbMethodThread ( 1473446Smrj void *Context); 1483446Smrj 1493446Smrj static ACPI_STATUS 1503446Smrj AcpiDbExecutionWalk ( 1513446Smrj ACPI_HANDLE ObjHandle, 1523446Smrj UINT32 NestingLevel, 1533446Smrj void *Context, 1543446Smrj void **ReturnValue); 1553446Smrj 1563446Smrj 1573446Smrj /******************************************************************************* 1583446Smrj * 1593446Smrj * FUNCTION: AcpiDbExecuteMethod 1603446Smrj * 1613446Smrj * PARAMETERS: Info - Valid info segment 1623446Smrj * ReturnObj - Where to put return object 1633446Smrj * 1643446Smrj * RETURN: Status 1653446Smrj * 1663446Smrj * DESCRIPTION: Execute a control method. 1673446Smrj * 1683446Smrj ******************************************************************************/ 1693446Smrj 1703446Smrj static ACPI_STATUS 1713446Smrj AcpiDbExecuteMethod ( 1723446Smrj ACPI_DB_METHOD_INFO *Info, 1733446Smrj ACPI_BUFFER *ReturnObj) 1743446Smrj { 1753446Smrj ACPI_STATUS Status; 1763446Smrj ACPI_OBJECT_LIST ParamObjects; 1773446Smrj ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; 178*7851SDana.Myers@Sun.COM ACPI_HANDLE Handle; 179*7851SDana.Myers@Sun.COM ACPI_BUFFER Buffer; 1803446Smrj UINT32 i; 181*7851SDana.Myers@Sun.COM ACPI_DEVICE_INFO *ObjInfo; 1823446Smrj 1833446Smrj 1843446Smrj if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel) 1853446Smrj { 1863446Smrj AcpiOsPrintf ("Warning: debug output is not enabled!\n"); 1873446Smrj } 1883446Smrj 189*7851SDana.Myers@Sun.COM /* Get the NS node, determines existence also */ 1903446Smrj 191*7851SDana.Myers@Sun.COM Status = AcpiGetHandle (NULL, Info->Pathname, &Handle); 192*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 1933446Smrj { 194*7851SDana.Myers@Sun.COM return (Status); 195*7851SDana.Myers@Sun.COM } 196*7851SDana.Myers@Sun.COM 197*7851SDana.Myers@Sun.COM /* Get the object info for number of method parameters */ 1983446Smrj 199*7851SDana.Myers@Sun.COM Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 200*7851SDana.Myers@Sun.COM Status = AcpiGetObjectInfo (Handle, &Buffer); 201*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 202*7851SDana.Myers@Sun.COM { 203*7851SDana.Myers@Sun.COM return (Status); 2043446Smrj } 205*7851SDana.Myers@Sun.COM 206*7851SDana.Myers@Sun.COM ParamObjects.Pointer = NULL; 207*7851SDana.Myers@Sun.COM ParamObjects.Count = 0; 208*7851SDana.Myers@Sun.COM 209*7851SDana.Myers@Sun.COM ObjInfo = Buffer.Pointer; 210*7851SDana.Myers@Sun.COM if (ObjInfo->Type == ACPI_TYPE_METHOD) 2113446Smrj { 212*7851SDana.Myers@Sun.COM /* Are there arguments to the method? */ 2133446Smrj 214*7851SDana.Myers@Sun.COM if (Info->Args && Info->Args[0]) 215*7851SDana.Myers@Sun.COM { 216*7851SDana.Myers@Sun.COM for (i = 0; Info->Args[i] && i < ACPI_METHOD_NUM_ARGS; i++) 217*7851SDana.Myers@Sun.COM { 218*7851SDana.Myers@Sun.COM Params[i].Type = ACPI_TYPE_INTEGER; 219*7851SDana.Myers@Sun.COM Params[i].Integer.Value = ACPI_STRTOUL (Info->Args[i], NULL, 16); 220*7851SDana.Myers@Sun.COM } 221*7851SDana.Myers@Sun.COM 222*7851SDana.Myers@Sun.COM ParamObjects.Pointer = Params; 223*7851SDana.Myers@Sun.COM ParamObjects.Count = i; 224*7851SDana.Myers@Sun.COM } 225*7851SDana.Myers@Sun.COM else 226*7851SDana.Myers@Sun.COM { 227*7851SDana.Myers@Sun.COM /* Setup default parameters */ 2283446Smrj 229*7851SDana.Myers@Sun.COM for (i = 0; i < ObjInfo->ParamCount; i++) 230*7851SDana.Myers@Sun.COM { 231*7851SDana.Myers@Sun.COM switch (i) 232*7851SDana.Myers@Sun.COM { 233*7851SDana.Myers@Sun.COM case 0: 234*7851SDana.Myers@Sun.COM 235*7851SDana.Myers@Sun.COM Params[0].Type = ACPI_TYPE_INTEGER; 236*7851SDana.Myers@Sun.COM Params[0].Integer.Value = 0x01020304; 237*7851SDana.Myers@Sun.COM break; 238*7851SDana.Myers@Sun.COM 239*7851SDana.Myers@Sun.COM case 1: 2403446Smrj 241*7851SDana.Myers@Sun.COM Params[1].Type = ACPI_TYPE_STRING; 242*7851SDana.Myers@Sun.COM Params[1].String.Length = 12; 243*7851SDana.Myers@Sun.COM Params[1].String.Pointer = "AML Debugger"; 244*7851SDana.Myers@Sun.COM break; 245*7851SDana.Myers@Sun.COM 246*7851SDana.Myers@Sun.COM default: 247*7851SDana.Myers@Sun.COM 248*7851SDana.Myers@Sun.COM Params[i].Type = ACPI_TYPE_INTEGER; 249*7851SDana.Myers@Sun.COM Params[i].Integer.Value = i * (ACPI_INTEGER) 0x1000; 250*7851SDana.Myers@Sun.COM break; 251*7851SDana.Myers@Sun.COM } 252*7851SDana.Myers@Sun.COM } 253*7851SDana.Myers@Sun.COM 254*7851SDana.Myers@Sun.COM ParamObjects.Pointer = Params; 255*7851SDana.Myers@Sun.COM ParamObjects.Count = ObjInfo->ParamCount; 256*7851SDana.Myers@Sun.COM } 2573446Smrj } 2583446Smrj 259*7851SDana.Myers@Sun.COM ACPI_FREE (Buffer.Pointer); 260*7851SDana.Myers@Sun.COM 2613446Smrj /* Prepare for a return object of arbitrary size */ 2623446Smrj 2633446Smrj ReturnObj->Pointer = AcpiGbl_DbBuffer; 2643446Smrj ReturnObj->Length = ACPI_DEBUG_BUFFER_SIZE; 2653446Smrj 2663446Smrj /* Do the actual method execution */ 2673446Smrj 2683446Smrj AcpiGbl_MethodExecuting = TRUE; 2693446Smrj Status = AcpiEvaluateObject (NULL, 2703446Smrj Info->Pathname, &ParamObjects, ReturnObj); 2713446Smrj 2723446Smrj AcpiGbl_CmSingleStep = FALSE; 2733446Smrj AcpiGbl_MethodExecuting = FALSE; 2743446Smrj 2753446Smrj return (Status); 2763446Smrj } 2773446Smrj 2783446Smrj 2793446Smrj /******************************************************************************* 2803446Smrj * 2813446Smrj * FUNCTION: AcpiDbExecuteSetup 2823446Smrj * 2833446Smrj * PARAMETERS: Info - Valid method info 2843446Smrj * 2853446Smrj * RETURN: None 2863446Smrj * 2873446Smrj * DESCRIPTION: Setup info segment prior to method execution 2883446Smrj * 2893446Smrj ******************************************************************************/ 2903446Smrj 2913446Smrj static void 2923446Smrj AcpiDbExecuteSetup ( 2933446Smrj ACPI_DB_METHOD_INFO *Info) 2943446Smrj { 2953446Smrj 2963446Smrj /* Catenate the current scope to the supplied name */ 2973446Smrj 2983446Smrj Info->Pathname[0] = 0; 2993446Smrj if ((Info->Name[0] != '\\') && 3003446Smrj (Info->Name[0] != '/')) 3013446Smrj { 3023446Smrj ACPI_STRCAT (Info->Pathname, AcpiGbl_DbScopeBuf); 3033446Smrj } 3043446Smrj 3053446Smrj ACPI_STRCAT (Info->Pathname, Info->Name); 3063446Smrj AcpiDbPrepNamestring (Info->Pathname); 3073446Smrj 3083446Smrj AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 3093446Smrj AcpiOsPrintf ("Executing %s\n", Info->Pathname); 3103446Smrj 3113446Smrj if (Info->Flags & EX_SINGLE_STEP) 3123446Smrj { 3133446Smrj AcpiGbl_CmSingleStep = TRUE; 3143446Smrj AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 3153446Smrj } 3163446Smrj 3173446Smrj else 3183446Smrj { 3193446Smrj /* No single step, allow redirection to a file */ 3203446Smrj 3213446Smrj AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 3223446Smrj } 3233446Smrj } 3243446Smrj 3253446Smrj 3263446Smrj #ifdef ACPI_DBG_TRACK_ALLOCATIONS 327*7851SDana.Myers@Sun.COM UINT32 3283446Smrj AcpiDbGetCacheInfo ( 3293446Smrj ACPI_MEMORY_LIST *Cache) 3303446Smrj { 3313446Smrj 3323446Smrj return (Cache->TotalAllocated - Cache->TotalFreed - Cache->CurrentDepth); 3333446Smrj } 3343446Smrj #endif 3353446Smrj 3363446Smrj /******************************************************************************* 3373446Smrj * 3383446Smrj * FUNCTION: AcpiDbGetOutstandingAllocations 3393446Smrj * 3403446Smrj * PARAMETERS: None 3413446Smrj * 3423446Smrj * RETURN: Current global allocation count minus cache entries 3433446Smrj * 3443446Smrj * DESCRIPTION: Determine the current number of "outstanding" allocations -- 3453446Smrj * those allocations that have not been freed and also are not 3463446Smrj * in one of the various object caches. 3473446Smrj * 3483446Smrj ******************************************************************************/ 3493446Smrj 3503446Smrj static UINT32 3513446Smrj AcpiDbGetOutstandingAllocations ( 3523446Smrj void) 3533446Smrj { 3543446Smrj UINT32 Outstanding = 0; 3553446Smrj 3563446Smrj #ifdef ACPI_DBG_TRACK_ALLOCATIONS 3573446Smrj 3583446Smrj Outstanding += AcpiDbGetCacheInfo (AcpiGbl_StateCache); 3593446Smrj Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeCache); 3603446Smrj Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeExtCache); 3613446Smrj Outstanding += AcpiDbGetCacheInfo (AcpiGbl_OperandCache); 3623446Smrj #endif 3633446Smrj 3643446Smrj return (Outstanding); 3653446Smrj } 3663446Smrj 3673446Smrj 3683446Smrj /******************************************************************************* 3693446Smrj * 3703446Smrj * FUNCTION: AcpiDbExecutionWalk 3713446Smrj * 3723446Smrj * PARAMETERS: WALK_CALLBACK 3733446Smrj * 3743446Smrj * RETURN: Status 3753446Smrj * 3763446Smrj * DESCRIPTION: Execute a control method. Name is relative to the current 3773446Smrj * scope. 3783446Smrj * 3793446Smrj ******************************************************************************/ 3803446Smrj 3813446Smrj static ACPI_STATUS 3823446Smrj AcpiDbExecutionWalk ( 3833446Smrj ACPI_HANDLE ObjHandle, 3843446Smrj UINT32 NestingLevel, 3853446Smrj void *Context, 3863446Smrj void **ReturnValue) 3873446Smrj { 3883446Smrj ACPI_OPERAND_OBJECT *ObjDesc; 3893446Smrj ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 3903446Smrj ACPI_BUFFER ReturnObj; 3913446Smrj ACPI_STATUS Status; 3923446Smrj 3933446Smrj 3943446Smrj ObjDesc = AcpiNsGetAttachedObject (Node); 3953446Smrj if (ObjDesc->Method.ParamCount) 3963446Smrj { 3973446Smrj return (AE_OK); 3983446Smrj } 3993446Smrj 4003446Smrj ReturnObj.Pointer = NULL; 4013446Smrj ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 4023446Smrj 4033446Smrj AcpiNsPrintNodePathname (Node, "Execute"); 4043446Smrj 4053446Smrj /* Do the actual method execution */ 4063446Smrj 4073446Smrj AcpiOsPrintf ("\n"); 4083446Smrj AcpiGbl_MethodExecuting = TRUE; 4093446Smrj 4103446Smrj Status = AcpiEvaluateObject (Node, NULL, NULL, &ReturnObj); 4113446Smrj 4123446Smrj AcpiOsPrintf ("[%4.4s] returned %s\n", AcpiUtGetNodeName (Node), 4133446Smrj AcpiFormatException (Status)); 4143446Smrj AcpiGbl_MethodExecuting = FALSE; 4153446Smrj 4163446Smrj return (AE_OK); 4173446Smrj } 4183446Smrj 4193446Smrj 4203446Smrj /******************************************************************************* 4213446Smrj * 4223446Smrj * FUNCTION: AcpiDbExecute 4233446Smrj * 4243446Smrj * PARAMETERS: Name - Name of method to execute 4253446Smrj * Args - Parameters to the method 4263446Smrj * Flags - single step/no single step 4273446Smrj * 4283446Smrj * RETURN: None 4293446Smrj * 4303446Smrj * DESCRIPTION: Execute a control method. Name is relative to the current 4313446Smrj * scope. 4323446Smrj * 4333446Smrj ******************************************************************************/ 4343446Smrj 4353446Smrj void 4363446Smrj AcpiDbExecute ( 4373446Smrj char *Name, 4383446Smrj char **Args, 4393446Smrj UINT32 Flags) 4403446Smrj { 4413446Smrj ACPI_STATUS Status; 4423446Smrj ACPI_BUFFER ReturnObj; 4433446Smrj char *NameString; 4443446Smrj 4453446Smrj 4463446Smrj #ifdef ACPI_DEBUG_OUTPUT 4473446Smrj UINT32 PreviousAllocations; 4483446Smrj UINT32 Allocations; 4493446Smrj 4503446Smrj 4513446Smrj /* Memory allocation tracking */ 4523446Smrj 4533446Smrj PreviousAllocations = AcpiDbGetOutstandingAllocations (); 4543446Smrj #endif 4553446Smrj 4563446Smrj if (*Name == '*') 4573446Smrj { 4583446Smrj (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT, 4593446Smrj ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL); 4603446Smrj return; 4613446Smrj } 4623446Smrj else 4633446Smrj { 4643446Smrj NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1); 4653446Smrj if (!NameString) 4663446Smrj { 4673446Smrj return; 4683446Smrj } 4693446Smrj 470*7851SDana.Myers@Sun.COM ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); 471*7851SDana.Myers@Sun.COM 4723446Smrj ACPI_STRCPY (NameString, Name); 4733446Smrj AcpiUtStrupr (NameString); 4743446Smrj AcpiGbl_DbMethodInfo.Name = NameString; 4753446Smrj AcpiGbl_DbMethodInfo.Args = Args; 4763446Smrj AcpiGbl_DbMethodInfo.Flags = Flags; 4773446Smrj 4783446Smrj ReturnObj.Pointer = NULL; 4793446Smrj ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 4803446Smrj 4813446Smrj AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 4823446Smrj Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj); 4833446Smrj ACPI_FREE (NameString); 4843446Smrj } 4853446Smrj 4863446Smrj /* 4873446Smrj * Allow any handlers in separate threads to complete. 4883446Smrj * (Such as Notify handlers invoked from AML executed above). 4893446Smrj */ 4903446Smrj AcpiOsSleep ((ACPI_INTEGER) 10); 4913446Smrj 4923446Smrj 4933446Smrj #ifdef ACPI_DEBUG_OUTPUT 4943446Smrj 4953446Smrj /* Memory allocation tracking */ 4963446Smrj 4973446Smrj Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations; 4983446Smrj 4993446Smrj AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 5003446Smrj 5013446Smrj if (Allocations > 0) 5023446Smrj { 5033446Smrj AcpiOsPrintf ("Outstanding: 0x%X allocations after execution\n", 5043446Smrj Allocations); 5053446Smrj } 5063446Smrj #endif 5073446Smrj 5083446Smrj if (ACPI_FAILURE (Status)) 5093446Smrj { 5103446Smrj AcpiOsPrintf ("Execution of %s failed with status %s\n", 5113446Smrj AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status)); 5123446Smrj } 5133446Smrj else 5143446Smrj { 5153446Smrj /* Display a return object, if any */ 5163446Smrj 5173446Smrj if (ReturnObj.Length) 5183446Smrj { 5193446Smrj AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 5203446Smrj AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, 5213446Smrj (UINT32) ReturnObj.Length); 5223446Smrj AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); 5233446Smrj } 5243446Smrj else 5253446Smrj { 5263446Smrj AcpiOsPrintf ("No return object from execution of %s\n", 5273446Smrj AcpiGbl_DbMethodInfo.Pathname); 5283446Smrj } 5293446Smrj } 5303446Smrj 5313446Smrj AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 5323446Smrj } 5333446Smrj 5343446Smrj 5353446Smrj /******************************************************************************* 5363446Smrj * 5373446Smrj * FUNCTION: AcpiDbMethodThread 5383446Smrj * 5393446Smrj * PARAMETERS: Context - Execution info segment 5403446Smrj * 5413446Smrj * RETURN: None 5423446Smrj * 5433446Smrj * DESCRIPTION: Debugger execute thread. Waits for a command line, then 5443446Smrj * simply dispatches it. 5453446Smrj * 5463446Smrj ******************************************************************************/ 5473446Smrj 5483446Smrj static void ACPI_SYSTEM_XFACE 5493446Smrj AcpiDbMethodThread ( 5503446Smrj void *Context) 5513446Smrj { 5523446Smrj ACPI_STATUS Status; 5533446Smrj ACPI_DB_METHOD_INFO *Info = Context; 5543446Smrj UINT32 i; 555*7851SDana.Myers@Sun.COM UINT8 Allow; 5563446Smrj ACPI_BUFFER ReturnObj; 5573446Smrj 5583446Smrj 559*7851SDana.Myers@Sun.COM if (Info->InitArgs) 560*7851SDana.Myers@Sun.COM { 561*7851SDana.Myers@Sun.COM AcpiDbUInt32ToHexString (Info->NumCreated, Info->IndexOfThreadStr); 562*7851SDana.Myers@Sun.COM AcpiDbUInt32ToHexString ((UINT32) AcpiOsGetThreadId (), Info->IdOfThreadStr); 563*7851SDana.Myers@Sun.COM } 564*7851SDana.Myers@Sun.COM 565*7851SDana.Myers@Sun.COM if (Info->Threads && (Info->NumCreated < Info->NumThreads)) 566*7851SDana.Myers@Sun.COM { 567*7851SDana.Myers@Sun.COM Info->Threads[Info->NumCreated++] = (UINT32) AcpiOsGetThreadId(); 568*7851SDana.Myers@Sun.COM } 569*7851SDana.Myers@Sun.COM 5703446Smrj for (i = 0; i < Info->NumLoops; i++) 5713446Smrj { 5723446Smrj Status = AcpiDbExecuteMethod (Info, &ReturnObj); 5733446Smrj if (ACPI_FAILURE (Status)) 5743446Smrj { 5753446Smrj AcpiOsPrintf ("%s During execution of %s at iteration %X\n", 5763446Smrj AcpiFormatException (Status), Info->Pathname, i); 5773446Smrj if (Status == AE_ABORT_METHOD) 5783446Smrj { 5793446Smrj break; 5803446Smrj } 5813446Smrj } 5823446Smrj 583*7851SDana.Myers@Sun.COM #if 0 5843446Smrj if ((i % 100) == 0) 5853446Smrj { 586*7851SDana.Myers@Sun.COM AcpiOsPrintf ("%d executions, Thread 0x%x\n", i, AcpiOsGetThreadId ()); 5873446Smrj } 5883446Smrj 5893446Smrj if (ReturnObj.Length) 5903446Smrj { 5913446Smrj AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 5923446Smrj Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length); 5933446Smrj AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); 5943446Smrj } 5953446Smrj #endif 5963446Smrj } 5973446Smrj 5983446Smrj /* Signal our completion */ 5993446Smrj 600*7851SDana.Myers@Sun.COM Allow = 0; 601*7851SDana.Myers@Sun.COM (void) AcpiOsWaitSemaphore (Info->ThreadCompleteGate, 1, ACPI_WAIT_FOREVER); 602*7851SDana.Myers@Sun.COM Info->NumCompleted++; 603*7851SDana.Myers@Sun.COM 604*7851SDana.Myers@Sun.COM if (Info->NumCompleted == Info->NumThreads) 6053446Smrj { 606*7851SDana.Myers@Sun.COM /* Do signal for main thread once only */ 607*7851SDana.Myers@Sun.COM Allow = 1; 608*7851SDana.Myers@Sun.COM } 609*7851SDana.Myers@Sun.COM 610*7851SDana.Myers@Sun.COM (void) AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1); 611*7851SDana.Myers@Sun.COM 612*7851SDana.Myers@Sun.COM if (Allow) 613*7851SDana.Myers@Sun.COM { 614*7851SDana.Myers@Sun.COM Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1); 615*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 616*7851SDana.Myers@Sun.COM { 617*7851SDana.Myers@Sun.COM AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n", 618*7851SDana.Myers@Sun.COM AcpiFormatException (Status)); 619*7851SDana.Myers@Sun.COM } 6203446Smrj } 6213446Smrj } 6223446Smrj 6233446Smrj 6243446Smrj /******************************************************************************* 6253446Smrj * 6263446Smrj * FUNCTION: AcpiDbCreateExecutionThreads 6273446Smrj * 6283446Smrj * PARAMETERS: NumThreadsArg - Number of threads to create 6293446Smrj * NumLoopsArg - Loop count for the thread(s) 6303446Smrj * MethodNameArg - Control method to execute 6313446Smrj * 6323446Smrj * RETURN: None 6333446Smrj * 6343446Smrj * DESCRIPTION: Create threads to execute method(s) 6353446Smrj * 6363446Smrj ******************************************************************************/ 6373446Smrj 6383446Smrj void 6393446Smrj AcpiDbCreateExecutionThreads ( 6403446Smrj char *NumThreadsArg, 6413446Smrj char *NumLoopsArg, 6423446Smrj char *MethodNameArg) 6433446Smrj { 6443446Smrj ACPI_STATUS Status; 6453446Smrj UINT32 NumThreads; 6463446Smrj UINT32 NumLoops; 6473446Smrj UINT32 i; 648*7851SDana.Myers@Sun.COM UINT32 Size; 649*7851SDana.Myers@Sun.COM ACPI_MUTEX MainThreadGate; 650*7851SDana.Myers@Sun.COM ACPI_MUTEX ThreadCompleteGate; 6513446Smrj 6523446Smrj /* Get the arguments */ 6533446Smrj 6543446Smrj NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0); 6553446Smrj NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0); 6563446Smrj 6573446Smrj if (!NumThreads || !NumLoops) 6583446Smrj { 6593446Smrj AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", 6603446Smrj NumThreads, NumLoops); 6613446Smrj return; 6623446Smrj } 6633446Smrj 664*7851SDana.Myers@Sun.COM /* 665*7851SDana.Myers@Sun.COM * Create the semaphore for synchronization of 666*7851SDana.Myers@Sun.COM * the created threads with the main thread. 667*7851SDana.Myers@Sun.COM */ 668*7851SDana.Myers@Sun.COM Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate); 6693446Smrj if (ACPI_FAILURE (Status)) 6703446Smrj { 671*7851SDana.Myers@Sun.COM AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n", 6723446Smrj AcpiFormatException (Status)); 6733446Smrj return; 6743446Smrj } 6753446Smrj 676*7851SDana.Myers@Sun.COM /* 677*7851SDana.Myers@Sun.COM * Create the semaphore for synchronization 678*7851SDana.Myers@Sun.COM * between the created threads. 679*7851SDana.Myers@Sun.COM */ 680*7851SDana.Myers@Sun.COM Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate); 681*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 682*7851SDana.Myers@Sun.COM { 683*7851SDana.Myers@Sun.COM AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n", 684*7851SDana.Myers@Sun.COM AcpiFormatException (Status)); 685*7851SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (MainThreadGate); 686*7851SDana.Myers@Sun.COM return; 687*7851SDana.Myers@Sun.COM } 688*7851SDana.Myers@Sun.COM 689*7851SDana.Myers@Sun.COM ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); 690*7851SDana.Myers@Sun.COM 691*7851SDana.Myers@Sun.COM /* Array to store IDs of threads */ 692*7851SDana.Myers@Sun.COM 693*7851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.NumThreads = NumThreads; 694*7851SDana.Myers@Sun.COM Size = 4 * AcpiGbl_DbMethodInfo.NumThreads; 695*7851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Threads = (UINT32 *) AcpiOsAllocate (Size); 696*7851SDana.Myers@Sun.COM if (AcpiGbl_DbMethodInfo.Threads == NULL) 697*7851SDana.Myers@Sun.COM { 698*7851SDana.Myers@Sun.COM AcpiOsPrintf ("No memory for thread IDs array\n"); 699*7851SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (MainThreadGate); 700*7851SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 701*7851SDana.Myers@Sun.COM return; 702*7851SDana.Myers@Sun.COM } 703*7851SDana.Myers@Sun.COM ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size); 704*7851SDana.Myers@Sun.COM 7053446Smrj /* Setup the context to be passed to each thread */ 7063446Smrj 7073446Smrj AcpiGbl_DbMethodInfo.Name = MethodNameArg; 7083446Smrj AcpiGbl_DbMethodInfo.Flags = 0; 7093446Smrj AcpiGbl_DbMethodInfo.NumLoops = NumLoops; 710*7851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate; 711*7851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate; 712*7851SDana.Myers@Sun.COM 713*7851SDana.Myers@Sun.COM /* Init arguments to be passed to method */ 714*7851SDana.Myers@Sun.COM 715*7851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.InitArgs = 1; 716*7851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments; 717*7851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr; 718*7851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr; 719*7851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr; 720*7851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Arguments[3] = NULL; 721*7851SDana.Myers@Sun.COM AcpiDbUInt32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr); 7223446Smrj 7233446Smrj AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 7243446Smrj 7253446Smrj /* Create the threads */ 7263446Smrj 7273446Smrj AcpiOsPrintf ("Creating %X threads to execute %X times each\n", 7283446Smrj NumThreads, NumLoops); 7293446Smrj 7303446Smrj for (i = 0; i < (NumThreads); i++) 7313446Smrj { 7323446Smrj Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread, 7333446Smrj &AcpiGbl_DbMethodInfo); 7343446Smrj if (ACPI_FAILURE (Status)) 7353446Smrj { 7363446Smrj break; 7373446Smrj } 7383446Smrj } 7393446Smrj 7403446Smrj /* Wait for all threads to complete */ 7413446Smrj 742*7851SDana.Myers@Sun.COM (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER); 7433446Smrj 7443446Smrj AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 7453446Smrj AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); 7463446Smrj AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 747*7851SDana.Myers@Sun.COM 748*7851SDana.Myers@Sun.COM /* Cleanup and exit */ 749*7851SDana.Myers@Sun.COM 750*7851SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (MainThreadGate); 751*7851SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 752*7851SDana.Myers@Sun.COM 753*7851SDana.Myers@Sun.COM AcpiOsFree (AcpiGbl_DbMethodInfo.Threads); 754*7851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Threads = NULL; 7553446Smrj } 7563446Smrj 7573446Smrj #endif /* ACPI_DEBUGGER */ 7583446Smrj 7593446Smrj 760