linux/drivers/acpi/acpica/dbobject.c
<<
>>
Prefs
   1/*******************************************************************************
   2 *
   3 * Module Name: dbobject - ACPI object decode and display
   4 *
   5 ******************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2016, Intel Corp.
   9 * All rights reserved.
  10 *
  11 * Redistribution and use in source and binary forms, with or without
  12 * modification, are permitted provided that the following conditions
  13 * are met:
  14 * 1. Redistributions of source code must retain the above copyright
  15 *    notice, this list of conditions, and the following disclaimer,
  16 *    without modification.
  17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18 *    substantially similar to the "NO WARRANTY" disclaimer below
  19 *    ("Disclaimer") and any redistribution must be conditioned upon
  20 *    including a substantially similar Disclaimer requirement for further
  21 *    binary redistribution.
  22 * 3. Neither the names of the above-listed copyright holders nor the names
  23 *    of any contributors may be used to endorse or promote products derived
  24 *    from this software without specific prior written permission.
  25 *
  26 * Alternatively, this software may be distributed under the terms of the
  27 * GNU General Public License ("GPL") version 2 as published by the Free
  28 * Software Foundation.
  29 *
  30 * NO WARRANTY
  31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41 * POSSIBILITY OF SUCH DAMAGES.
  42 */
  43
  44#include <acpi/acpi.h>
  45#include "accommon.h"
  46#include "acnamesp.h"
  47#include "acdebug.h"
  48
  49#define _COMPONENT          ACPI_CA_DEBUGGER
  50ACPI_MODULE_NAME("dbobject")
  51
  52/* Local prototypes */
  53static void acpi_db_decode_node(struct acpi_namespace_node *node);
  54
  55/*******************************************************************************
  56 *
  57 * FUNCTION:    acpi_db_dump_method_info
  58 *
  59 * PARAMETERS:  status          - Method execution status
  60 *              walk_state      - Current state of the parse tree walk
  61 *
  62 * RETURN:      None
  63 *
  64 * DESCRIPTION: Called when a method has been aborted because of an error.
  65 *              Dumps the method execution stack, and the method locals/args,
  66 *              and disassembles the AML opcode that failed.
  67 *
  68 ******************************************************************************/
  69
  70void
  71acpi_db_dump_method_info(acpi_status status, struct acpi_walk_state *walk_state)
  72{
  73        struct acpi_thread_state *thread;
  74
  75        /* Ignore control codes, they are not errors */
  76
  77        if ((status & AE_CODE_MASK) == AE_CODE_CONTROL) {
  78                return;
  79        }
  80
  81        /* We may be executing a deferred opcode */
  82
  83        if (walk_state->deferred_node) {
  84                acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
  85                return;
  86        }
  87
  88        /*
  89         * If there is no Thread, we are not actually executing a method.
  90         * This can happen when the iASL compiler calls the interpreter
  91         * to perform constant folding.
  92         */
  93        thread = walk_state->thread;
  94        if (!thread) {
  95                return;
  96        }
  97
  98        /* Display the method locals and arguments */
  99
 100        acpi_os_printf("\n");
 101        acpi_db_decode_locals(walk_state);
 102        acpi_os_printf("\n");
 103        acpi_db_decode_arguments(walk_state);
 104        acpi_os_printf("\n");
 105}
 106
 107/*******************************************************************************
 108 *
 109 * FUNCTION:    acpi_db_decode_internal_object
 110 *
 111 * PARAMETERS:  obj_desc        - Object to be displayed
 112 *
 113 * RETURN:      None
 114 *
 115 * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers.
 116 *
 117 ******************************************************************************/
 118
 119void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc)
 120{
 121        u32 i;
 122
 123        if (!obj_desc) {
 124                acpi_os_printf(" Uninitialized");
 125                return;
 126        }
 127
 128        if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
 129                acpi_os_printf(" %p [%s]", obj_desc,
 130                               acpi_ut_get_descriptor_name(obj_desc));
 131                return;
 132        }
 133
 134        acpi_os_printf(" %s", acpi_ut_get_object_type_name(obj_desc));
 135
 136        switch (obj_desc->common.type) {
 137        case ACPI_TYPE_INTEGER:
 138
 139                acpi_os_printf(" %8.8X%8.8X",
 140                               ACPI_FORMAT_UINT64(obj_desc->integer.value));
 141                break;
 142
 143        case ACPI_TYPE_STRING:
 144
 145                acpi_os_printf("(%u) \"%.60s",
 146                               obj_desc->string.length,
 147                               obj_desc->string.pointer);
 148
 149                if (obj_desc->string.length > 60) {
 150                        acpi_os_printf("...");
 151                } else {
 152                        acpi_os_printf("\"");
 153                }
 154                break;
 155
 156        case ACPI_TYPE_BUFFER:
 157
 158                acpi_os_printf("(%u)", obj_desc->buffer.length);
 159                for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) {
 160                        acpi_os_printf(" %2.2X", obj_desc->buffer.pointer[i]);
 161                }
 162                break;
 163
 164        default:
 165
 166                acpi_os_printf(" %p", obj_desc);
 167                break;
 168        }
 169}
 170
 171/*******************************************************************************
 172 *
 173 * FUNCTION:    acpi_db_decode_node
 174 *
 175 * PARAMETERS:  node        - Object to be displayed
 176 *
 177 * RETURN:      None
 178 *
 179 * DESCRIPTION: Short display of a namespace node
 180 *
 181 ******************************************************************************/
 182
 183static void acpi_db_decode_node(struct acpi_namespace_node *node)
 184{
 185
 186        acpi_os_printf("<Node>          Name %4.4s",
 187                       acpi_ut_get_node_name(node));
 188
 189        if (node->flags & ANOBJ_METHOD_ARG) {
 190                acpi_os_printf(" [Method Arg]");
 191        }
 192        if (node->flags & ANOBJ_METHOD_LOCAL) {
 193                acpi_os_printf(" [Method Local]");
 194        }
 195
 196        switch (node->type) {
 197
 198                /* These types have no attached object */
 199
 200        case ACPI_TYPE_DEVICE:
 201
 202                acpi_os_printf(" Device");
 203                break;
 204
 205        case ACPI_TYPE_THERMAL:
 206
 207                acpi_os_printf(" Thermal Zone");
 208                break;
 209
 210        default:
 211
 212                acpi_db_decode_internal_object(acpi_ns_get_attached_object
 213                                               (node));
 214                break;
 215        }
 216}
 217
 218/*******************************************************************************
 219 *
 220 * FUNCTION:    acpi_db_display_internal_object
 221 *
 222 * PARAMETERS:  obj_desc        - Object to be displayed
 223 *              walk_state      - Current walk state
 224 *
 225 * RETURN:      None
 226 *
 227 * DESCRIPTION: Short display of an internal object
 228 *
 229 ******************************************************************************/
 230
 231void
 232acpi_db_display_internal_object(union acpi_operand_object *obj_desc,
 233                                struct acpi_walk_state *walk_state)
 234{
 235        u8 type;
 236
 237        acpi_os_printf("%p ", obj_desc);
 238
 239        if (!obj_desc) {
 240                acpi_os_printf("<Null Object>\n");
 241                return;
 242        }
 243
 244        /* Decode the object type */
 245
 246        switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
 247        case ACPI_DESC_TYPE_PARSER:
 248
 249                acpi_os_printf("<Parser> ");
 250                break;
 251
 252        case ACPI_DESC_TYPE_NAMED:
 253
 254                acpi_db_decode_node((struct acpi_namespace_node *)obj_desc);
 255                break;
 256
 257        case ACPI_DESC_TYPE_OPERAND:
 258
 259                type = obj_desc->common.type;
 260                if (type > ACPI_TYPE_LOCAL_MAX) {
 261                        acpi_os_printf(" Type %X [Invalid Type]", (u32)type);
 262                        return;
 263                }
 264
 265                /* Decode the ACPI object type */
 266
 267                switch (obj_desc->common.type) {
 268                case ACPI_TYPE_LOCAL_REFERENCE:
 269
 270                        acpi_os_printf("[%s] ",
 271                                       acpi_ut_get_reference_name(obj_desc));
 272
 273                        /* Decode the refererence */
 274
 275                        switch (obj_desc->reference.class) {
 276                        case ACPI_REFCLASS_LOCAL:
 277
 278                                acpi_os_printf("%X ",
 279                                               obj_desc->reference.value);
 280                                if (walk_state) {
 281                                        obj_desc = walk_state->local_variables
 282                                            [obj_desc->reference.value].object;
 283                                        acpi_os_printf("%p", obj_desc);
 284                                        acpi_db_decode_internal_object
 285                                            (obj_desc);
 286                                }
 287                                break;
 288
 289                        case ACPI_REFCLASS_ARG:
 290
 291                                acpi_os_printf("%X ",
 292                                               obj_desc->reference.value);
 293                                if (walk_state) {
 294                                        obj_desc = walk_state->arguments
 295                                            [obj_desc->reference.value].object;
 296                                        acpi_os_printf("%p", obj_desc);
 297                                        acpi_db_decode_internal_object
 298                                            (obj_desc);
 299                                }
 300                                break;
 301
 302                        case ACPI_REFCLASS_INDEX:
 303
 304                                switch (obj_desc->reference.target_type) {
 305                                case ACPI_TYPE_BUFFER_FIELD:
 306
 307                                        acpi_os_printf("%p",
 308                                                       obj_desc->reference.
 309                                                       object);
 310                                        acpi_db_decode_internal_object
 311                                            (obj_desc->reference.object);
 312                                        break;
 313
 314                                case ACPI_TYPE_PACKAGE:
 315
 316                                        acpi_os_printf("%p",
 317                                                       obj_desc->reference.
 318                                                       where);
 319                                        if (!obj_desc->reference.where) {
 320                                                acpi_os_printf
 321                                                    (" Uninitialized WHERE pointer");
 322                                        } else {
 323                                                acpi_db_decode_internal_object(*
 324                                                                               (obj_desc->
 325                                                                                reference.
 326                                                                                where));
 327                                        }
 328                                        break;
 329
 330                                default:
 331
 332                                        acpi_os_printf
 333                                            ("Unknown index target type");
 334                                        break;
 335                                }
 336                                break;
 337
 338                        case ACPI_REFCLASS_REFOF:
 339
 340                                if (!obj_desc->reference.object) {
 341                                        acpi_os_printf
 342                                            ("Uninitialized reference subobject pointer");
 343                                        break;
 344                                }
 345
 346                                /* Reference can be to a Node or an Operand object */
 347
 348                                switch (ACPI_GET_DESCRIPTOR_TYPE
 349                                        (obj_desc->reference.object)) {
 350                                case ACPI_DESC_TYPE_NAMED:
 351
 352                                        acpi_db_decode_node(obj_desc->reference.
 353                                                            object);
 354                                        break;
 355
 356                                case ACPI_DESC_TYPE_OPERAND:
 357
 358                                        acpi_db_decode_internal_object
 359                                            (obj_desc->reference.object);
 360                                        break;
 361
 362                                default:
 363                                        break;
 364                                }
 365                                break;
 366
 367                        case ACPI_REFCLASS_NAME:
 368
 369                                acpi_db_decode_node(obj_desc->reference.node);
 370                                break;
 371
 372                        case ACPI_REFCLASS_DEBUG:
 373                        case ACPI_REFCLASS_TABLE:
 374
 375                                acpi_os_printf("\n");
 376                                break;
 377
 378                        default:        /* Unknown reference class */
 379
 380                                acpi_os_printf("%2.2X\n",
 381                                               obj_desc->reference.class);
 382                                break;
 383                        }
 384                        break;
 385
 386                default:
 387
 388                        acpi_os_printf("<Obj>          ");
 389                        acpi_db_decode_internal_object(obj_desc);
 390                        break;
 391                }
 392                break;
 393
 394        default:
 395
 396                acpi_os_printf("<Not a valid ACPI Object Descriptor> [%s]",
 397                               acpi_ut_get_descriptor_name(obj_desc));
 398                break;
 399        }
 400
 401        acpi_os_printf("\n");
 402}
 403
 404/*******************************************************************************
 405 *
 406 * FUNCTION:    acpi_db_decode_locals
 407 *
 408 * PARAMETERS:  walk_state      - State for current method
 409 *
 410 * RETURN:      None
 411 *
 412 * DESCRIPTION: Display all locals for the currently running control method
 413 *
 414 ******************************************************************************/
 415
 416void acpi_db_decode_locals(struct acpi_walk_state *walk_state)
 417{
 418        u32 i;
 419        union acpi_operand_object *obj_desc;
 420        struct acpi_namespace_node *node;
 421        u8 display_locals = FALSE;
 422
 423        obj_desc = walk_state->method_desc;
 424        node = walk_state->method_node;
 425
 426        if (!node) {
 427                acpi_os_printf
 428                    ("No method node (Executing subtree for buffer or opregion)\n");
 429                return;
 430        }
 431
 432        if (node->type != ACPI_TYPE_METHOD) {
 433                acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
 434                return;
 435        }
 436
 437        /* Are any locals actually set? */
 438
 439        for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
 440                obj_desc = walk_state->local_variables[i].object;
 441                if (obj_desc) {
 442                        display_locals = TRUE;
 443                        break;
 444                }
 445        }
 446
 447        /* If any are set, only display the ones that are set */
 448
 449        if (display_locals) {
 450                acpi_os_printf
 451                    ("\nInitialized Local Variables for method [%4.4s]:\n",
 452                     acpi_ut_get_node_name(node));
 453
 454                for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
 455                        obj_desc = walk_state->local_variables[i].object;
 456                        if (obj_desc) {
 457                                acpi_os_printf("  Local%X: ", i);
 458                                acpi_db_display_internal_object(obj_desc,
 459                                                                walk_state);
 460                        }
 461                }
 462        } else {
 463                acpi_os_printf
 464                    ("No Local Variables are initialized for method [%4.4s]\n",
 465                     acpi_ut_get_node_name(node));
 466        }
 467}
 468
 469/*******************************************************************************
 470 *
 471 * FUNCTION:    acpi_db_decode_arguments
 472 *
 473 * PARAMETERS:  walk_state      - State for current method
 474 *
 475 * RETURN:      None
 476 *
 477 * DESCRIPTION: Display all arguments for the currently running control method
 478 *
 479 ******************************************************************************/
 480
 481void acpi_db_decode_arguments(struct acpi_walk_state *walk_state)
 482{
 483        u32 i;
 484        union acpi_operand_object *obj_desc;
 485        struct acpi_namespace_node *node;
 486        u8 display_args = FALSE;
 487
 488        node = walk_state->method_node;
 489        obj_desc = walk_state->method_desc;
 490
 491        if (!node) {
 492                acpi_os_printf
 493                    ("No method node (Executing subtree for buffer or opregion)\n");
 494                return;
 495        }
 496
 497        if (node->type != ACPI_TYPE_METHOD) {
 498                acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
 499                return;
 500        }
 501
 502        /* Are any arguments actually set? */
 503
 504        for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
 505                obj_desc = walk_state->arguments[i].object;
 506                if (obj_desc) {
 507                        display_args = TRUE;
 508                        break;
 509                }
 510        }
 511
 512        /* If any are set, only display the ones that are set */
 513
 514        if (display_args) {
 515                acpi_os_printf("Initialized Arguments for Method [%4.4s]:  "
 516                               "(%X arguments defined for method invocation)\n",
 517                               acpi_ut_get_node_name(node),
 518                               obj_desc->method.param_count);
 519
 520                for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
 521                        obj_desc = walk_state->arguments[i].object;
 522                        if (obj_desc) {
 523                                acpi_os_printf("  Arg%u:   ", i);
 524                                acpi_db_display_internal_object(obj_desc,
 525                                                                walk_state);
 526                        }
 527                }
 528        } else {
 529                acpi_os_printf
 530                    ("No Arguments are initialized for method [%4.4s]\n",
 531                     acpi_ut_get_node_name(node));
 532        }
 533}
 534