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