1 /** @file 2 Main file for Pci shell Debug1 function. 3 4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR> 5 Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "UefiShellDebug1CommandsLib.h" 17 #include <Protocol/PciRootBridgeIo.h> 18 #include <Library/ShellLib.h> 19 #include <IndustryStandard/Pci.h> 20 #include <IndustryStandard/Acpi.h> 21 #include "Pci.h" 22 23 // 24 // Printable strings for Pci class code 25 // 26 typedef struct { 27 CHAR16 *BaseClass; // Pointer to the PCI base class string 28 CHAR16 *SubClass; // Pointer to the PCI sub class string 29 CHAR16 *PIFClass; // Pointer to the PCI programming interface string 30 } PCI_CLASS_STRINGS; 31 32 // 33 // a structure holding a single entry, which also points to its lower level 34 // class 35 // 36 typedef struct PCI_CLASS_ENTRY_TAG { 37 UINT8 Code; // Class, subclass or I/F code 38 CHAR16 *DescText; // Description string 39 struct PCI_CLASS_ENTRY_TAG *LowerLevelClass; // Subclass or I/F if any 40 } PCI_CLASS_ENTRY; 41 42 // 43 // Declarations of entries which contain printable strings for class codes 44 // in PCI configuration space 45 // 46 PCI_CLASS_ENTRY PCIBlankEntry[]; 47 PCI_CLASS_ENTRY PCISubClass_00[]; 48 PCI_CLASS_ENTRY PCISubClass_01[]; 49 PCI_CLASS_ENTRY PCISubClass_02[]; 50 PCI_CLASS_ENTRY PCISubClass_03[]; 51 PCI_CLASS_ENTRY PCISubClass_04[]; 52 PCI_CLASS_ENTRY PCISubClass_05[]; 53 PCI_CLASS_ENTRY PCISubClass_06[]; 54 PCI_CLASS_ENTRY PCISubClass_07[]; 55 PCI_CLASS_ENTRY PCISubClass_08[]; 56 PCI_CLASS_ENTRY PCISubClass_09[]; 57 PCI_CLASS_ENTRY PCISubClass_0a[]; 58 PCI_CLASS_ENTRY PCISubClass_0b[]; 59 PCI_CLASS_ENTRY PCISubClass_0c[]; 60 PCI_CLASS_ENTRY PCISubClass_0d[]; 61 PCI_CLASS_ENTRY PCISubClass_0e[]; 62 PCI_CLASS_ENTRY PCISubClass_0f[]; 63 PCI_CLASS_ENTRY PCISubClass_10[]; 64 PCI_CLASS_ENTRY PCISubClass_11[]; 65 PCI_CLASS_ENTRY PCISubClass_12[]; 66 PCI_CLASS_ENTRY PCISubClass_13[]; 67 PCI_CLASS_ENTRY PCIPIFClass_0100[]; 68 PCI_CLASS_ENTRY PCIPIFClass_0101[]; 69 PCI_CLASS_ENTRY PCIPIFClass_0105[]; 70 PCI_CLASS_ENTRY PCIPIFClass_0106[]; 71 PCI_CLASS_ENTRY PCIPIFClass_0107[]; 72 PCI_CLASS_ENTRY PCIPIFClass_0108[]; 73 PCI_CLASS_ENTRY PCIPIFClass_0109[]; 74 PCI_CLASS_ENTRY PCIPIFClass_0300[]; 75 PCI_CLASS_ENTRY PCIPIFClass_0604[]; 76 PCI_CLASS_ENTRY PCIPIFClass_0609[]; 77 PCI_CLASS_ENTRY PCIPIFClass_060b[]; 78 PCI_CLASS_ENTRY PCIPIFClass_0700[]; 79 PCI_CLASS_ENTRY PCIPIFClass_0701[]; 80 PCI_CLASS_ENTRY PCIPIFClass_0703[]; 81 PCI_CLASS_ENTRY PCIPIFClass_0800[]; 82 PCI_CLASS_ENTRY PCIPIFClass_0801[]; 83 PCI_CLASS_ENTRY PCIPIFClass_0802[]; 84 PCI_CLASS_ENTRY PCIPIFClass_0803[]; 85 PCI_CLASS_ENTRY PCIPIFClass_0904[]; 86 PCI_CLASS_ENTRY PCIPIFClass_0c00[]; 87 PCI_CLASS_ENTRY PCIPIFClass_0c03[]; 88 PCI_CLASS_ENTRY PCIPIFClass_0c07[]; 89 PCI_CLASS_ENTRY PCIPIFClass_0d01[]; 90 PCI_CLASS_ENTRY PCIPIFClass_0e00[]; 91 92 // 93 // Base class strings entries 94 // 95 PCI_CLASS_ENTRY gClassStringList[] = { 96 { 97 0x00, 98 L"Pre 2.0 device", 99 PCISubClass_00 100 }, 101 { 102 0x01, 103 L"Mass Storage Controller", 104 PCISubClass_01 105 }, 106 { 107 0x02, 108 L"Network Controller", 109 PCISubClass_02 110 }, 111 { 112 0x03, 113 L"Display Controller", 114 PCISubClass_03 115 }, 116 { 117 0x04, 118 L"Multimedia Device", 119 PCISubClass_04 120 }, 121 { 122 0x05, 123 L"Memory Controller", 124 PCISubClass_05 125 }, 126 { 127 0x06, 128 L"Bridge Device", 129 PCISubClass_06 130 }, 131 { 132 0x07, 133 L"Simple Communications Controllers", 134 PCISubClass_07 135 }, 136 { 137 0x08, 138 L"Base System Peripherals", 139 PCISubClass_08 140 }, 141 { 142 0x09, 143 L"Input Devices", 144 PCISubClass_09 145 }, 146 { 147 0x0a, 148 L"Docking Stations", 149 PCISubClass_0a 150 }, 151 { 152 0x0b, 153 L"Processors", 154 PCISubClass_0b 155 }, 156 { 157 0x0c, 158 L"Serial Bus Controllers", 159 PCISubClass_0c 160 }, 161 { 162 0x0d, 163 L"Wireless Controllers", 164 PCISubClass_0d 165 }, 166 { 167 0x0e, 168 L"Intelligent IO Controllers", 169 PCISubClass_0e 170 }, 171 { 172 0x0f, 173 L"Satellite Communications Controllers", 174 PCISubClass_0f 175 }, 176 { 177 0x10, 178 L"Encryption/Decryption Controllers", 179 PCISubClass_10 180 }, 181 { 182 0x11, 183 L"Data Acquisition & Signal Processing Controllers", 184 PCISubClass_11 185 }, 186 { 187 0x12, 188 L"Processing Accelerators", 189 PCISubClass_12 190 }, 191 { 192 0x13, 193 L"Non-Essential Instrumentation", 194 PCISubClass_13 195 }, 196 { 197 0xff, 198 L"Device does not fit in any defined classes", 199 PCIBlankEntry 200 }, 201 { 202 0x00, 203 NULL, 204 /* null string ends the list */NULL 205 } 206 }; 207 208 // 209 // Subclass strings entries 210 // 211 PCI_CLASS_ENTRY PCIBlankEntry[] = { 212 { 213 0x00, 214 L"", 215 PCIBlankEntry 216 }, 217 { 218 0x00, 219 NULL, 220 /* null string ends the list */NULL 221 } 222 }; 223 224 PCI_CLASS_ENTRY PCISubClass_00[] = { 225 { 226 0x00, 227 L"All devices other than VGA", 228 PCIBlankEntry 229 }, 230 { 231 0x01, 232 L"VGA-compatible devices", 233 PCIBlankEntry 234 }, 235 { 236 0x00, 237 NULL, 238 /* null string ends the list */NULL 239 } 240 }; 241 242 PCI_CLASS_ENTRY PCISubClass_01[] = { 243 { 244 0x00, 245 L"SCSI", 246 PCIPIFClass_0100 247 }, 248 { 249 0x01, 250 L"IDE controller", 251 PCIPIFClass_0101 252 }, 253 { 254 0x02, 255 L"Floppy disk controller", 256 PCIBlankEntry 257 }, 258 { 259 0x03, 260 L"IPI controller", 261 PCIBlankEntry 262 }, 263 { 264 0x04, 265 L"RAID controller", 266 PCIBlankEntry 267 }, 268 { 269 0x05, 270 L"ATA controller with ADMA interface", 271 PCIPIFClass_0105 272 }, 273 { 274 0x06, 275 L"Serial ATA controller", 276 PCIPIFClass_0106 277 }, 278 { 279 0x07, 280 L"Serial Attached SCSI (SAS) controller ", 281 PCIPIFClass_0107 282 }, 283 { 284 0x08, 285 L"Non-volatile memory subsystem", 286 PCIPIFClass_0108 287 }, 288 { 289 0x09, 290 L"Universal Flash Storage (UFS) controller ", 291 PCIPIFClass_0109 292 }, 293 { 294 0x80, 295 L"Other mass storage controller", 296 PCIBlankEntry 297 }, 298 { 299 0x00, 300 NULL, 301 /* null string ends the list */NULL 302 } 303 }; 304 305 PCI_CLASS_ENTRY PCISubClass_02[] = { 306 { 307 0x00, 308 L"Ethernet controller", 309 PCIBlankEntry 310 }, 311 { 312 0x01, 313 L"Token ring controller", 314 PCIBlankEntry 315 }, 316 { 317 0x02, 318 L"FDDI controller", 319 PCIBlankEntry 320 }, 321 { 322 0x03, 323 L"ATM controller", 324 PCIBlankEntry 325 }, 326 { 327 0x04, 328 L"ISDN controller", 329 PCIBlankEntry 330 }, 331 { 332 0x05, 333 L"WorldFip controller", 334 PCIBlankEntry 335 }, 336 { 337 0x06, 338 L"PICMG 2.14 Multi Computing", 339 PCIBlankEntry 340 }, 341 { 342 0x07, 343 L"InfiniBand controller", 344 PCIBlankEntry 345 }, 346 { 347 0x80, 348 L"Other network controller", 349 PCIBlankEntry 350 }, 351 { 352 0x00, 353 NULL, 354 /* null string ends the list */NULL 355 } 356 }; 357 358 PCI_CLASS_ENTRY PCISubClass_03[] = { 359 { 360 0x00, 361 L"VGA/8514 controller", 362 PCIPIFClass_0300 363 }, 364 { 365 0x01, 366 L"XGA controller", 367 PCIBlankEntry 368 }, 369 { 370 0x02, 371 L"3D controller", 372 PCIBlankEntry 373 }, 374 { 375 0x80, 376 L"Other display controller", 377 PCIBlankEntry 378 }, 379 { 380 0x00, 381 NULL, 382 /* null string ends the list */PCIBlankEntry 383 } 384 }; 385 386 PCI_CLASS_ENTRY PCISubClass_04[] = { 387 { 388 0x00, 389 L"Video device", 390 PCIBlankEntry 391 }, 392 { 393 0x01, 394 L"Audio device", 395 PCIBlankEntry 396 }, 397 { 398 0x02, 399 L"Computer Telephony device", 400 PCIBlankEntry 401 }, 402 { 403 0x03, 404 L"Mixed mode device", 405 PCIBlankEntry 406 }, 407 { 408 0x80, 409 L"Other multimedia device", 410 PCIBlankEntry 411 }, 412 { 413 0x00, 414 NULL, 415 /* null string ends the list */NULL 416 } 417 }; 418 419 PCI_CLASS_ENTRY PCISubClass_05[] = { 420 { 421 0x00, 422 L"RAM memory controller", 423 PCIBlankEntry 424 }, 425 { 426 0x01, 427 L"Flash memory controller", 428 PCIBlankEntry 429 }, 430 { 431 0x80, 432 L"Other memory controller", 433 PCIBlankEntry 434 }, 435 { 436 0x00, 437 NULL, 438 /* null string ends the list */NULL 439 } 440 }; 441 442 PCI_CLASS_ENTRY PCISubClass_06[] = { 443 { 444 0x00, 445 L"Host/PCI bridge", 446 PCIBlankEntry 447 }, 448 { 449 0x01, 450 L"PCI/ISA bridge", 451 PCIBlankEntry 452 }, 453 { 454 0x02, 455 L"PCI/EISA bridge", 456 PCIBlankEntry 457 }, 458 { 459 0x03, 460 L"PCI/Micro Channel bridge", 461 PCIBlankEntry 462 }, 463 { 464 0x04, 465 L"PCI/PCI bridge", 466 PCIPIFClass_0604 467 }, 468 { 469 0x05, 470 L"PCI/PCMCIA bridge", 471 PCIBlankEntry 472 }, 473 { 474 0x06, 475 L"NuBus bridge", 476 PCIBlankEntry 477 }, 478 { 479 0x07, 480 L"CardBus bridge", 481 PCIBlankEntry 482 }, 483 { 484 0x08, 485 L"RACEway bridge", 486 PCIBlankEntry 487 }, 488 { 489 0x09, 490 L"Semi-transparent PCI-to-PCI bridge", 491 PCIPIFClass_0609 492 }, 493 { 494 0x0A, 495 L"InfiniBand-to-PCI host bridge", 496 PCIBlankEntry 497 }, 498 { 499 0x0B, 500 L"Advanced Switching to PCI host bridge", 501 PCIPIFClass_060b 502 }, 503 { 504 0x80, 505 L"Other bridge type", 506 PCIBlankEntry 507 }, 508 { 509 0x00, 510 NULL, 511 /* null string ends the list */NULL 512 } 513 }; 514 515 PCI_CLASS_ENTRY PCISubClass_07[] = { 516 { 517 0x00, 518 L"Serial controller", 519 PCIPIFClass_0700 520 }, 521 { 522 0x01, 523 L"Parallel port", 524 PCIPIFClass_0701 525 }, 526 { 527 0x02, 528 L"Multiport serial controller", 529 PCIBlankEntry 530 }, 531 { 532 0x03, 533 L"Modem", 534 PCIPIFClass_0703 535 }, 536 { 537 0x04, 538 L"GPIB (IEEE 488.1/2) controller", 539 PCIBlankEntry 540 }, 541 { 542 0x05, 543 L"Smart Card", 544 PCIBlankEntry 545 }, 546 { 547 0x80, 548 L"Other communication device", 549 PCIBlankEntry 550 }, 551 { 552 0x00, 553 NULL, 554 /* null string ends the list */NULL 555 } 556 }; 557 558 PCI_CLASS_ENTRY PCISubClass_08[] = { 559 { 560 0x00, 561 L"PIC", 562 PCIPIFClass_0800 563 }, 564 { 565 0x01, 566 L"DMA controller", 567 PCIPIFClass_0801 568 }, 569 { 570 0x02, 571 L"System timer", 572 PCIPIFClass_0802 573 }, 574 { 575 0x03, 576 L"RTC controller", 577 PCIPIFClass_0803 578 }, 579 { 580 0x04, 581 L"Generic PCI Hot-Plug controller", 582 PCIBlankEntry 583 }, 584 { 585 0x05, 586 L"SD Host controller", 587 PCIBlankEntry 588 }, 589 { 590 0x06, 591 L"IOMMU", 592 PCIBlankEntry 593 }, 594 { 595 0x07, 596 L"Root Complex Event Collector", 597 PCIBlankEntry 598 }, 599 { 600 0x80, 601 L"Other system peripheral", 602 PCIBlankEntry 603 }, 604 { 605 0x00, 606 NULL, 607 /* null string ends the list */NULL 608 } 609 }; 610 611 PCI_CLASS_ENTRY PCISubClass_09[] = { 612 { 613 0x00, 614 L"Keyboard controller", 615 PCIBlankEntry 616 }, 617 { 618 0x01, 619 L"Digitizer (pen)", 620 PCIBlankEntry 621 }, 622 { 623 0x02, 624 L"Mouse controller", 625 PCIBlankEntry 626 }, 627 { 628 0x03, 629 L"Scanner controller", 630 PCIBlankEntry 631 }, 632 { 633 0x04, 634 L"Gameport controller", 635 PCIPIFClass_0904 636 }, 637 { 638 0x80, 639 L"Other input controller", 640 PCIBlankEntry 641 }, 642 { 643 0x00, 644 NULL, 645 /* null string ends the list */NULL 646 } 647 }; 648 649 PCI_CLASS_ENTRY PCISubClass_0a[] = { 650 { 651 0x00, 652 L"Generic docking station", 653 PCIBlankEntry 654 }, 655 { 656 0x80, 657 L"Other type of docking station", 658 PCIBlankEntry 659 }, 660 { 661 0x00, 662 NULL, 663 /* null string ends the list */NULL 664 } 665 }; 666 667 PCI_CLASS_ENTRY PCISubClass_0b[] = { 668 { 669 0x00, 670 L"386", 671 PCIBlankEntry 672 }, 673 { 674 0x01, 675 L"486", 676 PCIBlankEntry 677 }, 678 { 679 0x02, 680 L"Pentium", 681 PCIBlankEntry 682 }, 683 { 684 0x10, 685 L"Alpha", 686 PCIBlankEntry 687 }, 688 { 689 0x20, 690 L"PowerPC", 691 PCIBlankEntry 692 }, 693 { 694 0x30, 695 L"MIPS", 696 PCIBlankEntry 697 }, 698 { 699 0x40, 700 L"Co-processor", 701 PCIBlankEntry 702 }, 703 { 704 0x80, 705 L"Other processor", 706 PCIBlankEntry 707 }, 708 { 709 0x00, 710 NULL, 711 /* null string ends the list */NULL 712 } 713 }; 714 715 PCI_CLASS_ENTRY PCISubClass_0c[] = { 716 { 717 0x00, 718 L"IEEE 1394", 719 PCIPIFClass_0c00 720 }, 721 { 722 0x01, 723 L"ACCESS.bus", 724 PCIBlankEntry 725 }, 726 { 727 0x02, 728 L"SSA", 729 PCIBlankEntry 730 }, 731 { 732 0x03, 733 L"USB", 734 PCIPIFClass_0c03 735 }, 736 { 737 0x04, 738 L"Fibre Channel", 739 PCIBlankEntry 740 }, 741 { 742 0x05, 743 L"System Management Bus", 744 PCIBlankEntry 745 }, 746 { 747 0x06, 748 L"InfiniBand", 749 PCIBlankEntry 750 }, 751 { 752 0x07, 753 L"IPMI", 754 PCIPIFClass_0c07 755 }, 756 { 757 0x08, 758 L"SERCOS Interface Standard (IEC 61491)", 759 PCIBlankEntry 760 }, 761 { 762 0x09, 763 L"CANbus", 764 PCIBlankEntry 765 }, 766 { 767 0x80, 768 L"Other bus type", 769 PCIBlankEntry 770 }, 771 { 772 0x00, 773 NULL, 774 /* null string ends the list */NULL 775 } 776 }; 777 778 PCI_CLASS_ENTRY PCISubClass_0d[] = { 779 { 780 0x00, 781 L"iRDA compatible controller", 782 PCIBlankEntry 783 }, 784 { 785 0x01, 786 L"", 787 PCIPIFClass_0d01 788 }, 789 { 790 0x10, 791 L"RF controller", 792 PCIBlankEntry 793 }, 794 { 795 0x11, 796 L"Bluetooth", 797 PCIBlankEntry 798 }, 799 { 800 0x12, 801 L"Broadband", 802 PCIBlankEntry 803 }, 804 { 805 0x20, 806 L"Ethernet (802.11a - 5 GHz)", 807 PCIBlankEntry 808 }, 809 { 810 0x21, 811 L"Ethernet (802.11b - 2.4 GHz)", 812 PCIBlankEntry 813 }, 814 { 815 0x80, 816 L"Other type of wireless controller", 817 PCIBlankEntry 818 }, 819 { 820 0x00, 821 NULL, 822 /* null string ends the list */NULL 823 } 824 }; 825 826 PCI_CLASS_ENTRY PCISubClass_0e[] = { 827 { 828 0x00, 829 L"I2O Architecture", 830 PCIPIFClass_0e00 831 }, 832 { 833 0x00, 834 NULL, 835 /* null string ends the list */NULL 836 } 837 }; 838 839 PCI_CLASS_ENTRY PCISubClass_0f[] = { 840 { 841 0x01, 842 L"TV", 843 PCIBlankEntry 844 }, 845 { 846 0x02, 847 L"Audio", 848 PCIBlankEntry 849 }, 850 { 851 0x03, 852 L"Voice", 853 PCIBlankEntry 854 }, 855 { 856 0x04, 857 L"Data", 858 PCIBlankEntry 859 }, 860 { 861 0x80, 862 L"Other satellite communication controller", 863 PCIBlankEntry 864 }, 865 { 866 0x00, 867 NULL, 868 /* null string ends the list */NULL 869 } 870 }; 871 872 PCI_CLASS_ENTRY PCISubClass_10[] = { 873 { 874 0x00, 875 L"Network & computing Encrypt/Decrypt", 876 PCIBlankEntry 877 }, 878 { 879 0x01, 880 L"Entertainment Encrypt/Decrypt", 881 PCIBlankEntry 882 }, 883 { 884 0x80, 885 L"Other Encrypt/Decrypt", 886 PCIBlankEntry 887 }, 888 { 889 0x00, 890 NULL, 891 /* null string ends the list */NULL 892 } 893 }; 894 895 PCI_CLASS_ENTRY PCISubClass_11[] = { 896 { 897 0x00, 898 L"DPIO modules", 899 PCIBlankEntry 900 }, 901 { 902 0x01, 903 L"Performance Counters", 904 PCIBlankEntry 905 }, 906 { 907 0x10, 908 L"Communications synchronization plus time and frequency test/measurement ", 909 PCIBlankEntry 910 }, 911 { 912 0x20, 913 L"Management card", 914 PCIBlankEntry 915 }, 916 { 917 0x80, 918 L"Other DAQ & SP controllers", 919 PCIBlankEntry 920 }, 921 { 922 0x00, 923 NULL, 924 /* null string ends the list */NULL 925 } 926 }; 927 928 PCI_CLASS_ENTRY PCISubClass_12[] = { 929 { 930 0x00, 931 L"Processing Accelerator", 932 PCIBlankEntry 933 }, 934 { 935 0x00, 936 NULL, 937 /* null string ends the list */NULL 938 } 939 }; 940 941 PCI_CLASS_ENTRY PCISubClass_13[] = { 942 { 943 0x00, 944 L"Non-Essential Instrumentation Function", 945 PCIBlankEntry 946 }, 947 { 948 0x00, 949 NULL, 950 /* null string ends the list */NULL 951 } 952 }; 953 954 // 955 // Programming Interface entries 956 // 957 PCI_CLASS_ENTRY PCIPIFClass_0100[] = { 958 { 959 0x00, 960 L"SCSI controller", 961 PCIBlankEntry 962 }, 963 { 964 0x11, 965 L"SCSI storage device SOP using PQI", 966 PCIBlankEntry 967 }, 968 { 969 0x12, 970 L"SCSI controller SOP using PQI", 971 PCIBlankEntry 972 }, 973 { 974 0x13, 975 L"SCSI storage device and controller SOP using PQI", 976 PCIBlankEntry 977 }, 978 { 979 0x21, 980 L"SCSI storage device SOP using NVMe", 981 PCIBlankEntry 982 }, 983 { 984 0x00, 985 NULL, 986 /* null string ends the list */NULL 987 } 988 }; 989 990 PCI_CLASS_ENTRY PCIPIFClass_0101[] = { 991 { 992 0x00, 993 L"", 994 PCIBlankEntry 995 }, 996 { 997 0x01, 998 L"OM-primary", 999 PCIBlankEntry 1000 }, 1001 { 1002 0x02, 1003 L"PI-primary", 1004 PCIBlankEntry 1005 }, 1006 { 1007 0x03, 1008 L"OM/PI-primary", 1009 PCIBlankEntry 1010 }, 1011 { 1012 0x04, 1013 L"OM-secondary", 1014 PCIBlankEntry 1015 }, 1016 { 1017 0x05, 1018 L"OM-primary, OM-secondary", 1019 PCIBlankEntry 1020 }, 1021 { 1022 0x06, 1023 L"PI-primary, OM-secondary", 1024 PCIBlankEntry 1025 }, 1026 { 1027 0x07, 1028 L"OM/PI-primary, OM-secondary", 1029 PCIBlankEntry 1030 }, 1031 { 1032 0x08, 1033 L"OM-secondary", 1034 PCIBlankEntry 1035 }, 1036 { 1037 0x09, 1038 L"OM-primary, PI-secondary", 1039 PCIBlankEntry 1040 }, 1041 { 1042 0x0a, 1043 L"PI-primary, PI-secondary", 1044 PCIBlankEntry 1045 }, 1046 { 1047 0x0b, 1048 L"OM/PI-primary, PI-secondary", 1049 PCIBlankEntry 1050 }, 1051 { 1052 0x0c, 1053 L"OM-secondary", 1054 PCIBlankEntry 1055 }, 1056 { 1057 0x0d, 1058 L"OM-primary, OM/PI-secondary", 1059 PCIBlankEntry 1060 }, 1061 { 1062 0x0e, 1063 L"PI-primary, OM/PI-secondary", 1064 PCIBlankEntry 1065 }, 1066 { 1067 0x0f, 1068 L"OM/PI-primary, OM/PI-secondary", 1069 PCIBlankEntry 1070 }, 1071 { 1072 0x80, 1073 L"Master", 1074 PCIBlankEntry 1075 }, 1076 { 1077 0x81, 1078 L"Master, OM-primary", 1079 PCIBlankEntry 1080 }, 1081 { 1082 0x82, 1083 L"Master, PI-primary", 1084 PCIBlankEntry 1085 }, 1086 { 1087 0x83, 1088 L"Master, OM/PI-primary", 1089 PCIBlankEntry 1090 }, 1091 { 1092 0x84, 1093 L"Master, OM-secondary", 1094 PCIBlankEntry 1095 }, 1096 { 1097 0x85, 1098 L"Master, OM-primary, OM-secondary", 1099 PCIBlankEntry 1100 }, 1101 { 1102 0x86, 1103 L"Master, PI-primary, OM-secondary", 1104 PCIBlankEntry 1105 }, 1106 { 1107 0x87, 1108 L"Master, OM/PI-primary, OM-secondary", 1109 PCIBlankEntry 1110 }, 1111 { 1112 0x88, 1113 L"Master, OM-secondary", 1114 PCIBlankEntry 1115 }, 1116 { 1117 0x89, 1118 L"Master, OM-primary, PI-secondary", 1119 PCIBlankEntry 1120 }, 1121 { 1122 0x8a, 1123 L"Master, PI-primary, PI-secondary", 1124 PCIBlankEntry 1125 }, 1126 { 1127 0x8b, 1128 L"Master, OM/PI-primary, PI-secondary", 1129 PCIBlankEntry 1130 }, 1131 { 1132 0x8c, 1133 L"Master, OM-secondary", 1134 PCIBlankEntry 1135 }, 1136 { 1137 0x8d, 1138 L"Master, OM-primary, OM/PI-secondary", 1139 PCIBlankEntry 1140 }, 1141 { 1142 0x8e, 1143 L"Master, PI-primary, OM/PI-secondary", 1144 PCIBlankEntry 1145 }, 1146 { 1147 0x8f, 1148 L"Master, OM/PI-primary, OM/PI-secondary", 1149 PCIBlankEntry 1150 }, 1151 { 1152 0x00, 1153 NULL, 1154 /* null string ends the list */NULL 1155 } 1156 }; 1157 1158 PCI_CLASS_ENTRY PCIPIFClass_0105[] = { 1159 { 1160 0x20, 1161 L"Single stepping", 1162 PCIBlankEntry 1163 }, 1164 { 1165 0x30, 1166 L"Continuous operation", 1167 PCIBlankEntry 1168 }, 1169 { 1170 0x00, 1171 NULL, 1172 /* null string ends the list */NULL 1173 } 1174 }; 1175 1176 PCI_CLASS_ENTRY PCIPIFClass_0106[] = { 1177 { 1178 0x00, 1179 L"", 1180 PCIBlankEntry 1181 }, 1182 { 1183 0x01, 1184 L"AHCI", 1185 PCIBlankEntry 1186 }, 1187 { 1188 0x02, 1189 L"Serial Storage Bus", 1190 PCIBlankEntry 1191 }, 1192 { 1193 0x00, 1194 NULL, 1195 /* null string ends the list */NULL 1196 } 1197 }; 1198 1199 PCI_CLASS_ENTRY PCIPIFClass_0107[] = { 1200 { 1201 0x00, 1202 L"", 1203 PCIBlankEntry 1204 }, 1205 { 1206 0x01, 1207 L"Obsolete", 1208 PCIBlankEntry 1209 }, 1210 { 1211 0x00, 1212 NULL, 1213 /* null string ends the list */NULL 1214 } 1215 }; 1216 1217 PCI_CLASS_ENTRY PCIPIFClass_0108[] = { 1218 { 1219 0x00, 1220 L"", 1221 PCIBlankEntry 1222 }, 1223 { 1224 0x01, 1225 L"NVMHCI", 1226 PCIBlankEntry 1227 }, 1228 { 1229 0x02, 1230 L"NVM Express", 1231 PCIBlankEntry 1232 }, 1233 { 1234 0x00, 1235 NULL, 1236 /* null string ends the list */NULL 1237 } 1238 }; 1239 1240 PCI_CLASS_ENTRY PCIPIFClass_0109[] = { 1241 { 1242 0x00, 1243 L"", 1244 PCIBlankEntry 1245 }, 1246 { 1247 0x01, 1248 L"UFSHCI", 1249 PCIBlankEntry 1250 }, 1251 { 1252 0x00, 1253 NULL, 1254 /* null string ends the list */NULL 1255 } 1256 }; 1257 1258 PCI_CLASS_ENTRY PCIPIFClass_0300[] = { 1259 { 1260 0x00, 1261 L"VGA compatible", 1262 PCIBlankEntry 1263 }, 1264 { 1265 0x01, 1266 L"8514 compatible", 1267 PCIBlankEntry 1268 }, 1269 { 1270 0x00, 1271 NULL, 1272 /* null string ends the list */NULL 1273 } 1274 }; 1275 1276 PCI_CLASS_ENTRY PCIPIFClass_0604[] = { 1277 { 1278 0x00, 1279 L"", 1280 PCIBlankEntry 1281 }, 1282 { 1283 0x01, 1284 L"Subtractive decode", 1285 PCIBlankEntry 1286 }, 1287 { 1288 0x00, 1289 NULL, 1290 /* null string ends the list */NULL 1291 } 1292 }; 1293 1294 PCI_CLASS_ENTRY PCIPIFClass_0609[] = { 1295 { 1296 0x40, 1297 L"Primary PCI bus side facing the system host processor", 1298 PCIBlankEntry 1299 }, 1300 { 1301 0x80, 1302 L"Secondary PCI bus side facing the system host processor", 1303 PCIBlankEntry 1304 }, 1305 { 1306 0x00, 1307 NULL, 1308 /* null string ends the list */NULL 1309 } 1310 }; 1311 1312 PCI_CLASS_ENTRY PCIPIFClass_060b[] = { 1313 { 1314 0x00, 1315 L"Custom", 1316 PCIBlankEntry 1317 }, 1318 { 1319 0x01, 1320 L"ASI-SIG Defined Portal", 1321 PCIBlankEntry 1322 }, 1323 { 1324 0x00, 1325 NULL, 1326 /* null string ends the list */NULL 1327 } 1328 }; 1329 1330 PCI_CLASS_ENTRY PCIPIFClass_0700[] = { 1331 { 1332 0x00, 1333 L"Generic XT-compatible", 1334 PCIBlankEntry 1335 }, 1336 { 1337 0x01, 1338 L"16450-compatible", 1339 PCIBlankEntry 1340 }, 1341 { 1342 0x02, 1343 L"16550-compatible", 1344 PCIBlankEntry 1345 }, 1346 { 1347 0x03, 1348 L"16650-compatible", 1349 PCIBlankEntry 1350 }, 1351 { 1352 0x04, 1353 L"16750-compatible", 1354 PCIBlankEntry 1355 }, 1356 { 1357 0x05, 1358 L"16850-compatible", 1359 PCIBlankEntry 1360 }, 1361 { 1362 0x06, 1363 L"16950-compatible", 1364 PCIBlankEntry 1365 }, 1366 { 1367 0x00, 1368 NULL, 1369 /* null string ends the list */NULL 1370 } 1371 }; 1372 1373 PCI_CLASS_ENTRY PCIPIFClass_0701[] = { 1374 { 1375 0x00, 1376 L"", 1377 PCIBlankEntry 1378 }, 1379 { 1380 0x01, 1381 L"Bi-directional", 1382 PCIBlankEntry 1383 }, 1384 { 1385 0x02, 1386 L"ECP 1.X-compliant", 1387 PCIBlankEntry 1388 }, 1389 { 1390 0x03, 1391 L"IEEE 1284", 1392 PCIBlankEntry 1393 }, 1394 { 1395 0xfe, 1396 L"IEEE 1284 target (not a controller)", 1397 PCIBlankEntry 1398 }, 1399 { 1400 0x00, 1401 NULL, 1402 /* null string ends the list */NULL 1403 } 1404 }; 1405 1406 PCI_CLASS_ENTRY PCIPIFClass_0703[] = { 1407 { 1408 0x00, 1409 L"Generic", 1410 PCIBlankEntry 1411 }, 1412 { 1413 0x01, 1414 L"Hayes-compatible 16450", 1415 PCIBlankEntry 1416 }, 1417 { 1418 0x02, 1419 L"Hayes-compatible 16550", 1420 PCIBlankEntry 1421 }, 1422 { 1423 0x03, 1424 L"Hayes-compatible 16650", 1425 PCIBlankEntry 1426 }, 1427 { 1428 0x04, 1429 L"Hayes-compatible 16750", 1430 PCIBlankEntry 1431 }, 1432 { 1433 0x00, 1434 NULL, 1435 /* null string ends the list */NULL 1436 } 1437 }; 1438 1439 PCI_CLASS_ENTRY PCIPIFClass_0800[] = { 1440 { 1441 0x00, 1442 L"Generic 8259", 1443 PCIBlankEntry 1444 }, 1445 { 1446 0x01, 1447 L"ISA", 1448 PCIBlankEntry 1449 }, 1450 { 1451 0x02, 1452 L"EISA", 1453 PCIBlankEntry 1454 }, 1455 { 1456 0x10, 1457 L"IO APIC", 1458 PCIBlankEntry 1459 }, 1460 { 1461 0x20, 1462 L"IO(x) APIC interrupt controller", 1463 PCIBlankEntry 1464 }, 1465 { 1466 0x00, 1467 NULL, 1468 /* null string ends the list */NULL 1469 } 1470 }; 1471 1472 PCI_CLASS_ENTRY PCIPIFClass_0801[] = { 1473 { 1474 0x00, 1475 L"Generic 8237", 1476 PCIBlankEntry 1477 }, 1478 { 1479 0x01, 1480 L"ISA", 1481 PCIBlankEntry 1482 }, 1483 { 1484 0x02, 1485 L"EISA", 1486 PCIBlankEntry 1487 }, 1488 { 1489 0x00, 1490 NULL, 1491 /* null string ends the list */NULL 1492 } 1493 }; 1494 1495 PCI_CLASS_ENTRY PCIPIFClass_0802[] = { 1496 { 1497 0x00, 1498 L"Generic 8254", 1499 PCIBlankEntry 1500 }, 1501 { 1502 0x01, 1503 L"ISA", 1504 PCIBlankEntry 1505 }, 1506 { 1507 0x02, 1508 L"EISA", 1509 PCIBlankEntry 1510 }, 1511 { 1512 0x00, 1513 NULL, 1514 /* null string ends the list */NULL 1515 } 1516 }; 1517 1518 PCI_CLASS_ENTRY PCIPIFClass_0803[] = { 1519 { 1520 0x00, 1521 L"Generic", 1522 PCIBlankEntry 1523 }, 1524 { 1525 0x01, 1526 L"ISA", 1527 PCIBlankEntry 1528 }, 1529 { 1530 0x02, 1531 L"EISA", 1532 PCIBlankEntry 1533 }, 1534 { 1535 0x00, 1536 NULL, 1537 /* null string ends the list */NULL 1538 } 1539 }; 1540 1541 PCI_CLASS_ENTRY PCIPIFClass_0904[] = { 1542 { 1543 0x00, 1544 L"Generic", 1545 PCIBlankEntry 1546 }, 1547 { 1548 0x10, 1549 L"", 1550 PCIBlankEntry 1551 }, 1552 { 1553 0x00, 1554 NULL, 1555 /* null string ends the list */NULL 1556 } 1557 }; 1558 1559 PCI_CLASS_ENTRY PCIPIFClass_0c00[] = { 1560 { 1561 0x00, 1562 L"", 1563 PCIBlankEntry 1564 }, 1565 { 1566 0x10, 1567 L"Using 1394 OpenHCI spec", 1568 PCIBlankEntry 1569 }, 1570 { 1571 0x00, 1572 NULL, 1573 /* null string ends the list */NULL 1574 } 1575 }; 1576 1577 PCI_CLASS_ENTRY PCIPIFClass_0c03[] = { 1578 { 1579 0x00, 1580 L"UHCI", 1581 PCIBlankEntry 1582 }, 1583 { 1584 0x10, 1585 L"OHCI", 1586 PCIBlankEntry 1587 }, 1588 { 1589 0x20, 1590 L"EHCI", 1591 PCIBlankEntry 1592 }, 1593 { 1594 0x30, 1595 L"xHCI", 1596 PCIBlankEntry 1597 }, 1598 { 1599 0x80, 1600 L"No specific programming interface", 1601 PCIBlankEntry 1602 }, 1603 { 1604 0xfe, 1605 L"(Not Host Controller)", 1606 PCIBlankEntry 1607 }, 1608 { 1609 0x00, 1610 NULL, 1611 /* null string ends the list */NULL 1612 } 1613 }; 1614 1615 PCI_CLASS_ENTRY PCIPIFClass_0c07[] = { 1616 { 1617 0x00, 1618 L"SMIC", 1619 PCIBlankEntry 1620 }, 1621 { 1622 0x01, 1623 L"Keyboard Controller Style", 1624 PCIBlankEntry 1625 }, 1626 { 1627 0x02, 1628 L"Block Transfer", 1629 PCIBlankEntry 1630 }, 1631 { 1632 0x00, 1633 NULL, 1634 /* null string ends the list */NULL 1635 } 1636 }; 1637 1638 PCI_CLASS_ENTRY PCIPIFClass_0d01[] = { 1639 { 1640 0x00, 1641 L"Consumer IR controller", 1642 PCIBlankEntry 1643 }, 1644 { 1645 0x10, 1646 L"UWB Radio controller", 1647 PCIBlankEntry 1648 }, 1649 { 1650 0x00, 1651 NULL, 1652 /* null string ends the list */NULL 1653 } 1654 }; 1655 1656 PCI_CLASS_ENTRY PCIPIFClass_0e00[] = { 1657 { 1658 0x00, 1659 L"Message FIFO at offset 40h", 1660 PCIBlankEntry 1661 }, 1662 { 1663 0x01, 1664 L"", 1665 PCIBlankEntry 1666 }, 1667 { 1668 0x00, 1669 NULL, 1670 /* null string ends the list */NULL 1671 } 1672 }; 1673 1674 1675 /** 1676 Generates printable Unicode strings that represent PCI device class, 1677 subclass and programmed I/F based on a value passed to the function. 1678 1679 @param[in] ClassCode Value representing the PCI "Class Code" register read from a 1680 PCI device. The encodings are: 1681 bits 23:16 - Base Class Code 1682 bits 15:8 - Sub-Class Code 1683 bits 7:0 - Programming Interface 1684 @param[in, out] ClassStrings Pointer of PCI_CLASS_STRINGS structure, which contains 1685 printable class strings corresponding to ClassCode. The 1686 caller must not modify the strings that are pointed by 1687 the fields in ClassStrings. 1688 **/ 1689 VOID 1690 PciGetClassStrings ( 1691 IN UINT32 ClassCode, 1692 IN OUT PCI_CLASS_STRINGS *ClassStrings 1693 ) 1694 { 1695 INTN Index; 1696 UINT8 Code; 1697 PCI_CLASS_ENTRY *CurrentClass; 1698 1699 // 1700 // Assume no strings found 1701 // 1702 ClassStrings->BaseClass = L"UNDEFINED"; 1703 ClassStrings->SubClass = L"UNDEFINED"; 1704 ClassStrings->PIFClass = L"UNDEFINED"; 1705 1706 CurrentClass = gClassStringList; 1707 Code = (UINT8) (ClassCode >> 16); 1708 Index = 0; 1709 1710 // 1711 // Go through all entries of the base class, until the entry with a matching 1712 // base class code is found. If reaches an entry with a null description 1713 // text, the last entry is met, which means no text for the base class was 1714 // found, so no more action is needed. 1715 // 1716 while (Code != CurrentClass[Index].Code) { 1717 if (NULL == CurrentClass[Index].DescText) { 1718 return ; 1719 } 1720 1721 Index++; 1722 } 1723 // 1724 // A base class was found. Assign description, and check if this class has 1725 // sub-class defined. If sub-class defined, no more action is needed, 1726 // otherwise, continue to find description for the sub-class code. 1727 // 1728 ClassStrings->BaseClass = CurrentClass[Index].DescText; 1729 if (NULL == CurrentClass[Index].LowerLevelClass) { 1730 return ; 1731 } 1732 // 1733 // find Subclass entry 1734 // 1735 CurrentClass = CurrentClass[Index].LowerLevelClass; 1736 Code = (UINT8) (ClassCode >> 8); 1737 Index = 0; 1738 1739 // 1740 // Go through all entries of the sub-class, until the entry with a matching 1741 // sub-class code is found. If reaches an entry with a null description 1742 // text, the last entry is met, which means no text for the sub-class was 1743 // found, so no more action is needed. 1744 // 1745 while (Code != CurrentClass[Index].Code) { 1746 if (NULL == CurrentClass[Index].DescText) { 1747 return ; 1748 } 1749 1750 Index++; 1751 } 1752 // 1753 // A class was found for the sub-class code. Assign description, and check if 1754 // this sub-class has programming interface defined. If no, no more action is 1755 // needed, otherwise, continue to find description for the programming 1756 // interface. 1757 // 1758 ClassStrings->SubClass = CurrentClass[Index].DescText; 1759 if (NULL == CurrentClass[Index].LowerLevelClass) { 1760 return ; 1761 } 1762 // 1763 // Find programming interface entry 1764 // 1765 CurrentClass = CurrentClass[Index].LowerLevelClass; 1766 Code = (UINT8) ClassCode; 1767 Index = 0; 1768 1769 // 1770 // Go through all entries of the I/F entries, until the entry with a 1771 // matching I/F code is found. If reaches an entry with a null description 1772 // text, the last entry is met, which means no text was found, so no more 1773 // action is needed. 1774 // 1775 while (Code != CurrentClass[Index].Code) { 1776 if (NULL == CurrentClass[Index].DescText) { 1777 return ; 1778 } 1779 1780 Index++; 1781 } 1782 // 1783 // A class was found for the I/F code. Assign description, done! 1784 // 1785 ClassStrings->PIFClass = CurrentClass[Index].DescText; 1786 return ; 1787 } 1788 1789 /** 1790 Print strings that represent PCI device class, subclass and programmed I/F. 1791 1792 @param[in] ClassCodePtr Points to the memory which stores register Class Code in PCI 1793 configuration space. 1794 @param[in] IncludePIF If the printed string should include the programming I/F part 1795 **/ 1796 VOID 1797 PciPrintClassCode ( 1798 IN UINT8 *ClassCodePtr, 1799 IN BOOLEAN IncludePIF 1800 ) 1801 { 1802 UINT32 ClassCode; 1803 PCI_CLASS_STRINGS ClassStrings; 1804 1805 ClassCode = 0; 1806 ClassCode |= (UINT32)ClassCodePtr[0]; 1807 ClassCode |= (UINT32)(ClassCodePtr[1] << 8); 1808 ClassCode |= (UINT32)(ClassCodePtr[2] << 16); 1809 1810 // 1811 // Get name from class code 1812 // 1813 PciGetClassStrings (ClassCode, &ClassStrings); 1814 1815 if (IncludePIF) { 1816 // 1817 // Print base class, sub class, and programming inferface name 1818 // 1819 ShellPrintEx (-1, -1, L"%s - %s - %s", 1820 ClassStrings.BaseClass, 1821 ClassStrings.SubClass, 1822 ClassStrings.PIFClass 1823 ); 1824 1825 } else { 1826 // 1827 // Only print base class and sub class name 1828 // 1829 ShellPrintEx (-1, -1, L"%s - %s", 1830 ClassStrings.BaseClass, 1831 ClassStrings.SubClass 1832 ); 1833 } 1834 } 1835 1836 /** 1837 This function finds out the protocol which is in charge of the given 1838 segment, and its bus range covers the current bus number. It lookes 1839 each instances of RootBridgeIoProtocol handle, until the one meets the 1840 criteria is found. 1841 1842 @param[in] HandleBuf Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles. 1843 @param[in] HandleCount Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles. 1844 @param[in] Segment Segment number of device we are dealing with. 1845 @param[in] Bus Bus number of device we are dealing with. 1846 @param[out] IoDev Handle used to access configuration space of PCI device. 1847 1848 @retval EFI_SUCCESS The command completed successfully. 1849 @retval EFI_INVALID_PARAMETER Invalid parameter. 1850 1851 **/ 1852 EFI_STATUS 1853 PciFindProtocolInterface ( 1854 IN EFI_HANDLE *HandleBuf, 1855 IN UINTN HandleCount, 1856 IN UINT16 Segment, 1857 IN UINT16 Bus, 1858 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev 1859 ); 1860 1861 /** 1862 This function gets the protocol interface from the given handle, and 1863 obtains its address space descriptors. 1864 1865 @param[in] Handle The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle. 1866 @param[out] IoDev Handle used to access configuration space of PCI device. 1867 @param[out] Descriptors Points to the address space descriptors. 1868 1869 @retval EFI_SUCCESS The command completed successfully 1870 **/ 1871 EFI_STATUS 1872 PciGetProtocolAndResource ( 1873 IN EFI_HANDLE Handle, 1874 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev, 1875 OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors 1876 ); 1877 1878 /** 1879 This function get the next bus range of given address space descriptors. 1880 It also moves the pointer backward a node, to get prepared to be called 1881 again. 1882 1883 @param[in, out] Descriptors Points to current position of a serial of address space 1884 descriptors. 1885 @param[out] MinBus The lower range of bus number. 1886 @param[out] MaxBus The upper range of bus number. 1887 @param[out] IsEnd Meet end of the serial of descriptors. 1888 1889 @retval EFI_SUCCESS The command completed successfully. 1890 **/ 1891 EFI_STATUS 1892 PciGetNextBusRange ( 1893 IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, 1894 OUT UINT16 *MinBus, 1895 OUT UINT16 *MaxBus, 1896 OUT BOOLEAN *IsEnd 1897 ); 1898 1899 /** 1900 Explain the data in PCI configuration space. The part which is common for 1901 PCI device and bridge is interpreted in this function. It calls other 1902 functions to interpret data unique for device or bridge. 1903 1904 @param[in] ConfigSpace Data in PCI configuration space. 1905 @param[in] Address Address used to access configuration space of this PCI device. 1906 @param[in] IoDev Handle used to access configuration space of PCI device. 1907 @param[in] EnhancedDump The print format for the dump data. 1908 1909 @retval EFI_SUCCESS The command completed successfully. 1910 **/ 1911 EFI_STATUS 1912 PciExplainData ( 1913 IN PCI_CONFIG_SPACE *ConfigSpace, 1914 IN UINT64 Address, 1915 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev, 1916 IN CONST UINT16 EnhancedDump 1917 ); 1918 1919 /** 1920 Explain the device specific part of data in PCI configuration space. 1921 1922 @param[in] Device Data in PCI configuration space. 1923 @param[in] Address Address used to access configuration space of this PCI device. 1924 @param[in] IoDev Handle used to access configuration space of PCI device. 1925 1926 @retval EFI_SUCCESS The command completed successfully. 1927 **/ 1928 EFI_STATUS 1929 PciExplainDeviceData ( 1930 IN PCI_DEVICE_HEADER *Device, 1931 IN UINT64 Address, 1932 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev 1933 ); 1934 1935 /** 1936 Explain the bridge specific part of data in PCI configuration space. 1937 1938 @param[in] Bridge Bridge specific data region in PCI configuration space. 1939 @param[in] Address Address used to access configuration space of this PCI device. 1940 @param[in] IoDev Handle used to access configuration space of PCI device. 1941 1942 @retval EFI_SUCCESS The command completed successfully. 1943 **/ 1944 EFI_STATUS 1945 PciExplainBridgeData ( 1946 IN PCI_BRIDGE_HEADER *Bridge, 1947 IN UINT64 Address, 1948 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev 1949 ); 1950 1951 /** 1952 Explain the Base Address Register(Bar) in PCI configuration space. 1953 1954 @param[in] Bar Points to the Base Address Register intended to interpret. 1955 @param[in] Command Points to the register Command. 1956 @param[in] Address Address used to access configuration space of this PCI device. 1957 @param[in] IoDev Handle used to access configuration space of PCI device. 1958 @param[in, out] Index The Index. 1959 1960 @retval EFI_SUCCESS The command completed successfully. 1961 **/ 1962 EFI_STATUS 1963 PciExplainBar ( 1964 IN UINT32 *Bar, 1965 IN UINT16 *Command, 1966 IN UINT64 Address, 1967 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev, 1968 IN OUT UINTN *Index 1969 ); 1970 1971 /** 1972 Explain the cardbus specific part of data in PCI configuration space. 1973 1974 @param[in] CardBus CardBus specific region of PCI configuration space. 1975 @param[in] Address Address used to access configuration space of this PCI device. 1976 @param[in] IoDev Handle used to access configuration space of PCI device. 1977 1978 @retval EFI_SUCCESS The command completed successfully. 1979 **/ 1980 EFI_STATUS 1981 PciExplainCardBusData ( 1982 IN PCI_CARDBUS_HEADER *CardBus, 1983 IN UINT64 Address, 1984 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev 1985 ); 1986 1987 /** 1988 Explain each meaningful bit of register Status. The definition of Status is 1989 slightly different depending on the PCI header type. 1990 1991 @param[in] Status Points to the content of register Status. 1992 @param[in] MainStatus Indicates if this register is main status(not secondary 1993 status). 1994 @param[in] HeaderType Header type of this PCI device. 1995 1996 @retval EFI_SUCCESS The command completed successfully. 1997 **/ 1998 EFI_STATUS 1999 PciExplainStatus ( 2000 IN UINT16 *Status, 2001 IN BOOLEAN MainStatus, 2002 IN PCI_HEADER_TYPE HeaderType 2003 ); 2004 2005 /** 2006 Explain each meaningful bit of register Command. 2007 2008 @param[in] Command Points to the content of register Command. 2009 2010 @retval EFI_SUCCESS The command completed successfully. 2011 **/ 2012 EFI_STATUS 2013 PciExplainCommand ( 2014 IN UINT16 *Command 2015 ); 2016 2017 /** 2018 Explain each meaningful bit of register Bridge Control. 2019 2020 @param[in] BridgeControl Points to the content of register Bridge Control. 2021 @param[in] HeaderType The headertype. 2022 2023 @retval EFI_SUCCESS The command completed successfully. 2024 **/ 2025 EFI_STATUS 2026 PciExplainBridgeControl ( 2027 IN UINT16 *BridgeControl, 2028 IN PCI_HEADER_TYPE HeaderType 2029 ); 2030 2031 /** 2032 Print each capability structure. 2033 2034 @param[in] IoDev The pointer to the deivce. 2035 @param[in] Address The address to start at. 2036 @param[in] CapPtr The offset from the address. 2037 @param[in] EnhancedDump The print format for the dump data. 2038 2039 @retval EFI_SUCCESS The operation was successful. 2040 **/ 2041 EFI_STATUS 2042 PciExplainCapabilityStruct ( 2043 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev, 2044 IN UINT64 Address, 2045 IN UINT8 CapPtr, 2046 IN CONST UINT16 EnhancedDump 2047 ); 2048 2049 /** 2050 Display Pcie device structure. 2051 2052 @param[in] IoDev The pointer to the root pci protocol. 2053 @param[in] Address The Address to start at. 2054 @param[in] CapabilityPtr The offset from the address to start. 2055 @param[in] EnhancedDump The print format for the dump data. 2056 2057 @retval EFI_SUCCESS The command completed successfully. 2058 @retval @retval EFI_SUCCESS Pci express extend space IO is not suppoted. 2059 **/ 2060 EFI_STATUS 2061 PciExplainPciExpress ( 2062 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev, 2063 IN UINT64 Address, 2064 IN UINT8 CapabilityPtr, 2065 IN CONST UINT16 EnhancedDump 2066 ); 2067 2068 /** 2069 Print out information of the capability information. 2070 2071 @param[in] PciExpressCap The pointer to the structure about the device. 2072 2073 @retval EFI_SUCCESS The operation was successful. 2074 **/ 2075 EFI_STATUS 2076 ExplainPcieCapReg ( 2077 IN PCIE_CAP_STRUCTURE *PciExpressCap 2078 ); 2079 2080 /** 2081 Print out information of the device capability information. 2082 2083 @param[in] PciExpressCap The pointer to the structure about the device. 2084 2085 @retval EFI_SUCCESS The operation was successful. 2086 **/ 2087 EFI_STATUS 2088 ExplainPcieDeviceCap ( 2089 IN PCIE_CAP_STRUCTURE *PciExpressCap 2090 ); 2091 2092 /** 2093 Print out information of the device control information. 2094 2095 @param[in] PciExpressCap The pointer to the structure about the device. 2096 2097 @retval EFI_SUCCESS The operation was successful. 2098 **/ 2099 EFI_STATUS 2100 ExplainPcieDeviceControl ( 2101 IN PCIE_CAP_STRUCTURE *PciExpressCap 2102 ); 2103 2104 /** 2105 Print out information of the device status information. 2106 2107 @param[in] PciExpressCap The pointer to the structure about the device. 2108 2109 @retval EFI_SUCCESS The operation was successful. 2110 **/ 2111 EFI_STATUS 2112 ExplainPcieDeviceStatus ( 2113 IN PCIE_CAP_STRUCTURE *PciExpressCap 2114 ); 2115 2116 /** 2117 Print out information of the device link information. 2118 2119 @param[in] PciExpressCap The pointer to the structure about the device. 2120 2121 @retval EFI_SUCCESS The operation was successful. 2122 **/ 2123 EFI_STATUS 2124 ExplainPcieLinkCap ( 2125 IN PCIE_CAP_STRUCTURE *PciExpressCap 2126 ); 2127 2128 /** 2129 Print out information of the device link control information. 2130 2131 @param[in] PciExpressCap The pointer to the structure about the device. 2132 2133 @retval EFI_SUCCESS The operation was successful. 2134 **/ 2135 EFI_STATUS 2136 ExplainPcieLinkControl ( 2137 IN PCIE_CAP_STRUCTURE *PciExpressCap 2138 ); 2139 2140 /** 2141 Print out information of the device link status information. 2142 2143 @param[in] PciExpressCap The pointer to the structure about the device. 2144 2145 @retval EFI_SUCCESS The operation was successful. 2146 **/ 2147 EFI_STATUS 2148 ExplainPcieLinkStatus ( 2149 IN PCIE_CAP_STRUCTURE *PciExpressCap 2150 ); 2151 2152 /** 2153 Print out information of the device slot information. 2154 2155 @param[in] PciExpressCap The pointer to the structure about the device. 2156 2157 @retval EFI_SUCCESS The operation was successful. 2158 **/ 2159 EFI_STATUS 2160 ExplainPcieSlotCap ( 2161 IN PCIE_CAP_STRUCTURE *PciExpressCap 2162 ); 2163 2164 /** 2165 Print out information of the device slot control information. 2166 2167 @param[in] PciExpressCap The pointer to the structure about the device. 2168 2169 @retval EFI_SUCCESS The operation was successful. 2170 **/ 2171 EFI_STATUS 2172 ExplainPcieSlotControl ( 2173 IN PCIE_CAP_STRUCTURE *PciExpressCap 2174 ); 2175 2176 /** 2177 Print out information of the device slot status information. 2178 2179 @param[in] PciExpressCap The pointer to the structure about the device. 2180 2181 @retval EFI_SUCCESS The operation was successful. 2182 **/ 2183 EFI_STATUS 2184 ExplainPcieSlotStatus ( 2185 IN PCIE_CAP_STRUCTURE *PciExpressCap 2186 ); 2187 2188 /** 2189 Print out information of the device root information. 2190 2191 @param[in] PciExpressCap The pointer to the structure about the device. 2192 2193 @retval EFI_SUCCESS The operation was successful. 2194 **/ 2195 EFI_STATUS 2196 ExplainPcieRootControl ( 2197 IN PCIE_CAP_STRUCTURE *PciExpressCap 2198 ); 2199 2200 /** 2201 Print out information of the device root capability information. 2202 2203 @param[in] PciExpressCap The pointer to the structure about the device. 2204 2205 @retval EFI_SUCCESS The operation was successful. 2206 **/ 2207 EFI_STATUS 2208 ExplainPcieRootCap ( 2209 IN PCIE_CAP_STRUCTURE *PciExpressCap 2210 ); 2211 2212 /** 2213 Print out information of the device root status information. 2214 2215 @param[in] PciExpressCap The pointer to the structure about the device. 2216 2217 @retval EFI_SUCCESS The operation was successful. 2218 **/ 2219 EFI_STATUS 2220 ExplainPcieRootStatus ( 2221 IN PCIE_CAP_STRUCTURE *PciExpressCap 2222 ); 2223 2224 typedef EFI_STATUS (*PCIE_EXPLAIN_FUNCTION) (IN PCIE_CAP_STRUCTURE *PciExpressCap); 2225 2226 typedef enum { 2227 FieldWidthUINT8, 2228 FieldWidthUINT16, 2229 FieldWidthUINT32 2230 } PCIE_CAPREG_FIELD_WIDTH; 2231 2232 typedef enum { 2233 PcieExplainTypeCommon, 2234 PcieExplainTypeDevice, 2235 PcieExplainTypeLink, 2236 PcieExplainTypeSlot, 2237 PcieExplainTypeRoot, 2238 PcieExplainTypeMax 2239 } PCIE_EXPLAIN_TYPE; 2240 2241 typedef struct 2242 { 2243 UINT16 Token; 2244 UINTN Offset; 2245 PCIE_CAPREG_FIELD_WIDTH Width; 2246 PCIE_EXPLAIN_FUNCTION Func; 2247 PCIE_EXPLAIN_TYPE Type; 2248 } PCIE_EXPLAIN_STRUCT; 2249 2250 PCIE_EXPLAIN_STRUCT PcieExplainList[] = { 2251 { 2252 STRING_TOKEN (STR_PCIEX_CAPABILITY_CAPID), 2253 0x00, 2254 FieldWidthUINT8, 2255 NULL, 2256 PcieExplainTypeCommon 2257 }, 2258 { 2259 STRING_TOKEN (STR_PCIEX_NEXTCAP_PTR), 2260 0x01, 2261 FieldWidthUINT8, 2262 NULL, 2263 PcieExplainTypeCommon 2264 }, 2265 { 2266 STRING_TOKEN (STR_PCIEX_CAP_REGISTER), 2267 0x02, 2268 FieldWidthUINT16, 2269 ExplainPcieCapReg, 2270 PcieExplainTypeCommon 2271 }, 2272 { 2273 STRING_TOKEN (STR_PCIEX_DEVICE_CAP), 2274 0x04, 2275 FieldWidthUINT32, 2276 ExplainPcieDeviceCap, 2277 PcieExplainTypeDevice 2278 }, 2279 { 2280 STRING_TOKEN (STR_PCIEX_DEVICE_CONTROL), 2281 0x08, 2282 FieldWidthUINT16, 2283 ExplainPcieDeviceControl, 2284 PcieExplainTypeDevice 2285 }, 2286 { 2287 STRING_TOKEN (STR_PCIEX_DEVICE_STATUS), 2288 0x0a, 2289 FieldWidthUINT16, 2290 ExplainPcieDeviceStatus, 2291 PcieExplainTypeDevice 2292 }, 2293 { 2294 STRING_TOKEN (STR_PCIEX_LINK_CAPABILITIES), 2295 0x0c, 2296 FieldWidthUINT32, 2297 ExplainPcieLinkCap, 2298 PcieExplainTypeLink 2299 }, 2300 { 2301 STRING_TOKEN (STR_PCIEX_LINK_CONTROL), 2302 0x10, 2303 FieldWidthUINT16, 2304 ExplainPcieLinkControl, 2305 PcieExplainTypeLink 2306 }, 2307 { 2308 STRING_TOKEN (STR_PCIEX_LINK_STATUS), 2309 0x12, 2310 FieldWidthUINT16, 2311 ExplainPcieLinkStatus, 2312 PcieExplainTypeLink 2313 }, 2314 { 2315 STRING_TOKEN (STR_PCIEX_SLOT_CAPABILITIES), 2316 0x14, 2317 FieldWidthUINT32, 2318 ExplainPcieSlotCap, 2319 PcieExplainTypeSlot 2320 }, 2321 { 2322 STRING_TOKEN (STR_PCIEX_SLOT_CONTROL), 2323 0x18, 2324 FieldWidthUINT16, 2325 ExplainPcieSlotControl, 2326 PcieExplainTypeSlot 2327 }, 2328 { 2329 STRING_TOKEN (STR_PCIEX_SLOT_STATUS), 2330 0x1a, 2331 FieldWidthUINT16, 2332 ExplainPcieSlotStatus, 2333 PcieExplainTypeSlot 2334 }, 2335 { 2336 STRING_TOKEN (STR_PCIEX_ROOT_CONTROL), 2337 0x1c, 2338 FieldWidthUINT16, 2339 ExplainPcieRootControl, 2340 PcieExplainTypeRoot 2341 }, 2342 { 2343 STRING_TOKEN (STR_PCIEX_RSVDP), 2344 0x1e, 2345 FieldWidthUINT16, 2346 ExplainPcieRootCap, 2347 PcieExplainTypeRoot 2348 }, 2349 { 2350 STRING_TOKEN (STR_PCIEX_ROOT_STATUS), 2351 0x20, 2352 FieldWidthUINT32, 2353 ExplainPcieRootStatus, 2354 PcieExplainTypeRoot 2355 }, 2356 { 2357 0, 2358 0, 2359 (PCIE_CAPREG_FIELD_WIDTH)0, 2360 NULL, 2361 PcieExplainTypeMax 2362 } 2363 }; 2364 2365 // 2366 // Global Variables 2367 // 2368 PCI_CONFIG_SPACE *mConfigSpace = NULL; 2369 STATIC CONST SHELL_PARAM_ITEM ParamList[] = { 2370 {L"-s", TypeValue}, 2371 {L"-i", TypeFlag}, 2372 {NULL, TypeMax} 2373 }; 2374 2375 CHAR16 *DevicePortTypeTable[] = { 2376 L"PCI Express Endpoint", 2377 L"Legacy PCI Express Endpoint", 2378 L"Unknown Type", 2379 L"Unknonw Type", 2380 L"Root Port of PCI Express Root Complex", 2381 L"Upstream Port of PCI Express Switch", 2382 L"Downstream Port of PCI Express Switch", 2383 L"PCI Express to PCI/PCI-X Bridge", 2384 L"PCI/PCI-X to PCI Express Bridge", 2385 L"Root Complex Integrated Endpoint", 2386 L"Root Complex Event Collector" 2387 }; 2388 2389 CHAR16 *L0sLatencyStrTable[] = { 2390 L"Less than 64ns", 2391 L"64ns to less than 128ns", 2392 L"128ns to less than 256ns", 2393 L"256ns to less than 512ns", 2394 L"512ns to less than 1us", 2395 L"1us to less than 2us", 2396 L"2us-4us", 2397 L"More than 4us" 2398 }; 2399 2400 CHAR16 *L1LatencyStrTable[] = { 2401 L"Less than 1us", 2402 L"1us to less than 2us", 2403 L"2us to less than 4us", 2404 L"4us to less than 8us", 2405 L"8us to less than 16us", 2406 L"16us to less than 32us", 2407 L"32us-64us", 2408 L"More than 64us" 2409 }; 2410 2411 CHAR16 *ASPMCtrlStrTable[] = { 2412 L"Disabled", 2413 L"L0s Entry Enabled", 2414 L"L1 Entry Enabled", 2415 L"L0s and L1 Entry Enabled" 2416 }; 2417 2418 CHAR16 *SlotPwrLmtScaleTable[] = { 2419 L"1.0x", 2420 L"0.1x", 2421 L"0.01x", 2422 L"0.001x" 2423 }; 2424 2425 CHAR16 *IndicatorTable[] = { 2426 L"Reserved", 2427 L"On", 2428 L"Blink", 2429 L"Off" 2430 }; 2431 2432 2433 /** 2434 Function for 'pci' command. 2435 2436 @param[in] ImageHandle Handle to the Image (NULL if Internal). 2437 @param[in] SystemTable Pointer to the System Table (NULL if Internal). 2438 **/ 2439 SHELL_STATUS 2440 EFIAPI 2441 ShellCommandRunPci ( 2442 IN EFI_HANDLE ImageHandle, 2443 IN EFI_SYSTEM_TABLE *SystemTable 2444 ) 2445 { 2446 UINT16 Segment; 2447 UINT16 Bus; 2448 UINT16 Device; 2449 UINT16 Func; 2450 UINT64 Address; 2451 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev; 2452 EFI_STATUS Status; 2453 PCI_COMMON_HEADER PciHeader; 2454 PCI_CONFIG_SPACE ConfigSpace; 2455 UINTN ScreenCount; 2456 UINTN TempColumn; 2457 UINTN ScreenSize; 2458 BOOLEAN ExplainData; 2459 UINTN Index; 2460 UINTN SizeOfHeader; 2461 BOOLEAN PrintTitle; 2462 UINTN HandleBufSize; 2463 EFI_HANDLE *HandleBuf; 2464 UINTN HandleCount; 2465 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; 2466 UINT16 MinBus; 2467 UINT16 MaxBus; 2468 BOOLEAN IsEnd; 2469 LIST_ENTRY *Package; 2470 CHAR16 *ProblemParam; 2471 SHELL_STATUS ShellStatus; 2472 CONST CHAR16 *Temp; 2473 UINT64 RetVal; 2474 UINT16 EnhancedDump; 2475 2476 ShellStatus = SHELL_SUCCESS; 2477 Status = EFI_SUCCESS; 2478 Address = 0; 2479 IoDev = NULL; 2480 HandleBuf = NULL; 2481 Package = NULL; 2482 2483 // 2484 // initialize the shell lib (we must be in non-auto-init...) 2485 // 2486 Status = ShellInitialize(); 2487 ASSERT_EFI_ERROR(Status); 2488 2489 Status = CommandInit(); 2490 ASSERT_EFI_ERROR(Status); 2491 2492 // 2493 // parse the command line 2494 // 2495 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); 2496 if (EFI_ERROR(Status)) { 2497 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { 2498 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"pci", ProblemParam); 2499 FreePool(ProblemParam); 2500 ShellStatus = SHELL_INVALID_PARAMETER; 2501 } else { 2502 ASSERT(FALSE); 2503 } 2504 } else { 2505 2506 if (ShellCommandLineGetCount(Package) == 2) { 2507 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"pci"); 2508 ShellStatus = SHELL_INVALID_PARAMETER; 2509 goto Done; 2510 } 2511 2512 if (ShellCommandLineGetCount(Package) > 4) { 2513 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"pci"); 2514 ShellStatus = SHELL_INVALID_PARAMETER; 2515 goto Done; 2516 } 2517 if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetValue(Package, L"-s") == NULL) { 2518 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"pci", L"-s"); 2519 ShellStatus = SHELL_INVALID_PARAMETER; 2520 goto Done; 2521 } 2522 // 2523 // Get all instances of PciRootBridgeIo. Allocate space for 1 EFI_HANDLE and 2524 // call LibLocateHandle(), if EFI_BUFFER_TOO_SMALL is returned, allocate enough 2525 // space for handles and call it again. 2526 // 2527 HandleBufSize = sizeof (EFI_HANDLE); 2528 HandleBuf = (EFI_HANDLE *) AllocateZeroPool (HandleBufSize); 2529 if (HandleBuf == NULL) { 2530 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"pci"); 2531 ShellStatus = SHELL_OUT_OF_RESOURCES; 2532 goto Done; 2533 } 2534 2535 Status = gBS->LocateHandle ( 2536 ByProtocol, 2537 &gEfiPciRootBridgeIoProtocolGuid, 2538 NULL, 2539 &HandleBufSize, 2540 HandleBuf 2541 ); 2542 2543 if (Status == EFI_BUFFER_TOO_SMALL) { 2544 HandleBuf = ReallocatePool (sizeof (EFI_HANDLE), HandleBufSize, HandleBuf); 2545 if (HandleBuf == NULL) { 2546 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"pci"); 2547 ShellStatus = SHELL_OUT_OF_RESOURCES; 2548 goto Done; 2549 } 2550 2551 Status = gBS->LocateHandle ( 2552 ByProtocol, 2553 &gEfiPciRootBridgeIoProtocolGuid, 2554 NULL, 2555 &HandleBufSize, 2556 HandleBuf 2557 ); 2558 } 2559 2560 if (EFI_ERROR (Status)) { 2561 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle, L"pci"); 2562 ShellStatus = SHELL_NOT_FOUND; 2563 goto Done; 2564 } 2565 2566 HandleCount = HandleBufSize / sizeof (EFI_HANDLE); 2567 // 2568 // Argument Count == 1(no other argument): enumerate all pci functions 2569 // 2570 if (ShellCommandLineGetCount(Package) == 1) { 2571 gST->ConOut->QueryMode ( 2572 gST->ConOut, 2573 gST->ConOut->Mode->Mode, 2574 &TempColumn, 2575 &ScreenSize 2576 ); 2577 2578 ScreenCount = 0; 2579 ScreenSize -= 4; 2580 if ((ScreenSize & 1) == 1) { 2581 ScreenSize -= 1; 2582 } 2583 2584 PrintTitle = TRUE; 2585 2586 // 2587 // For each handle, which decides a segment and a bus number range, 2588 // enumerate all devices on it. 2589 // 2590 for (Index = 0; Index < HandleCount; Index++) { 2591 Status = PciGetProtocolAndResource ( 2592 HandleBuf[Index], 2593 &IoDev, 2594 &Descriptors 2595 ); 2596 if (EFI_ERROR (Status)) { 2597 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_HANDLE_CFG_ERR), gShellDebug1HiiHandle, L"pci"); 2598 ShellStatus = SHELL_NOT_FOUND; 2599 goto Done; 2600 } 2601 // 2602 // No document say it's impossible for a RootBridgeIo protocol handle 2603 // to have more than one address space descriptors, so find out every 2604 // bus range and for each of them do device enumeration. 2605 // 2606 while (TRUE) { 2607 Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd); 2608 2609 if (EFI_ERROR (Status)) { 2610 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_BUS_RANGE_ERR), gShellDebug1HiiHandle, L"pci"); 2611 ShellStatus = SHELL_NOT_FOUND; 2612 goto Done; 2613 } 2614 2615 if (IsEnd) { 2616 break; 2617 } 2618 2619 for (Bus = MinBus; Bus <= MaxBus; Bus++) { 2620 // 2621 // For each devices, enumerate all functions it contains 2622 // 2623 for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { 2624 // 2625 // For each function, read its configuration space and print summary 2626 // 2627 for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { 2628 if (ShellGetExecutionBreakFlag ()) { 2629 ShellStatus = SHELL_ABORTED; 2630 goto Done; 2631 } 2632 Address = CALC_EFI_PCI_ADDRESS (Bus, Device, Func, 0); 2633 IoDev->Pci.Read ( 2634 IoDev, 2635 EfiPciWidthUint16, 2636 Address, 2637 1, 2638 &PciHeader.VendorId 2639 ); 2640 2641 // 2642 // If VendorId = 0xffff, there does not exist a device at this 2643 // location. For each device, if there is any function on it, 2644 // there must be 1 function at Function 0. So if Func = 0, there 2645 // will be no more functions in the same device, so we can break 2646 // loop to deal with the next device. 2647 // 2648 if (PciHeader.VendorId == 0xffff && Func == 0) { 2649 break; 2650 } 2651 2652 if (PciHeader.VendorId != 0xffff) { 2653 2654 if (PrintTitle) { 2655 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_TITLE), gShellDebug1HiiHandle); 2656 PrintTitle = FALSE; 2657 } 2658 2659 IoDev->Pci.Read ( 2660 IoDev, 2661 EfiPciWidthUint32, 2662 Address, 2663 sizeof (PciHeader) / sizeof (UINT32), 2664 &PciHeader 2665 ); 2666 2667 ShellPrintHiiEx( 2668 -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P1), gShellDebug1HiiHandle, 2669 IoDev->SegmentNumber, 2670 Bus, 2671 Device, 2672 Func 2673 ); 2674 2675 PciPrintClassCode (PciHeader.ClassCode, FALSE); 2676 ShellPrintHiiEx( 2677 -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P2), gShellDebug1HiiHandle, 2678 PciHeader.VendorId, 2679 PciHeader.DeviceId, 2680 PciHeader.ClassCode[0] 2681 ); 2682 2683 ScreenCount += 2; 2684 if (ScreenCount >= ScreenSize && ScreenSize != 0) { 2685 // 2686 // If ScreenSize == 0 we have the console redirected so don't 2687 // block updates 2688 // 2689 ScreenCount = 0; 2690 } 2691 // 2692 // If this is not a multi-function device, we can leave the loop 2693 // to deal with the next device. 2694 // 2695 if (Func == 0 && ((PciHeader.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00)) { 2696 break; 2697 } 2698 } 2699 } 2700 } 2701 } 2702 // 2703 // If Descriptor is NULL, Configuration() returns EFI_UNSUPPRORED, 2704 // we assume the bus range is 0~PCI_MAX_BUS. After enumerated all 2705 // devices on all bus, we can leave loop. 2706 // 2707 if (Descriptors == NULL) { 2708 break; 2709 } 2710 } 2711 } 2712 2713 Status = EFI_SUCCESS; 2714 goto Done; 2715 } 2716 2717 ExplainData = FALSE; 2718 Segment = 0; 2719 Bus = 0; 2720 Device = 0; 2721 Func = 0; 2722 if (ShellCommandLineGetFlag(Package, L"-i")) { 2723 ExplainData = TRUE; 2724 } 2725 2726 Temp = ShellCommandLineGetValue(Package, L"-s"); 2727 if (Temp != NULL) { 2728 // 2729 // Input converted to hexadecimal number. 2730 // 2731 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) { 2732 Segment = (UINT16) RetVal; 2733 } else { 2734 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp); 2735 ShellStatus = SHELL_INVALID_PARAMETER; 2736 goto Done; 2737 } 2738 } 2739 2740 // 2741 // The first Argument(except "-i") is assumed to be Bus number, second 2742 // to be Device number, and third to be Func number. 2743 // 2744 Temp = ShellCommandLineGetRawValue(Package, 1); 2745 if (Temp != NULL) { 2746 // 2747 // Input converted to hexadecimal number. 2748 // 2749 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) { 2750 Bus = (UINT16) RetVal; 2751 } else { 2752 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp); 2753 ShellStatus = SHELL_INVALID_PARAMETER; 2754 goto Done; 2755 } 2756 2757 if (Bus > MAX_BUS_NUMBER) { 2758 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp); 2759 ShellStatus = SHELL_INVALID_PARAMETER; 2760 goto Done; 2761 } 2762 } 2763 Temp = ShellCommandLineGetRawValue(Package, 2); 2764 if (Temp != NULL) { 2765 // 2766 // Input converted to hexadecimal number. 2767 // 2768 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) { 2769 Device = (UINT16) RetVal; 2770 } else { 2771 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp); 2772 ShellStatus = SHELL_INVALID_PARAMETER; 2773 goto Done; 2774 } 2775 2776 if (Device > MAX_DEVICE_NUMBER){ 2777 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp); 2778 ShellStatus = SHELL_INVALID_PARAMETER; 2779 goto Done; 2780 } 2781 } 2782 2783 Temp = ShellCommandLineGetRawValue(Package, 3); 2784 if (Temp != NULL) { 2785 // 2786 // Input converted to hexadecimal number. 2787 // 2788 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) { 2789 Func = (UINT16) RetVal; 2790 } else { 2791 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp); 2792 ShellStatus = SHELL_INVALID_PARAMETER; 2793 goto Done; 2794 } 2795 2796 if (Func > MAX_FUNCTION_NUMBER){ 2797 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp); 2798 ShellStatus = SHELL_INVALID_PARAMETER; 2799 goto Done; 2800 } 2801 } 2802 2803 // 2804 // Find the protocol interface who's in charge of current segment, and its 2805 // bus range covers the current bus 2806 // 2807 Status = PciFindProtocolInterface ( 2808 HandleBuf, 2809 HandleCount, 2810 Segment, 2811 Bus, 2812 &IoDev 2813 ); 2814 2815 if (EFI_ERROR (Status)) { 2816 ShellPrintHiiEx( 2817 -1, -1, NULL, STRING_TOKEN (STR_PCI_NO_FIND), gShellDebug1HiiHandle, L"pci", 2818 Segment, 2819 Bus 2820 ); 2821 ShellStatus = SHELL_NOT_FOUND; 2822 goto Done; 2823 } 2824 2825 Address = CALC_EFI_PCI_ADDRESS (Bus, Device, Func, 0); 2826 Status = IoDev->Pci.Read ( 2827 IoDev, 2828 EfiPciWidthUint8, 2829 Address, 2830 sizeof (ConfigSpace), 2831 &ConfigSpace 2832 ); 2833 2834 if (EFI_ERROR (Status)) { 2835 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_NO_CFG), gShellDebug1HiiHandle, L"pci"); 2836 ShellStatus = SHELL_ACCESS_DENIED; 2837 goto Done; 2838 } 2839 2840 mConfigSpace = &ConfigSpace; 2841 ShellPrintHiiEx( 2842 -1, 2843 -1, 2844 NULL, 2845 STRING_TOKEN (STR_PCI_INFO), 2846 gShellDebug1HiiHandle, 2847 Segment, 2848 Bus, 2849 Device, 2850 Func, 2851 Segment, 2852 Bus, 2853 Device, 2854 Func 2855 ); 2856 2857 // 2858 // Dump standard header of configuration space 2859 // 2860 SizeOfHeader = sizeof (ConfigSpace.Common) + sizeof (ConfigSpace.NonCommon); 2861 2862 DumpHex (2, 0, SizeOfHeader, &ConfigSpace); 2863 ShellPrintEx(-1,-1, L"\r\n"); 2864 2865 // 2866 // Dump device dependent Part of configuration space 2867 // 2868 DumpHex ( 2869 2, 2870 SizeOfHeader, 2871 sizeof (ConfigSpace) - SizeOfHeader, 2872 ConfigSpace.Data 2873 ); 2874 2875 // 2876 // If "-i" appears in command line, interpret data in configuration space 2877 // 2878 if (ExplainData) { 2879 EnhancedDump = 0; 2880 if (ShellCommandLineGetFlag(Package, L"-_e")) { 2881 EnhancedDump = 0xFFFF; 2882 Temp = ShellCommandLineGetValue(Package, L"-_e"); 2883 if (Temp != NULL) { 2884 EnhancedDump = (UINT16) ShellHexStrToUintn (Temp); 2885 } 2886 } 2887 Status = PciExplainData (&ConfigSpace, Address, IoDev, EnhancedDump); 2888 } 2889 } 2890 Done: 2891 if (HandleBuf != NULL) { 2892 FreePool (HandleBuf); 2893 } 2894 if (Package != NULL) { 2895 ShellCommandLineFreeVarList (Package); 2896 } 2897 mConfigSpace = NULL; 2898 return ShellStatus; 2899 } 2900 2901 /** 2902 This function finds out the protocol which is in charge of the given 2903 segment, and its bus range covers the current bus number. It lookes 2904 each instances of RootBridgeIoProtocol handle, until the one meets the 2905 criteria is found. 2906 2907 @param[in] HandleBuf Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles. 2908 @param[in] HandleCount Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles. 2909 @param[in] Segment Segment number of device we are dealing with. 2910 @param[in] Bus Bus number of device we are dealing with. 2911 @param[out] IoDev Handle used to access configuration space of PCI device. 2912 2913 @retval EFI_SUCCESS The command completed successfully. 2914 @retval EFI_INVALID_PARAMETER Invalid parameter. 2915 2916 **/ 2917 EFI_STATUS 2918 PciFindProtocolInterface ( 2919 IN EFI_HANDLE *HandleBuf, 2920 IN UINTN HandleCount, 2921 IN UINT16 Segment, 2922 IN UINT16 Bus, 2923 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev 2924 ) 2925 { 2926 UINTN Index; 2927 EFI_STATUS Status; 2928 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; 2929 UINT16 MinBus; 2930 UINT16 MaxBus; 2931 BOOLEAN IsEnd; 2932 2933 // 2934 // Go through all handles, until the one meets the criteria is found 2935 // 2936 for (Index = 0; Index < HandleCount; Index++) { 2937 Status = PciGetProtocolAndResource (HandleBuf[Index], IoDev, &Descriptors); 2938 if (EFI_ERROR (Status)) { 2939 return Status; 2940 } 2941 // 2942 // When Descriptors == NULL, the Configuration() is not implemented, 2943 // so we only check the Segment number 2944 // 2945 if (Descriptors == NULL && Segment == (*IoDev)->SegmentNumber) { 2946 return EFI_SUCCESS; 2947 } 2948 2949 if ((*IoDev)->SegmentNumber != Segment) { 2950 continue; 2951 } 2952 2953 while (TRUE) { 2954 Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd); 2955 if (EFI_ERROR (Status)) { 2956 return Status; 2957 } 2958 2959 if (IsEnd) { 2960 break; 2961 } 2962 2963 if (MinBus <= Bus && MaxBus >= Bus) { 2964 return EFI_SUCCESS; 2965 } 2966 } 2967 } 2968 2969 return EFI_NOT_FOUND; 2970 } 2971 2972 /** 2973 This function gets the protocol interface from the given handle, and 2974 obtains its address space descriptors. 2975 2976 @param[in] Handle The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle. 2977 @param[out] IoDev Handle used to access configuration space of PCI device. 2978 @param[out] Descriptors Points to the address space descriptors. 2979 2980 @retval EFI_SUCCESS The command completed successfully 2981 **/ 2982 EFI_STATUS 2983 PciGetProtocolAndResource ( 2984 IN EFI_HANDLE Handle, 2985 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev, 2986 OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors 2987 ) 2988 { 2989 EFI_STATUS Status; 2990 2991 // 2992 // Get inferface from protocol 2993 // 2994 Status = gBS->HandleProtocol ( 2995 Handle, 2996 &gEfiPciRootBridgeIoProtocolGuid, 2997 (VOID**)IoDev 2998 ); 2999 3000 if (EFI_ERROR (Status)) { 3001 return Status; 3002 } 3003 // 3004 // Call Configuration() to get address space descriptors 3005 // 3006 Status = (*IoDev)->Configuration (*IoDev, (VOID**)Descriptors); 3007 if (Status == EFI_UNSUPPORTED) { 3008 *Descriptors = NULL; 3009 return EFI_SUCCESS; 3010 3011 } else { 3012 return Status; 3013 } 3014 } 3015 3016 /** 3017 This function get the next bus range of given address space descriptors. 3018 It also moves the pointer backward a node, to get prepared to be called 3019 again. 3020 3021 @param[in, out] Descriptors Points to current position of a serial of address space 3022 descriptors. 3023 @param[out] MinBus The lower range of bus number. 3024 @param[out] MaxBus The upper range of bus number. 3025 @param[out] IsEnd Meet end of the serial of descriptors. 3026 3027 @retval EFI_SUCCESS The command completed successfully. 3028 **/ 3029 EFI_STATUS 3030 PciGetNextBusRange ( 3031 IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, 3032 OUT UINT16 *MinBus, 3033 OUT UINT16 *MaxBus, 3034 OUT BOOLEAN *IsEnd 3035 ) 3036 { 3037 *IsEnd = FALSE; 3038 3039 // 3040 // When *Descriptors is NULL, Configuration() is not implemented, so assume 3041 // range is 0~PCI_MAX_BUS 3042 // 3043 if ((*Descriptors) == NULL) { 3044 *MinBus = 0; 3045 *MaxBus = PCI_MAX_BUS; 3046 return EFI_SUCCESS; 3047 } 3048 // 3049 // *Descriptors points to one or more address space descriptors, which 3050 // ends with a end tagged descriptor. Examine each of the descriptors, 3051 // if a bus typed one is found and its bus range covers bus, this handle 3052 // is the handle we are looking for. 3053 // 3054 3055 while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) { 3056 if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) { 3057 *MinBus = (UINT16) (*Descriptors)->AddrRangeMin; 3058 *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax; 3059 (*Descriptors)++; 3060 return (EFI_SUCCESS); 3061 } 3062 3063 (*Descriptors)++; 3064 } 3065 3066 if ((*Descriptors)->Desc == ACPI_END_TAG_DESCRIPTOR) { 3067 *IsEnd = TRUE; 3068 } 3069 3070 return EFI_SUCCESS; 3071 } 3072 3073 /** 3074 Explain the data in PCI configuration space. The part which is common for 3075 PCI device and bridge is interpreted in this function. It calls other 3076 functions to interpret data unique for device or bridge. 3077 3078 @param[in] ConfigSpace Data in PCI configuration space. 3079 @param[in] Address Address used to access configuration space of this PCI device. 3080 @param[in] IoDev Handle used to access configuration space of PCI device. 3081 @param[in] EnhancedDump The print format for the dump data. 3082 3083 @retval EFI_SUCCESS The command completed successfully. 3084 **/ 3085 EFI_STATUS 3086 PciExplainData ( 3087 IN PCI_CONFIG_SPACE *ConfigSpace, 3088 IN UINT64 Address, 3089 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev, 3090 IN CONST UINT16 EnhancedDump 3091 ) 3092 { 3093 PCI_COMMON_HEADER *Common; 3094 PCI_HEADER_TYPE HeaderType; 3095 EFI_STATUS Status; 3096 UINT8 CapPtr; 3097 3098 Common = &(ConfigSpace->Common); 3099 3100 ShellPrintEx (-1, -1, L"\r\n"); 3101 3102 // 3103 // Print Vendor Id and Device Id 3104 // 3105 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_VID_DID), gShellDebug1HiiHandle, 3106 INDEX_OF (&(Common->VendorId)), 3107 Common->VendorId, 3108 INDEX_OF (&(Common->DeviceId)), 3109 Common->DeviceId 3110 ); 3111 3112 // 3113 // Print register Command 3114 // 3115 PciExplainCommand (&(Common->Command)); 3116 3117 // 3118 // Print register Status 3119 // 3120 PciExplainStatus (&(Common->Status), TRUE, PciUndefined); 3121 3122 // 3123 // Print register Revision ID 3124 // 3125 ShellPrintEx(-1, -1, L"\r\n"); 3126 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_RID), gShellDebug1HiiHandle, 3127 INDEX_OF (&(Common->RevisionId)), 3128 Common->RevisionId 3129 ); 3130 3131 // 3132 // Print register BIST 3133 // 3134 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_BIST), gShellDebug1HiiHandle, INDEX_OF (&(Common->Bist))); 3135 if ((Common->Bist & PCI_BIT_7) != 0) { 3136 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP), gShellDebug1HiiHandle, 0x0f & Common->Bist); 3137 } else { 3138 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP_NO), gShellDebug1HiiHandle); 3139 } 3140 // 3141 // Print register Cache Line Size 3142 // 3143 ShellPrintHiiEx(-1, -1, NULL, 3144 STRING_TOKEN (STR_PCI2_CACHE_LINE_SIZE), 3145 gShellDebug1HiiHandle, 3146 INDEX_OF (&(Common->CacheLineSize)), 3147 Common->CacheLineSize 3148 ); 3149 3150 // 3151 // Print register Latency Timer 3152 // 3153 ShellPrintHiiEx(-1, -1, NULL, 3154 STRING_TOKEN (STR_PCI2_LATENCY_TIMER), 3155 gShellDebug1HiiHandle, 3156 INDEX_OF (&(Common->PrimaryLatencyTimer)), 3157 Common->PrimaryLatencyTimer 3158 ); 3159 3160 // 3161 // Print register Header Type 3162 // 3163 ShellPrintHiiEx(-1, -1, NULL, 3164 STRING_TOKEN (STR_PCI2_HEADER_TYPE), 3165 gShellDebug1HiiHandle, 3166 INDEX_OF (&(Common->HeaderType)), 3167 Common->HeaderType 3168 ); 3169 3170 if ((Common->HeaderType & PCI_BIT_7) != 0) { 3171 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MULTI_FUNCTION), gShellDebug1HiiHandle); 3172 3173 } else { 3174 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SINGLE_FUNCTION), gShellDebug1HiiHandle); 3175 } 3176 3177 HeaderType = (PCI_HEADER_TYPE)(UINT8) (Common->HeaderType & 0x7f); 3178 switch (HeaderType) { 3179 case PciDevice: 3180 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_PCI_DEVICE), gShellDebug1HiiHandle); 3181 break; 3182 3183 case PciP2pBridge: 3184 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_P2P_BRIDGE), gShellDebug1HiiHandle); 3185 break; 3186 3187 case PciCardBusBridge: 3188 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_BRIDGE), gShellDebug1HiiHandle); 3189 break; 3190 3191 default: 3192 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED), gShellDebug1HiiHandle); 3193 HeaderType = PciUndefined; 3194 } 3195 3196 // 3197 // Print register Class Code 3198 // 3199 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CLASS), gShellDebug1HiiHandle); 3200 PciPrintClassCode ((UINT8 *) Common->ClassCode, TRUE); 3201 ShellPrintEx (-1, -1, L"\r\n"); 3202 3203 if (ShellGetExecutionBreakFlag()) { 3204 return EFI_SUCCESS; 3205 } 3206 3207 // 3208 // Interpret remaining part of PCI configuration header depending on 3209 // HeaderType 3210 // 3211 CapPtr = 0; 3212 Status = EFI_SUCCESS; 3213 switch (HeaderType) { 3214 case PciDevice: 3215 Status = PciExplainDeviceData ( 3216 &(ConfigSpace->NonCommon.Device), 3217 Address, 3218 IoDev 3219 ); 3220 CapPtr = ConfigSpace->NonCommon.Device.CapabilitiesPtr; 3221 break; 3222 3223 case PciP2pBridge: 3224 Status = PciExplainBridgeData ( 3225 &(ConfigSpace->NonCommon.Bridge), 3226 Address, 3227 IoDev 3228 ); 3229 CapPtr = ConfigSpace->NonCommon.Bridge.CapabilitiesPtr; 3230 break; 3231 3232 case PciCardBusBridge: 3233 Status = PciExplainCardBusData ( 3234 &(ConfigSpace->NonCommon.CardBus), 3235 Address, 3236 IoDev 3237 ); 3238 CapPtr = ConfigSpace->NonCommon.CardBus.CapabilitiesPtr; 3239 break; 3240 case PciUndefined: 3241 default: 3242 break; 3243 } 3244 // 3245 // If Status bit4 is 1, dump or explain capability structure 3246 // 3247 if ((Common->Status) & EFI_PCI_STATUS_CAPABILITY) { 3248 PciExplainCapabilityStruct (IoDev, Address, CapPtr, EnhancedDump); 3249 } 3250 3251 return Status; 3252 } 3253 3254 /** 3255 Explain the device specific part of data in PCI configuration space. 3256 3257 @param[in] Device Data in PCI configuration space. 3258 @param[in] Address Address used to access configuration space of this PCI device. 3259 @param[in] IoDev Handle used to access configuration space of PCI device. 3260 3261 @retval EFI_SUCCESS The command completed successfully. 3262 **/ 3263 EFI_STATUS 3264 PciExplainDeviceData ( 3265 IN PCI_DEVICE_HEADER *Device, 3266 IN UINT64 Address, 3267 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev 3268 ) 3269 { 3270 UINTN Index; 3271 BOOLEAN BarExist; 3272 EFI_STATUS Status; 3273 UINTN BarCount; 3274 3275 // 3276 // Print Base Address Registers(Bar). When Bar = 0, this Bar does not 3277 // exist. If these no Bar for this function, print "none", otherwise 3278 // list detail information about this Bar. 3279 // 3280 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDR), gShellDebug1HiiHandle, INDEX_OF (Device->Bar)); 3281 3282 BarExist = FALSE; 3283 BarCount = sizeof (Device->Bar) / sizeof (Device->Bar[0]); 3284 for (Index = 0; Index < BarCount; Index++) { 3285 if (Device->Bar[Index] == 0) { 3286 continue; 3287 } 3288 3289 if (!BarExist) { 3290 BarExist = TRUE; 3291 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE), gShellDebug1HiiHandle); 3292 ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------"); 3293 } 3294 3295 Status = PciExplainBar ( 3296 &(Device->Bar[Index]), 3297 &(mConfigSpace->Common.Command), 3298 Address, 3299 IoDev, 3300 &Index 3301 ); 3302 3303 if (EFI_ERROR (Status)) { 3304 break; 3305 } 3306 } 3307 3308 if (!BarExist) { 3309 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle); 3310 3311 } else { 3312 ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------"); 3313 } 3314 3315 // 3316 // Print register Expansion ROM Base Address 3317 // 3318 if ((Device->ROMBar & PCI_BIT_0) == 0) { 3319 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_EXPANSION_ROM_DISABLED), gShellDebug1HiiHandle, INDEX_OF (&(Device->ROMBar))); 3320 3321 } else { 3322 ShellPrintHiiEx(-1, -1, NULL, 3323 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE), 3324 gShellDebug1HiiHandle, 3325 INDEX_OF (&(Device->ROMBar)), 3326 Device->ROMBar 3327 ); 3328 } 3329 // 3330 // Print register Cardbus CIS ptr 3331 // 3332 ShellPrintHiiEx(-1, -1, NULL, 3333 STRING_TOKEN (STR_PCI2_CARDBUS_CIS), 3334 gShellDebug1HiiHandle, 3335 INDEX_OF (&(Device->CardBusCISPtr)), 3336 Device->CardBusCISPtr 3337 ); 3338 3339 // 3340 // Print register Sub-vendor ID and subsystem ID 3341 // 3342 ShellPrintHiiEx(-1, -1, NULL, 3343 STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID), 3344 gShellDebug1HiiHandle, 3345 INDEX_OF (&(Device->SubVendorId)), 3346 Device->SubVendorId 3347 ); 3348 3349 ShellPrintHiiEx(-1, -1, NULL, 3350 STRING_TOKEN (STR_PCI2_SUBSYSTEM_ID), 3351 gShellDebug1HiiHandle, 3352 INDEX_OF (&(Device->SubSystemId)), 3353 Device->SubSystemId 3354 ); 3355 3356 // 3357 // Print register Capabilities Ptr 3358 // 3359 ShellPrintHiiEx(-1, -1, NULL, 3360 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR), 3361 gShellDebug1HiiHandle, 3362 INDEX_OF (&(Device->CapabilitiesPtr)), 3363 Device->CapabilitiesPtr 3364 ); 3365 3366 // 3367 // Print register Interrupt Line and interrupt pin 3368 // 3369 ShellPrintHiiEx(-1, -1, NULL, 3370 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE), 3371 gShellDebug1HiiHandle, 3372 INDEX_OF (&(Device->InterruptLine)), 3373 Device->InterruptLine 3374 ); 3375 3376 ShellPrintHiiEx(-1, -1, NULL, 3377 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN), 3378 gShellDebug1HiiHandle, 3379 INDEX_OF (&(Device->InterruptPin)), 3380 Device->InterruptPin 3381 ); 3382 3383 // 3384 // Print register Min_Gnt and Max_Lat 3385 // 3386 ShellPrintHiiEx(-1, -1, NULL, 3387 STRING_TOKEN (STR_PCI2_MIN_GNT), 3388 gShellDebug1HiiHandle, 3389 INDEX_OF (&(Device->MinGnt)), 3390 Device->MinGnt 3391 ); 3392 3393 ShellPrintHiiEx(-1, -1, NULL, 3394 STRING_TOKEN (STR_PCI2_MAX_LAT), 3395 gShellDebug1HiiHandle, 3396 INDEX_OF (&(Device->MaxLat)), 3397 Device->MaxLat 3398 ); 3399 3400 return EFI_SUCCESS; 3401 } 3402 3403 /** 3404 Explain the bridge specific part of data in PCI configuration space. 3405 3406 @param[in] Bridge Bridge specific data region in PCI configuration space. 3407 @param[in] Address Address used to access configuration space of this PCI device. 3408 @param[in] IoDev Handle used to access configuration space of PCI device. 3409 3410 @retval EFI_SUCCESS The command completed successfully. 3411 **/ 3412 EFI_STATUS 3413 PciExplainBridgeData ( 3414 IN PCI_BRIDGE_HEADER *Bridge, 3415 IN UINT64 Address, 3416 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev 3417 ) 3418 { 3419 UINTN Index; 3420 BOOLEAN BarExist; 3421 UINTN BarCount; 3422 UINT32 IoAddress32; 3423 EFI_STATUS Status; 3424 3425 // 3426 // Print Base Address Registers. When Bar = 0, this Bar does not 3427 // exist. If these no Bar for this function, print "none", otherwise 3428 // list detail information about this Bar. 3429 // 3430 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDRESS), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->Bar))); 3431 3432 BarExist = FALSE; 3433 BarCount = sizeof (Bridge->Bar) / sizeof (Bridge->Bar[0]); 3434 3435 for (Index = 0; Index < BarCount; Index++) { 3436 if (Bridge->Bar[Index] == 0) { 3437 continue; 3438 } 3439 3440 if (!BarExist) { 3441 BarExist = TRUE; 3442 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE_2), gShellDebug1HiiHandle); 3443 ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------"); 3444 } 3445 3446 Status = PciExplainBar ( 3447 &(Bridge->Bar[Index]), 3448 &(mConfigSpace->Common.Command), 3449 Address, 3450 IoDev, 3451 &Index 3452 ); 3453 3454 if (EFI_ERROR (Status)) { 3455 break; 3456 } 3457 } 3458 3459 if (!BarExist) { 3460 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle); 3461 } else { 3462 ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------"); 3463 } 3464 3465 // 3466 // Expansion register ROM Base Address 3467 // 3468 if ((Bridge->ROMBar & PCI_BIT_0) == 0) { 3469 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO_EXPANSION_ROM), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->ROMBar))); 3470 3471 } else { 3472 ShellPrintHiiEx(-1, -1, NULL, 3473 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE_2), 3474 gShellDebug1HiiHandle, 3475 INDEX_OF (&(Bridge->ROMBar)), 3476 Bridge->ROMBar 3477 ); 3478 } 3479 // 3480 // Print Bus Numbers(Primary, Secondary, and Subordinate 3481 // 3482 ShellPrintHiiEx(-1, -1, NULL, 3483 STRING_TOKEN (STR_PCI2_BUS_NUMBERS), 3484 gShellDebug1HiiHandle, 3485 INDEX_OF (&(Bridge->PrimaryBus)), 3486 INDEX_OF (&(Bridge->SecondaryBus)), 3487 INDEX_OF (&(Bridge->SubordinateBus)) 3488 ); 3489 3490 ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n"); 3491 3492 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->PrimaryBus); 3493 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SecondaryBus); 3494 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SubordinateBus); 3495 3496 // 3497 // Print register Secondary Latency Timer 3498 // 3499 ShellPrintHiiEx(-1, -1, NULL, 3500 STRING_TOKEN (STR_PCI2_SECONDARY_TIMER), 3501 gShellDebug1HiiHandle, 3502 INDEX_OF (&(Bridge->SecondaryLatencyTimer)), 3503 Bridge->SecondaryLatencyTimer 3504 ); 3505 3506 // 3507 // Print register Secondary Status 3508 // 3509 PciExplainStatus (&(Bridge->SecondaryStatus), FALSE, PciP2pBridge); 3510 3511 // 3512 // Print I/O and memory ranges this bridge forwards. There are 3 resource 3513 // types: I/O, memory, and pre-fetchable memory. For each resource type, 3514 // base and limit address are listed. 3515 // 3516 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE), gShellDebug1HiiHandle); 3517 ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n"); 3518 3519 // 3520 // IO Base & Limit 3521 // 3522 IoAddress32 = (Bridge->IoBaseUpper << 16 | Bridge->IoBase << 8); 3523 IoAddress32 &= 0xfffff000; 3524 ShellPrintHiiEx(-1, -1, NULL, 3525 STRING_TOKEN (STR_PCI2_TWO_VARS), 3526 gShellDebug1HiiHandle, 3527 INDEX_OF (&(Bridge->IoBase)), 3528 IoAddress32 3529 ); 3530 3531 IoAddress32 = (Bridge->IoLimitUpper << 16 | Bridge->IoLimit << 8); 3532 IoAddress32 |= 0x00000fff; 3533 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR), gShellDebug1HiiHandle, IoAddress32); 3534 3535 // 3536 // Memory Base & Limit 3537 // 3538 ShellPrintHiiEx(-1, -1, NULL, 3539 STRING_TOKEN (STR_PCI2_MEMORY), 3540 gShellDebug1HiiHandle, 3541 INDEX_OF (&(Bridge->MemoryBase)), 3542 (Bridge->MemoryBase << 16) & 0xfff00000 3543 ); 3544 3545 ShellPrintHiiEx(-1, -1, NULL, 3546 STRING_TOKEN (STR_PCI2_ONE_VAR), 3547 gShellDebug1HiiHandle, 3548 (Bridge->MemoryLimit << 16) | 0x000fffff 3549 ); 3550 3551 // 3552 // Pre-fetch-able Memory Base & Limit 3553 // 3554 ShellPrintHiiEx(-1, -1, NULL, 3555 STRING_TOKEN (STR_PCI2_PREFETCHABLE), 3556 gShellDebug1HiiHandle, 3557 INDEX_OF (&(Bridge->PrefetchableMemBase)), 3558 Bridge->PrefetchableBaseUpper, 3559 (Bridge->PrefetchableMemBase << 16) & 0xfff00000 3560 ); 3561 3562 ShellPrintHiiEx(-1, -1, NULL, 3563 STRING_TOKEN (STR_PCI2_TWO_VARS_2), 3564 gShellDebug1HiiHandle, 3565 Bridge->PrefetchableLimitUpper, 3566 (Bridge->PrefetchableMemLimit << 16) | 0x000fffff 3567 ); 3568 3569 // 3570 // Print register Capabilities Pointer 3571 // 3572 ShellPrintHiiEx(-1, -1, NULL, 3573 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR_2), 3574 gShellDebug1HiiHandle, 3575 INDEX_OF (&(Bridge->CapabilitiesPtr)), 3576 Bridge->CapabilitiesPtr 3577 ); 3578 3579 // 3580 // Print register Bridge Control 3581 // 3582 PciExplainBridgeControl (&(Bridge->BridgeControl), PciP2pBridge); 3583 3584 // 3585 // Print register Interrupt Line & PIN 3586 // 3587 ShellPrintHiiEx(-1, -1, NULL, 3588 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_2), 3589 gShellDebug1HiiHandle, 3590 INDEX_OF (&(Bridge->InterruptLine)), 3591 Bridge->InterruptLine 3592 ); 3593 3594 ShellPrintHiiEx(-1, -1, NULL, 3595 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN), 3596 gShellDebug1HiiHandle, 3597 INDEX_OF (&(Bridge->InterruptPin)), 3598 Bridge->InterruptPin 3599 ); 3600 3601 return EFI_SUCCESS; 3602 } 3603 3604 /** 3605 Explain the Base Address Register(Bar) in PCI configuration space. 3606 3607 @param[in] Bar Points to the Base Address Register intended to interpret. 3608 @param[in] Command Points to the register Command. 3609 @param[in] Address Address used to access configuration space of this PCI device. 3610 @param[in] IoDev Handle used to access configuration space of PCI device. 3611 @param[in, out] Index The Index. 3612 3613 @retval EFI_SUCCESS The command completed successfully. 3614 **/ 3615 EFI_STATUS 3616 PciExplainBar ( 3617 IN UINT32 *Bar, 3618 IN UINT16 *Command, 3619 IN UINT64 Address, 3620 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev, 3621 IN OUT UINTN *Index 3622 ) 3623 { 3624 UINT16 OldCommand; 3625 UINT16 NewCommand; 3626 UINT64 Bar64; 3627 UINT32 OldBar32; 3628 UINT32 NewBar32; 3629 UINT64 OldBar64; 3630 UINT64 NewBar64; 3631 BOOLEAN IsMem; 3632 BOOLEAN IsBar32; 3633 UINT64 RegAddress; 3634 3635 IsBar32 = TRUE; 3636 Bar64 = 0; 3637 NewBar32 = 0; 3638 NewBar64 = 0; 3639 3640 // 3641 // According the bar type, list detail about this bar, for example: 32 or 3642 // 64 bits; pre-fetchable or not. 3643 // 3644 if ((*Bar & PCI_BIT_0) == 0) { 3645 // 3646 // This bar is of memory type 3647 // 3648 IsMem = TRUE; 3649 3650 if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) == 0) { 3651 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0); 3652 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle); 3653 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_32_BITS), gShellDebug1HiiHandle); 3654 3655 } else if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) != 0) { 3656 Bar64 = 0x0; 3657 CopyMem (&Bar64, Bar, sizeof (UINT64)); 3658 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_2), gShellDebug1HiiHandle, (UINT32) RShiftU64 ((Bar64 & 0xfffffffffffffff0ULL), 32)); 3659 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_3), gShellDebug1HiiHandle, (UINT32) (Bar64 & 0xfffffffffffffff0ULL)); 3660 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle); 3661 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_64_BITS), gShellDebug1HiiHandle); 3662 IsBar32 = FALSE; 3663 *Index += 1; 3664 3665 } else { 3666 // 3667 // Reserved 3668 // 3669 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0); 3670 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM_2), gShellDebug1HiiHandle); 3671 } 3672 3673 if ((*Bar & PCI_BIT_3) == 0) { 3674 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO), gShellDebug1HiiHandle); 3675 3676 } else { 3677 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_YES), gShellDebug1HiiHandle); 3678 } 3679 3680 } else { 3681 // 3682 // This bar is of io type 3683 // 3684 IsMem = FALSE; 3685 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_4), gShellDebug1HiiHandle, *Bar & 0xfffffffc); 3686 ShellPrintEx (-1, -1, L"I/O "); 3687 } 3688 3689 // 3690 // Get BAR length(or the amount of resource this bar demands for). To get 3691 // Bar length, first we should temporarily disable I/O and memory access 3692 // of this function(by set bits in the register Command), then write all 3693 // "1"s to this bar. The bar value read back is the amount of resource 3694 // this bar demands for. 3695 // 3696 // 3697 // Disable io & mem access 3698 // 3699 OldCommand = *Command; 3700 NewCommand = (UINT16) (OldCommand & 0xfffc); 3701 RegAddress = Address | INDEX_OF (Command); 3702 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &NewCommand); 3703 3704 RegAddress = Address | INDEX_OF (Bar); 3705 3706 // 3707 // Read after write the BAR to get the size 3708 // 3709 if (IsBar32) { 3710 OldBar32 = *Bar; 3711 NewBar32 = 0xffffffff; 3712 3713 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32); 3714 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32); 3715 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &OldBar32); 3716 3717 if (IsMem) { 3718 NewBar32 = NewBar32 & 0xfffffff0; 3719 NewBar32 = (~NewBar32) + 1; 3720 3721 } else { 3722 NewBar32 = NewBar32 & 0xfffffffc; 3723 NewBar32 = (~NewBar32) + 1; 3724 NewBar32 = NewBar32 & 0x0000ffff; 3725 } 3726 } else { 3727 3728 OldBar64 = 0x0; 3729 CopyMem (&OldBar64, Bar, sizeof (UINT64)); 3730 NewBar64 = 0xffffffffffffffffULL; 3731 3732 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64); 3733 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64); 3734 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &OldBar64); 3735 3736 if (IsMem) { 3737 NewBar64 = NewBar64 & 0xfffffffffffffff0ULL; 3738 NewBar64 = (~NewBar64) + 1; 3739 3740 } else { 3741 NewBar64 = NewBar64 & 0xfffffffffffffffcULL; 3742 NewBar64 = (~NewBar64) + 1; 3743 NewBar64 = NewBar64 & 0x000000000000ffff; 3744 } 3745 } 3746 // 3747 // Enable io & mem access 3748 // 3749 RegAddress = Address | INDEX_OF (Command); 3750 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &OldCommand); 3751 3752 if (IsMem) { 3753 if (IsBar32) { 3754 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32), gShellDebug1HiiHandle, NewBar32); 3755 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_2), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffff0) - 1); 3756 3757 } else { 3758 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) RShiftU64 (NewBar64, 32)); 3759 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) NewBar64); 3760 ShellPrintEx (-1, -1, L" "); 3761 ShellPrintHiiEx(-1, -1, NULL, 3762 STRING_TOKEN (STR_PCI2_RSHIFT), 3763 gShellDebug1HiiHandle, 3764 (UINT32) RShiftU64 ((NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1), 32) 3765 ); 3766 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) (NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1)); 3767 3768 } 3769 } else { 3770 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_3), gShellDebug1HiiHandle, NewBar32); 3771 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_4), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffffc) - 1); 3772 } 3773 3774 return EFI_SUCCESS; 3775 } 3776 3777 /** 3778 Explain the cardbus specific part of data in PCI configuration space. 3779 3780 @param[in] CardBus CardBus specific region of PCI configuration space. 3781 @param[in] Address Address used to access configuration space of this PCI device. 3782 @param[in] IoDev Handle used to access configuration space of PCI device. 3783 3784 @retval EFI_SUCCESS The command completed successfully. 3785 **/ 3786 EFI_STATUS 3787 PciExplainCardBusData ( 3788 IN PCI_CARDBUS_HEADER *CardBus, 3789 IN UINT64 Address, 3790 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev 3791 ) 3792 { 3793 BOOLEAN Io32Bit; 3794 PCI_CARDBUS_DATA *CardBusData; 3795 3796 ShellPrintHiiEx(-1, -1, NULL, 3797 STRING_TOKEN (STR_PCI2_CARDBUS_SOCKET), 3798 gShellDebug1HiiHandle, 3799 INDEX_OF (&(CardBus->CardBusSocketReg)), 3800 CardBus->CardBusSocketReg 3801 ); 3802 3803 // 3804 // Print Secondary Status 3805 // 3806 PciExplainStatus (&(CardBus->SecondaryStatus), FALSE, PciCardBusBridge); 3807 3808 // 3809 // Print Bus Numbers(Primary bus number, CardBus bus number, and 3810 // Subordinate bus number 3811 // 3812 ShellPrintHiiEx(-1, -1, NULL, 3813 STRING_TOKEN (STR_PCI2_BUS_NUMBERS_2), 3814 gShellDebug1HiiHandle, 3815 INDEX_OF (&(CardBus->PciBusNumber)), 3816 INDEX_OF (&(CardBus->CardBusBusNumber)), 3817 INDEX_OF (&(CardBus->SubordinateBusNumber)) 3818 ); 3819 3820 ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n"); 3821 3822 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS), gShellDebug1HiiHandle, CardBus->PciBusNumber); 3823 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_2), gShellDebug1HiiHandle, CardBus->CardBusBusNumber); 3824 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_3), gShellDebug1HiiHandle, CardBus->SubordinateBusNumber); 3825 3826 // 3827 // Print CardBus Latency Timer 3828 // 3829 ShellPrintHiiEx(-1, -1, NULL, 3830 STRING_TOKEN (STR_PCI2_CARDBUS_LATENCY), 3831 gShellDebug1HiiHandle, 3832 INDEX_OF (&(CardBus->CardBusLatencyTimer)), 3833 CardBus->CardBusLatencyTimer 3834 ); 3835 3836 // 3837 // Print Memory/Io ranges this cardbus bridge forwards 3838 // 3839 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE_2), gShellDebug1HiiHandle); 3840 ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n"); 3841 3842 ShellPrintHiiEx(-1, -1, NULL, 3843 STRING_TOKEN (STR_PCI2_MEM_3), 3844 gShellDebug1HiiHandle, 3845 INDEX_OF (&(CardBus->MemoryBase0)), 3846 CardBus->BridgeControl & PCI_BIT_8 ? L" Prefetchable" : L"Non-Prefetchable", 3847 CardBus->MemoryBase0 & 0xfffff000, 3848 CardBus->MemoryLimit0 | 0x00000fff 3849 ); 3850 3851 ShellPrintHiiEx(-1, -1, NULL, 3852 STRING_TOKEN (STR_PCI2_MEM_3), 3853 gShellDebug1HiiHandle, 3854 INDEX_OF (&(CardBus->MemoryBase1)), 3855 CardBus->BridgeControl & PCI_BIT_9 ? L" Prefetchable" : L"Non-Prefetchable", 3856 CardBus->MemoryBase1 & 0xfffff000, 3857 CardBus->MemoryLimit1 | 0x00000fff 3858 ); 3859 3860 Io32Bit = (BOOLEAN) (CardBus->IoBase0 & PCI_BIT_0); 3861 ShellPrintHiiEx(-1, -1, NULL, 3862 STRING_TOKEN (STR_PCI2_IO_2), 3863 gShellDebug1HiiHandle, 3864 INDEX_OF (&(CardBus->IoBase0)), 3865 Io32Bit ? L" 32 bit" : L" 16 bit", 3866 CardBus->IoBase0 & (Io32Bit ? 0xfffffffc : 0x0000fffc), 3867 (CardBus->IoLimit0 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003 3868 ); 3869 3870 Io32Bit = (BOOLEAN) (CardBus->IoBase1 & PCI_BIT_0); 3871 ShellPrintHiiEx(-1, -1, NULL, 3872 STRING_TOKEN (STR_PCI2_IO_2), 3873 gShellDebug1HiiHandle, 3874 INDEX_OF (&(CardBus->IoBase1)), 3875 Io32Bit ? L" 32 bit" : L" 16 bit", 3876 CardBus->IoBase1 & (Io32Bit ? 0xfffffffc : 0x0000fffc), 3877 (CardBus->IoLimit1 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003 3878 ); 3879 3880 // 3881 // Print register Interrupt Line & PIN 3882 // 3883 ShellPrintHiiEx(-1, -1, NULL, 3884 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_3), 3885 gShellDebug1HiiHandle, 3886 INDEX_OF (&(CardBus->InterruptLine)), 3887 CardBus->InterruptLine, 3888 INDEX_OF (&(CardBus->InterruptPin)), 3889 CardBus->InterruptPin 3890 ); 3891 3892 // 3893 // Print register Bridge Control 3894 // 3895 PciExplainBridgeControl (&(CardBus->BridgeControl), PciCardBusBridge); 3896 3897 // 3898 // Print some registers in data region of PCI configuration space for cardbus 3899 // bridge. Fields include: Sub VendorId, Subsystem ID, and Legacy Mode Base 3900 // Address. 3901 // 3902 CardBusData = (PCI_CARDBUS_DATA *) ((UINT8 *) CardBus + sizeof (PCI_CARDBUS_HEADER)); 3903 3904 ShellPrintHiiEx(-1, -1, NULL, 3905 STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID_2), 3906 gShellDebug1HiiHandle, 3907 INDEX_OF (&(CardBusData->SubVendorId)), 3908 CardBusData->SubVendorId, 3909 INDEX_OF (&(CardBusData->SubSystemId)), 3910 CardBusData->SubSystemId 3911 ); 3912 3913 ShellPrintHiiEx(-1, -1, NULL, 3914 STRING_TOKEN (STR_PCI2_OPTIONAL), 3915 gShellDebug1HiiHandle, 3916 INDEX_OF (&(CardBusData->LegacyBase)), 3917 CardBusData->LegacyBase 3918 ); 3919 3920 return EFI_SUCCESS; 3921 } 3922 3923 /** 3924 Explain each meaningful bit of register Status. The definition of Status is 3925 slightly different depending on the PCI header type. 3926 3927 @param[in] Status Points to the content of register Status. 3928 @param[in] MainStatus Indicates if this register is main status(not secondary 3929 status). 3930 @param[in] HeaderType Header type of this PCI device. 3931 3932 @retval EFI_SUCCESS The command completed successfully. 3933 **/ 3934 EFI_STATUS 3935 PciExplainStatus ( 3936 IN UINT16 *Status, 3937 IN BOOLEAN MainStatus, 3938 IN PCI_HEADER_TYPE HeaderType 3939 ) 3940 { 3941 if (MainStatus) { 3942 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status); 3943 3944 } else { 3945 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SECONDARY_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status); 3946 } 3947 3948 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEW_CAPABILITIES), gShellDebug1HiiHandle, (*Status & PCI_BIT_4) != 0); 3949 3950 // 3951 // Bit 5 is meaningless for CardBus Bridge 3952 // 3953 if (HeaderType == PciCardBusBridge) { 3954 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE), gShellDebug1HiiHandle, (*Status & PCI_BIT_5) != 0); 3955 3956 } else { 3957 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE_2), gShellDebug1HiiHandle, (*Status & PCI_BIT_5) != 0); 3958 } 3959 3960 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST_BACK), gShellDebug1HiiHandle, (*Status & PCI_BIT_7) != 0); 3961 3962 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MASTER_DATA), gShellDebug1HiiHandle, (*Status & PCI_BIT_8) != 0); 3963 // 3964 // Bit 9 and bit 10 together decides the DEVSEL timing 3965 // 3966 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_DEVSEL_TIMING), gShellDebug1HiiHandle); 3967 if ((*Status & PCI_BIT_9) == 0 && (*Status & PCI_BIT_10) == 0) { 3968 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST), gShellDebug1HiiHandle); 3969 3970 } else if ((*Status & PCI_BIT_9) != 0 && (*Status & PCI_BIT_10) == 0) { 3971 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEDIUM), gShellDebug1HiiHandle); 3972 3973 } else if ((*Status & PCI_BIT_9) == 0 && (*Status & PCI_BIT_10) != 0) { 3974 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SLOW), gShellDebug1HiiHandle); 3975 3976 } else { 3977 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED_2), gShellDebug1HiiHandle); 3978 } 3979 3980 ShellPrintHiiEx(-1, -1, NULL, 3981 STRING_TOKEN (STR_PCI2_SIGNALED_TARGET), 3982 gShellDebug1HiiHandle, 3983 (*Status & PCI_BIT_11) != 0 3984 ); 3985 3986 ShellPrintHiiEx(-1, -1, NULL, 3987 STRING_TOKEN (STR_PCI2_RECEIVED_TARGET), 3988 gShellDebug1HiiHandle, 3989 (*Status & PCI_BIT_12) != 0 3990 ); 3991 3992 ShellPrintHiiEx(-1, -1, NULL, 3993 STRING_TOKEN (STR_PCI2_RECEIVED_MASTER), 3994 gShellDebug1HiiHandle, 3995 (*Status & PCI_BIT_13) != 0 3996 ); 3997 3998 if (MainStatus) { 3999 ShellPrintHiiEx(-1, -1, NULL, 4000 STRING_TOKEN (STR_PCI2_SIGNALED_ERROR), 4001 gShellDebug1HiiHandle, 4002 (*Status & PCI_BIT_14) != 0 4003 ); 4004 4005 } else { 4006 ShellPrintHiiEx(-1, -1, NULL, 4007 STRING_TOKEN (STR_PCI2_RECEIVED_ERROR), 4008 gShellDebug1HiiHandle, 4009 (*Status & PCI_BIT_14) != 0 4010 ); 4011 } 4012 4013 ShellPrintHiiEx(-1, -1, NULL, 4014 STRING_TOKEN (STR_PCI2_DETECTED_ERROR), 4015 gShellDebug1HiiHandle, 4016 (*Status & PCI_BIT_15) != 0 4017 ); 4018 4019 return EFI_SUCCESS; 4020 } 4021 4022 /** 4023 Explain each meaningful bit of register Command. 4024 4025 @param[in] Command Points to the content of register Command. 4026 4027 @retval EFI_SUCCESS The command completed successfully. 4028 **/ 4029 EFI_STATUS 4030 PciExplainCommand ( 4031 IN UINT16 *Command 4032 ) 4033 { 4034 // 4035 // Print the binary value of register Command 4036 // 4037 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_COMMAND), gShellDebug1HiiHandle, INDEX_OF (Command), *Command); 4038 4039 // 4040 // Explain register Command bit by bit 4041 // 4042 ShellPrintHiiEx(-1, -1, NULL, 4043 STRING_TOKEN (STR_PCI2_SPACE_ACCESS_DENIED), 4044 gShellDebug1HiiHandle, 4045 (*Command & PCI_BIT_0) != 0 4046 ); 4047 4048 ShellPrintHiiEx(-1, -1, NULL, 4049 STRING_TOKEN (STR_PCI2_MEMORY_SPACE), 4050 gShellDebug1HiiHandle, 4051 (*Command & PCI_BIT_1) != 0 4052 ); 4053 4054 ShellPrintHiiEx(-1, -1, NULL, 4055 STRING_TOKEN (STR_PCI2_BEHAVE_BUS_MASTER), 4056 gShellDebug1HiiHandle, 4057 (*Command & PCI_BIT_2) != 0 4058 ); 4059 4060 ShellPrintHiiEx(-1, -1, NULL, 4061 STRING_TOKEN (STR_PCI2_MONITOR_SPECIAL_CYCLE), 4062 gShellDebug1HiiHandle, 4063 (*Command & PCI_BIT_3) != 0 4064 ); 4065 4066 ShellPrintHiiEx(-1, -1, NULL, 4067 STRING_TOKEN (STR_PCI2_MEM_WRITE_INVALIDATE), 4068 gShellDebug1HiiHandle, 4069 (*Command & PCI_BIT_4) != 0 4070 ); 4071 4072 ShellPrintHiiEx(-1, -1, NULL, 4073 STRING_TOKEN (STR_PCI2_PALETTE_SNOOPING), 4074 gShellDebug1HiiHandle, 4075 (*Command & PCI_BIT_5) != 0 4076 ); 4077 4078 ShellPrintHiiEx(-1, -1, NULL, 4079 STRING_TOKEN (STR_PCI2_ASSERT_PERR), 4080 gShellDebug1HiiHandle, 4081 (*Command & PCI_BIT_6) != 0 4082 ); 4083 4084 ShellPrintHiiEx(-1, -1, NULL, 4085 STRING_TOKEN (STR_PCI2_DO_ADDR_STEPPING), 4086 gShellDebug1HiiHandle, 4087 (*Command & PCI_BIT_7) != 0 4088 ); 4089 4090 ShellPrintHiiEx(-1, -1, NULL, 4091 STRING_TOKEN (STR_PCI2_SERR_DRIVER), 4092 gShellDebug1HiiHandle, 4093 (*Command & PCI_BIT_8) != 0 4094 ); 4095 4096 ShellPrintHiiEx(-1, -1, NULL, 4097 STRING_TOKEN (STR_PCI2_FAST_BACK_2), 4098 gShellDebug1HiiHandle, 4099 (*Command & PCI_BIT_9) != 0 4100 ); 4101 4102 return EFI_SUCCESS; 4103 } 4104 4105 /** 4106 Explain each meaningful bit of register Bridge Control. 4107 4108 @param[in] BridgeControl Points to the content of register Bridge Control. 4109 @param[in] HeaderType The headertype. 4110 4111 @retval EFI_SUCCESS The command completed successfully. 4112 **/ 4113 EFI_STATUS 4114 PciExplainBridgeControl ( 4115 IN UINT16 *BridgeControl, 4116 IN PCI_HEADER_TYPE HeaderType 4117 ) 4118 { 4119 ShellPrintHiiEx(-1, -1, NULL, 4120 STRING_TOKEN (STR_PCI2_BRIDGE_CONTROL), 4121 gShellDebug1HiiHandle, 4122 INDEX_OF (BridgeControl), 4123 *BridgeControl 4124 ); 4125 4126 ShellPrintHiiEx(-1, -1, NULL, 4127 STRING_TOKEN (STR_PCI2_PARITY_ERROR), 4128 gShellDebug1HiiHandle, 4129 (*BridgeControl & PCI_BIT_0) != 0 4130 ); 4131 ShellPrintHiiEx(-1, -1, NULL, 4132 STRING_TOKEN (STR_PCI2_SERR_ENABLE), 4133 gShellDebug1HiiHandle, 4134 (*BridgeControl & PCI_BIT_1) != 0 4135 ); 4136 ShellPrintHiiEx(-1, -1, NULL, 4137 STRING_TOKEN (STR_PCI2_ISA_ENABLE), 4138 gShellDebug1HiiHandle, 4139 (*BridgeControl & PCI_BIT_2) != 0 4140 ); 4141 ShellPrintHiiEx(-1, -1, NULL, 4142 STRING_TOKEN (STR_PCI2_VGA_ENABLE), 4143 gShellDebug1HiiHandle, 4144 (*BridgeControl & PCI_BIT_3) != 0 4145 ); 4146 ShellPrintHiiEx(-1, -1, NULL, 4147 STRING_TOKEN (STR_PCI2_MASTER_ABORT), 4148 gShellDebug1HiiHandle, 4149 (*BridgeControl & PCI_BIT_5) != 0 4150 ); 4151 4152 // 4153 // Register Bridge Control has some slight differences between P2P bridge 4154 // and Cardbus bridge from bit 6 to bit 11. 4155 // 4156 if (HeaderType == PciP2pBridge) { 4157 ShellPrintHiiEx(-1, -1, NULL, 4158 STRING_TOKEN (STR_PCI2_SECONDARY_BUS_RESET), 4159 gShellDebug1HiiHandle, 4160 (*BridgeControl & PCI_BIT_6) != 0 4161 ); 4162 ShellPrintHiiEx(-1, -1, NULL, 4163 STRING_TOKEN (STR_PCI2_FAST_ENABLE), 4164 gShellDebug1HiiHandle, 4165 (*BridgeControl & PCI_BIT_7) != 0 4166 ); 4167 ShellPrintHiiEx(-1, -1, NULL, 4168 STRING_TOKEN (STR_PCI2_PRIMARY_DISCARD_TIMER), 4169 gShellDebug1HiiHandle, 4170 (*BridgeControl & PCI_BIT_8)!=0 ? L"2^10" : L"2^15" 4171 ); 4172 ShellPrintHiiEx(-1, -1, NULL, 4173 STRING_TOKEN (STR_PCI2_SECONDARY_DISCARD_TIMER), 4174 gShellDebug1HiiHandle, 4175 (*BridgeControl & PCI_BIT_9)!=0 ? L"2^10" : L"2^15" 4176 ); 4177 ShellPrintHiiEx(-1, -1, NULL, 4178 STRING_TOKEN (STR_PCI2_DISCARD_TIMER_STATUS), 4179 gShellDebug1HiiHandle, 4180 (*BridgeControl & PCI_BIT_10) != 0 4181 ); 4182 ShellPrintHiiEx(-1, -1, NULL, 4183 STRING_TOKEN (STR_PCI2_DISCARD_TIMER_SERR), 4184 gShellDebug1HiiHandle, 4185 (*BridgeControl & PCI_BIT_11) != 0 4186 ); 4187 4188 } else { 4189 ShellPrintHiiEx(-1, -1, NULL, 4190 STRING_TOKEN (STR_PCI2_CARDBUS_RESET), 4191 gShellDebug1HiiHandle, 4192 (*BridgeControl & PCI_BIT_6) != 0 4193 ); 4194 ShellPrintHiiEx(-1, -1, NULL, 4195 STRING_TOKEN (STR_PCI2_IREQ_ENABLE), 4196 gShellDebug1HiiHandle, 4197 (*BridgeControl & PCI_BIT_7) != 0 4198 ); 4199 ShellPrintHiiEx(-1, -1, NULL, 4200 STRING_TOKEN (STR_PCI2_WRITE_POSTING_ENABLE), 4201 gShellDebug1HiiHandle, 4202 (*BridgeControl & PCI_BIT_10) != 0 4203 ); 4204 } 4205 4206 return EFI_SUCCESS; 4207 } 4208 4209 /** 4210 Print each capability structure. 4211 4212 @param[in] IoDev The pointer to the deivce. 4213 @param[in] Address The address to start at. 4214 @param[in] CapPtr The offset from the address. 4215 @param[in] EnhancedDump The print format for the dump data. 4216 4217 @retval EFI_SUCCESS The operation was successful. 4218 **/ 4219 EFI_STATUS 4220 PciExplainCapabilityStruct ( 4221 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev, 4222 IN UINT64 Address, 4223 IN UINT8 CapPtr, 4224 IN CONST UINT16 EnhancedDump 4225 ) 4226 { 4227 UINT8 CapabilityPtr; 4228 UINT16 CapabilityEntry; 4229 UINT8 CapabilityID; 4230 UINT64 RegAddress; 4231 4232 CapabilityPtr = CapPtr; 4233 4234 // 4235 // Go through the Capability list 4236 // 4237 while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) { 4238 RegAddress = Address + CapabilityPtr; 4239 IoDev->Pci.Read (IoDev, EfiPciWidthUint16, RegAddress, 1, &CapabilityEntry); 4240 4241 CapabilityID = (UINT8) CapabilityEntry; 4242 4243 // 4244 // Explain PciExpress data 4245 // 4246 if (EFI_PCI_CAPABILITY_ID_PCIEXP == CapabilityID) { 4247 PciExplainPciExpress (IoDev, Address, CapabilityPtr, EnhancedDump); 4248 return EFI_SUCCESS; 4249 } 4250 // 4251 // Explain other capabilities here 4252 // 4253 CapabilityPtr = (UINT8) (CapabilityEntry >> 8); 4254 } 4255 4256 return EFI_SUCCESS; 4257 } 4258 4259 /** 4260 Print out information of the capability information. 4261 4262 @param[in] PciExpressCap The pointer to the structure about the device. 4263 4264 @retval EFI_SUCCESS The operation was successful. 4265 **/ 4266 EFI_STATUS 4267 ExplainPcieCapReg ( 4268 IN PCIE_CAP_STRUCTURE *PciExpressCap 4269 ) 4270 { 4271 UINT16 PcieCapReg; 4272 CHAR16 *DevicePortType; 4273 4274 PcieCapReg = PciExpressCap->PcieCapReg; 4275 ShellPrintEx (-1, -1, 4276 L" Capability Version(3:0): %E0x%04x%N\r\n", 4277 PCIE_CAP_VERSION (PcieCapReg) 4278 ); 4279 if ((UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) < PCIE_DEVICE_PORT_TYPE_MAX) { 4280 DevicePortType = DevicePortTypeTable[PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg)]; 4281 } else { 4282 DevicePortType = L"Unknown Type"; 4283 } 4284 ShellPrintEx (-1, -1, 4285 L" Device/PortType(7:4): %E%s%N\r\n", 4286 DevicePortType 4287 ); 4288 // 4289 // 'Slot Implemented' is only valid for: 4290 // a) Root Port of PCI Express Root Complex, or 4291 // b) Downstream Port of PCI Express Switch 4292 // 4293 if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_ROOT_COMPLEX_ROOT_PORT || 4294 PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_SWITCH_DOWNSTREAM_PORT) { 4295 ShellPrintEx (-1, -1, 4296 L" Slot Implemented(8): %E%d%N\r\n", 4297 PCIE_CAP_SLOT_IMPLEMENTED (PcieCapReg) 4298 ); 4299 } 4300 ShellPrintEx (-1, -1, 4301 L" Interrupt Message Number(13:9): %E0x%05x%N\r\n", 4302 PCIE_CAP_INT_MSG_NUM (PcieCapReg) 4303 ); 4304 return EFI_SUCCESS; 4305 } 4306 4307 /** 4308 Print out information of the device capability information. 4309 4310 @param[in] PciExpressCap The pointer to the structure about the device. 4311 4312 @retval EFI_SUCCESS The operation was successful. 4313 **/ 4314 EFI_STATUS 4315 ExplainPcieDeviceCap ( 4316 IN PCIE_CAP_STRUCTURE *PciExpressCap 4317 ) 4318 { 4319 UINT16 PcieCapReg; 4320 UINT32 PcieDeviceCap; 4321 UINT8 DevicePortType; 4322 UINT8 L0sLatency; 4323 UINT8 L1Latency; 4324 4325 PcieCapReg = PciExpressCap->PcieCapReg; 4326 PcieDeviceCap = PciExpressCap->PcieDeviceCap; 4327 DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg); 4328 ShellPrintEx (-1, -1, L" Max_Payload_Size Supported(2:0): "); 4329 if (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) < 6) { 4330 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) + 7)); 4331 } else { 4332 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n"); 4333 } 4334 ShellPrintEx (-1, -1, 4335 L" Phantom Functions Supported(4:3): %E%d%N\r\n", 4336 PCIE_CAP_PHANTOM_FUNC (PcieDeviceCap) 4337 ); 4338 ShellPrintEx (-1, -1, 4339 L" Extended Tag Field Supported(5): %E%d-bit Tag field supported%N\r\n", 4340 PCIE_CAP_EXTENDED_TAG (PcieDeviceCap) ? 8 : 5 4341 ); 4342 // 4343 // Endpoint L0s and L1 Acceptable Latency is only valid for Endpoint 4344 // 4345 if (IS_PCIE_ENDPOINT (DevicePortType)) { 4346 L0sLatency = (UINT8) PCIE_CAP_L0SLATENCY (PcieDeviceCap); 4347 L1Latency = (UINT8) PCIE_CAP_L1LATENCY (PcieDeviceCap); 4348 ShellPrintEx (-1, -1, L" Endpoint L0s Acceptable Latency(8:6): "); 4349 if (L0sLatency < 4) { 4350 ShellPrintEx (-1, -1, L"%EMaximum of %d ns%N\r\n", 1 << (L0sLatency + 6)); 4351 } else { 4352 if (L0sLatency < 7) { 4353 ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L0sLatency - 3)); 4354 } else { 4355 ShellPrintEx (-1, -1, L"%ENo limit%N\r\n"); 4356 } 4357 } 4358 ShellPrintEx (-1, -1, L" Endpoint L1 Acceptable Latency(11:9): "); 4359 if (L1Latency < 7) { 4360 ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L1Latency + 1)); 4361 } else { 4362 ShellPrintEx (-1, -1, L"%ENo limit%N\r\n"); 4363 } 4364 } 4365 ShellPrintEx (-1, -1, 4366 L" Role-based Error Reporting(15): %E%d%N\r\n", 4367 PCIE_CAP_ERR_REPORTING (PcieDeviceCap) 4368 ); 4369 // 4370 // Only valid for Upstream Port: 4371 // a) Captured Slot Power Limit Value 4372 // b) Captured Slot Power Scale 4373 // 4374 if (DevicePortType == PCIE_SWITCH_UPSTREAM_PORT) { 4375 ShellPrintEx (-1, -1, 4376 L" Captured Slot Power Limit Value(25:18): %E0x%02x%N\r\n", 4377 PCIE_CAP_SLOT_POWER_VALUE (PcieDeviceCap) 4378 ); 4379 ShellPrintEx (-1, -1, 4380 L" Captured Slot Power Limit Scale(27:26): %E%s%N\r\n", 4381 SlotPwrLmtScaleTable[PCIE_CAP_SLOT_POWER_SCALE (PcieDeviceCap)] 4382 ); 4383 } 4384 // 4385 // Function Level Reset Capability is only valid for Endpoint 4386 // 4387 if (IS_PCIE_ENDPOINT (DevicePortType)) { 4388 ShellPrintEx (-1, -1, 4389 L" Function Level Reset Capability(28): %E%d%N\r\n", 4390 PCIE_CAP_FUNC_LEVEL_RESET (PcieDeviceCap) 4391 ); 4392 } 4393 return EFI_SUCCESS; 4394 } 4395 4396 /** 4397 Print out information of the device control information. 4398 4399 @param[in] PciExpressCap The pointer to the structure about the device. 4400 4401 @retval EFI_SUCCESS The operation was successful. 4402 **/ 4403 EFI_STATUS 4404 ExplainPcieDeviceControl ( 4405 IN PCIE_CAP_STRUCTURE *PciExpressCap 4406 ) 4407 { 4408 UINT16 PcieCapReg; 4409 UINT16 PcieDeviceControl; 4410 4411 PcieCapReg = PciExpressCap->PcieCapReg; 4412 PcieDeviceControl = PciExpressCap->DeviceControl; 4413 ShellPrintEx (-1, -1, 4414 L" Correctable Error Reporting Enable(0): %E%d%N\r\n", 4415 PCIE_CAP_COR_ERR_REPORTING_ENABLE (PcieDeviceControl) 4416 ); 4417 ShellPrintEx (-1, -1, 4418 L" Non-Fatal Error Reporting Enable(1): %E%d%N\r\n", 4419 PCIE_CAP_NONFAT_ERR_REPORTING_ENABLE (PcieDeviceControl) 4420 ); 4421 ShellPrintEx (-1, -1, 4422 L" Fatal Error Reporting Enable(2): %E%d%N\r\n", 4423 PCIE_CAP_FATAL_ERR_REPORTING_ENABLE (PcieDeviceControl) 4424 ); 4425 ShellPrintEx (-1, -1, 4426 L" Unsupported Request Reporting Enable(3): %E%d%N\r\n", 4427 PCIE_CAP_UNSUP_REQ_REPORTING_ENABLE (PcieDeviceControl) 4428 ); 4429 ShellPrintEx (-1, -1, 4430 L" Enable Relaxed Ordering(4): %E%d%N\r\n", 4431 PCIE_CAP_RELAXED_ORDERING_ENABLE (PcieDeviceControl) 4432 ); 4433 ShellPrintEx (-1, -1, L" Max_Payload_Size(7:5): "); 4434 if (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) < 6) { 4435 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) + 7)); 4436 } else { 4437 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n"); 4438 } 4439 ShellPrintEx (-1, -1, 4440 L" Extended Tag Field Enable(8): %E%d%N\r\n", 4441 PCIE_CAP_EXTENDED_TAG_ENABLE (PcieDeviceControl) 4442 ); 4443 ShellPrintEx (-1, -1, 4444 L" Phantom Functions Enable(9): %E%d%N\r\n", 4445 PCIE_CAP_PHANTOM_FUNC_ENABLE (PcieDeviceControl) 4446 ); 4447 ShellPrintEx (-1, -1, 4448 L" Auxiliary (AUX) Power PM Enable(10): %E%d%N\r\n", 4449 PCIE_CAP_AUX_PM_ENABLE (PcieDeviceControl) 4450 ); 4451 ShellPrintEx (-1, -1, 4452 L" Enable No Snoop(11): %E%d%N\r\n", 4453 PCIE_CAP_NO_SNOOP_ENABLE (PcieDeviceControl) 4454 ); 4455 ShellPrintEx (-1, -1, L" Max_Read_Request_Size(14:12): "); 4456 if (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) < 6) { 4457 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) + 7)); 4458 } else { 4459 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n"); 4460 } 4461 // 4462 // Read operation is only valid for PCI Express to PCI/PCI-X Bridges 4463 // 4464 if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_PCIE_TO_PCIX_BRIDGE) { 4465 ShellPrintEx (-1, -1, 4466 L" Bridge Configuration Retry Enable(15): %E%d%N\r\n", 4467 PCIE_CAP_BRG_CONF_RETRY (PcieDeviceControl) 4468 ); 4469 } 4470 return EFI_SUCCESS; 4471 } 4472 4473 /** 4474 Print out information of the device status information. 4475 4476 @param[in] PciExpressCap The pointer to the structure about the device. 4477 4478 @retval EFI_SUCCESS The operation was successful. 4479 **/ 4480 EFI_STATUS 4481 ExplainPcieDeviceStatus ( 4482 IN PCIE_CAP_STRUCTURE *PciExpressCap 4483 ) 4484 { 4485 UINT16 PcieDeviceStatus; 4486 4487 PcieDeviceStatus = PciExpressCap->DeviceStatus; 4488 ShellPrintEx (-1, -1, 4489 L" Correctable Error Detected(0): %E%d%N\r\n", 4490 PCIE_CAP_COR_ERR_DETECTED (PcieDeviceStatus) 4491 ); 4492 ShellPrintEx (-1, -1, 4493 L" Non-Fatal Error Detected(1): %E%d%N\r\n", 4494 PCIE_CAP_NONFAT_ERR_DETECTED (PcieDeviceStatus) 4495 ); 4496 ShellPrintEx (-1, -1, 4497 L" Fatal Error Detected(2): %E%d%N\r\n", 4498 PCIE_CAP_FATAL_ERR_DETECTED (PcieDeviceStatus) 4499 ); 4500 ShellPrintEx (-1, -1, 4501 L" Unsupported Request Detected(3): %E%d%N\r\n", 4502 PCIE_CAP_UNSUP_REQ_DETECTED (PcieDeviceStatus) 4503 ); 4504 ShellPrintEx (-1, -1, 4505 L" AUX Power Detected(4): %E%d%N\r\n", 4506 PCIE_CAP_AUX_POWER_DETECTED (PcieDeviceStatus) 4507 ); 4508 ShellPrintEx (-1, -1, 4509 L" Transactions Pending(5): %E%d%N\r\n", 4510 PCIE_CAP_TRANSACTION_PENDING (PcieDeviceStatus) 4511 ); 4512 return EFI_SUCCESS; 4513 } 4514 4515 /** 4516 Print out information of the device link information. 4517 4518 @param[in] PciExpressCap The pointer to the structure about the device. 4519 4520 @retval EFI_SUCCESS The operation was successful. 4521 **/ 4522 EFI_STATUS 4523 ExplainPcieLinkCap ( 4524 IN PCIE_CAP_STRUCTURE *PciExpressCap 4525 ) 4526 { 4527 UINT32 PcieLinkCap; 4528 CHAR16 *MaxLinkSpeed; 4529 CHAR16 *AspmValue; 4530 4531 PcieLinkCap = PciExpressCap->LinkCap; 4532 switch (PCIE_CAP_MAX_LINK_SPEED (PcieLinkCap)) { 4533 case 1: 4534 MaxLinkSpeed = L"2.5 GT/s"; 4535 break; 4536 case 2: 4537 MaxLinkSpeed = L"5.0 GT/s"; 4538 break; 4539 case 3: 4540 MaxLinkSpeed = L"8.0 GT/s"; 4541 break; 4542 default: 4543 MaxLinkSpeed = L"Unknown"; 4544 break; 4545 } 4546 ShellPrintEx (-1, -1, 4547 L" Maximum Link Speed(3:0): %E%s%N\r\n", 4548 MaxLinkSpeed 4549 ); 4550 ShellPrintEx (-1, -1, 4551 L" Maximum Link Width(9:4): %Ex%d%N\r\n", 4552 PCIE_CAP_MAX_LINK_WIDTH (PcieLinkCap) 4553 ); 4554 switch (PCIE_CAP_ASPM_SUPPORT (PcieLinkCap)) { 4555 case 0: 4556 AspmValue = L"Not"; 4557 break; 4558 case 1: 4559 AspmValue = L"L0s"; 4560 break; 4561 case 2: 4562 AspmValue = L"L1"; 4563 break; 4564 case 3: 4565 AspmValue = L"L0s and L1"; 4566 break; 4567 default: 4568 AspmValue = L"Reserved"; 4569 break; 4570 } 4571 ShellPrintEx (-1, -1, 4572 L" Active State Power Management Support(11:10): %E%s Supported%N\r\n", 4573 AspmValue 4574 ); 4575 ShellPrintEx (-1, -1, 4576 L" L0s Exit Latency(14:12): %E%s%N\r\n", 4577 L0sLatencyStrTable[PCIE_CAP_L0S_LATENCY (PcieLinkCap)] 4578 ); 4579 ShellPrintEx (-1, -1, 4580 L" L1 Exit Latency(17:15): %E%s%N\r\n", 4581 L1LatencyStrTable[PCIE_CAP_L0S_LATENCY (PcieLinkCap)] 4582 ); 4583 ShellPrintEx (-1, -1, 4584 L" Clock Power Management(18): %E%d%N\r\n", 4585 PCIE_CAP_CLOCK_PM (PcieLinkCap) 4586 ); 4587 ShellPrintEx (-1, -1, 4588 L" Surprise Down Error Reporting Capable(19): %E%d%N\r\n", 4589 PCIE_CAP_SUP_DOWN_ERR_REPORTING (PcieLinkCap) 4590 ); 4591 ShellPrintEx (-1, -1, 4592 L" Data Link Layer Link Active Reporting Capable(20): %E%d%N\r\n", 4593 PCIE_CAP_LINK_ACTIVE_REPORTING (PcieLinkCap) 4594 ); 4595 ShellPrintEx (-1, -1, 4596 L" Link Bandwidth Notification Capability(21): %E%d%N\r\n", 4597 PCIE_CAP_LINK_BWD_NOTIF_CAP (PcieLinkCap) 4598 ); 4599 ShellPrintEx (-1, -1, 4600 L" Port Number(31:24): %E0x%02x%N\r\n", 4601 PCIE_CAP_PORT_NUMBER (PcieLinkCap) 4602 ); 4603 return EFI_SUCCESS; 4604 } 4605 4606 /** 4607 Print out information of the device link control information. 4608 4609 @param[in] PciExpressCap The pointer to the structure about the device. 4610 4611 @retval EFI_SUCCESS The operation was successful. 4612 **/ 4613 EFI_STATUS 4614 ExplainPcieLinkControl ( 4615 IN PCIE_CAP_STRUCTURE *PciExpressCap 4616 ) 4617 { 4618 UINT16 PcieLinkControl; 4619 UINT8 DevicePortType; 4620 4621 PcieLinkControl = PciExpressCap->LinkControl; 4622 DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap->PcieCapReg); 4623 ShellPrintEx (-1, -1, 4624 L" Active State Power Management Control(1:0): %E%s%N\r\n", 4625 ASPMCtrlStrTable[PCIE_CAP_ASPM_CONTROL (PcieLinkControl)] 4626 ); 4627 // 4628 // RCB is not applicable to switches 4629 // 4630 if (!IS_PCIE_SWITCH(DevicePortType)) { 4631 ShellPrintEx (-1, -1, 4632 L" Read Completion Boundary (RCB)(3): %E%d byte%N\r\n", 4633 1 << (PCIE_CAP_RCB (PcieLinkControl) + 6) 4634 ); 4635 } 4636 // 4637 // Link Disable is reserved on 4638 // a) Endpoints 4639 // b) PCI Express to PCI/PCI-X bridges 4640 // c) Upstream Ports of Switches 4641 // 4642 if (!IS_PCIE_ENDPOINT (DevicePortType) && 4643 DevicePortType != PCIE_SWITCH_UPSTREAM_PORT && 4644 DevicePortType != PCIE_PCIE_TO_PCIX_BRIDGE) { 4645 ShellPrintEx (-1, -1, 4646 L" Link Disable(4): %E%d%N\r\n", 4647 PCIE_CAP_LINK_DISABLE (PcieLinkControl) 4648 ); 4649 } 4650 ShellPrintEx (-1, -1, 4651 L" Common Clock Configuration(6): %E%d%N\r\n", 4652 PCIE_CAP_COMMON_CLK_CONF (PcieLinkControl) 4653 ); 4654 ShellPrintEx (-1, -1, 4655 L" Extended Synch(7): %E%d%N\r\n", 4656 PCIE_CAP_EXT_SYNC (PcieLinkControl) 4657 ); 4658 ShellPrintEx (-1, -1, 4659 L" Enable Clock Power Management(8): %E%d%N\r\n", 4660 PCIE_CAP_CLK_PWR_MNG (PcieLinkControl) 4661 ); 4662 ShellPrintEx (-1, -1, 4663 L" Hardware Autonomous Width Disable(9): %E%d%N\r\n", 4664 PCIE_CAP_HW_AUTO_WIDTH_DISABLE (PcieLinkControl) 4665 ); 4666 ShellPrintEx (-1, -1, 4667 L" Link Bandwidth Management Interrupt Enable(10): %E%d%N\r\n", 4668 PCIE_CAP_LINK_BDW_MNG_INT_EN (PcieLinkControl) 4669 ); 4670 ShellPrintEx (-1, -1, 4671 L" Link Autonomous Bandwidth Interrupt Enable(11): %E%d%N\r\n", 4672 PCIE_CAP_LINK_AUTO_BDW_INT_EN (PcieLinkControl) 4673 ); 4674 return EFI_SUCCESS; 4675 } 4676 4677 /** 4678 Print out information of the device link status information. 4679 4680 @param[in] PciExpressCap The pointer to the structure about the device. 4681 4682 @retval EFI_SUCCESS The operation was successful. 4683 **/ 4684 EFI_STATUS 4685 ExplainPcieLinkStatus ( 4686 IN PCIE_CAP_STRUCTURE *PciExpressCap 4687 ) 4688 { 4689 UINT16 PcieLinkStatus; 4690 CHAR16 *CurLinkSpeed; 4691 4692 PcieLinkStatus = PciExpressCap->LinkStatus; 4693 switch (PCIE_CAP_CUR_LINK_SPEED (PcieLinkStatus)) { 4694 case 1: 4695 CurLinkSpeed = L"2.5 GT/s"; 4696 break; 4697 case 2: 4698 CurLinkSpeed = L"5.0 GT/s"; 4699 break; 4700 case 3: 4701 CurLinkSpeed = L"8.0 GT/s"; 4702 break; 4703 default: 4704 CurLinkSpeed = L"Reserved"; 4705 break; 4706 } 4707 ShellPrintEx (-1, -1, 4708 L" Current Link Speed(3:0): %E%s%N\r\n", 4709 CurLinkSpeed 4710 ); 4711 ShellPrintEx (-1, -1, 4712 L" Negotiated Link Width(9:4): %Ex%d%N\r\n", 4713 PCIE_CAP_NEGO_LINK_WIDTH (PcieLinkStatus) 4714 ); 4715 ShellPrintEx (-1, -1, 4716 L" Link Training(11): %E%d%N\r\n", 4717 PCIE_CAP_LINK_TRAINING (PcieLinkStatus) 4718 ); 4719 ShellPrintEx (-1, -1, 4720 L" Slot Clock Configuration(12): %E%d%N\r\n", 4721 PCIE_CAP_SLOT_CLK_CONF (PcieLinkStatus) 4722 ); 4723 ShellPrintEx (-1, -1, 4724 L" Data Link Layer Link Active(13): %E%d%N\r\n", 4725 PCIE_CAP_DATA_LINK_ACTIVE (PcieLinkStatus) 4726 ); 4727 ShellPrintEx (-1, -1, 4728 L" Link Bandwidth Management Status(14): %E%d%N\r\n", 4729 PCIE_CAP_LINK_BDW_MNG_STAT (PcieLinkStatus) 4730 ); 4731 ShellPrintEx (-1, -1, 4732 L" Link Autonomous Bandwidth Status(15): %E%d%N\r\n", 4733 PCIE_CAP_LINK_AUTO_BDW_STAT (PcieLinkStatus) 4734 ); 4735 return EFI_SUCCESS; 4736 } 4737 4738 /** 4739 Print out information of the device slot information. 4740 4741 @param[in] PciExpressCap The pointer to the structure about the device. 4742 4743 @retval EFI_SUCCESS The operation was successful. 4744 **/ 4745 EFI_STATUS 4746 ExplainPcieSlotCap ( 4747 IN PCIE_CAP_STRUCTURE *PciExpressCap 4748 ) 4749 { 4750 UINT32 PcieSlotCap; 4751 4752 PcieSlotCap = PciExpressCap->SlotCap; 4753 4754 ShellPrintEx (-1, -1, 4755 L" Attention Button Present(0): %E%d%N\r\n", 4756 PCIE_CAP_ATT_BUT_PRESENT (PcieSlotCap) 4757 ); 4758 ShellPrintEx (-1, -1, 4759 L" Power Controller Present(1): %E%d%N\r\n", 4760 PCIE_CAP_PWR_CTRLLER_PRESENT (PcieSlotCap) 4761 ); 4762 ShellPrintEx (-1, -1, 4763 L" MRL Sensor Present(2): %E%d%N\r\n", 4764 PCIE_CAP_MRL_SENSOR_PRESENT (PcieSlotCap) 4765 ); 4766 ShellPrintEx (-1, -1, 4767 L" Attention Indicator Present(3): %E%d%N\r\n", 4768 PCIE_CAP_ATT_IND_PRESENT (PcieSlotCap) 4769 ); 4770 ShellPrintEx (-1, -1, 4771 L" Power Indicator Present(4): %E%d%N\r\n", 4772 PCIE_CAP_PWD_IND_PRESENT (PcieSlotCap) 4773 ); 4774 ShellPrintEx (-1, -1, 4775 L" Hot-Plug Surprise(5): %E%d%N\r\n", 4776 PCIE_CAP_HOTPLUG_SUPPRISE (PcieSlotCap) 4777 ); 4778 ShellPrintEx (-1, -1, 4779 L" Hot-Plug Capable(6): %E%d%N\r\n", 4780 PCIE_CAP_HOTPLUG_CAPABLE (PcieSlotCap) 4781 ); 4782 ShellPrintEx (-1, -1, 4783 L" Slot Power Limit Value(14:7): %E0x%02x%N\r\n", 4784 PCIE_CAP_SLOT_PWR_LIMIT_VALUE (PcieSlotCap) 4785 ); 4786 ShellPrintEx (-1, -1, 4787 L" Slot Power Limit Scale(16:15): %E%s%N\r\n", 4788 SlotPwrLmtScaleTable[PCIE_CAP_SLOT_PWR_LIMIT_SCALE (PcieSlotCap)] 4789 ); 4790 ShellPrintEx (-1, -1, 4791 L" Electromechanical Interlock Present(17): %E%d%N\r\n", 4792 PCIE_CAP_ELEC_INTERLOCK_PRESENT (PcieSlotCap) 4793 ); 4794 ShellPrintEx (-1, -1, 4795 L" No Command Completed Support(18): %E%d%N\r\n", 4796 PCIE_CAP_NO_COMM_COMPLETED_SUP (PcieSlotCap) 4797 ); 4798 ShellPrintEx (-1, -1, 4799 L" Physical Slot Number(31:19): %E%d%N\r\n", 4800 PCIE_CAP_PHY_SLOT_NUM (PcieSlotCap) 4801 ); 4802 4803 return EFI_SUCCESS; 4804 } 4805 4806 /** 4807 Print out information of the device slot control information. 4808 4809 @param[in] PciExpressCap The pointer to the structure about the device. 4810 4811 @retval EFI_SUCCESS The operation was successful. 4812 **/ 4813 EFI_STATUS 4814 ExplainPcieSlotControl ( 4815 IN PCIE_CAP_STRUCTURE *PciExpressCap 4816 ) 4817 { 4818 UINT16 PcieSlotControl; 4819 4820 PcieSlotControl = PciExpressCap->SlotControl; 4821 ShellPrintEx (-1, -1, 4822 L" Attention Button Pressed Enable(0): %E%d%N\r\n", 4823 PCIE_CAP_ATT_BUT_ENABLE (PcieSlotControl) 4824 ); 4825 ShellPrintEx (-1, -1, 4826 L" Power Fault Detected Enable(1): %E%d%N\r\n", 4827 PCIE_CAP_PWR_FLT_DETECT_ENABLE (PcieSlotControl) 4828 ); 4829 ShellPrintEx (-1, -1, 4830 L" MRL Sensor Changed Enable(2): %E%d%N\r\n", 4831 PCIE_CAP_MRL_SENSOR_CHANGE_ENABLE (PcieSlotControl) 4832 ); 4833 ShellPrintEx (-1, -1, 4834 L" Presence Detect Changed Enable(3): %E%d%N\r\n", 4835 PCIE_CAP_PRES_DETECT_CHANGE_ENABLE (PcieSlotControl) 4836 ); 4837 ShellPrintEx (-1, -1, 4838 L" Command Completed Interrupt Enable(4): %E%d%N\r\n", 4839 PCIE_CAP_COMM_CMPL_INT_ENABLE (PcieSlotControl) 4840 ); 4841 ShellPrintEx (-1, -1, 4842 L" Hot-Plug Interrupt Enable(5): %E%d%N\r\n", 4843 PCIE_CAP_HOTPLUG_INT_ENABLE (PcieSlotControl) 4844 ); 4845 ShellPrintEx (-1, -1, 4846 L" Attention Indicator Control(7:6): %E%s%N\r\n", 4847 IndicatorTable[PCIE_CAP_ATT_IND_CTRL (PcieSlotControl)] 4848 ); 4849 ShellPrintEx (-1, -1, 4850 L" Power Indicator Control(9:8): %E%s%N\r\n", 4851 IndicatorTable[PCIE_CAP_PWR_IND_CTRL (PcieSlotControl)] 4852 ); 4853 ShellPrintEx (-1, -1, L" Power Controller Control(10): %EPower "); 4854 if (PCIE_CAP_PWR_CTRLLER_CTRL (PcieSlotControl)) { 4855 ShellPrintEx (-1, -1, L"Off%N\r\n"); 4856 } else { 4857 ShellPrintEx (-1, -1, L"On%N\r\n"); 4858 } 4859 ShellPrintEx (-1, -1, 4860 L" Electromechanical Interlock Control(11): %E%d%N\r\n", 4861 PCIE_CAP_ELEC_INTERLOCK_CTRL (PcieSlotControl) 4862 ); 4863 ShellPrintEx (-1, -1, 4864 L" Data Link Layer State Changed Enable(12): %E%d%N\r\n", 4865 PCIE_CAP_DLINK_STAT_CHANGE_ENABLE (PcieSlotControl) 4866 ); 4867 return EFI_SUCCESS; 4868 } 4869 4870 /** 4871 Print out information of the device slot status information. 4872 4873 @param[in] PciExpressCap The pointer to the structure about the device. 4874 4875 @retval EFI_SUCCESS The operation was successful. 4876 **/ 4877 EFI_STATUS 4878 ExplainPcieSlotStatus ( 4879 IN PCIE_CAP_STRUCTURE *PciExpressCap 4880 ) 4881 { 4882 UINT16 PcieSlotStatus; 4883 4884 PcieSlotStatus = PciExpressCap->SlotStatus; 4885 4886 ShellPrintEx (-1, -1, 4887 L" Attention Button Pressed(0): %E%d%N\r\n", 4888 PCIE_CAP_ATT_BUT_PRESSED (PcieSlotStatus) 4889 ); 4890 ShellPrintEx (-1, -1, 4891 L" Power Fault Detected(1): %E%d%N\r\n", 4892 PCIE_CAP_PWR_FLT_DETECTED (PcieSlotStatus) 4893 ); 4894 ShellPrintEx (-1, -1, 4895 L" MRL Sensor Changed(2): %E%d%N\r\n", 4896 PCIE_CAP_MRL_SENSOR_CHANGED (PcieSlotStatus) 4897 ); 4898 ShellPrintEx (-1, -1, 4899 L" Presence Detect Changed(3): %E%d%N\r\n", 4900 PCIE_CAP_PRES_DETECT_CHANGED (PcieSlotStatus) 4901 ); 4902 ShellPrintEx (-1, -1, 4903 L" Command Completed(4): %E%d%N\r\n", 4904 PCIE_CAP_COMM_COMPLETED (PcieSlotStatus) 4905 ); 4906 ShellPrintEx (-1, -1, L" MRL Sensor State(5): %EMRL "); 4907 if (PCIE_CAP_MRL_SENSOR_STATE (PcieSlotStatus)) { 4908 ShellPrintEx (-1, -1, L" Opened%N\r\n"); 4909 } else { 4910 ShellPrintEx (-1, -1, L" Closed%N\r\n"); 4911 } 4912 ShellPrintEx (-1, -1, L" Presence Detect State(6): "); 4913 if (PCIE_CAP_PRES_DETECT_STATE (PcieSlotStatus)) { 4914 ShellPrintEx (-1, -1, L"%ECard Present in slot%N\r\n"); 4915 } else { 4916 ShellPrintEx (-1, -1, L"%ESlot Empty%N\r\n"); 4917 } 4918 ShellPrintEx (-1, -1, L" Electromechanical Interlock Status(7): %EElectromechanical Interlock "); 4919 if (PCIE_CAP_ELEC_INTERLOCK_STATE (PcieSlotStatus)) { 4920 ShellPrintEx (-1, -1, L"Engaged%N\r\n"); 4921 } else { 4922 ShellPrintEx (-1, -1, L"Disengaged%N\r\n"); 4923 } 4924 ShellPrintEx (-1, -1, 4925 L" Data Link Layer State Changed(8): %E%d%N\r\n", 4926 PCIE_CAP_DLINK_STAT_CHANGED (PcieSlotStatus) 4927 ); 4928 return EFI_SUCCESS; 4929 } 4930 4931 /** 4932 Print out information of the device root information. 4933 4934 @param[in] PciExpressCap The pointer to the structure about the device. 4935 4936 @retval EFI_SUCCESS The operation was successful. 4937 **/ 4938 EFI_STATUS 4939 ExplainPcieRootControl ( 4940 IN PCIE_CAP_STRUCTURE *PciExpressCap 4941 ) 4942 { 4943 UINT16 PcieRootControl; 4944 4945 PcieRootControl = PciExpressCap->RootControl; 4946 4947 ShellPrintEx (-1, -1, 4948 L" System Error on Correctable Error Enable(0): %E%d%N\r\n", 4949 PCIE_CAP_SYSERR_ON_CORERR_EN (PcieRootControl) 4950 ); 4951 ShellPrintEx (-1, -1, 4952 L" System Error on Non-Fatal Error Enable(1): %E%d%N\r\n", 4953 PCIE_CAP_SYSERR_ON_NONFATERR_EN (PcieRootControl) 4954 ); 4955 ShellPrintEx (-1, -1, 4956 L" System Error on Fatal Error Enable(2): %E%d%N\r\n", 4957 PCIE_CAP_SYSERR_ON_FATERR_EN (PcieRootControl) 4958 ); 4959 ShellPrintEx (-1, -1, 4960 L" PME Interrupt Enable(3): %E%d%N\r\n", 4961 PCIE_CAP_PME_INT_ENABLE (PcieRootControl) 4962 ); 4963 ShellPrintEx (-1, -1, 4964 L" CRS Software Visibility Enable(4): %E%d%N\r\n", 4965 PCIE_CAP_CRS_SW_VIS_ENABLE (PcieRootControl) 4966 ); 4967 4968 return EFI_SUCCESS; 4969 } 4970 4971 /** 4972 Print out information of the device root capability information. 4973 4974 @param[in] PciExpressCap The pointer to the structure about the device. 4975 4976 @retval EFI_SUCCESS The operation was successful. 4977 **/ 4978 EFI_STATUS 4979 ExplainPcieRootCap ( 4980 IN PCIE_CAP_STRUCTURE *PciExpressCap 4981 ) 4982 { 4983 UINT16 PcieRootCap; 4984 4985 PcieRootCap = PciExpressCap->RsvdP; 4986 4987 ShellPrintEx (-1, -1, 4988 L" CRS Software Visibility(0): %E%d%N\r\n", 4989 PCIE_CAP_CRS_SW_VIS (PcieRootCap) 4990 ); 4991 4992 return EFI_SUCCESS; 4993 } 4994 4995 /** 4996 Print out information of the device root status information. 4997 4998 @param[in] PciExpressCap The pointer to the structure about the device. 4999 5000 @retval EFI_SUCCESS The operation was successful. 5001 **/ 5002 EFI_STATUS 5003 ExplainPcieRootStatus ( 5004 IN PCIE_CAP_STRUCTURE *PciExpressCap 5005 ) 5006 { 5007 UINT32 PcieRootStatus; 5008 5009 PcieRootStatus = PciExpressCap->RootStatus; 5010 5011 ShellPrintEx (-1, -1, 5012 L" PME Requester ID(15:0): %E0x%04x%N\r\n", 5013 PCIE_CAP_PME_REQ_ID (PcieRootStatus) 5014 ); 5015 ShellPrintEx (-1, -1, 5016 L" PME Status(16): %E%d%N\r\n", 5017 PCIE_CAP_PME_STATUS (PcieRootStatus) 5018 ); 5019 ShellPrintEx (-1, -1, 5020 L" PME Pending(17): %E%d%N\r\n", 5021 PCIE_CAP_PME_PENDING (PcieRootStatus) 5022 ); 5023 return EFI_SUCCESS; 5024 } 5025 5026 /** 5027 Function to interpret and print out the link control structure 5028 5029 @param[in] HeaderAddress The Address of this capability header. 5030 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5031 **/ 5032 EFI_STATUS 5033 EFIAPI 5034 PrintInterpretedExtendedCompatibilityLinkControl ( 5035 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5036 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5037 ) 5038 { 5039 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL *Header; 5040 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL*)HeaderAddress; 5041 5042 ShellPrintHiiEx( 5043 -1, -1, NULL, 5044 STRING_TOKEN (STR_PCI_EXT_CAP_LINK_CONTROL), 5045 gShellDebug1HiiHandle, 5046 Header->RootComplexLinkCapabilities, 5047 Header->RootComplexLinkControl, 5048 Header->RootComplexLinkStatus 5049 ); 5050 DumpHex ( 5051 4, 5052 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5053 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL), 5054 (VOID *) (HeaderAddress) 5055 ); 5056 return (EFI_SUCCESS); 5057 } 5058 5059 /** 5060 Function to interpret and print out the power budgeting structure 5061 5062 @param[in] HeaderAddress The Address of this capability header. 5063 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5064 **/ 5065 EFI_STATUS 5066 EFIAPI 5067 PrintInterpretedExtendedCompatibilityPowerBudgeting ( 5068 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5069 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5070 ) 5071 { 5072 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING *Header; 5073 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING*)HeaderAddress; 5074 5075 ShellPrintHiiEx( 5076 -1, -1, NULL, 5077 STRING_TOKEN (STR_PCI_EXT_CAP_POWER), 5078 gShellDebug1HiiHandle, 5079 Header->DataSelect, 5080 Header->Data, 5081 Header->PowerBudgetCapability 5082 ); 5083 DumpHex ( 5084 4, 5085 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5086 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING), 5087 (VOID *) (HeaderAddress) 5088 ); 5089 return (EFI_SUCCESS); 5090 } 5091 5092 /** 5093 Function to interpret and print out the ACS structure 5094 5095 @param[in] HeaderAddress The Address of this capability header. 5096 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5097 **/ 5098 EFI_STATUS 5099 EFIAPI 5100 PrintInterpretedExtendedCompatibilityAcs ( 5101 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5102 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5103 ) 5104 { 5105 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED *Header; 5106 UINT16 VectorSize; 5107 UINT16 LoopCounter; 5108 5109 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED*)HeaderAddress; 5110 VectorSize = 0; 5111 5112 ShellPrintHiiEx( 5113 -1, -1, NULL, 5114 STRING_TOKEN (STR_PCI_EXT_CAP_ACS), 5115 gShellDebug1HiiHandle, 5116 Header->AcsCapability, 5117 Header->AcsControl 5118 ); 5119 if (PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_CONTROL(Header)) { 5120 VectorSize = PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_VECTOR_SIZE(Header); 5121 if (VectorSize == 0) { 5122 VectorSize = 256; 5123 } 5124 for (LoopCounter = 0 ; LoopCounter * 8 < VectorSize ; LoopCounter++) { 5125 ShellPrintHiiEx( 5126 -1, -1, NULL, 5127 STRING_TOKEN (STR_PCI_EXT_CAP_ACS2), 5128 gShellDebug1HiiHandle, 5129 LoopCounter + 1, 5130 Header->EgressControlVectorArray[LoopCounter] 5131 ); 5132 } 5133 } 5134 DumpHex ( 5135 4, 5136 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5137 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED) + (VectorSize / 8) - 1, 5138 (VOID *) (HeaderAddress) 5139 ); 5140 return (EFI_SUCCESS); 5141 } 5142 5143 /** 5144 Function to interpret and print out the latency tolerance reporting structure 5145 5146 @param[in] HeaderAddress The Address of this capability header. 5147 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5148 **/ 5149 EFI_STATUS 5150 EFIAPI 5151 PrintInterpretedExtendedCompatibilityLatencyToleranceReporting ( 5152 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5153 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5154 ) 5155 { 5156 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING *Header; 5157 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING*)HeaderAddress; 5158 5159 ShellPrintHiiEx( 5160 -1, -1, NULL, 5161 STRING_TOKEN (STR_PCI_EXT_CAP_LAT), 5162 gShellDebug1HiiHandle, 5163 Header->MaxSnoopLatency, 5164 Header->MaxNoSnoopLatency 5165 ); 5166 DumpHex ( 5167 4, 5168 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5169 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING), 5170 (VOID *) (HeaderAddress) 5171 ); 5172 return (EFI_SUCCESS); 5173 } 5174 5175 /** 5176 Function to interpret and print out the serial number structure 5177 5178 @param[in] HeaderAddress The Address of this capability header. 5179 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5180 **/ 5181 EFI_STATUS 5182 EFIAPI 5183 PrintInterpretedExtendedCompatibilitySerialNumber ( 5184 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5185 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5186 ) 5187 { 5188 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER *Header; 5189 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER*)HeaderAddress; 5190 5191 ShellPrintHiiEx( 5192 -1, -1, NULL, 5193 STRING_TOKEN (STR_PCI_EXT_CAP_SN), 5194 gShellDebug1HiiHandle, 5195 Header->SerialNumber 5196 ); 5197 DumpHex ( 5198 4, 5199 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5200 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER), 5201 (VOID *) (HeaderAddress) 5202 ); 5203 return (EFI_SUCCESS); 5204 } 5205 5206 /** 5207 Function to interpret and print out the RCRB structure 5208 5209 @param[in] HeaderAddress The Address of this capability header. 5210 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5211 **/ 5212 EFI_STATUS 5213 EFIAPI 5214 PrintInterpretedExtendedCompatibilityRcrb ( 5215 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5216 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5217 ) 5218 { 5219 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER *Header; 5220 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER*)HeaderAddress; 5221 5222 ShellPrintHiiEx( 5223 -1, -1, NULL, 5224 STRING_TOKEN (STR_PCI_EXT_CAP_RCRB), 5225 gShellDebug1HiiHandle, 5226 Header->VendorId, 5227 Header->DeviceId, 5228 Header->RcrbCapabilities, 5229 Header->RcrbControl 5230 ); 5231 DumpHex ( 5232 4, 5233 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5234 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER), 5235 (VOID *) (HeaderAddress) 5236 ); 5237 return (EFI_SUCCESS); 5238 } 5239 5240 /** 5241 Function to interpret and print out the vendor specific structure 5242 5243 @param[in] HeaderAddress The Address of this capability header. 5244 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5245 **/ 5246 EFI_STATUS 5247 EFIAPI 5248 PrintInterpretedExtendedCompatibilityVendorSpecific ( 5249 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5250 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5251 ) 5252 { 5253 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VENDOR_SPECIFIC *Header; 5254 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_VENDOR_SPECIFIC*)HeaderAddress; 5255 5256 ShellPrintHiiEx( 5257 -1, -1, NULL, 5258 STRING_TOKEN (STR_PCI_EXT_CAP_VEN), 5259 gShellDebug1HiiHandle, 5260 Header->VendorSpecificHeader 5261 ); 5262 DumpHex ( 5263 4, 5264 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5265 PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_GET_SIZE(Header), 5266 (VOID *) (HeaderAddress) 5267 ); 5268 return (EFI_SUCCESS); 5269 } 5270 5271 /** 5272 Function to interpret and print out the Event Collector Endpoint Association structure 5273 5274 @param[in] HeaderAddress The Address of this capability header. 5275 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5276 **/ 5277 EFI_STATUS 5278 EFIAPI 5279 PrintInterpretedExtendedCompatibilityECEA ( 5280 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5281 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5282 ) 5283 { 5284 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION *Header; 5285 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION*)HeaderAddress; 5286 5287 ShellPrintHiiEx( 5288 -1, -1, NULL, 5289 STRING_TOKEN (STR_PCI_EXT_CAP_ECEA), 5290 gShellDebug1HiiHandle, 5291 Header->AssociationBitmap 5292 ); 5293 DumpHex ( 5294 4, 5295 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5296 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION), 5297 (VOID *) (HeaderAddress) 5298 ); 5299 return (EFI_SUCCESS); 5300 } 5301 5302 /** 5303 Function to interpret and print out the ARI structure 5304 5305 @param[in] HeaderAddress The Address of this capability header. 5306 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5307 **/ 5308 EFI_STATUS 5309 EFIAPI 5310 PrintInterpretedExtendedCompatibilityAri ( 5311 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5312 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5313 ) 5314 { 5315 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY *Header; 5316 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY*)HeaderAddress; 5317 5318 ShellPrintHiiEx( 5319 -1, -1, NULL, 5320 STRING_TOKEN (STR_PCI_EXT_CAP_ARI), 5321 gShellDebug1HiiHandle, 5322 Header->AriCapability, 5323 Header->AriControl 5324 ); 5325 DumpHex ( 5326 4, 5327 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5328 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY), 5329 (VOID *) (HeaderAddress) 5330 ); 5331 return (EFI_SUCCESS); 5332 } 5333 5334 /** 5335 Function to interpret and print out the DPA structure 5336 5337 @param[in] HeaderAddress The Address of this capability header. 5338 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5339 **/ 5340 EFI_STATUS 5341 EFIAPI 5342 PrintInterpretedExtendedCompatibilityDynamicPowerAllocation ( 5343 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5344 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5345 ) 5346 { 5347 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION *Header; 5348 UINT8 LinkCount; 5349 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION*)HeaderAddress; 5350 5351 ShellPrintHiiEx( 5352 -1, -1, NULL, 5353 STRING_TOKEN (STR_PCI_EXT_CAP_DPA), 5354 gShellDebug1HiiHandle, 5355 Header->DpaCapability, 5356 Header->DpaLatencyIndicator, 5357 Header->DpaStatus, 5358 Header->DpaControl 5359 ); 5360 for (LinkCount = 0 ; LinkCount < PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_GET_SUBSTATE_MAX(Header) + 1 ; LinkCount++) { 5361 ShellPrintHiiEx( 5362 -1, -1, NULL, 5363 STRING_TOKEN (STR_PCI_EXT_CAP_DPA2), 5364 gShellDebug1HiiHandle, 5365 LinkCount+1, 5366 Header->DpaPowerAllocationArray[LinkCount] 5367 ); 5368 } 5369 DumpHex ( 5370 4, 5371 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5372 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION) - 1 + PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_GET_SUBSTATE_MAX(Header), 5373 (VOID *) (HeaderAddress) 5374 ); 5375 return (EFI_SUCCESS); 5376 } 5377 5378 /** 5379 Function to interpret and print out the link declaration structure 5380 5381 @param[in] HeaderAddress The Address of this capability header. 5382 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5383 **/ 5384 EFI_STATUS 5385 EFIAPI 5386 PrintInterpretedExtendedCompatibilityLinkDeclaration ( 5387 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5388 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5389 ) 5390 { 5391 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION *Header; 5392 UINT8 LinkCount; 5393 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION*)HeaderAddress; 5394 5395 ShellPrintHiiEx( 5396 -1, -1, NULL, 5397 STRING_TOKEN (STR_PCI_EXT_CAP_LINK_DECLAR), 5398 gShellDebug1HiiHandle, 5399 Header->ElementSelfDescription 5400 ); 5401 5402 for (LinkCount = 0 ; LinkCount < PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_GET_LINK_COUNT(Header) ; LinkCount++) { 5403 ShellPrintHiiEx( 5404 -1, -1, NULL, 5405 STRING_TOKEN (STR_PCI_EXT_CAP_LINK_DECLAR2), 5406 gShellDebug1HiiHandle, 5407 LinkCount+1, 5408 Header->LinkEntry[LinkCount] 5409 ); 5410 } 5411 DumpHex ( 5412 4, 5413 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5414 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION) + (PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_GET_LINK_COUNT(Header)-1)*sizeof(UINT32), 5415 (VOID *) (HeaderAddress) 5416 ); 5417 return (EFI_SUCCESS); 5418 } 5419 5420 /** 5421 Function to interpret and print out the Advanced Error Reporting structure 5422 5423 @param[in] HeaderAddress The Address of this capability header. 5424 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5425 **/ 5426 EFI_STATUS 5427 EFIAPI 5428 PrintInterpretedExtendedCompatibilityAer ( 5429 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5430 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5431 ) 5432 { 5433 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING *Header; 5434 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING*)HeaderAddress; 5435 5436 ShellPrintHiiEx( 5437 -1, -1, NULL, 5438 STRING_TOKEN (STR_PCI_EXT_CAP_AER), 5439 gShellDebug1HiiHandle, 5440 Header->UncorrectableErrorStatus, 5441 Header->UncorrectableErrorMask, 5442 Header->UncorrectableErrorSeverity, 5443 Header->CorrectableErrorStatus, 5444 Header->CorrectableErrorMask, 5445 Header->AdvancedErrorCapabilitiesAndControl, 5446 Header->HeaderLog, 5447 Header->RootErrorCommand, 5448 Header->RootErrorStatus, 5449 Header->ErrorSourceIdentification, 5450 Header->CorrectableErrorSourceIdentification, 5451 Header->TlpPrefixLog[0], 5452 Header->TlpPrefixLog[1], 5453 Header->TlpPrefixLog[2], 5454 Header->TlpPrefixLog[3] 5455 ); 5456 DumpHex ( 5457 4, 5458 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5459 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING), 5460 (VOID *) (HeaderAddress) 5461 ); 5462 return (EFI_SUCCESS); 5463 } 5464 5465 /** 5466 Function to interpret and print out the multicast structure 5467 5468 @param[in] HeaderAddress The Address of this capability header. 5469 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5470 @param[in] PciExpressCapPtr The address of the PCIe capabilities structure. 5471 **/ 5472 EFI_STATUS 5473 EFIAPI 5474 PrintInterpretedExtendedCompatibilityMulticast ( 5475 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5476 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress, 5477 IN CONST PCIE_CAP_STRUCTURE *PciExpressCapPtr 5478 ) 5479 { 5480 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST *Header; 5481 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST*)HeaderAddress; 5482 5483 ShellPrintHiiEx( 5484 -1, -1, NULL, 5485 STRING_TOKEN (STR_PCI_EXT_CAP_MULTICAST), 5486 gShellDebug1HiiHandle, 5487 Header->MultiCastCapability, 5488 Header->MulticastControl, 5489 Header->McBaseAddress, 5490 Header->McReceiveAddress, 5491 Header->McBlockAll, 5492 Header->McBlockUntranslated, 5493 Header->McOverlayBar 5494 ); 5495 5496 DumpHex ( 5497 4, 5498 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5499 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST), 5500 (VOID *) (HeaderAddress) 5501 ); 5502 5503 return (EFI_SUCCESS); 5504 } 5505 5506 /** 5507 Function to interpret and print out the virtual channel and multi virtual channel structure 5508 5509 @param[in] HeaderAddress The Address of this capability header. 5510 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5511 **/ 5512 EFI_STATUS 5513 EFIAPI 5514 PrintInterpretedExtendedCompatibilityVirtualChannel ( 5515 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5516 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5517 ) 5518 { 5519 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY *Header; 5520 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC *CapabilityItem; 5521 UINT32 ItemCount; 5522 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY*)HeaderAddress; 5523 5524 ShellPrintHiiEx( 5525 -1, -1, NULL, 5526 STRING_TOKEN (STR_PCI_EXT_CAP_VC_BASE), 5527 gShellDebug1HiiHandle, 5528 Header->ExtendedVcCount, 5529 Header->PortVcCapability1, 5530 Header->PortVcCapability2, 5531 Header->VcArbTableOffset, 5532 Header->PortVcControl, 5533 Header->PortVcStatus 5534 ); 5535 for (ItemCount = 0 ; ItemCount < Header->ExtendedVcCount ; ItemCount++) { 5536 CapabilityItem = &Header->Capability[ItemCount]; 5537 ShellPrintHiiEx( 5538 -1, -1, NULL, 5539 STRING_TOKEN (STR_PCI_EXT_CAP_VC_ITEM), 5540 gShellDebug1HiiHandle, 5541 ItemCount+1, 5542 CapabilityItem->VcResourceCapability, 5543 CapabilityItem->PortArbTableOffset, 5544 CapabilityItem->VcResourceControl, 5545 CapabilityItem->VcResourceStatus 5546 ); 5547 } 5548 5549 DumpHex ( 5550 4, 5551 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5552 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC) + (Header->ExtendedVcCount - 1) * sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY), 5553 (VOID *) (HeaderAddress) 5554 ); 5555 5556 return (EFI_SUCCESS); 5557 } 5558 5559 /** 5560 Function to interpret and print out the resizeable bar structure 5561 5562 @param[in] HeaderAddress The Address of this capability header. 5563 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5564 **/ 5565 EFI_STATUS 5566 EFIAPI 5567 PrintInterpretedExtendedCompatibilityResizeableBar ( 5568 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5569 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5570 ) 5571 { 5572 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR *Header; 5573 UINT32 ItemCount; 5574 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR*)HeaderAddress; 5575 5576 for (ItemCount = 0 ; ItemCount < (UINT32)GET_NUMBER_RESIZABLE_BARS(Header) ; ItemCount++) { 5577 ShellPrintHiiEx( 5578 -1, -1, NULL, 5579 STRING_TOKEN (STR_PCI_EXT_CAP_RESIZE_BAR), 5580 gShellDebug1HiiHandle, 5581 ItemCount+1, 5582 Header->Capability[ItemCount].ResizableBarCapability, 5583 Header->Capability[ItemCount].ResizableBarControl 5584 ); 5585 } 5586 5587 DumpHex ( 5588 4, 5589 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5590 (UINT32)GET_NUMBER_RESIZABLE_BARS(Header) * sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY), 5591 (VOID *) (HeaderAddress) 5592 ); 5593 5594 return (EFI_SUCCESS); 5595 } 5596 5597 /** 5598 Function to interpret and print out the TPH structure 5599 5600 @param[in] HeaderAddress The Address of this capability header. 5601 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5602 **/ 5603 EFI_STATUS 5604 EFIAPI 5605 PrintInterpretedExtendedCompatibilityTph ( 5606 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5607 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress 5608 ) 5609 { 5610 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH *Header; 5611 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH*)HeaderAddress; 5612 5613 ShellPrintHiiEx( 5614 -1, -1, NULL, 5615 STRING_TOKEN (STR_PCI_EXT_CAP_TPH), 5616 gShellDebug1HiiHandle, 5617 Header->TphRequesterCapability, 5618 Header->TphRequesterControl 5619 ); 5620 DumpHex ( 5621 8, 5622 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)Header->TphStTable - (UINT8*)HeadersBaseAddress), 5623 GET_TPH_TABLE_SIZE(Header), 5624 (VOID *)Header->TphStTable 5625 ); 5626 5627 DumpHex ( 5628 4, 5629 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5630 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH) + GET_TPH_TABLE_SIZE(Header) - sizeof(UINT16), 5631 (VOID *) (HeaderAddress) 5632 ); 5633 5634 return (EFI_SUCCESS); 5635 } 5636 5637 /** 5638 Function to interpret and print out the secondary PCIe capability structure 5639 5640 @param[in] HeaderAddress The Address of this capability header. 5641 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5642 @param[in] PciExpressCapPtr The address of the PCIe capabilities structure. 5643 **/ 5644 EFI_STATUS 5645 EFIAPI 5646 PrintInterpretedExtendedCompatibilitySecondary ( 5647 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5648 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress, 5649 IN CONST PCIE_CAP_STRUCTURE *PciExpressCapPtr 5650 ) 5651 { 5652 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE *Header; 5653 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE*)HeaderAddress; 5654 5655 ShellPrintHiiEx( 5656 -1, -1, NULL, 5657 STRING_TOKEN (STR_PCI_EXT_CAP_SECONDARY), 5658 gShellDebug1HiiHandle, 5659 Header->LinkControl3, 5660 Header->LaneErrorStatus 5661 ); 5662 DumpHex ( 5663 8, 5664 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)Header->EqualizationControl - (UINT8*)HeadersBaseAddress), 5665 PCIE_CAP_MAX_LINK_WIDTH(PciExpressCapPtr->LinkCap), 5666 (VOID *)Header->EqualizationControl 5667 ); 5668 5669 DumpHex ( 5670 4, 5671 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), 5672 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH) - sizeof(Header->EqualizationControl) + PCIE_CAP_MAX_LINK_WIDTH(PciExpressCapPtr->LinkCap), 5673 (VOID *) (HeaderAddress) 5674 ); 5675 5676 return (EFI_SUCCESS); 5677 } 5678 5679 /** 5680 Display Pcie extended capability details 5681 5682 @param[in] HeadersBaseAddress The address of all the extended capability headers. 5683 @param[in] HeaderAddress The address of this capability header. 5684 @param[in] PciExpressCapPtr The address of the PCIe capabilities structure. 5685 **/ 5686 EFI_STATUS 5687 EFIAPI 5688 PrintPciExtendedCapabilityDetails( 5689 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress, 5690 IN CONST PCI_EXP_EXT_HDR *HeaderAddress, 5691 IN CONST PCIE_CAP_STRUCTURE *PciExpressCapPtr 5692 ) 5693 { 5694 switch (HeaderAddress->CapabilityId){ 5695 case PCI_EXPRESS_EXTENDED_CAPABILITY_ADVANCED_ERROR_REPORTING_ID: 5696 return PrintInterpretedExtendedCompatibilityAer(HeaderAddress, HeadersBaseAddress); 5697 case PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_CONTROL_ID: 5698 return PrintInterpretedExtendedCompatibilityLinkControl(HeaderAddress, HeadersBaseAddress); 5699 case PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_ID: 5700 return PrintInterpretedExtendedCompatibilityLinkDeclaration(HeaderAddress, HeadersBaseAddress); 5701 case PCI_EXPRESS_EXTENDED_CAPABILITY_SERIAL_NUMBER_ID: 5702 return PrintInterpretedExtendedCompatibilitySerialNumber(HeaderAddress, HeadersBaseAddress); 5703 case PCI_EXPRESS_EXTENDED_CAPABILITY_POWER_BUDGETING_ID: 5704 return PrintInterpretedExtendedCompatibilityPowerBudgeting(HeaderAddress, HeadersBaseAddress); 5705 case PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_ID: 5706 return PrintInterpretedExtendedCompatibilityAcs(HeaderAddress, HeadersBaseAddress); 5707 case PCI_EXPRESS_EXTENDED_CAPABILITY_LATENCE_TOLERANCE_REPORTING_ID: 5708 return PrintInterpretedExtendedCompatibilityLatencyToleranceReporting(HeaderAddress, HeadersBaseAddress); 5709 case PCI_EXPRESS_EXTENDED_CAPABILITY_ARI_CAPABILITY_ID: 5710 return PrintInterpretedExtendedCompatibilityAri(HeaderAddress, HeadersBaseAddress); 5711 case PCI_EXPRESS_EXTENDED_CAPABILITY_RCRB_HEADER_ID: 5712 return PrintInterpretedExtendedCompatibilityRcrb(HeaderAddress, HeadersBaseAddress); 5713 case PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID: 5714 return PrintInterpretedExtendedCompatibilityVendorSpecific(HeaderAddress, HeadersBaseAddress); 5715 case PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_ID: 5716 return PrintInterpretedExtendedCompatibilityDynamicPowerAllocation(HeaderAddress, HeadersBaseAddress); 5717 case PCI_EXPRESS_EXTENDED_CAPABILITY_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION_ID: 5718 return PrintInterpretedExtendedCompatibilityECEA(HeaderAddress, HeadersBaseAddress); 5719 case PCI_EXPRESS_EXTENDED_CAPABILITY_VIRTUAL_CHANNEL_ID: 5720 case PCI_EXPRESS_EXTENDED_CAPABILITY_MULTI_FUNCTION_VIRTUAL_CHANNEL_ID: 5721 return PrintInterpretedExtendedCompatibilityVirtualChannel(HeaderAddress, HeadersBaseAddress); 5722 case PCI_EXPRESS_EXTENDED_CAPABILITY_MULTICAST_ID: 5723 // 5724 // should only be present if PCIE_CAP_DEVICEPORT_TYPE(PciExpressCapPtr->PcieCapReg) == 0100b, 0101b, or 0110b 5725 // 5726 return PrintInterpretedExtendedCompatibilityMulticast(HeaderAddress, HeadersBaseAddress, PciExpressCapPtr); 5727 case PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID: 5728 return PrintInterpretedExtendedCompatibilityResizeableBar(HeaderAddress, HeadersBaseAddress); 5729 case PCI_EXPRESS_EXTENDED_CAPABILITY_TPH_ID: 5730 return PrintInterpretedExtendedCompatibilityTph(HeaderAddress, HeadersBaseAddress); 5731 case PCI_EXPRESS_EXTENDED_CAPABILITY_SECONDARY_PCIE_ID: 5732 return PrintInterpretedExtendedCompatibilitySecondary(HeaderAddress, HeadersBaseAddress, PciExpressCapPtr); 5733 default: 5734 ShellPrintEx (-1, -1, 5735 L"Unknown PCIe extended capability ID (%04xh). No interpretation available.\r\n", 5736 HeaderAddress->CapabilityId 5737 ); 5738 return EFI_SUCCESS; 5739 }; 5740 5741 } 5742 5743 /** 5744 Display Pcie device structure. 5745 5746 @param[in] IoDev The pointer to the root pci protocol. 5747 @param[in] Address The Address to start at. 5748 @param[in] CapabilityPtr The offset from the address to start. 5749 @param[in] EnhancedDump The print format for the dump data. 5750 5751 **/ 5752 EFI_STATUS 5753 PciExplainPciExpress ( 5754 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev, 5755 IN UINT64 Address, 5756 IN UINT8 CapabilityPtr, 5757 IN CONST UINT16 EnhancedDump 5758 ) 5759 { 5760 5761 PCIE_CAP_STRUCTURE PciExpressCap; 5762 EFI_STATUS Status; 5763 UINT64 CapRegAddress; 5764 UINT8 Bus; 5765 UINT8 Dev; 5766 UINT8 Func; 5767 UINT8 *ExRegBuffer; 5768 UINTN ExtendRegSize; 5769 UINT64 Pciex_Address; 5770 UINT8 DevicePortType; 5771 UINTN Index; 5772 UINT8 *RegAddr; 5773 UINTN RegValue; 5774 PCI_EXP_EXT_HDR *ExtHdr; 5775 5776 CapRegAddress = Address + CapabilityPtr; 5777 IoDev->Pci.Read ( 5778 IoDev, 5779 EfiPciWidthUint32, 5780 CapRegAddress, 5781 sizeof (PciExpressCap) / sizeof (UINT32), 5782 &PciExpressCap 5783 ); 5784 5785 DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap.PcieCapReg); 5786 5787 ShellPrintEx (-1, -1, L"\r\nPci Express device capability structure:\r\n"); 5788 5789 for (Index = 0; PcieExplainList[Index].Type < PcieExplainTypeMax; Index++) { 5790 if (ShellGetExecutionBreakFlag()) { 5791 goto Done; 5792 } 5793 RegAddr = ((UINT8 *) &PciExpressCap) + PcieExplainList[Index].Offset; 5794 switch (PcieExplainList[Index].Width) { 5795 case FieldWidthUINT8: 5796 RegValue = *(UINT8 *) RegAddr; 5797 break; 5798 case FieldWidthUINT16: 5799 RegValue = *(UINT16 *) RegAddr; 5800 break; 5801 case FieldWidthUINT32: 5802 RegValue = *(UINT32 *) RegAddr; 5803 break; 5804 default: 5805 RegValue = 0; 5806 break; 5807 } 5808 ShellPrintHiiEx(-1, -1, NULL, 5809 PcieExplainList[Index].Token, 5810 gShellDebug1HiiHandle, 5811 PcieExplainList[Index].Offset, 5812 RegValue 5813 ); 5814 if (PcieExplainList[Index].Func == NULL) { 5815 continue; 5816 } 5817 switch (PcieExplainList[Index].Type) { 5818 case PcieExplainTypeLink: 5819 // 5820 // Link registers should not be used by 5821 // a) Root Complex Integrated Endpoint 5822 // b) Root Complex Event Collector 5823 // 5824 if (DevicePortType == PCIE_ROOT_COMPLEX_INTEGRATED_PORT || 5825 DevicePortType == PCIE_ROOT_COMPLEX_EVENT_COLLECTOR) { 5826 continue; 5827 } 5828 break; 5829 case PcieExplainTypeSlot: 5830 // 5831 // Slot registers are only valid for 5832 // a) Root Port of PCI Express Root Complex 5833 // b) Downstream Port of PCI Express Switch 5834 // and when SlotImplemented bit is set in PCIE cap register. 5835 // 5836 if ((DevicePortType != PCIE_ROOT_COMPLEX_ROOT_PORT && 5837 DevicePortType != PCIE_SWITCH_DOWNSTREAM_PORT) || 5838 !PCIE_CAP_SLOT_IMPLEMENTED (PciExpressCap.PcieCapReg)) { 5839 continue; 5840 } 5841 break; 5842 case PcieExplainTypeRoot: 5843 // 5844 // Root registers are only valid for 5845 // Root Port of PCI Express Root Complex 5846 // 5847 if (DevicePortType != PCIE_ROOT_COMPLEX_ROOT_PORT) { 5848 continue; 5849 } 5850 break; 5851 default: 5852 break; 5853 } 5854 PcieExplainList[Index].Func (&PciExpressCap); 5855 } 5856 5857 Bus = (UINT8) (RShiftU64 (Address, 24)); 5858 Dev = (UINT8) (RShiftU64 (Address, 16)); 5859 Func = (UINT8) (RShiftU64 (Address, 8)); 5860 5861 Pciex_Address = CALC_EFI_PCIEX_ADDRESS (Bus, Dev, Func, EFI_PCIE_CAPABILITY_BASE_OFFSET); 5862 5863 ExtendRegSize = 0x1000 - EFI_PCIE_CAPABILITY_BASE_OFFSET; 5864 5865 ExRegBuffer = (UINT8 *) AllocateZeroPool (ExtendRegSize); 5866 5867 // 5868 // PciRootBridgeIo protocol should support pci express extend space IO 5869 // (Begins at offset EFI_PCIE_CAPABILITY_BASE_OFFSET) 5870 // 5871 Status = IoDev->Pci.Read ( 5872 IoDev, 5873 EfiPciWidthUint32, 5874 Pciex_Address, 5875 (ExtendRegSize) / sizeof (UINT32), 5876 (VOID *) (ExRegBuffer) 5877 ); 5878 if (EFI_ERROR (Status) || ExRegBuffer == NULL) { 5879 SHELL_FREE_NON_NULL(ExRegBuffer); 5880 return EFI_UNSUPPORTED; 5881 } 5882 5883 if (EnhancedDump == 0) { 5884 // 5885 // Print the PciEx extend space in raw bytes ( 0xFF-0xFFF) 5886 // 5887 ShellPrintEx (-1, -1, L"\r\n%HStart dumping PCIex extended configuration space (0x100 - 0xFFF).%N\r\n\r\n"); 5888 5889 DumpHex ( 5890 2, 5891 EFI_PCIE_CAPABILITY_BASE_OFFSET, 5892 ExtendRegSize, 5893 (VOID *) (ExRegBuffer) 5894 ); 5895 } else { 5896 ExtHdr = (PCI_EXP_EXT_HDR*)ExRegBuffer; 5897 while (ExtHdr->CapabilityId != 0 && ExtHdr->CapabilityVersion != 0) { 5898 // 5899 // Process this item 5900 // 5901 if (EnhancedDump == 0xFFFF || EnhancedDump == ExtHdr->CapabilityId) { 5902 // 5903 // Print this item 5904 // 5905 PrintPciExtendedCapabilityDetails((PCI_EXP_EXT_HDR*)ExRegBuffer, ExtHdr, &PciExpressCap); 5906 } 5907 5908 // 5909 // Advance to the next item if it exists 5910 // 5911 if (ExtHdr->NextCapabilityOffset != 0) { 5912 ExtHdr = (PCI_EXP_EXT_HDR*)((UINT8*)ExRegBuffer + ExtHdr->NextCapabilityOffset); 5913 } else { 5914 break; 5915 } 5916 } 5917 } 5918 SHELL_FREE_NON_NULL(ExRegBuffer); 5919 5920 Done: 5921 return EFI_SUCCESS; 5922 } 5923