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