psycho.c revision 1.7 1 /* $NetBSD: psycho.c,v 1.7 2000/04/22 17:06:03 mrg Exp $ */
2
3 /*
4 * Copyright (c) 1999, 2000 Matthew R. Green
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
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,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 #include "opt_ddb.h"
32
33 /*
34 * PCI support for UltraSPARC `psycho'
35 */
36
37 #undef DEBUG
38 #define DEBUG
39
40 #ifdef DEBUG
41 #define PDB_PROM 0x01
42 #define PDB_IOMMU 0x02
43 #define PDB_BUSMAP 0x04
44 #define PDB_BUSDMA 0x08
45 #define PDB_INTR 0x10
46 int psycho_debug = 0x0;
47 #define DPRINTF(l, s) do { if (psycho_debug & l) printf s; } while (0)
48 #else
49 #define DPRINTF(l, s)
50 #endif
51
52 #include <sys/param.h>
53 #include <sys/device.h>
54 #include <sys/errno.h>
55 #include <sys/extent.h>
56 #include <sys/malloc.h>
57 #include <sys/systm.h>
58 #include <sys/time.h>
59
60 #include <vm/vm.h>
61 #include <vm/vm_kern.h>
62
63 #define _SPARC_BUS_DMA_PRIVATE
64 #include <machine/bus.h>
65 #include <machine/autoconf.h>
66
67 #include <dev/pci/pcivar.h>
68 #include <dev/pci/pcireg.h>
69
70 #include <sparc64/dev/iommureg.h>
71 #include <sparc64/dev/iommuvar.h>
72 #include <sparc64/dev/psychoreg.h>
73 #include <sparc64/dev/psychovar.h>
74 #include <sparc64/sparc64/cache.h>
75
76 static pci_chipset_tag_t psycho_alloc_chipset __P((struct psycho_pbm *, int,
77 pci_chipset_tag_t));
78 static void psycho_get_bus_range __P((int, int *));
79 static void psycho_get_ranges __P((int, struct psycho_ranges **, int *));
80 static void psycho_get_registers __P((int, struct psycho_registers **, int *));
81 static void psycho_get_intmap __P((int, struct psycho_interrupt_map **, int *));
82 static void psycho_get_intmapmask __P((int, struct psycho_interrupt_map_mask *));
83
84 /* IOMMU support */
85 static void psycho_iommu_init __P((struct psycho_softc *));
86
87 /*
88 * bus space and bus dma support for UltraSPARC `psycho'. note that most
89 * of the bus dma support is provided by the iommu dvma controller.
90 */
91 static int psycho_bus_mmap __P((bus_space_tag_t, bus_type_t, bus_addr_t,
92 int, bus_space_handle_t *));
93 static int _psycho_bus_map __P((bus_space_tag_t, bus_type_t, bus_addr_t,
94 bus_size_t, int, vaddr_t,
95 bus_space_handle_t *));
96 static void *psycho_intr_establish __P((bus_space_tag_t, int, int,
97 int (*) __P((void *)), void *));
98
99 static int psycho_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
100 bus_size_t, struct proc *, int));
101 static void psycho_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
102 static void psycho_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
103 bus_size_t, int));
104 int psycho_dmamem_alloc __P((bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t,
105 bus_dma_segment_t *, int, int *, int));
106 void psycho_dmamem_free __P((bus_dma_tag_t, bus_dma_segment_t *, int));
107 int psycho_dmamem_map __P((bus_dma_tag_t, bus_dma_segment_t *, int, size_t,
108 caddr_t *, int));
109 void psycho_dmamem_unmap __P((bus_dma_tag_t, caddr_t, size_t));
110
111 /* base pci_chipset */
112 extern struct sparc_pci_chipset _sparc_pci_chipset;
113
114 /*
115 * autoconfiguration
116 */
117 static int psycho_match __P((struct device *, struct cfdata *, void *));
118 static void psycho_attach __P((struct device *, struct device *, void *));
119 static int psycho_print __P((void *aux, const char *p));
120
121 static void sabre_init __P((struct psycho_softc *, struct pcibus_attach_args *));
122 static void psycho_init __P((struct psycho_softc *, struct pcibus_attach_args *));
123
124 struct cfattach psycho_ca = {
125 sizeof(struct psycho_softc), psycho_match, psycho_attach
126 };
127
128 /*
129 * "sabre" is the UltraSPARC IIi onboard PCI interface, normally connected to
130 * an APB (advanced PCI bridge), which was designed specifically for the IIi.
131 * the APB appears as two "simba"'s underneath the sabre. real devices
132 * typically appear on the "simba"'s only.
133 *
134 * a pair of "psycho"s sit on the mainbus and have real devices attached to
135 * them. they implemented in the U2P (UPA to PCI). these two devices share
136 * register space and as such need to be configured together, even though the
137 * autoconfiguration will attach them separately.
138 *
139 * each of these appears as two usable PCI busses, though the sabre itself
140 * takes pci0 in this case, leaving real devices on pci1 and pci2. there can
141 * be multiple pairs of psycho's, however, in multi-board machines.
142 */
143 #define ROM_PCI_NAME "pci"
144 #define ROM_SABRE_MODEL "SUNW,sabre"
145 #define ROM_SIMBA_MODEL "SUNW,simba"
146 #define ROM_PSYCHO_MODEL "SUNW,psycho"
147
148 static int
149 psycho_match(parent, match, aux)
150 struct device *parent;
151 struct cfdata *match;
152 void *aux;
153 {
154 struct mainbus_attach_args *ma = aux;
155 char *model = getpropstring(ma->ma_node, "model");
156
157 /* match on a name of "pci" and a sabre or a psycho */
158 if (strcmp(ma->ma_name, ROM_PCI_NAME) == 0 &&
159 (strcmp(model, ROM_SABRE_MODEL) == 0 ||
160 strcmp(model, ROM_PSYCHO_MODEL) == 0))
161 return (1);
162
163 return (0);
164 }
165
166 static void
167 psycho_attach(parent, self, aux)
168 struct device *parent, *self;
169 void *aux;
170 {
171 struct psycho_softc *sc = (struct psycho_softc *)self;
172 struct pcibus_attach_args pba;
173 struct mainbus_attach_args *ma = aux;
174 char *model = getpropstring(ma->ma_node, "model");
175
176 printf("\n");
177
178 sc->sc_node = ma->ma_node;
179 sc->sc_bustag = ma->ma_bustag;
180 sc->sc_dmatag = ma->ma_dmatag;
181
182 /*
183 * pull in all the information about the psycho as we can.
184 */
185
186 /*
187 * XXX use the prom address for the psycho registers? we do so far.
188 */
189 sc->sc_regs = (struct psychoreg *)(u_long)ma->ma_address[0];
190 sc->sc_basepaddr = (paddr_t)ma->ma_reg[0].ur_paddr;
191
192 /*
193 * call the model-specific initialisation routine.
194 */
195 if (strcmp(model, ROM_SABRE_MODEL) == 0)
196 sabre_init(sc, &pba);
197 else if (strcmp(model, ROM_PSYCHO_MODEL) == 0)
198 psycho_init(sc, &pba);
199 #ifdef DIAGNOSTIC
200 else
201 panic("psycho_attach: unknown model %s?", model);
202 #endif
203
204 /*
205 * attach the pci.. note we pass PCI A tags, etc., for the sabre here.
206 */
207 pba.pba_busname = "pci";
208 pba.pba_flags = sc->sc_psycho_this->pp_flags;
209 pba.pba_dmat = sc->sc_psycho_this->pp_dmat;
210 pba.pba_iot = sc->sc_psycho_this->pp_iot;
211 pba.pba_memt = sc->sc_psycho_this->pp_memt;
212
213 config_found(self, &pba, psycho_print);
214 }
215
216 static int
217 psycho_print(aux, p)
218 void *aux;
219 const char *p;
220 {
221
222 if (p == NULL)
223 return (UNCONF);
224 return (QUIET);
225 }
226
227 /*
228 * SUNW,sabre initialisation ..
229 * - get the sabre's ranges. this are used for both simba's.
230 * - find the two SUNW,simba's underneath (a and b)
231 * - work out which simba is which via the bus-range property
232 * - get each simba's interrupt-map and interrupt-map-mask.
233 * - turn on the iommu
234 */
235 static void
236 sabre_init(sc, pba)
237 struct psycho_softc *sc;
238 struct pcibus_attach_args *pba;
239 {
240 struct psycho_pbm *pp;
241 bus_space_handle_t bh;
242 u_int64_t csr;
243 int node;
244 int sabre_br[2], simba_br[2];
245
246 /* who? said a voice, incredulous */
247 sc->sc_mode = PSYCHO_MODE_SABRE;
248 printf("sabre: ");
249
250 /* setup the PCI control register; there is only one for the sabre */
251 csr = bus_space_read_8(sc->sc_bustag, (bus_space_handle_t)(u_long)&sc->sc_regs->psy_pcictl[0].pci_csr, 0);
252 csr |= PCICTL_MRLM |
253 PCICTL_ARB_PARK |
254 PCICTL_ERRINTEN |
255 PCICTL_4ENABLE;
256 csr &= ~(PCICTL_SERR |
257 PCICTL_CPU_PRIO |
258 PCICTL_ARB_PRIO |
259 PCICTL_RTRYWAIT);
260 bus_space_write_8(sc->sc_bustag, &sc->sc_regs->psy_pcictl[0].pci_csr, 0, csr);
261
262 /* allocate a pair of psycho_pbm's for our simba's */
263 sc->sc_sabre = malloc(sizeof *pp, M_DEVBUF, M_NOWAIT);
264 sc->sc_simba_a = malloc(sizeof *pp, M_DEVBUF, M_NOWAIT);
265 sc->sc_simba_b = malloc(sizeof *pp, M_DEVBUF, M_NOWAIT);
266 if (sc->sc_sabre == NULL || sc->sc_simba_a == NULL ||
267 sc->sc_simba_b == NULL)
268 panic("could not allocate simba pbm's");
269
270 memset(sc->sc_sabre, 0, sizeof *pp);
271 memset(sc->sc_simba_a, 0, sizeof *pp);
272 memset(sc->sc_simba_b, 0, sizeof *pp);
273
274 /* grab the sabre ranges; use them for both simba's */
275 psycho_get_ranges(sc->sc_node, &sc->sc_sabre->pp_range,
276 &sc->sc_sabre->pp_nrange);
277 sc->sc_simba_b->pp_range = sc->sc_simba_a->pp_range =
278 sc->sc_sabre->pp_range;
279 sc->sc_simba_b->pp_nrange = sc->sc_simba_a->pp_nrange =
280 sc->sc_sabre->pp_nrange;
281
282 /* get the bus-range for the sabre. we expect 0..2 */
283 psycho_get_bus_range(sc->sc_node, sabre_br);
284
285 pba->pba_bus = sabre_br[0];
286
287 printf("bus range %u to %u", sabre_br[0], sabre_br[1]);
288
289 for (node = firstchild(sc->sc_node); node; node = nextsibling(node)) {
290 char *name = getpropstring(node, "name");
291 char *model, who;
292
293 if (strcmp(name, ROM_PCI_NAME) != 0)
294 continue;
295
296 model = getpropstring(node, "model");
297 if (strcmp(model, ROM_SIMBA_MODEL) != 0)
298 continue;
299
300 psycho_get_bus_range(node, simba_br);
301
302 if (simba_br[0] == 1) { /* PCI B */
303 pp = sc->sc_simba_b;
304 pp->pp_pcictl = &sc->sc_regs->psy_pcictl[1];
305 who = 'b';
306 } else { /* PCI A */
307 pp = sc->sc_simba_a;
308 pp->pp_pcictl = &sc->sc_regs->psy_pcictl[0];
309 who = 'a';
310 }
311 /* link us in .. */
312 pp->pp_sc = sc;
313
314 printf("; simba %c, PCI bus %d", who, simba_br[0]);
315
316 /* grab the simba registers, interrupt map and map mask */
317 psycho_get_registers(node, &pp->pp_regs, &pp->pp_nregs);
318 psycho_get_intmap(node, &pp->pp_intmap, &pp->pp_nintmap);
319 psycho_get_intmapmask(node, &pp->pp_intmapmask);
320
321 /* allocate our tags */
322 pp->pp_memt = psycho_alloc_mem_tag(pp);
323 pp->pp_iot = psycho_alloc_io_tag(pp);
324 pp->pp_dmat = psycho_alloc_dma_tag(pp);
325 pp->pp_flags = (pp->pp_memt ? PCI_FLAGS_MEM_ENABLED : 0) |
326 (pp->pp_iot ? PCI_FLAGS_IO_ENABLED : 0);
327
328 /* allocate a chipset for this */
329 pp->pp_pc = psycho_alloc_chipset(pp, node, &_sparc_pci_chipset);
330 }
331
332 /* setup the rest of the sabre pbm */
333 pp = sc->sc_sabre;
334 pp->pp_sc = sc;
335 pp->pp_memt = sc->sc_psycho_this->pp_memt;
336 pp->pp_iot = sc->sc_psycho_this->pp_iot;
337 pp->pp_dmat = sc->sc_psycho_this->pp_dmat;
338 pp->pp_flags = sc->sc_psycho_this->pp_flags;
339 pp->pp_intmap = NULL;
340 pp->pp_regs = NULL;
341 pp->pp_pcictl = sc->sc_psycho_this->pp_pcictl;
342 pba->pba_pc = psycho_alloc_chipset(pp, sc->sc_node,
343 sc->sc_psycho_this->pp_pc);
344
345 printf("\n");
346
347 /* and finally start up the IOMMU ... */
348 psycho_iommu_init(sc);
349
350 /*
351 * get us a config space tag, and punch in the physical address
352 * of the PCI configuration space. note that we use unmapped
353 * access to PCI configuration space, relying on the bus space
354 * macros to provide the proper ASI based on the bus tag.
355 */
356 sc->sc_configtag = psycho_alloc_config_tag(sc->sc_simba_a);
357 if (bus_space_map2(sc->sc_bustag,
358 PCI_CONFIG_BUS_SPACE,
359 sc->sc_basepaddr + 0x01000000,
360 0x0100000,
361 0,
362 0,
363 &bh))
364 panic("could not map sabre PCI configuration space");
365 sc->sc_configaddr = (paddr_t)bh;
366 }
367
368 /*
369 * SUNW,psycho initialisation ..
370 * - XXX what do we do here?
371 *
372 * i think that an attaching psycho should here find it's partner psycho
373 * and if they haven't been attached yet, allocate both psycho_pbm's and
374 * fill them both in here, and when the partner attaches, there is little
375 * to do... perhaps keep a static array of what psycho have been found so
376 * far (or perhaps those that have not yet been finished). .mrg.
377 * note that the partner can be found via matching `ranges' properties.
378 */
379 static void
380 psycho_init(sc, pba)
381 struct psycho_softc *sc;
382 struct pcibus_attach_args *pba;
383 {
384 #if 1
385 panic("can't do SUNW,psycho yet");
386 #else
387
388 /*
389 * OK, so the deal here is:
390 * - given our base register address, search our sibling
391 * devices for a match.
392 * - if we find a match, we are attaching an almost
393 * already setup PCI bus, the partner already done.
394 * - otherwise, we are doing the hard slog.
395 */
396 for (n = 0; n < psycho_cd.cd_ndevs; n++) {
397 psycho_softc *osc = &psycho_cd.cd_devs[n];
398
399 /*
400 * I am not myself.
401 */
402 if (osc == sc || osc->sc_regs != sc->sc_regs)
403 continue;
404
405 /*
406 * OK, so we found a matching regs that wasn't me,
407 * so that must make me partly attached. Finish it.
408 */
409 }
410
411 /* Oh, dear. OK, lets get started */
412
413 /* who? said a voice, incredulous */
414 sc->sc_mode = PSYCHO_MODE_PSYCHO_A;
415 printf("psycho: ");
416 #endif
417 }
418
419 /*
420 * PCI bus support
421 */
422
423 /*
424 * allocate a PCI chipset tag and set it's cookie.
425 */
426 static pci_chipset_tag_t
427 psycho_alloc_chipset(pp, node, pc)
428 struct psycho_pbm *pp;
429 int node;
430 pci_chipset_tag_t pc;
431 {
432 pci_chipset_tag_t npc;
433
434 npc = malloc(sizeof *npc, M_DEVBUF, M_NOWAIT);
435 if (npc == NULL)
436 panic("could not allocate pci_chipset_tag_t");
437 memcpy(npc, pc, sizeof *pc);
438 npc->cookie = pp;
439 npc->node = node;
440
441 return (npc);
442 }
443
444 /*
445 * grovel the OBP for various psycho properties
446 */
447 static void
448 psycho_get_bus_range(node, brp)
449 int node;
450 int *brp;
451 {
452 int n;
453
454 if (getprop(node, "bus-range", sizeof(*brp), &n, (void **)&brp))
455 panic("could not get psycho bus-range");
456 if (n != 2)
457 panic("broken psycho bus-range");
458 DPRINTF(PDB_PROM, ("psycho debug: got `bus-range' for node %08x: %u - %u\n", node, brp[0], brp[1]));
459 }
460
461 static void
462 psycho_get_ranges(node, rp, np)
463 int node;
464 struct psycho_ranges **rp;
465 int *np;
466 {
467
468 if (getprop(node, "ranges", sizeof(**rp), np, (void **)rp))
469 panic("could not get psycho ranges");
470 DPRINTF(PDB_PROM, ("psycho debug: got `ranges' for node %08x: %d entries\n", node, *np));
471 }
472
473 static void
474 psycho_get_registers(node, rp, np)
475 int node;
476 struct psycho_registers **rp;
477 int *np;
478 {
479
480 if (getprop(node, "reg", sizeof(**rp), np, (void **)rp))
481 panic("could not get psycho registers");
482 DPRINTF(PDB_PROM, ("psycho debug: got `reg' for node %08x: %d entries\n", node, *np));
483 }
484
485 static void
486 psycho_get_intmap(node, imp, np)
487 int node;
488 struct psycho_interrupt_map **imp;
489 int *np;
490 {
491
492 if (getprop(node, "interrupt-map", sizeof(**imp), np, (void **)imp))
493 panic("could not get psycho interrupt-map");
494 DPRINTF(PDB_PROM, ("psycho debug: got `interupt-map' for node %08x\n", node));
495 }
496
497 static void
498 psycho_get_intmapmask(node, immp)
499 int node;
500 struct psycho_interrupt_map_mask *immp;
501 {
502 int n;
503
504 if (getprop(node, "interrupt-map-mask", sizeof(*immp), &n,
505 (void **)&immp))
506 panic("could not get psycho interrupt-map-mask");
507 if (n != 1)
508 panic("broken psycho interrupt-map-mask");
509 DPRINTF(PDB_PROM, ("psycho debug: got `interrupt-map-mask' for node %08x\n", node));
510 }
511
512 /*
513 * initialise the IOMMU..
514 */
515 void
516 psycho_iommu_init(sc)
517 struct psycho_softc *sc;
518 {
519 char *name;
520
521 /* punch in our copies */
522 sc->sc_is.is_bustag = sc->sc_bustag;
523 sc->sc_is.is_iommu = &sc->sc_regs->psy_iommu;
524 /* IIi does not have streaming buffers */
525 if (sc->sc_mode != PSYCHO_MODE_SABRE)
526 sc->sc_is.is_sb = &sc->sc_regs->psy_iommu_strbuf;
527 else
528 sc->sc_is.is_sb = 0;
529
530 /* give us a nice name.. */
531 name = (char *)malloc(32, M_DEVBUF, M_NOWAIT);
532 if (name == 0)
533 panic("couldn't malloc iommu name");
534 snprintf(name, 32, "%s dvma", sc->sc_dev.dv_xname);
535
536 /* XXX XXX XXX FIX ME tsbsize XXX XXX XXX */
537 iommu_init(name, &sc->sc_is, 0);
538 }
539
540 /*
541 * below here is bus space and bus dma support
542 */
543 bus_space_tag_t
544 psycho_alloc_bus_tag(pp, type)
545 struct psycho_pbm *pp;
546 int type;
547 {
548 struct psycho_softc *sc = pp->pp_sc;
549 bus_space_tag_t bt;
550
551 bt = (bus_space_tag_t)
552 malloc(sizeof(struct sparc_bus_space_tag), M_DEVBUF, M_NOWAIT);
553 if (bt == NULL)
554 panic("could not allocate psycho bus tag");
555
556 bzero(bt, sizeof *bt);
557 bt->cookie = pp;
558 bt->parent = sc->sc_bustag;
559 bt->type = type;
560 bt->sparc_bus_map = _psycho_bus_map;
561 bt->sparc_bus_mmap = psycho_bus_mmap;
562 bt->sparc_intr_establish = psycho_intr_establish;
563 return (bt);
564 }
565
566 bus_dma_tag_t
567 psycho_alloc_dma_tag(pp)
568 struct psycho_pbm *pp;
569 {
570 struct psycho_softc *sc = pp->pp_sc;
571 bus_dma_tag_t dt, pdt = sc->sc_dmatag;
572
573 dt = (bus_dma_tag_t)
574 malloc(sizeof(struct sparc_bus_dma_tag), M_DEVBUF, M_NOWAIT);
575 if (dt == NULL)
576 panic("could not allocate psycho dma tag");
577
578 bzero(dt, sizeof *dt);
579 dt->_cookie = pp;
580 dt->_parent = pdt;
581 #define PCOPY(x) dt->x = pdt->x
582 PCOPY(_dmamap_create);
583 PCOPY(_dmamap_destroy);
584 dt->_dmamap_load = psycho_dmamap_load;
585 PCOPY(_dmamap_load_mbuf);
586 PCOPY(_dmamap_load_uio);
587 PCOPY(_dmamap_load_raw);
588 dt->_dmamap_unload = psycho_dmamap_unload;
589 dt->_dmamap_sync = psycho_dmamap_sync;
590 dt->_dmamem_alloc = psycho_dmamem_alloc;
591 dt->_dmamem_free = psycho_dmamem_free;
592 dt->_dmamem_map = psycho_dmamem_map;
593 dt->_dmamem_unmap = psycho_dmamem_unmap;
594 PCOPY(_dmamem_mmap);
595 #undef PCOPY
596 return (dt);
597 }
598
599 /*
600 * bus space support. <sparc64/dev/psychoreg.h> has a discussion about
601 * PCI physical addresses.
602 */
603
604 static int get_childspace __P((int));
605
606 static int
607 get_childspace(type)
608 int type;
609 {
610 int ss;
611
612 switch (type) {
613 case PCI_CONFIG_BUS_SPACE:
614 ss = 0x00;
615 break;
616 case PCI_IO_BUS_SPACE:
617 ss = 0x01;
618 break;
619 case PCI_MEMORY_BUS_SPACE:
620 ss = 0x02;
621 break;
622 #if 0
623 /* we don't do 64 bit memory space */
624 case PCI_MEMORY64_BUS_SPACE:
625 ss = 0x03;
626 break;
627 #endif
628 default:
629 panic("get_childspace: unknown bus type");
630 }
631
632 return (ss);
633 }
634
635 static int
636 _psycho_bus_map(t, btype, offset, size, flags, vaddr, hp)
637 bus_space_tag_t t;
638 bus_type_t btype;
639 bus_addr_t offset;
640 bus_size_t size;
641 int flags;
642 vaddr_t vaddr;
643 bus_space_handle_t *hp;
644 {
645 struct psycho_pbm *pp = t->cookie;
646 struct psycho_softc *sc = pp->pp_sc;
647 int i, ss;
648
649 DPRINTF(PDB_BUSMAP, ("_psycho_bus_map: type %d off %qx sz %qx flags %d va %p", t->type, offset, size, flags, vaddr));
650
651 ss = get_childspace(t->type);
652 DPRINTF(PDB_BUSMAP, (" cspace %d", ss));
653
654
655 for (i = 0; i < pp->pp_nrange; i++) {
656 bus_addr_t paddr;
657
658 if (((pp->pp_range[i].cspace >> 24) & 0x03) != ss)
659 continue;
660
661 paddr = pp->pp_range[i].phys_lo + offset;
662 paddr |= ((bus_addr_t)pp->pp_range[i].phys_hi<<32);
663 DPRINTF(PDB_BUSMAP, ("\n_psycho_bus_map: mapping paddr space %lx offset %lx paddr %qx\n",
664 (long)ss, (long)offset, paddr));
665 return (bus_space_map2(sc->sc_bustag, t->type, paddr,
666 size, flags, vaddr, hp));
667 }
668 DPRINTF(PDB_BUSMAP, (" FAILED\n"));
669 return (EINVAL);
670 }
671
672 static int
673 psycho_bus_mmap(t, btype, paddr, flags, hp)
674 bus_space_tag_t t;
675 bus_type_t btype;
676 bus_addr_t paddr;
677 int flags;
678 bus_space_handle_t *hp;
679 {
680 bus_addr_t offset = paddr;
681 struct psycho_pbm *pp = t->cookie;
682 struct psycho_softc *sc = pp->pp_sc;
683 int i, ss;
684
685 ss = get_childspace(t->type);
686
687 DPRINTF(PDB_BUSMAP, ("_psycho_bus_mmap: type %d flags %d pa %qx\n", btype, flags, paddr));
688
689 for (i = 0; i < pp->pp_nrange; i++) {
690 bus_addr_t paddr;
691
692 if (((pp->pp_range[i].cspace >> 24) & 0x03) != ss)
693 continue;
694
695 paddr = pp->pp_range[i].phys_lo + offset;
696 paddr |= ((bus_addr_t)pp->pp_range[i].phys_hi<<32);
697 DPRINTF(PDB_BUSMAP, ("\n_psycho_bus_mmap: mapping paddr space %lx offset %lx paddr %qx\n",
698 (long)ss, (long)offset, paddr));
699 return (bus_space_mmap(sc->sc_bustag, 0, paddr,
700 flags, hp));
701 }
702
703 return (-1);
704 }
705
706 /*
707 * interrupt mapping. this tells what sparc ipl any given ino runs at.
708 */
709 static int pci_ino_to_ipl_table[] = {
710 0, 0, 0, 0, /* PCI A, Slot 0, INTA#/B#/C#/D# */
711 0, 0, 0, 0, /* PCI A, Slot 1, INTA#/B#/C#/D# */
712 0, 0, 0, 0, /* PCI A, Slot 2, INTA#/B#/C#/D# (unavailable) */
713 0, 0, 0, 0, /* PCI A, Slot 3, INTA#/B#/C#/D# (unavailable) */
714 0, 0, 0, 0, /* PCI B, Slot 0, INTA#/B#/C#/D# */
715 0, 0, 0, 0, /* PCI B, Slot 0, INTA#/B#/C#/D# */
716 0, 0, 0, 0, /* PCI B, Slot 2, INTA#/B#/C#/D# */
717 0, 0, 0, 0, /* PCI B, Slot 3, INTA#/B#/C#/D# */
718 4, /* SCSI */
719 6, /* Ethernet */
720 3, /* Parallel */
721 9, /* Audio Record */
722 9, /* Audio Playback */
723 14, /* Power Fail */
724 4, /* Keyboard/Mouse/Serial */
725 8, /* Floppy */
726 14, /* Thermal Warning */
727 12, /* Keyboard */
728 12, /* Mouse */
729 12, /* Serial */
730 0, /* Reserved */
731 0, /* Reserved */
732 14, /* Uncorrectable ECC error */
733 14, /* Correctable ECC error */
734 14, /* PCI A bus error */
735 14, /* PCI B bus error */
736 14, /* power management */
737 };
738
739 int
740 psycho_intr_map(tag, pin, line, ihp)
741 pcitag_t tag;
742 int pin;
743 int line;
744 pci_intr_handle_t *ihp;
745 {
746
747 if (line < 0 || line > 0x32)
748 panic("psycho_intr_map: line line < 0 || line > 0x32");
749
750 /* UltraSPARC IIi does not use this register, but we have set it */
751 (*ihp) = line;
752 return (0);
753 }
754
755 /*
756 * install an interrupt handler for a PCI device
757 */
758 void *
759 psycho_intr_establish(t, level, flags, handler, arg)
760 bus_space_tag_t t;
761 int level;
762 int flags;
763 int (*handler) __P((void *));
764 void *arg;
765 {
766 struct psycho_pbm *pp = t->cookie;
767 struct psycho_softc *sc = pp->pp_sc;
768 struct intrhand *ih;
769 int ino;
770 long vec = level;
771
772 ih = (struct intrhand *)
773 malloc(sizeof(struct intrhand), M_DEVBUF, M_NOWAIT);
774 if (ih == NULL)
775 return (NULL);
776
777 DPRINTF(PDB_INTR, ("\npsycho_intr_establish: level %x", level));
778 ino = INTINO(vec);
779 DPRINTF(PDB_INTR, (" ino %x", ino));
780 if ((flags & BUS_INTR_ESTABLISH_SOFTINTR) == 0) {
781 volatile int64_t *intrmapptr, *intrclrptr;
782 int64_t intrmap = 0;
783 int i;
784
785 DPRINTF(PDB_INTR, ("\npsycho: intr %lx: %lx\nHunting for IRQ...\n",
786 (long)ino, intrlev[ino]));
787 if ((ino & INTMAP_OBIO) == 0) {
788 /*
789 * there are only 8 PCI interrupt INO's available
790 */
791 i = INTPCIINOX(vec);
792
793 intrmapptr = &((&sc->sc_regs->pcia_slot0_int)[i]);
794 intrclrptr = &sc->sc_regs->pcia0_clr_int[i<<2];
795
796 DPRINTF(PDB_INTR, ("- turning on PCI intr %d", i));
797 } else {
798 /*
799 * there are INTPCI_MAXOBINO (0x16) OBIO interrupts
800 * available here (i think).
801 */
802 i = INTPCIOBINOX(vec);
803 if (i > INTPCI_MAXOBINO)
804 panic("ino %d", vec);
805
806 intrmapptr = &((&sc->sc_regs->scsi_int_map)[i]);
807 intrclrptr = &((&sc->sc_regs->scsi_clr_int)[i]);
808
809 DPRINTF(PDB_INTR, ("- turning on OBIO intr %d", i));
810 }
811
812 /* Register the map and clear intr registers */
813 ih->ih_map = intrmapptr;
814 ih->ih_clr = intrclrptr;
815
816 /*
817 * Read the current value as we can't change it besides the
818 * valid bit so so make sure only this bit is changed.
819 */
820 intrmap = *intrmapptr;
821 DPRINTF(PDB_INTR, ("; read intrmap = %016qx", intrmap));
822
823 /* Enable the interrupt */
824 intrmap |= INTMAP_V;
825 DPRINTF(PDB_INTR, ("; addr of intrmapptr = %p", intrmapptr));
826 DPRINTF(PDB_INTR, ("; writing intrmap = %016qx\n", intrmap));
827 *intrmapptr = intrmap;
828 DPRINTF(PDB_INTR, ("; reread intrmap = %016qx",
829 (intrmap = *intrmapptr)));
830 }
831 #ifdef DEBUG
832 if (psycho_debug & PDB_INTR) {
833 long i;
834
835 for (i = 0; i < 500000000; i++)
836 continue;
837 }
838 #endif
839
840 ih->ih_fun = handler;
841 ih->ih_arg = arg;
842 ih->ih_number = ino | 0x7c0;
843 ih->ih_pil = pci_ino_to_ipl_table[ino];
844 DPRINTF(PDB_INTR, ("; installing handler %p with ino %u pil %u\n",
845 handler, (u_int)ino, (u_int)ih->ih_pil));
846 intr_establish(ih->ih_pil, ih);
847 return (ih);
848 }
849
850 /*
851 * hooks into the iommu dvma calls.
852 */
853 int
854 psycho_dmamap_load(t, map, buf, buflen, p, flags)
855 bus_dma_tag_t t;
856 bus_dmamap_t map;
857 void *buf;
858 bus_size_t buflen;
859 struct proc *p;
860 int flags;
861 {
862 struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie;
863 struct psycho_softc *sc = pp->pp_sc;
864
865 return (iommu_dvmamap_load(t, &sc->sc_is, map, buf, buflen, p, flags));
866 }
867
868 void
869 psycho_dmamap_unload(t, map)
870 bus_dma_tag_t t;
871 bus_dmamap_t map;
872 {
873 struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie;
874 struct psycho_softc *sc = pp->pp_sc;
875
876 iommu_dvmamap_unload(t, &sc->sc_is, map);
877 }
878
879 void
880 psycho_dmamap_sync(t, map, offset, len, ops)
881 bus_dma_tag_t t;
882 bus_dmamap_t map;
883 bus_addr_t offset;
884 bus_size_t len;
885 int ops;
886 {
887 struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie;
888 struct psycho_softc *sc = pp->pp_sc;
889
890 iommu_dvmamap_sync(t, &sc->sc_is, map, offset, len, ops);
891 bus_dmamap_sync(t->_parent, map, offset, len, ops);
892 }
893
894 int
895 psycho_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags)
896 bus_dma_tag_t t;
897 bus_size_t size;
898 bus_size_t alignment;
899 bus_size_t boundary;
900 bus_dma_segment_t *segs;
901 int nsegs;
902 int *rsegs;
903 int flags;
904 {
905 struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie;
906 struct psycho_softc *sc = pp->pp_sc;
907
908 return (iommu_dvmamem_alloc(t, &sc->sc_is, size, alignment, boundary,
909 segs, nsegs, rsegs, flags));
910 }
911
912 void
913 psycho_dmamem_free(t, segs, nsegs)
914 bus_dma_tag_t t;
915 bus_dma_segment_t *segs;
916 int nsegs;
917 {
918 struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie;
919 struct psycho_softc *sc = pp->pp_sc;
920
921 iommu_dvmamem_free(t, &sc->sc_is, segs, nsegs);
922 }
923
924 int
925 psycho_dmamem_map(t, segs, nsegs, size, kvap, flags)
926 bus_dma_tag_t t;
927 bus_dma_segment_t *segs;
928 int nsegs;
929 size_t size;
930 caddr_t *kvap;
931 int flags;
932 {
933 struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie;
934 struct psycho_softc *sc = pp->pp_sc;
935
936 return (iommu_dvmamem_map(t, &sc->sc_is, segs, nsegs, size, kvap, flags));
937 }
938
939 void
940 psycho_dmamem_unmap(t, kva, size)
941 bus_dma_tag_t t;
942 caddr_t kva;
943 size_t size;
944 {
945 struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie;
946 struct psycho_softc *sc = pp->pp_sc;
947
948 iommu_dvmamem_unmap(t, &sc->sc_is, kva, size);
949 }
950