Home | History | Annotate | Download | only in UefiShellDebug1CommandsLib
      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