1 /* $OpenBSD: vpci.c,v 1.33 2020/10/27 21:01:33 kettenis Exp $ */ 2 /* 3 * Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/device.h> 20 #include <sys/errno.h> 21 #include <sys/malloc.h> 22 #include <sys/systm.h> 23 24 #include <uvm/uvm_extern.h> 25 26 #define _SPARC_BUS_DMA_PRIVATE 27 #include <machine/bus.h> 28 #include <machine/autoconf.h> 29 #include <machine/hypervisor.h> 30 #include <machine/openfirm.h> 31 32 #include <dev/pci/pcivar.h> 33 #include <dev/pci/pcireg.h> 34 35 #include <sparc64/dev/viommuvar.h> 36 #include <sparc64/dev/msivar.h> 37 38 #define VPCI_DEFAULT_MSI_EQS 36 39 40 extern struct sparc_pci_chipset _sparc_pci_chipset; 41 42 struct vpci_msi_msg { 43 uint32_t mm_version; 44 uint8_t mm_reserved[3]; 45 uint8_t mm_type; 46 uint64_t mm_sysino; 47 uint64_t mm_reserved1; 48 uint64_t mm_stick; 49 uint16_t mm_reserved2[3]; 50 uint16_t mm_reqid; 51 uint64_t mm_addr; 52 uint64_t mm_data; 53 uint64_t mm_reserved3; 54 }; 55 56 struct vpci_range { 57 u_int32_t cspace; 58 u_int32_t child_hi; 59 u_int32_t child_lo; 60 u_int32_t phys_hi; 61 u_int32_t phys_lo; 62 u_int32_t size_hi; 63 u_int32_t size_lo; 64 }; 65 66 struct vpci_eq { 67 char eq_name[16]; 68 int eq_id; 69 void *eq_ih; 70 struct msi_eq *eq_meq; 71 struct vpci_pbm *eq_pbm; 72 uint8_t *eq_ring; 73 uint64_t eq_mask; 74 }; 75 76 struct vpci_pbm { 77 struct vpci_softc *vp_sc; 78 uint64_t vp_devhandle; 79 80 struct vpci_range *vp_range; 81 pci_chipset_tag_t vp_pc; 82 int vp_nrange; 83 84 bus_space_tag_t vp_memt; 85 bus_space_tag_t vp_iot; 86 bus_dma_tag_t vp_dmat; 87 struct iommu_state vp_is; 88 89 bus_addr_t vp_msiaddr; 90 int vp_msibase; 91 int vp_msinum; 92 struct intrhand **vp_msi; 93 94 unsigned int vp_neq; 95 struct vpci_eq *vp_eq; 96 97 int vp_flags; 98 }; 99 100 struct vpci_softc { 101 struct device sc_dv; 102 bus_dma_tag_t sc_dmat; 103 bus_space_tag_t sc_bust; 104 int sc_node; 105 }; 106 107 uint64_t sun4v_group_sdio_major; 108 109 int vpci_match(struct device *, void *, void *); 110 void vpci_attach(struct device *, struct device *, void *); 111 void vpci_init_iommu(struct vpci_softc *, struct vpci_pbm *); 112 void vpci_init_msi(struct vpci_softc *, struct vpci_pbm *); 113 int vpci_print(void *, const char *); 114 115 pci_chipset_tag_t vpci_alloc_chipset(struct vpci_pbm *, int, 116 pci_chipset_tag_t); 117 bus_space_tag_t vpci_alloc_mem_tag(struct vpci_pbm *); 118 bus_space_tag_t vpci_alloc_io_tag(struct vpci_pbm *); 119 bus_space_tag_t vpci_alloc_bus_tag(struct vpci_pbm *, const char *, 120 int, int, int); 121 bus_dma_tag_t vpci_alloc_dma_tag(struct vpci_pbm *); 122 123 int vpci_conf_size(pci_chipset_tag_t, pcitag_t); 124 pcireg_t vpci_conf_read(pci_chipset_tag_t, pcitag_t, int); 125 void vpci_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t); 126 127 int vpci_intr_map(struct pci_attach_args *, pci_intr_handle_t *); 128 int vpci_intr_nomap(struct pci_attach_args *, pci_intr_handle_t *); 129 int vpci_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t, 130 bus_size_t, int, bus_space_handle_t *); 131 paddr_t vpci_bus_mmap(bus_space_tag_t, bus_space_tag_t, bus_addr_t, off_t, 132 int, int); 133 void *vpci_intr_establish(bus_space_tag_t, bus_space_tag_t, int, int, int, 134 int (*)(void *), void *, const char *); 135 void *vpci_intr_establish_cpu(bus_space_tag_t, bus_space_tag_t, int, int, 136 int, struct cpu_info *, int (*)(void *), void *, const char *); 137 void vpci_intr_ack(struct intrhand *); 138 void vpci_msi_ack(struct intrhand *); 139 140 int vpci_msi_eq_intr(void *); 141 142 int vpci_dmamap_create(bus_dma_tag_t, bus_dma_tag_t, bus_size_t, int, 143 bus_size_t, bus_size_t, int, bus_dmamap_t *); 144 void vpci_dmamap_destroy(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t); 145 int vpci_dmamap_load(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, 146 void *, bus_size_t, struct proc *, int); 147 void vpci_dmamap_unload(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t); 148 int vpci_dmamem_alloc(bus_dma_tag_t, bus_dma_tag_t, bus_size_t, 149 bus_size_t, bus_size_t, bus_dma_segment_t *, int, int *, int); 150 int vpci_dmamem_map(bus_dma_tag_t, bus_dma_tag_t, bus_dma_segment_t *, 151 int, size_t, caddr_t *, int); 152 void vpci_dmamem_unmap(bus_dma_tag_t, bus_dma_tag_t, caddr_t, size_t); 153 154 int 155 vpci_match(struct device *parent, void *match, void *aux) 156 { 157 struct mainbus_attach_args *ma = aux; 158 159 if (strcmp(ma->ma_name, "pci") != 0) 160 return (0); 161 162 return (OF_is_compatible(ma->ma_node, "SUNW,sun4v-pci") || 163 OF_is_compatible(ma->ma_node, "SUNW,sun4v-vpci")); 164 } 165 166 void 167 vpci_attach(struct device *parent, struct device *self, void *aux) 168 { 169 struct vpci_softc *sc = (struct vpci_softc *)self; 170 struct mainbus_attach_args *ma = aux; 171 struct pcibus_attach_args pba; 172 struct vpci_pbm *pbm; 173 int *busranges = NULL, nranges; 174 int virtual, intx; 175 176 sc->sc_dmat = ma->ma_dmatag; 177 sc->sc_bust = ma->ma_bustag; 178 sc->sc_node = ma->ma_node; 179 180 pbm = malloc(sizeof(*pbm), M_DEVBUF, M_NOWAIT | M_ZERO); 181 if (pbm == NULL) 182 panic("vpci: can't alloc vpci pbm"); 183 184 pbm->vp_sc = sc; 185 pbm->vp_devhandle = (ma->ma_reg[0].ur_paddr >> 32) & 0x0fffffff; 186 187 if (getprop(ma->ma_node, "ranges", sizeof(struct vpci_range), 188 &pbm->vp_nrange, (void **)&pbm->vp_range)) 189 panic("vpci: can't get ranges"); 190 191 if (getprop(ma->ma_node, "bus-range", sizeof(int), &nranges, 192 (void **)&busranges)) 193 panic("vpci: can't get bus-range"); 194 195 printf(": bus %d to %d, ", busranges[0], busranges[1]); 196 197 virtual = (OF_getproplen(ma->ma_node, "virtual-root-complex") == 0); 198 intx = (OF_getproplen(ma->ma_node, "pci-intx-not-supported") != 0); 199 200 pbm->vp_memt = vpci_alloc_mem_tag(pbm); 201 pbm->vp_iot = vpci_alloc_io_tag(pbm); 202 pbm->vp_dmat = vpci_alloc_dma_tag(pbm); 203 204 pbm->vp_pc = vpci_alloc_chipset(pbm, ma->ma_node, &_sparc_pci_chipset); 205 pbm->vp_pc->bustag = pbm->vp_memt; 206 207 vpci_init_iommu(sc, pbm); 208 vpci_init_msi(sc, pbm); 209 210 bzero(&pba, sizeof(pba)); 211 pba.pba_busname = "pci"; 212 pba.pba_domain = pci_ndomains++; 213 pba.pba_bus = busranges[0]; 214 pba.pba_pc = pbm->vp_pc; 215 pba.pba_flags = pbm->vp_flags; 216 pba.pba_dmat = pbm->vp_dmat; 217 pba.pba_memt = pbm->vp_memt; 218 pba.pba_iot = pbm->vp_iot; 219 pba.pba_pc->conf_size = vpci_conf_size; 220 pba.pba_pc->conf_read = vpci_conf_read; 221 pba.pba_pc->conf_write = vpci_conf_write; 222 pba.pba_pc->intr_map = (intx ? vpci_intr_map : vpci_intr_nomap); 223 224 free(busranges, M_DEVBUF, 0); 225 226 config_found(&sc->sc_dv, &pba, vpci_print); 227 228 /* 229 * Signal that we're ready to share this root complex with our 230 * guests. 231 */ 232 if (sun4v_group_sdio_major > 0 && !virtual) { 233 int err; 234 235 err = hv_pci_iov_root_configured(pbm->vp_devhandle); 236 if (err != H_EOK) { 237 printf("%s: pci_iov_root_configured: err %x\n", 238 sc->sc_dv.dv_xname, err); 239 } 240 241 } 242 } 243 244 void 245 vpci_init_iommu(struct vpci_softc *sc, struct vpci_pbm *pbm) 246 { 247 struct iommu_state *is = &pbm->vp_is; 248 int tsbsize = 8; 249 u_int32_t iobase = 0x80000000; 250 char *name; 251 252 name = (char *)malloc(32, M_DEVBUF, M_NOWAIT); 253 if (name == NULL) 254 panic("couldn't malloc iommu name"); 255 snprintf(name, 32, "%s dvma", sc->sc_dv.dv_xname); 256 257 viommu_init(name, is, tsbsize, iobase); 258 is->is_devhandle = pbm->vp_devhandle; 259 } 260 261 void 262 vpci_init_msi(struct vpci_softc *sc, struct vpci_pbm *pbm) 263 { 264 u_int32_t msi_addr_range[3]; 265 u_int32_t msi_eq_devino[3] = { 0, 36, 24 }; 266 u_int32_t msi_range[2]; 267 uint64_t sysino; 268 int msis, msi_eq_size, num_eq, unit; 269 struct vpci_eq *eq; 270 int err; 271 CPU_INFO_ITERATOR cii; 272 struct cpu_info *ci; 273 274 /* One eq per cpu, limited by the number of eqs. */ 275 num_eq = min(ncpus, getpropint(sc->sc_node, "#msi-eqs", 36)); 276 if (num_eq == 0) 277 return; 278 279 if (OF_getprop(sc->sc_node, "msi-address-ranges", 280 msi_addr_range, sizeof(msi_addr_range)) <= 0) 281 return; 282 pbm->vp_msiaddr = msi_addr_range[1]; 283 pbm->vp_msiaddr |= ((bus_addr_t)msi_addr_range[0]) << 32; 284 285 msis = getpropint(sc->sc_node, "#msi", 256); 286 pbm->vp_msi = mallocarray(msis, sizeof(*pbm->vp_msi), M_DEVBUF, 287 M_NOWAIT | M_ZERO); 288 if (pbm->vp_msi == NULL) 289 return; 290 291 msi_eq_size = getpropint(sc->sc_node, "msi-eq-size", 256); 292 293 if (OF_getprop(sc->sc_node, "msi-ranges", 294 msi_range, sizeof(msi_range)) <= 0) 295 goto free_table; 296 pbm->vp_msibase = msi_range[0]; 297 298 pbm->vp_neq = num_eq; 299 pbm->vp_eq = mallocarray(num_eq, sizeof(*eq), M_DEVBUF, 300 M_WAITOK | M_ZERO); 301 302 CPU_INFO_FOREACH(cii, ci) { 303 unit = CPU_INFO_UNIT(ci); 304 eq = &pbm->vp_eq[unit]; 305 306 if (unit >= num_eq) 307 continue; 308 309 eq->eq_id = unit; 310 eq->eq_pbm = pbm; 311 snprintf(eq->eq_name, sizeof(eq->eq_name), "%s:%d", 312 sc->sc_dv.dv_xname, unit); 313 314 eq->eq_meq = msi_eq_alloc(sc->sc_dmat, msi_eq_size, 1); 315 if (eq->eq_meq == NULL) 316 goto free_queues; 317 318 err = hv_pci_msiq_conf(pbm->vp_devhandle, unit, 319 eq->eq_meq->meq_map->dm_segs[0].ds_addr, 320 eq->eq_meq->meq_nentries); 321 if (err != H_EOK) 322 goto free_queues; 323 324 eq->eq_mask = (eq->eq_meq->meq_nentries * 325 sizeof(struct vpci_msi_msg)) - 1; 326 327 OF_getprop(sc->sc_node, "msi-eq-to-devino", 328 msi_eq_devino, sizeof(msi_eq_devino)); 329 err = sun4v_intr_devino_to_sysino(pbm->vp_devhandle, 330 msi_eq_devino[2] + unit, &sysino); 331 if (err != H_EOK) 332 goto free_queues; 333 334 eq->eq_ih = vpci_intr_establish_cpu(pbm->vp_memt, pbm->vp_memt, 335 sysino, IPL_HIGH, BUS_INTR_ESTABLISH_MPSAFE, ci, 336 vpci_msi_eq_intr, eq, eq->eq_name); 337 if (eq->eq_ih == NULL) 338 goto free_queues; 339 340 err = hv_pci_msiq_setvalid(pbm->vp_devhandle, unit, 341 PCI_MSIQ_VALID); 342 if (err != H_EOK) { 343 printf("%s: pci_msiq_setvalid(%d): err %d\n", __func__, 344 unit, err); 345 goto free_queues; 346 } 347 348 err = hv_pci_msiq_setstate(pbm->vp_devhandle, unit, 349 PCI_MSIQSTATE_IDLE); 350 if (err != H_EOK) { 351 printf("%s: pci_msiq_setstate(%d): err %d\n", __func__, 352 unit, err); 353 goto free_queues; 354 } 355 } 356 357 pbm->vp_flags |= PCI_FLAGS_MSI_ENABLED; 358 return; 359 360 free_queues: 361 CPU_INFO_FOREACH(cii, ci) { 362 unit = CPU_INFO_UNIT(ci); 363 eq = &pbm->vp_eq[unit]; 364 365 if (eq->eq_meq != NULL) 366 msi_eq_free(sc->sc_dmat, eq->eq_meq); 367 368 hv_pci_msiq_conf(pbm->vp_devhandle, unit, 0, 0); 369 } 370 free(pbm->vp_eq, M_DEVBUF, num_eq * sizeof(*eq)); 371 free_table: 372 free(pbm->vp_msi, M_DEVBUF, 0); 373 } 374 375 int 376 vpci_print(void *aux, const char *p) 377 { 378 if (p == NULL) 379 return (UNCONF); 380 return (QUIET); 381 } 382 383 int 384 vpci_conf_size(pci_chipset_tag_t pc, pcitag_t tag) 385 { 386 return PCIE_CONFIG_SPACE_SIZE; 387 } 388 389 pcireg_t 390 vpci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) 391 { 392 struct vpci_pbm *pbm = pc->cookie; 393 uint64_t error_flag, data; 394 395 hv_pci_config_get(pbm->vp_devhandle, PCITAG_OFFSET(tag), reg, 4, 396 &error_flag, &data); 397 398 return (error_flag ? (pcireg_t)~0 : data); 399 } 400 401 void 402 vpci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data) 403 { 404 struct vpci_pbm *pbm = pc->cookie; 405 uint64_t error_flag; 406 407 hv_pci_config_put(pbm->vp_devhandle, PCITAG_OFFSET(tag), reg, 4, 408 data, &error_flag); 409 } 410 411 /* 412 * Bus-specific interrupt mapping 413 */ 414 int 415 vpci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 416 { 417 struct vpci_pbm *pbm = pa->pa_pc->cookie; 418 uint64_t devhandle = pbm->vp_devhandle; 419 uint64_t devino, sysino; 420 int err; 421 422 /* 423 * If we didn't find a PROM mapping for this interrupt. Try 424 * to construct one ourselves based on the swizzled interrupt 425 * pin. 426 */ 427 if (*ihp == (pci_intr_handle_t)-1 && pa->pa_intrpin != 0) 428 *ihp = pa->pa_intrpin; 429 430 if (*ihp != (pci_intr_handle_t)-1) { 431 devino = INTVEC(*ihp); 432 err = sun4v_intr_devino_to_sysino(devhandle, devino, &sysino); 433 if (err != H_EOK) 434 return (-1); 435 436 *ihp = sysino; 437 return (0); 438 } 439 440 return (-1); 441 } 442 443 int 444 vpci_intr_nomap(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 445 { 446 return (-1); 447 } 448 449 bus_space_tag_t 450 vpci_alloc_mem_tag(struct vpci_pbm *pp) 451 { 452 return (vpci_alloc_bus_tag(pp, "mem", 453 0x02, /* 32-bit mem space (where's the #define???) */ 454 ASI_PRIMARY, ASI_PRIMARY_LITTLE)); 455 } 456 457 bus_space_tag_t 458 vpci_alloc_io_tag(struct vpci_pbm *pp) 459 { 460 return (vpci_alloc_bus_tag(pp, "io", 461 0x01, /* IO space (where's the #define???) */ 462 ASI_PRIMARY, ASI_PRIMARY_LITTLE)); 463 } 464 465 bus_space_tag_t 466 vpci_alloc_bus_tag(struct vpci_pbm *pbm, const char *name, int ss, 467 int asi, int sasi) 468 { 469 struct vpci_softc *sc = pbm->vp_sc; 470 struct sparc_bus_space_tag *bt; 471 472 bt = malloc(sizeof(*bt), M_DEVBUF, M_NOWAIT | M_ZERO); 473 if (bt == NULL) 474 panic("vpci: could not allocate bus tag"); 475 476 snprintf(bt->name, sizeof(bt->name), "%s-pbm_%s(%d/%2.2x)", 477 sc->sc_dv.dv_xname, name, ss, asi); 478 479 bt->cookie = pbm; 480 bt->parent = sc->sc_bust; 481 bt->default_type = ss; 482 bt->asi = asi; 483 bt->sasi = sasi; 484 bt->sparc_bus_map = vpci_bus_map; 485 bt->sparc_bus_mmap = vpci_bus_mmap; 486 bt->sparc_intr_establish = vpci_intr_establish; 487 bt->sparc_intr_establish_cpu = vpci_intr_establish_cpu; 488 return (bt); 489 } 490 491 bus_dma_tag_t 492 vpci_alloc_dma_tag(struct vpci_pbm *pbm) 493 { 494 struct vpci_softc *sc = pbm->vp_sc; 495 bus_dma_tag_t dt, pdt = sc->sc_dmat; 496 497 dt = malloc(sizeof(*dt), M_DEVBUF, M_NOWAIT | M_ZERO); 498 if (dt == NULL) 499 panic("vpci: could not alloc dma tag"); 500 501 dt->_cookie = pbm; 502 dt->_parent = pdt; 503 dt->_dmamap_create = vpci_dmamap_create; 504 dt->_dmamap_destroy = viommu_dvmamap_destroy; 505 dt->_dmamap_load = viommu_dvmamap_load; 506 dt->_dmamap_load_raw = viommu_dvmamap_load_raw; 507 dt->_dmamap_unload = viommu_dvmamap_unload; 508 dt->_dmamap_sync = viommu_dvmamap_sync; 509 dt->_dmamem_alloc = viommu_dvmamem_alloc; 510 dt->_dmamem_free = viommu_dvmamem_free; 511 return (dt); 512 } 513 514 pci_chipset_tag_t 515 vpci_alloc_chipset(struct vpci_pbm *pbm, int node, pci_chipset_tag_t pc) 516 { 517 pci_chipset_tag_t npc; 518 519 npc = malloc(sizeof *npc, M_DEVBUF, M_NOWAIT); 520 if (npc == NULL) 521 panic("vpci: could not allocate pci_chipset_tag_t"); 522 memcpy(npc, pc, sizeof *pc); 523 npc->cookie = pbm; 524 npc->rootnode = node; 525 return (npc); 526 } 527 528 #define BUS_DMA_FIND_PARENT(t, fn) \ 529 if (t->_parent == NULL) \ 530 panic("null bus_dma parent (" #fn ")"); \ 531 for (t = t->_parent; t->fn == NULL; t = t->_parent) \ 532 if (t->_parent == NULL) \ 533 panic("no bus_dma " #fn " located"); 534 535 int 536 vpci_dmamap_create(bus_dma_tag_t t, bus_dma_tag_t t0, bus_size_t size, 537 int nsegments, bus_size_t maxsegsz, bus_size_t boundary, int flags, 538 bus_dmamap_t *dmamap) 539 { 540 struct vpci_pbm *vp = t->_cookie; 541 542 return (viommu_dvmamap_create(t, t0, &vp->vp_is, size, nsegments, 543 maxsegsz, boundary, flags, dmamap)); 544 } 545 546 int 547 vpci_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t offset, 548 bus_size_t size, int flags, bus_space_handle_t *hp) 549 { 550 struct vpci_pbm *pbm = t->cookie; 551 int i, ss = t->default_type; 552 553 if (t->parent == 0 || t->parent->sparc_bus_map == 0) 554 panic("vpci_bus_map: invalid parent"); 555 556 if (flags & BUS_SPACE_MAP_PROMADDRESS) { 557 return ((*t->parent->sparc_bus_map) 558 (t, t0, offset, size, flags, hp)); 559 } 560 561 /* Check mappings for 64-bit-address Memory Space if appropriate. */ 562 if (ss == 0x02 && offset > 0xffffffff) 563 ss = 0x03; 564 565 for (i = 0; i < pbm->vp_nrange; i++) { 566 bus_addr_t child, paddr; 567 bus_size_t rsize; 568 569 if (((pbm->vp_range[i].cspace >> 24) & 0x03) != ss) 570 continue; 571 child = pbm->vp_range[i].child_lo; 572 child |= ((bus_addr_t)pbm->vp_range[i].child_hi) << 32; 573 rsize = pbm->vp_range[i].size_lo; 574 rsize |= ((bus_size_t)pbm->vp_range[i].size_hi) << 32; 575 if (offset < child || offset >= child + rsize) 576 continue; 577 578 paddr = pbm->vp_range[i].phys_lo; 579 paddr |= ((bus_addr_t)pbm->vp_range[i].phys_hi) << 32; 580 return ((*t->parent->sparc_bus_map) 581 (t, t0, paddr + offset - child, size, flags, hp)); 582 } 583 584 return (EINVAL); 585 } 586 587 paddr_t 588 vpci_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr, 589 off_t off, int prot, int flags) 590 { 591 bus_addr_t offset = paddr; 592 struct vpci_pbm *pbm = t->cookie; 593 int i, ss = t->default_type; 594 595 if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) 596 panic("vpci_bus_mmap: invalid parent"); 597 598 for (i = 0; i < pbm->vp_nrange; i++) { 599 bus_addr_t paddr; 600 601 if (((pbm->vp_range[i].cspace >> 24) & 0x03) != ss) 602 continue; 603 604 paddr = pbm->vp_range[i].phys_lo + offset; 605 paddr |= ((bus_addr_t)pbm->vp_range[i].phys_hi) << 32; 606 return ((*t->parent->sparc_bus_mmap) 607 (t, t0, paddr, off, prot, flags)); 608 } 609 610 return (-1); 611 } 612 613 void * 614 vpci_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int ihandle, 615 int level, int flags, int (*handler)(void *), void *arg, const char *what) 616 { 617 return (vpci_intr_establish_cpu(t, t0, ihandle, level, flags, NULL, 618 handler, arg, what)); 619 } 620 621 void * 622 vpci_intr_establish_cpu(bus_space_tag_t t, bus_space_tag_t t0, int ihandle, 623 int level, int flags, struct cpu_info *cpu, int (*handler)(void *), 624 void *arg, const char *what) 625 { 626 struct vpci_pbm *pbm = t->cookie; 627 uint64_t devhandle = pbm->vp_devhandle; 628 uint64_t sysino = INTVEC(ihandle); 629 struct intrhand *ih; 630 int err; 631 632 ih = bus_intr_allocate(t0, handler, arg, ihandle, level, 633 NULL, NULL, what); 634 if (ih == NULL) 635 return (NULL); 636 637 if (flags & BUS_INTR_ESTABLISH_MPSAFE) 638 ih->ih_mpsafe = 1; 639 640 if (PCI_INTR_TYPE(ihandle) != PCI_INTR_INTX) { 641 pci_chipset_tag_t pc = pbm->vp_pc; 642 pcitag_t tag = PCI_INTR_TAG(ihandle); 643 int msinum = pbm->vp_msinum++; 644 int msi = pbm->vp_msibase + msinum; 645 int eq = 0; 646 647 evcount_attach(&ih->ih_count, ih->ih_name, NULL); 648 649 ih->ih_ack = vpci_msi_ack; 650 651 pbm->vp_msi[msinum] = ih; 652 ih->ih_number = msinum; 653 654 switch (PCI_INTR_TYPE(ihandle)) { 655 case PCI_INTR_MSI: 656 pci_msi_enable(pc, tag, pbm->vp_msiaddr, msi); 657 break; 658 case PCI_INTR_MSIX: 659 pci_msix_enable(pc, tag, pbm->vp_memt, 660 PCI_INTR_VEC(ihandle), pbm->vp_msiaddr, msi); 661 break; 662 } 663 664 if (cpu != NULL) { 665 /* 666 * For now, if we have fewer eqs than cpus, map 667 * interrupts for the eq-less cpus onto other cpus. 668 */ 669 eq = CPU_INFO_UNIT(cpu) % pbm->vp_neq; 670 } 671 672 err = hv_pci_msi_setmsiq(devhandle, msi, eq, 0); 673 if (err != H_EOK) { 674 printf("%s: pci_msi_setmsiq: err %d\n", __func__, err); 675 return (NULL); 676 } 677 678 err = hv_pci_msi_setvalid(devhandle, msi, PCI_MSI_VALID); 679 if (err != H_EOK) { 680 printf("%s: pci_msi_setvalid: err %d\n", __func__, err); 681 return (NULL); 682 } 683 684 err = hv_pci_msi_setstate(devhandle, msi, PCI_MSISTATE_IDLE); 685 if (err != H_EOK) { 686 printf("%s: pci_msi_setstate: err %d\n", __func__, err); 687 return (NULL); 688 } 689 690 return (ih); 691 } 692 693 err = sun4v_intr_setcookie(devhandle, sysino, (vaddr_t)ih); 694 if (err != H_EOK) 695 return (NULL); 696 697 ih->ih_cpu = cpu; 698 intr_establish(ih->ih_pil, ih); 699 ih->ih_ack = vpci_intr_ack; 700 701 err = sun4v_intr_settarget(devhandle, sysino, ih->ih_cpu->ci_upaid); 702 if (err != H_EOK) 703 return (NULL); 704 705 /* Clear pending interrupts. */ 706 err = sun4v_intr_setstate(devhandle, sysino, INTR_IDLE); 707 if (err != H_EOK) 708 return (NULL); 709 710 err = sun4v_intr_setenabled(devhandle, sysino, INTR_ENABLED); 711 if (err != H_EOK) 712 return (NULL); 713 714 return (ih); 715 } 716 717 void 718 vpci_intr_ack(struct intrhand *ih) 719 { 720 bus_space_tag_t t = ih->ih_bus; 721 struct vpci_pbm *pbm = t->cookie; 722 uint64_t devhandle = pbm->vp_devhandle; 723 uint64_t sysino = INTVEC(ih->ih_number); 724 725 sun4v_intr_setstate(devhandle, sysino, INTR_IDLE); 726 } 727 728 void 729 vpci_msi_ack(struct intrhand *ih) 730 { 731 } 732 733 int 734 vpci_msi_eq_intr(void *arg) 735 { 736 struct vpci_eq *eq = arg; 737 struct vpci_pbm *pbm = eq->eq_pbm; 738 struct vpci_msi_msg *msg; 739 uint64_t devhandle = pbm->vp_devhandle; 740 uint64_t head, tail; 741 struct intrhand *ih; 742 int msinum, msi; 743 int err; 744 745 err = hv_pci_msiq_gethead(devhandle, eq->eq_id, &head); 746 if (err != H_EOK) 747 printf("%s: pci_msiq_gethead(%d): %d\n", __func__, eq->eq_id, 748 err); 749 750 err = hv_pci_msiq_gettail(devhandle, eq->eq_id, &tail); 751 if (err != H_EOK) 752 printf("%s: pci_msiq_gettail(%d): %d\n", __func__, eq->eq_id, 753 err); 754 755 if (head == tail) 756 return (0); 757 758 while (head != tail) { 759 msg = (struct vpci_msi_msg *)(eq->eq_meq->meq_va + head); 760 761 if (msg->mm_type == 0) 762 break; 763 msg->mm_type = 0; 764 765 msi = msg->mm_data; 766 msinum = msi - pbm->vp_msibase; 767 ih = pbm->vp_msi[msinum]; 768 err = hv_pci_msi_setstate(devhandle, msi, PCI_MSISTATE_IDLE); 769 if (err != H_EOK) 770 printf("%s: pci_msi_setstate: %d\n", __func__, err); 771 772 send_softint(-1, ih->ih_pil, ih); 773 774 head += sizeof(struct vpci_msi_msg); 775 head &= eq->eq_mask; 776 } 777 778 err = hv_pci_msiq_sethead(devhandle, eq->eq_id, head); 779 if (err != H_EOK) 780 printf("%s: pci_msiq_sethead(%d): %d\n", __func__, eq->eq_id, 781 err); 782 783 return (1); 784 } 785 786 const struct cfattach vpci_ca = { 787 sizeof(struct vpci_softc), vpci_match, vpci_attach 788 }; 789 790 struct cfdriver vpci_cd = { 791 NULL, "vpci", DV_DULL 792 }; 793