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