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