VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c@ 80721

Last change on this file since 80721 was 80721, checked in by vboxsync, 5 years ago

Devices/EFI/FirmwareNew: Start upgrade process to edk2-stable201908 (compiles on Windows and works to some extent), bugref:4643

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette