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