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