167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: dbutils - AML debugger utilities 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/acnamesp.h> 48193341Sjkim#include <contrib/dev/acpica/include/acdebug.h> 49193341Sjkim#include <contrib/dev/acpica/include/acdisasm.h> 5067754Smsmith 5167754Smsmith 52102550Siwasaki#ifdef ACPI_DEBUGGER 5367754Smsmith 54102550Siwasaki#define _COMPONENT ACPI_CA_DEBUGGER 5591116Smsmith ACPI_MODULE_NAME ("dbutils") 5667754Smsmith 57151937Sjkim/* Local prototypes */ 5867754Smsmith 59151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 60151937SjkimACPI_STATUS 61151937SjkimAcpiDbSecondPassParse ( 62151937Sjkim ACPI_PARSE_OBJECT *Root); 63151937Sjkim 64151937Sjkimvoid 65151937SjkimAcpiDbDumpBuffer ( 66151937Sjkim UINT32 Address); 67151937Sjkim#endif 68151937Sjkim 69167802Sjkimstatic char *Converter = "0123456789ABCDEF"; 70151937Sjkim 71167802Sjkim 7267754Smsmith/******************************************************************************* 7367754Smsmith * 74114237Snjl * FUNCTION: AcpiDbMatchArgument 75114237Snjl * 76114237Snjl * PARAMETERS: UserArgument - User command line 77114237Snjl * Arguments - Array of commands to match against 78114237Snjl * 79114237Snjl * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found 80114237Snjl * 81114237Snjl * DESCRIPTION: Search command array for a command match 82114237Snjl * 83114237Snjl ******************************************************************************/ 84114237Snjl 85114237SnjlACPI_OBJECT_TYPE 86114237SnjlAcpiDbMatchArgument ( 87114237Snjl char *UserArgument, 88114237Snjl ARGUMENT_INFO *Arguments) 89114237Snjl{ 90114237Snjl UINT32 i; 91114237Snjl 92114237Snjl 93114237Snjl if (!UserArgument || UserArgument[0] == 0) 94114237Snjl { 95114237Snjl return (ACPI_TYPE_NOT_FOUND); 96114237Snjl } 97114237Snjl 98114237Snjl for (i = 0; Arguments[i].Name; i++) 99114237Snjl { 100114237Snjl if (ACPI_STRSTR (Arguments[i].Name, UserArgument) == Arguments[i].Name) 101114237Snjl { 102114237Snjl return (i); 103114237Snjl } 104114237Snjl } 105114237Snjl 106114237Snjl /* Argument not recognized */ 107114237Snjl 108114237Snjl return (ACPI_TYPE_NOT_FOUND); 109114237Snjl} 110114237Snjl 111114237Snjl 112114237Snjl/******************************************************************************* 113114237Snjl * 11467754Smsmith * FUNCTION: AcpiDbSetOutputDestination 11567754Smsmith * 11667754Smsmith * PARAMETERS: OutputFlags - Current flags word 11767754Smsmith * 11867754Smsmith * RETURN: None 11967754Smsmith * 120151937Sjkim * DESCRIPTION: Set the current destination for debugger output. Also sets 12167754Smsmith * the debug output level accordingly. 12267754Smsmith * 12367754Smsmith ******************************************************************************/ 12467754Smsmith 12567754Smsmithvoid 12667754SmsmithAcpiDbSetOutputDestination ( 12767754Smsmith UINT32 OutputFlags) 12867754Smsmith{ 12967754Smsmith 13067754Smsmith AcpiGbl_DbOutputFlags = (UINT8) OutputFlags; 13167754Smsmith 13291116Smsmith if ((OutputFlags & ACPI_DB_REDIRECTABLE_OUTPUT) && AcpiGbl_DbOutputToFile) 13367754Smsmith { 13491116Smsmith AcpiDbgLevel = AcpiGbl_DbDebugLevel; 13567754Smsmith } 13667754Smsmith else 13767754Smsmith { 13867754Smsmith AcpiDbgLevel = AcpiGbl_DbConsoleDebugLevel; 13967754Smsmith } 14067754Smsmith} 14167754Smsmith 14267754Smsmith 14367754Smsmith/******************************************************************************* 14467754Smsmith * 145151937Sjkim * FUNCTION: AcpiDbDumpExternalObject 14667754Smsmith * 14767754Smsmith * PARAMETERS: ObjDesc - External ACPI object to dump 14867754Smsmith * Level - Nesting level. 14967754Smsmith * 15067754Smsmith * RETURN: None 15167754Smsmith * 15267754Smsmith * DESCRIPTION: Dump the contents of an ACPI external object 15367754Smsmith * 15467754Smsmith ******************************************************************************/ 15567754Smsmith 15667754Smsmithvoid 157151937SjkimAcpiDbDumpExternalObject ( 15867754Smsmith ACPI_OBJECT *ObjDesc, 15967754Smsmith UINT32 Level) 16067754Smsmith{ 16167754Smsmith UINT32 i; 16267754Smsmith 16367754Smsmith 16467754Smsmith if (!ObjDesc) 16567754Smsmith { 16667754Smsmith AcpiOsPrintf ("[Null Object]\n"); 16767754Smsmith return; 16867754Smsmith } 16967754Smsmith 17067754Smsmith for (i = 0; i < Level; i++) 17167754Smsmith { 17267754Smsmith AcpiOsPrintf (" "); 17367754Smsmith } 17467754Smsmith 17567754Smsmith switch (ObjDesc->Type) 17667754Smsmith { 17767754Smsmith case ACPI_TYPE_ANY: 17867754Smsmith 179193267Sjkim AcpiOsPrintf ("[Null Object] (Type=0)\n"); 18067754Smsmith break; 18167754Smsmith 18267754Smsmith 18371867Smsmith case ACPI_TYPE_INTEGER: 18482367Smsmith 18591116Smsmith AcpiOsPrintf ("[Integer] = %8.8X%8.8X\n", 186123315Snjl ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); 18767754Smsmith break; 18867754Smsmith 18967754Smsmith 19067754Smsmith case ACPI_TYPE_STRING: 19167754Smsmith 192167802Sjkim AcpiOsPrintf ("[String] Length %.2X = ", ObjDesc->String.Length); 19367754Smsmith for (i = 0; i < ObjDesc->String.Length; i++) 19467754Smsmith { 19567754Smsmith AcpiOsPrintf ("%c", ObjDesc->String.Pointer[i]); 19667754Smsmith } 19767754Smsmith AcpiOsPrintf ("\n"); 19867754Smsmith break; 19967754Smsmith 20067754Smsmith 20167754Smsmith case ACPI_TYPE_BUFFER: 20267754Smsmith 20399146Siwasaki AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length); 204114237Snjl if (ObjDesc->Buffer.Length) 205114237Snjl { 206200553Sjkim if (ObjDesc->Buffer.Length > 16) 207200553Sjkim { 208200553Sjkim AcpiOsPrintf ("\n"); 209200553Sjkim } 210167802Sjkim AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer), 211117521Snjl ObjDesc->Buffer.Length, DB_DWORD_DISPLAY, _COMPONENT); 212114237Snjl } 213114237Snjl else 214114237Snjl { 215114237Snjl AcpiOsPrintf ("\n"); 216114237Snjl } 21767754Smsmith break; 21867754Smsmith 21967754Smsmith 22067754Smsmith case ACPI_TYPE_PACKAGE: 22167754Smsmith 222209746Sjkim AcpiOsPrintf ("[Package] Contains %u Elements:\n", 223117521Snjl ObjDesc->Package.Count); 22467754Smsmith 22567754Smsmith for (i = 0; i < ObjDesc->Package.Count; i++) 22667754Smsmith { 227151937Sjkim AcpiDbDumpExternalObject (&ObjDesc->Package.Elements[i], Level+1); 22867754Smsmith } 22967754Smsmith break; 23067754Smsmith 23167754Smsmith 232107325Siwasaki case ACPI_TYPE_LOCAL_REFERENCE: 23382367Smsmith 234193267Sjkim AcpiOsPrintf ("[Object Reference] = "); 235138287Smarks AcpiDmDisplayInternalObject (ObjDesc->Reference.Handle, NULL); 23667754Smsmith break; 23767754Smsmith 23882367Smsmith 23967754Smsmith case ACPI_TYPE_PROCESSOR: 24082367Smsmith 24167754Smsmith AcpiOsPrintf ("[Processor]\n"); 24267754Smsmith break; 24367754Smsmith 24482367Smsmith 24567754Smsmith case ACPI_TYPE_POWER: 24682367Smsmith 24767754Smsmith AcpiOsPrintf ("[Power Resource]\n"); 24867754Smsmith break; 24967754Smsmith 25082367Smsmith 25167754Smsmith default: 25267754Smsmith 253151937Sjkim AcpiOsPrintf ("[Unknown Type] %X\n", ObjDesc->Type); 25467754Smsmith break; 25567754Smsmith } 25667754Smsmith} 25767754Smsmith 25867754Smsmith 25967754Smsmith/******************************************************************************* 26067754Smsmith * 26167754Smsmith * FUNCTION: AcpiDbPrepNamestring 26267754Smsmith * 26367754Smsmith * PARAMETERS: Name - String to prepare 26467754Smsmith * 26567754Smsmith * RETURN: None 26667754Smsmith * 26767754Smsmith * DESCRIPTION: Translate all forward slashes and dots to backslashes. 26867754Smsmith * 26967754Smsmith ******************************************************************************/ 27067754Smsmith 27167754Smsmithvoid 27267754SmsmithAcpiDbPrepNamestring ( 273114237Snjl char *Name) 27467754Smsmith{ 27567754Smsmith 27667754Smsmith if (!Name) 27767754Smsmith { 27867754Smsmith return; 27967754Smsmith } 28067754Smsmith 281151937Sjkim AcpiUtStrupr (Name); 28267754Smsmith 28367754Smsmith /* Convert a leading forward slash to a backslash */ 28467754Smsmith 28567754Smsmith if (*Name == '/') 28667754Smsmith { 28767754Smsmith *Name = '\\'; 28867754Smsmith } 28967754Smsmith 29067754Smsmith /* Ignore a leading backslash, this is the root prefix */ 29167754Smsmith 29267754Smsmith if (*Name == '\\') 29367754Smsmith { 29467754Smsmith Name++; 29567754Smsmith } 29667754Smsmith 29767754Smsmith /* Convert all slash path separators to dots */ 29867754Smsmith 29967754Smsmith while (*Name) 30067754Smsmith { 30167754Smsmith if ((*Name == '/') || 30267754Smsmith (*Name == '\\')) 30367754Smsmith { 30467754Smsmith *Name = '.'; 30567754Smsmith } 30667754Smsmith 30767754Smsmith Name++; 30867754Smsmith } 30967754Smsmith} 31067754Smsmith 31167754Smsmith 31267754Smsmith/******************************************************************************* 31367754Smsmith * 314151937Sjkim * FUNCTION: AcpiDbLocalNsLookup 315151937Sjkim * 316151937Sjkim * PARAMETERS: Name - Name to lookup 317151937Sjkim * 318151937Sjkim * RETURN: Pointer to a namespace node, null on failure 319151937Sjkim * 320151937Sjkim * DESCRIPTION: Lookup a name in the ACPI namespace 321151937Sjkim * 322151937Sjkim * Note: Currently begins search from the root. Could be enhanced to use 323151937Sjkim * the current prefix (scope) node as the search beginning point. 324151937Sjkim * 325151937Sjkim ******************************************************************************/ 326151937Sjkim 327151937SjkimACPI_NAMESPACE_NODE * 328151937SjkimAcpiDbLocalNsLookup ( 329151937Sjkim char *Name) 330151937Sjkim{ 331151937Sjkim char *InternalPath; 332151937Sjkim ACPI_STATUS Status; 333151937Sjkim ACPI_NAMESPACE_NODE *Node = NULL; 334151937Sjkim 335151937Sjkim 336151937Sjkim AcpiDbPrepNamestring (Name); 337151937Sjkim 338151937Sjkim /* Build an internal namestring */ 339151937Sjkim 340151937Sjkim Status = AcpiNsInternalizeName (Name, &InternalPath); 341151937Sjkim if (ACPI_FAILURE (Status)) 342151937Sjkim { 343151937Sjkim AcpiOsPrintf ("Invalid namestring: %s\n", Name); 344151937Sjkim return (NULL); 345151937Sjkim } 346151937Sjkim 347151937Sjkim /* 348151937Sjkim * Lookup the name. 349151937Sjkim * (Uses root node as the search starting point) 350151937Sjkim */ 351151937Sjkim Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 352151937Sjkim ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 353151937Sjkim if (ACPI_FAILURE (Status)) 354151937Sjkim { 355167802Sjkim AcpiOsPrintf ("Could not locate name: %s, %s\n", 356151937Sjkim Name, AcpiFormatException (Status)); 357151937Sjkim } 358151937Sjkim 359167802Sjkim ACPI_FREE (InternalPath); 360151937Sjkim return (Node); 361151937Sjkim} 362151937Sjkim 363151937Sjkim 364167802Sjkim/******************************************************************************* 365167802Sjkim * 366167802Sjkim * FUNCTION: AcpiDbUInt32ToHexString 367167802Sjkim * 368167802Sjkim * PARAMETERS: Value - The value to be converted to string 369167802Sjkim * Buffer - Buffer for result (not less than 11 bytes) 370167802Sjkim * 371167802Sjkim * RETURN: None 372167802Sjkim * 373167802Sjkim * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image 374167802Sjkim * 375167802Sjkim * NOTE: It is the caller's responsibility to ensure that the length of buffer 376167802Sjkim * is sufficient. 377167802Sjkim * 378167802Sjkim ******************************************************************************/ 379167802Sjkim 380167802Sjkimvoid 381167802SjkimAcpiDbUInt32ToHexString ( 382167802Sjkim UINT32 Value, 383167802Sjkim char *Buffer) 384167802Sjkim{ 385222544Sjkim int i; 386167802Sjkim 387167802Sjkim 388167802Sjkim if (Value == 0) 389167802Sjkim { 390167802Sjkim ACPI_STRCPY (Buffer, "0"); 391167802Sjkim return; 392167802Sjkim } 393167802Sjkim 394222544Sjkim Buffer[8] = '\0'; 395167802Sjkim 396222544Sjkim for (i = 7; i >= 0; i--) 397167802Sjkim { 398167802Sjkim Buffer[i] = Converter [Value & 0x0F]; 399167802Sjkim Value = Value >> 4; 400167802Sjkim } 401167802Sjkim} 402167802Sjkim 403167802Sjkim 404151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 405151937Sjkim/******************************************************************************* 406151937Sjkim * 40767754Smsmith * FUNCTION: AcpiDbSecondPassParse 40867754Smsmith * 40967754Smsmith * PARAMETERS: Root - Root of the parse tree 41067754Smsmith * 41167754Smsmith * RETURN: Status 41267754Smsmith * 41367754Smsmith * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until 41467754Smsmith * second pass to parse the control methods 41567754Smsmith * 41667754Smsmith ******************************************************************************/ 41767754Smsmith 41867754SmsmithACPI_STATUS 41967754SmsmithAcpiDbSecondPassParse ( 42067754Smsmith ACPI_PARSE_OBJECT *Root) 42167754Smsmith{ 42267754Smsmith ACPI_PARSE_OBJECT *Op = Root; 42399679Siwasaki ACPI_PARSE_OBJECT *Method; 42467754Smsmith ACPI_PARSE_OBJECT *SearchOp; 42567754Smsmith ACPI_PARSE_OBJECT *StartOp; 42667754Smsmith ACPI_STATUS Status = AE_OK; 42767754Smsmith UINT32 BaseAmlOffset; 42884491Smsmith ACPI_WALK_STATE *WalkState; 42967754Smsmith 43067754Smsmith 43191116Smsmith ACPI_FUNCTION_ENTRY (); 43284491Smsmith 43384491Smsmith 43467754Smsmith AcpiOsPrintf ("Pass two parse ....\n"); 43567754Smsmith 43667754Smsmith while (Op) 43767754Smsmith { 43899679Siwasaki if (Op->Common.AmlOpcode == AML_METHOD_OP) 43967754Smsmith { 44099679Siwasaki Method = Op; 44167754Smsmith 44299679Siwasaki /* Create a new walk state for the parse */ 44399679Siwasaki 444117521Snjl WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 44584491Smsmith if (!WalkState) 44684491Smsmith { 44784491Smsmith return (AE_NO_MEMORY); 44884491Smsmith } 44967754Smsmith 45099679Siwasaki /* Init the Walk State */ 45184491Smsmith 45284491Smsmith WalkState->ParserState.Aml = 45399679Siwasaki WalkState->ParserState.AmlStart = Method->Named.Data; 45484491Smsmith WalkState->ParserState.AmlEnd = 455151937Sjkim WalkState->ParserState.PkgEnd = Method->Named.Data + 456151937Sjkim Method->Named.Length; 45784491Smsmith WalkState->ParserState.StartScope = Op; 45884491Smsmith 45984491Smsmith WalkState->DescendingCallback = AcpiDsLoad1BeginOp; 46084491Smsmith WalkState->AscendingCallback = AcpiDsLoad1EndOp; 46184491Smsmith 46299679Siwasaki /* Perform the AML parse */ 46384491Smsmith 46484491Smsmith Status = AcpiPsParseAml (WalkState); 46584491Smsmith 46699679Siwasaki BaseAmlOffset = (Method->Common.Value.Arg)->Common.AmlOffset + 1; 46799679Siwasaki StartOp = (Method->Common.Value.Arg)->Common.Next; 46867754Smsmith SearchOp = StartOp; 46967754Smsmith 47067754Smsmith while (SearchOp) 47167754Smsmith { 47299679Siwasaki SearchOp->Common.AmlOffset += BaseAmlOffset; 47367754Smsmith SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 47467754Smsmith } 47567754Smsmith } 47667754Smsmith 47799679Siwasaki if (Op->Common.AmlOpcode == AML_REGION_OP) 47867754Smsmith { 47967754Smsmith /* TBD: [Investigate] this isn't quite the right thing to do! */ 48067754Smsmith /* 48167754Smsmith * 48267754Smsmith * Method = (ACPI_DEFERRED_OP *) Op; 48367754Smsmith * Status = AcpiPsParseAml (Op, Method->Body, Method->BodyLength); 48467754Smsmith */ 48567754Smsmith } 48667754Smsmith 48767754Smsmith if (ACPI_FAILURE (Status)) 48867754Smsmith { 48984491Smsmith break; 49067754Smsmith } 49167754Smsmith 49267754Smsmith Op = AcpiPsGetDepthNext (Root, Op); 49367754Smsmith } 49467754Smsmith 49567754Smsmith return (Status); 49667754Smsmith} 49767754Smsmith 49867754Smsmith 49967754Smsmith/******************************************************************************* 50067754Smsmith * 501151937Sjkim * FUNCTION: AcpiDbDumpBuffer 50267754Smsmith * 503151937Sjkim * PARAMETERS: Address - Pointer to the buffer 50467754Smsmith * 505151937Sjkim * RETURN: None 50667754Smsmith * 507151937Sjkim * DESCRIPTION: Print a portion of a buffer 50867754Smsmith * 50967754Smsmith ******************************************************************************/ 51067754Smsmith 511151937Sjkimvoid 512151937SjkimAcpiDbDumpBuffer ( 513151937Sjkim UINT32 Address) 51467754Smsmith{ 51567754Smsmith 516151937Sjkim AcpiOsPrintf ("\nLocation %X:\n", Address); 51767754Smsmith 518151937Sjkim AcpiDbgLevel |= ACPI_LV_TABLES; 519151937Sjkim AcpiUtDumpBuffer (ACPI_TO_POINTER (Address), 64, DB_BYTE_DISPLAY, 520151937Sjkim ACPI_UINT32_MAX); 52167754Smsmith} 522151937Sjkim#endif 52367754Smsmith 524102550Siwasaki#endif /* ACPI_DEBUGGER */ 52567754Smsmith 52667754Smsmith 527