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