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