195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
299575102SLv Zheng /*******************************************************************************
399575102SLv Zheng *
499575102SLv Zheng * Module Name: dbutils - AML debugger utilities
599575102SLv Zheng *
699575102SLv Zheng ******************************************************************************/
799575102SLv Zheng
899575102SLv Zheng #include <acpi/acpi.h>
999575102SLv Zheng #include "accommon.h"
1099575102SLv Zheng #include "acnamesp.h"
1199575102SLv Zheng #include "acdebug.h"
1299575102SLv Zheng
1399575102SLv Zheng #define _COMPONENT ACPI_CA_DEBUGGER
1499575102SLv Zheng ACPI_MODULE_NAME("dbutils")
1599575102SLv Zheng
1699575102SLv Zheng /* Local prototypes */
1799575102SLv Zheng #ifdef ACPI_OBSOLETE_FUNCTIONS
1899575102SLv Zheng acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root);
1999575102SLv Zheng
2099575102SLv Zheng void acpi_db_dump_buffer(u32 address);
2199575102SLv Zheng #endif
2299575102SLv Zheng
2399575102SLv Zheng /*******************************************************************************
2499575102SLv Zheng *
2599575102SLv Zheng * FUNCTION: acpi_db_match_argument
2699575102SLv Zheng *
2799575102SLv Zheng * PARAMETERS: user_argument - User command line
2899575102SLv Zheng * arguments - Array of commands to match against
2999575102SLv Zheng *
3099575102SLv Zheng * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found
3199575102SLv Zheng *
3299575102SLv Zheng * DESCRIPTION: Search command array for a command match
3399575102SLv Zheng *
3499575102SLv Zheng ******************************************************************************/
3599575102SLv Zheng
3699575102SLv Zheng acpi_object_type
acpi_db_match_argument(char * user_argument,struct acpi_db_argument_info * arguments)3799575102SLv Zheng acpi_db_match_argument(char *user_argument,
3899575102SLv Zheng struct acpi_db_argument_info *arguments)
3999575102SLv Zheng {
4099575102SLv Zheng u32 i;
4199575102SLv Zheng
4299575102SLv Zheng if (!user_argument || user_argument[0] == 0) {
4399575102SLv Zheng return (ACPI_TYPE_NOT_FOUND);
4499575102SLv Zheng }
4599575102SLv Zheng
4699575102SLv Zheng for (i = 0; arguments[i].name; i++) {
470dfaaa3dSBob Moore if (strstr(ACPI_CAST_PTR(char, arguments[i].name),
480dfaaa3dSBob Moore ACPI_CAST_PTR(char,
490dfaaa3dSBob Moore user_argument)) == arguments[i].name) {
5099575102SLv Zheng return (i);
5199575102SLv Zheng }
5299575102SLv Zheng }
5399575102SLv Zheng
5499575102SLv Zheng /* Argument not recognized */
5599575102SLv Zheng
5699575102SLv Zheng return (ACPI_TYPE_NOT_FOUND);
5799575102SLv Zheng }
5899575102SLv Zheng
5999575102SLv Zheng /*******************************************************************************
6099575102SLv Zheng *
6199575102SLv Zheng * FUNCTION: acpi_db_set_output_destination
6299575102SLv Zheng *
6399575102SLv Zheng * PARAMETERS: output_flags - Current flags word
6499575102SLv Zheng *
6599575102SLv Zheng * RETURN: None
6699575102SLv Zheng *
6799575102SLv Zheng * DESCRIPTION: Set the current destination for debugger output. Also sets
6899575102SLv Zheng * the debug output level accordingly.
6999575102SLv Zheng *
7099575102SLv Zheng ******************************************************************************/
7199575102SLv Zheng
acpi_db_set_output_destination(u32 output_flags)7299575102SLv Zheng void acpi_db_set_output_destination(u32 output_flags)
7399575102SLv Zheng {
7499575102SLv Zheng
7599575102SLv Zheng acpi_gbl_db_output_flags = (u8)output_flags;
7699575102SLv Zheng
7799575102SLv Zheng if ((output_flags & ACPI_DB_REDIRECTABLE_OUTPUT) &&
7899575102SLv Zheng acpi_gbl_db_output_to_file) {
7999575102SLv Zheng acpi_dbg_level = acpi_gbl_db_debug_level;
8099575102SLv Zheng } else {
8199575102SLv Zheng acpi_dbg_level = acpi_gbl_db_console_debug_level;
8299575102SLv Zheng }
8399575102SLv Zheng }
8499575102SLv Zheng
8599575102SLv Zheng /*******************************************************************************
8699575102SLv Zheng *
8799575102SLv Zheng * FUNCTION: acpi_db_dump_external_object
8899575102SLv Zheng *
8999575102SLv Zheng * PARAMETERS: obj_desc - External ACPI object to dump
9099575102SLv Zheng * level - Nesting level.
9199575102SLv Zheng *
9299575102SLv Zheng * RETURN: None
9399575102SLv Zheng *
9499575102SLv Zheng * DESCRIPTION: Dump the contents of an ACPI external object
9599575102SLv Zheng *
9699575102SLv Zheng ******************************************************************************/
9799575102SLv Zheng
acpi_db_dump_external_object(union acpi_object * obj_desc,u32 level)9899575102SLv Zheng void acpi_db_dump_external_object(union acpi_object *obj_desc, u32 level)
9999575102SLv Zheng {
10099575102SLv Zheng u32 i;
10199575102SLv Zheng
10299575102SLv Zheng if (!obj_desc) {
10399575102SLv Zheng acpi_os_printf("[Null Object]\n");
10499575102SLv Zheng return;
10599575102SLv Zheng }
10699575102SLv Zheng
10799575102SLv Zheng for (i = 0; i < level; i++) {
10899575102SLv Zheng acpi_os_printf(" ");
10999575102SLv Zheng }
11099575102SLv Zheng
11199575102SLv Zheng switch (obj_desc->type) {
11299575102SLv Zheng case ACPI_TYPE_ANY:
11399575102SLv Zheng
11499575102SLv Zheng acpi_os_printf("[Null Object] (Type=0)\n");
11599575102SLv Zheng break;
11699575102SLv Zheng
11799575102SLv Zheng case ACPI_TYPE_INTEGER:
11899575102SLv Zheng
11999575102SLv Zheng acpi_os_printf("[Integer] = %8.8X%8.8X\n",
12099575102SLv Zheng ACPI_FORMAT_UINT64(obj_desc->integer.value));
12199575102SLv Zheng break;
12299575102SLv Zheng
12399575102SLv Zheng case ACPI_TYPE_STRING:
12499575102SLv Zheng
12599575102SLv Zheng acpi_os_printf("[String] Length %.2X = ",
12699575102SLv Zheng obj_desc->string.length);
12799575102SLv Zheng acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
12899575102SLv Zheng acpi_os_printf("\n");
12999575102SLv Zheng break;
13099575102SLv Zheng
13199575102SLv Zheng case ACPI_TYPE_BUFFER:
13299575102SLv Zheng
13399575102SLv Zheng acpi_os_printf("[Buffer] Length %.2X = ",
13499575102SLv Zheng obj_desc->buffer.length);
13599575102SLv Zheng if (obj_desc->buffer.length) {
13699575102SLv Zheng if (obj_desc->buffer.length > 16) {
13799575102SLv Zheng acpi_os_printf("\n");
13899575102SLv Zheng }
1391fad8738SBob Moore
14099575102SLv Zheng acpi_ut_debug_dump_buffer(ACPI_CAST_PTR
14199575102SLv Zheng (u8,
14299575102SLv Zheng obj_desc->buffer.pointer),
14399575102SLv Zheng obj_desc->buffer.length,
14499575102SLv Zheng DB_BYTE_DISPLAY, _COMPONENT);
14599575102SLv Zheng } else {
14699575102SLv Zheng acpi_os_printf("\n");
14799575102SLv Zheng }
14899575102SLv Zheng break;
14999575102SLv Zheng
15099575102SLv Zheng case ACPI_TYPE_PACKAGE:
15199575102SLv Zheng
15299575102SLv Zheng acpi_os_printf("[Package] Contains %u Elements:\n",
15399575102SLv Zheng obj_desc->package.count);
15499575102SLv Zheng
15599575102SLv Zheng for (i = 0; i < obj_desc->package.count; i++) {
15699575102SLv Zheng acpi_db_dump_external_object(&obj_desc->package.
15799575102SLv Zheng elements[i], level + 1);
15899575102SLv Zheng }
15999575102SLv Zheng break;
16099575102SLv Zheng
16199575102SLv Zheng case ACPI_TYPE_LOCAL_REFERENCE:
16299575102SLv Zheng
16399575102SLv Zheng acpi_os_printf("[Object Reference] = ");
16499575102SLv Zheng acpi_db_display_internal_object(obj_desc->reference.handle,
16599575102SLv Zheng NULL);
16699575102SLv Zheng break;
16799575102SLv Zheng
16899575102SLv Zheng case ACPI_TYPE_PROCESSOR:
16999575102SLv Zheng
17099575102SLv Zheng acpi_os_printf("[Processor]\n");
17199575102SLv Zheng break;
17299575102SLv Zheng
17399575102SLv Zheng case ACPI_TYPE_POWER:
17499575102SLv Zheng
17599575102SLv Zheng acpi_os_printf("[Power Resource]\n");
17699575102SLv Zheng break;
17799575102SLv Zheng
17899575102SLv Zheng default:
17999575102SLv Zheng
18099575102SLv Zheng acpi_os_printf("[Unknown Type] %X\n", obj_desc->type);
18199575102SLv Zheng break;
18299575102SLv Zheng }
18399575102SLv Zheng }
18499575102SLv Zheng
18599575102SLv Zheng /*******************************************************************************
18699575102SLv Zheng *
18799575102SLv Zheng * FUNCTION: acpi_db_prep_namestring
18899575102SLv Zheng *
18999575102SLv Zheng * PARAMETERS: name - String to prepare
19099575102SLv Zheng *
19199575102SLv Zheng * RETURN: None
19299575102SLv Zheng *
19399575102SLv Zheng * DESCRIPTION: Translate all forward slashes and dots to backslashes.
19499575102SLv Zheng *
19599575102SLv Zheng ******************************************************************************/
19699575102SLv Zheng
acpi_db_prep_namestring(char * name)19799575102SLv Zheng void acpi_db_prep_namestring(char *name)
19899575102SLv Zheng {
19999575102SLv Zheng
20099575102SLv Zheng if (!name) {
20199575102SLv Zheng return;
20299575102SLv Zheng }
20399575102SLv Zheng
20499575102SLv Zheng acpi_ut_strupr(name);
20599575102SLv Zheng
20699575102SLv Zheng /* Convert a leading forward slash to a backslash */
20799575102SLv Zheng
20899575102SLv Zheng if (*name == '/') {
20999575102SLv Zheng *name = '\\';
21099575102SLv Zheng }
21199575102SLv Zheng
21299575102SLv Zheng /* Ignore a leading backslash, this is the root prefix */
21399575102SLv Zheng
21499575102SLv Zheng if (ACPI_IS_ROOT_PREFIX(*name)) {
21599575102SLv Zheng name++;
21699575102SLv Zheng }
21799575102SLv Zheng
21899575102SLv Zheng /* Convert all slash path separators to dots */
21999575102SLv Zheng
22099575102SLv Zheng while (*name) {
22199575102SLv Zheng if ((*name == '/') || (*name == '\\')) {
22299575102SLv Zheng *name = '.';
22399575102SLv Zheng }
22499575102SLv Zheng
22599575102SLv Zheng name++;
22699575102SLv Zheng }
22799575102SLv Zheng }
22899575102SLv Zheng
22999575102SLv Zheng /*******************************************************************************
23099575102SLv Zheng *
23199575102SLv Zheng * FUNCTION: acpi_db_local_ns_lookup
23299575102SLv Zheng *
23399575102SLv Zheng * PARAMETERS: name - Name to lookup
23499575102SLv Zheng *
23599575102SLv Zheng * RETURN: Pointer to a namespace node, null on failure
23699575102SLv Zheng *
23799575102SLv Zheng * DESCRIPTION: Lookup a name in the ACPI namespace
23899575102SLv Zheng *
23999575102SLv Zheng * Note: Currently begins search from the root. Could be enhanced to use
24099575102SLv Zheng * the current prefix (scope) node as the search beginning point.
24199575102SLv Zheng *
24299575102SLv Zheng ******************************************************************************/
24399575102SLv Zheng
acpi_db_local_ns_lookup(char * name)24499575102SLv Zheng struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name)
24599575102SLv Zheng {
24699575102SLv Zheng char *internal_path;
24799575102SLv Zheng acpi_status status;
24899575102SLv Zheng struct acpi_namespace_node *node = NULL;
24999575102SLv Zheng
25099575102SLv Zheng acpi_db_prep_namestring(name);
25199575102SLv Zheng
25299575102SLv Zheng /* Build an internal namestring */
25399575102SLv Zheng
25499575102SLv Zheng status = acpi_ns_internalize_name(name, &internal_path);
25599575102SLv Zheng if (ACPI_FAILURE(status)) {
25699575102SLv Zheng acpi_os_printf("Invalid namestring: %s\n", name);
25799575102SLv Zheng return (NULL);
25899575102SLv Zheng }
25999575102SLv Zheng
26099575102SLv Zheng /*
26199575102SLv Zheng * Lookup the name.
26299575102SLv Zheng * (Uses root node as the search starting point)
26399575102SLv Zheng */
26499575102SLv Zheng status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY,
26599575102SLv Zheng ACPI_IMODE_EXECUTE,
26699575102SLv Zheng ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
26799575102SLv Zheng NULL, &node);
26899575102SLv Zheng if (ACPI_FAILURE(status)) {
26999575102SLv Zheng acpi_os_printf("Could not locate name: %s, %s\n",
27099575102SLv Zheng name, acpi_format_exception(status));
27199575102SLv Zheng }
27299575102SLv Zheng
27399575102SLv Zheng ACPI_FREE(internal_path);
27499575102SLv Zheng return (node);
27599575102SLv Zheng }
27699575102SLv Zheng
27799575102SLv Zheng /*******************************************************************************
27899575102SLv Zheng *
27999575102SLv Zheng * FUNCTION: acpi_db_uint32_to_hex_string
28099575102SLv Zheng *
28199575102SLv Zheng * PARAMETERS: value - The value to be converted to string
28299575102SLv Zheng * buffer - Buffer for result (not less than 11 bytes)
28399575102SLv Zheng *
28499575102SLv Zheng * RETURN: None
28599575102SLv Zheng *
28699575102SLv Zheng * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image
28799575102SLv Zheng *
28899575102SLv Zheng * NOTE: It is the caller's responsibility to ensure that the length of buffer
28999575102SLv Zheng * is sufficient.
29099575102SLv Zheng *
29199575102SLv Zheng ******************************************************************************/
29299575102SLv Zheng
acpi_db_uint32_to_hex_string(u32 value,char * buffer)29399575102SLv Zheng void acpi_db_uint32_to_hex_string(u32 value, char *buffer)
29499575102SLv Zheng {
29599575102SLv Zheng int i;
29699575102SLv Zheng
29799575102SLv Zheng if (value == 0) {
29899575102SLv Zheng strcpy(buffer, "0");
29999575102SLv Zheng return;
30099575102SLv Zheng }
30199575102SLv Zheng
30299575102SLv Zheng buffer[8] = '\0';
30399575102SLv Zheng
30499575102SLv Zheng for (i = 7; i >= 0; i--) {
3050dfaaa3dSBob Moore buffer[i] = acpi_gbl_upper_hex_digits[value & 0x0F];
30699575102SLv Zheng value = value >> 4;
30799575102SLv Zheng }
30899575102SLv Zheng }
30999575102SLv Zheng
31099575102SLv Zheng #ifdef ACPI_OBSOLETE_FUNCTIONS
31199575102SLv Zheng /*******************************************************************************
31299575102SLv Zheng *
31399575102SLv Zheng * FUNCTION: acpi_db_second_pass_parse
31499575102SLv Zheng *
31599575102SLv Zheng * PARAMETERS: root - Root of the parse tree
31699575102SLv Zheng *
31799575102SLv Zheng * RETURN: Status
31899575102SLv Zheng *
31999575102SLv Zheng * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until
32099575102SLv Zheng * second pass to parse the control methods
32199575102SLv Zheng *
32299575102SLv Zheng ******************************************************************************/
32399575102SLv Zheng
acpi_db_second_pass_parse(union acpi_parse_object * root)32499575102SLv Zheng acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root)
32599575102SLv Zheng {
32699575102SLv Zheng union acpi_parse_object *op = root;
32799575102SLv Zheng union acpi_parse_object *method;
32899575102SLv Zheng union acpi_parse_object *search_op;
32999575102SLv Zheng union acpi_parse_object *start_op;
33099575102SLv Zheng acpi_status status = AE_OK;
33199575102SLv Zheng u32 base_aml_offset;
33299575102SLv Zheng struct acpi_walk_state *walk_state;
33399575102SLv Zheng
33499575102SLv Zheng ACPI_FUNCTION_ENTRY();
33599575102SLv Zheng
33699575102SLv Zheng acpi_os_printf("Pass two parse ....\n");
33799575102SLv Zheng
33899575102SLv Zheng while (op) {
33999575102SLv Zheng if (op->common.aml_opcode == AML_METHOD_OP) {
34099575102SLv Zheng method = op;
34199575102SLv Zheng
34299575102SLv Zheng /* Create a new walk state for the parse */
34399575102SLv Zheng
34499575102SLv Zheng walk_state =
34599575102SLv Zheng acpi_ds_create_walk_state(0, NULL, NULL, NULL);
34699575102SLv Zheng if (!walk_state) {
34799575102SLv Zheng return (AE_NO_MEMORY);
34899575102SLv Zheng }
34999575102SLv Zheng
35099575102SLv Zheng /* Init the Walk State */
35199575102SLv Zheng
35299575102SLv Zheng walk_state->parser_state.aml =
35399575102SLv Zheng walk_state->parser_state.aml_start =
35499575102SLv Zheng method->named.data;
35599575102SLv Zheng walk_state->parser_state.aml_end =
35699575102SLv Zheng walk_state->parser_state.pkg_end =
35799575102SLv Zheng method->named.data + method->named.length;
35899575102SLv Zheng walk_state->parser_state.start_scope = op;
35999575102SLv Zheng
36099575102SLv Zheng walk_state->descending_callback =
36199575102SLv Zheng acpi_ds_load1_begin_op;
36299575102SLv Zheng walk_state->ascending_callback = acpi_ds_load1_end_op;
36399575102SLv Zheng
36499575102SLv Zheng /* Perform the AML parse */
36599575102SLv Zheng
36699575102SLv Zheng status = acpi_ps_parse_aml(walk_state);
36799575102SLv Zheng
36899575102SLv Zheng base_aml_offset =
36999575102SLv Zheng (method->common.value.arg)->common.aml_offset + 1;
37099575102SLv Zheng start_op = (method->common.value.arg)->common.next;
37199575102SLv Zheng search_op = start_op;
37299575102SLv Zheng
37399575102SLv Zheng while (search_op) {
37499575102SLv Zheng search_op->common.aml_offset += base_aml_offset;
37599575102SLv Zheng search_op =
37699575102SLv Zheng acpi_ps_get_depth_next(start_op, search_op);
37799575102SLv Zheng }
37899575102SLv Zheng }
37999575102SLv Zheng
38099575102SLv Zheng if (op->common.aml_opcode == AML_REGION_OP) {
38199575102SLv Zheng
38299575102SLv Zheng /* TBD: [Investigate] this isn't quite the right thing to do! */
38399575102SLv Zheng /*
38499575102SLv Zheng *
38599575102SLv Zheng * Method = (ACPI_DEFERRED_OP *) Op;
38699575102SLv Zheng * Status = acpi_ps_parse_aml (Op, Method->Body, Method->body_length);
38799575102SLv Zheng */
38899575102SLv Zheng }
38999575102SLv Zheng
39099575102SLv Zheng if (ACPI_FAILURE(status)) {
39199575102SLv Zheng break;
39299575102SLv Zheng }
39399575102SLv Zheng
39499575102SLv Zheng op = acpi_ps_get_depth_next(root, op);
39599575102SLv Zheng }
39699575102SLv Zheng
39799575102SLv Zheng return (status);
39899575102SLv Zheng }
39999575102SLv Zheng
40099575102SLv Zheng /*******************************************************************************
40199575102SLv Zheng *
40299575102SLv Zheng * FUNCTION: acpi_db_dump_buffer
40399575102SLv Zheng *
40499575102SLv Zheng * PARAMETERS: address - Pointer to the buffer
40599575102SLv Zheng *
40699575102SLv Zheng * RETURN: None
40799575102SLv Zheng *
40899575102SLv Zheng * DESCRIPTION: Print a portion of a buffer
40999575102SLv Zheng *
41099575102SLv Zheng ******************************************************************************/
41199575102SLv Zheng
acpi_db_dump_buffer(u32 address)41299575102SLv Zheng void acpi_db_dump_buffer(u32 address)
41399575102SLv Zheng {
41499575102SLv Zheng
41599575102SLv Zheng acpi_os_printf("\nLocation %X:\n", address);
41699575102SLv Zheng
41799575102SLv Zheng acpi_dbg_level |= ACPI_LV_TABLES;
41899575102SLv Zheng acpi_ut_debug_dump_buffer(ACPI_TO_POINTER(address), 64, DB_BYTE_DISPLAY,
41999575102SLv Zheng ACPI_UINT32_MAX);
42099575102SLv Zheng }
42199575102SLv Zheng #endif
422