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