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