1285728Sjkim/****************************************************************************** 2285728Sjkim * 3285728Sjkim * Module Name: dsdebug - Parser/Interpreter interface - debugging 4285728Sjkim * 5285728Sjkim *****************************************************************************/ 6285728Sjkim 7285728Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9285728Sjkim * All rights reserved. 10285728Sjkim * 11285728Sjkim * Redistribution and use in source and binary forms, with or without 12285728Sjkim * modification, are permitted provided that the following conditions 13285728Sjkim * are met: 14285728Sjkim * 1. Redistributions of source code must retain the above copyright 15285728Sjkim * notice, this list of conditions, and the following disclaimer, 16285728Sjkim * without modification. 17285728Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18285728Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19285728Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20285728Sjkim * including a substantially similar Disclaimer requirement for further 21285728Sjkim * binary redistribution. 22285728Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23285728Sjkim * of any contributors may be used to endorse or promote products derived 24285728Sjkim * from this software without specific prior written permission. 25285728Sjkim * 26285728Sjkim * Alternatively, this software may be distributed under the terms of the 27285728Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28285728Sjkim * Software Foundation. 29285728Sjkim * 30285728Sjkim * NO WARRANTY 31285728Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32285728Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33285728Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34285728Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35285728Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36285728Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37285728Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38285728Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39285728Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40285728Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41285728Sjkim * POSSIBILITY OF SUCH DAMAGES. 42285728Sjkim */ 43285728Sjkim 44285797Sjkim#include <contrib/dev/acpica/include/acpi.h> 45285797Sjkim#include <contrib/dev/acpica/include/accommon.h> 46285797Sjkim#include <contrib/dev/acpica/include/acdispat.h> 47285797Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 48285797Sjkim#include <contrib/dev/acpica/include/acdisasm.h> 49285797Sjkim#include <contrib/dev/acpica/include/acinterp.h> 50285728Sjkim 51285728Sjkim 52285728Sjkim#define _COMPONENT ACPI_DISPATCHER 53285728Sjkim ACPI_MODULE_NAME ("dsdebug") 54285728Sjkim 55285728Sjkim 56285728Sjkim#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) 57285728Sjkim 58285728Sjkim/* Local prototypes */ 59285728Sjkim 60285728Sjkimstatic void 61285728SjkimAcpiDsPrintNodePathname ( 62285728Sjkim ACPI_NAMESPACE_NODE *Node, 63285728Sjkim const char *Message); 64285728Sjkim 65285728Sjkim 66285728Sjkim/******************************************************************************* 67285728Sjkim * 68285728Sjkim * FUNCTION: AcpiDsPrintNodePathname 69285728Sjkim * 70285728Sjkim * PARAMETERS: Node - Object 71285728Sjkim * Message - Prefix message 72285728Sjkim * 73285728Sjkim * DESCRIPTION: Print an object's full namespace pathname 74285728Sjkim * Manages allocation/freeing of a pathname buffer 75285728Sjkim * 76285728Sjkim ******************************************************************************/ 77285728Sjkim 78285728Sjkimstatic void 79285728SjkimAcpiDsPrintNodePathname ( 80285728Sjkim ACPI_NAMESPACE_NODE *Node, 81285728Sjkim const char *Message) 82285728Sjkim{ 83285728Sjkim ACPI_BUFFER Buffer; 84285728Sjkim ACPI_STATUS Status; 85285728Sjkim 86285728Sjkim 87285728Sjkim ACPI_FUNCTION_TRACE (DsPrintNodePathname); 88285728Sjkim 89285728Sjkim if (!Node) 90285728Sjkim { 91285728Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[NULL NAME]")); 92285728Sjkim return_VOID; 93285728Sjkim } 94285728Sjkim 95285728Sjkim /* Convert handle to full pathname and print it (with supplied message) */ 96285728Sjkim 97285728Sjkim Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 98285728Sjkim 99306536Sjkim Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE); 100285728Sjkim if (ACPI_SUCCESS (Status)) 101285728Sjkim { 102285728Sjkim if (Message) 103285728Sjkim { 104285728Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "%s ", Message)); 105285728Sjkim } 106285728Sjkim 107285728Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[%s] (Node %p)", 108285728Sjkim (char *) Buffer.Pointer, Node)); 109285728Sjkim ACPI_FREE (Buffer.Pointer); 110285728Sjkim } 111285728Sjkim 112285728Sjkim return_VOID; 113285728Sjkim} 114285728Sjkim 115285728Sjkim 116285728Sjkim/******************************************************************************* 117285728Sjkim * 118285728Sjkim * FUNCTION: AcpiDsDumpMethodStack 119285728Sjkim * 120285728Sjkim * PARAMETERS: Status - Method execution status 121285728Sjkim * WalkState - Current state of the parse tree walk 122285728Sjkim * Op - Executing parse op 123285728Sjkim * 124285728Sjkim * RETURN: None 125285728Sjkim * 126285728Sjkim * DESCRIPTION: Called when a method has been aborted because of an error. 127285728Sjkim * Dumps the method execution stack. 128285728Sjkim * 129285728Sjkim ******************************************************************************/ 130285728Sjkim 131285728Sjkimvoid 132285728SjkimAcpiDsDumpMethodStack ( 133285728Sjkim ACPI_STATUS Status, 134285728Sjkim ACPI_WALK_STATE *WalkState, 135285728Sjkim ACPI_PARSE_OBJECT *Op) 136285728Sjkim{ 137285728Sjkim ACPI_PARSE_OBJECT *Next; 138285728Sjkim ACPI_THREAD_STATE *Thread; 139285728Sjkim ACPI_WALK_STATE *NextWalkState; 140285728Sjkim ACPI_NAMESPACE_NODE *PreviousMethod = NULL; 141285728Sjkim ACPI_OPERAND_OBJECT *MethodDesc; 142285728Sjkim 143285728Sjkim 144285728Sjkim ACPI_FUNCTION_TRACE (DsDumpMethodStack); 145285728Sjkim 146285728Sjkim /* Ignore control codes, they are not errors */ 147285728Sjkim 148285728Sjkim if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL) 149285728Sjkim { 150285728Sjkim return_VOID; 151285728Sjkim } 152285728Sjkim 153285728Sjkim /* We may be executing a deferred opcode */ 154285728Sjkim 155285728Sjkim if (WalkState->DeferredNode) 156285728Sjkim { 157285728Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 158285728Sjkim "Executing subtree for Buffer/Package/Region\n")); 159285728Sjkim return_VOID; 160285728Sjkim } 161285728Sjkim 162285728Sjkim /* 163285728Sjkim * If there is no Thread, we are not actually executing a method. 164285728Sjkim * This can happen when the iASL compiler calls the interpreter 165285728Sjkim * to perform constant folding. 166285728Sjkim */ 167285728Sjkim Thread = WalkState->Thread; 168285728Sjkim if (!Thread) 169285728Sjkim { 170285728Sjkim return_VOID; 171285728Sjkim } 172285728Sjkim 173285728Sjkim /* Display exception and method name */ 174285728Sjkim 175285728Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 176285728Sjkim "\n**** Exception %s during execution of method ", 177285728Sjkim AcpiFormatException (Status))); 178306536Sjkim 179285728Sjkim AcpiDsPrintNodePathname (WalkState->MethodNode, NULL); 180285728Sjkim 181285728Sjkim /* Display stack of executing methods */ 182285728Sjkim 183285728Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, 184285728Sjkim "\n\nMethod Execution Stack:\n")); 185285728Sjkim NextWalkState = Thread->WalkStateList; 186285728Sjkim 187285728Sjkim /* Walk list of linked walk states */ 188285728Sjkim 189285728Sjkim while (NextWalkState) 190285728Sjkim { 191285728Sjkim MethodDesc = NextWalkState->MethodDesc; 192285728Sjkim if (MethodDesc) 193285728Sjkim { 194285728Sjkim AcpiExStopTraceMethod ( 195306536Sjkim (ACPI_NAMESPACE_NODE *) MethodDesc->Method.Node, 196306536Sjkim MethodDesc, WalkState); 197285728Sjkim } 198285728Sjkim 199285728Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 200285728Sjkim " Method [%4.4s] executing: ", 201285728Sjkim AcpiUtGetNodeName (NextWalkState->MethodNode))); 202285728Sjkim 203285728Sjkim /* First method is the currently executing method */ 204285728Sjkim 205285728Sjkim if (NextWalkState == WalkState) 206285728Sjkim { 207285728Sjkim if (Op) 208285728Sjkim { 209285728Sjkim /* Display currently executing ASL statement */ 210285728Sjkim 211285728Sjkim Next = Op->Common.Next; 212285728Sjkim Op->Common.Next = NULL; 213285728Sjkim 214285728Sjkim#ifdef ACPI_DISASSEMBLER 215285728Sjkim AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX); 216285728Sjkim#endif 217285728Sjkim Op->Common.Next = Next; 218285728Sjkim } 219285728Sjkim } 220285728Sjkim else 221285728Sjkim { 222285728Sjkim /* 223285728Sjkim * This method has called another method 224306536Sjkim * NOTE: the method call parse subtree is already deleted at 225306536Sjkim * this point, so we cannot disassemble the method invocation. 226285728Sjkim */ 227285728Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Call to method ")); 228285728Sjkim AcpiDsPrintNodePathname (PreviousMethod, NULL); 229285728Sjkim } 230285728Sjkim 231285728Sjkim PreviousMethod = NextWalkState->MethodNode; 232285728Sjkim NextWalkState = NextWalkState->Next; 233285728Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "\n")); 234285728Sjkim } 235285728Sjkim 236285728Sjkim return_VOID; 237285728Sjkim} 238285728Sjkim 239285728Sjkim#else 240285728Sjkim 241285728Sjkimvoid 242285728SjkimAcpiDsDumpMethodStack ( 243285728Sjkim ACPI_STATUS Status, 244285728Sjkim ACPI_WALK_STATE *WalkState, 245285728Sjkim ACPI_PARSE_OBJECT *Op) 246285728Sjkim{ 247285728Sjkim return; 248285728Sjkim} 249285728Sjkim 250285728Sjkim#endif 251