diff options
Diffstat (limited to 'sys/contrib/dev/acpica/components/debugger/dbobject.c')
-rw-r--r-- | sys/contrib/dev/acpica/components/debugger/dbobject.c | 580 |
1 files changed, 580 insertions, 0 deletions
diff --git a/sys/contrib/dev/acpica/components/debugger/dbobject.c b/sys/contrib/dev/acpica/components/debugger/dbobject.c new file mode 100644 index 0000000..062ad25 --- /dev/null +++ b/sys/contrib/dev/acpica/components/debugger/dbobject.c @@ -0,0 +1,580 @@ +/******************************************************************************* + * + * 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)); + } +} |