linux/drivers/acpi/acpica/rsdump.c
<<
>>
Prefs
   1/*******************************************************************************
   2 *
   3 * Module Name: rsdump - AML debugger support for resource structures.
   4 *
   5 ******************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2015, 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 "acresrc.h"
  47
  48#define _COMPONENT          ACPI_RESOURCES
  49ACPI_MODULE_NAME("rsdump")
  50
  51/*
  52 * All functions in this module are used by the AML Debugger only
  53 */
  54#if defined(ACPI_DEBUGGER)
  55/* Local prototypes */
  56static void acpi_rs_out_string(char *title, char *value);
  57
  58static void acpi_rs_out_integer8(char *title, u8 value);
  59
  60static void acpi_rs_out_integer16(char *title, u16 value);
  61
  62static void acpi_rs_out_integer32(char *title, u32 value);
  63
  64static void acpi_rs_out_integer64(char *title, u64 value);
  65
  66static void acpi_rs_out_title(char *title);
  67
  68static void acpi_rs_dump_byte_list(u16 length, u8 *data);
  69
  70static void acpi_rs_dump_word_list(u16 length, u16 *data);
  71
  72static void acpi_rs_dump_dword_list(u8 length, u32 *data);
  73
  74static void acpi_rs_dump_short_byte_list(u8 length, u8 *data);
  75
  76static void
  77acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source);
  78
  79static void acpi_rs_dump_address_common(union acpi_resource_data *resource);
  80
  81static void
  82acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table);
  83
  84/*******************************************************************************
  85 *
  86 * FUNCTION:    acpi_rs_dump_resource_list
  87 *
  88 * PARAMETERS:  resource_list       - Pointer to a resource descriptor list
  89 *
  90 * RETURN:      None
  91 *
  92 * DESCRIPTION: Dispatches the structure to the correct dump routine.
  93 *
  94 ******************************************************************************/
  95
  96void acpi_rs_dump_resource_list(struct acpi_resource *resource_list)
  97{
  98        u32 count = 0;
  99        u32 type;
 100
 101        ACPI_FUNCTION_ENTRY();
 102
 103        /* Check if debug output enabled */
 104
 105        if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_RESOURCES, _COMPONENT)) {
 106                return;
 107        }
 108
 109        /* Walk list and dump all resource descriptors (END_TAG terminates) */
 110
 111        do {
 112                acpi_os_printf("\n[%02X] ", count);
 113                count++;
 114
 115                /* Validate Type before dispatch */
 116
 117                type = resource_list->type;
 118                if (type > ACPI_RESOURCE_TYPE_MAX) {
 119                        acpi_os_printf
 120                            ("Invalid descriptor type (%X) in resource list\n",
 121                             resource_list->type);
 122                        return;
 123                }
 124
 125                /* Sanity check the length. It must not be zero, or we loop forever */
 126
 127                if (!resource_list->length) {
 128                        acpi_os_printf
 129                            ("Invalid zero length descriptor in resource list\n");
 130                        return;
 131                }
 132
 133                /* Dump the resource descriptor */
 134
 135                if (type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
 136                        acpi_rs_dump_descriptor(&resource_list->data,
 137                                                acpi_gbl_dump_serial_bus_dispatch
 138                                                [resource_list->data.
 139                                                 common_serial_bus.type]);
 140                } else {
 141                        acpi_rs_dump_descriptor(&resource_list->data,
 142                                                acpi_gbl_dump_resource_dispatch
 143                                                [type]);
 144                }
 145
 146                /* Point to the next resource structure */
 147
 148                resource_list = ACPI_NEXT_RESOURCE(resource_list);
 149
 150                /* Exit when END_TAG descriptor is reached */
 151
 152        } while (type != ACPI_RESOURCE_TYPE_END_TAG);
 153}
 154
 155/*******************************************************************************
 156 *
 157 * FUNCTION:    acpi_rs_dump_irq_list
 158 *
 159 * PARAMETERS:  route_table     - Pointer to the routing table to dump.
 160 *
 161 * RETURN:      None
 162 *
 163 * DESCRIPTION: Print IRQ routing table
 164 *
 165 ******************************************************************************/
 166
 167void acpi_rs_dump_irq_list(u8 *route_table)
 168{
 169        struct acpi_pci_routing_table *prt_element;
 170        u8 count;
 171
 172        ACPI_FUNCTION_ENTRY();
 173
 174        /* Check if debug output enabled */
 175
 176        if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_RESOURCES, _COMPONENT)) {
 177                return;
 178        }
 179
 180        prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, route_table);
 181
 182        /* Dump all table elements, Exit on zero length element */
 183
 184        for (count = 0; prt_element->length; count++) {
 185                acpi_os_printf("\n[%02X] PCI IRQ Routing Table Package\n",
 186                               count);
 187                acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt);
 188
 189                prt_element = ACPI_ADD_PTR(struct acpi_pci_routing_table,
 190                                           prt_element, prt_element->length);
 191        }
 192}
 193
 194/*******************************************************************************
 195 *
 196 * FUNCTION:    acpi_rs_dump_descriptor
 197 *
 198 * PARAMETERS:  resource            - Buffer containing the resource
 199 *              table               - Table entry to decode the resource
 200 *
 201 * RETURN:      None
 202 *
 203 * DESCRIPTION: Dump a resource descriptor based on a dump table entry.
 204 *
 205 ******************************************************************************/
 206
 207static void
 208acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
 209{
 210        u8 *target = NULL;
 211        u8 *previous_target;
 212        char *name;
 213        u8 count;
 214
 215        /* First table entry must contain the table length (# of table entries) */
 216
 217        count = table->offset;
 218
 219        while (count) {
 220                previous_target = target;
 221                target = ACPI_ADD_PTR(u8, resource, table->offset);
 222                name = table->name;
 223
 224                switch (table->opcode) {
 225                case ACPI_RSD_TITLE:
 226                        /*
 227                         * Optional resource title
 228                         */
 229                        if (table->name) {
 230                                acpi_os_printf("%s Resource\n", name);
 231                        }
 232                        break;
 233
 234                        /* Strings */
 235
 236                case ACPI_RSD_LITERAL:
 237
 238                        acpi_rs_out_string(name,
 239                                           ACPI_CAST_PTR(char, table->pointer));
 240                        break;
 241
 242                case ACPI_RSD_STRING:
 243
 244                        acpi_rs_out_string(name, ACPI_CAST_PTR(char, target));
 245                        break;
 246
 247                        /* Data items, 8/16/32/64 bit */
 248
 249                case ACPI_RSD_UINT8:
 250
 251                        if (table->pointer) {
 252                                acpi_rs_out_string(name, ACPI_CAST_PTR(char,
 253                                                                       table->
 254                                                                       pointer
 255                                                                       [*target]));
 256                        } else {
 257                                acpi_rs_out_integer8(name, ACPI_GET8(target));
 258                        }
 259                        break;
 260
 261                case ACPI_RSD_UINT16:
 262
 263                        acpi_rs_out_integer16(name, ACPI_GET16(target));
 264                        break;
 265
 266                case ACPI_RSD_UINT32:
 267
 268                        acpi_rs_out_integer32(name, ACPI_GET32(target));
 269                        break;
 270
 271                case ACPI_RSD_UINT64:
 272
 273                        acpi_rs_out_integer64(name, ACPI_GET64(target));
 274                        break;
 275
 276                        /* Flags: 1-bit and 2-bit flags supported */
 277
 278                case ACPI_RSD_1BITFLAG:
 279
 280                        acpi_rs_out_string(name, ACPI_CAST_PTR(char,
 281                                                               table->
 282                                                               pointer[*target &
 283                                                                       0x01]));
 284                        break;
 285
 286                case ACPI_RSD_2BITFLAG:
 287
 288                        acpi_rs_out_string(name, ACPI_CAST_PTR(char,
 289                                                               table->
 290                                                               pointer[*target &
 291                                                                       0x03]));
 292                        break;
 293
 294                case ACPI_RSD_3BITFLAG:
 295
 296                        acpi_rs_out_string(name, ACPI_CAST_PTR(char,
 297                                                               table->
 298                                                               pointer[*target &
 299                                                                       0x07]));
 300                        break;
 301
 302                case ACPI_RSD_SHORTLIST:
 303                        /*
 304                         * Short byte list (single line output) for DMA and IRQ resources
 305                         * Note: The list length is obtained from the previous table entry
 306                         */
 307                        if (previous_target) {
 308                                acpi_rs_out_title(name);
 309                                acpi_rs_dump_short_byte_list(*previous_target,
 310                                                             target);
 311                        }
 312                        break;
 313
 314                case ACPI_RSD_SHORTLISTX:
 315                        /*
 316                         * Short byte list (single line output) for GPIO vendor data
 317                         * Note: The list length is obtained from the previous table entry
 318                         */
 319                        if (previous_target) {
 320                                acpi_rs_out_title(name);
 321                                acpi_rs_dump_short_byte_list(*previous_target,
 322                                                             *
 323                                                             (ACPI_CAST_INDIRECT_PTR
 324                                                              (u8, target)));
 325                        }
 326                        break;
 327
 328                case ACPI_RSD_LONGLIST:
 329                        /*
 330                         * Long byte list for Vendor resource data
 331                         * Note: The list length is obtained from the previous table entry
 332                         */
 333                        if (previous_target) {
 334                                acpi_rs_dump_byte_list(ACPI_GET16
 335                                                       (previous_target),
 336                                                       target);
 337                        }
 338                        break;
 339
 340                case ACPI_RSD_DWORDLIST:
 341                        /*
 342                         * Dword list for Extended Interrupt resources
 343                         * Note: The list length is obtained from the previous table entry
 344                         */
 345                        if (previous_target) {
 346                                acpi_rs_dump_dword_list(*previous_target,
 347                                                        ACPI_CAST_PTR(u32,
 348                                                                      target));
 349                        }
 350                        break;
 351
 352                case ACPI_RSD_WORDLIST:
 353                        /*
 354                         * Word list for GPIO Pin Table
 355                         * Note: The list length is obtained from the previous table entry
 356                         */
 357                        if (previous_target) {
 358                                acpi_rs_dump_word_list(*previous_target,
 359                                                       *(ACPI_CAST_INDIRECT_PTR
 360                                                         (u16, target)));
 361                        }
 362                        break;
 363
 364                case ACPI_RSD_ADDRESS:
 365                        /*
 366                         * Common flags for all Address resources
 367                         */
 368                        acpi_rs_dump_address_common(ACPI_CAST_PTR
 369                                                    (union acpi_resource_data,
 370                                                     target));
 371                        break;
 372
 373                case ACPI_RSD_SOURCE:
 374                        /*
 375                         * Optional resource_source for Address resources
 376                         */
 377                        acpi_rs_dump_resource_source(ACPI_CAST_PTR
 378                                                     (struct
 379                                                                   acpi_resource_source,
 380                                                                   target));
 381                        break;
 382
 383                default:
 384
 385                        acpi_os_printf("**** Invalid table opcode [%X] ****\n",
 386                                       table->opcode);
 387                        return;
 388                }
 389
 390                table++;
 391                count--;
 392        }
 393}
 394
 395/*******************************************************************************
 396 *
 397 * FUNCTION:    acpi_rs_dump_resource_source
 398 *
 399 * PARAMETERS:  resource_source     - Pointer to a Resource Source struct
 400 *
 401 * RETURN:      None
 402 *
 403 * DESCRIPTION: Common routine for dumping the optional resource_source and the
 404 *              corresponding resource_source_index.
 405 *
 406 ******************************************************************************/
 407
 408static void
 409acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source)
 410{
 411        ACPI_FUNCTION_ENTRY();
 412
 413        if (resource_source->index == 0xFF) {
 414                return;
 415        }
 416
 417        acpi_rs_out_integer8("Resource Source Index", resource_source->index);
 418
 419        acpi_rs_out_string("Resource Source",
 420                           resource_source->string_ptr ?
 421                           resource_source->string_ptr : "[Not Specified]");
 422}
 423
 424/*******************************************************************************
 425 *
 426 * FUNCTION:    acpi_rs_dump_address_common
 427 *
 428 * PARAMETERS:  resource        - Pointer to an internal resource descriptor
 429 *
 430 * RETURN:      None
 431 *
 432 * DESCRIPTION: Dump the fields that are common to all Address resource
 433 *              descriptors
 434 *
 435 ******************************************************************************/
 436
 437static void acpi_rs_dump_address_common(union acpi_resource_data *resource)
 438{
 439        ACPI_FUNCTION_ENTRY();
 440
 441        /* Decode the type-specific flags */
 442
 443        switch (resource->address.resource_type) {
 444        case ACPI_MEMORY_RANGE:
 445
 446                acpi_rs_dump_descriptor(resource, acpi_rs_dump_memory_flags);
 447                break;
 448
 449        case ACPI_IO_RANGE:
 450
 451                acpi_rs_dump_descriptor(resource, acpi_rs_dump_io_flags);
 452                break;
 453
 454        case ACPI_BUS_NUMBER_RANGE:
 455
 456                acpi_rs_out_string("Resource Type", "Bus Number Range");
 457                break;
 458
 459        default:
 460
 461                acpi_rs_out_integer8("Resource Type",
 462                                     (u8) resource->address.resource_type);
 463                break;
 464        }
 465
 466        /* Decode the general flags */
 467
 468        acpi_rs_dump_descriptor(resource, acpi_rs_dump_general_flags);
 469}
 470
 471/*******************************************************************************
 472 *
 473 * FUNCTION:    acpi_rs_out*
 474 *
 475 * PARAMETERS:  title       - Name of the resource field
 476 *              value       - Value of the resource field
 477 *
 478 * RETURN:      None
 479 *
 480 * DESCRIPTION: Miscellaneous helper functions to consistently format the
 481 *              output of the resource dump routines
 482 *
 483 ******************************************************************************/
 484
 485static void acpi_rs_out_string(char *title, char *value)
 486{
 487        acpi_os_printf("%27s : %s", title, value);
 488        if (!*value) {
 489                acpi_os_printf("[NULL NAMESTRING]");
 490        }
 491        acpi_os_printf("\n");
 492}
 493
 494static void acpi_rs_out_integer8(char *title, u8 value)
 495{
 496        acpi_os_printf("%27s : %2.2X\n", title, value);
 497}
 498
 499static void acpi_rs_out_integer16(char *title, u16 value)
 500{
 501        acpi_os_printf("%27s : %4.4X\n", title, value);
 502}
 503
 504static void acpi_rs_out_integer32(char *title, u32 value)
 505{
 506        acpi_os_printf("%27s : %8.8X\n", title, value);
 507}
 508
 509static void acpi_rs_out_integer64(char *title, u64 value)
 510{
 511        acpi_os_printf("%27s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value));
 512}
 513
 514static void acpi_rs_out_title(char *title)
 515{
 516        acpi_os_printf("%27s : ", title);
 517}
 518
 519/*******************************************************************************
 520 *
 521 * FUNCTION:    acpi_rs_dump*List
 522 *
 523 * PARAMETERS:  length      - Number of elements in the list
 524 *              data        - Start of the list
 525 *
 526 * RETURN:      None
 527 *
 528 * DESCRIPTION: Miscellaneous functions to dump lists of raw data
 529 *
 530 ******************************************************************************/
 531
 532static void acpi_rs_dump_byte_list(u16 length, u8 * data)
 533{
 534        u8 i;
 535
 536        for (i = 0; i < length; i++) {
 537                acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]);
 538        }
 539}
 540
 541static void acpi_rs_dump_short_byte_list(u8 length, u8 * data)
 542{
 543        u8 i;
 544
 545        for (i = 0; i < length; i++) {
 546                acpi_os_printf("%X ", data[i]);
 547        }
 548        acpi_os_printf("\n");
 549}
 550
 551static void acpi_rs_dump_dword_list(u8 length, u32 * data)
 552{
 553        u8 i;
 554
 555        for (i = 0; i < length; i++) {
 556                acpi_os_printf("%25s%2.2X : %8.8X\n", "Dword", i, data[i]);
 557        }
 558}
 559
 560static void acpi_rs_dump_word_list(u16 length, u16 *data)
 561{
 562        u16 i;
 563
 564        for (i = 0; i < length; i++) {
 565                acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]);
 566        }
 567}
 568
 569#endif
 570