1 /* 2 * Copyright (c) 2006, Cisco Systems, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Cisco Systems, Inc. nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/module.h> 36 #include <sys/systm.h> 37 #include <sys/mbuf.h> 38 #include <sys/malloc.h> 39 #include <sys/kernel.h> 40 #include <sys/socket.h> 41 #include <sys/queue.h> 42 43 #include <machine/vmparam.h> 44 #include <vm/vm.h> 45 #include <vm/pmap.h> 46 47 #include <machine/bus.h> 48 #include <machine/resource.h> 49 #include <machine/frame.h> 50 51 #include <sys/bus.h> 52 #include <sys/rman.h> 53 54 #include <machine/intr_machdep.h> 55 56 #include <machine/xen-os.h> 57 #include <machine/hypervisor.h> 58 #include <machine/hypervisor-ifs.h> 59 #include <machine/xen_intr.h> 60 #include <machine/evtchn.h> 61 #include <machine/xenbus.h> 62 #include <machine/gnttab.h> 63 #include <machine/xen-public/memory.h> 64 #include <machine/xen-public/io/pciif.h> 65 66 #include <sys/pciio.h> 67 #include <dev/pci/pcivar.h> 68 #include "pcib_if.h" 69 70 #ifdef XEN_PCIDEV_FE_DEBUG 71 #define DPRINTF(fmt, args...) \ 72 printf("pcifront (%s:%d): " fmt, __FUNCTION__, __LINE__, ##args) 73 #else 74 #define DPRINTF(fmt, args...) ((void)0) 75 #endif 76 #define WPRINTF(fmt, args...) \ 77 printf("pcifront (%s:%d): " fmt, __FUNCTION__, __LINE__, ##args) 78 79 #define INVALID_GRANT_REF (0) 80 #define INVALID_EVTCHN (-1) 81 #define virt_to_mfn(x) (vtomach(x) >> PAGE_SHIFT) 82 83 struct pcifront_device { 84 STAILQ_ENTRY(pcifront_device) next; 85 86 struct xenbus_device *xdev; 87 88 int unit; 89 int evtchn; 90 int gnt_ref; 91 92 /* Lock this when doing any operations in sh_info */ 93 struct mtx sh_info_lock; 94 struct xen_pci_sharedinfo *sh_info; 95 96 device_t ndev; 97 98 int ref_cnt; 99 }; 100 101 static STAILQ_HEAD(pcifront_dlist, pcifront_device) pdev_list = STAILQ_HEAD_INITIALIZER(pdev_list); 102 103 struct xpcib_softc { 104 int domain; 105 int bus; 106 struct pcifront_device *pdev; 107 }; 108 109 /* Allocate a PCI device structure */ 110 static struct pcifront_device * 111 alloc_pdev(struct xenbus_device *xdev) 112 { 113 struct pcifront_device *pdev = NULL; 114 int err, unit; 115 116 err = sscanf(xdev->nodename, "device/pci/%d", &unit); 117 if (err != 1) { 118 if (err == 0) 119 err = -EINVAL; 120 xenbus_dev_fatal(pdev->xdev, err, "Error scanning pci device instance number"); 121 goto out; 122 } 123 124 pdev = (struct pcifront_device *)malloc(sizeof(struct pcifront_device), M_DEVBUF, M_NOWAIT); 125 if (pdev == NULL) { 126 err = -ENOMEM; 127 xenbus_dev_fatal(xdev, err, "Error allocating pcifront_device struct"); 128 goto out; 129 } 130 pdev->unit = unit; 131 pdev->xdev = xdev; 132 pdev->ref_cnt = 1; 133 134 pdev->sh_info = (struct xen_pci_sharedinfo *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT); 135 if (pdev->sh_info == NULL) { 136 free(pdev, M_DEVBUF); 137 pdev = NULL; 138 err = -ENOMEM; 139 xenbus_dev_fatal(xdev, err, "Error allocating sh_info struct"); 140 goto out; 141 } 142 pdev->sh_info->flags = 0; 143 144 xdev->data = pdev; 145 146 mtx_init(&pdev->sh_info_lock, "info_lock", "pci shared dev info lock", MTX_DEF); 147 148 pdev->evtchn = INVALID_EVTCHN; 149 pdev->gnt_ref = INVALID_GRANT_REF; 150 151 STAILQ_INSERT_TAIL(&pdev_list, pdev, next); 152 153 DPRINTF("Allocated pdev @ 0x%p (unit=%d)\n", pdev, unit); 154 155 out: 156 return pdev; 157 } 158 159 /* Hold a reference to a pcifront device */ 160 static void 161 get_pdev(struct pcifront_device *pdev) 162 { 163 pdev->ref_cnt++; 164 } 165 166 /* Release a reference to a pcifront device */ 167 static void 168 put_pdev(struct pcifront_device *pdev) 169 { 170 if (--pdev->ref_cnt > 0) 171 return; 172 173 DPRINTF("freeing pdev @ 0x%p (ref_cnt=%d)\n", pdev, pdev->ref_cnt); 174 175 if (pdev->evtchn != INVALID_EVTCHN) 176 xenbus_free_evtchn(pdev->xdev, pdev->evtchn); 177 178 if (pdev->gnt_ref != INVALID_GRANT_REF) 179 gnttab_end_foreign_access(pdev->gnt_ref, 0, (void *)pdev->sh_info); 180 181 pdev->xdev->data = NULL; 182 183 free(pdev, M_DEVBUF); 184 } 185 186 187 /* Write to the xenbus info needed by backend */ 188 static int 189 pcifront_publish_info(struct pcifront_device *pdev) 190 { 191 int err = 0; 192 struct xenbus_transaction *trans; 193 194 err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info)); 195 if (err < 0) { 196 WPRINTF("error granting access to ring page\n"); 197 goto out; 198 } 199 200 pdev->gnt_ref = err; 201 202 err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn); 203 if (err) 204 goto out; 205 206 do_publish: 207 trans = xenbus_transaction_start(); 208 if (IS_ERR(trans)) { 209 xenbus_dev_fatal(pdev->xdev, err, 210 "Error writing configuration for backend " 211 "(start transaction)"); 212 goto out; 213 } 214 215 err = xenbus_printf(trans, pdev->xdev->nodename, 216 "pci-op-ref", "%u", pdev->gnt_ref); 217 if (!err) 218 err = xenbus_printf(trans, pdev->xdev->nodename, 219 "event-channel", "%u", pdev->evtchn); 220 if (!err) 221 err = xenbus_printf(trans, pdev->xdev->nodename, 222 "magic", XEN_PCI_MAGIC); 223 if (!err) 224 err = xenbus_switch_state(pdev->xdev, trans, 225 XenbusStateInitialised); 226 227 if (err) { 228 xenbus_transaction_end(trans, 1); 229 xenbus_dev_fatal(pdev->xdev, err, 230 "Error writing configuration for backend"); 231 goto out; 232 } else { 233 err = xenbus_transaction_end(trans, 0); 234 if (err == -EAGAIN) 235 goto do_publish; 236 else if (err) { 237 xenbus_dev_fatal(pdev->xdev, err, 238 "Error completing transaction for backend"); 239 goto out; 240 } 241 } 242 243 out: 244 return err; 245 } 246 247 /* The backend is now connected so complete the connection process on our side */ 248 static int 249 pcifront_connect(struct pcifront_device *pdev) 250 { 251 device_t nexus; 252 devclass_t nexus_devclass; 253 254 /* We will add our device as a child of the nexus0 device */ 255 if (!(nexus_devclass = devclass_find("nexus")) || 256 !(nexus = devclass_get_device(nexus_devclass, 0))) { 257 WPRINTF("could not find nexus0!\n"); 258 return -1; 259 } 260 261 /* Create a newbus device representing this frontend instance */ 262 pdev->ndev = BUS_ADD_CHILD(nexus, 0, "xpcife", pdev->unit); 263 if (!pdev->ndev) { 264 WPRINTF("could not create xpcife%d!\n", pdev->unit); 265 return -EFAULT; 266 } 267 get_pdev(pdev); 268 device_set_ivars(pdev->ndev, pdev); 269 270 /* Good to go connected now */ 271 xenbus_switch_state(pdev->xdev, NULL, XenbusStateConnected); 272 273 printf("pcifront: connected to %s\n", pdev->xdev->nodename); 274 275 mtx_lock(&Giant); 276 device_probe_and_attach(pdev->ndev); 277 mtx_unlock(&Giant); 278 279 return 0; 280 } 281 282 /* The backend is closing so process a disconnect */ 283 static int 284 pcifront_disconnect(struct pcifront_device *pdev) 285 { 286 int err = 0; 287 XenbusState prev_state; 288 289 prev_state = xenbus_read_driver_state(pdev->xdev->nodename); 290 291 if (prev_state < XenbusStateClosing) { 292 err = xenbus_switch_state(pdev->xdev, NULL, XenbusStateClosing); 293 if (!err && prev_state == XenbusStateConnected) { 294 /* TODO - need to detach the newbus devices */ 295 } 296 } 297 298 return err; 299 } 300 301 /* Process a probe from the xenbus */ 302 static int 303 pcifront_probe(struct xenbus_device *xdev, 304 const struct xenbus_device_id *id) 305 { 306 int err = 0; 307 struct pcifront_device *pdev; 308 309 DPRINTF("xenbus probing\n"); 310 311 if ((pdev = alloc_pdev(xdev)) == NULL) 312 goto out; 313 314 err = pcifront_publish_info(pdev); 315 316 out: 317 if (err) 318 put_pdev(pdev); 319 return err; 320 } 321 322 /* Remove the xenbus PCI device */ 323 static int 324 pcifront_remove(struct xenbus_device *xdev) 325 { 326 DPRINTF("removing xenbus device node (%s)\n", xdev->nodename); 327 if (xdev->data) 328 put_pdev(xdev->data); 329 return 0; 330 } 331 332 /* Called by xenbus when our backend node changes state */ 333 static void 334 pcifront_backend_changed(struct xenbus_device *xdev, 335 XenbusState be_state) 336 { 337 struct pcifront_device *pdev = xdev->data; 338 339 switch (be_state) { 340 case XenbusStateClosing: 341 DPRINTF("backend closing (%s)\n", xdev->nodename); 342 pcifront_disconnect(pdev); 343 break; 344 345 case XenbusStateClosed: 346 DPRINTF("backend closed (%s)\n", xdev->nodename); 347 pcifront_disconnect(pdev); 348 break; 349 350 case XenbusStateConnected: 351 DPRINTF("backend connected (%s)\n", xdev->nodename); 352 pcifront_connect(pdev); 353 break; 354 355 default: 356 break; 357 } 358 } 359 360 /* Process PCI operation */ 361 static int 362 do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op) 363 { 364 int err = 0; 365 struct xen_pci_op *active_op = &pdev->sh_info->op; 366 evtchn_port_t port = pdev->evtchn; 367 time_t timeout; 368 369 mtx_lock(&pdev->sh_info_lock); 370 371 memcpy(active_op, op, sizeof(struct xen_pci_op)); 372 373 /* Go */ 374 wmb(); 375 set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags); 376 notify_remote_via_evtchn(port); 377 378 timeout = time_uptime + 2; 379 380 clear_evtchn(port); 381 382 /* Spin while waiting for the answer */ 383 while (test_bit 384 (_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags)) { 385 int err = HYPERVISOR_poll(&port, 1, 3 * hz); 386 if (err) 387 panic("Failed HYPERVISOR_poll: err=%d", err); 388 clear_evtchn(port); 389 if (time_uptime > timeout) { 390 WPRINTF("pciback not responding!!!\n"); 391 clear_bit(_XEN_PCIF_active, 392 (unsigned long *)&pdev->sh_info->flags); 393 err = XEN_PCI_ERR_dev_not_found; 394 goto out; 395 } 396 } 397 398 memcpy(op, active_op, sizeof(struct xen_pci_op)); 399 400 err = op->err; 401 out: 402 mtx_unlock(&pdev->sh_info_lock); 403 return err; 404 } 405 406 /* ** XenBus Driver registration ** */ 407 408 static struct xenbus_device_id pcifront_ids[] = { 409 { "pci" }, 410 { "" } 411 }; 412 413 static struct xenbus_driver pcifront = { 414 .name = "pcifront", 415 .ids = pcifront_ids, 416 .probe = pcifront_probe, 417 .remove = pcifront_remove, 418 .otherend_changed = pcifront_backend_changed, 419 }; 420 421 /* Register the driver with xenbus during sys init */ 422 static void 423 pcifront_init(void *unused) 424 { 425 if ((xen_start_info->flags & SIF_INITDOMAIN)) 426 return; 427 428 DPRINTF("xenbus registering\n"); 429 430 xenbus_register_frontend(&pcifront); 431 } 432 433 SYSINIT(pciif, SI_SUB_PSEUDO, SI_ORDER_ANY, pcifront_init, NULL) 434 435 436 /* Newbus xpcife device driver probe */ 437 static int 438 xpcife_probe(device_t dev) 439 { 440 #ifdef XEN_PCIDEV_FE_DEBUG 441 struct pcifront_device *pdev = (struct pcifront_device *)device_get_ivars(dev); 442 DPRINTF("xpcife probe (unit=%d)\n", pdev->unit); 443 #endif 444 return 0; 445 } 446 447 /* Newbus xpcife device driver attach */ 448 static int 449 xpcife_attach(device_t dev) 450 { 451 struct pcifront_device *pdev = (struct pcifront_device *)device_get_ivars(dev); 452 int i, num_roots, len, err; 453 char str[64]; 454 unsigned int domain, bus; 455 456 DPRINTF("xpcife attach (unit=%d)\n", pdev->unit); 457 458 err = xenbus_scanf(NULL, pdev->xdev->otherend, 459 "root_num", "%d", &num_roots); 460 if (err != 1) { 461 if (err == 0) 462 err = -EINVAL; 463 xenbus_dev_fatal(pdev->xdev, err, 464 "Error reading number of PCI roots"); 465 goto out; 466 } 467 468 /* Add a pcib device for each root */ 469 for (i = 0; i < num_roots; i++) { 470 device_t child; 471 472 len = snprintf(str, sizeof(str), "root-%d", i); 473 if (unlikely(len >= (sizeof(str) - 1))) { 474 err = -ENOMEM; 475 goto out; 476 } 477 478 err = xenbus_scanf(NULL, pdev->xdev->otherend, str, 479 "%x:%x", &domain, &bus); 480 if (err != 2) { 481 if (err >= 0) 482 err = -EINVAL; 483 xenbus_dev_fatal(pdev->xdev, err, 484 "Error reading PCI root %d", i); 485 goto out; 486 } 487 err = 0; 488 if (domain != pdev->xdev->otherend_id) { 489 err = -EINVAL; 490 xenbus_dev_fatal(pdev->xdev, err, 491 "Domain mismatch %d != %d", domain, pdev->xdev->otherend_id); 492 goto out; 493 } 494 495 child = device_add_child(dev, "pcib", bus); 496 if (!child) { 497 err = -ENOMEM; 498 xenbus_dev_fatal(pdev->xdev, err, 499 "Unable to create pcib%d", bus); 500 goto out; 501 } 502 } 503 504 out: 505 return bus_generic_attach(dev); 506 } 507 508 static devclass_t xpcife_devclass; 509 510 static device_method_t xpcife_methods[] = { 511 /* Device interface */ 512 DEVMETHOD(device_probe, xpcife_probe), 513 DEVMETHOD(device_attach, xpcife_attach), 514 DEVMETHOD(device_detach, bus_generic_detach), 515 DEVMETHOD(device_shutdown, bus_generic_shutdown), 516 DEVMETHOD(device_suspend, bus_generic_suspend), 517 DEVMETHOD(device_resume, bus_generic_resume), 518 /* Bus interface */ 519 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), 520 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 521 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 522 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 523 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 524 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 525 526 DEVMETHOD_END 527 }; 528 529 static driver_t xpcife_driver = { 530 "xpcife", 531 xpcife_methods, 532 0, 533 }; 534 535 DRIVER_MODULE(xpcife, nexus, xpcife_driver, xpcife_devclass, 0, 0); 536 537 538 /* Newbus xen pcib device driver probe */ 539 static int 540 xpcib_probe(device_t dev) 541 { 542 struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev); 543 struct pcifront_device *pdev = (struct pcifront_device *)device_get_ivars(device_get_parent(dev)); 544 545 DPRINTF("xpcib probe (bus=%d)\n", device_get_unit(dev)); 546 547 sc->domain = pdev->xdev->otherend_id; 548 sc->bus = device_get_unit(dev); 549 sc->pdev = pdev; 550 551 return 0; 552 } 553 554 /* Newbus xen pcib device driver attach */ 555 static int 556 xpcib_attach(device_t dev) 557 { 558 struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev); 559 560 DPRINTF("xpcib attach (bus=%d)\n", sc->bus); 561 562 device_add_child(dev, "pci", sc->bus); 563 return bus_generic_attach(dev); 564 } 565 566 static int 567 xpcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 568 { 569 struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev); 570 switch (which) { 571 case PCIB_IVAR_BUS: 572 *result = sc->bus; 573 return 0; 574 } 575 return ENOENT; 576 } 577 578 /* Return the number of slots supported */ 579 static int 580 xpcib_maxslots(device_t dev) 581 { 582 return 31; 583 } 584 585 #define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) 586 587 /* Read configuration space register */ 588 static u_int32_t 589 xpcib_read_config(device_t dev, int bus, int slot, int func, 590 int reg, int bytes) 591 { 592 struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev); 593 struct xen_pci_op op = { 594 .cmd = XEN_PCI_OP_conf_read, 595 .domain = sc->domain, 596 .bus = sc->bus, 597 .devfn = PCI_DEVFN(slot, func), 598 .offset = reg, 599 .size = bytes, 600 }; 601 int err; 602 603 err = do_pci_op(sc->pdev, &op); 604 605 DPRINTF("read config (b=%d, s=%d, f=%d, reg=%d, len=%d, val=%x, err=%d)\n", 606 bus, slot, func, reg, bytes, op.value, err); 607 608 if (err) 609 op.value = ~0; 610 611 return op.value; 612 } 613 614 /* Write configuration space register */ 615 static void 616 xpcib_write_config(device_t dev, int bus, int slot, int func, 617 int reg, u_int32_t data, int bytes) 618 { 619 struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev); 620 struct xen_pci_op op = { 621 .cmd = XEN_PCI_OP_conf_write, 622 .domain = sc->domain, 623 .bus = sc->bus, 624 .devfn = PCI_DEVFN(slot, func), 625 .offset = reg, 626 .size = bytes, 627 .value = data, 628 }; 629 int err; 630 631 err = do_pci_op(sc->pdev, &op); 632 633 DPRINTF("write config (b=%d, s=%d, f=%d, reg=%d, len=%d, val=%x, err=%d)\n", 634 bus, slot, func, reg, bytes, data, err); 635 } 636 637 static int 638 xpcib_route_interrupt(device_t pcib, device_t dev, int pin) 639 { 640 struct pci_devinfo *dinfo = device_get_ivars(dev); 641 pcicfgregs *cfg = &dinfo->cfg; 642 643 DPRINTF("route intr (pin=%d, line=%d)\n", pin, cfg->intline); 644 645 return cfg->intline; 646 } 647 648 static device_method_t xpcib_methods[] = { 649 /* Device interface */ 650 DEVMETHOD(device_probe, xpcib_probe), 651 DEVMETHOD(device_attach, xpcib_attach), 652 DEVMETHOD(device_detach, bus_generic_detach), 653 DEVMETHOD(device_shutdown, bus_generic_shutdown), 654 DEVMETHOD(device_suspend, bus_generic_suspend), 655 DEVMETHOD(device_resume, bus_generic_resume), 656 657 /* Bus interface */ 658 DEVMETHOD(bus_read_ivar, xpcib_read_ivar), 659 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), 660 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 661 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 662 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 663 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 664 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 665 666 /* pcib interface */ 667 DEVMETHOD(pcib_maxslots, xpcib_maxslots), 668 DEVMETHOD(pcib_read_config, xpcib_read_config), 669 DEVMETHOD(pcib_write_config, xpcib_write_config), 670 DEVMETHOD(pcib_route_interrupt, xpcib_route_interrupt), 671 672 DEVMETHOD_END 673 }; 674 675 static devclass_t xpcib_devclass; 676 677 DEFINE_CLASS_0(pcib, xpcib_driver, xpcib_methods, sizeof(struct xpcib_softc)); 678 DRIVER_MODULE(pcib, xpcife, xpcib_driver, xpcib_devclass, 0, 0); 679 680 /* 681 * Local variables: 682 * mode: C 683 * c-set-style: "BSD" 684 * c-basic-offset: 4 685 * tab-width: 4 686 * indent-tabs-mode: t 687 * End: 688 */ 689