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