brintos

brintos / linux-shallow public Read only

0
0
Text · 11.6 KiB · 95ab91b Raw
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