422 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/*******************************************************************************3 *4 * Module Name: dbutils - AML debugger utilities5 *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("dbutils")15 16/* Local prototypes */17#ifdef ACPI_OBSOLETE_FUNCTIONS18acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root);19 20void acpi_db_dump_buffer(u32 address);21#endif22 23/*******************************************************************************24 *25 * FUNCTION: acpi_db_match_argument26 *27 * PARAMETERS: user_argument - User command line28 * arguments - Array of commands to match against29 *30 * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found31 *32 * DESCRIPTION: Search command array for a command match33 *34 ******************************************************************************/35 36acpi_object_type37acpi_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_destination62 *63 * PARAMETERS: output_flags - Current flags word64 *65 * RETURN: None66 *67 * DESCRIPTION: Set the current destination for debugger output. Also sets68 * 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_object88 *89 * PARAMETERS: obj_desc - External ACPI object to dump90 * level - Nesting level.91 *92 * RETURN: None93 *94 * DESCRIPTION: Dump the contents of an ACPI external object95 *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_PTR141 (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_namestring188 *189 * PARAMETERS: name - String to prepare190 *191 * RETURN: None192 *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_lookup232 *233 * PARAMETERS: name - Name to lookup234 *235 * RETURN: Pointer to a namespace node, null on failure236 *237 * DESCRIPTION: Lookup a name in the ACPI namespace238 *239 * Note: Currently begins search from the root. Could be enhanced to use240 * 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_string280 *281 * PARAMETERS: value - The value to be converted to string282 * buffer - Buffer for result (not less than 11 bytes)283 *284 * RETURN: None285 *286 * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image287 *288 * NOTE: It is the caller's responsibility to ensure that the length of buffer289 * 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_FUNCTIONS311/*******************************************************************************312 *313 * FUNCTION: acpi_db_second_pass_parse314 *315 * PARAMETERS: root - Root of the parse tree316 *317 * RETURN: Status318 *319 * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until320 * second pass to parse the control methods321 *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_buffer403 *404 * PARAMETERS: address - Pointer to the buffer405 *406 * RETURN: None407 *408 * DESCRIPTION: Print a portion of a buffer409 *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#endif422