mirror of https://github.com/F-Stack/f-stack.git
581 lines
15 KiB
C
581 lines
15 KiB
C
|
/*******************************************************************************
|
||
|
*
|
||
|
* Module Name: dbobject - ACPI object decode and display
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions
|
||
|
* are met:
|
||
|
* 1. Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions, and the following disclaimer,
|
||
|
* without modification.
|
||
|
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||
|
* substantially similar to the "NO WARRANTY" disclaimer below
|
||
|
* ("Disclaimer") and any redistribution must be conditioned upon
|
||
|
* including a substantially similar Disclaimer requirement for further
|
||
|
* binary redistribution.
|
||
|
* 3. Neither the names of the above-listed copyright holders nor the names
|
||
|
* of any contributors may be used to endorse or promote products derived
|
||
|
* from this software without specific prior written permission.
|
||
|
*
|
||
|
* Alternatively, this software may be distributed under the terms of the
|
||
|
* GNU General Public License ("GPL") version 2 as published by the Free
|
||
|
* Software Foundation.
|
||
|
*
|
||
|
* NO WARRANTY
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
|
* POSSIBILITY OF SUCH DAMAGES.
|
||
|
*/
|
||
|
|
||
|
#include <contrib/dev/acpica/include/acpi.h>
|
||
|
#include <contrib/dev/acpica/include/accommon.h>
|
||
|
#include <contrib/dev/acpica/include/acnamesp.h>
|
||
|
#include <contrib/dev/acpica/include/acdebug.h>
|
||
|
|
||
|
|
||
|
#define _COMPONENT ACPI_CA_DEBUGGER
|
||
|
ACPI_MODULE_NAME ("dbobject")
|
||
|
|
||
|
|
||
|
/* Local prototypes */
|
||
|
|
||
|
static void
|
||
|
AcpiDbDecodeNode (
|
||
|
ACPI_NAMESPACE_NODE *Node);
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* FUNCTION: AcpiDbDumpMethodInfo
|
||
|
*
|
||
|
* PARAMETERS: Status - Method execution status
|
||
|
* WalkState - Current state of the parse tree walk
|
||
|
*
|
||
|
* RETURN: None
|
||
|
*
|
||
|
* DESCRIPTION: Called when a method has been aborted because of an error.
|
||
|
* Dumps the method execution stack, and the method locals/args,
|
||
|
* and disassembles the AML opcode that failed.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
void
|
||
|
AcpiDbDumpMethodInfo (
|
||
|
ACPI_STATUS Status,
|
||
|
ACPI_WALK_STATE *WalkState)
|
||
|
{
|
||
|
ACPI_THREAD_STATE *Thread;
|
||
|
|
||
|
|
||
|
/* Ignore control codes, they are not errors */
|
||
|
|
||
|
if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* We may be executing a deferred opcode */
|
||
|
|
||
|
if (WalkState->DeferredNode)
|
||
|
{
|
||
|
AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* If there is no Thread, we are not actually executing a method.
|
||
|
* This can happen when the iASL compiler calls the interpreter
|
||
|
* to perform constant folding.
|
||
|
*/
|
||
|
Thread = WalkState->Thread;
|
||
|
if (!Thread)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Display the method locals and arguments */
|
||
|
|
||
|
AcpiOsPrintf ("\n");
|
||
|
AcpiDbDecodeLocals (WalkState);
|
||
|
AcpiOsPrintf ("\n");
|
||
|
AcpiDbDecodeArguments (WalkState);
|
||
|
AcpiOsPrintf ("\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* FUNCTION: AcpiDbDecodeInternalObject
|
||
|
*
|
||
|
* PARAMETERS: ObjDesc - Object to be displayed
|
||
|
*
|
||
|
* RETURN: None
|
||
|
*
|
||
|
* DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
void
|
||
|
AcpiDbDecodeInternalObject (
|
||
|
ACPI_OPERAND_OBJECT *ObjDesc)
|
||
|
{
|
||
|
UINT32 i;
|
||
|
|
||
|
|
||
|
if (!ObjDesc)
|
||
|
{
|
||
|
AcpiOsPrintf (" Uninitialized");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND)
|
||
|
{
|
||
|
AcpiOsPrintf (" %p [%s]", ObjDesc,
|
||
|
AcpiUtGetDescriptorName (ObjDesc));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
AcpiOsPrintf (" %s", AcpiUtGetObjectTypeName (ObjDesc));
|
||
|
|
||
|
switch (ObjDesc->Common.Type)
|
||
|
{
|
||
|
case ACPI_TYPE_INTEGER:
|
||
|
|
||
|
AcpiOsPrintf (" %8.8X%8.8X",
|
||
|
ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
|
||
|
break;
|
||
|
|
||
|
case ACPI_TYPE_STRING:
|
||
|
|
||
|
AcpiOsPrintf ("(%u) \"%.60s",
|
||
|
ObjDesc->String.Length, ObjDesc->String.Pointer);
|
||
|
|
||
|
if (ObjDesc->String.Length > 60)
|
||
|
{
|
||
|
AcpiOsPrintf ("...");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AcpiOsPrintf ("\"");
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ACPI_TYPE_BUFFER:
|
||
|
|
||
|
AcpiOsPrintf ("(%u)", ObjDesc->Buffer.Length);
|
||
|
for (i = 0; (i < 8) && (i < ObjDesc->Buffer.Length); i++)
|
||
|
{
|
||
|
AcpiOsPrintf (" %2.2X", ObjDesc->Buffer.Pointer[i]);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
|
||
|
AcpiOsPrintf (" %p", ObjDesc);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* FUNCTION: AcpiDbDecodeNode
|
||
|
*
|
||
|
* PARAMETERS: Node - Object to be displayed
|
||
|
*
|
||
|
* RETURN: None
|
||
|
*
|
||
|
* DESCRIPTION: Short display of a namespace node
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
static void
|
||
|
AcpiDbDecodeNode (
|
||
|
ACPI_NAMESPACE_NODE *Node)
|
||
|
{
|
||
|
|
||
|
AcpiOsPrintf ("<Node> Name %4.4s",
|
||
|
AcpiUtGetNodeName (Node));
|
||
|
|
||
|
if (Node->Flags & ANOBJ_METHOD_ARG)
|
||
|
{
|
||
|
AcpiOsPrintf (" [Method Arg]");
|
||
|
}
|
||
|
if (Node->Flags & ANOBJ_METHOD_LOCAL)
|
||
|
{
|
||
|
AcpiOsPrintf (" [Method Local]");
|
||
|
}
|
||
|
|
||
|
switch (Node->Type)
|
||
|
{
|
||
|
/* These types have no attached object */
|
||
|
|
||
|
case ACPI_TYPE_DEVICE:
|
||
|
|
||
|
AcpiOsPrintf (" Device");
|
||
|
break;
|
||
|
|
||
|
case ACPI_TYPE_THERMAL:
|
||
|
|
||
|
AcpiOsPrintf (" Thermal Zone");
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
|
||
|
AcpiDbDecodeInternalObject (AcpiNsGetAttachedObject (Node));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* FUNCTION: AcpiDbDisplayInternalObject
|
||
|
*
|
||
|
* PARAMETERS: ObjDesc - Object to be displayed
|
||
|
* WalkState - Current walk state
|
||
|
*
|
||
|
* RETURN: None
|
||
|
*
|
||
|
* DESCRIPTION: Short display of an internal object
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
void
|
||
|
AcpiDbDisplayInternalObject (
|
||
|
ACPI_OPERAND_OBJECT *ObjDesc,
|
||
|
ACPI_WALK_STATE *WalkState)
|
||
|
{
|
||
|
UINT8 Type;
|
||
|
|
||
|
|
||
|
AcpiOsPrintf ("%p ", ObjDesc);
|
||
|
|
||
|
if (!ObjDesc)
|
||
|
{
|
||
|
AcpiOsPrintf ("<Null Object>\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Decode the object type */
|
||
|
|
||
|
switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
|
||
|
{
|
||
|
case ACPI_DESC_TYPE_PARSER:
|
||
|
|
||
|
AcpiOsPrintf ("<Parser> ");
|
||
|
break;
|
||
|
|
||
|
case ACPI_DESC_TYPE_NAMED:
|
||
|
|
||
|
AcpiDbDecodeNode ((ACPI_NAMESPACE_NODE *) ObjDesc);
|
||
|
break;
|
||
|
|
||
|
case ACPI_DESC_TYPE_OPERAND:
|
||
|
|
||
|
Type = ObjDesc->Common.Type;
|
||
|
if (Type > ACPI_TYPE_LOCAL_MAX)
|
||
|
{
|
||
|
AcpiOsPrintf (" Type %X [Invalid Type]", (UINT32) Type);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Decode the ACPI object type */
|
||
|
|
||
|
switch (ObjDesc->Common.Type)
|
||
|
{
|
||
|
case ACPI_TYPE_LOCAL_REFERENCE:
|
||
|
|
||
|
AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (ObjDesc));
|
||
|
|
||
|
/* Decode the refererence */
|
||
|
|
||
|
switch (ObjDesc->Reference.Class)
|
||
|
{
|
||
|
case ACPI_REFCLASS_LOCAL:
|
||
|
|
||
|
AcpiOsPrintf ("%X ", ObjDesc->Reference.Value);
|
||
|
if (WalkState)
|
||
|
{
|
||
|
ObjDesc = WalkState->LocalVariables
|
||
|
[ObjDesc->Reference.Value].Object;
|
||
|
AcpiOsPrintf ("%p", ObjDesc);
|
||
|
AcpiDbDecodeInternalObject (ObjDesc);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ACPI_REFCLASS_ARG:
|
||
|
|
||
|
AcpiOsPrintf ("%X ", ObjDesc->Reference.Value);
|
||
|
if (WalkState)
|
||
|
{
|
||
|
ObjDesc = WalkState->Arguments
|
||
|
[ObjDesc->Reference.Value].Object;
|
||
|
AcpiOsPrintf ("%p", ObjDesc);
|
||
|
AcpiDbDecodeInternalObject (ObjDesc);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ACPI_REFCLASS_INDEX:
|
||
|
|
||
|
switch (ObjDesc->Reference.TargetType)
|
||
|
{
|
||
|
case ACPI_TYPE_BUFFER_FIELD:
|
||
|
|
||
|
AcpiOsPrintf ("%p", ObjDesc->Reference.Object);
|
||
|
AcpiDbDecodeInternalObject (ObjDesc->Reference.Object);
|
||
|
break;
|
||
|
|
||
|
case ACPI_TYPE_PACKAGE:
|
||
|
|
||
|
AcpiOsPrintf ("%p", ObjDesc->Reference.Where);
|
||
|
if (!ObjDesc->Reference.Where)
|
||
|
{
|
||
|
AcpiOsPrintf (" Uninitialized WHERE pointer");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AcpiDbDecodeInternalObject (
|
||
|
*(ObjDesc->Reference.Where));
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
|
||
|
AcpiOsPrintf ("Unknown index target type");
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ACPI_REFCLASS_REFOF:
|
||
|
|
||
|
if (!ObjDesc->Reference.Object)
|
||
|
{
|
||
|
AcpiOsPrintf (
|
||
|
"Uninitialized reference subobject pointer");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Reference can be to a Node or an Operand object */
|
||
|
|
||
|
switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc->Reference.Object))
|
||
|
{
|
||
|
case ACPI_DESC_TYPE_NAMED:
|
||
|
|
||
|
AcpiDbDecodeNode (ObjDesc->Reference.Object);
|
||
|
break;
|
||
|
|
||
|
case ACPI_DESC_TYPE_OPERAND:
|
||
|
|
||
|
AcpiDbDecodeInternalObject (ObjDesc->Reference.Object);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ACPI_REFCLASS_NAME:
|
||
|
|
||
|
AcpiDbDecodeNode (ObjDesc->Reference.Node);
|
||
|
break;
|
||
|
|
||
|
case ACPI_REFCLASS_DEBUG:
|
||
|
case ACPI_REFCLASS_TABLE:
|
||
|
|
||
|
AcpiOsPrintf ("\n");
|
||
|
break;
|
||
|
|
||
|
default: /* Unknown reference class */
|
||
|
|
||
|
AcpiOsPrintf ("%2.2X\n", ObjDesc->Reference.Class);
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
|
||
|
AcpiOsPrintf ("<Obj> ");
|
||
|
AcpiDbDecodeInternalObject (ObjDesc);
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
|
||
|
AcpiOsPrintf ("<Not a valid ACPI Object Descriptor> [%s]",
|
||
|
AcpiUtGetDescriptorName (ObjDesc));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
AcpiOsPrintf ("\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* FUNCTION: AcpiDbDecodeLocals
|
||
|
*
|
||
|
* PARAMETERS: WalkState - State for current method
|
||
|
*
|
||
|
* RETURN: None
|
||
|
*
|
||
|
* DESCRIPTION: Display all locals for the currently running control method
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
void
|
||
|
AcpiDbDecodeLocals (
|
||
|
ACPI_WALK_STATE *WalkState)
|
||
|
{
|
||
|
UINT32 i;
|
||
|
ACPI_OPERAND_OBJECT *ObjDesc;
|
||
|
ACPI_NAMESPACE_NODE *Node;
|
||
|
BOOLEAN DisplayLocals = FALSE;
|
||
|
|
||
|
|
||
|
ObjDesc = WalkState->MethodDesc;
|
||
|
Node = WalkState->MethodNode;
|
||
|
|
||
|
if (!Node)
|
||
|
{
|
||
|
AcpiOsPrintf (
|
||
|
"No method node (Executing subtree for buffer or opregion)\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (Node->Type != ACPI_TYPE_METHOD)
|
||
|
{
|
||
|
AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Are any locals actually set? */
|
||
|
|
||
|
for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
|
||
|
{
|
||
|
ObjDesc = WalkState->LocalVariables[i].Object;
|
||
|
if (ObjDesc)
|
||
|
{
|
||
|
DisplayLocals = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* If any are set, only display the ones that are set */
|
||
|
|
||
|
if (DisplayLocals)
|
||
|
{
|
||
|
AcpiOsPrintf ("\nInitialized Local Variables for method [%4.4s]:\n",
|
||
|
AcpiUtGetNodeName (Node));
|
||
|
|
||
|
for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
|
||
|
{
|
||
|
ObjDesc = WalkState->LocalVariables[i].Object;
|
||
|
if (ObjDesc)
|
||
|
{
|
||
|
AcpiOsPrintf (" Local%X: ", i);
|
||
|
AcpiDbDisplayInternalObject (ObjDesc, WalkState);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AcpiOsPrintf (
|
||
|
"No Local Variables are initialized for method [%4.4s]\n",
|
||
|
AcpiUtGetNodeName (Node));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* FUNCTION: AcpiDbDecodeArguments
|
||
|
*
|
||
|
* PARAMETERS: WalkState - State for current method
|
||
|
*
|
||
|
* RETURN: None
|
||
|
*
|
||
|
* DESCRIPTION: Display all arguments for the currently running control method
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
void
|
||
|
AcpiDbDecodeArguments (
|
||
|
ACPI_WALK_STATE *WalkState)
|
||
|
{
|
||
|
UINT32 i;
|
||
|
ACPI_OPERAND_OBJECT *ObjDesc;
|
||
|
ACPI_NAMESPACE_NODE *Node;
|
||
|
BOOLEAN DisplayArgs = FALSE;
|
||
|
|
||
|
|
||
|
Node = WalkState->MethodNode;
|
||
|
ObjDesc = WalkState->MethodDesc;
|
||
|
|
||
|
if (!Node)
|
||
|
{
|
||
|
AcpiOsPrintf (
|
||
|
"No method node (Executing subtree for buffer or opregion)\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (Node->Type != ACPI_TYPE_METHOD)
|
||
|
{
|
||
|
AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Are any arguments actually set? */
|
||
|
|
||
|
for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
|
||
|
{
|
||
|
ObjDesc = WalkState->Arguments[i].Object;
|
||
|
if (ObjDesc)
|
||
|
{
|
||
|
DisplayArgs = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* If any are set, only display the ones that are set */
|
||
|
|
||
|
if (DisplayArgs)
|
||
|
{
|
||
|
AcpiOsPrintf (
|
||
|
"Initialized Arguments for Method [%4.4s]: "
|
||
|
"(%X arguments defined for method invocation)\n",
|
||
|
AcpiUtGetNodeName (Node), ObjDesc->Method.ParamCount);
|
||
|
|
||
|
for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
|
||
|
{
|
||
|
ObjDesc = WalkState->Arguments[i].Object;
|
||
|
if (ObjDesc)
|
||
|
{
|
||
|
AcpiOsPrintf (" Arg%u: ", i);
|
||
|
AcpiDbDisplayInternalObject (ObjDesc, WalkState);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AcpiOsPrintf (
|
||
|
"No Arguments are initialized for method [%4.4s]\n",
|
||
|
AcpiUtGetNodeName (Node));
|
||
|
}
|
||
|
}
|