linux/drivers/acpi/acpica/exdebug.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/******************************************************************************
   3 *
   4 * Module Name: exdebug - Support for stores to the AML Debug Object
   5 *
   6 * Copyright (C) 2000 - 2021, Intel Corp.
   7 *
   8 *****************************************************************************/
   9
  10#include <acpi/acpi.h>
  11#include "accommon.h"
  12#include "acinterp.h"
  13
  14#define _COMPONENT          ACPI_EXECUTER
  15ACPI_MODULE_NAME("exdebug")
  16
  17#ifndef ACPI_NO_ERROR_MESSAGES
  18/*******************************************************************************
  19 *
  20 * FUNCTION:    acpi_ex_do_debug_object
  21 *
  22 * PARAMETERS:  source_desc         - Object to be output to "Debug Object"
  23 *              level               - Indentation level (used for packages)
  24 *              index               - Current package element, zero if not pkg
  25 *
  26 * RETURN:      None
  27 *
  28 * DESCRIPTION: Handles stores to the AML Debug Object. For example:
  29 *              Store(INT1, Debug)
  30 *
  31 * This function is not compiled if ACPI_NO_ERROR_MESSAGES is set.
  32 *
  33 * This function is only enabled if acpi_gbl_enable_aml_debug_object is set, or
  34 * if ACPI_LV_DEBUG_OBJECT is set in the acpi_dbg_level. Thus, in the normal
  35 * operational case, stores to the debug object are ignored but can be easily
  36 * enabled if necessary.
  37 *
  38 ******************************************************************************/
  39void
  40acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
  41                        u32 level, u32 index)
  42{
  43        u32 i;
  44        u32 timer;
  45        union acpi_operand_object *object_desc;
  46        u32 value;
  47
  48        ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc);
  49
  50        /* Output must be enabled via the debug_object global or the dbg_level */
  51
  52        if (!acpi_gbl_enable_aml_debug_object &&
  53            !(acpi_dbg_level & ACPI_LV_DEBUG_OBJECT)) {
  54                return_VOID;
  55        }
  56
  57        /* Newline -- don't emit the line header */
  58
  59        if (source_desc &&
  60            (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) &&
  61            (source_desc->common.type == ACPI_TYPE_STRING)) {
  62                if ((source_desc->string.length == 1) &&
  63                    (*source_desc->string.pointer == '\n')) {
  64                        acpi_os_printf("\n");
  65                        return_VOID;
  66                }
  67        }
  68
  69        /*
  70         * Print line header as long as we are not in the middle of an
  71         * object display
  72         */
  73        if (!((level > 0) && index == 0)) {
  74                if (acpi_gbl_display_debug_timer) {
  75                        /*
  76                         * We will emit the current timer value (in microseconds) with each
  77                         * debug output. Only need the lower 26 bits. This allows for 67
  78                         * million microseconds or 67 seconds before rollover.
  79                         *
  80                         * Convert 100 nanosecond units to microseconds
  81                         */
  82                        timer = ((u32)acpi_os_get_timer() / 10);
  83                        timer &= 0x03FFFFFF;
  84
  85                        acpi_os_printf("ACPI Debug: T=0x%8.8X %*s", timer,
  86                                       level, " ");
  87                } else {
  88                        acpi_os_printf("ACPI Debug: %*s", level, " ");
  89                }
  90        }
  91
  92        /* Display the index for package output only */
  93
  94        if (index > 0) {
  95                acpi_os_printf("(%.2u) ", index - 1);
  96        }
  97
  98        if (!source_desc) {
  99                acpi_os_printf("[Null Object]\n");
 100                return_VOID;
 101        }
 102
 103        if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) {
 104
 105                /* No object type prefix needed for integers and strings */
 106
 107                if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
 108                    (source_desc->common.type != ACPI_TYPE_STRING)) {
 109                        acpi_os_printf("%s ",
 110                                       acpi_ut_get_object_type_name
 111                                       (source_desc));
 112                }
 113
 114                if (!acpi_ut_valid_internal_object(source_desc)) {
 115                        acpi_os_printf("%p, Invalid Internal Object!\n",
 116                                       source_desc);
 117                        return_VOID;
 118                }
 119        } else if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) ==
 120                   ACPI_DESC_TYPE_NAMED) {
 121                acpi_os_printf("%s (Node %p)\n",
 122                               acpi_ut_get_type_name(((struct
 123                                                       acpi_namespace_node *)
 124                                                      source_desc)->type),
 125                               source_desc);
 126                return_VOID;
 127        } else {
 128                return_VOID;
 129        }
 130
 131        /* source_desc is of type ACPI_DESC_TYPE_OPERAND */
 132
 133        switch (source_desc->common.type) {
 134        case ACPI_TYPE_INTEGER:
 135
 136                /* Output correct integer width */
 137
 138                if (acpi_gbl_integer_byte_width == 4) {
 139                        acpi_os_printf("0x%8.8X\n",
 140                                       (u32)source_desc->integer.value);
 141                } else {
 142                        acpi_os_printf("0x%8.8X%8.8X\n",
 143                                       ACPI_FORMAT_UINT64(source_desc->integer.
 144                                                          value));
 145                }
 146                break;
 147
 148        case ACPI_TYPE_BUFFER:
 149
 150                acpi_os_printf("[0x%.2X]\n", (u32)source_desc->buffer.length);
 151                acpi_ut_dump_buffer(source_desc->buffer.pointer,
 152                                    (source_desc->buffer.length < 256) ?
 153                                    source_desc->buffer.length : 256,
 154                                    DB_BYTE_DISPLAY, 0);
 155                break;
 156
 157        case ACPI_TYPE_STRING:
 158
 159                acpi_os_printf("\"%s\"\n", source_desc->string.pointer);
 160                break;
 161
 162        case ACPI_TYPE_PACKAGE:
 163
 164                acpi_os_printf("(Contains 0x%.2X Elements):\n",
 165                               source_desc->package.count);
 166
 167                /* Output the entire contents of the package */
 168
 169                for (i = 0; i < source_desc->package.count; i++) {
 170                        acpi_ex_do_debug_object(source_desc->package.
 171                                                elements[i], level + 4, i + 1);
 172                }
 173                break;
 174
 175        case ACPI_TYPE_LOCAL_REFERENCE:
 176
 177                acpi_os_printf("[%s] ",
 178                               acpi_ut_get_reference_name(source_desc));
 179
 180                /* Decode the reference */
 181
 182                switch (source_desc->reference.class) {
 183                case ACPI_REFCLASS_INDEX:
 184
 185                        acpi_os_printf("0x%X\n", source_desc->reference.value);
 186                        break;
 187
 188                case ACPI_REFCLASS_TABLE:
 189
 190                        /* Case for ddb_handle */
 191
 192                        acpi_os_printf("Table Index 0x%X\n",
 193                                       source_desc->reference.value);
 194                        return_VOID;
 195
 196                default:
 197
 198                        break;
 199                }
 200
 201                acpi_os_printf(" ");
 202
 203                /* Check for valid node first, then valid object */
 204
 205                if (source_desc->reference.node) {
 206                        if (ACPI_GET_DESCRIPTOR_TYPE
 207                            (source_desc->reference.node) !=
 208                            ACPI_DESC_TYPE_NAMED) {
 209                                acpi_os_printf
 210                                    (" %p - Not a valid namespace node\n",
 211                                     source_desc->reference.node);
 212                        } else {
 213                                acpi_os_printf("Node %p [%4.4s] ",
 214                                               source_desc->reference.node,
 215                                               (source_desc->reference.node)->
 216                                               name.ascii);
 217
 218                                switch ((source_desc->reference.node)->type) {
 219
 220                                        /* These types have no attached object */
 221
 222                                case ACPI_TYPE_DEVICE:
 223                                        acpi_os_printf("Device\n");
 224                                        break;
 225
 226                                case ACPI_TYPE_THERMAL:
 227                                        acpi_os_printf("Thermal Zone\n");
 228                                        break;
 229
 230                                default:
 231
 232                                        acpi_ex_do_debug_object((source_desc->
 233                                                                 reference.
 234                                                                 node)->object,
 235                                                                level + 4, 0);
 236                                        break;
 237                                }
 238                        }
 239                } else if (source_desc->reference.object) {
 240                        if (ACPI_GET_DESCRIPTOR_TYPE
 241                            (source_desc->reference.object) ==
 242                            ACPI_DESC_TYPE_NAMED) {
 243
 244                                /* Reference object is a namespace node */
 245
 246                                acpi_ex_do_debug_object(ACPI_CAST_PTR
 247                                                        (union
 248                                                         acpi_operand_object,
 249                                                         source_desc->reference.
 250                                                         object), level + 4, 0);
 251                        } else {
 252                                object_desc = source_desc->reference.object;
 253                                value = source_desc->reference.value;
 254
 255                                switch (object_desc->common.type) {
 256                                case ACPI_TYPE_BUFFER:
 257
 258                                        acpi_os_printf("Buffer[%u] = 0x%2.2X\n",
 259                                                       value,
 260                                                       *source_desc->reference.
 261                                                       index_pointer);
 262                                        break;
 263
 264                                case ACPI_TYPE_STRING:
 265
 266                                        acpi_os_printf
 267                                            ("String[%u] = \"%c\" (0x%2.2X)\n",
 268                                             value,
 269                                             *source_desc->reference.
 270                                             index_pointer,
 271                                             *source_desc->reference.
 272                                             index_pointer);
 273                                        break;
 274
 275                                case ACPI_TYPE_PACKAGE:
 276
 277                                        acpi_os_printf("Package[%u] = ", value);
 278                                        if (!(*source_desc->reference.where)) {
 279                                                acpi_os_printf
 280                                                    ("[Uninitialized Package Element]\n");
 281                                        } else {
 282                                                acpi_ex_do_debug_object
 283                                                    (*source_desc->reference.
 284                                                     where, level + 4, 0);
 285                                        }
 286                                        break;
 287
 288                                default:
 289
 290                                        acpi_os_printf
 291                                            ("Unknown Reference object type %X\n",
 292                                             object_desc->common.type);
 293                                        break;
 294                                }
 295                        }
 296                }
 297                break;
 298
 299        default:
 300
 301                acpi_os_printf("(Descriptor %p)\n", source_desc);
 302                break;
 303        }
 304
 305        ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "\n"));
 306        return_VOID;
 307}
 308#endif
 309