]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c
add comments to function declarations and definitions and updated to match coding...
[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] ManBus 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 BOOLEAN FoundInterface;
2468 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
2469 UINT16 MinBus;
2470 UINT16 MaxBus;
2471 BOOLEAN IsEnd;
2472
2473 FoundInterface = FALSE;
2474 //
2475 // Go through all handles, until the one meets the criteria is found
2476 //
2477 for (Index = 0; Index < HandleCount; Index++) {
2478 Status = PciGetProtocolAndResource (HandleBuf[Index], IoDev, &Descriptors);
2479 if (EFI_ERROR (Status)) {
2480 return Status;
2481 }
2482 //
2483 // When Descriptors == NULL, the Configuration() is not implemented,
2484 // so we only check the Segment number
2485 //
2486 if (Descriptors == NULL && Segment == (*IoDev)->SegmentNumber) {
2487 return EFI_SUCCESS;
2488 }
2489
2490 if ((*IoDev)->SegmentNumber != Segment) {
2491 continue;
2492 }
2493
2494 while (TRUE) {
2495 Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
2496 if (EFI_ERROR (Status)) {
2497 return Status;
2498 }
2499
2500 if (IsEnd) {
2501 break;
2502 }
2503
2504 if (MinBus <= Bus && MaxBus >= Bus) {
2505 FoundInterface = TRUE;
2506 break;
2507 }
2508 }
2509 }
2510
2511 if (FoundInterface) {
2512 return EFI_SUCCESS;
2513 } else {
2514 return EFI_INVALID_PARAMETER;
2515 }
2516 }
2517
2518 /**
2519 This function gets the protocol interface from the given handle, and
2520 obtains its address space descriptors.
2521
2522 @param[in] Handle The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle.
2523 @param[out] IoDev Handle used to access configuration space of PCI device.
2524 @param[out] Descriptors Points to the address space descriptors.
2525
2526 @retval EFI_SUCCESS The command completed successfully
2527 **/
2528 EFI_STATUS
2529 PciGetProtocolAndResource (
2530 IN EFI_HANDLE Handle,
2531 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev,
2532 OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors
2533 )
2534 {
2535 EFI_STATUS Status;
2536
2537 //
2538 // Get inferface from protocol
2539 //
2540 Status = gBS->HandleProtocol (
2541 Handle,
2542 &gEfiPciRootBridgeIoProtocolGuid,
2543 (VOID**)IoDev
2544 );
2545
2546 if (EFI_ERROR (Status)) {
2547 return Status;
2548 }
2549 //
2550 // Call Configuration() to get address space descriptors
2551 //
2552 Status = (*IoDev)->Configuration (*IoDev, (VOID**)Descriptors);
2553 if (Status == EFI_UNSUPPORTED) {
2554 *Descriptors = NULL;
2555 return EFI_SUCCESS;
2556
2557 } else {
2558 return Status;
2559 }
2560 }
2561
2562 /**
2563 This function get the next bus range of given address space descriptors.
2564 It also moves the pointer backward a node, to get prepared to be called
2565 again.
2566
2567 @param[in,out] Descriptors Points to current position of a serial of address space
2568 descriptors.
2569 @param[out] MinBus The lower range of bus number.
2570 @param[out] ManBus The upper range of bus number.
2571 @param[out] IsEnd Meet end of the serial of descriptors.
2572
2573 @retval EFI_SUCCESS The command completed successfully.
2574 **/
2575 EFI_STATUS
2576 PciGetNextBusRange (
2577 IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,
2578 OUT UINT16 *MinBus,
2579 OUT UINT16 *MaxBus,
2580 OUT BOOLEAN *IsEnd
2581 )
2582 {
2583 *IsEnd = FALSE;
2584
2585 //
2586 // When *Descriptors is NULL, Configuration() is not implemented, so assume
2587 // range is 0~PCI_MAX_BUS
2588 //
2589 if ((*Descriptors) == NULL) {
2590 *MinBus = 0;
2591 *MaxBus = PCI_MAX_BUS;
2592 return EFI_SUCCESS;
2593 }
2594 //
2595 // *Descriptors points to one or more address space descriptors, which
2596 // ends with a end tagged descriptor. Examine each of the descriptors,
2597 // if a bus typed one is found and its bus range covers bus, this handle
2598 // is the handle we are looking for.
2599 //
2600
2601 while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {
2602 if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
2603 *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;
2604 *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;
2605 (*Descriptors)++;
2606 return (EFI_SUCCESS);
2607 }
2608
2609 (*Descriptors)++;
2610 }
2611
2612 if ((*Descriptors)->Desc == ACPI_END_TAG_DESCRIPTOR) {
2613 *IsEnd = TRUE;
2614 }
2615
2616 return EFI_SUCCESS;
2617 }
2618
2619 /**
2620 Explain the data in PCI configuration space. The part which is common for
2621 PCI device and bridge is interpreted in this function. It calls other
2622 functions to interpret data unique for device or bridge.
2623
2624 @param[in] ConfigSpace Data in PCI configuration space.
2625 @param[in] Address Address used to access configuration space of this PCI device.
2626 @param[in] IoDev Handle used to access configuration space of PCI device.
2627
2628 @retval EFI_SUCCESS The command completed successfully.
2629 **/
2630 EFI_STATUS
2631 PciExplainData (
2632 IN PCI_CONFIG_SPACE *ConfigSpace,
2633 IN UINT64 Address,
2634 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
2635 )
2636 {
2637 PCI_COMMON_HEADER *Common;
2638 PCI_HEADER_TYPE HeaderType;
2639 EFI_STATUS Status;
2640 UINT8 CapPtr;
2641
2642 Common = &(ConfigSpace->Common);
2643
2644 Print (L"\n");
2645
2646 //
2647 // Print Vendor Id and Device Id
2648 //
2649 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_VID_DID), gShellDebug1HiiHandle,
2650 INDEX_OF (&(Common->VendorId)),
2651 Common->VendorId,
2652 INDEX_OF (&(Common->DeviceId)),
2653 Common->DeviceId
2654 );
2655
2656 //
2657 // Print register Command
2658 //
2659 PciExplainCommand (&(Common->Command));
2660
2661 //
2662 // Print register Status
2663 //
2664 PciExplainStatus (&(Common->Status), TRUE, PciUndefined);
2665
2666 //
2667 // Print register Revision ID
2668 //
2669 ShellPrintEx(-1, -1, L"/r/n");
2670 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_RID), gShellDebug1HiiHandle,
2671 INDEX_OF (&(Common->RevisionId)),
2672 Common->RevisionId
2673 );
2674
2675 //
2676 // Print register BIST
2677 //
2678 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_BIST), gShellDebug1HiiHandle, INDEX_OF (&(Common->Bist)));
2679 if ((Common->Bist & PCI_BIT_7) != 0) {
2680 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP), gShellDebug1HiiHandle, 0x0f & Common->Bist);
2681 } else {
2682 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP_NO), gShellDebug1HiiHandle);
2683 }
2684 //
2685 // Print register Cache Line Size
2686 //
2687 ShellPrintHiiEx(-1, -1, NULL,
2688 STRING_TOKEN (STR_PCI2_CACHE_LINE_SIZE),
2689 gShellDebug1HiiHandle,
2690 INDEX_OF (&(Common->CacheLineSize)),
2691 Common->CacheLineSize
2692 );
2693
2694 //
2695 // Print register Latency Timer
2696 //
2697 ShellPrintHiiEx(-1, -1, NULL,
2698 STRING_TOKEN (STR_PCI2_LATENCY_TIMER),
2699 gShellDebug1HiiHandle,
2700 INDEX_OF (&(Common->PrimaryLatencyTimer)),
2701 Common->PrimaryLatencyTimer
2702 );
2703
2704 //
2705 // Print register Header Type
2706 //
2707 ShellPrintHiiEx(-1, -1, NULL,
2708 STRING_TOKEN (STR_PCI2_HEADER_TYPE),
2709 gShellDebug1HiiHandle,
2710 INDEX_OF (&(Common->HeaderType)),
2711 Common->HeaderType
2712 );
2713
2714 if ((Common->HeaderType & PCI_BIT_7) != 0) {
2715 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MULTI_FUNCTION), gShellDebug1HiiHandle);
2716
2717 } else {
2718 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SINGLE_FUNCTION), gShellDebug1HiiHandle);
2719 }
2720
2721 HeaderType = (PCI_HEADER_TYPE)(UINT8) (Common->HeaderType & 0x7f);
2722 switch (HeaderType) {
2723 case PciDevice:
2724 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_PCI_DEVICE), gShellDebug1HiiHandle);
2725 break;
2726
2727 case PciP2pBridge:
2728 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_P2P_BRIDGE), gShellDebug1HiiHandle);
2729 break;
2730
2731 case PciCardBusBridge:
2732 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_BRIDGE), gShellDebug1HiiHandle);
2733 break;
2734
2735 default:
2736 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED), gShellDebug1HiiHandle);
2737 HeaderType = PciUndefined;
2738 }
2739
2740 //
2741 // Print register Class Code
2742 //
2743 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CLASS), gShellDebug1HiiHandle);
2744 PciPrintClassCode ((UINT8 *) Common->ClassCode, TRUE);
2745 Print (L"\n");
2746
2747 if (ShellGetExecutionBreakFlag()) {
2748 return EFI_SUCCESS;
2749 }
2750
2751 //
2752 // Interpret remaining part of PCI configuration header depending on
2753 // HeaderType
2754 //
2755 CapPtr = 0;
2756 Status = EFI_SUCCESS;
2757 switch (HeaderType) {
2758 case PciDevice:
2759 Status = PciExplainDeviceData (
2760 &(ConfigSpace->NonCommon.Device),
2761 Address,
2762 IoDev
2763 );
2764 CapPtr = ConfigSpace->NonCommon.Device.CapabilitiesPtr;
2765 break;
2766
2767 case PciP2pBridge:
2768 Status = PciExplainBridgeData (
2769 &(ConfigSpace->NonCommon.Bridge),
2770 Address,
2771 IoDev
2772 );
2773 CapPtr = ConfigSpace->NonCommon.Bridge.CapabilitiesPtr;
2774 break;
2775
2776 case PciCardBusBridge:
2777 Status = PciExplainCardBusData (
2778 &(ConfigSpace->NonCommon.CardBus),
2779 Address,
2780 IoDev
2781 );
2782 CapPtr = ConfigSpace->NonCommon.CardBus.CapabilitiesPtr;
2783 break;
2784 }
2785 //
2786 // If Status bit4 is 1, dump or explain capability structure
2787 //
2788 if ((Common->Status) & EFI_PCI_STATUS_CAPABILITY) {
2789 PciExplainCapabilityStruct (IoDev, Address, CapPtr);
2790 }
2791
2792 return Status;
2793 }
2794
2795 /**
2796 Explain the device specific part of data in PCI configuration space.
2797
2798 @param[in] Device Data in PCI configuration space.
2799 @param[in] Address Address used to access configuration space of this PCI device.
2800 @param[in] IoDev Handle used to access configuration space of PCI device.
2801
2802 @retval EFI_SUCCESS The command completed successfully.
2803 **/
2804 EFI_STATUS
2805 PciExplainDeviceData (
2806 IN PCI_DEVICE_HEADER *Device,
2807 IN UINT64 Address,
2808 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
2809 )
2810 {
2811 UINTN Index;
2812 BOOLEAN BarExist;
2813 EFI_STATUS Status;
2814 UINTN BarCount;
2815
2816 //
2817 // Print Base Address Registers(Bar). When Bar = 0, this Bar does not
2818 // exist. If these no Bar for this function, print "none", otherwise
2819 // list detail information about this Bar.
2820 //
2821 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDR), gShellDebug1HiiHandle, INDEX_OF (Device->Bar));
2822
2823 BarExist = FALSE;
2824 BarCount = sizeof (Device->Bar) / sizeof (Device->Bar[0]);
2825 for (Index = 0; Index < BarCount; Index++) {
2826 if (Device->Bar[Index] == 0) {
2827 continue;
2828 }
2829
2830 if (!BarExist) {
2831 BarExist = TRUE;
2832 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE), gShellDebug1HiiHandle);
2833 Print (L" --------------------------------------------------------------------------");
2834 }
2835
2836 Status = PciExplainBar (
2837 &(Device->Bar[Index]),
2838 &(mConfigSpace->Common.Command),
2839 Address,
2840 IoDev,
2841 &Index
2842 );
2843
2844 if (EFI_ERROR (Status)) {
2845 break;
2846 }
2847 }
2848
2849 if (!BarExist) {
2850 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
2851
2852 } else {
2853 Print (L"\n --------------------------------------------------------------------------");
2854 }
2855
2856 //
2857 // Print register Expansion ROM Base Address
2858 //
2859 if ((Device->ROMBar & PCI_BIT_0) == 0) {
2860 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_EXPANSION_ROM_DISABLED), gShellDebug1HiiHandle, INDEX_OF (&(Device->ROMBar)));
2861
2862 } else {
2863 ShellPrintHiiEx(-1, -1, NULL,
2864 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE),
2865 gShellDebug1HiiHandle,
2866 INDEX_OF (&(Device->ROMBar)),
2867 Device->ROMBar
2868 );
2869 }
2870 //
2871 // Print register Cardbus CIS ptr
2872 //
2873 ShellPrintHiiEx(-1, -1, NULL,
2874 STRING_TOKEN (STR_PCI2_CARDBUS_CIS),
2875 gShellDebug1HiiHandle,
2876 INDEX_OF (&(Device->CardBusCISPtr)),
2877 Device->CardBusCISPtr
2878 );
2879
2880 //
2881 // Print register Sub-vendor ID and subsystem ID
2882 //
2883 ShellPrintHiiEx(-1, -1, NULL,
2884 STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID),
2885 gShellDebug1HiiHandle,
2886 INDEX_OF (&(Device->SubVendorId)),
2887 Device->SubVendorId
2888 );
2889
2890 ShellPrintHiiEx(-1, -1, NULL,
2891 STRING_TOKEN (STR_PCI2_SUBSYSTEM_ID),
2892 gShellDebug1HiiHandle,
2893 INDEX_OF (&(Device->SubSystemId)),
2894 Device->SubSystemId
2895 );
2896
2897 //
2898 // Print register Capabilities Ptr
2899 //
2900 ShellPrintHiiEx(-1, -1, NULL,
2901 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR),
2902 gShellDebug1HiiHandle,
2903 INDEX_OF (&(Device->CapabilitiesPtr)),
2904 Device->CapabilitiesPtr
2905 );
2906
2907 //
2908 // Print register Interrupt Line and interrupt pin
2909 //
2910 ShellPrintHiiEx(-1, -1, NULL,
2911 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE),
2912 gShellDebug1HiiHandle,
2913 INDEX_OF (&(Device->InterruptLine)),
2914 Device->InterruptLine
2915 );
2916
2917 ShellPrintHiiEx(-1, -1, NULL,
2918 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
2919 gShellDebug1HiiHandle,
2920 INDEX_OF (&(Device->InterruptPin)),
2921 Device->InterruptPin
2922 );
2923
2924 //
2925 // Print register Min_Gnt and Max_Lat
2926 //
2927 ShellPrintHiiEx(-1, -1, NULL,
2928 STRING_TOKEN (STR_PCI2_MIN_GNT),
2929 gShellDebug1HiiHandle,
2930 INDEX_OF (&(Device->MinGnt)),
2931 Device->MinGnt
2932 );
2933
2934 ShellPrintHiiEx(-1, -1, NULL,
2935 STRING_TOKEN (STR_PCI2_MAX_LAT),
2936 gShellDebug1HiiHandle,
2937 INDEX_OF (&(Device->MaxLat)),
2938 Device->MaxLat
2939 );
2940
2941 return EFI_SUCCESS;
2942 }
2943
2944 /**
2945 Explain the bridge specific part of data in PCI configuration space.
2946
2947 @param[in] Bridge Bridge specific data region in PCI configuration space.
2948 @param[in] Address Address used to access configuration space of this PCI device.
2949 @param[in] IoDev Handle used to access configuration space of PCI device.
2950
2951 @retval EFI_SUCCESS The command completed successfully.
2952 **/
2953 EFI_STATUS
2954 PciExplainBridgeData (
2955 IN PCI_BRIDGE_HEADER *Bridge,
2956 IN UINT64 Address,
2957 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
2958 )
2959 {
2960 UINTN Index;
2961 BOOLEAN BarExist;
2962 UINTN BarCount;
2963 UINT32 IoAddress32;
2964 EFI_STATUS Status;
2965
2966 //
2967 // Print Base Address Registers. When Bar = 0, this Bar does not
2968 // exist. If these no Bar for this function, print "none", otherwise
2969 // list detail information about this Bar.
2970 //
2971 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDRESS), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->Bar)));
2972
2973 BarExist = FALSE;
2974 BarCount = sizeof (Bridge->Bar) / sizeof (Bridge->Bar[0]);
2975
2976 for (Index = 0; Index < BarCount; Index++) {
2977 if (Bridge->Bar[Index] == 0) {
2978 continue;
2979 }
2980
2981 if (!BarExist) {
2982 BarExist = TRUE;
2983 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE_2), gShellDebug1HiiHandle);
2984 Print (L" --------------------------------------------------------------------------");
2985 }
2986
2987 Status = PciExplainBar (
2988 &(Bridge->Bar[Index]),
2989 &(mConfigSpace->Common.Command),
2990 Address,
2991 IoDev,
2992 &Index
2993 );
2994
2995 if (EFI_ERROR (Status)) {
2996 break;
2997 }
2998 }
2999
3000 if (!BarExist) {
3001 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
3002 } else {
3003 Print (L"\n --------------------------------------------------------------------------");
3004 }
3005
3006 //
3007 // Expansion register ROM Base Address
3008 //
3009 if ((Bridge->ROMBar & PCI_BIT_0) == 0) {
3010 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO_EXPANSION_ROM), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->ROMBar)));
3011
3012 } else {
3013 ShellPrintHiiEx(-1, -1, NULL,
3014 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE_2),
3015 gShellDebug1HiiHandle,
3016 INDEX_OF (&(Bridge->ROMBar)),
3017 Bridge->ROMBar
3018 );
3019 }
3020 //
3021 // Print Bus Numbers(Primary, Secondary, and Subordinate
3022 //
3023 ShellPrintHiiEx(-1, -1, NULL,
3024 STRING_TOKEN (STR_PCI2_BUS_NUMBERS),
3025 gShellDebug1HiiHandle,
3026 INDEX_OF (&(Bridge->PrimaryBus)),
3027 INDEX_OF (&(Bridge->SecondaryBus)),
3028 INDEX_OF (&(Bridge->SubordinateBus))
3029 );
3030
3031 Print (L" ------------------------------------------------------\n");
3032
3033 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->PrimaryBus);
3034 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SecondaryBus);
3035 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SubordinateBus);
3036
3037 //
3038 // Print register Secondary Latency Timer
3039 //
3040 ShellPrintHiiEx(-1, -1, NULL,
3041 STRING_TOKEN (STR_PCI2_SECONDARY_TIMER),
3042 gShellDebug1HiiHandle,
3043 INDEX_OF (&(Bridge->SecondaryLatencyTimer)),
3044 Bridge->SecondaryLatencyTimer
3045 );
3046
3047 //
3048 // Print register Secondary Status
3049 //
3050 PciExplainStatus (&(Bridge->SecondaryStatus), FALSE, PciP2pBridge);
3051
3052 //
3053 // Print I/O and memory ranges this bridge forwards. There are 3 resource
3054 // types: I/O, memory, and pre-fetchable memory. For each resource type,
3055 // base and limit address are listed.
3056 //
3057 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE), gShellDebug1HiiHandle);
3058 Print (L"----------------------------------------------------------------------\n");
3059
3060 //
3061 // IO Base & Limit
3062 //
3063 IoAddress32 = (Bridge->IoBaseUpper << 16 | Bridge->IoBase << 8);
3064 IoAddress32 &= 0xfffff000;
3065 ShellPrintHiiEx(-1, -1, NULL,
3066 STRING_TOKEN (STR_PCI2_TWO_VARS),
3067 gShellDebug1HiiHandle,
3068 INDEX_OF (&(Bridge->IoBase)),
3069 IoAddress32
3070 );
3071
3072 IoAddress32 = (Bridge->IoLimitUpper << 16 | Bridge->IoLimit << 8);
3073 IoAddress32 |= 0x00000fff;
3074 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR), gShellDebug1HiiHandle, IoAddress32);
3075
3076 //
3077 // Memory Base & Limit
3078 //
3079 ShellPrintHiiEx(-1, -1, NULL,
3080 STRING_TOKEN (STR_PCI2_MEMORY),
3081 gShellDebug1HiiHandle,
3082 INDEX_OF (&(Bridge->MemoryBase)),
3083 (Bridge->MemoryBase << 16) & 0xfff00000
3084 );
3085
3086 ShellPrintHiiEx(-1, -1, NULL,
3087 STRING_TOKEN (STR_PCI2_ONE_VAR),
3088 gShellDebug1HiiHandle,
3089 (Bridge->MemoryLimit << 16) | 0x000fffff
3090 );
3091
3092 //
3093 // Pre-fetch-able Memory Base & Limit
3094 //
3095 ShellPrintHiiEx(-1, -1, NULL,
3096 STRING_TOKEN (STR_PCI2_PREFETCHABLE),
3097 gShellDebug1HiiHandle,
3098 INDEX_OF (&(Bridge->PrefetchableMemBase)),
3099 Bridge->PrefetchableBaseUpper,
3100 (Bridge->PrefetchableMemBase << 16) & 0xfff00000
3101 );
3102
3103 ShellPrintHiiEx(-1, -1, NULL,
3104 STRING_TOKEN (STR_PCI2_TWO_VARS_2),
3105 gShellDebug1HiiHandle,
3106 Bridge->PrefetchableLimitUpper,
3107 (Bridge->PrefetchableMemLimit << 16) | 0x000fffff
3108 );
3109
3110 //
3111 // Print register Capabilities Pointer
3112 //
3113 ShellPrintHiiEx(-1, -1, NULL,
3114 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR_2),
3115 gShellDebug1HiiHandle,
3116 INDEX_OF (&(Bridge->CapabilitiesPtr)),
3117 Bridge->CapabilitiesPtr
3118 );
3119
3120 //
3121 // Print register Bridge Control
3122 //
3123 PciExplainBridgeControl (&(Bridge->BridgeControl), PciP2pBridge);
3124
3125 //
3126 // Print register Interrupt Line & PIN
3127 //
3128 ShellPrintHiiEx(-1, -1, NULL,
3129 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_2),
3130 gShellDebug1HiiHandle,
3131 INDEX_OF (&(Bridge->InterruptLine)),
3132 Bridge->InterruptLine
3133 );
3134
3135 ShellPrintHiiEx(-1, -1, NULL,
3136 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
3137 gShellDebug1HiiHandle,
3138 INDEX_OF (&(Bridge->InterruptPin)),
3139 Bridge->InterruptPin
3140 );
3141
3142 return EFI_SUCCESS;
3143 }
3144
3145 /**
3146 Explain the Base Address Register(Bar) in PCI configuration space.
3147
3148 @param[in] Bar Points to the Base Address Register intended to interpret.
3149 @param[in] Command Points to the register Command.
3150 @param[in] Address Address used to access configuration space of this PCI device.
3151 @param[in] IoDev Handle used to access configuration space of PCI device.
3152 @param[in,out] Index The Index.
3153
3154 @retval EFI_SUCCESS The command completed successfully.
3155 **/
3156 EFI_STATUS
3157 PciExplainBar (
3158 IN UINT32 *Bar,
3159 IN UINT16 *Command,
3160 IN UINT64 Address,
3161 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
3162 IN OUT UINTN *Index
3163 )
3164 {
3165 UINT16 OldCommand;
3166 UINT16 NewCommand;
3167 UINT64 Bar64;
3168 UINT32 OldBar32;
3169 UINT32 NewBar32;
3170 UINT64 OldBar64;
3171 UINT64 NewBar64;
3172 BOOLEAN IsMem;
3173 BOOLEAN IsBar32;
3174 UINT64 RegAddress;
3175
3176 IsBar32 = TRUE;
3177 Bar64 = 0;
3178 NewBar32 = 0;
3179 NewBar64 = 0;
3180
3181 //
3182 // According the bar type, list detail about this bar, for example: 32 or
3183 // 64 bits; pre-fetchable or not.
3184 //
3185 if ((*Bar & PCI_BIT_0) == 0) {
3186 //
3187 // This bar is of memory type
3188 //
3189 IsMem = TRUE;
3190
3191 if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) == 0) {
3192 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
3193 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
3194 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_32_BITS), gShellDebug1HiiHandle);
3195
3196 } else if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) != 0) {
3197 Bar64 = 0x0;
3198 CopyMem (&Bar64, Bar, sizeof (UINT64));
3199 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_2), gShellDebug1HiiHandle, RShiftU64 ((Bar64 & 0xfffffffffffffff0), 32));
3200 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_3), gShellDebug1HiiHandle, (UINT32) (Bar64 & 0xfffffffffffffff0));
3201 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
3202 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_64_BITS), gShellDebug1HiiHandle);
3203 IsBar32 = FALSE;
3204 *Index += 1;
3205
3206 } else {
3207 //
3208 // Reserved
3209 //
3210 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
3211 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM_2), gShellDebug1HiiHandle);
3212 }
3213
3214 if ((*Bar & PCI_BIT_3) == 0) {
3215 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO), gShellDebug1HiiHandle);
3216
3217 } else {
3218 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_YES), gShellDebug1HiiHandle);
3219 }
3220
3221 } else {
3222 //
3223 // This bar is of io type
3224 //
3225 IsMem = FALSE;
3226 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_4), gShellDebug1HiiHandle, *Bar & 0xfffffffc);
3227 Print (L"I/O ");
3228 }
3229
3230 //
3231 // Get BAR length(or the amount of resource this bar demands for). To get
3232 // Bar length, first we should temporarily disable I/O and memory access
3233 // of this function(by set bits in the register Command), then write all
3234 // "1"s to this bar. The bar value read back is the amount of resource
3235 // this bar demands for.
3236 //
3237 //
3238 // Disable io & mem access
3239 //
3240 OldCommand = *Command;
3241 NewCommand = (UINT16) (OldCommand & 0xfffc);
3242 RegAddress = Address | INDEX_OF (Command);
3243 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &NewCommand);
3244
3245 RegAddress = Address | INDEX_OF (Bar);
3246
3247 //
3248 // Read after write the BAR to get the size
3249 //
3250 if (IsBar32) {
3251 OldBar32 = *Bar;
3252 NewBar32 = 0xffffffff;
3253
3254 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
3255 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
3256 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &OldBar32);
3257
3258 if (IsMem) {
3259 NewBar32 = NewBar32 & 0xfffffff0;
3260 NewBar32 = (~NewBar32) + 1;
3261
3262 } else {
3263 NewBar32 = NewBar32 & 0xfffffffc;
3264 NewBar32 = (~NewBar32) + 1;
3265 NewBar32 = NewBar32 & 0x0000ffff;
3266 }
3267 } else {
3268
3269 OldBar64 = 0x0;
3270 CopyMem (&OldBar64, Bar, sizeof (UINT64));
3271 NewBar64 = 0xffffffffffffffff;
3272
3273 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
3274 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
3275 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &OldBar64);
3276
3277 if (IsMem) {
3278 NewBar64 = NewBar64 & 0xfffffffffffffff0;
3279 NewBar64 = (~NewBar64) + 1;
3280
3281 } else {
3282 NewBar64 = NewBar64 & 0xfffffffffffffffc;
3283 NewBar64 = (~NewBar64) + 1;
3284 NewBar64 = NewBar64 & 0x000000000000ffff;
3285 }
3286 }
3287 //
3288 // Enable io & mem access
3289 //
3290 RegAddress = Address | INDEX_OF (Command);
3291 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &OldCommand);
3292
3293 if (IsMem) {
3294 if (IsBar32) {
3295 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32), gShellDebug1HiiHandle, NewBar32);
3296 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_2), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffff0) - 1);
3297
3298 } else {
3299 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, RShiftU64 (NewBar64, 32));
3300 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) NewBar64);
3301 Print (L" ");
3302 ShellPrintHiiEx(-1, -1, NULL,
3303 STRING_TOKEN (STR_PCI2_RSHIFT),
3304 gShellDebug1HiiHandle,
3305 RShiftU64 ((NewBar64 + (Bar64 & 0xfffffffffffffff0) - 1), 32)
3306 );
3307 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) (NewBar64 + (Bar64 & 0xfffffffffffffff0) - 1));
3308
3309 }
3310 } else {
3311 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_3), gShellDebug1HiiHandle, NewBar32);
3312 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_4), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffffc) - 1);
3313 }
3314
3315 return EFI_SUCCESS;
3316 }
3317
3318 /**
3319 Explain the cardbus specific part of data in PCI configuration space.
3320
3321 @param[in] CardBus CardBus specific region of PCI configuration space.
3322 @param[in] Address Address used to access configuration space of this PCI device.
3323 @param[in] IoDev Handle used to access configuration space of PCI device.
3324
3325 @retval EFI_SUCCESS The command completed successfully.
3326 **/
3327 EFI_STATUS
3328 PciExplainCardBusData (
3329 IN PCI_CARDBUS_HEADER *CardBus,
3330 IN UINT64 Address,
3331 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
3332 )
3333 {
3334 BOOLEAN Io32Bit;
3335 PCI_CARDBUS_DATA *CardBusData;
3336
3337 ShellPrintHiiEx(-1, -1, NULL,
3338 STRING_TOKEN (STR_PCI2_CARDBUS_SOCKET),
3339 gShellDebug1HiiHandle,
3340 INDEX_OF (&(CardBus->CardBusSocketReg)),
3341 CardBus->CardBusSocketReg
3342 );
3343
3344 //
3345 // Print Secondary Status
3346 //
3347 PciExplainStatus (&(CardBus->SecondaryStatus), FALSE, PciCardBusBridge);
3348
3349 //
3350 // Print Bus Numbers(Primary bus number, CardBus bus number, and
3351 // Subordinate bus number
3352 //
3353 ShellPrintHiiEx(-1, -1, NULL,
3354 STRING_TOKEN (STR_PCI2_BUS_NUMBERS_2),
3355 gShellDebug1HiiHandle,
3356 INDEX_OF (&(CardBus->PciBusNumber)),
3357 INDEX_OF (&(CardBus->CardBusBusNumber)),
3358 INDEX_OF (&(CardBus->SubordinateBusNumber))
3359 );
3360
3361 Print (L" ------------------------------------------------------\n");
3362
3363 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS), gShellDebug1HiiHandle, CardBus->PciBusNumber);
3364 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_2), gShellDebug1HiiHandle, CardBus->CardBusBusNumber);
3365 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_3), gShellDebug1HiiHandle, CardBus->SubordinateBusNumber);
3366
3367 //
3368 // Print CardBus Latency Timer
3369 //
3370 ShellPrintHiiEx(-1, -1, NULL,
3371 STRING_TOKEN (STR_PCI2_CARDBUS_LATENCY),
3372 gShellDebug1HiiHandle,
3373 INDEX_OF (&(CardBus->CardBusLatencyTimer)),
3374 CardBus->CardBusLatencyTimer
3375 );
3376
3377 //
3378 // Print Memory/Io ranges this cardbus bridge forwards
3379 //
3380 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE_2), gShellDebug1HiiHandle);
3381 Print (L"----------------------------------------------------------------------\n");
3382
3383 ShellPrintHiiEx(-1, -1, NULL,
3384 STRING_TOKEN (STR_PCI2_MEM_3),
3385 gShellDebug1HiiHandle,
3386 INDEX_OF (&(CardBus->MemoryBase0)),
3387 CardBus->BridgeControl & PCI_BIT_8 ? L" Prefetchable" : L"Non-Prefetchable",
3388 CardBus->MemoryBase0 & 0xfffff000,
3389 CardBus->MemoryLimit0 | 0x00000fff
3390 );
3391
3392 ShellPrintHiiEx(-1, -1, NULL,
3393 STRING_TOKEN (STR_PCI2_MEM_3),
3394 gShellDebug1HiiHandle,
3395 INDEX_OF (&(CardBus->MemoryBase1)),
3396 CardBus->BridgeControl & PCI_BIT_9 ? L" Prefetchable" : L"Non-Prefetchable",
3397 CardBus->MemoryBase1 & 0xfffff000,
3398 CardBus->MemoryLimit1 | 0x00000fff
3399 );
3400
3401 Io32Bit = (BOOLEAN) (CardBus->IoBase0 & PCI_BIT_0);
3402 ShellPrintHiiEx(-1, -1, NULL,
3403 STRING_TOKEN (STR_PCI2_IO_2),
3404 gShellDebug1HiiHandle,
3405 INDEX_OF (&(CardBus->IoBase0)),
3406 Io32Bit ? L" 32 bit" : L" 16 bit",
3407 CardBus->IoBase0 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
3408 CardBus->IoLimit0 & (Io32Bit ? 0xffffffff : 0x0000ffff) | 0x00000003
3409 );
3410
3411 Io32Bit = (BOOLEAN) (CardBus->IoBase1 & PCI_BIT_0);
3412 ShellPrintHiiEx(-1, -1, NULL,
3413 STRING_TOKEN (STR_PCI2_IO_2),
3414 gShellDebug1HiiHandle,
3415 INDEX_OF (&(CardBus->IoBase1)),
3416 Io32Bit ? L" 32 bit" : L" 16 bit",
3417 CardBus->IoBase1 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
3418 CardBus->IoLimit1 & (Io32Bit ? 0xffffffff : 0x0000ffff) | 0x00000003
3419 );
3420
3421 //
3422 // Print register Interrupt Line & PIN
3423 //
3424 ShellPrintHiiEx(-1, -1, NULL,
3425 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_3),
3426 gShellDebug1HiiHandle,
3427 INDEX_OF (&(CardBus->InterruptLine)),
3428 CardBus->InterruptLine,
3429 INDEX_OF (&(CardBus->InterruptPin)),
3430 CardBus->InterruptPin
3431 );
3432
3433 //
3434 // Print register Bridge Control
3435 //
3436 PciExplainBridgeControl (&(CardBus->BridgeControl), PciCardBusBridge);
3437
3438 //
3439 // Print some registers in data region of PCI configuration space for cardbus
3440 // bridge. Fields include: Sub VendorId, Subsystem ID, and Legacy Mode Base
3441 // Address.
3442 //
3443 CardBusData = (PCI_CARDBUS_DATA *) ((UINT8 *) CardBus + sizeof (PCI_CARDBUS_HEADER));
3444
3445 ShellPrintHiiEx(-1, -1, NULL,
3446 STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID_2),
3447 gShellDebug1HiiHandle,
3448 INDEX_OF (&(CardBusData->SubVendorId)),
3449 CardBusData->SubVendorId,
3450 INDEX_OF (&(CardBusData->SubSystemId)),
3451 CardBusData->SubSystemId
3452 );
3453
3454 ShellPrintHiiEx(-1, -1, NULL,
3455 STRING_TOKEN (STR_PCI2_OPTIONAL),
3456 gShellDebug1HiiHandle,
3457 INDEX_OF (&(CardBusData->LegacyBase)),
3458 CardBusData->LegacyBase
3459 );
3460
3461 return EFI_SUCCESS;
3462 }
3463
3464 /**
3465 Explain each meaningful bit of register Status. The definition of Status is
3466 slightly different depending on the PCI header type.
3467
3468 @param[in] Status Points to the content of register Status.
3469 @param[in] MainStatus Indicates if this register is main status(not secondary
3470 status).
3471 @param[in] HeaderType Header type of this PCI device.
3472
3473 @retval EFI_SUCCESS The command completed successfully.
3474 **/
3475 EFI_STATUS
3476 PciExplainStatus (
3477 IN UINT16 *Status,
3478 IN BOOLEAN MainStatus,
3479 IN PCI_HEADER_TYPE HeaderType
3480 )
3481 {
3482 if (MainStatus) {
3483 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status);
3484
3485 } else {
3486 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SECONDARY_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status);
3487 }
3488
3489 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEW_CAPABILITIES), gShellDebug1HiiHandle, (*Status & PCI_BIT_4) != 0);
3490
3491 //
3492 // Bit 5 is meaningless for CardBus Bridge
3493 //
3494 if (HeaderType == PciCardBusBridge) {
3495 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE), gShellDebug1HiiHandle, (*Status & PCI_BIT_5) != 0);
3496
3497 } else {
3498 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE_2), gShellDebug1HiiHandle, (*Status & PCI_BIT_5) != 0);
3499 }
3500
3501 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST_BACK), gShellDebug1HiiHandle, (*Status & PCI_BIT_7) != 0);
3502
3503 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MASTER_DATA), gShellDebug1HiiHandle, (*Status & PCI_BIT_8) != 0);
3504 //
3505 // Bit 9 and bit 10 together decides the DEVSEL timing
3506 //
3507 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_DEVSEL_TIMING), gShellDebug1HiiHandle);
3508 if ((*Status & PCI_BIT_9) == 0 && (*Status & PCI_BIT_10) == 0) {
3509 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST), gShellDebug1HiiHandle);
3510
3511 } else if ((*Status & PCI_BIT_9) != 0 && (*Status & PCI_BIT_10) == 0) {
3512 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEDIUM), gShellDebug1HiiHandle);
3513
3514 } else if ((*Status & PCI_BIT_9) == 0 && (*Status & PCI_BIT_10) != 0) {
3515 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SLOW), gShellDebug1HiiHandle);
3516
3517 } else {
3518 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED_2), gShellDebug1HiiHandle);
3519 }
3520
3521 ShellPrintHiiEx(-1, -1, NULL,
3522 STRING_TOKEN (STR_PCI2_SIGNALED_TARGET),
3523 gShellDebug1HiiHandle,
3524 (*Status & PCI_BIT_11) != 0
3525 );
3526
3527 ShellPrintHiiEx(-1, -1, NULL,
3528 STRING_TOKEN (STR_PCI2_RECEIVED_TARGET),
3529 gShellDebug1HiiHandle,
3530 (*Status & PCI_BIT_12) != 0
3531 );
3532
3533 ShellPrintHiiEx(-1, -1, NULL,
3534 STRING_TOKEN (STR_PCI2_RECEIVED_MASTER),
3535 gShellDebug1HiiHandle,
3536 (*Status & PCI_BIT_13) != 0
3537 );
3538
3539 if (MainStatus) {
3540 ShellPrintHiiEx(-1, -1, NULL,
3541 STRING_TOKEN (STR_PCI2_SIGNALED_ERROR),
3542 gShellDebug1HiiHandle,
3543 (*Status & PCI_BIT_14) != 0
3544 );
3545
3546 } else {
3547 ShellPrintHiiEx(-1, -1, NULL,
3548 STRING_TOKEN (STR_PCI2_RECEIVED_ERROR),
3549 gShellDebug1HiiHandle,
3550 (*Status & PCI_BIT_14) != 0
3551 );
3552 }
3553
3554 ShellPrintHiiEx(-1, -1, NULL,
3555 STRING_TOKEN (STR_PCI2_DETECTED_ERROR),
3556 gShellDebug1HiiHandle,
3557 (*Status & PCI_BIT_15) != 0
3558 );
3559
3560 return EFI_SUCCESS;
3561 }
3562
3563 /**
3564 Explain each meaningful bit of register Command.
3565
3566 @param[in] Command Points to the content of register Command.
3567
3568 @retval EFI_SUCCESS The command completed successfully.
3569 **/
3570 EFI_STATUS
3571 PciExplainCommand (
3572 IN UINT16 *Command
3573 )
3574 {
3575 //
3576 // Print the binary value of register Command
3577 //
3578 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_COMMAND), gShellDebug1HiiHandle, INDEX_OF (Command), *Command);
3579
3580 //
3581 // Explain register Command bit by bit
3582 //
3583 ShellPrintHiiEx(-1, -1, NULL,
3584 STRING_TOKEN (STR_PCI2_SPACE_ACCESS_DENIED),
3585 gShellDebug1HiiHandle,
3586 (*Command & PCI_BIT_0) != 0
3587 );
3588
3589 ShellPrintHiiEx(-1, -1, NULL,
3590 STRING_TOKEN (STR_PCI2_MEMORY_SPACE),
3591 gShellDebug1HiiHandle,
3592 (*Command & PCI_BIT_1) != 0
3593 );
3594
3595 ShellPrintHiiEx(-1, -1, NULL,
3596 STRING_TOKEN (STR_PCI2_BEHAVE_BUS_MASTER),
3597 gShellDebug1HiiHandle,
3598 (*Command & PCI_BIT_2) != 0
3599 );
3600
3601 ShellPrintHiiEx(-1, -1, NULL,
3602 STRING_TOKEN (STR_PCI2_MONITOR_SPECIAL_CYCLE),
3603 gShellDebug1HiiHandle,
3604 (*Command & PCI_BIT_3) != 0
3605 );
3606
3607 ShellPrintHiiEx(-1, -1, NULL,
3608 STRING_TOKEN (STR_PCI2_MEM_WRITE_INVALIDATE),
3609 gShellDebug1HiiHandle,
3610 (*Command & PCI_BIT_4) != 0
3611 );
3612
3613 ShellPrintHiiEx(-1, -1, NULL,
3614 STRING_TOKEN (STR_PCI2_PALETTE_SNOOPING),
3615 gShellDebug1HiiHandle,
3616 (*Command & PCI_BIT_5) != 0
3617 );
3618
3619 ShellPrintHiiEx(-1, -1, NULL,
3620 STRING_TOKEN (STR_PCI2_ASSERT_PERR),
3621 gShellDebug1HiiHandle,
3622 (*Command & PCI_BIT_6) != 0
3623 );
3624
3625 ShellPrintHiiEx(-1, -1, NULL,
3626 STRING_TOKEN (STR_PCI2_DO_ADDR_STEPPING),
3627 gShellDebug1HiiHandle,
3628 (*Command & PCI_BIT_7) != 0
3629 );
3630
3631 ShellPrintHiiEx(-1, -1, NULL,
3632 STRING_TOKEN (STR_PCI2_SERR_DRIVER),
3633 gShellDebug1HiiHandle,
3634 (*Command & PCI_BIT_8) != 0
3635 );
3636
3637 ShellPrintHiiEx(-1, -1, NULL,
3638 STRING_TOKEN (STR_PCI2_FAST_BACK_2),
3639 gShellDebug1HiiHandle,
3640 (*Command & PCI_BIT_9) != 0
3641 );
3642
3643 return EFI_SUCCESS;
3644 }
3645
3646 /**
3647 Explain each meaningful bit of register Bridge Control.
3648
3649 @param[in] BridgeControl Points to the content of register Bridge Control.
3650 @param[in] HeaderType The headertype.
3651
3652 @retval EFI_SUCCESS The command completed successfully.
3653 **/
3654 EFI_STATUS
3655 PciExplainBridgeControl (
3656 IN UINT16 *BridgeControl,
3657 IN PCI_HEADER_TYPE HeaderType
3658 )
3659 {
3660 ShellPrintHiiEx(-1, -1, NULL,
3661 STRING_TOKEN (STR_PCI2_BRIDGE_CONTROL),
3662 gShellDebug1HiiHandle,
3663 INDEX_OF (BridgeControl),
3664 *BridgeControl
3665 );
3666
3667 ShellPrintHiiEx(-1, -1, NULL,
3668 STRING_TOKEN (STR_PCI2_PARITY_ERROR),
3669 gShellDebug1HiiHandle,
3670 (*BridgeControl & PCI_BIT_0) != 0
3671 );
3672 ShellPrintHiiEx(-1, -1, NULL,
3673 STRING_TOKEN (STR_PCI2_SERR_ENABLE),
3674 gShellDebug1HiiHandle,
3675 (*BridgeControl & PCI_BIT_1) != 0
3676 );
3677 ShellPrintHiiEx(-1, -1, NULL,
3678 STRING_TOKEN (STR_PCI2_ISA_ENABLE),
3679 gShellDebug1HiiHandle,
3680 (*BridgeControl & PCI_BIT_2) != 0
3681 );
3682 ShellPrintHiiEx(-1, -1, NULL,
3683 STRING_TOKEN (STR_PCI2_VGA_ENABLE),
3684 gShellDebug1HiiHandle,
3685 (*BridgeControl & PCI_BIT_3) != 0
3686 );
3687 ShellPrintHiiEx(-1, -1, NULL,
3688 STRING_TOKEN (STR_PCI2_MASTER_ABORT),
3689 gShellDebug1HiiHandle,
3690 (*BridgeControl & PCI_BIT_5) != 0
3691 );
3692
3693 //
3694 // Register Bridge Control has some slight differences between P2P bridge
3695 // and Cardbus bridge from bit 6 to bit 11.
3696 //
3697 if (HeaderType == PciP2pBridge) {
3698 ShellPrintHiiEx(-1, -1, NULL,
3699 STRING_TOKEN (STR_PCI2_SECONDARY_BUS_RESET),
3700 gShellDebug1HiiHandle,
3701 (*BridgeControl & PCI_BIT_6) != 0
3702 );
3703 ShellPrintHiiEx(-1, -1, NULL,
3704 STRING_TOKEN (STR_PCI2_FAST_ENABLE),
3705 gShellDebug1HiiHandle,
3706 (*BridgeControl & PCI_BIT_7) != 0
3707 );
3708 ShellPrintHiiEx(-1, -1, NULL,
3709 STRING_TOKEN (STR_PCI2_PRIMARY_DISCARD_TIMER),
3710 gShellDebug1HiiHandle,
3711 (*BridgeControl & PCI_BIT_8)!=0 ? L"2^10" : L"2^15"
3712 );
3713 ShellPrintHiiEx(-1, -1, NULL,
3714 STRING_TOKEN (STR_PCI2_SECONDARY_DISCARD_TIMER),
3715 gShellDebug1HiiHandle,
3716 (*BridgeControl & PCI_BIT_9)!=0 ? L"2^10" : L"2^15"
3717 );
3718 ShellPrintHiiEx(-1, -1, NULL,
3719 STRING_TOKEN (STR_PCI2_DISCARD_TIMER_STATUS),
3720 gShellDebug1HiiHandle,
3721 (*BridgeControl & PCI_BIT_10) != 0
3722 );
3723 ShellPrintHiiEx(-1, -1, NULL,
3724 STRING_TOKEN (STR_PCI2_DISCARD_TIMER_SERR),
3725 gShellDebug1HiiHandle,
3726 (*BridgeControl & PCI_BIT_11) != 0
3727 );
3728
3729 } else {
3730 ShellPrintHiiEx(-1, -1, NULL,
3731 STRING_TOKEN (STR_PCI2_CARDBUS_RESET),
3732 gShellDebug1HiiHandle,
3733 (*BridgeControl & PCI_BIT_6) != 0
3734 );
3735 ShellPrintHiiEx(-1, -1, NULL,
3736 STRING_TOKEN (STR_PCI2_IREQ_ENABLE),
3737 gShellDebug1HiiHandle,
3738 (*BridgeControl & PCI_BIT_7) != 0
3739 );
3740 ShellPrintHiiEx(-1, -1, NULL,
3741 STRING_TOKEN (STR_PCI2_WRITE_POSTING_ENABLE),
3742 gShellDebug1HiiHandle,
3743 (*BridgeControl & PCI_BIT_10) != 0
3744 );
3745 }
3746
3747 return EFI_SUCCESS;
3748 }
3749
3750 /**
3751 Print each capability structure.
3752
3753 @param[in] IoDev The pointer to the deivce.
3754 @param[in] Address The address to start at.
3755 @param[in] CapPtr The offset from the address.
3756
3757 @retval EFI_SUCCESS The operation was successful.
3758 **/
3759 EFI_STATUS
3760 PciExplainCapabilityStruct (
3761 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
3762 IN UINT64 Address,
3763 IN UINT8 CapPtr
3764 )
3765 {
3766 UINT8 CapabilityPtr;
3767 UINT16 CapabilityEntry;
3768 UINT8 CapabilityID;
3769 UINT64 RegAddress;
3770
3771 CapabilityPtr = CapPtr;
3772
3773 //
3774 // Go through the Capability list
3775 //
3776 while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) {
3777 RegAddress = Address + CapabilityPtr;
3778 IoDev->Pci.Read (IoDev, EfiPciWidthUint16, RegAddress, 1, &CapabilityEntry);
3779
3780 CapabilityID = (UINT8) CapabilityEntry;
3781
3782 //
3783 // Explain PciExpress data
3784 //
3785 if (EFI_PCI_CAPABILITY_ID_PCIEXP == CapabilityID) {
3786 PciExplainPciExpress (IoDev, Address, CapabilityPtr);
3787 return EFI_SUCCESS;
3788 }
3789 //
3790 // Explain other capabilities here
3791 //
3792 CapabilityPtr = (UINT8) (CapabilityEntry >> 8);
3793 }
3794
3795 return EFI_SUCCESS;
3796 }
3797
3798 /**
3799 Print out information of the capability information.
3800
3801 @param[in] PciExpressCap The pointer to the structure about the device.
3802
3803 @retval EFI_SUCCESS The operation was successful.
3804 **/
3805 EFI_STATUS
3806 ExplainPcieCapReg (
3807 IN PCIE_CAP_STURCTURE *PciExpressCap
3808 )
3809 {
3810 UINT16 PcieCapReg;
3811 CHAR16 *DevicePortType;
3812
3813 PcieCapReg = PciExpressCap->PcieCapReg;
3814 Print (
3815 L" Capability Version(3:0): %E0x%04x%N\n",
3816 PCIE_CAP_VERSION (PcieCapReg)
3817 );
3818 if ((UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) < PCIE_DEVICE_PORT_TYPE_MAX) {
3819 DevicePortType = DevicePortTypeTable[PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg)];
3820 } else {
3821 DevicePortType = L"Unknown Type";
3822 }
3823 Print (
3824 L" Device/PortType(7:4): %E%s%N\n",
3825 DevicePortType
3826 );
3827 //
3828 // 'Slot Implemented' is only valid for:
3829 // a) Root Port of PCI Express Root Complex, or
3830 // b) Downstream Port of PCI Express Switch
3831 //
3832 if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_ROOT_COMPLEX_ROOT_PORT ||
3833 PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_SWITCH_DOWNSTREAM_PORT) {
3834 Print (
3835 L" Slot Implemented(8): %E%d%N\n",
3836 PCIE_CAP_SLOT_IMPLEMENTED (PcieCapReg)
3837 );
3838 }
3839 Print (
3840 L" Interrupt Message Number(13:9): %E0x%05x%N\n",
3841 PCIE_CAP_INT_MSG_NUM (PcieCapReg)
3842 );
3843 return EFI_SUCCESS;
3844 }
3845
3846 /**
3847 Print out information of the device capability information.
3848
3849 @param[in] PciExpressCap The pointer to the structure about the device.
3850
3851 @retval EFI_SUCCESS The operation was successful.
3852 **/
3853 EFI_STATUS
3854 ExplainPcieDeviceCap (
3855 IN PCIE_CAP_STURCTURE *PciExpressCap
3856 )
3857 {
3858 UINT16 PcieCapReg;
3859 UINT32 PcieDeviceCap;
3860 UINT8 DevicePortType;
3861 UINT8 L0sLatency;
3862 UINT8 L1Latency;
3863
3864 PcieCapReg = PciExpressCap->PcieCapReg;
3865 PcieDeviceCap = PciExpressCap->PcieDeviceCap;
3866 DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg);
3867 Print (L" Max_Payload_Size Supported(2:0): ");
3868 if (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) < 6) {
3869 Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) + 7));
3870 } else {
3871 Print (L"%EUnknown%N\n");
3872 }
3873 Print (
3874 L" Phantom Functions Supported(4:3): %E%d%N\n",
3875 PCIE_CAP_PHANTOM_FUNC (PcieDeviceCap)
3876 );
3877 Print (
3878 L" Extended Tag Field Supported(5): %E%d-bit Tag field supported%N\n",
3879 PCIE_CAP_EXTENDED_TAG (PcieDeviceCap) ? 8 : 5
3880 );
3881 //
3882 // Endpoint L0s and L1 Acceptable Latency is only valid for Endpoint
3883 //
3884 if (IS_PCIE_ENDPOINT (DevicePortType)) {
3885 L0sLatency = (UINT8) PCIE_CAP_L0SLATENCY (PcieDeviceCap);
3886 L1Latency = (UINT8) PCIE_CAP_L1LATENCY (PcieDeviceCap);
3887 Print (L" Endpoint L0s Acceptable Latency(8:6): ");
3888 if (L0sLatency < 4) {
3889 Print (L"%EMaximum of %d ns%N\n", 1 << (L0sLatency + 6));
3890 } else {
3891 if (L0sLatency < 7) {
3892 Print (L"%EMaximum of %d us%N\n", 1 << (L0sLatency - 3));
3893 } else {
3894 Print (L"%ENo limit%N\n");
3895 }
3896 }
3897 Print (L" Endpoint L1 Acceptable Latency(11:9): ");
3898 if (L1Latency < 7) {
3899 Print (L"%EMaximum of %d us%N\n", 1 << (L1Latency + 1));
3900 } else {
3901 Print (L"%ENo limit%N\n");
3902 }
3903 }
3904 Print (
3905 L" Role-based Error Reporting(15): %E%d%N\n",
3906 PCIE_CAP_ERR_REPORTING (PcieDeviceCap)
3907 );
3908 //
3909 // Only valid for Upstream Port:
3910 // a) Captured Slot Power Limit Value
3911 // b) Captured Slot Power Scale
3912 //
3913 if (DevicePortType == PCIE_SWITCH_UPSTREAM_PORT) {
3914 Print (
3915 L" Captured Slot Power Limit Value(25:18): %E0x%02x%N\n",
3916 PCIE_CAP_SLOT_POWER_VALUE (PcieDeviceCap)
3917 );
3918 Print (
3919 L" Captured Slot Power Limit Scale(27:26): %E%s%N\n",
3920 SlotPwrLmtScaleTable[PCIE_CAP_SLOT_POWER_SCALE (PcieDeviceCap)]
3921 );
3922 }
3923 //
3924 // Function Level Reset Capability is only valid for Endpoint
3925 //
3926 if (IS_PCIE_ENDPOINT (DevicePortType)) {
3927 Print (
3928 L" Function Level Reset Capability(28): %E%d%N\n",
3929 PCIE_CAP_FUNC_LEVEL_RESET (PcieDeviceCap)
3930 );
3931 }
3932 return EFI_SUCCESS;
3933 }
3934
3935 /**
3936 Print out information of the device control information.
3937
3938 @param[in] PciExpressCap The pointer to the structure about the device.
3939
3940 @retval EFI_SUCCESS The operation was successful.
3941 **/
3942 EFI_STATUS
3943 ExplainPcieDeviceControl (
3944 IN PCIE_CAP_STURCTURE *PciExpressCap
3945 )
3946 {
3947 UINT16 PcieCapReg;
3948 UINT16 PcieDeviceControl;
3949
3950 PcieCapReg = PciExpressCap->PcieCapReg;
3951 PcieDeviceControl = PciExpressCap->DeviceControl;
3952 Print (
3953 L" Correctable Error Reporting Enable(0): %E%d%N\n",
3954 PCIE_CAP_COR_ERR_REPORTING_ENABLE (PcieDeviceControl)
3955 );
3956 Print (
3957 L" Non-Fatal Error Reporting Enable(1): %E%d%N\n",
3958 PCIE_CAP_NONFAT_ERR_REPORTING_ENABLE (PcieDeviceControl)
3959 );
3960 Print (
3961 L" Fatal Error Reporting Enable(2): %E%d%N\n",
3962 PCIE_CAP_FATAL_ERR_REPORTING_ENABLE (PcieDeviceControl)
3963 );
3964 Print (
3965 L" Unsupported Request Reporting Enable(3): %E%d%N\n",
3966 PCIE_CAP_UNSUP_REQ_REPORTING_ENABLE (PcieDeviceControl)
3967 );
3968 Print (
3969 L" Enable Relaxed Ordering(4): %E%d%N\n",
3970 PCIE_CAP_RELAXED_ORDERING_ENABLE (PcieDeviceControl)
3971 );
3972 Print (L" Max_Payload_Size(7:5): ");
3973 if (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) < 6) {
3974 Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) + 7));
3975 } else {
3976 Print (L"%EUnknown%N\n");
3977 }
3978 Print (
3979 L" Extended Tag Field Enable(8): %E%d%N\n",
3980 PCIE_CAP_EXTENDED_TAG_ENABLE (PcieDeviceControl)
3981 );
3982 Print (
3983 L" Phantom Functions Enable(9): %E%d%N\n",
3984 PCIE_CAP_PHANTOM_FUNC_ENABLE (PcieDeviceControl)
3985 );
3986 Print (
3987 L" Auxiliary (AUX) Power PM Enable(10): %E%d%N\n",
3988 PCIE_CAP_AUX_PM_ENABLE (PcieDeviceControl)
3989 );
3990 Print (
3991 L" Enable No Snoop(11): %E%d%N\n",
3992 PCIE_CAP_NO_SNOOP_ENABLE (PcieDeviceControl)
3993 );
3994 Print (L" Max_Read_Request_Size(14:12): ");
3995 if (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) < 6) {
3996 Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) + 7));
3997 } else {
3998 Print (L"%EUnknown%N\n");
3999 }
4000 //
4001 // Read operation is only valid for PCI Express to PCI/PCI-X Bridges
4002 //
4003 if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_PCIE_TO_PCIX_BRIDGE) {
4004 Print (
4005 L" Bridge Configuration Retry Enable(15): %E%d%N\n",
4006 PCIE_CAP_BRG_CONF_RETRY (PcieDeviceControl)
4007 );
4008 }
4009 return EFI_SUCCESS;
4010 }
4011
4012 /**
4013 Print out information of the device status information.
4014
4015 @param[in] PciExpressCap The pointer to the structure about the device.
4016
4017 @retval EFI_SUCCESS The operation was successful.
4018 **/
4019 EFI_STATUS
4020 ExplainPcieDeviceStatus (
4021 IN PCIE_CAP_STURCTURE *PciExpressCap
4022 )
4023 {
4024 UINT16 PcieDeviceStatus;
4025
4026 PcieDeviceStatus = PciExpressCap->DeviceStatus;
4027 Print (
4028 L" Correctable Error Detected(0): %E%d%N\n",
4029 PCIE_CAP_COR_ERR_DETECTED (PcieDeviceStatus)
4030 );
4031 Print (
4032 L" Non-Fatal Error Detected(1): %E%d%N\n",
4033 PCIE_CAP_NONFAT_ERR_DETECTED (PcieDeviceStatus)
4034 );
4035 Print (
4036 L" Fatal Error Detected(2): %E%d%N\n",
4037 PCIE_CAP_FATAL_ERR_DETECTED (PcieDeviceStatus)
4038 );
4039 Print (
4040 L" Unsupported Request Detected(3): %E%d%N\n",
4041 PCIE_CAP_UNSUP_REQ_DETECTED (PcieDeviceStatus)
4042 );
4043 Print (
4044 L" AUX Power Detected(4): %E%d%N\n",
4045 PCIE_CAP_AUX_POWER_DETECTED (PcieDeviceStatus)
4046 );
4047 Print (
4048 L" Transactions Pending(5): %E%d%N\n",
4049 PCIE_CAP_TRANSACTION_PENDING (PcieDeviceStatus)
4050 );
4051 return EFI_SUCCESS;
4052 }
4053
4054 /**
4055 Print out information of the device link information.
4056
4057 @param[in] PciExpressCap The pointer to the structure about the device.
4058
4059 @retval EFI_SUCCESS The operation was successful.
4060 **/
4061 EFI_STATUS
4062 ExplainPcieLinkCap (
4063 IN PCIE_CAP_STURCTURE *PciExpressCap
4064 )
4065 {
4066 UINT32 PcieLinkCap;
4067 CHAR16 *SupLinkSpeeds;
4068 CHAR16 *AspmValue;
4069
4070 PcieLinkCap = PciExpressCap->LinkCap;
4071 switch (PCIE_CAP_SUP_LINK_SPEEDS (PcieLinkCap)) {
4072 case 1:
4073 SupLinkSpeeds = L"2.5 GT/s";
4074 break;
4075 case 2:
4076 SupLinkSpeeds = L"5.0 GT/s and 2.5 GT/s";
4077 break;
4078 default:
4079 SupLinkSpeeds = L"Unknown";
4080 break;
4081 }
4082 Print (
4083 L" Supported Link Speeds(3:0): %E%s supported%N\n",
4084 SupLinkSpeeds
4085 );
4086 Print (
4087 L" Maximum Link Width(9:4): %Ex%d%N\n",
4088 PCIE_CAP_MAX_LINK_WIDTH (PcieLinkCap)
4089 );
4090 switch (PCIE_CAP_ASPM_SUPPORT (PcieLinkCap)) {
4091 case 1:
4092 AspmValue = L"L0s Entry";
4093 break;
4094 case 3:
4095 AspmValue = L"L0s and L1";
4096 break;
4097 default:
4098 AspmValue = L"Reserved";
4099 break;
4100 }
4101 Print (
4102 L" Active State Power Management Support(11:10): %E%s Supported%N\n",
4103 AspmValue
4104 );
4105 Print (
4106 L" L0s Exit Latency(14:12): %E%s%N\n",
4107 L0sLatencyStrTable[PCIE_CAP_L0S_LATENCY (PcieLinkCap)]
4108 );
4109 Print (
4110 L" L1 Exit Latency(17:15): %E%s%N\n",
4111 L1LatencyStrTable[PCIE_CAP_L0S_LATENCY (PcieLinkCap)]
4112 );
4113 Print (
4114 L" Clock Power Management(18): %E%d%N\n",
4115 PCIE_CAP_CLOCK_PM (PcieLinkCap)
4116 );
4117 Print (
4118 L" Surprise Down Error Reporting Capable(19): %E%d%N\n",
4119 PCIE_CAP_SUP_DOWN_ERR_REPORTING (PcieLinkCap)
4120 );
4121 Print (
4122 L" Data Link Layer Link Active Reporting Capable(20): %E%d%N\n",
4123 PCIE_CAP_LINK_ACTIVE_REPORTING (PcieLinkCap)
4124 );
4125 Print (
4126 L" Link Bandwidth Notification Capability(21): %E%d%N\n",
4127 PCIE_CAP_LINK_BWD_NOTIF_CAP (PcieLinkCap)
4128 );
4129 Print (
4130 L" Port Number(31:24): %E0x%02x%N\n",
4131 PCIE_CAP_PORT_NUMBER (PcieLinkCap)
4132 );
4133 return EFI_SUCCESS;
4134 }
4135
4136 /**
4137 Print out information of the device link control information.
4138
4139 @param[in] PciExpressCap The pointer to the structure about the device.
4140
4141 @retval EFI_SUCCESS The operation was successful.
4142 **/
4143 EFI_STATUS
4144 ExplainPcieLinkControl (
4145 IN PCIE_CAP_STURCTURE *PciExpressCap
4146 )
4147 {
4148 UINT16 PcieLinkControl;
4149 UINT8 DevicePortType;
4150
4151 PcieLinkControl = PciExpressCap->LinkControl;
4152 DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap->PcieCapReg);
4153 Print (
4154 L" Active State Power Management Control(1:0): %E%s%N\n",
4155 ASPMCtrlStrTable[PCIE_CAP_ASPM_CONTROL (PcieLinkControl)]
4156 );
4157 //
4158 // RCB is not applicable to switches
4159 //
4160 if (!IS_PCIE_SWITCH(DevicePortType)) {
4161 Print (
4162 L" Read Completion Boundary (RCB)(3): %E%d byte%N\n",
4163 1 << (PCIE_CAP_RCB (PcieLinkControl) + 6)
4164 );
4165 }
4166 //
4167 // Link Disable is reserved on
4168 // a) Endpoints
4169 // b) PCI Express to PCI/PCI-X bridges
4170 // c) Upstream Ports of Switches
4171 //
4172 if (!IS_PCIE_ENDPOINT (DevicePortType) &&
4173 DevicePortType != PCIE_SWITCH_UPSTREAM_PORT &&
4174 DevicePortType != PCIE_PCIE_TO_PCIX_BRIDGE) {
4175 Print (
4176 L" Link Disable(4): %E%d%N\n",
4177 PCIE_CAP_LINK_DISABLE (PcieLinkControl)
4178 );
4179 }
4180 Print (
4181 L" Common Clock Configuration(6): %E%d%N\n",
4182 PCIE_CAP_COMMON_CLK_CONF (PcieLinkControl)
4183 );
4184 Print (
4185 L" Extended Synch(7): %E%d%N\n",
4186 PCIE_CAP_EXT_SYNC (PcieLinkControl)
4187 );
4188 Print (
4189 L" Enable Clock Power Management(8): %E%d%N\n",
4190 PCIE_CAP_CLK_PWR_MNG (PcieLinkControl)
4191 );
4192 Print (
4193 L" Hardware Autonomous Width Disable(9): %E%d%N\n",
4194 PCIE_CAP_HW_AUTO_WIDTH_DISABLE (PcieLinkControl)
4195 );
4196 Print (
4197 L" Link Bandwidth Management Interrupt Enable(10): %E%d%N\n",
4198 PCIE_CAP_LINK_BDW_MNG_INT_EN (PcieLinkControl)
4199 );
4200 Print (
4201 L" Link Autonomous Bandwidth Interrupt Enable(11): %E%d%N\n",
4202 PCIE_CAP_LINK_AUTO_BDW_INT_EN (PcieLinkControl)
4203 );
4204 return EFI_SUCCESS;
4205 }
4206
4207 /**
4208 Print out information of the device link status information.
4209
4210 @param[in] PciExpressCap The pointer to the structure about the device.
4211
4212 @retval EFI_SUCCESS The operation was successful.
4213 **/
4214 EFI_STATUS
4215 ExplainPcieLinkStatus (
4216 IN PCIE_CAP_STURCTURE *PciExpressCap
4217 )
4218 {
4219 UINT16 PcieLinkStatus;
4220 CHAR16 *SupLinkSpeeds;
4221
4222 PcieLinkStatus = PciExpressCap->LinkStatus;
4223 switch (PCIE_CAP_CUR_LINK_SPEED (PcieLinkStatus)) {
4224 case 1:
4225 SupLinkSpeeds = L"2.5 GT/s";
4226 break;
4227 case 2:
4228 SupLinkSpeeds = L"5.0 GT/s";
4229 break;
4230 default:
4231 SupLinkSpeeds = L"Reserved";
4232 break;
4233 }
4234 Print (
4235 L" Current Link Speed(3:0): %E%s%N\n",
4236 SupLinkSpeeds
4237 );
4238 Print (
4239 L" Negotiated Link Width(9:4): %Ex%d%N\n",
4240 PCIE_CAP_NEGO_LINK_WIDTH (PcieLinkStatus)
4241 );
4242 Print (
4243 L" Link Training(11): %E%d%N\n",
4244 PCIE_CAP_LINK_TRAINING (PcieLinkStatus)
4245 );
4246 Print (
4247 L" Slot Clock Configuration(12): %E%d%N\n",
4248 PCIE_CAP_SLOT_CLK_CONF (PcieLinkStatus)
4249 );
4250 Print (
4251 L" Data Link Layer Link Active(13): %E%d%N\n",
4252 PCIE_CAP_DATA_LINK_ACTIVE (PcieLinkStatus)
4253 );
4254 Print (
4255 L" Link Bandwidth Management Status(14): %E%d%N\n",
4256 PCIE_CAP_LINK_BDW_MNG_STAT (PcieLinkStatus)
4257 );
4258 Print (
4259 L" Link Autonomous Bandwidth Status(15): %E%d%N\n",
4260 PCIE_CAP_LINK_AUTO_BDW_STAT (PcieLinkStatus)
4261 );
4262 return EFI_SUCCESS;
4263 }
4264
4265 /**
4266 Print out information of the device slot information.
4267
4268 @param[in] PciExpressCap The pointer to the structure about the device.
4269
4270 @retval EFI_SUCCESS The operation was successful.
4271 **/
4272 EFI_STATUS
4273 ExplainPcieSlotCap (
4274 IN PCIE_CAP_STURCTURE *PciExpressCap
4275 )
4276 {
4277 UINT32 PcieSlotCap;
4278
4279 PcieSlotCap = PciExpressCap->SlotCap;
4280
4281 Print (
4282 L" Attention Button Present(0): %E%d%N\n",
4283 PCIE_CAP_ATT_BUT_PRESENT (PcieSlotCap)
4284 );
4285 Print (
4286 L" Power Controller Present(1): %E%d%N\n",
4287 PCIE_CAP_PWR_CTRLLER_PRESENT (PcieSlotCap)
4288 );
4289 Print (
4290 L" MRL Sensor Present(2): %E%d%N\n",
4291 PCIE_CAP_MRL_SENSOR_PRESENT (PcieSlotCap)
4292 );
4293 Print (
4294 L" Attention Indicator Present(3): %E%d%N\n",
4295 PCIE_CAP_ATT_IND_PRESENT (PcieSlotCap)
4296 );
4297 Print (
4298 L" Power Indicator Present(4): %E%d%N\n",
4299 PCIE_CAP_PWD_IND_PRESENT (PcieSlotCap)
4300 );
4301 Print (
4302 L" Hot-Plug Surprise(5): %E%d%N\n",
4303 PCIE_CAP_HOTPLUG_SUPPRISE (PcieSlotCap)
4304 );
4305 Print (
4306 L" Hot-Plug Capable(6): %E%d%N\n",
4307 PCIE_CAP_HOTPLUG_CAPABLE (PcieSlotCap)
4308 );
4309 Print (
4310 L" Slot Power Limit Value(14:7): %E0x%02x%N\n",
4311 PCIE_CAP_SLOT_PWR_LIMIT_VALUE (PcieSlotCap)
4312 );
4313 Print (
4314 L" Slot Power Limit Scale(16:15): %E%s%N\n",
4315 SlotPwrLmtScaleTable[PCIE_CAP_SLOT_PWR_LIMIT_SCALE (PcieSlotCap)]
4316 );
4317 Print (
4318 L" Electromechanical Interlock Present(17): %E%d%N\n",
4319 PCIE_CAP_ELEC_INTERLOCK_PRESENT (PcieSlotCap)
4320 );
4321 Print (
4322 L" No Command Completed Support(18): %E%d%N\n",
4323 PCIE_CAP_NO_COMM_COMPLETED_SUP (PcieSlotCap)
4324 );
4325 Print (
4326 L" Physical Slot Number(31:19): %E%d%N\n",
4327 PCIE_CAP_PHY_SLOT_NUM (PcieSlotCap)
4328 );
4329
4330 return EFI_SUCCESS;
4331 }
4332
4333 /**
4334 Print out information of the device slot control information.
4335
4336 @param[in] PciExpressCap The pointer to the structure about the device.
4337
4338 @retval EFI_SUCCESS The operation was successful.
4339 **/
4340 EFI_STATUS
4341 ExplainPcieSlotControl (
4342 IN PCIE_CAP_STURCTURE *PciExpressCap
4343 )
4344 {
4345 UINT16 PcieSlotControl;
4346
4347 PcieSlotControl = PciExpressCap->SlotControl;
4348 Print (
4349 L" Attention Button Pressed Enable(0): %E%d%N\n",
4350 PCIE_CAP_ATT_BUT_ENABLE (PcieSlotControl)
4351 );
4352 Print (
4353 L" Power Fault Detected Enable(1): %E%d%N\n",
4354 PCIE_CAP_PWR_FLT_DETECT_ENABLE (PcieSlotControl)
4355 );
4356 Print (
4357 L" MRL Sensor Changed Enable(2): %E%d%N\n",
4358 PCIE_CAP_MRL_SENSOR_CHANGE_ENABLE (PcieSlotControl)
4359 );
4360 Print (
4361 L" Presence Detect Changed Enable(3): %E%d%N\n",
4362 PCIE_CAP_PRES_DETECT_CHANGE_ENABLE (PcieSlotControl)
4363 );
4364 Print (
4365 L" Command Completed Interrupt Enable(4): %E%d%N\n",
4366 PCIE_CAP_COMM_CMPL_INT_ENABLE (PcieSlotControl)
4367 );
4368 Print (
4369 L" Hot-Plug Interrupt Enable(5): %E%d%N\n",
4370 PCIE_CAP_HOTPLUG_INT_ENABLE (PcieSlotControl)
4371 );
4372 Print (
4373 L" Attention Indicator Control(7:6): %E%s%N\n",
4374 IndicatorTable[PCIE_CAP_ATT_IND_CTRL (PcieSlotControl)]
4375 );
4376 Print (
4377 L" Power Indicator Control(9:8): %E%s%N\n",
4378 IndicatorTable[PCIE_CAP_PWR_IND_CTRL (PcieSlotControl)]
4379 );
4380 Print (L" Power Controller Control(10): %EPower ");
4381 if (PCIE_CAP_PWR_CTRLLER_CTRL (PcieSlotControl)) {
4382 Print (L"Off%N\n");
4383 } else {
4384 Print (L"On%N\n");
4385 }
4386 Print (
4387 L" Electromechanical Interlock Control(11): %E%d%N\n",
4388 PCIE_CAP_ELEC_INTERLOCK_CTRL (PcieSlotControl)
4389 );
4390 Print (
4391 L" Data Link Layer State Changed Enable(12): %E%d%N\n",
4392 PCIE_CAP_DLINK_STAT_CHANGE_ENABLE (PcieSlotControl)
4393 );
4394 return EFI_SUCCESS;
4395 }
4396
4397 /**
4398 Print out information of the device slot status information.
4399
4400 @param[in] PciExpressCap The pointer to the structure about the device.
4401
4402 @retval EFI_SUCCESS The operation was successful.
4403 **/
4404 EFI_STATUS
4405 ExplainPcieSlotStatus (
4406 IN PCIE_CAP_STURCTURE *PciExpressCap
4407 )
4408 {
4409 UINT16 PcieSlotStatus;
4410
4411 PcieSlotStatus = PciExpressCap->SlotStatus;
4412
4413 Print (
4414 L" Attention Button Pressed(0): %E%d%N\n",
4415 PCIE_CAP_ATT_BUT_PRESSED (PcieSlotStatus)
4416 );
4417 Print (
4418 L" Power Fault Detected(1): %E%d%N\n",
4419 PCIE_CAP_PWR_FLT_DETECTED (PcieSlotStatus)
4420 );
4421 Print (
4422 L" MRL Sensor Changed(2): %E%d%N\n",
4423 PCIE_CAP_MRL_SENSOR_CHANGED (PcieSlotStatus)
4424 );
4425 Print (
4426 L" Presence Detect Changed(3): %E%d%N\n",
4427 PCIE_CAP_PRES_DETECT_CHANGED (PcieSlotStatus)
4428 );
4429 Print (
4430 L" Command Completed(4): %E%d%N\n",
4431 PCIE_CAP_COMM_COMPLETED (PcieSlotStatus)
4432 );
4433 Print (L" MRL Sensor State(5): %EMRL ");
4434 if (PCIE_CAP_MRL_SENSOR_STATE (PcieSlotStatus)) {
4435 Print (L" Opened%N\n");
4436 } else {
4437 Print (L" Closed%N\n");
4438 }
4439 Print (L" Presence Detect State(6): ");
4440 if (PCIE_CAP_PRES_DETECT_STATE (PcieSlotStatus)) {
4441 Print (L"%ECard Present in slot%N\n");
4442 } else {
4443 Print (L"%ESlot Empty%N\n");
4444 }
4445 Print (L" Electromechanical Interlock Status(7): %EElectromechanical Interlock ");
4446 if (PCIE_CAP_ELEC_INTERLOCK_STATE (PcieSlotStatus)) {
4447 Print (L"Engaged%N\n");
4448 } else {
4449 Print (L"Disengaged%N\n");
4450 }
4451 Print (
4452 L" Data Link Layer State Changed(8): %E%d%N\n",
4453 PCIE_CAP_DLINK_STAT_CHANGED (PcieSlotStatus)
4454 );
4455 return EFI_SUCCESS;
4456 }
4457
4458 /**
4459 Print out information of the device root information.
4460
4461 @param[in] PciExpressCap The pointer to the structure about the device.
4462
4463 @retval EFI_SUCCESS The operation was successful.
4464 **/
4465 EFI_STATUS
4466 ExplainPcieRootControl (
4467 IN PCIE_CAP_STURCTURE *PciExpressCap
4468 )
4469 {
4470 UINT16 PcieRootControl;
4471
4472 PcieRootControl = PciExpressCap->RootControl;
4473
4474 Print (
4475 L" System Error on Correctable Error Enable(0): %E%d%N\n",
4476 PCIE_CAP_SYSERR_ON_CORERR_EN (PcieRootControl)
4477 );
4478 Print (
4479 L" System Error on Non-Fatal Error Enable(1): %E%d%N\n",
4480 PCIE_CAP_SYSERR_ON_NONFATERR_EN (PcieRootControl)
4481 );
4482 Print (
4483 L" System Error on Fatal Error Enable(2): %E%d%N\n",
4484 PCIE_CAP_SYSERR_ON_FATERR_EN (PcieRootControl)
4485 );
4486 Print (
4487 L" PME Interrupt Enable(3): %E%d%N\n",
4488 PCIE_CAP_PME_INT_ENABLE (PcieRootControl)
4489 );
4490 Print (
4491 L" CRS Software Visibility Enable(4): %E%d%N\n",
4492 PCIE_CAP_CRS_SW_VIS_ENABLE (PcieRootControl)
4493 );
4494
4495 return EFI_SUCCESS;
4496 }
4497
4498 /**
4499 Print out information of the device root capability information.
4500
4501 @param[in] PciExpressCap The pointer to the structure about the device.
4502
4503 @retval EFI_SUCCESS The operation was successful.
4504 **/
4505 EFI_STATUS
4506 ExplainPcieRootCap (
4507 IN PCIE_CAP_STURCTURE *PciExpressCap
4508 )
4509 {
4510 UINT16 PcieRootCap;
4511
4512 PcieRootCap = PciExpressCap->RsvdP;
4513
4514 Print (
4515 L" CRS Software Visibility(0): %E%d%N\n",
4516 PCIE_CAP_CRS_SW_VIS (PcieRootCap)
4517 );
4518
4519 return EFI_SUCCESS;
4520 }
4521
4522 /**
4523 Print out information of the device root status information.
4524
4525 @param[in] PciExpressCap The pointer to the structure about the device.
4526
4527 @retval EFI_SUCCESS The operation was successful.
4528 **/
4529 EFI_STATUS
4530 ExplainPcieRootStatus (
4531 IN PCIE_CAP_STURCTURE *PciExpressCap
4532 )
4533 {
4534 UINT32 PcieRootStatus;
4535
4536 PcieRootStatus = PciExpressCap->RootStatus;
4537
4538 Print (
4539 L" PME Requester ID(15:0): %E0x%04x%N\n",
4540 PCIE_CAP_PME_REQ_ID (PcieRootStatus)
4541 );
4542 Print (
4543 L" PME Status(16): %E%d%N\n",
4544 PCIE_CAP_PME_STATUS (PcieRootStatus)
4545 );
4546 Print (
4547 L" PME Pending(17): %E%d%N\n",
4548 PCIE_CAP_PME_PENDING (PcieRootStatus)
4549 );
4550 return EFI_SUCCESS;
4551 }
4552
4553 /**
4554 Display Pcie device structure.
4555
4556 @param[in] IoDev The pointer to the root pci protocol.
4557 @param[in] Address The Address to start at.
4558 @param[in] CapabilityPtr The offset from the address to start.
4559 **/
4560 EFI_STATUS
4561 PciExplainPciExpress (
4562 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
4563 IN UINT64 Address,
4564 IN UINT8 CapabilityPtr
4565 )
4566 {
4567
4568 PCIE_CAP_STURCTURE PciExpressCap;
4569 EFI_STATUS Status;
4570 UINT64 CapRegAddress;
4571 UINT8 Bus;
4572 UINT8 Dev;
4573 UINT8 Func;
4574 UINT8 *ExRegBuffer;
4575 UINTN ExtendRegSize;
4576 UINT64 Pciex_Address;
4577 UINT8 DevicePortType;
4578 UINTN Index;
4579 UINT8 *RegAddr;
4580 UINTN RegValue;
4581
4582 CapRegAddress = Address + CapabilityPtr;
4583 IoDev->Pci.Read (
4584 IoDev,
4585 EfiPciWidthUint32,
4586 CapRegAddress,
4587 sizeof (PciExpressCap) / sizeof (UINT32),
4588 &PciExpressCap
4589 );
4590
4591 DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap.PcieCapReg);
4592
4593 Print (L"\nPci Express device capability structure:\n");
4594
4595 for (Index = 0; PcieExplainList[Index].Type < PcieExplainTypeMax; Index++) {
4596 if (ShellGetExecutionBreakFlag()) {
4597 goto Done;
4598 }
4599 RegAddr = ((UINT8 *) &PciExpressCap) + PcieExplainList[Index].Offset;
4600 switch (PcieExplainList[Index].Width) {
4601 case FieldWidthUINT8:
4602 RegValue = *(UINT8 *) RegAddr;
4603 break;
4604 case FieldWidthUINT16:
4605 RegValue = *(UINT16 *) RegAddr;
4606 break;
4607 case FieldWidthUINT32:
4608 RegValue = *(UINT32 *) RegAddr;
4609 break;
4610 default:
4611 RegValue = 0;
4612 break;
4613 }
4614 ShellPrintHiiEx(-1, -1, NULL,
4615 PcieExplainList[Index].Token,
4616 gShellDebug1HiiHandle,
4617 PcieExplainList[Index].Offset,
4618 RegValue
4619 );
4620 if (PcieExplainList[Index].Func == NULL) {
4621 continue;
4622 }
4623 switch (PcieExplainList[Index].Type) {
4624 case PcieExplainTypeLink:
4625 //
4626 // Link registers should not be used by
4627 // a) Root Complex Integrated Endpoint
4628 // b) Root Complex Event Collector
4629 //
4630 if (DevicePortType == PCIE_ROOT_COMPLEX_INTEGRATED_PORT ||
4631 DevicePortType == PCIE_ROOT_COMPLEX_EVENT_COLLECTOR) {
4632 continue;
4633 }
4634 break;
4635 case PcieExplainTypeSlot:
4636 //
4637 // Slot registers are only valid for
4638 // a) Root Port of PCI Express Root Complex
4639 // b) Downstream Port of PCI Express Switch
4640 // and when SlotImplemented bit is set in PCIE cap register.
4641 //
4642 if ((DevicePortType != PCIE_ROOT_COMPLEX_ROOT_PORT &&
4643 DevicePortType != PCIE_SWITCH_DOWNSTREAM_PORT) ||
4644 !PCIE_CAP_SLOT_IMPLEMENTED (PciExpressCap.PcieCapReg)) {
4645 continue;
4646 }
4647 break;
4648 case PcieExplainTypeRoot:
4649 //
4650 // Root registers are only valid for
4651 // Root Port of PCI Express Root Complex
4652 //
4653 if (DevicePortType != PCIE_ROOT_COMPLEX_ROOT_PORT) {
4654 continue;
4655 }
4656 break;
4657 default:
4658 break;
4659 }
4660 PcieExplainList[Index].Func (&PciExpressCap);
4661 }
4662
4663 Bus = (UINT8) (RShiftU64 (Address, 24));
4664 Dev = (UINT8) (RShiftU64 (Address, 16));
4665 Func = (UINT8) (RShiftU64 (Address, 8));
4666
4667 Pciex_Address = CALC_EFI_PCIEX_ADDRESS (Bus, Dev, Func, 0x100);
4668
4669 ExtendRegSize = 0x1000 - 0x100;
4670
4671 ExRegBuffer = (UINT8 *) AllocateZeroPool (ExtendRegSize);
4672
4673 //
4674 // PciRootBridgeIo protocol should support pci express extend space IO
4675 // (Begins at offset 0x100)
4676 //
4677 Status = IoDev->Pci.Read (
4678 IoDev,
4679 EfiPciWidthUint32,
4680 Pciex_Address,
4681 (ExtendRegSize) / sizeof (UINT32),
4682 (VOID *) (ExRegBuffer)
4683 );
4684 if (EFI_ERROR (Status)) {
4685 FreePool ((VOID *) ExRegBuffer);
4686 return EFI_UNSUPPORTED;
4687 }
4688 //
4689 // Start outputing PciEx extend space( 0xFF-0xFFF)
4690 //
4691 Print (L"\n%HStart dumping PCIex extended configuration space (0x100 - 0xFFF).%N\n\n");
4692
4693 DumpHex (
4694 2,
4695 0x100,
4696 ExtendRegSize,
4697 (VOID *) (ExRegBuffer)
4698 );
4699
4700 FreePool ((VOID *) ExRegBuffer);
4701
4702 Done:
4703 return EFI_SUCCESS;
4704 }