1 /*- 2 * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> 3 * Copyright (c) 2014 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * This software was developed by SRI International and the University of 7 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 8 * ("CTSRD"), as part of the DARPA CRASH research programme. 9 * 10 * Portions of this software were developed by Andrew Turner 11 * under sponsorship from the FreeBSD Foundation. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 /* 36 * VirtIO MMIO interface. 37 * This driver is heavily based on VirtIO PCI interface driver. 38 */ 39 40 /* 41 * FDT example: 42 * virtio_block@1000 { 43 * compatible = "virtio,mmio"; 44 * reg = <0x1000 0x100>; 45 * interrupts = <63>; 46 * interrupt-parent = <&GIC>; 47 * }; 48 */ 49 50 #include <sys/cdefs.h> 51 __FBSDID("$FreeBSD$"); 52 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/bus.h> 56 #include <sys/kernel.h> 57 #include <sys/module.h> 58 #include <sys/malloc.h> 59 #include <sys/rman.h> 60 61 #include <machine/bus.h> 62 #include <machine/resource.h> 63 64 #include <dev/fdt/fdt_common.h> 65 #include <dev/ofw/openfirm.h> 66 #include <dev/ofw/ofw_bus.h> 67 #include <dev/ofw/ofw_bus_subr.h> 68 69 #include <dev/virtio/virtio.h> 70 #include <dev/virtio/virtqueue.h> 71 #include <dev/virtio/mmio/virtio_mmio.h> 72 73 #include "virtio_mmio_if.h" 74 #include "virtio_bus_if.h" 75 #include "virtio_if.h" 76 77 #define PAGE_SHIFT 12 78 79 struct vtmmio_virtqueue { 80 struct virtqueue *vtv_vq; 81 int vtv_no_intr; 82 }; 83 84 struct vtmmio_softc { 85 device_t dev; 86 device_t platform; 87 struct resource *res[2]; 88 89 uint64_t vtmmio_features; 90 uint32_t vtmmio_flags; 91 92 /* This "bus" will only ever have one child. */ 93 device_t vtmmio_child_dev; 94 struct virtio_feature_desc *vtmmio_child_feat_desc; 95 96 int vtmmio_nvqs; 97 struct vtmmio_virtqueue *vtmmio_vqs; 98 void *ih; 99 }; 100 101 static int vtmmio_probe(device_t); 102 static int vtmmio_attach(device_t); 103 static int vtmmio_detach(device_t); 104 static int vtmmio_suspend(device_t); 105 static int vtmmio_resume(device_t); 106 static int vtmmio_shutdown(device_t); 107 static void vtmmio_driver_added(device_t, driver_t *); 108 static void vtmmio_child_detached(device_t, device_t); 109 static int vtmmio_read_ivar(device_t, device_t, int, uintptr_t *); 110 static int vtmmio_write_ivar(device_t, device_t, int, uintptr_t); 111 static uint64_t vtmmio_negotiate_features(device_t, uint64_t); 112 static int vtmmio_with_feature(device_t, uint64_t); 113 static int vtmmio_alloc_virtqueues(device_t, int, int, 114 struct vq_alloc_info *); 115 static int vtmmio_setup_intr(device_t, enum intr_type); 116 static void vtmmio_stop(device_t); 117 static void vtmmio_poll(device_t); 118 static int vtmmio_reinit(device_t, uint64_t); 119 static void vtmmio_reinit_complete(device_t); 120 static void vtmmio_notify_virtqueue(device_t, uint16_t); 121 static uint8_t vtmmio_get_status(device_t); 122 static void vtmmio_set_status(device_t, uint8_t); 123 static void vtmmio_read_dev_config(device_t, bus_size_t, void *, int); 124 static void vtmmio_write_dev_config(device_t, bus_size_t, void *, int); 125 static void vtmmio_describe_features(struct vtmmio_softc *, const char *, 126 uint64_t); 127 static void vtmmio_probe_and_attach_child(struct vtmmio_softc *); 128 static int vtmmio_reinit_virtqueue(struct vtmmio_softc *, int); 129 static void vtmmio_free_interrupts(struct vtmmio_softc *); 130 static void vtmmio_free_virtqueues(struct vtmmio_softc *); 131 static void vtmmio_release_child_resources(struct vtmmio_softc *); 132 static void vtmmio_reset(struct vtmmio_softc *); 133 static void vtmmio_select_virtqueue(struct vtmmio_softc *, int); 134 static void vtmmio_vq_intr(void *); 135 136 /* 137 * I/O port read/write wrappers. 138 */ 139 #define vtmmio_write_config_1(sc, o, v) \ 140 do { \ 141 bus_write_1((sc)->res[0], (o), (v)); \ 142 if (sc->platform != NULL) \ 143 VIRTIO_MMIO_NOTE(sc->platform, (o), (v)); \ 144 } while (0) 145 #define vtmmio_write_config_2(sc, o, v) \ 146 do { \ 147 bus_write_2((sc)->res[0], (o), (v)); \ 148 if (sc->platform != NULL) \ 149 VIRTIO_MMIO_NOTE(sc->platform, (o), (v)); \ 150 } while (0) 151 #define vtmmio_write_config_4(sc, o, v) \ 152 do { \ 153 bus_write_4((sc)->res[0], (o), (v)); \ 154 if (sc->platform != NULL) \ 155 VIRTIO_MMIO_NOTE(sc->platform, (o), (v)); \ 156 } while (0) 157 158 #define vtmmio_read_config_1(sc, o) \ 159 bus_read_1((sc)->res[0], (o)) 160 #define vtmmio_read_config_2(sc, o) \ 161 bus_read_2((sc)->res[0], (o)) 162 #define vtmmio_read_config_4(sc, o) \ 163 bus_read_4((sc)->res[0], (o)) 164 165 static device_method_t vtmmio_methods[] = { 166 /* Device interface. */ 167 DEVMETHOD(device_probe, vtmmio_probe), 168 DEVMETHOD(device_attach, vtmmio_attach), 169 DEVMETHOD(device_detach, vtmmio_detach), 170 DEVMETHOD(device_suspend, vtmmio_suspend), 171 DEVMETHOD(device_resume, vtmmio_resume), 172 DEVMETHOD(device_shutdown, vtmmio_shutdown), 173 174 /* Bus interface. */ 175 DEVMETHOD(bus_driver_added, vtmmio_driver_added), 176 DEVMETHOD(bus_child_detached, vtmmio_child_detached), 177 DEVMETHOD(bus_read_ivar, vtmmio_read_ivar), 178 DEVMETHOD(bus_write_ivar, vtmmio_write_ivar), 179 180 /* VirtIO bus interface. */ 181 DEVMETHOD(virtio_bus_negotiate_features, vtmmio_negotiate_features), 182 DEVMETHOD(virtio_bus_with_feature, vtmmio_with_feature), 183 DEVMETHOD(virtio_bus_alloc_virtqueues, vtmmio_alloc_virtqueues), 184 DEVMETHOD(virtio_bus_setup_intr, vtmmio_setup_intr), 185 DEVMETHOD(virtio_bus_stop, vtmmio_stop), 186 DEVMETHOD(virtio_bus_poll, vtmmio_poll), 187 DEVMETHOD(virtio_bus_reinit, vtmmio_reinit), 188 DEVMETHOD(virtio_bus_reinit_complete, vtmmio_reinit_complete), 189 DEVMETHOD(virtio_bus_notify_vq, vtmmio_notify_virtqueue), 190 DEVMETHOD(virtio_bus_read_device_config, vtmmio_read_dev_config), 191 DEVMETHOD(virtio_bus_write_device_config, vtmmio_write_dev_config), 192 193 DEVMETHOD_END 194 }; 195 196 static driver_t vtmmio_driver = { 197 "virtio_mmio", 198 vtmmio_methods, 199 sizeof(struct vtmmio_softc) 200 }; 201 202 devclass_t vtmmio_devclass; 203 204 DRIVER_MODULE(virtio_mmio, simplebus, vtmmio_driver, vtmmio_devclass, 0, 0); 205 MODULE_VERSION(virtio_mmio, 1); 206 MODULE_DEPEND(virtio_mmio, simplebus, 1, 1, 1); 207 MODULE_DEPEND(virtio_mmio, virtio, 1, 1, 1); 208 209 static int 210 vtmmio_setup_intr(device_t dev, enum intr_type type) 211 { 212 struct vtmmio_softc *sc; 213 int rid; 214 int err; 215 216 sc = device_get_softc(dev); 217 218 if (sc->platform != NULL) { 219 err = VIRTIO_MMIO_SETUP_INTR(sc->platform, sc->dev, 220 vtmmio_vq_intr, sc); 221 if (err == 0) { 222 /* Okay we have backend-specific interrupts */ 223 return (0); 224 } 225 } 226 227 rid = 0; 228 sc->res[1] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 229 RF_ACTIVE); 230 if (!sc->res[1]) { 231 device_printf(dev, "Can't allocate interrupt\n"); 232 return (ENXIO); 233 } 234 235 if (bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, 236 NULL, vtmmio_vq_intr, sc, &sc->ih)) { 237 device_printf(dev, "Can't setup the interrupt\n"); 238 return (ENXIO); 239 } 240 241 return (0); 242 } 243 244 static int 245 vtmmio_probe(device_t dev) 246 { 247 248 if (!ofw_bus_status_okay(dev)) 249 return (ENXIO); 250 251 if (!ofw_bus_is_compatible(dev, "virtio,mmio")) 252 return (ENXIO); 253 254 device_set_desc(dev, "VirtIO MMIO adapter"); 255 return (BUS_PROBE_DEFAULT); 256 } 257 258 static int 259 vtmmio_setup_platform(struct vtmmio_softc *sc) 260 { 261 phandle_t platform_node; 262 struct fdt_ic *ic; 263 phandle_t xref; 264 phandle_t node; 265 266 sc->platform = NULL; 267 268 if ((node = ofw_bus_get_node(sc->dev)) == -1) 269 return (ENXIO); 270 271 if (OF_searchencprop(node, "platform", &xref, 272 sizeof(xref)) == -1) { 273 return (ENXIO); 274 } 275 276 platform_node = OF_node_from_xref(xref); 277 278 SLIST_FOREACH(ic, &fdt_ic_list_head, fdt_ics) { 279 if (ic->iph == platform_node) { 280 sc->platform = ic->dev; 281 break; 282 } 283 } 284 285 if (sc->platform == NULL) { 286 /* No platform-specific device. Ignore it. */ 287 } 288 289 return (0); 290 } 291 292 static int 293 vtmmio_attach(device_t dev) 294 { 295 struct vtmmio_softc *sc; 296 device_t child; 297 int rid; 298 299 sc = device_get_softc(dev); 300 sc->dev = dev; 301 302 vtmmio_setup_platform(sc); 303 304 rid = 0; 305 sc->res[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 306 RF_ACTIVE); 307 if (!sc->res[0]) { 308 device_printf(dev, "Cannot allocate memory window.\n"); 309 return (ENXIO); 310 } 311 312 vtmmio_reset(sc); 313 314 /* Tell the host we've noticed this device. */ 315 vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_ACK); 316 317 if ((child = device_add_child(dev, NULL, -1)) == NULL) { 318 device_printf(dev, "Cannot create child device.\n"); 319 vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_FAILED); 320 vtmmio_detach(dev); 321 return (ENOMEM); 322 } 323 324 sc->vtmmio_child_dev = child; 325 vtmmio_probe_and_attach_child(sc); 326 327 return (0); 328 } 329 330 static int 331 vtmmio_detach(device_t dev) 332 { 333 struct vtmmio_softc *sc; 334 device_t child; 335 int error; 336 337 sc = device_get_softc(dev); 338 339 if ((child = sc->vtmmio_child_dev) != NULL) { 340 error = device_delete_child(dev, child); 341 if (error) 342 return (error); 343 sc->vtmmio_child_dev = NULL; 344 } 345 346 vtmmio_reset(sc); 347 348 if (sc->res[0] != NULL) { 349 bus_release_resource(dev, SYS_RES_MEMORY, 0, 350 sc->res[0]); 351 sc->res[0] = NULL; 352 } 353 354 return (0); 355 } 356 357 static int 358 vtmmio_suspend(device_t dev) 359 { 360 361 return (bus_generic_suspend(dev)); 362 } 363 364 static int 365 vtmmio_resume(device_t dev) 366 { 367 368 return (bus_generic_resume(dev)); 369 } 370 371 static int 372 vtmmio_shutdown(device_t dev) 373 { 374 375 (void) bus_generic_shutdown(dev); 376 377 /* Forcibly stop the host device. */ 378 vtmmio_stop(dev); 379 380 return (0); 381 } 382 383 static void 384 vtmmio_driver_added(device_t dev, driver_t *driver) 385 { 386 struct vtmmio_softc *sc; 387 388 sc = device_get_softc(dev); 389 390 vtmmio_probe_and_attach_child(sc); 391 } 392 393 static void 394 vtmmio_child_detached(device_t dev, device_t child) 395 { 396 struct vtmmio_softc *sc; 397 398 sc = device_get_softc(dev); 399 400 vtmmio_reset(sc); 401 vtmmio_release_child_resources(sc); 402 } 403 404 static int 405 vtmmio_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) 406 { 407 struct vtmmio_softc *sc; 408 409 sc = device_get_softc(dev); 410 411 if (sc->vtmmio_child_dev != child) 412 return (ENOENT); 413 414 switch (index) { 415 case VIRTIO_IVAR_DEVTYPE: 416 case VIRTIO_IVAR_SUBDEVICE: 417 *result = vtmmio_read_config_4(sc, VIRTIO_MMIO_DEVICE_ID); 418 break; 419 case VIRTIO_IVAR_VENDOR: 420 *result = vtmmio_read_config_4(sc, VIRTIO_MMIO_VENDOR_ID); 421 break; 422 default: 423 return (ENOENT); 424 } 425 426 return (0); 427 } 428 429 static int 430 vtmmio_write_ivar(device_t dev, device_t child, int index, uintptr_t value) 431 { 432 struct vtmmio_softc *sc; 433 434 sc = device_get_softc(dev); 435 436 if (sc->vtmmio_child_dev != child) 437 return (ENOENT); 438 439 switch (index) { 440 case VIRTIO_IVAR_FEATURE_DESC: 441 sc->vtmmio_child_feat_desc = (void *) value; 442 break; 443 default: 444 return (ENOENT); 445 } 446 447 return (0); 448 } 449 450 static uint64_t 451 vtmmio_negotiate_features(device_t dev, uint64_t child_features) 452 { 453 struct vtmmio_softc *sc; 454 uint64_t host_features, features; 455 456 sc = device_get_softc(dev); 457 458 host_features = vtmmio_read_config_4(sc, VIRTIO_MMIO_HOST_FEATURES); 459 vtmmio_describe_features(sc, "host", host_features); 460 461 /* 462 * Limit negotiated features to what the driver, virtqueue, and 463 * host all support. 464 */ 465 features = host_features & child_features; 466 features = virtqueue_filter_features(features); 467 sc->vtmmio_features = features; 468 469 vtmmio_describe_features(sc, "negotiated", features); 470 vtmmio_write_config_4(sc, VIRTIO_MMIO_GUEST_FEATURES, features); 471 472 return (features); 473 } 474 475 static int 476 vtmmio_with_feature(device_t dev, uint64_t feature) 477 { 478 struct vtmmio_softc *sc; 479 480 sc = device_get_softc(dev); 481 482 return ((sc->vtmmio_features & feature) != 0); 483 } 484 485 static int 486 vtmmio_alloc_virtqueues(device_t dev, int flags, int nvqs, 487 struct vq_alloc_info *vq_info) 488 { 489 struct vtmmio_virtqueue *vqx; 490 struct vq_alloc_info *info; 491 struct vtmmio_softc *sc; 492 struct virtqueue *vq; 493 uint32_t size; 494 int idx, error; 495 496 sc = device_get_softc(dev); 497 498 if (sc->vtmmio_nvqs != 0) 499 return (EALREADY); 500 if (nvqs <= 0) 501 return (EINVAL); 502 503 sc->vtmmio_vqs = malloc(nvqs * sizeof(struct vtmmio_virtqueue), 504 M_DEVBUF, M_NOWAIT | M_ZERO); 505 if (sc->vtmmio_vqs == NULL) 506 return (ENOMEM); 507 508 for (idx = 0; idx < nvqs; idx++) { 509 vqx = &sc->vtmmio_vqs[idx]; 510 info = &vq_info[idx]; 511 512 vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_SEL, idx); 513 514 vtmmio_select_virtqueue(sc, idx); 515 size = vtmmio_read_config_4(sc, VIRTIO_MMIO_QUEUE_NUM_MAX); 516 517 error = virtqueue_alloc(dev, idx, size, 518 VIRTIO_MMIO_VRING_ALIGN, 0xFFFFFFFFUL, info, &vq); 519 if (error) { 520 device_printf(dev, 521 "cannot allocate virtqueue %d: %d\n", 522 idx, error); 523 break; 524 } 525 526 vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_NUM, size); 527 vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_ALIGN, 528 VIRTIO_MMIO_VRING_ALIGN); 529 #if 0 530 device_printf(dev, "virtqueue paddr 0x%08lx\n", 531 (uint64_t)virtqueue_paddr(vq)); 532 #endif 533 vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_PFN, 534 virtqueue_paddr(vq) >> PAGE_SHIFT); 535 536 vqx->vtv_vq = *info->vqai_vq = vq; 537 vqx->vtv_no_intr = info->vqai_intr == NULL; 538 539 sc->vtmmio_nvqs++; 540 } 541 542 if (error) 543 vtmmio_free_virtqueues(sc); 544 545 return (error); 546 } 547 548 static void 549 vtmmio_stop(device_t dev) 550 { 551 552 vtmmio_reset(device_get_softc(dev)); 553 } 554 555 static void 556 vtmmio_poll(device_t dev) 557 { 558 struct vtmmio_softc *sc; 559 560 sc = device_get_softc(dev); 561 562 if (sc->platform != NULL) 563 VIRTIO_MMIO_POLL(sc->platform); 564 } 565 566 static int 567 vtmmio_reinit(device_t dev, uint64_t features) 568 { 569 struct vtmmio_softc *sc; 570 int idx, error; 571 572 sc = device_get_softc(dev); 573 574 if (vtmmio_get_status(dev) != VIRTIO_CONFIG_STATUS_RESET) 575 vtmmio_stop(dev); 576 577 /* 578 * Quickly drive the status through ACK and DRIVER. The device 579 * does not become usable again until vtmmio_reinit_complete(). 580 */ 581 vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_ACK); 582 vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER); 583 584 vtmmio_negotiate_features(dev, features); 585 586 for (idx = 0; idx < sc->vtmmio_nvqs; idx++) { 587 error = vtmmio_reinit_virtqueue(sc, idx); 588 if (error) 589 return (error); 590 } 591 592 return (0); 593 } 594 595 static void 596 vtmmio_reinit_complete(device_t dev) 597 { 598 599 vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER_OK); 600 } 601 602 static void 603 vtmmio_notify_virtqueue(device_t dev, uint16_t queue) 604 { 605 struct vtmmio_softc *sc; 606 607 sc = device_get_softc(dev); 608 609 vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_NOTIFY, queue); 610 } 611 612 static uint8_t 613 vtmmio_get_status(device_t dev) 614 { 615 struct vtmmio_softc *sc; 616 617 sc = device_get_softc(dev); 618 619 return (vtmmio_read_config_4(sc, VIRTIO_MMIO_STATUS)); 620 } 621 622 static void 623 vtmmio_set_status(device_t dev, uint8_t status) 624 { 625 struct vtmmio_softc *sc; 626 627 sc = device_get_softc(dev); 628 629 if (status != VIRTIO_CONFIG_STATUS_RESET) 630 status |= vtmmio_get_status(dev); 631 632 vtmmio_write_config_4(sc, VIRTIO_MMIO_STATUS, status); 633 } 634 635 static void 636 vtmmio_read_dev_config(device_t dev, bus_size_t offset, 637 void *dst, int length) 638 { 639 struct vtmmio_softc *sc; 640 bus_size_t off; 641 uint8_t *d; 642 int size; 643 644 sc = device_get_softc(dev); 645 off = VIRTIO_MMIO_CONFIG + offset; 646 647 for (d = dst; length > 0; d += size, off += size, length -= size) { 648 #ifdef ALLOW_WORD_ALIGNED_ACCESS 649 if (length >= 4) { 650 size = 4; 651 *(uint32_t *)d = vtmmio_read_config_4(sc, off); 652 } else if (length >= 2) { 653 size = 2; 654 *(uint16_t *)d = vtmmio_read_config_2(sc, off); 655 } else 656 #endif 657 { 658 size = 1; 659 *d = vtmmio_read_config_1(sc, off); 660 } 661 } 662 } 663 664 static void 665 vtmmio_write_dev_config(device_t dev, bus_size_t offset, 666 void *src, int length) 667 { 668 struct vtmmio_softc *sc; 669 bus_size_t off; 670 uint8_t *s; 671 int size; 672 673 sc = device_get_softc(dev); 674 off = VIRTIO_MMIO_CONFIG + offset; 675 676 for (s = src; length > 0; s += size, off += size, length -= size) { 677 #ifdef ALLOW_WORD_ALIGNED_ACCESS 678 if (length >= 4) { 679 size = 4; 680 vtmmio_write_config_4(sc, off, *(uint32_t *)s); 681 } else if (length >= 2) { 682 size = 2; 683 vtmmio_write_config_2(sc, off, *(uint16_t *)s); 684 } else 685 #endif 686 { 687 size = 1; 688 vtmmio_write_config_1(sc, off, *s); 689 } 690 } 691 } 692 693 static void 694 vtmmio_describe_features(struct vtmmio_softc *sc, const char *msg, 695 uint64_t features) 696 { 697 device_t dev, child; 698 699 dev = sc->dev; 700 child = sc->vtmmio_child_dev; 701 702 if (device_is_attached(child) && bootverbose == 0) 703 return; 704 705 virtio_describe(dev, msg, features, sc->vtmmio_child_feat_desc); 706 } 707 708 static void 709 vtmmio_probe_and_attach_child(struct vtmmio_softc *sc) 710 { 711 device_t dev, child; 712 713 dev = sc->dev; 714 child = sc->vtmmio_child_dev; 715 716 if (child == NULL) 717 return; 718 719 if (device_get_state(child) != DS_NOTPRESENT) { 720 return; 721 } 722 723 if (device_probe(child) != 0) { 724 return; 725 } 726 727 vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER); 728 if (device_attach(child) != 0) { 729 vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_FAILED); 730 vtmmio_reset(sc); 731 vtmmio_release_child_resources(sc); 732 /* Reset status for future attempt. */ 733 vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_ACK); 734 } else { 735 vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER_OK); 736 VIRTIO_ATTACH_COMPLETED(child); 737 } 738 } 739 740 static int 741 vtmmio_reinit_virtqueue(struct vtmmio_softc *sc, int idx) 742 { 743 struct vtmmio_virtqueue *vqx; 744 struct virtqueue *vq; 745 int error; 746 uint16_t size; 747 748 vqx = &sc->vtmmio_vqs[idx]; 749 vq = vqx->vtv_vq; 750 751 KASSERT(vq != NULL, ("%s: vq %d not allocated", __func__, idx)); 752 753 vtmmio_select_virtqueue(sc, idx); 754 size = vtmmio_read_config_4(sc, VIRTIO_MMIO_QUEUE_NUM_MAX); 755 756 error = virtqueue_reinit(vq, size); 757 if (error) 758 return (error); 759 760 vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_PFN, 761 virtqueue_paddr(vq) >> PAGE_SHIFT); 762 763 return (0); 764 } 765 766 static void 767 vtmmio_free_interrupts(struct vtmmio_softc *sc) 768 { 769 770 if (sc->ih != NULL) 771 bus_teardown_intr(sc->dev, sc->res[1], sc->ih); 772 773 if (sc->res[1] != NULL) 774 bus_release_resource(sc->dev, SYS_RES_IRQ, 0, sc->res[1]); 775 } 776 777 static void 778 vtmmio_free_virtqueues(struct vtmmio_softc *sc) 779 { 780 struct vtmmio_virtqueue *vqx; 781 int idx; 782 783 for (idx = 0; idx < sc->vtmmio_nvqs; idx++) { 784 vqx = &sc->vtmmio_vqs[idx]; 785 786 vtmmio_select_virtqueue(sc, idx); 787 vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_PFN, 0); 788 789 virtqueue_free(vqx->vtv_vq); 790 vqx->vtv_vq = NULL; 791 } 792 793 free(sc->vtmmio_vqs, M_DEVBUF); 794 sc->vtmmio_vqs = NULL; 795 sc->vtmmio_nvqs = 0; 796 } 797 798 static void 799 vtmmio_release_child_resources(struct vtmmio_softc *sc) 800 { 801 802 vtmmio_free_interrupts(sc); 803 vtmmio_free_virtqueues(sc); 804 } 805 806 static void 807 vtmmio_reset(struct vtmmio_softc *sc) 808 { 809 810 /* 811 * Setting the status to RESET sets the host device to 812 * the original, uninitialized state. 813 */ 814 vtmmio_set_status(sc->dev, VIRTIO_CONFIG_STATUS_RESET); 815 } 816 817 static void 818 vtmmio_select_virtqueue(struct vtmmio_softc *sc, int idx) 819 { 820 821 vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_SEL, idx); 822 } 823 824 static void 825 vtmmio_vq_intr(void *arg) 826 { 827 struct vtmmio_virtqueue *vqx; 828 struct vtmmio_softc *sc; 829 struct virtqueue *vq; 830 uint32_t status; 831 int idx; 832 833 sc = arg; 834 835 status = vtmmio_read_config_4(sc, VIRTIO_MMIO_INTERRUPT_STATUS); 836 vtmmio_write_config_4(sc, VIRTIO_MMIO_INTERRUPT_ACK, status); 837 838 /* The config changed */ 839 if (status & VIRTIO_MMIO_INT_CONFIG) 840 if (sc->vtmmio_child_dev != NULL) 841 VIRTIO_CONFIG_CHANGE(sc->vtmmio_child_dev); 842 843 /* Notify all virtqueues. */ 844 if (status & VIRTIO_MMIO_INT_VRING) { 845 for (idx = 0; idx < sc->vtmmio_nvqs; idx++) { 846 vqx = &sc->vtmmio_vqs[idx]; 847 if (vqx->vtv_no_intr == 0) { 848 vq = vqx->vtv_vq; 849 virtqueue_intr(vq); 850 } 851 } 852 } 853 } 854