]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c
37f15d6cdf175dec5faf2c86130458295252f734
[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 EnhancedDump = 0xFFFF;
2730 if (ShellCommandLineGetFlag(Package, L"-i")) {
2731 ExplainData = TRUE;
2732 }
2733
2734 Temp = ShellCommandLineGetValue(Package, L"-s");
2735 if (Temp != NULL) {
2736 //
2737 // Input converted to hexadecimal number.
2738 //
2739 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2740 Segment = (UINT16) RetVal;
2741 } else {
2742 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp);
2743 ShellStatus = SHELL_INVALID_PARAMETER;
2744 goto Done;
2745 }
2746 }
2747
2748 //
2749 // The first Argument(except "-i") is assumed to be Bus number, second
2750 // to be Device number, and third to be Func number.
2751 //
2752 Temp = ShellCommandLineGetRawValue(Package, 1);
2753 if (Temp != NULL) {
2754 //
2755 // Input converted to hexadecimal number.
2756 //
2757 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2758 Bus = (UINT16) RetVal;
2759 } else {
2760 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp);
2761 ShellStatus = SHELL_INVALID_PARAMETER;
2762 goto Done;
2763 }
2764
2765 if (Bus > PCI_MAX_BUS) {
2766 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp);
2767 ShellStatus = SHELL_INVALID_PARAMETER;
2768 goto Done;
2769 }
2770 }
2771 Temp = ShellCommandLineGetRawValue(Package, 2);
2772 if (Temp != NULL) {
2773 //
2774 // Input converted to hexadecimal number.
2775 //
2776 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2777 Device = (UINT16) RetVal;
2778 } else {
2779 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp);
2780 ShellStatus = SHELL_INVALID_PARAMETER;
2781 goto Done;
2782 }
2783
2784 if (Device > PCI_MAX_DEVICE){
2785 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp);
2786 ShellStatus = SHELL_INVALID_PARAMETER;
2787 goto Done;
2788 }
2789 }
2790
2791 Temp = ShellCommandLineGetRawValue(Package, 3);
2792 if (Temp != NULL) {
2793 //
2794 // Input converted to hexadecimal number.
2795 //
2796 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2797 Func = (UINT16) RetVal;
2798 } else {
2799 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp);
2800 ShellStatus = SHELL_INVALID_PARAMETER;
2801 goto Done;
2802 }
2803
2804 if (Func > PCI_MAX_FUNC){
2805 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp);
2806 ShellStatus = SHELL_INVALID_PARAMETER;
2807 goto Done;
2808 }
2809 }
2810
2811 Temp = ShellCommandLineGetValue (Package, L"-ec");
2812 if (Temp != NULL) {
2813 //
2814 // Input converted to hexadecimal number.
2815 //
2816 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2817 EnhancedDump = (UINT16) RetVal;
2818 } else {
2819 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp);
2820 ShellStatus = SHELL_INVALID_PARAMETER;
2821 goto Done;
2822 }
2823 }
2824
2825 //
2826 // Find the protocol interface who's in charge of current segment, and its
2827 // bus range covers the current bus
2828 //
2829 Status = PciFindProtocolInterface (
2830 HandleBuf,
2831 HandleCount,
2832 Segment,
2833 Bus,
2834 &IoDev
2835 );
2836
2837 if (EFI_ERROR (Status)) {
2838 ShellPrintHiiEx(
2839 -1, -1, NULL, STRING_TOKEN (STR_PCI_NO_FIND), gShellDebug1HiiHandle, L"pci",
2840 Segment,
2841 Bus
2842 );
2843 ShellStatus = SHELL_NOT_FOUND;
2844 goto Done;
2845 }
2846
2847 Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
2848 Status = IoDev->Pci.Read (
2849 IoDev,
2850 EfiPciWidthUint8,
2851 Address,
2852 sizeof (ConfigSpace),
2853 &ConfigSpace
2854 );
2855
2856 if (EFI_ERROR (Status)) {
2857 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_NO_CFG), gShellDebug1HiiHandle, L"pci");
2858 ShellStatus = SHELL_ACCESS_DENIED;
2859 goto Done;
2860 }
2861
2862 mConfigSpace = &ConfigSpace;
2863 ShellPrintHiiEx(
2864 -1,
2865 -1,
2866 NULL,
2867 STRING_TOKEN (STR_PCI_INFO),
2868 gShellDebug1HiiHandle,
2869 Segment,
2870 Bus,
2871 Device,
2872 Func,
2873 Segment,
2874 Bus,
2875 Device,
2876 Func
2877 );
2878
2879 //
2880 // Dump standard header of configuration space
2881 //
2882 SizeOfHeader = sizeof (ConfigSpace.Common) + sizeof (ConfigSpace.NonCommon);
2883
2884 DumpHex (2, 0, SizeOfHeader, &ConfigSpace);
2885 ShellPrintEx(-1,-1, L"\r\n");
2886
2887 //
2888 // Dump device dependent Part of configuration space
2889 //
2890 DumpHex (
2891 2,
2892 SizeOfHeader,
2893 sizeof (ConfigSpace) - SizeOfHeader,
2894 ConfigSpace.Data
2895 );
2896
2897 //
2898 // If "-i" appears in command line, interpret data in configuration space
2899 //
2900 if (ExplainData) {
2901 Status = PciExplainData (&ConfigSpace, Address, IoDev, EnhancedDump);
2902 }
2903 }
2904 Done:
2905 if (HandleBuf != NULL) {
2906 FreePool (HandleBuf);
2907 }
2908 if (Package != NULL) {
2909 ShellCommandLineFreeVarList (Package);
2910 }
2911 mConfigSpace = NULL;
2912 return ShellStatus;
2913 }
2914
2915 /**
2916 This function finds out the protocol which is in charge of the given
2917 segment, and its bus range covers the current bus number. It lookes
2918 each instances of RootBridgeIoProtocol handle, until the one meets the
2919 criteria is found.
2920
2921 @param[in] HandleBuf Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
2922 @param[in] HandleCount Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
2923 @param[in] Segment Segment number of device we are dealing with.
2924 @param[in] Bus Bus number of device we are dealing with.
2925 @param[out] IoDev Handle used to access configuration space of PCI device.
2926
2927 @retval EFI_SUCCESS The command completed successfully.
2928 @retval EFI_INVALID_PARAMETER Invalid parameter.
2929
2930 **/
2931 EFI_STATUS
2932 PciFindProtocolInterface (
2933 IN EFI_HANDLE *HandleBuf,
2934 IN UINTN HandleCount,
2935 IN UINT16 Segment,
2936 IN UINT16 Bus,
2937 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev
2938 )
2939 {
2940 UINTN Index;
2941 EFI_STATUS Status;
2942 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
2943 UINT16 MinBus;
2944 UINT16 MaxBus;
2945 BOOLEAN IsEnd;
2946
2947 //
2948 // Go through all handles, until the one meets the criteria is found
2949 //
2950 for (Index = 0; Index < HandleCount; Index++) {
2951 Status = PciGetProtocolAndResource (HandleBuf[Index], IoDev, &Descriptors);
2952 if (EFI_ERROR (Status)) {
2953 return Status;
2954 }
2955 //
2956 // When Descriptors == NULL, the Configuration() is not implemented,
2957 // so we only check the Segment number
2958 //
2959 if (Descriptors == NULL && Segment == (*IoDev)->SegmentNumber) {
2960 return EFI_SUCCESS;
2961 }
2962
2963 if ((*IoDev)->SegmentNumber != Segment) {
2964 continue;
2965 }
2966
2967 while (TRUE) {
2968 Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
2969 if (EFI_ERROR (Status)) {
2970 return Status;
2971 }
2972
2973 if (IsEnd) {
2974 break;
2975 }
2976
2977 if (MinBus <= Bus && MaxBus >= Bus) {
2978 return EFI_SUCCESS;
2979 }
2980 }
2981 }
2982
2983 return EFI_NOT_FOUND;
2984 }
2985
2986 /**
2987 This function gets the protocol interface from the given handle, and
2988 obtains its address space descriptors.
2989
2990 @param[in] Handle The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle.
2991 @param[out] IoDev Handle used to access configuration space of PCI device.
2992 @param[out] Descriptors Points to the address space descriptors.
2993
2994 @retval EFI_SUCCESS The command completed successfully
2995 **/
2996 EFI_STATUS
2997 PciGetProtocolAndResource (
2998 IN EFI_HANDLE Handle,
2999 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev,
3000 OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors
3001 )
3002 {
3003 EFI_STATUS Status;
3004
3005 //
3006 // Get inferface from protocol
3007 //
3008 Status = gBS->HandleProtocol (
3009 Handle,
3010 &gEfiPciRootBridgeIoProtocolGuid,
3011 (VOID**)IoDev
3012 );
3013
3014 if (EFI_ERROR (Status)) {
3015 return Status;
3016 }
3017 //
3018 // Call Configuration() to get address space descriptors
3019 //
3020 Status = (*IoDev)->Configuration (*IoDev, (VOID**)Descriptors);
3021 if (Status == EFI_UNSUPPORTED) {
3022 *Descriptors = NULL;
3023 return EFI_SUCCESS;
3024
3025 } else {
3026 return Status;
3027 }
3028 }
3029
3030 /**
3031 This function get the next bus range of given address space descriptors.
3032 It also moves the pointer backward a node, to get prepared to be called
3033 again.
3034
3035 @param[in, out] Descriptors Points to current position of a serial of address space
3036 descriptors.
3037 @param[out] MinBus The lower range of bus number.
3038 @param[out] MaxBus The upper range of bus number.
3039 @param[out] IsEnd Meet end of the serial of descriptors.
3040
3041 @retval EFI_SUCCESS The command completed successfully.
3042 **/
3043 EFI_STATUS
3044 PciGetNextBusRange (
3045 IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,
3046 OUT UINT16 *MinBus,
3047 OUT UINT16 *MaxBus,
3048 OUT BOOLEAN *IsEnd
3049 )
3050 {
3051 *IsEnd = FALSE;
3052
3053 //
3054 // When *Descriptors is NULL, Configuration() is not implemented, so assume
3055 // range is 0~PCI_MAX_BUS
3056 //
3057 if ((*Descriptors) == NULL) {
3058 *MinBus = 0;
3059 *MaxBus = PCI_MAX_BUS;
3060 return EFI_SUCCESS;
3061 }
3062 //
3063 // *Descriptors points to one or more address space descriptors, which
3064 // ends with a end tagged descriptor. Examine each of the descriptors,
3065 // if a bus typed one is found and its bus range covers bus, this handle
3066 // is the handle we are looking for.
3067 //
3068
3069 while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {
3070 if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
3071 *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;
3072 *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;
3073 (*Descriptors)++;
3074 return (EFI_SUCCESS);
3075 }
3076
3077 (*Descriptors)++;
3078 }
3079
3080 if ((*Descriptors)->Desc == ACPI_END_TAG_DESCRIPTOR) {
3081 *IsEnd = TRUE;
3082 }
3083
3084 return EFI_SUCCESS;
3085 }
3086
3087 /**
3088 Explain the data in PCI configuration space. The part which is common for
3089 PCI device and bridge is interpreted in this function. It calls other
3090 functions to interpret data unique for device or bridge.
3091
3092 @param[in] ConfigSpace Data in PCI configuration space.
3093 @param[in] Address Address used to access configuration space of this PCI device.
3094 @param[in] IoDev Handle used to access configuration space of PCI device.
3095 @param[in] EnhancedDump The print format for the dump data.
3096
3097 @retval EFI_SUCCESS The command completed successfully.
3098 **/
3099 EFI_STATUS
3100 PciExplainData (
3101 IN PCI_CONFIG_SPACE *ConfigSpace,
3102 IN UINT64 Address,
3103 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
3104 IN CONST UINT16 EnhancedDump
3105 )
3106 {
3107 PCI_DEVICE_INDEPENDENT_REGION *Common;
3108 PCI_HEADER_TYPE HeaderType;
3109 EFI_STATUS Status;
3110 UINT8 CapPtr;
3111
3112 Common = &(ConfigSpace->Common);
3113
3114 ShellPrintEx (-1, -1, L"\r\n");
3115
3116 //
3117 // Print Vendor Id and Device Id
3118 //
3119 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_VID_DID), gShellDebug1HiiHandle,
3120 INDEX_OF (&(Common->VendorId)),
3121 Common->VendorId,
3122 INDEX_OF (&(Common->DeviceId)),
3123 Common->DeviceId
3124 );
3125
3126 //
3127 // Print register Command
3128 //
3129 PciExplainCommand (&(Common->Command));
3130
3131 //
3132 // Print register Status
3133 //
3134 PciExplainStatus (&(Common->Status), TRUE, PciUndefined);
3135
3136 //
3137 // Print register Revision ID
3138 //
3139 ShellPrintEx(-1, -1, L"\r\n");
3140 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_RID), gShellDebug1HiiHandle,
3141 INDEX_OF (&(Common->RevisionID)),
3142 Common->RevisionID
3143 );
3144
3145 //
3146 // Print register BIST
3147 //
3148 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_BIST), gShellDebug1HiiHandle, INDEX_OF (&(Common->BIST)));
3149 if ((Common->BIST & BIT7) != 0) {
3150 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP), gShellDebug1HiiHandle, 0x0f & Common->BIST);
3151 } else {
3152 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP_NO), gShellDebug1HiiHandle);
3153 }
3154 //
3155 // Print register Cache Line Size
3156 //
3157 ShellPrintHiiEx(-1, -1, NULL,
3158 STRING_TOKEN (STR_PCI2_CACHE_LINE_SIZE),
3159 gShellDebug1HiiHandle,
3160 INDEX_OF (&(Common->CacheLineSize)),
3161 Common->CacheLineSize
3162 );
3163
3164 //
3165 // Print register Latency Timer
3166 //
3167 ShellPrintHiiEx(-1, -1, NULL,
3168 STRING_TOKEN (STR_PCI2_LATENCY_TIMER),
3169 gShellDebug1HiiHandle,
3170 INDEX_OF (&(Common->LatencyTimer)),
3171 Common->LatencyTimer
3172 );
3173
3174 //
3175 // Print register Header Type
3176 //
3177 ShellPrintHiiEx(-1, -1, NULL,
3178 STRING_TOKEN (STR_PCI2_HEADER_TYPE),
3179 gShellDebug1HiiHandle,
3180 INDEX_OF (&(Common->HeaderType)),
3181 Common->HeaderType
3182 );
3183
3184 if ((Common->HeaderType & BIT7) != 0) {
3185 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MULTI_FUNCTION), gShellDebug1HiiHandle);
3186
3187 } else {
3188 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SINGLE_FUNCTION), gShellDebug1HiiHandle);
3189 }
3190
3191 HeaderType = (PCI_HEADER_TYPE)(UINT8) (Common->HeaderType & 0x7f);
3192 switch (HeaderType) {
3193 case PciDevice:
3194 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_PCI_DEVICE), gShellDebug1HiiHandle);
3195 break;
3196
3197 case PciP2pBridge:
3198 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_P2P_BRIDGE), gShellDebug1HiiHandle);
3199 break;
3200
3201 case PciCardBusBridge:
3202 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_BRIDGE), gShellDebug1HiiHandle);
3203 break;
3204
3205 default:
3206 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED), gShellDebug1HiiHandle);
3207 HeaderType = PciUndefined;
3208 }
3209
3210 //
3211 // Print register Class Code
3212 //
3213 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CLASS), gShellDebug1HiiHandle);
3214 PciPrintClassCode ((UINT8 *) Common->ClassCode, TRUE);
3215 ShellPrintEx (-1, -1, L"\r\n");
3216
3217 if (ShellGetExecutionBreakFlag()) {
3218 return EFI_SUCCESS;
3219 }
3220
3221 //
3222 // Interpret remaining part of PCI configuration header depending on
3223 // HeaderType
3224 //
3225 CapPtr = 0;
3226 Status = EFI_SUCCESS;
3227 switch (HeaderType) {
3228 case PciDevice:
3229 Status = PciExplainDeviceData (
3230 &(ConfigSpace->NonCommon.Device),
3231 Address,
3232 IoDev
3233 );
3234 CapPtr = ConfigSpace->NonCommon.Device.CapabilityPtr;
3235 break;
3236
3237 case PciP2pBridge:
3238 Status = PciExplainBridgeData (
3239 &(ConfigSpace->NonCommon.Bridge),
3240 Address,
3241 IoDev
3242 );
3243 CapPtr = ConfigSpace->NonCommon.Bridge.CapabilityPtr;
3244 break;
3245
3246 case PciCardBusBridge:
3247 Status = PciExplainCardBusData (
3248 &(ConfigSpace->NonCommon.CardBus),
3249 Address,
3250 IoDev
3251 );
3252 CapPtr = ConfigSpace->NonCommon.CardBus.Cap_Ptr;
3253 break;
3254 case PciUndefined:
3255 default:
3256 break;
3257 }
3258 //
3259 // If Status bit4 is 1, dump or explain capability structure
3260 //
3261 if ((Common->Status) & EFI_PCI_STATUS_CAPABILITY) {
3262 PciExplainCapabilityStruct (IoDev, Address, CapPtr, EnhancedDump);
3263 }
3264
3265 return Status;
3266 }
3267
3268 /**
3269 Explain the device specific part of data in PCI configuration space.
3270
3271 @param[in] Device Data in PCI configuration space.
3272 @param[in] Address Address used to access configuration space of this PCI device.
3273 @param[in] IoDev Handle used to access configuration space of PCI device.
3274
3275 @retval EFI_SUCCESS The command completed successfully.
3276 **/
3277 EFI_STATUS
3278 PciExplainDeviceData (
3279 IN PCI_DEVICE_HEADER_TYPE_REGION *Device,
3280 IN UINT64 Address,
3281 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
3282 )
3283 {
3284 UINTN Index;
3285 BOOLEAN BarExist;
3286 EFI_STATUS Status;
3287 UINTN BarCount;
3288
3289 //
3290 // Print Base Address Registers(Bar). When Bar = 0, this Bar does not
3291 // exist. If these no Bar for this function, print "none", otherwise
3292 // list detail information about this Bar.
3293 //
3294 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDR), gShellDebug1HiiHandle, INDEX_OF (Device->Bar));
3295
3296 BarExist = FALSE;
3297 BarCount = sizeof (Device->Bar) / sizeof (Device->Bar[0]);
3298 for (Index = 0; Index < BarCount; Index++) {
3299 if (Device->Bar[Index] == 0) {
3300 continue;
3301 }
3302
3303 if (!BarExist) {
3304 BarExist = TRUE;
3305 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE), gShellDebug1HiiHandle);
3306 ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------");
3307 }
3308
3309 Status = PciExplainBar (
3310 &(Device->Bar[Index]),
3311 &(mConfigSpace->Common.Command),
3312 Address,
3313 IoDev,
3314 &Index
3315 );
3316
3317 if (EFI_ERROR (Status)) {
3318 break;
3319 }
3320 }
3321
3322 if (!BarExist) {
3323 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
3324
3325 } else {
3326 ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------");
3327 }
3328
3329 //
3330 // Print register Expansion ROM Base Address
3331 //
3332 if ((Device->ExpansionRomBar & BIT0) == 0) {
3333 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_EXPANSION_ROM_DISABLED), gShellDebug1HiiHandle, INDEX_OF (&(Device->ExpansionRomBar)));
3334
3335 } else {
3336 ShellPrintHiiEx(-1, -1, NULL,
3337 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE),
3338 gShellDebug1HiiHandle,
3339 INDEX_OF (&(Device->ExpansionRomBar)),
3340 Device->ExpansionRomBar
3341 );
3342 }
3343 //
3344 // Print register Cardbus CIS ptr
3345 //
3346 ShellPrintHiiEx(-1, -1, NULL,
3347 STRING_TOKEN (STR_PCI2_CARDBUS_CIS),
3348 gShellDebug1HiiHandle,
3349 INDEX_OF (&(Device->CISPtr)),
3350 Device->CISPtr
3351 );
3352
3353 //
3354 // Print register Sub-vendor ID and subsystem ID
3355 //
3356 ShellPrintHiiEx(-1, -1, NULL,
3357 STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID),
3358 gShellDebug1HiiHandle,
3359 INDEX_OF (&(Device->SubsystemVendorID)),
3360 Device->SubsystemVendorID
3361 );
3362
3363 ShellPrintHiiEx(-1, -1, NULL,
3364 STRING_TOKEN (STR_PCI2_SUBSYSTEM_ID),
3365 gShellDebug1HiiHandle,
3366 INDEX_OF (&(Device->SubsystemID)),
3367 Device->SubsystemID
3368 );
3369
3370 //
3371 // Print register Capabilities Ptr
3372 //
3373 ShellPrintHiiEx(-1, -1, NULL,
3374 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR),
3375 gShellDebug1HiiHandle,
3376 INDEX_OF (&(Device->CapabilityPtr)),
3377 Device->CapabilityPtr
3378 );
3379
3380 //
3381 // Print register Interrupt Line and interrupt pin
3382 //
3383 ShellPrintHiiEx(-1, -1, NULL,
3384 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE),
3385 gShellDebug1HiiHandle,
3386 INDEX_OF (&(Device->InterruptLine)),
3387 Device->InterruptLine
3388 );
3389
3390 ShellPrintHiiEx(-1, -1, NULL,
3391 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
3392 gShellDebug1HiiHandle,
3393 INDEX_OF (&(Device->InterruptPin)),
3394 Device->InterruptPin
3395 );
3396
3397 //
3398 // Print register Min_Gnt and Max_Lat
3399 //
3400 ShellPrintHiiEx(-1, -1, NULL,
3401 STRING_TOKEN (STR_PCI2_MIN_GNT),
3402 gShellDebug1HiiHandle,
3403 INDEX_OF (&(Device->MinGnt)),
3404 Device->MinGnt
3405 );
3406
3407 ShellPrintHiiEx(-1, -1, NULL,
3408 STRING_TOKEN (STR_PCI2_MAX_LAT),
3409 gShellDebug1HiiHandle,
3410 INDEX_OF (&(Device->MaxLat)),
3411 Device->MaxLat
3412 );
3413
3414 return EFI_SUCCESS;
3415 }
3416
3417 /**
3418 Explain the bridge specific part of data in PCI configuration space.
3419
3420 @param[in] Bridge Bridge specific data region in PCI configuration space.
3421 @param[in] Address Address used to access configuration space of this PCI device.
3422 @param[in] IoDev Handle used to access configuration space of PCI device.
3423
3424 @retval EFI_SUCCESS The command completed successfully.
3425 **/
3426 EFI_STATUS
3427 PciExplainBridgeData (
3428 IN PCI_BRIDGE_CONTROL_REGISTER *Bridge,
3429 IN UINT64 Address,
3430 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
3431 )
3432 {
3433 UINTN Index;
3434 BOOLEAN BarExist;
3435 UINTN BarCount;
3436 UINT32 IoAddress32;
3437 EFI_STATUS Status;
3438
3439 //
3440 // Print Base Address Registers. When Bar = 0, this Bar does not
3441 // exist. If these no Bar for this function, print "none", otherwise
3442 // list detail information about this Bar.
3443 //
3444 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDRESS), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->Bar)));
3445
3446 BarExist = FALSE;
3447 BarCount = sizeof (Bridge->Bar) / sizeof (Bridge->Bar[0]);
3448
3449 for (Index = 0; Index < BarCount; Index++) {
3450 if (Bridge->Bar[Index] == 0) {
3451 continue;
3452 }
3453
3454 if (!BarExist) {
3455 BarExist = TRUE;
3456 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE_2), gShellDebug1HiiHandle);
3457 ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------");
3458 }
3459
3460 Status = PciExplainBar (
3461 &(Bridge->Bar[Index]),
3462 &(mConfigSpace->Common.Command),
3463 Address,
3464 IoDev,
3465 &Index
3466 );
3467
3468 if (EFI_ERROR (Status)) {
3469 break;
3470 }
3471 }
3472
3473 if (!BarExist) {
3474 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
3475 } else {
3476 ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------");
3477 }
3478
3479 //
3480 // Expansion register ROM Base Address
3481 //
3482 if ((Bridge->ExpansionRomBAR & BIT0) == 0) {
3483 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO_EXPANSION_ROM), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->ExpansionRomBAR)));
3484
3485 } else {
3486 ShellPrintHiiEx(-1, -1, NULL,
3487 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE_2),
3488 gShellDebug1HiiHandle,
3489 INDEX_OF (&(Bridge->ExpansionRomBAR)),
3490 Bridge->ExpansionRomBAR
3491 );
3492 }
3493 //
3494 // Print Bus Numbers(Primary, Secondary, and Subordinate
3495 //
3496 ShellPrintHiiEx(-1, -1, NULL,
3497 STRING_TOKEN (STR_PCI2_BUS_NUMBERS),
3498 gShellDebug1HiiHandle,
3499 INDEX_OF (&(Bridge->PrimaryBus)),
3500 INDEX_OF (&(Bridge->SecondaryBus)),
3501 INDEX_OF (&(Bridge->SubordinateBus))
3502 );
3503
3504 ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n");
3505
3506 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->PrimaryBus);
3507 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SecondaryBus);
3508 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SubordinateBus);
3509
3510 //
3511 // Print register Secondary Latency Timer
3512 //
3513 ShellPrintHiiEx(-1, -1, NULL,
3514 STRING_TOKEN (STR_PCI2_SECONDARY_TIMER),
3515 gShellDebug1HiiHandle,
3516 INDEX_OF (&(Bridge->SecondaryLatencyTimer)),
3517 Bridge->SecondaryLatencyTimer
3518 );
3519
3520 //
3521 // Print register Secondary Status
3522 //
3523 PciExplainStatus (&(Bridge->SecondaryStatus), FALSE, PciP2pBridge);
3524
3525 //
3526 // Print I/O and memory ranges this bridge forwards. There are 3 resource
3527 // types: I/O, memory, and pre-fetchable memory. For each resource type,
3528 // base and limit address are listed.
3529 //
3530 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE), gShellDebug1HiiHandle);
3531 ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n");
3532
3533 //
3534 // IO Base & Limit
3535 //
3536 IoAddress32 = (Bridge->IoBaseUpper16 << 16 | Bridge->IoBase << 8);
3537 IoAddress32 &= 0xfffff000;
3538 ShellPrintHiiEx(-1, -1, NULL,
3539 STRING_TOKEN (STR_PCI2_TWO_VARS),
3540 gShellDebug1HiiHandle,
3541 INDEX_OF (&(Bridge->IoBase)),
3542 IoAddress32
3543 );
3544
3545 IoAddress32 = (Bridge->IoLimitUpper16 << 16 | Bridge->IoLimit << 8);
3546 IoAddress32 |= 0x00000fff;
3547 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR), gShellDebug1HiiHandle, IoAddress32);
3548
3549 //
3550 // Memory Base & Limit
3551 //
3552 ShellPrintHiiEx(-1, -1, NULL,
3553 STRING_TOKEN (STR_PCI2_MEMORY),
3554 gShellDebug1HiiHandle,
3555 INDEX_OF (&(Bridge->MemoryBase)),
3556 (Bridge->MemoryBase << 16) & 0xfff00000
3557 );
3558
3559 ShellPrintHiiEx(-1, -1, NULL,
3560 STRING_TOKEN (STR_PCI2_ONE_VAR),
3561 gShellDebug1HiiHandle,
3562 (Bridge->MemoryLimit << 16) | 0x000fffff
3563 );
3564
3565 //
3566 // Pre-fetch-able Memory Base & Limit
3567 //
3568 ShellPrintHiiEx(-1, -1, NULL,
3569 STRING_TOKEN (STR_PCI2_PREFETCHABLE),
3570 gShellDebug1HiiHandle,
3571 INDEX_OF (&(Bridge->PrefetchableMemoryBase)),
3572 Bridge->PrefetchableBaseUpper32,
3573 (Bridge->PrefetchableMemoryBase << 16) & 0xfff00000
3574 );
3575
3576 ShellPrintHiiEx(-1, -1, NULL,
3577 STRING_TOKEN (STR_PCI2_TWO_VARS_2),
3578 gShellDebug1HiiHandle,
3579 Bridge->PrefetchableLimitUpper32,
3580 (Bridge->PrefetchableMemoryLimit << 16) | 0x000fffff
3581 );
3582
3583 //
3584 // Print register Capabilities Pointer
3585 //
3586 ShellPrintHiiEx(-1, -1, NULL,
3587 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR_2),
3588 gShellDebug1HiiHandle,
3589 INDEX_OF (&(Bridge->CapabilityPtr)),
3590 Bridge->CapabilityPtr
3591 );
3592
3593 //
3594 // Print register Bridge Control
3595 //
3596 PciExplainBridgeControl (&(Bridge->BridgeControl), PciP2pBridge);
3597
3598 //
3599 // Print register Interrupt Line & PIN
3600 //
3601 ShellPrintHiiEx(-1, -1, NULL,
3602 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_2),
3603 gShellDebug1HiiHandle,
3604 INDEX_OF (&(Bridge->InterruptLine)),
3605 Bridge->InterruptLine
3606 );
3607
3608 ShellPrintHiiEx(-1, -1, NULL,
3609 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
3610 gShellDebug1HiiHandle,
3611 INDEX_OF (&(Bridge->InterruptPin)),
3612 Bridge->InterruptPin
3613 );
3614
3615 return EFI_SUCCESS;
3616 }
3617
3618 /**
3619 Explain the Base Address Register(Bar) in PCI configuration space.
3620
3621 @param[in] Bar Points to the Base Address Register intended to interpret.
3622 @param[in] Command Points to the register Command.
3623 @param[in] Address Address used to access configuration space of this PCI device.
3624 @param[in] IoDev Handle used to access configuration space of PCI device.
3625 @param[in, out] Index The Index.
3626
3627 @retval EFI_SUCCESS The command completed successfully.
3628 **/
3629 EFI_STATUS
3630 PciExplainBar (
3631 IN UINT32 *Bar,
3632 IN UINT16 *Command,
3633 IN UINT64 Address,
3634 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
3635 IN OUT UINTN *Index
3636 )
3637 {
3638 UINT16 OldCommand;
3639 UINT16 NewCommand;
3640 UINT64 Bar64;
3641 UINT32 OldBar32;
3642 UINT32 NewBar32;
3643 UINT64 OldBar64;
3644 UINT64 NewBar64;
3645 BOOLEAN IsMem;
3646 BOOLEAN IsBar32;
3647 UINT64 RegAddress;
3648
3649 IsBar32 = TRUE;
3650 Bar64 = 0;
3651 NewBar32 = 0;
3652 NewBar64 = 0;
3653
3654 //
3655 // According the bar type, list detail about this bar, for example: 32 or
3656 // 64 bits; pre-fetchable or not.
3657 //
3658 if ((*Bar & BIT0) == 0) {
3659 //
3660 // This bar is of memory type
3661 //
3662 IsMem = TRUE;
3663
3664 if ((*Bar & BIT1) == 0 && (*Bar & BIT2) == 0) {
3665 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
3666 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
3667 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_32_BITS), gShellDebug1HiiHandle);
3668
3669 } else if ((*Bar & BIT1) == 0 && (*Bar & BIT2) != 0) {
3670 Bar64 = 0x0;
3671 CopyMem (&Bar64, Bar, sizeof (UINT64));
3672 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_2), gShellDebug1HiiHandle, (UINT32) RShiftU64 ((Bar64 & 0xfffffffffffffff0ULL), 32));
3673 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_3), gShellDebug1HiiHandle, (UINT32) (Bar64 & 0xfffffffffffffff0ULL));
3674 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
3675 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_64_BITS), gShellDebug1HiiHandle);
3676 IsBar32 = FALSE;
3677 *Index += 1;
3678
3679 } else {
3680 //
3681 // Reserved
3682 //
3683 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
3684 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM_2), gShellDebug1HiiHandle);
3685 }
3686
3687 if ((*Bar & BIT3) == 0) {
3688 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO), gShellDebug1HiiHandle);
3689
3690 } else {
3691 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_YES), gShellDebug1HiiHandle);
3692 }
3693
3694 } else {
3695 //
3696 // This bar is of io type
3697 //
3698 IsMem = FALSE;
3699 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_4), gShellDebug1HiiHandle, *Bar & 0xfffffffc);
3700 ShellPrintEx (-1, -1, L"I/O ");
3701 }
3702
3703 //
3704 // Get BAR length(or the amount of resource this bar demands for). To get
3705 // Bar length, first we should temporarily disable I/O and memory access
3706 // of this function(by set bits in the register Command), then write all
3707 // "1"s to this bar. The bar value read back is the amount of resource
3708 // this bar demands for.
3709 //
3710 //
3711 // Disable io & mem access
3712 //
3713 OldCommand = *Command;
3714 NewCommand = (UINT16) (OldCommand & 0xfffc);
3715 RegAddress = Address | INDEX_OF (Command);
3716 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &NewCommand);
3717
3718 RegAddress = Address | INDEX_OF (Bar);
3719
3720 //
3721 // Read after write the BAR to get the size
3722 //
3723 if (IsBar32) {
3724 OldBar32 = *Bar;
3725 NewBar32 = 0xffffffff;
3726
3727 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
3728 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
3729 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &OldBar32);
3730
3731 if (IsMem) {
3732 NewBar32 = NewBar32 & 0xfffffff0;
3733 NewBar32 = (~NewBar32) + 1;
3734
3735 } else {
3736 NewBar32 = NewBar32 & 0xfffffffc;
3737 NewBar32 = (~NewBar32) + 1;
3738 NewBar32 = NewBar32 & 0x0000ffff;
3739 }
3740 } else {
3741
3742 OldBar64 = 0x0;
3743 CopyMem (&OldBar64, Bar, sizeof (UINT64));
3744 NewBar64 = 0xffffffffffffffffULL;
3745
3746 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
3747 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
3748 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &OldBar64);
3749
3750 if (IsMem) {
3751 NewBar64 = NewBar64 & 0xfffffffffffffff0ULL;
3752 NewBar64 = (~NewBar64) + 1;
3753
3754 } else {
3755 NewBar64 = NewBar64 & 0xfffffffffffffffcULL;
3756 NewBar64 = (~NewBar64) + 1;
3757 NewBar64 = NewBar64 & 0x000000000000ffff;
3758 }
3759 }
3760 //
3761 // Enable io & mem access
3762 //
3763 RegAddress = Address | INDEX_OF (Command);
3764 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &OldCommand);
3765
3766 if (IsMem) {
3767 if (IsBar32) {
3768 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32), gShellDebug1HiiHandle, NewBar32);
3769 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_2), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffff0) - 1);
3770
3771 } else {
3772 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) RShiftU64 (NewBar64, 32));
3773 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) NewBar64);
3774 ShellPrintEx (-1, -1, L" ");
3775 ShellPrintHiiEx(-1, -1, NULL,
3776 STRING_TOKEN (STR_PCI2_RSHIFT),
3777 gShellDebug1HiiHandle,
3778 (UINT32) RShiftU64 ((NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1), 32)
3779 );
3780 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) (NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1));
3781
3782 }
3783 } else {
3784 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_3), gShellDebug1HiiHandle, NewBar32);
3785 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_4), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffffc) - 1);
3786 }
3787
3788 return EFI_SUCCESS;
3789 }
3790
3791 /**
3792 Explain the cardbus specific part of data in PCI configuration space.
3793
3794 @param[in] CardBus CardBus specific region of PCI configuration space.
3795 @param[in] Address Address used to access configuration space of this PCI device.
3796 @param[in] IoDev Handle used to access configuration space of PCI device.
3797
3798 @retval EFI_SUCCESS The command completed successfully.
3799 **/
3800 EFI_STATUS
3801 PciExplainCardBusData (
3802 IN PCI_CARDBUS_CONTROL_REGISTER *CardBus,
3803 IN UINT64 Address,
3804 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
3805 )
3806 {
3807 BOOLEAN Io32Bit;
3808 PCI_CARDBUS_DATA *CardBusData;
3809
3810 ShellPrintHiiEx(-1, -1, NULL,
3811 STRING_TOKEN (STR_PCI2_CARDBUS_SOCKET),
3812 gShellDebug1HiiHandle,
3813 INDEX_OF (&(CardBus->CardBusSocketReg)),
3814 CardBus->CardBusSocketReg
3815 );
3816
3817 //
3818 // Print Secondary Status
3819 //
3820 PciExplainStatus (&(CardBus->SecondaryStatus), FALSE, PciCardBusBridge);
3821
3822 //
3823 // Print Bus Numbers(Primary bus number, CardBus bus number, and
3824 // Subordinate bus number
3825 //
3826 ShellPrintHiiEx(-1, -1, NULL,
3827 STRING_TOKEN (STR_PCI2_BUS_NUMBERS_2),
3828 gShellDebug1HiiHandle,
3829 INDEX_OF (&(CardBus->PciBusNumber)),
3830 INDEX_OF (&(CardBus->CardBusBusNumber)),
3831 INDEX_OF (&(CardBus->SubordinateBusNumber))
3832 );
3833
3834 ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n");
3835
3836 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS), gShellDebug1HiiHandle, CardBus->PciBusNumber);
3837 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_2), gShellDebug1HiiHandle, CardBus->CardBusBusNumber);
3838 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_3), gShellDebug1HiiHandle, CardBus->SubordinateBusNumber);
3839
3840 //
3841 // Print CardBus Latency Timer
3842 //
3843 ShellPrintHiiEx(-1, -1, NULL,
3844 STRING_TOKEN (STR_PCI2_CARDBUS_LATENCY),
3845 gShellDebug1HiiHandle,
3846 INDEX_OF (&(CardBus->CardBusLatencyTimer)),
3847 CardBus->CardBusLatencyTimer
3848 );
3849
3850 //
3851 // Print Memory/Io ranges this cardbus bridge forwards
3852 //
3853 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE_2), gShellDebug1HiiHandle);
3854 ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n");
3855
3856 ShellPrintHiiEx(-1, -1, NULL,
3857 STRING_TOKEN (STR_PCI2_MEM_3),
3858 gShellDebug1HiiHandle,
3859 INDEX_OF (&(CardBus->MemoryBase0)),
3860 CardBus->BridgeControl & BIT8 ? L" Prefetchable" : L"Non-Prefetchable",
3861 CardBus->MemoryBase0 & 0xfffff000,
3862 CardBus->MemoryLimit0 | 0x00000fff
3863 );
3864
3865 ShellPrintHiiEx(-1, -1, NULL,
3866 STRING_TOKEN (STR_PCI2_MEM_3),
3867 gShellDebug1HiiHandle,
3868 INDEX_OF (&(CardBus->MemoryBase1)),
3869 CardBus->BridgeControl & BIT9 ? L" Prefetchable" : L"Non-Prefetchable",
3870 CardBus->MemoryBase1 & 0xfffff000,
3871 CardBus->MemoryLimit1 | 0x00000fff
3872 );
3873
3874 Io32Bit = (BOOLEAN) (CardBus->IoBase0 & BIT0);
3875 ShellPrintHiiEx(-1, -1, NULL,
3876 STRING_TOKEN (STR_PCI2_IO_2),
3877 gShellDebug1HiiHandle,
3878 INDEX_OF (&(CardBus->IoBase0)),
3879 Io32Bit ? L" 32 bit" : L" 16 bit",
3880 CardBus->IoBase0 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
3881 (CardBus->IoLimit0 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003
3882 );
3883
3884 Io32Bit = (BOOLEAN) (CardBus->IoBase1 & BIT0);
3885 ShellPrintHiiEx(-1, -1, NULL,
3886 STRING_TOKEN (STR_PCI2_IO_2),
3887 gShellDebug1HiiHandle,
3888 INDEX_OF (&(CardBus->IoBase1)),
3889 Io32Bit ? L" 32 bit" : L" 16 bit",
3890 CardBus->IoBase1 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
3891 (CardBus->IoLimit1 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003
3892 );
3893
3894 //
3895 // Print register Interrupt Line & PIN
3896 //
3897 ShellPrintHiiEx(-1, -1, NULL,
3898 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_3),
3899 gShellDebug1HiiHandle,
3900 INDEX_OF (&(CardBus->InterruptLine)),
3901 CardBus->InterruptLine,
3902 INDEX_OF (&(CardBus->InterruptPin)),
3903 CardBus->InterruptPin
3904 );
3905
3906 //
3907 // Print register Bridge Control
3908 //
3909 PciExplainBridgeControl (&(CardBus->BridgeControl), PciCardBusBridge);
3910
3911 //
3912 // Print some registers in data region of PCI configuration space for cardbus
3913 // bridge. Fields include: Sub VendorId, Subsystem ID, and Legacy Mode Base
3914 // Address.
3915 //
3916 CardBusData = (PCI_CARDBUS_DATA *) ((UINT8 *) CardBus + sizeof (PCI_CARDBUS_CONTROL_REGISTER));
3917
3918 ShellPrintHiiEx(-1, -1, NULL,
3919 STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID_2),
3920 gShellDebug1HiiHandle,
3921 INDEX_OF (&(CardBusData->SubVendorId)),
3922 CardBusData->SubVendorId,
3923 INDEX_OF (&(CardBusData->SubSystemId)),
3924 CardBusData->SubSystemId
3925 );
3926
3927 ShellPrintHiiEx(-1, -1, NULL,
3928 STRING_TOKEN (STR_PCI2_OPTIONAL),
3929 gShellDebug1HiiHandle,
3930 INDEX_OF (&(CardBusData->LegacyBase)),
3931 CardBusData->LegacyBase
3932 );
3933
3934 return EFI_SUCCESS;
3935 }
3936
3937 /**
3938 Explain each meaningful bit of register Status. The definition of Status is
3939 slightly different depending on the PCI header type.
3940
3941 @param[in] Status Points to the content of register Status.
3942 @param[in] MainStatus Indicates if this register is main status(not secondary
3943 status).
3944 @param[in] HeaderType Header type of this PCI device.
3945
3946 @retval EFI_SUCCESS The command completed successfully.
3947 **/
3948 EFI_STATUS
3949 PciExplainStatus (
3950 IN UINT16 *Status,
3951 IN BOOLEAN MainStatus,
3952 IN PCI_HEADER_TYPE HeaderType
3953 )
3954 {
3955 if (MainStatus) {
3956 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status);
3957
3958 } else {
3959 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SECONDARY_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status);
3960 }
3961
3962 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEW_CAPABILITIES), gShellDebug1HiiHandle, (*Status & BIT4) != 0);
3963
3964 //
3965 // Bit 5 is meaningless for CardBus Bridge
3966 //
3967 if (HeaderType == PciCardBusBridge) {
3968 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE), gShellDebug1HiiHandle, (*Status & BIT5) != 0);
3969
3970 } else {
3971 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE_2), gShellDebug1HiiHandle, (*Status & BIT5) != 0);
3972 }
3973
3974 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST_BACK), gShellDebug1HiiHandle, (*Status & BIT7) != 0);
3975
3976 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MASTER_DATA), gShellDebug1HiiHandle, (*Status & BIT8) != 0);
3977 //
3978 // Bit 9 and bit 10 together decides the DEVSEL timing
3979 //
3980 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_DEVSEL_TIMING), gShellDebug1HiiHandle);
3981 if ((*Status & BIT9) == 0 && (*Status & BIT10) == 0) {
3982 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST), gShellDebug1HiiHandle);
3983
3984 } else if ((*Status & BIT9) != 0 && (*Status & BIT10) == 0) {
3985 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEDIUM), gShellDebug1HiiHandle);
3986
3987 } else if ((*Status & BIT9) == 0 && (*Status & BIT10) != 0) {
3988 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SLOW), gShellDebug1HiiHandle);
3989
3990 } else {
3991 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED_2), gShellDebug1HiiHandle);
3992 }
3993
3994 ShellPrintHiiEx(-1, -1, NULL,
3995 STRING_TOKEN (STR_PCI2_SIGNALED_TARGET),
3996 gShellDebug1HiiHandle,
3997 (*Status & BIT11) != 0
3998 );
3999
4000 ShellPrintHiiEx(-1, -1, NULL,
4001 STRING_TOKEN (STR_PCI2_RECEIVED_TARGET),
4002 gShellDebug1HiiHandle,
4003 (*Status & BIT12) != 0
4004 );
4005
4006 ShellPrintHiiEx(-1, -1, NULL,
4007 STRING_TOKEN (STR_PCI2_RECEIVED_MASTER),
4008 gShellDebug1HiiHandle,
4009 (*Status & BIT13) != 0
4010 );
4011
4012 if (MainStatus) {
4013 ShellPrintHiiEx(-1, -1, NULL,
4014 STRING_TOKEN (STR_PCI2_SIGNALED_ERROR),
4015 gShellDebug1HiiHandle,
4016 (*Status & BIT14) != 0
4017 );
4018
4019 } else {
4020 ShellPrintHiiEx(-1, -1, NULL,
4021 STRING_TOKEN (STR_PCI2_RECEIVED_ERROR),
4022 gShellDebug1HiiHandle,
4023 (*Status & BIT14) != 0
4024 );
4025 }
4026
4027 ShellPrintHiiEx(-1, -1, NULL,
4028 STRING_TOKEN (STR_PCI2_DETECTED_ERROR),
4029 gShellDebug1HiiHandle,
4030 (*Status & BIT15) != 0
4031 );
4032
4033 return EFI_SUCCESS;
4034 }
4035
4036 /**
4037 Explain each meaningful bit of register Command.
4038
4039 @param[in] Command Points to the content of register Command.
4040
4041 @retval EFI_SUCCESS The command completed successfully.
4042 **/
4043 EFI_STATUS
4044 PciExplainCommand (
4045 IN UINT16 *Command
4046 )
4047 {
4048 //
4049 // Print the binary value of register Command
4050 //
4051 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_COMMAND), gShellDebug1HiiHandle, INDEX_OF (Command), *Command);
4052
4053 //
4054 // Explain register Command bit by bit
4055 //
4056 ShellPrintHiiEx(-1, -1, NULL,
4057 STRING_TOKEN (STR_PCI2_SPACE_ACCESS_DENIED),
4058 gShellDebug1HiiHandle,
4059 (*Command & BIT0) != 0
4060 );
4061
4062 ShellPrintHiiEx(-1, -1, NULL,
4063 STRING_TOKEN (STR_PCI2_MEMORY_SPACE),
4064 gShellDebug1HiiHandle,
4065 (*Command & BIT1) != 0
4066 );
4067
4068 ShellPrintHiiEx(-1, -1, NULL,
4069 STRING_TOKEN (STR_PCI2_BEHAVE_BUS_MASTER),
4070 gShellDebug1HiiHandle,
4071 (*Command & BIT2) != 0
4072 );
4073
4074 ShellPrintHiiEx(-1, -1, NULL,
4075 STRING_TOKEN (STR_PCI2_MONITOR_SPECIAL_CYCLE),
4076 gShellDebug1HiiHandle,
4077 (*Command & BIT3) != 0
4078 );
4079
4080 ShellPrintHiiEx(-1, -1, NULL,
4081 STRING_TOKEN (STR_PCI2_MEM_WRITE_INVALIDATE),
4082 gShellDebug1HiiHandle,
4083 (*Command & BIT4) != 0
4084 );
4085
4086 ShellPrintHiiEx(-1, -1, NULL,
4087 STRING_TOKEN (STR_PCI2_PALETTE_SNOOPING),
4088 gShellDebug1HiiHandle,
4089 (*Command & BIT5) != 0
4090 );
4091
4092 ShellPrintHiiEx(-1, -1, NULL,
4093 STRING_TOKEN (STR_PCI2_ASSERT_PERR),
4094 gShellDebug1HiiHandle,
4095 (*Command & BIT6) != 0
4096 );
4097
4098 ShellPrintHiiEx(-1, -1, NULL,
4099 STRING_TOKEN (STR_PCI2_DO_ADDR_STEPPING),
4100 gShellDebug1HiiHandle,
4101 (*Command & BIT7) != 0
4102 );
4103
4104 ShellPrintHiiEx(-1, -1, NULL,
4105 STRING_TOKEN (STR_PCI2_SERR_DRIVER),
4106 gShellDebug1HiiHandle,
4107 (*Command & BIT8) != 0
4108 );
4109
4110 ShellPrintHiiEx(-1, -1, NULL,
4111 STRING_TOKEN (STR_PCI2_FAST_BACK_2),
4112 gShellDebug1HiiHandle,
4113 (*Command & BIT9) != 0
4114 );
4115
4116 return EFI_SUCCESS;
4117 }
4118
4119 /**
4120 Explain each meaningful bit of register Bridge Control.
4121
4122 @param[in] BridgeControl Points to the content of register Bridge Control.
4123 @param[in] HeaderType The headertype.
4124
4125 @retval EFI_SUCCESS The command completed successfully.
4126 **/
4127 EFI_STATUS
4128 PciExplainBridgeControl (
4129 IN UINT16 *BridgeControl,
4130 IN PCI_HEADER_TYPE HeaderType
4131 )
4132 {
4133 ShellPrintHiiEx(-1, -1, NULL,
4134 STRING_TOKEN (STR_PCI2_BRIDGE_CONTROL),
4135 gShellDebug1HiiHandle,
4136 INDEX_OF (BridgeControl),
4137 *BridgeControl
4138 );
4139
4140 ShellPrintHiiEx(-1, -1, NULL,
4141 STRING_TOKEN (STR_PCI2_PARITY_ERROR),
4142 gShellDebug1HiiHandle,
4143 (*BridgeControl & BIT0) != 0
4144 );
4145 ShellPrintHiiEx(-1, -1, NULL,
4146 STRING_TOKEN (STR_PCI2_SERR_ENABLE),
4147 gShellDebug1HiiHandle,
4148 (*BridgeControl & BIT1) != 0
4149 );
4150 ShellPrintHiiEx(-1, -1, NULL,
4151 STRING_TOKEN (STR_PCI2_ISA_ENABLE),
4152 gShellDebug1HiiHandle,
4153 (*BridgeControl & BIT2) != 0
4154 );
4155 ShellPrintHiiEx(-1, -1, NULL,
4156 STRING_TOKEN (STR_PCI2_VGA_ENABLE),
4157 gShellDebug1HiiHandle,
4158 (*BridgeControl & BIT3) != 0
4159 );
4160 ShellPrintHiiEx(-1, -1, NULL,
4161 STRING_TOKEN (STR_PCI2_MASTER_ABORT),
4162 gShellDebug1HiiHandle,
4163 (*BridgeControl & BIT5) != 0
4164 );
4165
4166 //
4167 // Register Bridge Control has some slight differences between P2P bridge
4168 // and Cardbus bridge from bit 6 to bit 11.
4169 //
4170 if (HeaderType == PciP2pBridge) {
4171 ShellPrintHiiEx(-1, -1, NULL,
4172 STRING_TOKEN (STR_PCI2_SECONDARY_BUS_RESET),
4173 gShellDebug1HiiHandle,
4174 (*BridgeControl & BIT6) != 0
4175 );
4176 ShellPrintHiiEx(-1, -1, NULL,
4177 STRING_TOKEN (STR_PCI2_FAST_ENABLE),
4178 gShellDebug1HiiHandle,
4179 (*BridgeControl & BIT7) != 0
4180 );
4181 ShellPrintHiiEx(-1, -1, NULL,
4182 STRING_TOKEN (STR_PCI2_PRIMARY_DISCARD_TIMER),
4183 gShellDebug1HiiHandle,
4184 (*BridgeControl & BIT8)!=0 ? L"2^10" : L"2^15"
4185 );
4186 ShellPrintHiiEx(-1, -1, NULL,
4187 STRING_TOKEN (STR_PCI2_SECONDARY_DISCARD_TIMER),
4188 gShellDebug1HiiHandle,
4189 (*BridgeControl & BIT9)!=0 ? L"2^10" : L"2^15"
4190 );
4191 ShellPrintHiiEx(-1, -1, NULL,
4192 STRING_TOKEN (STR_PCI2_DISCARD_TIMER_STATUS),
4193 gShellDebug1HiiHandle,
4194 (*BridgeControl & BIT10) != 0
4195 );
4196 ShellPrintHiiEx(-1, -1, NULL,
4197 STRING_TOKEN (STR_PCI2_DISCARD_TIMER_SERR),
4198 gShellDebug1HiiHandle,
4199 (*BridgeControl & BIT11) != 0
4200 );
4201
4202 } else {
4203 ShellPrintHiiEx(-1, -1, NULL,
4204 STRING_TOKEN (STR_PCI2_CARDBUS_RESET),
4205 gShellDebug1HiiHandle,
4206 (*BridgeControl & BIT6) != 0
4207 );
4208 ShellPrintHiiEx(-1, -1, NULL,
4209 STRING_TOKEN (STR_PCI2_IREQ_ENABLE),
4210 gShellDebug1HiiHandle,
4211 (*BridgeControl & BIT7) != 0
4212 );
4213 ShellPrintHiiEx(-1, -1, NULL,
4214 STRING_TOKEN (STR_PCI2_WRITE_POSTING_ENABLE),
4215 gShellDebug1HiiHandle,
4216 (*BridgeControl & BIT10) != 0
4217 );
4218 }
4219
4220 return EFI_SUCCESS;
4221 }
4222
4223 /**
4224 Print each capability structure.
4225
4226 @param[in] IoDev The pointer to the deivce.
4227 @param[in] Address The address to start at.
4228 @param[in] CapPtr The offset from the address.
4229 @param[in] EnhancedDump The print format for the dump data.
4230
4231 @retval EFI_SUCCESS The operation was successful.
4232 **/
4233 EFI_STATUS
4234 PciExplainCapabilityStruct (
4235 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
4236 IN UINT64 Address,
4237 IN UINT8 CapPtr,
4238 IN CONST UINT16 EnhancedDump
4239 )
4240 {
4241 UINT8 CapabilityPtr;
4242 UINT16 CapabilityEntry;
4243 UINT8 CapabilityID;
4244 UINT64 RegAddress;
4245
4246 CapabilityPtr = CapPtr;
4247
4248 //
4249 // Go through the Capability list
4250 //
4251 while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) {
4252 RegAddress = Address + CapabilityPtr;
4253 IoDev->Pci.Read (IoDev, EfiPciWidthUint16, RegAddress, 1, &CapabilityEntry);
4254
4255 CapabilityID = (UINT8) CapabilityEntry;
4256
4257 //
4258 // Explain PciExpress data
4259 //
4260 if (EFI_PCI_CAPABILITY_ID_PCIEXP == CapabilityID) {
4261 PciExplainPciExpress (IoDev, Address, CapabilityPtr, EnhancedDump);
4262 return EFI_SUCCESS;
4263 }
4264 //
4265 // Explain other capabilities here
4266 //
4267 CapabilityPtr = (UINT8) (CapabilityEntry >> 8);
4268 }
4269
4270 return EFI_SUCCESS;
4271 }
4272
4273 /**
4274 Print out information of the capability information.
4275
4276 @param[in] PciExpressCap The pointer to the structure about the device.
4277
4278 @retval EFI_SUCCESS The operation was successful.
4279 **/
4280 EFI_STATUS
4281 ExplainPcieCapReg (
4282 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4283 )
4284 {
4285 CHAR16 *DevicePortType;
4286
4287 ShellPrintEx (-1, -1,
4288 L" Capability Version(3:0): %E0x%04x%N\r\n",
4289 PciExpressCap->Capability.Bits.Version
4290 );
4291 if (PciExpressCap->Capability.Bits.DevicePortType < ARRAY_SIZE (DevicePortTypeTable)) {
4292 DevicePortType = DevicePortTypeTable[PciExpressCap->Capability.Bits.DevicePortType];
4293 } else {
4294 DevicePortType = L"Unknown Type";
4295 }
4296 ShellPrintEx (-1, -1,
4297 L" Device/PortType(7:4): %E%s%N\r\n",
4298 DevicePortType
4299 );
4300 //
4301 // 'Slot Implemented' is only valid for:
4302 // a) Root Port of PCI Express Root Complex, or
4303 // b) Downstream Port of PCI Express Switch
4304 //
4305 if (PciExpressCap->Capability.Bits.DevicePortType== PCIE_DEVICE_PORT_TYPE_ROOT_PORT ||
4306 PciExpressCap->Capability.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT) {
4307 ShellPrintEx (-1, -1,
4308 L" Slot Implemented(8): %E%d%N\r\n",
4309 PciExpressCap->Capability.Bits.SlotImplemented
4310 );
4311 }
4312 ShellPrintEx (-1, -1,
4313 L" Interrupt Message Number(13:9): %E0x%05x%N\r\n",
4314 PciExpressCap->Capability.Bits.InterruptMessageNumber
4315 );
4316 return EFI_SUCCESS;
4317 }
4318
4319 /**
4320 Print out information of the device capability information.
4321
4322 @param[in] PciExpressCap The pointer to the structure about the device.
4323
4324 @retval EFI_SUCCESS The operation was successful.
4325 **/
4326 EFI_STATUS
4327 ExplainPcieDeviceCap (
4328 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4329 )
4330 {
4331 UINT8 DevicePortType;
4332 UINT8 L0sLatency;
4333 UINT8 L1Latency;
4334
4335 DevicePortType = (UINT8)PciExpressCap->Capability.Bits.DevicePortType;
4336 ShellPrintEx (-1, -1, L" Max_Payload_Size Supported(2:0): ");
4337 if (PciExpressCap->DeviceCapability.Bits.MaxPayloadSize < 6) {
4338 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PciExpressCap->DeviceCapability.Bits.MaxPayloadSize + 7));
4339 } else {
4340 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
4341 }
4342 ShellPrintEx (-1, -1,
4343 L" Phantom Functions Supported(4:3): %E%d%N\r\n",
4344 PciExpressCap->DeviceCapability.Bits.PhantomFunctions
4345 );
4346 ShellPrintEx (-1, -1,
4347 L" Extended Tag Field Supported(5): %E%d-bit Tag field supported%N\r\n",
4348 PciExpressCap->DeviceCapability.Bits.ExtendedTagField ? 8 : 5
4349 );
4350 //
4351 // Endpoint L0s and L1 Acceptable Latency is only valid for Endpoint
4352 //
4353 if (IS_PCIE_ENDPOINT (DevicePortType)) {
4354 L0sLatency = (UINT8)PciExpressCap->DeviceCapability.Bits.EndpointL0sAcceptableLatency;
4355 L1Latency = (UINT8)PciExpressCap->DeviceCapability.Bits.EndpointL1AcceptableLatency;
4356 ShellPrintEx (-1, -1, L" Endpoint L0s Acceptable Latency(8:6): ");
4357 if (L0sLatency < 4) {
4358 ShellPrintEx (-1, -1, L"%EMaximum of %d ns%N\r\n", 1 << (L0sLatency + 6));
4359 } else {
4360 if (L0sLatency < 7) {
4361 ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L0sLatency - 3));
4362 } else {
4363 ShellPrintEx (-1, -1, L"%ENo limit%N\r\n");
4364 }
4365 }
4366 ShellPrintEx (-1, -1, L" Endpoint L1 Acceptable Latency(11:9): ");
4367 if (L1Latency < 7) {
4368 ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L1Latency + 1));
4369 } else {
4370 ShellPrintEx (-1, -1, L"%ENo limit%N\r\n");
4371 }
4372 }
4373 ShellPrintEx (-1, -1,
4374 L" Role-based Error Reporting(15): %E%d%N\r\n",
4375 PciExpressCap->DeviceCapability.Bits.RoleBasedErrorReporting
4376 );
4377 //
4378 // Only valid for Upstream Port:
4379 // a) Captured Slot Power Limit Value
4380 // b) Captured Slot Power Scale
4381 //
4382 if (DevicePortType == PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT) {
4383 ShellPrintEx (-1, -1,
4384 L" Captured Slot Power Limit Value(25:18): %E0x%02x%N\r\n",
4385 PciExpressCap->DeviceCapability.Bits.CapturedSlotPowerLimitValue
4386 );
4387 ShellPrintEx (-1, -1,
4388 L" Captured Slot Power Limit Scale(27:26): %E%s%N\r\n",
4389 SlotPwrLmtScaleTable[PciExpressCap->DeviceCapability.Bits.CapturedSlotPowerLimitScale]
4390 );
4391 }
4392 //
4393 // Function Level Reset Capability is only valid for Endpoint
4394 //
4395 if (IS_PCIE_ENDPOINT (DevicePortType)) {
4396 ShellPrintEx (-1, -1,
4397 L" Function Level Reset Capability(28): %E%d%N\r\n",
4398 PciExpressCap->DeviceCapability.Bits.FunctionLevelReset
4399 );
4400 }
4401 return EFI_SUCCESS;
4402 }
4403
4404 /**
4405 Print out information of the device control information.
4406
4407 @param[in] PciExpressCap The pointer to the structure about the device.
4408
4409 @retval EFI_SUCCESS The operation was successful.
4410 **/
4411 EFI_STATUS
4412 ExplainPcieDeviceControl (
4413 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4414 )
4415 {
4416 ShellPrintEx (-1, -1,
4417 L" Correctable Error Reporting Enable(0): %E%d%N\r\n",
4418 PciExpressCap->DeviceControl.Bits.CorrectableError
4419 );
4420 ShellPrintEx (-1, -1,
4421 L" Non-Fatal Error Reporting Enable(1): %E%d%N\r\n",
4422 PciExpressCap->DeviceControl.Bits.NonFatalError
4423 );
4424 ShellPrintEx (-1, -1,
4425 L" Fatal Error Reporting Enable(2): %E%d%N\r\n",
4426 PciExpressCap->DeviceControl.Bits.FatalError
4427 );
4428 ShellPrintEx (-1, -1,
4429 L" Unsupported Request Reporting Enable(3): %E%d%N\r\n",
4430 PciExpressCap->DeviceControl.Bits.UnsupportedRequest
4431 );
4432 ShellPrintEx (-1, -1,
4433 L" Enable Relaxed Ordering(4): %E%d%N\r\n",
4434 PciExpressCap->DeviceControl.Bits.RelaxedOrdering
4435 );
4436 ShellPrintEx (-1, -1, L" Max_Payload_Size(7:5): ");
4437 if (PciExpressCap->DeviceControl.Bits.MaxPayloadSize < 6) {
4438 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PciExpressCap->DeviceControl.Bits.MaxPayloadSize + 7));
4439 } else {
4440 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
4441 }
4442 ShellPrintEx (-1, -1,
4443 L" Extended Tag Field Enable(8): %E%d%N\r\n",
4444 PciExpressCap->DeviceControl.Bits.ExtendedTagField
4445 );
4446 ShellPrintEx (-1, -1,
4447 L" Phantom Functions Enable(9): %E%d%N\r\n",
4448 PciExpressCap->DeviceControl.Bits.PhantomFunctions
4449 );
4450 ShellPrintEx (-1, -1,
4451 L" Auxiliary (AUX) Power PM Enable(10): %E%d%N\r\n",
4452 PciExpressCap->DeviceControl.Bits.AuxPower
4453 );
4454 ShellPrintEx (-1, -1,
4455 L" Enable No Snoop(11): %E%d%N\r\n",
4456 PciExpressCap->DeviceControl.Bits.NoSnoop
4457 );
4458 ShellPrintEx (-1, -1, L" Max_Read_Request_Size(14:12): ");
4459 if (PciExpressCap->DeviceControl.Bits.MaxReadRequestSize < 6) {
4460 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PciExpressCap->DeviceControl.Bits.MaxReadRequestSize + 7));
4461 } else {
4462 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
4463 }
4464 //
4465 // Read operation is only valid for PCI Express to PCI/PCI-X Bridges
4466 //
4467 if (PciExpressCap->Capability.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_PCIE_TO_PCI_BRIDGE) {
4468 ShellPrintEx (-1, -1,
4469 L" Bridge Configuration Retry Enable(15): %E%d%N\r\n",
4470 PciExpressCap->DeviceControl.Bits.BridgeConfigurationRetryOrFunctionLevelReset
4471 );
4472 }
4473 return EFI_SUCCESS;
4474 }
4475
4476 /**
4477 Print out information of the device status information.
4478
4479 @param[in] PciExpressCap The pointer to the structure about the device.
4480
4481 @retval EFI_SUCCESS The operation was successful.
4482 **/
4483 EFI_STATUS
4484 ExplainPcieDeviceStatus (
4485 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4486 )
4487 {
4488 ShellPrintEx (-1, -1,
4489 L" Correctable Error Detected(0): %E%d%N\r\n",
4490 PciExpressCap->DeviceStatus.Bits.CorrectableError
4491 );
4492 ShellPrintEx (-1, -1,
4493 L" Non-Fatal Error Detected(1): %E%d%N\r\n",
4494 PciExpressCap->DeviceStatus.Bits.NonFatalError
4495 );
4496 ShellPrintEx (-1, -1,
4497 L" Fatal Error Detected(2): %E%d%N\r\n",
4498 PciExpressCap->DeviceStatus.Bits.FatalError
4499 );
4500 ShellPrintEx (-1, -1,
4501 L" Unsupported Request Detected(3): %E%d%N\r\n",
4502 PciExpressCap->DeviceStatus.Bits.UnsupportedRequest
4503 );
4504 ShellPrintEx (-1, -1,
4505 L" AUX Power Detected(4): %E%d%N\r\n",
4506 PciExpressCap->DeviceStatus.Bits.AuxPower
4507 );
4508 ShellPrintEx (-1, -1,
4509 L" Transactions Pending(5): %E%d%N\r\n",
4510 PciExpressCap->DeviceStatus.Bits.TransactionsPending
4511 );
4512 return EFI_SUCCESS;
4513 }
4514
4515 /**
4516 Print out information of the device link information.
4517
4518 @param[in] PciExpressCap The pointer to the structure about the device.
4519
4520 @retval EFI_SUCCESS The operation was successful.
4521 **/
4522 EFI_STATUS
4523 ExplainPcieLinkCap (
4524 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4525 )
4526 {
4527 CHAR16 *MaxLinkSpeed;
4528 CHAR16 *AspmValue;
4529
4530 switch (PciExpressCap->LinkCapability.Bits.MaxLinkSpeed) {
4531 case 1:
4532 MaxLinkSpeed = L"2.5 GT/s";
4533 break;
4534 case 2:
4535 MaxLinkSpeed = L"5.0 GT/s";
4536 break;
4537 case 3:
4538 MaxLinkSpeed = L"8.0 GT/s";
4539 break;
4540 default:
4541 MaxLinkSpeed = L"Unknown";
4542 break;
4543 }
4544 ShellPrintEx (-1, -1,
4545 L" Maximum Link Speed(3:0): %E%s%N\r\n",
4546 MaxLinkSpeed
4547 );
4548 ShellPrintEx (-1, -1,
4549 L" Maximum Link Width(9:4): %Ex%d%N\r\n",
4550 PciExpressCap->LinkCapability.Bits.MaxLinkWidth
4551 );
4552 switch (PciExpressCap->LinkCapability.Bits.Aspm) {
4553 case 0:
4554 AspmValue = L"Not";
4555 break;
4556 case 1:
4557 AspmValue = L"L0s";
4558 break;
4559 case 2:
4560 AspmValue = L"L1";
4561 break;
4562 case 3:
4563 AspmValue = L"L0s and L1";
4564 break;
4565 default:
4566 AspmValue = L"Reserved";
4567 break;
4568 }
4569 ShellPrintEx (-1, -1,
4570 L" Active State Power Management Support(11:10): %E%s Supported%N\r\n",
4571 AspmValue
4572 );
4573 ShellPrintEx (-1, -1,
4574 L" L0s Exit Latency(14:12): %E%s%N\r\n",
4575 L0sLatencyStrTable[PciExpressCap->LinkCapability.Bits.L0sExitLatency]
4576 );
4577 ShellPrintEx (-1, -1,
4578 L" L1 Exit Latency(17:15): %E%s%N\r\n",
4579 L1LatencyStrTable[PciExpressCap->LinkCapability.Bits.L1ExitLatency]
4580 );
4581 ShellPrintEx (-1, -1,
4582 L" Clock Power Management(18): %E%d%N\r\n",
4583 PciExpressCap->LinkCapability.Bits.ClockPowerManagement
4584 );
4585 ShellPrintEx (-1, -1,
4586 L" Surprise Down Error Reporting Capable(19): %E%d%N\r\n",
4587 PciExpressCap->LinkCapability.Bits.SurpriseDownError
4588 );
4589 ShellPrintEx (-1, -1,
4590 L" Data Link Layer Link Active Reporting Capable(20): %E%d%N\r\n",
4591 PciExpressCap->LinkCapability.Bits.DataLinkLayerLinkActive
4592 );
4593 ShellPrintEx (-1, -1,
4594 L" Link Bandwidth Notification Capability(21): %E%d%N\r\n",
4595 PciExpressCap->LinkCapability.Bits.LinkBandwidthNotification
4596 );
4597 ShellPrintEx (-1, -1,
4598 L" Port Number(31:24): %E0x%02x%N\r\n",
4599 PciExpressCap->LinkCapability.Bits.PortNumber
4600 );
4601 return EFI_SUCCESS;
4602 }
4603
4604 /**
4605 Print out information of the device link control information.
4606
4607 @param[in] PciExpressCap The pointer to the structure about the device.
4608
4609 @retval EFI_SUCCESS The operation was successful.
4610 **/
4611 EFI_STATUS
4612 ExplainPcieLinkControl (
4613 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4614 )
4615 {
4616 UINT8 DevicePortType;
4617
4618 DevicePortType = (UINT8)PciExpressCap->Capability.Bits.DevicePortType;
4619 ShellPrintEx (-1, -1,
4620 L" Active State Power Management Control(1:0): %E%s%N\r\n",
4621 ASPMCtrlStrTable[PciExpressCap->LinkControl.Bits.AspmControl]
4622 );
4623 //
4624 // RCB is not applicable to switches
4625 //
4626 if (!IS_PCIE_SWITCH(DevicePortType)) {
4627 ShellPrintEx (-1, -1,
4628 L" Read Completion Boundary (RCB)(3): %E%d byte%N\r\n",
4629 1 << (PciExpressCap->LinkControl.Bits.ReadCompletionBoundary + 6)
4630 );
4631 }
4632 //
4633 // Link Disable is reserved on
4634 // a) Endpoints
4635 // b) PCI Express to PCI/PCI-X bridges
4636 // c) Upstream Ports of Switches
4637 //
4638 if (!IS_PCIE_ENDPOINT (DevicePortType) &&
4639 DevicePortType != PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT &&
4640 DevicePortType != PCIE_DEVICE_PORT_TYPE_PCIE_TO_PCI_BRIDGE) {
4641 ShellPrintEx (-1, -1,
4642 L" Link Disable(4): %E%d%N\r\n",
4643 PciExpressCap->LinkControl.Bits.LinkDisable
4644 );
4645 }
4646 ShellPrintEx (-1, -1,
4647 L" Common Clock Configuration(6): %E%d%N\r\n",
4648 PciExpressCap->LinkControl.Bits.CommonClockConfiguration
4649 );
4650 ShellPrintEx (-1, -1,
4651 L" Extended Synch(7): %E%d%N\r\n",
4652 PciExpressCap->LinkControl.Bits.ExtendedSynch
4653 );
4654 ShellPrintEx (-1, -1,
4655 L" Enable Clock Power Management(8): %E%d%N\r\n",
4656 PciExpressCap->LinkControl.Bits.ClockPowerManagement
4657 );
4658 ShellPrintEx (-1, -1,
4659 L" Hardware Autonomous Width Disable(9): %E%d%N\r\n",
4660 PciExpressCap->LinkControl.Bits.HardwareAutonomousWidthDisable
4661 );
4662 ShellPrintEx (-1, -1,
4663 L" Link Bandwidth Management Interrupt Enable(10): %E%d%N\r\n",
4664 PciExpressCap->LinkControl.Bits.LinkBandwidthManagementInterrupt
4665 );
4666 ShellPrintEx (-1, -1,
4667 L" Link Autonomous Bandwidth Interrupt Enable(11): %E%d%N\r\n",
4668 PciExpressCap->LinkControl.Bits.LinkAutonomousBandwidthInterrupt
4669 );
4670 return EFI_SUCCESS;
4671 }
4672
4673 /**
4674 Print out information of the device link status information.
4675
4676 @param[in] PciExpressCap The pointer to the structure about the device.
4677
4678 @retval EFI_SUCCESS The operation was successful.
4679 **/
4680 EFI_STATUS
4681 ExplainPcieLinkStatus (
4682 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4683 )
4684 {
4685 CHAR16 *CurLinkSpeed;
4686
4687 switch (PciExpressCap->LinkStatus.Bits.CurrentLinkSpeed) {
4688 case 1:
4689 CurLinkSpeed = L"2.5 GT/s";
4690 break;
4691 case 2:
4692 CurLinkSpeed = L"5.0 GT/s";
4693 break;
4694 case 3:
4695 CurLinkSpeed = L"8.0 GT/s";
4696 break;
4697 default:
4698 CurLinkSpeed = L"Reserved";
4699 break;
4700 }
4701 ShellPrintEx (-1, -1,
4702 L" Current Link Speed(3:0): %E%s%N\r\n",
4703 CurLinkSpeed
4704 );
4705 ShellPrintEx (-1, -1,
4706 L" Negotiated Link Width(9:4): %Ex%d%N\r\n",
4707 PciExpressCap->LinkStatus.Bits.NegotiatedLinkWidth
4708 );
4709 ShellPrintEx (-1, -1,
4710 L" Link Training(11): %E%d%N\r\n",
4711 PciExpressCap->LinkStatus.Bits.LinkTraining
4712 );
4713 ShellPrintEx (-1, -1,
4714 L" Slot Clock Configuration(12): %E%d%N\r\n",
4715 PciExpressCap->LinkStatus.Bits.SlotClockConfiguration
4716 );
4717 ShellPrintEx (-1, -1,
4718 L" Data Link Layer Link Active(13): %E%d%N\r\n",
4719 PciExpressCap->LinkStatus.Bits.DataLinkLayerLinkActive
4720 );
4721 ShellPrintEx (-1, -1,
4722 L" Link Bandwidth Management Status(14): %E%d%N\r\n",
4723 PciExpressCap->LinkStatus.Bits.LinkBandwidthManagement
4724 );
4725 ShellPrintEx (-1, -1,
4726 L" Link Autonomous Bandwidth Status(15): %E%d%N\r\n",
4727 PciExpressCap->LinkStatus.Bits.LinkAutonomousBandwidth
4728 );
4729 return EFI_SUCCESS;
4730 }
4731
4732 /**
4733 Print out information of the device slot information.
4734
4735 @param[in] PciExpressCap The pointer to the structure about the device.
4736
4737 @retval EFI_SUCCESS The operation was successful.
4738 **/
4739 EFI_STATUS
4740 ExplainPcieSlotCap (
4741 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4742 )
4743 {
4744 ShellPrintEx (-1, -1,
4745 L" Attention Button Present(0): %E%d%N\r\n",
4746 PciExpressCap->SlotCapability.Bits.AttentionButton
4747 );
4748 ShellPrintEx (-1, -1,
4749 L" Power Controller Present(1): %E%d%N\r\n",
4750 PciExpressCap->SlotCapability.Bits.PowerController
4751 );
4752 ShellPrintEx (-1, -1,
4753 L" MRL Sensor Present(2): %E%d%N\r\n",
4754 PciExpressCap->SlotCapability.Bits.MrlSensor
4755 );
4756 ShellPrintEx (-1, -1,
4757 L" Attention Indicator Present(3): %E%d%N\r\n",
4758 PciExpressCap->SlotCapability.Bits.AttentionIndicator
4759 );
4760 ShellPrintEx (-1, -1,
4761 L" Power Indicator Present(4): %E%d%N\r\n",
4762 PciExpressCap->SlotCapability.Bits.PowerIndicator
4763 );
4764 ShellPrintEx (-1, -1,
4765 L" Hot-Plug Surprise(5): %E%d%N\r\n",
4766 PciExpressCap->SlotCapability.Bits.HotPlugSurprise
4767 );
4768 ShellPrintEx (-1, -1,
4769 L" Hot-Plug Capable(6): %E%d%N\r\n",
4770 PciExpressCap->SlotCapability.Bits.HotPlugCapable
4771 );
4772 ShellPrintEx (-1, -1,
4773 L" Slot Power Limit Value(14:7): %E0x%02x%N\r\n",
4774 PciExpressCap->SlotCapability.Bits.SlotPowerLimitValue
4775 );
4776 ShellPrintEx (-1, -1,
4777 L" Slot Power Limit Scale(16:15): %E%s%N\r\n",
4778 SlotPwrLmtScaleTable[PciExpressCap->SlotCapability.Bits.SlotPowerLimitScale]
4779 );
4780 ShellPrintEx (-1, -1,
4781 L" Electromechanical Interlock Present(17): %E%d%N\r\n",
4782 PciExpressCap->SlotCapability.Bits.ElectromechanicalInterlock
4783 );
4784 ShellPrintEx (-1, -1,
4785 L" No Command Completed Support(18): %E%d%N\r\n",
4786 PciExpressCap->SlotCapability.Bits.NoCommandCompleted
4787 );
4788 ShellPrintEx (-1, -1,
4789 L" Physical Slot Number(31:19): %E%d%N\r\n",
4790 PciExpressCap->SlotCapability.Bits.PhysicalSlotNumber
4791 );
4792
4793 return EFI_SUCCESS;
4794 }
4795
4796 /**
4797 Print out information of the device slot control information.
4798
4799 @param[in] PciExpressCap The pointer to the structure about the device.
4800
4801 @retval EFI_SUCCESS The operation was successful.
4802 **/
4803 EFI_STATUS
4804 ExplainPcieSlotControl (
4805 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4806 )
4807 {
4808 ShellPrintEx (-1, -1,
4809 L" Attention Button Pressed Enable(0): %E%d%N\r\n",
4810 PciExpressCap->SlotControl.Bits.AttentionButtonPressed
4811 );
4812 ShellPrintEx (-1, -1,
4813 L" Power Fault Detected Enable(1): %E%d%N\r\n",
4814 PciExpressCap->SlotControl.Bits.PowerFaultDetected
4815 );
4816 ShellPrintEx (-1, -1,
4817 L" MRL Sensor Changed Enable(2): %E%d%N\r\n",
4818 PciExpressCap->SlotControl.Bits.MrlSensorChanged
4819 );
4820 ShellPrintEx (-1, -1,
4821 L" Presence Detect Changed Enable(3): %E%d%N\r\n",
4822 PciExpressCap->SlotControl.Bits.PresenceDetectChanged
4823 );
4824 ShellPrintEx (-1, -1,
4825 L" Command Completed Interrupt Enable(4): %E%d%N\r\n",
4826 PciExpressCap->SlotControl.Bits.CommandCompletedInterrupt
4827 );
4828 ShellPrintEx (-1, -1,
4829 L" Hot-Plug Interrupt Enable(5): %E%d%N\r\n",
4830 PciExpressCap->SlotControl.Bits.HotPlugInterrupt
4831 );
4832 ShellPrintEx (-1, -1,
4833 L" Attention Indicator Control(7:6): %E%s%N\r\n",
4834 IndicatorTable[
4835 PciExpressCap->SlotControl.Bits.AttentionIndicator]
4836 );
4837 ShellPrintEx (-1, -1,
4838 L" Power Indicator Control(9:8): %E%s%N\r\n",
4839 IndicatorTable[PciExpressCap->SlotControl.Bits.PowerIndicator]
4840 );
4841 ShellPrintEx (-1, -1, L" Power Controller Control(10): %EPower ");
4842 if (
4843 PciExpressCap->SlotControl.Bits.PowerController) {
4844 ShellPrintEx (-1, -1, L"Off%N\r\n");
4845 } else {
4846 ShellPrintEx (-1, -1, L"On%N\r\n");
4847 }
4848 ShellPrintEx (-1, -1,
4849 L" Electromechanical Interlock Control(11): %E%d%N\r\n",
4850 PciExpressCap->SlotControl.Bits.ElectromechanicalInterlock
4851 );
4852 ShellPrintEx (-1, -1,
4853 L" Data Link Layer State Changed Enable(12): %E%d%N\r\n",
4854 PciExpressCap->SlotControl.Bits.DataLinkLayerStateChanged
4855 );
4856 return EFI_SUCCESS;
4857 }
4858
4859 /**
4860 Print out information of the device slot status information.
4861
4862 @param[in] PciExpressCap The pointer to the structure about the device.
4863
4864 @retval EFI_SUCCESS The operation was successful.
4865 **/
4866 EFI_STATUS
4867 ExplainPcieSlotStatus (
4868 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4869 )
4870 {
4871 ShellPrintEx (-1, -1,
4872 L" Attention Button Pressed(0): %E%d%N\r\n",
4873 PciExpressCap->SlotStatus.Bits.AttentionButtonPressed
4874 );
4875 ShellPrintEx (-1, -1,
4876 L" Power Fault Detected(1): %E%d%N\r\n",
4877 PciExpressCap->SlotStatus.Bits.PowerFaultDetected
4878 );
4879 ShellPrintEx (-1, -1,
4880 L" MRL Sensor Changed(2): %E%d%N\r\n",
4881 PciExpressCap->SlotStatus.Bits.MrlSensorChanged
4882 );
4883 ShellPrintEx (-1, -1,
4884 L" Presence Detect Changed(3): %E%d%N\r\n",
4885 PciExpressCap->SlotStatus.Bits.PresenceDetectChanged
4886 );
4887 ShellPrintEx (-1, -1,
4888 L" Command Completed(4): %E%d%N\r\n",
4889 PciExpressCap->SlotStatus.Bits.CommandCompleted
4890 );
4891 ShellPrintEx (-1, -1, L" MRL Sensor State(5): %EMRL ");
4892 if (
4893 PciExpressCap->SlotStatus.Bits.MrlSensor) {
4894 ShellPrintEx (-1, -1, L" Opened%N\r\n");
4895 } else {
4896 ShellPrintEx (-1, -1, L" Closed%N\r\n");
4897 }
4898 ShellPrintEx (-1, -1, L" Presence Detect State(6): ");
4899 if (
4900 PciExpressCap->SlotStatus.Bits.PresenceDetect) {
4901 ShellPrintEx (-1, -1, L"%ECard Present in slot%N\r\n");
4902 } else {
4903 ShellPrintEx (-1, -1, L"%ESlot Empty%N\r\n");
4904 }
4905 ShellPrintEx (-1, -1, L" Electromechanical Interlock Status(7): %EElectromechanical Interlock ");
4906 if (
4907 PciExpressCap->SlotStatus.Bits.ElectromechanicalInterlock) {
4908 ShellPrintEx (-1, -1, L"Engaged%N\r\n");
4909 } else {
4910 ShellPrintEx (-1, -1, L"Disengaged%N\r\n");
4911 }
4912 ShellPrintEx (-1, -1,
4913 L" Data Link Layer State Changed(8): %E%d%N\r\n",
4914 PciExpressCap->SlotStatus.Bits.DataLinkLayerStateChanged
4915 );
4916 return EFI_SUCCESS;
4917 }
4918
4919 /**
4920 Print out information of the device root information.
4921
4922 @param[in] PciExpressCap The pointer to the structure about the device.
4923
4924 @retval EFI_SUCCESS The operation was successful.
4925 **/
4926 EFI_STATUS
4927 ExplainPcieRootControl (
4928 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4929 )
4930 {
4931 ShellPrintEx (-1, -1,
4932 L" System Error on Correctable Error Enable(0): %E%d%N\r\n",
4933 PciExpressCap->RootControl.Bits.SystemErrorOnCorrectableError
4934 );
4935 ShellPrintEx (-1, -1,
4936 L" System Error on Non-Fatal Error Enable(1): %E%d%N\r\n",
4937 PciExpressCap->RootControl.Bits.SystemErrorOnNonFatalError
4938 );
4939 ShellPrintEx (-1, -1,
4940 L" System Error on Fatal Error Enable(2): %E%d%N\r\n",
4941 PciExpressCap->RootControl.Bits.SystemErrorOnFatalError
4942 );
4943 ShellPrintEx (-1, -1,
4944 L" PME Interrupt Enable(3): %E%d%N\r\n",
4945 PciExpressCap->RootControl.Bits.PmeInterrupt
4946 );
4947 ShellPrintEx (-1, -1,
4948 L" CRS Software Visibility Enable(4): %E%d%N\r\n",
4949 PciExpressCap->RootControl.Bits.CrsSoftwareVisibility
4950 );
4951
4952 return EFI_SUCCESS;
4953 }
4954
4955 /**
4956 Print out information of the device root capability information.
4957
4958 @param[in] PciExpressCap The pointer to the structure about the device.
4959
4960 @retval EFI_SUCCESS The operation was successful.
4961 **/
4962 EFI_STATUS
4963 ExplainPcieRootCap (
4964 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4965 )
4966 {
4967 ShellPrintEx (-1, -1,
4968 L" CRS Software Visibility(0): %E%d%N\r\n",
4969 PciExpressCap->RootCapability.Bits.CrsSoftwareVisibility
4970 );
4971
4972 return EFI_SUCCESS;
4973 }
4974
4975 /**
4976 Print out information of the device root status information.
4977
4978 @param[in] PciExpressCap The pointer to the structure about the device.
4979
4980 @retval EFI_SUCCESS The operation was successful.
4981 **/
4982 EFI_STATUS
4983 ExplainPcieRootStatus (
4984 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4985 )
4986 {
4987 ShellPrintEx (-1, -1,
4988 L" PME Requester ID(15:0): %E0x%04x%N\r\n",
4989 PciExpressCap->RootStatus.Bits.PmeRequesterId
4990 );
4991 ShellPrintEx (-1, -1,
4992 L" PME Status(16): %E%d%N\r\n",
4993 PciExpressCap->RootStatus.Bits.PmeStatus
4994 );
4995 ShellPrintEx (-1, -1,
4996 L" PME Pending(17): %E%d%N\r\n",
4997 PciExpressCap->RootStatus.Bits.PmePending
4998 );
4999 return EFI_SUCCESS;
5000 }
5001
5002 /**
5003 Function to interpret and print out the link control structure
5004
5005 @param[in] HeaderAddress The Address of this capability header.
5006 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5007 **/
5008 EFI_STATUS
5009 PrintInterpretedExtendedCompatibilityLinkControl (
5010 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5011 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5012 )
5013 {
5014 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL *Header;
5015 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL*)HeaderAddress;
5016
5017 ShellPrintHiiEx(
5018 -1, -1, NULL,
5019 STRING_TOKEN (STR_PCI_EXT_CAP_LINK_CONTROL),
5020 gShellDebug1HiiHandle,
5021 Header->RootComplexLinkCapabilities,
5022 Header->RootComplexLinkControl,
5023 Header->RootComplexLinkStatus
5024 );
5025 DumpHex (
5026 4,
5027 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5028 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL),
5029 (VOID *) (HeaderAddress)
5030 );
5031 return (EFI_SUCCESS);
5032 }
5033
5034 /**
5035 Function to interpret and print out the power budgeting structure
5036
5037 @param[in] HeaderAddress The Address of this capability header.
5038 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5039 **/
5040 EFI_STATUS
5041 PrintInterpretedExtendedCompatibilityPowerBudgeting (
5042 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5043 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5044 )
5045 {
5046 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING *Header;
5047 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING*)HeaderAddress;
5048
5049 ShellPrintHiiEx(
5050 -1, -1, NULL,
5051 STRING_TOKEN (STR_PCI_EXT_CAP_POWER),
5052 gShellDebug1HiiHandle,
5053 Header->DataSelect,
5054 Header->Data,
5055 Header->PowerBudgetCapability
5056 );
5057 DumpHex (
5058 4,
5059 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5060 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING),
5061 (VOID *) (HeaderAddress)
5062 );
5063 return (EFI_SUCCESS);
5064 }
5065
5066 /**
5067 Function to interpret and print out the ACS structure
5068
5069 @param[in] HeaderAddress The Address of this capability header.
5070 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5071 **/
5072 EFI_STATUS
5073 PrintInterpretedExtendedCompatibilityAcs (
5074 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5075 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5076 )
5077 {
5078 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED *Header;
5079 UINT16 VectorSize;
5080 UINT16 LoopCounter;
5081
5082 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED*)HeaderAddress;
5083 VectorSize = 0;
5084
5085 ShellPrintHiiEx(
5086 -1, -1, NULL,
5087 STRING_TOKEN (STR_PCI_EXT_CAP_ACS),
5088 gShellDebug1HiiHandle,
5089 Header->AcsCapability,
5090 Header->AcsControl
5091 );
5092 if (PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_CONTROL(Header)) {
5093 VectorSize = PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_VECTOR_SIZE(Header);
5094 if (VectorSize == 0) {
5095 VectorSize = 256;
5096 }
5097 for (LoopCounter = 0 ; LoopCounter * 8 < VectorSize ; LoopCounter++) {
5098 ShellPrintHiiEx(
5099 -1, -1, NULL,
5100 STRING_TOKEN (STR_PCI_EXT_CAP_ACS2),
5101 gShellDebug1HiiHandle,
5102 LoopCounter + 1,
5103 Header->EgressControlVectorArray[LoopCounter]
5104 );
5105 }
5106 }
5107 DumpHex (
5108 4,
5109 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5110 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED) + (VectorSize / 8) - 1,
5111 (VOID *) (HeaderAddress)
5112 );
5113 return (EFI_SUCCESS);
5114 }
5115
5116 /**
5117 Function to interpret and print out the latency tolerance reporting structure
5118
5119 @param[in] HeaderAddress The Address of this capability header.
5120 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5121 **/
5122 EFI_STATUS
5123 PrintInterpretedExtendedCompatibilityLatencyToleranceReporting (
5124 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5125 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5126 )
5127 {
5128 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING *Header;
5129 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING*)HeaderAddress;
5130
5131 ShellPrintHiiEx(
5132 -1, -1, NULL,
5133 STRING_TOKEN (STR_PCI_EXT_CAP_LAT),
5134 gShellDebug1HiiHandle,
5135 Header->MaxSnoopLatency,
5136 Header->MaxNoSnoopLatency
5137 );
5138 DumpHex (
5139 4,
5140 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5141 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING),
5142 (VOID *) (HeaderAddress)
5143 );
5144 return (EFI_SUCCESS);
5145 }
5146
5147 /**
5148 Function to interpret and print out the serial number structure
5149
5150 @param[in] HeaderAddress The Address of this capability header.
5151 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5152 **/
5153 EFI_STATUS
5154 PrintInterpretedExtendedCompatibilitySerialNumber (
5155 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5156 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5157 )
5158 {
5159 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER *Header;
5160 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER*)HeaderAddress;
5161
5162 ShellPrintHiiEx(
5163 -1, -1, NULL,
5164 STRING_TOKEN (STR_PCI_EXT_CAP_SN),
5165 gShellDebug1HiiHandle,
5166 Header->SerialNumber
5167 );
5168 DumpHex (
5169 4,
5170 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5171 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER),
5172 (VOID *) (HeaderAddress)
5173 );
5174 return (EFI_SUCCESS);
5175 }
5176
5177 /**
5178 Function to interpret and print out the RCRB structure
5179
5180 @param[in] HeaderAddress The Address of this capability header.
5181 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5182 **/
5183 EFI_STATUS
5184 PrintInterpretedExtendedCompatibilityRcrb (
5185 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5186 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5187 )
5188 {
5189 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER *Header;
5190 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER*)HeaderAddress;
5191
5192 ShellPrintHiiEx(
5193 -1, -1, NULL,
5194 STRING_TOKEN (STR_PCI_EXT_CAP_RCRB),
5195 gShellDebug1HiiHandle,
5196 Header->VendorId,
5197 Header->DeviceId,
5198 Header->RcrbCapabilities,
5199 Header->RcrbControl
5200 );
5201 DumpHex (
5202 4,
5203 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5204 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER),
5205 (VOID *) (HeaderAddress)
5206 );
5207 return (EFI_SUCCESS);
5208 }
5209
5210 /**
5211 Function to interpret and print out the vendor specific structure
5212
5213 @param[in] HeaderAddress The Address of this capability header.
5214 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5215 **/
5216 EFI_STATUS
5217 PrintInterpretedExtendedCompatibilityVendorSpecific (
5218 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5219 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5220 )
5221 {
5222 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VENDOR_SPECIFIC *Header;
5223 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_VENDOR_SPECIFIC*)HeaderAddress;
5224
5225 ShellPrintHiiEx(
5226 -1, -1, NULL,
5227 STRING_TOKEN (STR_PCI_EXT_CAP_VEN),
5228 gShellDebug1HiiHandle,
5229 Header->VendorSpecificHeader
5230 );
5231 DumpHex (
5232 4,
5233 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5234 PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_GET_SIZE(Header),
5235 (VOID *) (HeaderAddress)
5236 );
5237 return (EFI_SUCCESS);
5238 }
5239
5240 /**
5241 Function to interpret and print out the Event Collector Endpoint Association structure
5242
5243 @param[in] HeaderAddress The Address of this capability header.
5244 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5245 **/
5246 EFI_STATUS
5247 PrintInterpretedExtendedCompatibilityECEA (
5248 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5249 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5250 )
5251 {
5252 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION *Header;
5253 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION*)HeaderAddress;
5254
5255 ShellPrintHiiEx(
5256 -1, -1, NULL,
5257 STRING_TOKEN (STR_PCI_EXT_CAP_ECEA),
5258 gShellDebug1HiiHandle,
5259 Header->AssociationBitmap
5260 );
5261 DumpHex (
5262 4,
5263 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5264 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION),
5265 (VOID *) (HeaderAddress)
5266 );
5267 return (EFI_SUCCESS);
5268 }
5269
5270 /**
5271 Function to interpret and print out the ARI structure
5272
5273 @param[in] HeaderAddress The Address of this capability header.
5274 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5275 **/
5276 EFI_STATUS
5277 PrintInterpretedExtendedCompatibilityAri (
5278 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5279 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5280 )
5281 {
5282 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY *Header;
5283 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY*)HeaderAddress;
5284
5285 ShellPrintHiiEx(
5286 -1, -1, NULL,
5287 STRING_TOKEN (STR_PCI_EXT_CAP_ARI),
5288 gShellDebug1HiiHandle,
5289 Header->AriCapability,
5290 Header->AriControl
5291 );
5292 DumpHex (
5293 4,
5294 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5295 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY),
5296 (VOID *) (HeaderAddress)
5297 );
5298 return (EFI_SUCCESS);
5299 }
5300
5301 /**
5302 Function to interpret and print out the DPA structure
5303
5304 @param[in] HeaderAddress The Address of this capability header.
5305 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5306 **/
5307 EFI_STATUS
5308 PrintInterpretedExtendedCompatibilityDynamicPowerAllocation (
5309 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5310 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5311 )
5312 {
5313 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION *Header;
5314 UINT8 LinkCount;
5315 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION*)HeaderAddress;
5316
5317 ShellPrintHiiEx(
5318 -1, -1, NULL,
5319 STRING_TOKEN (STR_PCI_EXT_CAP_DPA),
5320 gShellDebug1HiiHandle,
5321 Header->DpaCapability,
5322 Header->DpaLatencyIndicator,
5323 Header->DpaStatus,
5324 Header->DpaControl
5325 );
5326 for (LinkCount = 0 ; LinkCount < PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_GET_SUBSTATE_MAX(Header) + 1 ; LinkCount++) {
5327 ShellPrintHiiEx(
5328 -1, -1, NULL,
5329 STRING_TOKEN (STR_PCI_EXT_CAP_DPA2),
5330 gShellDebug1HiiHandle,
5331 LinkCount+1,
5332 Header->DpaPowerAllocationArray[LinkCount]
5333 );
5334 }
5335 DumpHex (
5336 4,
5337 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5338 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION) - 1 + PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_GET_SUBSTATE_MAX(Header),
5339 (VOID *) (HeaderAddress)
5340 );
5341 return (EFI_SUCCESS);
5342 }
5343
5344 /**
5345 Function to interpret and print out the link declaration structure
5346
5347 @param[in] HeaderAddress The Address of this capability header.
5348 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5349 **/
5350 EFI_STATUS
5351 PrintInterpretedExtendedCompatibilityLinkDeclaration (
5352 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5353 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5354 )
5355 {
5356 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION *Header;
5357 UINT8 LinkCount;
5358 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION*)HeaderAddress;
5359
5360 ShellPrintHiiEx(
5361 -1, -1, NULL,
5362 STRING_TOKEN (STR_PCI_EXT_CAP_LINK_DECLAR),
5363 gShellDebug1HiiHandle,
5364 Header->ElementSelfDescription
5365 );
5366
5367 for (LinkCount = 0 ; LinkCount < PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_GET_LINK_COUNT(Header) ; LinkCount++) {
5368 ShellPrintHiiEx(
5369 -1, -1, NULL,
5370 STRING_TOKEN (STR_PCI_EXT_CAP_LINK_DECLAR2),
5371 gShellDebug1HiiHandle,
5372 LinkCount+1,
5373 Header->LinkEntry[LinkCount]
5374 );
5375 }
5376 DumpHex (
5377 4,
5378 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5379 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION) + (PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_GET_LINK_COUNT(Header)-1)*sizeof(UINT32),
5380 (VOID *) (HeaderAddress)
5381 );
5382 return (EFI_SUCCESS);
5383 }
5384
5385 /**
5386 Function to interpret and print out the Advanced Error Reporting structure
5387
5388 @param[in] HeaderAddress The Address of this capability header.
5389 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5390 **/
5391 EFI_STATUS
5392 PrintInterpretedExtendedCompatibilityAer (
5393 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5394 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5395 )
5396 {
5397 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING *Header;
5398 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING*)HeaderAddress;
5399
5400 ShellPrintHiiEx(
5401 -1, -1, NULL,
5402 STRING_TOKEN (STR_PCI_EXT_CAP_AER),
5403 gShellDebug1HiiHandle,
5404 Header->UncorrectableErrorStatus,
5405 Header->UncorrectableErrorMask,
5406 Header->UncorrectableErrorSeverity,
5407 Header->CorrectableErrorStatus,
5408 Header->CorrectableErrorMask,
5409 Header->AdvancedErrorCapabilitiesAndControl,
5410 Header->HeaderLog[0],
5411 Header->HeaderLog[1],
5412 Header->HeaderLog[2],
5413 Header->HeaderLog[3],
5414 Header->RootErrorCommand,
5415 Header->RootErrorStatus,
5416 Header->ErrorSourceIdentification,
5417 Header->CorrectableErrorSourceIdentification,
5418 Header->TlpPrefixLog[0],
5419 Header->TlpPrefixLog[1],
5420 Header->TlpPrefixLog[2],
5421 Header->TlpPrefixLog[3]
5422 );
5423 DumpHex (
5424 4,
5425 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5426 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING),
5427 (VOID *) (HeaderAddress)
5428 );
5429 return (EFI_SUCCESS);
5430 }
5431
5432 /**
5433 Function to interpret and print out the multicast structure
5434
5435 @param[in] HeaderAddress The Address of this capability header.
5436 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5437 @param[in] PciExpressCapPtr The address of the PCIe capabilities structure.
5438 **/
5439 EFI_STATUS
5440 PrintInterpretedExtendedCompatibilityMulticast (
5441 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5442 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress,
5443 IN CONST PCI_CAPABILITY_PCIEXP *PciExpressCapPtr
5444 )
5445 {
5446 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST *Header;
5447 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST*)HeaderAddress;
5448
5449 ShellPrintHiiEx(
5450 -1, -1, NULL,
5451 STRING_TOKEN (STR_PCI_EXT_CAP_MULTICAST),
5452 gShellDebug1HiiHandle,
5453 Header->MultiCastCapability,
5454 Header->MulticastControl,
5455 Header->McBaseAddress,
5456 Header->McReceiveAddress,
5457 Header->McBlockAll,
5458 Header->McBlockUntranslated,
5459 Header->McOverlayBar
5460 );
5461
5462 DumpHex (
5463 4,
5464 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5465 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST),
5466 (VOID *) (HeaderAddress)
5467 );
5468
5469 return (EFI_SUCCESS);
5470 }
5471
5472 /**
5473 Function to interpret and print out the virtual channel and multi virtual channel structure
5474
5475 @param[in] HeaderAddress The Address of this capability header.
5476 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5477 **/
5478 EFI_STATUS
5479 PrintInterpretedExtendedCompatibilityVirtualChannel (
5480 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5481 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5482 )
5483 {
5484 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY *Header;
5485 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC *CapabilityItem;
5486 UINT32 ItemCount;
5487 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY*)HeaderAddress;
5488
5489 ShellPrintHiiEx(
5490 -1, -1, NULL,
5491 STRING_TOKEN (STR_PCI_EXT_CAP_VC_BASE),
5492 gShellDebug1HiiHandle,
5493 Header->ExtendedVcCount,
5494 Header->PortVcCapability1,
5495 Header->PortVcCapability2,
5496 Header->VcArbTableOffset,
5497 Header->PortVcControl,
5498 Header->PortVcStatus
5499 );
5500 for (ItemCount = 0 ; ItemCount < Header->ExtendedVcCount ; ItemCount++) {
5501 CapabilityItem = &Header->Capability[ItemCount];
5502 ShellPrintHiiEx(
5503 -1, -1, NULL,
5504 STRING_TOKEN (STR_PCI_EXT_CAP_VC_ITEM),
5505 gShellDebug1HiiHandle,
5506 ItemCount+1,
5507 CapabilityItem->VcResourceCapability,
5508 CapabilityItem->PortArbTableOffset,
5509 CapabilityItem->VcResourceControl,
5510 CapabilityItem->VcResourceStatus
5511 );
5512 }
5513
5514 DumpHex (
5515 4,
5516 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5517 sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY)
5518 + Header->ExtendedVcCount * sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC),
5519 (VOID *) (HeaderAddress)
5520 );
5521
5522 return (EFI_SUCCESS);
5523 }
5524
5525 /**
5526 Function to interpret and print out the resizeable bar structure
5527
5528 @param[in] HeaderAddress The Address of this capability header.
5529 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5530 **/
5531 EFI_STATUS
5532 PrintInterpretedExtendedCompatibilityResizeableBar (
5533 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5534 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5535 )
5536 {
5537 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR *Header;
5538 UINT32 ItemCount;
5539 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR*)HeaderAddress;
5540
5541 for (ItemCount = 0 ; ItemCount < (UINT32)GET_NUMBER_RESIZABLE_BARS(Header) ; ItemCount++) {
5542 ShellPrintHiiEx(
5543 -1, -1, NULL,
5544 STRING_TOKEN (STR_PCI_EXT_CAP_RESIZE_BAR),
5545 gShellDebug1HiiHandle,
5546 ItemCount+1,
5547 Header->Capability[ItemCount].ResizableBarCapability,
5548 Header->Capability[ItemCount].ResizableBarControl
5549 );
5550 }
5551
5552 DumpHex (
5553 4,
5554 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5555 (UINT32)GET_NUMBER_RESIZABLE_BARS(Header) * sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY),
5556 (VOID *) (HeaderAddress)
5557 );
5558
5559 return (EFI_SUCCESS);
5560 }
5561
5562 /**
5563 Function to interpret and print out the TPH structure
5564
5565 @param[in] HeaderAddress The Address of this capability header.
5566 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5567 **/
5568 EFI_STATUS
5569 PrintInterpretedExtendedCompatibilityTph (
5570 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5571 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5572 )
5573 {
5574 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH *Header;
5575 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH*)HeaderAddress;
5576
5577 ShellPrintHiiEx(
5578 -1, -1, NULL,
5579 STRING_TOKEN (STR_PCI_EXT_CAP_TPH),
5580 gShellDebug1HiiHandle,
5581 Header->TphRequesterCapability,
5582 Header->TphRequesterControl
5583 );
5584 DumpHex (
5585 8,
5586 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)Header->TphStTable - (UINT8*)HeadersBaseAddress),
5587 GET_TPH_TABLE_SIZE(Header),
5588 (VOID *)Header->TphStTable
5589 );
5590
5591 DumpHex (
5592 4,
5593 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5594 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH) + GET_TPH_TABLE_SIZE(Header) - sizeof(UINT16),
5595 (VOID *) (HeaderAddress)
5596 );
5597
5598 return (EFI_SUCCESS);
5599 }
5600
5601 /**
5602 Function to interpret and print out the secondary PCIe capability structure
5603
5604 @param[in] HeaderAddress The Address of this capability header.
5605 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5606 @param[in] PciExpressCapPtr The address of the PCIe capabilities structure.
5607 **/
5608 EFI_STATUS
5609 PrintInterpretedExtendedCompatibilitySecondary (
5610 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5611 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress,
5612 IN CONST PCI_CAPABILITY_PCIEXP *PciExpressCap
5613 )
5614 {
5615 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE *Header;
5616 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE*)HeaderAddress;
5617
5618 ShellPrintHiiEx(
5619 -1, -1, NULL,
5620 STRING_TOKEN (STR_PCI_EXT_CAP_SECONDARY),
5621 gShellDebug1HiiHandle,
5622 Header->LinkControl3.Uint32,
5623 Header->LaneErrorStatus
5624 );
5625 DumpHex (
5626 8,
5627 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)Header->EqualizationControl - (UINT8*)HeadersBaseAddress),
5628 PciExpressCap->LinkCapability.Bits.MaxLinkWidth * sizeof (PCI_EXPRESS_REG_LANE_EQUALIZATION_CONTROL),
5629 (VOID *)Header->EqualizationControl
5630 );
5631
5632 DumpHex (
5633 4,
5634 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5635 sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE) - sizeof (Header->EqualizationControl)
5636 + PciExpressCap->LinkCapability.Bits.MaxLinkWidth * sizeof (PCI_EXPRESS_REG_LANE_EQUALIZATION_CONTROL),
5637 (VOID *) (HeaderAddress)
5638 );
5639
5640 return (EFI_SUCCESS);
5641 }
5642
5643 /**
5644 Display Pcie extended capability details
5645
5646 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5647 @param[in] HeaderAddress The address of this capability header.
5648 @param[in] PciExpressCapPtr The address of the PCIe capabilities structure.
5649 **/
5650 EFI_STATUS
5651 PrintPciExtendedCapabilityDetails(
5652 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress,
5653 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5654 IN CONST PCI_CAPABILITY_PCIEXP *PciExpressCapPtr
5655 )
5656 {
5657 switch (HeaderAddress->CapabilityId){
5658 case PCI_EXPRESS_EXTENDED_CAPABILITY_ADVANCED_ERROR_REPORTING_ID:
5659 return PrintInterpretedExtendedCompatibilityAer(HeaderAddress, HeadersBaseAddress);
5660 case PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_CONTROL_ID:
5661 return PrintInterpretedExtendedCompatibilityLinkControl(HeaderAddress, HeadersBaseAddress);
5662 case PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_ID:
5663 return PrintInterpretedExtendedCompatibilityLinkDeclaration(HeaderAddress, HeadersBaseAddress);
5664 case PCI_EXPRESS_EXTENDED_CAPABILITY_SERIAL_NUMBER_ID:
5665 return PrintInterpretedExtendedCompatibilitySerialNumber(HeaderAddress, HeadersBaseAddress);
5666 case PCI_EXPRESS_EXTENDED_CAPABILITY_POWER_BUDGETING_ID:
5667 return PrintInterpretedExtendedCompatibilityPowerBudgeting(HeaderAddress, HeadersBaseAddress);
5668 case PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_ID:
5669 return PrintInterpretedExtendedCompatibilityAcs(HeaderAddress, HeadersBaseAddress);
5670 case PCI_EXPRESS_EXTENDED_CAPABILITY_LATENCE_TOLERANCE_REPORTING_ID:
5671 return PrintInterpretedExtendedCompatibilityLatencyToleranceReporting(HeaderAddress, HeadersBaseAddress);
5672 case PCI_EXPRESS_EXTENDED_CAPABILITY_ARI_CAPABILITY_ID:
5673 return PrintInterpretedExtendedCompatibilityAri(HeaderAddress, HeadersBaseAddress);
5674 case PCI_EXPRESS_EXTENDED_CAPABILITY_RCRB_HEADER_ID:
5675 return PrintInterpretedExtendedCompatibilityRcrb(HeaderAddress, HeadersBaseAddress);
5676 case PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID:
5677 return PrintInterpretedExtendedCompatibilityVendorSpecific(HeaderAddress, HeadersBaseAddress);
5678 case PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_ID:
5679 return PrintInterpretedExtendedCompatibilityDynamicPowerAllocation(HeaderAddress, HeadersBaseAddress);
5680 case PCI_EXPRESS_EXTENDED_CAPABILITY_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION_ID:
5681 return PrintInterpretedExtendedCompatibilityECEA(HeaderAddress, HeadersBaseAddress);
5682 case PCI_EXPRESS_EXTENDED_CAPABILITY_VIRTUAL_CHANNEL_ID:
5683 case PCI_EXPRESS_EXTENDED_CAPABILITY_MULTI_FUNCTION_VIRTUAL_CHANNEL_ID:
5684 return PrintInterpretedExtendedCompatibilityVirtualChannel(HeaderAddress, HeadersBaseAddress);
5685 case PCI_EXPRESS_EXTENDED_CAPABILITY_MULTICAST_ID:
5686 //
5687 // should only be present if PCIE_CAP_DEVICEPORT_TYPE(PciExpressCapPtr->PcieCapReg) == 0100b, 0101b, or 0110b
5688 //
5689 return PrintInterpretedExtendedCompatibilityMulticast(HeaderAddress, HeadersBaseAddress, PciExpressCapPtr);
5690 case PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID:
5691 return PrintInterpretedExtendedCompatibilityResizeableBar(HeaderAddress, HeadersBaseAddress);
5692 case PCI_EXPRESS_EXTENDED_CAPABILITY_TPH_ID:
5693 return PrintInterpretedExtendedCompatibilityTph(HeaderAddress, HeadersBaseAddress);
5694 case PCI_EXPRESS_EXTENDED_CAPABILITY_SECONDARY_PCIE_ID:
5695 return PrintInterpretedExtendedCompatibilitySecondary(HeaderAddress, HeadersBaseAddress, PciExpressCapPtr);
5696 default:
5697 ShellPrintEx (-1, -1,
5698 L"Unknown PCIe extended capability ID (%04xh). No interpretation available.\r\n",
5699 HeaderAddress->CapabilityId
5700 );
5701 return EFI_SUCCESS;
5702 };
5703
5704 }
5705
5706 /**
5707 Display Pcie device structure.
5708
5709 @param[in] IoDev The pointer to the root pci protocol.
5710 @param[in] Address The Address to start at.
5711 @param[in] CapabilityPtr The offset from the address to start.
5712 @param[in] EnhancedDump The print format for the dump data.
5713
5714 **/
5715 EFI_STATUS
5716 PciExplainPciExpress (
5717 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
5718 IN UINT64 Address,
5719 IN UINT8 CapabilityPtr,
5720 IN CONST UINT16 EnhancedDump
5721 )
5722 {
5723 PCI_CAPABILITY_PCIEXP PciExpressCap;
5724 EFI_STATUS Status;
5725 UINT64 CapRegAddress;
5726 UINT8 Bus;
5727 UINT8 Dev;
5728 UINT8 Func;
5729 UINT8 *ExRegBuffer;
5730 UINTN ExtendRegSize;
5731 UINT64 Pciex_Address;
5732 UINT8 DevicePortType;
5733 UINTN Index;
5734 UINT8 *RegAddr;
5735 UINTN RegValue;
5736 PCI_EXP_EXT_HDR *ExtHdr;
5737
5738 CapRegAddress = Address + CapabilityPtr;
5739 IoDev->Pci.Read (
5740 IoDev,
5741 EfiPciWidthUint32,
5742 CapRegAddress,
5743 sizeof (PciExpressCap) / sizeof (UINT32),
5744 &PciExpressCap
5745 );
5746
5747 DevicePortType = (UINT8)PciExpressCap.Capability.Bits.DevicePortType;
5748
5749 ShellPrintEx (-1, -1, L"\r\nPci Express device capability structure:\r\n");
5750
5751 for (Index = 0; PcieExplainList[Index].Type < PcieExplainTypeMax; Index++) {
5752 if (ShellGetExecutionBreakFlag()) {
5753 goto Done;
5754 }
5755 RegAddr = ((UINT8 *) &PciExpressCap) + PcieExplainList[Index].Offset;
5756 switch (PcieExplainList[Index].Width) {
5757 case FieldWidthUINT8:
5758 RegValue = *(UINT8 *) RegAddr;
5759 break;
5760 case FieldWidthUINT16:
5761 RegValue = *(UINT16 *) RegAddr;
5762 break;
5763 case FieldWidthUINT32:
5764 RegValue = *(UINT32 *) RegAddr;
5765 break;
5766 default:
5767 RegValue = 0;
5768 break;
5769 }
5770 ShellPrintHiiEx(-1, -1, NULL,
5771 PcieExplainList[Index].Token,
5772 gShellDebug1HiiHandle,
5773 PcieExplainList[Index].Offset,
5774 RegValue
5775 );
5776 if (PcieExplainList[Index].Func == NULL) {
5777 continue;
5778 }
5779 switch (PcieExplainList[Index].Type) {
5780 case PcieExplainTypeLink:
5781 //
5782 // Link registers should not be used by
5783 // a) Root Complex Integrated Endpoint
5784 // b) Root Complex Event Collector
5785 //
5786 if (DevicePortType == PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_INTEGRATED_ENDPOINT ||
5787 DevicePortType == PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_EVENT_COLLECTOR) {
5788 continue;
5789 }
5790 break;
5791 case PcieExplainTypeSlot:
5792 //
5793 // Slot registers are only valid for
5794 // a) Root Port of PCI Express Root Complex
5795 // b) Downstream Port of PCI Express Switch
5796 // and when SlotImplemented bit is set in PCIE cap register.
5797 //
5798 if ((DevicePortType != PCIE_DEVICE_PORT_TYPE_ROOT_PORT &&
5799 DevicePortType != PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT) ||
5800 !PciExpressCap.Capability.Bits.SlotImplemented) {
5801 continue;
5802 }
5803 break;
5804 case PcieExplainTypeRoot:
5805 //
5806 // Root registers are only valid for
5807 // Root Port of PCI Express Root Complex
5808 //
5809 if (DevicePortType != PCIE_DEVICE_PORT_TYPE_ROOT_PORT) {
5810 continue;
5811 }
5812 break;
5813 default:
5814 break;
5815 }
5816 PcieExplainList[Index].Func (&PciExpressCap);
5817 }
5818
5819 Bus = (UINT8) (RShiftU64 (Address, 24));
5820 Dev = (UINT8) (RShiftU64 (Address, 16));
5821 Func = (UINT8) (RShiftU64 (Address, 8));
5822
5823 Pciex_Address = EFI_PCI_ADDRESS (Bus, Dev, Func, EFI_PCIE_CAPABILITY_BASE_OFFSET);
5824
5825 ExtendRegSize = 0x1000 - EFI_PCIE_CAPABILITY_BASE_OFFSET;
5826
5827 ExRegBuffer = (UINT8 *) AllocateZeroPool (ExtendRegSize);
5828
5829 //
5830 // PciRootBridgeIo protocol should support pci express extend space IO
5831 // (Begins at offset EFI_PCIE_CAPABILITY_BASE_OFFSET)
5832 //
5833 Status = IoDev->Pci.Read (
5834 IoDev,
5835 EfiPciWidthUint32,
5836 Pciex_Address,
5837 (ExtendRegSize) / sizeof (UINT32),
5838 (VOID *) (ExRegBuffer)
5839 );
5840 if (EFI_ERROR (Status) || ExRegBuffer == NULL) {
5841 SHELL_FREE_NON_NULL(ExRegBuffer);
5842 return EFI_UNSUPPORTED;
5843 }
5844
5845 ExtHdr = (PCI_EXP_EXT_HDR*)ExRegBuffer;
5846 while (ExtHdr->CapabilityId != 0 && ExtHdr->CapabilityVersion != 0) {
5847 //
5848 // Process this item
5849 //
5850 if (EnhancedDump == 0xFFFF || EnhancedDump == ExtHdr->CapabilityId) {
5851 //
5852 // Print this item
5853 //
5854 PrintPciExtendedCapabilityDetails((PCI_EXP_EXT_HDR*)ExRegBuffer, ExtHdr, &PciExpressCap);
5855 }
5856
5857 //
5858 // Advance to the next item if it exists
5859 //
5860 if (ExtHdr->NextCapabilityOffset != 0) {
5861 ExtHdr = (PCI_EXP_EXT_HDR*)((UINT8*)ExRegBuffer + ExtHdr->NextCapabilityOffset - EFI_PCIE_CAPABILITY_BASE_OFFSET);
5862 } else {
5863 break;
5864 }
5865 }
5866 SHELL_FREE_NON_NULL(ExRegBuffer);
5867
5868 Done:
5869 return EFI_SUCCESS;
5870 }