1 /* $OpenBSD: virtio_pci.c,v 1.6 2013/03/10 21:58:02 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/kernel.h> 33 #include <sys/device.h> 34 #include <sys/mutex.h> 35 36 #include <dev/pci/pcidevs.h> 37 #include <dev/pci/pcireg.h> 38 #include <dev/pci/pcivar.h> 39 40 #include <dev/pci/virtioreg.h> 41 #include <dev/pci/virtiovar.h> 42 43 /* 44 * XXX: Before being used on big endian arches, the access to config registers 45 * XXX: needs to be reviewed/fixed. The non-device specific registers are 46 * XXX: PCI-endian while the device specific registers are native endian. 47 */ 48 49 #define virtio_set_status(sc, s) virtio_pci_set_status(sc, s) 50 #define virtio_device_reset(sc) virtio_set_status((sc), 0) 51 52 int virtio_pci_match(struct device *, void *, void *); 53 void virtio_pci_attach(struct device *, struct device *, void *); 54 int virtio_pci_detach(struct device *, int); 55 56 void virtio_pci_kick(struct virtio_softc *, uint16_t); 57 uint8_t virtio_pci_read_device_config_1(struct virtio_softc *, int); 58 uint16_t virtio_pci_read_device_config_2(struct virtio_softc *, int); 59 uint32_t virtio_pci_read_device_config_4(struct virtio_softc *, int); 60 uint64_t virtio_pci_read_device_config_8(struct virtio_softc *, int); 61 void virtio_pci_write_device_config_1(struct virtio_softc *, int, uint8_t); 62 void virtio_pci_write_device_config_2(struct virtio_softc *, int, uint16_t); 63 void virtio_pci_write_device_config_4(struct virtio_softc *, int, uint32_t); 64 void virtio_pci_write_device_config_8(struct virtio_softc *, int, uint64_t); 65 uint16_t virtio_pci_read_queue_size(struct virtio_softc *, uint16_t); 66 void virtio_pci_setup_queue(struct virtio_softc *, uint16_t, uint32_t); 67 void virtio_pci_set_status(struct virtio_softc *, int); 68 uint32_t virtio_pci_negotiate_features(struct virtio_softc *, uint32_t, 69 const struct virtio_feature_name *); 70 int virtio_pci_intr(void *); 71 72 struct virtio_pci_softc { 73 struct virtio_softc sc_sc; 74 pci_chipset_tag_t sc_pc; 75 76 bus_space_tag_t sc_iot; 77 bus_space_handle_t sc_ioh; 78 bus_size_t sc_iosize; 79 80 void *sc_ih; 81 82 int sc_config_offset; 83 }; 84 85 struct cfattach virtio_pci_ca = { 86 sizeof(struct virtio_pci_softc), 87 virtio_pci_match, 88 virtio_pci_attach, 89 virtio_pci_detach, 90 NULL 91 }; 92 93 struct virtio_ops virtio_pci_ops = { 94 virtio_pci_kick, 95 virtio_pci_read_device_config_1, 96 virtio_pci_read_device_config_2, 97 virtio_pci_read_device_config_4, 98 virtio_pci_read_device_config_8, 99 virtio_pci_write_device_config_1, 100 virtio_pci_write_device_config_2, 101 virtio_pci_write_device_config_4, 102 virtio_pci_write_device_config_8, 103 virtio_pci_read_queue_size, 104 virtio_pci_setup_queue, 105 virtio_pci_set_status, 106 virtio_pci_negotiate_features, 107 virtio_pci_intr, 108 }; 109 110 uint16_t 111 virtio_pci_read_queue_size(struct virtio_softc *vsc, uint16_t idx) 112 { 113 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 114 bus_space_write_2(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_QUEUE_SELECT, 115 idx); 116 return bus_space_read_2(sc->sc_iot, sc->sc_ioh, 117 VIRTIO_CONFIG_QUEUE_SIZE); 118 } 119 120 void 121 virtio_pci_setup_queue(struct virtio_softc *vsc, uint16_t idx, uint32_t addr) 122 { 123 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 124 bus_space_write_2(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_QUEUE_SELECT, 125 idx); 126 bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_QUEUE_ADDRESS, 127 addr); 128 } 129 130 void 131 virtio_pci_set_status(struct virtio_softc *vsc, int status) 132 { 133 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 134 int old = 0; 135 136 if (status != 0) 137 old = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 138 VIRTIO_CONFIG_DEVICE_STATUS); 139 bus_space_write_1(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_DEVICE_STATUS, 140 status|old); 141 } 142 143 int 144 virtio_pci_match(struct device *parent, void *match, void *aux) 145 { 146 struct pci_attach_args *pa; 147 148 pa = (struct pci_attach_args *)aux; 149 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_QUMRANET && 150 PCI_PRODUCT(pa->pa_id) >= 0x1000 && 151 PCI_PRODUCT(pa->pa_id) <= 0x103f && 152 PCI_REVISION(pa->pa_class) == 0) 153 return 1; 154 return 0; 155 } 156 157 void 158 virtio_pci_attach(struct device *parent, struct device *self, void *aux) 159 { 160 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)self; 161 struct virtio_softc *vsc = &sc->sc_sc; 162 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 163 pci_chipset_tag_t pc = pa->pa_pc; 164 pcitag_t tag = pa->pa_tag; 165 int revision; 166 pcireg_t id; 167 char const *intrstr; 168 pci_intr_handle_t ih; 169 170 revision = PCI_REVISION(pa->pa_class); 171 if (revision != 0) { 172 printf("unknown revision 0x%02x; giving up\n", revision); 173 return; 174 } 175 176 /* subsystem ID shows what I am */ 177 id = PCI_PRODUCT(pci_conf_read(pc, tag, PCI_SUBSYS_ID_REG)); 178 printf(": Virtio %s Device", virtio_device_string(id)); 179 180 #ifdef notyet 181 if (pci_get_capability(pc, tag, PCI_CAP_MSIX, NULL, NULL)) 182 printf(", msix capable"); 183 #endif 184 printf("\n"); 185 186 vsc->sc_ops = &virtio_pci_ops; 187 sc->sc_pc = pc; 188 vsc->sc_dmat = pa->pa_dmat; 189 sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI; 190 191 if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0, 192 &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize, 0)) { 193 printf("%s: can't map i/o space\n", vsc->sc_dev.dv_xname); 194 return; 195 } 196 197 virtio_device_reset(vsc); 198 virtio_pci_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_ACK); 199 virtio_pci_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER); 200 201 /* XXX: use softc as aux... */ 202 vsc->sc_childdevid = id; 203 vsc->sc_child = NULL; 204 config_found(self, sc, NULL); 205 if (vsc->sc_child == NULL) { 206 printf("%s: no matching child driver; not configured\n", 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", vsc->sc_dev.dv_xname); 211 goto fail_1; 212 } 213 214 if (pci_intr_map(pa, &ih)) { 215 printf("%s: couldn't map interrupt\n", vsc->sc_dev.dv_xname); 216 goto fail_2; 217 } 218 intrstr = pci_intr_string(pc, ih); 219 sc->sc_ih = pci_intr_establish(pc, ih, vsc->sc_ipl, virtio_pci_intr, sc, vsc->sc_dev.dv_xname); 220 if (sc->sc_ih == NULL) { 221 printf("%s: couldn't establish interrupt", vsc->sc_dev.dv_xname); 222 if (intrstr != NULL) 223 printf(" at %s", intrstr); 224 printf("\n"); 225 goto fail_2; 226 } 227 printf("%s: %s\n", vsc->sc_dev.dv_xname, intrstr); 228 229 virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK); 230 return; 231 232 fail_2: 233 config_detach(vsc->sc_child, 0); 234 fail_1: 235 /* no pci_mapreg_unmap() or pci_intr_unmap() */ 236 virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); 237 } 238 239 int 240 virtio_pci_detach(struct device *self, int flags) 241 { 242 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)self; 243 struct virtio_softc *vsc = &sc->sc_sc; 244 int r; 245 246 if (vsc->sc_child != 0 && vsc->sc_child != VIRTIO_CHILD_ERROR) { 247 r = config_detach(vsc->sc_child, flags); 248 if (r) 249 return r; 250 } 251 KASSERT(vsc->sc_child == 0 || vsc->sc_child == VIRTIO_CHILD_ERROR); 252 KASSERT(vsc->sc_vqs == 0); 253 pci_intr_disestablish(sc->sc_pc, sc->sc_ih); 254 sc->sc_ih = 0; 255 if (sc->sc_iosize) 256 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize); 257 sc->sc_iosize = 0; 258 259 return 0; 260 } 261 262 /* 263 * Feature negotiation. 264 * Prints available / negotiated features if guest_feature_names != NULL and 265 * VIRTIO_DEBUG is 1 266 */ 267 uint32_t 268 virtio_pci_negotiate_features(struct virtio_softc *vsc, uint32_t guest_features, 269 const struct virtio_feature_name *guest_feature_names) 270 { 271 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 272 uint32_t host, neg; 273 274 /* 275 * indirect descriptors can be switched off by setting bit 1 in the 276 * driver flags, see config(8) 277 */ 278 if (!(vsc->sc_dev.dv_cfdata->cf_flags & 1) && 279 !(vsc->sc_child->dv_cfdata->cf_flags & 1)) { 280 guest_features |= VIRTIO_F_RING_INDIRECT_DESC; 281 } else { 282 printf("RingIndirectDesc disabled by UKC\n"); 283 } 284 host = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 285 VIRTIO_CONFIG_DEVICE_FEATURES); 286 neg = host & guest_features; 287 #if VIRTIO_DEBUG 288 if (guest_feature_names) 289 virtio_log_features(host, neg, guest_feature_names); 290 #endif 291 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 292 VIRTIO_CONFIG_GUEST_FEATURES, neg); 293 vsc->sc_features = neg; 294 if (neg & VIRTIO_F_RING_INDIRECT_DESC) 295 vsc->sc_indirect = 1; 296 else 297 vsc->sc_indirect = 0; 298 299 return neg; 300 } 301 302 /* 303 * Device configuration registers. 304 */ 305 uint8_t 306 virtio_pci_read_device_config_1(struct virtio_softc *vsc, int index) 307 { 308 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 309 return bus_space_read_1(sc->sc_iot, sc->sc_ioh, 310 sc->sc_config_offset + index); 311 } 312 313 uint16_t 314 virtio_pci_read_device_config_2(struct virtio_softc *vsc, int index) 315 { 316 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 317 return bus_space_read_2(sc->sc_iot, sc->sc_ioh, 318 sc->sc_config_offset + index); 319 } 320 321 uint32_t 322 virtio_pci_read_device_config_4(struct virtio_softc *vsc, int index) 323 { 324 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 325 return bus_space_read_4(sc->sc_iot, sc->sc_ioh, 326 sc->sc_config_offset + index); 327 } 328 329 uint64_t 330 virtio_pci_read_device_config_8(struct virtio_softc *vsc, int index) 331 { 332 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 333 uint64_t r; 334 335 r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 336 sc->sc_config_offset + index + sizeof(uint32_t)); 337 r <<= 32; 338 r += bus_space_read_4(sc->sc_iot, sc->sc_ioh, 339 sc->sc_config_offset + index); 340 return r; 341 } 342 343 void 344 virtio_pci_write_device_config_1(struct virtio_softc *vsc, 345 int index, uint8_t value) 346 { 347 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 348 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 349 sc->sc_config_offset + index, value); 350 } 351 352 void 353 virtio_pci_write_device_config_2(struct virtio_softc *vsc, 354 int index, uint16_t value) 355 { 356 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 357 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 358 sc->sc_config_offset + index, value); 359 } 360 361 void 362 virtio_pci_write_device_config_4(struct virtio_softc *vsc, 363 int index, uint32_t value) 364 { 365 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 366 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 367 sc->sc_config_offset + index, value); 368 } 369 370 void 371 virtio_pci_write_device_config_8(struct virtio_softc *vsc, 372 int index, uint64_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, 377 value & 0xffffffff); 378 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 379 sc->sc_config_offset + index + sizeof(uint32_t), 380 value >> 32); 381 } 382 383 /* 384 * Interrupt handler. 385 */ 386 int 387 virtio_pci_intr(void *arg) 388 { 389 struct virtio_pci_softc *sc = arg; 390 struct virtio_softc *vsc = &sc->sc_sc; 391 int isr, r = 0; 392 393 /* check and ack the interrupt */ 394 isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 395 VIRTIO_CONFIG_ISR_STATUS); 396 if (isr == 0) 397 return 0; 398 if ((isr & VIRTIO_CONFIG_ISR_CONFIG_CHANGE) && 399 (vsc->sc_config_change != NULL)) 400 r = (vsc->sc_config_change)(vsc); 401 if (vsc->sc_intrhand != NULL) 402 r |= (vsc->sc_intrhand)(vsc); 403 404 return r; 405 } 406 407 void 408 virtio_pci_kick(struct virtio_softc *vsc, uint16_t idx) 409 { 410 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 411 bus_space_write_2(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_QUEUE_NOTIFY, 412 idx); 413 } 414