13446Smrj /******************************************************************************* 23446Smrj * 33446Smrj * Module Name: dbexec - debugger control method execution 43446Smrj * 53446Smrj ******************************************************************************/ 63446Smrj 73446Smrj /****************************************************************************** 83446Smrj * 93446Smrj * 1. Copyright Notice 103446Smrj * 11*9980SDana.Myers@Sun.COM * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 123446Smrj * All rights reserved. 133446Smrj * 143446Smrj * 2. License 153446Smrj * 163446Smrj * 2.1. This is your license from Intel Corp. under its intellectual property 173446Smrj * rights. You may have additional license terms from the party that provided 183446Smrj * you this software, covering your right to use that party's intellectual 193446Smrj * property rights. 203446Smrj * 213446Smrj * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 223446Smrj * copy of the source code appearing in this file ("Covered Code") an 233446Smrj * irrevocable, perpetual, worldwide license under Intel's copyrights in the 243446Smrj * base code distributed originally by Intel ("Original Intel Code") to copy, 253446Smrj * make derivatives, distribute, use and display any portion of the Covered 263446Smrj * Code in any form, with the right to sublicense such rights; and 273446Smrj * 283446Smrj * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 293446Smrj * license (with the right to sublicense), under only those claims of Intel 303446Smrj * patents that are infringed by the Original Intel Code, to make, use, sell, 313446Smrj * offer to sell, and import the Covered Code and derivative works thereof 323446Smrj * solely to the minimum extent necessary to exercise the above copyright 333446Smrj * license, and in no event shall the patent license extend to any additions 343446Smrj * to or modifications of the Original Intel Code. No other license or right 353446Smrj * is granted directly or by implication, estoppel or otherwise; 363446Smrj * 373446Smrj * The above copyright and patent license is granted only if the following 383446Smrj * conditions are met: 393446Smrj * 403446Smrj * 3. Conditions 413446Smrj * 423446Smrj * 3.1. Redistribution of Source with Rights to Further Distribute Source. 433446Smrj * Redistribution of source code of any substantial portion of the Covered 443446Smrj * Code or modification with rights to further distribute source must include 453446Smrj * the above Copyright Notice, the above License, this list of Conditions, 463446Smrj * and the following Disclaimer and Export Compliance provision. In addition, 473446Smrj * Licensee must cause all Covered Code to which Licensee contributes to 483446Smrj * contain a file documenting the changes Licensee made to create that Covered 493446Smrj * Code and the date of any change. Licensee must include in that file the 503446Smrj * documentation of any changes made by any predecessor Licensee. Licensee 513446Smrj * must include a prominent statement that the modification is derived, 523446Smrj * directly or indirectly, from Original Intel Code. 533446Smrj * 543446Smrj * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 553446Smrj * Redistribution of source code of any substantial portion of the Covered 563446Smrj * Code or modification without rights to further distribute source must 573446Smrj * include the following Disclaimer and Export Compliance provision in the 583446Smrj * documentation and/or other materials provided with distribution. In 593446Smrj * addition, Licensee may not authorize further sublicense of source of any 603446Smrj * portion of the Covered Code, and must include terms to the effect that the 613446Smrj * license from Licensee to its licensee is limited to the intellectual 623446Smrj * property embodied in the software Licensee provides to its licensee, and 633446Smrj * not to intellectual property embodied in modifications its licensee may 643446Smrj * make. 653446Smrj * 663446Smrj * 3.3. Redistribution of Executable. Redistribution in executable form of any 673446Smrj * substantial portion of the Covered Code or modification must reproduce the 683446Smrj * above Copyright Notice, and the following Disclaimer and Export Compliance 693446Smrj * provision in the documentation and/or other materials provided with the 703446Smrj * distribution. 713446Smrj * 723446Smrj * 3.4. Intel retains all right, title, and interest in and to the Original 733446Smrj * Intel Code. 743446Smrj * 753446Smrj * 3.5. Neither the name Intel nor any other trademark owned or controlled by 763446Smrj * Intel shall be used in advertising or otherwise to promote the sale, use or 773446Smrj * other dealings in products derived from or relating to the Covered Code 783446Smrj * without prior written authorization from Intel. 793446Smrj * 803446Smrj * 4. Disclaimer and Export Compliance 813446Smrj * 823446Smrj * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 833446Smrj * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 843446Smrj * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 853446Smrj * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 863446Smrj * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 873446Smrj * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 883446Smrj * PARTICULAR PURPOSE. 893446Smrj * 903446Smrj * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 913446Smrj * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 923446Smrj * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 933446Smrj * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 943446Smrj * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 953446Smrj * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 963446Smrj * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 973446Smrj * LIMITED REMEDY. 983446Smrj * 993446Smrj * 4.3. Licensee shall not export, either directly or indirectly, any of this 1003446Smrj * software or system incorporating such software without first obtaining any 1013446Smrj * required license or other approval from the U. S. Department of Commerce or 1023446Smrj * any other agency or department of the United States Government. In the 1033446Smrj * event Licensee exports any such software from the United States or 1043446Smrj * re-exports any such software from a foreign destination, Licensee shall 1053446Smrj * ensure that the distribution and export/re-export of the software is in 1063446Smrj * compliance with all laws, regulations, orders, or other restrictions of the 1073446Smrj * U.S. Export Administration Regulations. Licensee agrees that neither it nor 1083446Smrj * any of its subsidiaries will export/re-export any technical data, process, 1093446Smrj * software, or service, directly or indirectly, to any country for which the 1103446Smrj * United States government or any agency thereof requires an export license, 1113446Smrj * other governmental approval, or letter of assurance, without first obtaining 1123446Smrj * such license, approval or letter. 1133446Smrj * 1143446Smrj *****************************************************************************/ 1153446Smrj 1163446Smrj 1173446Smrj #include "acpi.h" 118*9980SDana.Myers@Sun.COM #include "accommon.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]; 1787851SDana.Myers@Sun.COM ACPI_HANDLE Handle; 1797851SDana.Myers@Sun.COM ACPI_BUFFER Buffer; 1803446Smrj UINT32 i; 1817851SDana.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 1897851SDana.Myers@Sun.COM /* Get the NS node, determines existence also */ 1903446Smrj 1917851SDana.Myers@Sun.COM Status = AcpiGetHandle (NULL, Info->Pathname, &Handle); 1927851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 1933446Smrj { 1947851SDana.Myers@Sun.COM return (Status); 1957851SDana.Myers@Sun.COM } 1967851SDana.Myers@Sun.COM 1977851SDana.Myers@Sun.COM /* Get the object info for number of method parameters */ 1983446Smrj 1997851SDana.Myers@Sun.COM Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 2007851SDana.Myers@Sun.COM Status = AcpiGetObjectInfo (Handle, &Buffer); 2017851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 2027851SDana.Myers@Sun.COM { 2037851SDana.Myers@Sun.COM return (Status); 2043446Smrj } 2057851SDana.Myers@Sun.COM 2067851SDana.Myers@Sun.COM ParamObjects.Pointer = NULL; 2077851SDana.Myers@Sun.COM ParamObjects.Count = 0; 2087851SDana.Myers@Sun.COM 2097851SDana.Myers@Sun.COM ObjInfo = Buffer.Pointer; 2107851SDana.Myers@Sun.COM if (ObjInfo->Type == ACPI_TYPE_METHOD) 2113446Smrj { 2127851SDana.Myers@Sun.COM /* Are there arguments to the method? */ 2133446Smrj 2147851SDana.Myers@Sun.COM if (Info->Args && Info->Args[0]) 2157851SDana.Myers@Sun.COM { 2167851SDana.Myers@Sun.COM for (i = 0; Info->Args[i] && i < ACPI_METHOD_NUM_ARGS; i++) 2177851SDana.Myers@Sun.COM { 2187851SDana.Myers@Sun.COM Params[i].Type = ACPI_TYPE_INTEGER; 2197851SDana.Myers@Sun.COM Params[i].Integer.Value = ACPI_STRTOUL (Info->Args[i], NULL, 16); 2207851SDana.Myers@Sun.COM } 2217851SDana.Myers@Sun.COM 2227851SDana.Myers@Sun.COM ParamObjects.Pointer = Params; 2237851SDana.Myers@Sun.COM ParamObjects.Count = i; 2247851SDana.Myers@Sun.COM } 2257851SDana.Myers@Sun.COM else 2267851SDana.Myers@Sun.COM { 2277851SDana.Myers@Sun.COM /* Setup default parameters */ 2283446Smrj 2297851SDana.Myers@Sun.COM for (i = 0; i < ObjInfo->ParamCount; i++) 2307851SDana.Myers@Sun.COM { 2317851SDana.Myers@Sun.COM switch (i) 2327851SDana.Myers@Sun.COM { 2337851SDana.Myers@Sun.COM case 0: 2347851SDana.Myers@Sun.COM 2357851SDana.Myers@Sun.COM Params[0].Type = ACPI_TYPE_INTEGER; 2367851SDana.Myers@Sun.COM Params[0].Integer.Value = 0x01020304; 2377851SDana.Myers@Sun.COM break; 2387851SDana.Myers@Sun.COM 2397851SDana.Myers@Sun.COM case 1: 2403446Smrj 2417851SDana.Myers@Sun.COM Params[1].Type = ACPI_TYPE_STRING; 2427851SDana.Myers@Sun.COM Params[1].String.Length = 12; 2437851SDana.Myers@Sun.COM Params[1].String.Pointer = "AML Debugger"; 2447851SDana.Myers@Sun.COM break; 2457851SDana.Myers@Sun.COM 2467851SDana.Myers@Sun.COM default: 2477851SDana.Myers@Sun.COM 2487851SDana.Myers@Sun.COM Params[i].Type = ACPI_TYPE_INTEGER; 2497851SDana.Myers@Sun.COM Params[i].Integer.Value = i * (ACPI_INTEGER) 0x1000; 2507851SDana.Myers@Sun.COM break; 2517851SDana.Myers@Sun.COM } 2527851SDana.Myers@Sun.COM } 2537851SDana.Myers@Sun.COM 2547851SDana.Myers@Sun.COM ParamObjects.Pointer = Params; 2557851SDana.Myers@Sun.COM ParamObjects.Count = ObjInfo->ParamCount; 2567851SDana.Myers@Sun.COM } 2573446Smrj } 2583446Smrj 2597851SDana.Myers@Sun.COM ACPI_FREE (Buffer.Pointer); 2607851SDana.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 3277851SDana.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 4707851SDana.Myers@Sun.COM ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); 4717851SDana.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; 554*9980SDana.Myers@Sun.COM ACPI_DB_METHOD_INFO LocalInfo; 5553446Smrj UINT32 i; 5567851SDana.Myers@Sun.COM UINT8 Allow; 5573446Smrj ACPI_BUFFER ReturnObj; 5583446Smrj 5593446Smrj 560*9980SDana.Myers@Sun.COM /* 561*9980SDana.Myers@Sun.COM * AcpiGbl_DbMethodInfo.Arguments will be passed as method arguments. 562*9980SDana.Myers@Sun.COM * Prevent AcpiGbl_DbMethodInfo from being modified by multiple threads 563*9980SDana.Myers@Sun.COM * concurrently. 564*9980SDana.Myers@Sun.COM * 565*9980SDana.Myers@Sun.COM * Note: The arguments we are passing are used by the ASL test suite 566*9980SDana.Myers@Sun.COM * (aslts). Do not change them without updating the tests. 567*9980SDana.Myers@Sun.COM */ 568*9980SDana.Myers@Sun.COM (void) AcpiOsWaitSemaphore (Info->InfoGate, 1, ACPI_WAIT_FOREVER); 569*9980SDana.Myers@Sun.COM 5707851SDana.Myers@Sun.COM if (Info->InitArgs) 5717851SDana.Myers@Sun.COM { 5727851SDana.Myers@Sun.COM AcpiDbUInt32ToHexString (Info->NumCreated, Info->IndexOfThreadStr); 573*9980SDana.Myers@Sun.COM AcpiDbUInt32ToHexString (ACPI_TO_INTEGER (AcpiOsGetThreadId ()), 574*9980SDana.Myers@Sun.COM Info->IdOfThreadStr); 5757851SDana.Myers@Sun.COM } 5767851SDana.Myers@Sun.COM 5777851SDana.Myers@Sun.COM if (Info->Threads && (Info->NumCreated < Info->NumThreads)) 5787851SDana.Myers@Sun.COM { 579*9980SDana.Myers@Sun.COM Info->Threads[Info->NumCreated++] = 580*9980SDana.Myers@Sun.COM ACPI_TO_INTEGER (AcpiOsGetThreadId()); 5817851SDana.Myers@Sun.COM } 5827851SDana.Myers@Sun.COM 583*9980SDana.Myers@Sun.COM LocalInfo = *Info; 584*9980SDana.Myers@Sun.COM LocalInfo.Args = LocalInfo.Arguments; 585*9980SDana.Myers@Sun.COM LocalInfo.Arguments[0] = LocalInfo.NumThreadsStr; 586*9980SDana.Myers@Sun.COM LocalInfo.Arguments[1] = LocalInfo.IdOfThreadStr; 587*9980SDana.Myers@Sun.COM LocalInfo.Arguments[2] = LocalInfo.IndexOfThreadStr; 588*9980SDana.Myers@Sun.COM LocalInfo.Arguments[3] = NULL; 589*9980SDana.Myers@Sun.COM 590*9980SDana.Myers@Sun.COM (void) AcpiOsSignalSemaphore (Info->InfoGate, 1); 591*9980SDana.Myers@Sun.COM 5923446Smrj for (i = 0; i < Info->NumLoops; i++) 5933446Smrj { 594*9980SDana.Myers@Sun.COM Status = AcpiDbExecuteMethod (&LocalInfo, &ReturnObj); 5953446Smrj if (ACPI_FAILURE (Status)) 5963446Smrj { 5973446Smrj AcpiOsPrintf ("%s During execution of %s at iteration %X\n", 5983446Smrj AcpiFormatException (Status), Info->Pathname, i); 5993446Smrj if (Status == AE_ABORT_METHOD) 6003446Smrj { 6013446Smrj break; 6023446Smrj } 6033446Smrj } 6043446Smrj 6057851SDana.Myers@Sun.COM #if 0 6063446Smrj if ((i % 100) == 0) 6073446Smrj { 6087851SDana.Myers@Sun.COM AcpiOsPrintf ("%d executions, Thread 0x%x\n", i, AcpiOsGetThreadId ()); 6093446Smrj } 6103446Smrj 6113446Smrj if (ReturnObj.Length) 6123446Smrj { 6133446Smrj AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 6143446Smrj Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length); 6153446Smrj AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); 6163446Smrj } 6173446Smrj #endif 6183446Smrj } 6193446Smrj 6203446Smrj /* Signal our completion */ 6213446Smrj 6227851SDana.Myers@Sun.COM Allow = 0; 6237851SDana.Myers@Sun.COM (void) AcpiOsWaitSemaphore (Info->ThreadCompleteGate, 1, ACPI_WAIT_FOREVER); 6247851SDana.Myers@Sun.COM Info->NumCompleted++; 6257851SDana.Myers@Sun.COM 6267851SDana.Myers@Sun.COM if (Info->NumCompleted == Info->NumThreads) 6273446Smrj { 6287851SDana.Myers@Sun.COM /* Do signal for main thread once only */ 6297851SDana.Myers@Sun.COM Allow = 1; 6307851SDana.Myers@Sun.COM } 6317851SDana.Myers@Sun.COM 6327851SDana.Myers@Sun.COM (void) AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1); 6337851SDana.Myers@Sun.COM 6347851SDana.Myers@Sun.COM if (Allow) 6357851SDana.Myers@Sun.COM { 6367851SDana.Myers@Sun.COM Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1); 6377851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 6387851SDana.Myers@Sun.COM { 6397851SDana.Myers@Sun.COM AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n", 6407851SDana.Myers@Sun.COM AcpiFormatException (Status)); 6417851SDana.Myers@Sun.COM } 6423446Smrj } 6433446Smrj } 6443446Smrj 6453446Smrj 6463446Smrj /******************************************************************************* 6473446Smrj * 6483446Smrj * FUNCTION: AcpiDbCreateExecutionThreads 6493446Smrj * 6503446Smrj * PARAMETERS: NumThreadsArg - Number of threads to create 6513446Smrj * NumLoopsArg - Loop count for the thread(s) 6523446Smrj * MethodNameArg - Control method to execute 6533446Smrj * 6543446Smrj * RETURN: None 6553446Smrj * 6563446Smrj * DESCRIPTION: Create threads to execute method(s) 6573446Smrj * 6583446Smrj ******************************************************************************/ 6593446Smrj 6603446Smrj void 6613446Smrj AcpiDbCreateExecutionThreads ( 6623446Smrj char *NumThreadsArg, 6633446Smrj char *NumLoopsArg, 6643446Smrj char *MethodNameArg) 6653446Smrj { 6663446Smrj ACPI_STATUS Status; 6673446Smrj UINT32 NumThreads; 6683446Smrj UINT32 NumLoops; 6693446Smrj UINT32 i; 6707851SDana.Myers@Sun.COM UINT32 Size; 6717851SDana.Myers@Sun.COM ACPI_MUTEX MainThreadGate; 6727851SDana.Myers@Sun.COM ACPI_MUTEX ThreadCompleteGate; 673*9980SDana.Myers@Sun.COM ACPI_MUTEX InfoGate; 674*9980SDana.Myers@Sun.COM 6753446Smrj 6763446Smrj /* Get the arguments */ 6773446Smrj 6783446Smrj NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0); 6793446Smrj NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0); 6803446Smrj 6813446Smrj if (!NumThreads || !NumLoops) 6823446Smrj { 6833446Smrj AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", 6843446Smrj NumThreads, NumLoops); 6853446Smrj return; 6863446Smrj } 6873446Smrj 6887851SDana.Myers@Sun.COM /* 6897851SDana.Myers@Sun.COM * Create the semaphore for synchronization of 6907851SDana.Myers@Sun.COM * the created threads with the main thread. 6917851SDana.Myers@Sun.COM */ 6927851SDana.Myers@Sun.COM Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate); 6933446Smrj if (ACPI_FAILURE (Status)) 6943446Smrj { 6957851SDana.Myers@Sun.COM AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n", 6963446Smrj AcpiFormatException (Status)); 6973446Smrj return; 6983446Smrj } 6993446Smrj 7007851SDana.Myers@Sun.COM /* 7017851SDana.Myers@Sun.COM * Create the semaphore for synchronization 7027851SDana.Myers@Sun.COM * between the created threads. 7037851SDana.Myers@Sun.COM */ 7047851SDana.Myers@Sun.COM Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate); 7057851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 7067851SDana.Myers@Sun.COM { 7077851SDana.Myers@Sun.COM AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n", 7087851SDana.Myers@Sun.COM AcpiFormatException (Status)); 7097851SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (MainThreadGate); 7107851SDana.Myers@Sun.COM return; 7117851SDana.Myers@Sun.COM } 7127851SDana.Myers@Sun.COM 713*9980SDana.Myers@Sun.COM Status = AcpiOsCreateSemaphore (1, 1, &InfoGate); 714*9980SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 715*9980SDana.Myers@Sun.COM { 716*9980SDana.Myers@Sun.COM AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n", 717*9980SDana.Myers@Sun.COM AcpiFormatException (Status)); 718*9980SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 719*9980SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (MainThreadGate); 720*9980SDana.Myers@Sun.COM return; 721*9980SDana.Myers@Sun.COM } 722*9980SDana.Myers@Sun.COM 7237851SDana.Myers@Sun.COM ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); 7247851SDana.Myers@Sun.COM 7257851SDana.Myers@Sun.COM /* Array to store IDs of threads */ 7267851SDana.Myers@Sun.COM 7277851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.NumThreads = NumThreads; 7287851SDana.Myers@Sun.COM Size = 4 * AcpiGbl_DbMethodInfo.NumThreads; 7297851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Threads = (UINT32 *) AcpiOsAllocate (Size); 7307851SDana.Myers@Sun.COM if (AcpiGbl_DbMethodInfo.Threads == NULL) 7317851SDana.Myers@Sun.COM { 7327851SDana.Myers@Sun.COM AcpiOsPrintf ("No memory for thread IDs array\n"); 7337851SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (MainThreadGate); 7347851SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 735*9980SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (InfoGate); 7367851SDana.Myers@Sun.COM return; 7377851SDana.Myers@Sun.COM } 7387851SDana.Myers@Sun.COM ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size); 7397851SDana.Myers@Sun.COM 7403446Smrj /* Setup the context to be passed to each thread */ 7413446Smrj 7423446Smrj AcpiGbl_DbMethodInfo.Name = MethodNameArg; 7433446Smrj AcpiGbl_DbMethodInfo.Flags = 0; 7443446Smrj AcpiGbl_DbMethodInfo.NumLoops = NumLoops; 7457851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate; 7467851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate; 747*9980SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.InfoGate = InfoGate; 7487851SDana.Myers@Sun.COM 7497851SDana.Myers@Sun.COM /* Init arguments to be passed to method */ 7507851SDana.Myers@Sun.COM 7517851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.InitArgs = 1; 7527851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments; 7537851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr; 7547851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr; 7557851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr; 7567851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Arguments[3] = NULL; 7577851SDana.Myers@Sun.COM AcpiDbUInt32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr); 7583446Smrj 7593446Smrj AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 7603446Smrj 7613446Smrj /* Create the threads */ 7623446Smrj 7633446Smrj AcpiOsPrintf ("Creating %X threads to execute %X times each\n", 7643446Smrj NumThreads, NumLoops); 7653446Smrj 7663446Smrj for (i = 0; i < (NumThreads); i++) 7673446Smrj { 7683446Smrj Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread, 7693446Smrj &AcpiGbl_DbMethodInfo); 7703446Smrj if (ACPI_FAILURE (Status)) 7713446Smrj { 7723446Smrj break; 7733446Smrj } 7743446Smrj } 7753446Smrj 7763446Smrj /* Wait for all threads to complete */ 7773446Smrj 7787851SDana.Myers@Sun.COM (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER); 7793446Smrj 7803446Smrj AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 7813446Smrj AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); 7823446Smrj AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 7837851SDana.Myers@Sun.COM 7847851SDana.Myers@Sun.COM /* Cleanup and exit */ 7857851SDana.Myers@Sun.COM 7867851SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (MainThreadGate); 7877851SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 788*9980SDana.Myers@Sun.COM (void) AcpiOsDeleteSemaphore (InfoGate); 7897851SDana.Myers@Sun.COM 7907851SDana.Myers@Sun.COM AcpiOsFree (AcpiGbl_DbMethodInfo.Threads); 7917851SDana.Myers@Sun.COM AcpiGbl_DbMethodInfo.Threads = NULL; 7923446Smrj } 7933446Smrj 7943446Smrj #endif /* ACPI_DEBUGGER */ 7953446Smrj 7963446Smrj 797