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 
  45 #define __RSDUMP_C__
  46 
  47 #include "acpi.h"
  48 #include "accommon.h"
  49 #include "acresrc.h"
  50 
  51 #define _COMPONENT          ACPI_RESOURCES
  52         ACPI_MODULE_NAME    ("rsdump")
  53 
  54 
  55 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
  56 
  57 /* Local prototypes */
  58 
  59 static void
  60 AcpiRsOutString (
  61     char                    *Title,
  62     char                    *Value);
  63 
  64 static void
  65 AcpiRsOutInteger8 (
  66     char                    *Title,
  67     UINT8                   Value);
  68 
  69 static void
  70 AcpiRsOutInteger16 (
  71     char                    *Title,
  72     UINT16                  Value);
  73 
  74 static void
  75 AcpiRsOutInteger32 (
  76     char                    *Title,
  77     UINT32                  Value);
  78 
  79 static void
  80 AcpiRsOutInteger64 (
  81     char                    *Title,
  82     UINT64                  Value);
  83 
  84 static void
  85 AcpiRsOutTitle (
  86     char                    *Title);
  87 
  88 static void
  89 AcpiRsDumpByteList (
  90     UINT16                  Length,
  91     UINT8                   *Data);
  92 
  93 static void
  94 AcpiRsDumpWordList (
  95     UINT16                   Length,
  96     UINT16                   *Data);
  97 
  98 static void
  99 AcpiRsDumpDwordList (
 100     UINT8                   Length,
 101     UINT32                  *Data);
 102 
 103 static void
 104 AcpiRsDumpShortByteList (
 105     UINT8                  Length,
 106     UINT8                  *Data);
 107 
 108 static void
 109 AcpiRsDumpResourceSource (
 110     ACPI_RESOURCE_SOURCE    *ResourceSource);
 111 
 112 static void
 113 AcpiRsDumpAddressCommon (
 114     ACPI_RESOURCE_DATA      *Resource);
 115 
 116 static void
 117 AcpiRsDumpDescriptor (
 118     void                    *Resource,
 119     ACPI_RSDUMP_INFO *Table);
 120 
 121 
 122 /*******************************************************************************
 123  *
 124  * FUNCTION:    AcpiRsDumpDescriptor
 125  *
 126  * PARAMETERS:  Resource            - Buffer containing the resource
 127  *              Table               - Table entry to decode the resource
 128  *
 129  * RETURN:      None
 130  *
 131  * DESCRIPTION: Dump a resource descriptor based on a dump table entry.
 132  *
 133  ******************************************************************************/
 134 
 135 static void
 136 AcpiRsDumpDescriptor (
 137     void                    *Resource,
 138     ACPI_RSDUMP_INFO        *Table)
 139 {
 140     UINT8                   *Target = NULL;
 141     UINT8                   *PreviousTarget;
 142     char                    *Name;
 143     UINT8                    Count;
 144 
 145 
 146     /* First table entry must contain the table length (# of table entries) */
 147 
 148     Count = Table->Offset;
 149 
 150     while (Count)
 151     {
 152         PreviousTarget = Target;
 153         Target = ACPI_ADD_PTR (UINT8, Resource, Table->Offset);
 154         Name = Table->Name;
 155 
 156         switch (Table->Opcode)
 157         {
 158         case ACPI_RSD_TITLE:
 159             /*
 160              * Optional resource title
 161              */
 162             if (Table->Name)
 163             {
 164                 AcpiOsPrintf ("%s Resource\n", Name);
 165             }
 166             break;
 167 
 168         /* Strings */
 169 
 170         case ACPI_RSD_LITERAL:
 171 
 172             AcpiRsOutString (Name, ACPI_CAST_PTR (char, Table->Pointer));
 173             break;
 174 
 175         case ACPI_RSD_STRING:
 176 
 177             AcpiRsOutString (Name, ACPI_CAST_PTR (char, Target));
 178             break;
 179 
 180         /* Data items, 8/16/32/64 bit */
 181 
 182         case ACPI_RSD_UINT8:
 183 
 184             if (Table->Pointer)
 185             {
 186                 AcpiRsOutString (Name, ACPI_CAST_PTR (char,
 187                     Table->Pointer [*Target]));
 188             }
 189             else
 190             {
 191                 AcpiRsOutInteger8 (Name, ACPI_GET8 (Target));
 192             }
 193             break;
 194 
 195         case ACPI_RSD_UINT16:
 196 
 197             AcpiRsOutInteger16 (Name, ACPI_GET16 (Target));
 198             break;
 199 
 200         case ACPI_RSD_UINT32:
 201 
 202             AcpiRsOutInteger32 (Name, ACPI_GET32 (Target));
 203             break;
 204 
 205         case ACPI_RSD_UINT64:
 206 
 207             AcpiRsOutInteger64 (Name, ACPI_GET64 (Target));
 208             break;
 209 
 210         /* Flags: 1-bit and 2-bit flags supported */
 211 
 212         case ACPI_RSD_1BITFLAG:
 213 
 214             AcpiRsOutString (Name, ACPI_CAST_PTR (char,
 215                 Table->Pointer [*Target & 0x01]));
 216             break;
 217 
 218         case ACPI_RSD_2BITFLAG:
 219 
 220             AcpiRsOutString (Name, ACPI_CAST_PTR (char,
 221                 Table->Pointer [*Target & 0x03]));
 222             break;
 223 
 224         case ACPI_RSD_3BITFLAG:
 225 
 226             AcpiRsOutString (Name, ACPI_CAST_PTR (char,
 227                 Table->Pointer [*Target & 0x07]));
 228             break;
 229 
 230         case ACPI_RSD_SHORTLIST:
 231             /*
 232              * Short byte list (single line output) for DMA and IRQ resources
 233              * Note: The list length is obtained from the previous table entry
 234              */
 235             if (PreviousTarget)
 236             {
 237                 AcpiRsOutTitle (Name);
 238                 AcpiRsDumpShortByteList (*PreviousTarget, Target);
 239             }
 240             break;
 241 
 242         case ACPI_RSD_SHORTLISTX:
 243             /*
 244              * Short byte list (single line output) for GPIO vendor data
 245              * Note: The list length is obtained from the previous table entry
 246              */
 247             if (PreviousTarget)
 248             {
 249                 AcpiRsOutTitle (Name);
 250                 AcpiRsDumpShortByteList (*PreviousTarget,
 251                     *(ACPI_CAST_INDIRECT_PTR (UINT8, Target)));
 252             }
 253             break;
 254 
 255         case ACPI_RSD_LONGLIST:
 256             /*
 257              * Long byte list for Vendor resource data
 258              * Note: The list length is obtained from the previous table entry
 259              */
 260             if (PreviousTarget)
 261             {
 262                 AcpiRsDumpByteList (ACPI_GET16 (PreviousTarget), Target);
 263             }
 264             break;
 265 
 266         case ACPI_RSD_DWORDLIST:
 267             /*
 268              * Dword list for Extended Interrupt resources
 269              * Note: The list length is obtained from the previous table entry
 270              */
 271             if (PreviousTarget)
 272             {
 273                 AcpiRsDumpDwordList (*PreviousTarget,
 274                     ACPI_CAST_PTR (UINT32, Target));
 275             }
 276             break;
 277 
 278         case ACPI_RSD_WORDLIST:
 279             /*
 280              * Word list for GPIO Pin Table
 281              * Note: The list length is obtained from the previous table entry
 282              */
 283             if (PreviousTarget)
 284             {
 285                 AcpiRsDumpWordList (*PreviousTarget,
 286                     *(ACPI_CAST_INDIRECT_PTR (UINT16, Target)));
 287             }
 288             break;
 289 
 290         case ACPI_RSD_ADDRESS:
 291             /*
 292              * Common flags for all Address resources
 293              */
 294             AcpiRsDumpAddressCommon (ACPI_CAST_PTR (ACPI_RESOURCE_DATA, Target));
 295             break;
 296 
 297         case ACPI_RSD_SOURCE:
 298             /*
 299              * Optional ResourceSource for Address resources
 300              */
 301             AcpiRsDumpResourceSource (ACPI_CAST_PTR (ACPI_RESOURCE_SOURCE, Target));
 302             break;
 303 
 304         default:
 305 
 306             AcpiOsPrintf ("**** Invalid table opcode [%X] ****\n",
 307                 Table->Opcode);
 308             return;
 309         }
 310 
 311         Table++;
 312         Count--;
 313     }
 314 }
 315 
 316 
 317 /*******************************************************************************
 318  *
 319  * FUNCTION:    AcpiRsDumpResourceSource
 320  *
 321  * PARAMETERS:  ResourceSource      - Pointer to a Resource Source struct
 322  *
 323  * RETURN:      None
 324  *
 325  * DESCRIPTION: Common routine for dumping the optional ResourceSource and the
 326  *              corresponding ResourceSourceIndex.
 327  *
 328  ******************************************************************************/
 329 
 330 static void
 331 AcpiRsDumpResourceSource (
 332     ACPI_RESOURCE_SOURCE    *ResourceSource)
 333 {
 334     ACPI_FUNCTION_ENTRY ();
 335 
 336 
 337     if (ResourceSource->Index == 0xFF)
 338     {
 339         return;
 340     }
 341 
 342     AcpiRsOutInteger8 ("Resource Source Index",
 343         ResourceSource->Index);
 344 
 345     AcpiRsOutString ("Resource Source",
 346         ResourceSource->StringPtr ?
 347             ResourceSource->StringPtr : "[Not Specified]");
 348 }
 349 
 350 
 351 /*******************************************************************************
 352  *
 353  * FUNCTION:    AcpiRsDumpAddressCommon
 354  *
 355  * PARAMETERS:  Resource        - Pointer to an internal resource descriptor
 356  *
 357  * RETURN:      None
 358  *
 359  * DESCRIPTION: Dump the fields that are common to all Address resource
 360  *              descriptors
 361  *
 362  ******************************************************************************/
 363 
 364 static void
 365 AcpiRsDumpAddressCommon (
 366     ACPI_RESOURCE_DATA      *Resource)
 367 {
 368     ACPI_FUNCTION_ENTRY ();
 369 
 370 
 371    /* Decode the type-specific flags */
 372 
 373     switch (Resource->Address.ResourceType)
 374     {
 375     case ACPI_MEMORY_RANGE:
 376 
 377         AcpiRsDumpDescriptor (Resource, AcpiRsDumpMemoryFlags);
 378         break;
 379 
 380     case ACPI_IO_RANGE:
 381 
 382         AcpiRsDumpDescriptor (Resource, AcpiRsDumpIoFlags);
 383         break;
 384 
 385     case ACPI_BUS_NUMBER_RANGE:
 386 
 387         AcpiRsOutString ("Resource Type", "Bus Number Range");
 388         break;
 389 
 390     default:
 391 
 392         AcpiRsOutInteger8 ("Resource Type",
 393             (UINT8) Resource->Address.ResourceType);
 394         break;
 395     }
 396 
 397     /* Decode the general flags */
 398 
 399     AcpiRsDumpDescriptor (Resource, AcpiRsDumpGeneralFlags);
 400 }
 401 
 402 
 403 /*******************************************************************************
 404  *
 405  * FUNCTION:    AcpiRsDumpResourceList
 406  *
 407  * PARAMETERS:  ResourceList        - Pointer to a resource descriptor list
 408  *
 409  * RETURN:      None
 410  *
 411  * DESCRIPTION: Dispatches the structure to the correct dump routine.
 412  *
 413  ******************************************************************************/
 414 
 415 void
 416 AcpiRsDumpResourceList (
 417     ACPI_RESOURCE           *ResourceList)
 418 {
 419     UINT32                  Count = 0;
 420     UINT32                  Type;
 421 
 422 
 423     ACPI_FUNCTION_ENTRY ();
 424 
 425 
 426     /* Check if debug output enabled */
 427 
 428     if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_RESOURCES, _COMPONENT))
 429     {
 430         return;
 431     }
 432 
 433     /* Walk list and dump all resource descriptors (END_TAG terminates) */
 434 
 435     do
 436     {
 437         AcpiOsPrintf ("\n[%02X] ", Count);
 438         Count++;
 439 
 440         /* Validate Type before dispatch */
 441 
 442         Type = ResourceList->Type;
 443         if (Type > ACPI_RESOURCE_TYPE_MAX)
 444         {
 445             AcpiOsPrintf (
 446                 "Invalid descriptor type (%X) in resource list\n",
 447                 ResourceList->Type);
 448             return;
 449         }
 450 
 451         /* Sanity check the length. It must not be zero, or we loop forever */
 452 
 453         if (!ResourceList->Length)
 454         {
 455             AcpiOsPrintf (
 456                 "Invalid zero length descriptor in resource list\n");
 457             return;
 458         }
 459 
 460         /* Dump the resource descriptor */
 461 
 462         if (Type == ACPI_RESOURCE_TYPE_SERIAL_BUS)
 463         {
 464             AcpiRsDumpDescriptor (&ResourceList->Data,
 465                 AcpiGbl_DumpSerialBusDispatch[ResourceList->Data.CommonSerialBus.Type]);
 466         }
 467         else
 468         {
 469             AcpiRsDumpDescriptor (&ResourceList->Data,
 470                 AcpiGbl_DumpResourceDispatch[Type]);
 471         }
 472 
 473         /* Point to the next resource structure */
 474 
 475         ResourceList = ACPI_NEXT_RESOURCE (ResourceList);
 476 
 477         /* Exit when END_TAG descriptor is reached */
 478 
 479     } while (Type != ACPI_RESOURCE_TYPE_END_TAG);
 480 }
 481 
 482 
 483 /*******************************************************************************
 484  *
 485  * FUNCTION:    AcpiRsDumpIrqList
 486  *
 487  * PARAMETERS:  RouteTable      - Pointer to the routing table to dump.
 488  *
 489  * RETURN:      None
 490  *
 491  * DESCRIPTION: Print IRQ routing table
 492  *
 493  ******************************************************************************/
 494 
 495 void
 496 AcpiRsDumpIrqList (
 497     UINT8                   *RouteTable)
 498 {
 499     ACPI_PCI_ROUTING_TABLE  *PrtElement;
 500     UINT8                   Count;
 501 
 502 
 503     ACPI_FUNCTION_ENTRY ();
 504 
 505 
 506     /* Check if debug output enabled */
 507 
 508     if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_RESOURCES, _COMPONENT))
 509     {
 510         return;
 511     }
 512 
 513     PrtElement = ACPI_CAST_PTR (ACPI_PCI_ROUTING_TABLE, RouteTable);
 514 
 515     /* Dump all table elements, Exit on zero length element */
 516 
 517     for (Count = 0; PrtElement->Length; Count++)
 518     {
 519         AcpiOsPrintf ("\n[%02X] PCI IRQ Routing Table Package\n", Count);
 520         AcpiRsDumpDescriptor (PrtElement, AcpiRsDumpPrt);
 521 
 522         PrtElement = ACPI_ADD_PTR (ACPI_PCI_ROUTING_TABLE,
 523                         PrtElement, PrtElement->Length);
 524     }
 525 }
 526 
 527 
 528 /*******************************************************************************
 529  *
 530  * FUNCTION:    AcpiRsOut*
 531  *
 532  * PARAMETERS:  Title       - Name of the resource field
 533  *              Value       - Value of the resource field
 534  *
 535  * RETURN:      None
 536  *
 537  * DESCRIPTION: Miscellaneous helper functions to consistently format the
 538  *              output of the resource dump routines
 539  *
 540  ******************************************************************************/
 541 
 542 static void
 543 AcpiRsOutString (
 544     char                    *Title,
 545     char                    *Value)
 546 {
 547     AcpiOsPrintf ("%27s : %s", Title, Value);
 548     if (!*Value)
 549     {
 550         AcpiOsPrintf ("[NULL NAMESTRING]");
 551     }
 552     AcpiOsPrintf ("\n");
 553 }
 554 
 555 static void
 556 AcpiRsOutInteger8 (
 557     char                    *Title,
 558     UINT8                   Value)
 559 {
 560     AcpiOsPrintf ("%27s : %2.2X\n", Title, Value);
 561 }
 562 
 563 static void
 564 AcpiRsOutInteger16 (
 565     char                    *Title,
 566     UINT16                  Value)
 567 {
 568     AcpiOsPrintf ("%27s : %4.4X\n", Title, Value);
 569 }
 570 
 571 static void
 572 AcpiRsOutInteger32 (
 573     char                    *Title,
 574     UINT32                  Value)
 575 {
 576     AcpiOsPrintf ("%27s : %8.8X\n", Title, Value);
 577 }
 578 
 579 static void
 580 AcpiRsOutInteger64 (
 581     char                    *Title,
 582     UINT64                  Value)
 583 {
 584     AcpiOsPrintf ("%27s : %8.8X%8.8X\n", Title,
 585         ACPI_FORMAT_UINT64 (Value));
 586 }
 587 
 588 static void
 589 AcpiRsOutTitle (
 590     char                    *Title)
 591 {
 592     AcpiOsPrintf ("%27s : ", Title);
 593 }
 594 
 595 
 596 /*******************************************************************************
 597  *
 598  * FUNCTION:    AcpiRsDump*List
 599  *
 600  * PARAMETERS:  Length      - Number of elements in the list
 601  *              Data        - Start of the list
 602  *
 603  * RETURN:      None
 604  *
 605  * DESCRIPTION: Miscellaneous functions to dump lists of raw data
 606  *
 607  ******************************************************************************/
 608 
 609 static void
 610 AcpiRsDumpByteList (
 611     UINT16                  Length,
 612     UINT8                   *Data)
 613 {
 614     UINT8                   i;
 615 
 616 
 617     for (i = 0; i < Length; i++)
 618     {
 619         AcpiOsPrintf ("%25s%2.2X : %2.2X\n",
 620             "Byte", i, Data[i]);
 621     }
 622 }
 623 
 624 static void
 625 AcpiRsDumpShortByteList (
 626     UINT8                  Length,
 627     UINT8                  *Data)
 628 {
 629     UINT8                   i;
 630 
 631 
 632     for (i = 0; i < Length; i++)
 633     {
 634         AcpiOsPrintf ("%X ", Data[i]);
 635     }
 636     AcpiOsPrintf ("\n");
 637 }
 638 
 639 static void
 640 AcpiRsDumpDwordList (
 641     UINT8                   Length,
 642     UINT32                  *Data)
 643 {
 644     UINT8                   i;
 645 
 646 
 647     for (i = 0; i < Length; i++)
 648     {
 649         AcpiOsPrintf ("%25s%2.2X : %8.8X\n",
 650             "Dword", i, Data[i]);
 651     }
 652 }
 653 
 654 static void
 655 AcpiRsDumpWordList (
 656     UINT16                  Length,
 657     UINT16                  *Data)
 658 {
 659     UINT16                  i;
 660 
 661 
 662     for (i = 0; i < Length; i++)
 663     {
 664         AcpiOsPrintf ("%25s%2.2X : %4.4X\n",
 665             "Word", i, Data[i]);
 666     }
 667 }
 668 
 669 #endif