dbutils.c revision 306536
1139749Simp/******************************************************************************* 2196008Smjacob * 3167403Smjacob * Module Name: dbutils - AML debugger utilities 4196008Smjacob * 5167403Smjacob ******************************************************************************/ 6167403Smjacob 7167403Smjacob/* 8196008Smjacob * Copyright (C) 2000 - 2016, Intel Corp. 9167403Smjacob * All rights reserved. 10167403Smjacob * 11167403Smjacob * Redistribution and use in source and binary forms, with or without 12167403Smjacob * modification, are permitted provided that the following conditions 13167403Smjacob * are met: 14196008Smjacob * 1. Redistributions of source code must retain the above copyright 15167403Smjacob * notice, this list of conditions, and the following disclaimer, 16167403Smjacob * without modification. 17167403Smjacob * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18167403Smjacob * substantially similar to the "NO WARRANTY" disclaimer below 19167403Smjacob * ("Disclaimer") and any redistribution must be conditioned upon 20167403Smjacob * including a substantially similar Disclaimer requirement for further 21167403Smjacob * binary redistribution. 22167403Smjacob * 3. Neither the names of the above-listed copyright holders nor the names 23167403Smjacob * of any contributors may be used to endorse or promote products derived 24167403Smjacob * from this software without specific prior written permission. 25167403Smjacob * 26196008Smjacob * Alternatively, this software may be distributed under the terms of the 27167403Smjacob * GNU General Public License ("GPL") version 2 as published by the Free 28167403Smjacob * Software Foundation. 2955373Smjacob * 3055373Smjacob * NO WARRANTY 3155373Smjacob * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3290224Smjacob * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3390224Smjacob * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3490224Smjacob * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3590224Smjacob * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3655373Smjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3755373Smjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3855373Smjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3955373Smjacob * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4055373Smjacob * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4155373Smjacob * POSSIBILITY OF SUCH DAMAGES. 4255373Smjacob */ 43160410Smjacob 44160410Smjacob#include <contrib/dev/acpica/include/acpi.h> 4555373Smjacob#include <contrib/dev/acpica/include/accommon.h> 4655373Smjacob#include <contrib/dev/acpica/include/acnamesp.h> 4755373Smjacob#include <contrib/dev/acpica/include/acdebug.h> 4855373Smjacob 4955373Smjacob 5055373Smjacob#define _COMPONENT ACPI_CA_DEBUGGER 5155373Smjacob ACPI_MODULE_NAME ("dbutils") 5255373Smjacob 5355373Smjacob 5455373Smjacob/* Local prototypes */ 55196008Smjacob 56196008Smjacob#ifdef ACPI_OBSOLETE_FUNCTIONS 57196008SmjacobACPI_STATUS 5855373SmjacobAcpiDbSecondPassParse ( 59157943Smjacob ACPI_PARSE_OBJECT *Root); 60157943Smjacob 61163899Smjacobvoid 62157943SmjacobAcpiDbDumpBuffer ( 63157943Smjacob UINT32 Address); 64157943Smjacob#endif 65157943Smjacob 66163899Smjacob 67196008Smjacob/******************************************************************************* 6855373Smjacob * 6955373Smjacob * FUNCTION: AcpiDbMatchArgument 7055373Smjacob * 7155373Smjacob * PARAMETERS: UserArgument - User command line 7255373Smjacob * Arguments - Array of commands to match against 7355373Smjacob * 7455373Smjacob * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found 7555373Smjacob * 7655373Smjacob * DESCRIPTION: Search command array for a command match 7755373Smjacob * 7855373Smjacob ******************************************************************************/ 7955373Smjacob 8055373SmjacobACPI_OBJECT_TYPE 8155373SmjacobAcpiDbMatchArgument ( 8255373Smjacob char *UserArgument, 8355373Smjacob ACPI_DB_ARGUMENT_INFO *Arguments) 8455373Smjacob{ 8555373Smjacob UINT32 i; 8655373Smjacob 8755373Smjacob 8855373Smjacob if (!UserArgument || UserArgument[0] == 0) 8955373Smjacob { 9055373Smjacob return (ACPI_TYPE_NOT_FOUND); 9155373Smjacob } 9255373Smjacob 9355373Smjacob for (i = 0; Arguments[i].Name; i++) 9455373Smjacob { 9555373Smjacob if (strstr ( 9655373Smjacob ACPI_CAST_PTR (char, Arguments[i].Name), 9772082Sasmodai ACPI_CAST_PTR (char, UserArgument)) == Arguments[i].Name) 9855373Smjacob { 9955373Smjacob return (i); 10055373Smjacob } 10155373Smjacob } 10255373Smjacob 10355373Smjacob /* Argument not recognized */ 10455373Smjacob 10555373Smjacob return (ACPI_TYPE_NOT_FOUND); 10655373Smjacob} 10755373Smjacob 10855373Smjacob 10955373Smjacob/******************************************************************************* 11055373Smjacob * 11155373Smjacob * FUNCTION: AcpiDbSetOutputDestination 11255373Smjacob * 11355373Smjacob * PARAMETERS: OutputFlags - Current flags word 11455373Smjacob * 11555373Smjacob * RETURN: None 116163899Smjacob * 11755373Smjacob * DESCRIPTION: Set the current destination for debugger output. Also sets 118163899Smjacob * the debug output level accordingly. 119163899Smjacob * 12055373Smjacob ******************************************************************************/ 12155373Smjacob 12255373Smjacobvoid 123154704SmjacobAcpiDbSetOutputDestination ( 124163899Smjacob UINT32 OutputFlags) 12555373Smjacob{ 12655373Smjacob 127154704Smjacob AcpiGbl_DbOutputFlags = (UINT8) OutputFlags; 128163899Smjacob 12955373Smjacob if ((OutputFlags & ACPI_DB_REDIRECTABLE_OUTPUT) && 13055373Smjacob AcpiGbl_DbOutputToFile) 13155373Smjacob { 132154704Smjacob AcpiDbgLevel = AcpiGbl_DbDebugLevel; 133163899Smjacob } 13455373Smjacob else 13555373Smjacob { 136154704Smjacob AcpiDbgLevel = AcpiGbl_DbConsoleDebugLevel; 137163899Smjacob } 13855373Smjacob} 139163899Smjacob 140163899Smjacob 141163899Smjacob/******************************************************************************* 14255373Smjacob * 14355373Smjacob * FUNCTION: AcpiDbDumpExternalObject 14455373Smjacob * 145154704Smjacob * PARAMETERS: ObjDesc - External ACPI object to dump 146163899Smjacob * Level - Nesting level. 14755373Smjacob * 14855373Smjacob * RETURN: None 149154704Smjacob * 150163899Smjacob * DESCRIPTION: Dump the contents of an ACPI external object 15155373Smjacob * 15255373Smjacob ******************************************************************************/ 15355373Smjacob 154154704Smjacobvoid 155163899SmjacobAcpiDbDumpExternalObject ( 15655373Smjacob ACPI_OBJECT *ObjDesc, 15755373Smjacob UINT32 Level) 158154704Smjacob{ 159163899Smjacob UINT32 i; 160163899Smjacob 161163899Smjacob 162163899Smjacob if (!ObjDesc) 16355373Smjacob { 16455373Smjacob AcpiOsPrintf ("[Null Object]\n"); 165155704Smjacob return; 166196008Smjacob } 167163899Smjacob 168196008Smjacob for (i = 0; i < Level; i++) 16955373Smjacob { 17087635Smjacob AcpiOsPrintf (" "); 17155373Smjacob } 17255373Smjacob 17355373Smjacob switch (ObjDesc->Type) 17455373Smjacob { 175196008Smjacob case ACPI_TYPE_ANY: 17655373Smjacob 177163899Smjacob AcpiOsPrintf ("[Null Object] (Type=0)\n"); 178163899Smjacob break; 179163899Smjacob 180163899Smjacob case ACPI_TYPE_INTEGER: 181163899Smjacob 182163899Smjacob AcpiOsPrintf ("[Integer] = %8.8X%8.8X\n", 183196008Smjacob ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); 184196008Smjacob break; 185163899Smjacob 186163899Smjacob case ACPI_TYPE_STRING: 187163899Smjacob 188163899Smjacob AcpiOsPrintf ("[String] Length %.2X = ", ObjDesc->String.Length); 189196008Smjacob AcpiUtPrintString (ObjDesc->String.Pointer, ACPI_UINT8_MAX); 190163899Smjacob AcpiOsPrintf ("\n"); 191196008Smjacob break; 192163899Smjacob 193163899Smjacob case ACPI_TYPE_BUFFER: 194163899Smjacob 195163899Smjacob AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length); 196163899Smjacob if (ObjDesc->Buffer.Length) 197163899Smjacob { 198163899Smjacob if (ObjDesc->Buffer.Length > 16) 199163899Smjacob { 200163899Smjacob AcpiOsPrintf ("\n"); 201163899Smjacob } 202163899Smjacob 203163899Smjacob AcpiUtDebugDumpBuffer ( 204163899Smjacob ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer), 205196008Smjacob ObjDesc->Buffer.Length, DB_BYTE_DISPLAY, _COMPONENT); 206163899Smjacob } 207163899Smjacob else 208163899Smjacob { 209163899Smjacob AcpiOsPrintf ("\n"); 21055373Smjacob } 211163899Smjacob break; 21255373Smjacob 21387635Smjacob case ACPI_TYPE_PACKAGE: 21487635Smjacob 21555373Smjacob AcpiOsPrintf ("[Package] Contains %u Elements:\n", 216163899Smjacob ObjDesc->Package.Count); 21755373Smjacob 218196008Smjacob for (i = 0; i < ObjDesc->Package.Count; i++) 219154704Smjacob { 220160251Smjacob AcpiDbDumpExternalObject ( 221154704Smjacob &ObjDesc->Package.Elements[i], Level+1); 222163899Smjacob } 22387635Smjacob break; 22455373Smjacob 225163899Smjacob case ACPI_TYPE_LOCAL_REFERENCE: 226125187Smjacob 22755373Smjacob AcpiOsPrintf ("[Object Reference] = "); 228196008Smjacob AcpiDbDisplayInternalObject (ObjDesc->Reference.Handle, NULL); 229154704Smjacob break; 230160251Smjacob 231154704Smjacob case ACPI_TYPE_PROCESSOR: 232163899Smjacob 23387635Smjacob AcpiOsPrintf ("[Processor]\n"); 23455373Smjacob break; 235163899Smjacob 236163899Smjacob case ACPI_TYPE_POWER: 237163899Smjacob 238163899Smjacob AcpiOsPrintf ("[Power Resource]\n"); 239163899Smjacob break; 240163899Smjacob 24155373Smjacob default: 24255373Smjacob 24387635Smjacob AcpiOsPrintf ("[Unknown Type] %X\n", ObjDesc->Type); 244196008Smjacob break; 24555373Smjacob } 24655373Smjacob} 24755373Smjacob 24857216Smjacob 249163899Smjacob/******************************************************************************* 250196008Smjacob * 251163899Smjacob * FUNCTION: AcpiDbPrepNamestring 252196008Smjacob * 253163899Smjacob * PARAMETERS: Name - String to prepare 254196008Smjacob * 255196008Smjacob * RETURN: None 256196008Smjacob * 257196008Smjacob * DESCRIPTION: Translate all forward slashes and dots to backslashes. 258196008Smjacob * 259196008Smjacob ******************************************************************************/ 260196008Smjacob 261196008Smjacobvoid 262160978SmjacobAcpiDbPrepNamestring ( 263196008Smjacob char *Name) 264196008Smjacob{ 265196008Smjacob 266196008Smjacob if (!Name) 267196008Smjacob { 268160978Smjacob return; 26955373Smjacob } 270196008Smjacob 271196008Smjacob AcpiUtStrupr (Name); 272196008Smjacob 273196008Smjacob /* Convert a leading forward slash to a backslash */ 274196008Smjacob 27557216Smjacob if (*Name == '/') 276196008Smjacob { 277196008Smjacob *Name = '\\'; 27857216Smjacob } 27955373Smjacob 280160978Smjacob /* Ignore a leading backslash, this is the root prefix */ 281196008Smjacob 28283027Smjacob if (ACPI_IS_ROOT_PREFIX (*Name)) 28355373Smjacob { 28455373Smjacob Name++; 28555373Smjacob } 28655373Smjacob 287154704Smjacob /* Convert all slash path separators to dots */ 28855373Smjacob 289154704Smjacob while (*Name) 29055373Smjacob { 29155373Smjacob if ((*Name == '/') || 29255373Smjacob (*Name == '\\')) 293163899Smjacob { 294240015Smjacob *Name = '.'; 29555373Smjacob } 296196008Smjacob 297154704Smjacob Name++; 298196008Smjacob } 299163899Smjacob} 300196008Smjacob 301196008Smjacob 302196008Smjacob/******************************************************************************* 303196008Smjacob * 304196008Smjacob * FUNCTION: AcpiDbLocalNsLookup 305163899Smjacob * 306163899Smjacob * PARAMETERS: Name - Name to lookup 307196008Smjacob * 308163899Smjacob * RETURN: Pointer to a namespace node, null on failure 309163899Smjacob * 310196008Smjacob * DESCRIPTION: Lookup a name in the ACPI namespace 311196008Smjacob * 312154704Smjacob * Note: Currently begins search from the root. Could be enhanced to use 313196008Smjacob * the current prefix (scope) node as the search beginning point. 31498284Smjacob * 315196008Smjacob ******************************************************************************/ 316196008Smjacob 317196008SmjacobACPI_NAMESPACE_NODE * 318196008SmjacobAcpiDbLocalNsLookup ( 319196008Smjacob char *Name) 320196008Smjacob{ 321196008Smjacob char *InternalPath; 322196008Smjacob ACPI_STATUS Status; 323196008Smjacob ACPI_NAMESPACE_NODE *Node = NULL; 324196008Smjacob 325196008Smjacob 326196008Smjacob AcpiDbPrepNamestring (Name); 32755373Smjacob 328196008Smjacob /* Build an internal namestring */ 329196008Smjacob 330196008Smjacob Status = AcpiNsInternalizeName (Name, &InternalPath); 331196008Smjacob if (ACPI_FAILURE (Status)) 332196008Smjacob { 333196008Smjacob AcpiOsPrintf ("Invalid namestring: %s\n", Name); 334196008Smjacob return (NULL); 335196008Smjacob } 336196008Smjacob 337196008Smjacob /* 338196008Smjacob * Lookup the name. 339196008Smjacob * (Uses root node as the search starting point) 34055373Smjacob */ 341196008Smjacob Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY, 342196008Smjacob ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, 343196008Smjacob NULL, &Node); 344196008Smjacob if (ACPI_FAILURE (Status)) 345196008Smjacob { 346196008Smjacob AcpiOsPrintf ("Could not locate name: %s, %s\n", 347196008Smjacob Name, AcpiFormatException (Status)); 348196008Smjacob } 349240015Smjacob 350240015Smjacob ACPI_FREE (InternalPath); 351196008Smjacob return (Node); 35255373Smjacob} 353196008Smjacob 354196008Smjacob 355196008Smjacob/******************************************************************************* 356240015Smjacob * 357240015Smjacob * FUNCTION: AcpiDbUint32ToHexString 358240015Smjacob * 359240015Smjacob * PARAMETERS: Value - The value to be converted to string 360240015Smjacob * Buffer - Buffer for result (not less than 11 bytes) 361240015Smjacob * 362240015Smjacob * RETURN: None 363240015Smjacob * 364240015Smjacob * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image 365240015Smjacob * 366196008Smjacob * NOTE: It is the caller's responsibility to ensure that the length of buffer 367196008Smjacob * is sufficient. 36855373Smjacob * 369196008Smjacob ******************************************************************************/ 370196008Smjacob 371240015Smjacobvoid 37255373SmjacobAcpiDbUint32ToHexString ( 37355373Smjacob UINT32 Value, 37455373Smjacob char *Buffer) 37555373Smjacob{ 37655373Smjacob int i; 37755373Smjacob 37855373Smjacob 37955373Smjacob if (Value == 0) 38055373Smjacob { 381163899Smjacob strcpy (Buffer, "0"); 382196008Smjacob return; 383163899Smjacob } 384163899Smjacob 385163899Smjacob Buffer[8] = '\0'; 386163899Smjacob 387163899Smjacob for (i = 7; i >= 0; i--) 388163899Smjacob { 389196008Smjacob Buffer[i] = AcpiGbl_UpperHexDigits [Value & 0x0F]; 390163899Smjacob Value = Value >> 4; 391196008Smjacob } 392196008Smjacob} 393160251Smjacob 394196008Smjacob 395163899Smjacob#ifdef ACPI_OBSOLETE_FUNCTIONS 39687635Smjacob/******************************************************************************* 397163899Smjacob * 398163899Smjacob * FUNCTION: AcpiDbSecondPassParse 399163899Smjacob * 400163899Smjacob * PARAMETERS: Root - Root of the parse tree 401163899Smjacob * 402196008Smjacob * RETURN: Status 40355373Smjacob * 40487635Smjacob * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until 40587635Smjacob * second pass to parse the control methods 406163899Smjacob * 407163899Smjacob ******************************************************************************/ 408163899Smjacob 409163899SmjacobACPI_STATUS 410163899SmjacobAcpiDbSecondPassParse ( 411196008Smjacob ACPI_PARSE_OBJECT *Root) 41255373Smjacob{ 41355373Smjacob ACPI_PARSE_OBJECT *Op = Root; 414163899Smjacob ACPI_PARSE_OBJECT *Method; 415163899Smjacob ACPI_PARSE_OBJECT *SearchOp; 416163899Smjacob ACPI_PARSE_OBJECT *StartOp; 417196008Smjacob ACPI_STATUS Status = AE_OK; 418163899Smjacob UINT32 BaseAmlOffset; 419163899Smjacob ACPI_WALK_STATE *WalkState; 420163899Smjacob 421163899Smjacob 422163899Smjacob ACPI_FUNCTION_ENTRY (); 423163899Smjacob 424163899Smjacob 425163899Smjacob AcpiOsPrintf ("Pass two parse ....\n"); 426163899Smjacob 427196008Smjacob while (Op) 428196008Smjacob { 429163899Smjacob if (Op->Common.AmlOpcode == AML_METHOD_OP) 43055373Smjacob { 431196008Smjacob Method = Op; 43298284Smjacob 43355373Smjacob /* Create a new walk state for the parse */ 43455373Smjacob 43555373Smjacob WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 43655373Smjacob if (!WalkState) 437154704Smjacob { 438163899Smjacob return (AE_NO_MEMORY); 43955373Smjacob } 44055373Smjacob 441154704Smjacob /* Init the Walk State */ 442163899Smjacob 44355373Smjacob WalkState->ParserState.Aml = 44455373Smjacob WalkState->ParserState.AmlStart = Method->Named.Data; 44555373Smjacob WalkState->ParserState.AmlEnd = 446154704Smjacob WalkState->ParserState.PkgEnd = Method->Named.Data + 447163899Smjacob Method->Named.Length; 44855373Smjacob WalkState->ParserState.StartScope = Op; 44955373Smjacob 450154704Smjacob WalkState->DescendingCallback = AcpiDsLoad1BeginOp; 451163899Smjacob WalkState->AscendingCallback = AcpiDsLoad1EndOp; 452163899Smjacob 453163899Smjacob /* Perform the AML parse */ 454163899Smjacob 45555373Smjacob Status = AcpiPsParseAml (WalkState); 45655373Smjacob 45755373Smjacob BaseAmlOffset = (Method->Common.Value.Arg)->Common.AmlOffset + 1; 45855373Smjacob StartOp = (Method->Common.Value.Arg)->Common.Next; 459196008Smjacob SearchOp = StartOp; 46055373Smjacob 461196008Smjacob while (SearchOp) 46255373Smjacob { 46355373Smjacob SearchOp->Common.AmlOffset += BaseAmlOffset; 46455373Smjacob SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 46555373Smjacob } 46655373Smjacob } 467196008Smjacob 46855373Smjacob if (Op->Common.AmlOpcode == AML_REGION_OP) 46955373Smjacob { 470196008Smjacob /* TBD: [Investigate] this isn't quite the right thing to do! */ 47155373Smjacob /* 47255373Smjacob * 47355373Smjacob * Method = (ACPI_DEFERRED_OP *) Op; 47455373Smjacob * Status = AcpiPsParseAml (Op, Method->Body, Method->BodyLength); 475196008Smjacob */ 47657216Smjacob } 47757216Smjacob 47857216Smjacob if (ACPI_FAILURE (Status)) 479240015Smjacob { 480240015Smjacob break; 48155373Smjacob } 48255373Smjacob 48361774Smjacob Op = AcpiPsGetDepthNext (Root, Op); 48455373Smjacob } 48555373Smjacob 48655373Smjacob return (Status); 487240015Smjacob} 488240015Smjacob 489240015Smjacob 490240015Smjacob/******************************************************************************* 491240015Smjacob * 492240015Smjacob * FUNCTION: AcpiDbDumpBuffer 493240015Smjacob * 494240015Smjacob * PARAMETERS: Address - Pointer to the buffer 495240015Smjacob * 496240015Smjacob * RETURN: None 497240015Smjacob * 498240015Smjacob * DESCRIPTION: Print a portion of a buffer 499240015Smjacob * 50055373Smjacob ******************************************************************************/ 501240015Smjacob 502240015Smjacobvoid 50355373SmjacobAcpiDbDumpBuffer ( 50455373Smjacob UINT32 Address) 50555373Smjacob{ 50655373Smjacob 507196008Smjacob AcpiOsPrintf ("\nLocation %X:\n", Address); 50855373Smjacob 509196008Smjacob AcpiDbgLevel |= ACPI_LV_TABLES; 51055373Smjacob AcpiUtDebugDumpBuffer (ACPI_TO_POINTER (Address), 64, DB_BYTE_DISPLAY, 51155373Smjacob ACPI_UINT32_MAX); 512164908Smjacob} 51355373Smjacob#endif 514196008Smjacob