]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c
ShellPkg/[hex]edit: use SimpleTextInEx to read console
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / Pci.c
1 /** @file
2 Main file for Pci shell Debug1 function.
3
4 Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
6 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 #include "UefiShellDebug1CommandsLib.h"
18 #include <Protocol/PciRootBridgeIo.h>
19 #include <Library/ShellLib.h>
20 #include <IndustryStandard/Pci.h>
21 #include <IndustryStandard/Acpi.h>
22 #include "Pci.h"
23
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 PCISubClass_12[];
67 PCI_CLASS_ENTRY PCISubClass_13[];
68 PCI_CLASS_ENTRY PCIPIFClass_0100[];
69 PCI_CLASS_ENTRY PCIPIFClass_0101[];
70 PCI_CLASS_ENTRY PCIPIFClass_0105[];
71 PCI_CLASS_ENTRY PCIPIFClass_0106[];
72 PCI_CLASS_ENTRY PCIPIFClass_0107[];
73 PCI_CLASS_ENTRY PCIPIFClass_0108[];
74 PCI_CLASS_ENTRY PCIPIFClass_0109[];
75 PCI_CLASS_ENTRY PCIPIFClass_0300[];
76 PCI_CLASS_ENTRY PCIPIFClass_0604[];
77 PCI_CLASS_ENTRY PCIPIFClass_0609[];
78 PCI_CLASS_ENTRY PCIPIFClass_060b[];
79 PCI_CLASS_ENTRY PCIPIFClass_0700[];
80 PCI_CLASS_ENTRY PCIPIFClass_0701[];
81 PCI_CLASS_ENTRY PCIPIFClass_0703[];
82 PCI_CLASS_ENTRY PCIPIFClass_0800[];
83 PCI_CLASS_ENTRY PCIPIFClass_0801[];
84 PCI_CLASS_ENTRY PCIPIFClass_0802[];
85 PCI_CLASS_ENTRY PCIPIFClass_0803[];
86 PCI_CLASS_ENTRY PCIPIFClass_0904[];
87 PCI_CLASS_ENTRY PCIPIFClass_0c00[];
88 PCI_CLASS_ENTRY PCIPIFClass_0c03[];
89 PCI_CLASS_ENTRY PCIPIFClass_0c07[];
90 PCI_CLASS_ENTRY PCIPIFClass_0d01[];
91 PCI_CLASS_ENTRY PCIPIFClass_0e00[];
92
93 //
94 // Base class strings entries
95 //
96 PCI_CLASS_ENTRY gClassStringList[] = {
97 {
98 0x00,
99 L"Pre 2.0 device",
100 PCISubClass_00
101 },
102 {
103 0x01,
104 L"Mass Storage Controller",
105 PCISubClass_01
106 },
107 {
108 0x02,
109 L"Network Controller",
110 PCISubClass_02
111 },
112 {
113 0x03,
114 L"Display Controller",
115 PCISubClass_03
116 },
117 {
118 0x04,
119 L"Multimedia Device",
120 PCISubClass_04
121 },
122 {
123 0x05,
124 L"Memory Controller",
125 PCISubClass_05
126 },
127 {
128 0x06,
129 L"Bridge Device",
130 PCISubClass_06
131 },
132 {
133 0x07,
134 L"Simple Communications Controllers",
135 PCISubClass_07
136 },
137 {
138 0x08,
139 L"Base System Peripherals",
140 PCISubClass_08
141 },
142 {
143 0x09,
144 L"Input Devices",
145 PCISubClass_09
146 },
147 {
148 0x0a,
149 L"Docking Stations",
150 PCISubClass_0a
151 },
152 {
153 0x0b,
154 L"Processors",
155 PCISubClass_0b
156 },
157 {
158 0x0c,
159 L"Serial Bus Controllers",
160 PCISubClass_0c
161 },
162 {
163 0x0d,
164 L"Wireless Controllers",
165 PCISubClass_0d
166 },
167 {
168 0x0e,
169 L"Intelligent IO Controllers",
170 PCISubClass_0e
171 },
172 {
173 0x0f,
174 L"Satellite Communications Controllers",
175 PCISubClass_0f
176 },
177 {
178 0x10,
179 L"Encryption/Decryption Controllers",
180 PCISubClass_10
181 },
182 {
183 0x11,
184 L"Data Acquisition & Signal Processing Controllers",
185 PCISubClass_11
186 },
187 {
188 0x12,
189 L"Processing Accelerators",
190 PCISubClass_12
191 },
192 {
193 0x13,
194 L"Non-Essential Instrumentation",
195 PCISubClass_13
196 },
197 {
198 0xff,
199 L"Device does not fit in any defined classes",
200 PCIBlankEntry
201 },
202 {
203 0x00,
204 NULL,
205 /* null string ends the list */NULL
206 }
207 };
208
209 //
210 // Subclass strings entries
211 //
212 PCI_CLASS_ENTRY PCIBlankEntry[] = {
213 {
214 0x00,
215 L"",
216 PCIBlankEntry
217 },
218 {
219 0x00,
220 NULL,
221 /* null string ends the list */NULL
222 }
223 };
224
225 PCI_CLASS_ENTRY PCISubClass_00[] = {
226 {
227 0x00,
228 L"All devices other than VGA",
229 PCIBlankEntry
230 },
231 {
232 0x01,
233 L"VGA-compatible devices",
234 PCIBlankEntry
235 },
236 {
237 0x00,
238 NULL,
239 /* null string ends the list */NULL
240 }
241 };
242
243 PCI_CLASS_ENTRY PCISubClass_01[] = {
244 {
245 0x00,
246 L"SCSI",
247 PCIPIFClass_0100
248 },
249 {
250 0x01,
251 L"IDE controller",
252 PCIPIFClass_0101
253 },
254 {
255 0x02,
256 L"Floppy disk controller",
257 PCIBlankEntry
258 },
259 {
260 0x03,
261 L"IPI controller",
262 PCIBlankEntry
263 },
264 {
265 0x04,
266 L"RAID controller",
267 PCIBlankEntry
268 },
269 {
270 0x05,
271 L"ATA controller with ADMA interface",
272 PCIPIFClass_0105
273 },
274 {
275 0x06,
276 L"Serial ATA controller",
277 PCIPIFClass_0106
278 },
279 {
280 0x07,
281 L"Serial Attached SCSI (SAS) controller ",
282 PCIPIFClass_0107
283 },
284 {
285 0x08,
286 L"Non-volatile memory subsystem",
287 PCIPIFClass_0108
288 },
289 {
290 0x09,
291 L"Universal Flash Storage (UFS) controller ",
292 PCIPIFClass_0109
293 },
294 {
295 0x80,
296 L"Other mass storage controller",
297 PCIBlankEntry
298 },
299 {
300 0x00,
301 NULL,
302 /* null string ends the list */NULL
303 }
304 };
305
306 PCI_CLASS_ENTRY PCISubClass_02[] = {
307 {
308 0x00,
309 L"Ethernet controller",
310 PCIBlankEntry
311 },
312 {
313 0x01,
314 L"Token ring controller",
315 PCIBlankEntry
316 },
317 {
318 0x02,
319 L"FDDI controller",
320 PCIBlankEntry
321 },
322 {
323 0x03,
324 L"ATM controller",
325 PCIBlankEntry
326 },
327 {
328 0x04,
329 L"ISDN controller",
330 PCIBlankEntry
331 },
332 {
333 0x05,
334 L"WorldFip controller",
335 PCIBlankEntry
336 },
337 {
338 0x06,
339 L"PICMG 2.14 Multi Computing",
340 PCIBlankEntry
341 },
342 {
343 0x07,
344 L"InfiniBand controller",
345 PCIBlankEntry
346 },
347 {
348 0x80,
349 L"Other network controller",
350 PCIBlankEntry
351 },
352 {
353 0x00,
354 NULL,
355 /* null string ends the list */NULL
356 }
357 };
358
359 PCI_CLASS_ENTRY PCISubClass_03[] = {
360 {
361 0x00,
362 L"VGA/8514 controller",
363 PCIPIFClass_0300
364 },
365 {
366 0x01,
367 L"XGA controller",
368 PCIBlankEntry
369 },
370 {
371 0x02,
372 L"3D controller",
373 PCIBlankEntry
374 },
375 {
376 0x80,
377 L"Other display controller",
378 PCIBlankEntry
379 },
380 {
381 0x00,
382 NULL,
383 /* null string ends the list */PCIBlankEntry
384 }
385 };
386
387 PCI_CLASS_ENTRY PCISubClass_04[] = {
388 {
389 0x00,
390 L"Video device",
391 PCIBlankEntry
392 },
393 {
394 0x01,
395 L"Audio device",
396 PCIBlankEntry
397 },
398 {
399 0x02,
400 L"Computer Telephony device",
401 PCIBlankEntry
402 },
403 {
404 0x03,
405 L"Mixed mode device",
406 PCIBlankEntry
407 },
408 {
409 0x80,
410 L"Other multimedia device",
411 PCIBlankEntry
412 },
413 {
414 0x00,
415 NULL,
416 /* null string ends the list */NULL
417 }
418 };
419
420 PCI_CLASS_ENTRY PCISubClass_05[] = {
421 {
422 0x00,
423 L"RAM memory controller",
424 PCIBlankEntry
425 },
426 {
427 0x01,
428 L"Flash memory controller",
429 PCIBlankEntry
430 },
431 {
432 0x80,
433 L"Other memory controller",
434 PCIBlankEntry
435 },
436 {
437 0x00,
438 NULL,
439 /* null string ends the list */NULL
440 }
441 };
442
443 PCI_CLASS_ENTRY PCISubClass_06[] = {
444 {
445 0x00,
446 L"Host/PCI bridge",
447 PCIBlankEntry
448 },
449 {
450 0x01,
451 L"PCI/ISA bridge",
452 PCIBlankEntry
453 },
454 {
455 0x02,
456 L"PCI/EISA bridge",
457 PCIBlankEntry
458 },
459 {
460 0x03,
461 L"PCI/Micro Channel bridge",
462 PCIBlankEntry
463 },
464 {
465 0x04,
466 L"PCI/PCI bridge",
467 PCIPIFClass_0604
468 },
469 {
470 0x05,
471 L"PCI/PCMCIA bridge",
472 PCIBlankEntry
473 },
474 {
475 0x06,
476 L"NuBus bridge",
477 PCIBlankEntry
478 },
479 {
480 0x07,
481 L"CardBus bridge",
482 PCIBlankEntry
483 },
484 {
485 0x08,
486 L"RACEway bridge",
487 PCIBlankEntry
488 },
489 {
490 0x09,
491 L"Semi-transparent PCI-to-PCI bridge",
492 PCIPIFClass_0609
493 },
494 {
495 0x0A,
496 L"InfiniBand-to-PCI host bridge",
497 PCIBlankEntry
498 },
499 {
500 0x0B,
501 L"Advanced Switching to PCI host bridge",
502 PCIPIFClass_060b
503 },
504 {
505 0x80,
506 L"Other bridge type",
507 PCIBlankEntry
508 },
509 {
510 0x00,
511 NULL,
512 /* null string ends the list */NULL
513 }
514 };
515
516 PCI_CLASS_ENTRY PCISubClass_07[] = {
517 {
518 0x00,
519 L"Serial controller",
520 PCIPIFClass_0700
521 },
522 {
523 0x01,
524 L"Parallel port",
525 PCIPIFClass_0701
526 },
527 {
528 0x02,
529 L"Multiport serial controller",
530 PCIBlankEntry
531 },
532 {
533 0x03,
534 L"Modem",
535 PCIPIFClass_0703
536 },
537 {
538 0x04,
539 L"GPIB (IEEE 488.1/2) controller",
540 PCIBlankEntry
541 },
542 {
543 0x05,
544 L"Smart Card",
545 PCIBlankEntry
546 },
547 {
548 0x80,
549 L"Other communication device",
550 PCIBlankEntry
551 },
552 {
553 0x00,
554 NULL,
555 /* null string ends the list */NULL
556 }
557 };
558
559 PCI_CLASS_ENTRY PCISubClass_08[] = {
560 {
561 0x00,
562 L"PIC",
563 PCIPIFClass_0800
564 },
565 {
566 0x01,
567 L"DMA controller",
568 PCIPIFClass_0801
569 },
570 {
571 0x02,
572 L"System timer",
573 PCIPIFClass_0802
574 },
575 {
576 0x03,
577 L"RTC controller",
578 PCIPIFClass_0803
579 },
580 {
581 0x04,
582 L"Generic PCI Hot-Plug controller",
583 PCIBlankEntry
584 },
585 {
586 0x05,
587 L"SD Host controller",
588 PCIBlankEntry
589 },
590 {
591 0x06,
592 L"IOMMU",
593 PCIBlankEntry
594 },
595 {
596 0x07,
597 L"Root Complex Event Collector",
598 PCIBlankEntry
599 },
600 {
601 0x80,
602 L"Other system peripheral",
603 PCIBlankEntry
604 },
605 {
606 0x00,
607 NULL,
608 /* null string ends the list */NULL
609 }
610 };
611
612 PCI_CLASS_ENTRY PCISubClass_09[] = {
613 {
614 0x00,
615 L"Keyboard controller",
616 PCIBlankEntry
617 },
618 {
619 0x01,
620 L"Digitizer (pen)",
621 PCIBlankEntry
622 },
623 {
624 0x02,
625 L"Mouse controller",
626 PCIBlankEntry
627 },
628 {
629 0x03,
630 L"Scanner controller",
631 PCIBlankEntry
632 },
633 {
634 0x04,
635 L"Gameport controller",
636 PCIPIFClass_0904
637 },
638 {
639 0x80,
640 L"Other input controller",
641 PCIBlankEntry
642 },
643 {
644 0x00,
645 NULL,
646 /* null string ends the list */NULL
647 }
648 };
649
650 PCI_CLASS_ENTRY PCISubClass_0a[] = {
651 {
652 0x00,
653 L"Generic docking station",
654 PCIBlankEntry
655 },
656 {
657 0x80,
658 L"Other type of docking station",
659 PCIBlankEntry
660 },
661 {
662 0x00,
663 NULL,
664 /* null string ends the list */NULL
665 }
666 };
667
668 PCI_CLASS_ENTRY PCISubClass_0b[] = {
669 {
670 0x00,
671 L"386",
672 PCIBlankEntry
673 },
674 {
675 0x01,
676 L"486",
677 PCIBlankEntry
678 },
679 {
680 0x02,
681 L"Pentium",
682 PCIBlankEntry
683 },
684 {
685 0x10,
686 L"Alpha",
687 PCIBlankEntry
688 },
689 {
690 0x20,
691 L"PowerPC",
692 PCIBlankEntry
693 },
694 {
695 0x30,
696 L"MIPS",
697 PCIBlankEntry
698 },
699 {
700 0x40,
701 L"Co-processor",
702 PCIBlankEntry
703 },
704 {
705 0x80,
706 L"Other processor",
707 PCIBlankEntry
708 },
709 {
710 0x00,
711 NULL,
712 /* null string ends the list */NULL
713 }
714 };
715
716 PCI_CLASS_ENTRY PCISubClass_0c[] = {
717 {
718 0x00,
719 L"IEEE 1394",
720 PCIPIFClass_0c00
721 },
722 {
723 0x01,
724 L"ACCESS.bus",
725 PCIBlankEntry
726 },
727 {
728 0x02,
729 L"SSA",
730 PCIBlankEntry
731 },
732 {
733 0x03,
734 L"USB",
735 PCIPIFClass_0c03
736 },
737 {
738 0x04,
739 L"Fibre Channel",
740 PCIBlankEntry
741 },
742 {
743 0x05,
744 L"System Management Bus",
745 PCIBlankEntry
746 },
747 {
748 0x06,
749 L"InfiniBand",
750 PCIBlankEntry
751 },
752 {
753 0x07,
754 L"IPMI",
755 PCIPIFClass_0c07
756 },
757 {
758 0x08,
759 L"SERCOS Interface Standard (IEC 61491)",
760 PCIBlankEntry
761 },
762 {
763 0x09,
764 L"CANbus",
765 PCIBlankEntry
766 },
767 {
768 0x80,
769 L"Other bus type",
770 PCIBlankEntry
771 },
772 {
773 0x00,
774 NULL,
775 /* null string ends the list */NULL
776 }
777 };
778
779 PCI_CLASS_ENTRY PCISubClass_0d[] = {
780 {
781 0x00,
782 L"iRDA compatible controller",
783 PCIBlankEntry
784 },
785 {
786 0x01,
787 L"",
788 PCIPIFClass_0d01
789 },
790 {
791 0x10,
792 L"RF controller",
793 PCIBlankEntry
794 },
795 {
796 0x11,
797 L"Bluetooth",
798 PCIBlankEntry
799 },
800 {
801 0x12,
802 L"Broadband",
803 PCIBlankEntry
804 },
805 {
806 0x20,
807 L"Ethernet (802.11a - 5 GHz)",
808 PCIBlankEntry
809 },
810 {
811 0x21,
812 L"Ethernet (802.11b - 2.4 GHz)",
813 PCIBlankEntry
814 },
815 {
816 0x80,
817 L"Other type of wireless controller",
818 PCIBlankEntry
819 },
820 {
821 0x00,
822 NULL,
823 /* null string ends the list */NULL
824 }
825 };
826
827 PCI_CLASS_ENTRY PCISubClass_0e[] = {
828 {
829 0x00,
830 L"I2O Architecture",
831 PCIPIFClass_0e00
832 },
833 {
834 0x00,
835 NULL,
836 /* null string ends the list */NULL
837 }
838 };
839
840 PCI_CLASS_ENTRY PCISubClass_0f[] = {
841 {
842 0x01,
843 L"TV",
844 PCIBlankEntry
845 },
846 {
847 0x02,
848 L"Audio",
849 PCIBlankEntry
850 },
851 {
852 0x03,
853 L"Voice",
854 PCIBlankEntry
855 },
856 {
857 0x04,
858 L"Data",
859 PCIBlankEntry
860 },
861 {
862 0x80,
863 L"Other satellite communication controller",
864 PCIBlankEntry
865 },
866 {
867 0x00,
868 NULL,
869 /* null string ends the list */NULL
870 }
871 };
872
873 PCI_CLASS_ENTRY PCISubClass_10[] = {
874 {
875 0x00,
876 L"Network & computing Encrypt/Decrypt",
877 PCIBlankEntry
878 },
879 {
880 0x01,
881 L"Entertainment Encrypt/Decrypt",
882 PCIBlankEntry
883 },
884 {
885 0x80,
886 L"Other Encrypt/Decrypt",
887 PCIBlankEntry
888 },
889 {
890 0x00,
891 NULL,
892 /* null string ends the list */NULL
893 }
894 };
895
896 PCI_CLASS_ENTRY PCISubClass_11[] = {
897 {
898 0x00,
899 L"DPIO modules",
900 PCIBlankEntry
901 },
902 {
903 0x01,
904 L"Performance Counters",
905 PCIBlankEntry
906 },
907 {
908 0x10,
909 L"Communications synchronization plus time and frequency test/measurement ",
910 PCIBlankEntry
911 },
912 {
913 0x20,
914 L"Management card",
915 PCIBlankEntry
916 },
917 {
918 0x80,
919 L"Other DAQ & SP controllers",
920 PCIBlankEntry
921 },
922 {
923 0x00,
924 NULL,
925 /* null string ends the list */NULL
926 }
927 };
928
929 PCI_CLASS_ENTRY PCISubClass_12[] = {
930 {
931 0x00,
932 L"Processing Accelerator",
933 PCIBlankEntry
934 },
935 {
936 0x00,
937 NULL,
938 /* null string ends the list */NULL
939 }
940 };
941
942 PCI_CLASS_ENTRY PCISubClass_13[] = {
943 {
944 0x00,
945 L"Non-Essential Instrumentation Function",
946 PCIBlankEntry
947 },
948 {
949 0x00,
950 NULL,
951 /* null string ends the list */NULL
952 }
953 };
954
955 //
956 // Programming Interface entries
957 //
958 PCI_CLASS_ENTRY PCIPIFClass_0100[] = {
959 {
960 0x00,
961 L"SCSI controller",
962 PCIBlankEntry
963 },
964 {
965 0x11,
966 L"SCSI storage device SOP using PQI",
967 PCIBlankEntry
968 },
969 {
970 0x12,
971 L"SCSI controller SOP using PQI",
972 PCIBlankEntry
973 },
974 {
975 0x13,
976 L"SCSI storage device and controller SOP using PQI",
977 PCIBlankEntry
978 },
979 {
980 0x21,
981 L"SCSI storage device SOP using NVMe",
982 PCIBlankEntry
983 },
984 {
985 0x00,
986 NULL,
987 /* null string ends the list */NULL
988 }
989 };
990
991 PCI_CLASS_ENTRY PCIPIFClass_0101[] = {
992 {
993 0x00,
994 L"",
995 PCIBlankEntry
996 },
997 {
998 0x01,
999 L"OM-primary",
1000 PCIBlankEntry
1001 },
1002 {
1003 0x02,
1004 L"PI-primary",
1005 PCIBlankEntry
1006 },
1007 {
1008 0x03,
1009 L"OM/PI-primary",
1010 PCIBlankEntry
1011 },
1012 {
1013 0x04,
1014 L"OM-secondary",
1015 PCIBlankEntry
1016 },
1017 {
1018 0x05,
1019 L"OM-primary, OM-secondary",
1020 PCIBlankEntry
1021 },
1022 {
1023 0x06,
1024 L"PI-primary, OM-secondary",
1025 PCIBlankEntry
1026 },
1027 {
1028 0x07,
1029 L"OM/PI-primary, OM-secondary",
1030 PCIBlankEntry
1031 },
1032 {
1033 0x08,
1034 L"OM-secondary",
1035 PCIBlankEntry
1036 },
1037 {
1038 0x09,
1039 L"OM-primary, PI-secondary",
1040 PCIBlankEntry
1041 },
1042 {
1043 0x0a,
1044 L"PI-primary, PI-secondary",
1045 PCIBlankEntry
1046 },
1047 {
1048 0x0b,
1049 L"OM/PI-primary, PI-secondary",
1050 PCIBlankEntry
1051 },
1052 {
1053 0x0c,
1054 L"OM-secondary",
1055 PCIBlankEntry
1056 },
1057 {
1058 0x0d,
1059 L"OM-primary, OM/PI-secondary",
1060 PCIBlankEntry
1061 },
1062 {
1063 0x0e,
1064 L"PI-primary, OM/PI-secondary",
1065 PCIBlankEntry
1066 },
1067 {
1068 0x0f,
1069 L"OM/PI-primary, OM/PI-secondary",
1070 PCIBlankEntry
1071 },
1072 {
1073 0x80,
1074 L"Master",
1075 PCIBlankEntry
1076 },
1077 {
1078 0x81,
1079 L"Master, OM-primary",
1080 PCIBlankEntry
1081 },
1082 {
1083 0x82,
1084 L"Master, PI-primary",
1085 PCIBlankEntry
1086 },
1087 {
1088 0x83,
1089 L"Master, OM/PI-primary",
1090 PCIBlankEntry
1091 },
1092 {
1093 0x84,
1094 L"Master, OM-secondary",
1095 PCIBlankEntry
1096 },
1097 {
1098 0x85,
1099 L"Master, OM-primary, OM-secondary",
1100 PCIBlankEntry
1101 },
1102 {
1103 0x86,
1104 L"Master, PI-primary, OM-secondary",
1105 PCIBlankEntry
1106 },
1107 {
1108 0x87,
1109 L"Master, OM/PI-primary, OM-secondary",
1110 PCIBlankEntry
1111 },
1112 {
1113 0x88,
1114 L"Master, OM-secondary",
1115 PCIBlankEntry
1116 },
1117 {
1118 0x89,
1119 L"Master, OM-primary, PI-secondary",
1120 PCIBlankEntry
1121 },
1122 {
1123 0x8a,
1124 L"Master, PI-primary, PI-secondary",
1125 PCIBlankEntry
1126 },
1127 {
1128 0x8b,
1129 L"Master, OM/PI-primary, PI-secondary",
1130 PCIBlankEntry
1131 },
1132 {
1133 0x8c,
1134 L"Master, OM-secondary",
1135 PCIBlankEntry
1136 },
1137 {
1138 0x8d,
1139 L"Master, OM-primary, OM/PI-secondary",
1140 PCIBlankEntry
1141 },
1142 {
1143 0x8e,
1144 L"Master, PI-primary, OM/PI-secondary",
1145 PCIBlankEntry
1146 },
1147 {
1148 0x8f,
1149 L"Master, OM/PI-primary, OM/PI-secondary",
1150 PCIBlankEntry
1151 },
1152 {
1153 0x00,
1154 NULL,
1155 /* null string ends the list */NULL
1156 }
1157 };
1158
1159 PCI_CLASS_ENTRY PCIPIFClass_0105[] = {
1160 {
1161 0x20,
1162 L"Single stepping",
1163 PCIBlankEntry
1164 },
1165 {
1166 0x30,
1167 L"Continuous operation",
1168 PCIBlankEntry
1169 },
1170 {
1171 0x00,
1172 NULL,
1173 /* null string ends the list */NULL
1174 }
1175 };
1176
1177 PCI_CLASS_ENTRY PCIPIFClass_0106[] = {
1178 {
1179 0x00,
1180 L"",
1181 PCIBlankEntry
1182 },
1183 {
1184 0x01,
1185 L"AHCI",
1186 PCIBlankEntry
1187 },
1188 {
1189 0x02,
1190 L"Serial Storage Bus",
1191 PCIBlankEntry
1192 },
1193 {
1194 0x00,
1195 NULL,
1196 /* null string ends the list */NULL
1197 }
1198 };
1199
1200 PCI_CLASS_ENTRY PCIPIFClass_0107[] = {
1201 {
1202 0x00,
1203 L"",
1204 PCIBlankEntry
1205 },
1206 {
1207 0x01,
1208 L"Obsolete",
1209 PCIBlankEntry
1210 },
1211 {
1212 0x00,
1213 NULL,
1214 /* null string ends the list */NULL
1215 }
1216 };
1217
1218 PCI_CLASS_ENTRY PCIPIFClass_0108[] = {
1219 {
1220 0x00,
1221 L"",
1222 PCIBlankEntry
1223 },
1224 {
1225 0x01,
1226 L"NVMHCI",
1227 PCIBlankEntry
1228 },
1229 {
1230 0x02,
1231 L"NVM Express",
1232 PCIBlankEntry
1233 },
1234 {
1235 0x00,
1236 NULL,
1237 /* null string ends the list */NULL
1238 }
1239 };
1240
1241 PCI_CLASS_ENTRY PCIPIFClass_0109[] = {
1242 {
1243 0x00,
1244 L"",
1245 PCIBlankEntry
1246 },
1247 {
1248 0x01,
1249 L"UFSHCI",
1250 PCIBlankEntry
1251 },
1252 {
1253 0x00,
1254 NULL,
1255 /* null string ends the list */NULL
1256 }
1257 };
1258
1259 PCI_CLASS_ENTRY PCIPIFClass_0300[] = {
1260 {
1261 0x00,
1262 L"VGA compatible",
1263 PCIBlankEntry
1264 },
1265 {
1266 0x01,
1267 L"8514 compatible",
1268 PCIBlankEntry
1269 },
1270 {
1271 0x00,
1272 NULL,
1273 /* null string ends the list */NULL
1274 }
1275 };
1276
1277 PCI_CLASS_ENTRY PCIPIFClass_0604[] = {
1278 {
1279 0x00,
1280 L"",
1281 PCIBlankEntry
1282 },
1283 {
1284 0x01,
1285 L"Subtractive decode",
1286 PCIBlankEntry
1287 },
1288 {
1289 0x00,
1290 NULL,
1291 /* null string ends the list */NULL
1292 }
1293 };
1294
1295 PCI_CLASS_ENTRY PCIPIFClass_0609[] = {
1296 {
1297 0x40,
1298 L"Primary PCI bus side facing the system host processor",
1299 PCIBlankEntry
1300 },
1301 {
1302 0x80,
1303 L"Secondary PCI bus side facing the system host processor",
1304 PCIBlankEntry
1305 },
1306 {
1307 0x00,
1308 NULL,
1309 /* null string ends the list */NULL
1310 }
1311 };
1312
1313 PCI_CLASS_ENTRY PCIPIFClass_060b[] = {
1314 {
1315 0x00,
1316 L"Custom",
1317 PCIBlankEntry
1318 },
1319 {
1320 0x01,
1321 L"ASI-SIG Defined Portal",
1322 PCIBlankEntry
1323 },
1324 {
1325 0x00,
1326 NULL,
1327 /* null string ends the list */NULL
1328 }
1329 };
1330
1331 PCI_CLASS_ENTRY PCIPIFClass_0700[] = {
1332 {
1333 0x00,
1334 L"Generic XT-compatible",
1335 PCIBlankEntry
1336 },
1337 {
1338 0x01,
1339 L"16450-compatible",
1340 PCIBlankEntry
1341 },
1342 {
1343 0x02,
1344 L"16550-compatible",
1345 PCIBlankEntry
1346 },
1347 {
1348 0x03,
1349 L"16650-compatible",
1350 PCIBlankEntry
1351 },
1352 {
1353 0x04,
1354 L"16750-compatible",
1355 PCIBlankEntry
1356 },
1357 {
1358 0x05,
1359 L"16850-compatible",
1360 PCIBlankEntry
1361 },
1362 {
1363 0x06,
1364 L"16950-compatible",
1365 PCIBlankEntry
1366 },
1367 {
1368 0x00,
1369 NULL,
1370 /* null string ends the list */NULL
1371 }
1372 };
1373
1374 PCI_CLASS_ENTRY PCIPIFClass_0701[] = {
1375 {
1376 0x00,
1377 L"",
1378 PCIBlankEntry
1379 },
1380 {
1381 0x01,
1382 L"Bi-directional",
1383 PCIBlankEntry
1384 },
1385 {
1386 0x02,
1387 L"ECP 1.X-compliant",
1388 PCIBlankEntry
1389 },
1390 {
1391 0x03,
1392 L"IEEE 1284",
1393 PCIBlankEntry
1394 },
1395 {
1396 0xfe,
1397 L"IEEE 1284 target (not a controller)",
1398 PCIBlankEntry
1399 },
1400 {
1401 0x00,
1402 NULL,
1403 /* null string ends the list */NULL
1404 }
1405 };
1406
1407 PCI_CLASS_ENTRY PCIPIFClass_0703[] = {
1408 {
1409 0x00,
1410 L"Generic",
1411 PCIBlankEntry
1412 },
1413 {
1414 0x01,
1415 L"Hayes-compatible 16450",
1416 PCIBlankEntry
1417 },
1418 {
1419 0x02,
1420 L"Hayes-compatible 16550",
1421 PCIBlankEntry
1422 },
1423 {
1424 0x03,
1425 L"Hayes-compatible 16650",
1426 PCIBlankEntry
1427 },
1428 {
1429 0x04,
1430 L"Hayes-compatible 16750",
1431 PCIBlankEntry
1432 },
1433 {
1434 0x00,
1435 NULL,
1436 /* null string ends the list */NULL
1437 }
1438 };
1439
1440 PCI_CLASS_ENTRY PCIPIFClass_0800[] = {
1441 {
1442 0x00,
1443 L"Generic 8259",
1444 PCIBlankEntry
1445 },
1446 {
1447 0x01,
1448 L"ISA",
1449 PCIBlankEntry
1450 },
1451 {
1452 0x02,
1453 L"EISA",
1454 PCIBlankEntry
1455 },
1456 {
1457 0x10,
1458 L"IO APIC",
1459 PCIBlankEntry
1460 },
1461 {
1462 0x20,
1463 L"IO(x) APIC interrupt controller",
1464 PCIBlankEntry
1465 },
1466 {
1467 0x00,
1468 NULL,
1469 /* null string ends the list */NULL
1470 }
1471 };
1472
1473 PCI_CLASS_ENTRY PCIPIFClass_0801[] = {
1474 {
1475 0x00,
1476 L"Generic 8237",
1477 PCIBlankEntry
1478 },
1479 {
1480 0x01,
1481 L"ISA",
1482 PCIBlankEntry
1483 },
1484 {
1485 0x02,
1486 L"EISA",
1487 PCIBlankEntry
1488 },
1489 {
1490 0x00,
1491 NULL,
1492 /* null string ends the list */NULL
1493 }
1494 };
1495
1496 PCI_CLASS_ENTRY PCIPIFClass_0802[] = {
1497 {
1498 0x00,
1499 L"Generic 8254",
1500 PCIBlankEntry
1501 },
1502 {
1503 0x01,
1504 L"ISA",
1505 PCIBlankEntry
1506 },
1507 {
1508 0x02,
1509 L"EISA",
1510 PCIBlankEntry
1511 },
1512 {
1513 0x00,
1514 NULL,
1515 /* null string ends the list */NULL
1516 }
1517 };
1518
1519 PCI_CLASS_ENTRY PCIPIFClass_0803[] = {
1520 {
1521 0x00,
1522 L"Generic",
1523 PCIBlankEntry
1524 },
1525 {
1526 0x01,
1527 L"ISA",
1528 PCIBlankEntry
1529 },
1530 {
1531 0x02,
1532 L"EISA",
1533 PCIBlankEntry
1534 },
1535 {
1536 0x00,
1537 NULL,
1538 /* null string ends the list */NULL
1539 }
1540 };
1541
1542 PCI_CLASS_ENTRY PCIPIFClass_0904[] = {
1543 {
1544 0x00,
1545 L"Generic",
1546 PCIBlankEntry
1547 },
1548 {
1549 0x10,
1550 L"",
1551 PCIBlankEntry
1552 },
1553 {
1554 0x00,
1555 NULL,
1556 /* null string ends the list */NULL
1557 }
1558 };
1559
1560 PCI_CLASS_ENTRY PCIPIFClass_0c00[] = {
1561 {
1562 0x00,
1563 L"",
1564 PCIBlankEntry
1565 },
1566 {
1567 0x10,
1568 L"Using 1394 OpenHCI spec",
1569 PCIBlankEntry
1570 },
1571 {
1572 0x00,
1573 NULL,
1574 /* null string ends the list */NULL
1575 }
1576 };
1577
1578 PCI_CLASS_ENTRY PCIPIFClass_0c03[] = {
1579 {
1580 0x00,
1581 L"UHCI",
1582 PCIBlankEntry
1583 },
1584 {
1585 0x10,
1586 L"OHCI",
1587 PCIBlankEntry
1588 },
1589 {
1590 0x20,
1591 L"EHCI",
1592 PCIBlankEntry
1593 },
1594 {
1595 0x30,
1596 L"xHCI",
1597 PCIBlankEntry
1598 },
1599 {
1600 0x80,
1601 L"No specific programming interface",
1602 PCIBlankEntry
1603 },
1604 {
1605 0xfe,
1606 L"(Not Host Controller)",
1607 PCIBlankEntry
1608 },
1609 {
1610 0x00,
1611 NULL,
1612 /* null string ends the list */NULL
1613 }
1614 };
1615
1616 PCI_CLASS_ENTRY PCIPIFClass_0c07[] = {
1617 {
1618 0x00,
1619 L"SMIC",
1620 PCIBlankEntry
1621 },
1622 {
1623 0x01,
1624 L"Keyboard Controller Style",
1625 PCIBlankEntry
1626 },
1627 {
1628 0x02,
1629 L"Block Transfer",
1630 PCIBlankEntry
1631 },
1632 {
1633 0x00,
1634 NULL,
1635 /* null string ends the list */NULL
1636 }
1637 };
1638
1639 PCI_CLASS_ENTRY PCIPIFClass_0d01[] = {
1640 {
1641 0x00,
1642 L"Consumer IR controller",
1643 PCIBlankEntry
1644 },
1645 {
1646 0x10,
1647 L"UWB Radio controller",
1648 PCIBlankEntry
1649 },
1650 {
1651 0x00,
1652 NULL,
1653 /* null string ends the list */NULL
1654 }
1655 };
1656
1657 PCI_CLASS_ENTRY PCIPIFClass_0e00[] = {
1658 {
1659 0x00,
1660 L"Message FIFO at offset 40h",
1661 PCIBlankEntry
1662 },
1663 {
1664 0x01,
1665 L"",
1666 PCIBlankEntry
1667 },
1668 {
1669 0x00,
1670 NULL,
1671 /* null string ends the list */NULL
1672 }
1673 };
1674
1675
1676 /**
1677 Generates printable Unicode strings that represent PCI device class,
1678 subclass and programmed I/F based on a value passed to the function.
1679
1680 @param[in] ClassCode Value representing the PCI "Class Code" register read from a
1681 PCI device. The encodings are:
1682 bits 23:16 - Base Class Code
1683 bits 15:8 - Sub-Class Code
1684 bits 7:0 - Programming Interface
1685 @param[in, out] ClassStrings Pointer of PCI_CLASS_STRINGS structure, which contains
1686 printable class strings corresponding to ClassCode. The
1687 caller must not modify the strings that are pointed by
1688 the fields in ClassStrings.
1689 **/
1690 VOID
1691 PciGetClassStrings (
1692 IN UINT32 ClassCode,
1693 IN OUT PCI_CLASS_STRINGS *ClassStrings
1694 )
1695 {
1696 INTN Index;
1697 UINT8 Code;
1698 PCI_CLASS_ENTRY *CurrentClass;
1699
1700 //
1701 // Assume no strings found
1702 //
1703 ClassStrings->BaseClass = L"UNDEFINED";
1704 ClassStrings->SubClass = L"UNDEFINED";
1705 ClassStrings->PIFClass = L"UNDEFINED";
1706
1707 CurrentClass = gClassStringList;
1708 Code = (UINT8) (ClassCode >> 16);
1709 Index = 0;
1710
1711 //
1712 // Go through all entries of the base class, until the entry with a matching
1713 // base class code is found. If reaches an entry with a null description
1714 // text, the last entry is met, which means no text for the base class was
1715 // found, so no more action is needed.
1716 //
1717 while (Code != CurrentClass[Index].Code) {
1718 if (NULL == CurrentClass[Index].DescText) {
1719 return ;
1720 }
1721
1722 Index++;
1723 }
1724 //
1725 // A base class was found. Assign description, and check if this class has
1726 // sub-class defined. If sub-class defined, no more action is needed,
1727 // otherwise, continue to find description for the sub-class code.
1728 //
1729 ClassStrings->BaseClass = CurrentClass[Index].DescText;
1730 if (NULL == CurrentClass[Index].LowerLevelClass) {
1731 return ;
1732 }
1733 //
1734 // find Subclass entry
1735 //
1736 CurrentClass = CurrentClass[Index].LowerLevelClass;
1737 Code = (UINT8) (ClassCode >> 8);
1738 Index = 0;
1739
1740 //
1741 // Go through all entries of the sub-class, until the entry with a matching
1742 // sub-class code is found. If reaches an entry with a null description
1743 // text, the last entry is met, which means no text for the sub-class was
1744 // found, so no more action is needed.
1745 //
1746 while (Code != CurrentClass[Index].Code) {
1747 if (NULL == CurrentClass[Index].DescText) {
1748 return ;
1749 }
1750
1751 Index++;
1752 }
1753 //
1754 // A class was found for the sub-class code. Assign description, and check if
1755 // this sub-class has programming interface defined. If no, no more action is
1756 // needed, otherwise, continue to find description for the programming
1757 // interface.
1758 //
1759 ClassStrings->SubClass = CurrentClass[Index].DescText;
1760 if (NULL == CurrentClass[Index].LowerLevelClass) {
1761 return ;
1762 }
1763 //
1764 // Find programming interface entry
1765 //
1766 CurrentClass = CurrentClass[Index].LowerLevelClass;
1767 Code = (UINT8) ClassCode;
1768 Index = 0;
1769
1770 //
1771 // Go through all entries of the I/F entries, until the entry with a
1772 // matching I/F code is found. If reaches an entry with a null description
1773 // text, the last entry is met, which means no text was found, so no more
1774 // action is needed.
1775 //
1776 while (Code != CurrentClass[Index].Code) {
1777 if (NULL == CurrentClass[Index].DescText) {
1778 return ;
1779 }
1780
1781 Index++;
1782 }
1783 //
1784 // A class was found for the I/F code. Assign description, done!
1785 //
1786 ClassStrings->PIFClass = CurrentClass[Index].DescText;
1787 return ;
1788 }
1789
1790 /**
1791 Print strings that represent PCI device class, subclass and programmed I/F.
1792
1793 @param[in] ClassCodePtr Points to the memory which stores register Class Code in PCI
1794 configuration space.
1795 @param[in] IncludePIF If the printed string should include the programming I/F part
1796 **/
1797 VOID
1798 PciPrintClassCode (
1799 IN UINT8 *ClassCodePtr,
1800 IN BOOLEAN IncludePIF
1801 )
1802 {
1803 UINT32 ClassCode;
1804 PCI_CLASS_STRINGS ClassStrings;
1805
1806 ClassCode = 0;
1807 ClassCode |= (UINT32)ClassCodePtr[0];
1808 ClassCode |= (UINT32)(ClassCodePtr[1] << 8);
1809 ClassCode |= (UINT32)(ClassCodePtr[2] << 16);
1810
1811 //
1812 // Get name from class code
1813 //
1814 PciGetClassStrings (ClassCode, &ClassStrings);
1815
1816 if (IncludePIF) {
1817 //
1818 // Print base class, sub class, and programming inferface name
1819 //
1820 ShellPrintEx (-1, -1, L"%s - %s - %s",
1821 ClassStrings.BaseClass,
1822 ClassStrings.SubClass,
1823 ClassStrings.PIFClass
1824 );
1825
1826 } else {
1827 //
1828 // Only print base class and sub class name
1829 //
1830 ShellPrintEx (-1, -1, L"%s - %s",
1831 ClassStrings.BaseClass,
1832 ClassStrings.SubClass
1833 );
1834 }
1835 }
1836
1837 /**
1838 This function finds out the protocol which is in charge of the given
1839 segment, and its bus range covers the current bus number. It lookes
1840 each instances of RootBridgeIoProtocol handle, until the one meets the
1841 criteria is found.
1842
1843 @param[in] HandleBuf Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
1844 @param[in] HandleCount Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
1845 @param[in] Segment Segment number of device we are dealing with.
1846 @param[in] Bus Bus number of device we are dealing with.
1847 @param[out] IoDev Handle used to access configuration space of PCI device.
1848
1849 @retval EFI_SUCCESS The command completed successfully.
1850 @retval EFI_INVALID_PARAMETER Invalid parameter.
1851
1852 **/
1853 EFI_STATUS
1854 PciFindProtocolInterface (
1855 IN EFI_HANDLE *HandleBuf,
1856 IN UINTN HandleCount,
1857 IN UINT16 Segment,
1858 IN UINT16 Bus,
1859 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev
1860 );
1861
1862 /**
1863 This function gets the protocol interface from the given handle, and
1864 obtains its address space descriptors.
1865
1866 @param[in] Handle The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle.
1867 @param[out] IoDev Handle used to access configuration space of PCI device.
1868 @param[out] Descriptors Points to the address space descriptors.
1869
1870 @retval EFI_SUCCESS The command completed successfully
1871 **/
1872 EFI_STATUS
1873 PciGetProtocolAndResource (
1874 IN EFI_HANDLE Handle,
1875 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev,
1876 OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors
1877 );
1878
1879 /**
1880 This function get the next bus range of given address space descriptors.
1881 It also moves the pointer backward a node, to get prepared to be called
1882 again.
1883
1884 @param[in, out] Descriptors Points to current position of a serial of address space
1885 descriptors.
1886 @param[out] MinBus The lower range of bus number.
1887 @param[out] MaxBus The upper range of bus number.
1888 @param[out] IsEnd Meet end of the serial of descriptors.
1889
1890 @retval EFI_SUCCESS The command completed successfully.
1891 **/
1892 EFI_STATUS
1893 PciGetNextBusRange (
1894 IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,
1895 OUT UINT16 *MinBus,
1896 OUT UINT16 *MaxBus,
1897 OUT BOOLEAN *IsEnd
1898 );
1899
1900 /**
1901 Explain the data in PCI configuration space. The part which is common for
1902 PCI device and bridge is interpreted in this function. It calls other
1903 functions to interpret data unique for device or bridge.
1904
1905 @param[in] ConfigSpace Data in PCI configuration space.
1906 @param[in] Address Address used to access configuration space of this PCI device.
1907 @param[in] IoDev Handle used to access configuration space of PCI device.
1908 **/
1909 VOID
1910 PciExplainPci (
1911 IN PCI_CONFIG_SPACE *ConfigSpace,
1912 IN UINT64 Address,
1913 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
1914 );
1915
1916 /**
1917 Explain the device specific part of data in PCI configuration space.
1918
1919 @param[in] Device Data in PCI configuration space.
1920 @param[in] Address Address used to access configuration space of this PCI device.
1921 @param[in] IoDev Handle used to access configuration space of PCI device.
1922
1923 @retval EFI_SUCCESS The command completed successfully.
1924 **/
1925 EFI_STATUS
1926 PciExplainDeviceData (
1927 IN PCI_DEVICE_HEADER_TYPE_REGION *Device,
1928 IN UINT64 Address,
1929 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
1930 );
1931
1932 /**
1933 Explain the bridge specific part of data in PCI configuration space.
1934
1935 @param[in] Bridge Bridge specific data region in PCI configuration space.
1936 @param[in] Address Address used to access configuration space of this PCI device.
1937 @param[in] IoDev Handle used to access configuration space of PCI device.
1938
1939 @retval EFI_SUCCESS The command completed successfully.
1940 **/
1941 EFI_STATUS
1942 PciExplainBridgeData (
1943 IN PCI_BRIDGE_CONTROL_REGISTER *Bridge,
1944 IN UINT64 Address,
1945 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
1946 );
1947
1948 /**
1949 Explain the Base Address Register(Bar) in PCI configuration space.
1950
1951 @param[in] Bar Points to the Base Address Register intended to interpret.
1952 @param[in] Command Points to the register Command.
1953 @param[in] Address Address used to access configuration space of this PCI device.
1954 @param[in] IoDev Handle used to access configuration space of PCI device.
1955 @param[in, out] Index The Index.
1956
1957 @retval EFI_SUCCESS The command completed successfully.
1958 **/
1959 EFI_STATUS
1960 PciExplainBar (
1961 IN UINT32 *Bar,
1962 IN UINT16 *Command,
1963 IN UINT64 Address,
1964 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
1965 IN OUT UINTN *Index
1966 );
1967
1968 /**
1969 Explain the cardbus specific part of data in PCI configuration space.
1970
1971 @param[in] CardBus CardBus specific region of PCI configuration space.
1972 @param[in] Address Address used to access configuration space of this PCI device.
1973 @param[in] IoDev Handle used to access configuration space of PCI device.
1974
1975 @retval EFI_SUCCESS The command completed successfully.
1976 **/
1977 EFI_STATUS
1978 PciExplainCardBusData (
1979 IN PCI_CARDBUS_CONTROL_REGISTER *CardBus,
1980 IN UINT64 Address,
1981 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
1982 );
1983
1984 /**
1985 Explain each meaningful bit of register Status. The definition of Status is
1986 slightly different depending on the PCI header type.
1987
1988 @param[in] Status Points to the content of register Status.
1989 @param[in] MainStatus Indicates if this register is main status(not secondary
1990 status).
1991 @param[in] HeaderType Header type of this PCI device.
1992
1993 @retval EFI_SUCCESS The command completed successfully.
1994 **/
1995 EFI_STATUS
1996 PciExplainStatus (
1997 IN UINT16 *Status,
1998 IN BOOLEAN MainStatus,
1999 IN PCI_HEADER_TYPE HeaderType
2000 );
2001
2002 /**
2003 Explain each meaningful bit of register Command.
2004
2005 @param[in] Command Points to the content of register Command.
2006
2007 @retval EFI_SUCCESS The command completed successfully.
2008 **/
2009 EFI_STATUS
2010 PciExplainCommand (
2011 IN UINT16 *Command
2012 );
2013
2014 /**
2015 Explain each meaningful bit of register Bridge Control.
2016
2017 @param[in] BridgeControl Points to the content of register Bridge Control.
2018 @param[in] HeaderType The headertype.
2019
2020 @retval EFI_SUCCESS The command completed successfully.
2021 **/
2022 EFI_STATUS
2023 PciExplainBridgeControl (
2024 IN UINT16 *BridgeControl,
2025 IN PCI_HEADER_TYPE HeaderType
2026 );
2027
2028 /**
2029 Locate capability register block per capability ID.
2030
2031 @param[in] ConfigSpace Data in PCI configuration space.
2032 @param[in] CapabilityId The capability ID.
2033
2034 @return The offset of the register block per capability ID.
2035 **/
2036 UINT8
2037 LocatePciCapability (
2038 IN PCI_CONFIG_SPACE *ConfigSpace,
2039 IN UINT8 CapabilityId
2040 );
2041
2042 /**
2043 Display Pcie device structure.
2044
2045 @param[in] PciExpressCap PCI Express capability buffer.
2046 @param[in] ExtendedConfigSpace PCI Express extended configuration space.
2047 @param[in] ExtendedCapability PCI Express extended capability ID to explain.
2048 **/
2049 VOID
2050 PciExplainPciExpress (
2051 IN PCI_CAPABILITY_PCIEXP *PciExpressCap,
2052 IN UINT8 *ExtendedConfigSpace,
2053 IN CONST UINT16 ExtendedCapability
2054 );
2055
2056 /**
2057 Print out information of the capability information.
2058
2059 @param[in] PciExpressCap The pointer to the structure about the device.
2060
2061 @retval EFI_SUCCESS The operation was successful.
2062 **/
2063 EFI_STATUS
2064 ExplainPcieCapReg (
2065 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2066 );
2067
2068 /**
2069 Print out information of the device capability information.
2070
2071 @param[in] PciExpressCap The pointer to the structure about the device.
2072
2073 @retval EFI_SUCCESS The operation was successful.
2074 **/
2075 EFI_STATUS
2076 ExplainPcieDeviceCap (
2077 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2078 );
2079
2080 /**
2081 Print out information of the device control information.
2082
2083 @param[in] PciExpressCap The pointer to the structure about the device.
2084
2085 @retval EFI_SUCCESS The operation was successful.
2086 **/
2087 EFI_STATUS
2088 ExplainPcieDeviceControl (
2089 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2090 );
2091
2092 /**
2093 Print out information of the device status information.
2094
2095 @param[in] PciExpressCap The pointer to the structure about the device.
2096
2097 @retval EFI_SUCCESS The operation was successful.
2098 **/
2099 EFI_STATUS
2100 ExplainPcieDeviceStatus (
2101 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2102 );
2103
2104 /**
2105 Print out information of the device link information.
2106
2107 @param[in] PciExpressCap The pointer to the structure about the device.
2108
2109 @retval EFI_SUCCESS The operation was successful.
2110 **/
2111 EFI_STATUS
2112 ExplainPcieLinkCap (
2113 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2114 );
2115
2116 /**
2117 Print out information of the device link control information.
2118
2119 @param[in] PciExpressCap The pointer to the structure about the device.
2120
2121 @retval EFI_SUCCESS The operation was successful.
2122 **/
2123 EFI_STATUS
2124 ExplainPcieLinkControl (
2125 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2126 );
2127
2128 /**
2129 Print out information of the device link status information.
2130
2131 @param[in] PciExpressCap The pointer to the structure about the device.
2132
2133 @retval EFI_SUCCESS The operation was successful.
2134 **/
2135 EFI_STATUS
2136 ExplainPcieLinkStatus (
2137 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2138 );
2139
2140 /**
2141 Print out information of the device slot information.
2142
2143 @param[in] PciExpressCap The pointer to the structure about the device.
2144
2145 @retval EFI_SUCCESS The operation was successful.
2146 **/
2147 EFI_STATUS
2148 ExplainPcieSlotCap (
2149 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2150 );
2151
2152 /**
2153 Print out information of the device slot control information.
2154
2155 @param[in] PciExpressCap The pointer to the structure about the device.
2156
2157 @retval EFI_SUCCESS The operation was successful.
2158 **/
2159 EFI_STATUS
2160 ExplainPcieSlotControl (
2161 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2162 );
2163
2164 /**
2165 Print out information of the device slot status information.
2166
2167 @param[in] PciExpressCap The pointer to the structure about the device.
2168
2169 @retval EFI_SUCCESS The operation was successful.
2170 **/
2171 EFI_STATUS
2172 ExplainPcieSlotStatus (
2173 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2174 );
2175
2176 /**
2177 Print out information of the device root information.
2178
2179 @param[in] PciExpressCap The pointer to the structure about the device.
2180
2181 @retval EFI_SUCCESS The operation was successful.
2182 **/
2183 EFI_STATUS
2184 ExplainPcieRootControl (
2185 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2186 );
2187
2188 /**
2189 Print out information of the device root capability information.
2190
2191 @param[in] PciExpressCap The pointer to the structure about the device.
2192
2193 @retval EFI_SUCCESS The operation was successful.
2194 **/
2195 EFI_STATUS
2196 ExplainPcieRootCap (
2197 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2198 );
2199
2200 /**
2201 Print out information of the device root status information.
2202
2203 @param[in] PciExpressCap The pointer to the structure about the device.
2204
2205 @retval EFI_SUCCESS The operation was successful.
2206 **/
2207 EFI_STATUS
2208 ExplainPcieRootStatus (
2209 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
2210 );
2211
2212 typedef EFI_STATUS (*PCIE_EXPLAIN_FUNCTION) (IN PCI_CAPABILITY_PCIEXP *PciExpressCap);
2213
2214 typedef enum {
2215 FieldWidthUINT8,
2216 FieldWidthUINT16,
2217 FieldWidthUINT32
2218 } PCIE_CAPREG_FIELD_WIDTH;
2219
2220 typedef enum {
2221 PcieExplainTypeCommon,
2222 PcieExplainTypeDevice,
2223 PcieExplainTypeLink,
2224 PcieExplainTypeSlot,
2225 PcieExplainTypeRoot,
2226 PcieExplainTypeMax
2227 } PCIE_EXPLAIN_TYPE;
2228
2229 typedef struct
2230 {
2231 UINT16 Token;
2232 UINTN Offset;
2233 PCIE_CAPREG_FIELD_WIDTH Width;
2234 PCIE_EXPLAIN_FUNCTION Func;
2235 PCIE_EXPLAIN_TYPE Type;
2236 } PCIE_EXPLAIN_STRUCT;
2237
2238 PCIE_EXPLAIN_STRUCT PcieExplainList[] = {
2239 {
2240 STRING_TOKEN (STR_PCIEX_CAPABILITY_CAPID),
2241 0x00,
2242 FieldWidthUINT8,
2243 NULL,
2244 PcieExplainTypeCommon
2245 },
2246 {
2247 STRING_TOKEN (STR_PCIEX_NEXTCAP_PTR),
2248 0x01,
2249 FieldWidthUINT8,
2250 NULL,
2251 PcieExplainTypeCommon
2252 },
2253 {
2254 STRING_TOKEN (STR_PCIEX_CAP_REGISTER),
2255 0x02,
2256 FieldWidthUINT16,
2257 ExplainPcieCapReg,
2258 PcieExplainTypeCommon
2259 },
2260 {
2261 STRING_TOKEN (STR_PCIEX_DEVICE_CAP),
2262 0x04,
2263 FieldWidthUINT32,
2264 ExplainPcieDeviceCap,
2265 PcieExplainTypeDevice
2266 },
2267 {
2268 STRING_TOKEN (STR_PCIEX_DEVICE_CONTROL),
2269 0x08,
2270 FieldWidthUINT16,
2271 ExplainPcieDeviceControl,
2272 PcieExplainTypeDevice
2273 },
2274 {
2275 STRING_TOKEN (STR_PCIEX_DEVICE_STATUS),
2276 0x0a,
2277 FieldWidthUINT16,
2278 ExplainPcieDeviceStatus,
2279 PcieExplainTypeDevice
2280 },
2281 {
2282 STRING_TOKEN (STR_PCIEX_LINK_CAPABILITIES),
2283 0x0c,
2284 FieldWidthUINT32,
2285 ExplainPcieLinkCap,
2286 PcieExplainTypeLink
2287 },
2288 {
2289 STRING_TOKEN (STR_PCIEX_LINK_CONTROL),
2290 0x10,
2291 FieldWidthUINT16,
2292 ExplainPcieLinkControl,
2293 PcieExplainTypeLink
2294 },
2295 {
2296 STRING_TOKEN (STR_PCIEX_LINK_STATUS),
2297 0x12,
2298 FieldWidthUINT16,
2299 ExplainPcieLinkStatus,
2300 PcieExplainTypeLink
2301 },
2302 {
2303 STRING_TOKEN (STR_PCIEX_SLOT_CAPABILITIES),
2304 0x14,
2305 FieldWidthUINT32,
2306 ExplainPcieSlotCap,
2307 PcieExplainTypeSlot
2308 },
2309 {
2310 STRING_TOKEN (STR_PCIEX_SLOT_CONTROL),
2311 0x18,
2312 FieldWidthUINT16,
2313 ExplainPcieSlotControl,
2314 PcieExplainTypeSlot
2315 },
2316 {
2317 STRING_TOKEN (STR_PCIEX_SLOT_STATUS),
2318 0x1a,
2319 FieldWidthUINT16,
2320 ExplainPcieSlotStatus,
2321 PcieExplainTypeSlot
2322 },
2323 {
2324 STRING_TOKEN (STR_PCIEX_ROOT_CONTROL),
2325 0x1c,
2326 FieldWidthUINT16,
2327 ExplainPcieRootControl,
2328 PcieExplainTypeRoot
2329 },
2330 {
2331 STRING_TOKEN (STR_PCIEX_RSVDP),
2332 0x1e,
2333 FieldWidthUINT16,
2334 ExplainPcieRootCap,
2335 PcieExplainTypeRoot
2336 },
2337 {
2338 STRING_TOKEN (STR_PCIEX_ROOT_STATUS),
2339 0x20,
2340 FieldWidthUINT32,
2341 ExplainPcieRootStatus,
2342 PcieExplainTypeRoot
2343 },
2344 {
2345 0,
2346 0,
2347 (PCIE_CAPREG_FIELD_WIDTH)0,
2348 NULL,
2349 PcieExplainTypeMax
2350 }
2351 };
2352
2353 //
2354 // Global Variables
2355 //
2356 PCI_CONFIG_SPACE *mConfigSpace = NULL;
2357 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
2358 {L"-s", TypeValue},
2359 {L"-i", TypeFlag},
2360 {L"-ec", TypeValue},
2361 {NULL, TypeMax}
2362 };
2363
2364 CHAR16 *DevicePortTypeTable[] = {
2365 L"PCI Express Endpoint",
2366 L"Legacy PCI Express Endpoint",
2367 L"Unknown Type",
2368 L"Unknonw Type",
2369 L"Root Port of PCI Express Root Complex",
2370 L"Upstream Port of PCI Express Switch",
2371 L"Downstream Port of PCI Express Switch",
2372 L"PCI Express to PCI/PCI-X Bridge",
2373 L"PCI/PCI-X to PCI Express Bridge",
2374 L"Root Complex Integrated Endpoint",
2375 L"Root Complex Event Collector"
2376 };
2377
2378 CHAR16 *L0sLatencyStrTable[] = {
2379 L"Less than 64ns",
2380 L"64ns to less than 128ns",
2381 L"128ns to less than 256ns",
2382 L"256ns to less than 512ns",
2383 L"512ns to less than 1us",
2384 L"1us to less than 2us",
2385 L"2us-4us",
2386 L"More than 4us"
2387 };
2388
2389 CHAR16 *L1LatencyStrTable[] = {
2390 L"Less than 1us",
2391 L"1us to less than 2us",
2392 L"2us to less than 4us",
2393 L"4us to less than 8us",
2394 L"8us to less than 16us",
2395 L"16us to less than 32us",
2396 L"32us-64us",
2397 L"More than 64us"
2398 };
2399
2400 CHAR16 *ASPMCtrlStrTable[] = {
2401 L"Disabled",
2402 L"L0s Entry Enabled",
2403 L"L1 Entry Enabled",
2404 L"L0s and L1 Entry Enabled"
2405 };
2406
2407 CHAR16 *SlotPwrLmtScaleTable[] = {
2408 L"1.0x",
2409 L"0.1x",
2410 L"0.01x",
2411 L"0.001x"
2412 };
2413
2414 CHAR16 *IndicatorTable[] = {
2415 L"Reserved",
2416 L"On",
2417 L"Blink",
2418 L"Off"
2419 };
2420
2421
2422 /**
2423 Function for 'pci' command.
2424
2425 @param[in] ImageHandle Handle to the Image (NULL if Internal).
2426 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
2427 **/
2428 SHELL_STATUS
2429 EFIAPI
2430 ShellCommandRunPci (
2431 IN EFI_HANDLE ImageHandle,
2432 IN EFI_SYSTEM_TABLE *SystemTable
2433 )
2434 {
2435 UINT16 Segment;
2436 UINT16 Bus;
2437 UINT16 Device;
2438 UINT16 Func;
2439 UINT64 Address;
2440 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev;
2441 EFI_STATUS Status;
2442 PCI_DEVICE_INDEPENDENT_REGION PciHeader;
2443 PCI_CONFIG_SPACE ConfigSpace;
2444 UINTN ScreenCount;
2445 UINTN TempColumn;
2446 UINTN ScreenSize;
2447 BOOLEAN ExplainData;
2448 UINTN Index;
2449 UINTN SizeOfHeader;
2450 BOOLEAN PrintTitle;
2451 UINTN HandleBufSize;
2452 EFI_HANDLE *HandleBuf;
2453 UINTN HandleCount;
2454 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
2455 UINT16 MinBus;
2456 UINT16 MaxBus;
2457 BOOLEAN IsEnd;
2458 LIST_ENTRY *Package;
2459 CHAR16 *ProblemParam;
2460 SHELL_STATUS ShellStatus;
2461 CONST CHAR16 *Temp;
2462 UINT64 RetVal;
2463 UINT16 ExtendedCapability;
2464 UINT8 PcieCapabilityPtr;
2465 UINT8 *ExtendedConfigSpace;
2466 UINTN ExtendedConfigSize;
2467
2468 ShellStatus = SHELL_SUCCESS;
2469 Status = EFI_SUCCESS;
2470 Address = 0;
2471 IoDev = NULL;
2472 HandleBuf = NULL;
2473 Package = NULL;
2474
2475 //
2476 // initialize the shell lib (we must be in non-auto-init...)
2477 //
2478 Status = ShellInitialize();
2479 ASSERT_EFI_ERROR(Status);
2480
2481 Status = CommandInit();
2482 ASSERT_EFI_ERROR(Status);
2483
2484 //
2485 // parse the command line
2486 //
2487 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
2488 if (EFI_ERROR(Status)) {
2489 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
2490 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"pci", ProblemParam);
2491 FreePool(ProblemParam);
2492 ShellStatus = SHELL_INVALID_PARAMETER;
2493 } else {
2494 ASSERT(FALSE);
2495 }
2496 } else {
2497
2498 if (ShellCommandLineGetCount(Package) == 2) {
2499 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"pci");
2500 ShellStatus = SHELL_INVALID_PARAMETER;
2501 goto Done;
2502 }
2503
2504 if (ShellCommandLineGetCount(Package) > 4) {
2505 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"pci");
2506 ShellStatus = SHELL_INVALID_PARAMETER;
2507 goto Done;
2508 }
2509 if (ShellCommandLineGetFlag(Package, L"-ec") && ShellCommandLineGetValue(Package, L"-ec") == NULL) {
2510 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"pci", L"-ec");
2511 ShellStatus = SHELL_INVALID_PARAMETER;
2512 goto Done;
2513 }
2514 if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetValue(Package, L"-s") == NULL) {
2515 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"pci", L"-s");
2516 ShellStatus = SHELL_INVALID_PARAMETER;
2517 goto Done;
2518 }
2519 //
2520 // Get all instances of PciRootBridgeIo. Allocate space for 1 EFI_HANDLE and
2521 // call LibLocateHandle(), if EFI_BUFFER_TOO_SMALL is returned, allocate enough
2522 // space for handles and call it again.
2523 //
2524 HandleBufSize = sizeof (EFI_HANDLE);
2525 HandleBuf = (EFI_HANDLE *) AllocateZeroPool (HandleBufSize);
2526 if (HandleBuf == NULL) {
2527 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"pci");
2528 ShellStatus = SHELL_OUT_OF_RESOURCES;
2529 goto Done;
2530 }
2531
2532 Status = gBS->LocateHandle (
2533 ByProtocol,
2534 &gEfiPciRootBridgeIoProtocolGuid,
2535 NULL,
2536 &HandleBufSize,
2537 HandleBuf
2538 );
2539
2540 if (Status == EFI_BUFFER_TOO_SMALL) {
2541 HandleBuf = ReallocatePool (sizeof (EFI_HANDLE), HandleBufSize, HandleBuf);
2542 if (HandleBuf == NULL) {
2543 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"pci");
2544 ShellStatus = SHELL_OUT_OF_RESOURCES;
2545 goto Done;
2546 }
2547
2548 Status = gBS->LocateHandle (
2549 ByProtocol,
2550 &gEfiPciRootBridgeIoProtocolGuid,
2551 NULL,
2552 &HandleBufSize,
2553 HandleBuf
2554 );
2555 }
2556
2557 if (EFI_ERROR (Status)) {
2558 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle, L"pci");
2559 ShellStatus = SHELL_NOT_FOUND;
2560 goto Done;
2561 }
2562
2563 HandleCount = HandleBufSize / sizeof (EFI_HANDLE);
2564 //
2565 // Argument Count == 1(no other argument): enumerate all pci functions
2566 //
2567 if (ShellCommandLineGetCount(Package) == 1) {
2568 gST->ConOut->QueryMode (
2569 gST->ConOut,
2570 gST->ConOut->Mode->Mode,
2571 &TempColumn,
2572 &ScreenSize
2573 );
2574
2575 ScreenCount = 0;
2576 ScreenSize -= 4;
2577 if ((ScreenSize & 1) == 1) {
2578 ScreenSize -= 1;
2579 }
2580
2581 PrintTitle = TRUE;
2582
2583 //
2584 // For each handle, which decides a segment and a bus number range,
2585 // enumerate all devices on it.
2586 //
2587 for (Index = 0; Index < HandleCount; Index++) {
2588 Status = PciGetProtocolAndResource (
2589 HandleBuf[Index],
2590 &IoDev,
2591 &Descriptors
2592 );
2593 if (EFI_ERROR (Status)) {
2594 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_HANDLE_CFG_ERR), gShellDebug1HiiHandle, L"pci");
2595 ShellStatus = SHELL_NOT_FOUND;
2596 goto Done;
2597 }
2598 //
2599 // No document say it's impossible for a RootBridgeIo protocol handle
2600 // to have more than one address space descriptors, so find out every
2601 // bus range and for each of them do device enumeration.
2602 //
2603 while (TRUE) {
2604 Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
2605
2606 if (EFI_ERROR (Status)) {
2607 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_BUS_RANGE_ERR), gShellDebug1HiiHandle, L"pci");
2608 ShellStatus = SHELL_NOT_FOUND;
2609 goto Done;
2610 }
2611
2612 if (IsEnd) {
2613 break;
2614 }
2615
2616 for (Bus = MinBus; Bus <= MaxBus; Bus++) {
2617 //
2618 // For each devices, enumerate all functions it contains
2619 //
2620 for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
2621 //
2622 // For each function, read its configuration space and print summary
2623 //
2624 for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
2625 if (ShellGetExecutionBreakFlag ()) {
2626 ShellStatus = SHELL_ABORTED;
2627 goto Done;
2628 }
2629 Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
2630 IoDev->Pci.Read (
2631 IoDev,
2632 EfiPciWidthUint16,
2633 Address,
2634 1,
2635 &PciHeader.VendorId
2636 );
2637
2638 //
2639 // If VendorId = 0xffff, there does not exist a device at this
2640 // location. For each device, if there is any function on it,
2641 // there must be 1 function at Function 0. So if Func = 0, there
2642 // will be no more functions in the same device, so we can break
2643 // loop to deal with the next device.
2644 //
2645 if (PciHeader.VendorId == 0xffff && Func == 0) {
2646 break;
2647 }
2648
2649 if (PciHeader.VendorId != 0xffff) {
2650
2651 if (PrintTitle) {
2652 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_TITLE), gShellDebug1HiiHandle);
2653 PrintTitle = FALSE;
2654 }
2655
2656 IoDev->Pci.Read (
2657 IoDev,
2658 EfiPciWidthUint32,
2659 Address,
2660 sizeof (PciHeader) / sizeof (UINT32),
2661 &PciHeader
2662 );
2663
2664 ShellPrintHiiEx(
2665 -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P1), gShellDebug1HiiHandle,
2666 IoDev->SegmentNumber,
2667 Bus,
2668 Device,
2669 Func
2670 );
2671
2672 PciPrintClassCode (PciHeader.ClassCode, FALSE);
2673 ShellPrintHiiEx(
2674 -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P2), gShellDebug1HiiHandle,
2675 PciHeader.VendorId,
2676 PciHeader.DeviceId,
2677 PciHeader.ClassCode[0]
2678 );
2679
2680 ScreenCount += 2;
2681 if (ScreenCount >= ScreenSize && ScreenSize != 0) {
2682 //
2683 // If ScreenSize == 0 we have the console redirected so don't
2684 // block updates
2685 //
2686 ScreenCount = 0;
2687 }
2688 //
2689 // If this is not a multi-function device, we can leave the loop
2690 // to deal with the next device.
2691 //
2692 if (Func == 0 && ((PciHeader.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00)) {
2693 break;
2694 }
2695 }
2696 }
2697 }
2698 }
2699 //
2700 // If Descriptor is NULL, Configuration() returns EFI_UNSUPPRORED,
2701 // we assume the bus range is 0~PCI_MAX_BUS. After enumerated all
2702 // devices on all bus, we can leave loop.
2703 //
2704 if (Descriptors == NULL) {
2705 break;
2706 }
2707 }
2708 }
2709
2710 Status = EFI_SUCCESS;
2711 goto Done;
2712 }
2713
2714 ExplainData = FALSE;
2715 Segment = 0;
2716 Bus = 0;
2717 Device = 0;
2718 Func = 0;
2719 ExtendedCapability = 0xFFFF;
2720 if (ShellCommandLineGetFlag(Package, L"-i")) {
2721 ExplainData = TRUE;
2722 }
2723
2724 Temp = ShellCommandLineGetValue(Package, L"-s");
2725 if (Temp != NULL) {
2726 //
2727 // Input converted to hexadecimal number.
2728 //
2729 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2730 Segment = (UINT16) RetVal;
2731 } else {
2732 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp);
2733 ShellStatus = SHELL_INVALID_PARAMETER;
2734 goto Done;
2735 }
2736 }
2737
2738 //
2739 // The first Argument(except "-i") is assumed to be Bus number, second
2740 // to be Device number, and third to be Func number.
2741 //
2742 Temp = ShellCommandLineGetRawValue(Package, 1);
2743 if (Temp != NULL) {
2744 //
2745 // Input converted to hexadecimal number.
2746 //
2747 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2748 Bus = (UINT16) RetVal;
2749 } else {
2750 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp);
2751 ShellStatus = SHELL_INVALID_PARAMETER;
2752 goto Done;
2753 }
2754
2755 if (Bus > PCI_MAX_BUS) {
2756 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp);
2757 ShellStatus = SHELL_INVALID_PARAMETER;
2758 goto Done;
2759 }
2760 }
2761 Temp = ShellCommandLineGetRawValue(Package, 2);
2762 if (Temp != NULL) {
2763 //
2764 // Input converted to hexadecimal number.
2765 //
2766 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2767 Device = (UINT16) RetVal;
2768 } else {
2769 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp);
2770 ShellStatus = SHELL_INVALID_PARAMETER;
2771 goto Done;
2772 }
2773
2774 if (Device > PCI_MAX_DEVICE){
2775 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp);
2776 ShellStatus = SHELL_INVALID_PARAMETER;
2777 goto Done;
2778 }
2779 }
2780
2781 Temp = ShellCommandLineGetRawValue(Package, 3);
2782 if (Temp != NULL) {
2783 //
2784 // Input converted to hexadecimal number.
2785 //
2786 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2787 Func = (UINT16) RetVal;
2788 } else {
2789 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp);
2790 ShellStatus = SHELL_INVALID_PARAMETER;
2791 goto Done;
2792 }
2793
2794 if (Func > PCI_MAX_FUNC){
2795 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp);
2796 ShellStatus = SHELL_INVALID_PARAMETER;
2797 goto Done;
2798 }
2799 }
2800
2801 Temp = ShellCommandLineGetValue (Package, L"-ec");
2802 if (Temp != NULL) {
2803 //
2804 // Input converted to hexadecimal number.
2805 //
2806 if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
2807 ExtendedCapability = (UINT16) RetVal;
2808 } else {
2809 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp);
2810 ShellStatus = SHELL_INVALID_PARAMETER;
2811 goto Done;
2812 }
2813 }
2814
2815 //
2816 // Find the protocol interface who's in charge of current segment, and its
2817 // bus range covers the current bus
2818 //
2819 Status = PciFindProtocolInterface (
2820 HandleBuf,
2821 HandleCount,
2822 Segment,
2823 Bus,
2824 &IoDev
2825 );
2826
2827 if (EFI_ERROR (Status)) {
2828 ShellPrintHiiEx(
2829 -1, -1, NULL, STRING_TOKEN (STR_PCI_NO_FIND), gShellDebug1HiiHandle, L"pci",
2830 Segment,
2831 Bus
2832 );
2833 ShellStatus = SHELL_NOT_FOUND;
2834 goto Done;
2835 }
2836
2837 Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
2838 Status = IoDev->Pci.Read (
2839 IoDev,
2840 EfiPciWidthUint8,
2841 Address,
2842 sizeof (ConfigSpace),
2843 &ConfigSpace
2844 );
2845
2846 if (EFI_ERROR (Status)) {
2847 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_NO_CFG), gShellDebug1HiiHandle, L"pci");
2848 ShellStatus = SHELL_ACCESS_DENIED;
2849 goto Done;
2850 }
2851
2852 mConfigSpace = &ConfigSpace;
2853 ShellPrintHiiEx(
2854 -1,
2855 -1,
2856 NULL,
2857 STRING_TOKEN (STR_PCI_INFO),
2858 gShellDebug1HiiHandle,
2859 Segment,
2860 Bus,
2861 Device,
2862 Func,
2863 Segment,
2864 Bus,
2865 Device,
2866 Func
2867 );
2868
2869 //
2870 // Dump standard header of configuration space
2871 //
2872 SizeOfHeader = sizeof (ConfigSpace.Common) + sizeof (ConfigSpace.NonCommon);
2873
2874 DumpHex (2, 0, SizeOfHeader, &ConfigSpace);
2875 ShellPrintEx(-1,-1, L"\r\n");
2876
2877 //
2878 // Dump device dependent Part of configuration space
2879 //
2880 DumpHex (
2881 2,
2882 SizeOfHeader,
2883 sizeof (ConfigSpace) - SizeOfHeader,
2884 ConfigSpace.Data
2885 );
2886
2887 ExtendedConfigSpace = NULL;
2888 ExtendedConfigSize = 0;
2889 PcieCapabilityPtr = LocatePciCapability (&ConfigSpace, EFI_PCI_CAPABILITY_ID_PCIEXP);
2890 if (PcieCapabilityPtr != 0) {
2891 ExtendedConfigSize = 0x1000 - EFI_PCIE_CAPABILITY_BASE_OFFSET;
2892 ExtendedConfigSpace = AllocatePool (ExtendedConfigSize);
2893 if (ExtendedConfigSpace != NULL) {
2894 Status = IoDev->Pci.Read (
2895 IoDev,
2896 EfiPciWidthUint32,
2897 EFI_PCI_ADDRESS (Bus, Device, Func, EFI_PCIE_CAPABILITY_BASE_OFFSET),
2898 ExtendedConfigSize / sizeof (UINT32),
2899 ExtendedConfigSpace
2900 );
2901 if (EFI_ERROR (Status)) {
2902 SHELL_FREE_NON_NULL (ExtendedConfigSpace);
2903 }
2904 }
2905 }
2906
2907 if ((ExtendedConfigSpace != NULL) && !ShellGetExecutionBreakFlag ()) {
2908 //
2909 // Print the PciEx extend space in raw bytes ( 0xFF-0xFFF)
2910 //
2911 ShellPrintEx (-1, -1, L"\r\n%HStart dumping PCIex extended configuration space (0x100 - 0xFFF).%N\r\n\r\n");
2912
2913 DumpHex (
2914 2,
2915 EFI_PCIE_CAPABILITY_BASE_OFFSET,
2916 ExtendedConfigSize,
2917 ExtendedConfigSpace
2918 );
2919 }
2920
2921 //
2922 // If "-i" appears in command line, interpret data in configuration space
2923 //
2924 if (ExplainData) {
2925 PciExplainPci (&ConfigSpace, Address, IoDev);
2926 if ((ExtendedConfigSpace != NULL) && !ShellGetExecutionBreakFlag ()) {
2927 PciExplainPciExpress (
2928 (PCI_CAPABILITY_PCIEXP *) ((UINT8 *) &ConfigSpace + PcieCapabilityPtr),
2929 ExtendedConfigSpace,
2930 ExtendedCapability
2931 );
2932 }
2933 }
2934 }
2935 Done:
2936 if (HandleBuf != NULL) {
2937 FreePool (HandleBuf);
2938 }
2939 if (Package != NULL) {
2940 ShellCommandLineFreeVarList (Package);
2941 }
2942 mConfigSpace = NULL;
2943 return ShellStatus;
2944 }
2945
2946 /**
2947 This function finds out the protocol which is in charge of the given
2948 segment, and its bus range covers the current bus number. It lookes
2949 each instances of RootBridgeIoProtocol handle, until the one meets the
2950 criteria is found.
2951
2952 @param[in] HandleBuf Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
2953 @param[in] HandleCount Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
2954 @param[in] Segment Segment number of device we are dealing with.
2955 @param[in] Bus Bus number of device we are dealing with.
2956 @param[out] IoDev Handle used to access configuration space of PCI device.
2957
2958 @retval EFI_SUCCESS The command completed successfully.
2959 @retval EFI_INVALID_PARAMETER Invalid parameter.
2960
2961 **/
2962 EFI_STATUS
2963 PciFindProtocolInterface (
2964 IN EFI_HANDLE *HandleBuf,
2965 IN UINTN HandleCount,
2966 IN UINT16 Segment,
2967 IN UINT16 Bus,
2968 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev
2969 )
2970 {
2971 UINTN Index;
2972 EFI_STATUS Status;
2973 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
2974 UINT16 MinBus;
2975 UINT16 MaxBus;
2976 BOOLEAN IsEnd;
2977
2978 //
2979 // Go through all handles, until the one meets the criteria is found
2980 //
2981 for (Index = 0; Index < HandleCount; Index++) {
2982 Status = PciGetProtocolAndResource (HandleBuf[Index], IoDev, &Descriptors);
2983 if (EFI_ERROR (Status)) {
2984 return Status;
2985 }
2986 //
2987 // When Descriptors == NULL, the Configuration() is not implemented,
2988 // so we only check the Segment number
2989 //
2990 if (Descriptors == NULL && Segment == (*IoDev)->SegmentNumber) {
2991 return EFI_SUCCESS;
2992 }
2993
2994 if ((*IoDev)->SegmentNumber != Segment) {
2995 continue;
2996 }
2997
2998 while (TRUE) {
2999 Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
3000 if (EFI_ERROR (Status)) {
3001 return Status;
3002 }
3003
3004 if (IsEnd) {
3005 break;
3006 }
3007
3008 if (MinBus <= Bus && MaxBus >= Bus) {
3009 return EFI_SUCCESS;
3010 }
3011 }
3012 }
3013
3014 return EFI_NOT_FOUND;
3015 }
3016
3017 /**
3018 This function gets the protocol interface from the given handle, and
3019 obtains its address space descriptors.
3020
3021 @param[in] Handle The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle.
3022 @param[out] IoDev Handle used to access configuration space of PCI device.
3023 @param[out] Descriptors Points to the address space descriptors.
3024
3025 @retval EFI_SUCCESS The command completed successfully
3026 **/
3027 EFI_STATUS
3028 PciGetProtocolAndResource (
3029 IN EFI_HANDLE Handle,
3030 OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev,
3031 OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors
3032 )
3033 {
3034 EFI_STATUS Status;
3035
3036 //
3037 // Get inferface from protocol
3038 //
3039 Status = gBS->HandleProtocol (
3040 Handle,
3041 &gEfiPciRootBridgeIoProtocolGuid,
3042 (VOID**)IoDev
3043 );
3044
3045 if (EFI_ERROR (Status)) {
3046 return Status;
3047 }
3048 //
3049 // Call Configuration() to get address space descriptors
3050 //
3051 Status = (*IoDev)->Configuration (*IoDev, (VOID**)Descriptors);
3052 if (Status == EFI_UNSUPPORTED) {
3053 *Descriptors = NULL;
3054 return EFI_SUCCESS;
3055
3056 } else {
3057 return Status;
3058 }
3059 }
3060
3061 /**
3062 This function get the next bus range of given address space descriptors.
3063 It also moves the pointer backward a node, to get prepared to be called
3064 again.
3065
3066 @param[in, out] Descriptors Points to current position of a serial of address space
3067 descriptors.
3068 @param[out] MinBus The lower range of bus number.
3069 @param[out] MaxBus The upper range of bus number.
3070 @param[out] IsEnd Meet end of the serial of descriptors.
3071
3072 @retval EFI_SUCCESS The command completed successfully.
3073 **/
3074 EFI_STATUS
3075 PciGetNextBusRange (
3076 IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,
3077 OUT UINT16 *MinBus,
3078 OUT UINT16 *MaxBus,
3079 OUT BOOLEAN *IsEnd
3080 )
3081 {
3082 *IsEnd = FALSE;
3083
3084 //
3085 // When *Descriptors is NULL, Configuration() is not implemented, so assume
3086 // range is 0~PCI_MAX_BUS
3087 //
3088 if ((*Descriptors) == NULL) {
3089 *MinBus = 0;
3090 *MaxBus = PCI_MAX_BUS;
3091 return EFI_SUCCESS;
3092 }
3093 //
3094 // *Descriptors points to one or more address space descriptors, which
3095 // ends with a end tagged descriptor. Examine each of the descriptors,
3096 // if a bus typed one is found and its bus range covers bus, this handle
3097 // is the handle we are looking for.
3098 //
3099
3100 while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {
3101 if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
3102 *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;
3103 *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;
3104 (*Descriptors)++;
3105 return (EFI_SUCCESS);
3106 }
3107
3108 (*Descriptors)++;
3109 }
3110
3111 if ((*Descriptors)->Desc == ACPI_END_TAG_DESCRIPTOR) {
3112 *IsEnd = TRUE;
3113 }
3114
3115 return EFI_SUCCESS;
3116 }
3117
3118 /**
3119 Explain the data in PCI configuration space. The part which is common for
3120 PCI device and bridge is interpreted in this function. It calls other
3121 functions to interpret data unique for device or bridge.
3122
3123 @param[in] ConfigSpace Data in PCI configuration space.
3124 @param[in] Address Address used to access configuration space of this PCI device.
3125 @param[in] IoDev Handle used to access configuration space of PCI device.
3126 **/
3127 VOID
3128 PciExplainPci (
3129 IN PCI_CONFIG_SPACE *ConfigSpace,
3130 IN UINT64 Address,
3131 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
3132 )
3133 {
3134 PCI_DEVICE_INDEPENDENT_REGION *Common;
3135 PCI_HEADER_TYPE HeaderType;
3136
3137 Common = &(ConfigSpace->Common);
3138
3139 ShellPrintEx (-1, -1, L"\r\n");
3140
3141 //
3142 // Print Vendor Id and Device Id
3143 //
3144 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_VID_DID), gShellDebug1HiiHandle,
3145 INDEX_OF (&(Common->VendorId)),
3146 Common->VendorId,
3147 INDEX_OF (&(Common->DeviceId)),
3148 Common->DeviceId
3149 );
3150
3151 //
3152 // Print register Command
3153 //
3154 PciExplainCommand (&(Common->Command));
3155
3156 //
3157 // Print register Status
3158 //
3159 PciExplainStatus (&(Common->Status), TRUE, PciUndefined);
3160
3161 //
3162 // Print register Revision ID
3163 //
3164 ShellPrintEx(-1, -1, L"\r\n");
3165 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_RID), gShellDebug1HiiHandle,
3166 INDEX_OF (&(Common->RevisionID)),
3167 Common->RevisionID
3168 );
3169
3170 //
3171 // Print register BIST
3172 //
3173 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_BIST), gShellDebug1HiiHandle, INDEX_OF (&(Common->BIST)));
3174 if ((Common->BIST & BIT7) != 0) {
3175 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP), gShellDebug1HiiHandle, 0x0f & Common->BIST);
3176 } else {
3177 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP_NO), gShellDebug1HiiHandle);
3178 }
3179 //
3180 // Print register Cache Line Size
3181 //
3182 ShellPrintHiiEx(-1, -1, NULL,
3183 STRING_TOKEN (STR_PCI2_CACHE_LINE_SIZE),
3184 gShellDebug1HiiHandle,
3185 INDEX_OF (&(Common->CacheLineSize)),
3186 Common->CacheLineSize
3187 );
3188
3189 //
3190 // Print register Latency Timer
3191 //
3192 ShellPrintHiiEx(-1, -1, NULL,
3193 STRING_TOKEN (STR_PCI2_LATENCY_TIMER),
3194 gShellDebug1HiiHandle,
3195 INDEX_OF (&(Common->LatencyTimer)),
3196 Common->LatencyTimer
3197 );
3198
3199 //
3200 // Print register Header Type
3201 //
3202 ShellPrintHiiEx(-1, -1, NULL,
3203 STRING_TOKEN (STR_PCI2_HEADER_TYPE),
3204 gShellDebug1HiiHandle,
3205 INDEX_OF (&(Common->HeaderType)),
3206 Common->HeaderType
3207 );
3208
3209 if ((Common->HeaderType & BIT7) != 0) {
3210 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MULTI_FUNCTION), gShellDebug1HiiHandle);
3211
3212 } else {
3213 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SINGLE_FUNCTION), gShellDebug1HiiHandle);
3214 }
3215
3216 HeaderType = (PCI_HEADER_TYPE)(UINT8) (Common->HeaderType & 0x7f);
3217 switch (HeaderType) {
3218 case PciDevice:
3219 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_PCI_DEVICE), gShellDebug1HiiHandle);
3220 break;
3221
3222 case PciP2pBridge:
3223 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_P2P_BRIDGE), gShellDebug1HiiHandle);
3224 break;
3225
3226 case PciCardBusBridge:
3227 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_BRIDGE), gShellDebug1HiiHandle);
3228 break;
3229
3230 default:
3231 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED), gShellDebug1HiiHandle);
3232 HeaderType = PciUndefined;
3233 }
3234
3235 //
3236 // Print register Class Code
3237 //
3238 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CLASS), gShellDebug1HiiHandle);
3239 PciPrintClassCode ((UINT8 *) Common->ClassCode, TRUE);
3240 ShellPrintEx (-1, -1, L"\r\n");
3241 }
3242
3243 /**
3244 Explain the device specific part of data in PCI configuration space.
3245
3246 @param[in] Device Data in PCI configuration space.
3247 @param[in] Address Address used to access configuration space of this PCI device.
3248 @param[in] IoDev Handle used to access configuration space of PCI device.
3249
3250 @retval EFI_SUCCESS The command completed successfully.
3251 **/
3252 EFI_STATUS
3253 PciExplainDeviceData (
3254 IN PCI_DEVICE_HEADER_TYPE_REGION *Device,
3255 IN UINT64 Address,
3256 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
3257 )
3258 {
3259 UINTN Index;
3260 BOOLEAN BarExist;
3261 EFI_STATUS Status;
3262 UINTN BarCount;
3263
3264 //
3265 // Print Base Address Registers(Bar). When Bar = 0, this Bar does not
3266 // exist. If these no Bar for this function, print "none", otherwise
3267 // list detail information about this Bar.
3268 //
3269 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDR), gShellDebug1HiiHandle, INDEX_OF (Device->Bar));
3270
3271 BarExist = FALSE;
3272 BarCount = sizeof (Device->Bar) / sizeof (Device->Bar[0]);
3273 for (Index = 0; Index < BarCount; Index++) {
3274 if (Device->Bar[Index] == 0) {
3275 continue;
3276 }
3277
3278 if (!BarExist) {
3279 BarExist = TRUE;
3280 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE), gShellDebug1HiiHandle);
3281 ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------");
3282 }
3283
3284 Status = PciExplainBar (
3285 &(Device->Bar[Index]),
3286 &(mConfigSpace->Common.Command),
3287 Address,
3288 IoDev,
3289 &Index
3290 );
3291
3292 if (EFI_ERROR (Status)) {
3293 break;
3294 }
3295 }
3296
3297 if (!BarExist) {
3298 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
3299
3300 } else {
3301 ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------");
3302 }
3303
3304 //
3305 // Print register Expansion ROM Base Address
3306 //
3307 if ((Device->ExpansionRomBar & BIT0) == 0) {
3308 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_EXPANSION_ROM_DISABLED), gShellDebug1HiiHandle, INDEX_OF (&(Device->ExpansionRomBar)));
3309
3310 } else {
3311 ShellPrintHiiEx(-1, -1, NULL,
3312 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE),
3313 gShellDebug1HiiHandle,
3314 INDEX_OF (&(Device->ExpansionRomBar)),
3315 Device->ExpansionRomBar
3316 );
3317 }
3318 //
3319 // Print register Cardbus CIS ptr
3320 //
3321 ShellPrintHiiEx(-1, -1, NULL,
3322 STRING_TOKEN (STR_PCI2_CARDBUS_CIS),
3323 gShellDebug1HiiHandle,
3324 INDEX_OF (&(Device->CISPtr)),
3325 Device->CISPtr
3326 );
3327
3328 //
3329 // Print register Sub-vendor ID and subsystem ID
3330 //
3331 ShellPrintHiiEx(-1, -1, NULL,
3332 STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID),
3333 gShellDebug1HiiHandle,
3334 INDEX_OF (&(Device->SubsystemVendorID)),
3335 Device->SubsystemVendorID
3336 );
3337
3338 ShellPrintHiiEx(-1, -1, NULL,
3339 STRING_TOKEN (STR_PCI2_SUBSYSTEM_ID),
3340 gShellDebug1HiiHandle,
3341 INDEX_OF (&(Device->SubsystemID)),
3342 Device->SubsystemID
3343 );
3344
3345 //
3346 // Print register Capabilities Ptr
3347 //
3348 ShellPrintHiiEx(-1, -1, NULL,
3349 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR),
3350 gShellDebug1HiiHandle,
3351 INDEX_OF (&(Device->CapabilityPtr)),
3352 Device->CapabilityPtr
3353 );
3354
3355 //
3356 // Print register Interrupt Line and interrupt pin
3357 //
3358 ShellPrintHiiEx(-1, -1, NULL,
3359 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE),
3360 gShellDebug1HiiHandle,
3361 INDEX_OF (&(Device->InterruptLine)),
3362 Device->InterruptLine
3363 );
3364
3365 ShellPrintHiiEx(-1, -1, NULL,
3366 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
3367 gShellDebug1HiiHandle,
3368 INDEX_OF (&(Device->InterruptPin)),
3369 Device->InterruptPin
3370 );
3371
3372 //
3373 // Print register Min_Gnt and Max_Lat
3374 //
3375 ShellPrintHiiEx(-1, -1, NULL,
3376 STRING_TOKEN (STR_PCI2_MIN_GNT),
3377 gShellDebug1HiiHandle,
3378 INDEX_OF (&(Device->MinGnt)),
3379 Device->MinGnt
3380 );
3381
3382 ShellPrintHiiEx(-1, -1, NULL,
3383 STRING_TOKEN (STR_PCI2_MAX_LAT),
3384 gShellDebug1HiiHandle,
3385 INDEX_OF (&(Device->MaxLat)),
3386 Device->MaxLat
3387 );
3388
3389 return EFI_SUCCESS;
3390 }
3391
3392 /**
3393 Explain the bridge specific part of data in PCI configuration space.
3394
3395 @param[in] Bridge Bridge specific data region in PCI configuration space.
3396 @param[in] Address Address used to access configuration space of this PCI device.
3397 @param[in] IoDev Handle used to access configuration space of PCI device.
3398
3399 @retval EFI_SUCCESS The command completed successfully.
3400 **/
3401 EFI_STATUS
3402 PciExplainBridgeData (
3403 IN PCI_BRIDGE_CONTROL_REGISTER *Bridge,
3404 IN UINT64 Address,
3405 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
3406 )
3407 {
3408 UINTN Index;
3409 BOOLEAN BarExist;
3410 UINTN BarCount;
3411 UINT32 IoAddress32;
3412 EFI_STATUS Status;
3413
3414 //
3415 // Print Base Address Registers. When Bar = 0, this Bar does not
3416 // exist. If these no Bar for this function, print "none", otherwise
3417 // list detail information about this Bar.
3418 //
3419 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDRESS), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->Bar)));
3420
3421 BarExist = FALSE;
3422 BarCount = sizeof (Bridge->Bar) / sizeof (Bridge->Bar[0]);
3423
3424 for (Index = 0; Index < BarCount; Index++) {
3425 if (Bridge->Bar[Index] == 0) {
3426 continue;
3427 }
3428
3429 if (!BarExist) {
3430 BarExist = TRUE;
3431 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE_2), gShellDebug1HiiHandle);
3432 ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------");
3433 }
3434
3435 Status = PciExplainBar (
3436 &(Bridge->Bar[Index]),
3437 &(mConfigSpace->Common.Command),
3438 Address,
3439 IoDev,
3440 &Index
3441 );
3442
3443 if (EFI_ERROR (Status)) {
3444 break;
3445 }
3446 }
3447
3448 if (!BarExist) {
3449 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
3450 } else {
3451 ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------");
3452 }
3453
3454 //
3455 // Expansion register ROM Base Address
3456 //
3457 if ((Bridge->ExpansionRomBAR & BIT0) == 0) {
3458 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO_EXPANSION_ROM), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->ExpansionRomBAR)));
3459
3460 } else {
3461 ShellPrintHiiEx(-1, -1, NULL,
3462 STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE_2),
3463 gShellDebug1HiiHandle,
3464 INDEX_OF (&(Bridge->ExpansionRomBAR)),
3465 Bridge->ExpansionRomBAR
3466 );
3467 }
3468 //
3469 // Print Bus Numbers(Primary, Secondary, and Subordinate
3470 //
3471 ShellPrintHiiEx(-1, -1, NULL,
3472 STRING_TOKEN (STR_PCI2_BUS_NUMBERS),
3473 gShellDebug1HiiHandle,
3474 INDEX_OF (&(Bridge->PrimaryBus)),
3475 INDEX_OF (&(Bridge->SecondaryBus)),
3476 INDEX_OF (&(Bridge->SubordinateBus))
3477 );
3478
3479 ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n");
3480
3481 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->PrimaryBus);
3482 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SecondaryBus);
3483 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SubordinateBus);
3484
3485 //
3486 // Print register Secondary Latency Timer
3487 //
3488 ShellPrintHiiEx(-1, -1, NULL,
3489 STRING_TOKEN (STR_PCI2_SECONDARY_TIMER),
3490 gShellDebug1HiiHandle,
3491 INDEX_OF (&(Bridge->SecondaryLatencyTimer)),
3492 Bridge->SecondaryLatencyTimer
3493 );
3494
3495 //
3496 // Print register Secondary Status
3497 //
3498 PciExplainStatus (&(Bridge->SecondaryStatus), FALSE, PciP2pBridge);
3499
3500 //
3501 // Print I/O and memory ranges this bridge forwards. There are 3 resource
3502 // types: I/O, memory, and pre-fetchable memory. For each resource type,
3503 // base and limit address are listed.
3504 //
3505 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE), gShellDebug1HiiHandle);
3506 ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n");
3507
3508 //
3509 // IO Base & Limit
3510 //
3511 IoAddress32 = (Bridge->IoBaseUpper16 << 16 | Bridge->IoBase << 8);
3512 IoAddress32 &= 0xfffff000;
3513 ShellPrintHiiEx(-1, -1, NULL,
3514 STRING_TOKEN (STR_PCI2_TWO_VARS),
3515 gShellDebug1HiiHandle,
3516 INDEX_OF (&(Bridge->IoBase)),
3517 IoAddress32
3518 );
3519
3520 IoAddress32 = (Bridge->IoLimitUpper16 << 16 | Bridge->IoLimit << 8);
3521 IoAddress32 |= 0x00000fff;
3522 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR), gShellDebug1HiiHandle, IoAddress32);
3523
3524 //
3525 // Memory Base & Limit
3526 //
3527 ShellPrintHiiEx(-1, -1, NULL,
3528 STRING_TOKEN (STR_PCI2_MEMORY),
3529 gShellDebug1HiiHandle,
3530 INDEX_OF (&(Bridge->MemoryBase)),
3531 (Bridge->MemoryBase << 16) & 0xfff00000
3532 );
3533
3534 ShellPrintHiiEx(-1, -1, NULL,
3535 STRING_TOKEN (STR_PCI2_ONE_VAR),
3536 gShellDebug1HiiHandle,
3537 (Bridge->MemoryLimit << 16) | 0x000fffff
3538 );
3539
3540 //
3541 // Pre-fetch-able Memory Base & Limit
3542 //
3543 ShellPrintHiiEx(-1, -1, NULL,
3544 STRING_TOKEN (STR_PCI2_PREFETCHABLE),
3545 gShellDebug1HiiHandle,
3546 INDEX_OF (&(Bridge->PrefetchableMemoryBase)),
3547 Bridge->PrefetchableBaseUpper32,
3548 (Bridge->PrefetchableMemoryBase << 16) & 0xfff00000
3549 );
3550
3551 ShellPrintHiiEx(-1, -1, NULL,
3552 STRING_TOKEN (STR_PCI2_TWO_VARS_2),
3553 gShellDebug1HiiHandle,
3554 Bridge->PrefetchableLimitUpper32,
3555 (Bridge->PrefetchableMemoryLimit << 16) | 0x000fffff
3556 );
3557
3558 //
3559 // Print register Capabilities Pointer
3560 //
3561 ShellPrintHiiEx(-1, -1, NULL,
3562 STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR_2),
3563 gShellDebug1HiiHandle,
3564 INDEX_OF (&(Bridge->CapabilityPtr)),
3565 Bridge->CapabilityPtr
3566 );
3567
3568 //
3569 // Print register Bridge Control
3570 //
3571 PciExplainBridgeControl (&(Bridge->BridgeControl), PciP2pBridge);
3572
3573 //
3574 // Print register Interrupt Line & PIN
3575 //
3576 ShellPrintHiiEx(-1, -1, NULL,
3577 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_2),
3578 gShellDebug1HiiHandle,
3579 INDEX_OF (&(Bridge->InterruptLine)),
3580 Bridge->InterruptLine
3581 );
3582
3583 ShellPrintHiiEx(-1, -1, NULL,
3584 STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
3585 gShellDebug1HiiHandle,
3586 INDEX_OF (&(Bridge->InterruptPin)),
3587 Bridge->InterruptPin
3588 );
3589
3590 return EFI_SUCCESS;
3591 }
3592
3593 /**
3594 Explain the Base Address Register(Bar) in PCI configuration space.
3595
3596 @param[in] Bar Points to the Base Address Register intended to interpret.
3597 @param[in] Command Points to the register Command.
3598 @param[in] Address Address used to access configuration space of this PCI device.
3599 @param[in] IoDev Handle used to access configuration space of PCI device.
3600 @param[in, out] Index The Index.
3601
3602 @retval EFI_SUCCESS The command completed successfully.
3603 **/
3604 EFI_STATUS
3605 PciExplainBar (
3606 IN UINT32 *Bar,
3607 IN UINT16 *Command,
3608 IN UINT64 Address,
3609 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
3610 IN OUT UINTN *Index
3611 )
3612 {
3613 UINT16 OldCommand;
3614 UINT16 NewCommand;
3615 UINT64 Bar64;
3616 UINT32 OldBar32;
3617 UINT32 NewBar32;
3618 UINT64 OldBar64;
3619 UINT64 NewBar64;
3620 BOOLEAN IsMem;
3621 BOOLEAN IsBar32;
3622 UINT64 RegAddress;
3623
3624 IsBar32 = TRUE;
3625 Bar64 = 0;
3626 NewBar32 = 0;
3627 NewBar64 = 0;
3628
3629 //
3630 // According the bar type, list detail about this bar, for example: 32 or
3631 // 64 bits; pre-fetchable or not.
3632 //
3633 if ((*Bar & BIT0) == 0) {
3634 //
3635 // This bar is of memory type
3636 //
3637 IsMem = TRUE;
3638
3639 if ((*Bar & BIT1) == 0 && (*Bar & BIT2) == 0) {
3640 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
3641 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
3642 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_32_BITS), gShellDebug1HiiHandle);
3643
3644 } else if ((*Bar & BIT1) == 0 && (*Bar & BIT2) != 0) {
3645 Bar64 = 0x0;
3646 CopyMem (&Bar64, Bar, sizeof (UINT64));
3647 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_2), gShellDebug1HiiHandle, (UINT32) RShiftU64 ((Bar64 & 0xfffffffffffffff0ULL), 32));
3648 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_3), gShellDebug1HiiHandle, (UINT32) (Bar64 & 0xfffffffffffffff0ULL));
3649 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
3650 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_64_BITS), gShellDebug1HiiHandle);
3651 IsBar32 = FALSE;
3652 *Index += 1;
3653
3654 } else {
3655 //
3656 // Reserved
3657 //
3658 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
3659 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM_2), gShellDebug1HiiHandle);
3660 }
3661
3662 if ((*Bar & BIT3) == 0) {
3663 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO), gShellDebug1HiiHandle);
3664
3665 } else {
3666 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_YES), gShellDebug1HiiHandle);
3667 }
3668
3669 } else {
3670 //
3671 // This bar is of io type
3672 //
3673 IsMem = FALSE;
3674 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_4), gShellDebug1HiiHandle, *Bar & 0xfffffffc);
3675 ShellPrintEx (-1, -1, L"I/O ");
3676 }
3677
3678 //
3679 // Get BAR length(or the amount of resource this bar demands for). To get
3680 // Bar length, first we should temporarily disable I/O and memory access
3681 // of this function(by set bits in the register Command), then write all
3682 // "1"s to this bar. The bar value read back is the amount of resource
3683 // this bar demands for.
3684 //
3685 //
3686 // Disable io & mem access
3687 //
3688 OldCommand = *Command;
3689 NewCommand = (UINT16) (OldCommand & 0xfffc);
3690 RegAddress = Address | INDEX_OF (Command);
3691 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &NewCommand);
3692
3693 RegAddress = Address | INDEX_OF (Bar);
3694
3695 //
3696 // Read after write the BAR to get the size
3697 //
3698 if (IsBar32) {
3699 OldBar32 = *Bar;
3700 NewBar32 = 0xffffffff;
3701
3702 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
3703 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
3704 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &OldBar32);
3705
3706 if (IsMem) {
3707 NewBar32 = NewBar32 & 0xfffffff0;
3708 NewBar32 = (~NewBar32) + 1;
3709
3710 } else {
3711 NewBar32 = NewBar32 & 0xfffffffc;
3712 NewBar32 = (~NewBar32) + 1;
3713 NewBar32 = NewBar32 & 0x0000ffff;
3714 }
3715 } else {
3716
3717 OldBar64 = 0x0;
3718 CopyMem (&OldBar64, Bar, sizeof (UINT64));
3719 NewBar64 = 0xffffffffffffffffULL;
3720
3721 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
3722 IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
3723 IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &OldBar64);
3724
3725 if (IsMem) {
3726 NewBar64 = NewBar64 & 0xfffffffffffffff0ULL;
3727 NewBar64 = (~NewBar64) + 1;
3728
3729 } else {
3730 NewBar64 = NewBar64 & 0xfffffffffffffffcULL;
3731 NewBar64 = (~NewBar64) + 1;
3732 NewBar64 = NewBar64 & 0x000000000000ffff;
3733 }
3734 }
3735 //
3736 // Enable io & mem access
3737 //
3738 RegAddress = Address | INDEX_OF (Command);
3739 IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &OldCommand);
3740
3741 if (IsMem) {
3742 if (IsBar32) {
3743 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32), gShellDebug1HiiHandle, NewBar32);
3744 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_2), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffff0) - 1);
3745
3746 } else {
3747 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) RShiftU64 (NewBar64, 32));
3748 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) NewBar64);
3749 ShellPrintEx (-1, -1, L" ");
3750 ShellPrintHiiEx(-1, -1, NULL,
3751 STRING_TOKEN (STR_PCI2_RSHIFT),
3752 gShellDebug1HiiHandle,
3753 (UINT32) RShiftU64 ((NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1), 32)
3754 );
3755 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) (NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1));
3756
3757 }
3758 } else {
3759 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_3), gShellDebug1HiiHandle, NewBar32);
3760 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_4), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffffc) - 1);
3761 }
3762
3763 return EFI_SUCCESS;
3764 }
3765
3766 /**
3767 Explain the cardbus specific part of data in PCI configuration space.
3768
3769 @param[in] CardBus CardBus specific region of PCI configuration space.
3770 @param[in] Address Address used to access configuration space of this PCI device.
3771 @param[in] IoDev Handle used to access configuration space of PCI device.
3772
3773 @retval EFI_SUCCESS The command completed successfully.
3774 **/
3775 EFI_STATUS
3776 PciExplainCardBusData (
3777 IN PCI_CARDBUS_CONTROL_REGISTER *CardBus,
3778 IN UINT64 Address,
3779 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
3780 )
3781 {
3782 BOOLEAN Io32Bit;
3783 PCI_CARDBUS_DATA *CardBusData;
3784
3785 ShellPrintHiiEx(-1, -1, NULL,
3786 STRING_TOKEN (STR_PCI2_CARDBUS_SOCKET),
3787 gShellDebug1HiiHandle,
3788 INDEX_OF (&(CardBus->CardBusSocketReg)),
3789 CardBus->CardBusSocketReg
3790 );
3791
3792 //
3793 // Print Secondary Status
3794 //
3795 PciExplainStatus (&(CardBus->SecondaryStatus), FALSE, PciCardBusBridge);
3796
3797 //
3798 // Print Bus Numbers(Primary bus number, CardBus bus number, and
3799 // Subordinate bus number
3800 //
3801 ShellPrintHiiEx(-1, -1, NULL,
3802 STRING_TOKEN (STR_PCI2_BUS_NUMBERS_2),
3803 gShellDebug1HiiHandle,
3804 INDEX_OF (&(CardBus->PciBusNumber)),
3805 INDEX_OF (&(CardBus->CardBusBusNumber)),
3806 INDEX_OF (&(CardBus->SubordinateBusNumber))
3807 );
3808
3809 ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n");
3810
3811 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS), gShellDebug1HiiHandle, CardBus->PciBusNumber);
3812 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_2), gShellDebug1HiiHandle, CardBus->CardBusBusNumber);
3813 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_3), gShellDebug1HiiHandle, CardBus->SubordinateBusNumber);
3814
3815 //
3816 // Print CardBus Latency Timer
3817 //
3818 ShellPrintHiiEx(-1, -1, NULL,
3819 STRING_TOKEN (STR_PCI2_CARDBUS_LATENCY),
3820 gShellDebug1HiiHandle,
3821 INDEX_OF (&(CardBus->CardBusLatencyTimer)),
3822 CardBus->CardBusLatencyTimer
3823 );
3824
3825 //
3826 // Print Memory/Io ranges this cardbus bridge forwards
3827 //
3828 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE_2), gShellDebug1HiiHandle);
3829 ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n");
3830
3831 ShellPrintHiiEx(-1, -1, NULL,
3832 STRING_TOKEN (STR_PCI2_MEM_3),
3833 gShellDebug1HiiHandle,
3834 INDEX_OF (&(CardBus->MemoryBase0)),
3835 CardBus->BridgeControl & BIT8 ? L" Prefetchable" : L"Non-Prefetchable",
3836 CardBus->MemoryBase0 & 0xfffff000,
3837 CardBus->MemoryLimit0 | 0x00000fff
3838 );
3839
3840 ShellPrintHiiEx(-1, -1, NULL,
3841 STRING_TOKEN (STR_PCI2_MEM_3),
3842 gShellDebug1HiiHandle,
3843 INDEX_OF (&(CardBus->MemoryBase1)),
3844 CardBus->BridgeControl & BIT9 ? L" Prefetchable" : L"Non-Prefetchable",
3845 CardBus->MemoryBase1 & 0xfffff000,
3846 CardBus->MemoryLimit1 | 0x00000fff
3847 );
3848
3849 Io32Bit = (BOOLEAN) (CardBus->IoBase0 & BIT0);
3850 ShellPrintHiiEx(-1, -1, NULL,
3851 STRING_TOKEN (STR_PCI2_IO_2),
3852 gShellDebug1HiiHandle,
3853 INDEX_OF (&(CardBus->IoBase0)),
3854 Io32Bit ? L" 32 bit" : L" 16 bit",
3855 CardBus->IoBase0 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
3856 (CardBus->IoLimit0 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003
3857 );
3858
3859 Io32Bit = (BOOLEAN) (CardBus->IoBase1 & BIT0);
3860 ShellPrintHiiEx(-1, -1, NULL,
3861 STRING_TOKEN (STR_PCI2_IO_2),
3862 gShellDebug1HiiHandle,
3863 INDEX_OF (&(CardBus->IoBase1)),
3864 Io32Bit ? L" 32 bit" : L" 16 bit",
3865 CardBus->IoBase1 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
3866 (CardBus->IoLimit1 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003
3867 );
3868
3869 //
3870 // Print register Interrupt Line & PIN
3871 //
3872 ShellPrintHiiEx(-1, -1, NULL,
3873 STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_3),
3874 gShellDebug1HiiHandle,
3875 INDEX_OF (&(CardBus->InterruptLine)),
3876 CardBus->InterruptLine,
3877 INDEX_OF (&(CardBus->InterruptPin)),
3878 CardBus->InterruptPin
3879 );
3880
3881 //
3882 // Print register Bridge Control
3883 //
3884 PciExplainBridgeControl (&(CardBus->BridgeControl), PciCardBusBridge);
3885
3886 //
3887 // Print some registers in data region of PCI configuration space for cardbus
3888 // bridge. Fields include: Sub VendorId, Subsystem ID, and Legacy Mode Base
3889 // Address.
3890 //
3891 CardBusData = (PCI_CARDBUS_DATA *) ((UINT8 *) CardBus + sizeof (PCI_CARDBUS_CONTROL_REGISTER));
3892
3893 ShellPrintHiiEx(-1, -1, NULL,
3894 STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID_2),
3895 gShellDebug1HiiHandle,
3896 INDEX_OF (&(CardBusData->SubVendorId)),
3897 CardBusData->SubVendorId,
3898 INDEX_OF (&(CardBusData->SubSystemId)),
3899 CardBusData->SubSystemId
3900 );
3901
3902 ShellPrintHiiEx(-1, -1, NULL,
3903 STRING_TOKEN (STR_PCI2_OPTIONAL),
3904 gShellDebug1HiiHandle,
3905 INDEX_OF (&(CardBusData->LegacyBase)),
3906 CardBusData->LegacyBase
3907 );
3908
3909 return EFI_SUCCESS;
3910 }
3911
3912 /**
3913 Explain each meaningful bit of register Status. The definition of Status is
3914 slightly different depending on the PCI header type.
3915
3916 @param[in] Status Points to the content of register Status.
3917 @param[in] MainStatus Indicates if this register is main status(not secondary
3918 status).
3919 @param[in] HeaderType Header type of this PCI device.
3920
3921 @retval EFI_SUCCESS The command completed successfully.
3922 **/
3923 EFI_STATUS
3924 PciExplainStatus (
3925 IN UINT16 *Status,
3926 IN BOOLEAN MainStatus,
3927 IN PCI_HEADER_TYPE HeaderType
3928 )
3929 {
3930 if (MainStatus) {
3931 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status);
3932
3933 } else {
3934 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SECONDARY_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status);
3935 }
3936
3937 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEW_CAPABILITIES), gShellDebug1HiiHandle, (*Status & BIT4) != 0);
3938
3939 //
3940 // Bit 5 is meaningless for CardBus Bridge
3941 //
3942 if (HeaderType == PciCardBusBridge) {
3943 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE), gShellDebug1HiiHandle, (*Status & BIT5) != 0);
3944
3945 } else {
3946 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE_2), gShellDebug1HiiHandle, (*Status & BIT5) != 0);
3947 }
3948
3949 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST_BACK), gShellDebug1HiiHandle, (*Status & BIT7) != 0);
3950
3951 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MASTER_DATA), gShellDebug1HiiHandle, (*Status & BIT8) != 0);
3952 //
3953 // Bit 9 and bit 10 together decides the DEVSEL timing
3954 //
3955 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_DEVSEL_TIMING), gShellDebug1HiiHandle);
3956 if ((*Status & BIT9) == 0 && (*Status & BIT10) == 0) {
3957 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST), gShellDebug1HiiHandle);
3958
3959 } else if ((*Status & BIT9) != 0 && (*Status & BIT10) == 0) {
3960 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEDIUM), gShellDebug1HiiHandle);
3961
3962 } else if ((*Status & BIT9) == 0 && (*Status & BIT10) != 0) {
3963 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SLOW), gShellDebug1HiiHandle);
3964
3965 } else {
3966 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED_2), gShellDebug1HiiHandle);
3967 }
3968
3969 ShellPrintHiiEx(-1, -1, NULL,
3970 STRING_TOKEN (STR_PCI2_SIGNALED_TARGET),
3971 gShellDebug1HiiHandle,
3972 (*Status & BIT11) != 0
3973 );
3974
3975 ShellPrintHiiEx(-1, -1, NULL,
3976 STRING_TOKEN (STR_PCI2_RECEIVED_TARGET),
3977 gShellDebug1HiiHandle,
3978 (*Status & BIT12) != 0
3979 );
3980
3981 ShellPrintHiiEx(-1, -1, NULL,
3982 STRING_TOKEN (STR_PCI2_RECEIVED_MASTER),
3983 gShellDebug1HiiHandle,
3984 (*Status & BIT13) != 0
3985 );
3986
3987 if (MainStatus) {
3988 ShellPrintHiiEx(-1, -1, NULL,
3989 STRING_TOKEN (STR_PCI2_SIGNALED_ERROR),
3990 gShellDebug1HiiHandle,
3991 (*Status & BIT14) != 0
3992 );
3993
3994 } else {
3995 ShellPrintHiiEx(-1, -1, NULL,
3996 STRING_TOKEN (STR_PCI2_RECEIVED_ERROR),
3997 gShellDebug1HiiHandle,
3998 (*Status & BIT14) != 0
3999 );
4000 }
4001
4002 ShellPrintHiiEx(-1, -1, NULL,
4003 STRING_TOKEN (STR_PCI2_DETECTED_ERROR),
4004 gShellDebug1HiiHandle,
4005 (*Status & BIT15) != 0
4006 );
4007
4008 return EFI_SUCCESS;
4009 }
4010
4011 /**
4012 Explain each meaningful bit of register Command.
4013
4014 @param[in] Command Points to the content of register Command.
4015
4016 @retval EFI_SUCCESS The command completed successfully.
4017 **/
4018 EFI_STATUS
4019 PciExplainCommand (
4020 IN UINT16 *Command
4021 )
4022 {
4023 //
4024 // Print the binary value of register Command
4025 //
4026 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_COMMAND), gShellDebug1HiiHandle, INDEX_OF (Command), *Command);
4027
4028 //
4029 // Explain register Command bit by bit
4030 //
4031 ShellPrintHiiEx(-1, -1, NULL,
4032 STRING_TOKEN (STR_PCI2_SPACE_ACCESS_DENIED),
4033 gShellDebug1HiiHandle,
4034 (*Command & BIT0) != 0
4035 );
4036
4037 ShellPrintHiiEx(-1, -1, NULL,
4038 STRING_TOKEN (STR_PCI2_MEMORY_SPACE),
4039 gShellDebug1HiiHandle,
4040 (*Command & BIT1) != 0
4041 );
4042
4043 ShellPrintHiiEx(-1, -1, NULL,
4044 STRING_TOKEN (STR_PCI2_BEHAVE_BUS_MASTER),
4045 gShellDebug1HiiHandle,
4046 (*Command & BIT2) != 0
4047 );
4048
4049 ShellPrintHiiEx(-1, -1, NULL,
4050 STRING_TOKEN (STR_PCI2_MONITOR_SPECIAL_CYCLE),
4051 gShellDebug1HiiHandle,
4052 (*Command & BIT3) != 0
4053 );
4054
4055 ShellPrintHiiEx(-1, -1, NULL,
4056 STRING_TOKEN (STR_PCI2_MEM_WRITE_INVALIDATE),
4057 gShellDebug1HiiHandle,
4058 (*Command & BIT4) != 0
4059 );
4060
4061 ShellPrintHiiEx(-1, -1, NULL,
4062 STRING_TOKEN (STR_PCI2_PALETTE_SNOOPING),
4063 gShellDebug1HiiHandle,
4064 (*Command & BIT5) != 0
4065 );
4066
4067 ShellPrintHiiEx(-1, -1, NULL,
4068 STRING_TOKEN (STR_PCI2_ASSERT_PERR),
4069 gShellDebug1HiiHandle,
4070 (*Command & BIT6) != 0
4071 );
4072
4073 ShellPrintHiiEx(-1, -1, NULL,
4074 STRING_TOKEN (STR_PCI2_DO_ADDR_STEPPING),
4075 gShellDebug1HiiHandle,
4076 (*Command & BIT7) != 0
4077 );
4078
4079 ShellPrintHiiEx(-1, -1, NULL,
4080 STRING_TOKEN (STR_PCI2_SERR_DRIVER),
4081 gShellDebug1HiiHandle,
4082 (*Command & BIT8) != 0
4083 );
4084
4085 ShellPrintHiiEx(-1, -1, NULL,
4086 STRING_TOKEN (STR_PCI2_FAST_BACK_2),
4087 gShellDebug1HiiHandle,
4088 (*Command & BIT9) != 0
4089 );
4090
4091 return EFI_SUCCESS;
4092 }
4093
4094 /**
4095 Explain each meaningful bit of register Bridge Control.
4096
4097 @param[in] BridgeControl Points to the content of register Bridge Control.
4098 @param[in] HeaderType The headertype.
4099
4100 @retval EFI_SUCCESS The command completed successfully.
4101 **/
4102 EFI_STATUS
4103 PciExplainBridgeControl (
4104 IN UINT16 *BridgeControl,
4105 IN PCI_HEADER_TYPE HeaderType
4106 )
4107 {
4108 ShellPrintHiiEx(-1, -1, NULL,
4109 STRING_TOKEN (STR_PCI2_BRIDGE_CONTROL),
4110 gShellDebug1HiiHandle,
4111 INDEX_OF (BridgeControl),
4112 *BridgeControl
4113 );
4114
4115 ShellPrintHiiEx(-1, -1, NULL,
4116 STRING_TOKEN (STR_PCI2_PARITY_ERROR),
4117 gShellDebug1HiiHandle,
4118 (*BridgeControl & BIT0) != 0
4119 );
4120 ShellPrintHiiEx(-1, -1, NULL,
4121 STRING_TOKEN (STR_PCI2_SERR_ENABLE),
4122 gShellDebug1HiiHandle,
4123 (*BridgeControl & BIT1) != 0
4124 );
4125 ShellPrintHiiEx(-1, -1, NULL,
4126 STRING_TOKEN (STR_PCI2_ISA_ENABLE),
4127 gShellDebug1HiiHandle,
4128 (*BridgeControl & BIT2) != 0
4129 );
4130 ShellPrintHiiEx(-1, -1, NULL,
4131 STRING_TOKEN (STR_PCI2_VGA_ENABLE),
4132 gShellDebug1HiiHandle,
4133 (*BridgeControl & BIT3) != 0
4134 );
4135 ShellPrintHiiEx(-1, -1, NULL,
4136 STRING_TOKEN (STR_PCI2_MASTER_ABORT),
4137 gShellDebug1HiiHandle,
4138 (*BridgeControl & BIT5) != 0
4139 );
4140
4141 //
4142 // Register Bridge Control has some slight differences between P2P bridge
4143 // and Cardbus bridge from bit 6 to bit 11.
4144 //
4145 if (HeaderType == PciP2pBridge) {
4146 ShellPrintHiiEx(-1, -1, NULL,
4147 STRING_TOKEN (STR_PCI2_SECONDARY_BUS_RESET),
4148 gShellDebug1HiiHandle,
4149 (*BridgeControl & BIT6) != 0
4150 );
4151 ShellPrintHiiEx(-1, -1, NULL,
4152 STRING_TOKEN (STR_PCI2_FAST_ENABLE),
4153 gShellDebug1HiiHandle,
4154 (*BridgeControl & BIT7) != 0
4155 );
4156 ShellPrintHiiEx(-1, -1, NULL,
4157 STRING_TOKEN (STR_PCI2_PRIMARY_DISCARD_TIMER),
4158 gShellDebug1HiiHandle,
4159 (*BridgeControl & BIT8)!=0 ? L"2^10" : L"2^15"
4160 );
4161 ShellPrintHiiEx(-1, -1, NULL,
4162 STRING_TOKEN (STR_PCI2_SECONDARY_DISCARD_TIMER),
4163 gShellDebug1HiiHandle,
4164 (*BridgeControl & BIT9)!=0 ? L"2^10" : L"2^15"
4165 );
4166 ShellPrintHiiEx(-1, -1, NULL,
4167 STRING_TOKEN (STR_PCI2_DISCARD_TIMER_STATUS),
4168 gShellDebug1HiiHandle,
4169 (*BridgeControl & BIT10) != 0
4170 );
4171 ShellPrintHiiEx(-1, -1, NULL,
4172 STRING_TOKEN (STR_PCI2_DISCARD_TIMER_SERR),
4173 gShellDebug1HiiHandle,
4174 (*BridgeControl & BIT11) != 0
4175 );
4176
4177 } else {
4178 ShellPrintHiiEx(-1, -1, NULL,
4179 STRING_TOKEN (STR_PCI2_CARDBUS_RESET),
4180 gShellDebug1HiiHandle,
4181 (*BridgeControl & BIT6) != 0
4182 );
4183 ShellPrintHiiEx(-1, -1, NULL,
4184 STRING_TOKEN (STR_PCI2_IREQ_ENABLE),
4185 gShellDebug1HiiHandle,
4186 (*BridgeControl & BIT7) != 0
4187 );
4188 ShellPrintHiiEx(-1, -1, NULL,
4189 STRING_TOKEN (STR_PCI2_WRITE_POSTING_ENABLE),
4190 gShellDebug1HiiHandle,
4191 (*BridgeControl & BIT10) != 0
4192 );
4193 }
4194
4195 return EFI_SUCCESS;
4196 }
4197
4198 /**
4199 Locate capability register block per capability ID.
4200
4201 @param[in] ConfigSpace Data in PCI configuration space.
4202 @param[in] CapabilityId The capability ID.
4203
4204 @return The offset of the register block per capability ID,
4205 or 0 if the register block cannot be found.
4206 **/
4207 UINT8
4208 LocatePciCapability (
4209 IN PCI_CONFIG_SPACE *ConfigSpace,
4210 IN UINT8 CapabilityId
4211 )
4212 {
4213 UINT8 CapabilityPtr;
4214 EFI_PCI_CAPABILITY_HDR *CapabilityEntry;
4215
4216 //
4217 // To check the cpability of this device supports
4218 //
4219 if ((ConfigSpace->Common.Status & EFI_PCI_STATUS_CAPABILITY) == 0) {
4220 return 0;
4221 }
4222
4223 switch ((PCI_HEADER_TYPE)(ConfigSpace->Common.HeaderType & 0x7f)) {
4224 case PciDevice:
4225 CapabilityPtr = ConfigSpace->NonCommon.Device.CapabilityPtr;
4226 break;
4227 case PciP2pBridge:
4228 CapabilityPtr = ConfigSpace->NonCommon.Bridge.CapabilityPtr;
4229 break;
4230 case PciCardBusBridge:
4231 CapabilityPtr = ConfigSpace->NonCommon.CardBus.Cap_Ptr;
4232 break;
4233 default:
4234 return 0;
4235 }
4236
4237 while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) {
4238 CapabilityEntry = (EFI_PCI_CAPABILITY_HDR *) ((UINT8 *) ConfigSpace + CapabilityPtr);
4239 if (CapabilityEntry->CapabilityID == CapabilityId) {
4240 return CapabilityPtr;
4241 }
4242
4243 //
4244 // Certain PCI device may incorrectly have capability pointing to itself,
4245 // break to avoid dead loop.
4246 //
4247 if (CapabilityPtr == CapabilityEntry->NextItemPtr) {
4248 break;
4249 }
4250
4251 CapabilityPtr = CapabilityEntry->NextItemPtr;
4252 }
4253
4254 return 0;
4255 }
4256
4257 /**
4258 Print out information of the capability information.
4259
4260 @param[in] PciExpressCap The pointer to the structure about the device.
4261
4262 @retval EFI_SUCCESS The operation was successful.
4263 **/
4264 EFI_STATUS
4265 ExplainPcieCapReg (
4266 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4267 )
4268 {
4269 CHAR16 *DevicePortType;
4270
4271 ShellPrintEx (-1, -1,
4272 L" Capability Version(3:0): %E0x%04x%N\r\n",
4273 PciExpressCap->Capability.Bits.Version
4274 );
4275 if (PciExpressCap->Capability.Bits.DevicePortType < ARRAY_SIZE (DevicePortTypeTable)) {
4276 DevicePortType = DevicePortTypeTable[PciExpressCap->Capability.Bits.DevicePortType];
4277 } else {
4278 DevicePortType = L"Unknown Type";
4279 }
4280 ShellPrintEx (-1, -1,
4281 L" Device/PortType(7:4): %E%s%N\r\n",
4282 DevicePortType
4283 );
4284 //
4285 // 'Slot Implemented' is only valid for:
4286 // a) Root Port of PCI Express Root Complex, or
4287 // b) Downstream Port of PCI Express Switch
4288 //
4289 if (PciExpressCap->Capability.Bits.DevicePortType== PCIE_DEVICE_PORT_TYPE_ROOT_PORT ||
4290 PciExpressCap->Capability.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT) {
4291 ShellPrintEx (-1, -1,
4292 L" Slot Implemented(8): %E%d%N\r\n",
4293 PciExpressCap->Capability.Bits.SlotImplemented
4294 );
4295 }
4296 ShellPrintEx (-1, -1,
4297 L" Interrupt Message Number(13:9): %E0x%05x%N\r\n",
4298 PciExpressCap->Capability.Bits.InterruptMessageNumber
4299 );
4300 return EFI_SUCCESS;
4301 }
4302
4303 /**
4304 Print out information of the device capability information.
4305
4306 @param[in] PciExpressCap The pointer to the structure about the device.
4307
4308 @retval EFI_SUCCESS The operation was successful.
4309 **/
4310 EFI_STATUS
4311 ExplainPcieDeviceCap (
4312 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4313 )
4314 {
4315 UINT8 DevicePortType;
4316 UINT8 L0sLatency;
4317 UINT8 L1Latency;
4318
4319 DevicePortType = (UINT8)PciExpressCap->Capability.Bits.DevicePortType;
4320 ShellPrintEx (-1, -1, L" Max_Payload_Size Supported(2:0): ");
4321 if (PciExpressCap->DeviceCapability.Bits.MaxPayloadSize < 6) {
4322 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PciExpressCap->DeviceCapability.Bits.MaxPayloadSize + 7));
4323 } else {
4324 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
4325 }
4326 ShellPrintEx (-1, -1,
4327 L" Phantom Functions Supported(4:3): %E%d%N\r\n",
4328 PciExpressCap->DeviceCapability.Bits.PhantomFunctions
4329 );
4330 ShellPrintEx (-1, -1,
4331 L" Extended Tag Field Supported(5): %E%d-bit Tag field supported%N\r\n",
4332 PciExpressCap->DeviceCapability.Bits.ExtendedTagField ? 8 : 5
4333 );
4334 //
4335 // Endpoint L0s and L1 Acceptable Latency is only valid for Endpoint
4336 //
4337 if (IS_PCIE_ENDPOINT (DevicePortType)) {
4338 L0sLatency = (UINT8)PciExpressCap->DeviceCapability.Bits.EndpointL0sAcceptableLatency;
4339 L1Latency = (UINT8)PciExpressCap->DeviceCapability.Bits.EndpointL1AcceptableLatency;
4340 ShellPrintEx (-1, -1, L" Endpoint L0s Acceptable Latency(8:6): ");
4341 if (L0sLatency < 4) {
4342 ShellPrintEx (-1, -1, L"%EMaximum of %d ns%N\r\n", 1 << (L0sLatency + 6));
4343 } else {
4344 if (L0sLatency < 7) {
4345 ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L0sLatency - 3));
4346 } else {
4347 ShellPrintEx (-1, -1, L"%ENo limit%N\r\n");
4348 }
4349 }
4350 ShellPrintEx (-1, -1, L" Endpoint L1 Acceptable Latency(11:9): ");
4351 if (L1Latency < 7) {
4352 ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L1Latency + 1));
4353 } else {
4354 ShellPrintEx (-1, -1, L"%ENo limit%N\r\n");
4355 }
4356 }
4357 ShellPrintEx (-1, -1,
4358 L" Role-based Error Reporting(15): %E%d%N\r\n",
4359 PciExpressCap->DeviceCapability.Bits.RoleBasedErrorReporting
4360 );
4361 //
4362 // Only valid for Upstream Port:
4363 // a) Captured Slot Power Limit Value
4364 // b) Captured Slot Power Scale
4365 //
4366 if (DevicePortType == PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT) {
4367 ShellPrintEx (-1, -1,
4368 L" Captured Slot Power Limit Value(25:18): %E0x%02x%N\r\n",
4369 PciExpressCap->DeviceCapability.Bits.CapturedSlotPowerLimitValue
4370 );
4371 ShellPrintEx (-1, -1,
4372 L" Captured Slot Power Limit Scale(27:26): %E%s%N\r\n",
4373 SlotPwrLmtScaleTable[PciExpressCap->DeviceCapability.Bits.CapturedSlotPowerLimitScale]
4374 );
4375 }
4376 //
4377 // Function Level Reset Capability is only valid for Endpoint
4378 //
4379 if (IS_PCIE_ENDPOINT (DevicePortType)) {
4380 ShellPrintEx (-1, -1,
4381 L" Function Level Reset Capability(28): %E%d%N\r\n",
4382 PciExpressCap->DeviceCapability.Bits.FunctionLevelReset
4383 );
4384 }
4385 return EFI_SUCCESS;
4386 }
4387
4388 /**
4389 Print out information of the device control information.
4390
4391 @param[in] PciExpressCap The pointer to the structure about the device.
4392
4393 @retval EFI_SUCCESS The operation was successful.
4394 **/
4395 EFI_STATUS
4396 ExplainPcieDeviceControl (
4397 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4398 )
4399 {
4400 ShellPrintEx (-1, -1,
4401 L" Correctable Error Reporting Enable(0): %E%d%N\r\n",
4402 PciExpressCap->DeviceControl.Bits.CorrectableError
4403 );
4404 ShellPrintEx (-1, -1,
4405 L" Non-Fatal Error Reporting Enable(1): %E%d%N\r\n",
4406 PciExpressCap->DeviceControl.Bits.NonFatalError
4407 );
4408 ShellPrintEx (-1, -1,
4409 L" Fatal Error Reporting Enable(2): %E%d%N\r\n",
4410 PciExpressCap->DeviceControl.Bits.FatalError
4411 );
4412 ShellPrintEx (-1, -1,
4413 L" Unsupported Request Reporting Enable(3): %E%d%N\r\n",
4414 PciExpressCap->DeviceControl.Bits.UnsupportedRequest
4415 );
4416 ShellPrintEx (-1, -1,
4417 L" Enable Relaxed Ordering(4): %E%d%N\r\n",
4418 PciExpressCap->DeviceControl.Bits.RelaxedOrdering
4419 );
4420 ShellPrintEx (-1, -1, L" Max_Payload_Size(7:5): ");
4421 if (PciExpressCap->DeviceControl.Bits.MaxPayloadSize < 6) {
4422 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PciExpressCap->DeviceControl.Bits.MaxPayloadSize + 7));
4423 } else {
4424 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
4425 }
4426 ShellPrintEx (-1, -1,
4427 L" Extended Tag Field Enable(8): %E%d%N\r\n",
4428 PciExpressCap->DeviceControl.Bits.ExtendedTagField
4429 );
4430 ShellPrintEx (-1, -1,
4431 L" Phantom Functions Enable(9): %E%d%N\r\n",
4432 PciExpressCap->DeviceControl.Bits.PhantomFunctions
4433 );
4434 ShellPrintEx (-1, -1,
4435 L" Auxiliary (AUX) Power PM Enable(10): %E%d%N\r\n",
4436 PciExpressCap->DeviceControl.Bits.AuxPower
4437 );
4438 ShellPrintEx (-1, -1,
4439 L" Enable No Snoop(11): %E%d%N\r\n",
4440 PciExpressCap->DeviceControl.Bits.NoSnoop
4441 );
4442 ShellPrintEx (-1, -1, L" Max_Read_Request_Size(14:12): ");
4443 if (PciExpressCap->DeviceControl.Bits.MaxReadRequestSize < 6) {
4444 ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PciExpressCap->DeviceControl.Bits.MaxReadRequestSize + 7));
4445 } else {
4446 ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
4447 }
4448 //
4449 // Read operation is only valid for PCI Express to PCI/PCI-X Bridges
4450 //
4451 if (PciExpressCap->Capability.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_PCIE_TO_PCI_BRIDGE) {
4452 ShellPrintEx (-1, -1,
4453 L" Bridge Configuration Retry Enable(15): %E%d%N\r\n",
4454 PciExpressCap->DeviceControl.Bits.BridgeConfigurationRetryOrFunctionLevelReset
4455 );
4456 }
4457 return EFI_SUCCESS;
4458 }
4459
4460 /**
4461 Print out information of the device status information.
4462
4463 @param[in] PciExpressCap The pointer to the structure about the device.
4464
4465 @retval EFI_SUCCESS The operation was successful.
4466 **/
4467 EFI_STATUS
4468 ExplainPcieDeviceStatus (
4469 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4470 )
4471 {
4472 ShellPrintEx (-1, -1,
4473 L" Correctable Error Detected(0): %E%d%N\r\n",
4474 PciExpressCap->DeviceStatus.Bits.CorrectableError
4475 );
4476 ShellPrintEx (-1, -1,
4477 L" Non-Fatal Error Detected(1): %E%d%N\r\n",
4478 PciExpressCap->DeviceStatus.Bits.NonFatalError
4479 );
4480 ShellPrintEx (-1, -1,
4481 L" Fatal Error Detected(2): %E%d%N\r\n",
4482 PciExpressCap->DeviceStatus.Bits.FatalError
4483 );
4484 ShellPrintEx (-1, -1,
4485 L" Unsupported Request Detected(3): %E%d%N\r\n",
4486 PciExpressCap->DeviceStatus.Bits.UnsupportedRequest
4487 );
4488 ShellPrintEx (-1, -1,
4489 L" AUX Power Detected(4): %E%d%N\r\n",
4490 PciExpressCap->DeviceStatus.Bits.AuxPower
4491 );
4492 ShellPrintEx (-1, -1,
4493 L" Transactions Pending(5): %E%d%N\r\n",
4494 PciExpressCap->DeviceStatus.Bits.TransactionsPending
4495 );
4496 return EFI_SUCCESS;
4497 }
4498
4499 /**
4500 Print out information of the device link information.
4501
4502 @param[in] PciExpressCap The pointer to the structure about the device.
4503
4504 @retval EFI_SUCCESS The operation was successful.
4505 **/
4506 EFI_STATUS
4507 ExplainPcieLinkCap (
4508 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4509 )
4510 {
4511 CHAR16 *MaxLinkSpeed;
4512 CHAR16 *AspmValue;
4513
4514 switch (PciExpressCap->LinkCapability.Bits.MaxLinkSpeed) {
4515 case 1:
4516 MaxLinkSpeed = L"2.5 GT/s";
4517 break;
4518 case 2:
4519 MaxLinkSpeed = L"5.0 GT/s";
4520 break;
4521 case 3:
4522 MaxLinkSpeed = L"8.0 GT/s";
4523 break;
4524 default:
4525 MaxLinkSpeed = L"Unknown";
4526 break;
4527 }
4528 ShellPrintEx (-1, -1,
4529 L" Maximum Link Speed(3:0): %E%s%N\r\n",
4530 MaxLinkSpeed
4531 );
4532 ShellPrintEx (-1, -1,
4533 L" Maximum Link Width(9:4): %Ex%d%N\r\n",
4534 PciExpressCap->LinkCapability.Bits.MaxLinkWidth
4535 );
4536 switch (PciExpressCap->LinkCapability.Bits.Aspm) {
4537 case 0:
4538 AspmValue = L"Not";
4539 break;
4540 case 1:
4541 AspmValue = L"L0s";
4542 break;
4543 case 2:
4544 AspmValue = L"L1";
4545 break;
4546 case 3:
4547 AspmValue = L"L0s and L1";
4548 break;
4549 default:
4550 AspmValue = L"Reserved";
4551 break;
4552 }
4553 ShellPrintEx (-1, -1,
4554 L" Active State Power Management Support(11:10): %E%s Supported%N\r\n",
4555 AspmValue
4556 );
4557 ShellPrintEx (-1, -1,
4558 L" L0s Exit Latency(14:12): %E%s%N\r\n",
4559 L0sLatencyStrTable[PciExpressCap->LinkCapability.Bits.L0sExitLatency]
4560 );
4561 ShellPrintEx (-1, -1,
4562 L" L1 Exit Latency(17:15): %E%s%N\r\n",
4563 L1LatencyStrTable[PciExpressCap->LinkCapability.Bits.L1ExitLatency]
4564 );
4565 ShellPrintEx (-1, -1,
4566 L" Clock Power Management(18): %E%d%N\r\n",
4567 PciExpressCap->LinkCapability.Bits.ClockPowerManagement
4568 );
4569 ShellPrintEx (-1, -1,
4570 L" Surprise Down Error Reporting Capable(19): %E%d%N\r\n",
4571 PciExpressCap->LinkCapability.Bits.SurpriseDownError
4572 );
4573 ShellPrintEx (-1, -1,
4574 L" Data Link Layer Link Active Reporting Capable(20): %E%d%N\r\n",
4575 PciExpressCap->LinkCapability.Bits.DataLinkLayerLinkActive
4576 );
4577 ShellPrintEx (-1, -1,
4578 L" Link Bandwidth Notification Capability(21): %E%d%N\r\n",
4579 PciExpressCap->LinkCapability.Bits.LinkBandwidthNotification
4580 );
4581 ShellPrintEx (-1, -1,
4582 L" Port Number(31:24): %E0x%02x%N\r\n",
4583 PciExpressCap->LinkCapability.Bits.PortNumber
4584 );
4585 return EFI_SUCCESS;
4586 }
4587
4588 /**
4589 Print out information of the device link control information.
4590
4591 @param[in] PciExpressCap The pointer to the structure about the device.
4592
4593 @retval EFI_SUCCESS The operation was successful.
4594 **/
4595 EFI_STATUS
4596 ExplainPcieLinkControl (
4597 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4598 )
4599 {
4600 UINT8 DevicePortType;
4601
4602 DevicePortType = (UINT8)PciExpressCap->Capability.Bits.DevicePortType;
4603 ShellPrintEx (-1, -1,
4604 L" Active State Power Management Control(1:0): %E%s%N\r\n",
4605 ASPMCtrlStrTable[PciExpressCap->LinkControl.Bits.AspmControl]
4606 );
4607 //
4608 // RCB is not applicable to switches
4609 //
4610 if (!IS_PCIE_SWITCH(DevicePortType)) {
4611 ShellPrintEx (-1, -1,
4612 L" Read Completion Boundary (RCB)(3): %E%d byte%N\r\n",
4613 1 << (PciExpressCap->LinkControl.Bits.ReadCompletionBoundary + 6)
4614 );
4615 }
4616 //
4617 // Link Disable is reserved on
4618 // a) Endpoints
4619 // b) PCI Express to PCI/PCI-X bridges
4620 // c) Upstream Ports of Switches
4621 //
4622 if (!IS_PCIE_ENDPOINT (DevicePortType) &&
4623 DevicePortType != PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT &&
4624 DevicePortType != PCIE_DEVICE_PORT_TYPE_PCIE_TO_PCI_BRIDGE) {
4625 ShellPrintEx (-1, -1,
4626 L" Link Disable(4): %E%d%N\r\n",
4627 PciExpressCap->LinkControl.Bits.LinkDisable
4628 );
4629 }
4630 ShellPrintEx (-1, -1,
4631 L" Common Clock Configuration(6): %E%d%N\r\n",
4632 PciExpressCap->LinkControl.Bits.CommonClockConfiguration
4633 );
4634 ShellPrintEx (-1, -1,
4635 L" Extended Synch(7): %E%d%N\r\n",
4636 PciExpressCap->LinkControl.Bits.ExtendedSynch
4637 );
4638 ShellPrintEx (-1, -1,
4639 L" Enable Clock Power Management(8): %E%d%N\r\n",
4640 PciExpressCap->LinkControl.Bits.ClockPowerManagement
4641 );
4642 ShellPrintEx (-1, -1,
4643 L" Hardware Autonomous Width Disable(9): %E%d%N\r\n",
4644 PciExpressCap->LinkControl.Bits.HardwareAutonomousWidthDisable
4645 );
4646 ShellPrintEx (-1, -1,
4647 L" Link Bandwidth Management Interrupt Enable(10): %E%d%N\r\n",
4648 PciExpressCap->LinkControl.Bits.LinkBandwidthManagementInterrupt
4649 );
4650 ShellPrintEx (-1, -1,
4651 L" Link Autonomous Bandwidth Interrupt Enable(11): %E%d%N\r\n",
4652 PciExpressCap->LinkControl.Bits.LinkAutonomousBandwidthInterrupt
4653 );
4654 return EFI_SUCCESS;
4655 }
4656
4657 /**
4658 Print out information of the device link status information.
4659
4660 @param[in] PciExpressCap The pointer to the structure about the device.
4661
4662 @retval EFI_SUCCESS The operation was successful.
4663 **/
4664 EFI_STATUS
4665 ExplainPcieLinkStatus (
4666 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4667 )
4668 {
4669 CHAR16 *CurLinkSpeed;
4670
4671 switch (PciExpressCap->LinkStatus.Bits.CurrentLinkSpeed) {
4672 case 1:
4673 CurLinkSpeed = L"2.5 GT/s";
4674 break;
4675 case 2:
4676 CurLinkSpeed = L"5.0 GT/s";
4677 break;
4678 case 3:
4679 CurLinkSpeed = L"8.0 GT/s";
4680 break;
4681 default:
4682 CurLinkSpeed = L"Reserved";
4683 break;
4684 }
4685 ShellPrintEx (-1, -1,
4686 L" Current Link Speed(3:0): %E%s%N\r\n",
4687 CurLinkSpeed
4688 );
4689 ShellPrintEx (-1, -1,
4690 L" Negotiated Link Width(9:4): %Ex%d%N\r\n",
4691 PciExpressCap->LinkStatus.Bits.NegotiatedLinkWidth
4692 );
4693 ShellPrintEx (-1, -1,
4694 L" Link Training(11): %E%d%N\r\n",
4695 PciExpressCap->LinkStatus.Bits.LinkTraining
4696 );
4697 ShellPrintEx (-1, -1,
4698 L" Slot Clock Configuration(12): %E%d%N\r\n",
4699 PciExpressCap->LinkStatus.Bits.SlotClockConfiguration
4700 );
4701 ShellPrintEx (-1, -1,
4702 L" Data Link Layer Link Active(13): %E%d%N\r\n",
4703 PciExpressCap->LinkStatus.Bits.DataLinkLayerLinkActive
4704 );
4705 ShellPrintEx (-1, -1,
4706 L" Link Bandwidth Management Status(14): %E%d%N\r\n",
4707 PciExpressCap->LinkStatus.Bits.LinkBandwidthManagement
4708 );
4709 ShellPrintEx (-1, -1,
4710 L" Link Autonomous Bandwidth Status(15): %E%d%N\r\n",
4711 PciExpressCap->LinkStatus.Bits.LinkAutonomousBandwidth
4712 );
4713 return EFI_SUCCESS;
4714 }
4715
4716 /**
4717 Print out information of the device slot information.
4718
4719 @param[in] PciExpressCap The pointer to the structure about the device.
4720
4721 @retval EFI_SUCCESS The operation was successful.
4722 **/
4723 EFI_STATUS
4724 ExplainPcieSlotCap (
4725 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4726 )
4727 {
4728 ShellPrintEx (-1, -1,
4729 L" Attention Button Present(0): %E%d%N\r\n",
4730 PciExpressCap->SlotCapability.Bits.AttentionButton
4731 );
4732 ShellPrintEx (-1, -1,
4733 L" Power Controller Present(1): %E%d%N\r\n",
4734 PciExpressCap->SlotCapability.Bits.PowerController
4735 );
4736 ShellPrintEx (-1, -1,
4737 L" MRL Sensor Present(2): %E%d%N\r\n",
4738 PciExpressCap->SlotCapability.Bits.MrlSensor
4739 );
4740 ShellPrintEx (-1, -1,
4741 L" Attention Indicator Present(3): %E%d%N\r\n",
4742 PciExpressCap->SlotCapability.Bits.AttentionIndicator
4743 );
4744 ShellPrintEx (-1, -1,
4745 L" Power Indicator Present(4): %E%d%N\r\n",
4746 PciExpressCap->SlotCapability.Bits.PowerIndicator
4747 );
4748 ShellPrintEx (-1, -1,
4749 L" Hot-Plug Surprise(5): %E%d%N\r\n",
4750 PciExpressCap->SlotCapability.Bits.HotPlugSurprise
4751 );
4752 ShellPrintEx (-1, -1,
4753 L" Hot-Plug Capable(6): %E%d%N\r\n",
4754 PciExpressCap->SlotCapability.Bits.HotPlugCapable
4755 );
4756 ShellPrintEx (-1, -1,
4757 L" Slot Power Limit Value(14:7): %E0x%02x%N\r\n",
4758 PciExpressCap->SlotCapability.Bits.SlotPowerLimitValue
4759 );
4760 ShellPrintEx (-1, -1,
4761 L" Slot Power Limit Scale(16:15): %E%s%N\r\n",
4762 SlotPwrLmtScaleTable[PciExpressCap->SlotCapability.Bits.SlotPowerLimitScale]
4763 );
4764 ShellPrintEx (-1, -1,
4765 L" Electromechanical Interlock Present(17): %E%d%N\r\n",
4766 PciExpressCap->SlotCapability.Bits.ElectromechanicalInterlock
4767 );
4768 ShellPrintEx (-1, -1,
4769 L" No Command Completed Support(18): %E%d%N\r\n",
4770 PciExpressCap->SlotCapability.Bits.NoCommandCompleted
4771 );
4772 ShellPrintEx (-1, -1,
4773 L" Physical Slot Number(31:19): %E%d%N\r\n",
4774 PciExpressCap->SlotCapability.Bits.PhysicalSlotNumber
4775 );
4776
4777 return EFI_SUCCESS;
4778 }
4779
4780 /**
4781 Print out information of the device slot control information.
4782
4783 @param[in] PciExpressCap The pointer to the structure about the device.
4784
4785 @retval EFI_SUCCESS The operation was successful.
4786 **/
4787 EFI_STATUS
4788 ExplainPcieSlotControl (
4789 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4790 )
4791 {
4792 ShellPrintEx (-1, -1,
4793 L" Attention Button Pressed Enable(0): %E%d%N\r\n",
4794 PciExpressCap->SlotControl.Bits.AttentionButtonPressed
4795 );
4796 ShellPrintEx (-1, -1,
4797 L" Power Fault Detected Enable(1): %E%d%N\r\n",
4798 PciExpressCap->SlotControl.Bits.PowerFaultDetected
4799 );
4800 ShellPrintEx (-1, -1,
4801 L" MRL Sensor Changed Enable(2): %E%d%N\r\n",
4802 PciExpressCap->SlotControl.Bits.MrlSensorChanged
4803 );
4804 ShellPrintEx (-1, -1,
4805 L" Presence Detect Changed Enable(3): %E%d%N\r\n",
4806 PciExpressCap->SlotControl.Bits.PresenceDetectChanged
4807 );
4808 ShellPrintEx (-1, -1,
4809 L" Command Completed Interrupt Enable(4): %E%d%N\r\n",
4810 PciExpressCap->SlotControl.Bits.CommandCompletedInterrupt
4811 );
4812 ShellPrintEx (-1, -1,
4813 L" Hot-Plug Interrupt Enable(5): %E%d%N\r\n",
4814 PciExpressCap->SlotControl.Bits.HotPlugInterrupt
4815 );
4816 ShellPrintEx (-1, -1,
4817 L" Attention Indicator Control(7:6): %E%s%N\r\n",
4818 IndicatorTable[
4819 PciExpressCap->SlotControl.Bits.AttentionIndicator]
4820 );
4821 ShellPrintEx (-1, -1,
4822 L" Power Indicator Control(9:8): %E%s%N\r\n",
4823 IndicatorTable[PciExpressCap->SlotControl.Bits.PowerIndicator]
4824 );
4825 ShellPrintEx (-1, -1, L" Power Controller Control(10): %EPower ");
4826 if (
4827 PciExpressCap->SlotControl.Bits.PowerController) {
4828 ShellPrintEx (-1, -1, L"Off%N\r\n");
4829 } else {
4830 ShellPrintEx (-1, -1, L"On%N\r\n");
4831 }
4832 ShellPrintEx (-1, -1,
4833 L" Electromechanical Interlock Control(11): %E%d%N\r\n",
4834 PciExpressCap->SlotControl.Bits.ElectromechanicalInterlock
4835 );
4836 ShellPrintEx (-1, -1,
4837 L" Data Link Layer State Changed Enable(12): %E%d%N\r\n",
4838 PciExpressCap->SlotControl.Bits.DataLinkLayerStateChanged
4839 );
4840 return EFI_SUCCESS;
4841 }
4842
4843 /**
4844 Print out information of the device slot status information.
4845
4846 @param[in] PciExpressCap The pointer to the structure about the device.
4847
4848 @retval EFI_SUCCESS The operation was successful.
4849 **/
4850 EFI_STATUS
4851 ExplainPcieSlotStatus (
4852 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4853 )
4854 {
4855 ShellPrintEx (-1, -1,
4856 L" Attention Button Pressed(0): %E%d%N\r\n",
4857 PciExpressCap->SlotStatus.Bits.AttentionButtonPressed
4858 );
4859 ShellPrintEx (-1, -1,
4860 L" Power Fault Detected(1): %E%d%N\r\n",
4861 PciExpressCap->SlotStatus.Bits.PowerFaultDetected
4862 );
4863 ShellPrintEx (-1, -1,
4864 L" MRL Sensor Changed(2): %E%d%N\r\n",
4865 PciExpressCap->SlotStatus.Bits.MrlSensorChanged
4866 );
4867 ShellPrintEx (-1, -1,
4868 L" Presence Detect Changed(3): %E%d%N\r\n",
4869 PciExpressCap->SlotStatus.Bits.PresenceDetectChanged
4870 );
4871 ShellPrintEx (-1, -1,
4872 L" Command Completed(4): %E%d%N\r\n",
4873 PciExpressCap->SlotStatus.Bits.CommandCompleted
4874 );
4875 ShellPrintEx (-1, -1, L" MRL Sensor State(5): %EMRL ");
4876 if (
4877 PciExpressCap->SlotStatus.Bits.MrlSensor) {
4878 ShellPrintEx (-1, -1, L" Opened%N\r\n");
4879 } else {
4880 ShellPrintEx (-1, -1, L" Closed%N\r\n");
4881 }
4882 ShellPrintEx (-1, -1, L" Presence Detect State(6): ");
4883 if (
4884 PciExpressCap->SlotStatus.Bits.PresenceDetect) {
4885 ShellPrintEx (-1, -1, L"%ECard Present in slot%N\r\n");
4886 } else {
4887 ShellPrintEx (-1, -1, L"%ESlot Empty%N\r\n");
4888 }
4889 ShellPrintEx (-1, -1, L" Electromechanical Interlock Status(7): %EElectromechanical Interlock ");
4890 if (
4891 PciExpressCap->SlotStatus.Bits.ElectromechanicalInterlock) {
4892 ShellPrintEx (-1, -1, L"Engaged%N\r\n");
4893 } else {
4894 ShellPrintEx (-1, -1, L"Disengaged%N\r\n");
4895 }
4896 ShellPrintEx (-1, -1,
4897 L" Data Link Layer State Changed(8): %E%d%N\r\n",
4898 PciExpressCap->SlotStatus.Bits.DataLinkLayerStateChanged
4899 );
4900 return EFI_SUCCESS;
4901 }
4902
4903 /**
4904 Print out information of the device root information.
4905
4906 @param[in] PciExpressCap The pointer to the structure about the device.
4907
4908 @retval EFI_SUCCESS The operation was successful.
4909 **/
4910 EFI_STATUS
4911 ExplainPcieRootControl (
4912 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4913 )
4914 {
4915 ShellPrintEx (-1, -1,
4916 L" System Error on Correctable Error Enable(0): %E%d%N\r\n",
4917 PciExpressCap->RootControl.Bits.SystemErrorOnCorrectableError
4918 );
4919 ShellPrintEx (-1, -1,
4920 L" System Error on Non-Fatal Error Enable(1): %E%d%N\r\n",
4921 PciExpressCap->RootControl.Bits.SystemErrorOnNonFatalError
4922 );
4923 ShellPrintEx (-1, -1,
4924 L" System Error on Fatal Error Enable(2): %E%d%N\r\n",
4925 PciExpressCap->RootControl.Bits.SystemErrorOnFatalError
4926 );
4927 ShellPrintEx (-1, -1,
4928 L" PME Interrupt Enable(3): %E%d%N\r\n",
4929 PciExpressCap->RootControl.Bits.PmeInterrupt
4930 );
4931 ShellPrintEx (-1, -1,
4932 L" CRS Software Visibility Enable(4): %E%d%N\r\n",
4933 PciExpressCap->RootControl.Bits.CrsSoftwareVisibility
4934 );
4935
4936 return EFI_SUCCESS;
4937 }
4938
4939 /**
4940 Print out information of the device root capability information.
4941
4942 @param[in] PciExpressCap The pointer to the structure about the device.
4943
4944 @retval EFI_SUCCESS The operation was successful.
4945 **/
4946 EFI_STATUS
4947 ExplainPcieRootCap (
4948 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4949 )
4950 {
4951 ShellPrintEx (-1, -1,
4952 L" CRS Software Visibility(0): %E%d%N\r\n",
4953 PciExpressCap->RootCapability.Bits.CrsSoftwareVisibility
4954 );
4955
4956 return EFI_SUCCESS;
4957 }
4958
4959 /**
4960 Print out information of the device root status information.
4961
4962 @param[in] PciExpressCap The pointer to the structure about the device.
4963
4964 @retval EFI_SUCCESS The operation was successful.
4965 **/
4966 EFI_STATUS
4967 ExplainPcieRootStatus (
4968 IN PCI_CAPABILITY_PCIEXP *PciExpressCap
4969 )
4970 {
4971 ShellPrintEx (-1, -1,
4972 L" PME Requester ID(15:0): %E0x%04x%N\r\n",
4973 PciExpressCap->RootStatus.Bits.PmeRequesterId
4974 );
4975 ShellPrintEx (-1, -1,
4976 L" PME Status(16): %E%d%N\r\n",
4977 PciExpressCap->RootStatus.Bits.PmeStatus
4978 );
4979 ShellPrintEx (-1, -1,
4980 L" PME Pending(17): %E%d%N\r\n",
4981 PciExpressCap->RootStatus.Bits.PmePending
4982 );
4983 return EFI_SUCCESS;
4984 }
4985
4986 /**
4987 Function to interpret and print out the link control structure
4988
4989 @param[in] HeaderAddress The Address of this capability header.
4990 @param[in] HeadersBaseAddress The address of all the extended capability headers.
4991 **/
4992 EFI_STATUS
4993 PrintInterpretedExtendedCompatibilityLinkControl (
4994 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
4995 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
4996 )
4997 {
4998 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL *Header;
4999 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL*)HeaderAddress;
5000
5001 ShellPrintHiiEx(
5002 -1, -1, NULL,
5003 STRING_TOKEN (STR_PCI_EXT_CAP_LINK_CONTROL),
5004 gShellDebug1HiiHandle,
5005 Header->RootComplexLinkCapabilities,
5006 Header->RootComplexLinkControl,
5007 Header->RootComplexLinkStatus
5008 );
5009 DumpHex (
5010 4,
5011 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5012 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL),
5013 (VOID *) (HeaderAddress)
5014 );
5015 return (EFI_SUCCESS);
5016 }
5017
5018 /**
5019 Function to interpret and print out the power budgeting structure
5020
5021 @param[in] HeaderAddress The Address of this capability header.
5022 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5023 **/
5024 EFI_STATUS
5025 PrintInterpretedExtendedCompatibilityPowerBudgeting (
5026 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5027 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5028 )
5029 {
5030 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING *Header;
5031 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING*)HeaderAddress;
5032
5033 ShellPrintHiiEx(
5034 -1, -1, NULL,
5035 STRING_TOKEN (STR_PCI_EXT_CAP_POWER),
5036 gShellDebug1HiiHandle,
5037 Header->DataSelect,
5038 Header->Data,
5039 Header->PowerBudgetCapability
5040 );
5041 DumpHex (
5042 4,
5043 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5044 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING),
5045 (VOID *) (HeaderAddress)
5046 );
5047 return (EFI_SUCCESS);
5048 }
5049
5050 /**
5051 Function to interpret and print out the ACS structure
5052
5053 @param[in] HeaderAddress The Address of this capability header.
5054 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5055 **/
5056 EFI_STATUS
5057 PrintInterpretedExtendedCompatibilityAcs (
5058 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5059 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5060 )
5061 {
5062 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED *Header;
5063 UINT16 VectorSize;
5064 UINT16 LoopCounter;
5065
5066 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED*)HeaderAddress;
5067 VectorSize = 0;
5068
5069 ShellPrintHiiEx(
5070 -1, -1, NULL,
5071 STRING_TOKEN (STR_PCI_EXT_CAP_ACS),
5072 gShellDebug1HiiHandle,
5073 Header->AcsCapability,
5074 Header->AcsControl
5075 );
5076 if (PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_CONTROL(Header)) {
5077 VectorSize = PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_VECTOR_SIZE(Header);
5078 if (VectorSize == 0) {
5079 VectorSize = 256;
5080 }
5081 for (LoopCounter = 0 ; LoopCounter * 8 < VectorSize ; LoopCounter++) {
5082 ShellPrintHiiEx(
5083 -1, -1, NULL,
5084 STRING_TOKEN (STR_PCI_EXT_CAP_ACS2),
5085 gShellDebug1HiiHandle,
5086 LoopCounter + 1,
5087 Header->EgressControlVectorArray[LoopCounter]
5088 );
5089 }
5090 }
5091 DumpHex (
5092 4,
5093 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5094 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED) + (VectorSize / 8) - 1,
5095 (VOID *) (HeaderAddress)
5096 );
5097 return (EFI_SUCCESS);
5098 }
5099
5100 /**
5101 Function to interpret and print out the latency tolerance reporting structure
5102
5103 @param[in] HeaderAddress The Address of this capability header.
5104 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5105 **/
5106 EFI_STATUS
5107 PrintInterpretedExtendedCompatibilityLatencyToleranceReporting (
5108 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5109 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5110 )
5111 {
5112 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING *Header;
5113 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING*)HeaderAddress;
5114
5115 ShellPrintHiiEx(
5116 -1, -1, NULL,
5117 STRING_TOKEN (STR_PCI_EXT_CAP_LAT),
5118 gShellDebug1HiiHandle,
5119 Header->MaxSnoopLatency,
5120 Header->MaxNoSnoopLatency
5121 );
5122 DumpHex (
5123 4,
5124 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5125 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING),
5126 (VOID *) (HeaderAddress)
5127 );
5128 return (EFI_SUCCESS);
5129 }
5130
5131 /**
5132 Function to interpret and print out the serial number structure
5133
5134 @param[in] HeaderAddress The Address of this capability header.
5135 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5136 **/
5137 EFI_STATUS
5138 PrintInterpretedExtendedCompatibilitySerialNumber (
5139 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5140 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5141 )
5142 {
5143 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER *Header;
5144 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER*)HeaderAddress;
5145
5146 ShellPrintHiiEx(
5147 -1, -1, NULL,
5148 STRING_TOKEN (STR_PCI_EXT_CAP_SN),
5149 gShellDebug1HiiHandle,
5150 Header->SerialNumber
5151 );
5152 DumpHex (
5153 4,
5154 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5155 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER),
5156 (VOID *) (HeaderAddress)
5157 );
5158 return (EFI_SUCCESS);
5159 }
5160
5161 /**
5162 Function to interpret and print out the RCRB structure
5163
5164 @param[in] HeaderAddress The Address of this capability header.
5165 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5166 **/
5167 EFI_STATUS
5168 PrintInterpretedExtendedCompatibilityRcrb (
5169 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5170 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5171 )
5172 {
5173 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER *Header;
5174 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER*)HeaderAddress;
5175
5176 ShellPrintHiiEx(
5177 -1, -1, NULL,
5178 STRING_TOKEN (STR_PCI_EXT_CAP_RCRB),
5179 gShellDebug1HiiHandle,
5180 Header->VendorId,
5181 Header->DeviceId,
5182 Header->RcrbCapabilities,
5183 Header->RcrbControl
5184 );
5185 DumpHex (
5186 4,
5187 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5188 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER),
5189 (VOID *) (HeaderAddress)
5190 );
5191 return (EFI_SUCCESS);
5192 }
5193
5194 /**
5195 Function to interpret and print out the vendor specific structure
5196
5197 @param[in] HeaderAddress The Address of this capability header.
5198 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5199 **/
5200 EFI_STATUS
5201 PrintInterpretedExtendedCompatibilityVendorSpecific (
5202 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5203 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5204 )
5205 {
5206 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VENDOR_SPECIFIC *Header;
5207 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_VENDOR_SPECIFIC*)HeaderAddress;
5208
5209 ShellPrintHiiEx(
5210 -1, -1, NULL,
5211 STRING_TOKEN (STR_PCI_EXT_CAP_VEN),
5212 gShellDebug1HiiHandle,
5213 Header->VendorSpecificHeader
5214 );
5215 DumpHex (
5216 4,
5217 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5218 PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_GET_SIZE(Header),
5219 (VOID *) (HeaderAddress)
5220 );
5221 return (EFI_SUCCESS);
5222 }
5223
5224 /**
5225 Function to interpret and print out the Event Collector Endpoint Association structure
5226
5227 @param[in] HeaderAddress The Address of this capability header.
5228 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5229 **/
5230 EFI_STATUS
5231 PrintInterpretedExtendedCompatibilityECEA (
5232 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5233 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5234 )
5235 {
5236 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION *Header;
5237 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION*)HeaderAddress;
5238
5239 ShellPrintHiiEx(
5240 -1, -1, NULL,
5241 STRING_TOKEN (STR_PCI_EXT_CAP_ECEA),
5242 gShellDebug1HiiHandle,
5243 Header->AssociationBitmap
5244 );
5245 DumpHex (
5246 4,
5247 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5248 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION),
5249 (VOID *) (HeaderAddress)
5250 );
5251 return (EFI_SUCCESS);
5252 }
5253
5254 /**
5255 Function to interpret and print out the ARI structure
5256
5257 @param[in] HeaderAddress The Address of this capability header.
5258 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5259 **/
5260 EFI_STATUS
5261 PrintInterpretedExtendedCompatibilityAri (
5262 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5263 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5264 )
5265 {
5266 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY *Header;
5267 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY*)HeaderAddress;
5268
5269 ShellPrintHiiEx(
5270 -1, -1, NULL,
5271 STRING_TOKEN (STR_PCI_EXT_CAP_ARI),
5272 gShellDebug1HiiHandle,
5273 Header->AriCapability,
5274 Header->AriControl
5275 );
5276 DumpHex (
5277 4,
5278 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5279 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY),
5280 (VOID *) (HeaderAddress)
5281 );
5282 return (EFI_SUCCESS);
5283 }
5284
5285 /**
5286 Function to interpret and print out the DPA structure
5287
5288 @param[in] HeaderAddress The Address of this capability header.
5289 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5290 **/
5291 EFI_STATUS
5292 PrintInterpretedExtendedCompatibilityDynamicPowerAllocation (
5293 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5294 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5295 )
5296 {
5297 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION *Header;
5298 UINT8 LinkCount;
5299 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION*)HeaderAddress;
5300
5301 ShellPrintHiiEx(
5302 -1, -1, NULL,
5303 STRING_TOKEN (STR_PCI_EXT_CAP_DPA),
5304 gShellDebug1HiiHandle,
5305 Header->DpaCapability,
5306 Header->DpaLatencyIndicator,
5307 Header->DpaStatus,
5308 Header->DpaControl
5309 );
5310 for (LinkCount = 0 ; LinkCount < PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_GET_SUBSTATE_MAX(Header) + 1 ; LinkCount++) {
5311 ShellPrintHiiEx(
5312 -1, -1, NULL,
5313 STRING_TOKEN (STR_PCI_EXT_CAP_DPA2),
5314 gShellDebug1HiiHandle,
5315 LinkCount+1,
5316 Header->DpaPowerAllocationArray[LinkCount]
5317 );
5318 }
5319 DumpHex (
5320 4,
5321 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5322 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION) - 1 + PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_GET_SUBSTATE_MAX(Header),
5323 (VOID *) (HeaderAddress)
5324 );
5325 return (EFI_SUCCESS);
5326 }
5327
5328 /**
5329 Function to interpret and print out the link declaration structure
5330
5331 @param[in] HeaderAddress The Address of this capability header.
5332 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5333 **/
5334 EFI_STATUS
5335 PrintInterpretedExtendedCompatibilityLinkDeclaration (
5336 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5337 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5338 )
5339 {
5340 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION *Header;
5341 UINT8 LinkCount;
5342 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION*)HeaderAddress;
5343
5344 ShellPrintHiiEx(
5345 -1, -1, NULL,
5346 STRING_TOKEN (STR_PCI_EXT_CAP_LINK_DECLAR),
5347 gShellDebug1HiiHandle,
5348 Header->ElementSelfDescription
5349 );
5350
5351 for (LinkCount = 0 ; LinkCount < PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_GET_LINK_COUNT(Header) ; LinkCount++) {
5352 ShellPrintHiiEx(
5353 -1, -1, NULL,
5354 STRING_TOKEN (STR_PCI_EXT_CAP_LINK_DECLAR2),
5355 gShellDebug1HiiHandle,
5356 LinkCount+1,
5357 Header->LinkEntry[LinkCount]
5358 );
5359 }
5360 DumpHex (
5361 4,
5362 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5363 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION) + (PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_GET_LINK_COUNT(Header)-1)*sizeof(UINT32),
5364 (VOID *) (HeaderAddress)
5365 );
5366 return (EFI_SUCCESS);
5367 }
5368
5369 /**
5370 Function to interpret and print out the Advanced Error Reporting structure
5371
5372 @param[in] HeaderAddress The Address of this capability header.
5373 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5374 **/
5375 EFI_STATUS
5376 PrintInterpretedExtendedCompatibilityAer (
5377 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5378 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5379 )
5380 {
5381 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING *Header;
5382 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING*)HeaderAddress;
5383
5384 ShellPrintHiiEx(
5385 -1, -1, NULL,
5386 STRING_TOKEN (STR_PCI_EXT_CAP_AER),
5387 gShellDebug1HiiHandle,
5388 Header->UncorrectableErrorStatus,
5389 Header->UncorrectableErrorMask,
5390 Header->UncorrectableErrorSeverity,
5391 Header->CorrectableErrorStatus,
5392 Header->CorrectableErrorMask,
5393 Header->AdvancedErrorCapabilitiesAndControl,
5394 Header->HeaderLog[0],
5395 Header->HeaderLog[1],
5396 Header->HeaderLog[2],
5397 Header->HeaderLog[3],
5398 Header->RootErrorCommand,
5399 Header->RootErrorStatus,
5400 Header->ErrorSourceIdentification,
5401 Header->CorrectableErrorSourceIdentification,
5402 Header->TlpPrefixLog[0],
5403 Header->TlpPrefixLog[1],
5404 Header->TlpPrefixLog[2],
5405 Header->TlpPrefixLog[3]
5406 );
5407 DumpHex (
5408 4,
5409 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5410 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING),
5411 (VOID *) (HeaderAddress)
5412 );
5413 return (EFI_SUCCESS);
5414 }
5415
5416 /**
5417 Function to interpret and print out the multicast structure
5418
5419 @param[in] HeaderAddress The Address of this capability header.
5420 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5421 @param[in] PciExpressCapPtr The address of the PCIe capabilities structure.
5422 **/
5423 EFI_STATUS
5424 PrintInterpretedExtendedCompatibilityMulticast (
5425 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5426 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress,
5427 IN CONST PCI_CAPABILITY_PCIEXP *PciExpressCapPtr
5428 )
5429 {
5430 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST *Header;
5431 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST*)HeaderAddress;
5432
5433 ShellPrintHiiEx(
5434 -1, -1, NULL,
5435 STRING_TOKEN (STR_PCI_EXT_CAP_MULTICAST),
5436 gShellDebug1HiiHandle,
5437 Header->MultiCastCapability,
5438 Header->MulticastControl,
5439 Header->McBaseAddress,
5440 Header->McReceiveAddress,
5441 Header->McBlockAll,
5442 Header->McBlockUntranslated,
5443 Header->McOverlayBar
5444 );
5445
5446 DumpHex (
5447 4,
5448 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5449 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST),
5450 (VOID *) (HeaderAddress)
5451 );
5452
5453 return (EFI_SUCCESS);
5454 }
5455
5456 /**
5457 Function to interpret and print out the virtual channel and multi virtual channel structure
5458
5459 @param[in] HeaderAddress The Address of this capability header.
5460 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5461 **/
5462 EFI_STATUS
5463 PrintInterpretedExtendedCompatibilityVirtualChannel (
5464 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5465 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5466 )
5467 {
5468 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY *Header;
5469 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC *CapabilityItem;
5470 UINT32 ItemCount;
5471 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY*)HeaderAddress;
5472
5473 ShellPrintHiiEx(
5474 -1, -1, NULL,
5475 STRING_TOKEN (STR_PCI_EXT_CAP_VC_BASE),
5476 gShellDebug1HiiHandle,
5477 Header->ExtendedVcCount,
5478 Header->PortVcCapability1,
5479 Header->PortVcCapability2,
5480 Header->VcArbTableOffset,
5481 Header->PortVcControl,
5482 Header->PortVcStatus
5483 );
5484 for (ItemCount = 0 ; ItemCount < Header->ExtendedVcCount ; ItemCount++) {
5485 CapabilityItem = &Header->Capability[ItemCount];
5486 ShellPrintHiiEx(
5487 -1, -1, NULL,
5488 STRING_TOKEN (STR_PCI_EXT_CAP_VC_ITEM),
5489 gShellDebug1HiiHandle,
5490 ItemCount+1,
5491 CapabilityItem->VcResourceCapability,
5492 CapabilityItem->PortArbTableOffset,
5493 CapabilityItem->VcResourceControl,
5494 CapabilityItem->VcResourceStatus
5495 );
5496 }
5497
5498 DumpHex (
5499 4,
5500 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5501 sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY)
5502 + Header->ExtendedVcCount * sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC),
5503 (VOID *) (HeaderAddress)
5504 );
5505
5506 return (EFI_SUCCESS);
5507 }
5508
5509 /**
5510 Function to interpret and print out the resizeable bar structure
5511
5512 @param[in] HeaderAddress The Address of this capability header.
5513 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5514 **/
5515 EFI_STATUS
5516 PrintInterpretedExtendedCompatibilityResizeableBar (
5517 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5518 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5519 )
5520 {
5521 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR *Header;
5522 UINT32 ItemCount;
5523 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR*)HeaderAddress;
5524
5525 for (ItemCount = 0 ; ItemCount < (UINT32)GET_NUMBER_RESIZABLE_BARS(Header) ; ItemCount++) {
5526 ShellPrintHiiEx(
5527 -1, -1, NULL,
5528 STRING_TOKEN (STR_PCI_EXT_CAP_RESIZE_BAR),
5529 gShellDebug1HiiHandle,
5530 ItemCount+1,
5531 Header->Capability[ItemCount].ResizableBarCapability,
5532 Header->Capability[ItemCount].ResizableBarControl
5533 );
5534 }
5535
5536 DumpHex (
5537 4,
5538 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5539 (UINT32)GET_NUMBER_RESIZABLE_BARS(Header) * sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY),
5540 (VOID *) (HeaderAddress)
5541 );
5542
5543 return (EFI_SUCCESS);
5544 }
5545
5546 /**
5547 Function to interpret and print out the TPH structure
5548
5549 @param[in] HeaderAddress The Address of this capability header.
5550 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5551 **/
5552 EFI_STATUS
5553 PrintInterpretedExtendedCompatibilityTph (
5554 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5555 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
5556 )
5557 {
5558 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH *Header;
5559 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH*)HeaderAddress;
5560
5561 ShellPrintHiiEx(
5562 -1, -1, NULL,
5563 STRING_TOKEN (STR_PCI_EXT_CAP_TPH),
5564 gShellDebug1HiiHandle,
5565 Header->TphRequesterCapability,
5566 Header->TphRequesterControl
5567 );
5568 DumpHex (
5569 8,
5570 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)Header->TphStTable - (UINT8*)HeadersBaseAddress),
5571 GET_TPH_TABLE_SIZE(Header),
5572 (VOID *)Header->TphStTable
5573 );
5574
5575 DumpHex (
5576 4,
5577 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5578 sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH) + GET_TPH_TABLE_SIZE(Header) - sizeof(UINT16),
5579 (VOID *) (HeaderAddress)
5580 );
5581
5582 return (EFI_SUCCESS);
5583 }
5584
5585 /**
5586 Function to interpret and print out the secondary PCIe capability structure
5587
5588 @param[in] HeaderAddress The Address of this capability header.
5589 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5590 @param[in] PciExpressCapPtr The address of the PCIe capabilities structure.
5591 **/
5592 EFI_STATUS
5593 PrintInterpretedExtendedCompatibilitySecondary (
5594 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5595 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress,
5596 IN CONST PCI_CAPABILITY_PCIEXP *PciExpressCap
5597 )
5598 {
5599 CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE *Header;
5600 Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE*)HeaderAddress;
5601
5602 ShellPrintHiiEx(
5603 -1, -1, NULL,
5604 STRING_TOKEN (STR_PCI_EXT_CAP_SECONDARY),
5605 gShellDebug1HiiHandle,
5606 Header->LinkControl3.Uint32,
5607 Header->LaneErrorStatus
5608 );
5609 DumpHex (
5610 8,
5611 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)Header->EqualizationControl - (UINT8*)HeadersBaseAddress),
5612 PciExpressCap->LinkCapability.Bits.MaxLinkWidth * sizeof (PCI_EXPRESS_REG_LANE_EQUALIZATION_CONTROL),
5613 (VOID *)Header->EqualizationControl
5614 );
5615
5616 DumpHex (
5617 4,
5618 EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
5619 sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE) - sizeof (Header->EqualizationControl)
5620 + PciExpressCap->LinkCapability.Bits.MaxLinkWidth * sizeof (PCI_EXPRESS_REG_LANE_EQUALIZATION_CONTROL),
5621 (VOID *) (HeaderAddress)
5622 );
5623
5624 return (EFI_SUCCESS);
5625 }
5626
5627 /**
5628 Display Pcie extended capability details
5629
5630 @param[in] HeadersBaseAddress The address of all the extended capability headers.
5631 @param[in] HeaderAddress The address of this capability header.
5632 @param[in] PciExpressCapPtr The address of the PCIe capabilities structure.
5633 **/
5634 EFI_STATUS
5635 PrintPciExtendedCapabilityDetails(
5636 IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress,
5637 IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
5638 IN CONST PCI_CAPABILITY_PCIEXP *PciExpressCapPtr
5639 )
5640 {
5641 switch (HeaderAddress->CapabilityId){
5642 case PCI_EXPRESS_EXTENDED_CAPABILITY_ADVANCED_ERROR_REPORTING_ID:
5643 return PrintInterpretedExtendedCompatibilityAer(HeaderAddress, HeadersBaseAddress);
5644 case PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_CONTROL_ID:
5645 return PrintInterpretedExtendedCompatibilityLinkControl(HeaderAddress, HeadersBaseAddress);
5646 case PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_ID:
5647 return PrintInterpretedExtendedCompatibilityLinkDeclaration(HeaderAddress, HeadersBaseAddress);
5648 case PCI_EXPRESS_EXTENDED_CAPABILITY_SERIAL_NUMBER_ID:
5649 return PrintInterpretedExtendedCompatibilitySerialNumber(HeaderAddress, HeadersBaseAddress);
5650 case PCI_EXPRESS_EXTENDED_CAPABILITY_POWER_BUDGETING_ID:
5651 return PrintInterpretedExtendedCompatibilityPowerBudgeting(HeaderAddress, HeadersBaseAddress);
5652 case PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_ID:
5653 return PrintInterpretedExtendedCompatibilityAcs(HeaderAddress, HeadersBaseAddress);
5654 case PCI_EXPRESS_EXTENDED_CAPABILITY_LATENCE_TOLERANCE_REPORTING_ID:
5655 return PrintInterpretedExtendedCompatibilityLatencyToleranceReporting(HeaderAddress, HeadersBaseAddress);
5656 case PCI_EXPRESS_EXTENDED_CAPABILITY_ARI_CAPABILITY_ID:
5657 return PrintInterpretedExtendedCompatibilityAri(HeaderAddress, HeadersBaseAddress);
5658 case PCI_EXPRESS_EXTENDED_CAPABILITY_RCRB_HEADER_ID:
5659 return PrintInterpretedExtendedCompatibilityRcrb(HeaderAddress, HeadersBaseAddress);
5660 case PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID:
5661 return PrintInterpretedExtendedCompatibilityVendorSpecific(HeaderAddress, HeadersBaseAddress);
5662 case PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_ID:
5663 return PrintInterpretedExtendedCompatibilityDynamicPowerAllocation(HeaderAddress, HeadersBaseAddress);
5664 case PCI_EXPRESS_EXTENDED_CAPABILITY_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION_ID:
5665 return PrintInterpretedExtendedCompatibilityECEA(HeaderAddress, HeadersBaseAddress);
5666 case PCI_EXPRESS_EXTENDED_CAPABILITY_VIRTUAL_CHANNEL_ID:
5667 case PCI_EXPRESS_EXTENDED_CAPABILITY_MULTI_FUNCTION_VIRTUAL_CHANNEL_ID:
5668 return PrintInterpretedExtendedCompatibilityVirtualChannel(HeaderAddress, HeadersBaseAddress);
5669 case PCI_EXPRESS_EXTENDED_CAPABILITY_MULTICAST_ID:
5670 //
5671 // should only be present if PCIE_CAP_DEVICEPORT_TYPE(PciExpressCapPtr->PcieCapReg) == 0100b, 0101b, or 0110b
5672 //
5673 return PrintInterpretedExtendedCompatibilityMulticast(HeaderAddress, HeadersBaseAddress, PciExpressCapPtr);
5674 case PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID:
5675 return PrintInterpretedExtendedCompatibilityResizeableBar(HeaderAddress, HeadersBaseAddress);
5676 case PCI_EXPRESS_EXTENDED_CAPABILITY_TPH_ID:
5677 return PrintInterpretedExtendedCompatibilityTph(HeaderAddress, HeadersBaseAddress);
5678 case PCI_EXPRESS_EXTENDED_CAPABILITY_SECONDARY_PCIE_ID:
5679 return PrintInterpretedExtendedCompatibilitySecondary(HeaderAddress, HeadersBaseAddress, PciExpressCapPtr);
5680 default:
5681 ShellPrintEx (-1, -1,
5682 L"Unknown PCIe extended capability ID (%04xh). No interpretation available.\r\n",
5683 HeaderAddress->CapabilityId
5684 );
5685 return EFI_SUCCESS;
5686 };
5687
5688 }
5689
5690 /**
5691 Display Pcie device structure.
5692
5693 @param[in] PciExpressCap PCI Express capability buffer.
5694 @param[in] ExtendedConfigSpace PCI Express extended configuration space.
5695 @param[in] ExtendedCapability PCI Express extended capability ID to explain.
5696 **/
5697 VOID
5698 PciExplainPciExpress (
5699 IN PCI_CAPABILITY_PCIEXP *PciExpressCap,
5700 IN UINT8 *ExtendedConfigSpace,
5701 IN CONST UINT16 ExtendedCapability
5702 )
5703 {
5704 UINT8 DevicePortType;
5705 UINTN Index;
5706 UINT8 *RegAddr;
5707 UINTN RegValue;
5708 PCI_EXP_EXT_HDR *ExtHdr;
5709
5710 DevicePortType = (UINT8)PciExpressCap->Capability.Bits.DevicePortType;
5711
5712 ShellPrintEx (-1, -1, L"\r\nPci Express device capability structure:\r\n");
5713
5714 for (Index = 0; PcieExplainList[Index].Type < PcieExplainTypeMax; Index++) {
5715 if (ShellGetExecutionBreakFlag()) {
5716 return;
5717 }
5718 RegAddr = (UINT8 *) PciExpressCap + PcieExplainList[Index].Offset;
5719 switch (PcieExplainList[Index].Width) {
5720 case FieldWidthUINT8:
5721 RegValue = *(UINT8 *) RegAddr;
5722 break;
5723 case FieldWidthUINT16:
5724 RegValue = *(UINT16 *) RegAddr;
5725 break;
5726 case FieldWidthUINT32:
5727 RegValue = *(UINT32 *) RegAddr;
5728 break;
5729 default:
5730 RegValue = 0;
5731 break;
5732 }
5733 ShellPrintHiiEx(-1, -1, NULL,
5734 PcieExplainList[Index].Token,
5735 gShellDebug1HiiHandle,
5736 PcieExplainList[Index].Offset,
5737 RegValue
5738 );
5739 if (PcieExplainList[Index].Func == NULL) {
5740 continue;
5741 }
5742 switch (PcieExplainList[Index].Type) {
5743 case PcieExplainTypeLink:
5744 //
5745 // Link registers should not be used by
5746 // a) Root Complex Integrated Endpoint
5747 // b) Root Complex Event Collector
5748 //
5749 if (DevicePortType == PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_INTEGRATED_ENDPOINT ||
5750 DevicePortType == PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_EVENT_COLLECTOR) {
5751 continue;
5752 }
5753 break;
5754 case PcieExplainTypeSlot:
5755 //
5756 // Slot registers are only valid for
5757 // a) Root Port of PCI Express Root Complex
5758 // b) Downstream Port of PCI Express Switch
5759 // and when SlotImplemented bit is set in PCIE cap register.
5760 //
5761 if ((DevicePortType != PCIE_DEVICE_PORT_TYPE_ROOT_PORT &&
5762 DevicePortType != PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT) ||
5763 !PciExpressCap->Capability.Bits.SlotImplemented) {
5764 continue;
5765 }
5766 break;
5767 case PcieExplainTypeRoot:
5768 //
5769 // Root registers are only valid for
5770 // Root Port of PCI Express Root Complex
5771 //
5772 if (DevicePortType != PCIE_DEVICE_PORT_TYPE_ROOT_PORT) {
5773 continue;
5774 }
5775 break;
5776 default:
5777 break;
5778 }
5779 PcieExplainList[Index].Func (PciExpressCap);
5780 }
5781
5782 ExtHdr = (PCI_EXP_EXT_HDR*)ExtendedConfigSpace;
5783 while (ExtHdr->CapabilityId != 0 && ExtHdr->CapabilityVersion != 0) {
5784 //
5785 // Process this item
5786 //
5787 if (ExtendedCapability == 0xFFFF || ExtendedCapability == ExtHdr->CapabilityId) {
5788 //
5789 // Print this item
5790 //
5791 PrintPciExtendedCapabilityDetails((PCI_EXP_EXT_HDR*)ExtendedConfigSpace, ExtHdr, PciExpressCap);
5792 }
5793
5794 //
5795 // Advance to the next item if it exists
5796 //
5797 if (ExtHdr->NextCapabilityOffset != 0) {
5798 ExtHdr = (PCI_EXP_EXT_HDR*)(ExtendedConfigSpace + ExtHdr->NextCapabilityOffset - EFI_PCIE_CAPABILITY_BASE_OFFSET);
5799 } else {
5800 break;
5801 }
5802 }
5803 }