]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c
ShellPkg: Fix pci command to parse seg, bus, dev, and func arguments as hex
[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 - 2011, 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 );
1504
1505 /**
1506 Explain the device specific part of data in PCI configuration space.
1507
1508 @param[in] Device Data in PCI configuration space.
1509 @param[in] Address Address used to access configuration space of this PCI device.
1510 @param[in] IoDev Handle used to access configuration space of PCI device.
1511
1512 @retval EFI_SUCCESS The command completed successfully.
1513 **/
1514 EFI_STATUS
1515 PciExplainDeviceData (
1516 IN PCI_DEVICE_HEADER *Device,
1517 IN UINT64 Address,
1518 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
1519 );
1520
1521 /**
1522 Explain the bridge specific part of data in PCI configuration space.
1523
1524 @param[in] Bridge Bridge specific data region in PCI configuration space.
1525 @param[in] Address Address used to access configuration space of this PCI device.
1526 @param[in] IoDev Handle used to access configuration space of PCI device.
1527
1528 @retval EFI_SUCCESS The command completed successfully.
1529 **/
1530 EFI_STATUS
1531 PciExplainBridgeData (
1532 IN PCI_BRIDGE_HEADER *Bridge,
1533 IN UINT64 Address,
1534 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
1535 );
1536
1537 /**
1538 Explain the Base Address Register(Bar) in PCI configuration space.
1539
1540 @param[in] Bar Points to the Base Address Register intended to interpret.
1541 @param[in] Command Points to the register Command.
1542 @param[in] Address Address used to access configuration space of this PCI device.
1543 @param[in] IoDev Handle used to access configuration space of PCI device.
1544 @param[in, out] Index The Index.
1545
1546 @retval EFI_SUCCESS The command completed successfully.
1547 **/
1548 EFI_STATUS
1549 PciExplainBar (
1550 IN UINT32 *Bar,
1551 IN UINT16 *Command,
1552 IN UINT64 Address,
1553 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
1554 IN OUT UINTN *Index
1555 );
1556
1557 /**
1558 Explain the cardbus specific part of data in PCI configuration space.
1559
1560 @param[in] CardBus CardBus specific region of PCI configuration space.
1561 @param[in] Address Address used to access configuration space of this PCI device.
1562 @param[in] IoDev Handle used to access configuration space of PCI device.
1563
1564 @retval EFI_SUCCESS The command completed successfully.
1565 **/
1566 EFI_STATUS
1567 PciExplainCardBusData (
1568 IN PCI_CARDBUS_HEADER *CardBus,
1569 IN UINT64 Address,
1570 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
1571 );
1572
1573 /**
1574 Explain each meaningful bit of register Status. The definition of Status is
1575 slightly different depending on the PCI header type.
1576
1577 @param[in] Status Points to the content of register Status.
1578 @param[in] MainStatus Indicates if this register is main status(not secondary
1579 status).
1580 @param[in] HeaderType Header type of this PCI device.
1581
1582 @retval EFI_SUCCESS The command completed successfully.
1583 **/
1584 EFI_STATUS
1585 PciExplainStatus (
1586 IN UINT16 *Status,
1587 IN BOOLEAN MainStatus,
1588 IN PCI_HEADER_TYPE HeaderType
1589 );
1590
1591 /**
1592 Explain each meaningful bit of register Command.
1593
1594 @param[in] Command Points to the content of register Command.
1595
1596 @retval EFI_SUCCESS The command completed successfully.
1597 **/
1598 EFI_STATUS
1599 PciExplainCommand (
1600 IN UINT16 *Command
1601 );
1602
1603 /**
1604 Explain each meaningful bit of register Bridge Control.
1605
1606 @param[in] BridgeControl Points to the content of register Bridge Control.
1607 @param[in] HeaderType The headertype.
1608
1609 @retval EFI_SUCCESS The command completed successfully.
1610 **/
1611 EFI_STATUS
1612 PciExplainBridgeControl (
1613 IN UINT16 *BridgeControl,
1614 IN PCI_HEADER_TYPE HeaderType
1615 );
1616
1617 /**
1618 Print each capability structure.
1619
1620 @param[in] IoDev The pointer to the deivce.
1621 @param[in] Address The address to start at.
1622 @param[in] CapPtr The offset from the address.
1623
1624 @retval EFI_SUCCESS The operation was successful.
1625 **/
1626 EFI_STATUS
1627 PciExplainCapabilityStruct (
1628 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
1629 IN UINT64 Address,
1630 IN UINT8 CapPtr
1631 );
1632
1633 /**
1634 Display Pcie device structure.
1635
1636 @param[in] IoDev The pointer to the root pci protocol.
1637 @param[in] Address The Address to start at.
1638 @param[in] CapabilityPtr The offset from the address to start.
1639 **/
1640 EFI_STATUS
1641 PciExplainPciExpress (
1642 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
1643 IN UINT64 Address,
1644 IN UINT8 CapabilityPtr
1645 );
1646
1647 /**
1648 Print out information of the capability information.
1649
1650 @param[in] PciExpressCap The pointer to the structure about the device.
1651
1652 @retval EFI_SUCCESS The operation was successful.
1653 **/
1654 EFI_STATUS
1655 ExplainPcieCapReg (
1656 IN PCIE_CAP_STURCTURE *PciExpressCap
1657 );
1658
1659 /**
1660 Print out information of the device capability information.
1661
1662 @param[in] PciExpressCap The pointer to the structure about the device.
1663
1664 @retval EFI_SUCCESS The operation was successful.
1665 **/
1666 EFI_STATUS
1667 ExplainPcieDeviceCap (
1668 IN PCIE_CAP_STURCTURE *PciExpressCap
1669 );
1670
1671 /**
1672 Print out information of the device control information.
1673
1674 @param[in] PciExpressCap The pointer to the structure about the device.
1675
1676 @retval EFI_SUCCESS The operation was successful.
1677 **/
1678 EFI_STATUS
1679 ExplainPcieDeviceControl (
1680 IN PCIE_CAP_STURCTURE *PciExpressCap
1681 );
1682
1683 /**
1684 Print out information of the device status information.
1685
1686 @param[in] PciExpressCap The pointer to the structure about the device.
1687
1688 @retval EFI_SUCCESS The operation was successful.
1689 **/
1690 EFI_STATUS
1691 ExplainPcieDeviceStatus (
1692 IN PCIE_CAP_STURCTURE *PciExpressCap
1693 );
1694
1695 /**
1696 Print out information of the device link information.
1697
1698 @param[in] PciExpressCap The pointer to the structure about the device.
1699
1700 @retval EFI_SUCCESS The operation was successful.
1701 **/
1702 EFI_STATUS
1703 ExplainPcieLinkCap (
1704 IN PCIE_CAP_STURCTURE *PciExpressCap
1705 );
1706
1707 /**
1708 Print out information of the device link control information.
1709
1710 @param[in] PciExpressCap The pointer to the structure about the device.
1711
1712 @retval EFI_SUCCESS The operation was successful.
1713 **/
1714 EFI_STATUS
1715 ExplainPcieLinkControl (
1716 IN PCIE_CAP_STURCTURE *PciExpressCap
1717 );
1718
1719 /**
1720 Print out information of the device link status information.
1721
1722 @param[in] PciExpressCap The pointer to the structure about the device.
1723
1724 @retval EFI_SUCCESS The operation was successful.
1725 **/
1726 EFI_STATUS
1727 ExplainPcieLinkStatus (
1728 IN PCIE_CAP_STURCTURE *PciExpressCap
1729 );
1730
1731 /**
1732 Print out information of the device slot information.
1733
1734 @param[in] PciExpressCap The pointer to the structure about the device.
1735
1736 @retval EFI_SUCCESS The operation was successful.
1737 **/
1738 EFI_STATUS
1739 ExplainPcieSlotCap (
1740 IN PCIE_CAP_STURCTURE *PciExpressCap
1741 );
1742
1743 /**
1744 Print out information of the device slot control information.
1745
1746 @param[in] PciExpressCap The pointer to the structure about the device.
1747
1748 @retval EFI_SUCCESS The operation was successful.
1749 **/
1750 EFI_STATUS
1751 ExplainPcieSlotControl (
1752 IN PCIE_CAP_STURCTURE *PciExpressCap
1753 );
1754
1755 /**
1756 Print out information of the device slot status information.
1757
1758 @param[in] PciExpressCap The pointer to the structure about the device.
1759
1760 @retval EFI_SUCCESS The operation was successful.
1761 **/
1762 EFI_STATUS
1763 ExplainPcieSlotStatus (
1764 IN PCIE_CAP_STURCTURE *PciExpressCap
1765 );
1766
1767 /**
1768 Print out information of the device root information.
1769
1770 @param[in] PciExpressCap The pointer to the structure about the device.
1771
1772 @retval EFI_SUCCESS The operation was successful.
1773 **/
1774 EFI_STATUS
1775 ExplainPcieRootControl (
1776 IN PCIE_CAP_STURCTURE *PciExpressCap
1777 );
1778
1779 /**
1780 Print out information of the device root capability information.
1781
1782 @param[in] PciExpressCap The pointer to the structure about the device.
1783
1784 @retval EFI_SUCCESS The operation was successful.
1785 **/
1786 EFI_STATUS
1787 ExplainPcieRootCap (
1788 IN PCIE_CAP_STURCTURE *PciExpressCap
1789 );
1790
1791 /**
1792 Print out information of the device root status information.
1793
1794 @param[in] PciExpressCap The pointer to the structure about the device.
1795
1796 @retval EFI_SUCCESS The operation was successful.
1797 **/
1798 EFI_STATUS
1799 ExplainPcieRootStatus (
1800 IN PCIE_CAP_STURCTURE *PciExpressCap
1801 );
1802
1803 typedef EFI_STATUS (*PCIE_EXPLAIN_FUNCTION) (IN PCIE_CAP_STURCTURE *PciExpressCap);
1804
1805 typedef enum {
1806 FieldWidthUINT8,
1807 FieldWidthUINT16,
1808 FieldWidthUINT32
1809 } PCIE_CAPREG_FIELD_WIDTH;
1810
1811 typedef enum {
1812 PcieExplainTypeCommon,
1813 PcieExplainTypeDevice,
1814 PcieExplainTypeLink,
1815 PcieExplainTypeSlot,
1816 PcieExplainTypeRoot,
1817 PcieExplainTypeMax
1818 } PCIE_EXPLAIN_TYPE;
1819
1820 typedef struct
1821 {
1822 UINT16 Token;
1823 UINTN Offset;
1824 PCIE_CAPREG_FIELD_WIDTH Width;
1825 PCIE_EXPLAIN_FUNCTION Func;
1826 PCIE_EXPLAIN_TYPE Type;
1827 } PCIE_EXPLAIN_STRUCT;
1828
1829 PCIE_EXPLAIN_STRUCT PcieExplainList[] = {
1830 {
1831 STRING_TOKEN (STR_PCIEX_CAPABILITY_CAPID),
1832 0x00,
1833 FieldWidthUINT8,
1834 NULL,
1835 PcieExplainTypeCommon
1836 },
1837 {
1838 STRING_TOKEN (STR_PCIEX_NEXTCAP_PTR),
1839 0x01,
1840 FieldWidthUINT8,
1841 NULL,
1842 PcieExplainTypeCommon
1843 },
1844 {
1845 STRING_TOKEN (STR_PCIEX_CAP_REGISTER),
1846 0x02,
1847 FieldWidthUINT16,
1848 ExplainPcieCapReg,
1849 PcieExplainTypeCommon
1850 },
1851 {
1852 STRING_TOKEN (STR_PCIEX_DEVICE_CAP),
1853 0x04,
1854 FieldWidthUINT32,
1855 ExplainPcieDeviceCap,
1856 PcieExplainTypeDevice
1857 },
1858 {
1859 STRING_TOKEN (STR_PCIEX_DEVICE_CONTROL),
1860 0x08,
1861 FieldWidthUINT16,
1862 ExplainPcieDeviceControl,
1863 PcieExplainTypeDevice
1864 },
1865 {
1866 STRING_TOKEN (STR_PCIEX_DEVICE_STATUS),
1867 0x0a,
1868 FieldWidthUINT16,
1869 ExplainPcieDeviceStatus,
1870 PcieExplainTypeDevice
1871 },
1872 {
1873 STRING_TOKEN (STR_PCIEX_LINK_CAPABILITIES),
1874 0x0c,
1875 FieldWidthUINT32,
1876 ExplainPcieLinkCap,
1877 PcieExplainTypeLink
1878 },
1879 {
1880 STRING_TOKEN (STR_PCIEX_LINK_CONTROL),
1881 0x10,
1882 FieldWidthUINT16,
1883 ExplainPcieLinkControl,
1884 PcieExplainTypeLink
1885 },
1886 {
1887 STRING_TOKEN (STR_PCIEX_LINK_STATUS),
1888 0x12,
1889 FieldWidthUINT16,
1890 ExplainPcieLinkStatus,
1891 PcieExplainTypeLink
1892 },
1893 {
1894 STRING_TOKEN (STR_PCIEX_SLOT_CAPABILITIES),
1895 0x14,
1896 FieldWidthUINT32,
1897 ExplainPcieSlotCap,
1898 PcieExplainTypeSlot
1899 },
1900 {
1901 STRING_TOKEN (STR_PCIEX_SLOT_CONTROL),
1902 0x18,
1903 FieldWidthUINT16,
1904 ExplainPcieSlotControl,
1905 PcieExplainTypeSlot
1906 },
1907 {
1908 STRING_TOKEN (STR_PCIEX_SLOT_STATUS),
1909 0x1a,
1910 FieldWidthUINT16,
1911 ExplainPcieSlotStatus,
1912 PcieExplainTypeSlot
1913 },
1914 {
1915 STRING_TOKEN (STR_PCIEX_ROOT_CONTROL),
1916 0x1c,
1917 FieldWidthUINT16,
1918 ExplainPcieRootControl,
1919 PcieExplainTypeRoot
1920 },
1921 {
1922 STRING_TOKEN (STR_PCIEX_RSVDP),
1923 0x1e,
1924 FieldWidthUINT16,
1925 ExplainPcieRootCap,
1926 PcieExplainTypeRoot
1927 },
1928 {
1929 STRING_TOKEN (STR_PCIEX_ROOT_STATUS),
1930 0x20,
1931 FieldWidthUINT32,
1932 ExplainPcieRootStatus,
1933 PcieExplainTypeRoot
1934 },
1935 {
1936 0,
1937 0,
1938 (PCIE_CAPREG_FIELD_WIDTH)0,
1939 NULL,
1940 PcieExplainTypeMax
1941 }
1942 };
1943
1944 //
1945 // Global Variables
1946 //
1947 PCI_CONFIG_SPACE *mConfigSpace = NULL;
1948 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
1949 {L"-s", TypeValue},
1950 {L"-i", TypeFlag},
1951 {NULL, TypeMax}
1952 };
1953
1954 CHAR16 *DevicePortTypeTable[] = {
1955 L"PCI Express Endpoint",
1956 L"Legacy PCI Express Endpoint",
1957 L"Unknown Type",
1958 L"Unknonw Type",
1959 L"Root Port of PCI Express Root Complex",
1960 L"Upstream Port of PCI Express Switch",
1961 L"Downstream Port of PCI Express Switch",
1962 L"PCI Express to PCI/PCI-X Bridge",
1963 L"PCI/PCI-X to PCI Express Bridge",
1964 L"Root Complex Integrated Endpoint",
1965 L"Root Complex Event Collector"
1966 };
1967
1968 CHAR16 *L0sLatencyStrTable[] = {
1969 L"Less than 64ns",
1970 L"64ns to less than 128ns",
1971 L"128ns to less than 256ns",
1972 L"256ns to less than 512ns",
1973 L"512ns to less than 1us",
1974 L"1us to less than 2us",
1975 L"2us-4us",
1976 L"More than 4us"
1977 };
1978
1979 CHAR16 *L1LatencyStrTable[] = {
1980 L"Less than 1us",
1981 L"1us to less than 2us",
1982 L"2us to less than 4us",
1983 L"4us to less than 8us",
1984 L"8us to less than 16us",
1985 L"16us to less than 32us",
1986 L"32us-64us",
1987 L"More than 64us"
1988 };
1989
1990 CHAR16 *ASPMCtrlStrTable[] = {
1991 L"Disabled",
1992 L"L0s Entry Enabled",
1993 L"L1 Entry Enabled",
1994 L"L0s and L1 Entry Enabled"
1995 };
1996
1997 CHAR16 *SlotPwrLmtScaleTable[] = {
1998 L"1.0x",
1999 L"0.1x",
2000 L"0.01x",
2001 L"0.001x"
2002 };
2003
2004 CHAR16 *IndicatorTable[] = {
2005 L"Reserved",
2006 L"On",
2007 L"Blink",
2008 L"Off"
2009 };
2010
2011
2012 /**
2013 Function for 'pci' command.
2014
2015 @param[in] ImageHandle Handle to the Image (NULL if Internal).
2016 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
2017 **/
2018 SHELL_STATUS
2019 EFIAPI
2020 ShellCommandRunPci (
2021 IN EFI_HANDLE ImageHandle,
2022 IN EFI_SYSTEM_TABLE *SystemTable
2023 )
2024 {
2025 UINT16 Segment;
2026 UINT16 Bus;
2027 UINT16 Device;
2028 UINT16 Func;
2029 UINT64 Address;
2030 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev;
2031 EFI_STATUS Status;
2032 PCI_COMMON_HEADER PciHeader;
2033 PCI_CONFIG_SPACE ConfigSpace;
2034 UINTN ScreenCount;
2035 UINTN TempColumn;
2036 UINTN ScreenSize;
2037 BOOLEAN ExplainData;
2038 UINTN Index;
2039 UINTN SizeOfHeader;
2040 BOOLEAN PrintTitle;
2041 UINTN HandleBufSize;
2042 EFI_HANDLE *HandleBuf;
2043 UINTN HandleCount;
2044 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
2045 UINT16 MinBus;
2046 UINT16 MaxBus;
2047 BOOLEAN IsEnd;
2048 LIST_ENTRY *Package;
2049 CHAR16 *ProblemParam;
2050 SHELL_STATUS ShellStatus;
2051 CONST CHAR16 *Temp;
2052 UINT64 RetVal;
2053
2054 ShellStatus = SHELL_SUCCESS;
2055 Status = EFI_SUCCESS;
2056 Address = 0;
2057 IoDev = NULL;
2058 HandleBuf = NULL;
2059 Package = NULL;
2060
2061 //
2062 // initialize the shell lib (we must be in non-auto-init...)
2063 //
2064 Status = ShellInitialize();
2065 ASSERT_EFI_ERROR(Status);
2066
2067 Status = CommandInit();
2068 ASSERT_EFI_ERROR(Status);
2069
2070 //
2071 // parse the command line
2072 //
2073 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
2074 if (EFI_ERROR(Status)) {
2075 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
2076 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);
2077 FreePool(ProblemParam);
2078 ShellStatus = SHELL_INVALID_PARAMETER;
2079 } else {
2080 ASSERT(FALSE);
2081 }
2082 } else {
2083
2084 if (ShellCommandLineGetCount(Package) == 2) {
2085 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);
2086 ShellStatus = SHELL_INVALID_PARAMETER;
2087 goto Done;
2088 }
2089
2090 if (ShellCommandLineGetCount(Package) > 4) {
2091 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
2092 ShellStatus = SHELL_INVALID_PARAMETER;
2093 goto Done;
2094 }
2095 if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetValue(Package, L"-s") == NULL) {
2096 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-s");
2097 ShellStatus = SHELL_INVALID_PARAMETER;
2098 goto Done;
2099 }
2100 //
2101 // Get all instances of PciRootBridgeIo. Allocate space for 1 EFI_HANDLE and
2102 // call LibLocateHandle(), if EFI_BUFFER_TOO_SMALL is returned, allocate enough
2103 // space for handles and call it again.
2104 //
2105 HandleBufSize = sizeof (EFI_HANDLE);
2106 HandleBuf = (EFI_HANDLE *) AllocateZeroPool (HandleBufSize);
2107 if (HandleBuf == NULL) {
2108 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);
2109 ShellStatus = SHELL_OUT_OF_RESOURCES;
2110 goto Done;
2111 }
2112
2113 Status = gBS->LocateHandle (
2114 ByProtocol,
2115 &gEfiPciRootBridgeIoProtocolGuid,
2116 NULL,
2117 &HandleBufSize,
2118 HandleBuf
2119 );
2120
2121 if (Status == EFI_BUFFER_TOO_SMALL) {
2122 HandleBuf = ReallocatePool (sizeof (EFI_HANDLE), HandleBufSize, HandleBuf);
2123 if (HandleBuf == NULL) {
2124 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);
2125 ShellStatus = SHELL_OUT_OF_RESOURCES;
2126 goto Done;
2127 }
2128
2129 Status = gBS->LocateHandle (
2130 ByProtocol,
2131 &gEfiPciRootBridgeIoProtocolGuid,
2132 NULL,
2133 &HandleBufSize,
2134 HandleBuf
2135 );
2136 }
2137
2138 if (EFI_ERROR (Status)) {
2139 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle);
2140 ShellStatus = SHELL_NOT_FOUND;
2141 goto Done;
2142 }
2143
2144 HandleCount = HandleBufSize / sizeof (EFI_HANDLE);
2145 //
2146 // Argument Count == 1(no other argument): enumerate all pci functions
2147 //
2148 if (ShellCommandLineGetCount(Package) == 1) {
2149 gST->ConOut->QueryMode (
2150 gST->ConOut,
2151 gST->ConOut->Mode->Mode,
2152 &TempColumn,
2153 &ScreenSize
2154 );
2155
2156 ScreenCount = 0;
2157 ScreenSize -= 4;
2158 if ((ScreenSize & 1) == 1) {
2159 ScreenSize -= 1;
2160 }
2161
2162 PrintTitle = TRUE;
2163
2164 //
2165 // For each handle, which decides a segment and a bus number range,
2166 // enumerate all devices on it.
2167 //
2168 for (Index = 0; Index < HandleCount; Index++) {
2169 Status = PciGetProtocolAndResource (
2170 HandleBuf[Index],
2171 &IoDev,
2172 &Descriptors
2173 );
2174 if (EFI_ERROR (Status)) {
2175 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_HANDLE_CFG_ERR), gShellDebug1HiiHandle, Status);
2176 ShellStatus = SHELL_NOT_FOUND;
2177 goto Done;
2178 }
2179 //
2180 // No document say it's impossible for a RootBridgeIo protocol handle
2181 // to have more than one address space descriptors, so find out every
2182 // bus range and for each of them do device enumeration.
2183 //
2184 while (TRUE) {
2185 Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
2186
2187 if (EFI_ERROR (Status)) {
2188 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_BUS_RANGE_ERR), gShellDebug1HiiHandle, Status);
2189 ShellStatus = SHELL_NOT_FOUND;
2190 goto Done;
2191 }
2192
2193 if (IsEnd) {
2194 break;
2195 }
2196
2197 for (Bus = MinBus; Bus <= MaxBus; Bus++) {
2198 //
2199 // For each devices, enumerate all functions it contains
2200 //
2201 for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
2202 //
2203 // For each function, read its configuration space and print summary
2204 //
2205 for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
2206 if (ShellGetExecutionBreakFlag ()) {
2207 ShellStatus = SHELL_ABORTED;
2208 goto Done;
2209 }
2210 Address = CALC_EFI_PCI_ADDRESS (Bus, Device, Func, 0);
2211 IoDev->Pci.Read (
2212 IoDev,
2213 EfiPciWidthUint16,
2214 Address,
2215 1,
2216 &PciHeader.VendorId
2217 );
2218
2219 //
2220 // If VendorId = 0xffff, there does not exist a device at this
2221 // location. For each device, if there is any function on it,
2222 // there must be 1 function at Function 0. So if Func = 0, there
2223 // will be no more functions in the same device, so we can break
2224 // loop to deal with the next device.
2225 //
2226 if (PciHeader.VendorId == 0xffff && Func == 0) {
2227 break;
2228 }
2229
2230 if (PciHeader.VendorId != 0xffff) {
2231
2232 if (PrintTitle) {
2233 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_TITLE), gShellDebug1HiiHandle);
2234 PrintTitle = FALSE;
2235 }
2236
2237 IoDev->Pci.Read (
2238 IoDev,
2239 EfiPciWidthUint32,
2240 Address,
2241 sizeof (PciHeader) / sizeof (UINT32),
2242 &PciHeader
2243 );
2244
2245 ShellPrintHiiEx(
2246 -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P1), gShellDebug1HiiHandle,
2247 IoDev->SegmentNumber,
2248 Bus,
2249 Device,
2250 Func
2251 );
2252
2253 PciPrintClassCode (PciHeader.ClassCode, FALSE);
2254 ShellPrintHiiEx(
2255 -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P2), gShellDebug1HiiHandle,
2256 PciHeader.VendorId,
2257 PciHeader.DeviceId,
2258 PciHeader.ClassCode[0]
2259 );
2260
2261 ScreenCount += 2;
2262 if (ScreenCount >= ScreenSize && ScreenSize != 0) {
2263 //
2264 // If ScreenSize == 0 we have the console redirected so don't
2265 // block updates
2266 //
2267 ScreenCount = 0;
2268 }
2269 //
2270 // If this is not a multi-function device, we can leave the loop
2271 // to deal with the next device.
2272 //
2273 if (Func == 0 && ((PciHeader.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00)) {
2274 break;
2275 }
2276 }
2277 }
2278 }
2279 }
2280 //
2281 // If Descriptor is NULL, Configuration() returns EFI_UNSUPPRORED,
2282 // we assume the bus range is 0~PCI_MAX_BUS. After enumerated all
2283 // devices on all bus, we can leave loop.
2284 //
2285 if (Descriptors == NULL) {
2286 break;
2287 }
2288 }
2289 }
2290
2291 Status = EFI_SUCCESS;
2292 goto Done;
2293 }
2294
2295 ExplainData = FALSE;
2296 Segment = 0;
2297 Bus = 0;
2298 Device = 0;
2299 Func = 0;
2300 if (ShellCommandLineGetFlag(Package, L"-i")) {
2301 ExplainData = TRUE;
2302 }
2303
2304 Temp = ShellCommandLineGetValue(Package, L"-s");
2305 if (Temp != NULL) {
2306 //
2307 // Input converted to hexadecimal number.
2308 //
2309 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2310 Segment = (UINT16) RetVal;
2311 } else {
2312 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
2313 ShellStatus = SHELL_INVALID_PARAMETER;
2314 goto Done;
2315 }
2316 }
2317
2318 //
2319 // The first Argument(except "-i") is assumed to be Bus number, second
2320 // to be Device number, and third to be Func number.
2321 //
2322 Temp = ShellCommandLineGetRawValue(Package, 1);
2323 if (Temp != NULL) {
2324 //
2325 // Input converted to hexadecimal number.
2326 //
2327 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2328 Bus = (UINT16) RetVal;
2329 } else {
2330 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
2331 ShellStatus = SHELL_INVALID_PARAMETER;
2332 goto Done;
2333 }
2334
2335 if (Bus > MAX_BUS_NUMBER) {
2336 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
2337 ShellStatus = SHELL_INVALID_PARAMETER;
2338 goto Done;
2339 }
2340 }
2341 Temp = ShellCommandLineGetRawValue(Package, 2);
2342 if (Temp != NULL) {
2343 //
2344 // Input converted to hexadecimal number.
2345 //
2346 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2347 Device = (UINT16) RetVal;
2348 } else {
2349 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
2350 ShellStatus = SHELL_INVALID_PARAMETER;
2351 goto Done;
2352 }
2353
2354 if (Device > MAX_DEVICE_NUMBER){
2355 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
2356 ShellStatus = SHELL_INVALID_PARAMETER;
2357 goto Done;
2358 }
2359 }
2360
2361 Temp = ShellCommandLineGetRawValue(Package, 3);
2362 if (Temp != NULL) {
2363 //
2364 // Input converted to hexadecimal number.
2365 //
2366 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2367 Func = (UINT16) RetVal;
2368 } else {
2369 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
2370 ShellStatus = SHELL_INVALID_PARAMETER;
2371 goto Done;
2372 }
2373
2374 if (Func > MAX_FUNCTION_NUMBER){
2375 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
2376 ShellStatus = SHELL_INVALID_PARAMETER;
2377 goto Done;
2378 }
2379 }
2380
2381 //
2382 // Find the protocol interface who's in charge of current segment, and its
2383 // bus range covers the current bus
2384 //
2385 Status = PciFindProtocolInterface (
2386 HandleBuf,
2387 HandleCount,
2388 Segment,
2389 Bus,
2390 &IoDev
2391 );
2392
2393 if (EFI_ERROR (Status)) {
2394 ShellPrintHiiEx(
2395 -1, -1, NULL, STRING_TOKEN (STR_PCI_NO_FIND), gShellDebug1HiiHandle,
2396 Segment,
2397 Bus
2398 );
2399 ShellStatus = SHELL_NOT_FOUND;
2400 goto Done;
2401 }
2402
2403 Address = CALC_EFI_PCI_ADDRESS (Bus, Device, Func, 0);
2404 Status = IoDev->Pci.Read (
2405 IoDev,
2406 EfiPciWidthUint8,
2407 Address,
2408 sizeof (ConfigSpace),
2409 &ConfigSpace
2410 );
2411
2412 if (EFI_ERROR (Status)) {
2413 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_NO_CFG), gShellDebug1HiiHandle, Status);
2414 ShellStatus = SHELL_ACCESS_DENIED;
2415 goto Done;
2416 }
2417
2418 mConfigSpace = &ConfigSpace;
2419 ShellPrintHiiEx(
2420 -1,
2421 -1,
2422 NULL,
2423 STRING_TOKEN (STR_PCI_INFO),
2424 gShellDebug1HiiHandle,
2425 Segment,
2426 Bus,
2427 Device,
2428 Func,
2429 Segment,
2430 Bus,
2431 Device,
2432 Func
2433 );
2434
2435 //
2436 // Dump standard header of configuration space
2437 //
2438 SizeOfHeader = sizeof (ConfigSpace.Common) + sizeof (ConfigSpace.NonCommon);
2439
2440 DumpHex (2, 0, SizeOfHeader, &ConfigSpace);
2441 ShellPrintEx(-1,-1, L"\r\n");
2442
2443 //
2444 // Dump device dependent Part of configuration space
2445 //
2446 DumpHex (
2447 2,
2448 SizeOfHeader,
2449 sizeof (ConfigSpace) - SizeOfHeader,
2450 ConfigSpace.Data
2451 );
2452
2453 //
2454 // If "-i" appears in command line, interpret data in configuration space
2455 //
2456 if (ExplainData) {
2457 Status = PciExplainData (&ConfigSpace, Address, IoDev);
2458 }
2459 }
2460 Done:
2461 if (HandleBuf != NULL) {
2462 FreePool (HandleBuf);
2463 }
2464 if (Package != NULL) {
2465 ShellCommandLineFreeVarList (Package);
2466 }
2467 mConfigSpace = NULL;
2468 return ShellStatus;
2469 }
2470
2471 /**
2472 This function finds out the protocol which is in charge of the given
2473 segment, and its bus range covers the current bus number. It lookes
2474 each instances of RootBridgeIoProtocol handle, until the one meets the
2475 criteria is found.
2476
2477 @param[in] HandleBuf Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
2478 @param[in] HandleCount Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
2479 @param[in] Segment Segment number of device we are dealing with.
2480 @param[in] Bus Bus number of device we are dealing with.
2481 @param[out] IoDev Handle used to access configuration space of PCI device.
2482
2483 @retval EFI_SUCCESS The command completed successfully.
2484 @retval EFI_INVALID_PARAMETER Invalid parameter.
2485
2486 **/
2487 EFI_STATUS
2488 PciFindProtocolInterface (
2489 IN EFI_HANDLE *HandleBuf,
2490 IN UINTN HandleCount,
2491 IN UINT16 Segment,
2492 IN UINT16 Bus,
2493 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev
2494 )
2495 {
2496 UINTN Index;
2497 EFI_STATUS Status;
2498 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
2499 UINT16 MinBus;
2500 UINT16 MaxBus;
2501 BOOLEAN IsEnd;
2502
2503 //
2504 // Go through all handles, until the one meets the criteria is found
2505 //
2506 for (Index = 0; Index < HandleCount; Index++) {
2507 Status = PciGetProtocolAndResource (HandleBuf[Index], IoDev, &Descriptors);
2508 if (EFI_ERROR (Status)) {
2509 return Status;
2510 }
2511 //
2512 // When Descriptors == NULL, the Configuration() is not implemented,
2513 // so we only check the Segment number
2514 //
2515 if (Descriptors == NULL && Segment == (*IoDev)->SegmentNumber) {
2516 return EFI_SUCCESS;
2517 }
2518
2519 if ((*IoDev)->SegmentNumber != Segment) {
2520 continue;
2521 }
2522
2523 while (TRUE) {
2524 Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
2525 if (EFI_ERROR (Status)) {
2526 return Status;
2527 }
2528
2529 if (IsEnd) {
2530 break;
2531 }
2532
2533 if (MinBus <= Bus && MaxBus >= Bus) {
2534 return EFI_SUCCESS;
2535 }
2536 }
2537 }
2538
2539 return EFI_NOT_FOUND;
2540 }
2541
2542 /**
2543 This function gets the protocol interface from the given handle, and
2544 obtains its address space descriptors.
2545
2546 @param[in] Handle The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle.
2547 @param[out] IoDev Handle used to access configuration space of PCI device.
2548 @param[out] Descriptors Points to the address space descriptors.
2549
2550 @retval EFI_SUCCESS The command completed successfully
2551 **/
2552 EFI_STATUS
2553 PciGetProtocolAndResource (
2554 IN EFI_HANDLE Handle,
2555 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev,
2556 OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors
2557 )
2558 {
2559 EFI_STATUS Status;
2560
2561 //
2562 // Get inferface from protocol
2563 //
2564 Status = gBS->HandleProtocol (
2565 Handle,
2566 &gEfiPciRootBridgeIoProtocolGuid,
2567 (VOID**)IoDev
2568 );
2569
2570 if (EFI_ERROR (Status)) {
2571 return Status;
2572 }
2573 //
2574 // Call Configuration() to get address space descriptors
2575 //
2576 Status = (*IoDev)->Configuration (*IoDev, (VOID**)Descriptors);
2577 if (Status == EFI_UNSUPPORTED) {
2578 *Descriptors = NULL;
2579 return EFI_SUCCESS;
2580
2581 } else {
2582 return Status;
2583 }
2584 }
2585
2586 /**
2587 This function get the next bus range of given address space descriptors.
2588 It also moves the pointer backward a node, to get prepared to be called
2589 again.
2590
2591 @param[in, out] Descriptors Points to current position of a serial of address space
2592 descriptors.
2593 @param[out] MinBus The lower range of bus number.
2594 @param[out] MaxBus The upper range of bus number.
2595 @param[out] IsEnd Meet end of the serial of descriptors.
2596
2597 @retval EFI_SUCCESS The command completed successfully.
2598 **/
2599 EFI_STATUS
2600 PciGetNextBusRange (
2601 IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,
2602 OUT UINT16 *MinBus,
2603 OUT UINT16 *MaxBus,
2604 OUT BOOLEAN *IsEnd
2605 )
2606 {
2607 *IsEnd = FALSE;
2608
2609 //
2610 // When *Descriptors is NULL, Configuration() is not implemented, so assume
2611 // range is 0~PCI_MAX_BUS
2612 //
2613 if ((*Descriptors) == NULL) {
2614 *MinBus = 0;
2615 *MaxBus = PCI_MAX_BUS;
2616 return EFI_SUCCESS;
2617 }
2618 //
2619 // *Descriptors points to one or more address space descriptors, which
2620 // ends with a end tagged descriptor. Examine each of the descriptors,
2621 // if a bus typed one is found and its bus range covers bus, this handle
2622 // is the handle we are looking for.
2623 //
2624
2625 while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {
2626 if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
2627 *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;
2628 *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;
2629 (*Descriptors)++;
2630 return (EFI_SUCCESS);
2631 }
2632
2633 (*Descriptors)++;
2634 }
2635
2636 if ((*Descriptors)->Desc == ACPI_END_TAG_DESCRIPTOR) {
2637 *IsEnd = TRUE;
2638 }
2639
2640 return EFI_SUCCESS;
2641 }
2642
2643 /**
2644 Explain the data in PCI configuration space. The part which is common for
2645 PCI device and bridge is interpreted in this function. It calls other
2646 functions to interpret data unique for device or bridge.
2647
2648 @param[in] ConfigSpace Data in PCI configuration space.
2649 @param[in] Address Address used to access configuration space of this PCI device.
2650 @param[in] IoDev Handle used to access configuration space of PCI device.
2651
2652 @retval EFI_SUCCESS The command completed successfully.
2653 **/
2654 EFI_STATUS
2655 PciExplainData (
2656 IN PCI_CONFIG_SPACE *ConfigSpace,
2657 IN UINT64 Address,
2658 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
2659 )
2660 {
2661 PCI_COMMON_HEADER *Common;
2662 PCI_HEADER_TYPE HeaderType;
2663 EFI_STATUS Status;
2664 UINT8 CapPtr;
2665
2666 Common = &(ConfigSpace->Common);
2667
2668 ShellPrintEx (-1, -1, L"\r\n");
2669
2670 //
2671 // Print Vendor Id and Device Id
2672 //
2673 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_VID_DID), gShellDebug1HiiHandle,
2674 INDEX_OF (&(Common->VendorId)),
2675 Common->VendorId,
2676 INDEX_OF (&(Common->DeviceId)),
2677 Common->DeviceId
2678 );
2679
2680 //
2681 // Print register Command
2682 //
2683 PciExplainCommand (&(Common->Command));
2684
2685 //
2686 // Print register Status
2687 //
2688 PciExplainStatus (&(Common->Status), TRUE, PciUndefined);
2689
2690 //
2691 // Print register Revision ID
2692 //
2693 ShellPrintEx(-1, -1, L"\r\n");
2694 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_RID), gShellDebug1HiiHandle,
2695 INDEX_OF (&(Common->RevisionId)),
2696 Common->RevisionId
2697 );
2698
2699 //
2700 // Print register BIST
2701 //
2702 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_BIST), gShellDebug1HiiHandle, INDEX_OF (&(Common->Bist)));
2703 if ((Common->Bist & PCI_BIT_7) != 0) {
2704 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP), gShellDebug1HiiHandle, 0x0f & Common->Bist);
2705 } else {
2706 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP_NO), gShellDebug1HiiHandle);
2707 }
2708 //
2709 // Print register Cache Line Size
2710 //
2711 ShellPrintHiiEx(-1, -1, NULL,
2712 STRING_TOKEN (STR_PCI2_CACHE_LINE_SIZE),
2713 gShellDebug1HiiHandle,
2714 INDEX_OF (&(Common->CacheLineSize)),
2715 Common->CacheLineSize
2716 );
2717
2718 //
2719 // Print register Latency Timer
2720 //
2721 ShellPrintHiiEx(-1, -1, NULL,
2722 STRING_TOKEN (STR_PCI2_LATENCY_TIMER),
2723 gShellDebug1HiiHandle,
2724 INDEX_OF (&(Common->PrimaryLatencyTimer)),
2725 Common->PrimaryLatencyTimer
2726 );
2727
2728 //
2729 // Print register Header Type
2730 //
2731 ShellPrintHiiEx(-1, -1, NULL,
2732 STRING_TOKEN (STR_PCI2_HEADER_TYPE),
2733 gShellDebug1HiiHandle,
2734 INDEX_OF (&(Common->HeaderType)),
2735 Common->HeaderType
2736 );
2737
2738 if ((Common->HeaderType & PCI_BIT_7) != 0) {
2739 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MULTI_FUNCTION), gShellDebug1HiiHandle);
2740
2741 } else {
2742 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SINGLE_FUNCTION), gShellDebug1HiiHandle);
2743 }
2744
2745 HeaderType = (PCI_HEADER_TYPE)(UINT8) (Common->HeaderType & 0x7f);
2746 switch (HeaderType) {
2747 case PciDevice:
2748 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_PCI_DEVICE), gShellDebug1HiiHandle);
2749 break;
2750
2751 case PciP2pBridge:
2752 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_P2P_BRIDGE), gShellDebug1HiiHandle);
2753 break;
2754
2755 case PciCardBusBridge:
2756 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_BRIDGE), gShellDebug1HiiHandle);
2757 break;
2758
2759 default:
2760 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED), gShellDebug1HiiHandle);
2761 HeaderType = PciUndefined;
2762 }
2763
2764 //
2765 // Print register Class Code
2766 //
2767 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CLASS), gShellDebug1HiiHandle);
2768 PciPrintClassCode ((UINT8 *) Common->ClassCode, TRUE);
2769 ShellPrintEx (-1, -1, L"\r\n");
2770
2771 if (ShellGetExecutionBreakFlag()) {
2772 return EFI_SUCCESS;
2773 }
2774
2775 //
2776 // Interpret remaining part of PCI configuration header depending on
2777 // HeaderType
2778 //
2779 CapPtr = 0;
2780 Status = EFI_SUCCESS;
2781 switch (HeaderType) {
2782 case PciDevice:
2783 Status = PciExplainDeviceData (
2784 &(ConfigSpace->NonCommon.Device),
2785 Address,
2786 IoDev
2787 );
2788 CapPtr = ConfigSpace->NonCommon.Device.CapabilitiesPtr;
2789 break;
2790
2791 case PciP2pBridge:
2792 Status = PciExplainBridgeData (
2793 &(ConfigSpace->NonCommon.Bridge),
2794 Address,
2795 IoDev
2796 );
2797 CapPtr = ConfigSpace->NonCommon.Bridge.CapabilitiesPtr;
2798 break;
2799
2800 case PciCardBusBridge:
2801 Status = PciExplainCardBusData (
2802 &(ConfigSpace->NonCommon.CardBus),
2803 Address,
2804 IoDev
2805 );
2806 CapPtr = ConfigSpace->NonCommon.CardBus.CapabilitiesPtr;
2807 break;
2808 case PciUndefined:
2809 default:
2810 break;
2811 }
2812 //
2813 // If Status bit4 is 1, dump or explain capability structure
2814 //
2815 if ((Common->Status) & EFI_PCI_STATUS_CAPABILITY) {
2816 PciExplainCapabilityStruct (IoDev, Address, CapPtr);
2817 }
2818
2819 return Status;
2820 }
2821
2822 /**
2823 Explain the device specific part of data in PCI configuration space.
2824
2825 @param[in] Device Data in PCI configuration space.
2826 @param[in] Address Address used to access configuration space of this PCI device.
2827 @param[in] IoDev Handle used to access configuration space of PCI device.
2828
2829 @retval EFI_SUCCESS The command completed successfully.
2830 **/
2831 EFI_STATUS
2832 PciExplainDeviceData (
2833 IN PCI_DEVICE_HEADER *Device,
2834 IN UINT64 Address,
2835 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
2836 )
2837 {
2838 UINTN Index;
2839 BOOLEAN BarExist;
2840 EFI_STATUS Status;
2841 UINTN BarCount;
2842
2843 //
2844 // Print Base Address Registers(Bar). When Bar = 0, this Bar does not
2845 // exist. If these no Bar for this function, print "none", otherwise
2846 // list detail information about this Bar.
2847 //
2848 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDR), gShellDebug1HiiHandle, INDEX_OF (Device->Bar));
2849
2850 BarExist = FALSE;
2851 BarCount = sizeof (Device->Bar) / sizeof (Device->Bar[0]);
2852 for (Index = 0; Index < BarCount; Index++) {
2853 if (Device->Bar[Index] == 0) {
2854 continue;
2855 }
2856
2857 if (!BarExist) {
2858 BarExist = TRUE;
2859 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE), gShellDebug1HiiHandle);
2860 ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------");
2861 }
2862
2863 Status = PciExplainBar (
2864 &(Device->Bar[Index]),
2865 &(mConfigSpace->Common.Command),
2866 Address,
2867 IoDev,
2868 &Index
2869 );
2870
2871 if (EFI_ERROR (Status)) {
2872 break;
2873 }
2874 }
2875
2876 if (!BarExist) {
2877 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
2878
2879 } else {
2880 ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------");
2881 }
2882
2883 //
2884 // Print register Expansion ROM Base Address
2885 //
2886 if ((Device->ROMBar & PCI_BIT_0) == 0) {
2887 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_EXPANSION_ROM_DISABLED), gShellDebug1HiiHandle, INDEX_OF (&(Device->ROMBar)));
2888
2889 } else {
2890 ShellPrintHiiEx(-1, -1, NULL,
2891 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE),
2892 gShellDebug1HiiHandle,
2893 INDEX_OF (&(Device->ROMBar)),
2894 Device->ROMBar
2895 );
2896 }
2897 //
2898 // Print register Cardbus CIS ptr
2899 //
2900 ShellPrintHiiEx(-1, -1, NULL,
2901 STRING_TOKEN (STR_PCI2_CARDBUS_CIS),
2902 gShellDebug1HiiHandle,
2903 INDEX_OF (&(Device->CardBusCISPtr)),
2904 Device->CardBusCISPtr
2905 );
2906
2907 //
2908 // Print register Sub-vendor ID and subsystem ID
2909 //
2910 ShellPrintHiiEx(-1, -1, NULL,
2911 STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID),
2912 gShellDebug1HiiHandle,
2913 INDEX_OF (&(Device->SubVendorId)),
2914 Device->SubVendorId
2915 );
2916
2917 ShellPrintHiiEx(-1, -1, NULL,
2918 STRING_TOKEN (STR_PCI2_SUBSYSTEM_ID),
2919 gShellDebug1HiiHandle,
2920 INDEX_OF (&(Device->SubSystemId)),
2921 Device->SubSystemId
2922 );
2923
2924 //
2925 // Print register Capabilities Ptr
2926 //
2927 ShellPrintHiiEx(-1, -1, NULL,
2928 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR),
2929 gShellDebug1HiiHandle,
2930 INDEX_OF (&(Device->CapabilitiesPtr)),
2931 Device->CapabilitiesPtr
2932 );
2933
2934 //
2935 // Print register Interrupt Line and interrupt pin
2936 //
2937 ShellPrintHiiEx(-1, -1, NULL,
2938 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE),
2939 gShellDebug1HiiHandle,
2940 INDEX_OF (&(Device->InterruptLine)),
2941 Device->InterruptLine
2942 );
2943
2944 ShellPrintHiiEx(-1, -1, NULL,
2945 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
2946 gShellDebug1HiiHandle,
2947 INDEX_OF (&(Device->InterruptPin)),
2948 Device->InterruptPin
2949 );
2950
2951 //
2952 // Print register Min_Gnt and Max_Lat
2953 //
2954 ShellPrintHiiEx(-1, -1, NULL,
2955 STRING_TOKEN (STR_PCI2_MIN_GNT),
2956 gShellDebug1HiiHandle,
2957 INDEX_OF (&(Device->MinGnt)),
2958 Device->MinGnt
2959 );
2960
2961 ShellPrintHiiEx(-1, -1, NULL,
2962 STRING_TOKEN (STR_PCI2_MAX_LAT),
2963 gShellDebug1HiiHandle,
2964 INDEX_OF (&(Device->MaxLat)),
2965 Device->MaxLat
2966 );
2967
2968 return EFI_SUCCESS;
2969 }
2970
2971 /**
2972 Explain the bridge specific part of data in PCI configuration space.
2973
2974 @param[in] Bridge Bridge specific data region in PCI configuration space.
2975 @param[in] Address Address used to access configuration space of this PCI device.
2976 @param[in] IoDev Handle used to access configuration space of PCI device.
2977
2978 @retval EFI_SUCCESS The command completed successfully.
2979 **/
2980 EFI_STATUS
2981 PciExplainBridgeData (
2982 IN PCI_BRIDGE_HEADER *Bridge,
2983 IN UINT64 Address,
2984 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
2985 )
2986 {
2987 UINTN Index;
2988 BOOLEAN BarExist;
2989 UINTN BarCount;
2990 UINT32 IoAddress32;
2991 EFI_STATUS Status;
2992
2993 //
2994 // Print Base Address Registers. When Bar = 0, this Bar does not
2995 // exist. If these no Bar for this function, print "none", otherwise
2996 // list detail information about this Bar.
2997 //
2998 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDRESS), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->Bar)));
2999
3000 BarExist = FALSE;
3001 BarCount = sizeof (Bridge->Bar) / sizeof (Bridge->Bar[0]);
3002
3003 for (Index = 0; Index < BarCount; Index++) {
3004 if (Bridge->Bar[Index] == 0) {
3005 continue;
3006 }
3007
3008 if (!BarExist) {
3009 BarExist = TRUE;
3010 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE_2), gShellDebug1HiiHandle);
3011 ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------");
3012 }
3013
3014 Status = PciExplainBar (
3015 &(Bridge->Bar[Index]),
3016 &(mConfigSpace->Common.Command),
3017 Address,
3018 IoDev,
3019 &Index
3020 );
3021
3022 if (EFI_ERROR (Status)) {
3023 break;
3024 }
3025 }
3026
3027 if (!BarExist) {
3028 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
3029 } else {
3030 ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------");
3031 }
3032
3033 //
3034 // Expansion register ROM Base Address
3035 //
3036 if ((Bridge->ROMBar & PCI_BIT_0) == 0) {
3037 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO_EXPANSION_ROM), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->ROMBar)));
3038
3039 } else {
3040 ShellPrintHiiEx(-1, -1, NULL,
3041 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE_2),
3042 gShellDebug1HiiHandle,
3043 INDEX_OF (&(Bridge->ROMBar)),
3044 Bridge->ROMBar
3045 );
3046 }
3047 //
3048 // Print Bus Numbers(Primary, Secondary, and Subordinate
3049 //
3050 ShellPrintHiiEx(-1, -1, NULL,
3051 STRING_TOKEN (STR_PCI2_BUS_NUMBERS),
3052 gShellDebug1HiiHandle,
3053 INDEX_OF (&(Bridge->PrimaryBus)),
3054 INDEX_OF (&(Bridge->SecondaryBus)),
3055 INDEX_OF (&(Bridge->SubordinateBus))
3056 );
3057
3058 ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n");
3059
3060 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->PrimaryBus);
3061 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SecondaryBus);
3062 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SubordinateBus);
3063
3064 //
3065 // Print register Secondary Latency Timer
3066 //
3067 ShellPrintHiiEx(-1, -1, NULL,
3068 STRING_TOKEN (STR_PCI2_SECONDARY_TIMER),
3069 gShellDebug1HiiHandle,
3070 INDEX_OF (&(Bridge->SecondaryLatencyTimer)),
3071 Bridge->SecondaryLatencyTimer
3072 );
3073
3074 //
3075 // Print register Secondary Status
3076 //
3077 PciExplainStatus (&(Bridge->SecondaryStatus), FALSE, PciP2pBridge);
3078
3079 //
3080 // Print I/O and memory ranges this bridge forwards. There are 3 resource
3081 // types: I/O, memory, and pre-fetchable memory. For each resource type,
3082 // base and limit address are listed.
3083 //
3084 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE), gShellDebug1HiiHandle);
3085 ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n");
3086
3087 //
3088 // IO Base & Limit
3089 //
3090 IoAddress32 = (Bridge->IoBaseUpper << 16 | Bridge->IoBase << 8);
3091 IoAddress32 &= 0xfffff000;
3092 ShellPrintHiiEx(-1, -1, NULL,
3093 STRING_TOKEN (STR_PCI2_TWO_VARS),
3094 gShellDebug1HiiHandle,
3095 INDEX_OF (&(Bridge->IoBase)),
3096 IoAddress32
3097 );
3098
3099 IoAddress32 = (Bridge->IoLimitUpper << 16 | Bridge->IoLimit << 8);
3100 IoAddress32 |= 0x00000fff;
3101 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR), gShellDebug1HiiHandle, IoAddress32);
3102
3103 //
3104 // Memory Base & Limit
3105 //
3106 ShellPrintHiiEx(-1, -1, NULL,
3107 STRING_TOKEN (STR_PCI2_MEMORY),
3108 gShellDebug1HiiHandle,
3109 INDEX_OF (&(Bridge->MemoryBase)),
3110 (Bridge->MemoryBase << 16) & 0xfff00000
3111 );
3112
3113 ShellPrintHiiEx(-1, -1, NULL,
3114 STRING_TOKEN (STR_PCI2_ONE_VAR),
3115 gShellDebug1HiiHandle,
3116 (Bridge->MemoryLimit << 16) | 0x000fffff
3117 );
3118
3119 //
3120 // Pre-fetch-able Memory Base & Limit
3121 //
3122 ShellPrintHiiEx(-1, -1, NULL,
3123 STRING_TOKEN (STR_PCI2_PREFETCHABLE),
3124 gShellDebug1HiiHandle,
3125 INDEX_OF (&(Bridge->PrefetchableMemBase)),
3126 Bridge->PrefetchableBaseUpper,
3127 (Bridge->PrefetchableMemBase << 16) & 0xfff00000
3128 );
3129
3130 ShellPrintHiiEx(-1, -1, NULL,
3131 STRING_TOKEN (STR_PCI2_TWO_VARS_2),
3132 gShellDebug1HiiHandle,
3133 Bridge->PrefetchableLimitUpper,
3134 (Bridge->PrefetchableMemLimit << 16) | 0x000fffff
3135 );
3136
3137 //
3138 // Print register Capabilities Pointer
3139 //
3140 ShellPrintHiiEx(-1, -1, NULL,
3141 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR_2),
3142 gShellDebug1HiiHandle,
3143 INDEX_OF (&(Bridge->CapabilitiesPtr)),
3144 Bridge->CapabilitiesPtr
3145 );
3146
3147 //
3148 // Print register Bridge Control
3149 //
3150 PciExplainBridgeControl (&(Bridge->BridgeControl), PciP2pBridge);
3151
3152 //
3153 // Print register Interrupt Line & PIN
3154 //
3155 ShellPrintHiiEx(-1, -1, NULL,
3156 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_2),
3157 gShellDebug1HiiHandle,
3158 INDEX_OF (&(Bridge->InterruptLine)),
3159 Bridge->InterruptLine
3160 );
3161
3162 ShellPrintHiiEx(-1, -1, NULL,
3163 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
3164 gShellDebug1HiiHandle,
3165 INDEX_OF (&(Bridge->InterruptPin)),
3166 Bridge->InterruptPin
3167 );
3168
3169 return EFI_SUCCESS;
3170 }
3171
3172 /**
3173 Explain the Base Address Register(Bar) in PCI configuration space.
3174
3175 @param[in] Bar Points to the Base Address Register intended to interpret.
3176 @param[in] Command Points to the register Command.
3177 @param[in] Address Address used to access configuration space of this PCI device.
3178 @param[in] IoDev Handle used to access configuration space of PCI device.
3179 @param[in, out] Index The Index.
3180
3181 @retval EFI_SUCCESS The command completed successfully.
3182 **/
3183 EFI_STATUS
3184 PciExplainBar (
3185 IN UINT32 *Bar,
3186 IN UINT16 *Command,
3187 IN UINT64 Address,
3188 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
3189 IN OUT UINTN *Index
3190 )
3191 {
3192 UINT16 OldCommand;
3193 UINT16 NewCommand;
3194 UINT64 Bar64;
3195 UINT32 OldBar32;
3196 UINT32 NewBar32;
3197 UINT64 OldBar64;
3198 UINT64 NewBar64;
3199 BOOLEAN IsMem;
3200 BOOLEAN IsBar32;
3201 UINT64 RegAddress;
3202
3203 IsBar32 = TRUE;
3204 Bar64 = 0;
3205 NewBar32 = 0;
3206 NewBar64 = 0;
3207
3208 //
3209 // According the bar type, list detail about this bar, for example: 32 or
3210 // 64 bits; pre-fetchable or not.
3211 //
3212 if ((*Bar & PCI_BIT_0) == 0) {
3213 //
3214 // This bar is of memory type
3215 //
3216 IsMem = TRUE;
3217
3218 if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) == 0) {
3219 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
3220 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
3221 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_32_BITS), gShellDebug1HiiHandle);
3222
3223 } else if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) != 0) {
3224 Bar64 = 0x0;
3225 CopyMem (&Bar64, Bar, sizeof (UINT64));
3226 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_2), gShellDebug1HiiHandle, (UINT32) RShiftU64 ((Bar64 & 0xfffffffffffffff0ULL), 32));
3227 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_3), gShellDebug1HiiHandle, (UINT32) (Bar64 & 0xfffffffffffffff0ULL));
3228 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
3229 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_64_BITS), gShellDebug1HiiHandle);
3230 IsBar32 = FALSE;
3231 *Index += 1;
3232
3233 } else {
3234 //
3235 // Reserved
3236 //
3237 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
3238 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM_2), gShellDebug1HiiHandle);
3239 }
3240
3241 if ((*Bar & PCI_BIT_3) == 0) {
3242 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO), gShellDebug1HiiHandle);
3243
3244 } else {
3245 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_YES), gShellDebug1HiiHandle);
3246 }
3247
3248 } else {
3249 //
3250 // This bar is of io type
3251 //
3252 IsMem = FALSE;
3253 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_4), gShellDebug1HiiHandle, *Bar & 0xfffffffc);
3254 ShellPrintEx (-1, -1, L"I/O ");
3255 }
3256
3257 //
3258 // Get BAR length(or the amount of resource this bar demands for). To get
3259 // Bar length, first we should temporarily disable I/O and memory access
3260 // of this function(by set bits in the register Command), then write all
3261 // "1"s to this bar. The bar value read back is the amount of resource
3262 // this bar demands for.
3263 //
3264 //
3265 // Disable io & mem access
3266 //
3267 OldCommand = *Command;
3268 NewCommand = (UINT16) (OldCommand & 0xfffc);
3269 RegAddress = Address | INDEX_OF (Command);
3270 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &NewCommand);
3271
3272 RegAddress = Address | INDEX_OF (Bar);
3273
3274 //
3275 // Read after write the BAR to get the size
3276 //
3277 if (IsBar32) {
3278 OldBar32 = *Bar;
3279 NewBar32 = 0xffffffff;
3280
3281 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
3282 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
3283 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &OldBar32);
3284
3285 if (IsMem) {
3286 NewBar32 = NewBar32 & 0xfffffff0;
3287 NewBar32 = (~NewBar32) + 1;
3288
3289 } else {
3290 NewBar32 = NewBar32 & 0xfffffffc;
3291 NewBar32 = (~NewBar32) + 1;
3292 NewBar32 = NewBar32 & 0x0000ffff;
3293 }
3294 } else {
3295
3296 OldBar64 = 0x0;
3297 CopyMem (&OldBar64, Bar, sizeof (UINT64));
3298 NewBar64 = 0xffffffffffffffffULL;
3299
3300 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
3301 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
3302 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &OldBar64);
3303
3304 if (IsMem) {
3305 NewBar64 = NewBar64 & 0xfffffffffffffff0ULL;
3306 NewBar64 = (~NewBar64) + 1;
3307
3308 } else {
3309 NewBar64 = NewBar64 & 0xfffffffffffffffcULL;
3310 NewBar64 = (~NewBar64) + 1;
3311 NewBar64 = NewBar64 & 0x000000000000ffff;
3312 }
3313 }
3314 //
3315 // Enable io & mem access
3316 //
3317 RegAddress = Address | INDEX_OF (Command);
3318 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &OldCommand);
3319
3320 if (IsMem) {
3321 if (IsBar32) {
3322 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32), gShellDebug1HiiHandle, NewBar32);
3323 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_2), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffff0) - 1);
3324
3325 } else {
3326 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) RShiftU64 (NewBar64, 32));
3327 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) NewBar64);
3328 ShellPrintEx (-1, -1, L" ");
3329 ShellPrintHiiEx(-1, -1, NULL,
3330 STRING_TOKEN (STR_PCI2_RSHIFT),
3331 gShellDebug1HiiHandle,
3332 (UINT32) RShiftU64 ((NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1), 32)
3333 );
3334 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) (NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1));
3335
3336 }
3337 } else {
3338 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_3), gShellDebug1HiiHandle, NewBar32);
3339 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_4), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffffc) - 1);
3340 }
3341
3342 return EFI_SUCCESS;
3343 }
3344
3345 /**
3346 Explain the cardbus specific part of data in PCI configuration space.
3347
3348 @param[in] CardBus CardBus specific region of PCI configuration space.
3349 @param[in] Address Address used to access configuration space of this PCI device.
3350 @param[in] IoDev Handle used to access configuration space of PCI device.
3351
3352 @retval EFI_SUCCESS The command completed successfully.
3353 **/
3354 EFI_STATUS
3355 PciExplainCardBusData (
3356 IN PCI_CARDBUS_HEADER *CardBus,
3357 IN UINT64 Address,
3358 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
3359 )
3360 {
3361 BOOLEAN Io32Bit;
3362 PCI_CARDBUS_DATA *CardBusData;
3363
3364 ShellPrintHiiEx(-1, -1, NULL,
3365 STRING_TOKEN (STR_PCI2_CARDBUS_SOCKET),
3366 gShellDebug1HiiHandle,
3367 INDEX_OF (&(CardBus->CardBusSocketReg)),
3368 CardBus->CardBusSocketReg
3369 );
3370
3371 //
3372 // Print Secondary Status
3373 //
3374 PciExplainStatus (&(CardBus->SecondaryStatus), FALSE, PciCardBusBridge);
3375
3376 //
3377 // Print Bus Numbers(Primary bus number, CardBus bus number, and
3378 // Subordinate bus number
3379 //
3380 ShellPrintHiiEx(-1, -1, NULL,
3381 STRING_TOKEN (STR_PCI2_BUS_NUMBERS_2),
3382 gShellDebug1HiiHandle,
3383 INDEX_OF (&(CardBus->PciBusNumber)),
3384 INDEX_OF (&(CardBus->CardBusBusNumber)),
3385 INDEX_OF (&(CardBus->SubordinateBusNumber))
3386 );
3387
3388 ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n");
3389
3390 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS), gShellDebug1HiiHandle, CardBus->PciBusNumber);
3391 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_2), gShellDebug1HiiHandle, CardBus->CardBusBusNumber);
3392 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_3), gShellDebug1HiiHandle, CardBus->SubordinateBusNumber);
3393
3394 //
3395 // Print CardBus Latency Timer
3396 //
3397 ShellPrintHiiEx(-1, -1, NULL,
3398 STRING_TOKEN (STR_PCI2_CARDBUS_LATENCY),
3399 gShellDebug1HiiHandle,
3400 INDEX_OF (&(CardBus->CardBusLatencyTimer)),
3401 CardBus->CardBusLatencyTimer
3402 );
3403
3404 //
3405 // Print Memory/Io ranges this cardbus bridge forwards
3406 //
3407 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE_2), gShellDebug1HiiHandle);
3408 ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n");
3409
3410 ShellPrintHiiEx(-1, -1, NULL,
3411 STRING_TOKEN (STR_PCI2_MEM_3),
3412 gShellDebug1HiiHandle,
3413 INDEX_OF (&(CardBus->MemoryBase0)),
3414 CardBus->BridgeControl & PCI_BIT_8 ? L" Prefetchable" : L"Non-Prefetchable",
3415 CardBus->MemoryBase0 & 0xfffff000,
3416 CardBus->MemoryLimit0 | 0x00000fff
3417 );
3418
3419 ShellPrintHiiEx(-1, -1, NULL,
3420 STRING_TOKEN (STR_PCI2_MEM_3),
3421 gShellDebug1HiiHandle,
3422 INDEX_OF (&(CardBus->MemoryBase1)),
3423 CardBus->BridgeControl & PCI_BIT_9 ? L" Prefetchable" : L"Non-Prefetchable",
3424 CardBus->MemoryBase1 & 0xfffff000,
3425 CardBus->MemoryLimit1 | 0x00000fff
3426 );
3427
3428 Io32Bit = (BOOLEAN) (CardBus->IoBase0 & PCI_BIT_0);
3429 ShellPrintHiiEx(-1, -1, NULL,
3430 STRING_TOKEN (STR_PCI2_IO_2),
3431 gShellDebug1HiiHandle,
3432 INDEX_OF (&(CardBus->IoBase0)),
3433 Io32Bit ? L" 32 bit" : L" 16 bit",
3434 CardBus->IoBase0 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
3435 (CardBus->IoLimit0 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003
3436 );
3437
3438 Io32Bit = (BOOLEAN) (CardBus->IoBase1 & PCI_BIT_0);
3439 ShellPrintHiiEx(-1, -1, NULL,
3440 STRING_TOKEN (STR_PCI2_IO_2),
3441 gShellDebug1HiiHandle,
3442 INDEX_OF (&(CardBus->IoBase1)),
3443 Io32Bit ? L" 32 bit" : L" 16 bit",
3444 CardBus->IoBase1 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
3445 (CardBus->IoLimit1 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003
3446 );
3447
3448 //
3449 // Print register Interrupt Line & PIN
3450 //
3451 ShellPrintHiiEx(-1, -1, NULL,
3452 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_3),
3453 gShellDebug1HiiHandle,
3454 INDEX_OF (&(CardBus->InterruptLine)),
3455 CardBus->InterruptLine,
3456 INDEX_OF (&(CardBus->InterruptPin)),
3457 CardBus->InterruptPin
3458 );
3459
3460 //
3461 // Print register Bridge Control
3462 //
3463 PciExplainBridgeControl (&(CardBus->BridgeControl), PciCardBusBridge);
3464
3465 //
3466 // Print some registers in data region of PCI configuration space for cardbus
3467 // bridge. Fields include: Sub VendorId, Subsystem ID, and Legacy Mode Base
3468 // Address.
3469 //
3470 CardBusData = (PCI_CARDBUS_DATA *) ((UINT8 *) CardBus + sizeof (PCI_CARDBUS_HEADER));
3471
3472 ShellPrintHiiEx(-1, -1, NULL,
3473 STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID_2),
3474 gShellDebug1HiiHandle,
3475 INDEX_OF (&(CardBusData->SubVendorId)),
3476 CardBusData->SubVendorId,
3477 INDEX_OF (&(CardBusData->SubSystemId)),
3478 CardBusData->SubSystemId
3479 );
3480
3481 ShellPrintHiiEx(-1, -1, NULL,
3482 STRING_TOKEN (STR_PCI2_OPTIONAL),
3483 gShellDebug1HiiHandle,
3484 INDEX_OF (&(CardBusData->LegacyBase)),
3485 CardBusData->LegacyBase
3486 );
3487
3488 return EFI_SUCCESS;
3489 }
3490
3491 /**
3492 Explain each meaningful bit of register Status. The definition of Status is
3493 slightly different depending on the PCI header type.
3494
3495 @param[in] Status Points to the content of register Status.
3496 @param[in] MainStatus Indicates if this register is main status(not secondary
3497 status).
3498 @param[in] HeaderType Header type of this PCI device.
3499
3500 @retval EFI_SUCCESS The command completed successfully.
3501 **/
3502 EFI_STATUS
3503 PciExplainStatus (
3504 IN UINT16 *Status,
3505 IN BOOLEAN MainStatus,
3506 IN PCI_HEADER_TYPE HeaderType
3507 )
3508 {
3509 if (MainStatus) {
3510 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status);
3511
3512 } else {
3513 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SECONDARY_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status);
3514 }
3515
3516 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEW_CAPABILITIES), gShellDebug1HiiHandle, (*Status & PCI_BIT_4) != 0);
3517
3518 //
3519 // Bit 5 is meaningless for CardBus Bridge
3520 //
3521 if (HeaderType == PciCardBusBridge) {
3522 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE), gShellDebug1HiiHandle, (*Status & PCI_BIT_5) != 0);
3523
3524 } else {
3525 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE_2), gShellDebug1HiiHandle, (*Status & PCI_BIT_5) != 0);
3526 }
3527
3528 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST_BACK), gShellDebug1HiiHandle, (*Status & PCI_BIT_7) != 0);
3529
3530 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MASTER_DATA), gShellDebug1HiiHandle, (*Status & PCI_BIT_8) != 0);
3531 //
3532 // Bit 9 and bit 10 together decides the DEVSEL timing
3533 //
3534 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_DEVSEL_TIMING), gShellDebug1HiiHandle);
3535 if ((*Status & PCI_BIT_9) == 0 && (*Status & PCI_BIT_10) == 0) {
3536 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST), gShellDebug1HiiHandle);
3537
3538 } else if ((*Status & PCI_BIT_9) != 0 && (*Status & PCI_BIT_10) == 0) {
3539 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEDIUM), gShellDebug1HiiHandle);
3540
3541 } else if ((*Status & PCI_BIT_9) == 0 && (*Status & PCI_BIT_10) != 0) {
3542 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SLOW), gShellDebug1HiiHandle);
3543
3544 } else {
3545 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED_2), gShellDebug1HiiHandle);
3546 }
3547
3548 ShellPrintHiiEx(-1, -1, NULL,
3549 STRING_TOKEN (STR_PCI2_SIGNALED_TARGET),
3550 gShellDebug1HiiHandle,
3551 (*Status & PCI_BIT_11) != 0
3552 );
3553
3554 ShellPrintHiiEx(-1, -1, NULL,
3555 STRING_TOKEN (STR_PCI2_RECEIVED_TARGET),
3556 gShellDebug1HiiHandle,
3557 (*Status & PCI_BIT_12) != 0
3558 );
3559
3560 ShellPrintHiiEx(-1, -1, NULL,
3561 STRING_TOKEN (STR_PCI2_RECEIVED_MASTER),
3562 gShellDebug1HiiHandle,
3563 (*Status & PCI_BIT_13) != 0
3564 );
3565
3566 if (MainStatus) {
3567 ShellPrintHiiEx(-1, -1, NULL,
3568 STRING_TOKEN (STR_PCI2_SIGNALED_ERROR),
3569 gShellDebug1HiiHandle,
3570 (*Status & PCI_BIT_14) != 0
3571 );
3572
3573 } else {
3574 ShellPrintHiiEx(-1, -1, NULL,
3575 STRING_TOKEN (STR_PCI2_RECEIVED_ERROR),
3576 gShellDebug1HiiHandle,
3577 (*Status & PCI_BIT_14) != 0
3578 );
3579 }
3580
3581 ShellPrintHiiEx(-1, -1, NULL,
3582 STRING_TOKEN (STR_PCI2_DETECTED_ERROR),
3583 gShellDebug1HiiHandle,
3584 (*Status & PCI_BIT_15) != 0
3585 );
3586
3587 return EFI_SUCCESS;
3588 }
3589
3590 /**
3591 Explain each meaningful bit of register Command.
3592
3593 @param[in] Command Points to the content of register Command.
3594
3595 @retval EFI_SUCCESS The command completed successfully.
3596 **/
3597 EFI_STATUS
3598 PciExplainCommand (
3599 IN UINT16 *Command
3600 )
3601 {
3602 //
3603 // Print the binary value of register Command
3604 //
3605 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_COMMAND), gShellDebug1HiiHandle, INDEX_OF (Command), *Command);
3606
3607 //
3608 // Explain register Command bit by bit
3609 //
3610 ShellPrintHiiEx(-1, -1, NULL,
3611 STRING_TOKEN (STR_PCI2_SPACE_ACCESS_DENIED),
3612 gShellDebug1HiiHandle,
3613 (*Command & PCI_BIT_0) != 0
3614 );
3615
3616 ShellPrintHiiEx(-1, -1, NULL,
3617 STRING_TOKEN (STR_PCI2_MEMORY_SPACE),
3618 gShellDebug1HiiHandle,
3619 (*Command & PCI_BIT_1) != 0
3620 );
3621
3622 ShellPrintHiiEx(-1, -1, NULL,
3623 STRING_TOKEN (STR_PCI2_BEHAVE_BUS_MASTER),
3624 gShellDebug1HiiHandle,
3625 (*Command & PCI_BIT_2) != 0
3626 );
3627
3628 ShellPrintHiiEx(-1, -1, NULL,
3629 STRING_TOKEN (STR_PCI2_MONITOR_SPECIAL_CYCLE),
3630 gShellDebug1HiiHandle,
3631 (*Command & PCI_BIT_3) != 0
3632 );
3633
3634 ShellPrintHiiEx(-1, -1, NULL,
3635 STRING_TOKEN (STR_PCI2_MEM_WRITE_INVALIDATE),
3636 gShellDebug1HiiHandle,
3637 (*Command & PCI_BIT_4) != 0
3638 );
3639
3640 ShellPrintHiiEx(-1, -1, NULL,
3641 STRING_TOKEN (STR_PCI2_PALETTE_SNOOPING),
3642 gShellDebug1HiiHandle,
3643 (*Command & PCI_BIT_5) != 0
3644 );
3645
3646 ShellPrintHiiEx(-1, -1, NULL,
3647 STRING_TOKEN (STR_PCI2_ASSERT_PERR),
3648 gShellDebug1HiiHandle,
3649 (*Command & PCI_BIT_6) != 0
3650 );
3651
3652 ShellPrintHiiEx(-1, -1, NULL,
3653 STRING_TOKEN (STR_PCI2_DO_ADDR_STEPPING),
3654 gShellDebug1HiiHandle,
3655 (*Command & PCI_BIT_7) != 0
3656 );
3657
3658 ShellPrintHiiEx(-1, -1, NULL,
3659 STRING_TOKEN (STR_PCI2_SERR_DRIVER),
3660 gShellDebug1HiiHandle,
3661 (*Command & PCI_BIT_8) != 0
3662 );
3663
3664 ShellPrintHiiEx(-1, -1, NULL,
3665 STRING_TOKEN (STR_PCI2_FAST_BACK_2),
3666 gShellDebug1HiiHandle,
3667 (*Command & PCI_BIT_9) != 0
3668 );
3669
3670 return EFI_SUCCESS;
3671 }
3672
3673 /**
3674 Explain each meaningful bit of register Bridge Control.
3675
3676 @param[in] BridgeControl Points to the content of register Bridge Control.
3677 @param[in] HeaderType The headertype.
3678
3679 @retval EFI_SUCCESS The command completed successfully.
3680 **/
3681 EFI_STATUS
3682 PciExplainBridgeControl (
3683 IN UINT16 *BridgeControl,
3684 IN PCI_HEADER_TYPE HeaderType
3685 )
3686 {
3687 ShellPrintHiiEx(-1, -1, NULL,
3688 STRING_TOKEN (STR_PCI2_BRIDGE_CONTROL),
3689 gShellDebug1HiiHandle,
3690 INDEX_OF (BridgeControl),
3691 *BridgeControl
3692 );
3693
3694 ShellPrintHiiEx(-1, -1, NULL,
3695 STRING_TOKEN (STR_PCI2_PARITY_ERROR),
3696 gShellDebug1HiiHandle,
3697 (*BridgeControl & PCI_BIT_0) != 0
3698 );
3699 ShellPrintHiiEx(-1, -1, NULL,
3700 STRING_TOKEN (STR_PCI2_SERR_ENABLE),
3701 gShellDebug1HiiHandle,
3702 (*BridgeControl & PCI_BIT_1) != 0
3703 );
3704 ShellPrintHiiEx(-1, -1, NULL,
3705 STRING_TOKEN (STR_PCI2_ISA_ENABLE),
3706 gShellDebug1HiiHandle,
3707 (*BridgeControl & PCI_BIT_2) != 0
3708 );
3709 ShellPrintHiiEx(-1, -1, NULL,
3710 STRING_TOKEN (STR_PCI2_VGA_ENABLE),
3711 gShellDebug1HiiHandle,
3712 (*BridgeControl & PCI_BIT_3) != 0
3713 );
3714 ShellPrintHiiEx(-1, -1, NULL,
3715 STRING_TOKEN (STR_PCI2_MASTER_ABORT),
3716 gShellDebug1HiiHandle,
3717 (*BridgeControl & PCI_BIT_5) != 0
3718 );
3719
3720 //
3721 // Register Bridge Control has some slight differences between P2P bridge
3722 // and Cardbus bridge from bit 6 to bit 11.
3723 //
3724 if (HeaderType == PciP2pBridge) {
3725 ShellPrintHiiEx(-1, -1, NULL,
3726 STRING_TOKEN (STR_PCI2_SECONDARY_BUS_RESET),
3727 gShellDebug1HiiHandle,
3728 (*BridgeControl & PCI_BIT_6) != 0
3729 );
3730 ShellPrintHiiEx(-1, -1, NULL,
3731 STRING_TOKEN (STR_PCI2_FAST_ENABLE),
3732 gShellDebug1HiiHandle,
3733 (*BridgeControl & PCI_BIT_7) != 0
3734 );
3735 ShellPrintHiiEx(-1, -1, NULL,
3736 STRING_TOKEN (STR_PCI2_PRIMARY_DISCARD_TIMER),
3737 gShellDebug1HiiHandle,
3738 (*BridgeControl & PCI_BIT_8)!=0 ? L"2^10" : L"2^15"
3739 );
3740 ShellPrintHiiEx(-1, -1, NULL,
3741 STRING_TOKEN (STR_PCI2_SECONDARY_DISCARD_TIMER),
3742 gShellDebug1HiiHandle,
3743 (*BridgeControl & PCI_BIT_9)!=0 ? L"2^10" : L"2^15"
3744 );
3745 ShellPrintHiiEx(-1, -1, NULL,
3746 STRING_TOKEN (STR_PCI2_DISCARD_TIMER_STATUS),
3747 gShellDebug1HiiHandle,
3748 (*BridgeControl & PCI_BIT_10) != 0
3749 );
3750 ShellPrintHiiEx(-1, -1, NULL,
3751 STRING_TOKEN (STR_PCI2_DISCARD_TIMER_SERR),
3752 gShellDebug1HiiHandle,
3753 (*BridgeControl & PCI_BIT_11) != 0
3754 );
3755
3756 } else {
3757 ShellPrintHiiEx(-1, -1, NULL,
3758 STRING_TOKEN (STR_PCI2_CARDBUS_RESET),
3759 gShellDebug1HiiHandle,
3760 (*BridgeControl & PCI_BIT_6) != 0
3761 );
3762 ShellPrintHiiEx(-1, -1, NULL,
3763 STRING_TOKEN (STR_PCI2_IREQ_ENABLE),
3764 gShellDebug1HiiHandle,
3765 (*BridgeControl & PCI_BIT_7) != 0
3766 );
3767 ShellPrintHiiEx(-1, -1, NULL,
3768 STRING_TOKEN (STR_PCI2_WRITE_POSTING_ENABLE),
3769 gShellDebug1HiiHandle,
3770 (*BridgeControl & PCI_BIT_10) != 0
3771 );
3772 }
3773
3774 return EFI_SUCCESS;
3775 }
3776
3777 /**
3778 Print each capability structure.
3779
3780 @param[in] IoDev The pointer to the deivce.
3781 @param[in] Address The address to start at.
3782 @param[in] CapPtr The offset from the address.
3783
3784 @retval EFI_SUCCESS The operation was successful.
3785 **/
3786 EFI_STATUS
3787 PciExplainCapabilityStruct (
3788 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
3789 IN UINT64 Address,
3790 IN UINT8 CapPtr
3791 )
3792 {
3793 UINT8 CapabilityPtr;
3794 UINT16 CapabilityEntry;
3795 UINT8 CapabilityID;
3796 UINT64 RegAddress;
3797
3798 CapabilityPtr = CapPtr;
3799
3800 //
3801 // Go through the Capability list
3802 //
3803 while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) {
3804 RegAddress = Address + CapabilityPtr;
3805 IoDev->Pci.Read (IoDev, EfiPciWidthUint16, RegAddress, 1, &CapabilityEntry);
3806
3807 CapabilityID = (UINT8) CapabilityEntry;
3808
3809 //
3810 // Explain PciExpress data
3811 //
3812 if (EFI_PCI_CAPABILITY_ID_PCIEXP == CapabilityID) {
3813 PciExplainPciExpress (IoDev, Address, CapabilityPtr);
3814 return EFI_SUCCESS;
3815 }
3816 //
3817 // Explain other capabilities here
3818 //
3819 CapabilityPtr = (UINT8) (CapabilityEntry >> 8);
3820 }
3821
3822 return EFI_SUCCESS;
3823 }
3824
3825 /**
3826 Print out information of the capability information.
3827
3828 @param[in] PciExpressCap The pointer to the structure about the device.
3829
3830 @retval EFI_SUCCESS The operation was successful.
3831 **/
3832 EFI_STATUS
3833 ExplainPcieCapReg (
3834 IN PCIE_CAP_STURCTURE *PciExpressCap
3835 )
3836 {
3837 UINT16 PcieCapReg;
3838 CHAR16 *DevicePortType;
3839
3840 PcieCapReg = PciExpressCap->PcieCapReg;
3841 ShellPrintEx (-1, -1,
3842 L" Capability Version(3:0): %E0x%04x%N\r\n",
3843 PCIE_CAP_VERSION (PcieCapReg)
3844 );
3845 if ((UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) < PCIE_DEVICE_PORT_TYPE_MAX) {
3846 DevicePortType = DevicePortTypeTable[PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg)];
3847 } else {
3848 DevicePortType = L"Unknown Type";
3849 }
3850 ShellPrintEx (-1, -1,
3851 L" Device/PortType(7:4): %E%s%N\r\n",
3852 DevicePortType
3853 );
3854 //
3855 // 'Slot Implemented' is only valid for:
3856 // a) Root Port of PCI Express Root Complex, or
3857 // b) Downstream Port of PCI Express Switch
3858 //
3859 if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_ROOT_COMPLEX_ROOT_PORT ||
3860 PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_SWITCH_DOWNSTREAM_PORT) {
3861 ShellPrintEx (-1, -1,
3862 L" Slot Implemented(8): %E%d%N\r\n",
3863 PCIE_CAP_SLOT_IMPLEMENTED (PcieCapReg)
3864 );
3865 }
3866 ShellPrintEx (-1, -1,
3867 L" Interrupt Message Number(13:9): %E0x%05x%N\r\n",
3868 PCIE_CAP_INT_MSG_NUM (PcieCapReg)
3869 );
3870 return EFI_SUCCESS;
3871 }
3872
3873 /**
3874 Print out information of the device capability information.
3875
3876 @param[in] PciExpressCap The pointer to the structure about the device.
3877
3878 @retval EFI_SUCCESS The operation was successful.
3879 **/
3880 EFI_STATUS
3881 ExplainPcieDeviceCap (
3882 IN PCIE_CAP_STURCTURE *PciExpressCap
3883 )
3884 {
3885 UINT16 PcieCapReg;
3886 UINT32 PcieDeviceCap;
3887 UINT8 DevicePortType;
3888 UINT8 L0sLatency;
3889 UINT8 L1Latency;
3890
3891 PcieCapReg = PciExpressCap->PcieCapReg;
3892 PcieDeviceCap = PciExpressCap->PcieDeviceCap;
3893 DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg);
3894 ShellPrintEx (-1, -1, L" Max_Payload_Size Supported(2:0): ");
3895 if (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) < 6) {
3896 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) + 7));
3897 } else {
3898 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
3899 }
3900 ShellPrintEx (-1, -1,
3901 L" Phantom Functions Supported(4:3): %E%d%N\r\n",
3902 PCIE_CAP_PHANTOM_FUNC (PcieDeviceCap)
3903 );
3904 ShellPrintEx (-1, -1,
3905 L" Extended Tag Field Supported(5): %E%d-bit Tag field supported%N\r\n",
3906 PCIE_CAP_EXTENDED_TAG (PcieDeviceCap) ? 8 : 5
3907 );
3908 //
3909 // Endpoint L0s and L1 Acceptable Latency is only valid for Endpoint
3910 //
3911 if (IS_PCIE_ENDPOINT (DevicePortType)) {
3912 L0sLatency = (UINT8) PCIE_CAP_L0SLATENCY (PcieDeviceCap);
3913 L1Latency = (UINT8) PCIE_CAP_L1LATENCY (PcieDeviceCap);
3914 ShellPrintEx (-1, -1, L" Endpoint L0s Acceptable Latency(8:6): ");
3915 if (L0sLatency < 4) {
3916 ShellPrintEx (-1, -1, L"%EMaximum of %d ns%N\r\n", 1 << (L0sLatency + 6));
3917 } else {
3918 if (L0sLatency < 7) {
3919 ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L0sLatency - 3));
3920 } else {
3921 ShellPrintEx (-1, -1, L"%ENo limit%N\r\n");
3922 }
3923 }
3924 ShellPrintEx (-1, -1, L" Endpoint L1 Acceptable Latency(11:9): ");
3925 if (L1Latency < 7) {
3926 ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L1Latency + 1));
3927 } else {
3928 ShellPrintEx (-1, -1, L"%ENo limit%N\r\n");
3929 }
3930 }
3931 ShellPrintEx (-1, -1,
3932 L" Role-based Error Reporting(15): %E%d%N\r\n",
3933 PCIE_CAP_ERR_REPORTING (PcieDeviceCap)
3934 );
3935 //
3936 // Only valid for Upstream Port:
3937 // a) Captured Slot Power Limit Value
3938 // b) Captured Slot Power Scale
3939 //
3940 if (DevicePortType == PCIE_SWITCH_UPSTREAM_PORT) {
3941 ShellPrintEx (-1, -1,
3942 L" Captured Slot Power Limit Value(25:18): %E0x%02x%N\r\n",
3943 PCIE_CAP_SLOT_POWER_VALUE (PcieDeviceCap)
3944 );
3945 ShellPrintEx (-1, -1,
3946 L" Captured Slot Power Limit Scale(27:26): %E%s%N\r\n",
3947 SlotPwrLmtScaleTable[PCIE_CAP_SLOT_POWER_SCALE (PcieDeviceCap)]
3948 );
3949 }
3950 //
3951 // Function Level Reset Capability is only valid for Endpoint
3952 //
3953 if (IS_PCIE_ENDPOINT (DevicePortType)) {
3954 ShellPrintEx (-1, -1,
3955 L" Function Level Reset Capability(28): %E%d%N\r\n",
3956 PCIE_CAP_FUNC_LEVEL_RESET (PcieDeviceCap)
3957 );
3958 }
3959 return EFI_SUCCESS;
3960 }
3961
3962 /**
3963 Print out information of the device control information.
3964
3965 @param[in] PciExpressCap The pointer to the structure about the device.
3966
3967 @retval EFI_SUCCESS The operation was successful.
3968 **/
3969 EFI_STATUS
3970 ExplainPcieDeviceControl (
3971 IN PCIE_CAP_STURCTURE *PciExpressCap
3972 )
3973 {
3974 UINT16 PcieCapReg;
3975 UINT16 PcieDeviceControl;
3976
3977 PcieCapReg = PciExpressCap->PcieCapReg;
3978 PcieDeviceControl = PciExpressCap->DeviceControl;
3979 ShellPrintEx (-1, -1,
3980 L" Correctable Error Reporting Enable(0): %E%d%N\r\n",
3981 PCIE_CAP_COR_ERR_REPORTING_ENABLE (PcieDeviceControl)
3982 );
3983 ShellPrintEx (-1, -1,
3984 L" Non-Fatal Error Reporting Enable(1): %E%d%N\r\n",
3985 PCIE_CAP_NONFAT_ERR_REPORTING_ENABLE (PcieDeviceControl)
3986 );
3987 ShellPrintEx (-1, -1,
3988 L" Fatal Error Reporting Enable(2): %E%d%N\r\n",
3989 PCIE_CAP_FATAL_ERR_REPORTING_ENABLE (PcieDeviceControl)
3990 );
3991 ShellPrintEx (-1, -1,
3992 L" Unsupported Request Reporting Enable(3): %E%d%N\r\n",
3993 PCIE_CAP_UNSUP_REQ_REPORTING_ENABLE (PcieDeviceControl)
3994 );
3995 ShellPrintEx (-1, -1,
3996 L" Enable Relaxed Ordering(4): %E%d%N\r\n",
3997 PCIE_CAP_RELAXED_ORDERING_ENABLE (PcieDeviceControl)
3998 );
3999 ShellPrintEx (-1, -1, L" Max_Payload_Size(7:5): ");
4000 if (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) < 6) {
4001 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) + 7));
4002 } else {
4003 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
4004 }
4005 ShellPrintEx (-1, -1,
4006 L" Extended Tag Field Enable(8): %E%d%N\r\n",
4007 PCIE_CAP_EXTENDED_TAG_ENABLE (PcieDeviceControl)
4008 );
4009 ShellPrintEx (-1, -1,
4010 L" Phantom Functions Enable(9): %E%d%N\r\n",
4011 PCIE_CAP_PHANTOM_FUNC_ENABLE (PcieDeviceControl)
4012 );
4013 ShellPrintEx (-1, -1,
4014 L" Auxiliary (AUX) Power PM Enable(10): %E%d%N\r\n",
4015 PCIE_CAP_AUX_PM_ENABLE (PcieDeviceControl)
4016 );
4017 ShellPrintEx (-1, -1,
4018 L" Enable No Snoop(11): %E%d%N\r\n",
4019 PCIE_CAP_NO_SNOOP_ENABLE (PcieDeviceControl)
4020 );
4021 ShellPrintEx (-1, -1, L" Max_Read_Request_Size(14:12): ");
4022 if (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) < 6) {
4023 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) + 7));
4024 } else {
4025 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
4026 }
4027 //
4028 // Read operation is only valid for PCI Express to PCI/PCI-X Bridges
4029 //
4030 if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_PCIE_TO_PCIX_BRIDGE) {
4031 ShellPrintEx (-1, -1,
4032 L" Bridge Configuration Retry Enable(15): %E%d%N\r\n",
4033 PCIE_CAP_BRG_CONF_RETRY (PcieDeviceControl)
4034 );
4035 }
4036 return EFI_SUCCESS;
4037 }
4038
4039 /**
4040 Print out information of the device status information.
4041
4042 @param[in] PciExpressCap The pointer to the structure about the device.
4043
4044 @retval EFI_SUCCESS The operation was successful.
4045 **/
4046 EFI_STATUS
4047 ExplainPcieDeviceStatus (
4048 IN PCIE_CAP_STURCTURE *PciExpressCap
4049 )
4050 {
4051 UINT16 PcieDeviceStatus;
4052
4053 PcieDeviceStatus = PciExpressCap->DeviceStatus;
4054 ShellPrintEx (-1, -1,
4055 L" Correctable Error Detected(0): %E%d%N\r\n",
4056 PCIE_CAP_COR_ERR_DETECTED (PcieDeviceStatus)
4057 );
4058 ShellPrintEx (-1, -1,
4059 L" Non-Fatal Error Detected(1): %E%d%N\r\n",
4060 PCIE_CAP_NONFAT_ERR_DETECTED (PcieDeviceStatus)
4061 );
4062 ShellPrintEx (-1, -1,
4063 L" Fatal Error Detected(2): %E%d%N\r\n",
4064 PCIE_CAP_FATAL_ERR_DETECTED (PcieDeviceStatus)
4065 );
4066 ShellPrintEx (-1, -1,
4067 L" Unsupported Request Detected(3): %E%d%N\r\n",
4068 PCIE_CAP_UNSUP_REQ_DETECTED (PcieDeviceStatus)
4069 );
4070 ShellPrintEx (-1, -1,
4071 L" AUX Power Detected(4): %E%d%N\r\n",
4072 PCIE_CAP_AUX_POWER_DETECTED (PcieDeviceStatus)
4073 );
4074 ShellPrintEx (-1, -1,
4075 L" Transactions Pending(5): %E%d%N\r\n",
4076 PCIE_CAP_TRANSACTION_PENDING (PcieDeviceStatus)
4077 );
4078 return EFI_SUCCESS;
4079 }
4080
4081 /**
4082 Print out information of the device link information.
4083
4084 @param[in] PciExpressCap The pointer to the structure about the device.
4085
4086 @retval EFI_SUCCESS The operation was successful.
4087 **/
4088 EFI_STATUS
4089 ExplainPcieLinkCap (
4090 IN PCIE_CAP_STURCTURE *PciExpressCap
4091 )
4092 {
4093 UINT32 PcieLinkCap;
4094 CHAR16 *MaxLinkSpeed;
4095 CHAR16 *AspmValue;
4096
4097 PcieLinkCap = PciExpressCap->LinkCap;
4098 switch (PCIE_CAP_MAX_LINK_SPEED (PcieLinkCap)) {
4099 case 1:
4100 MaxLinkSpeed = L"2.5 GT/s";
4101 break;
4102 case 2:
4103 MaxLinkSpeed = L"5.0 GT/s";
4104 break;
4105 case 3:
4106 MaxLinkSpeed = L"8.0 GT/s";
4107 break;
4108 default:
4109 MaxLinkSpeed = L"Unknown";
4110 break;
4111 }
4112 ShellPrintEx (-1, -1,
4113 L" Maximum Link Speed(3:0): %E%s%N\r\n",
4114 MaxLinkSpeed
4115 );
4116 ShellPrintEx (-1, -1,
4117 L" Maximum Link Width(9:4): %Ex%d%N\r\n",
4118 PCIE_CAP_MAX_LINK_WIDTH (PcieLinkCap)
4119 );
4120 switch (PCIE_CAP_ASPM_SUPPORT (PcieLinkCap)) {
4121 case 0:
4122 AspmValue = L"Not";
4123 break;
4124 case 1:
4125 AspmValue = L"L0s";
4126 break;
4127 case 2:
4128 AspmValue = L"L1";
4129 break;
4130 case 3:
4131 AspmValue = L"L0s and L1";
4132 break;
4133 default:
4134 AspmValue = L"Reserved";
4135 break;
4136 }
4137 ShellPrintEx (-1, -1,
4138 L" Active State Power Management Support(11:10): %E%s Supported%N\r\n",
4139 AspmValue
4140 );
4141 ShellPrintEx (-1, -1,
4142 L" L0s Exit Latency(14:12): %E%s%N\r\n",
4143 L0sLatencyStrTable[PCIE_CAP_L0S_LATENCY (PcieLinkCap)]
4144 );
4145 ShellPrintEx (-1, -1,
4146 L" L1 Exit Latency(17:15): %E%s%N\r\n",
4147 L1LatencyStrTable[PCIE_CAP_L0S_LATENCY (PcieLinkCap)]
4148 );
4149 ShellPrintEx (-1, -1,
4150 L" Clock Power Management(18): %E%d%N\r\n",
4151 PCIE_CAP_CLOCK_PM (PcieLinkCap)
4152 );
4153 ShellPrintEx (-1, -1,
4154 L" Surprise Down Error Reporting Capable(19): %E%d%N\r\n",
4155 PCIE_CAP_SUP_DOWN_ERR_REPORTING (PcieLinkCap)
4156 );
4157 ShellPrintEx (-1, -1,
4158 L" Data Link Layer Link Active Reporting Capable(20): %E%d%N\r\n",
4159 PCIE_CAP_LINK_ACTIVE_REPORTING (PcieLinkCap)
4160 );
4161 ShellPrintEx (-1, -1,
4162 L" Link Bandwidth Notification Capability(21): %E%d%N\r\n",
4163 PCIE_CAP_LINK_BWD_NOTIF_CAP (PcieLinkCap)
4164 );
4165 ShellPrintEx (-1, -1,
4166 L" Port Number(31:24): %E0x%02x%N\r\n",
4167 PCIE_CAP_PORT_NUMBER (PcieLinkCap)
4168 );
4169 return EFI_SUCCESS;
4170 }
4171
4172 /**
4173 Print out information of the device link control information.
4174
4175 @param[in] PciExpressCap The pointer to the structure about the device.
4176
4177 @retval EFI_SUCCESS The operation was successful.
4178 **/
4179 EFI_STATUS
4180 ExplainPcieLinkControl (
4181 IN PCIE_CAP_STURCTURE *PciExpressCap
4182 )
4183 {
4184 UINT16 PcieLinkControl;
4185 UINT8 DevicePortType;
4186
4187 PcieLinkControl = PciExpressCap->LinkControl;
4188 DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap->PcieCapReg);
4189 ShellPrintEx (-1, -1,
4190 L" Active State Power Management Control(1:0): %E%s%N\r\n",
4191 ASPMCtrlStrTable[PCIE_CAP_ASPM_CONTROL (PcieLinkControl)]
4192 );
4193 //
4194 // RCB is not applicable to switches
4195 //
4196 if (!IS_PCIE_SWITCH(DevicePortType)) {
4197 ShellPrintEx (-1, -1,
4198 L" Read Completion Boundary (RCB)(3): %E%d byte%N\r\n",
4199 1 << (PCIE_CAP_RCB (PcieLinkControl) + 6)
4200 );
4201 }
4202 //
4203 // Link Disable is reserved on
4204 // a) Endpoints
4205 // b) PCI Express to PCI/PCI-X bridges
4206 // c) Upstream Ports of Switches
4207 //
4208 if (!IS_PCIE_ENDPOINT (DevicePortType) &&
4209 DevicePortType != PCIE_SWITCH_UPSTREAM_PORT &&
4210 DevicePortType != PCIE_PCIE_TO_PCIX_BRIDGE) {
4211 ShellPrintEx (-1, -1,
4212 L" Link Disable(4): %E%d%N\r\n",
4213 PCIE_CAP_LINK_DISABLE (PcieLinkControl)
4214 );
4215 }
4216 ShellPrintEx (-1, -1,
4217 L" Common Clock Configuration(6): %E%d%N\r\n",
4218 PCIE_CAP_COMMON_CLK_CONF (PcieLinkControl)
4219 );
4220 ShellPrintEx (-1, -1,
4221 L" Extended Synch(7): %E%d%N\r\n",
4222 PCIE_CAP_EXT_SYNC (PcieLinkControl)
4223 );
4224 ShellPrintEx (-1, -1,
4225 L" Enable Clock Power Management(8): %E%d%N\r\n",
4226 PCIE_CAP_CLK_PWR_MNG (PcieLinkControl)
4227 );
4228 ShellPrintEx (-1, -1,
4229 L" Hardware Autonomous Width Disable(9): %E%d%N\r\n",
4230 PCIE_CAP_HW_AUTO_WIDTH_DISABLE (PcieLinkControl)
4231 );
4232 ShellPrintEx (-1, -1,
4233 L" Link Bandwidth Management Interrupt Enable(10): %E%d%N\r\n",
4234 PCIE_CAP_LINK_BDW_MNG_INT_EN (PcieLinkControl)
4235 );
4236 ShellPrintEx (-1, -1,
4237 L" Link Autonomous Bandwidth Interrupt Enable(11): %E%d%N\r\n",
4238 PCIE_CAP_LINK_AUTO_BDW_INT_EN (PcieLinkControl)
4239 );
4240 return EFI_SUCCESS;
4241 }
4242
4243 /**
4244 Print out information of the device link status information.
4245
4246 @param[in] PciExpressCap The pointer to the structure about the device.
4247
4248 @retval EFI_SUCCESS The operation was successful.
4249 **/
4250 EFI_STATUS
4251 ExplainPcieLinkStatus (
4252 IN PCIE_CAP_STURCTURE *PciExpressCap
4253 )
4254 {
4255 UINT16 PcieLinkStatus;
4256 CHAR16 *CurLinkSpeed;
4257
4258 PcieLinkStatus = PciExpressCap->LinkStatus;
4259 switch (PCIE_CAP_CUR_LINK_SPEED (PcieLinkStatus)) {
4260 case 1:
4261 CurLinkSpeed = L"2.5 GT/s";
4262 break;
4263 case 2:
4264 CurLinkSpeed = L"5.0 GT/s";
4265 break;
4266 case 3:
4267 CurLinkSpeed = L"8.0 GT/s";
4268 break;
4269 default:
4270 CurLinkSpeed = L"Reserved";
4271 break;
4272 }
4273 ShellPrintEx (-1, -1,
4274 L" Current Link Speed(3:0): %E%s%N\r\n",
4275 CurLinkSpeed
4276 );
4277 ShellPrintEx (-1, -1,
4278 L" Negotiated Link Width(9:4): %Ex%d%N\r\n",
4279 PCIE_CAP_NEGO_LINK_WIDTH (PcieLinkStatus)
4280 );
4281 ShellPrintEx (-1, -1,
4282 L" Link Training(11): %E%d%N\r\n",
4283 PCIE_CAP_LINK_TRAINING (PcieLinkStatus)
4284 );
4285 ShellPrintEx (-1, -1,
4286 L" Slot Clock Configuration(12): %E%d%N\r\n",
4287 PCIE_CAP_SLOT_CLK_CONF (PcieLinkStatus)
4288 );
4289 ShellPrintEx (-1, -1,
4290 L" Data Link Layer Link Active(13): %E%d%N\r\n",
4291 PCIE_CAP_DATA_LINK_ACTIVE (PcieLinkStatus)
4292 );
4293 ShellPrintEx (-1, -1,
4294 L" Link Bandwidth Management Status(14): %E%d%N\r\n",
4295 PCIE_CAP_LINK_BDW_MNG_STAT (PcieLinkStatus)
4296 );
4297 ShellPrintEx (-1, -1,
4298 L" Link Autonomous Bandwidth Status(15): %E%d%N\r\n",
4299 PCIE_CAP_LINK_AUTO_BDW_STAT (PcieLinkStatus)
4300 );
4301 return EFI_SUCCESS;
4302 }
4303
4304 /**
4305 Print out information of the device slot information.
4306
4307 @param[in] PciExpressCap The pointer to the structure about the device.
4308
4309 @retval EFI_SUCCESS The operation was successful.
4310 **/
4311 EFI_STATUS
4312 ExplainPcieSlotCap (
4313 IN PCIE_CAP_STURCTURE *PciExpressCap
4314 )
4315 {
4316 UINT32 PcieSlotCap;
4317
4318 PcieSlotCap = PciExpressCap->SlotCap;
4319
4320 ShellPrintEx (-1, -1,
4321 L" Attention Button Present(0): %E%d%N\r\n",
4322 PCIE_CAP_ATT_BUT_PRESENT (PcieSlotCap)
4323 );
4324 ShellPrintEx (-1, -1,
4325 L" Power Controller Present(1): %E%d%N\r\n",
4326 PCIE_CAP_PWR_CTRLLER_PRESENT (PcieSlotCap)
4327 );
4328 ShellPrintEx (-1, -1,
4329 L" MRL Sensor Present(2): %E%d%N\r\n",
4330 PCIE_CAP_MRL_SENSOR_PRESENT (PcieSlotCap)
4331 );
4332 ShellPrintEx (-1, -1,
4333 L" Attention Indicator Present(3): %E%d%N\r\n",
4334 PCIE_CAP_ATT_IND_PRESENT (PcieSlotCap)
4335 );
4336 ShellPrintEx (-1, -1,
4337 L" Power Indicator Present(4): %E%d%N\r\n",
4338 PCIE_CAP_PWD_IND_PRESENT (PcieSlotCap)
4339 );
4340 ShellPrintEx (-1, -1,
4341 L" Hot-Plug Surprise(5): %E%d%N\r\n",
4342 PCIE_CAP_HOTPLUG_SUPPRISE (PcieSlotCap)
4343 );
4344 ShellPrintEx (-1, -1,
4345 L" Hot-Plug Capable(6): %E%d%N\r\n",
4346 PCIE_CAP_HOTPLUG_CAPABLE (PcieSlotCap)
4347 );
4348 ShellPrintEx (-1, -1,
4349 L" Slot Power Limit Value(14:7): %E0x%02x%N\r\n",
4350 PCIE_CAP_SLOT_PWR_LIMIT_VALUE (PcieSlotCap)
4351 );
4352 ShellPrintEx (-1, -1,
4353 L" Slot Power Limit Scale(16:15): %E%s%N\r\n",
4354 SlotPwrLmtScaleTable[PCIE_CAP_SLOT_PWR_LIMIT_SCALE (PcieSlotCap)]
4355 );
4356 ShellPrintEx (-1, -1,
4357 L" Electromechanical Interlock Present(17): %E%d%N\r\n",
4358 PCIE_CAP_ELEC_INTERLOCK_PRESENT (PcieSlotCap)
4359 );
4360 ShellPrintEx (-1, -1,
4361 L" No Command Completed Support(18): %E%d%N\r\n",
4362 PCIE_CAP_NO_COMM_COMPLETED_SUP (PcieSlotCap)
4363 );
4364 ShellPrintEx (-1, -1,
4365 L" Physical Slot Number(31:19): %E%d%N\r\n",
4366 PCIE_CAP_PHY_SLOT_NUM (PcieSlotCap)
4367 );
4368
4369 return EFI_SUCCESS;
4370 }
4371
4372 /**
4373 Print out information of the device slot control information.
4374
4375 @param[in] PciExpressCap The pointer to the structure about the device.
4376
4377 @retval EFI_SUCCESS The operation was successful.
4378 **/
4379 EFI_STATUS
4380 ExplainPcieSlotControl (
4381 IN PCIE_CAP_STURCTURE *PciExpressCap
4382 )
4383 {
4384 UINT16 PcieSlotControl;
4385
4386 PcieSlotControl = PciExpressCap->SlotControl;
4387 ShellPrintEx (-1, -1,
4388 L" Attention Button Pressed Enable(0): %E%d%N\r\n",
4389 PCIE_CAP_ATT_BUT_ENABLE (PcieSlotControl)
4390 );
4391 ShellPrintEx (-1, -1,
4392 L" Power Fault Detected Enable(1): %E%d%N\r\n",
4393 PCIE_CAP_PWR_FLT_DETECT_ENABLE (PcieSlotControl)
4394 );
4395 ShellPrintEx (-1, -1,
4396 L" MRL Sensor Changed Enable(2): %E%d%N\r\n",
4397 PCIE_CAP_MRL_SENSOR_CHANGE_ENABLE (PcieSlotControl)
4398 );
4399 ShellPrintEx (-1, -1,
4400 L" Presence Detect Changed Enable(3): %E%d%N\r\n",
4401 PCIE_CAP_PRES_DETECT_CHANGE_ENABLE (PcieSlotControl)
4402 );
4403 ShellPrintEx (-1, -1,
4404 L" Command Completed Interrupt Enable(4): %E%d%N\r\n",
4405 PCIE_CAP_COMM_CMPL_INT_ENABLE (PcieSlotControl)
4406 );
4407 ShellPrintEx (-1, -1,
4408 L" Hot-Plug Interrupt Enable(5): %E%d%N\r\n",
4409 PCIE_CAP_HOTPLUG_INT_ENABLE (PcieSlotControl)
4410 );
4411 ShellPrintEx (-1, -1,
4412 L" Attention Indicator Control(7:6): %E%s%N\r\n",
4413 IndicatorTable[PCIE_CAP_ATT_IND_CTRL (PcieSlotControl)]
4414 );
4415 ShellPrintEx (-1, -1,
4416 L" Power Indicator Control(9:8): %E%s%N\r\n",
4417 IndicatorTable[PCIE_CAP_PWR_IND_CTRL (PcieSlotControl)]
4418 );
4419 ShellPrintEx (-1, -1, L" Power Controller Control(10): %EPower ");
4420 if (PCIE_CAP_PWR_CTRLLER_CTRL (PcieSlotControl)) {
4421 ShellPrintEx (-1, -1, L"Off%N\r\n");
4422 } else {
4423 ShellPrintEx (-1, -1, L"On%N\r\n");
4424 }
4425 ShellPrintEx (-1, -1,
4426 L" Electromechanical Interlock Control(11): %E%d%N\r\n",
4427 PCIE_CAP_ELEC_INTERLOCK_CTRL (PcieSlotControl)
4428 );
4429 ShellPrintEx (-1, -1,
4430 L" Data Link Layer State Changed Enable(12): %E%d%N\r\n",
4431 PCIE_CAP_DLINK_STAT_CHANGE_ENABLE (PcieSlotControl)
4432 );
4433 return EFI_SUCCESS;
4434 }
4435
4436 /**
4437 Print out information of the device slot status information.
4438
4439 @param[in] PciExpressCap The pointer to the structure about the device.
4440
4441 @retval EFI_SUCCESS The operation was successful.
4442 **/
4443 EFI_STATUS
4444 ExplainPcieSlotStatus (
4445 IN PCIE_CAP_STURCTURE *PciExpressCap
4446 )
4447 {
4448 UINT16 PcieSlotStatus;
4449
4450 PcieSlotStatus = PciExpressCap->SlotStatus;
4451
4452 ShellPrintEx (-1, -1,
4453 L" Attention Button Pressed(0): %E%d%N\r\n",
4454 PCIE_CAP_ATT_BUT_PRESSED (PcieSlotStatus)
4455 );
4456 ShellPrintEx (-1, -1,
4457 L" Power Fault Detected(1): %E%d%N\r\n",
4458 PCIE_CAP_PWR_FLT_DETECTED (PcieSlotStatus)
4459 );
4460 ShellPrintEx (-1, -1,
4461 L" MRL Sensor Changed(2): %E%d%N\r\n",
4462 PCIE_CAP_MRL_SENSOR_CHANGED (PcieSlotStatus)
4463 );
4464 ShellPrintEx (-1, -1,
4465 L" Presence Detect Changed(3): %E%d%N\r\n",
4466 PCIE_CAP_PRES_DETECT_CHANGED (PcieSlotStatus)
4467 );
4468 ShellPrintEx (-1, -1,
4469 L" Command Completed(4): %E%d%N\r\n",
4470 PCIE_CAP_COMM_COMPLETED (PcieSlotStatus)
4471 );
4472 ShellPrintEx (-1, -1, L" MRL Sensor State(5): %EMRL ");
4473 if (PCIE_CAP_MRL_SENSOR_STATE (PcieSlotStatus)) {
4474 ShellPrintEx (-1, -1, L" Opened%N\r\n");
4475 } else {
4476 ShellPrintEx (-1, -1, L" Closed%N\r\n");
4477 }
4478 ShellPrintEx (-1, -1, L" Presence Detect State(6): ");
4479 if (PCIE_CAP_PRES_DETECT_STATE (PcieSlotStatus)) {
4480 ShellPrintEx (-1, -1, L"%ECard Present in slot%N\r\n");
4481 } else {
4482 ShellPrintEx (-1, -1, L"%ESlot Empty%N\r\n");
4483 }
4484 ShellPrintEx (-1, -1, L" Electromechanical Interlock Status(7): %EElectromechanical Interlock ");
4485 if (PCIE_CAP_ELEC_INTERLOCK_STATE (PcieSlotStatus)) {
4486 ShellPrintEx (-1, -1, L"Engaged%N\r\n");
4487 } else {
4488 ShellPrintEx (-1, -1, L"Disengaged%N\r\n");
4489 }
4490 ShellPrintEx (-1, -1,
4491 L" Data Link Layer State Changed(8): %E%d%N\r\n",
4492 PCIE_CAP_DLINK_STAT_CHANGED (PcieSlotStatus)
4493 );
4494 return EFI_SUCCESS;
4495 }
4496
4497 /**
4498 Print out information of the device root information.
4499
4500 @param[in] PciExpressCap The pointer to the structure about the device.
4501
4502 @retval EFI_SUCCESS The operation was successful.
4503 **/
4504 EFI_STATUS
4505 ExplainPcieRootControl (
4506 IN PCIE_CAP_STURCTURE *PciExpressCap
4507 )
4508 {
4509 UINT16 PcieRootControl;
4510
4511 PcieRootControl = PciExpressCap->RootControl;
4512
4513 ShellPrintEx (-1, -1,
4514 L" System Error on Correctable Error Enable(0): %E%d%N\r\n",
4515 PCIE_CAP_SYSERR_ON_CORERR_EN (PcieRootControl)
4516 );
4517 ShellPrintEx (-1, -1,
4518 L" System Error on Non-Fatal Error Enable(1): %E%d%N\r\n",
4519 PCIE_CAP_SYSERR_ON_NONFATERR_EN (PcieRootControl)
4520 );
4521 ShellPrintEx (-1, -1,
4522 L" System Error on Fatal Error Enable(2): %E%d%N\r\n",
4523 PCIE_CAP_SYSERR_ON_FATERR_EN (PcieRootControl)
4524 );
4525 ShellPrintEx (-1, -1,
4526 L" PME Interrupt Enable(3): %E%d%N\r\n",
4527 PCIE_CAP_PME_INT_ENABLE (PcieRootControl)
4528 );
4529 ShellPrintEx (-1, -1,
4530 L" CRS Software Visibility Enable(4): %E%d%N\r\n",
4531 PCIE_CAP_CRS_SW_VIS_ENABLE (PcieRootControl)
4532 );
4533
4534 return EFI_SUCCESS;
4535 }
4536
4537 /**
4538 Print out information of the device root capability information.
4539
4540 @param[in] PciExpressCap The pointer to the structure about the device.
4541
4542 @retval EFI_SUCCESS The operation was successful.
4543 **/
4544 EFI_STATUS
4545 ExplainPcieRootCap (
4546 IN PCIE_CAP_STURCTURE *PciExpressCap
4547 )
4548 {
4549 UINT16 PcieRootCap;
4550
4551 PcieRootCap = PciExpressCap->RsvdP;
4552
4553 ShellPrintEx (-1, -1,
4554 L" CRS Software Visibility(0): %E%d%N\r\n",
4555 PCIE_CAP_CRS_SW_VIS (PcieRootCap)
4556 );
4557
4558 return EFI_SUCCESS;
4559 }
4560
4561 /**
4562 Print out information of the device root status information.
4563
4564 @param[in] PciExpressCap The pointer to the structure about the device.
4565
4566 @retval EFI_SUCCESS The operation was successful.
4567 **/
4568 EFI_STATUS
4569 ExplainPcieRootStatus (
4570 IN PCIE_CAP_STURCTURE *PciExpressCap
4571 )
4572 {
4573 UINT32 PcieRootStatus;
4574
4575 PcieRootStatus = PciExpressCap->RootStatus;
4576
4577 ShellPrintEx (-1, -1,
4578 L" PME Requester ID(15:0): %E0x%04x%N\r\n",
4579 PCIE_CAP_PME_REQ_ID (PcieRootStatus)
4580 );
4581 ShellPrintEx (-1, -1,
4582 L" PME Status(16): %E%d%N\r\n",
4583 PCIE_CAP_PME_STATUS (PcieRootStatus)
4584 );
4585 ShellPrintEx (-1, -1,
4586 L" PME Pending(17): %E%d%N\r\n",
4587 PCIE_CAP_PME_PENDING (PcieRootStatus)
4588 );
4589 return EFI_SUCCESS;
4590 }
4591
4592 /**
4593 Display Pcie device structure.
4594
4595 @param[in] IoDev The pointer to the root pci protocol.
4596 @param[in] Address The Address to start at.
4597 @param[in] CapabilityPtr The offset from the address to start.
4598 **/
4599 EFI_STATUS
4600 PciExplainPciExpress (
4601 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
4602 IN UINT64 Address,
4603 IN UINT8 CapabilityPtr
4604 )
4605 {
4606
4607 PCIE_CAP_STURCTURE PciExpressCap;
4608 EFI_STATUS Status;
4609 UINT64 CapRegAddress;
4610 UINT8 Bus;
4611 UINT8 Dev;
4612 UINT8 Func;
4613 UINT8 *ExRegBuffer;
4614 UINTN ExtendRegSize;
4615 UINT64 Pciex_Address;
4616 UINT8 DevicePortType;
4617 UINTN Index;
4618 UINT8 *RegAddr;
4619 UINTN RegValue;
4620
4621 CapRegAddress = Address + CapabilityPtr;
4622 IoDev->Pci.Read (
4623 IoDev,
4624 EfiPciWidthUint32,
4625 CapRegAddress,
4626 sizeof (PciExpressCap) / sizeof (UINT32),
4627 &PciExpressCap
4628 );
4629
4630 DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap.PcieCapReg);
4631
4632 ShellPrintEx (-1, -1, L"\r\nPci Express device capability structure:\r\n");
4633
4634 for (Index = 0; PcieExplainList[Index].Type < PcieExplainTypeMax; Index++) {
4635 if (ShellGetExecutionBreakFlag()) {
4636 goto Done;
4637 }
4638 RegAddr = ((UINT8 *) &PciExpressCap) + PcieExplainList[Index].Offset;
4639 switch (PcieExplainList[Index].Width) {
4640 case FieldWidthUINT8:
4641 RegValue = *(UINT8 *) RegAddr;
4642 break;
4643 case FieldWidthUINT16:
4644 RegValue = *(UINT16 *) RegAddr;
4645 break;
4646 case FieldWidthUINT32:
4647 RegValue = *(UINT32 *) RegAddr;
4648 break;
4649 default:
4650 RegValue = 0;
4651 break;
4652 }
4653 ShellPrintHiiEx(-1, -1, NULL,
4654 PcieExplainList[Index].Token,
4655 gShellDebug1HiiHandle,
4656 PcieExplainList[Index].Offset,
4657 RegValue
4658 );
4659 if (PcieExplainList[Index].Func == NULL) {
4660 continue;
4661 }
4662 switch (PcieExplainList[Index].Type) {
4663 case PcieExplainTypeLink:
4664 //
4665 // Link registers should not be used by
4666 // a) Root Complex Integrated Endpoint
4667 // b) Root Complex Event Collector
4668 //
4669 if (DevicePortType == PCIE_ROOT_COMPLEX_INTEGRATED_PORT ||
4670 DevicePortType == PCIE_ROOT_COMPLEX_EVENT_COLLECTOR) {
4671 continue;
4672 }
4673 break;
4674 case PcieExplainTypeSlot:
4675 //
4676 // Slot registers are only valid for
4677 // a) Root Port of PCI Express Root Complex
4678 // b) Downstream Port of PCI Express Switch
4679 // and when SlotImplemented bit is set in PCIE cap register.
4680 //
4681 if ((DevicePortType != PCIE_ROOT_COMPLEX_ROOT_PORT &&
4682 DevicePortType != PCIE_SWITCH_DOWNSTREAM_PORT) ||
4683 !PCIE_CAP_SLOT_IMPLEMENTED (PciExpressCap.PcieCapReg)) {
4684 continue;
4685 }
4686 break;
4687 case PcieExplainTypeRoot:
4688 //
4689 // Root registers are only valid for
4690 // Root Port of PCI Express Root Complex
4691 //
4692 if (DevicePortType != PCIE_ROOT_COMPLEX_ROOT_PORT) {
4693 continue;
4694 }
4695 break;
4696 default:
4697 break;
4698 }
4699 PcieExplainList[Index].Func (&PciExpressCap);
4700 }
4701
4702 Bus = (UINT8) (RShiftU64 (Address, 24));
4703 Dev = (UINT8) (RShiftU64 (Address, 16));
4704 Func = (UINT8) (RShiftU64 (Address, 8));
4705
4706 Pciex_Address = CALC_EFI_PCIEX_ADDRESS (Bus, Dev, Func, 0x100);
4707
4708 ExtendRegSize = 0x1000 - 0x100;
4709
4710 ExRegBuffer = (UINT8 *) AllocateZeroPool (ExtendRegSize);
4711
4712 //
4713 // PciRootBridgeIo protocol should support pci express extend space IO
4714 // (Begins at offset 0x100)
4715 //
4716 Status = IoDev->Pci.Read (
4717 IoDev,
4718 EfiPciWidthUint32,
4719 Pciex_Address,
4720 (ExtendRegSize) / sizeof (UINT32),
4721 (VOID *) (ExRegBuffer)
4722 );
4723 if (EFI_ERROR (Status)) {
4724 FreePool ((VOID *) ExRegBuffer);
4725 return EFI_UNSUPPORTED;
4726 }
4727 //
4728 // Start outputing PciEx extend space( 0xFF-0xFFF)
4729 //
4730 ShellPrintEx (-1, -1, L"\r\n%HStart dumping PCIex extended configuration space (0x100 - 0xFFF).%N\r\n\r\n");
4731
4732 if (ExRegBuffer != NULL) {
4733 DumpHex (
4734 2,
4735 0x100,
4736 ExtendRegSize,
4737 (VOID *) (ExRegBuffer)
4738 );
4739
4740 FreePool ((VOID *) ExRegBuffer);
4741 }
4742
4743 Done:
4744 return EFI_SUCCESS;
4745 }