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