1 /******************************************************************************* 2 * 3 * Module Name: dbobject - ACPI object decode and display 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 #ifdef ACPI_DISASSEMBLER 49 #include <contrib/dev/acpica/include/acdisasm.h> 50 #endif 51 52 53 #ifdef ACPI_DEBUGGER 54 55 #define _COMPONENT ACPI_CA_DEBUGGER 56 ACPI_MODULE_NAME ("dbobject") 57 58 /* Local prototypes */ 59 60 static void 61 AcpiDbDecodeNode ( 62 ACPI_NAMESPACE_NODE *Node); 63 64 65 /******************************************************************************* 66 * 67 * FUNCTION: AcpiDbDumpMethodInfo 68 * 69 * PARAMETERS: Status - Method execution status 70 * WalkState - Current state of the parse tree walk 71 * 72 * RETURN: None 73 * 74 * DESCRIPTION: Called when a method has been aborted because of an error. 75 * Dumps the method execution stack, and the method locals/args, 76 * and disassembles the AML opcode that failed. 77 * 78 ******************************************************************************/ 79 80 void 81 AcpiDbDumpMethodInfo ( 82 ACPI_STATUS Status, 83 ACPI_WALK_STATE *WalkState) 84 { 85 ACPI_THREAD_STATE *Thread; 86 87 88 /* Ignore control codes, they are not errors */ 89 90 if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL) 91 { 92 return; 93 } 94 95 /* We may be executing a deferred opcode */ 96 97 if (WalkState->DeferredNode) 98 { 99 AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n"); 100 return; 101 } 102 103 /* 104 * If there is no Thread, we are not actually executing a method. 105 * This can happen when the iASL compiler calls the interpreter 106 * to perform constant folding. 107 */ 108 Thread = WalkState->Thread; 109 if (!Thread) 110 { 111 return; 112 } 113 114 /* Display the method locals and arguments */ 115 116 AcpiOsPrintf ("\n"); 117 AcpiDbDecodeLocals (WalkState); 118 AcpiOsPrintf ("\n"); 119 AcpiDbDecodeArguments (WalkState); 120 AcpiOsPrintf ("\n"); 121 } 122 123 124 /******************************************************************************* 125 * 126 * FUNCTION: AcpiDbDecodeInternalObject 127 * 128 * PARAMETERS: ObjDesc - Object to be displayed 129 * 130 * RETURN: None 131 * 132 * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers. 133 * 134 ******************************************************************************/ 135 136 void 137 AcpiDbDecodeInternalObject ( 138 ACPI_OPERAND_OBJECT *ObjDesc) 139 { 140 UINT32 i; 141 142 143 if (!ObjDesc) 144 { 145 AcpiOsPrintf (" Uninitialized"); 146 return; 147 } 148 149 if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND) 150 { 151 AcpiOsPrintf (" %p [%s]", ObjDesc, AcpiUtGetDescriptorName (ObjDesc)); 152 return; 153 } 154 155 AcpiOsPrintf (" %s", AcpiUtGetObjectTypeName (ObjDesc)); 156 157 switch (ObjDesc->Common.Type) 158 { 159 case ACPI_TYPE_INTEGER: 160 161 AcpiOsPrintf (" %8.8X%8.8X", 162 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); 163 break; 164 165 case ACPI_TYPE_STRING: 166 167 AcpiOsPrintf ("(%u) \"%.24s", 168 ObjDesc->String.Length, ObjDesc->String.Pointer); 169 170 if (ObjDesc->String.Length > 24) 171 { 172 AcpiOsPrintf ("..."); 173 } 174 else 175 { 176 AcpiOsPrintf ("\""); 177 } 178 break; 179 180 case ACPI_TYPE_BUFFER: 181 182 AcpiOsPrintf ("(%u)", ObjDesc->Buffer.Length); 183 for (i = 0; (i < 8) && (i < ObjDesc->Buffer.Length); i++) 184 { 185 AcpiOsPrintf (" %2.2X", ObjDesc->Buffer.Pointer[i]); 186 } 187 break; 188 189 default: 190 191 AcpiOsPrintf (" %p", ObjDesc); 192 break; 193 } 194 } 195 196 197 /******************************************************************************* 198 * 199 * FUNCTION: AcpiDbDecodeNode 200 * 201 * PARAMETERS: Node - Object to be displayed 202 * 203 * RETURN: None 204 * 205 * DESCRIPTION: Short display of a namespace node 206 * 207 ******************************************************************************/ 208 209 static void 210 AcpiDbDecodeNode ( 211 ACPI_NAMESPACE_NODE *Node) 212 { 213 214 AcpiOsPrintf ("<Node> Name %4.4s", 215 AcpiUtGetNodeName (Node)); 216 217 if (Node->Flags & ANOBJ_METHOD_ARG) 218 { 219 AcpiOsPrintf (" [Method Arg]"); 220 } 221 if (Node->Flags & ANOBJ_METHOD_LOCAL) 222 { 223 AcpiOsPrintf (" [Method Local]"); 224 } 225 226 switch (Node->Type) 227 { 228 /* These types have no attached object */ 229 230 case ACPI_TYPE_DEVICE: 231 232 AcpiOsPrintf (" Device"); 233 break; 234 235 case ACPI_TYPE_THERMAL: 236 237 AcpiOsPrintf (" Thermal Zone"); 238 break; 239 240 default: 241 242 AcpiDbDecodeInternalObject (AcpiNsGetAttachedObject (Node)); 243 break; 244 } 245 } 246 247 248 /******************************************************************************* 249 * 250 * FUNCTION: AcpiDbDisplayInternalObject 251 * 252 * PARAMETERS: ObjDesc - Object to be displayed 253 * WalkState - Current walk state 254 * 255 * RETURN: None 256 * 257 * DESCRIPTION: Short display of an internal object 258 * 259 ******************************************************************************/ 260 261 void 262 AcpiDbDisplayInternalObject ( 263 ACPI_OPERAND_OBJECT *ObjDesc, 264 ACPI_WALK_STATE *WalkState) 265 { 266 UINT8 Type; 267 268 269 AcpiOsPrintf ("%p ", ObjDesc); 270 271 if (!ObjDesc) 272 { 273 AcpiOsPrintf ("<Null Object>\n"); 274 return; 275 } 276 277 /* Decode the object type */ 278 279 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)) 280 { 281 case ACPI_DESC_TYPE_PARSER: 282 283 AcpiOsPrintf ("<Parser> "); 284 break; 285 286 case ACPI_DESC_TYPE_NAMED: 287 288 AcpiDbDecodeNode ((ACPI_NAMESPACE_NODE *) ObjDesc); 289 break; 290 291 case ACPI_DESC_TYPE_OPERAND: 292 293 Type = ObjDesc->Common.Type; 294 if (Type > ACPI_TYPE_LOCAL_MAX) 295 { 296 AcpiOsPrintf (" Type %X [Invalid Type]", (UINT32) Type); 297 return; 298 } 299 300 /* Decode the ACPI object type */ 301 302 switch (ObjDesc->Common.Type) 303 { 304 case ACPI_TYPE_LOCAL_REFERENCE: 305 306 AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (ObjDesc)); 307 308 /* Decode the refererence */ 309 310 switch (ObjDesc->Reference.Class) 311 { 312 case ACPI_REFCLASS_LOCAL: 313 314 AcpiOsPrintf ("%X ", ObjDesc->Reference.Value); 315 if (WalkState) 316 { 317 ObjDesc = WalkState->LocalVariables 318 [ObjDesc->Reference.Value].Object; 319 AcpiOsPrintf ("%p", ObjDesc); 320 AcpiDbDecodeInternalObject (ObjDesc); 321 } 322 break; 323 324 case ACPI_REFCLASS_ARG: 325 326 AcpiOsPrintf ("%X ", ObjDesc->Reference.Value); 327 if (WalkState) 328 { 329 ObjDesc = WalkState->Arguments 330 [ObjDesc->Reference.Value].Object; 331 AcpiOsPrintf ("%p", ObjDesc); 332 AcpiDbDecodeInternalObject (ObjDesc); 333 } 334 break; 335 336 case ACPI_REFCLASS_INDEX: 337 338 switch (ObjDesc->Reference.TargetType) 339 { 340 case ACPI_TYPE_BUFFER_FIELD: 341 342 AcpiOsPrintf ("%p", ObjDesc->Reference.Object); 343 AcpiDbDecodeInternalObject (ObjDesc->Reference.Object); 344 break; 345 346 case ACPI_TYPE_PACKAGE: 347 348 AcpiOsPrintf ("%p", ObjDesc->Reference.Where); 349 if (!ObjDesc->Reference.Where) 350 { 351 AcpiOsPrintf (" Uninitialized WHERE pointer"); 352 } 353 else 354 { 355 AcpiDbDecodeInternalObject ( 356 *(ObjDesc->Reference.Where)); 357 } 358 break; 359 360 default: 361 362 AcpiOsPrintf ("Unknown index target type"); 363 break; 364 } 365 break; 366 367 case ACPI_REFCLASS_REFOF: 368 369 if (!ObjDesc->Reference.Object) 370 { 371 AcpiOsPrintf ("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 AcpiDbDecodeNode (ObjDesc->Reference.Object); 381 break; 382 383 case ACPI_DESC_TYPE_OPERAND: 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 449 450 ObjDesc = WalkState->MethodDesc; 451 Node = WalkState->MethodNode; 452 if (!Node) 453 { 454 AcpiOsPrintf ( 455 "No method node (Executing subtree for buffer or opregion)\n"); 456 return; 457 } 458 459 if (Node->Type != ACPI_TYPE_METHOD) 460 { 461 AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n"); 462 return; 463 } 464 465 AcpiOsPrintf ("Local Variables for method [%4.4s]:\n", 466 AcpiUtGetNodeName (Node)); 467 468 for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) 469 { 470 ObjDesc = WalkState->LocalVariables[i].Object; 471 AcpiOsPrintf (" Local%X: ", i); 472 AcpiDbDisplayInternalObject (ObjDesc, WalkState); 473 } 474 } 475 476 477 /******************************************************************************* 478 * 479 * FUNCTION: AcpiDbDecodeArguments 480 * 481 * PARAMETERS: WalkState - State for current method 482 * 483 * RETURN: None 484 * 485 * DESCRIPTION: Display all arguments for the currently running control method 486 * 487 ******************************************************************************/ 488 489 void 490 AcpiDbDecodeArguments ( 491 ACPI_WALK_STATE *WalkState) 492 { 493 UINT32 i; 494 ACPI_OPERAND_OBJECT *ObjDesc; 495 ACPI_NAMESPACE_NODE *Node; 496 497 498 ObjDesc = WalkState->MethodDesc; 499 Node = WalkState->MethodNode; 500 if (!Node) 501 { 502 AcpiOsPrintf ( 503 "No method node (Executing subtree for buffer or opregion)\n"); 504 return; 505 } 506 507 if (Node->Type != ACPI_TYPE_METHOD) 508 { 509 AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n"); 510 return; 511 } 512 513 AcpiOsPrintf ( 514 "Arguments for Method [%4.4s]: (%X arguments defined, max concurrency = %X)\n", 515 AcpiUtGetNodeName (Node), ObjDesc->Method.ParamCount, ObjDesc->Method.SyncLevel); 516 517 for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) 518 { 519 ObjDesc = WalkState->Arguments[i].Object; 520 AcpiOsPrintf (" Arg%u: ", i); 521 AcpiDbDisplayInternalObject (ObjDesc, WalkState); 522 } 523 } 524 525 #endif 526