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

dbutils.c (10255B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/*******************************************************************************
      3 *
      4 * Module Name: dbutils - AML debugger utilities
      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("dbutils")
     15
     16/* Local prototypes */
     17#ifdef ACPI_OBSOLETE_FUNCTIONS
     18acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root);
     19
     20void acpi_db_dump_buffer(u32 address);
     21#endif
     22
     23/*******************************************************************************
     24 *
     25 * FUNCTION:    acpi_db_match_argument
     26 *
     27 * PARAMETERS:  user_argument           - User command line
     28 *              arguments               - Array of commands to match against
     29 *
     30 * RETURN:      Index into command array or ACPI_TYPE_NOT_FOUND if not found
     31 *
     32 * DESCRIPTION: Search command array for a command match
     33 *
     34 ******************************************************************************/
     35
     36acpi_object_type
     37acpi_db_match_argument(char *user_argument,
     38		       struct acpi_db_argument_info *arguments)
     39{
     40	u32 i;
     41
     42	if (!user_argument || user_argument[0] == 0) {
     43		return (ACPI_TYPE_NOT_FOUND);
     44	}
     45
     46	for (i = 0; arguments[i].name; i++) {
     47		if (strstr(ACPI_CAST_PTR(char, arguments[i].name),
     48			   ACPI_CAST_PTR(char,
     49					 user_argument)) == arguments[i].name) {
     50			return (i);
     51		}
     52	}
     53
     54	/* Argument not recognized */
     55
     56	return (ACPI_TYPE_NOT_FOUND);
     57}
     58
     59/*******************************************************************************
     60 *
     61 * FUNCTION:    acpi_db_set_output_destination
     62 *
     63 * PARAMETERS:  output_flags        - Current flags word
     64 *
     65 * RETURN:      None
     66 *
     67 * DESCRIPTION: Set the current destination for debugger output. Also sets
     68 *              the debug output level accordingly.
     69 *
     70 ******************************************************************************/
     71
     72void acpi_db_set_output_destination(u32 output_flags)
     73{
     74
     75	acpi_gbl_db_output_flags = (u8)output_flags;
     76
     77	if ((output_flags & ACPI_DB_REDIRECTABLE_OUTPUT) &&
     78	    acpi_gbl_db_output_to_file) {
     79		acpi_dbg_level = acpi_gbl_db_debug_level;
     80	} else {
     81		acpi_dbg_level = acpi_gbl_db_console_debug_level;
     82	}
     83}
     84
     85/*******************************************************************************
     86 *
     87 * FUNCTION:    acpi_db_dump_external_object
     88 *
     89 * PARAMETERS:  obj_desc        - External ACPI object to dump
     90 *              level           - Nesting level.
     91 *
     92 * RETURN:      None
     93 *
     94 * DESCRIPTION: Dump the contents of an ACPI external object
     95 *
     96 ******************************************************************************/
     97
     98void acpi_db_dump_external_object(union acpi_object *obj_desc, u32 level)
     99{
    100	u32 i;
    101
    102	if (!obj_desc) {
    103		acpi_os_printf("[Null Object]\n");
    104		return;
    105	}
    106
    107	for (i = 0; i < level; i++) {
    108		acpi_os_printf(" ");
    109	}
    110
    111	switch (obj_desc->type) {
    112	case ACPI_TYPE_ANY:
    113
    114		acpi_os_printf("[Null Object] (Type=0)\n");
    115		break;
    116
    117	case ACPI_TYPE_INTEGER:
    118
    119		acpi_os_printf("[Integer] = %8.8X%8.8X\n",
    120			       ACPI_FORMAT_UINT64(obj_desc->integer.value));
    121		break;
    122
    123	case ACPI_TYPE_STRING:
    124
    125		acpi_os_printf("[String] Length %.2X = ",
    126			       obj_desc->string.length);
    127		acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
    128		acpi_os_printf("\n");
    129		break;
    130
    131	case ACPI_TYPE_BUFFER:
    132
    133		acpi_os_printf("[Buffer] Length %.2X = ",
    134			       obj_desc->buffer.length);
    135		if (obj_desc->buffer.length) {
    136			if (obj_desc->buffer.length > 16) {
    137				acpi_os_printf("\n");
    138			}
    139
    140			acpi_ut_debug_dump_buffer(ACPI_CAST_PTR
    141						  (u8,
    142						   obj_desc->buffer.pointer),
    143						  obj_desc->buffer.length,
    144						  DB_BYTE_DISPLAY, _COMPONENT);
    145		} else {
    146			acpi_os_printf("\n");
    147		}
    148		break;
    149
    150	case ACPI_TYPE_PACKAGE:
    151
    152		acpi_os_printf("[Package] Contains %u Elements:\n",
    153			       obj_desc->package.count);
    154
    155		for (i = 0; i < obj_desc->package.count; i++) {
    156			acpi_db_dump_external_object(&obj_desc->package.
    157						     elements[i], level + 1);
    158		}
    159		break;
    160
    161	case ACPI_TYPE_LOCAL_REFERENCE:
    162
    163		acpi_os_printf("[Object Reference] = ");
    164		acpi_db_display_internal_object(obj_desc->reference.handle,
    165						NULL);
    166		break;
    167
    168	case ACPI_TYPE_PROCESSOR:
    169
    170		acpi_os_printf("[Processor]\n");
    171		break;
    172
    173	case ACPI_TYPE_POWER:
    174
    175		acpi_os_printf("[Power Resource]\n");
    176		break;
    177
    178	default:
    179
    180		acpi_os_printf("[Unknown Type] %X\n", obj_desc->type);
    181		break;
    182	}
    183}
    184
    185/*******************************************************************************
    186 *
    187 * FUNCTION:    acpi_db_prep_namestring
    188 *
    189 * PARAMETERS:  name            - String to prepare
    190 *
    191 * RETURN:      None
    192 *
    193 * DESCRIPTION: Translate all forward slashes and dots to backslashes.
    194 *
    195 ******************************************************************************/
    196
    197void acpi_db_prep_namestring(char *name)
    198{
    199
    200	if (!name) {
    201		return;
    202	}
    203
    204	acpi_ut_strupr(name);
    205
    206	/* Convert a leading forward slash to a backslash */
    207
    208	if (*name == '/') {
    209		*name = '\\';
    210	}
    211
    212	/* Ignore a leading backslash, this is the root prefix */
    213
    214	if (ACPI_IS_ROOT_PREFIX(*name)) {
    215		name++;
    216	}
    217
    218	/* Convert all slash path separators to dots */
    219
    220	while (*name) {
    221		if ((*name == '/') || (*name == '\\')) {
    222			*name = '.';
    223		}
    224
    225		name++;
    226	}
    227}
    228
    229/*******************************************************************************
    230 *
    231 * FUNCTION:    acpi_db_local_ns_lookup
    232 *
    233 * PARAMETERS:  name            - Name to lookup
    234 *
    235 * RETURN:      Pointer to a namespace node, null on failure
    236 *
    237 * DESCRIPTION: Lookup a name in the ACPI namespace
    238 *
    239 * Note: Currently begins search from the root. Could be enhanced to use
    240 * the current prefix (scope) node as the search beginning point.
    241 *
    242 ******************************************************************************/
    243
    244struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name)
    245{
    246	char *internal_path;
    247	acpi_status status;
    248	struct acpi_namespace_node *node = NULL;
    249
    250	acpi_db_prep_namestring(name);
    251
    252	/* Build an internal namestring */
    253
    254	status = acpi_ns_internalize_name(name, &internal_path);
    255	if (ACPI_FAILURE(status)) {
    256		acpi_os_printf("Invalid namestring: %s\n", name);
    257		return (NULL);
    258	}
    259
    260	/*
    261	 * Lookup the name.
    262	 * (Uses root node as the search starting point)
    263	 */
    264	status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY,
    265				ACPI_IMODE_EXECUTE,
    266				ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
    267				NULL, &node);
    268	if (ACPI_FAILURE(status)) {
    269		acpi_os_printf("Could not locate name: %s, %s\n",
    270			       name, acpi_format_exception(status));
    271	}
    272
    273	ACPI_FREE(internal_path);
    274	return (node);
    275}
    276
    277/*******************************************************************************
    278 *
    279 * FUNCTION:    acpi_db_uint32_to_hex_string
    280 *
    281 * PARAMETERS:  value           - The value to be converted to string
    282 *              buffer          - Buffer for result (not less than 11 bytes)
    283 *
    284 * RETURN:      None
    285 *
    286 * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image
    287 *
    288 * NOTE: It is the caller's responsibility to ensure that the length of buffer
    289 *       is sufficient.
    290 *
    291 ******************************************************************************/
    292
    293void acpi_db_uint32_to_hex_string(u32 value, char *buffer)
    294{
    295	int i;
    296
    297	if (value == 0) {
    298		strcpy(buffer, "0");
    299		return;
    300	}
    301
    302	buffer[8] = '\0';
    303
    304	for (i = 7; i >= 0; i--) {
    305		buffer[i] = acpi_gbl_upper_hex_digits[value & 0x0F];
    306		value = value >> 4;
    307	}
    308}
    309
    310#ifdef ACPI_OBSOLETE_FUNCTIONS
    311/*******************************************************************************
    312 *
    313 * FUNCTION:    acpi_db_second_pass_parse
    314 *
    315 * PARAMETERS:  root            - Root of the parse tree
    316 *
    317 * RETURN:      Status
    318 *
    319 * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until
    320 *              second pass to parse the control methods
    321 *
    322 ******************************************************************************/
    323
    324acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root)
    325{
    326	union acpi_parse_object *op = root;
    327	union acpi_parse_object *method;
    328	union acpi_parse_object *search_op;
    329	union acpi_parse_object *start_op;
    330	acpi_status status = AE_OK;
    331	u32 base_aml_offset;
    332	struct acpi_walk_state *walk_state;
    333
    334	ACPI_FUNCTION_ENTRY();
    335
    336	acpi_os_printf("Pass two parse ....\n");
    337
    338	while (op) {
    339		if (op->common.aml_opcode == AML_METHOD_OP) {
    340			method = op;
    341
    342			/* Create a new walk state for the parse */
    343
    344			walk_state =
    345			    acpi_ds_create_walk_state(0, NULL, NULL, NULL);
    346			if (!walk_state) {
    347				return (AE_NO_MEMORY);
    348			}
    349
    350			/* Init the Walk State */
    351
    352			walk_state->parser_state.aml =
    353			    walk_state->parser_state.aml_start =
    354			    method->named.data;
    355			walk_state->parser_state.aml_end =
    356			    walk_state->parser_state.pkg_end =
    357			    method->named.data + method->named.length;
    358			walk_state->parser_state.start_scope = op;
    359
    360			walk_state->descending_callback =
    361			    acpi_ds_load1_begin_op;
    362			walk_state->ascending_callback = acpi_ds_load1_end_op;
    363
    364			/* Perform the AML parse */
    365
    366			status = acpi_ps_parse_aml(walk_state);
    367
    368			base_aml_offset =
    369			    (method->common.value.arg)->common.aml_offset + 1;
    370			start_op = (method->common.value.arg)->common.next;
    371			search_op = start_op;
    372
    373			while (search_op) {
    374				search_op->common.aml_offset += base_aml_offset;
    375				search_op =
    376				    acpi_ps_get_depth_next(start_op, search_op);
    377			}
    378		}
    379
    380		if (op->common.aml_opcode == AML_REGION_OP) {
    381
    382			/* TBD: [Investigate] this isn't quite the right thing to do! */
    383			/*
    384			 *
    385			 * Method = (ACPI_DEFERRED_OP *) Op;
    386			 * Status = acpi_ps_parse_aml (Op, Method->Body, Method->body_length);
    387			 */
    388		}
    389
    390		if (ACPI_FAILURE(status)) {
    391			break;
    392		}
    393
    394		op = acpi_ps_get_depth_next(root, op);
    395	}
    396
    397	return (status);
    398}
    399
    400/*******************************************************************************
    401 *
    402 * FUNCTION:    acpi_db_dump_buffer
    403 *
    404 * PARAMETERS:  address             - Pointer to the buffer
    405 *
    406 * RETURN:      None
    407 *
    408 * DESCRIPTION: Print a portion of a buffer
    409 *
    410 ******************************************************************************/
    411
    412void acpi_db_dump_buffer(u32 address)
    413{
    414
    415	acpi_os_printf("\nLocation %X:\n", address);
    416
    417	acpi_dbg_level |= ACPI_LV_TABLES;
    418	acpi_ut_debug_dump_buffer(ACPI_TO_POINTER(address), 64, DB_BYTE_DISPLAY,
    419				  ACPI_UINT32_MAX);
    420}
    421#endif