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