Update the comments in function headers to follow Doxygen special documentation block...
[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 @param[in] EnhancedDump The print format for the dump data.
1496
1497 @retval EFI_SUCCESS The command completed successfully.
1498 **/
1499 EFI_STATUS
1500 PciExplainData (
1501 IN PCI_CONFIG_SPACE *ConfigSpace,
1502 IN UINT64 Address,
1503 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
1504 IN CONST UINT16 EnhancedDump
1505 );
1506
1507 /**
1508 Explain the device specific part of data in PCI configuration space.
1509
1510 @param[in] Device Data in PCI configuration space.
1511 @param[in] Address Address used to access configuration space of this PCI device.
1512 @param[in] IoDev Handle used to access configuration space of PCI device.
1513
1514 @retval EFI_SUCCESS The command completed successfully.
1515 **/
1516 EFI_STATUS
1517 PciExplainDeviceData (
1518 IN PCI_DEVICE_HEADER *Device,
1519 IN UINT64 Address,
1520 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
1521 );
1522
1523 /**
1524 Explain the bridge specific part of data in PCI configuration space.
1525
1526 @param[in] Bridge Bridge specific data region in PCI configuration space.
1527 @param[in] Address Address used to access configuration space of this PCI device.
1528 @param[in] IoDev Handle used to access configuration space of PCI device.
1529
1530 @retval EFI_SUCCESS The command completed successfully.
1531 **/
1532 EFI_STATUS
1533 PciExplainBridgeData (
1534 IN PCI_BRIDGE_HEADER *Bridge,
1535 IN UINT64 Address,
1536 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
1537 );
1538
1539 /**
1540 Explain the Base Address Register(Bar) in PCI configuration space.
1541
1542 @param[in] Bar Points to the Base Address Register intended to interpret.
1543 @param[in] Command Points to the register Command.
1544 @param[in] Address Address used to access configuration space of this PCI device.
1545 @param[in] IoDev Handle used to access configuration space of PCI device.
1546 @param[in, out] Index The Index.
1547
1548 @retval EFI_SUCCESS The command completed successfully.
1549 **/
1550 EFI_STATUS
1551 PciExplainBar (
1552 IN UINT32 *Bar,
1553 IN UINT16 *Command,
1554 IN UINT64 Address,
1555 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
1556 IN OUT UINTN *Index
1557 );
1558
1559 /**
1560 Explain the cardbus specific part of data in PCI configuration space.
1561
1562 @param[in] CardBus CardBus specific region of PCI configuration space.
1563 @param[in] Address Address used to access configuration space of this PCI device.
1564 @param[in] IoDev Handle used to access configuration space of PCI device.
1565
1566 @retval EFI_SUCCESS The command completed successfully.
1567 **/
1568 EFI_STATUS
1569 PciExplainCardBusData (
1570 IN PCI_CARDBUS_HEADER *CardBus,
1571 IN UINT64 Address,
1572 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
1573 );
1574
1575 /**
1576 Explain each meaningful bit of register Status. The definition of Status is
1577 slightly different depending on the PCI header type.
1578
1579 @param[in] Status Points to the content of register Status.
1580 @param[in] MainStatus Indicates if this register is main status(not secondary
1581 status).
1582 @param[in] HeaderType Header type of this PCI device.
1583
1584 @retval EFI_SUCCESS The command completed successfully.
1585 **/
1586 EFI_STATUS
1587 PciExplainStatus (
1588 IN UINT16 *Status,
1589 IN BOOLEAN MainStatus,
1590 IN PCI_HEADER_TYPE HeaderType
1591 );
1592
1593 /**
1594 Explain each meaningful bit of register Command.
1595
1596 @param[in] Command Points to the content of register Command.
1597
1598 @retval EFI_SUCCESS The command completed successfully.
1599 **/
1600 EFI_STATUS
1601 PciExplainCommand (
1602 IN UINT16 *Command
1603 );
1604
1605 /**
1606 Explain each meaningful bit of register Bridge Control.
1607
1608 @param[in] BridgeControl Points to the content of register Bridge Control.
1609 @param[in] HeaderType The headertype.
1610
1611 @retval EFI_SUCCESS The command completed successfully.
1612 **/
1613 EFI_STATUS
1614 PciExplainBridgeControl (
1615 IN UINT16 *BridgeControl,
1616 IN PCI_HEADER_TYPE HeaderType
1617 );
1618
1619 /**
1620 Print each capability structure.
1621
1622 @param[in] IoDev The pointer to the deivce.
1623 @param[in] Address The address to start at.
1624 @param[in] CapPtr The offset from the address.
1625 @param[in] EnhancedDump The print format for the dump data.
1626
1627 @retval EFI_SUCCESS The operation was successful.
1628 **/
1629 EFI_STATUS
1630 PciExplainCapabilityStruct (
1631 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
1632 IN UINT64 Address,
1633 IN UINT8 CapPtr,
1634 IN CONST UINT16 EnhancedDump
1635 );
1636
1637 /**
1638 Display Pcie device structure.
1639
1640 @param[in] IoDev The pointer to the root pci protocol.
1641 @param[in] Address The Address to start at.
1642 @param[in] CapabilityPtr The offset from the address to start.
1643 @param[in] EnhancedDump The print format for the dump data.
1644
1645 @retval EFI_SUCCESS The command completed successfully.
1646 @retval @retval EFI_SUCCESS Pci express extend space IO is not suppoted.
1647 **/
1648 EFI_STATUS
1649 PciExplainPciExpress (
1650 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
1651 IN UINT64 Address,
1652 IN UINT8 CapabilityPtr,
1653 IN CONST UINT16 EnhancedDump
1654 );
1655
1656 /**
1657 Print out information of the capability information.
1658
1659 @param[in] PciExpressCap The pointer to the structure about the device.
1660
1661 @retval EFI_SUCCESS The operation was successful.
1662 **/
1663 EFI_STATUS
1664 ExplainPcieCapReg (
1665 IN PCIE_CAP_STURCTURE *PciExpressCap
1666 );
1667
1668 /**
1669 Print out information of the device capability information.
1670
1671 @param[in] PciExpressCap The pointer to the structure about the device.
1672
1673 @retval EFI_SUCCESS The operation was successful.
1674 **/
1675 EFI_STATUS
1676 ExplainPcieDeviceCap (
1677 IN PCIE_CAP_STURCTURE *PciExpressCap
1678 );
1679
1680 /**
1681 Print out information of the device control information.
1682
1683 @param[in] PciExpressCap The pointer to the structure about the device.
1684
1685 @retval EFI_SUCCESS The operation was successful.
1686 **/
1687 EFI_STATUS
1688 ExplainPcieDeviceControl (
1689 IN PCIE_CAP_STURCTURE *PciExpressCap
1690 );
1691
1692 /**
1693 Print out information of the device status information.
1694
1695 @param[in] PciExpressCap The pointer to the structure about the device.
1696
1697 @retval EFI_SUCCESS The operation was successful.
1698 **/
1699 EFI_STATUS
1700 ExplainPcieDeviceStatus (
1701 IN PCIE_CAP_STURCTURE *PciExpressCap
1702 );
1703
1704 /**
1705 Print out information of the device link information.
1706
1707 @param[in] PciExpressCap The pointer to the structure about the device.
1708
1709 @retval EFI_SUCCESS The operation was successful.
1710 **/
1711 EFI_STATUS
1712 ExplainPcieLinkCap (
1713 IN PCIE_CAP_STURCTURE *PciExpressCap
1714 );
1715
1716 /**
1717 Print out information of the device link control information.
1718
1719 @param[in] PciExpressCap The pointer to the structure about the device.
1720
1721 @retval EFI_SUCCESS The operation was successful.
1722 **/
1723 EFI_STATUS
1724 ExplainPcieLinkControl (
1725 IN PCIE_CAP_STURCTURE *PciExpressCap
1726 );
1727
1728 /**
1729 Print out information of the device link status information.
1730
1731 @param[in] PciExpressCap The pointer to the structure about the device.
1732
1733 @retval EFI_SUCCESS The operation was successful.
1734 **/
1735 EFI_STATUS
1736 ExplainPcieLinkStatus (
1737 IN PCIE_CAP_STURCTURE *PciExpressCap
1738 );
1739
1740 /**
1741 Print out information of the device slot information.
1742
1743 @param[in] PciExpressCap The pointer to the structure about the device.
1744
1745 @retval EFI_SUCCESS The operation was successful.
1746 **/
1747 EFI_STATUS
1748 ExplainPcieSlotCap (
1749 IN PCIE_CAP_STURCTURE *PciExpressCap
1750 );
1751
1752 /**
1753 Print out information of the device slot control information.
1754
1755 @param[in] PciExpressCap The pointer to the structure about the device.
1756
1757 @retval EFI_SUCCESS The operation was successful.
1758 **/
1759 EFI_STATUS
1760 ExplainPcieSlotControl (
1761 IN PCIE_CAP_STURCTURE *PciExpressCap
1762 );
1763
1764 /**
1765 Print out information of the device slot status information.
1766
1767 @param[in] PciExpressCap The pointer to the structure about the device.
1768
1769 @retval EFI_SUCCESS The operation was successful.
1770 **/
1771 EFI_STATUS
1772 ExplainPcieSlotStatus (
1773 IN PCIE_CAP_STURCTURE *PciExpressCap
1774 );
1775
1776 /**
1777 Print out information of the device root information.
1778
1779 @param[in] PciExpressCap The pointer to the structure about the device.
1780
1781 @retval EFI_SUCCESS The operation was successful.
1782 **/
1783 EFI_STATUS
1784 ExplainPcieRootControl (
1785 IN PCIE_CAP_STURCTURE *PciExpressCap
1786 );
1787
1788 /**
1789 Print out information of the device root capability information.
1790
1791 @param[in] PciExpressCap The pointer to the structure about the device.
1792
1793 @retval EFI_SUCCESS The operation was successful.
1794 **/
1795 EFI_STATUS
1796 ExplainPcieRootCap (
1797 IN PCIE_CAP_STURCTURE *PciExpressCap
1798 );
1799
1800 /**
1801 Print out information of the device root status information.
1802
1803 @param[in] PciExpressCap The pointer to the structure about the device.
1804
1805 @retval EFI_SUCCESS The operation was successful.
1806 **/
1807 EFI_STATUS
1808 ExplainPcieRootStatus (
1809 IN PCIE_CAP_STURCTURE *PciExpressCap
1810 );
1811
1812 typedef EFI_STATUS (*PCIE_EXPLAIN_FUNCTION) (IN PCIE_CAP_STURCTURE *PciExpressCap);
1813
1814 typedef enum {
1815 FieldWidthUINT8,
1816 FieldWidthUINT16,
1817 FieldWidthUINT32
1818 } PCIE_CAPREG_FIELD_WIDTH;
1819
1820 typedef enum {
1821 PcieExplainTypeCommon,
1822 PcieExplainTypeDevice,
1823 PcieExplainTypeLink,
1824 PcieExplainTypeSlot,
1825 PcieExplainTypeRoot,
1826 PcieExplainTypeMax
1827 } PCIE_EXPLAIN_TYPE;
1828
1829 typedef struct
1830 {
1831 UINT16 Token;
1832 UINTN Offset;
1833 PCIE_CAPREG_FIELD_WIDTH Width;
1834 PCIE_EXPLAIN_FUNCTION Func;
1835 PCIE_EXPLAIN_TYPE Type;
1836 } PCIE_EXPLAIN_STRUCT;
1837
1838 PCIE_EXPLAIN_STRUCT PcieExplainList[] = {
1839 {
1840 STRING_TOKEN (STR_PCIEX_CAPABILITY_CAPID),
1841 0x00,
1842 FieldWidthUINT8,
1843 NULL,
1844 PcieExplainTypeCommon
1845 },
1846 {
1847 STRING_TOKEN (STR_PCIEX_NEXTCAP_PTR),
1848 0x01,
1849 FieldWidthUINT8,
1850 NULL,
1851 PcieExplainTypeCommon
1852 },
1853 {
1854 STRING_TOKEN (STR_PCIEX_CAP_REGISTER),
1855 0x02,
1856 FieldWidthUINT16,
1857 ExplainPcieCapReg,
1858 PcieExplainTypeCommon
1859 },
1860 {
1861 STRING_TOKEN (STR_PCIEX_DEVICE_CAP),
1862 0x04,
1863 FieldWidthUINT32,
1864 ExplainPcieDeviceCap,
1865 PcieExplainTypeDevice
1866 },
1867 {
1868 STRING_TOKEN (STR_PCIEX_DEVICE_CONTROL),
1869 0x08,
1870 FieldWidthUINT16,
1871 ExplainPcieDeviceControl,
1872 PcieExplainTypeDevice
1873 },
1874 {
1875 STRING_TOKEN (STR_PCIEX_DEVICE_STATUS),
1876 0x0a,
1877 FieldWidthUINT16,
1878 ExplainPcieDeviceStatus,
1879 PcieExplainTypeDevice
1880 },
1881 {
1882 STRING_TOKEN (STR_PCIEX_LINK_CAPABILITIES),
1883 0x0c,
1884 FieldWidthUINT32,
1885 ExplainPcieLinkCap,
1886 PcieExplainTypeLink
1887 },
1888 {
1889 STRING_TOKEN (STR_PCIEX_LINK_CONTROL),
1890 0x10,
1891 FieldWidthUINT16,
1892 ExplainPcieLinkControl,
1893 PcieExplainTypeLink
1894 },
1895 {
1896 STRING_TOKEN (STR_PCIEX_LINK_STATUS),
1897 0x12,
1898 FieldWidthUINT16,
1899 ExplainPcieLinkStatus,
1900 PcieExplainTypeLink
1901 },
1902 {
1903 STRING_TOKEN (STR_PCIEX_SLOT_CAPABILITIES),
1904 0x14,
1905 FieldWidthUINT32,
1906 ExplainPcieSlotCap,
1907 PcieExplainTypeSlot
1908 },
1909 {
1910 STRING_TOKEN (STR_PCIEX_SLOT_CONTROL),
1911 0x18,
1912 FieldWidthUINT16,
1913 ExplainPcieSlotControl,
1914 PcieExplainTypeSlot
1915 },
1916 {
1917 STRING_TOKEN (STR_PCIEX_SLOT_STATUS),
1918 0x1a,
1919 FieldWidthUINT16,
1920 ExplainPcieSlotStatus,
1921 PcieExplainTypeSlot
1922 },
1923 {
1924 STRING_TOKEN (STR_PCIEX_ROOT_CONTROL),
1925 0x1c,
1926 FieldWidthUINT16,
1927 ExplainPcieRootControl,
1928 PcieExplainTypeRoot
1929 },
1930 {
1931 STRING_TOKEN (STR_PCIEX_RSVDP),
1932 0x1e,
1933 FieldWidthUINT16,
1934 ExplainPcieRootCap,
1935 PcieExplainTypeRoot
1936 },
1937 {
1938 STRING_TOKEN (STR_PCIEX_ROOT_STATUS),
1939 0x20,
1940 FieldWidthUINT32,
1941 ExplainPcieRootStatus,
1942 PcieExplainTypeRoot
1943 },
1944 {
1945 0,
1946 0,
1947 (PCIE_CAPREG_FIELD_WIDTH)0,
1948 NULL,
1949 PcieExplainTypeMax
1950 }
1951 };
1952
1953 //
1954 // Global Variables
1955 //
1956 PCI_CONFIG_SPACE *mConfigSpace = NULL;
1957 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
1958 {L"-s", TypeValue},
1959 {L"-i", TypeFlag},
1960 {NULL, TypeMax}
1961 };
1962
1963 CHAR16 *DevicePortTypeTable[] = {
1964 L"PCI Express Endpoint",
1965 L"Legacy PCI Express Endpoint",
1966 L"Unknown Type",
1967 L"Unknonw Type",
1968 L"Root Port of PCI Express Root Complex",
1969 L"Upstream Port of PCI Express Switch",
1970 L"Downstream Port of PCI Express Switch",
1971 L"PCI Express to PCI/PCI-X Bridge",
1972 L"PCI/PCI-X to PCI Express Bridge",
1973 L"Root Complex Integrated Endpoint",
1974 L"Root Complex Event Collector"
1975 };
1976
1977 CHAR16 *L0sLatencyStrTable[] = {
1978 L"Less than 64ns",
1979 L"64ns to less than 128ns",
1980 L"128ns to less than 256ns",
1981 L"256ns to less than 512ns",
1982 L"512ns to less than 1us",
1983 L"1us to less than 2us",
1984 L"2us-4us",
1985 L"More than 4us"
1986 };
1987
1988 CHAR16 *L1LatencyStrTable[] = {
1989 L"Less than 1us",
1990 L"1us to less than 2us",
1991 L"2us to less than 4us",
1992 L"4us to less than 8us",
1993 L"8us to less than 16us",
1994 L"16us to less than 32us",
1995 L"32us-64us",
1996 L"More than 64us"
1997 };
1998
1999 CHAR16 *ASPMCtrlStrTable[] = {
2000 L"Disabled",
2001 L"L0s Entry Enabled",
2002 L"L1 Entry Enabled",
2003 L"L0s and L1 Entry Enabled"
2004 };
2005
2006 CHAR16 *SlotPwrLmtScaleTable[] = {
2007 L"1.0x",
2008 L"0.1x",
2009 L"0.01x",
2010 L"0.001x"
2011 };
2012
2013 CHAR16 *IndicatorTable[] = {
2014 L"Reserved",
2015 L"On",
2016 L"Blink",
2017 L"Off"
2018 };
2019
2020
2021 /**
2022 Function for 'pci' command.
2023
2024 @param[in] ImageHandle Handle to the Image (NULL if Internal).
2025 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
2026 **/
2027 SHELL_STATUS
2028 EFIAPI
2029 ShellCommandRunPci (
2030 IN EFI_HANDLE ImageHandle,
2031 IN EFI_SYSTEM_TABLE *SystemTable
2032 )
2033 {
2034 UINT16 Segment;
2035 UINT16 Bus;
2036 UINT16 Device;
2037 UINT16 Func;
2038 UINT64 Address;
2039 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev;
2040 EFI_STATUS Status;
2041 PCI_COMMON_HEADER PciHeader;
2042 PCI_CONFIG_SPACE ConfigSpace;
2043 UINTN ScreenCount;
2044 UINTN TempColumn;
2045 UINTN ScreenSize;
2046 BOOLEAN ExplainData;
2047 UINTN Index;
2048 UINTN SizeOfHeader;
2049 BOOLEAN PrintTitle;
2050 UINTN HandleBufSize;
2051 EFI_HANDLE *HandleBuf;
2052 UINTN HandleCount;
2053 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
2054 UINT16 MinBus;
2055 UINT16 MaxBus;
2056 BOOLEAN IsEnd;
2057 LIST_ENTRY *Package;
2058 CHAR16 *ProblemParam;
2059 SHELL_STATUS ShellStatus;
2060 CONST CHAR16 *Temp;
2061 UINT64 RetVal;
2062 UINT16 EnhancedDump;
2063
2064 ShellStatus = SHELL_SUCCESS;
2065 Status = EFI_SUCCESS;
2066 Address = 0;
2067 IoDev = NULL;
2068 HandleBuf = NULL;
2069 Package = NULL;
2070
2071 //
2072 // initialize the shell lib (we must be in non-auto-init...)
2073 //
2074 Status = ShellInitialize();
2075 ASSERT_EFI_ERROR(Status);
2076
2077 Status = CommandInit();
2078 ASSERT_EFI_ERROR(Status);
2079
2080 //
2081 // parse the command line
2082 //
2083 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
2084 if (EFI_ERROR(Status)) {
2085 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
2086 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);
2087 FreePool(ProblemParam);
2088 ShellStatus = SHELL_INVALID_PARAMETER;
2089 } else {
2090 ASSERT(FALSE);
2091 }
2092 } else {
2093
2094 if (ShellCommandLineGetCount(Package) == 2) {
2095 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);
2096 ShellStatus = SHELL_INVALID_PARAMETER;
2097 goto Done;
2098 }
2099
2100 if (ShellCommandLineGetCount(Package) > 4) {
2101 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
2102 ShellStatus = SHELL_INVALID_PARAMETER;
2103 goto Done;
2104 }
2105 if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetValue(Package, L"-s") == NULL) {
2106 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-s");
2107 ShellStatus = SHELL_INVALID_PARAMETER;
2108 goto Done;
2109 }
2110 //
2111 // Get all instances of PciRootBridgeIo. Allocate space for 1 EFI_HANDLE and
2112 // call LibLocateHandle(), if EFI_BUFFER_TOO_SMALL is returned, allocate enough
2113 // space for handles and call it again.
2114 //
2115 HandleBufSize = sizeof (EFI_HANDLE);
2116 HandleBuf = (EFI_HANDLE *) AllocateZeroPool (HandleBufSize);
2117 if (HandleBuf == NULL) {
2118 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);
2119 ShellStatus = SHELL_OUT_OF_RESOURCES;
2120 goto Done;
2121 }
2122
2123 Status = gBS->LocateHandle (
2124 ByProtocol,
2125 &gEfiPciRootBridgeIoProtocolGuid,
2126 NULL,
2127 &HandleBufSize,
2128 HandleBuf
2129 );
2130
2131 if (Status == EFI_BUFFER_TOO_SMALL) {
2132 HandleBuf = ReallocatePool (sizeof (EFI_HANDLE), HandleBufSize, HandleBuf);
2133 if (HandleBuf == NULL) {
2134 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);
2135 ShellStatus = SHELL_OUT_OF_RESOURCES;
2136 goto Done;
2137 }
2138
2139 Status = gBS->LocateHandle (
2140 ByProtocol,
2141 &gEfiPciRootBridgeIoProtocolGuid,
2142 NULL,
2143 &HandleBufSize,
2144 HandleBuf
2145 );
2146 }
2147
2148 if (EFI_ERROR (Status)) {
2149 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle);
2150 ShellStatus = SHELL_NOT_FOUND;
2151 goto Done;
2152 }
2153
2154 HandleCount = HandleBufSize / sizeof (EFI_HANDLE);
2155 //
2156 // Argument Count == 1(no other argument): enumerate all pci functions
2157 //
2158 if (ShellCommandLineGetCount(Package) == 1) {
2159 gST->ConOut->QueryMode (
2160 gST->ConOut,
2161 gST->ConOut->Mode->Mode,
2162 &TempColumn,
2163 &ScreenSize
2164 );
2165
2166 ScreenCount = 0;
2167 ScreenSize -= 4;
2168 if ((ScreenSize & 1) == 1) {
2169 ScreenSize -= 1;
2170 }
2171
2172 PrintTitle = TRUE;
2173
2174 //
2175 // For each handle, which decides a segment and a bus number range,
2176 // enumerate all devices on it.
2177 //
2178 for (Index = 0; Index < HandleCount; Index++) {
2179 Status = PciGetProtocolAndResource (
2180 HandleBuf[Index],
2181 &IoDev,
2182 &Descriptors
2183 );
2184 if (EFI_ERROR (Status)) {
2185 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_HANDLE_CFG_ERR), gShellDebug1HiiHandle, Status);
2186 ShellStatus = SHELL_NOT_FOUND;
2187 goto Done;
2188 }
2189 //
2190 // No document say it's impossible for a RootBridgeIo protocol handle
2191 // to have more than one address space descriptors, so find out every
2192 // bus range and for each of them do device enumeration.
2193 //
2194 while (TRUE) {
2195 Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
2196
2197 if (EFI_ERROR (Status)) {
2198 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_BUS_RANGE_ERR), gShellDebug1HiiHandle, Status);
2199 ShellStatus = SHELL_NOT_FOUND;
2200 goto Done;
2201 }
2202
2203 if (IsEnd) {
2204 break;
2205 }
2206
2207 for (Bus = MinBus; Bus <= MaxBus; Bus++) {
2208 //
2209 // For each devices, enumerate all functions it contains
2210 //
2211 for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
2212 //
2213 // For each function, read its configuration space and print summary
2214 //
2215 for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
2216 if (ShellGetExecutionBreakFlag ()) {
2217 ShellStatus = SHELL_ABORTED;
2218 goto Done;
2219 }
2220 Address = CALC_EFI_PCI_ADDRESS (Bus, Device, Func, 0);
2221 IoDev->Pci.Read (
2222 IoDev,
2223 EfiPciWidthUint16,
2224 Address,
2225 1,
2226 &PciHeader.VendorId
2227 );
2228
2229 //
2230 // If VendorId = 0xffff, there does not exist a device at this
2231 // location. For each device, if there is any function on it,
2232 // there must be 1 function at Function 0. So if Func = 0, there
2233 // will be no more functions in the same device, so we can break
2234 // loop to deal with the next device.
2235 //
2236 if (PciHeader.VendorId == 0xffff && Func == 0) {
2237 break;
2238 }
2239
2240 if (PciHeader.VendorId != 0xffff) {
2241
2242 if (PrintTitle) {
2243 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_TITLE), gShellDebug1HiiHandle);
2244 PrintTitle = FALSE;
2245 }
2246
2247 IoDev->Pci.Read (
2248 IoDev,
2249 EfiPciWidthUint32,
2250 Address,
2251 sizeof (PciHeader) / sizeof (UINT32),
2252 &PciHeader
2253 );
2254
2255 ShellPrintHiiEx(
2256 -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P1), gShellDebug1HiiHandle,
2257 IoDev->SegmentNumber,
2258 Bus,
2259 Device,
2260 Func
2261 );
2262
2263 PciPrintClassCode (PciHeader.ClassCode, FALSE);
2264 ShellPrintHiiEx(
2265 -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P2), gShellDebug1HiiHandle,
2266 PciHeader.VendorId,
2267 PciHeader.DeviceId,
2268 PciHeader.ClassCode[0]
2269 );
2270
2271 ScreenCount += 2;
2272 if (ScreenCount >= ScreenSize && ScreenSize != 0) {
2273 //
2274 // If ScreenSize == 0 we have the console redirected so don't
2275 // block updates
2276 //
2277 ScreenCount = 0;
2278 }
2279 //
2280 // If this is not a multi-function device, we can leave the loop
2281 // to deal with the next device.
2282 //
2283 if (Func == 0 && ((PciHeader.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00)) {
2284 break;
2285 }
2286 }
2287 }
2288 }
2289 }
2290 //
2291 // If Descriptor is NULL, Configuration() returns EFI_UNSUPPRORED,
2292 // we assume the bus range is 0~PCI_MAX_BUS. After enumerated all
2293 // devices on all bus, we can leave loop.
2294 //
2295 if (Descriptors == NULL) {
2296 break;
2297 }
2298 }
2299 }
2300
2301 Status = EFI_SUCCESS;
2302 goto Done;
2303 }
2304
2305 ExplainData = FALSE;
2306 Segment = 0;
2307 Bus = 0;
2308 Device = 0;
2309 Func = 0;
2310 if (ShellCommandLineGetFlag(Package, L"-i")) {
2311 ExplainData = TRUE;
2312 }
2313
2314 Temp = ShellCommandLineGetValue(Package, L"-s");
2315 if (Temp != NULL) {
2316 //
2317 // Input converted to hexadecimal number.
2318 //
2319 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2320 Segment = (UINT16) RetVal;
2321 } else {
2322 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
2323 ShellStatus = SHELL_INVALID_PARAMETER;
2324 goto Done;
2325 }
2326 }
2327
2328 //
2329 // The first Argument(except "-i") is assumed to be Bus number, second
2330 // to be Device number, and third to be Func number.
2331 //
2332 Temp = ShellCommandLineGetRawValue(Package, 1);
2333 if (Temp != NULL) {
2334 //
2335 // Input converted to hexadecimal number.
2336 //
2337 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2338 Bus = (UINT16) RetVal;
2339 } else {
2340 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
2341 ShellStatus = SHELL_INVALID_PARAMETER;
2342 goto Done;
2343 }
2344
2345 if (Bus > MAX_BUS_NUMBER) {
2346 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
2347 ShellStatus = SHELL_INVALID_PARAMETER;
2348 goto Done;
2349 }
2350 }
2351 Temp = ShellCommandLineGetRawValue(Package, 2);
2352 if (Temp != NULL) {
2353 //
2354 // Input converted to hexadecimal number.
2355 //
2356 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2357 Device = (UINT16) RetVal;
2358 } else {
2359 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
2360 ShellStatus = SHELL_INVALID_PARAMETER;
2361 goto Done;
2362 }
2363
2364 if (Device > MAX_DEVICE_NUMBER){
2365 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
2366 ShellStatus = SHELL_INVALID_PARAMETER;
2367 goto Done;
2368 }
2369 }
2370
2371 Temp = ShellCommandLineGetRawValue(Package, 3);
2372 if (Temp != NULL) {
2373 //
2374 // Input converted to hexadecimal number.
2375 //
2376 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2377 Func = (UINT16) RetVal;
2378 } else {
2379 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
2380 ShellStatus = SHELL_INVALID_PARAMETER;
2381 goto Done;
2382 }
2383
2384 if (Func > MAX_FUNCTION_NUMBER){
2385 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
2386 ShellStatus = SHELL_INVALID_PARAMETER;
2387 goto Done;
2388 }
2389 }
2390
2391 //
2392 // Find the protocol interface who's in charge of current segment, and its
2393 // bus range covers the current bus
2394 //
2395 Status = PciFindProtocolInterface (
2396 HandleBuf,
2397 HandleCount,
2398 Segment,
2399 Bus,
2400 &IoDev
2401 );
2402
2403 if (EFI_ERROR (Status)) {
2404 ShellPrintHiiEx(
2405 -1, -1, NULL, STRING_TOKEN (STR_PCI_NO_FIND), gShellDebug1HiiHandle,
2406 Segment,
2407 Bus
2408 );
2409 ShellStatus = SHELL_NOT_FOUND;
2410 goto Done;
2411 }
2412
2413 Address = CALC_EFI_PCI_ADDRESS (Bus, Device, Func, 0);
2414 Status = IoDev->Pci.Read (
2415 IoDev,
2416 EfiPciWidthUint8,
2417 Address,
2418 sizeof (ConfigSpace),
2419 &ConfigSpace
2420 );
2421
2422 if (EFI_ERROR (Status)) {
2423 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_NO_CFG), gShellDebug1HiiHandle, Status);
2424 ShellStatus = SHELL_ACCESS_DENIED;
2425 goto Done;
2426 }
2427
2428 mConfigSpace = &ConfigSpace;
2429 ShellPrintHiiEx(
2430 -1,
2431 -1,
2432 NULL,
2433 STRING_TOKEN (STR_PCI_INFO),
2434 gShellDebug1HiiHandle,
2435 Segment,
2436 Bus,
2437 Device,
2438 Func,
2439 Segment,
2440 Bus,
2441 Device,
2442 Func
2443 );
2444
2445 //
2446 // Dump standard header of configuration space
2447 //
2448 SizeOfHeader = sizeof (ConfigSpace.Common) + sizeof (ConfigSpace.NonCommon);
2449
2450 DumpHex (2, 0, SizeOfHeader, &ConfigSpace);
2451 ShellPrintEx(-1,-1, L"\r\n");
2452
2453 //
2454 // Dump device dependent Part of configuration space
2455 //
2456 DumpHex (
2457 2,
2458 SizeOfHeader,
2459 sizeof (ConfigSpace) - SizeOfHeader,
2460 ConfigSpace.Data
2461 );
2462
2463 //
2464 // If "-i" appears in command line, interpret data in configuration space
2465 //
2466 if (ExplainData) {
2467 EnhancedDump = 0;
2468 if (ShellCommandLineGetFlag(Package, L"-_e")) {
2469 EnhancedDump = 0xFFFF;
2470 Temp = ShellCommandLineGetValue(Package, L"-_e");
2471 if (Temp != NULL) {
2472 EnhancedDump = (UINT16) ShellHexStrToUintn (Temp);
2473 }
2474 }
2475 Status = PciExplainData (&ConfigSpace, Address, IoDev, EnhancedDump);
2476 }
2477 }
2478 Done:
2479 if (HandleBuf != NULL) {
2480 FreePool (HandleBuf);
2481 }
2482 if (Package != NULL) {
2483 ShellCommandLineFreeVarList (Package);
2484 }
2485 mConfigSpace = NULL;
2486 return ShellStatus;
2487 }
2488
2489 /**
2490 This function finds out the protocol which is in charge of the given
2491 segment, and its bus range covers the current bus number. It lookes
2492 each instances of RootBridgeIoProtocol handle, until the one meets the
2493 criteria is found.
2494
2495 @param[in] HandleBuf Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
2496 @param[in] HandleCount Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
2497 @param[in] Segment Segment number of device we are dealing with.
2498 @param[in] Bus Bus number of device we are dealing with.
2499 @param[out] IoDev Handle used to access configuration space of PCI device.
2500
2501 @retval EFI_SUCCESS The command completed successfully.
2502 @retval EFI_INVALID_PARAMETER Invalid parameter.
2503
2504 **/
2505 EFI_STATUS
2506 PciFindProtocolInterface (
2507 IN EFI_HANDLE *HandleBuf,
2508 IN UINTN HandleCount,
2509 IN UINT16 Segment,
2510 IN UINT16 Bus,
2511 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev
2512 )
2513 {
2514 UINTN Index;
2515 EFI_STATUS Status;
2516 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
2517 UINT16 MinBus;
2518 UINT16 MaxBus;
2519 BOOLEAN IsEnd;
2520
2521 //
2522 // Go through all handles, until the one meets the criteria is found
2523 //
2524 for (Index = 0; Index < HandleCount; Index++) {
2525 Status = PciGetProtocolAndResource (HandleBuf[Index], IoDev, &Descriptors);
2526 if (EFI_ERROR (Status)) {
2527 return Status;
2528 }
2529 //
2530 // When Descriptors == NULL, the Configuration() is not implemented,
2531 // so we only check the Segment number
2532 //
2533 if (Descriptors == NULL && Segment == (*IoDev)->SegmentNumber) {
2534 return EFI_SUCCESS;
2535 }
2536
2537 if ((*IoDev)->SegmentNumber != Segment) {
2538 continue;
2539 }
2540
2541 while (TRUE) {
2542 Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
2543 if (EFI_ERROR (Status)) {
2544 return Status;
2545 }
2546
2547 if (IsEnd) {
2548 break;
2549 }
2550
2551 if (MinBus <= Bus && MaxBus >= Bus) {
2552 return EFI_SUCCESS;
2553 }
2554 }
2555 }
2556
2557 return EFI_NOT_FOUND;
2558 }
2559
2560 /**
2561 This function gets the protocol interface from the given handle, and
2562 obtains its address space descriptors.
2563
2564 @param[in] Handle The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle.
2565 @param[out] IoDev Handle used to access configuration space of PCI device.
2566 @param[out] Descriptors Points to the address space descriptors.
2567
2568 @retval EFI_SUCCESS The command completed successfully
2569 **/
2570 EFI_STATUS
2571 PciGetProtocolAndResource (
2572 IN EFI_HANDLE Handle,
2573 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev,
2574 OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors
2575 )
2576 {
2577 EFI_STATUS Status;
2578
2579 //
2580 // Get inferface from protocol
2581 //
2582 Status = gBS->HandleProtocol (
2583 Handle,
2584 &gEfiPciRootBridgeIoProtocolGuid,
2585 (VOID**)IoDev
2586 );
2587
2588 if (EFI_ERROR (Status)) {
2589 return Status;
2590 }
2591 //
2592 // Call Configuration() to get address space descriptors
2593 //
2594 Status = (*IoDev)->Configuration (*IoDev, (VOID**)Descriptors);
2595 if (Status == EFI_UNSUPPORTED) {
2596 *Descriptors = NULL;
2597 return EFI_SUCCESS;
2598
2599 } else {
2600 return Status;
2601 }
2602 }
2603
2604 /**
2605 This function get the next bus range of given address space descriptors.
2606 It also moves the pointer backward a node, to get prepared to be called
2607 again.
2608
2609 @param[in, out] Descriptors Points to current position of a serial of address space
2610 descriptors.
2611 @param[out] MinBus The lower range of bus number.
2612 @param[out] MaxBus The upper range of bus number.
2613 @param[out] IsEnd Meet end of the serial of descriptors.
2614
2615 @retval EFI_SUCCESS The command completed successfully.
2616 **/
2617 EFI_STATUS
2618 PciGetNextBusRange (
2619 IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,
2620 OUT UINT16 *MinBus,
2621 OUT UINT16 *MaxBus,
2622 OUT BOOLEAN *IsEnd
2623 )
2624 {
2625 *IsEnd = FALSE;
2626
2627 //
2628 // When *Descriptors is NULL, Configuration() is not implemented, so assume
2629 // range is 0~PCI_MAX_BUS
2630 //
2631 if ((*Descriptors) == NULL) {
2632 *MinBus = 0;
2633 *MaxBus = PCI_MAX_BUS;
2634 return EFI_SUCCESS;
2635 }
2636 //
2637 // *Descriptors points to one or more address space descriptors, which
2638 // ends with a end tagged descriptor. Examine each of the descriptors,
2639 // if a bus typed one is found and its bus range covers bus, this handle
2640 // is the handle we are looking for.
2641 //
2642
2643 while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {
2644 if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
2645 *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;
2646 *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;
2647 (*Descriptors)++;
2648 return (EFI_SUCCESS);
2649 }
2650
2651 (*Descriptors)++;
2652 }
2653
2654 if ((*Descriptors)->Desc == ACPI_END_TAG_DESCRIPTOR) {
2655 *IsEnd = TRUE;
2656 }
2657
2658 return EFI_SUCCESS;
2659 }
2660
2661 /**
2662 Explain the data in PCI configuration space. The part which is common for
2663 PCI device and bridge is interpreted in this function. It calls other
2664 functions to interpret data unique for device or bridge.
2665
2666 @param[in] ConfigSpace Data in PCI configuration space.
2667 @param[in] Address Address used to access configuration space of this PCI device.
2668 @param[in] IoDev Handle used to access configuration space of PCI device.
2669 @param[in] EnhancedDump The print format for the dump data.
2670
2671 @retval EFI_SUCCESS The command completed successfully.
2672 **/
2673 EFI_STATUS
2674 PciExplainData (
2675 IN PCI_CONFIG_SPACE *ConfigSpace,
2676 IN UINT64 Address,
2677 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
2678 IN CONST UINT16 EnhancedDump
2679 )
2680 {
2681 PCI_COMMON_HEADER *Common;
2682 PCI_HEADER_TYPE HeaderType;
2683 EFI_STATUS Status;
2684 UINT8 CapPtr;
2685
2686 Common = &(ConfigSpace->Common);
2687
2688 ShellPrintEx (-1, -1, L"\r\n");
2689
2690 //
2691 // Print Vendor Id and Device Id
2692 //
2693 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_VID_DID), gShellDebug1HiiHandle,
2694 INDEX_OF (&(Common->VendorId)),
2695 Common->VendorId,
2696 INDEX_OF (&(Common->DeviceId)),
2697 Common->DeviceId
2698 );
2699
2700 //
2701 // Print register Command
2702 //
2703 PciExplainCommand (&(Common->Command));
2704
2705 //
2706 // Print register Status
2707 //
2708 PciExplainStatus (&(Common->Status), TRUE, PciUndefined);
2709
2710 //
2711 // Print register Revision ID
2712 //
2713 ShellPrintEx(-1, -1, L"\r\n");
2714 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_RID), gShellDebug1HiiHandle,
2715 INDEX_OF (&(Common->RevisionId)),
2716 Common->RevisionId
2717 );
2718
2719 //
2720 // Print register BIST
2721 //
2722 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_BIST), gShellDebug1HiiHandle, INDEX_OF (&(Common->Bist)));
2723 if ((Common->Bist & PCI_BIT_7) != 0) {
2724 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP), gShellDebug1HiiHandle, 0x0f & Common->Bist);
2725 } else {
2726 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP_NO), gShellDebug1HiiHandle);
2727 }
2728 //
2729 // Print register Cache Line Size
2730 //
2731 ShellPrintHiiEx(-1, -1, NULL,
2732 STRING_TOKEN (STR_PCI2_CACHE_LINE_SIZE),
2733 gShellDebug1HiiHandle,
2734 INDEX_OF (&(Common->CacheLineSize)),
2735 Common->CacheLineSize
2736 );
2737
2738 //
2739 // Print register Latency Timer
2740 //
2741 ShellPrintHiiEx(-1, -1, NULL,
2742 STRING_TOKEN (STR_PCI2_LATENCY_TIMER),
2743 gShellDebug1HiiHandle,
2744 INDEX_OF (&(Common->PrimaryLatencyTimer)),
2745 Common->PrimaryLatencyTimer
2746 );
2747
2748 //
2749 // Print register Header Type
2750 //
2751 ShellPrintHiiEx(-1, -1, NULL,
2752 STRING_TOKEN (STR_PCI2_HEADER_TYPE),
2753 gShellDebug1HiiHandle,
2754 INDEX_OF (&(Common->HeaderType)),
2755 Common->HeaderType
2756 );
2757
2758 if ((Common->HeaderType & PCI_BIT_7) != 0) {
2759 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MULTI_FUNCTION), gShellDebug1HiiHandle);
2760
2761 } else {
2762 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SINGLE_FUNCTION), gShellDebug1HiiHandle);
2763 }
2764
2765 HeaderType = (PCI_HEADER_TYPE)(UINT8) (Common->HeaderType & 0x7f);
2766 switch (HeaderType) {
2767 case PciDevice:
2768 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_PCI_DEVICE), gShellDebug1HiiHandle);
2769 break;
2770
2771 case PciP2pBridge:
2772 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_P2P_BRIDGE), gShellDebug1HiiHandle);
2773 break;
2774
2775 case PciCardBusBridge:
2776 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_BRIDGE), gShellDebug1HiiHandle);
2777 break;
2778
2779 default:
2780 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED), gShellDebug1HiiHandle);
2781 HeaderType = PciUndefined;
2782 }
2783
2784 //
2785 // Print register Class Code
2786 //
2787 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CLASS), gShellDebug1HiiHandle);
2788 PciPrintClassCode ((UINT8 *) Common->ClassCode, TRUE);
2789 ShellPrintEx (-1, -1, L"\r\n");
2790
2791 if (ShellGetExecutionBreakFlag()) {
2792 return EFI_SUCCESS;
2793 }
2794
2795 //
2796 // Interpret remaining part of PCI configuration header depending on
2797 // HeaderType
2798 //
2799 CapPtr = 0;
2800 Status = EFI_SUCCESS;
2801 switch (HeaderType) {
2802 case PciDevice:
2803 Status = PciExplainDeviceData (
2804 &(ConfigSpace->NonCommon.Device),
2805 Address,
2806 IoDev
2807 );
2808 CapPtr = ConfigSpace->NonCommon.Device.CapabilitiesPtr;
2809 break;
2810
2811 case PciP2pBridge:
2812 Status = PciExplainBridgeData (
2813 &(ConfigSpace->NonCommon.Bridge),
2814 Address,
2815 IoDev
2816 );
2817 CapPtr = ConfigSpace->NonCommon.Bridge.CapabilitiesPtr;
2818 break;
2819
2820 case PciCardBusBridge:
2821 Status = PciExplainCardBusData (
2822 &(ConfigSpace->NonCommon.CardBus),
2823 Address,
2824 IoDev
2825 );
2826 CapPtr = ConfigSpace->NonCommon.CardBus.CapabilitiesPtr;
2827 break;
2828 case PciUndefined:
2829 default:
2830 break;
2831 }
2832 //
2833 // If Status bit4 is 1, dump or explain capability structure
2834 //
2835 if ((Common->Status) & EFI_PCI_STATUS_CAPABILITY) {
2836 PciExplainCapabilityStruct (IoDev, Address, CapPtr, EnhancedDump);
2837 }
2838
2839 return Status;
2840 }
2841
2842 /**
2843 Explain the device specific part of data in PCI configuration space.
2844
2845 @param[in] Device Data in PCI configuration space.
2846 @param[in] Address Address used to access configuration space of this PCI device.
2847 @param[in] IoDev Handle used to access configuration space of PCI device.
2848
2849 @retval EFI_SUCCESS The command completed successfully.
2850 **/
2851 EFI_STATUS
2852 PciExplainDeviceData (
2853 IN PCI_DEVICE_HEADER *Device,
2854 IN UINT64 Address,
2855 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
2856 )
2857 {
2858 UINTN Index;
2859 BOOLEAN BarExist;
2860 EFI_STATUS Status;
2861 UINTN BarCount;
2862
2863 //
2864 // Print Base Address Registers(Bar). When Bar = 0, this Bar does not
2865 // exist. If these no Bar for this function, print "none", otherwise
2866 // list detail information about this Bar.
2867 //
2868 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDR), gShellDebug1HiiHandle, INDEX_OF (Device->Bar));
2869
2870 BarExist = FALSE;
2871 BarCount = sizeof (Device->Bar) / sizeof (Device->Bar[0]);
2872 for (Index = 0; Index < BarCount; Index++) {
2873 if (Device->Bar[Index] == 0) {
2874 continue;
2875 }
2876
2877 if (!BarExist) {
2878 BarExist = TRUE;
2879 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE), gShellDebug1HiiHandle);
2880 ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------");
2881 }
2882
2883 Status = PciExplainBar (
2884 &(Device->Bar[Index]),
2885 &(mConfigSpace->Common.Command),
2886 Address,
2887 IoDev,
2888 &Index
2889 );
2890
2891 if (EFI_ERROR (Status)) {
2892 break;
2893 }
2894 }
2895
2896 if (!BarExist) {
2897 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
2898
2899 } else {
2900 ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------");
2901 }
2902
2903 //
2904 // Print register Expansion ROM Base Address
2905 //
2906 if ((Device->ROMBar & PCI_BIT_0) == 0) {
2907 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_EXPANSION_ROM_DISABLED), gShellDebug1HiiHandle, INDEX_OF (&(Device->ROMBar)));
2908
2909 } else {
2910 ShellPrintHiiEx(-1, -1, NULL,
2911 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE),
2912 gShellDebug1HiiHandle,
2913 INDEX_OF (&(Device->ROMBar)),
2914 Device->ROMBar
2915 );
2916 }
2917 //
2918 // Print register Cardbus CIS ptr
2919 //
2920 ShellPrintHiiEx(-1, -1, NULL,
2921 STRING_TOKEN (STR_PCI2_CARDBUS_CIS),
2922 gShellDebug1HiiHandle,
2923 INDEX_OF (&(Device->CardBusCISPtr)),
2924 Device->CardBusCISPtr
2925 );
2926
2927 //
2928 // Print register Sub-vendor ID and subsystem ID
2929 //
2930 ShellPrintHiiEx(-1, -1, NULL,
2931 STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID),
2932 gShellDebug1HiiHandle,
2933 INDEX_OF (&(Device->SubVendorId)),
2934 Device->SubVendorId
2935 );
2936
2937 ShellPrintHiiEx(-1, -1, NULL,
2938 STRING_TOKEN (STR_PCI2_SUBSYSTEM_ID),
2939 gShellDebug1HiiHandle,
2940 INDEX_OF (&(Device->SubSystemId)),
2941 Device->SubSystemId
2942 );
2943
2944 //
2945 // Print register Capabilities Ptr
2946 //
2947 ShellPrintHiiEx(-1, -1, NULL,
2948 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR),
2949 gShellDebug1HiiHandle,
2950 INDEX_OF (&(Device->CapabilitiesPtr)),
2951 Device->CapabilitiesPtr
2952 );
2953
2954 //
2955 // Print register Interrupt Line and interrupt pin
2956 //
2957 ShellPrintHiiEx(-1, -1, NULL,
2958 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE),
2959 gShellDebug1HiiHandle,
2960 INDEX_OF (&(Device->InterruptLine)),
2961 Device->InterruptLine
2962 );
2963
2964 ShellPrintHiiEx(-1, -1, NULL,
2965 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
2966 gShellDebug1HiiHandle,
2967 INDEX_OF (&(Device->InterruptPin)),
2968 Device->InterruptPin
2969 );
2970
2971 //
2972 // Print register Min_Gnt and Max_Lat
2973 //
2974 ShellPrintHiiEx(-1, -1, NULL,
2975 STRING_TOKEN (STR_PCI2_MIN_GNT),
2976 gShellDebug1HiiHandle,
2977 INDEX_OF (&(Device->MinGnt)),
2978 Device->MinGnt
2979 );
2980
2981 ShellPrintHiiEx(-1, -1, NULL,
2982 STRING_TOKEN (STR_PCI2_MAX_LAT),
2983 gShellDebug1HiiHandle,
2984 INDEX_OF (&(Device->MaxLat)),
2985 Device->MaxLat
2986 );
2987
2988 return EFI_SUCCESS;
2989 }
2990
2991 /**
2992 Explain the bridge specific part of data in PCI configuration space.
2993
2994 @param[in] Bridge Bridge specific data region in PCI configuration space.
2995 @param[in] Address Address used to access configuration space of this PCI device.
2996 @param[in] IoDev Handle used to access configuration space of PCI device.
2997
2998 @retval EFI_SUCCESS The command completed successfully.
2999 **/
3000 EFI_STATUS
3001 PciExplainBridgeData (
3002 IN PCI_BRIDGE_HEADER *Bridge,
3003 IN UINT64 Address,
3004 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
3005 )
3006 {
3007 UINTN Index;
3008 BOOLEAN BarExist;
3009 UINTN BarCount;
3010 UINT32 IoAddress32;
3011 EFI_STATUS Status;
3012
3013 //
3014 // Print Base Address Registers. When Bar = 0, this Bar does not
3015 // exist. If these no Bar for this function, print "none", otherwise
3016 // list detail information about this Bar.
3017 //
3018 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDRESS), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->Bar)));
3019
3020 BarExist = FALSE;
3021 BarCount = sizeof (Bridge->Bar) / sizeof (Bridge->Bar[0]);
3022
3023 for (Index = 0; Index < BarCount; Index++) {
3024 if (Bridge->Bar[Index] == 0) {
3025 continue;
3026 }
3027
3028 if (!BarExist) {
3029 BarExist = TRUE;
3030 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE_2), gShellDebug1HiiHandle);
3031 ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------");
3032 }
3033
3034 Status = PciExplainBar (
3035 &(Bridge->Bar[Index]),
3036 &(mConfigSpace->Common.Command),
3037 Address,
3038 IoDev,
3039 &Index
3040 );
3041
3042 if (EFI_ERROR (Status)) {
3043 break;
3044 }
3045 }
3046
3047 if (!BarExist) {
3048 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
3049 } else {
3050 ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------");
3051 }
3052
3053 //
3054 // Expansion register ROM Base Address
3055 //
3056 if ((Bridge->ROMBar & PCI_BIT_0) == 0) {
3057 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO_EXPANSION_ROM), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->ROMBar)));
3058
3059 } else {
3060 ShellPrintHiiEx(-1, -1, NULL,
3061 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE_2),
3062 gShellDebug1HiiHandle,
3063 INDEX_OF (&(Bridge->ROMBar)),
3064 Bridge->ROMBar
3065 );
3066 }
3067 //
3068 // Print Bus Numbers(Primary, Secondary, and Subordinate
3069 //
3070 ShellPrintHiiEx(-1, -1, NULL,
3071 STRING_TOKEN (STR_PCI2_BUS_NUMBERS),
3072 gShellDebug1HiiHandle,
3073 INDEX_OF (&(Bridge->PrimaryBus)),
3074 INDEX_OF (&(Bridge->SecondaryBus)),
3075 INDEX_OF (&(Bridge->SubordinateBus))
3076 );
3077
3078 ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n");
3079
3080 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->PrimaryBus);
3081 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SecondaryBus);
3082 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SubordinateBus);
3083
3084 //
3085 // Print register Secondary Latency Timer
3086 //
3087 ShellPrintHiiEx(-1, -1, NULL,
3088 STRING_TOKEN (STR_PCI2_SECONDARY_TIMER),
3089 gShellDebug1HiiHandle,
3090 INDEX_OF (&(Bridge->SecondaryLatencyTimer)),
3091 Bridge->SecondaryLatencyTimer
3092 );
3093
3094 //
3095 // Print register Secondary Status
3096 //
3097 PciExplainStatus (&(Bridge->SecondaryStatus), FALSE, PciP2pBridge);
3098
3099 //
3100 // Print I/O and memory ranges this bridge forwards. There are 3 resource
3101 // types: I/O, memory, and pre-fetchable memory. For each resource type,
3102 // base and limit address are listed.
3103 //
3104 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE), gShellDebug1HiiHandle);
3105 ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n");
3106
3107 //
3108 // IO Base & Limit
3109 //
3110 IoAddress32 = (Bridge->IoBaseUpper << 16 | Bridge->IoBase << 8);
3111 IoAddress32 &= 0xfffff000;
3112 ShellPrintHiiEx(-1, -1, NULL,
3113 STRING_TOKEN (STR_PCI2_TWO_VARS),
3114 gShellDebug1HiiHandle,
3115 INDEX_OF (&(Bridge->IoBase)),
3116 IoAddress32
3117 );
3118
3119 IoAddress32 = (Bridge->IoLimitUpper << 16 | Bridge->IoLimit << 8);
3120 IoAddress32 |= 0x00000fff;
3121 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR), gShellDebug1HiiHandle, IoAddress32);
3122
3123 //
3124 // Memory Base & Limit
3125 //
3126 ShellPrintHiiEx(-1, -1, NULL,
3127 STRING_TOKEN (STR_PCI2_MEMORY),
3128 gShellDebug1HiiHandle,
3129 INDEX_OF (&(Bridge->MemoryBase)),
3130 (Bridge->MemoryBase << 16) & 0xfff00000
3131 );
3132
3133 ShellPrintHiiEx(-1, -1, NULL,
3134 STRING_TOKEN (STR_PCI2_ONE_VAR),
3135 gShellDebug1HiiHandle,
3136 (Bridge->MemoryLimit << 16) | 0x000fffff
3137 );
3138
3139 //
3140 // Pre-fetch-able Memory Base & Limit
3141 //
3142 ShellPrintHiiEx(-1, -1, NULL,
3143 STRING_TOKEN (STR_PCI2_PREFETCHABLE),
3144 gShellDebug1HiiHandle,
3145 INDEX_OF (&(Bridge->PrefetchableMemBase)),
3146 Bridge->PrefetchableBaseUpper,
3147 (Bridge->PrefetchableMemBase << 16) & 0xfff00000
3148 );
3149
3150 ShellPrintHiiEx(-1, -1, NULL,
3151 STRING_TOKEN (STR_PCI2_TWO_VARS_2),
3152 gShellDebug1HiiHandle,
3153 Bridge->PrefetchableLimitUpper,
3154 (Bridge->PrefetchableMemLimit << 16) | 0x000fffff
3155 );
3156
3157 //
3158 // Print register Capabilities Pointer
3159 //
3160 ShellPrintHiiEx(-1, -1, NULL,
3161 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR_2),
3162 gShellDebug1HiiHandle,
3163 INDEX_OF (&(Bridge->CapabilitiesPtr)),
3164 Bridge->CapabilitiesPtr
3165 );
3166
3167 //
3168 // Print register Bridge Control
3169 //
3170 PciExplainBridgeControl (&(Bridge->BridgeControl), PciP2pBridge);
3171
3172 //
3173 // Print register Interrupt Line & PIN
3174 //
3175 ShellPrintHiiEx(-1, -1, NULL,
3176 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_2),
3177 gShellDebug1HiiHandle,
3178 INDEX_OF (&(Bridge->InterruptLine)),
3179 Bridge->InterruptLine
3180 );
3181
3182 ShellPrintHiiEx(-1, -1, NULL,
3183 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
3184 gShellDebug1HiiHandle,
3185 INDEX_OF (&(Bridge->InterruptPin)),
3186 Bridge->InterruptPin
3187 );
3188
3189 return EFI_SUCCESS;
3190 }
3191
3192 /**
3193 Explain the Base Address Register(Bar) in PCI configuration space.
3194
3195 @param[in] Bar Points to the Base Address Register intended to interpret.
3196 @param[in] Command Points to the register Command.
3197 @param[in] Address Address used to access configuration space of this PCI device.
3198 @param[in] IoDev Handle used to access configuration space of PCI device.
3199 @param[in, out] Index The Index.
3200
3201 @retval EFI_SUCCESS The command completed successfully.
3202 **/
3203 EFI_STATUS
3204 PciExplainBar (
3205 IN UINT32 *Bar,
3206 IN UINT16 *Command,
3207 IN UINT64 Address,
3208 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
3209 IN OUT UINTN *Index
3210 )
3211 {
3212 UINT16 OldCommand;
3213 UINT16 NewCommand;
3214 UINT64 Bar64;
3215 UINT32 OldBar32;
3216 UINT32 NewBar32;
3217 UINT64 OldBar64;
3218 UINT64 NewBar64;
3219 BOOLEAN IsMem;
3220 BOOLEAN IsBar32;
3221 UINT64 RegAddress;
3222
3223 IsBar32 = TRUE;
3224 Bar64 = 0;
3225 NewBar32 = 0;
3226 NewBar64 = 0;
3227
3228 //
3229 // According the bar type, list detail about this bar, for example: 32 or
3230 // 64 bits; pre-fetchable or not.
3231 //
3232 if ((*Bar & PCI_BIT_0) == 0) {
3233 //
3234 // This bar is of memory type
3235 //
3236 IsMem = TRUE;
3237
3238 if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) == 0) {
3239 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
3240 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
3241 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_32_BITS), gShellDebug1HiiHandle);
3242
3243 } else if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) != 0) {
3244 Bar64 = 0x0;
3245 CopyMem (&Bar64, Bar, sizeof (UINT64));
3246 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_2), gShellDebug1HiiHandle, (UINT32) RShiftU64 ((Bar64 & 0xfffffffffffffff0ULL), 32));
3247 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_3), gShellDebug1HiiHandle, (UINT32) (Bar64 & 0xfffffffffffffff0ULL));
3248 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
3249 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_64_BITS), gShellDebug1HiiHandle);
3250 IsBar32 = FALSE;
3251 *Index += 1;
3252
3253 } else {
3254 //
3255 // Reserved
3256 //
3257 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
3258 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM_2), gShellDebug1HiiHandle);
3259 }
3260
3261 if ((*Bar & PCI_BIT_3) == 0) {
3262 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO), gShellDebug1HiiHandle);
3263
3264 } else {
3265 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_YES), gShellDebug1HiiHandle);
3266 }
3267
3268 } else {
3269 //
3270 // This bar is of io type
3271 //
3272 IsMem = FALSE;
3273 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_4), gShellDebug1HiiHandle, *Bar & 0xfffffffc);
3274 ShellPrintEx (-1, -1, L"I/O ");
3275 }
3276
3277 //
3278 // Get BAR length(or the amount of resource this bar demands for). To get
3279 // Bar length, first we should temporarily disable I/O and memory access
3280 // of this function(by set bits in the register Command), then write all
3281 // "1"s to this bar. The bar value read back is the amount of resource
3282 // this bar demands for.
3283 //
3284 //
3285 // Disable io & mem access
3286 //
3287 OldCommand = *Command;
3288 NewCommand = (UINT16) (OldCommand & 0xfffc);
3289 RegAddress = Address | INDEX_OF (Command);
3290 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &NewCommand);
3291
3292 RegAddress = Address | INDEX_OF (Bar);
3293
3294 //
3295 // Read after write the BAR to get the size
3296 //
3297 if (IsBar32) {
3298 OldBar32 = *Bar;
3299 NewBar32 = 0xffffffff;
3300
3301 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
3302 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
3303 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &OldBar32);
3304
3305 if (IsMem) {
3306 NewBar32 = NewBar32 & 0xfffffff0;
3307 NewBar32 = (~NewBar32) + 1;
3308
3309 } else {
3310 NewBar32 = NewBar32 & 0xfffffffc;
3311 NewBar32 = (~NewBar32) + 1;
3312 NewBar32 = NewBar32 & 0x0000ffff;
3313 }
3314 } else {
3315
3316 OldBar64 = 0x0;
3317 CopyMem (&OldBar64, Bar, sizeof (UINT64));
3318 NewBar64 = 0xffffffffffffffffULL;
3319
3320 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
3321 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
3322 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &OldBar64);
3323
3324 if (IsMem) {
3325 NewBar64 = NewBar64 & 0xfffffffffffffff0ULL;
3326 NewBar64 = (~NewBar64) + 1;
3327
3328 } else {
3329 NewBar64 = NewBar64 & 0xfffffffffffffffcULL;
3330 NewBar64 = (~NewBar64) + 1;
3331 NewBar64 = NewBar64 & 0x000000000000ffff;
3332 }
3333 }
3334 //
3335 // Enable io & mem access
3336 //
3337 RegAddress = Address | INDEX_OF (Command);
3338 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &OldCommand);
3339
3340 if (IsMem) {
3341 if (IsBar32) {
3342 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32), gShellDebug1HiiHandle, NewBar32);
3343 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_2), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffff0) - 1);