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