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