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