1 /******************************************************************************* 2 * 3 * Module Name: dmobject - ACPI object decode and display 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 45 #include "acpi.h" 46 #include "accommon.h" 47 #include "acnamesp.h" 48 #include "acdisasm.h" 49 50 51 #ifdef ACPI_DISASSEMBLER 52 53 #define _COMPONENT ACPI_CA_DEBUGGER 54 ACPI_MODULE_NAME ("dmnames") 55 56 /* Local prototypes */ 57 58 static void 59 AcpiDmDecodeNode ( 60 ACPI_NAMESPACE_NODE *Node); 61 62 63 /******************************************************************************* 64 * 65 * FUNCTION: AcpiDmDumpMethodInfo 66 * 67 * PARAMETERS: Status - Method execution status 68 * WalkState - Current state of the parse tree walk 69 * Op - Executing parse op 70 * 71 * RETURN: None 72 * 73 * DESCRIPTION: Called when a method has been aborted because of an error. 74 * Dumps the method execution stack, and the method locals/args, 75 * and disassembles the AML opcode that failed. 76 * 77 ******************************************************************************/ 78 79 void 80 AcpiDmDumpMethodInfo ( 81 ACPI_STATUS Status, 82 ACPI_WALK_STATE *WalkState, 83 ACPI_PARSE_OBJECT *Op) 84 { 85 ACPI_PARSE_OBJECT *Next; 86 ACPI_THREAD_STATE *Thread; 87 ACPI_WALK_STATE *NextWalkState; 88 ACPI_NAMESPACE_NODE *PreviousMethod = NULL; 89 90 91 /* Ignore control codes, they are not errors */ 92 93 if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL) 94 { 95 return; 96 } 97 98 /* We may be executing a deferred opcode */ 99 100 if (WalkState->DeferredNode) 101 { 102 AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n"); 103 return; 104 } 105 106 /* 107 * If there is no Thread, we are not actually executing a method. 108 * This can happen when the iASL compiler calls the interpreter 109 * to perform constant folding. 110 */ 111 Thread = WalkState->Thread; 112 if (!Thread) 113 { 114 return; 115 } 116 117 /* Display exception and method name */ 118 119 AcpiOsPrintf ("\n**** Exception %s during execution of method ", 120 AcpiFormatException (Status)); 121 AcpiNsPrintNodePathname (WalkState->MethodNode, NULL); 122 123 /* Display stack of executing methods */ 124 125 AcpiOsPrintf ("\n\nMethod Execution Stack:\n"); 126 NextWalkState = Thread->WalkStateList; 127 128 /* Walk list of linked walk states */ 129 130 while (NextWalkState) 131 { 132 AcpiOsPrintf (" Method [%4.4s] executing: ", 133 AcpiUtGetNodeName (NextWalkState->MethodNode)); 134 135 /* First method is the currently executing method */ 136 137 if (NextWalkState == WalkState) 138 { 139 if (Op) 140 { 141 /* Display currently executing ASL statement */ 142 143 Next = Op->Common.Next; 144 Op->Common.Next = NULL; 145 146 AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX); 147 Op->Common.Next = Next; 148 } 149 } 150 else 151 { 152 /* 153 * This method has called another method 154 * NOTE: the method call parse subtree is already deleted at this 155 * point, so we cannot disassemble the method invocation. 156 */ 157 AcpiOsPrintf ("Call to method "); 158 AcpiNsPrintNodePathname (PreviousMethod, NULL); 159 } 160 161 PreviousMethod = NextWalkState->MethodNode; 162 NextWalkState = NextWalkState->Next; 163 AcpiOsPrintf ("\n"); 164 } 165 166 /* Display the method locals and arguments */ 167 168 AcpiOsPrintf ("\n"); 169 AcpiDmDisplayLocals (WalkState); 170 AcpiOsPrintf ("\n"); 171 AcpiDmDisplayArguments (WalkState); 172 AcpiOsPrintf ("\n"); 173 } 174 175 176 /******************************************************************************* 177 * 178 * FUNCTION: AcpiDmDecodeInternalObject 179 * 180 * PARAMETERS: ObjDesc - Object to be displayed 181 * 182 * RETURN: None 183 * 184 * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers. 185 * 186 ******************************************************************************/ 187 188 void 189 AcpiDmDecodeInternalObject ( 190 ACPI_OPERAND_OBJECT *ObjDesc) 191 { 192 UINT32 i; 193 194 195 if (!ObjDesc) 196 { 197 AcpiOsPrintf (" Uninitialized"); 198 return; 199 } 200 201 if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND) 202 { 203 AcpiOsPrintf (" %p [%s]", ObjDesc, AcpiUtGetDescriptorName (ObjDesc)); 204 return; 205 } 206 207 AcpiOsPrintf (" %s", AcpiUtGetObjectTypeName (ObjDesc)); 208 209 switch (ObjDesc->Common.Type) 210 { 211 case ACPI_TYPE_INTEGER: 212 213 AcpiOsPrintf (" %8.8X%8.8X", 214 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); 215 break; 216 217 case ACPI_TYPE_STRING: 218 219 AcpiOsPrintf ("(%u) \"%.24s", 220 ObjDesc->String.Length, ObjDesc->String.Pointer); 221 222 if (ObjDesc->String.Length > 24) 223 { 224 AcpiOsPrintf ("..."); 225 } 226 else 227 { 228 AcpiOsPrintf ("\""); 229 } 230 break; 231 232 case ACPI_TYPE_BUFFER: 233 234 AcpiOsPrintf ("(%u)", ObjDesc->Buffer.Length); 235 for (i = 0; (i < 8) && (i < ObjDesc->Buffer.Length); i++) 236 { 237 AcpiOsPrintf (" %2.2X", ObjDesc->Buffer.Pointer[i]); 238 } 239 break; 240 241 default: 242 243 AcpiOsPrintf (" %p", ObjDesc); 244 break; 245 } 246 } 247 248 249 /******************************************************************************* 250 * 251 * FUNCTION: AcpiDmDecodeNode 252 * 253 * PARAMETERS: Node - Object to be displayed 254 * 255 * RETURN: None 256 * 257 * DESCRIPTION: Short display of a namespace node 258 * 259 ******************************************************************************/ 260 261 static void 262 AcpiDmDecodeNode ( 263 ACPI_NAMESPACE_NODE *Node) 264 { 265 266 AcpiOsPrintf ("<Node> Name %4.4s", 267 AcpiUtGetNodeName (Node)); 268 269 if (Node->Flags & ANOBJ_METHOD_ARG) 270 { 271 AcpiOsPrintf (" [Method Arg]"); 272 } 273 if (Node->Flags & ANOBJ_METHOD_LOCAL) 274 { 275 AcpiOsPrintf (" [Method Local]"); 276 } 277 278 switch (Node->Type) 279 { 280 /* These types have no attached object */ 281 282 case ACPI_TYPE_DEVICE: 283 284 AcpiOsPrintf (" Device"); 285 break; 286 287 case ACPI_TYPE_THERMAL: 288 289 AcpiOsPrintf (" Thermal Zone"); 290 break; 291 292 default: 293 294 AcpiDmDecodeInternalObject (AcpiNsGetAttachedObject (Node)); 295 break; 296 } 297 } 298 299 300 /******************************************************************************* 301 * 302 * FUNCTION: AcpiDmDisplayInternalObject 303 * 304 * PARAMETERS: ObjDesc - Object to be displayed 305 * WalkState - Current walk state 306 * 307 * RETURN: None 308 * 309 * DESCRIPTION: Short display of an internal object 310 * 311 ******************************************************************************/ 312 313 void 314 AcpiDmDisplayInternalObject ( 315 ACPI_OPERAND_OBJECT *ObjDesc, 316 ACPI_WALK_STATE *WalkState) 317 { 318 UINT8 Type; 319 320 321 AcpiOsPrintf ("%p ", ObjDesc); 322 323 if (!ObjDesc) 324 { 325 AcpiOsPrintf ("<Null Object>\n"); 326 return; 327 } 328 329 /* Decode the object type */ 330 331 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)) 332 { 333 case ACPI_DESC_TYPE_PARSER: 334 335 AcpiOsPrintf ("<Parser> "); 336 break; 337 338 case ACPI_DESC_TYPE_NAMED: 339 340 AcpiDmDecodeNode ((ACPI_NAMESPACE_NODE *) ObjDesc); 341 break; 342 343 case ACPI_DESC_TYPE_OPERAND: 344 345 Type = ObjDesc->Common.Type; 346 if (Type > ACPI_TYPE_LOCAL_MAX) 347 { 348 AcpiOsPrintf (" Type %X [Invalid Type]", (UINT32) Type); 349 return; 350 } 351 352 /* Decode the ACPI object type */ 353 354 switch (ObjDesc->Common.Type) 355 { 356 case ACPI_TYPE_LOCAL_REFERENCE: 357 358 AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (ObjDesc)); 359 360 /* Decode the refererence */ 361 362 switch (ObjDesc->Reference.Class) 363 { 364 case ACPI_REFCLASS_LOCAL: 365 366 AcpiOsPrintf ("%X ", ObjDesc->Reference.Value); 367 if (WalkState) 368 { 369 ObjDesc = WalkState->LocalVariables 370 [ObjDesc->Reference.Value].Object; 371 AcpiOsPrintf ("%p", ObjDesc); 372 AcpiDmDecodeInternalObject (ObjDesc); 373 } 374 break; 375 376 case ACPI_REFCLASS_ARG: 377 378 AcpiOsPrintf ("%X ", ObjDesc->Reference.Value); 379 if (WalkState) 380 { 381 ObjDesc = WalkState->Arguments 382 [ObjDesc->Reference.Value].Object; 383 AcpiOsPrintf ("%p", ObjDesc); 384 AcpiDmDecodeInternalObject (ObjDesc); 385 } 386 break; 387 388 case ACPI_REFCLASS_INDEX: 389 390 switch (ObjDesc->Reference.TargetType) 391 { 392 case ACPI_TYPE_BUFFER_FIELD: 393 394 AcpiOsPrintf ("%p", ObjDesc->Reference.Object); 395 AcpiDmDecodeInternalObject (ObjDesc->Reference.Object); 396 break; 397 398 case ACPI_TYPE_PACKAGE: 399 400 AcpiOsPrintf ("%p", ObjDesc->Reference.Where); 401 if (!ObjDesc->Reference.Where) 402 { 403 AcpiOsPrintf (" Uninitialized WHERE pointer"); 404 } 405 else 406 { 407 AcpiDmDecodeInternalObject ( 408 *(ObjDesc->Reference.Where)); 409 } 410 break; 411 412 default: 413 414 AcpiOsPrintf ("Unknown index target type"); 415 break; 416 } 417 break; 418 419 case ACPI_REFCLASS_REFOF: 420 421 if (!ObjDesc->Reference.Object) 422 { 423 AcpiOsPrintf ("Uninitialized reference subobject pointer"); 424 break; 425 } 426 427 /* Reference can be to a Node or an Operand object */ 428 429 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc->Reference.Object)) 430 { 431 case ACPI_DESC_TYPE_NAMED: 432 AcpiDmDecodeNode (ObjDesc->Reference.Object); 433 break; 434 435 case ACPI_DESC_TYPE_OPERAND: 436 AcpiDmDecodeInternalObject (ObjDesc->Reference.Object); 437 break; 438 439 default: 440 break; 441 } 442 break; 443 444 case ACPI_REFCLASS_NAME: 445 446 AcpiDmDecodeNode (ObjDesc->Reference.Node); 447 break; 448 449 case ACPI_REFCLASS_DEBUG: 450 case ACPI_REFCLASS_TABLE: 451 452 AcpiOsPrintf ("\n"); 453 break; 454 455 default: /* Unknown reference class */ 456 457 AcpiOsPrintf ("%2.2X\n", ObjDesc->Reference.Class); 458 break; 459 } 460 break; 461 462 default: 463 464 AcpiOsPrintf ("<Obj> "); 465 AcpiDmDecodeInternalObject (ObjDesc); 466 break; 467 } 468 break; 469 470 default: 471 472 AcpiOsPrintf ("<Not a valid ACPI Object Descriptor> [%s]", 473 AcpiUtGetDescriptorName (ObjDesc)); 474 break; 475 } 476 477 AcpiOsPrintf ("\n"); 478 } 479 480 481 /******************************************************************************* 482 * 483 * FUNCTION: AcpiDmDisplayLocals 484 * 485 * PARAMETERS: WalkState - State for current method 486 * 487 * RETURN: None 488 * 489 * DESCRIPTION: Display all locals for the currently running control method 490 * 491 ******************************************************************************/ 492 493 void 494 AcpiDmDisplayLocals ( 495 ACPI_WALK_STATE *WalkState) 496 { 497 UINT32 i; 498 ACPI_OPERAND_OBJECT *ObjDesc; 499 ACPI_NAMESPACE_NODE *Node; 500 501 502 ObjDesc = WalkState->MethodDesc; 503 Node = WalkState->MethodNode; 504 if (!Node) 505 { 506 AcpiOsPrintf ( 507 "No method node (Executing subtree for buffer or opregion)\n"); 508 return; 509 } 510 511 if (Node->Type != ACPI_TYPE_METHOD) 512 { 513 AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n"); 514 return; 515 } 516 517 AcpiOsPrintf ("Local Variables for method [%4.4s]:\n", 518 AcpiUtGetNodeName (Node)); 519 520 for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) 521 { 522 ObjDesc = WalkState->LocalVariables[i].Object; 523 AcpiOsPrintf (" Local%X: ", i); 524 AcpiDmDisplayInternalObject (ObjDesc, WalkState); 525 } 526 } 527 528 529 /******************************************************************************* 530 * 531 * FUNCTION: AcpiDmDisplayArguments 532 * 533 * PARAMETERS: WalkState - State for current method 534 * 535 * RETURN: None 536 * 537 * DESCRIPTION: Display all arguments for the currently running control method 538 * 539 ******************************************************************************/ 540 541 void 542 AcpiDmDisplayArguments ( 543 ACPI_WALK_STATE *WalkState) 544 { 545 UINT32 i; 546 ACPI_OPERAND_OBJECT *ObjDesc; 547 ACPI_NAMESPACE_NODE *Node; 548 549 550 ObjDesc = WalkState->MethodDesc; 551 Node = WalkState->MethodNode; 552 if (!Node) 553 { 554 AcpiOsPrintf ( 555 "No method node (Executing subtree for buffer or opregion)\n"); 556 return; 557 } 558 559 if (Node->Type != ACPI_TYPE_METHOD) 560 { 561 AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n"); 562 return; 563 } 564 565 AcpiOsPrintf ( 566 "Arguments for Method [%4.4s]: (%X arguments defined, max concurrency = %X)\n", 567 AcpiUtGetNodeName (Node), ObjDesc->Method.ParamCount, ObjDesc->Method.SyncLevel); 568 569 for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) 570 { 571 ObjDesc = WalkState->Arguments[i].Object; 572 AcpiOsPrintf (" Arg%u: ", i); 573 AcpiDmDisplayInternalObject (ObjDesc, WalkState); 574 } 575 } 576 577 #endif