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