]> mj.ucw.cz Git - pciutils.git/blob - ls-caps-vendor.c
lspci: add VirtIO SharedMemory capability support
[pciutils.git] / ls-caps-vendor.c
1 /*
2  *      The PCI Utilities -- Show Vendor-specific Capabilities
3  *
4  *      Copyright (c) 2014 Gerd Hoffmann <kraxel@redhat.com>
5  *
6  *      Can be freely distributed and used under the terms of the GNU GPL v2+.
7  *
8  *      SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include <stdio.h>
12 #include <string.h>
13
14 #include "lspci.h"
15
16 static int
17 show_vendor_caps_virtio(struct device *d, int where, int cap)
18 {
19   int length = BITS(cap, 0, 8);
20   int type = BITS(cap, 8, 8);
21   char *tname;
22
23   if (length < 16)
24     return 0;
25   if (!config_fetch(d, where, length))
26     return 0;
27
28   switch (type)
29     {
30     case 1:
31       tname = "CommonCfg";
32       break;
33     case 2:
34       tname = "Notify";
35       break;
36     case 3:
37       tname = "ISR";
38       break;
39     case 4:
40       tname = "DeviceCfg";
41       break;
42     default:
43       tname = "<unknown>";
44       break;
45     }
46
47   printf("VirtIO: %s\n", tname);
48
49   if (verbose < 2)
50     return 1;
51
52   printf("\t\tBAR=%d offset=%08x size=%08x",
53          get_conf_byte(d, where +  4),
54          get_conf_long(d, where +  8),
55          get_conf_long(d, where + 12));
56
57   if (type == 2 && length >= 20)
58     printf(" multiplier=%08x", get_conf_long(d, where+16));
59
60   printf("\n");
61   return 1;
62 }
63
64 static int
65 show_vendor_caps_intel(struct device *d, int where, int cap)
66 {
67   int length = BITS(cap, 0, 8);
68   int version = BITS(cap, 8, 4);
69   int type = BITS(cap, 12, 4);
70   u32 l;
71
72   if (type == 0)
73     {
74       printf("Intel Capabilities v%d\n", version);
75       /*
76        * Intel Capabilities is used at least on Intel Host Bridge / DRAM Controller
77        * and Intel Integrated Graphics Controller. Format of the CAPID0_<X>
78        * registers parsed below matches Cap Version 1 which is used since second
79        * generation of the Intel Core processors (Sandy Bridge). Parsing of other
80        * versions is not currently supported.
81        */
82       if (version != 1)
83         return 1;
84     }
85   else if (type == 1)
86     {
87       printf("Intel Feature Detection\n");
88       /*
89        * Intel Feature Detection Capabilities is used on Intel LPC Controller.
90        * Capabilities are accessed indirectly by writing indirect capability
91        * register to PCI config space. Because lspci cannot write to PCI config
92        * space, it is not possible to read or parse Intel Feature Vector Space.
93        */
94       return 1;
95     }
96   else
97     {
98       printf("Intel <unknown>\n");
99       return 1;
100     }
101
102   if (!config_fetch(d, where, length))
103     return 0;
104
105   /* CAPID0_A */
106   if (length >= 8)
107     {
108       l = get_conf_long(d, where + 4);
109       printf("\t\tCapA:");
110       printf(" Peg60Dis%c", FLAG(l, BIT(31)));
111       printf(" Peg12Dis%c", FLAG(l, BIT(30)));
112       printf(" Peg11Dis%c", FLAG(l, BIT(29)));
113       printf(" Peg10Dis%c", FLAG(l, BIT(28)));
114       printf(" PeLWUDis%c", FLAG(l, BIT(27)));
115       printf(" DmiWidth=x%u", (l & BIT(26)) ? 2 : 4);
116       printf("\n\t\t     ");
117       printf(" EccDis%c", FLAG(l, BIT(25)));
118       printf(" ForceEccEn%c", FLAG(l, BIT(24)));
119       printf(" VTdDis%c", FLAG(l, BIT(23)));
120       printf(" DmiG2Dis%c", FLAG(l, BIT(22)));
121       printf(" PegG2Dis%c", FLAG(l, BIT(21)));
122       printf(" DDRMaxSize=");
123       if (BITS(l, 19, 2) == 0)
124         printf("Unlimited");
125       else
126         printf("%gGB/chan", 512 * (1 << ((3-BITS(l, 19, 2))*2)) / 1024.0);
127       printf("\n\t\t     ");
128       printf(" 1NDis%c", FLAG(l, BIT(17)));
129       printf(" CDDis%c", FLAG(l, BIT(15)));
130       printf(" DDPCDis%c", FLAG(l, BIT(14)));
131       printf(" X2APICEn%c", FLAG(l, BIT(13)));
132       printf(" PDCDis%c", FLAG(l, BIT(12)));
133       printf(" IGDis%c", FLAG(l, BIT(11)));
134       printf(" CDID=%u", BITS(l, 8, 2));
135       printf(" CRID=%u", BITS(l, 4, 4));
136       printf("\n\t\t     ");
137       printf(" DDROCCAP%c", FLAG(l, BIT(3)));
138       printf(" OCEn%c", FLAG(l, BIT(2)));
139       printf(" DDRWrtVrefEn%c", FLAG(l, BIT(1)));
140       printf(" DDR3LEn%c", FLAG(l, BIT(0)));
141       printf("\n");
142     }
143
144   /* CAPID0_B */
145   if (length >= 12)
146     {
147       l = get_conf_long(d, where + 8);
148       printf("\t\tCapB:");
149       printf(" ImguDis%c", FLAG(l, BIT(31)));
150       printf(" OCbySSKUCap%c", FLAG(l, BIT(30)));
151       printf(" OCbySSKUEn%c", FLAG(l, BIT(29)));
152       printf(" SMTCap%c", FLAG(l, BIT(28)));
153       printf(" CacheSzCap 0x%x", BITS(l, 25, 3));
154       printf("\n\t\t     ");
155       printf(" SoftBinCap%c", FLAG(l, BIT(24)));
156       printf(" DDR3MaxFreqWithRef100=");
157       if (BITS(l, 21, 3) == 0)
158         printf("Disabled");
159       else if (BITS(l, 21, 3) == 7)
160         printf("Unlimited");
161       else
162         printf("%uMHz", (6+BITS(l, 21, 3)) * 200);
163       printf(" PegG3Dis%c", FLAG(l, BIT(20)));
164       printf("\n\t\t     ");
165       printf(" PkgTyp%c", FLAG(l, BIT(19)));
166       printf(" AddGfxEn%c", FLAG(l, BIT(18)));
167       printf(" AddGfxCap%c", FLAG(l, BIT(17)));
168       printf(" PegX16Dis%c", FLAG(l, BIT(16)));
169       printf(" DmiG3Dis%c", FLAG(l, BIT(15)));
170       printf(" GmmDis%c", FLAG(l, BIT(8)));
171       printf("\n\t\t     ");
172       printf(" DDR3MaxFreq=%uMHz", (11-BITS(l, 4, 2)) * 2666 / 10);
173       printf(" LPDDR3En%c", FLAG(l, BIT(2)));
174       printf("\n");
175     }
176
177   /* CAPID0_C */
178   if (length >= 16)
179     {
180       l = get_conf_long(d, where + 12);
181       printf("\t\tCapC:");
182       printf(" PegG4Dis%c", FLAG(l, BIT(28)));
183       printf(" DDR4MaxFreq=");
184       if (BITS(l, 23, 4) == 0)
185         printf("Unlimited");
186       else
187         printf("%uMHz", BITS(l, 0, 4) * 2666 / 10);
188       printf(" LPDDREn%c", FLAG(l, BIT(22)));
189       printf(" LPDDR4MaxFreq=");
190       if (BITS(l, 17, 4) == 0)
191         printf("Unlimited");
192       else
193         printf("%uMHz", BITS(l, 0, 4) * 2666 / 10);
194       printf(" LPDDR4En%c", FLAG(l, BIT(16)));
195       printf("\n\t\t     ");
196       printf(" QClkGvDis%c", FLAG(l, BIT(14)));
197       printf(" SgxDis%c", FLAG(l, BIT(9)));
198       printf(" BClkOC=%s", BITS(l, 7, 2) == 0 ? "Disabled" :
199                            BITS(l, 7, 2) == 1 ? "115MHz" :
200                            BITS(l, 7, 2) == 2 ? "130MHz" :
201                                                 "Unlimited");
202       printf(" IddDis%c", FLAG(l, BIT(6)));
203       printf(" Pipe3Dis%c", FLAG(l, BIT(5)));
204       printf(" Gear1MaxFreq=");
205       if (BITS(l, 0, 4) == 0)
206         printf("Unlimited");
207       else
208         printf("%uMHz", BITS(l, 0, 4) * 2666 / 10);
209       printf("\n");
210     }
211
212   return 1;
213 }
214
215 static int
216 do_show_vendor_caps(struct device *d, int where, int cap)
217 {
218   switch (d->dev->vendor_id)
219     {
220     case 0x1af4: /* Red Hat */
221       if (d->dev->device_id >= 0x1000 &&
222           d->dev->device_id <= 0x107f)
223         return show_vendor_caps_virtio(d, where, cap);
224       break;
225     case 0x8086: /* Intel */
226       return show_vendor_caps_intel(d, where, cap);
227     }
228   return 0;
229 }
230
231 void
232 show_vendor_caps(struct device *d, int where, int cap)
233 {
234   printf("Vendor Specific Information: ");
235   if (!do_show_vendor_caps(d, where, cap))
236     printf("Len=%02x <?>\n", BITS(cap, 0, 8));
237 }