Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /*******************************************************************************
0003  *
0004  * Module Name: dbobject - ACPI object decode and display
0005  *
0006  ******************************************************************************/
0007 
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "acnamesp.h"
0011 #include "acdebug.h"
0012 
0013 #define _COMPONENT          ACPI_CA_DEBUGGER
0014 ACPI_MODULE_NAME("dbobject")
0015 
0016 /* Local prototypes */
0017 static void acpi_db_decode_node(struct acpi_namespace_node *node);
0018 
0019 /*******************************************************************************
0020  *
0021  * FUNCTION:    acpi_db_dump_method_info
0022  *
0023  * PARAMETERS:  status          - Method execution status
0024  *              walk_state      - Current state of the parse tree walk
0025  *
0026  * RETURN:      None
0027  *
0028  * DESCRIPTION: Called when a method has been aborted because of an error.
0029  *              Dumps the method execution stack, and the method locals/args,
0030  *              and disassembles the AML opcode that failed.
0031  *
0032  ******************************************************************************/
0033 
0034 void
0035 acpi_db_dump_method_info(acpi_status status, struct acpi_walk_state *walk_state)
0036 {
0037     struct acpi_thread_state *thread;
0038     struct acpi_namespace_node *node;
0039 
0040     node = walk_state->method_node;
0041 
0042     /* There are no locals or arguments for the module-level code case */
0043 
0044     if (node == acpi_gbl_root_node) {
0045         return;
0046     }
0047 
0048     /* Ignore control codes, they are not errors */
0049 
0050     if (ACPI_CNTL_EXCEPTION(status)) {
0051         return;
0052     }
0053 
0054     /* We may be executing a deferred opcode */
0055 
0056     if (walk_state->deferred_node) {
0057         acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
0058         return;
0059     }
0060 
0061     /*
0062      * If there is no Thread, we are not actually executing a method.
0063      * This can happen when the iASL compiler calls the interpreter
0064      * to perform constant folding.
0065      */
0066     thread = walk_state->thread;
0067     if (!thread) {
0068         return;
0069     }
0070 
0071     /* Display the method locals and arguments */
0072 
0073     acpi_os_printf("\n");
0074     acpi_db_decode_locals(walk_state);
0075     acpi_os_printf("\n");
0076     acpi_db_decode_arguments(walk_state);
0077     acpi_os_printf("\n");
0078 }
0079 
0080 /*******************************************************************************
0081  *
0082  * FUNCTION:    acpi_db_decode_internal_object
0083  *
0084  * PARAMETERS:  obj_desc        - Object to be displayed
0085  *
0086  * RETURN:      None
0087  *
0088  * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers.
0089  *
0090  ******************************************************************************/
0091 
0092 void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc)
0093 {
0094     u32 i;
0095 
0096     if (!obj_desc) {
0097         acpi_os_printf(" Uninitialized");
0098         return;
0099     }
0100 
0101     if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
0102         acpi_os_printf(" %p [%s]", obj_desc,
0103                    acpi_ut_get_descriptor_name(obj_desc));
0104         return;
0105     }
0106 
0107     acpi_os_printf(" %s", acpi_ut_get_object_type_name(obj_desc));
0108 
0109     switch (obj_desc->common.type) {
0110     case ACPI_TYPE_INTEGER:
0111 
0112         acpi_os_printf(" %8.8X%8.8X",
0113                    ACPI_FORMAT_UINT64(obj_desc->integer.value));
0114         break;
0115 
0116     case ACPI_TYPE_STRING:
0117 
0118         acpi_os_printf("(%u) \"%.60s",
0119                    obj_desc->string.length,
0120                    obj_desc->string.pointer);
0121 
0122         if (obj_desc->string.length > 60) {
0123             acpi_os_printf("...");
0124         } else {
0125             acpi_os_printf("\"");
0126         }
0127         break;
0128 
0129     case ACPI_TYPE_BUFFER:
0130 
0131         acpi_os_printf("(%u)", obj_desc->buffer.length);
0132         for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) {
0133             acpi_os_printf(" %2.2X", obj_desc->buffer.pointer[i]);
0134         }
0135         break;
0136 
0137     default:
0138 
0139         acpi_os_printf(" %p", obj_desc);
0140         break;
0141     }
0142 }
0143 
0144 /*******************************************************************************
0145  *
0146  * FUNCTION:    acpi_db_decode_node
0147  *
0148  * PARAMETERS:  node        - Object to be displayed
0149  *
0150  * RETURN:      None
0151  *
0152  * DESCRIPTION: Short display of a namespace node
0153  *
0154  ******************************************************************************/
0155 
0156 static void acpi_db_decode_node(struct acpi_namespace_node *node)
0157 {
0158 
0159     acpi_os_printf("<Node>          Name %4.4s",
0160                acpi_ut_get_node_name(node));
0161 
0162     if (node->flags & ANOBJ_METHOD_ARG) {
0163         acpi_os_printf(" [Method Arg]");
0164     }
0165     if (node->flags & ANOBJ_METHOD_LOCAL) {
0166         acpi_os_printf(" [Method Local]");
0167     }
0168 
0169     switch (node->type) {
0170 
0171         /* These types have no attached object */
0172 
0173     case ACPI_TYPE_DEVICE:
0174 
0175         acpi_os_printf(" Device");
0176         break;
0177 
0178     case ACPI_TYPE_THERMAL:
0179 
0180         acpi_os_printf(" Thermal Zone");
0181         break;
0182 
0183     default:
0184 
0185         acpi_db_decode_internal_object(acpi_ns_get_attached_object
0186                            (node));
0187         break;
0188     }
0189 }
0190 
0191 /*******************************************************************************
0192  *
0193  * FUNCTION:    acpi_db_display_internal_object
0194  *
0195  * PARAMETERS:  obj_desc        - Object to be displayed
0196  *              walk_state      - Current walk state
0197  *
0198  * RETURN:      None
0199  *
0200  * DESCRIPTION: Short display of an internal object
0201  *
0202  ******************************************************************************/
0203 
0204 void
0205 acpi_db_display_internal_object(union acpi_operand_object *obj_desc,
0206                 struct acpi_walk_state *walk_state)
0207 {
0208     u8 type;
0209 
0210     acpi_os_printf("%p ", obj_desc);
0211 
0212     if (!obj_desc) {
0213         acpi_os_printf("<Null Object>\n");
0214         return;
0215     }
0216 
0217     /* Decode the object type */
0218 
0219     switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
0220     case ACPI_DESC_TYPE_PARSER:
0221 
0222         acpi_os_printf("<Parser> ");
0223         break;
0224 
0225     case ACPI_DESC_TYPE_NAMED:
0226 
0227         acpi_db_decode_node((struct acpi_namespace_node *)obj_desc);
0228         break;
0229 
0230     case ACPI_DESC_TYPE_OPERAND:
0231 
0232         type = obj_desc->common.type;
0233         if (type > ACPI_TYPE_LOCAL_MAX) {
0234             acpi_os_printf(" Type %X [Invalid Type]", (u32)type);
0235             return;
0236         }
0237 
0238         /* Decode the ACPI object type */
0239 
0240         switch (obj_desc->common.type) {
0241         case ACPI_TYPE_LOCAL_REFERENCE:
0242 
0243             acpi_os_printf("[%s] ",
0244                        acpi_ut_get_reference_name(obj_desc));
0245 
0246             /* Decode the reference */
0247 
0248             switch (obj_desc->reference.class) {
0249             case ACPI_REFCLASS_LOCAL:
0250 
0251                 acpi_os_printf("%X ",
0252                            obj_desc->reference.value);
0253                 if (walk_state) {
0254                     obj_desc = walk_state->local_variables
0255                         [obj_desc->reference.value].object;
0256                     acpi_os_printf("%p", obj_desc);
0257                     acpi_db_decode_internal_object
0258                         (obj_desc);
0259                 }
0260                 break;
0261 
0262             case ACPI_REFCLASS_ARG:
0263 
0264                 acpi_os_printf("%X ",
0265                            obj_desc->reference.value);
0266                 if (walk_state) {
0267                     obj_desc = walk_state->arguments
0268                         [obj_desc->reference.value].object;
0269                     acpi_os_printf("%p", obj_desc);
0270                     acpi_db_decode_internal_object
0271                         (obj_desc);
0272                 }
0273                 break;
0274 
0275             case ACPI_REFCLASS_INDEX:
0276 
0277                 switch (obj_desc->reference.target_type) {
0278                 case ACPI_TYPE_BUFFER_FIELD:
0279 
0280                     acpi_os_printf("%p",
0281                                obj_desc->reference.
0282                                object);
0283                     acpi_db_decode_internal_object
0284                         (obj_desc->reference.object);
0285                     break;
0286 
0287                 case ACPI_TYPE_PACKAGE:
0288 
0289                     acpi_os_printf("%p",
0290                                obj_desc->reference.
0291                                where);
0292                     if (!obj_desc->reference.where) {
0293                         acpi_os_printf
0294                             (" Uninitialized WHERE pointer");
0295                     } else {
0296                         acpi_db_decode_internal_object(*
0297                                            (obj_desc->
0298                                         reference.
0299                                         where));
0300                     }
0301                     break;
0302 
0303                 default:
0304 
0305                     acpi_os_printf
0306                         ("Unknown index target type");
0307                     break;
0308                 }
0309                 break;
0310 
0311             case ACPI_REFCLASS_REFOF:
0312 
0313                 if (!obj_desc->reference.object) {
0314                     acpi_os_printf
0315                         ("Uninitialized reference subobject pointer");
0316                     break;
0317                 }
0318 
0319                 /* Reference can be to a Node or an Operand object */
0320 
0321                 switch (ACPI_GET_DESCRIPTOR_TYPE
0322                     (obj_desc->reference.object)) {
0323                 case ACPI_DESC_TYPE_NAMED:
0324 
0325                     acpi_db_decode_node(obj_desc->reference.
0326                                 object);
0327                     break;
0328 
0329                 case ACPI_DESC_TYPE_OPERAND:
0330 
0331                     acpi_db_decode_internal_object
0332                         (obj_desc->reference.object);
0333                     break;
0334 
0335                 default:
0336                     break;
0337                 }
0338                 break;
0339 
0340             case ACPI_REFCLASS_NAME:
0341 
0342                 acpi_db_decode_node(obj_desc->reference.node);
0343                 break;
0344 
0345             case ACPI_REFCLASS_DEBUG:
0346             case ACPI_REFCLASS_TABLE:
0347 
0348                 acpi_os_printf("\n");
0349                 break;
0350 
0351             default:    /* Unknown reference class */
0352 
0353                 acpi_os_printf("%2.2X\n",
0354                            obj_desc->reference.class);
0355                 break;
0356             }
0357             break;
0358 
0359         default:
0360 
0361             acpi_os_printf("<Obj>          ");
0362             acpi_db_decode_internal_object(obj_desc);
0363             break;
0364         }
0365         break;
0366 
0367     default:
0368 
0369         acpi_os_printf("<Not a valid ACPI Object Descriptor> [%s]",
0370                    acpi_ut_get_descriptor_name(obj_desc));
0371         break;
0372     }
0373 
0374     acpi_os_printf("\n");
0375 }
0376 
0377 /*******************************************************************************
0378  *
0379  * FUNCTION:    acpi_db_decode_locals
0380  *
0381  * PARAMETERS:  walk_state      - State for current method
0382  *
0383  * RETURN:      None
0384  *
0385  * DESCRIPTION: Display all locals for the currently running control method
0386  *
0387  ******************************************************************************/
0388 
0389 void acpi_db_decode_locals(struct acpi_walk_state *walk_state)
0390 {
0391     u32 i;
0392     union acpi_operand_object *obj_desc;
0393     struct acpi_namespace_node *node;
0394     u8 display_locals = FALSE;
0395 
0396     node = walk_state->method_node;
0397 
0398     /* There are no locals for the module-level code case */
0399 
0400     if (node == acpi_gbl_root_node) {
0401         return;
0402     }
0403 
0404     if (!node) {
0405         acpi_os_printf
0406             ("No method node (Executing subtree for buffer or opregion)\n");
0407         return;
0408     }
0409 
0410     if (node->type != ACPI_TYPE_METHOD) {
0411         acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
0412         return;
0413     }
0414 
0415     /* Are any locals actually set? */
0416 
0417     for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
0418         obj_desc = walk_state->local_variables[i].object;
0419         if (obj_desc) {
0420             display_locals = TRUE;
0421             break;
0422         }
0423     }
0424 
0425     /* If any are set, only display the ones that are set */
0426 
0427     if (display_locals) {
0428         acpi_os_printf
0429             ("\nInitialized Local Variables for Method [%4.4s]:\n",
0430              acpi_ut_get_node_name(node));
0431 
0432         for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
0433             obj_desc = walk_state->local_variables[i].object;
0434             if (obj_desc) {
0435                 acpi_os_printf("  Local%X: ", i);
0436                 acpi_db_display_internal_object(obj_desc,
0437                                 walk_state);
0438             }
0439         }
0440     } else {
0441         acpi_os_printf
0442             ("No Local Variables are initialized for Method [%4.4s]\n",
0443              acpi_ut_get_node_name(node));
0444     }
0445 }
0446 
0447 /*******************************************************************************
0448  *
0449  * FUNCTION:    acpi_db_decode_arguments
0450  *
0451  * PARAMETERS:  walk_state      - State for current method
0452  *
0453  * RETURN:      None
0454  *
0455  * DESCRIPTION: Display all arguments for the currently running control method
0456  *
0457  ******************************************************************************/
0458 
0459 void acpi_db_decode_arguments(struct acpi_walk_state *walk_state)
0460 {
0461     u32 i;
0462     union acpi_operand_object *obj_desc;
0463     struct acpi_namespace_node *node;
0464     u8 display_args = FALSE;
0465 
0466     node = walk_state->method_node;
0467 
0468     /* There are no arguments for the module-level code case */
0469 
0470     if (node == acpi_gbl_root_node) {
0471         return;
0472     }
0473 
0474     if (!node) {
0475         acpi_os_printf
0476             ("No method node (Executing subtree for buffer or opregion)\n");
0477         return;
0478     }
0479 
0480     if (node->type != ACPI_TYPE_METHOD) {
0481         acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
0482         return;
0483     }
0484 
0485     /* Are any arguments actually set? */
0486 
0487     for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
0488         obj_desc = walk_state->arguments[i].object;
0489         if (obj_desc) {
0490             display_args = TRUE;
0491             break;
0492         }
0493     }
0494 
0495     /* If any are set, only display the ones that are set */
0496 
0497     if (display_args) {
0498         acpi_os_printf("Initialized Arguments for Method [%4.4s]:  "
0499                    "(%X arguments defined for method invocation)\n",
0500                    acpi_ut_get_node_name(node),
0501                    node->object->method.param_count);
0502 
0503         for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
0504             obj_desc = walk_state->arguments[i].object;
0505             if (obj_desc) {
0506                 acpi_os_printf("  Arg%u:   ", i);
0507                 acpi_db_display_internal_object(obj_desc,
0508                                 walk_state);
0509             }
0510         }
0511     } else {
0512         acpi_os_printf
0513             ("No Arguments are initialized for method [%4.4s]\n",
0514              acpi_ut_get_node_name(node));
0515     }
0516 }