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