cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dbobject.c (11867B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/*******************************************************************************
      3 *
      4 * Module Name: dbobject - ACPI object decode and display
      5 *
      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_DEBUGGER
     14ACPI_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_info
     22 *
     23 * PARAMETERS:  status          - Method execution status
     24 *              walk_state      - Current state of the parse tree walk
     25 *
     26 * RETURN:      None
     27 *
     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
     34void
     35acpi_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 interpreter
     64	 * 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_object
     83 *
     84 * PARAMETERS:  obj_desc        - Object to be displayed
     85 *
     86 * RETURN:      None
     87 *
     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_node
    147 *
    148 * PARAMETERS:  node        - Object to be displayed
    149 *
    150 * RETURN:      None
    151 *
    152 * DESCRIPTION: Short display of a namespace node
    153 *
    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_object
    186					       (node));
    187		break;
    188	}
    189}
    190
    191/*******************************************************************************
    192 *
    193 * FUNCTION:    acpi_db_display_internal_object
    194 *
    195 * PARAMETERS:  obj_desc        - Object to be displayed
    196 *              walk_state      - Current walk state
    197 *
    198 * RETURN:      None
    199 *
    200 * DESCRIPTION: Short display of an internal object
    201 *
    202 ******************************************************************************/
    203
    204void
    205acpi_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_variables
    255					    [obj_desc->reference.value].object;
    256					acpi_os_printf("%p", obj_desc);
    257					acpi_db_decode_internal_object
    258					    (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->arguments
    268					    [obj_desc->reference.value].object;
    269					acpi_os_printf("%p", obj_desc);
    270					acpi_db_decode_internal_object
    271					    (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_object
    284					    (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_printf
    294						    (" 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_printf
    306					    ("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_printf
    315					    ("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_TYPE
    322					(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_object
    332					    (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_locals
    380 *
    381 * PARAMETERS:  walk_state      - State for current method
    382 *
    383 * RETURN:      None
    384 *
    385 * DESCRIPTION: Display all locals for the currently running control method
    386 *
    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_printf
    406		    ("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_printf
    429		    ("\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_printf
    442		    ("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_arguments
    450 *
    451 * PARAMETERS:  walk_state      - State for current method
    452 *
    453 * RETURN:      None
    454 *
    455 * DESCRIPTION: Display all arguments for the currently running control method
    456 *
    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_printf
    476		    ("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_printf
    513		    ("No Arguments are initialized for method [%4.4s]\n",
    514		     acpi_ut_get_node_name(node));
    515	}
    516}