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