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