167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: dbutils - AML debugger utilities 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, 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 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 47193341Sjkim#include <contrib/dev/acpica/include/acdebug.h> 4867754Smsmith 4967754Smsmith 50102550Siwasaki#define _COMPONENT ACPI_CA_DEBUGGER 5191116Smsmith ACPI_MODULE_NAME ("dbutils") 5267754Smsmith 53306536Sjkim 54151937Sjkim/* Local prototypes */ 5567754Smsmith 56151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 57151937SjkimACPI_STATUS 58151937SjkimAcpiDbSecondPassParse ( 59151937Sjkim ACPI_PARSE_OBJECT *Root); 60151937Sjkim 61151937Sjkimvoid 62151937SjkimAcpiDbDumpBuffer ( 63151937Sjkim UINT32 Address); 64151937Sjkim#endif 65151937Sjkim 66151937Sjkim 6767754Smsmith/******************************************************************************* 6867754Smsmith * 69114237Snjl * FUNCTION: AcpiDbMatchArgument 70114237Snjl * 71114237Snjl * PARAMETERS: UserArgument - User command line 72114237Snjl * Arguments - Array of commands to match against 73114237Snjl * 74114237Snjl * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found 75114237Snjl * 76114237Snjl * DESCRIPTION: Search command array for a command match 77114237Snjl * 78114237Snjl ******************************************************************************/ 79114237Snjl 80114237SnjlACPI_OBJECT_TYPE 81114237SnjlAcpiDbMatchArgument ( 82114237Snjl char *UserArgument, 83240716Sjkim ACPI_DB_ARGUMENT_INFO *Arguments) 84114237Snjl{ 85114237Snjl UINT32 i; 86114237Snjl 87114237Snjl 88114237Snjl if (!UserArgument || UserArgument[0] == 0) 89114237Snjl { 90114237Snjl return (ACPI_TYPE_NOT_FOUND); 91114237Snjl } 92114237Snjl 93114237Snjl for (i = 0; Arguments[i].Name; i++) 94114237Snjl { 95306536Sjkim if (strstr ( 96306536Sjkim ACPI_CAST_PTR (char, Arguments[i].Name), 97306536Sjkim ACPI_CAST_PTR (char, UserArgument)) == Arguments[i].Name) 98114237Snjl { 99114237Snjl return (i); 100114237Snjl } 101114237Snjl } 102114237Snjl 103114237Snjl /* Argument not recognized */ 104114237Snjl 105114237Snjl return (ACPI_TYPE_NOT_FOUND); 106114237Snjl} 107114237Snjl 108114237Snjl 109114237Snjl/******************************************************************************* 110114237Snjl * 11167754Smsmith * FUNCTION: AcpiDbSetOutputDestination 11267754Smsmith * 11367754Smsmith * PARAMETERS: OutputFlags - Current flags word 11467754Smsmith * 11567754Smsmith * RETURN: None 11667754Smsmith * 117241973Sjkim * DESCRIPTION: Set the current destination for debugger output. Also sets 11867754Smsmith * the debug output level accordingly. 11967754Smsmith * 12067754Smsmith ******************************************************************************/ 12167754Smsmith 12267754Smsmithvoid 12367754SmsmithAcpiDbSetOutputDestination ( 12467754Smsmith UINT32 OutputFlags) 12567754Smsmith{ 12667754Smsmith 12767754Smsmith AcpiGbl_DbOutputFlags = (UINT8) OutputFlags; 12867754Smsmith 129306536Sjkim if ((OutputFlags & ACPI_DB_REDIRECTABLE_OUTPUT) && 130306536Sjkim AcpiGbl_DbOutputToFile) 13167754Smsmith { 13291116Smsmith AcpiDbgLevel = AcpiGbl_DbDebugLevel; 13367754Smsmith } 13467754Smsmith else 13567754Smsmith { 13667754Smsmith AcpiDbgLevel = AcpiGbl_DbConsoleDebugLevel; 13767754Smsmith } 13867754Smsmith} 13967754Smsmith 14067754Smsmith 14167754Smsmith/******************************************************************************* 14267754Smsmith * 143151937Sjkim * FUNCTION: AcpiDbDumpExternalObject 14467754Smsmith * 14567754Smsmith * PARAMETERS: ObjDesc - External ACPI object to dump 14667754Smsmith * Level - Nesting level. 14767754Smsmith * 14867754Smsmith * RETURN: None 14967754Smsmith * 15067754Smsmith * DESCRIPTION: Dump the contents of an ACPI external object 15167754Smsmith * 15267754Smsmith ******************************************************************************/ 15367754Smsmith 15467754Smsmithvoid 155151937SjkimAcpiDbDumpExternalObject ( 15667754Smsmith ACPI_OBJECT *ObjDesc, 15767754Smsmith UINT32 Level) 15867754Smsmith{ 15967754Smsmith UINT32 i; 16067754Smsmith 16167754Smsmith 16267754Smsmith if (!ObjDesc) 16367754Smsmith { 16467754Smsmith AcpiOsPrintf ("[Null Object]\n"); 16567754Smsmith return; 16667754Smsmith } 16767754Smsmith 16867754Smsmith for (i = 0; i < Level; i++) 16967754Smsmith { 17067754Smsmith AcpiOsPrintf (" "); 17167754Smsmith } 17267754Smsmith 17367754Smsmith switch (ObjDesc->Type) 17467754Smsmith { 17567754Smsmith case ACPI_TYPE_ANY: 17667754Smsmith 177193267Sjkim AcpiOsPrintf ("[Null Object] (Type=0)\n"); 17867754Smsmith break; 17967754Smsmith 18071867Smsmith case ACPI_TYPE_INTEGER: 18182367Smsmith 18291116Smsmith AcpiOsPrintf ("[Integer] = %8.8X%8.8X\n", 183306536Sjkim ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); 18467754Smsmith break; 18567754Smsmith 18667754Smsmith case ACPI_TYPE_STRING: 18767754Smsmith 188167802Sjkim AcpiOsPrintf ("[String] Length %.2X = ", ObjDesc->String.Length); 189234623Sjkim AcpiUtPrintString (ObjDesc->String.Pointer, ACPI_UINT8_MAX); 19067754Smsmith AcpiOsPrintf ("\n"); 19167754Smsmith break; 19267754Smsmith 19367754Smsmith case ACPI_TYPE_BUFFER: 19467754Smsmith 19599146Siwasaki AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length); 196114237Snjl if (ObjDesc->Buffer.Length) 197114237Snjl { 198200553Sjkim if (ObjDesc->Buffer.Length > 16) 199200553Sjkim { 200200553Sjkim AcpiOsPrintf ("\n"); 201200553Sjkim } 202306536Sjkim 203306536Sjkim AcpiUtDebugDumpBuffer ( 204306536Sjkim ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer), 205306536Sjkim ObjDesc->Buffer.Length, DB_BYTE_DISPLAY, _COMPONENT); 206114237Snjl } 207114237Snjl else 208114237Snjl { 209114237Snjl AcpiOsPrintf ("\n"); 210114237Snjl } 21167754Smsmith break; 21267754Smsmith 21367754Smsmith case ACPI_TYPE_PACKAGE: 21467754Smsmith 215209746Sjkim AcpiOsPrintf ("[Package] Contains %u Elements:\n", 216306536Sjkim ObjDesc->Package.Count); 21767754Smsmith 21867754Smsmith for (i = 0; i < ObjDesc->Package.Count; i++) 21967754Smsmith { 220306536Sjkim AcpiDbDumpExternalObject ( 221306536Sjkim &ObjDesc->Package.Elements[i], Level+1); 22267754Smsmith } 22367754Smsmith break; 22467754Smsmith 225107325Siwasaki case ACPI_TYPE_LOCAL_REFERENCE: 22682367Smsmith 227193267Sjkim AcpiOsPrintf ("[Object Reference] = "); 228306536Sjkim AcpiDbDisplayInternalObject (ObjDesc->Reference.Handle, NULL); 22967754Smsmith break; 23067754Smsmith 23167754Smsmith case ACPI_TYPE_PROCESSOR: 23282367Smsmith 23367754Smsmith AcpiOsPrintf ("[Processor]\n"); 23467754Smsmith break; 23567754Smsmith 23667754Smsmith case ACPI_TYPE_POWER: 23782367Smsmith 23867754Smsmith AcpiOsPrintf ("[Power Resource]\n"); 23967754Smsmith break; 24067754Smsmith 24167754Smsmith default: 24267754Smsmith 243151937Sjkim AcpiOsPrintf ("[Unknown Type] %X\n", ObjDesc->Type); 24467754Smsmith break; 24567754Smsmith } 24667754Smsmith} 24767754Smsmith 24867754Smsmith 24967754Smsmith/******************************************************************************* 25067754Smsmith * 25167754Smsmith * FUNCTION: AcpiDbPrepNamestring 25267754Smsmith * 25367754Smsmith * PARAMETERS: Name - String to prepare 25467754Smsmith * 25567754Smsmith * RETURN: None 25667754Smsmith * 25767754Smsmith * DESCRIPTION: Translate all forward slashes and dots to backslashes. 25867754Smsmith * 25967754Smsmith ******************************************************************************/ 26067754Smsmith 26167754Smsmithvoid 26267754SmsmithAcpiDbPrepNamestring ( 263114237Snjl char *Name) 26467754Smsmith{ 26567754Smsmith 26667754Smsmith if (!Name) 26767754Smsmith { 26867754Smsmith return; 26967754Smsmith } 27067754Smsmith 271151937Sjkim AcpiUtStrupr (Name); 27267754Smsmith 27367754Smsmith /* Convert a leading forward slash to a backslash */ 27467754Smsmith 27567754Smsmith if (*Name == '/') 27667754Smsmith { 27767754Smsmith *Name = '\\'; 27867754Smsmith } 27967754Smsmith 28067754Smsmith /* Ignore a leading backslash, this is the root prefix */ 28167754Smsmith 282245582Sjkim if (ACPI_IS_ROOT_PREFIX (*Name)) 28367754Smsmith { 28467754Smsmith Name++; 28567754Smsmith } 28667754Smsmith 28767754Smsmith /* Convert all slash path separators to dots */ 28867754Smsmith 28967754Smsmith while (*Name) 29067754Smsmith { 29167754Smsmith if ((*Name == '/') || 29267754Smsmith (*Name == '\\')) 29367754Smsmith { 29467754Smsmith *Name = '.'; 29567754Smsmith } 29667754Smsmith 29767754Smsmith Name++; 29867754Smsmith } 29967754Smsmith} 30067754Smsmith 30167754Smsmith 30267754Smsmith/******************************************************************************* 30367754Smsmith * 304151937Sjkim * FUNCTION: AcpiDbLocalNsLookup 305151937Sjkim * 306151937Sjkim * PARAMETERS: Name - Name to lookup 307151937Sjkim * 308151937Sjkim * RETURN: Pointer to a namespace node, null on failure 309151937Sjkim * 310151937Sjkim * DESCRIPTION: Lookup a name in the ACPI namespace 311151937Sjkim * 312241973Sjkim * Note: Currently begins search from the root. Could be enhanced to use 313151937Sjkim * the current prefix (scope) node as the search beginning point. 314151937Sjkim * 315151937Sjkim ******************************************************************************/ 316151937Sjkim 317151937SjkimACPI_NAMESPACE_NODE * 318151937SjkimAcpiDbLocalNsLookup ( 319151937Sjkim char *Name) 320151937Sjkim{ 321151937Sjkim char *InternalPath; 322151937Sjkim ACPI_STATUS Status; 323151937Sjkim ACPI_NAMESPACE_NODE *Node = NULL; 324151937Sjkim 325151937Sjkim 326151937Sjkim AcpiDbPrepNamestring (Name); 327151937Sjkim 328151937Sjkim /* Build an internal namestring */ 329151937Sjkim 330151937Sjkim Status = AcpiNsInternalizeName (Name, &InternalPath); 331151937Sjkim if (ACPI_FAILURE (Status)) 332151937Sjkim { 333151937Sjkim AcpiOsPrintf ("Invalid namestring: %s\n", Name); 334151937Sjkim return (NULL); 335151937Sjkim } 336151937Sjkim 337151937Sjkim /* 338151937Sjkim * Lookup the name. 339151937Sjkim * (Uses root node as the search starting point) 340151937Sjkim */ 341306536Sjkim Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY, 342306536Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, 343306536Sjkim NULL, &Node); 344151937Sjkim if (ACPI_FAILURE (Status)) 345151937Sjkim { 346167802Sjkim AcpiOsPrintf ("Could not locate name: %s, %s\n", 347306536Sjkim Name, AcpiFormatException (Status)); 348151937Sjkim } 349151937Sjkim 350167802Sjkim ACPI_FREE (InternalPath); 351151937Sjkim return (Node); 352151937Sjkim} 353151937Sjkim 354151937Sjkim 355167802Sjkim/******************************************************************************* 356167802Sjkim * 357237412Sjkim * FUNCTION: AcpiDbUint32ToHexString 358167802Sjkim * 359167802Sjkim * PARAMETERS: Value - The value to be converted to string 360167802Sjkim * Buffer - Buffer for result (not less than 11 bytes) 361167802Sjkim * 362167802Sjkim * RETURN: None 363167802Sjkim * 364167802Sjkim * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image 365167802Sjkim * 366167802Sjkim * NOTE: It is the caller's responsibility to ensure that the length of buffer 367167802Sjkim * is sufficient. 368167802Sjkim * 369167802Sjkim ******************************************************************************/ 370167802Sjkim 371167802Sjkimvoid 372237412SjkimAcpiDbUint32ToHexString ( 373167802Sjkim UINT32 Value, 374167802Sjkim char *Buffer) 375167802Sjkim{ 376222544Sjkim int i; 377167802Sjkim 378167802Sjkim 379167802Sjkim if (Value == 0) 380167802Sjkim { 381306536Sjkim strcpy (Buffer, "0"); 382167802Sjkim return; 383167802Sjkim } 384167802Sjkim 385222544Sjkim Buffer[8] = '\0'; 386167802Sjkim 387222544Sjkim for (i = 7; i >= 0; i--) 388167802Sjkim { 389306536Sjkim Buffer[i] = AcpiGbl_UpperHexDigits [Value & 0x0F]; 390167802Sjkim Value = Value >> 4; 391167802Sjkim } 392167802Sjkim} 393167802Sjkim 394167802Sjkim 395151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 396151937Sjkim/******************************************************************************* 397151937Sjkim * 39867754Smsmith * FUNCTION: AcpiDbSecondPassParse 39967754Smsmith * 40067754Smsmith * PARAMETERS: Root - Root of the parse tree 40167754Smsmith * 40267754Smsmith * RETURN: Status 40367754Smsmith * 404241973Sjkim * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until 40567754Smsmith * second pass to parse the control methods 40667754Smsmith * 40767754Smsmith ******************************************************************************/ 40867754Smsmith 40967754SmsmithACPI_STATUS 41067754SmsmithAcpiDbSecondPassParse ( 41167754Smsmith ACPI_PARSE_OBJECT *Root) 41267754Smsmith{ 41367754Smsmith ACPI_PARSE_OBJECT *Op = Root; 41499679Siwasaki ACPI_PARSE_OBJECT *Method; 41567754Smsmith ACPI_PARSE_OBJECT *SearchOp; 41667754Smsmith ACPI_PARSE_OBJECT *StartOp; 41767754Smsmith ACPI_STATUS Status = AE_OK; 41867754Smsmith UINT32 BaseAmlOffset; 41984491Smsmith ACPI_WALK_STATE *WalkState; 42067754Smsmith 42167754Smsmith 42291116Smsmith ACPI_FUNCTION_ENTRY (); 42384491Smsmith 42484491Smsmith 42567754Smsmith AcpiOsPrintf ("Pass two parse ....\n"); 42667754Smsmith 42767754Smsmith while (Op) 42867754Smsmith { 42999679Siwasaki if (Op->Common.AmlOpcode == AML_METHOD_OP) 43067754Smsmith { 43199679Siwasaki Method = Op; 43267754Smsmith 43399679Siwasaki /* Create a new walk state for the parse */ 43499679Siwasaki 435117521Snjl WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 43684491Smsmith if (!WalkState) 43784491Smsmith { 43884491Smsmith return (AE_NO_MEMORY); 43984491Smsmith } 44067754Smsmith 44199679Siwasaki /* Init the Walk State */ 44284491Smsmith 44384491Smsmith WalkState->ParserState.Aml = 44499679Siwasaki WalkState->ParserState.AmlStart = Method->Named.Data; 44584491Smsmith WalkState->ParserState.AmlEnd = 446151937Sjkim WalkState->ParserState.PkgEnd = Method->Named.Data + 447151937Sjkim Method->Named.Length; 44884491Smsmith WalkState->ParserState.StartScope = Op; 44984491Smsmith 45084491Smsmith WalkState->DescendingCallback = AcpiDsLoad1BeginOp; 45184491Smsmith WalkState->AscendingCallback = AcpiDsLoad1EndOp; 45284491Smsmith 45399679Siwasaki /* Perform the AML parse */ 45484491Smsmith 45584491Smsmith Status = AcpiPsParseAml (WalkState); 45684491Smsmith 45799679Siwasaki BaseAmlOffset = (Method->Common.Value.Arg)->Common.AmlOffset + 1; 45899679Siwasaki StartOp = (Method->Common.Value.Arg)->Common.Next; 45967754Smsmith SearchOp = StartOp; 46067754Smsmith 46167754Smsmith while (SearchOp) 46267754Smsmith { 46399679Siwasaki SearchOp->Common.AmlOffset += BaseAmlOffset; 46467754Smsmith SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 46567754Smsmith } 46667754Smsmith } 46767754Smsmith 46899679Siwasaki if (Op->Common.AmlOpcode == AML_REGION_OP) 46967754Smsmith { 47067754Smsmith /* TBD: [Investigate] this isn't quite the right thing to do! */ 47167754Smsmith /* 47267754Smsmith * 47367754Smsmith * Method = (ACPI_DEFERRED_OP *) Op; 47467754Smsmith * Status = AcpiPsParseAml (Op, Method->Body, Method->BodyLength); 47567754Smsmith */ 47667754Smsmith } 47767754Smsmith 47867754Smsmith if (ACPI_FAILURE (Status)) 47967754Smsmith { 48084491Smsmith break; 48167754Smsmith } 48267754Smsmith 48367754Smsmith Op = AcpiPsGetDepthNext (Root, Op); 48467754Smsmith } 48567754Smsmith 48667754Smsmith return (Status); 48767754Smsmith} 48867754Smsmith 48967754Smsmith 49067754Smsmith/******************************************************************************* 49167754Smsmith * 492151937Sjkim * FUNCTION: AcpiDbDumpBuffer 49367754Smsmith * 494151937Sjkim * PARAMETERS: Address - Pointer to the buffer 49567754Smsmith * 496151937Sjkim * RETURN: None 49767754Smsmith * 498151937Sjkim * DESCRIPTION: Print a portion of a buffer 49967754Smsmith * 50067754Smsmith ******************************************************************************/ 50167754Smsmith 502151937Sjkimvoid 503151937SjkimAcpiDbDumpBuffer ( 504151937Sjkim UINT32 Address) 50567754Smsmith{ 50667754Smsmith 507151937Sjkim AcpiOsPrintf ("\nLocation %X:\n", Address); 50867754Smsmith 509151937Sjkim AcpiDbgLevel |= ACPI_LV_TABLES; 510241973Sjkim AcpiUtDebugDumpBuffer (ACPI_TO_POINTER (Address), 64, DB_BYTE_DISPLAY, 511306536Sjkim ACPI_UINT32_MAX); 51267754Smsmith} 513151937Sjkim#endif 514