dbexec.c revision 222544
167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: dbexec - debugger control method execution 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 4467754Smsmith 45193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 46193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 47193341Sjkim#include <contrib/dev/acpica/include/acdebug.h> 48193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 4967754Smsmith 50102550Siwasaki#ifdef ACPI_DEBUGGER 5167754Smsmith 52102550Siwasaki#define _COMPONENT ACPI_CA_DEBUGGER 5391116Smsmith ACPI_MODULE_NAME ("dbexec") 5467754Smsmith 5567754Smsmith 56222544Sjkimstatic ACPI_DB_METHOD_INFO AcpiGbl_DbMethodInfo; 57222544Sjkim#define DB_DEFAULT_PKG_ELEMENTS 33 5867754Smsmith 59151937Sjkim/* Local prototypes */ 6067754Smsmith 61151937Sjkimstatic ACPI_STATUS 62151937SjkimAcpiDbExecuteMethod ( 63151937Sjkim ACPI_DB_METHOD_INFO *Info, 64151937Sjkim ACPI_BUFFER *ReturnObj); 65151937Sjkim 66151937Sjkimstatic void 67151937SjkimAcpiDbExecuteSetup ( 68151937Sjkim ACPI_DB_METHOD_INFO *Info); 69151937Sjkim 70151937Sjkimstatic UINT32 71151937SjkimAcpiDbGetOutstandingAllocations ( 72151937Sjkim void); 73151937Sjkim 74151937Sjkimstatic void ACPI_SYSTEM_XFACE 75151937SjkimAcpiDbMethodThread ( 76151937Sjkim void *Context); 77151937Sjkim 78151937Sjkimstatic ACPI_STATUS 79151937SjkimAcpiDbExecutionWalk ( 80151937Sjkim ACPI_HANDLE ObjHandle, 81151937Sjkim UINT32 NestingLevel, 82151937Sjkim void *Context, 83151937Sjkim void **ReturnValue); 84151937Sjkim 85222544Sjkimstatic ACPI_STATUS 86222544SjkimAcpiDbHexCharToValue ( 87222544Sjkim int HexChar, 88222544Sjkim UINT8 *ReturnValue); 89151937Sjkim 90222544Sjkimstatic ACPI_STATUS 91222544SjkimAcpiDbConvertToPackage ( 92222544Sjkim char *String, 93222544Sjkim ACPI_OBJECT *Object); 94222544Sjkim 95222544Sjkimstatic ACPI_STATUS 96222544SjkimAcpiDbConvertToObject ( 97222544Sjkim ACPI_OBJECT_TYPE Type, 98222544Sjkim char *String, 99222544Sjkim ACPI_OBJECT *Object); 100222544Sjkim 101222544Sjkimstatic void 102222544SjkimAcpiDbDeleteObjects ( 103222544Sjkim UINT32 Count, 104222544Sjkim ACPI_OBJECT *Objects); 105222544Sjkim 106222544Sjkim 10767754Smsmith/******************************************************************************* 10867754Smsmith * 109222544Sjkim * FUNCTION: AcpiDbHexCharToValue 110222544Sjkim * 111222544Sjkim * PARAMETERS: HexChar - Ascii Hex digit, 0-9|a-f|A-F 112222544Sjkim * ReturnValue - Where the converted value is returned 113222544Sjkim * 114222544Sjkim * RETURN: Status 115222544Sjkim * 116222544Sjkim * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16). 117222544Sjkim * 118222544Sjkim ******************************************************************************/ 119222544Sjkim 120222544Sjkimstatic ACPI_STATUS 121222544SjkimAcpiDbHexCharToValue ( 122222544Sjkim int HexChar, 123222544Sjkim UINT8 *ReturnValue) 124222544Sjkim{ 125222544Sjkim UINT8 Value; 126222544Sjkim 127222544Sjkim 128222544Sjkim /* Digit must be ascii [0-9a-fA-F] */ 129222544Sjkim 130222544Sjkim if (!ACPI_IS_XDIGIT (HexChar)) 131222544Sjkim { 132222544Sjkim return (AE_BAD_HEX_CONSTANT); 133222544Sjkim } 134222544Sjkim 135222544Sjkim if (HexChar <= 0x39) 136222544Sjkim { 137222544Sjkim Value = (UINT8) (HexChar - 0x30); 138222544Sjkim } 139222544Sjkim else 140222544Sjkim { 141222544Sjkim Value = (UINT8) (ACPI_TOUPPER (HexChar) - 0x37); 142222544Sjkim } 143222544Sjkim 144222544Sjkim *ReturnValue = Value; 145222544Sjkim return (AE_OK); 146222544Sjkim} 147222544Sjkim 148222544Sjkim 149222544Sjkim/******************************************************************************* 150222544Sjkim * 151222544Sjkim * FUNCTION: AcpiDbHexByteToBinary 152222544Sjkim * 153222544Sjkim * PARAMETERS: HexByte - Double hex digit (0x00 - 0xFF) in format: 154222544Sjkim * HiByte then LoByte. 155222544Sjkim * ReturnValue - Where the converted value is returned 156222544Sjkim * 157222544Sjkim * RETURN: Status 158222544Sjkim * 159222544Sjkim * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255). 160222544Sjkim * 161222544Sjkim ******************************************************************************/ 162222544Sjkim 163222544Sjkimstatic ACPI_STATUS 164222544SjkimAcpiDbHexByteToBinary ( 165222544Sjkim char *HexByte, 166222544Sjkim UINT8 *ReturnValue) 167222544Sjkim{ 168222544Sjkim UINT8 Local0; 169222544Sjkim UINT8 Local1; 170222544Sjkim ACPI_STATUS Status; 171222544Sjkim 172222544Sjkim 173222544Sjkim /* High byte */ 174222544Sjkim 175222544Sjkim Status = AcpiDbHexCharToValue (HexByte[0], &Local0); 176222544Sjkim if (ACPI_FAILURE (Status)) 177222544Sjkim { 178222544Sjkim return (Status); 179222544Sjkim } 180222544Sjkim 181222544Sjkim /* Low byte */ 182222544Sjkim 183222544Sjkim Status = AcpiDbHexCharToValue (HexByte[1], &Local1); 184222544Sjkim if (ACPI_FAILURE (Status)) 185222544Sjkim { 186222544Sjkim return (Status); 187222544Sjkim } 188222544Sjkim 189222544Sjkim *ReturnValue = (UINT8) ((Local0 << 4) | Local1); 190222544Sjkim return (AE_OK); 191222544Sjkim} 192222544Sjkim 193222544Sjkim 194222544Sjkim/******************************************************************************* 195222544Sjkim * 196222544Sjkim * FUNCTION: AcpiDbConvertToBuffer 197222544Sjkim * 198222544Sjkim * PARAMETERS: String - Input string to be converted 199222544Sjkim * Object - Where the buffer object is returned 200222544Sjkim * 201222544Sjkim * RETURN: Status 202222544Sjkim * 203222544Sjkim * DESCRIPTION: Convert a string to a buffer object. String is treated a list 204222544Sjkim * of buffer elements, each separated by a space or comma. 205222544Sjkim * 206222544Sjkim ******************************************************************************/ 207222544Sjkim 208222544Sjkimstatic ACPI_STATUS 209222544SjkimAcpiDbConvertToBuffer ( 210222544Sjkim char *String, 211222544Sjkim ACPI_OBJECT *Object) 212222544Sjkim{ 213222544Sjkim UINT32 i; 214222544Sjkim UINT32 j; 215222544Sjkim UINT32 Length; 216222544Sjkim UINT8 *Buffer; 217222544Sjkim ACPI_STATUS Status; 218222544Sjkim 219222544Sjkim 220222544Sjkim /* Generate the final buffer length */ 221222544Sjkim 222222544Sjkim for (i = 0, Length = 0; String[i];) 223222544Sjkim { 224222544Sjkim i+=2; 225222544Sjkim Length++; 226222544Sjkim 227222544Sjkim while (String[i] && 228222544Sjkim ((String[i] == ',') || (String[i] == ' '))) 229222544Sjkim { 230222544Sjkim i++; 231222544Sjkim } 232222544Sjkim } 233222544Sjkim 234222544Sjkim Buffer = ACPI_ALLOCATE (Length); 235222544Sjkim if (!Buffer) 236222544Sjkim { 237222544Sjkim return (AE_NO_MEMORY); 238222544Sjkim } 239222544Sjkim 240222544Sjkim /* Convert the command line bytes to the buffer */ 241222544Sjkim 242222544Sjkim for (i = 0, j = 0; String[i];) 243222544Sjkim { 244222544Sjkim Status = AcpiDbHexByteToBinary (&String[i], &Buffer[j]); 245222544Sjkim if (ACPI_FAILURE (Status)) 246222544Sjkim { 247222544Sjkim ACPI_FREE (Buffer); 248222544Sjkim return (Status); 249222544Sjkim } 250222544Sjkim 251222544Sjkim j++; 252222544Sjkim i+=2; 253222544Sjkim while (String[i] && 254222544Sjkim ((String[i] == ',') || (String[i] == ' '))) 255222544Sjkim { 256222544Sjkim i++; 257222544Sjkim } 258222544Sjkim } 259222544Sjkim 260222544Sjkim Object->Type = ACPI_TYPE_BUFFER; 261222544Sjkim Object->Buffer.Pointer = Buffer; 262222544Sjkim Object->Buffer.Length = Length; 263222544Sjkim return (AE_OK); 264222544Sjkim} 265222544Sjkim 266222544Sjkim 267222544Sjkim/******************************************************************************* 268222544Sjkim * 269222544Sjkim * FUNCTION: AcpiDbConvertToPackage 270222544Sjkim * 271222544Sjkim * PARAMETERS: String - Input string to be converted 272222544Sjkim * Object - Where the package object is returned 273222544Sjkim * 274222544Sjkim * RETURN: Status 275222544Sjkim * 276222544Sjkim * DESCRIPTION: Convert a string to a package object. Handles nested packages 277222544Sjkim * via recursion with AcpiDbConvertToObject. 278222544Sjkim * 279222544Sjkim ******************************************************************************/ 280222544Sjkim 281222544Sjkimstatic ACPI_STATUS 282222544SjkimAcpiDbConvertToPackage ( 283222544Sjkim char *String, 284222544Sjkim ACPI_OBJECT *Object) 285222544Sjkim{ 286222544Sjkim char *This; 287222544Sjkim char *Next; 288222544Sjkim UINT32 i; 289222544Sjkim ACPI_OBJECT_TYPE Type; 290222544Sjkim ACPI_OBJECT *Elements; 291222544Sjkim ACPI_STATUS Status; 292222544Sjkim 293222544Sjkim 294222544Sjkim Elements = ACPI_ALLOCATE_ZEROED ( 295222544Sjkim DB_DEFAULT_PKG_ELEMENTS * sizeof (ACPI_OBJECT)); 296222544Sjkim 297222544Sjkim This = String; 298222544Sjkim for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) 299222544Sjkim { 300222544Sjkim This = AcpiDbGetNextToken (This, &Next, &Type); 301222544Sjkim if (!This) 302222544Sjkim { 303222544Sjkim break; 304222544Sjkim } 305222544Sjkim 306222544Sjkim /* Recursive call to convert each package element */ 307222544Sjkim 308222544Sjkim Status = AcpiDbConvertToObject (Type, This, &Elements[i]); 309222544Sjkim if (ACPI_FAILURE (Status)) 310222544Sjkim { 311222544Sjkim AcpiDbDeleteObjects (i + 1, Elements); 312222544Sjkim ACPI_FREE (Elements); 313222544Sjkim return (Status); 314222544Sjkim } 315222544Sjkim 316222544Sjkim This = Next; 317222544Sjkim } 318222544Sjkim 319222544Sjkim Object->Type = ACPI_TYPE_PACKAGE; 320222544Sjkim Object->Package.Count = i; 321222544Sjkim Object->Package.Elements = Elements; 322222544Sjkim return (AE_OK); 323222544Sjkim} 324222544Sjkim 325222544Sjkim 326222544Sjkim/******************************************************************************* 327222544Sjkim * 328222544Sjkim * FUNCTION: AcpiDbConvertToObject 329222544Sjkim * 330222544Sjkim * PARAMETERS: Type - Object type as determined by parser 331222544Sjkim * String - Input string to be converted 332222544Sjkim * Object - Where the new object is returned 333222544Sjkim * 334222544Sjkim * RETURN: Status 335222544Sjkim * 336222544Sjkim * DESCRIPTION: Convert a typed and tokenized string to an ACPI_OBJECT. Typing: 337222544Sjkim * 1) String objects were surrounded by quotes. 338222544Sjkim * 2) Buffer objects were surrounded by parentheses. 339222544Sjkim * 3) Package objects were surrounded by brackets "[]". 340222544Sjkim * 4) All standalone tokens are treated as integers. 341222544Sjkim * 342222544Sjkim ******************************************************************************/ 343222544Sjkim 344222544Sjkimstatic ACPI_STATUS 345222544SjkimAcpiDbConvertToObject ( 346222544Sjkim ACPI_OBJECT_TYPE Type, 347222544Sjkim char *String, 348222544Sjkim ACPI_OBJECT *Object) 349222544Sjkim{ 350222544Sjkim ACPI_STATUS Status = AE_OK; 351222544Sjkim 352222544Sjkim 353222544Sjkim switch (Type) 354222544Sjkim { 355222544Sjkim case ACPI_TYPE_STRING: 356222544Sjkim Object->Type = ACPI_TYPE_STRING; 357222544Sjkim Object->String.Pointer = String; 358222544Sjkim Object->String.Length = (UINT32) ACPI_STRLEN (String); 359222544Sjkim break; 360222544Sjkim 361222544Sjkim case ACPI_TYPE_BUFFER: 362222544Sjkim Status = AcpiDbConvertToBuffer (String, Object); 363222544Sjkim break; 364222544Sjkim 365222544Sjkim case ACPI_TYPE_PACKAGE: 366222544Sjkim Status = AcpiDbConvertToPackage (String, Object); 367222544Sjkim break; 368222544Sjkim 369222544Sjkim default: 370222544Sjkim Object->Type = ACPI_TYPE_INTEGER; 371222544Sjkim Status = AcpiUtStrtoul64 (String, 16, &Object->Integer.Value); 372222544Sjkim break; 373222544Sjkim } 374222544Sjkim 375222544Sjkim return (Status); 376222544Sjkim} 377222544Sjkim 378222544Sjkim 379222544Sjkim/******************************************************************************* 380222544Sjkim * 381222544Sjkim * FUNCTION: AcpiDbDeleteObjects 382222544Sjkim * 383222544Sjkim * PARAMETERS: Count - Count of objects in the list 384222544Sjkim * Objects - Array of ACPI_OBJECTs to be deleted 385222544Sjkim * 386222544Sjkim * RETURN: None 387222544Sjkim * 388222544Sjkim * DESCRIPTION: Delete a list of ACPI_OBJECTS. Handles packages and nested 389222544Sjkim * packages via recursion. 390222544Sjkim * 391222544Sjkim ******************************************************************************/ 392222544Sjkim 393222544Sjkimstatic void 394222544SjkimAcpiDbDeleteObjects ( 395222544Sjkim UINT32 Count, 396222544Sjkim ACPI_OBJECT *Objects) 397222544Sjkim{ 398222544Sjkim UINT32 i; 399222544Sjkim 400222544Sjkim 401222544Sjkim for (i = 0; i < Count; i++) 402222544Sjkim { 403222544Sjkim switch (Objects[i].Type) 404222544Sjkim { 405222544Sjkim case ACPI_TYPE_BUFFER: 406222544Sjkim ACPI_FREE (Objects[i].Buffer.Pointer); 407222544Sjkim break; 408222544Sjkim 409222544Sjkim case ACPI_TYPE_PACKAGE: 410222544Sjkim 411222544Sjkim /* Recursive call to delete package elements */ 412222544Sjkim 413222544Sjkim AcpiDbDeleteObjects (Objects[i].Package.Count, 414222544Sjkim Objects[i].Package.Elements); 415222544Sjkim 416222544Sjkim /* Free the elements array */ 417222544Sjkim 418222544Sjkim ACPI_FREE (Objects[i].Package.Elements); 419222544Sjkim break; 420222544Sjkim 421222544Sjkim default: 422222544Sjkim break; 423222544Sjkim } 424222544Sjkim } 425222544Sjkim} 426222544Sjkim 427222544Sjkim 428222544Sjkim/******************************************************************************* 429222544Sjkim * 43067754Smsmith * FUNCTION: AcpiDbExecuteMethod 43167754Smsmith * 43267754Smsmith * PARAMETERS: Info - Valid info segment 43367754Smsmith * ReturnObj - Where to put return object 43467754Smsmith * 43567754Smsmith * RETURN: Status 43667754Smsmith * 43767754Smsmith * DESCRIPTION: Execute a control method. 43867754Smsmith * 43967754Smsmith ******************************************************************************/ 44067754Smsmith 441151937Sjkimstatic ACPI_STATUS 44267754SmsmithAcpiDbExecuteMethod ( 44391116Smsmith ACPI_DB_METHOD_INFO *Info, 44467754Smsmith ACPI_BUFFER *ReturnObj) 44567754Smsmith{ 44667754Smsmith ACPI_STATUS Status; 44767754Smsmith ACPI_OBJECT_LIST ParamObjects; 448114237Snjl ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; 449193267Sjkim ACPI_HANDLE Handle; 450222544Sjkim ACPI_DEVICE_INFO *ObjInfo; 45167754Smsmith UINT32 i; 45267754Smsmith 45367754Smsmith 454216471Sjkim ACPI_FUNCTION_TRACE (DbExecuteMethod); 455216471Sjkim 456216471Sjkim 45783174Smsmith if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel) 45867754Smsmith { 45967754Smsmith AcpiOsPrintf ("Warning: debug output is not enabled!\n"); 46067754Smsmith } 46167754Smsmith 462193267Sjkim /* Get the NS node, determines existence also */ 46367754Smsmith 464193267Sjkim Status = AcpiGetHandle (NULL, Info->Pathname, &Handle); 465193267Sjkim if (ACPI_FAILURE (Status)) 46667754Smsmith { 467216471Sjkim return_ACPI_STATUS (Status); 468193267Sjkim } 46967754Smsmith 470193267Sjkim /* Get the object info for number of method parameters */ 471193267Sjkim 472197104Sjkim Status = AcpiGetObjectInfo (Handle, &ObjInfo); 473193267Sjkim if (ACPI_FAILURE (Status)) 474193267Sjkim { 475216471Sjkim return_ACPI_STATUS (Status); 47667754Smsmith } 477193267Sjkim 478193267Sjkim ParamObjects.Pointer = NULL; 479193267Sjkim ParamObjects.Count = 0; 480193267Sjkim 481193267Sjkim if (ObjInfo->Type == ACPI_TYPE_METHOD) 48267754Smsmith { 483193267Sjkim /* Are there arguments to the method? */ 48467754Smsmith 485222544Sjkim i = 0; 486193267Sjkim if (Info->Args && Info->Args[0]) 487193267Sjkim { 488222544Sjkim /* Get arguments passed on the command line */ 489222544Sjkim 490222544Sjkim for (; Info->Args[i] && 491217365Sjkim (i < ACPI_METHOD_NUM_ARGS) && 492217365Sjkim (i < ObjInfo->ParamCount); 493217365Sjkim i++) 494193267Sjkim { 495222544Sjkim /* Convert input string (token) to an actual ACPI_OBJECT */ 496222544Sjkim 497222544Sjkim Status = AcpiDbConvertToObject (Info->Types[i], 498222544Sjkim Info->Args[i], &Params[i]); 499222544Sjkim if (ACPI_FAILURE (Status)) 500222544Sjkim { 501222544Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 502222544Sjkim "While parsing method arguments")); 503222544Sjkim goto Cleanup; 504222544Sjkim } 505193267Sjkim } 506222544Sjkim } 50767754Smsmith 508222544Sjkim /* Create additional "default" parameters as needed */ 509222544Sjkim 510222544Sjkim if (i < ObjInfo->ParamCount) 511193267Sjkim { 512222544Sjkim AcpiOsPrintf ("Adding %u arguments containing default values\n", 513222544Sjkim ObjInfo->ParamCount - i); 51467754Smsmith 515222544Sjkim for (; i < ObjInfo->ParamCount; i++) 516193267Sjkim { 517193267Sjkim switch (i) 518193267Sjkim { 519193267Sjkim case 0: 520193267Sjkim 521193267Sjkim Params[0].Type = ACPI_TYPE_INTEGER; 522193267Sjkim Params[0].Integer.Value = 0x01020304; 523193267Sjkim break; 524193267Sjkim 525193267Sjkim case 1: 526193267Sjkim 527193267Sjkim Params[1].Type = ACPI_TYPE_STRING; 528193267Sjkim Params[1].String.Length = 12; 529193267Sjkim Params[1].String.Pointer = "AML Debugger"; 530193267Sjkim break; 531193267Sjkim 532193267Sjkim default: 533193267Sjkim 534193267Sjkim Params[i].Type = ACPI_TYPE_INTEGER; 535202771Sjkim Params[i].Integer.Value = i * (UINT64) 0x1000; 536193267Sjkim break; 537193267Sjkim } 538193267Sjkim } 539222544Sjkim } 540193267Sjkim 541222544Sjkim ParamObjects.Count = ObjInfo->ParamCount; 542222544Sjkim ParamObjects.Pointer = Params; 54367754Smsmith } 54467754Smsmith 54567754Smsmith /* Prepare for a return object of arbitrary size */ 54667754Smsmith 547151937Sjkim ReturnObj->Pointer = AcpiGbl_DbBuffer; 548151937Sjkim ReturnObj->Length = ACPI_DEBUG_BUFFER_SIZE; 54967754Smsmith 55067754Smsmith /* Do the actual method execution */ 55167754Smsmith 552114237Snjl AcpiGbl_MethodExecuting = TRUE; 553151937Sjkim Status = AcpiEvaluateObject (NULL, 554222544Sjkim Info->Pathname, &ParamObjects, ReturnObj); 55567754Smsmith 55667754Smsmith AcpiGbl_CmSingleStep = FALSE; 55767754Smsmith AcpiGbl_MethodExecuting = FALSE; 55867754Smsmith 559216471Sjkim if (ACPI_FAILURE (Status)) 560216471Sjkim { 561216471Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 562222544Sjkim "while executing %s from debugger", Info->Pathname)); 563216471Sjkim 564216471Sjkim if (Status == AE_BUFFER_OVERFLOW) 565216471Sjkim { 566216471Sjkim ACPI_ERROR ((AE_INFO, 567222544Sjkim "Possible overflow of internal debugger buffer (size 0x%X needed 0x%X)", 568216471Sjkim ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length)); 569216471Sjkim } 570216471Sjkim } 571216471Sjkim 572222544SjkimCleanup: 573222544Sjkim AcpiDbDeleteObjects (ObjInfo->ParamCount, Params); 574222544Sjkim ACPI_FREE (ObjInfo); 575222544Sjkim 576216471Sjkim return_ACPI_STATUS (Status); 57767754Smsmith} 57867754Smsmith 57967754Smsmith 58067754Smsmith/******************************************************************************* 58167754Smsmith * 58267754Smsmith * FUNCTION: AcpiDbExecuteSetup 58367754Smsmith * 58467754Smsmith * PARAMETERS: Info - Valid method info 58567754Smsmith * 586151937Sjkim * RETURN: None 58767754Smsmith * 58867754Smsmith * DESCRIPTION: Setup info segment prior to method execution 58967754Smsmith * 59067754Smsmith ******************************************************************************/ 59167754Smsmith 592151937Sjkimstatic void 59367754SmsmithAcpiDbExecuteSetup ( 59499679Siwasaki ACPI_DB_METHOD_INFO *Info) 59567754Smsmith{ 59667754Smsmith 59767754Smsmith /* Catenate the current scope to the supplied name */ 59867754Smsmith 59967754Smsmith Info->Pathname[0] = 0; 60067754Smsmith if ((Info->Name[0] != '\\') && 60167754Smsmith (Info->Name[0] != '/')) 60267754Smsmith { 60391116Smsmith ACPI_STRCAT (Info->Pathname, AcpiGbl_DbScopeBuf); 60467754Smsmith } 60567754Smsmith 60691116Smsmith ACPI_STRCAT (Info->Pathname, Info->Name); 60767754Smsmith AcpiDbPrepNamestring (Info->Pathname); 60867754Smsmith 60991116Smsmith AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 61067754Smsmith AcpiOsPrintf ("Executing %s\n", Info->Pathname); 61167754Smsmith 61267754Smsmith if (Info->Flags & EX_SINGLE_STEP) 61367754Smsmith { 61467754Smsmith AcpiGbl_CmSingleStep = TRUE; 61591116Smsmith AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 61667754Smsmith } 61767754Smsmith 61867754Smsmith else 61967754Smsmith { 62067754Smsmith /* No single step, allow redirection to a file */ 62167754Smsmith 62291116Smsmith AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 62367754Smsmith } 62467754Smsmith} 62567754Smsmith 62667754Smsmith 627151937Sjkim#ifdef ACPI_DBG_TRACK_ALLOCATIONS 628167802SjkimUINT32 629151937SjkimAcpiDbGetCacheInfo ( 630151937Sjkim ACPI_MEMORY_LIST *Cache) 631151937Sjkim{ 632151937Sjkim 633151937Sjkim return (Cache->TotalAllocated - Cache->TotalFreed - Cache->CurrentDepth); 634151937Sjkim} 635151937Sjkim#endif 636151937Sjkim 63767754Smsmith/******************************************************************************* 63867754Smsmith * 63982367Smsmith * FUNCTION: AcpiDbGetOutstandingAllocations 64082367Smsmith * 64182367Smsmith * PARAMETERS: None 64282367Smsmith * 64382367Smsmith * RETURN: Current global allocation count minus cache entries 64482367Smsmith * 64582367Smsmith * DESCRIPTION: Determine the current number of "outstanding" allocations -- 64682367Smsmith * those allocations that have not been freed and also are not 64782367Smsmith * in one of the various object caches. 64882367Smsmith * 64982367Smsmith ******************************************************************************/ 65082367Smsmith 651151937Sjkimstatic UINT32 65299679SiwasakiAcpiDbGetOutstandingAllocations ( 65399679Siwasaki void) 65482367Smsmith{ 65582367Smsmith UINT32 Outstanding = 0; 65682367Smsmith 65782367Smsmith#ifdef ACPI_DBG_TRACK_ALLOCATIONS 65882367Smsmith 659151937Sjkim Outstanding += AcpiDbGetCacheInfo (AcpiGbl_StateCache); 660151937Sjkim Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeCache); 661151937Sjkim Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeExtCache); 662151937Sjkim Outstanding += AcpiDbGetCacheInfo (AcpiGbl_OperandCache); 66382367Smsmith#endif 66482367Smsmith 66582367Smsmith return (Outstanding); 66682367Smsmith} 66782367Smsmith 66882367Smsmith 66982367Smsmith/******************************************************************************* 67082367Smsmith * 671114237Snjl * FUNCTION: AcpiDbExecutionWalk 672114237Snjl * 673114237Snjl * PARAMETERS: WALK_CALLBACK 674114237Snjl * 675114237Snjl * RETURN: Status 676114237Snjl * 677114237Snjl * DESCRIPTION: Execute a control method. Name is relative to the current 678114237Snjl * scope. 679114237Snjl * 680114237Snjl ******************************************************************************/ 681114237Snjl 682151937Sjkimstatic ACPI_STATUS 683114237SnjlAcpiDbExecutionWalk ( 684114237Snjl ACPI_HANDLE ObjHandle, 685114237Snjl UINT32 NestingLevel, 686114237Snjl void *Context, 687114237Snjl void **ReturnValue) 688114237Snjl{ 689114237Snjl ACPI_OPERAND_OBJECT *ObjDesc; 690114237Snjl ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 691114237Snjl ACPI_BUFFER ReturnObj; 692114237Snjl ACPI_STATUS Status; 693114237Snjl 694114237Snjl 695114237Snjl ObjDesc = AcpiNsGetAttachedObject (Node); 696114237Snjl if (ObjDesc->Method.ParamCount) 697114237Snjl { 698114237Snjl return (AE_OK); 699114237Snjl } 700114237Snjl 701114237Snjl ReturnObj.Pointer = NULL; 702114237Snjl ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 703114237Snjl 704114237Snjl AcpiNsPrintNodePathname (Node, "Execute"); 705114237Snjl 706114237Snjl /* Do the actual method execution */ 707114237Snjl 708114237Snjl AcpiOsPrintf ("\n"); 709114237Snjl AcpiGbl_MethodExecuting = TRUE; 710114237Snjl 711114237Snjl Status = AcpiEvaluateObject (Node, NULL, NULL, &ReturnObj); 712114237Snjl 713123315Snjl AcpiOsPrintf ("[%4.4s] returned %s\n", AcpiUtGetNodeName (Node), 714123315Snjl AcpiFormatException (Status)); 715114237Snjl AcpiGbl_MethodExecuting = FALSE; 716114237Snjl 717114237Snjl return (AE_OK); 718114237Snjl} 719114237Snjl 720114237Snjl 721114237Snjl/******************************************************************************* 722114237Snjl * 72367754Smsmith * FUNCTION: AcpiDbExecute 72467754Smsmith * 72567754Smsmith * PARAMETERS: Name - Name of method to execute 72667754Smsmith * Args - Parameters to the method 72767754Smsmith * Flags - single step/no single step 72867754Smsmith * 729151937Sjkim * RETURN: None 73067754Smsmith * 73167754Smsmith * DESCRIPTION: Execute a control method. Name is relative to the current 73267754Smsmith * scope. 73367754Smsmith * 73467754Smsmith ******************************************************************************/ 73567754Smsmith 73667754Smsmithvoid 73767754SmsmithAcpiDbExecute ( 738114237Snjl char *Name, 739114237Snjl char **Args, 740222544Sjkim ACPI_OBJECT_TYPE *Types, 74167754Smsmith UINT32 Flags) 74267754Smsmith{ 74367754Smsmith ACPI_STATUS Status; 74469450Smsmith ACPI_BUFFER ReturnObj; 745167802Sjkim char *NameString; 74669450Smsmith 74769450Smsmith 748102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT 74967754Smsmith UINT32 PreviousAllocations; 75067754Smsmith UINT32 Allocations; 75167754Smsmith 75267754Smsmith 75367754Smsmith /* Memory allocation tracking */ 75467754Smsmith 75582367Smsmith PreviousAllocations = AcpiDbGetOutstandingAllocations (); 75669450Smsmith#endif 75767754Smsmith 758114237Snjl if (*Name == '*') 759114237Snjl { 760151937Sjkim (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT, 761199337Sjkim ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL); 762114237Snjl return; 763114237Snjl } 764114237Snjl else 765114237Snjl { 766167802Sjkim NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1); 767167802Sjkim if (!NameString) 768167802Sjkim { 769167802Sjkim return; 770167802Sjkim } 771167802Sjkim 772167802Sjkim ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); 773167802Sjkim 774167802Sjkim ACPI_STRCPY (NameString, Name); 775167802Sjkim AcpiUtStrupr (NameString); 776167802Sjkim AcpiGbl_DbMethodInfo.Name = NameString; 777114237Snjl AcpiGbl_DbMethodInfo.Args = Args; 778222544Sjkim AcpiGbl_DbMethodInfo.Types = Types; 779114237Snjl AcpiGbl_DbMethodInfo.Flags = Flags; 78067754Smsmith 781114237Snjl ReturnObj.Pointer = NULL; 782114237Snjl ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 783100966Siwasaki 784114237Snjl AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 785114237Snjl Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj); 786167802Sjkim ACPI_FREE (NameString); 787114237Snjl } 78867754Smsmith 78982367Smsmith /* 79082367Smsmith * Allow any handlers in separate threads to complete. 79182367Smsmith * (Such as Notify handlers invoked from AML executed above). 79282367Smsmith */ 793202771Sjkim AcpiOsSleep ((UINT64) 10); 79467754Smsmith 79582367Smsmith 796102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT 79769450Smsmith 79867754Smsmith /* Memory allocation tracking */ 79967754Smsmith 80082367Smsmith Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations; 80167754Smsmith 80291116Smsmith AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 80367754Smsmith 80467754Smsmith if (Allocations > 0) 80567754Smsmith { 806138287Smarks AcpiOsPrintf ("Outstanding: 0x%X allocations after execution\n", 80782367Smsmith Allocations); 80867754Smsmith } 80969450Smsmith#endif 81067754Smsmith 81167754Smsmith if (ACPI_FAILURE (Status)) 81267754Smsmith { 81383174Smsmith AcpiOsPrintf ("Execution of %s failed with status %s\n", 81483174Smsmith AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status)); 81567754Smsmith } 81667754Smsmith else 81767754Smsmith { 81867754Smsmith /* Display a return object, if any */ 81967754Smsmith 82067754Smsmith if (ReturnObj.Length) 82167754Smsmith { 82277424Smsmith AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 823114237Snjl AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, 824104470Siwasaki (UINT32) ReturnObj.Length); 825151937Sjkim AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); 82667754Smsmith } 827100966Siwasaki else 828100966Siwasaki { 829102550Siwasaki AcpiOsPrintf ("No return object from execution of %s\n", 830100966Siwasaki AcpiGbl_DbMethodInfo.Pathname); 831100966Siwasaki } 83267754Smsmith } 83367754Smsmith 83491116Smsmith AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 83567754Smsmith} 83667754Smsmith 83767754Smsmith 83867754Smsmith/******************************************************************************* 83967754Smsmith * 84067754Smsmith * FUNCTION: AcpiDbMethodThread 84167754Smsmith * 84267754Smsmith * PARAMETERS: Context - Execution info segment 84367754Smsmith * 84467754Smsmith * RETURN: None 84567754Smsmith * 84667754Smsmith * DESCRIPTION: Debugger execute thread. Waits for a command line, then 84767754Smsmith * simply dispatches it. 84867754Smsmith * 84967754Smsmith ******************************************************************************/ 85067754Smsmith 851151937Sjkimstatic void ACPI_SYSTEM_XFACE 85267754SmsmithAcpiDbMethodThread ( 85367754Smsmith void *Context) 85467754Smsmith{ 85567754Smsmith ACPI_STATUS Status; 85691116Smsmith ACPI_DB_METHOD_INFO *Info = Context; 857193267Sjkim ACPI_DB_METHOD_INFO LocalInfo; 85867754Smsmith UINT32 i; 859167802Sjkim UINT8 Allow; 86067754Smsmith ACPI_BUFFER ReturnObj; 86167754Smsmith 86267754Smsmith 863193267Sjkim /* 864193267Sjkim * AcpiGbl_DbMethodInfo.Arguments will be passed as method arguments. 865193267Sjkim * Prevent AcpiGbl_DbMethodInfo from being modified by multiple threads 866193267Sjkim * concurrently. 867193267Sjkim * 868193267Sjkim * Note: The arguments we are passing are used by the ASL test suite 869193267Sjkim * (aslts). Do not change them without updating the tests. 870193267Sjkim */ 871193267Sjkim (void) AcpiOsWaitSemaphore (Info->InfoGate, 1, ACPI_WAIT_FOREVER); 872193267Sjkim 873167802Sjkim if (Info->InitArgs) 874167802Sjkim { 875167802Sjkim AcpiDbUInt32ToHexString (Info->NumCreated, Info->IndexOfThreadStr); 876212761Sjkim AcpiDbUInt32ToHexString ((UINT32) AcpiOsGetThreadId (), Info->IdOfThreadStr); 877167802Sjkim } 878167802Sjkim 879167802Sjkim if (Info->Threads && (Info->NumCreated < Info->NumThreads)) 880167802Sjkim { 881212761Sjkim Info->Threads[Info->NumCreated++] = AcpiOsGetThreadId(); 882167802Sjkim } 883167802Sjkim 884193267Sjkim LocalInfo = *Info; 885193267Sjkim LocalInfo.Args = LocalInfo.Arguments; 886193267Sjkim LocalInfo.Arguments[0] = LocalInfo.NumThreadsStr; 887193267Sjkim LocalInfo.Arguments[1] = LocalInfo.IdOfThreadStr; 888193267Sjkim LocalInfo.Arguments[2] = LocalInfo.IndexOfThreadStr; 889193267Sjkim LocalInfo.Arguments[3] = NULL; 890193267Sjkim 891222544Sjkim LocalInfo.Types = LocalInfo.ArgTypes; 892222544Sjkim 893193267Sjkim (void) AcpiOsSignalSemaphore (Info->InfoGate, 1); 894193267Sjkim 89567754Smsmith for (i = 0; i < Info->NumLoops; i++) 89667754Smsmith { 897193267Sjkim Status = AcpiDbExecuteMethod (&LocalInfo, &ReturnObj); 898117521Snjl if (ACPI_FAILURE (Status)) 89967754Smsmith { 900117521Snjl AcpiOsPrintf ("%s During execution of %s at iteration %X\n", 901117521Snjl AcpiFormatException (Status), Info->Pathname, i); 902127175Snjl if (Status == AE_ABORT_METHOD) 903127175Snjl { 904127175Snjl break; 905127175Snjl } 90667754Smsmith } 907117521Snjl 908167802Sjkim#if 0 909128212Snjl if ((i % 100) == 0) 910117521Snjl { 911209746Sjkim AcpiOsPrintf ("%u executions, Thread 0x%x\n", i, AcpiOsGetThreadId ()); 912117521Snjl } 913117521Snjl 914117521Snjl if (ReturnObj.Length) 915117521Snjl { 916117521Snjl AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 917117521Snjl Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length); 918151937Sjkim AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); 919117521Snjl } 920117521Snjl#endif 92167754Smsmith } 92267754Smsmith 92367754Smsmith /* Signal our completion */ 92467754Smsmith 925167802Sjkim Allow = 0; 926193267Sjkim (void) AcpiOsWaitSemaphore (Info->ThreadCompleteGate, 1, ACPI_WAIT_FOREVER); 927167802Sjkim Info->NumCompleted++; 928167802Sjkim 929167802Sjkim if (Info->NumCompleted == Info->NumThreads) 93099679Siwasaki { 931167802Sjkim /* Do signal for main thread once only */ 932167802Sjkim Allow = 1; 93399679Siwasaki } 934167802Sjkim 935193267Sjkim (void) AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1); 936167802Sjkim 937167802Sjkim if (Allow) 938167802Sjkim { 939167802Sjkim Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1); 940167802Sjkim if (ACPI_FAILURE (Status)) 941167802Sjkim { 942167802Sjkim AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n", 943167802Sjkim AcpiFormatException (Status)); 944167802Sjkim } 945167802Sjkim } 94667754Smsmith} 94767754Smsmith 94867754Smsmith 94967754Smsmith/******************************************************************************* 95067754Smsmith * 95167754Smsmith * FUNCTION: AcpiDbCreateExecutionThreads 95267754Smsmith * 95367754Smsmith * PARAMETERS: NumThreadsArg - Number of threads to create 95467754Smsmith * NumLoopsArg - Loop count for the thread(s) 95567754Smsmith * MethodNameArg - Control method to execute 95667754Smsmith * 95767754Smsmith * RETURN: None 95867754Smsmith * 95967754Smsmith * DESCRIPTION: Create threads to execute method(s) 96067754Smsmith * 96167754Smsmith ******************************************************************************/ 96267754Smsmith 96367754Smsmithvoid 96467754SmsmithAcpiDbCreateExecutionThreads ( 965114237Snjl char *NumThreadsArg, 966114237Snjl char *NumLoopsArg, 967114237Snjl char *MethodNameArg) 96867754Smsmith{ 96967754Smsmith ACPI_STATUS Status; 97067754Smsmith UINT32 NumThreads; 97167754Smsmith UINT32 NumLoops; 97267754Smsmith UINT32 i; 973167802Sjkim UINT32 Size; 974167802Sjkim ACPI_MUTEX MainThreadGate; 975167802Sjkim ACPI_MUTEX ThreadCompleteGate; 976193267Sjkim ACPI_MUTEX InfoGate; 97767754Smsmith 978193267Sjkim 97967754Smsmith /* Get the arguments */ 98067754Smsmith 98191116Smsmith NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0); 98291116Smsmith NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0); 98367754Smsmith 98467754Smsmith if (!NumThreads || !NumLoops) 98567754Smsmith { 986151937Sjkim AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", 987151937Sjkim NumThreads, NumLoops); 98867754Smsmith return; 98967754Smsmith } 99067754Smsmith 991167802Sjkim /* 992167802Sjkim * Create the semaphore for synchronization of 993167802Sjkim * the created threads with the main thread. 994167802Sjkim */ 995167802Sjkim Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate); 996167802Sjkim if (ACPI_FAILURE (Status)) 997167802Sjkim { 998167802Sjkim AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n", 999167802Sjkim AcpiFormatException (Status)); 1000167802Sjkim return; 1001167802Sjkim } 100267754Smsmith 1003167802Sjkim /* 1004167802Sjkim * Create the semaphore for synchronization 1005167802Sjkim * between the created threads. 1006167802Sjkim */ 1007167802Sjkim Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate); 100867754Smsmith if (ACPI_FAILURE (Status)) 100967754Smsmith { 1010167802Sjkim AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n", 1011151937Sjkim AcpiFormatException (Status)); 1012167802Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 101367754Smsmith return; 101467754Smsmith } 101567754Smsmith 1016193267Sjkim Status = AcpiOsCreateSemaphore (1, 1, &InfoGate); 1017193267Sjkim if (ACPI_FAILURE (Status)) 1018193267Sjkim { 1019193267Sjkim AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n", 1020193267Sjkim AcpiFormatException (Status)); 1021193267Sjkim (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 1022193267Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 1023193267Sjkim return; 1024193267Sjkim } 1025193267Sjkim 1026167802Sjkim ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); 1027167802Sjkim 1028167802Sjkim /* Array to store IDs of threads */ 1029167802Sjkim 1030167802Sjkim AcpiGbl_DbMethodInfo.NumThreads = NumThreads; 1031212761Sjkim Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads; 1032212761Sjkim AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size); 1033167802Sjkim if (AcpiGbl_DbMethodInfo.Threads == NULL) 1034167802Sjkim { 1035167802Sjkim AcpiOsPrintf ("No memory for thread IDs array\n"); 1036167802Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 1037167802Sjkim (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 1038193267Sjkim (void) AcpiOsDeleteSemaphore (InfoGate); 1039167802Sjkim return; 1040167802Sjkim } 1041167802Sjkim ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size); 1042167802Sjkim 104367754Smsmith /* Setup the context to be passed to each thread */ 104467754Smsmith 104583174Smsmith AcpiGbl_DbMethodInfo.Name = MethodNameArg; 104683174Smsmith AcpiGbl_DbMethodInfo.Flags = 0; 104783174Smsmith AcpiGbl_DbMethodInfo.NumLoops = NumLoops; 1048167802Sjkim AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate; 1049167802Sjkim AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate; 1050193267Sjkim AcpiGbl_DbMethodInfo.InfoGate = InfoGate; 105167754Smsmith 1052167802Sjkim /* Init arguments to be passed to method */ 1053167802Sjkim 1054167802Sjkim AcpiGbl_DbMethodInfo.InitArgs = 1; 1055167802Sjkim AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments; 1056167802Sjkim AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr; 1057167802Sjkim AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr; 1058167802Sjkim AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr; 1059167802Sjkim AcpiGbl_DbMethodInfo.Arguments[3] = NULL; 1060222544Sjkim 1061222544Sjkim AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes; 1062222544Sjkim AcpiGbl_DbMethodInfo.ArgTypes[0] = ACPI_TYPE_INTEGER; 1063222544Sjkim AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER; 1064222544Sjkim AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER; 1065222544Sjkim 1066167802Sjkim AcpiDbUInt32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr); 1067167802Sjkim 106883174Smsmith AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 106967754Smsmith 107067754Smsmith /* Create the threads */ 107167754Smsmith 1072151937Sjkim AcpiOsPrintf ("Creating %X threads to execute %X times each\n", 1073151937Sjkim NumThreads, NumLoops); 107467754Smsmith 107567754Smsmith for (i = 0; i < (NumThreads); i++) 107667754Smsmith { 1077167802Sjkim Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread, 1078151937Sjkim &AcpiGbl_DbMethodInfo); 107999679Siwasaki if (ACPI_FAILURE (Status)) 108099679Siwasaki { 108199679Siwasaki break; 108299679Siwasaki } 108367754Smsmith } 108467754Smsmith 108567754Smsmith /* Wait for all threads to complete */ 108667754Smsmith 1087193267Sjkim (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER); 108867754Smsmith 1089167802Sjkim AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 1090167802Sjkim AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); 1091167802Sjkim AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1092167802Sjkim 109367754Smsmith /* Cleanup and exit */ 109467754Smsmith 1095167802Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 1096167802Sjkim (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 1097193267Sjkim (void) AcpiOsDeleteSemaphore (InfoGate); 109867754Smsmith 1099167802Sjkim AcpiOsFree (AcpiGbl_DbMethodInfo.Threads); 1100167802Sjkim AcpiGbl_DbMethodInfo.Threads = NULL; 110167754Smsmith} 110267754Smsmith 1103102550Siwasaki#endif /* ACPI_DEBUGGER */ 110467754Smsmith 110567754Smsmith 1106