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