dbexec.c revision 239340
167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: dbexec - debugger control method execution 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8229989Sjkim * Copyright (C) 2000 - 2012, 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 107239340Sjkimstatic UINT8 * 108239340SjkimAcpiDbEncodePldBuffer ( 109239340Sjkim ACPI_PLD_INFO *PldInfo); 110239340Sjkim 111239340Sjkimstatic void 112239340SjkimAcpiDbDumpPldBuffer ( 113239340Sjkim ACPI_OBJECT *ObjDesc); 114239340Sjkim 115239340Sjkim 11667754Smsmith/******************************************************************************* 11767754Smsmith * 118222544Sjkim * FUNCTION: AcpiDbHexCharToValue 119222544Sjkim * 120222544Sjkim * PARAMETERS: HexChar - Ascii Hex digit, 0-9|a-f|A-F 121222544Sjkim * ReturnValue - Where the converted value is returned 122222544Sjkim * 123222544Sjkim * RETURN: Status 124222544Sjkim * 125222544Sjkim * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16). 126222544Sjkim * 127222544Sjkim ******************************************************************************/ 128222544Sjkim 129222544Sjkimstatic ACPI_STATUS 130222544SjkimAcpiDbHexCharToValue ( 131222544Sjkim int HexChar, 132222544Sjkim UINT8 *ReturnValue) 133222544Sjkim{ 134222544Sjkim UINT8 Value; 135222544Sjkim 136222544Sjkim 137222544Sjkim /* Digit must be ascii [0-9a-fA-F] */ 138222544Sjkim 139222544Sjkim if (!ACPI_IS_XDIGIT (HexChar)) 140222544Sjkim { 141222544Sjkim return (AE_BAD_HEX_CONSTANT); 142222544Sjkim } 143222544Sjkim 144222544Sjkim if (HexChar <= 0x39) 145222544Sjkim { 146222544Sjkim Value = (UINT8) (HexChar - 0x30); 147222544Sjkim } 148222544Sjkim else 149222544Sjkim { 150222544Sjkim Value = (UINT8) (ACPI_TOUPPER (HexChar) - 0x37); 151222544Sjkim } 152222544Sjkim 153222544Sjkim *ReturnValue = Value; 154222544Sjkim return (AE_OK); 155222544Sjkim} 156222544Sjkim 157222544Sjkim 158222544Sjkim/******************************************************************************* 159222544Sjkim * 160222544Sjkim * FUNCTION: AcpiDbHexByteToBinary 161222544Sjkim * 162222544Sjkim * PARAMETERS: HexByte - Double hex digit (0x00 - 0xFF) in format: 163222544Sjkim * HiByte then LoByte. 164222544Sjkim * ReturnValue - Where the converted value is returned 165222544Sjkim * 166222544Sjkim * RETURN: Status 167222544Sjkim * 168222544Sjkim * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255). 169222544Sjkim * 170222544Sjkim ******************************************************************************/ 171222544Sjkim 172222544Sjkimstatic ACPI_STATUS 173222544SjkimAcpiDbHexByteToBinary ( 174222544Sjkim char *HexByte, 175222544Sjkim UINT8 *ReturnValue) 176222544Sjkim{ 177222544Sjkim UINT8 Local0; 178222544Sjkim UINT8 Local1; 179222544Sjkim ACPI_STATUS Status; 180222544Sjkim 181222544Sjkim 182222544Sjkim /* High byte */ 183222544Sjkim 184222544Sjkim Status = AcpiDbHexCharToValue (HexByte[0], &Local0); 185222544Sjkim if (ACPI_FAILURE (Status)) 186222544Sjkim { 187222544Sjkim return (Status); 188222544Sjkim } 189222544Sjkim 190222544Sjkim /* Low byte */ 191222544Sjkim 192222544Sjkim Status = AcpiDbHexCharToValue (HexByte[1], &Local1); 193222544Sjkim if (ACPI_FAILURE (Status)) 194222544Sjkim { 195222544Sjkim return (Status); 196222544Sjkim } 197222544Sjkim 198222544Sjkim *ReturnValue = (UINT8) ((Local0 << 4) | Local1); 199222544Sjkim return (AE_OK); 200222544Sjkim} 201222544Sjkim 202222544Sjkim 203222544Sjkim/******************************************************************************* 204222544Sjkim * 205222544Sjkim * FUNCTION: AcpiDbConvertToBuffer 206222544Sjkim * 207222544Sjkim * PARAMETERS: String - Input string to be converted 208222544Sjkim * Object - Where the buffer object is returned 209222544Sjkim * 210222544Sjkim * RETURN: Status 211222544Sjkim * 212222544Sjkim * DESCRIPTION: Convert a string to a buffer object. String is treated a list 213222544Sjkim * of buffer elements, each separated by a space or comma. 214222544Sjkim * 215222544Sjkim ******************************************************************************/ 216222544Sjkim 217222544Sjkimstatic ACPI_STATUS 218222544SjkimAcpiDbConvertToBuffer ( 219222544Sjkim char *String, 220222544Sjkim ACPI_OBJECT *Object) 221222544Sjkim{ 222222544Sjkim UINT32 i; 223222544Sjkim UINT32 j; 224222544Sjkim UINT32 Length; 225222544Sjkim UINT8 *Buffer; 226222544Sjkim ACPI_STATUS Status; 227222544Sjkim 228222544Sjkim 229222544Sjkim /* Generate the final buffer length */ 230222544Sjkim 231222544Sjkim for (i = 0, Length = 0; String[i];) 232222544Sjkim { 233222544Sjkim i+=2; 234222544Sjkim Length++; 235222544Sjkim 236222544Sjkim while (String[i] && 237222544Sjkim ((String[i] == ',') || (String[i] == ' '))) 238222544Sjkim { 239222544Sjkim i++; 240222544Sjkim } 241222544Sjkim } 242222544Sjkim 243222544Sjkim Buffer = ACPI_ALLOCATE (Length); 244222544Sjkim if (!Buffer) 245222544Sjkim { 246222544Sjkim return (AE_NO_MEMORY); 247222544Sjkim } 248222544Sjkim 249222544Sjkim /* Convert the command line bytes to the buffer */ 250222544Sjkim 251222544Sjkim for (i = 0, j = 0; String[i];) 252222544Sjkim { 253222544Sjkim Status = AcpiDbHexByteToBinary (&String[i], &Buffer[j]); 254222544Sjkim if (ACPI_FAILURE (Status)) 255222544Sjkim { 256222544Sjkim ACPI_FREE (Buffer); 257222544Sjkim return (Status); 258222544Sjkim } 259222544Sjkim 260222544Sjkim j++; 261222544Sjkim i+=2; 262222544Sjkim while (String[i] && 263222544Sjkim ((String[i] == ',') || (String[i] == ' '))) 264222544Sjkim { 265222544Sjkim i++; 266222544Sjkim } 267222544Sjkim } 268222544Sjkim 269222544Sjkim Object->Type = ACPI_TYPE_BUFFER; 270222544Sjkim Object->Buffer.Pointer = Buffer; 271222544Sjkim Object->Buffer.Length = Length; 272222544Sjkim return (AE_OK); 273222544Sjkim} 274222544Sjkim 275222544Sjkim 276222544Sjkim/******************************************************************************* 277222544Sjkim * 278222544Sjkim * FUNCTION: AcpiDbConvertToPackage 279222544Sjkim * 280222544Sjkim * PARAMETERS: String - Input string to be converted 281222544Sjkim * Object - Where the package object is returned 282222544Sjkim * 283222544Sjkim * RETURN: Status 284222544Sjkim * 285222544Sjkim * DESCRIPTION: Convert a string to a package object. Handles nested packages 286222544Sjkim * via recursion with AcpiDbConvertToObject. 287222544Sjkim * 288222544Sjkim ******************************************************************************/ 289222544Sjkim 290222544Sjkimstatic ACPI_STATUS 291222544SjkimAcpiDbConvertToPackage ( 292222544Sjkim char *String, 293222544Sjkim ACPI_OBJECT *Object) 294222544Sjkim{ 295222544Sjkim char *This; 296222544Sjkim char *Next; 297222544Sjkim UINT32 i; 298222544Sjkim ACPI_OBJECT_TYPE Type; 299222544Sjkim ACPI_OBJECT *Elements; 300222544Sjkim ACPI_STATUS Status; 301222544Sjkim 302222544Sjkim 303222544Sjkim Elements = ACPI_ALLOCATE_ZEROED ( 304222544Sjkim DB_DEFAULT_PKG_ELEMENTS * sizeof (ACPI_OBJECT)); 305222544Sjkim 306222544Sjkim This = String; 307222544Sjkim for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) 308222544Sjkim { 309222544Sjkim This = AcpiDbGetNextToken (This, &Next, &Type); 310222544Sjkim if (!This) 311222544Sjkim { 312222544Sjkim break; 313222544Sjkim } 314222544Sjkim 315222544Sjkim /* Recursive call to convert each package element */ 316222544Sjkim 317222544Sjkim Status = AcpiDbConvertToObject (Type, This, &Elements[i]); 318222544Sjkim if (ACPI_FAILURE (Status)) 319222544Sjkim { 320222544Sjkim AcpiDbDeleteObjects (i + 1, Elements); 321222544Sjkim ACPI_FREE (Elements); 322222544Sjkim return (Status); 323222544Sjkim } 324222544Sjkim 325222544Sjkim This = Next; 326222544Sjkim } 327222544Sjkim 328222544Sjkim Object->Type = ACPI_TYPE_PACKAGE; 329222544Sjkim Object->Package.Count = i; 330222544Sjkim Object->Package.Elements = Elements; 331222544Sjkim return (AE_OK); 332222544Sjkim} 333222544Sjkim 334222544Sjkim 335222544Sjkim/******************************************************************************* 336222544Sjkim * 337222544Sjkim * FUNCTION: AcpiDbConvertToObject 338222544Sjkim * 339222544Sjkim * PARAMETERS: Type - Object type as determined by parser 340222544Sjkim * String - Input string to be converted 341222544Sjkim * Object - Where the new object is returned 342222544Sjkim * 343222544Sjkim * RETURN: Status 344222544Sjkim * 345222544Sjkim * DESCRIPTION: Convert a typed and tokenized string to an ACPI_OBJECT. Typing: 346222544Sjkim * 1) String objects were surrounded by quotes. 347222544Sjkim * 2) Buffer objects were surrounded by parentheses. 348222544Sjkim * 3) Package objects were surrounded by brackets "[]". 349222544Sjkim * 4) All standalone tokens are treated as integers. 350222544Sjkim * 351222544Sjkim ******************************************************************************/ 352222544Sjkim 353222544Sjkimstatic ACPI_STATUS 354222544SjkimAcpiDbConvertToObject ( 355222544Sjkim ACPI_OBJECT_TYPE Type, 356222544Sjkim char *String, 357222544Sjkim ACPI_OBJECT *Object) 358222544Sjkim{ 359222544Sjkim ACPI_STATUS Status = AE_OK; 360222544Sjkim 361222544Sjkim 362222544Sjkim switch (Type) 363222544Sjkim { 364222544Sjkim case ACPI_TYPE_STRING: 365222544Sjkim Object->Type = ACPI_TYPE_STRING; 366222544Sjkim Object->String.Pointer = String; 367222544Sjkim Object->String.Length = (UINT32) ACPI_STRLEN (String); 368222544Sjkim break; 369222544Sjkim 370222544Sjkim case ACPI_TYPE_BUFFER: 371222544Sjkim Status = AcpiDbConvertToBuffer (String, Object); 372222544Sjkim break; 373222544Sjkim 374222544Sjkim case ACPI_TYPE_PACKAGE: 375222544Sjkim Status = AcpiDbConvertToPackage (String, Object); 376222544Sjkim break; 377222544Sjkim 378222544Sjkim default: 379222544Sjkim Object->Type = ACPI_TYPE_INTEGER; 380222544Sjkim Status = AcpiUtStrtoul64 (String, 16, &Object->Integer.Value); 381222544Sjkim break; 382222544Sjkim } 383222544Sjkim 384222544Sjkim return (Status); 385222544Sjkim} 386222544Sjkim 387222544Sjkim 388222544Sjkim/******************************************************************************* 389222544Sjkim * 390222544Sjkim * FUNCTION: AcpiDbDeleteObjects 391222544Sjkim * 392222544Sjkim * PARAMETERS: Count - Count of objects in the list 393222544Sjkim * Objects - Array of ACPI_OBJECTs to be deleted 394222544Sjkim * 395222544Sjkim * RETURN: None 396222544Sjkim * 397222544Sjkim * DESCRIPTION: Delete a list of ACPI_OBJECTS. Handles packages and nested 398222544Sjkim * packages via recursion. 399222544Sjkim * 400222544Sjkim ******************************************************************************/ 401222544Sjkim 402222544Sjkimstatic void 403222544SjkimAcpiDbDeleteObjects ( 404222544Sjkim UINT32 Count, 405222544Sjkim ACPI_OBJECT *Objects) 406222544Sjkim{ 407222544Sjkim UINT32 i; 408222544Sjkim 409222544Sjkim 410222544Sjkim for (i = 0; i < Count; i++) 411222544Sjkim { 412222544Sjkim switch (Objects[i].Type) 413222544Sjkim { 414222544Sjkim case ACPI_TYPE_BUFFER: 415222544Sjkim ACPI_FREE (Objects[i].Buffer.Pointer); 416222544Sjkim break; 417222544Sjkim 418222544Sjkim case ACPI_TYPE_PACKAGE: 419222544Sjkim 420222544Sjkim /* Recursive call to delete package elements */ 421222544Sjkim 422222544Sjkim AcpiDbDeleteObjects (Objects[i].Package.Count, 423222544Sjkim Objects[i].Package.Elements); 424222544Sjkim 425222544Sjkim /* Free the elements array */ 426222544Sjkim 427222544Sjkim ACPI_FREE (Objects[i].Package.Elements); 428222544Sjkim break; 429222544Sjkim 430222544Sjkim default: 431222544Sjkim break; 432222544Sjkim } 433222544Sjkim } 434222544Sjkim} 435222544Sjkim 436222544Sjkim 437222544Sjkim/******************************************************************************* 438222544Sjkim * 43967754Smsmith * FUNCTION: AcpiDbExecuteMethod 44067754Smsmith * 44167754Smsmith * PARAMETERS: Info - Valid info segment 44267754Smsmith * ReturnObj - Where to put return object 44367754Smsmith * 44467754Smsmith * RETURN: Status 44567754Smsmith * 44667754Smsmith * DESCRIPTION: Execute a control method. 44767754Smsmith * 44867754Smsmith ******************************************************************************/ 44967754Smsmith 450151937Sjkimstatic ACPI_STATUS 45167754SmsmithAcpiDbExecuteMethod ( 45291116Smsmith ACPI_DB_METHOD_INFO *Info, 45367754Smsmith ACPI_BUFFER *ReturnObj) 45467754Smsmith{ 45567754Smsmith ACPI_STATUS Status; 45667754Smsmith ACPI_OBJECT_LIST ParamObjects; 457114237Snjl ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; 458222544Sjkim ACPI_DEVICE_INFO *ObjInfo; 45967754Smsmith UINT32 i; 46067754Smsmith 46167754Smsmith 462216471Sjkim ACPI_FUNCTION_TRACE (DbExecuteMethod); 463216471Sjkim 464216471Sjkim 46583174Smsmith if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel) 46667754Smsmith { 46767754Smsmith AcpiOsPrintf ("Warning: debug output is not enabled!\n"); 46867754Smsmith } 46967754Smsmith 470193267Sjkim /* Get the object info for number of method parameters */ 471193267Sjkim 472239340Sjkim Status = AcpiGetObjectInfo (Info->Method, &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 * 723239340Sjkim * FUNCTION: AcpiDbEncodePldBuffer 724239340Sjkim * 725239340Sjkim * PARAMETERS: PldInfo - _PLD buffer struct (Using local struct) 726239340Sjkim * 727239340Sjkim * RETURN: Encode _PLD buffer suitable for return value from _PLD 728239340Sjkim * 729239340Sjkim * DESCRIPTION: Bit-packs a _PLD buffer struct. Used to test the _PLD macros 730239340Sjkim * 731239340Sjkim ******************************************************************************/ 732239340Sjkim 733239340Sjkimstatic UINT8 * 734239340SjkimAcpiDbEncodePldBuffer ( 735239340Sjkim ACPI_PLD_INFO *PldInfo) 736239340Sjkim{ 737239340Sjkim UINT32 *Buffer; 738239340Sjkim UINT32 Dword; 739239340Sjkim 740239340Sjkim 741239340Sjkim Buffer = ACPI_ALLOCATE_ZEROED (ACPI_PLD_BUFFER_SIZE); 742239340Sjkim if (!Buffer) 743239340Sjkim { 744239340Sjkim return (NULL); 745239340Sjkim } 746239340Sjkim 747239340Sjkim /* First 32 bits */ 748239340Sjkim 749239340Sjkim Dword = 0; 750239340Sjkim ACPI_PLD_SET_REVISION (&Dword, PldInfo->Revision); 751239340Sjkim ACPI_PLD_SET_IGNORE_COLOR (&Dword, PldInfo->IgnoreColor); 752239340Sjkim ACPI_PLD_SET_COLOR (&Dword, PldInfo->Color); 753239340Sjkim ACPI_MOVE_32_TO_32 (&Buffer[0], &Dword); 754239340Sjkim 755239340Sjkim /* Second 32 bits */ 756239340Sjkim 757239340Sjkim Dword = 0; 758239340Sjkim ACPI_PLD_SET_WIDTH (&Dword, PldInfo->Width); 759239340Sjkim ACPI_PLD_SET_HEIGHT (&Dword, PldInfo->Height); 760239340Sjkim ACPI_MOVE_32_TO_32 (&Buffer[1], &Dword); 761239340Sjkim 762239340Sjkim /* Third 32 bits */ 763239340Sjkim 764239340Sjkim Dword = 0; 765239340Sjkim ACPI_PLD_SET_USER_VISIBLE (&Dword, PldInfo->UserVisible); 766239340Sjkim ACPI_PLD_SET_DOCK (&Dword, PldInfo->Dock); 767239340Sjkim ACPI_PLD_SET_LID (&Dword, PldInfo->Lid); 768239340Sjkim ACPI_PLD_SET_PANEL (&Dword, PldInfo->Panel); 769239340Sjkim ACPI_PLD_SET_VERTICAL (&Dword, PldInfo->VerticalPosition); 770239340Sjkim ACPI_PLD_SET_HORIZONTAL (&Dword, PldInfo->HorizontalPosition); 771239340Sjkim ACPI_PLD_SET_SHAPE (&Dword, PldInfo->Shape); 772239340Sjkim ACPI_PLD_SET_ORIENTATION (&Dword, PldInfo->GroupOrientation); 773239340Sjkim ACPI_PLD_SET_TOKEN (&Dword, PldInfo->GroupToken); 774239340Sjkim ACPI_PLD_SET_POSITION (&Dword, PldInfo->GroupPosition); 775239340Sjkim ACPI_PLD_SET_BAY (&Dword, PldInfo->Bay); 776239340Sjkim ACPI_MOVE_32_TO_32 (&Buffer[2], &Dword); 777239340Sjkim 778239340Sjkim /* Fourth 32 bits */ 779239340Sjkim 780239340Sjkim Dword = 0; 781239340Sjkim ACPI_PLD_SET_EJECTABLE (&Dword, PldInfo->Ejectable); 782239340Sjkim ACPI_PLD_SET_OSPM_EJECT (&Dword, PldInfo->OspmEjectRequired); 783239340Sjkim ACPI_PLD_SET_CABINET (&Dword, PldInfo->CabinetNumber); 784239340Sjkim ACPI_PLD_SET_CARD_CAGE (&Dword, PldInfo->CardCageNumber); 785239340Sjkim ACPI_PLD_SET_REFERENCE (&Dword, PldInfo->Reference); 786239340Sjkim ACPI_PLD_SET_ROTATION (&Dword, PldInfo->Rotation); 787239340Sjkim ACPI_PLD_SET_ORDER (&Dword, PldInfo->Order); 788239340Sjkim ACPI_MOVE_32_TO_32 (&Buffer[3], &Dword); 789239340Sjkim 790239340Sjkim if (PldInfo->Revision >= 2) 791239340Sjkim { 792239340Sjkim /* Fifth 32 bits */ 793239340Sjkim 794239340Sjkim Dword = 0; 795239340Sjkim ACPI_PLD_SET_VERT_OFFSET (&Dword, PldInfo->VerticalOffset); 796239340Sjkim ACPI_PLD_SET_HORIZ_OFFSET (&Dword, PldInfo->HorizontalOffset); 797239340Sjkim ACPI_MOVE_32_TO_32 (&Buffer[4], &Dword); 798239340Sjkim } 799239340Sjkim 800239340Sjkim return (ACPI_CAST_PTR (UINT8, Buffer)); 801239340Sjkim} 802239340Sjkim 803239340Sjkim 804239340Sjkim/******************************************************************************* 805239340Sjkim * 806239340Sjkim * FUNCTION: AcpiDbDumpPldBuffer 807239340Sjkim * 808239340Sjkim * PARAMETERS: ObjDesc - Object returned from _PLD method 809239340Sjkim * 810239340Sjkim * RETURN: None. 811239340Sjkim * 812239340Sjkim * DESCRIPTION: Dumps formatted contents of a _PLD return buffer. 813239340Sjkim * 814239340Sjkim ******************************************************************************/ 815239340Sjkim 816239340Sjkim#define ACPI_PLD_OUTPUT "%20s : %-6X\n" 817239340Sjkim 818239340Sjkimstatic void 819239340SjkimAcpiDbDumpPldBuffer ( 820239340Sjkim ACPI_OBJECT *ObjDesc) 821239340Sjkim{ 822239340Sjkim ACPI_OBJECT *BufferDesc; 823239340Sjkim ACPI_PLD_INFO *PldInfo; 824239340Sjkim UINT8 *NewBuffer; 825239340Sjkim ACPI_STATUS Status; 826239340Sjkim 827239340Sjkim 828239340Sjkim /* Object must be of type Package with at least one Buffer element */ 829239340Sjkim 830239340Sjkim if (ObjDesc->Type != ACPI_TYPE_PACKAGE) 831239340Sjkim { 832239340Sjkim return; 833239340Sjkim } 834239340Sjkim 835239340Sjkim BufferDesc = &ObjDesc->Package.Elements[0]; 836239340Sjkim if (BufferDesc->Type != ACPI_TYPE_BUFFER) 837239340Sjkim { 838239340Sjkim return; 839239340Sjkim } 840239340Sjkim 841239340Sjkim /* Convert _PLD buffer to local _PLD struct */ 842239340Sjkim 843239340Sjkim Status = AcpiDecodePldBuffer (BufferDesc->Buffer.Pointer, 844239340Sjkim BufferDesc->Buffer.Length, &PldInfo); 845239340Sjkim if (ACPI_FAILURE (Status)) 846239340Sjkim { 847239340Sjkim return; 848239340Sjkim } 849239340Sjkim 850239340Sjkim /* Encode local _PLD struct back to a _PLD buffer */ 851239340Sjkim 852239340Sjkim NewBuffer = AcpiDbEncodePldBuffer (PldInfo); 853239340Sjkim if (!NewBuffer) 854239340Sjkim { 855239340Sjkim return; 856239340Sjkim } 857239340Sjkim 858239340Sjkim /* The two bit-packed buffers should match */ 859239340Sjkim 860239340Sjkim if (ACPI_MEMCMP (NewBuffer, BufferDesc->Buffer.Pointer, 861239340Sjkim BufferDesc->Buffer.Length)) 862239340Sjkim { 863239340Sjkim AcpiOsPrintf ("Converted _PLD buffer does not compare. New:\n"); 864239340Sjkim 865239340Sjkim AcpiUtDumpBuffer2 (NewBuffer, 866239340Sjkim BufferDesc->Buffer.Length, DB_BYTE_DISPLAY); 867239340Sjkim } 868239340Sjkim 869239340Sjkim /* First 32-bit dword */ 870239340Sjkim 871239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Revision", PldInfo->Revision); 872239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "IgnoreColor", PldInfo->IgnoreColor); 873239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Color", PldInfo->Color); 874239340Sjkim 875239340Sjkim /* Second 32-bit dword */ 876239340Sjkim 877239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Width", PldInfo->Width); 878239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Height", PldInfo->Height); 879239340Sjkim 880239340Sjkim /* Third 32-bit dword */ 881239340Sjkim 882239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "UserVisible", PldInfo->UserVisible); 883239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Dock", PldInfo->Dock); 884239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Lid", PldInfo->Lid); 885239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Panel", PldInfo->Panel); 886239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "VerticalPosition", PldInfo->VerticalPosition); 887239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "HorizontalPosition", PldInfo->HorizontalPosition); 888239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Shape", PldInfo->Shape); 889239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "GroupOrientation", PldInfo->GroupOrientation); 890239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "GroupToken", PldInfo->GroupToken); 891239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "GroupPosition", PldInfo->GroupPosition); 892239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Bay", PldInfo->Bay); 893239340Sjkim 894239340Sjkim /* Fourth 32-bit dword */ 895239340Sjkim 896239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Ejectable", PldInfo->Ejectable); 897239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "OspmEjectRequired", PldInfo->OspmEjectRequired); 898239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "CabinetNumber", PldInfo->CabinetNumber); 899239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "CardCageNumber", PldInfo->CardCageNumber); 900239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Reference", PldInfo->Reference); 901239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Rotation", PldInfo->Rotation); 902239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "Order", PldInfo->Order); 903239340Sjkim 904239340Sjkim /* Fifth 32-bit dword */ 905239340Sjkim 906239340Sjkim if (BufferDesc->Buffer.Length > 16) 907239340Sjkim { 908239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "VerticalOffset", PldInfo->VerticalOffset); 909239340Sjkim AcpiOsPrintf (ACPI_PLD_OUTPUT, "HorizontalOffset", PldInfo->HorizontalOffset); 910239340Sjkim } 911239340Sjkim 912239340Sjkim ACPI_FREE (PldInfo); 913239340Sjkim ACPI_FREE (NewBuffer); 914239340Sjkim} 915239340Sjkim 916239340Sjkim 917239340Sjkim/******************************************************************************* 918239340Sjkim * 91967754Smsmith * FUNCTION: AcpiDbExecute 92067754Smsmith * 92167754Smsmith * PARAMETERS: Name - Name of method to execute 92267754Smsmith * Args - Parameters to the method 92367754Smsmith * Flags - single step/no single step 92467754Smsmith * 925151937Sjkim * RETURN: None 92667754Smsmith * 92767754Smsmith * DESCRIPTION: Execute a control method. Name is relative to the current 92867754Smsmith * scope. 92967754Smsmith * 93067754Smsmith ******************************************************************************/ 93167754Smsmith 93267754Smsmithvoid 93367754SmsmithAcpiDbExecute ( 934114237Snjl char *Name, 935114237Snjl char **Args, 936222544Sjkim ACPI_OBJECT_TYPE *Types, 93767754Smsmith UINT32 Flags) 93867754Smsmith{ 93967754Smsmith ACPI_STATUS Status; 94069450Smsmith ACPI_BUFFER ReturnObj; 941167802Sjkim char *NameString; 94269450Smsmith 94369450Smsmith 944102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT 94567754Smsmith UINT32 PreviousAllocations; 94667754Smsmith UINT32 Allocations; 94767754Smsmith 94867754Smsmith 94967754Smsmith /* Memory allocation tracking */ 95067754Smsmith 95182367Smsmith PreviousAllocations = AcpiDbGetOutstandingAllocations (); 95269450Smsmith#endif 95367754Smsmith 954114237Snjl if (*Name == '*') 955114237Snjl { 956151937Sjkim (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT, 957199337Sjkim ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL); 958114237Snjl return; 959114237Snjl } 960114237Snjl else 961114237Snjl { 962167802Sjkim NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1); 963167802Sjkim if (!NameString) 964167802Sjkim { 965167802Sjkim return; 966167802Sjkim } 967167802Sjkim 968167802Sjkim ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); 969167802Sjkim 970167802Sjkim ACPI_STRCPY (NameString, Name); 971167802Sjkim AcpiUtStrupr (NameString); 972167802Sjkim AcpiGbl_DbMethodInfo.Name = NameString; 973114237Snjl AcpiGbl_DbMethodInfo.Args = Args; 974222544Sjkim AcpiGbl_DbMethodInfo.Types = Types; 975114237Snjl AcpiGbl_DbMethodInfo.Flags = Flags; 97667754Smsmith 977114237Snjl ReturnObj.Pointer = NULL; 978114237Snjl ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 979100966Siwasaki 980114237Snjl AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 981239340Sjkim 982239340Sjkim /* Get the NS node, determines existence also */ 983239340Sjkim 984239340Sjkim Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname, 985239340Sjkim &AcpiGbl_DbMethodInfo.Method); 986239340Sjkim if (ACPI_FAILURE (Status)) 987239340Sjkim { 988239340Sjkim return; 989239340Sjkim } 990239340Sjkim 991114237Snjl Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj); 992167802Sjkim ACPI_FREE (NameString); 993114237Snjl } 99467754Smsmith 99582367Smsmith /* 99682367Smsmith * Allow any handlers in separate threads to complete. 99782367Smsmith * (Such as Notify handlers invoked from AML executed above). 99882367Smsmith */ 999202771Sjkim AcpiOsSleep ((UINT64) 10); 100067754Smsmith 100182367Smsmith 1002102550Siwasaki#ifdef ACPI_DEBUG_OUTPUT 100369450Smsmith 100467754Smsmith /* Memory allocation tracking */ 100567754Smsmith 100682367Smsmith Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations; 100767754Smsmith 100891116Smsmith AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 100967754Smsmith 101067754Smsmith if (Allocations > 0) 101167754Smsmith { 1012138287Smarks AcpiOsPrintf ("Outstanding: 0x%X allocations after execution\n", 101382367Smsmith Allocations); 101467754Smsmith } 101569450Smsmith#endif 101667754Smsmith 101767754Smsmith if (ACPI_FAILURE (Status)) 101867754Smsmith { 101983174Smsmith AcpiOsPrintf ("Execution of %s failed with status %s\n", 102083174Smsmith AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status)); 102167754Smsmith } 102267754Smsmith else 102367754Smsmith { 102467754Smsmith /* Display a return object, if any */ 102567754Smsmith 102667754Smsmith if (ReturnObj.Length) 102767754Smsmith { 102877424Smsmith AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 1029114237Snjl AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, 1030104470Siwasaki (UINT32) ReturnObj.Length); 1031151937Sjkim AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); 1032239340Sjkim 1033239340Sjkim /* Dump a _PLD buffer if present */ 1034239340Sjkim 1035239340Sjkim if (ACPI_COMPARE_NAME ((ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, 1036239340Sjkim AcpiGbl_DbMethodInfo.Method)->Name.Ascii), METHOD_NAME__PLD)) 1037239340Sjkim { 1038239340Sjkim AcpiDbDumpPldBuffer (ReturnObj.Pointer); 1039239340Sjkim } 104067754Smsmith } 1041100966Siwasaki else 1042100966Siwasaki { 1043102550Siwasaki AcpiOsPrintf ("No return object from execution of %s\n", 1044100966Siwasaki AcpiGbl_DbMethodInfo.Pathname); 1045100966Siwasaki } 104667754Smsmith } 104767754Smsmith 104891116Smsmith AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 104967754Smsmith} 105067754Smsmith 105167754Smsmith 105267754Smsmith/******************************************************************************* 105367754Smsmith * 105467754Smsmith * FUNCTION: AcpiDbMethodThread 105567754Smsmith * 105667754Smsmith * PARAMETERS: Context - Execution info segment 105767754Smsmith * 105867754Smsmith * RETURN: None 105967754Smsmith * 106067754Smsmith * DESCRIPTION: Debugger execute thread. Waits for a command line, then 106167754Smsmith * simply dispatches it. 106267754Smsmith * 106367754Smsmith ******************************************************************************/ 106467754Smsmith 1065151937Sjkimstatic void ACPI_SYSTEM_XFACE 106667754SmsmithAcpiDbMethodThread ( 106767754Smsmith void *Context) 106867754Smsmith{ 106967754Smsmith ACPI_STATUS Status; 107091116Smsmith ACPI_DB_METHOD_INFO *Info = Context; 1071193267Sjkim ACPI_DB_METHOD_INFO LocalInfo; 107267754Smsmith UINT32 i; 1073167802Sjkim UINT8 Allow; 107467754Smsmith ACPI_BUFFER ReturnObj; 107567754Smsmith 107667754Smsmith 1077193267Sjkim /* 1078193267Sjkim * AcpiGbl_DbMethodInfo.Arguments will be passed as method arguments. 1079193267Sjkim * Prevent AcpiGbl_DbMethodInfo from being modified by multiple threads 1080193267Sjkim * concurrently. 1081193267Sjkim * 1082193267Sjkim * Note: The arguments we are passing are used by the ASL test suite 1083193267Sjkim * (aslts). Do not change them without updating the tests. 1084193267Sjkim */ 1085193267Sjkim (void) AcpiOsWaitSemaphore (Info->InfoGate, 1, ACPI_WAIT_FOREVER); 1086193267Sjkim 1087167802Sjkim if (Info->InitArgs) 1088167802Sjkim { 1089237412Sjkim AcpiDbUint32ToHexString (Info->NumCreated, Info->IndexOfThreadStr); 1090237412Sjkim AcpiDbUint32ToHexString ((UINT32) AcpiOsGetThreadId (), Info->IdOfThreadStr); 1091167802Sjkim } 1092167802Sjkim 1093167802Sjkim if (Info->Threads && (Info->NumCreated < Info->NumThreads)) 1094167802Sjkim { 1095212761Sjkim Info->Threads[Info->NumCreated++] = AcpiOsGetThreadId(); 1096167802Sjkim } 1097167802Sjkim 1098193267Sjkim LocalInfo = *Info; 1099193267Sjkim LocalInfo.Args = LocalInfo.Arguments; 1100193267Sjkim LocalInfo.Arguments[0] = LocalInfo.NumThreadsStr; 1101193267Sjkim LocalInfo.Arguments[1] = LocalInfo.IdOfThreadStr; 1102193267Sjkim LocalInfo.Arguments[2] = LocalInfo.IndexOfThreadStr; 1103193267Sjkim LocalInfo.Arguments[3] = NULL; 1104193267Sjkim 1105222544Sjkim LocalInfo.Types = LocalInfo.ArgTypes; 1106222544Sjkim 1107193267Sjkim (void) AcpiOsSignalSemaphore (Info->InfoGate, 1); 1108193267Sjkim 110967754Smsmith for (i = 0; i < Info->NumLoops; i++) 111067754Smsmith { 1111193267Sjkim Status = AcpiDbExecuteMethod (&LocalInfo, &ReturnObj); 1112117521Snjl if (ACPI_FAILURE (Status)) 111367754Smsmith { 1114117521Snjl AcpiOsPrintf ("%s During execution of %s at iteration %X\n", 1115117521Snjl AcpiFormatException (Status), Info->Pathname, i); 1116127175Snjl if (Status == AE_ABORT_METHOD) 1117127175Snjl { 1118127175Snjl break; 1119127175Snjl } 112067754Smsmith } 1121117521Snjl 1122167802Sjkim#if 0 1123128212Snjl if ((i % 100) == 0) 1124117521Snjl { 1125209746Sjkim AcpiOsPrintf ("%u executions, Thread 0x%x\n", i, AcpiOsGetThreadId ()); 1126117521Snjl } 1127117521Snjl 1128117521Snjl if (ReturnObj.Length) 1129117521Snjl { 1130117521Snjl AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", 1131117521Snjl Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length); 1132151937Sjkim AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); 1133117521Snjl } 1134117521Snjl#endif 113567754Smsmith } 113667754Smsmith 113767754Smsmith /* Signal our completion */ 113867754Smsmith 1139167802Sjkim Allow = 0; 1140193267Sjkim (void) AcpiOsWaitSemaphore (Info->ThreadCompleteGate, 1, ACPI_WAIT_FOREVER); 1141167802Sjkim Info->NumCompleted++; 1142167802Sjkim 1143167802Sjkim if (Info->NumCompleted == Info->NumThreads) 114499679Siwasaki { 1145167802Sjkim /* Do signal for main thread once only */ 1146167802Sjkim Allow = 1; 114799679Siwasaki } 1148167802Sjkim 1149193267Sjkim (void) AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1); 1150167802Sjkim 1151167802Sjkim if (Allow) 1152167802Sjkim { 1153167802Sjkim Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1); 1154167802Sjkim if (ACPI_FAILURE (Status)) 1155167802Sjkim { 1156167802Sjkim AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n", 1157167802Sjkim AcpiFormatException (Status)); 1158167802Sjkim } 1159167802Sjkim } 116067754Smsmith} 116167754Smsmith 116267754Smsmith 116367754Smsmith/******************************************************************************* 116467754Smsmith * 116567754Smsmith * FUNCTION: AcpiDbCreateExecutionThreads 116667754Smsmith * 116767754Smsmith * PARAMETERS: NumThreadsArg - Number of threads to create 116867754Smsmith * NumLoopsArg - Loop count for the thread(s) 116967754Smsmith * MethodNameArg - Control method to execute 117067754Smsmith * 117167754Smsmith * RETURN: None 117267754Smsmith * 117367754Smsmith * DESCRIPTION: Create threads to execute method(s) 117467754Smsmith * 117567754Smsmith ******************************************************************************/ 117667754Smsmith 117767754Smsmithvoid 117867754SmsmithAcpiDbCreateExecutionThreads ( 1179114237Snjl char *NumThreadsArg, 1180114237Snjl char *NumLoopsArg, 1181114237Snjl char *MethodNameArg) 118267754Smsmith{ 118367754Smsmith ACPI_STATUS Status; 118467754Smsmith UINT32 NumThreads; 118567754Smsmith UINT32 NumLoops; 118667754Smsmith UINT32 i; 1187167802Sjkim UINT32 Size; 1188167802Sjkim ACPI_MUTEX MainThreadGate; 1189167802Sjkim ACPI_MUTEX ThreadCompleteGate; 1190193267Sjkim ACPI_MUTEX InfoGate; 119167754Smsmith 1192193267Sjkim 119367754Smsmith /* Get the arguments */ 119467754Smsmith 119591116Smsmith NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0); 119691116Smsmith NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0); 119767754Smsmith 119867754Smsmith if (!NumThreads || !NumLoops) 119967754Smsmith { 1200151937Sjkim AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", 1201151937Sjkim NumThreads, NumLoops); 120267754Smsmith return; 120367754Smsmith } 120467754Smsmith 1205167802Sjkim /* 1206167802Sjkim * Create the semaphore for synchronization of 1207167802Sjkim * the created threads with the main thread. 1208167802Sjkim */ 1209167802Sjkim Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate); 1210167802Sjkim if (ACPI_FAILURE (Status)) 1211167802Sjkim { 1212167802Sjkim AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n", 1213167802Sjkim AcpiFormatException (Status)); 1214167802Sjkim return; 1215167802Sjkim } 121667754Smsmith 1217167802Sjkim /* 1218167802Sjkim * Create the semaphore for synchronization 1219167802Sjkim * between the created threads. 1220167802Sjkim */ 1221167802Sjkim Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate); 122267754Smsmith if (ACPI_FAILURE (Status)) 122367754Smsmith { 1224167802Sjkim AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n", 1225151937Sjkim AcpiFormatException (Status)); 1226167802Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 122767754Smsmith return; 122867754Smsmith } 122967754Smsmith 1230193267Sjkim Status = AcpiOsCreateSemaphore (1, 1, &InfoGate); 1231193267Sjkim if (ACPI_FAILURE (Status)) 1232193267Sjkim { 1233193267Sjkim AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n", 1234193267Sjkim AcpiFormatException (Status)); 1235193267Sjkim (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 1236193267Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 1237193267Sjkim return; 1238193267Sjkim } 1239193267Sjkim 1240167802Sjkim ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); 1241167802Sjkim 1242167802Sjkim /* Array to store IDs of threads */ 1243167802Sjkim 1244167802Sjkim AcpiGbl_DbMethodInfo.NumThreads = NumThreads; 1245212761Sjkim Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads; 1246212761Sjkim AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size); 1247167802Sjkim if (AcpiGbl_DbMethodInfo.Threads == NULL) 1248167802Sjkim { 1249167802Sjkim AcpiOsPrintf ("No memory for thread IDs array\n"); 1250167802Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 1251167802Sjkim (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 1252193267Sjkim (void) AcpiOsDeleteSemaphore (InfoGate); 1253167802Sjkim return; 1254167802Sjkim } 1255167802Sjkim ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size); 1256167802Sjkim 125767754Smsmith /* Setup the context to be passed to each thread */ 125867754Smsmith 125983174Smsmith AcpiGbl_DbMethodInfo.Name = MethodNameArg; 126083174Smsmith AcpiGbl_DbMethodInfo.Flags = 0; 126183174Smsmith AcpiGbl_DbMethodInfo.NumLoops = NumLoops; 1262167802Sjkim AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate; 1263167802Sjkim AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate; 1264193267Sjkim AcpiGbl_DbMethodInfo.InfoGate = InfoGate; 126567754Smsmith 1266167802Sjkim /* Init arguments to be passed to method */ 1267167802Sjkim 1268167802Sjkim AcpiGbl_DbMethodInfo.InitArgs = 1; 1269167802Sjkim AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments; 1270167802Sjkim AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr; 1271167802Sjkim AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr; 1272167802Sjkim AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr; 1273167802Sjkim AcpiGbl_DbMethodInfo.Arguments[3] = NULL; 1274222544Sjkim 1275222544Sjkim AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes; 1276222544Sjkim AcpiGbl_DbMethodInfo.ArgTypes[0] = ACPI_TYPE_INTEGER; 1277222544Sjkim AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER; 1278222544Sjkim AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER; 1279222544Sjkim 1280237412Sjkim AcpiDbUint32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr); 1281167802Sjkim 128283174Smsmith AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); 128367754Smsmith 1284239340Sjkim /* Get the NS node, determines existence also */ 1285239340Sjkim 1286239340Sjkim Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname, 1287239340Sjkim &AcpiGbl_DbMethodInfo.Method); 1288239340Sjkim if (ACPI_FAILURE (Status)) 1289239340Sjkim { 1290239340Sjkim AcpiOsPrintf ("%s Could not get handle for %s\n", 1291239340Sjkim AcpiFormatException (Status), AcpiGbl_DbMethodInfo.Pathname); 1292239340Sjkim goto CleanupAndExit; 1293239340Sjkim } 1294239340Sjkim 129567754Smsmith /* Create the threads */ 129667754Smsmith 1297151937Sjkim AcpiOsPrintf ("Creating %X threads to execute %X times each\n", 1298151937Sjkim NumThreads, NumLoops); 129967754Smsmith 130067754Smsmith for (i = 0; i < (NumThreads); i++) 130167754Smsmith { 1302167802Sjkim Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread, 1303151937Sjkim &AcpiGbl_DbMethodInfo); 130499679Siwasaki if (ACPI_FAILURE (Status)) 130599679Siwasaki { 130699679Siwasaki break; 130799679Siwasaki } 130867754Smsmith } 130967754Smsmith 131067754Smsmith /* Wait for all threads to complete */ 131167754Smsmith 1312193267Sjkim (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER); 131367754Smsmith 1314167802Sjkim AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 1315167802Sjkim AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); 1316167802Sjkim AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1317167802Sjkim 1318239340SjkimCleanupAndExit: 1319239340Sjkim 132067754Smsmith /* Cleanup and exit */ 132167754Smsmith 1322167802Sjkim (void) AcpiOsDeleteSemaphore (MainThreadGate); 1323167802Sjkim (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); 1324193267Sjkim (void) AcpiOsDeleteSemaphore (InfoGate); 132567754Smsmith 1326167802Sjkim AcpiOsFree (AcpiGbl_DbMethodInfo.Threads); 1327167802Sjkim AcpiGbl_DbMethodInfo.Threads = NULL; 132867754Smsmith} 132967754Smsmith 1330102550Siwasaki#endif /* ACPI_DEBUGGER */ 133167754Smsmith 133267754Smsmith 1333