1 /* $OpenBSD: virtio_pci.c,v 1.11 2015/07/18 16:35:33 sf 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", 206 vsc->sc_dev.dv_xname); 207 goto fail_1; 208 } 209 if (vsc->sc_child == VIRTIO_CHILD_ERROR) { 210 printf("%s: virtio configuration failed\n", 211 vsc->sc_dev.dv_xname); 212 goto fail_1; 213 } 214 215 if (pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) { 216 printf("%s: couldn't map interrupt\n", vsc->sc_dev.dv_xname); 217 goto fail_2; 218 } 219 intrstr = pci_intr_string(pc, ih); 220 /* 221 * We always set the IPL_MPSAFE flag in order to do the relatively 222 * expensive ISR read without lock, and then grab the kernel lock in 223 * the interrupt handler. 224 * For now, we don't support IPL_MPSAFE vq_done functions. 225 */ 226 KASSERT((vsc->sc_ipl & IPL_MPSAFE) == 0); 227 sc->sc_ih = pci_intr_establish(pc, ih, vsc->sc_ipl | IPL_MPSAFE, 228 virtio_pci_intr, sc, vsc->sc_dev.dv_xname); 229 if (sc->sc_ih == NULL) { 230 printf("%s: couldn't establish interrupt", vsc->sc_dev.dv_xname); 231 if (intrstr != NULL) 232 printf(" at %s", intrstr); 233 printf("\n"); 234 goto fail_2; 235 } 236 printf("%s: %s\n", vsc->sc_dev.dv_xname, intrstr); 237 238 virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK); 239 return; 240 241 fail_2: 242 config_detach(vsc->sc_child, 0); 243 fail_1: 244 /* no pci_mapreg_unmap() or pci_intr_unmap() */ 245 virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); 246 } 247 248 int 249 virtio_pci_detach(struct device *self, int flags) 250 { 251 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)self; 252 struct virtio_softc *vsc = &sc->sc_sc; 253 int r; 254 255 if (vsc->sc_child != 0 && vsc->sc_child != VIRTIO_CHILD_ERROR) { 256 r = config_detach(vsc->sc_child, flags); 257 if (r) 258 return r; 259 } 260 KASSERT(vsc->sc_child == 0 || vsc->sc_child == VIRTIO_CHILD_ERROR); 261 KASSERT(vsc->sc_vqs == 0); 262 pci_intr_disestablish(sc->sc_pc, sc->sc_ih); 263 sc->sc_ih = 0; 264 if (sc->sc_iosize) 265 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize); 266 sc->sc_iosize = 0; 267 268 return 0; 269 } 270 271 /* 272 * Feature negotiation. 273 * Prints available / negotiated features if guest_feature_names != NULL and 274 * VIRTIO_DEBUG is 1 275 */ 276 uint32_t 277 virtio_pci_negotiate_features(struct virtio_softc *vsc, uint32_t guest_features, 278 const struct virtio_feature_name *guest_feature_names) 279 { 280 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 281 uint32_t host, neg; 282 283 /* 284 * indirect descriptors can be switched off by setting bit 1 in the 285 * driver flags, see config(8) 286 */ 287 if (!(vsc->sc_dev.dv_cfdata->cf_flags & 1) && 288 !(vsc->sc_child->dv_cfdata->cf_flags & 1)) { 289 guest_features |= VIRTIO_F_RING_INDIRECT_DESC; 290 } else { 291 printf("RingIndirectDesc disabled by UKC\n"); 292 } 293 host = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 294 VIRTIO_CONFIG_DEVICE_FEATURES); 295 neg = host & guest_features; 296 #if VIRTIO_DEBUG 297 if (guest_feature_names) 298 virtio_log_features(host, neg, guest_feature_names); 299 #endif 300 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 301 VIRTIO_CONFIG_GUEST_FEATURES, neg); 302 vsc->sc_features = neg; 303 if (neg & VIRTIO_F_RING_INDIRECT_DESC) 304 vsc->sc_indirect = 1; 305 else 306 vsc->sc_indirect = 0; 307 308 return neg; 309 } 310 311 /* 312 * Device configuration registers. 313 */ 314 uint8_t 315 virtio_pci_read_device_config_1(struct virtio_softc *vsc, int index) 316 { 317 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 318 return bus_space_read_1(sc->sc_iot, sc->sc_ioh, 319 sc->sc_config_offset + index); 320 } 321 322 uint16_t 323 virtio_pci_read_device_config_2(struct virtio_softc *vsc, int index) 324 { 325 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 326 return bus_space_read_2(sc->sc_iot, sc->sc_ioh, 327 sc->sc_config_offset + index); 328 } 329 330 uint32_t 331 virtio_pci_read_device_config_4(struct virtio_softc *vsc, int index) 332 { 333 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 334 return bus_space_read_4(sc->sc_iot, sc->sc_ioh, 335 sc->sc_config_offset + index); 336 } 337 338 uint64_t 339 virtio_pci_read_device_config_8(struct virtio_softc *vsc, int index) 340 { 341 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 342 uint64_t r; 343 344 r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 345 sc->sc_config_offset + index + sizeof(uint32_t)); 346 r <<= 32; 347 r += bus_space_read_4(sc->sc_iot, sc->sc_ioh, 348 sc->sc_config_offset + index); 349 return r; 350 } 351 352 void 353 virtio_pci_write_device_config_1(struct virtio_softc *vsc, int index, 354 uint8_t value) 355 { 356 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 357 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 358 sc->sc_config_offset + index, value); 359 } 360 361 void 362 virtio_pci_write_device_config_2(struct virtio_softc *vsc, int index, 363 uint16_t value) 364 { 365 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 366 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 367 sc->sc_config_offset + index, value); 368 } 369 370 void 371 virtio_pci_write_device_config_4(struct virtio_softc *vsc, 372 int index, uint32_t value) 373 { 374 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 375 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 376 sc->sc_config_offset + index, value); 377 } 378 379 void 380 virtio_pci_write_device_config_8(struct virtio_softc *vsc, 381 int index, uint64_t value) 382 { 383 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 384 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 385 sc->sc_config_offset + index, value & 0xffffffff); 386 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 387 sc->sc_config_offset + index + sizeof(uint32_t), value >> 32); 388 } 389 390 /* 391 * Interrupt handler. 392 */ 393 int 394 virtio_pci_intr(void *arg) 395 { 396 struct virtio_pci_softc *sc = arg; 397 struct virtio_softc *vsc = &sc->sc_sc; 398 int isr, r = 0; 399 400 /* check and ack the interrupt */ 401 isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 402 VIRTIO_CONFIG_ISR_STATUS); 403 if (isr == 0) 404 return 0; 405 KERNEL_LOCK(); 406 if ((isr & VIRTIO_CONFIG_ISR_CONFIG_CHANGE) && 407 (vsc->sc_config_change != NULL)) 408 r = (vsc->sc_config_change)(vsc); 409 if (vsc->sc_intrhand != NULL) 410 r |= (vsc->sc_intrhand)(vsc); 411 KERNEL_UNLOCK(); 412 413 return r; 414 } 415 416 void 417 virtio_pci_kick(struct virtio_softc *vsc, uint16_t idx) 418 { 419 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 420 bus_space_write_2(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_QUEUE_NOTIFY, 421 idx); 422 } 423