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