xref: /openbsd-src/sys/dev/pci/virtio_pci.c (revision cb39b41371628601fbe4c618205356d538b9d08a)
1 /*	$OpenBSD: virtio_pci.c,v 1.9 2015/03/14 03:38:49 jsg Exp $	*/
2 /*	$NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $	*/
3 
4 /*
5  * Copyright (c) 2012 Stefan Fritsch.
6  * Copyright (c) 2010 Minoura Makoto.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/device.h>
33 #include <sys/mutex.h>
34 
35 #include <dev/pci/pcidevs.h>
36 #include <dev/pci/pcireg.h>
37 #include <dev/pci/pcivar.h>
38 
39 #include <dev/pci/virtioreg.h>
40 #include <dev/pci/virtiovar.h>
41 
42 /*
43  * XXX: Before being used on big endian arches, the access to config registers
44  * XXX: needs to be reviewed/fixed. The non-device specific registers are
45  * XXX: PCI-endian while the device specific registers are native endian.
46  */
47 
48 #define virtio_set_status(sc, s) virtio_pci_set_status(sc, s)
49 #define virtio_device_reset(sc) virtio_set_status((sc), 0)
50 
51 int		virtio_pci_match(struct device *, void *, void *);
52 void		virtio_pci_attach(struct device *, struct device *, void *);
53 int		virtio_pci_detach(struct device *, int);
54 
55 void		virtio_pci_kick(struct virtio_softc *, uint16_t);
56 uint8_t		virtio_pci_read_device_config_1(struct virtio_softc *, int);
57 uint16_t	virtio_pci_read_device_config_2(struct virtio_softc *, int);
58 uint32_t	virtio_pci_read_device_config_4(struct virtio_softc *, int);
59 uint64_t	virtio_pci_read_device_config_8(struct virtio_softc *, int);
60 void		virtio_pci_write_device_config_1(struct virtio_softc *, int, uint8_t);
61 void		virtio_pci_write_device_config_2(struct virtio_softc *, int, uint16_t);
62 void		virtio_pci_write_device_config_4(struct virtio_softc *, int, uint32_t);
63 void		virtio_pci_write_device_config_8(struct virtio_softc *, int, uint64_t);
64 uint16_t	virtio_pci_read_queue_size(struct virtio_softc *, uint16_t);
65 void		virtio_pci_setup_queue(struct virtio_softc *, uint16_t, uint32_t);
66 void		virtio_pci_set_status(struct virtio_softc *, int);
67 uint32_t	virtio_pci_negotiate_features(struct virtio_softc *, uint32_t,
68 					      const struct virtio_feature_name *);
69 int		virtio_pci_intr(void *);
70 
71 struct virtio_pci_softc {
72 	struct virtio_softc	sc_sc;
73 	pci_chipset_tag_t	sc_pc;
74 
75 	bus_space_tag_t		sc_iot;
76 	bus_space_handle_t	sc_ioh;
77 	bus_size_t		sc_iosize;
78 
79 	void                    *sc_ih;
80 
81 	int			sc_config_offset;
82 };
83 
84 struct cfattach virtio_pci_ca = {
85 	sizeof(struct virtio_pci_softc),
86 	virtio_pci_match,
87 	virtio_pci_attach,
88 	virtio_pci_detach,
89 	NULL
90 };
91 
92 struct virtio_ops virtio_pci_ops = {
93 	virtio_pci_kick,
94 	virtio_pci_read_device_config_1,
95 	virtio_pci_read_device_config_2,
96 	virtio_pci_read_device_config_4,
97 	virtio_pci_read_device_config_8,
98 	virtio_pci_write_device_config_1,
99 	virtio_pci_write_device_config_2,
100 	virtio_pci_write_device_config_4,
101 	virtio_pci_write_device_config_8,
102 	virtio_pci_read_queue_size,
103 	virtio_pci_setup_queue,
104 	virtio_pci_set_status,
105 	virtio_pci_negotiate_features,
106 	virtio_pci_intr,
107 };
108 
109 uint16_t
110 virtio_pci_read_queue_size(struct virtio_softc *vsc, uint16_t idx)
111 {
112 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
113 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_QUEUE_SELECT,
114 	    idx);
115 	return bus_space_read_2(sc->sc_iot, sc->sc_ioh,
116 	    VIRTIO_CONFIG_QUEUE_SIZE);
117 }
118 
119 void
120 virtio_pci_setup_queue(struct virtio_softc *vsc, uint16_t idx, uint32_t addr)
121 {
122 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
123 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_QUEUE_SELECT,
124 	    idx);
125 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_QUEUE_ADDRESS,
126 	    addr);
127 }
128 
129 void
130 virtio_pci_set_status(struct virtio_softc *vsc, int status)
131 {
132 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
133 	int old = 0;
134 
135 	if (status != 0)
136 		old = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
137 				       VIRTIO_CONFIG_DEVICE_STATUS);
138 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_DEVICE_STATUS,
139 			  status|old);
140 }
141 
142 int
143 virtio_pci_match(struct device *parent, void *match, void *aux)
144 {
145 	struct pci_attach_args *pa;
146 
147 	pa = (struct pci_attach_args *)aux;
148 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_QUMRANET &&
149 	    PCI_PRODUCT(pa->pa_id) >= 0x1000 &&
150 	    PCI_PRODUCT(pa->pa_id) <= 0x103f &&
151 	    PCI_REVISION(pa->pa_class) == 0)
152 		return 1;
153 	return 0;
154 }
155 
156 void
157 virtio_pci_attach(struct device *parent, struct device *self, void *aux)
158 {
159 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)self;
160 	struct virtio_softc *vsc = &sc->sc_sc;
161 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
162 	pci_chipset_tag_t pc = pa->pa_pc;
163 	pcitag_t tag = pa->pa_tag;
164 	int revision;
165 	pcireg_t id;
166 	char const *intrstr;
167 	pci_intr_handle_t ih;
168 
169 	revision = PCI_REVISION(pa->pa_class);
170 	if (revision != 0) {
171 		printf("unknown revision 0x%02x; giving up\n", revision);
172 		return;
173 	}
174 
175 	/* subsystem ID shows what I am */
176 	id = PCI_PRODUCT(pci_conf_read(pc, tag, PCI_SUBSYS_ID_REG));
177 	printf(": Virtio %s Device", virtio_device_string(id));
178 
179 #ifdef notyet
180 	if (pci_get_capability(pc, tag, PCI_CAP_MSIX, NULL, NULL))
181 		printf(", msix capable");
182 #endif
183 	printf("\n");
184 
185 	vsc->sc_ops = &virtio_pci_ops;
186 	sc->sc_pc = pc;
187 	vsc->sc_dmat = pa->pa_dmat;
188 	sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI;
189 
190 	if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0,
191 			   &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize, 0)) {
192 		printf("%s: can't map i/o space\n", vsc->sc_dev.dv_xname);
193 		return;
194 	}
195 
196 	virtio_device_reset(vsc);
197 	virtio_pci_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
198 	virtio_pci_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER);
199 
200 	/* XXX: use softc as aux... */
201 	vsc->sc_childdevid = id;
202 	vsc->sc_child = NULL;
203 	config_found(self, sc, NULL);
204 	if (vsc->sc_child == NULL) {
205 		printf("%s: no matching child driver; not configured\n", vsc->sc_dev.dv_xname);
206 		goto fail_1;
207 	}
208 	if (vsc->sc_child == VIRTIO_CHILD_ERROR) {
209 		printf("%s: virtio configuration failed\n", vsc->sc_dev.dv_xname);
210 		goto fail_1;
211 	}
212 
213 	if (pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
214 		printf("%s: couldn't map interrupt\n", vsc->sc_dev.dv_xname);
215 		goto fail_2;
216 	}
217 	intrstr = pci_intr_string(pc, ih);
218 	sc->sc_ih = pci_intr_establish(pc, ih, vsc->sc_ipl, virtio_pci_intr, sc, vsc->sc_dev.dv_xname);
219 	if (sc->sc_ih == NULL) {
220 		printf("%s: couldn't establish interrupt", vsc->sc_dev.dv_xname);
221 		if (intrstr != NULL)
222 			printf(" at %s", intrstr);
223 		printf("\n");
224 		goto fail_2;
225 	}
226 	printf("%s: %s\n", vsc->sc_dev.dv_xname, intrstr);
227 
228 	virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
229 	return;
230 
231 fail_2:
232 	config_detach(vsc->sc_child, 0);
233 fail_1:
234 	/* no pci_mapreg_unmap() or pci_intr_unmap() */
235 	virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
236 }
237 
238 int
239 virtio_pci_detach(struct device *self, int flags)
240 {
241 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)self;
242 	struct virtio_softc *vsc = &sc->sc_sc;
243 	int r;
244 
245 	if (vsc->sc_child != 0 && vsc->sc_child != VIRTIO_CHILD_ERROR) {
246 		r = config_detach(vsc->sc_child, flags);
247 		if (r)
248 			return r;
249 	}
250 	KASSERT(vsc->sc_child == 0 || vsc->sc_child == VIRTIO_CHILD_ERROR);
251 	KASSERT(vsc->sc_vqs == 0);
252 	pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
253 	sc->sc_ih = 0;
254 	if (sc->sc_iosize)
255 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize);
256 	sc->sc_iosize = 0;
257 
258 	return 0;
259 }
260 
261 /*
262  * Feature negotiation.
263  * Prints available / negotiated features if guest_feature_names != NULL and
264  * VIRTIO_DEBUG is 1
265  */
266 uint32_t
267 virtio_pci_negotiate_features(struct virtio_softc *vsc, uint32_t guest_features,
268 			  const struct virtio_feature_name *guest_feature_names)
269 {
270 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
271 	uint32_t host, neg;
272 
273 	/*
274 	 * indirect descriptors can be switched off by setting bit 1 in the
275 	 * driver flags, see config(8)
276 	 */
277 	if (!(vsc->sc_dev.dv_cfdata->cf_flags & 1) &&
278 	    !(vsc->sc_child->dv_cfdata->cf_flags & 1)) {
279 		guest_features |= VIRTIO_F_RING_INDIRECT_DESC;
280 	} else {
281 		printf("RingIndirectDesc disabled by UKC\n");
282 	}
283 	host = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
284 				VIRTIO_CONFIG_DEVICE_FEATURES);
285 	neg = host & guest_features;
286 #if VIRTIO_DEBUG
287 	if (guest_feature_names)
288 		virtio_log_features(host, neg, guest_feature_names);
289 #endif
290 	bus_space_write_4(sc->sc_iot, sc->sc_ioh,
291 			  VIRTIO_CONFIG_GUEST_FEATURES, neg);
292 	vsc->sc_features = neg;
293 	if (neg & VIRTIO_F_RING_INDIRECT_DESC)
294 		vsc->sc_indirect = 1;
295 	else
296 		vsc->sc_indirect = 0;
297 
298 	return neg;
299 }
300 
301 /*
302  * Device configuration registers.
303  */
304 uint8_t
305 virtio_pci_read_device_config_1(struct virtio_softc *vsc, int index)
306 {
307 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
308 	return bus_space_read_1(sc->sc_iot, sc->sc_ioh,
309 				sc->sc_config_offset + index);
310 }
311 
312 uint16_t
313 virtio_pci_read_device_config_2(struct virtio_softc *vsc, int index)
314 {
315 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
316 	return bus_space_read_2(sc->sc_iot, sc->sc_ioh,
317 				sc->sc_config_offset + index);
318 }
319 
320 uint32_t
321 virtio_pci_read_device_config_4(struct virtio_softc *vsc, int index)
322 {
323 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
324 	return bus_space_read_4(sc->sc_iot, sc->sc_ioh,
325 				sc->sc_config_offset + index);
326 }
327 
328 uint64_t
329 virtio_pci_read_device_config_8(struct virtio_softc *vsc, int index)
330 {
331 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
332 	uint64_t r;
333 
334 	r = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
335 			     sc->sc_config_offset + index + sizeof(uint32_t));
336 	r <<= 32;
337 	r += bus_space_read_4(sc->sc_iot, sc->sc_ioh,
338 			      sc->sc_config_offset + index);
339 	return r;
340 }
341 
342 void
343 virtio_pci_write_device_config_1(struct virtio_softc *vsc,
344 			     int index, uint8_t value)
345 {
346 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
347 	bus_space_write_1(sc->sc_iot, sc->sc_ioh,
348 			  sc->sc_config_offset + index, value);
349 }
350 
351 void
352 virtio_pci_write_device_config_2(struct virtio_softc *vsc,
353 			     int index, uint16_t value)
354 {
355 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
356 	bus_space_write_2(sc->sc_iot, sc->sc_ioh,
357 			  sc->sc_config_offset + index, value);
358 }
359 
360 void
361 virtio_pci_write_device_config_4(struct virtio_softc *vsc,
362 			     int index, uint32_t value)
363 {
364 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
365 	bus_space_write_4(sc->sc_iot, sc->sc_ioh,
366 			  sc->sc_config_offset + index, value);
367 }
368 
369 void
370 virtio_pci_write_device_config_8(struct virtio_softc *vsc,
371 			     int index, uint64_t value)
372 {
373 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
374 	bus_space_write_4(sc->sc_iot, sc->sc_ioh,
375 			  sc->sc_config_offset + index,
376 			  value & 0xffffffff);
377 	bus_space_write_4(sc->sc_iot, sc->sc_ioh,
378 			  sc->sc_config_offset + index + sizeof(uint32_t),
379 			  value >> 32);
380 }
381 
382 /*
383  * Interrupt handler.
384  */
385 int
386 virtio_pci_intr(void *arg)
387 {
388 	struct virtio_pci_softc *sc = arg;
389 	struct virtio_softc *vsc = &sc->sc_sc;
390 	int isr, r = 0;
391 
392 	/* check and ack the interrupt */
393 	isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
394 			       VIRTIO_CONFIG_ISR_STATUS);
395 	if (isr == 0)
396 		return 0;
397 	if ((isr & VIRTIO_CONFIG_ISR_CONFIG_CHANGE) &&
398 	    (vsc->sc_config_change != NULL))
399 		r = (vsc->sc_config_change)(vsc);
400 	if (vsc->sc_intrhand != NULL)
401 		r |= (vsc->sc_intrhand)(vsc);
402 
403 	return r;
404 }
405 
406 void
407 virtio_pci_kick(struct virtio_softc *vsc, uint16_t idx)
408 {
409 	struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc;
410 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_QUEUE_NOTIFY,
411 	    idx);
412 }
413