1 /******************************************************************************* 2 * 3 * Module Name: dbobject - ACPI object decode and display 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2020, 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 #include "acpi.h" 45 #include "accommon.h" 46 #include "acnamesp.h" 47 #include "acdebug.h" 48 49 50 #define _COMPONENT ACPI_CA_DEBUGGER 51 ACPI_MODULE_NAME ("dbobject") 52 53 54 /* Local prototypes */ 55 56 static void 57 AcpiDbDecodeNode ( 58 ACPI_NAMESPACE_NODE *Node); 59 60 61 /******************************************************************************* 62 * 63 * FUNCTION: AcpiDbDumpMethodInfo 64 * 65 * PARAMETERS: Status - Method execution status 66 * WalkState - Current state of the parse tree walk 67 * 68 * RETURN: None 69 * 70 * DESCRIPTION: Called when a method has been aborted because of an error. 71 * Dumps the method execution stack, and the method locals/args, 72 * and disassembles the AML opcode that failed. 73 * 74 ******************************************************************************/ 75 76 void 77 AcpiDbDumpMethodInfo ( 78 ACPI_STATUS Status, 79 ACPI_WALK_STATE *WalkState) 80 { 81 ACPI_THREAD_STATE *Thread; 82 ACPI_NAMESPACE_NODE *Node; 83 84 85 Node = WalkState->MethodNode; 86 87 /* There are no locals or arguments for the module-level code case */ 88 89 if (Node == AcpiGbl_RootNode) 90 { 91 return; 92 } 93 94 /* Ignore control codes, they are not errors */ 95 96 if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL) 97 { 98 return; 99 } 100 101 /* We may be executing a deferred opcode */ 102 103 if (WalkState->DeferredNode) 104 { 105 AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n"); 106 return; 107 } 108 109 /* 110 * If there is no Thread, we are not actually executing a method. 111 * This can happen when the iASL compiler calls the interpreter 112 * to perform constant folding. 113 */ 114 Thread = WalkState->Thread; 115 if (!Thread) 116 { 117 return; 118 } 119 120 /* Display the method locals and arguments */ 121 122 AcpiOsPrintf ("\n"); 123 AcpiDbDecodeLocals (WalkState); 124 AcpiOsPrintf ("\n"); 125 AcpiDbDecodeArguments (WalkState); 126 AcpiOsPrintf ("\n"); 127 } 128 129 130 /******************************************************************************* 131 * 132 * FUNCTION: AcpiDbDecodeInternalObject 133 * 134 * PARAMETERS: ObjDesc - Object to be displayed 135 * 136 * RETURN: None 137 * 138 * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers. 139 * 140 ******************************************************************************/ 141 142 void 143 AcpiDbDecodeInternalObject ( 144 ACPI_OPERAND_OBJECT *ObjDesc) 145 { 146 UINT32 i; 147 148 149 if (!ObjDesc) 150 { 151 AcpiOsPrintf (" Uninitialized"); 152 return; 153 } 154 155 if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND) 156 { 157 AcpiOsPrintf (" %p [%s]", ObjDesc, 158 AcpiUtGetDescriptorName (ObjDesc)); 159 return; 160 } 161 162 AcpiOsPrintf (" %s", AcpiUtGetObjectTypeName (ObjDesc)); 163 164 switch (ObjDesc->Common.Type) 165 { 166 case ACPI_TYPE_INTEGER: 167 168 AcpiOsPrintf (" %8.8X%8.8X", 169 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); 170 break; 171 172 case ACPI_TYPE_STRING: 173 174 AcpiOsPrintf ("(%u) \"%.60s", 175 ObjDesc->String.Length, ObjDesc->String.Pointer); 176 177 if (ObjDesc->String.Length > 60) 178 { 179 AcpiOsPrintf ("..."); 180 } 181 else 182 { 183 AcpiOsPrintf ("\""); 184 } 185 break; 186 187 case ACPI_TYPE_BUFFER: 188 189 AcpiOsPrintf ("(%u)", ObjDesc->Buffer.Length); 190 for (i = 0; (i < 8) && (i < ObjDesc->Buffer.Length); i++) 191 { 192 AcpiOsPrintf (" %2.2X", ObjDesc->Buffer.Pointer[i]); 193 } 194 break; 195 196 default: 197 198 AcpiOsPrintf (" %p", ObjDesc); 199 break; 200 } 201 } 202 203 204 /******************************************************************************* 205 * 206 * FUNCTION: AcpiDbDecodeNode 207 * 208 * PARAMETERS: Node - Object to be displayed 209 * 210 * RETURN: None 211 * 212 * DESCRIPTION: Short display of a namespace node 213 * 214 ******************************************************************************/ 215 216 static void 217 AcpiDbDecodeNode ( 218 ACPI_NAMESPACE_NODE *Node) 219 { 220 221 AcpiOsPrintf ("<Node> Name %4.4s", 222 AcpiUtGetNodeName (Node)); 223 224 if (Node->Flags & ANOBJ_METHOD_ARG) 225 { 226 AcpiOsPrintf (" [Method Arg]"); 227 } 228 if (Node->Flags & ANOBJ_METHOD_LOCAL) 229 { 230 AcpiOsPrintf (" [Method Local]"); 231 } 232 233 switch (Node->Type) 234 { 235 /* These types have no attached object */ 236 237 case ACPI_TYPE_DEVICE: 238 239 AcpiOsPrintf (" Device"); 240 break; 241 242 case ACPI_TYPE_THERMAL: 243 244 AcpiOsPrintf (" Thermal Zone"); 245 break; 246 247 default: 248 249 AcpiDbDecodeInternalObject (AcpiNsGetAttachedObject (Node)); 250 break; 251 } 252 } 253 254 255 /******************************************************************************* 256 * 257 * FUNCTION: AcpiDbDisplayInternalObject 258 * 259 * PARAMETERS: ObjDesc - Object to be displayed 260 * WalkState - Current walk state 261 * 262 * RETURN: None 263 * 264 * DESCRIPTION: Short display of an internal object 265 * 266 ******************************************************************************/ 267 268 void 269 AcpiDbDisplayInternalObject ( 270 ACPI_OPERAND_OBJECT *ObjDesc, 271 ACPI_WALK_STATE *WalkState) 272 { 273 UINT8 Type; 274 275 276 AcpiOsPrintf ("%p ", ObjDesc); 277 278 if (!ObjDesc) 279 { 280 AcpiOsPrintf ("<Null Object>\n"); 281 return; 282 } 283 284 /* Decode the object type */ 285 286 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)) 287 { 288 case ACPI_DESC_TYPE_PARSER: 289 290 AcpiOsPrintf ("<Parser> "); 291 break; 292 293 case ACPI_DESC_TYPE_NAMED: 294 295 AcpiDbDecodeNode ((ACPI_NAMESPACE_NODE *) ObjDesc); 296 break; 297 298 case ACPI_DESC_TYPE_OPERAND: 299 300 Type = ObjDesc->Common.Type; 301 if (Type > ACPI_TYPE_LOCAL_MAX) 302 { 303 AcpiOsPrintf (" Type %X [Invalid Type]", (UINT32) Type); 304 return; 305 } 306 307 /* Decode the ACPI object type */ 308 309 switch (ObjDesc->Common.Type) 310 { 311 case ACPI_TYPE_LOCAL_REFERENCE: 312 313 AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (ObjDesc)); 314 315 /* Decode the reference */ 316 317 switch (ObjDesc->Reference.Class) 318 { 319 case ACPI_REFCLASS_LOCAL: 320 321 AcpiOsPrintf ("%X ", ObjDesc->Reference.Value); 322 if (WalkState) 323 { 324 ObjDesc = WalkState->LocalVariables 325 [ObjDesc->Reference.Value].Object; 326 AcpiOsPrintf ("%p", ObjDesc); 327 AcpiDbDecodeInternalObject (ObjDesc); 328 } 329 break; 330 331 case ACPI_REFCLASS_ARG: 332 333 AcpiOsPrintf ("%X ", ObjDesc->Reference.Value); 334 if (WalkState) 335 { 336 ObjDesc = WalkState->Arguments 337 [ObjDesc->Reference.Value].Object; 338 AcpiOsPrintf ("%p", ObjDesc); 339 AcpiDbDecodeInternalObject (ObjDesc); 340 } 341 break; 342 343 case ACPI_REFCLASS_INDEX: 344 345 switch (ObjDesc->Reference.TargetType) 346 { 347 case ACPI_TYPE_BUFFER_FIELD: 348 349 AcpiOsPrintf ("%p", ObjDesc->Reference.Object); 350 AcpiDbDecodeInternalObject (ObjDesc->Reference.Object); 351 break; 352 353 case ACPI_TYPE_PACKAGE: 354 355 AcpiOsPrintf ("%p", ObjDesc->Reference.Where); 356 if (!ObjDesc->Reference.Where) 357 { 358 AcpiOsPrintf (" Uninitialized WHERE pointer"); 359 } 360 else 361 { 362 AcpiDbDecodeInternalObject ( 363 *(ObjDesc->Reference.Where)); 364 } 365 break; 366 367 default: 368 369 AcpiOsPrintf ("Unknown index target type"); 370 break; 371 } 372 break; 373 374 case ACPI_REFCLASS_REFOF: 375 376 if (!ObjDesc->Reference.Object) 377 { 378 AcpiOsPrintf ( 379 "Uninitialized reference subobject pointer"); 380 break; 381 } 382 383 /* Reference can be to a Node or an Operand object */ 384 385 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc->Reference.Object)) 386 { 387 case ACPI_DESC_TYPE_NAMED: 388 389 AcpiDbDecodeNode (ObjDesc->Reference.Object); 390 break; 391 392 case ACPI_DESC_TYPE_OPERAND: 393 394 AcpiDbDecodeInternalObject (ObjDesc->Reference.Object); 395 break; 396 397 default: 398 break; 399 } 400 break; 401 402 case ACPI_REFCLASS_NAME: 403 404 AcpiDbDecodeNode (ObjDesc->Reference.Node); 405 break; 406 407 case ACPI_REFCLASS_DEBUG: 408 case ACPI_REFCLASS_TABLE: 409 410 AcpiOsPrintf ("\n"); 411 break; 412 413 default: /* Unknown reference class */ 414 415 AcpiOsPrintf ("%2.2X\n", ObjDesc->Reference.Class); 416 break; 417 } 418 break; 419 420 default: 421 422 AcpiOsPrintf ("<Obj> "); 423 AcpiDbDecodeInternalObject (ObjDesc); 424 break; 425 } 426 break; 427 428 default: 429 430 AcpiOsPrintf ("<Not a valid ACPI Object Descriptor> [%s]", 431 AcpiUtGetDescriptorName (ObjDesc)); 432 break; 433 } 434 435 AcpiOsPrintf ("\n"); 436 } 437 438 439 /******************************************************************************* 440 * 441 * FUNCTION: AcpiDbDecodeLocals 442 * 443 * PARAMETERS: WalkState - State for current method 444 * 445 * RETURN: None 446 * 447 * DESCRIPTION: Display all locals for the currently running control method 448 * 449 ******************************************************************************/ 450 451 void 452 AcpiDbDecodeLocals ( 453 ACPI_WALK_STATE *WalkState) 454 { 455 UINT32 i; 456 ACPI_OPERAND_OBJECT *ObjDesc; 457 ACPI_NAMESPACE_NODE *Node; 458 BOOLEAN DisplayLocals = FALSE; 459 460 461 Node = WalkState->MethodNode; 462 463 /* There are no locals for the module-level code case */ 464 465 if (Node == AcpiGbl_RootNode) 466 { 467 return; 468 } 469 470 if (!Node) 471 { 472 AcpiOsPrintf ( 473 "No method node (Executing subtree for buffer or opregion)\n"); 474 return; 475 } 476 477 if (Node->Type != ACPI_TYPE_METHOD) 478 { 479 AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n"); 480 return; 481 } 482 483 /* Are any locals actually set? */ 484 485 for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) 486 { 487 ObjDesc = WalkState->LocalVariables[i].Object; 488 if (ObjDesc) 489 { 490 DisplayLocals = TRUE; 491 break; 492 } 493 } 494 495 /* If any are set, only display the ones that are set */ 496 497 if (DisplayLocals) 498 { 499 AcpiOsPrintf ("\nInitialized Local Variables for Method [%4.4s]:\n", 500 AcpiUtGetNodeName (Node)); 501 502 for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) 503 { 504 ObjDesc = WalkState->LocalVariables[i].Object; 505 if (ObjDesc) 506 { 507 AcpiOsPrintf (" Local%X: ", i); 508 AcpiDbDisplayInternalObject (ObjDesc, WalkState); 509 } 510 } 511 } 512 else 513 { 514 AcpiOsPrintf ( 515 "No Local Variables are initialized for Method [%4.4s]\n", 516 AcpiUtGetNodeName (Node)); 517 } 518 } 519 520 521 /******************************************************************************* 522 * 523 * FUNCTION: AcpiDbDecodeArguments 524 * 525 * PARAMETERS: WalkState - State for current method 526 * 527 * RETURN: None 528 * 529 * DESCRIPTION: Display all arguments for the currently running control method 530 * 531 ******************************************************************************/ 532 533 void 534 AcpiDbDecodeArguments ( 535 ACPI_WALK_STATE *WalkState) 536 { 537 UINT32 i; 538 ACPI_OPERAND_OBJECT *ObjDesc; 539 ACPI_NAMESPACE_NODE *Node; 540 BOOLEAN DisplayArgs = FALSE; 541 542 543 Node = WalkState->MethodNode; 544 545 /* There are no arguments for the module-level code case */ 546 547 if (Node == AcpiGbl_RootNode) 548 { 549 return; 550 } 551 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 /* Are any arguments actually set? */ 566 567 for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) 568 { 569 ObjDesc = WalkState->Arguments[i].Object; 570 if (ObjDesc) 571 { 572 DisplayArgs = TRUE; 573 break; 574 } 575 } 576 577 /* If any are set, only display the ones that are set */ 578 579 if (DisplayArgs) 580 { 581 AcpiOsPrintf ( 582 "Initialized Arguments for Method [%4.4s]: " 583 "(%X arguments defined for method invocation)\n", 584 AcpiUtGetNodeName (Node), Node->Object->Method.ParamCount); 585 586 for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) 587 { 588 ObjDesc = WalkState->Arguments[i].Object; 589 if (ObjDesc) 590 { 591 AcpiOsPrintf (" Arg%u: ", i); 592 AcpiDbDisplayInternalObject (ObjDesc, WalkState); 593 } 594 } 595 } 596 else 597 { 598 AcpiOsPrintf ( 599 "No Arguments are initialized for method [%4.4s]\n", 600 AcpiUtGetNodeName (Node)); 601 } 602 } 603