linux/drivers/acpi/acpica/dbutils.c
<<
>>
Prefs
   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
 422