dbexec.c revision 216471
167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: dbexec - debugger control method execution 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 767754Smsmith/****************************************************************************** 867754Smsmith * 967754Smsmith * 1. Copyright Notice 1067754Smsmith * 11202771Sjkim * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. 1270243Smsmith * All rights reserved. 1367754Smsmith * 1467754Smsmith * 2. License 1567754Smsmith * 1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1767754Smsmith * rights. You may have additional license terms from the party that provided 1867754Smsmith * you this software, covering your right to use that party's intellectual 1967754Smsmith * property rights. 2067754Smsmith * 2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2667754Smsmith * Code in any form, with the right to sublicense such rights; and 2767754Smsmith * 2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 2967754Smsmith * license (with the right to sublicense), under only those claims of Intel 3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3367754Smsmith * license, and in no event shall the patent license extend to any additions 3467754Smsmith * to or modifications of the Original Intel Code. No other license or right 3567754Smsmith * is granted directly or by implication, estoppel or otherwise; 3667754Smsmith * 3767754Smsmith * The above copyright and patent license is granted only if the following 3867754Smsmith * conditions are met: 3967754Smsmith * 4067754Smsmith * 3. Conditions 4167754Smsmith * 4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4367754Smsmith * Redistribution of source code of any substantial portion of the Covered 4467754Smsmith * Code or modification with rights to further distribute source must include 4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4667754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered 4967754Smsmith * Code and the date of any change. Licensee must include in that file the 5067754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5167754Smsmith * must include a prominent statement that the modification is derived, 5267754Smsmith * directly or indirectly, from Original Intel Code. 5367754Smsmith * 5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5567754Smsmith * Redistribution of source code of any substantial portion of the Covered 5667754Smsmith * Code or modification without rights to further distribute source must 5767754Smsmith * include the following Disclaimer and Export Compliance provision in the 5867754Smsmith * documentation and/or other materials provided with distribution. In 5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6167754Smsmith * license from Licensee to its licensee is limited to the intellectual 6267754Smsmith * property embodied in the software Licensee provides to its licensee, and 6367754Smsmith * not to intellectual property embodied in modifications its licensee may 6467754Smsmith * make. 6567754Smsmith * 6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the 6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 6967754Smsmith * provision in the documentation and/or other materials provided with the 7067754Smsmith * distribution. 7167754Smsmith * 7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7367754Smsmith * Intel Code. 7467754Smsmith * 7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7767754Smsmith * other dealings in products derived from or relating to the Covered Code 7867754Smsmith * without prior written authorization from Intel. 7967754Smsmith * 8067754Smsmith * 4. Disclaimer and Export Compliance 8167754Smsmith * 8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8367754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8867754Smsmith * PARTICULAR PURPOSE. 8967754Smsmith * 9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9767754Smsmith * LIMITED REMEDY. 9867754Smsmith * 9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10067754Smsmith * software or system incorporating such software without first obtaining any 10167754Smsmith * required license or other approval from the U. S. Department of Commerce or 10267754Smsmith * any other agency or department of the United States Government. In the 10367754Smsmith * event Licensee exports any such software from the United States or 10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10567754Smsmith * ensure that the distribution and export/re-export of the software is in 10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 10967754Smsmith * software, or service, directly or indirectly, to any country for which the 11067754Smsmith * United States government or any agency thereof requires an export license, 11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11267754Smsmith * such license, approval or letter. 11367754Smsmith * 11467754Smsmith *****************************************************************************/ 11567754Smsmith 11667754Smsmith 117193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 118193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 119193341Sjkim#include <contrib/dev/acpica/include/acdebug.h> 120193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 12167754Smsmith 122102550Siwasaki#ifdef ACPI_DEBUGGER 12367754Smsmith 124102550Siwasaki#define _COMPONENT ACPI_CA_DEBUGGER 12591116Smsmith ACPI_MODULE_NAME ("dbexec") 12667754Smsmith 12767754Smsmith 12899679Siwasakistatic ACPI_DB_METHOD_INFO AcpiGbl_DbMethodInfo; 12967754Smsmith 130151937Sjkim/* Local prototypes */ 13167754Smsmith 132151937Sjkimstatic ACPI_STATUS 133151937SjkimAcpiDbExecuteMethod ( 134151937Sjkim ACPI_DB_METHOD_INFO *Info, 135151937Sjkim ACPI_BUFFER *ReturnObj); 136151937Sjkim 137151937Sjkimstatic void 138151937SjkimAcpiDbExecuteSetup ( 139151937Sjkim ACPI_DB_METHOD_INFO *Info); 140151937Sjkim 141151937Sjkimstatic UINT32 142151937SjkimAcpiDbGetOutstandingAllocations ( 143151937Sjkim void); 144151937Sjkim 145151937Sjkimstatic void ACPI_SYSTEM_XFACE 146151937SjkimAcpiDbMethodThread ( 147151937Sjkim void *Context); 148151937Sjkim 149151937Sjkimstatic ACPI_STATUS 150151937SjkimAcpiDbExecutionWalk ( 151151937Sjkim ACPI_HANDLE ObjHandle, 152151937Sjkim UINT32 NestingLevel, 153151937Sjkim void *Context, 154151937Sjkim void **ReturnValue); 155151937Sjkim 156151937Sjkim 15767754Smsmith/******************************************************************************* 15867754Smsmith * 15967754Smsmith * FUNCTION: AcpiDbExecuteMethod 16067754Smsmith * 16167754Smsmith * PARAMETERS: Info - Valid info segment 16267754Smsmith * ReturnObj - Where to put return object 16367754Smsmith * 16467754Smsmith * RETURN: Status 16567754Smsmith * 16667754Smsmith * DESCRIPTION: Execute a control method. 16767754Smsmith * 16867754Smsmith ******************************************************************************/ 16967754Smsmith 170151937Sjkimstatic ACPI_STATUS 17167754SmsmithAcpiDbExecuteMethod ( 17291116Smsmith ACPI_DB_METHOD_INFO *Info, 17367754Smsmith ACPI_BUFFER *ReturnObj) 17467754Smsmith{ 17567754Smsmith ACPI_STATUS Status; 17667754Smsmith ACPI_OBJECT_LIST ParamObjects; 177114237Snjl ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; 178193267Sjkim ACPI_HANDLE Handle; 17967754Smsmith UINT32 i; 180193267Sjkim ACPI_DEVICE_INFO *ObjInfo; 18167754Smsmith 18267754Smsmith 183216471Sjkim ACPI_FUNCTION_TRACE (DbExecuteMethod); 184216471Sjkim 185216471Sjkim 18683174Smsmith if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel) 18767754Smsmith { 18867754Smsmith AcpiOsPrintf ("Warning: debug output is not enabled!\n"); 18967754Smsmith } 19067754Smsmith 191193267Sjkim /* Get the NS node, determines existence also */ 19267754Smsmith 193193267Sjkim Status = AcpiGetHandle (NULL, Info->Pathname, &Handle); 194193267Sjkim if (ACPI_FAILURE (Status)) 19567754Smsmith { 196216471Sjkim return_ACPI_STATUS (Status); 197193267Sjkim } 19867754Smsmith 199193267Sjkim /* Get the object info for number of method parameters */ 200193267Sjkim 201197104Sjkim Status = AcpiGetObjectInfo (Handle, &ObjInfo); 202193267Sjkim if (ACPI_FAILURE (Status)) 203193267Sjkim { 204216471Sjkim return_ACPI_STATUS (Status); 20567754Smsmith } 206193267Sjkim 207193267Sjkim ParamObjects.Pointer = NULL; 208193267Sjkim ParamObjects.Count = 0; 209193267Sjkim 210193267Sjkim if (ObjInfo->Type == ACPI_TYPE_METHOD) 21167754Smsmith { 212193267Sjkim /* Are there arguments to the method? */ 21367754Smsmith 214193267Sjkim if (Info->Args && Info->Args[0]) 215193267Sjkim { 216193267Sjkim for (i = 0; Info->Args[i] && i < ACPI_METHOD_NUM_ARGS; i++) 217193267Sjkim { 218193267Sjkim Params[i].Type = ACPI_TYPE_INTEGER; 219193267Sjkim Params[i].Integer.Value = ACPI_STRTOUL (Info->Args[i], NULL, 16); 220193267Sjkim } 22167754Smsmith 222193267Sjkim ParamObjects.Pointer = Params; 223193267Sjkim ParamObjects.Count = i; 224193267Sjkim } 225193267Sjkim else 226193267Sjkim { 227193267Sjkim /* Setup default parameters */ 22867754Smsmith 229193267Sjkim for (i = 0; i < ObjInfo->ParamCount; i++) 230193267Sjkim { 231193267Sjkim switch (i) 232193267Sjkim { 233193267Sjkim case 0: 234193267Sjkim 235193267Sjkim Params[0].Type = ACPI_TYPE_INTEGER; 236193267Sjkim Params[0].Integer.Value = 0x01020304; 237193267Sjkim break; 238193267Sjkim 239193267Sjkim case 1: 240193267Sjkim 241193267Sjkim Params[1].Type = ACPI_TYPE_STRING; 242193267Sjkim Params[1].String.Length = 12; 243193267Sjkim Params[1].String.Pointer = "AML Debugger"; 244193267Sjkim break; 245193267Sjkim 246193267Sjkim default: 247193267Sjkim 248193267Sjkim Params[i].Type = ACPI_TYPE_INTEGER; 249202771Sjkim Params[i].Integer.Value = i * (UINT64) 0x1000; 250193267Sjkim break; 251193267Sjkim } 252193267Sjkim } 253193267Sjkim 254193267Sjkim ParamObjects.Pointer = Params; 255193267Sjkim ParamObjects.Count = ObjInfo->ParamCount; 256193267Sjkim } 25767754Smsmith } 25867754Smsmith 259197104Sjkim ACPI_FREE (ObjInfo); 260193267Sjkim 26167754Smsmith /* Prepare for a return object of arbitrary size */ 26267754Smsmith 263151937Sjkim ReturnObj->Pointer = AcpiGbl_DbBuffer; 264151937Sjkim ReturnObj->Length = ACPI_DEBUG_BUFFER_SIZE; 26567754Smsmith 26667754Smsmith /* Do the actual method execution */ 26767754Smsmith 268114237Snjl AcpiGbl_MethodExecuting = TRUE; 269151937Sjkim Status = AcpiEvaluateObject (NULL, 270151937Sjkim Info->Pathname, &ParamObjects, ReturnObj); 27167754Smsmith 27267754Smsmith AcpiGbl_CmSingleStep = FALSE; 27367754Smsmith AcpiGbl_MethodExecuting = FALSE; 27467754Smsmith 275216471Sjkim if (ACPI_FAILURE (Status)) 276216471Sjkim { 277216471Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 278216471Sjkim "while executing %s from debugger", Info->Pathname)); 279216471Sjkim 280216471Sjkim if (Status == AE_BUFFER_OVERFLOW) 281216471Sjkim { 282216471Sjkim ACPI_ERROR ((AE_INFO, 283216471Sjkim "Possible overflow of internal debugger buffer (size 0x%X needed 0x%X)", 284216471Sjkim ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length)); 285216471Sjkim } 286216471Sjkim } 287216471Sjkim 288216471Sjkim return_ACPI_STATUS (Status); 28967754Smsmith} 29067754Smsmith 29167754Smsmith 29267754Smsmith/******************************************************************************* 29367754Smsmith * 29467754Smsmith * FUNCTION: AcpiDbExecuteSetup 29567754Smsmith * 29667754Smsmith * PARAMETERS: Info - Valid method info 29767754Smsmith * 298151937Sjkim * RETURN: None 29967754Smsmith * 30067754Smsmith * DESCRIPTION: Setup info segment prior to method execution 30167754Smsmith * 30267754Smsmith ******************************************************************************/ 30367754Smsmith 304151937Sjkimstatic void 30567754SmsmithAcpiDbExecuteSetup ( 30699679Siwasaki ACPI_DB_METHOD_INFO *Info) 30767754Smsmith{ 30867754Smsmith 30967754Smsmith /* Catenate the current scope to the supplied name */ 31067754Smsmith 31167754Smsmith Info->Pathname[0] = 0; 31267754Smsmith if ((Info->Name[0] != '\\') && 31367754Smsmith (Info->Name[0] != '/')) 31467754Smsmith { 31591116Smsmith ACPI_STRCAT (Info->Pathname, AcpiGbl_DbScopeBuf); 31667754Smsmith } 31767754Smsmith 31891116Smsmith ACPI_STRCAT (Info->Pathname, Info->Name); 31967754Smsmith AcpiDbPrepNamestring (Info->Pathname); 32067754Smsmith 32191116Smsmith AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 32267754Smsmith AcpiOsPrintf ("Executing %s\n", Info->Pathname); 32367754Smsmith 32467754Smsmith if (Info->Flags & EX_SINGLE_STEP) 32567754Smsmith { 32667754Smsmith AcpiGbl_CmSingleStep = TRUE; 32791116Smsmith AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 32867754Smsmith } 32967754Smsmith 33067754Smsmith else 33167754Smsmith { 33267754Smsmith /* No single step, allow redirection to a file */ 33367754Smsmith 33491116Smsmith AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 33567754Smsmith } 33667754Smsmith} 33767754Smsmith 33867754Smsmith 339151937Sjkim#ifdef ACPI_DBG_TRACK_ALLOCATIONS 340167802SjkimUINT32 341151937SjkimAcpiDbGetCacheInfo ( 342151937Sjkim ACPI_MEMORY_LIST *Cache) 343151937Sjkim{ 344151937Sjkim 345151937Sjkim return (Cache->TotalAllocated - Cache->TotalFreed - Cache->CurrentDepth); 346151937Sjkim} 347151937Sjkim#endif 348151937Sjkim 34967754Smsmith/******************************************************************************* 35067754Smsmith * 35182367Smsmith * FUNCTION: AcpiDbGetOutstandingAllocations 35282367Smsmith * 35382367Smsmith * PARAMETERS: None 35482367Smsmith * 35582367Smsmith * RETURN: Current global allocation count minus cache entries 35682367Smsmith * 35782367Smsmith * DESCRIPTION: Determine the current number of "outstanding" allocations -- 35882367Smsmith * those allocations that have not been freed and also are not 35982367Smsmith * in one of the various object caches. 36082367Smsmith * 36182367Smsmith ******************************************************************************/ 36282367Smsmith 363151937Sjkimstatic UINT32 36499679SiwasakiAcpiDbGetOutstandingAllocations ( 36599679Siwasaki void) 36682367Smsmith{ 36782367Smsmith UINT32 Outstanding = 0; 36882367Smsmith 36982367Smsmith#ifdef ACPI_DBG_TRACK_ALLOCATIONS 37082367Smsmith 371151937Sjkim Outstanding += AcpiDbGetCacheInfo (AcpiGbl_StateCache); 372151937Sjkim Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeCache); 373151937Sjkim Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeExtCache); 374151937Sjkim Outstanding += AcpiDbGetCacheInfo (AcpiGbl_OperandCache); 37582367Smsmith#endif 37682367Smsmith 37782367Smsmith return (Outstanding); 37882367Smsmith} 37982367Smsmith 38082367Smsmith 38182367Smsmith/******************************************************************************* 38282367Smsmith * 383114237Snjl * FUNCTION: AcpiDbExecutionWalk 384114237Snjl * 385114237Snjl * PARAMETERS: WALK_CALLBACK 386114237Snjl * 387114237Snjl * RETURN: Status 388114237Snjl * 389114237Snjl * DESCRIPTION: Execute a control method. Name is relative to the current 390114237Snjl * scope. 391114237Snjl * 392114237Snjl ******************************************************************************/ 393114237Snjl 394151937Sjkimstatic ACPI_STATUS 395114237SnjlAcpiDbExecutionWalk ( 396114237Snjl ACPI_HANDLE ObjHandle, 397114237Snjl UINT32 NestingLevel, 398114237Snjl void *Context, 399114237Snjl void **ReturnValue) 400114237Snjl{ 401114237Snjl ACPI_OPERAND_OBJECT *ObjDesc; 402114237Snjl ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 403114237Snjl ACPI_BUFFER ReturnObj; 404114237Snjl ACPI_STATUS Status; 405114237Snjl 406114237Snjl 407114237Snjl ObjDesc = AcpiNsGetAttachedObject (Node); 408114237Snjl if (ObjDesc->Method.ParamCount) 409114237Snjl { 410114237Snjl return (AE_OK); 411114237Snjl } 412114237Snjl 413114237Snjl ReturnObj.Pointer = NULL; 414114237Snjl ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 415114237Snjl 416114237Snjl AcpiNsPrintNodePathname (Node, "Execute"); 417114237Snjl 418114237Snjl /* Do the actual method execution */ 419114237Snjl 420114237Snjl AcpiOsPrintf ("\n"); 421114237Snjl AcpiGbl_MethodExecuting = TRUE; 422114237Snjl 423114237Snjl Status = AcpiEvaluateObject (Node, NULL, NULL, &ReturnObj); 424114237Snjl 425123315Snjl AcpiOsPrintf ("[%4.4s] returned %s\n", AcpiUtGetNodeName (Node), 426123315Snjl AcpiFormatException (Status)); 427114237Snjl AcpiGbl_MethodExecuting = FALSE; 428114237Snjl 429114237Snjl return (AE_OK); 430114237Snjl} 431114237Snjl 432114237Snjl 433114237Snjl/******************************************************************************* 434114237Snjl * 43567754Smsmith * FUNCTION: AcpiDbExecute 43667754Smsmith * 43767754Smsmith * PARAMETERS: Name - Name of method to execute 43867754Smsmith * Args - Parameters to the method 43967754Smsmith * Flags - single step/no single step 44067754Smsmith * 441151937Sjkim * RETURN: None 44267754Smsmith * 44367754Smsmith * DESCRIPTION: Execute a control method. Name is relative to the current 44467754Smsmith * scope. 44567754Smsmith * 44667754Smsmith ******************************************************************************/ 44767754Smsmith 44867754Smsmithvoid 44967754SmsmithAcpiDbExecute ( 450114237Snjl char *Name, 451114237Snjl char **Args, 45267754Smsmith UINT32 Flags) 45367754Smsmith{ 45467754Smsmith ACPI_STATUS Status; 45569450Smsmith ACPI_BUFFER ReturnObj; 456167802Sjkim char *NameString; 45769450Smsmith 45869450Smsmith 459102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT 46067754Smsmith UINT32 PreviousAllocations; 46167754Smsmith UINT32 Allocations; 46267754Smsmith 46367754Smsmith 46467754Smsmith /* Memory allocation tracking */ 46567754Smsmith 46682367Smsmith PreviousAllocations = AcpiDbGetOutstandingAllocations (); 46769450Smsmith#endif 46867754Smsmith 469114237Snjl if (*Name == '*') 470114237Snjl { 471151937Sjkim (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT, 472199337Sjkim ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL); 473114237Snjl return; 474114237Snjl } 475114237Snjl else 476114237Snjl { 477167802Sjkim NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1); 478167802Sjkim if (!NameString) 479167802Sjkim { 480167802Sjkim return; 481167802Sjkim } 482167802Sjkim 483167802Sjkim ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); 484167802Sjkim 485167802Sjkim ACPI_STRCPY (NameString, Name); 486167802Sjkim AcpiUtStrupr (NameString); 487167802Sjkim AcpiGbl_DbMethodInfo.Name = NameString; 488114237Snjl AcpiGbl_DbMethodInfo.Args = Args; 489114237Snjl AcpiGbl_DbMethodInfo.Flags = Flags; 49067754Smsmith 491114237Snjl ReturnObj.Pointer = NULL; 492114237Snjl ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 493100966Siwasaki 494114237Snjl AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 495114237Snjl Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj); 496167802Sjkim ACPI_FREE (NameString); 497114237Snjl } 49867754Smsmith 49982367Smsmith /* 50082367Smsmith * Allow any handlers in separate threads to complete. 50182367Smsmith * (Such as Notify handlers invoked from AML executed above). 50282367Smsmith */ 503202771Sjkim AcpiOsSleep ((UINT64) 10); 50467754Smsmith 50582367Smsmith 506102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT 50769450Smsmith 50867754Smsmith /* Memory allocation tracking */ 50967754Smsmith 51082367Smsmith Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations; 51167754Smsmith 51291116Smsmith AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 51367754Smsmith 51467754Smsmith if (Allocations > 0) 51567754Smsmith { 516138287Smarks AcpiOsPrintf ("Outstanding: 0x%X allocations after execution\n", 51782367Smsmith Allocations); 51867754Smsmith } 51969450Smsmith#endif 52067754Smsmith 52167754Smsmith if (ACPI_FAILURE (Status)) 52267754Smsmith { 52383174Smsmith AcpiOsPrintf ("Execution of %s failed with status %s\n", 52483174Smsmith AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status)); 52567754Smsmith } 52667754Smsmith else 52767754Smsmith { 52867754Smsmith /* Display a return object, if any */ 52967754Smsmith 53067754Smsmith if (ReturnObj.Length) 53167754Smsmith { 53277424Smsmith AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 533114237Snjl AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, 534104470Siwasaki (UINT32) ReturnObj.Length); 535151937Sjkim AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); 53667754Smsmith } 537100966Siwasaki else 538100966Siwasaki { 539102550Siwasaki AcpiOsPrintf ("No return object from execution of %s\n", 540100966Siwasaki AcpiGbl_DbMethodInfo.Pathname); 541100966Siwasaki } 54267754Smsmith } 54367754Smsmith 54491116Smsmith AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 54567754Smsmith} 54667754Smsmith 54767754Smsmith 54867754Smsmith/******************************************************************************* 54967754Smsmith * 55067754Smsmith * FUNCTION: AcpiDbMethodThread 55167754Smsmith * 55267754Smsmith * PARAMETERS: Context - Execution info segment 55367754Smsmith * 55467754Smsmith * RETURN: None 55567754Smsmith * 55667754Smsmith * DESCRIPTION: Debugger execute thread. Waits for a command line, then 55767754Smsmith * simply dispatches it. 55867754Smsmith * 55967754Smsmith ******************************************************************************/ 56067754Smsmith 561151937Sjkimstatic void ACPI_SYSTEM_XFACE 56267754SmsmithAcpiDbMethodThread ( 56367754Smsmith void *Context) 56467754Smsmith{ 56567754Smsmith ACPI_STATUS Status; 56691116Smsmith ACPI_DB_METHOD_INFO *Info = Context; 567193267Sjkim ACPI_DB_METHOD_INFO LocalInfo; 56867754Smsmith UINT32 i; 569167802Sjkim UINT8 Allow; 57067754Smsmith ACPI_BUFFER ReturnObj; 57167754Smsmith 57267754Smsmith 573193267Sjkim /* 574193267Sjkim * AcpiGbl_DbMethodInfo.Arguments will be passed as method arguments. 575193267Sjkim * Prevent AcpiGbl_DbMethodInfo from being modified by multiple threads 576193267Sjkim * concurrently. 577193267Sjkim * 578193267Sjkim * Note: The arguments we are passing are used by the ASL test suite 579193267Sjkim * (aslts). Do not change them without updating the tests. 580193267Sjkim */ 581193267Sjkim (void) AcpiOsWaitSemaphore (Info->InfoGate, 1, ACPI_WAIT_FOREVER); 582193267Sjkim 583167802Sjkim if (Info->InitArgs) 584167802Sjkim { 585167802Sjkim AcpiDbUInt32ToHexString (Info->NumCreated, Info->IndexOfThreadStr); 586212761Sjkim AcpiDbUInt32ToHexString ((UINT32) AcpiOsGetThreadId (), Info->IdOfThreadStr); 587167802Sjkim } 588167802Sjkim 589167802Sjkim if (Info->Threads && (Info->NumCreated < Info->NumThreads)) 590167802Sjkim { 591212761Sjkim Info->Threads[Info->NumCreated++] = AcpiOsGetThreadId(); 592167802Sjkim } 593167802Sjkim 594193267Sjkim LocalInfo = *Info; 595193267Sjkim LocalInfo.Args = LocalInfo.Arguments; 596193267Sjkim LocalInfo.Arguments[0] = LocalInfo.NumThreadsStr; 597193267Sjkim LocalInfo.Arguments[1] = LocalInfo.IdOfThreadStr; 598193267Sjkim LocalInfo.Arguments[2] = LocalInfo.IndexOfThreadStr; 599193267Sjkim LocalInfo.Arguments[3] = NULL; 600193267Sjkim 601193267Sjkim (void) AcpiOsSignalSemaphore (Info->InfoGate, 1); 602193267Sjkim 60367754Smsmith for (i = 0; i < Info->NumLoops; i++) 60467754Smsmith { 605193267Sjkim Status = AcpiDbExecuteMethod (&LocalInfo, &ReturnObj); 606117521Snjl if (ACPI_FAILURE (Status)) 60767754Smsmith { 608117521Snjl AcpiOsPrintf ("%s During execution of %s at iteration %X\n", 609117521Snjl AcpiFormatException (Status), Info->Pathname, i); 610127175Snjl if (Status == AE_ABORT_METHOD) 611127175Snjl { 612127175Snjl break; 613127175Snjl } 61467754Smsmith } 615117521Snjl 616167802Sjkim#if 0 617128212Snjl if ((i % 100) == 0) 618117521Snjl { 619209746Sjkim AcpiOsPrintf ("%u executions, Thread 0x%x\n", i, AcpiOsGetThreadId ()); 620117521Snjl } 621117521Snjl 622117521Snjl if (ReturnObj.Length) 623117521Snjl { 624117521Snjl AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 625117521Snjl Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length); 626151937Sjkim AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); 627117521Snjl } 628117521Snjl#endif 62967754Smsmith } 63067754Smsmith 63167754Smsmith /* Signal our completion */ 63267754Smsmith 633167802Sjkim Allow = 0; 634193267Sjkim (void) AcpiOsWaitSemaphore (Info->ThreadCompleteGate, 1, ACPI_WAIT_FOREVER); 635167802Sjkim Info->NumCompleted++; 636167802Sjkim 637167802Sjkim if (Info->NumCompleted == Info->NumThreads) 63899679Siwasaki { 639167802Sjkim /* Do signal for main thread once only */ 640167802Sjkim Allow = 1; 64199679Siwasaki } 642167802Sjkim 643193267Sjkim (void) AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1); 644167802Sjkim 645167802Sjkim if (Allow) 646167802Sjkim { 647167802Sjkim Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1); 648167802Sjkim if (ACPI_FAILURE (Status)) 649167802Sjkim { 650167802Sjkim AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n", 651167802Sjkim AcpiFormatException (Status)); 652167802Sjkim } 653167802Sjkim } 65467754Smsmith} 65567754Smsmith 65667754Smsmith 65767754Smsmith/******************************************************************************* 65867754Smsmith * 65967754Smsmith * FUNCTION: AcpiDbCreateExecutionThreads 66067754Smsmith * 66167754Smsmith * PARAMETERS: NumThreadsArg - Number of threads to create 66267754Smsmith * NumLoopsArg - Loop count for the thread(s) 66367754Smsmith * MethodNameArg - Control method to execute 66467754Smsmith * 66567754Smsmith * RETURN: None 66667754Smsmith * 66767754Smsmith * DESCRIPTION: Create threads to execute method(s) 66867754Smsmith * 66967754Smsmith ******************************************************************************/ 67067754Smsmith 67167754Smsmithvoid 67267754SmsmithAcpiDbCreateExecutionThreads ( 673114237Snjl char *NumThreadsArg, 674114237Snjl char *NumLoopsArg, 675114237Snjl char *MethodNameArg) 67667754Smsmith{ 67767754Smsmith ACPI_STATUS Status; 67867754Smsmith UINT32 NumThreads; 67967754Smsmith UINT32 NumLoops; 68067754Smsmith UINT32 i; 681167802Sjkim UINT32 Size; 682167802Sjkim ACPI_MUTEX MainThreadGate; 683167802Sjkim ACPI_MUTEX ThreadCompleteGate; 684193267Sjkim ACPI_MUTEX InfoGate; 68567754Smsmith 686193267Sjkim 68767754Smsmith /* Get the arguments */ 68867754Smsmith 68991116Smsmith NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0); 69091116Smsmith NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0); 69167754Smsmith 69267754Smsmith if (!NumThreads || !NumLoops) 69367754Smsmith { 694151937Sjkim AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", 695151937Sjkim NumThreads, NumLoops); 69667754Smsmith return; 69767754Smsmith } 69867754Smsmith 699167802Sjkim /* 700167802Sjkim * Create the semaphore for synchronization of 701167802Sjkim * the created threads with the main thread. 702167802Sjkim */ 703167802Sjkim Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate); 704167802Sjkim if (ACPI_FAILURE (Status)) 705167802Sjkim { 706167802Sjkim AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n", 707167802Sjkim AcpiFormatException (Status)); 708167802Sjkim return; 709167802Sjkim } 71067754Smsmith 711167802Sjkim /* 712167802Sjkim * Create the semaphore for synchronization 713167802Sjkim * between the created threads. 714167802Sjkim */ 715167802Sjkim Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate); 71667754Smsmith if (ACPI_FAILURE (Status)) 71767754Smsmith { 718167802Sjkim AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n", 719151937Sjkim AcpiFormatException (Status)); 720167802Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 72167754Smsmith return; 72267754Smsmith } 72367754Smsmith 724193267Sjkim Status = AcpiOsCreateSemaphore (1, 1, &InfoGate); 725193267Sjkim if (ACPI_FAILURE (Status)) 726193267Sjkim { 727193267Sjkim AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n", 728193267Sjkim AcpiFormatException (Status)); 729193267Sjkim (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 730193267Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 731193267Sjkim return; 732193267Sjkim } 733193267Sjkim 734167802Sjkim ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); 735167802Sjkim 736167802Sjkim /* Array to store IDs of threads */ 737167802Sjkim 738167802Sjkim AcpiGbl_DbMethodInfo.NumThreads = NumThreads; 739212761Sjkim Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads; 740212761Sjkim AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size); 741167802Sjkim if (AcpiGbl_DbMethodInfo.Threads == NULL) 742167802Sjkim { 743167802Sjkim AcpiOsPrintf ("No memory for thread IDs array\n"); 744167802Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 745167802Sjkim (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 746193267Sjkim (void) AcpiOsDeleteSemaphore (InfoGate); 747167802Sjkim return; 748167802Sjkim } 749167802Sjkim ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size); 750167802Sjkim 75167754Smsmith /* Setup the context to be passed to each thread */ 75267754Smsmith 75383174Smsmith AcpiGbl_DbMethodInfo.Name = MethodNameArg; 75483174Smsmith AcpiGbl_DbMethodInfo.Flags = 0; 75583174Smsmith AcpiGbl_DbMethodInfo.NumLoops = NumLoops; 756167802Sjkim AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate; 757167802Sjkim AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate; 758193267Sjkim AcpiGbl_DbMethodInfo.InfoGate = InfoGate; 75967754Smsmith 760167802Sjkim /* Init arguments to be passed to method */ 761167802Sjkim 762167802Sjkim AcpiGbl_DbMethodInfo.InitArgs = 1; 763167802Sjkim AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments; 764167802Sjkim AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr; 765167802Sjkim AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr; 766167802Sjkim AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr; 767167802Sjkim AcpiGbl_DbMethodInfo.Arguments[3] = NULL; 768167802Sjkim AcpiDbUInt32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr); 769167802Sjkim 77083174Smsmith AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 77167754Smsmith 77267754Smsmith /* Create the threads */ 77367754Smsmith 774151937Sjkim AcpiOsPrintf ("Creating %X threads to execute %X times each\n", 775151937Sjkim NumThreads, NumLoops); 77667754Smsmith 77767754Smsmith for (i = 0; i < (NumThreads); i++) 77867754Smsmith { 779167802Sjkim Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread, 780151937Sjkim &AcpiGbl_DbMethodInfo); 78199679Siwasaki if (ACPI_FAILURE (Status)) 78299679Siwasaki { 78399679Siwasaki break; 78499679Siwasaki } 78567754Smsmith } 78667754Smsmith 78767754Smsmith /* Wait for all threads to complete */ 78867754Smsmith 789193267Sjkim (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER); 79067754Smsmith 791167802Sjkim AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 792167802Sjkim AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); 793167802Sjkim AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 794167802Sjkim 79567754Smsmith /* Cleanup and exit */ 79667754Smsmith 797167802Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 798167802Sjkim (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 799193267Sjkim (void) AcpiOsDeleteSemaphore (InfoGate); 80067754Smsmith 801167802Sjkim AcpiOsFree (AcpiGbl_DbMethodInfo.Threads); 802167802Sjkim AcpiGbl_DbMethodInfo.Threads = NULL; 80367754Smsmith} 80467754Smsmith 805102550Siwasaki#endif /* ACPI_DEBUGGER */ 80667754Smsmith 80767754Smsmith 808