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