diff options
author | Henric Jungheim <henric@cvs.openbsd.org> | 2003-02-17 01:29:22 +0000 |
---|---|---|
committer | Henric Jungheim <henric@cvs.openbsd.org> | 2003-02-17 01:29:22 +0000 |
commit | ecebaec0fd1a08a0975b8f756936722a40ae03a6 (patch) | |
tree | 59277d25c05e37b02700a112ccaf0a5859342f3b /sys/arch/sparc64/dev | |
parent | 914c2239132eb3f27af97793d1c7534d2e08045d (diff) |
Add support for the Sun Enterprise 450
Reduce the size of a GENERIC kernel by ~190k
Remove the nasty pointer/bus_space_handle_t casts
Adds debug bus_space code including the ability to trace
bus operations (it actually works now).
The following rules are now followed (and verfified by the debug
code):
1. A "bus_space_handle_t" may only be used with the
"bus_space_tag_t" that created it.
2. Only "bus_space_map()" may create "bus_space_handle_t"s.
3. A "bus_space_handle_t" may not be modified after it has
been created (other than being destroyed by "bus_space_unmap()").
Thanks to help from mcbride, marc, jason, drahn, to anyone that might
have slipped my mind at the moment.
ok jason@, deraadt@
Diffstat (limited to 'sys/arch/sparc64/dev')
-rw-r--r-- | sys/arch/sparc64/dev/auxio.c | 43 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/beeper.c | 14 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/ce4231.c | 18 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/com_ebus.c | 32 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/comkbd_ebus.c | 41 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/ebus.c | 247 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/ebusvar.h | 8 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/iommu.c | 589 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/iommureg.h | 7 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/iommuvar.h | 34 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/lpt_ebus.c | 15 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/pci_machdep.c | 42 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/pckbc_ebus.c | 13 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/psycho.c | 665 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/psychovar.h | 37 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/sab.c | 18 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/sbus.c | 379 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/sbusvar.h | 7 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/schizo.c | 351 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/schizovar.h | 9 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/upa.c | 63 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/uperf_ebus.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/zs.c | 4 |
23 files changed, 1307 insertions, 1333 deletions
diff --git a/sys/arch/sparc64/dev/auxio.c b/sys/arch/sparc64/dev/auxio.c index 5b23a0b0ad4..1e33b7298be 100644 --- a/sys/arch/sparc64/dev/auxio.c +++ b/sys/arch/sparc64/dev/auxio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auxio.c,v 1.4 2002/03/14 01:26:44 millert Exp $ */ +/* $OpenBSD: auxio.c,v 1.5 2003/02/17 01:29:19 henric Exp $ */ /* $NetBSD: auxio.c,v 1.1 2000/04/15 03:08:13 mrg Exp $ */ /* @@ -100,19 +100,39 @@ auxio_ebus_attach(parent, self, aux) return; } + sc->sc_tag = ea->ea_memtag; + if (ea->ea_nregs != 5 || ea->ea_nvaddrs != 5) { printf(": not 5 (%d) registers, only setting led", ea->ea_nregs); sc->sc_flags = AUXIO_LEDONLY|AUXIO_EBUS; } else { sc->sc_flags = AUXIO_EBUS; - sc->sc_pci = (bus_space_handle_t)(u_long)ea->ea_vaddrs[1]; - sc->sc_freq = (bus_space_handle_t)(u_long)ea->ea_vaddrs[1]; - sc->sc_scsi = (bus_space_handle_t)(u_long)ea->ea_vaddrs[1]; - sc->sc_temp = (bus_space_handle_t)(u_long)ea->ea_vaddrs[1]; + if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[2], + sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS, + &sc->sc_freq)) { + printf(": unable to map freq\n"); + return; + } + if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[3], + sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS, + &sc->sc_scsi)) { + printf(": unable to map SCSI\n"); + return; + } + if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[4], + sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS, + &sc->sc_temp)) { + printf(": unable to map temp\n"); + return; + } + } + + if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[0], sizeof(u_int32_t), + BUS_SPACE_MAP_PROMADDRESS, &sc->sc_led)) { + printf(": unable to map LED\n"); + return; } - sc->sc_led = (bus_space_handle_t)(u_long)ea->ea_vaddrs[0]; - sc->sc_tag = ea->ea_bustag; auxio_attach_common(sc); } @@ -138,6 +158,8 @@ auxio_sbus_attach(parent, self, aux) timeout_set(&sc->sc_to, auxio_led_blink, sc); + sc->sc_tag = sa->sa_bustag; + if (sa->sa_nreg < 1 || sa->sa_npromvaddrs < 1) { printf(": no registers??\n"); return; @@ -150,8 +172,11 @@ auxio_sbus_attach(parent, self, aux) /* sbus auxio only has one set of registers */ sc->sc_flags = AUXIO_LEDONLY|AUXIO_SBUS; - sc->sc_led = (bus_space_handle_t)(u_long)sa->sa_promvaddr; - sc->sc_tag = sa->sa_bustag; + if (bus_space_map(sc->sc_tag, sa->sa_promvaddr, 1, + BUS_SPACE_MAP_PROMADDRESS, &sc->sc_led)) { + printf(": couldn't map registers\n"); + return; + } auxio_attach_common(sc); } diff --git a/sys/arch/sparc64/dev/beeper.c b/sys/arch/sparc64/dev/beeper.c index b87e7144b0e..b8386f34bec 100644 --- a/sys/arch/sparc64/dev/beeper.c +++ b/sys/arch/sparc64/dev/beeper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: beeper.c,v 1.6 2002/08/19 20:19:13 jason Exp $ */ +/* $OpenBSD: beeper.c,v 1.7 2003/02/17 01:29:19 henric Exp $ */ /* * Copyright (c) 2001 Jason L. Wright (jason@thought.net) @@ -108,12 +108,16 @@ beeper_attach(parent, self, aux) struct beeper_softc *sc = (void *)self; struct ebus_attach_args *ea = aux; - sc->sc_iot = ea->ea_bustag; + sc->sc_iot = ea->ea_iotag; /* Use prom address if available, otherwise map it. */ - if (ea->ea_nvaddrs) - sc->sc_ioh = (bus_space_handle_t)ea->ea_vaddrs[0]; - else if (ebus_bus_map(sc->sc_iot, 0, + if (ea->ea_nvaddrs) { + if (bus_space_map(sc->sc_iot, ea->ea_vaddrs[0], 0, + BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh)) { + printf(": can't map PROM register space\n"); + return; + } + } else if (ebus_bus_map(sc->sc_iot, 0, EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_ioh) != 0) { printf(": can't map register space\n"); diff --git a/sys/arch/sparc64/dev/ce4231.c b/sys/arch/sparc64/dev/ce4231.c index 1983f7e8fe9..a09ad77b145 100644 --- a/sys/arch/sparc64/dev/ce4231.c +++ b/sys/arch/sparc64/dev/ce4231.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ce4231.c,v 1.11 2002/09/10 17:27:27 jason Exp $ */ +/* $OpenBSD: ce4231.c,v 1.12 2003/02/17 01:29:19 henric Exp $ */ /* * Copyright (c) 1999 Jason L. Wright (jason@thought.net) @@ -237,7 +237,7 @@ ce4231_attach(parent, self, aux) sc->sc_last_format = 0xffffffff; /* Pass on the bus tags */ - sc->sc_bustag = ea->ea_bustag; + sc->sc_bustag = ea->ea_memtag; sc->sc_dmatag = ea->ea_dmatag; /* Make sure things are sane. */ @@ -251,13 +251,13 @@ ce4231_attach(parent, self, aux) return; } - sc->sc_cih = bus_intr_establish(ea->ea_bustag, ea->ea_intrs[0], + sc->sc_cih = bus_intr_establish(sc->sc_bustag, ea->ea_intrs[0], IPL_AUDIO, 0, ce4231_cintr, sc); if (sc->sc_cih == NULL) { printf(": couldn't establish capture interrupt\n"); return; } - sc->sc_pih = bus_intr_establish(ea->ea_bustag, ea->ea_intrs[1], + sc->sc_pih = bus_intr_establish(sc->sc_bustag, ea->ea_intrs[1], IPL_AUDIO, 0, ce4231_pintr, sc); if (sc->sc_pih == NULL) { printf(": couldn't establish play interrupt1\n"); @@ -266,28 +266,28 @@ ce4231_attach(parent, self, aux) /* XXX what if prom has already mapped?! */ - if (ebus_bus_map(ea->ea_bustag, 0, + if (ebus_bus_map(sc->sc_bustag, 0, EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_cshandle) != 0) { printf(": couldn't map cs4231 registers\n"); return; } - if (ebus_bus_map(ea->ea_bustag, 0, + if (ebus_bus_map(sc->sc_bustag, 0, EBUS_PADDR_FROM_REG(&ea->ea_regs[1]), ea->ea_regs[1].size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_pdmahandle) != 0) { printf(": couldn't map dma1 registers\n"); return; } - if (ebus_bus_map(ea->ea_bustag, 0, + if (ebus_bus_map(sc->sc_bustag, 0, EBUS_PADDR_FROM_REG(&ea->ea_regs[2]), ea->ea_regs[2].size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_cdmahandle) != 0) { printf(": couldn't map dma2 registers\n"); return; } - if (ebus_bus_map(ea->ea_bustag, 0, + if (ebus_bus_map(sc->sc_bustag, 0, EBUS_PADDR_FROM_REG(&ea->ea_regs[3]), ea->ea_regs[3].size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_auxhandle) != 0) { printf(": couldn't map aux registers\n"); @@ -1480,7 +1480,7 @@ ce4231_trigger_output(addr, start, end, blksize, intr, arg, param) for (p = sc->sc_dmas; p->addr != start; p = p->next) /*EMPTY*/; if (p == NULL) { - printf("%s: trigger_output: bad addr: %x\n", + printf("%s: trigger_output: bad addr: %p\n", sc->sc_dev.dv_xname, start); return (EINVAL); } diff --git a/sys/arch/sparc64/dev/com_ebus.c b/sys/arch/sparc64/dev/com_ebus.c index 7b5b2ca7c02..1afdc6553c8 100644 --- a/sys/arch/sparc64/dev/com_ebus.c +++ b/sys/arch/sparc64/dev/com_ebus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com_ebus.c,v 1.7 2002/06/04 19:26:49 jason Exp $ */ +/* $OpenBSD: com_ebus.c,v 1.8 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: com_ebus.c,v 1.6 2001/07/24 19:27:10 eeh Exp $ */ /* @@ -106,10 +106,9 @@ com_ebus_attach(parent, self, aux) struct ebus_attach_args *ea = aux; int i, com_is_input, com_is_output; - sc->sc_iot = ea->ea_bustag; sc->sc_iobase = EBUS_PADDR_FROM_REG(&ea->ea_regs[0]); /* - * Addresses that shoud be supplied by the prom: + * Addresses that should be supplied by the prom: * - normal com registers * - ns873xx configuration registers * - DMA space @@ -119,22 +118,31 @@ com_ebus_attach(parent, self, aux) * * Use the prom address if there. */ - if (ea->ea_nvaddrs) - sc->sc_ioh = (bus_space_handle_t)ea->ea_vaddrs[0]; - else if (ebus_bus_map(sc->sc_iot, 0, - EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), - ea->ea_regs[0].size, - BUS_SPACE_MAP_LINEAR, - 0, &sc->sc_ioh) != 0) { + if (ea->ea_nvaddrs) { + if (bus_space_map(ea->ea_memtag, ea->ea_vaddrs[0], 0, + BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh) == 0) { + printf(": can't map register space\n"); + return; + } + sc->sc_iot = ea->ea_memtag; + } else if (ebus_bus_map(ea->ea_memtag, 0, + EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), + ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) { + sc->sc_iot = ea->ea_memtag; + } else if (ebus_bus_map(ea->ea_iotag, 0, + EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), + ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) { + sc->sc_iot = ea->ea_iotag; + } else { printf(": can't map register space\n"); - return; + return; } sc->sc_hwflags = 0; sc->sc_swflags = 0; sc->sc_frequency = BAUD_BASE; for (i = 0; i < ea->ea_nintrs; i++) - bus_intr_establish(ea->ea_bustag, ea->ea_intrs[i], + bus_intr_establish(sc->sc_iot, ea->ea_intrs[i], IPL_TTY, 0, comintr, sc); /* Figure out if we're the console. */ diff --git a/sys/arch/sparc64/dev/comkbd_ebus.c b/sys/arch/sparc64/dev/comkbd_ebus.c index 4dd348f2769..68c0535b4a2 100644 --- a/sys/arch/sparc64/dev/comkbd_ebus.c +++ b/sys/arch/sparc64/dev/comkbd_ebus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: comkbd_ebus.c,v 1.10 2002/12/22 16:13:30 miod Exp $ */ +/* $OpenBSD: comkbd_ebus.c,v 1.11 2003/02/17 01:29:20 henric Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -197,7 +197,7 @@ comkbd_attach(parent, self, aux) timeout_set(&sc->sc_bellto, comkbd_bellstop, sc); - sc->sc_iot = ea->ea_bustag; + sc->sc_iot = ea->ea_memtag; sc->sc_rxget = sc->sc_rxput = sc->sc_rxbeg = sc->sc_rxbuf; sc->sc_rxend = sc->sc_rxbuf + COMK_RX_RING; @@ -215,34 +215,41 @@ comkbd_attach(parent, self, aux) return; } - sc->sc_ih = bus_intr_establish(ea->ea_bustag, + /* Use prom address if available, otherwise map it. */ + if (ea->ea_nvaddrs && bus_space_map(ea->ea_memtag, ea->ea_vaddrs[0], 0, + BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh) == 0) { + sc->sc_iot = ea->ea_memtag; + } else if (ebus_bus_map(ea->ea_memtag, 0, + EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), + ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) { + sc->sc_iot = ea->ea_memtag; + } else if (ebus_bus_map(ea->ea_iotag, 0, + EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), + ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) { + sc->sc_iot = ea->ea_iotag; + } else { + printf(": can't map register space\n"); + return; + } + + sc->sc_ih = bus_intr_establish(sc->sc_iot, ea->ea_intrs[0], IPL_TTY, 0, comkbd_intr, sc); if (sc->sc_ih == NULL) { printf(": can't get hard intr\n"); return; } - /* Use prom address if available, otherwise map it. */ - if (ea->ea_nvaddrs) - sc->sc_ioh = (bus_space_handle_t)ea->ea_vaddrs[0]; - else if (ebus_bus_map(sc->sc_iot, 0, - EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), - ea->ea_regs[0].size, - BUS_SPACE_MAP_LINEAR, - 0, &sc->sc_ioh) != 0) { - printf(": can't map register space\n"); - return; - } - if (console) { comkbd_init(sc); cn_tab->cn_dev = makedev(77, sc->sc_dv.dv_unit); /* XXX */ cn_tab->cn_pollc = wskbd_cnpollc; cn_tab->cn_getc = wskbd_cngetc; if (ISTYPE5(sc->sc_layout)) { - wskbd_cnattach(&comkbd_consops, sc, &sunkbd5_keymapdata); + wskbd_cnattach(&comkbd_consops, sc, + &sunkbd5_keymapdata); } else { - wskbd_cnattach(&comkbd_consops, sc, &sunkbd_keymapdata); + wskbd_cnattach(&comkbd_consops, sc, + &sunkbd_keymapdata); } sc->sc_ier = IER_ETXRDY | IER_ERXRDY; COM_WRITE(sc, com_ier, sc->sc_ier); diff --git a/sys/arch/sparc64/dev/ebus.c b/sys/arch/sparc64/dev/ebus.c index cc3f022b634..8f802a40c69 100644 --- a/sys/arch/sparc64/dev/ebus.c +++ b/sys/arch/sparc64/dev/ebus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ebus.c,v 1.9 2002/03/14 03:16:00 millert Exp $ */ +/* $OpenBSD: ebus.c,v 1.10 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: ebus.c,v 1.24 2001/07/25 03:49:54 eeh Exp $ */ /* @@ -99,30 +99,31 @@ int ebus_find_node(struct pci_attach_args *); /* * here are our bus space and bus dma routines. */ -static paddr_t ebus_bus_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int); -static int _ebus_bus_map(bus_space_tag_t, bus_type_t, bus_addr_t, - bus_size_t, int, vaddr_t, - bus_space_handle_t *); -static void *ebus_intr_establish(bus_space_tag_t, int, int, int, - int (*)(void *), void *); - -static int ebus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, - bus_size_t, struct proc *, int); +static paddr_t ebus_bus_mmap(bus_space_tag_t, bus_space_tag_t, bus_addr_t, + off_t, int, int); +static int _ebus_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t, + bus_size_t, int, bus_space_handle_t *); +static void *ebus_intr_establish(bus_space_tag_t, bus_space_tag_t, int, int, + int, int (*)(void *), void *); +static int ebus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t, + struct proc *, int); static void ebus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t); static void ebus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t, - bus_size_t, int); + bus_size_t, int); int ebus_dmamem_alloc(bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t, - bus_dma_segment_t *, int, int *, int); + bus_dma_segment_t *, int, int *, int); void ebus_dmamem_free(bus_dma_tag_t, bus_dma_segment_t *, int); int ebus_dmamem_map(bus_dma_tag_t, bus_dma_segment_t *, int, size_t, - caddr_t *, int); + caddr_t *, int); void ebus_dmamem_unmap(bus_dma_tag_t, caddr_t, size_t); +bus_space_tag_t ebus_alloc_mem_tag(struct ebus_softc *, bus_space_tag_t); +bus_space_tag_t ebus_alloc_io_tag(struct ebus_softc *, bus_space_tag_t); +bus_space_tag_t _ebus_alloc_bus_tag(struct ebus_softc *sc, const char *, + bus_space_tag_t, int); + int -ebus_match(parent, match, aux) - struct device *parent; - void *match; - void *aux; +ebus_match(struct device *parent, void *match, void *aux) { struct pci_attach_args *pa = aux; char name[10]; @@ -161,9 +162,7 @@ ebus_match(parent, match, aux) * after the sbus code which does similar things. */ void -ebus_attach(parent, self, aux) - struct device *parent, *self; - void *aux; +ebus_attach(struct device *parent, struct device *self, void *aux) { struct ebus_softc *sc = (struct ebus_softc *)self; struct pci_attach_args *pa = aux; @@ -173,9 +172,8 @@ ebus_attach(parent, self, aux) printf("\n"); - sc->sc_memtag = pa->pa_memt; - sc->sc_iotag = pa->pa_iot; - sc->sc_childbustag = ebus_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE); + sc->sc_memtag = ebus_alloc_mem_tag(sc, pa->pa_memt); + sc->sc_iotag = ebus_alloc_io_tag(sc, pa->pa_iot); sc->sc_dmatag = ebus_alloc_dma_tag(sc, pa->pa_dmat); node = PCITAG_NODE(pa->pa_tag); @@ -235,10 +233,8 @@ ebus_attach(parent, self, aux) } int -ebus_setup_attach_args(sc, node, ea) - struct ebus_softc *sc; - int node; - struct ebus_attach_args *ea; +ebus_setup_attach_args(struct ebus_softc *sc, int node, + struct ebus_attach_args *ea) { int n, rv; @@ -249,7 +245,8 @@ ebus_setup_attach_args(sc, node, ea) ea->ea_name[n] = '\0'; ea->ea_node = node; - ea->ea_bustag = sc->sc_childbustag; + ea->ea_memtag = sc->sc_memtag; + ea->ea_iotag = sc->sc_iotag; ea->ea_dmatag = sc->sc_dmatag; rv = getprop(node, "reg", sizeof(struct ebus_regs), &ea->ea_nregs, @@ -279,10 +276,8 @@ ebus_setup_attach_args(sc, node, ea) } void -ebus_destroy_attach_args(ea) - struct ebus_attach_args *ea; +ebus_destroy_attach_args(struct ebus_attach_args *ea) { - if (ea->ea_name) free((void *)ea->ea_name, M_DEVBUF); if (ea->ea_regs) @@ -294,9 +289,7 @@ ebus_destroy_attach_args(ea) } int -ebus_print(aux, p) - void *aux; - const char *p; +ebus_print(void *aux, const char *p) { struct ebus_attach_args *ea = aux; int i; @@ -323,9 +316,7 @@ ebus_print(aux, p) * to give the INO for this interrupt. */ void -ebus_find_ino(sc, ea) - struct ebus_softc *sc; - struct ebus_attach_args *ea; +ebus_find_ino(struct ebus_softc *sc, struct ebus_attach_args *ea) { u_int32_t hi, lo, intr; int i, j, k; @@ -376,26 +367,41 @@ next_intr:; } } +bus_space_tag_t +ebus_alloc_mem_tag(struct ebus_softc *sc, bus_space_tag_t parent) +{ + return (_ebus_alloc_bus_tag(sc, "mem", parent, + 0x02)); /* 32-bit mem space (where's the #define???) */ +} + +bus_space_tag_t +ebus_alloc_io_tag(struct ebus_softc *sc, bus_space_tag_t parent) +{ + return (_ebus_alloc_bus_tag(sc, "io", parent, + 0x01)); /* IO space (where's the #define???) */ +} /* * bus space and bus dma below here */ bus_space_tag_t -ebus_alloc_bus_tag(sc, type) - struct ebus_softc *sc; - int type; +_ebus_alloc_bus_tag(struct ebus_softc *sc, const char *name, + bus_space_tag_t parent, int ss) { - bus_space_tag_t bt; + struct sparc_bus_space_tag *bt; - bt = (bus_space_tag_t) - malloc(sizeof(struct sparc_bus_space_tag), M_DEVBUF, M_NOWAIT); + bt = malloc(sizeof(*bt), M_DEVBUF, M_NOWAIT); if (bt == NULL) panic("could not allocate ebus bus tag"); bzero(bt, sizeof *bt); + snprintf(bt->name, sizeof(bt->name), "%s_%s", + sc->sc_dev.dv_xname, name); bt->cookie = sc; - bt->parent = sc->sc_memtag; - bt->type = type; + bt->parent = parent; + bt->default_type = ss; + bt->asi = parent->asi; + bt->sasi = parent->sasi; bt->sparc_bus_map = _ebus_bus_map; bt->sparc_bus_mmap = ebus_bus_mmap; bt->sparc_intr_establish = ebus_intr_establish; @@ -403,9 +409,7 @@ ebus_alloc_bus_tag(sc, type) } bus_dma_tag_t -ebus_alloc_dma_tag(sc, pdt) - struct ebus_softc *sc; - bus_dma_tag_t pdt; +ebus_alloc_dma_tag(struct ebus_softc *sc, bus_dma_tag_t pdt) { bus_dma_tag_t dt; @@ -441,26 +445,33 @@ ebus_alloc_dma_tag(sc, pdt) * about PCI physical addresses, which also applies to ebus. */ static int -_ebus_bus_map(t, btype, offset, size, flags, vaddr, hp) - bus_space_tag_t t; - bus_type_t btype; - bus_addr_t offset; - bus_size_t size; - int flags; - vaddr_t vaddr; - bus_space_handle_t *hp; +_ebus_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) { struct ebus_softc *sc = t->cookie; bus_addr_t hi, lo; - int i, ss; + int i; DPRINTF(EDB_BUSMAP, - ("\n_ebus_bus_map: type %d off %016llx sz %x flags %d va %p", - (int)t->type, (unsigned long long)offset, (int)size, (int)flags, - (void *)vaddr)); + ("\n_ebus_bus_map: type %d off %016llx sz %x flags %d", + (int)t->default_type, (unsigned long long)offset, (int)size, + (int)flags)); + + if (t->parent == 0 || t->parent->sparc_bus_map == 0) { + printf("\n_ebus_bus_map: invalid parent"); + return (EINVAL); + } + + t = t->parent; + + if (flags & BUS_SPACE_MAP_PROMADDRESS) { + return ((*t->sparc_bus_map) + (t, t0, offset, size, flags, hp)); + } hi = offset >> 32UL; lo = offset & 0xffffffff; + DPRINTF(EDB_BUSMAP, (" (hi %08x lo %08x)", (u_int)hi, (u_int)lo)); for (i = 0; i < sc->sc_nrange; i++) { bus_addr_t pciaddr; @@ -472,49 +483,41 @@ _ebus_bus_map(t, btype, offset, size, flags, vaddr, hp) (sc->sc_range[i].child_lo + sc->sc_range[i].size)) continue; - /* Isolate address space and find the right tag */ - ss = (sc->sc_range[i].phys_hi>>24)&3; - switch (ss) { - case 1: /* I/O space */ - t = sc->sc_iotag; - break; - case 2: /* Memory space */ - t = sc->sc_memtag; - break; - case 0: /* Config space */ - case 3: /* 64-bit Memory space */ - default: /* WTF? */ - /* We don't handle these */ - panic("_ebus_bus_map: illegal space %x", ss); - break; - } + if(((sc->sc_range[i].phys_hi >> 24) & 3) != t->default_type) + continue; + pciaddr = ((bus_addr_t)sc->sc_range[i].phys_mid << 32UL) | sc->sc_range[i].phys_lo; pciaddr += lo; DPRINTF(EDB_BUSMAP, - ("\n_ebus_bus_map: mapping space %x paddr offset %qx pciaddr %qx\n", - ss, (unsigned long long)offset, (unsigned long long)pciaddr)); + ("\n_ebus_bus_map: mapping space %x paddr offset %qx " + "pciaddr %qx\n", (int)t->default_type, + (unsigned long long)offset, (unsigned long long)pciaddr)); /* pass it onto the psycho */ - return (bus_space_map2(t, 0, pciaddr, size, flags, vaddr, hp)); + return ((*t->sparc_bus_map)(t, t0, pciaddr, size, flags, hp)); } DPRINTF(EDB_BUSMAP, (": FAILED\n")); return (EINVAL); } static paddr_t -ebus_bus_mmap(t, paddr, off, prot, flags) - bus_space_tag_t t; - bus_addr_t paddr; - off_t off; - int prot; - int flags; +ebus_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr, + off_t off, int prot, int flags) { bus_addr_t offset = paddr; struct ebus_softc *sc = t->cookie; int i; + if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) { + printf("\nebus_bus_mmap: invalid parent"); + return (-1); + } + + t = t->parent; + for (i = 0; i < sc->sc_nrange; i++) { - bus_addr_t paddr = ((bus_addr_t)sc->sc_range[i].child_hi << 32) | + bus_addr_t paddr = + ((bus_addr_t)sc->sc_range[i].child_hi << 32) | sc->sc_range[i].child_lo; if (offset != paddr) @@ -522,7 +525,7 @@ ebus_bus_mmap(t, paddr, off, prot, flags) DPRINTF(EDB_BUSMAP, ("\n_ebus_bus_mmap: mapping paddr %qx\n", (unsigned long long)paddr)); - return (bus_space_mmap(sc->sc_memtag, paddr, off, prot, flags)); + return ((*t->sparc_bus_mmap)(t, t0, paddr, off, prot, flags)); } return (-1); @@ -532,15 +535,17 @@ ebus_bus_mmap(t, paddr, off, prot, flags) * install an interrupt handler for a PCI device */ void * -ebus_intr_establish(t, pri, level, flags, handler, arg) - bus_space_tag_t t; - int pri; - int level; - int flags; - int (*handler)(void *); - void *arg; +ebus_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int pri, int level, + int flags, int (*handler)(void *), void *arg) { - return (bus_intr_establish(t->parent, pri, level, flags, + if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) { + printf("\nebus_bus_mmap: invalid parent"); + return (NULL); + } + + t = t->parent; + + return ((*t->sparc_intr_establish)(t, t0, pri, level, flags, handler, arg)); } @@ -548,77 +553,49 @@ ebus_intr_establish(t, pri, level, flags, handler, arg) * bus dma support */ int -ebus_dmamap_load(t, map, buf, buflen, p, flags) - bus_dma_tag_t t; - bus_dmamap_t map; - void *buf; - bus_size_t buflen; - struct proc *p; - int flags; +ebus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf, + bus_size_t buflen, struct proc *p, int flags) { return (bus_dmamap_load(t->_parent, map, buf, buflen, p, flags)); } void -ebus_dmamap_unload(t, map) - bus_dma_tag_t t; - bus_dmamap_t map; +ebus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map) { bus_dmamap_unload(t->_parent, map); } void -ebus_dmamap_sync(t, map, offset, len, ops) - bus_dma_tag_t t; - bus_dmamap_t map; - bus_addr_t offset; - bus_size_t len; - int ops; +ebus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, + bus_size_t len, int ops) { bus_dmamap_sync(t->_parent, map, offset, len, ops); } int -ebus_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags) - bus_dma_tag_t t; - bus_size_t size; - bus_size_t alignment; - bus_size_t boundary; - bus_dma_segment_t *segs; - int nsegs; - int *rsegs; - int flags; +ebus_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment, + bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, + int flags) { return (bus_dmamem_alloc(t->_parent, size, alignment, boundary, segs, nsegs, rsegs, flags)); } void -ebus_dmamem_free(t, segs, nsegs) - bus_dma_tag_t t; - bus_dma_segment_t *segs; - int nsegs; +ebus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs) { bus_dmamem_free(t->_parent, segs, nsegs); } int -ebus_dmamem_map(t, segs, nsegs, size, kvap, flags) - bus_dma_tag_t t; - bus_dma_segment_t *segs; - int nsegs; - size_t size; - caddr_t *kvap; - int flags; +ebus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, + size_t size, caddr_t *kvap, int flags) { return (bus_dmamem_map(t->_parent, segs, nsegs, size, kvap, flags)); } void -ebus_dmamem_unmap(t, kva, size) - bus_dma_tag_t t; - caddr_t kva; - size_t size; +ebus_dmamem_unmap(bus_dma_tag_t t, caddr_t kva, size_t size) { return (bus_dmamem_unmap(t->_parent, kva, size)); } diff --git a/sys/arch/sparc64/dev/ebusvar.h b/sys/arch/sparc64/dev/ebusvar.h index a2203c69dd9..023d8350ebb 100644 --- a/sys/arch/sparc64/dev/ebusvar.h +++ b/sys/arch/sparc64/dev/ebusvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ebusvar.h,v 1.4 2002/03/14 01:26:44 millert Exp $ */ +/* $OpenBSD: ebusvar.h,v 1.5 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: ebusvar.h,v 1.5 2001/07/20 00:07:13 eeh Exp $ */ /* @@ -41,7 +41,8 @@ struct ebus_attach_args { char *ea_name; /* PROM name */ int ea_node; /* PROM node */ - bus_space_tag_t ea_bustag; + bus_space_tag_t ea_memtag; + bus_space_tag_t ea_iotag; bus_dma_tag_t ea_dmatag; struct ebus_regs *ea_regs; /* registers */ @@ -60,7 +61,6 @@ struct ebus_softc { bus_space_tag_t sc_memtag; /* from pci */ bus_space_tag_t sc_iotag; /* from pci */ - bus_space_tag_t sc_childbustag; /* pass to children */ bus_dma_tag_t sc_dmatag; /* XXX */ struct ebus_ranges *sc_range; @@ -75,6 +75,6 @@ bus_dma_tag_t ebus_alloc_dma_tag(struct ebus_softc *, bus_dma_tag_t); bus_space_tag_t ebus_alloc_bus_tag(struct ebus_softc *, int); #define ebus_bus_map(t, bt, a, s, f, v, hp) \ - bus_space_map2(t, bt, a, s, f, v, hp) + bus_space_map(t, a, s, f, hp) #endif /* _SPARC64_DEV_EBUSVAR_H_ */ diff --git a/sys/arch/sparc64/dev/iommu.c b/sys/arch/sparc64/dev/iommu.c index e3829d1763e..9b75a86c311 100644 --- a/sys/arch/sparc64/dev/iommu.c +++ b/sys/arch/sparc64/dev/iommu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iommu.c,v 1.23 2002/10/12 01:09:43 krw Exp $ */ +/* $OpenBSD: iommu.c,v 1.24 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: iommu.c,v 1.47 2002/02/08 20:03:45 eeh Exp $ */ /* @@ -68,19 +68,21 @@ int iommudebug = 0x0; int iommu_dvmamap_sync_seg(bus_dma_tag_t, struct iommu_state *, bus_dma_segment_t *, bus_addr_t, bus_size_t, int); +int iommu_dvmamap_sync_range(struct iommu_state *, vaddr_t, bus_size_t); -#define iommu_strbuf_flush(i,v) do { \ - if ((i)->is_sb[0]) \ - bus_space_write_8((i)->is_bustag, \ - (bus_space_handle_t)(u_long) \ - &(i)->is_sb[0]->strbuf_pgflush, \ - 0, (v)); \ - if ((i)->is_sb[1]) \ - bus_space_write_8((i)->is_bustag, \ - (bus_space_handle_t)(u_long) \ - &(i)->is_sb[1]->strbuf_pgflush, \ - 0, (v)); \ - } while (0) +static inline void +iommu_strbuf_flush(struct iommu_state* is, vaddr_t va) +{ + int i; + for(i = 0; i < 2; ++i) { + struct strbuf_ctl *sb = is->is_sb[i]; + if(sb == NULL || sb->sb_flush == NULL) + continue; + + bus_space_write_8(sb->sb_bustag, sb->sb_sb, + STRBUFREG(strbuf_pgflush), va); + } +} static int iommu_strbuf_flush_done(struct iommu_state *); int64_t iommu_tsb_entry(struct iommu_state *, vaddr_t); @@ -94,11 +96,7 @@ static int iommu_tv_comp(struct timeval *, struct timeval *); * - create a private DVMA map. */ void -iommu_init(name, is, tsbsize, iovabase) - char *name; - struct iommu_state *is; - int tsbsize; - u_int32_t iovabase; +iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase) { psize_t size; vaddr_t va; @@ -137,7 +135,7 @@ iommu_init(name, is, tsbsize, iovabase) * contiguous. */ - size = NBPG<<(is->is_tsbsize); + size = NBPG << is->is_tsbsize; TAILQ_INIT(&mlist); if (uvm_pglistalloc((psize_t)size, (paddr_t)0, (paddr_t)-1, (paddr_t)NBPG, (paddr_t)0, &mlist, 1, 0) != 0) @@ -160,39 +158,39 @@ iommu_init(name, is, tsbsize, iovabase) va += NBPG; } pmap_update(pmap_kernel()); - bzero(is->is_tsb, size); + memset(is->is_tsb, 0, size); #ifdef DEBUG - if (iommudebug & IDB_INFO) - { + if (iommudebug & IDB_INFO) { /* Probe the iommu */ - struct iommureg *regs = is->is_iommu; - + /* The address or contents of the regs...? */ printf("iommu regs at: cr=%lx tsb=%lx flush=%lx\n", - (u_long)®s->iommu_cr, - (u_long)®s->iommu_tsb, - (u_long)®s->iommu_flush); - printf("iommu cr=%llx tsb=%llx\n", (unsigned long long)regs->iommu_cr, (unsigned long long)regs->iommu_tsb); - printf("TSB base %p phys %llx\n", (void *)is->is_tsb, (unsigned long long)is->is_ptsb); + (u_long)bus_space_vaddr(is->is_bustag, is->is_iommu) + + IOMMUREG(iommu_cr), + (u_long)bus_space_vaddr(is->is_bustag, is->is_iommu) + + IOMMUREG(iommu_tsb), + (u_long)bus_space_vaddr(is->is_bustag, is->is_iommu) + + IOMMUREG(iommu_flush)); + printf("iommu cr=%llx tsb=%llx\n", + IOMMUREG_READ(is, iommu_cr), + IOMMUREG_READ(is, iommu_tsb)); + printf("TSB base %p phys %llx\n", + (void *)is->is_tsb, (unsigned long long)is->is_ptsb); delay(1000000); /* 1 s */ } #endif /* - * Initialize streaming buffer, if it is there. - */ - if (is->is_sb[0] || is->is_sb[1]) - (void)pmap_extract(pmap_kernel(), (vaddr_t)&is->is_flush[0], - &is->is_flushpa); - - /* * now actually start up the IOMMU + * Don't start the thing until it can see all the TSB data */ + membar(MemIssue); iommu_reset(is); /* * Now all the hardware's working we need to allocate a dvma map. */ + printf("DVMA map: %x to %x\n", is->is_dvmabase, is->is_dvmaend); printf("IOTDB: %llx to %llx\n", (unsigned long long)is->is_ptsb, (unsigned long long)(is->is_ptsb + size)); @@ -207,33 +205,40 @@ iommu_init(name, is, tsbsize, iovabase) * they aren't there when the STRBUF_EN bit does not remain. */ void -iommu_reset(is) - struct iommu_state *is; +iommu_reset(struct iommu_state *is) { - struct iommu_strbuf *sb; int i; /* Need to do 64-bit stores */ - bus_space_write_8(is->is_bustag, - (bus_space_handle_t)(u_long)&is->is_iommu->iommu_tsb, - 0, is->is_ptsb); + + IOMMUREG_WRITE(is, iommu_tsb, is->is_ptsb); + /* Enable IOMMU in diagnostic mode */ - bus_space_write_8(is->is_bustag, - (bus_space_handle_t)(u_long)&is->is_iommu->iommu_cr, 0, - is->is_cr|IOMMUCR_DE); - - for (i=0; i<2; i++) { - if ((sb = is->is_sb[i]) != NULL) { - /* Enable diagnostics mode? */ - bus_space_write_8(is->is_bustag, - (bus_space_handle_t)(u_long)&sb->strbuf_ctl, - 0, STRBUF_EN); - - /* No streaming buffers? Disable them */ - if (bus_space_read_8(is->is_bustag, - (bus_space_handle_t)(u_long)&sb->strbuf_ctl, - 0) == 0) - is->is_sb[i] = 0; + IOMMUREG_WRITE(is, iommu_cr, is->is_cr | IOMMUCR_DE); + + for (i = 0; i < 2; i++) { + struct strbuf_ctl *sb = is->is_sb[i]; + + if(sb == NULL || sb->sb_flush == NULL) + continue; + + /* Enable diagnostics mode? */ + bus_space_write_8(sb->sb_bustag, sb->sb_sb, + STRBUFREG(strbuf_ctl), STRBUF_EN); + + membar(Lookaside); + + /* No streaming buffers? Disable them */ + if (bus_space_read_8(sb->sb_bustag, sb->sb_sb, + STRBUFREG(strbuf_ctl)) == 0) { + sb->sb_flush = NULL; + } else { + /* + * locate the pa of the flush buffer + */ + + pmap_extract(pmap_kernel(), + (vaddr_t)sb->sb_flush, &sb->sb_flushpa); } } } @@ -242,71 +247,74 @@ iommu_reset(is) * Here are the iommu control routines. */ void -iommu_enter(is, va, pa, flags) - struct iommu_state *is; - vaddr_t va; - int64_t pa; - int flags; +iommu_enter(struct iommu_state *is, vaddr_t va, int64_t pa, int flags) { int64_t tte; + int strbuf = flags & BUS_DMA_STREAMING; #ifdef DIAGNOSTIC if (va < is->is_dvmabase || va > is->is_dvmaend) panic("iommu_enter: va %#lx not in DVMA space", va); #endif - tte = MAKEIOTTE(pa, !(flags&BUS_DMA_NOWRITE), !(flags&BUS_DMA_NOCACHE), - (flags&BUS_DMA_STREAMING)); -tte |= (flags & 0xff000LL)<<(4*8);/* DEBUG */ - /* Is the streamcache flush really needed? */ - if (is->is_sb[0] || is->is_sb[1]) { + if (is->is_sb[0] != NULL || is->is_sb[1] != NULL) { iommu_strbuf_flush(is, va); iommu_strbuf_flush_done(is); } + else + strbuf = 0; + + tte = MAKEIOTTE(pa, !(flags & BUS_DMA_NOWRITE), + !(flags & BUS_DMA_NOCACHE), (strbuf)); +#ifdef DEBUG + tte |= (flags & 0xff000LL) << (4 * 8); /* DEBUG */ +#endif /* DEBUG */ + + DPRINTF(IDB_IOMMU, ("Clearing TSB slot %d for va %p\n", (int)IOTSBSLOT(va,is->is_tsbsize), (void *)(u_long)va)); is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)] = tte; - bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long) - &is->is_iommu->iommu_flush, 0, va); + /* Make is->is_tsb[] change globally visible. Needed? */ + membar(MemIssue); + IOMMUREG_WRITE(is, iommu_flush, va); + DPRINTF(IDB_IOMMU, ("iommu_enter: va %lx pa %lx TSB[%lx]@%p=%lx\n", va, (long)pa, (u_long)IOTSBSLOT(va,is->is_tsbsize), - (void *)(u_long)&is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)], + (void *)(u_long) + &is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)], (u_long)tte)); } - /* * Find the value of a DVMA address (debug routine). */ paddr_t -iommu_extract(is, dva) - struct iommu_state *is; - vaddr_t dva; +iommu_extract(struct iommu_state *is, vaddr_t dva) { int64_t tte = 0; if (dva >= is->is_dvmabase && dva < is->is_dvmaend) - tte = is->is_tsb[IOTSBSLOT(dva,is->is_tsbsize)]; + tte = is->is_tsb[IOTSBSLOT(dva, is->is_tsbsize)]; - if ((tte&IOTTE_V) == 0) + if ((tte & IOTTE_V) == 0) return ((paddr_t)-1L); - return (tte&IOTTE_PAMASK); + return (tte & IOTTE_PAMASK); } /* * Fetch a tsb entry with some sanity checking. */ int64_t -iommu_tsb_entry(is, dva) - struct iommu_state *is; - vaddr_t dva; +iommu_tsb_entry(struct iommu_state *is, vaddr_t dva) { int64_t tte; if (dva < is->is_dvmabase && dva >= is->is_dvmaend) panic("invalid dva: %llx", (long long)dva); + membar(Lookaside); + tte = is->is_tsb[IOTSBSLOT(dva,is->is_tsbsize)]; if ((tte & IOTTE_V) == 0) @@ -323,10 +331,7 @@ iommu_tsb_entry(is, dva) * XXX: this function needs better internal error checking. */ void -iommu_remove(is, va, len) - struct iommu_state *is; - vaddr_t va; - size_t len; +iommu_remove(struct iommu_state *is, vaddr_t va, size_t len) { #ifdef DIAGNOSTIC if (va < is->is_dvmabase || va > is->is_dvmaend) @@ -343,21 +348,34 @@ iommu_remove(is, va, len) va, (u_long)IOTSBSLOT(va,is->is_tsbsize), &is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)])); while (len > 0) { - DPRINTF(IDB_IOMMU, ("iommu_remove: clearing TSB slot %d for va %p size %lx\n", - (int)IOTSBSLOT(va,is->is_tsbsize), (void *)(u_long)va, (u_long)len)); - if (is->is_sb[0] || is->is_sb[0]) { - DPRINTF(IDB_IOMMU, ("iommu_remove: flushing va %p TSB[%lx]@%p=%lx, %lu bytes left\n", - (void *)(u_long)va, (long)IOTSBSLOT(va,is->is_tsbsize), - (void *)(u_long)&is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)], - (long)(is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)]), + /* NetBSD does *not* flush the streaming buffer (here, anyway) */ + DPRINTF(IDB_IOMMU, + ("iommu_remove: clearing TSB slot %d for va %p size %lx\n", + (int)IOTSBSLOT(va,is->is_tsbsize), + (void *)(u_long)va, (u_long)len)); + if (is->is_sb[0] != NULL || is->is_sb[1] != NULL) { + DPRINTF(IDB_IOMMU, + ("iommu_remove: flushing va %p TSB[%lx]@%p=%lx, " + "%lu bytes left\n", + (void *)(u_long)va, + (long)IOTSBSLOT(va,is->is_tsbsize), + (void *)(u_long) + &is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)], + (long) + (is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)]), (u_long)len)); iommu_strbuf_flush(is, va); if (len <= NBPG) iommu_strbuf_flush_done(is); - DPRINTF(IDB_IOMMU, ("iommu_remove: flushed va %p TSB[%lx]@%p=%lx, %lu bytes left\n", - (void *)(u_long)va, (long)IOTSBSLOT(va,is->is_tsbsize), - (void *)(u_long)&is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)], - (long)(is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)]), + DPRINTF(IDB_IOMMU, + ("iommu_remove: flushed va %p TSB[%lx]@%p=%lx, " + "%lu bytes left\n", + (void *)(u_long)va, + (long)IOTSBSLOT(va,is->is_tsbsize), + (void *)(u_long) + &is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)], + (long) + (is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)]), (u_long)len)); } @@ -367,16 +385,15 @@ iommu_remove(is, va, len) len -= NBPG; /* XXX Zero-ing the entry would not require RMW */ - is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)] &= ~IOTTE_V; - bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long) - &is->is_iommu->iommu_flush, 0, va); + is->is_tsb[IOTSBSLOT(va, is->is_tsbsize)] &= ~IOTTE_V; + membar(MemIssue); /* Needed? */ + IOMMUREG_WRITE(is, iommu_flush, va); va += NBPG; } } static int -iommu_tv_comp(t1, t2) - struct timeval *t1, *t2; +iommu_tv_comp(struct timeval *t1, struct timeval *t2) { if (t1->tv_sec < t2->tv_sec) return (-1); @@ -391,12 +408,22 @@ iommu_tv_comp(t1, t2) } static int -iommu_strbuf_flush_done(is) - struct iommu_state *is; +iommu_strbuf_flush_done(struct iommu_state *is) { struct timeval cur, flushtimeout; + struct timeval to = { 0, 500000 }; + u_int64_t flush[2]; + struct strbuf_ctl *sb[2]; + int i; + int present[2]; + + for(i = 0; i < 2; ++i) { + sb[i] = is->is_sb[i]; + present[i] = + (sb[i] == NULL || sb[i]->sb_flush == NULL) ? 0 : 1; + } - if (!is->is_sb[0] && !is->is_sb[1]) + if (!present[0] && !present[1]) return (0); /* @@ -411,74 +438,86 @@ iommu_strbuf_flush_done(is) * If it takes more than .5 sec, something * went wrong. */ - is->is_flush[0] = (is->is_sb[0] == NULL) ? 1 : 0; - is->is_flush[1] = (is->is_sb[1] == NULL) ? 1 : 0; - membar_memissue(); - - if (is->is_sb[0]) { - bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long) - &is->is_sb[0]->strbuf_flushsync, 0, is->is_flushpa); - bus_space_barrier(is->is_bustag, (bus_space_handle_t)(u_long) - &is->is_sb[0]->strbuf_flushsync, 0, sizeof(u_int64_t), - BUS_SPACE_BARRIER_WRITE); - } - if (is->is_sb[1]) { - bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long) - &is->is_sb[1]->strbuf_flushsync, 0, is->is_flushpa + 8); - bus_space_barrier(is->is_bustag, (bus_space_handle_t)(u_long) - &is->is_sb[1]->strbuf_flushsync, 0, sizeof(u_int64_t), - BUS_SPACE_BARRIER_WRITE); + /* + * If we're reading from the ASI_PHYS_CACHED, then we'll write to + * it too. No need to tempt fate or learn about Si bugs or such. + * FreeBSD just uses normal "volatile" reads/writes... + */ + + for(i = 0; i < 2; ++i) + if(present[i]) + stxa(sb[i]->sb_flushpa, ASI_PHYS_CACHED, 0); + + /* + * Insure any previous strbuf operations are complete and that + * memory is initialized before the IOMMU uses it + */ + membar(MemIssue); + + for(i = 0; i < 2; ++i) { + if (present[i]) + bus_space_write_8(sb[i]->sb_bustag, sb[i]->sb_sb, + STRBUFREG(strbuf_flushsync), sb[i]->sb_flushpa); } microtime(&cur); - flushtimeout.tv_usec = cur.tv_usec + 500000; /* 1/2 sec */ - if (flushtimeout.tv_usec >= 1000000) { - flushtimeout.tv_usec -= 1000000; - flushtimeout.tv_sec = cur.tv_sec + 1; - } else - flushtimeout.tv_sec = cur.tv_sec; + timeradd(&cur, &to, &flushtimeout); - DPRINTF(IDB_IOMMU, ("iommu_strbuf_flush_done: flush = %lx at va = %lx pa = %lx now=%lx:%lx until = %lx:%lx\n", - (long)is->is_flush, (long)&is->is_flush, - (long)is->is_flushpa, cur.tv_sec, cur.tv_usec, - flushtimeout.tv_sec, flushtimeout.tv_usec)); + DPRINTF(IDB_IOMMU, + ("iommu_strbuf_flush_done: flush[0] = %lx flush[1] = %lx " + "pa[0] = %lx pa[1] = %lx now=%lx:%lx until = %lx:%lx\n", + (long)present[0] ? + ldxa(sb[0]->sb_flushpa, ASI_PHYS_CACHED) : 1, + (long)present[1] ? + ldxa(sb[1]->sb_flushpa, ASI_PHYS_CACHED) : 1, + (long)sb[0]->sb_flushpa, + (long)sb[1]->sb_flushpa, cur.tv_sec, cur.tv_usec, + flushtimeout.tv_sec, flushtimeout.tv_usec)); + + membar(MemIssue | Lookaside); /* Bypass non-coherent D$ */ - while (((ldxa(is->is_flushpa, ASI_PHYS_CACHED) == 0) || - (ldxa(is->is_flushpa + 8, ASI_PHYS_CACHED) == 0)) && - (iommu_tv_comp(&cur, &flushtimeout) <= 0)) { + /* non-coherent...? Huh? */ + for(;;) { + membar(LoadLoad); + + flush[0] = + present[0] ? ldxa(sb[0]->sb_flushpa, ASI_PHYS_CACHED) : 1; + flush[1] = + present[1] ? ldxa(sb[1]->sb_flushpa, ASI_PHYS_CACHED) : 1; + + if(flush[0] && flush[1]) + break; + microtime(&cur); + /* Use existing time compare macros? */ + if(iommu_tv_comp(&cur, &flushtimeout) <= 0) + break; } #ifdef DIAGNOSTIC - if (((is->is_sb[0] != NULL) && (ldxa(is->is_flushpa, ASI_PHYS_CACHED) == 0)) || - ((is->is_sb[1] != NULL) && (ldxa(is->is_flushpa + 8, ASI_PHYS_CACHED) == 0))) { - printf("iommu_strbuf_flush_done: flush timeout %p,%p at %p\n", - (void *)(u_long)is->is_flush[0], - (void *)(u_long)is->is_flush[1], - (void *)(u_long)is->is_flushpa); /* panic? */ + if (flush[0] == 0 || flush[1] == 0) { + printf("iommu_strbuf_flush_done: flush timeout %p/%llx, " + "%p/%llx\n", + (void *)sb[0]->sb_flushpa, flush[0], + (void *)sb[1]->sb_flushpa, flush[1]); + /* panic? */ #ifdef DDB Debugger(); #endif } #endif DPRINTF(IDB_IOMMU, ("iommu_strbuf_flush_done: flushed\n")); - return (is->is_flush[0] && is->is_flush[1]); + return (flush[0] && flush[1]); } /* * IOMMU DVMA operations, common to SBUS and PCI. */ int -iommu_dvmamap_load(t, is, map, buf, buflen, p, flags) - bus_dma_tag_t t; - struct iommu_state *is; - bus_dmamap_t map; - void *buf; - bus_size_t buflen; - struct proc *p; - int flags; +iommu_dvmamap_load(bus_dma_tag_t t, struct iommu_state *is, bus_dmamap_t map, + void *buf, bus_size_t buflen, struct proc *p, int flags) { int s; int err; @@ -526,19 +565,18 @@ iommu_dvmamap_load(t, is, map, buf, buflen, p, flags) sgstart = is->is_dvmamap->ex_start; sgend = is->is_dvmamap->ex_end; } - s = splhigh(); /* * If our segment size is larger than the boundary we need to * split the transfer up int little pieces ourselves. */ + s = splhigh(); err = extent_alloc_subregion(is->is_dvmamap, sgstart, sgend, sgsize, align, 0, (sgsize > boundary) ? 0 : boundary, - EX_NOWAIT|EX_BOUNDZERO, (u_long *)&dvmaddr); + EX_NOWAIT | EX_BOUNDZERO, (u_long *)&dvmaddr); splx(s); #ifdef DEBUG - if (err || (dvmaddr == (bus_addr_t)-1)) - { + if (err || (dvmaddr == (bus_addr_t)-1)) { printf("iommu_dvmamap_load(): extent_alloc(%d, %x) failed!\n", (int)sgsize, flags); #ifdef DDB @@ -594,7 +632,7 @@ iommu_dvmamap_load(t, is, map, buf, buflen, p, flags) DPRINTF(IDB_INFO, ("iommu_dvmamap_load: " "seg %d start %lx size %lx\n", seg, (long)map->dm_segs[seg].ds_addr, map->dm_segs[seg].ds_len)); - map->dm_nsegs = seg+1; + map->dm_nsegs = seg + 1; map->dm_mapsize = buflen; if (p != NULL) @@ -624,7 +662,7 @@ iommu_dvmamap_load(t, is, map, buf, buflen, p, flags) map, (void *)vaddr, (long)dvmaddr, (long)(curaddr&~(NBPG-1)))); iommu_enter(is, trunc_page(dvmaddr), trunc_page(curaddr), - flags|0x4000); + flags | 0x4000); /* 0x4000? Magic...? */ dvmaddr += PAGE_SIZE; vaddr += sgsize; @@ -648,10 +686,7 @@ iommu_dvmamap_load(t, is, map, buf, buflen, p, flags) void -iommu_dvmamap_unload(t, is, map) - bus_dma_tag_t t; - struct iommu_state *is; - bus_dmamap_t map; +iommu_dvmamap_unload(bus_dma_tag_t t, struct iommu_state *is, bus_dmamap_t map) { int error, s; bus_size_t sgsize; @@ -673,7 +708,9 @@ iommu_dvmamap_unload(t, is, map) /* Mark the mappings as invalid. */ map->dm_mapsize = 0; map->dm_nsegs = 0; - + + sgsize = map->_dm_dvmasize; + s = splhigh(); error = extent_free(is->is_dvmamap, map->_dm_dvmastart, map->_dm_dvmasize, EX_NOWAIT); @@ -688,14 +725,9 @@ iommu_dvmamap_unload(t, is, map) int -iommu_dvmamap_load_raw(t, is, map, segs, nsegs, flags, size) - bus_dma_tag_t t; - struct iommu_state *is; - bus_dmamap_t map; - bus_dma_segment_t *segs; - int nsegs; - int flags; - bus_size_t size; +iommu_dvmamap_load_raw(bus_dma_tag_t t, struct iommu_state *is, + bus_dmamap_t map, bus_dma_segment_t *segs, int nsegs, int flags, + bus_size_t size) { struct vm_page *m; int i, j, s; @@ -734,7 +766,7 @@ iommu_dvmamap_load_raw(t, is, map, segs, nsegs, flags, size) pa = segs[0].ds_addr; sgsize = 0; left = size; - for (i=0; left && i<nsegs; i++) { + for (i = 0; left && i < nsegs; i++) { if (round_page(pa) != round_page(segs[i].ds_addr)) sgsize = round_page(sgsize); sgsize += min(left, segs[i].ds_len); @@ -757,17 +789,16 @@ iommu_dvmamap_load_raw(t, is, map, segs, nsegs, flags, size) */ err = extent_alloc_subregion(is->is_dvmamap, sgstart, sgend, sgsize, align, 0, (sgsize > boundary) ? 0 : boundary, - EX_NOWAIT|EX_BOUNDZERO, (u_long *)&dvmaddr); + EX_NOWAIT | EX_BOUNDZERO, (u_long *)&dvmaddr); splx(s); if (err != 0) return (err); #ifdef DEBUG - if (dvmaddr == (bus_addr_t)-1) - { - printf("iommu_dvmamap_load_raw(): extent_alloc(%d, %x) failed!\n", - (int)sgsize, flags); + if (dvmaddr == (bus_addr_t)-1) { + printf("iommu_dvmamap_load_raw(): extent_alloc(%d, %x) " + "failed!\n", (int)sgsize, flags); #ifdef DDB Debugger(); #else @@ -858,7 +889,7 @@ printf("appending offset %x pa %lx, prev %lx dva %lx prev %lx\n", DPRINTF(IDB_INFO, ("iommu_dvmamap_load_raw: " "seg %d start %lx size %lx\n", j, (long)map->dm_segs[j].ds_addr, - map->dm_segs[j].ds_len)); + (long)map->dm_segs[j].ds_len)); if (++j >= map->_dm_segcnt) { iommu_dvmamap_unload(t, is, map); return (E2BIG); @@ -884,7 +915,8 @@ printf("appending offset %x pa %lx, prev %lx dva %lx prev %lx\n", { if (iommudebug & 0x10) printf("seg %d:5d entering dvma %lx, prev %lx pa %lx\n", i, j, dvmaddr, prev_va, pa); #endif iommu_enter(is, prev_va = dvmaddr, - prev_pa = pa, flags|(++npg<<12)); + prev_pa = pa, + flags | (++npg << 12)); #ifdef DEBUG } else if (iommudebug & 0x10) printf("seg %d:%d skipping dvma %lx, prev %lx\n", i, j, dvmaddr, prev_va); #endif @@ -899,13 +931,17 @@ printf("appending offset %x pa %lx, prev %lx dva %lx prev %lx\n", map->dm_nsegs = j; #ifdef DIAGNOSTIC - { + { /* Scope */ int seg; for (seg = 0; seg < map->dm_nsegs; seg++) { - if (map->dm_segs[seg].ds_addr < is->is_dvmabase || - map->dm_segs[seg].ds_addr > is->is_dvmaend) { - printf("seg %d dvmaddr %lx out of range %x - %x\n", - seg, (long)map->dm_segs[seg].ds_addr, + if (map->dm_segs[seg].ds_addr < + is->is_dvmabase || + map->dm_segs[seg].ds_addr > + is->is_dvmaend) { + printf("seg %d dvmaddr %lx out of " + "range %x - %x\n", + seg, + (long)map->dm_segs[seg].ds_addr, is->is_dvmabase, is->is_dvmaend); #ifdef DDB Debugger(); @@ -957,22 +993,24 @@ printf("appending offset %x pa %lx, prev %lx dva %lx prev %lx\n", pa = VM_PAGE_TO_PHYS(m); DPRINTF(IDB_BUSDMA, - ("iommu_dvmamap_load_raw: map %p loading va %lx at pa %lx\n", + ("iommu_dvmamap_load_raw: map %p loading va %lx at " + "pa %lx\n", map, (long)dvmaddr, (long)(pa))); - iommu_enter(is, dvmaddr, pa, flags|0x8000); + iommu_enter(is, dvmaddr, pa, flags | 0x8000); /* Magic 0x8000? */ dvmaddr += pagesz; sgsize -= pagesz; } map->dm_mapsize = size; - map->dm_nsegs = i+1; + map->dm_nsegs = i + 1; #ifdef DIAGNOSTIC { int seg; for (seg = 0; seg < map->dm_nsegs; seg++) { if (map->dm_segs[seg].ds_addr < is->is_dvmabase || map->dm_segs[seg].ds_addr > is->is_dvmaend) { - printf("seg %d dvmaddr %lx out of range %x - %x\n", + printf("seg %d dvmaddr %lx out of range %x " + "- %x\n", seg, (long)map->dm_segs[seg].ds_addr, is->is_dvmabase, is->is_dvmaend); #ifdef DDB @@ -986,17 +1024,15 @@ printf("appending offset %x pa %lx, prev %lx dva %lx prev %lx\n", } void -iommu_dvmamap_sync(t, is, map, offset, len, ops) - bus_dma_tag_t t; - struct iommu_state *is; - bus_dmamap_t map; - bus_addr_t offset; - bus_size_t len; - int ops; +iommu_dvmamap_sync(bus_dma_tag_t t, struct iommu_state *is, bus_dmamap_t map, + bus_addr_t offset, bus_size_t len, int ops) { bus_size_t count; int i, needsflush = 0; + if (is->is_sb[0] == NULL && is->is_sb[1] == NULL) + return; + for (i = 0; i < map->dm_nsegs; i++) { if (offset < map->dm_segs[i].ds_len) break; @@ -1008,8 +1044,9 @@ iommu_dvmamap_sync(t, is, map, offset, len, ops) for (; len > 0 && i < map->dm_nsegs; i++) { count = min(map->dm_segs[i].ds_len - offset, len); - needsflush += iommu_dvmamap_sync_seg(t, is, &map->dm_segs[i], - offset, count, ops); + if(iommu_dvmamap_sync_seg(t, is, &map->dm_segs[i], + offset, count, ops)) + needsflush = 1; len -= count; } @@ -1024,109 +1061,87 @@ iommu_dvmamap_sync(t, is, map, offset, len, ops) * Flush an individual dma segment, returns non-zero if the streaming buffers * need flushing afterwards. */ + +int +iommu_dvmamap_sync_range(struct iommu_state *is, vaddr_t va, bus_size_t len) +{ + vaddr_t vaend; + + if (is->is_sb[0] == NULL && is->is_sb[1] == NULL) + return (0); + +#ifdef DIAGNOSTIC + if (va < is->is_dvmabase || va >= is->is_dvmaend) + panic("invalid va: %llx", (long long)va); +#endif + + if ((is->is_tsb[IOTSBSLOT(va, is->is_tsbsize)] & IOTTE_STREAM) == 0) + return (0); + + vaend = (va + len + PGOFSET) & ~PGOFSET; + va &= ~PGOFSET; + +#ifdef DIAGNOSTIC + if (va < is->is_dvmabase || vaend >= is->is_dvmaend) + panic("invalid va range: %llx to %llx (%x to %x)", + (long long)va, (long long)vaend, + is->is_dvmabase, + is->is_dvmaend); +#endif + + for( ; va <= vaend; va += NBPG) { + DPRINTF(IDB_BUSDMA, + ("iommu_dvmamap_sync_range: flushing va %p\n", + (void *)(u_long)va)); + iommu_strbuf_flush(is, va); + } + + return (1); +} + int -iommu_dvmamap_sync_seg(t, is, seg, offset, len, ops) - bus_dma_tag_t t; - struct iommu_state *is; - bus_dma_segment_t *seg; - bus_addr_t offset; - bus_size_t len; - int ops; +iommu_dvmamap_sync_seg(bus_dma_tag_t t, struct iommu_state *is, + bus_dma_segment_t *seg, bus_addr_t offset, bus_size_t len, int ops) { int needsflush = 0; vaddr_t va = seg->ds_addr + offset; - if (len == 0) - goto out; + DPRINTF(IDB_SYNC, + ("iommu_dvmamap_sync_seg: syncing va %p len %lu (%x)\n", + (void *)(u_long)va, (u_long)len, ops)); - len += offset & PGOFSET; - - if (ops & BUS_DMASYNC_PREREAD) { - DPRINTF(IDB_SYNC, - ("iommu_dvmamap_sync_seg: syncing va %p len %lu " - "BUS_DMASYNC_PREREAD\n", (void *)(u_long)va, (u_long)len)); + if (len == 0) + return (0); + if (ops & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTWRITE)) { /* Nothing to do */; } - if (ops & BUS_DMASYNC_POSTREAD) { - DPRINTF(IDB_SYNC, - ("iommu_dvmamap_sync_seg: syncing va %p len %lu " - "BUS_DMASYNC_POSTREAD\n", (void *)(u_long)va, (u_long)len)); - /* if we have a streaming buffer, flush it here first */ - if (is->is_sb[0] || is->is_sb[1]) - while (len > 0) { - DPRINTF(IDB_BUSDMA, - ("iommu_dvmamap_sync_seg: flushing va %p, %lu " - "bytes left\n", (void *)(u_long)va, (u_long)len)); - if (iommu_tsb_entry(is, va) & IOTTE_STREAM) { - iommu_strbuf_flush(is, va); - needsflush = 1; - } - if (len <= NBPG) - len = 0; - else - len -= NBPG; - va += NBPG; - } - } - if (ops & BUS_DMASYNC_PREWRITE) { - DPRINTF(IDB_SYNC, - ("iommu_dvmamap_sync_seg: syncing va %p len %lu " - "BUS_DMASYNC_PREWRITE\n", (void *)(u_long)va, (u_long)len)); - /* if we have a streaming buffer, flush it here first */ - if (is->is_sb[0] || is->is_sb[1]) - while (len > 0) { - DPRINTF(IDB_BUSDMA, - ("iommu_dvmamap_sync_seg: flushing va %p, %lu " - "bytes left\n", (void *)(u_long)va, (u_long)len)); - if (iommu_tsb_entry(is, va) & IOTTE_STREAM) { - iommu_strbuf_flush(is, va); - needsflush = 1; - } - if (len <= NBPG) - len = 0; - else - len -= NBPG; - va += NBPG; - } - } - if (ops & BUS_DMASYNC_POSTWRITE) { - DPRINTF(IDB_SYNC, - ("iommu_dvmamap_sync_seg: syncing va %p len %lu " - "BUS_DMASYNC_POSTWRITE\n", (void *)(u_long)va, (u_long)len)); - /* Nothing to do */; + if (ops & (BUS_DMASYNC_POSTREAD | BUS_DMASYNC_PREWRITE)) { + if (iommu_dvmamap_sync_range(is, va, len)) + needsflush = 1; } -out: return (needsflush); } int -iommu_dvmamem_alloc(t, is, size, alignment, boundary, segs, nsegs, rsegs, flags) - bus_dma_tag_t t; - struct iommu_state *is; - bus_size_t size, alignment, boundary; - bus_dma_segment_t *segs; - int nsegs; - int *rsegs; - int flags; +iommu_dvmamem_alloc(bus_dma_tag_t t, struct iommu_state *is, bus_size_t size, + bus_size_t alignment, bus_size_t boundary, bus_dma_segment_t *segs, + int nsegs, int *rsegs, int flags) { - DPRINTF(IDB_BUSDMA, ("iommu_dvmamem_alloc: sz %llx align %llx bound %llx " - "segp %p flags %d\n", (unsigned long long)size, - (unsigned long long)alignment, (unsigned long long)boundary, - segs, flags)); + DPRINTF(IDB_BUSDMA, ("iommu_dvmamem_alloc: sz %llx align %llx " + "bound %llx segp %p flags %d\n", (unsigned long long)size, + (unsigned long long)alignment, (unsigned long long)boundary, + segs, flags)); return (bus_dmamem_alloc(t->_parent, size, alignment, boundary, - segs, nsegs, rsegs, flags|BUS_DMA_DVMA)); + segs, nsegs, rsegs, flags | BUS_DMA_DVMA)); } void -iommu_dvmamem_free(t, is, segs, nsegs) - bus_dma_tag_t t; - struct iommu_state *is; - bus_dma_segment_t *segs; - int nsegs; +iommu_dvmamem_free(bus_dma_tag_t t, struct iommu_state *is, + bus_dma_segment_t *segs, int nsegs) { DPRINTF(IDB_BUSDMA, ("iommu_dvmamem_free: segp %p nsegs %d\n", @@ -1139,20 +1154,14 @@ iommu_dvmamem_free(t, is, segs, nsegs) * Check the flags to see whether we're streaming or coherent. */ int -iommu_dvmamem_map(t, is, segs, nsegs, size, kvap, flags) - bus_dma_tag_t t; - struct iommu_state *is; - bus_dma_segment_t *segs; - int nsegs; - size_t size; - caddr_t *kvap; - int flags; +iommu_dvmamem_map(bus_dma_tag_t t, struct iommu_state *is, + bus_dma_segment_t *segs, int nsegs, size_t size, caddr_t *kvap, int flags) { struct vm_page *m; vaddr_t va; bus_addr_t addr; struct pglist *mlist; - int cbit; + bus_addr_t cbit = 0; DPRINTF(IDB_BUSDMA, ("iommu_dvmamem_map: segp %p nsegs %d size %lx\n", segs, nsegs, size)); @@ -1171,7 +1180,6 @@ iommu_dvmamem_map(t, is, segs, nsegs, size, kvap, flags) /* * digest flags: */ - cbit = 0; if (flags & BUS_DMA_COHERENT) /* Disable vcache */ cbit |= PMAP_NVC; if (flags & BUS_DMA_NOCACHE) /* sideffects */ @@ -1188,7 +1196,8 @@ iommu_dvmamem_map(t, is, segs, nsegs, size, kvap, flags) #endif addr = VM_PAGE_TO_PHYS(m); DPRINTF(IDB_BUSDMA, ("iommu_dvmamem_map: " - "mapping va %lx at %llx\n", va, (unsigned long long)addr | cbit)); + "mapping va %lx at %llx\n", va, + (unsigned long long)addr | cbit)); pmap_enter(pmap_kernel(), va, addr | cbit, VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED); @@ -1204,11 +1213,8 @@ iommu_dvmamem_map(t, is, segs, nsegs, size, kvap, flags) * Unmap DVMA mappings from kernel */ void -iommu_dvmamem_unmap(t, is, kva, size) - bus_dma_tag_t t; - struct iommu_state *is; - caddr_t kva; - size_t size; +iommu_dvmamem_unmap(bus_dma_tag_t t, struct iommu_state *is, caddr_t kva, + size_t size) { DPRINTF(IDB_BUSDMA, ("iommu_dvmamem_unmap: kvm %p size %lx\n", @@ -1224,3 +1230,4 @@ iommu_dvmamem_unmap(t, is, kva, size) pmap_update(pmap_kernel()); uvm_km_free(kernel_map, (vaddr_t)kva, size); } + diff --git a/sys/arch/sparc64/dev/iommureg.h b/sys/arch/sparc64/dev/iommureg.h index 78e50e0743d..a03d49ab378 100644 --- a/sys/arch/sparc64/dev/iommureg.h +++ b/sys/arch/sparc64/dev/iommureg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iommureg.h,v 1.4 2002/07/24 19:03:19 jason Exp $ */ +/* $OpenBSD: iommureg.h,v 1.5 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: iommureg.h,v 1.6 2001/07/20 00:07:13 eeh Exp $ */ /* @@ -67,6 +67,9 @@ struct iommu_strbuf { volatile u_int64_t strbuf_flushsync;/* streaming buffer flush sync */ }; +#define IOMMUREG(x) (offsetof(struct iommureg, x)) +#define STRBUFREG(x) (offsetof(struct iommu_strbuf, x)) + /* streaming buffer control register */ #define STRBUF_EN 0x000000000000000001LL #define STRBUF_D 0x000000000000000002LL @@ -154,6 +157,8 @@ struct iommu_strbuf { #define INTSLOT(x) (((x)>>3)&0x7) #define INTPRI(x) ((x)&0x7) #define INTINO(x) ((x)&INTMAP_INO) +#define INTTID_SHIFT 26 +#define INTTID(x) (((x) & INTMAP_TID) >> INTTID_SHIFT) #define INTPCI_MAXOBINO 0x16 /* maximum OBIO INO value for PCI */ #define INTPCIOBINOX(x) ((x)&0x1f) /* OBIO ino index (for PCI machines) */ diff --git a/sys/arch/sparc64/dev/iommuvar.h b/sys/arch/sparc64/dev/iommuvar.h index 22933f7dccf..6dfccb6dea0 100644 --- a/sys/arch/sparc64/dev/iommuvar.h +++ b/sys/arch/sparc64/dev/iommuvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iommuvar.h,v 1.6 2002/03/14 01:26:44 millert Exp $ */ +/* $OpenBSD: iommuvar.h,v 1.7 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: iommuvar.h,v 1.9 2001/10/07 20:30:41 eeh Exp $ */ /* @@ -33,6 +33,17 @@ #define _SPARC64_DEV_IOMMUVAR_H_ /* + * per-Streaming Buffer state + */ + +struct strbuf_ctl { + bus_space_tag_t sb_bustag; /* streaming buffer registers */ + bus_space_handle_t sb_sb; /* Handle for our regs */ + paddr_t sb_flushpa; /* to flush streaming buffers */ + volatile int64_t *sb_flush; +}; + +/* * per-IOMMU state */ struct iommu_state { @@ -41,17 +52,14 @@ struct iommu_state { int is_tsbsize; /* 0 = 8K, ... */ u_int is_dvmabase; u_int is_dvmaend; - int64_t is_cr; /* IOMMU control regiter value */ + int64_t is_cr; /* IOMMU control register value */ struct extent *is_dvmamap; /* DVMA map for this instance */ - paddr_t is_flushpa; /* used to flush the SBUS */ - /* Needs to be volatile or egcs optimizes away loads */ - volatile int64_t is_flush[2]; + struct strbuf_ctl *is_sb[2]; /* Streaming buffers if any */ /* copies of our parents state, to allow us to be self contained */ bus_space_tag_t is_bustag; /* our bus tag */ - struct iommureg *is_iommu; /* IOMMU registers */ - struct iommu_strbuf *is_sb[2]; /* streaming buffer(s) */ + bus_space_handle_t is_iommu; /* IOMMU registers */ }; /* interfaces for PCI/SBUS code */ @@ -79,4 +87,16 @@ int iommu_dvmamem_map(bus_dma_tag_t, struct iommu_state *, void iommu_dvmamem_unmap(bus_dma_tag_t, struct iommu_state *, caddr_t, size_t); +#define IOMMUREG_READ(is, reg) \ + bus_space_read_8((is)->is_bustag, \ + (is)->is_iommu, \ + IOMMUREG(reg)) + +#define IOMMUREG_WRITE(is, reg, v) \ + bus_space_write_8((is)->is_bustag, \ + (is)->is_iommu, \ + IOMMUREG(reg), \ + (v)) + #endif /* _SPARC64_DEV_IOMMUVAR_H_ */ + diff --git a/sys/arch/sparc64/dev/lpt_ebus.c b/sys/arch/sparc64/dev/lpt_ebus.c index d51c64898d8..15d7f500c3e 100644 --- a/sys/arch/sparc64/dev/lpt_ebus.c +++ b/sys/arch/sparc64/dev/lpt_ebus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lpt_ebus.c,v 1.6 2002/07/18 02:20:17 jason Exp $ */ +/* $OpenBSD: lpt_ebus.c,v 1.7 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: lpt_ebus.c,v 1.8 2002/03/01 11:51:00 martin Exp $ */ /* @@ -80,13 +80,18 @@ lpt_ebus_attach(parent, self, aux) struct lpt_ebus_softc *sc = (void *)self; struct ebus_attach_args *ea = aux; - sc->sc_lpt.sc_iot = ea->ea_bustag; - if (ebus_bus_map(sc->sc_lpt.sc_iot, 0, + if (ebus_bus_map(ea->ea_memtag, 0, EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, - BUS_SPACE_MAP_LINEAR, 0, &sc->sc_lpt.sc_ioh) != 0) { + 0, 0, &sc->sc_lpt.sc_ioh) == 0) { + sc->sc_lpt.sc_iot = ea->ea_memtag; + } else if (ebus_bus_map(ea->ea_iotag, 0, + EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, + 0, 0, &sc->sc_lpt.sc_ioh) == 0) { + sc->sc_lpt.sc_iot = ea->ea_iotag; + } else { printf(": can't map register space\n"); - return; + return; } if (ebus_bus_map(sc->sc_lpt.sc_iot, 0, diff --git a/sys/arch/sparc64/dev/pci_machdep.c b/sys/arch/sparc64/dev/pci_machdep.c index 7889eada313..2b2088390b3 100644 --- a/sys/arch/sparc64/dev/pci_machdep.c +++ b/sys/arch/sparc64/dev/pci_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_machdep.c,v 1.10 2003/01/13 16:04:38 jason Exp $ */ +/* $OpenBSD: pci_machdep.c,v 1.11 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: pci_machdep.c,v 1.22 2001/07/20 00:07:13 eeh Exp $ */ /* @@ -338,24 +338,40 @@ pci_make_tag(pc, b, d, f) /* assume we are mapped little-endian/side-effect */ pcireg_t -pci_conf_read(pc, tag, reg) - pci_chipset_tag_t pc; - pcitag_t tag; - int reg; +pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) { - return (pc->conf_read(pc, tag, reg)); + pcireg_t val = (pcireg_t)~0; + + DPRINTF(SPDB_CONF, ("pci_conf_read: tag %lx reg %x ", + (long)PCITAG_OFFSET(tag), reg)); + if (PCITAG_NODE(tag) != -1) { + val = bus_space_read_4(pc->bustag, pc->bushandle, + PCITAG_OFFSET(tag) + reg); + } +#ifdef DEBUG + else DPRINTF(SPDB_CONF, ("pci_conf_read: bogus pcitag %x\n", + (int)PCITAG_OFFSET(tag))); +#endif + DPRINTF(SPDB_CONF, (" returning %08x\n", (u_int)val)); + + return (val); } void -pci_conf_write(pc, tag, reg, data) - pci_chipset_tag_t pc; - pcitag_t tag; - int reg; - pcireg_t data; +pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data) { - return (pc->conf_write(pc, tag, reg, data)); -} + DPRINTF(SPDB_CONF, ("pci_conf_write: tag %lx; reg %x; data %x; ", + (long)PCITAG_OFFSET(tag), reg, (int)data)); + /* If we don't know it, just punt. */ + if (PCITAG_NODE(tag) == -1) { + DPRINTF(SPDB_CONF, ("pci_config_write: bad addr")); + return; + } + + bus_space_write_4(pc->bustag, pc->bushandle, + PCITAG_OFFSET(tag) + reg, data); +} /* * interrupt mapping foo. diff --git a/sys/arch/sparc64/dev/pckbc_ebus.c b/sys/arch/sparc64/dev/pckbc_ebus.c index 59454d2bcd5..63408f88d1a 100644 --- a/sys/arch/sparc64/dev/pckbc_ebus.c +++ b/sys/arch/sparc64/dev/pckbc_ebus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pckbc_ebus.c,v 1.2 2002/04/08 17:49:42 jason Exp $ */ +/* $OpenBSD: pckbc_ebus.c,v 1.3 2003/02/17 01:29:20 henric Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -99,10 +99,10 @@ pckbc_ebus_attach(parent, self, aux) struct pckbc_ebus_softc *sc = (void *)self; struct pckbc_softc *psc = &sc->sc_pckbc; struct ebus_attach_args *ea = aux; - struct pckbc_internal *t; + struct pckbc_internal *t = NULL; int console; - sc->sc_iot = ea->ea_bustag; + sc->sc_iot = ea->ea_iotag; sc->sc_node = ea->ea_node; console = pckbc_ebus_is_console(sc); @@ -121,7 +121,8 @@ pckbc_ebus_attach(parent, self, aux) if (console == 0) { /* Use prom address if available, otherwise map it. */ if (ea->ea_nvaddrs) - sc->sc_ioh = (bus_space_handle_t)ea->ea_vaddrs[0]; + bus_space_map(sc->sc_iot, ea->ea_vaddrs[0], 0, 0, + &sc->sc_ioh); else if (ebus_bus_map(sc->sc_iot, 0, EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_ioh) != 0) { @@ -146,14 +147,14 @@ pckbc_ebus_attach(parent, self, aux) psc->intr_establish = pckbc_ebus_intr_establish; - sc->sc_irq[0] = bus_intr_establish(ea->ea_bustag, ea->ea_intrs[0], + sc->sc_irq[0] = bus_intr_establish(ea->ea_iotag, ea->ea_intrs[0], IPL_TTY, 0, pckbcintr, psc); if (sc->sc_irq[0] == NULL) { printf(": couldn't get intr0\n"); return; } - sc->sc_irq[1] = bus_intr_establish(ea->ea_bustag, ea->ea_intrs[1], + sc->sc_irq[1] = bus_intr_establish(ea->ea_iotag, ea->ea_intrs[1], IPL_TTY, 0, pckbcintr, psc); if (sc->sc_irq[1] == NULL) { printf(": couldn't get intr1\n"); diff --git a/sys/arch/sparc64/dev/psycho.c b/sys/arch/sparc64/dev/psycho.c index 951fa5ae12c..2e58495cd9c 100644 --- a/sys/arch/sparc64/dev/psycho.c +++ b/sys/arch/sparc64/dev/psycho.c @@ -1,8 +1,9 @@ -/* $OpenBSD: psycho.c,v 1.26 2003/02/11 19:20:26 mickey Exp $ */ +/* $OpenBSD: psycho.c,v 1.27 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp $ */ /* * Copyright (c) 1999, 2000 Matthew R. Green + * Copyright (c) 2003 Henric Jungheim * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -62,7 +63,7 @@ #define PDB_BUSMAP 0x02 #define PDB_INTR 0x04 #define PDB_CONF 0x08 -int psycho_debug = 0; +int psycho_debug = ~0; #define DPRINTF(l, s) do { if (psycho_debug & l) printf s; } while (0) #else #define DPRINTF(l, s) @@ -74,6 +75,8 @@ void psycho_get_bus_range(int, int *); void psycho_get_ranges(int, struct psycho_ranges **, int *); void psycho_set_intr(struct psycho_softc *, int, void *, u_int64_t *, u_int64_t *); +bus_space_tag_t _psycho_alloc_bus_tag(struct psycho_pbm *, + const char *, int, int, int); /* Interrupt handlers */ int psycho_ue(void *); @@ -91,12 +94,11 @@ void psycho_iommu_init(struct psycho_softc *, int); * bus space and bus dma support for UltraSPARC `psycho'. note that most * of the bus dma support is provided by the iommu dvma controller. */ -pcireg_t psycho_pci_conf_read(pci_chipset_tag_t pc, pcitag_t, int); -void psycho_pci_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t); -paddr_t psycho_bus_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int); -int _psycho_bus_map(bus_space_tag_t, bus_type_t, bus_addr_t, - bus_size_t, int, vaddr_t, bus_space_handle_t *); -void *psycho_intr_establish(bus_space_tag_t, int, int, int, +paddr_t psycho_bus_mmap(bus_space_tag_t, bus_space_tag_t, bus_addr_t, off_t, + int, int); +int _psycho_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t, + bus_size_t, int, bus_space_handle_t *); +void *psycho_intr_establish(bus_space_tag_t, bus_space_tag_t, int, int, int, int (*)(void *), void *); int psycho_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, @@ -112,6 +114,8 @@ void psycho_dmamem_free(bus_dma_tag_t, bus_dma_segment_t *, int); int psycho_dmamem_map(bus_dma_tag_t, bus_dma_segment_t *, int, size_t, caddr_t *, int); void psycho_dmamem_unmap(bus_dma_tag_t, caddr_t, size_t); +void psycho_map_psycho(struct psycho_softc *, int, bus_addr_t, bus_size_t, + bus_addr_t, bus_size_t); /* base pci_chipset */ extern struct sparc_pci_chipset _sparc_pci_chipset; @@ -122,7 +126,6 @@ extern struct sparc_pci_chipset _sparc_pci_chipset; int psycho_match(struct device *, void *, void *); void psycho_attach(struct device *, struct device *, void *); int psycho_print(void *aux, const char *p); -int psycho_get_childspace(int); struct cfattach psycho_ca = { @@ -185,10 +188,7 @@ struct psycho_type { }; int -psycho_match(parent, match, aux) - struct device *parent; - void *match; - void *aux; +psycho_match(struct device *parent, void *match, void *aux) { struct mainbus_attach_args *ma = aux; struct psycho_type *ptype; @@ -222,19 +222,15 @@ psycho_match(parent, match, aux) * just copy it's tags and addresses. */ void -psycho_attach(parent, self, aux) - struct device *parent, *self; - void *aux; +psycho_attach(struct device *parent, struct device *self, void *aux) { struct psycho_softc *sc = (struct psycho_softc *)self; struct psycho_softc *osc = NULL; struct psycho_pbm *pp; struct pcibus_attach_args pba; struct mainbus_attach_args *ma = aux; - bus_space_handle_t bh; u_int64_t csr; int psycho_br[2], n; - struct pci_ctl *pci_ctl; struct psycho_type *ptype; printf("\n"); @@ -244,7 +240,7 @@ psycho_attach(parent, self, aux) sc->sc_dmatag = ma->ma_dmatag; /* - * call the model-specific initialisation routine. + * call the model-specific initialization routine. */ for (ptype = psycho_types; ptype->p_name != NULL; ptype++) { @@ -276,26 +272,13 @@ psycho_attach(parent, self, aux) sc->sc_basepaddr = (paddr_t)ma->ma_reg[2].ur_paddr; if (ma->ma_naddress > 2) { - sc->sc_regs = (struct psychoreg *) - (u_long)ma->ma_address[2]; - pci_ctl = (struct pci_ctl *) - (u_long)ma->ma_address[0]; + psycho_map_psycho(sc, 0, + ma->ma_address[2], sizeof(struct psychoreg), + ma->ma_address[0], sizeof(struct pci_ctl)); } else if (ma->ma_nreg > 2) { - bus_space_handle_t handle; - - /* We need to map this in ourselves. */ - if (bus_space_map2(sc->sc_bustag, 0, + psycho_map_psycho(sc, 1, ma->ma_reg[2].ur_paddr, ma->ma_reg[2].ur_len, - 0, NULL, &handle)) - panic("psycho_attach: cannot map regs"); - sc->sc_regs = (struct psychoreg *)(u_long)handle; - - if (bus_space_map2(sc->sc_bustag, 0, - ma->ma_reg[0].ur_paddr, ma->ma_reg[0].ur_len, - 0, NULL, &handle)) - panic("psycho_attach: cannot map ctl"); -/* XXX -- this is lost but never unmapped */ - pci_ctl = (struct pci_ctl *)(u_long)handle; + ma->ma_reg[0].ur_paddr, ma->ma_reg[0].ur_len); } else panic("psycho_attach: %d not enough registers", ma->ma_nreg); @@ -303,25 +286,23 @@ psycho_attach(parent, self, aux) sc->sc_basepaddr = (paddr_t)ma->ma_reg[0].ur_paddr; if (ma->ma_naddress) { - sc->sc_regs = (struct psychoreg *) - (u_long)ma->ma_address[0]; - pci_ctl = (struct pci_ctl *)&sc->sc_regs->psy_pcictl[0]; + psycho_map_psycho(sc, 0, + ma->ma_address[0], sizeof(struct psychoreg), + ma->ma_address[0] + + offsetof(struct psychoreg, psy_pcictl[0]), + sizeof(struct pci_ctl)); } else if (ma->ma_nreg) { - bus_space_handle_t handle; - - /* We need to map this in ourselves. */ - if (bus_space_map2(sc->sc_bustag, 0, + psycho_map_psycho(sc, 1, ma->ma_reg[0].ur_paddr, ma->ma_reg[0].ur_len, - 0, NULL, &handle)) - panic("psycho_attach: cannot map regs"); - sc->sc_regs = (struct psychoreg *)(u_long)handle; - pci_ctl = (struct pci_ctl *)&sc->sc_regs->psy_pcictl[0]; + ma->ma_reg[0].ur_paddr + + offsetof(struct psychoreg, psy_pcictl[0]), + sizeof(struct pci_ctl)); } else panic("psycho_attach: %d not enough registers", ma->ma_nreg); } - csr = sc->sc_regs->psy_csr; + csr = psycho_psychoreg_read(sc, psy_csr); sc->sc_ign = 0x7c0; /* APB IGN is always 0x7c */ if (sc->sc_mode == PSYCHO_MODE_PSYCHO) sc->sc_ign = PSYCHO_GCSR_IGN(csr) << 6; @@ -351,21 +332,17 @@ psycho_attach(parent, self, aux) break; } - /* Oh, dear. OK, lets get started */ /* * Setup the PCI control register */ - csr = bus_space_read_8(sc->sc_bustag, - (bus_space_handle_t)(u_long)&pci_ctl->pci_csr, 0); + csr = psycho_pcictl_read(sc, pci_csr); csr |= PCICTL_MRLM | PCICTL_ARB_PARK | PCICTL_ERRINTEN | PCICTL_4ENABLE; csr &= ~(PCICTL_SERR | PCICTL_CPU_PRIO | PCICTL_ARB_PRIO | PCICTL_RTRYWAIT); - bus_space_write_8(sc->sc_bustag, - (bus_space_handle_t)(u_long)&pci_ctl->pci_csr, 0, csr); - + psycho_pcictl_write(sc, pci_csr, csr); /* * Allocate our psycho_pbm @@ -389,14 +366,14 @@ psycho_attach(parent, self, aux) printf("bus range %u to %u", psycho_br[0], psycho_br[1]); printf("; PCI bus %d", psycho_br[0]); - pp->pp_pcictl = &sc->sc_regs->psy_pcictl[0]; + pp->pp_pcictl = sc->sc_pcictl; /* allocate our tags */ pp->pp_memt = psycho_alloc_mem_tag(pp); pp->pp_iot = psycho_alloc_io_tag(pp); pp->pp_dmat = psycho_alloc_dma_tag(pp); pp->pp_flags = (pp->pp_memt ? PCI_FLAGS_MEM_ENABLED : 0) | - (pp->pp_iot ? PCI_FLAGS_IO_ENABLED : 0); + (pp->pp_iot ? PCI_FLAGS_IO_ENABLED : 0); /* allocate a chipset for this */ pp->pp_pc = psycho_alloc_chipset(pp, sc->sc_node, &_sparc_pci_chipset); @@ -404,16 +381,16 @@ psycho_attach(parent, self, aux) /* setup the rest of the psycho pbm */ pba.pba_pc = pp->pp_pc; - pba.pba_pc->conf_read = psycho_pci_conf_read; - pba.pba_pc->conf_write = psycho_pci_conf_write; - printf("\n"); /* * And finally, if we're a sabre or the first of a pair of psycho's to * arrive here, start up the IOMMU and get a config space tag. */ + if (osc == NULL) { + uint64_t timeo; + /* * Establish handlers for interesting interrupts.... * @@ -424,33 +401,49 @@ psycho_attach(parent, self, aux) * is better than trying to sort through this mess. */ psycho_set_intr(sc, 15, psycho_ue, - &sc->sc_regs->ue_int_map, - &sc->sc_regs->ue_clr_int); + psycho_psychoreg_vaddr(sc, ue_int_map), + psycho_psychoreg_vaddr(sc, ue_clr_int)); psycho_set_intr(sc, 1, psycho_ce, - &sc->sc_regs->ce_int_map, - &sc->sc_regs->ce_clr_int); + psycho_psychoreg_vaddr(sc, ce_int_map), + psycho_psychoreg_vaddr(sc, ce_clr_int)); psycho_set_intr(sc, 15, psycho_bus_a, - &sc->sc_regs->pciaerr_int_map, - &sc->sc_regs->pciaerr_clr_int); + psycho_psychoreg_vaddr(sc, pciaerr_int_map), + psycho_psychoreg_vaddr(sc, pciaerr_clr_int)); psycho_set_intr(sc, 15, psycho_bus_b, - &sc->sc_regs->pciberr_int_map, - &sc->sc_regs->pciberr_clr_int); + psycho_psychoreg_vaddr(sc, pciberr_int_map), + psycho_psychoreg_vaddr(sc, pciberr_clr_int)); #if 0 psycho_set_intr(sc, 15, psycho_powerfail, - &sc->sc_regs->power_int_map, - &sc->sc_regs->power_clr_int); + psycho_psychoreg_vaddr(sc, power_int_map), + psycho_psychoreg_vaddr(sc, power_clr_int)); #endif psycho_set_intr(sc, 1, psycho_wakeup, - &sc->sc_regs->pwrmgt_int_map, - &sc->sc_regs->pwrmgt_clr_int); + psycho_psychoreg_vaddr(sc, pwrmgt_int_map), + psycho_psychoreg_vaddr(sc, pwrmgt_clr_int)); + + /* + * Apparently a number of machines with psycho and psycho+ + * controllers have interrupt latency issues. We'll try + * setting the interrupt retry timeout to 0xff which gives us + * a retry of 3-6 usec (which is what sysio is set to) for the + * moment, which seems to help alleviate this problem. + */ + timeo = psycho_psychoreg_read(sc, intr_retry_timer); + if (timeo > 0xfff) { +#ifdef DEBUG + printf("decreasing interrupt retry timeout " + "from %lx to 0xff\n", (long)timeo); +#endif + psycho_psychoreg_write(sc, intr_retry_timer, 0xff); + } /* * Setup IOMMU and PCI configuration if we're the first * of a pair of psycho's to arrive here. * - * We should calculate a TSB size based on amount of RAM - * and number of bus controllers and number an type of - * child devices. + * We should calculate a TSB size based on the amount of RAM, + * number of bus controllers, and number and type of child + * devices. * * For the moment, 32KB should be more than enough. */ @@ -459,38 +452,71 @@ psycho_attach(parent, self, aux) if (sc->sc_is == NULL) panic("psycho_attach: malloc iommu_state"); + memset(sc->sc_is, 0, sizeof *sc->sc_is); + + if (getproplen(sc->sc_node, "no-streaming-cache") >= 0) { + struct strbuf_ctl *sb = &pp->pp_sb; + vaddr_t va = (vaddr_t)pp->pp_flush[0x40]; + + /* + * Initialize the strbuf_ctl. + * + * The flush sync buffer must be 64-byte aligned. + */ + + sb->sb_flush = (void *)(va & ~0x3f); + + sb->sb_bustag = sc->sc_bustag; + if (bus_space_subregion(sc->sc_bustag, sc->sc_pcictl, + offsetof(struct pci_ctl, pci_strbuf), + sizeof(struct iommu_strbuf), + &sb->sb_sb)) { + sb->sb_flush = 0; + } - sc->sc_is->is_sb[0] = NULL; - sc->sc_is->is_sb[1] = NULL; - if (getproplen(sc->sc_node, "no-streaming-cache") >= 0) - sc->sc_is->is_sb[0] = &pci_ctl->pci_strbuf; + /* Point out iommu at the strbuf_ctl. */ + sc->sc_is->is_sb[0] = sb; + } psycho_iommu_init(sc, 2); sc->sc_configtag = psycho_alloc_config_tag(sc->sc_psycho_this); - if (bus_space_map2(sc->sc_bustag, - PCI_CONFIG_BUS_SPACE, sc->sc_basepaddr + 0x01000000, - 0x0100000, 0, 0, &bh)) + if (bus_space_map(sc->sc_configtag, + sc->sc_basepaddr, 0x0100000, 0, &sc->sc_configaddr)) panic("could not map psycho PCI configuration space"); - sc->sc_configaddr = (off_t)bh; } else { /* Just copy IOMMU state, config tag and address */ sc->sc_is = osc->sc_is; sc->sc_configtag = osc->sc_configtag; sc->sc_configaddr = osc->sc_configaddr; - if (getproplen(sc->sc_node, "no-streaming-cache") >= 0) - sc->sc_is->is_sb[1] = &pci_ctl->pci_strbuf; + if (getproplen(sc->sc_node, "no-streaming-cache") >= 0) { + struct strbuf_ctl *sb = &pp->pp_sb; + vaddr_t va = (vaddr_t)pp->pp_flush[0x40]; + + /* + * Initialize the strbuf_ctl. + * + * The flush sync buffer must be 64-byte aligned. + */ + + sb->sb_flush = (void *)(va & ~0x3f); + + sb->sb_bustag = sc->sc_bustag; + if (bus_space_subregion(sc->sc_bustag, sc->sc_pcictl, + offsetof(struct pci_ctl, pci_strbuf), + sizeof(struct iommu_strbuf), + &sb->sb_sb)) { + sb->sb_flush = 0; + } + + /* Point out iommu at the strbuf_ctl. */ + sc->sc_is->is_sb[1] = sb; + } iommu_reset(sc->sc_is); } /* - * XXX Linux magic, helps U30 - * "PROM sets the IRQ retry value too low, increase it." - */ - sc->sc_regs->intr_retry_timer = 0xff; - - /* * attach the pci.. note we pass PCI A tags, etc., for the sabre here. */ pba.pba_busname = "pci"; @@ -500,28 +526,51 @@ psycho_attach(parent, self, aux) pba.pba_dmat = sc->sc_psycho_this->pp_dmat; pba.pba_iot = sc->sc_psycho_this->pp_iot; pba.pba_memt = sc->sc_psycho_this->pp_memt; + pba.pba_pc->bustag = sc->sc_configtag; + pba.pba_pc->bushandle = sc->sc_configaddr; config_found(self, &pba, psycho_print); } -int -psycho_print(aux, p) - void *aux; - const char *p; +void +psycho_map_psycho(struct psycho_softc* sc, int do_map, bus_addr_t reg_addr, + bus_size_t reg_size, bus_addr_t pci_addr, bus_size_t pci_size) { + if (do_map) { + if (bus_space_map(sc->sc_bustag, + reg_addr, reg_size, 0, &sc->sc_regsh)) + panic("psycho_attach: cannot map regs"); + + if (pci_addr >= reg_addr && + pci_addr + pci_size <= reg_addr + reg_size) { + if (bus_space_subregion(sc->sc_bustag, sc->sc_regsh, + pci_addr - reg_addr, pci_size, &sc->sc_pcictl)) + panic("psycho_map_psycho: map ctl"); + } + else if (bus_space_map(sc->sc_bustag, pci_addr, pci_size, + 0, &sc->sc_pcictl)) + panic("psycho_map_psycho: cannot map pci"); + } else { + if (bus_space_map(sc->sc_bustag, reg_addr, reg_size, + BUS_SPACE_MAP_PROMADDRESS, &sc->sc_regsh)) + panic("psycho_map_psycho: cannot map ctl"); + if (bus_space_map(sc->sc_bustag, pci_addr, pci_size, + BUS_SPACE_MAP_PROMADDRESS, &sc->sc_pcictl)) + panic("psycho_map_psycho: cannot map pci"); + } +} +int +psycho_print(void *aux, const char *p) +{ if (p == NULL) return (UNCONF); return (QUIET); } void -psycho_set_intr(sc, ipl, handler, mapper, clearer) - struct psycho_softc *sc; - int ipl; - void *handler; - u_int64_t *mapper; - u_int64_t *clearer; +psycho_set_intr(struct psycho_softc *sc, int ipl, void *handler, + u_int64_t *mapper, u_int64_t *clearer) { struct intrhand *ih; @@ -533,12 +582,13 @@ psycho_set_intr(sc, ipl, handler, mapper, clearer) ih->ih_map = mapper; ih->ih_clr = clearer; ih->ih_fun = handler; - ih->ih_pil = (1<<ipl); + ih->ih_pil = (1 << ipl); ih->ih_number = INTVEC(*(ih->ih_map)); DPRINTF(PDB_INTR, ( - "; installing handler %p arg %p with number %x pil %u\n", - ih->ih_fun, ih->ih_arg, ih->ih_number, ih->ih_pil)); + "\ninstalling handler %p arg %p for %s with number %x pil %u", + ih->ih_fun, ih->ih_arg, sc->sc_dev.dv_xname, ih->ih_number, + ih->ih_pil)); intr_establish(ipl, ih); *(ih->ih_map) |= INTMAP_V; @@ -552,10 +602,7 @@ psycho_set_intr(sc, ipl, handler, mapper, clearer) * allocate a PCI chipset tag and set it's cookie. */ pci_chipset_tag_t -psycho_alloc_chipset(pp, node, pc) - struct psycho_pbm *pp; - int node; - pci_chipset_tag_t pc; +psycho_alloc_chipset(struct psycho_pbm *pp, int node, pci_chipset_tag_t pc) { pci_chipset_tag_t npc; @@ -584,19 +631,20 @@ psycho_get_bus_range(node, brp) panic("could not get psycho bus-range"); if (n != 2) panic("broken psycho bus-range"); - DPRINTF(PDB_PROM, ("psycho debug: got `bus-range' for node %08x: %u - %u\n", node, brp[0], brp[1])); + DPRINTF(PDB_PROM, + ("psycho debug: got `bus-range' for node %08x: %u - %u\n", + node, brp[0], brp[1])); } void -psycho_get_ranges(node, rp, np) - int node; - struct psycho_ranges **rp; - int *np; +psycho_get_ranges(int node, struct psycho_ranges **rp, int *np) { if (getprop(node, "ranges", sizeof(**rp), np, (void **)rp)) panic("could not get psycho ranges"); - DPRINTF(PDB_PROM, ("psycho debug: got `ranges' for node %08x: %d entries\n", node, *np)); + DPRINTF(PDB_PROM, + ("psycho debug: got `ranges' for node %08x: %d entries\n", + node, *np)); } /* @@ -604,13 +652,11 @@ psycho_get_ranges(node, rp, np) */ int -psycho_ue(arg) - void *arg; +psycho_ue(void *arg) { - struct psycho_softc *sc = (struct psycho_softc *)arg; - struct psychoreg *regs = sc->sc_regs; - unsigned long long afsr = regs->psy_ue_afsr; - unsigned long long afar = regs->psy_ue_afar; + struct psycho_softc *sc = arg; + unsigned long long afsr = psycho_psychoreg_read(sc, psy_ue_afsr); + unsigned long long afar = psycho_psychoreg_read(sc, psy_ue_afar); /* * It's uncorrectable. Dump the regs and panic. @@ -622,11 +668,9 @@ psycho_ue(arg) } int -psycho_ce(arg) - void *arg; +psycho_ce(void *arg) { - struct psycho_softc *sc = (struct psycho_softc *)arg; - struct psychoreg *regs = sc->sc_regs; + struct psycho_softc *sc = arg; /* * It's correctable. Dump the regs and continue. @@ -634,20 +678,18 @@ psycho_ce(arg) printf("%s: correctable DMA error AFAR %llx AFSR %llx\n", sc->sc_dev.dv_xname, - (long long)regs->psy_ce_afar, (long long)regs->psy_ce_afsr); + (long long)psycho_psychoreg_read(sc, psy_ce_afar), + (long long)psycho_psychoreg_read(sc, psy_ce_afsr)); return (1); } int -psycho_bus_error(sc, bus) - struct psycho_softc *sc; - int bus; +psycho_bus_error(struct psycho_softc *sc, int bus) { - struct psychoreg *regs = sc->sc_regs; u_int64_t afsr, afar, bits; - afar = regs->psy_pcictl[bus].pci_afar; - afsr = regs->psy_pcictl[bus].pci_afsr; + afar = psycho_psychoreg_read(sc, psy_pcictl[bus].pci_afar); + afsr = psycho_psychoreg_read(sc, psy_pcictl[bus].pci_afsr); bits = afsr & (PSY_PCIAFSR_PMA | PSY_PCIAFSR_PTA | PSY_PCIAFSR_PTRY | PSY_PCIAFSR_PPERR | PSY_PCIAFSR_SMA | PSY_PCIAFSR_STA | @@ -664,33 +706,29 @@ psycho_bus_error(sc, bus) (long long)iommu_extract(sc->sc_is, (vaddr_t)afar), (long long)afsr); - regs->psy_pcictl[bus].pci_afsr = bits; + psycho_psychoreg_write(sc, psy_pcictl[bus].pci_afsr, bits); return (1); } int -psycho_bus_a(arg) - void *arg; +psycho_bus_a(void *arg) { - struct psycho_softc *sc = (struct psycho_softc *)arg; + struct psycho_softc *sc = arg; return (psycho_bus_error(sc, 0)); } int -psycho_bus_b(arg) - void *arg; +psycho_bus_b(void *arg) { - struct psycho_softc *sc = (struct psycho_softc *)arg; + struct psycho_softc *sc = arg; return (psycho_bus_error(sc, 1)); } int -psycho_powerfail(arg) - void *arg; +psycho_powerfail(void *arg) { - /* * We lost power. Try to shut down NOW. */ @@ -700,10 +738,9 @@ psycho_powerfail(arg) } int -psycho_wakeup(arg) - void *arg; +psycho_wakeup(void *arg) { - struct psycho_softc *sc = (struct psycho_softc *)arg; + struct psycho_softc *sc = arg; /* * Gee, we don't really have a framework to deal with this @@ -717,9 +754,7 @@ psycho_wakeup(arg) * initialise the IOMMU.. */ void -psycho_iommu_init(sc, tsbsize) - struct psycho_softc *sc; - int tsbsize; +psycho_iommu_init(struct psycho_softc *sc, int tsbsize) { char *name; struct iommu_state *is = sc->sc_is; @@ -729,7 +764,9 @@ psycho_iommu_init(sc, tsbsize) /* punch in our copies */ is->is_bustag = sc->sc_bustag; - is->is_iommu = &sc->sc_regs->psy_iommu; + bus_space_subregion(sc->sc_bustag, sc->sc_regsh, + offsetof(struct psychoreg, psy_iommu), sizeof(struct iommureg), + &is->is_iommu); /* * Separate the men from the boys. Get the `virtual-dma' @@ -743,7 +780,7 @@ psycho_iommu_init(sc, tsbsize) (void **)&vdma)) { /* Damn. Gotta use these values. */ iobase = vdma[0]; -#define TSBCASE(x) case 1<<((x)+23): tsbsize = (x); break +#define TSBCASE(x) case 1 << ((x) + 23): tsbsize = (x); break switch (vdma[1]) { TSBCASE(1); TSBCASE(2); TSBCASE(3); TSBCASE(4); TSBCASE(5); TSBCASE(6); @@ -752,6 +789,11 @@ psycho_iommu_init(sc, tsbsize) TSBCASE(7); } #undef TSBCASE + DPRINTF(PDB_CONF, ("psycho_iommu_init: iobase=0x%x\n", iobase)); + } + else { + DPRINTF(PDB_CONF, ("psycho_iommu_init: getprop failed, " + "iobase=0x%x\n", iobase)); } /* give us a nice name.. */ @@ -766,32 +808,61 @@ psycho_iommu_init(sc, tsbsize) /* * below here is bus space and bus dma support */ + bus_space_tag_t -psycho_alloc_bus_tag(pp, type) - struct psycho_pbm *pp; - int type; +psycho_alloc_mem_tag(struct psycho_pbm *pp) +{ + return (_psycho_alloc_bus_tag(pp, "mem", + 0x02, /* 32-bit mem space (where's the #define???) */ + ASI_PRIMARY, ASI_PRIMARY_LITTLE)); +} + +bus_space_tag_t +psycho_alloc_io_tag(struct psycho_pbm *pp) +{ + return (_psycho_alloc_bus_tag(pp, "io", + 0x01, /* IO space (where's the #define???) */ + ASI_PHYS_NON_CACHED_LITTLE, ASI_PHYS_NON_CACHED)); +} + +bus_space_tag_t +psycho_alloc_config_tag(struct psycho_pbm *pp) +{ + return (_psycho_alloc_bus_tag(pp, "cfg", + 0x00, /* Config space (where's the #define???) */ + ASI_PHYS_NON_CACHED_LITTLE, ASI_PHYS_NON_CACHED)); +} + +bus_space_tag_t +_psycho_alloc_bus_tag(struct psycho_pbm *pp, + const char *name, int ss, int asi, int sasi) { struct psycho_softc *sc = pp->pp_sc; - bus_space_tag_t bt; + struct sparc_bus_space_tag *bt; - bt = (bus_space_tag_t) - malloc(sizeof(struct sparc_bus_space_tag), M_DEVBUF, M_NOWAIT); + bt = malloc(sizeof(*bt), M_DEVBUF, M_NOWAIT); if (bt == NULL) panic("could not allocate psycho bus tag"); bzero(bt, sizeof *bt); + + snprintf(bt->name, sizeof(bt->name), "%s-pbm_%s(%d-%2.2x)", + sc->sc_dev.dv_xname, name, ss, asi); + bt->cookie = pp; bt->parent = sc->sc_bustag; - bt->type = type; + bt->default_type = ss; + bt->asi = asi; + bt->sasi = sasi; bt->sparc_bus_map = _psycho_bus_map; bt->sparc_bus_mmap = psycho_bus_mmap; bt->sparc_intr_establish = psycho_intr_establish; + return (bt); } bus_dma_tag_t -psycho_alloc_dma_tag(pp) - struct psycho_pbm *pp; +psycho_alloc_dma_tag(struct psycho_pbm *pp) { struct psycho_softc *sc = pp->pp_sc; bus_dma_tag_t dt, pdt = sc->sc_dmatag; @@ -828,56 +899,30 @@ psycho_alloc_dma_tag(pp) */ int -psycho_get_childspace(type) - int type; -{ - int ss; - - switch (type) { - case PCI_CONFIG_BUS_SPACE: - ss = 0x00; - break; - case PCI_IO_BUS_SPACE: - ss = 0x01; - break; - case PCI_MEMORY_BUS_SPACE: - ss = 0x02; - break; -#if 0 - /* we don't do 64 bit memory space */ - case PCI_MEMORY64_BUS_SPACE: - ss = 0x03; - break; -#endif - default: - panic("psycho_get_childspace: unknown bus type"); - } - - return (ss); -} - -int -_psycho_bus_map(t, btype, offset, size, flags, vaddr, hp) - bus_space_tag_t t; - bus_type_t btype; - bus_addr_t offset; - bus_size_t size; - int flags; - vaddr_t vaddr; - bus_space_handle_t *hp; +_psycho_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) { struct psycho_pbm *pp = t->cookie; - struct psycho_softc *sc = pp->pp_sc; int i, ss; - DPRINTF(PDB_BUSMAP, ("_psycho_bus_map: type %d off %qx sz %qx flags %d va %p", t->type, (unsigned long long)offset, (unsigned long long)size, flags, - (void *)vaddr)); + DPRINTF(PDB_BUSMAP, ("\n_psycho_bus_map: type %d off %qx sz %qx " + "flags %d", t->default_type, (unsigned long long)offset, + (unsigned long long)size, flags)); - ss = psycho_get_childspace(t->type); + ss = t->default_type; DPRINTF(PDB_BUSMAP, (" cspace %d", ss)); - if (btype == 0) - btype = t->type; + if (t->parent == 0 || t->parent->sparc_bus_map == 0) { + printf("\n_psycho_bus_map: invalid parent"); + return (EINVAL); + } + + t = t->parent; + + if (flags & BUS_SPACE_MAP_PROMADDRESS) { + return ((*t->sparc_bus_map) + (t, t0, offset, size, flags, hp)); + } for (i = 0; i < pp->pp_nrange; i++) { bus_addr_t paddr; @@ -886,35 +931,38 @@ _psycho_bus_map(t, btype, offset, size, flags, vaddr, hp) continue; paddr = pp->pp_range[i].phys_lo + offset; - paddr |= ((bus_addr_t)pp->pp_range[i].phys_hi<<32); - DPRINTF(PDB_BUSMAP, ("\n_psycho_bus_map: mapping paddr space %lx offset %lx paddr %qx\n", + paddr |= ((bus_addr_t)pp->pp_range[i].phys_hi << 32); + DPRINTF(PDB_BUSMAP, + ("\n_psycho_bus_map: mapping paddr space %lx offset %lx " + "paddr %qx", (long)ss, (long)offset, (unsigned long long)paddr)); - return (bus_space_map2(sc->sc_bustag, btype, paddr, - size, flags, vaddr, hp)); + return ((*t->sparc_bus_map)(t, t0, paddr, size, flags, hp)); } DPRINTF(PDB_BUSMAP, (" FAILED\n")); return (EINVAL); } paddr_t -psycho_bus_mmap(t, paddr, off, prot, flags) - bus_space_tag_t t; - bus_addr_t paddr; - off_t off; - int prot; - int flags; +psycho_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr, + off_t off, int prot, int flags) { bus_addr_t offset = paddr; struct psycho_pbm *pp = t->cookie; - struct psycho_softc *sc = pp->pp_sc; int i, ss; - ss = psycho_get_childspace(t->type); + ss = t->default_type; - DPRINTF(PDB_BUSMAP, ("_psycho_bus_mmap: prot %d flags %d pa %qx\n", + DPRINTF(PDB_BUSMAP, ("\n_psycho_bus_mmap: prot %d flags %d pa %qx", prot, flags, (unsigned long long)paddr)); + if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) { + printf("\n_psycho_bus_mmap: invalid parent"); + return (-1); + } + + t = t->parent; + for (i = 0; i < pp->pp_nrange; i++) { bus_addr_t paddr; @@ -922,12 +970,12 @@ psycho_bus_mmap(t, paddr, off, prot, flags) continue; paddr = pp->pp_range[i].phys_lo + offset; - paddr |= ((bus_addr_t)pp->pp_range[i].phys_hi<<32); + paddr |= ((bus_addr_t)pp->pp_range[i].phys_hi << 32); DPRINTF(PDB_BUSMAP, ("\n_psycho_bus_mmap: mapping paddr " - "space %lx offset %lx paddr %qx\n", + "space %lx offset %lx paddr %qx", (long)ss, (long)offset, (unsigned long long)paddr)); - return (bus_space_mmap(sc->sc_bustag, paddr, off, prot, flags)); + return ((*t->sparc_bus_mmap)(t, t0, paddr, off, prot, flags)); } return (-1); @@ -937,13 +985,8 @@ psycho_bus_mmap(t, paddr, off, prot, flags) * install an interrupt handler for a PCI device */ void * -psycho_intr_establish(t, ihandle, level, flags, handler, arg) - bus_space_tag_t t; - int ihandle; - int level; - int flags; - int (*handler)(void *); - void *arg; +psycho_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int ihandle, + int level, int flags, int (*handler)(void *), void *arg) { struct psycho_pbm *pp = t->cookie; struct psycho_softc *sc = pp->pp_sc; @@ -969,12 +1012,14 @@ psycho_intr_establish(t, ihandle, level, flags, handler, arg) */ - DPRINTF(PDB_INTR, ("\npsycho_intr_establish: ihandle %x vec %lx", ihandle, vec)); + DPRINTF(PDB_INTR, + ("\npsycho_intr_establish: ihandle %x vec %lx", ihandle, vec)); ino = INTINO(vec); DPRINTF(PDB_INTR, (" ino %x", ino)); /* If the device didn't ask for an IPL, use the one encoded. */ - if (level == IPL_NONE) level = INTLEV(vec); + if (level == IPL_NONE) + level = INTLEV(vec); /* If it still has no level, print a warning and assign IPL 2 */ if (level == IPL_NONE) { printf("ERROR: no IPL, setting IPL 2.\n"); @@ -983,27 +1028,32 @@ psycho_intr_establish(t, ihandle, level, flags, handler, arg) if ((flags & BUS_INTR_ESTABLISH_SOFTINTR) == 0) { - DPRINTF(PDB_INTR, ("\npsycho: intr %lx: %p\nHunting for IRQ...\n", + DPRINTF(PDB_INTR, + ("\npsycho: intr %lx: %p\nHunting for IRQ...\n", (long)ino, intrlev[ino])); /* Hunt thru obio first */ - for (intrmapptr = &sc->sc_regs->scsi_int_map, - intrclrptr = &sc->sc_regs->scsi_clr_int; - intrmapptr < &sc->sc_regs->ffb0_int_map; + for (intrmapptr = psycho_psychoreg_vaddr(sc, scsi_int_map), + intrclrptr = psycho_psychoreg_vaddr(sc, scsi_clr_int); + intrmapptr < (volatile u_int64_t *) + psycho_psychoreg_vaddr(sc, ffb0_int_map); intrmapptr++, intrclrptr++) { if (INTINO(*intrmapptr) == ino) goto found; } /* Now do PCI interrupts */ - for (intrmapptr = &sc->sc_regs->pcia_slot0_int, - intrclrptr = &sc->sc_regs->pcia0_clr_int[0]; - intrmapptr <= &sc->sc_regs->pcib_slot3_int; + for (intrmapptr = psycho_psychoreg_vaddr(sc, pcia_slot0_int), + intrclrptr = psycho_psychoreg_vaddr(sc, pcia0_clr_int[0]); + intrmapptr <= (volatile u_int64_t *) + psycho_psychoreg_vaddr(sc, pcib_slot3_int); intrmapptr++, intrclrptr += 4) { /* Skip PCI-A Slot 2 and PCI-A Slot 3 on psycho's */ if (sc->sc_mode == PSYCHO_MODE_PSYCHO && - (intrmapptr == &sc->sc_regs->pcia_slot2_int || - intrmapptr == &sc->sc_regs->pcia_slot3_int)) + (intrmapptr == + psycho_psychoreg_vaddr(sc, pcia_slot2_int) || + intrmapptr == + psycho_psychoreg_vaddr(sc, pcia_slot3_int))) continue; if (((*intrmapptr ^ vec) & 0x3c) == 0) { @@ -1034,7 +1084,7 @@ psycho_intr_establish(t, ihandle, level, flags, handler, arg) ih->ih_number = ino | sc->sc_ign; DPRINTF(PDB_INTR, ( - "; installing handler %p arg %p with number %x pil %u\n", + "\ninstalling handler %p arg %p with number %x pil %u", ih->ih_fun, ih->ih_arg, ih->ih_number, ih->ih_pil)); intr_establish(ih->ih_pil, ih); @@ -1057,7 +1107,7 @@ psycho_intr_establish(t, ihandle, level, flags, handler, arg) DPRINTF(PDB_INTR, ("; writing intrmap = %016qx", (unsigned long long)intrmap)); *intrmapptr = intrmap; - DPRINTF(PDB_INTR, ("; reread intrmap = %016qx\n", + DPRINTF(PDB_INTR, ("; reread intrmap = %016qx", (unsigned long long)(intrmap = *intrmapptr))); } return (ih); @@ -1067,55 +1117,40 @@ psycho_intr_establish(t, ihandle, level, flags, handler, arg) * hooks into the iommu dvma calls. */ int -psycho_dmamap_load(t, map, buf, buflen, p, flags) - bus_dma_tag_t t; - bus_dmamap_t map; - void *buf; - bus_size_t buflen; - struct proc *p; - int flags; +psycho_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf, + bus_size_t buflen, struct proc *p, int flags) { - struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie; + struct psycho_pbm *pp = t->_cookie; struct psycho_softc *sc = pp->pp_sc; return (iommu_dvmamap_load(t, sc->sc_is, map, buf, buflen, p, flags)); } void -psycho_dmamap_unload(t, map) - bus_dma_tag_t t; - bus_dmamap_t map; +psycho_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map) { - struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie; + struct psycho_pbm *pp = t->_cookie; struct psycho_softc *sc = pp->pp_sc; iommu_dvmamap_unload(t, sc->sc_is, map); } int -psycho_dmamap_load_raw(t, map, segs, nsegs, size, flags) - bus_dma_tag_t t; - bus_dmamap_t map; - bus_dma_segment_t *segs; - int nsegs; - bus_size_t size; - int flags; +psycho_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map, + bus_dma_segment_t *segs, int nsegs, bus_size_t size, int flags) { - struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie; + struct psycho_pbm *pp = t->_cookie; struct psycho_softc *sc = pp->pp_sc; - return (iommu_dvmamap_load_raw(t, sc->sc_is, map, segs, nsegs, flags, size)); + return (iommu_dvmamap_load_raw(t, sc->sc_is, map, segs, nsegs, flags, + size)); } void -psycho_dmamap_sync(t, map, offset, len, ops) - bus_dma_tag_t t; - bus_dmamap_t map; - bus_addr_t offset; - bus_size_t len; - int ops; +psycho_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, + bus_size_t len, int ops) { - struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie; + struct psycho_pbm *pp = t->_cookie; struct psycho_softc *sc = pp->pp_sc; if (ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) { @@ -1128,21 +1163,14 @@ psycho_dmamap_sync(t, map, offset, len, ops) iommu_dvmamap_sync(t, sc->sc_is, map, offset, len, ops); bus_dmamap_sync(t->_parent, map, offset, len, ops); } - } int -psycho_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags) - bus_dma_tag_t t; - bus_size_t size; - bus_size_t alignment; - bus_size_t boundary; - bus_dma_segment_t *segs; - int nsegs; - int *rsegs; - int flags; +psycho_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment, + bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, + int flags) { - struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie; + struct psycho_pbm *pp = t->_cookie; struct psycho_softc *sc = pp->pp_sc; return (iommu_dvmamem_alloc(t, sc->sc_is, size, alignment, boundary, @@ -1150,98 +1178,31 @@ psycho_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags) } void -psycho_dmamem_free(t, segs, nsegs) - bus_dma_tag_t t; - bus_dma_segment_t *segs; - int nsegs; +psycho_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs) { - struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie; + struct psycho_pbm *pp = t->_cookie; struct psycho_softc *sc = pp->pp_sc; iommu_dvmamem_free(t, sc->sc_is, segs, nsegs); } int -psycho_dmamem_map(t, segs, nsegs, size, kvap, flags) - bus_dma_tag_t t; - bus_dma_segment_t *segs; - int nsegs; - size_t size; - caddr_t *kvap; - int flags; +psycho_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, + size_t size, caddr_t *kvap, int flags) { - struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie; + struct psycho_pbm *pp = t->_cookie; struct psycho_softc *sc = pp->pp_sc; - return (iommu_dvmamem_map(t, sc->sc_is, segs, nsegs, size, kvap, flags)); + return (iommu_dvmamem_map + (t, sc->sc_is, segs, nsegs, size, kvap, flags)); } void -psycho_dmamem_unmap(t, kva, size) - bus_dma_tag_t t; - caddr_t kva; - size_t size; +psycho_dmamem_unmap(bus_dma_tag_t t, caddr_t kva, size_t size) { - struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie; + struct psycho_pbm *pp = t->_cookie; struct psycho_softc *sc = pp->pp_sc; iommu_dvmamem_unmap(t, sc->sc_is, kva, size); } -pcireg_t -psycho_pci_conf_read(pc, tag, reg) - pci_chipset_tag_t pc; - pcitag_t tag; - int reg; -{ - struct psycho_pbm *pp = pc->cookie; - struct psycho_softc *sc = pp->pp_sc; - pcireg_t val = (pcireg_t)~0; - - DPRINTF(PDB_CONF, ("pci_conf_read: tag %lx reg %x ", - (long)tag, reg)); - if (PCITAG_NODE(tag) != -1) { - DPRINTF(PDB_CONF, ("asi=%x addr=%qx (offset=%x) ...", - bus_type_asi[sc->sc_configtag->type], - (long long)(sc->sc_configaddr + - PCITAG_OFFSET(tag) + reg), - (int)PCITAG_OFFSET(tag) + reg)); - - val = bus_space_read_4(sc->sc_configtag, sc->sc_configaddr, - PCITAG_OFFSET(tag) + reg); - } -#ifdef DEBUG - else DPRINTF(PDB_CONF, ("pci_conf_read: bogus pcitag %x\n", - (int)PCITAG_OFFSET(tag))); -#endif - DPRINTF(PDB_CONF, (" returning %08x\n", (u_int)val)); - - return (val); -} - -void -psycho_pci_conf_write(pc, tag, reg, data) - pci_chipset_tag_t pc; - pcitag_t tag; - int reg; - pcireg_t data; -{ - struct psycho_pbm *pp = pc->cookie; - struct psycho_softc *sc = pp->pp_sc; - - DPRINTF(PDB_CONF, ("pci_conf_write: tag %lx; reg %x; data %x; ", - (long)PCITAG_OFFSET(tag), reg, (int)data)); - DPRINTF(PDB_CONF, ("asi = %x; readaddr = %qx (offset = %x)\n", - bus_type_asi[sc->sc_configtag->type], - (long long)(sc->sc_configaddr + PCITAG_OFFSET(tag) + reg), - (int)PCITAG_OFFSET(tag) + reg)); - - /* If we don't know it, just punt. */ - if (PCITAG_NODE(tag) == -1) { - DPRINTF(PDB_CONF, ("pci_config_write: bad addr")); - return; - } - - bus_space_write_4(sc->sc_configtag, sc->sc_configaddr, - PCITAG_OFFSET(tag) + reg, data); -} diff --git a/sys/arch/sparc64/dev/psychovar.h b/sys/arch/sparc64/dev/psychovar.h index 174ab307fea..aa632dd65ac 100644 --- a/sys/arch/sparc64/dev/psychovar.h +++ b/sys/arch/sparc64/dev/psychovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: psychovar.h,v 1.4 2002/03/14 01:26:44 millert Exp $ */ +/* $OpenBSD: psychovar.h,v 1.5 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: psychovar.h,v 1.6 2001/07/20 00:07:13 eeh Exp $ */ /* @@ -63,7 +63,10 @@ struct psycho_pbm { int pp_flags; /* and pointers into the psycho regs for our bits */ - struct pci_ctl *pp_pcictl; + bus_space_handle_t pp_pcictl; + struct strbuf_ctl pp_sb; + /* area we can use for flushing our streaming buffer */ + char pp_flush[0x80]; }; /* @@ -86,7 +89,8 @@ struct psycho_softc { * PSYCHO register. we record the base physical address of these * also as it is the base of the entire PSYCHO */ - struct psychoreg *sc_regs; + bus_space_handle_t sc_regsh; + bus_space_handle_t sc_pcictl; paddr_t sc_basepaddr; /* Interrupt Group Number for this device */ @@ -111,11 +115,10 @@ struct psycho_softc { /* config space is per-psycho. mem/io/dma are per-pci bus */ bus_dma_tag_t psycho_alloc_dma_tag(struct psycho_pbm *); -bus_space_tag_t psycho_alloc_bus_tag(struct psycho_pbm *, int); -#define psycho_alloc_config_tag(pp) psycho_alloc_bus_tag((pp), PCI_CONFIG_BUS_SPACE) -#define psycho_alloc_mem_tag(pp) psycho_alloc_bus_tag((pp), PCI_MEMORY_BUS_SPACE) -#define psycho_alloc_io_tag(pp) psycho_alloc_bus_tag((pp), PCI_IO_BUS_SPACE) +bus_space_tag_t psycho_alloc_mem_tag(struct psycho_pbm *); +bus_space_tag_t psycho_alloc_io_tag(struct psycho_pbm *); +bus_space_tag_t psycho_alloc_config_tag(struct psycho_pbm *); /* uperf attachment to psycho's */ struct uperf_psycho_attach_args { @@ -123,4 +126,24 @@ struct uperf_psycho_attach_args { struct perfmon *upaa_regs; }; +#define psycho_psychoreg_read(sc, reg) \ + bus_space_read_8((sc)->sc_bustag, (sc)->sc_regsh, \ + offsetof(struct psychoreg, reg)) + +#define psycho_psychoreg_write(sc, reg, v) \ + bus_space_write_8((sc)->sc_bustag, (sc)->sc_regsh, \ + offsetof(struct psychoreg, reg), (v)) + +#define psycho_psychoreg_vaddr(sc, reg) \ + (bus_space_vaddr((sc)->sc_bustag, (sc)->sc_regsh) + \ + offsetof(struct psychoreg, reg)) + +#define psycho_pcictl_read(sc, reg) \ + bus_space_read_8((sc)->sc_bustag, (sc)->sc_pcictl, \ + offsetof(struct pci_ctl, reg)) + +#define psycho_pcictl_write(sc, reg, v) \ + bus_space_write_8((sc)->sc_bustag, (sc)->sc_pcictl, \ + offsetof(struct pci_ctl, reg), (v)) + #endif /* _SPARC64_DEV_PSYCHOVAR_H_ */ diff --git a/sys/arch/sparc64/dev/sab.c b/sys/arch/sparc64/dev/sab.c index 3989e80ccf4..23ffe9ced0c 100644 --- a/sys/arch/sparc64/dev/sab.c +++ b/sys/arch/sparc64/dev/sab.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sab.c,v 1.9 2002/09/23 18:43:18 jason Exp $ */ +/* $OpenBSD: sab.c,v 1.10 2003/02/17 01:29:20 henric Exp $ */ /* * Copyright (c) 2001 Jason L. Wright (jason@thought.net) @@ -235,20 +235,26 @@ sab_attach(parent, self, aux) u_int8_t r; u_int i; - sc->sc_bt = ea->ea_bustag; + sc->sc_bt = ea->ea_memtag; sc->sc_node = ea->ea_node; /* Use prom mapping, if available. */ - if (ea->ea_nvaddrs) - sc->sc_bh = (bus_space_handle_t)ea->ea_vaddrs[0]; - else if (ebus_bus_map(sc->sc_bt, 0, + if (ea->ea_nvaddrs) { + if (bus_space_map(sc->sc_bt, ea->ea_vaddrs[0], + 0, BUS_SPACE_MAP_PROMADDRESS, &sc->sc_bh) != 0) { + printf(": can't map register space\n"); + return; + } + } else if (ebus_bus_map(sc->sc_bt, 0, EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_bh) != 0) { printf(": can't map register space\n"); return; } - sc->sc_ih = bus_intr_establish(ea->ea_bustag, ea->ea_intrs[0], + BUS_SPACE_SET_FLAGS(sc->sc_bt, sc->sc_bh, BSHDB_NO_ACCESS); + + sc->sc_ih = bus_intr_establish(sc->sc_bt, ea->ea_intrs[0], IPL_TTY, 0, sab_intr, sc); if (sc->sc_ih == NULL) { printf(": can't map interrupt\n"); diff --git a/sys/arch/sparc64/dev/sbus.c b/sys/arch/sparc64/dev/sbus.c index dc753d1a770..c86439995ce 100644 --- a/sys/arch/sparc64/dev/sbus.c +++ b/sys/arch/sparc64/dev/sbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sbus.c,v 1.14 2002/03/14 20:26:20 jason Exp $ */ +/* $OpenBSD: sbus.c,v 1.15 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: sbus.c,v 1.46 2001/10/07 20:30:41 eeh Exp $ */ /*- @@ -143,25 +143,19 @@ void sbusreset(int); static bus_space_tag_t sbus_alloc_bustag(struct sbus_softc *); static bus_dma_tag_t sbus_alloc_dmatag(struct sbus_softc *); static int sbus_get_intr(struct sbus_softc *, int, - struct sbus_intr **, int *, int); -int sbus_bus_mmap(bus_space_tag_t, bus_type_t, bus_addr_t, - int, bus_space_handle_t *); + struct sbus_intr **, int *, int); static int sbus_overtemp(void *); -static int _sbus_bus_map( - bus_space_tag_t, - bus_type_t, - bus_addr_t, /*offset*/ - bus_size_t, /*size*/ - int, /*flags*/ - vaddr_t, /*preferred virtual address */ - bus_space_handle_t *); -static void *sbus_intr_establish( - bus_space_tag_t, - int, /*Sbus interrupt level*/ - int, /*`device class' priority*/ - int, /*flags*/ - int (*)(void *), /*handler*/ - void *); /*handler arg*/ +static int _sbus_bus_map(bus_space_tag_t, bus_space_tag_t, + bus_addr_t, /*offset*/ + bus_size_t, /*size*/ + int, /*flags*/ + bus_space_handle_t *); +static void *sbus_intr_establish(bus_space_tag_t, bus_space_tag_t, + int, /*Sbus interrupt level*/ + int, /*`device class' priority*/ + int, /*flags*/ + int (*)(void *), /*handler*/ + void *); /*handler arg*/ /* autoconfiguration driver */ @@ -182,23 +176,19 @@ extern struct cfdriver sbus_cd; /* * DVMA routines */ -int sbus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, - bus_size_t, struct proc *, int); +int sbus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t, + struct proc *, int); void sbus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t); -int sbus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t, - bus_dma_segment_t *, int, bus_size_t, int); -void sbus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t, - bus_size_t, int); -int sbus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size, - bus_size_t alignment, bus_size_t boundary, - bus_dma_segment_t *segs, int nsegs, int *rsegs, - int flags); -void sbus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs, - int nsegs); -int sbus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs, - int nsegs, size_t size, caddr_t *kvap, int flags); -void sbus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva, - size_t size); +int sbus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t, bus_dma_segment_t *, + int, bus_size_t, int); +void sbus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t, bus_size_t, int); +int sbus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size, bus_size_t alignment, + bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, + int flags); +void sbus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs, int nsegs); +int sbus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs, int nsegs, + size_t size, caddr_t *kvap, int flags); +void sbus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva, size_t size); /* * Child devices receive the Sbus interrupt level in their attach @@ -231,9 +221,7 @@ static int intr_sbus2ipl_4u[] = { * Return UNCONF (config_find ignores this if the device was configured). */ int -sbus_print(args, busname) - void *args; - const char *busname; +sbus_print(void *args, const char *busname) { struct sbus_attach_args *sa = args; int i; @@ -253,10 +241,7 @@ sbus_print(args, busname) } int -sbus_match(parent, vcf, aux) - struct device *parent; - void *vcf; - void *aux; +sbus_match(struct device *parent, void *vcf, void *aux) { struct cfdata *cf = vcf; struct mainbus_attach_args *ma = aux; @@ -268,26 +253,28 @@ sbus_match(parent, vcf, aux) * Attach an Sbus. */ void -sbus_attach(parent, self, aux) - struct device *parent; - struct device *self; - void *aux; +sbus_attach(struct device *parent, struct device *self, void *aux) { struct sbus_softc *sc = (struct sbus_softc *)self; struct mainbus_attach_args *ma = aux; struct intrhand *ih; + struct sysioreg *sysio; int ipl; char *name; int node = ma->ma_node; - int node0, error; bus_space_tag_t sbt; struct sbus_attach_args sa; sc->sc_bustag = ma->ma_bustag; sc->sc_dmatag = ma->ma_dmatag; - sc->sc_sysio = (struct sysioreg*)(u_long)ma->ma_address[0]; /* Use prom mapping for sysio. */ - sc->sc_ign = ma->ma_interrupts[0] & INTMAP_IGN; /* Find interrupt group no */ + /* Find interrupt group no */ + sc->sc_ign = ma->ma_interrupts[0] & INTMAP_IGN; + + bus_space_map(sc->sc_bustag, + ma->ma_address[0], sizeof(struct sysioreg), + BUS_SPACE_MAP_PROMADDRESS, &sc->sc_bh); + sysio = bus_space_vaddr(sc->sc_bustag, sc->sc_bh); /* Setup interrupt translation tables */ sc->sc_intr2ipl = intr_sbus2ipl_4u; @@ -315,13 +302,24 @@ sbus_attach(parent, self, aux) if (error) panic("%s: error getting ranges property", sc->sc_dev.dv_xname); - /* initailise the IOMMU */ + /* initialize the IOMMU */ /* punch in our copies */ sc->sc_is.is_bustag = sc->sc_bustag; - sc->sc_is.is_iommu = &sc->sc_sysio->sys_iommu; - sc->sc_is.is_sb[0] = &sc->sc_sysio->sys_strbuf; - sc->sc_is.is_sb[1] = NULL; + bus_space_subregion(sc->sc_bustag, sc->sc_bh, + offsetof(struct sysioreg, sys_iommu), + sizeof(struct iommureg), &sc->sc_is.is_iommu); + + /* initialize our strbuf_ctl */ + sc->sc_is.is_sb[0] = &sc->sc_sb; + if (bus_space_subregion(sc->sc_bustag, sc->sc_bh, + offsetof(struct sysioreg, sys_strbuf), + sizeof(struct iommu_strbuf), &sc->sc_sb.sb_sb) == 0) { + /* point sb_flush to our flush buffer */ + sc->sc_sb.sb_flush = &sc->sc_flush; + sc->sc_sb.sb_bustag = sc->sc_bustag; + } else + sc->sc_is.is_sb[0] = NULL; /* give us a nice name.. */ name = (char *)malloc(32, M_DEVBUF, M_NOWAIT); @@ -336,11 +334,11 @@ sbus_attach(parent, self, aux) malloc(sizeof(struct intrhand), M_DEVBUF, M_NOWAIT); if (ih == NULL) panic("couldn't malloc intrhand"); - ih->ih_map = &sc->sc_sysio->therm_int_map; - ih->ih_clr = NULL; /* &sc->sc_sysio->therm_clr_int; */ + ih->ih_map = &sysio->therm_int_map; + ih->ih_clr = NULL; /* &sysio->therm_clr_int; */ ih->ih_fun = sbus_overtemp; ipl = 1; - ih->ih_pil = (1<<ipl); + ih->ih_pil = (1 << ipl); ih->ih_number = INTVEC(*(ih->ih_map)); intr_establish(ipl, ih); *(ih->ih_map) |= INTMAP_V; @@ -354,8 +352,8 @@ sbus_attach(parent, self, aux) u_long dummy; if (extent_alloc_subregion(sc->sc_is.is_dvmamap, - sc->sc_is.is_dvmabase, sc->sc_is.is_dvmabase + NBPG, - NBPG, NBPG, 0, 0, EX_NOWAIT|EX_BOUNDZERO, + sc->sc_is.is_dvmabase, sc->sc_is.is_dvmabase + NBPG, NBPG, + NBPG, 0, 0, EX_NOWAIT | EX_BOUNDZERO, (u_long *)&dummy) != 0) panic("sbus iommu: can't toss first dvma page"); } @@ -381,17 +379,11 @@ sbus_attach(parent, self, aux) } int -sbus_setup_attach_args(sc, bustag, dmatag, node, sa) - struct sbus_softc *sc; - bus_space_tag_t bustag; - bus_dma_tag_t dmatag; - int node; - struct sbus_attach_args *sa; +sbus_setup_attach_args(struct sbus_softc *sc, bus_space_tag_t bustag, + bus_dma_tag_t dmatag, int node, struct sbus_attach_args *sa) { - /*struct sbus_reg sbusreg;*/ - /*int base;*/ int error; - int n; + int n; bzero(sa, sizeof(struct sbus_attach_args)); error = getprop(node, "name", 1, &n, (void **)&sa->sa_name); @@ -436,8 +428,7 @@ sbus_setup_attach_args(sc, bustag, dmatag, node, sa) } void -sbus_destroy_attach_args(sa) - struct sbus_attach_args *sa; +sbus_destroy_attach_args(struct sbus_attach_args *sa) { if (sa->sa_name != NULL) free(sa->sa_name, M_DEVBUF); @@ -456,19 +447,24 @@ sbus_destroy_attach_args(sa) int -_sbus_bus_map(t, btype, offset, size, flags, vaddr, hp) - bus_space_tag_t t; - bus_type_t btype; - bus_addr_t offset; - bus_size_t size; - int flags; - vaddr_t vaddr; - bus_space_handle_t *hp; +_sbus_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t addr, + bus_size_t size, int flags, bus_space_handle_t *hp) { struct sbus_softc *sc = t->cookie; - int64_t slot = btype; + int64_t slot = BUS_ADDR_IOSPACE(addr); + int64_t offset = BUS_ADDR_PADDR(addr); int i; + if (t->parent == NULL || t->parent->sparc_bus_map == NULL) { + printf("\n_psycho_bus_map: invalid parent"); + return (EINVAL); + } + + if (flags & BUS_SPACE_MAP_PROMADDRESS) { + return ((*t->parent->sparc_bus_map)(t, t0, addr, + size, flags, hp)); + } + for (i = 0; i < sc->sc_nrange; i++) { bus_addr_t paddr; @@ -477,53 +473,22 @@ _sbus_bus_map(t, btype, offset, size, flags, vaddr, hp) /* We've found the connection to the parent bus */ paddr = sc->sc_range[i].poffset + offset; - paddr |= ((bus_addr_t)sc->sc_range[i].pspace<<32); - DPRINTF(SDB_DVMA, -("\n_sbus_bus_map: mapping paddr slot %lx offset %lx poffset %lx paddr %lx\n", + paddr |= ((bus_addr_t)sc->sc_range[i].pspace << 32); + DPRINTF(SDB_DVMA, ("_sbus_bus_map: mapping paddr " + "slot %lx offset %lx poffset %lx paddr %lx\n", (long)slot, (long)offset, (long)sc->sc_range[i].poffset, (long)paddr)); - return (bus_space_map2(sc->sc_bustag, 0, paddr, - size, flags, vaddr, hp)); + return ((*t->parent->sparc_bus_map)(t, t0, paddr, + size, flags, hp)); } return (EINVAL); } -int -sbus_bus_mmap(t, btype, paddr, flags, hp) - bus_space_tag_t t; - bus_type_t btype; - bus_addr_t paddr; - int flags; - bus_space_handle_t *hp; -{ - bus_addr_t offset = paddr; - int slot = btype; - struct sbus_softc *sc = t->cookie; - int i; - - for (i = 0; i < sc->sc_nrange; i++) { - bus_addr_t paddr; - - if (sc->sc_range[i].cspace != slot) - continue; - - paddr = sc->sc_range[i].poffset + offset; - paddr |= ((bus_addr_t)sc->sc_range[i].pspace<<32); - *hp = bus_space_mmap(sc->sc_bustag, paddr, 0, - VM_PROT_READ|VM_PROT_WRITE, flags); - } - - return (*hp == -1 ? -1 : 0); -} - bus_addr_t -sbus_bus_addr(t, btype, offset) - bus_space_tag_t t; - u_int btype; - u_int offset; +sbus_bus_addr(bus_space_tag_t t, u_int btype, u_int offset) { - bus_addr_t baddr; + bus_addr_t baddr = ~(bus_addr_t)0; int slot = btype; struct sbus_softc *sc = t->cookie; int i; @@ -533,7 +498,7 @@ sbus_bus_addr(t, btype, offset) continue; baddr = sc->sc_range[i].poffset + offset; - baddr |= ((bus_addr_t)sc->sc_range[i].pspace<<32); + baddr |= (bus_addr_t)sc->sc_range[i].pspace << 32; } return (baddr); @@ -545,12 +510,10 @@ sbus_bus_addr(t, btype, offset) * its sbusdev portion. */ void -sbus_establish(sd, dev) - register struct sbusdev *sd; - register struct device *dev; +sbus_establish(struct sbusdev *sd, struct device *dev) { - register struct sbus_softc *sc; - register struct device *curdev; + struct sbus_softc *sc; + struct device *curdev; /* * We have to look for the sbus by name, since it is not necessarily @@ -579,10 +542,9 @@ sbus_establish(sd, dev) * Reset the given sbus. */ void -sbusreset(sbus) - int sbus; +sbusreset(int sbus) { - register struct sbusdev *sd; + struct sbusdev *sd; struct sbus_softc *sc = sbus_cd.cd_devs[sbus]; struct device *dev; @@ -607,8 +569,7 @@ sbusreset(sbus) * The same needs to be done to PCI controller drivers. */ int -sbus_overtemp(arg) - void *arg; +sbus_overtemp(void *arg) { /* Should try a clean shutdown first */ printf("DANGER: OVER TEMPERATURE detected\nShutting down...\n"); @@ -622,12 +583,8 @@ sbus_overtemp(arg) * Get interrupt attributes for an Sbus device. */ int -sbus_get_intr(sc, node, ipp, np, slot) - struct sbus_softc *sc; - int node; - struct sbus_intr **ipp; - int *np; - int slot; +sbus_get_intr(struct sbus_softc *sc, int node, struct sbus_intr **ipp, int *np, + int slot) { int *ipl; int n, i; @@ -681,7 +638,7 @@ sbus_get_intr(sc, node, ipp, np, slot) * Stuff the real vector in sbi_vec. */ - ip[n].sbi_pri = pri|ipl[n]; + ip[n].sbi_pri = pri | ipl[n]; ip[n].sbi_vec = ipl[n]; } free(ipl, M_DEVBUF); @@ -696,19 +653,17 @@ sbus_get_intr(sc, node, ipp, np, slot) * Install an interrupt handler for an Sbus device. */ void * -sbus_intr_establish(t, pri, level, flags, handler, arg) - bus_space_tag_t t; - int pri; - int level; - int flags; - int (*handler)(void *); - void *arg; +sbus_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int pri, int level, + int flags, int (*handler)(void *), void *arg) { struct sbus_softc *sc = t->cookie; + struct sysioreg *sysio; struct intrhand *ih; int ipl; long vec = pri; + sysio = bus_space_vaddr(sc->sc_bustag, sc->sc_bh); + ih = (struct intrhand *) malloc(sizeof(struct intrhand), M_DEVBUF, M_NOWAIT); if (ih == NULL) @@ -734,11 +689,11 @@ sbus_intr_establish(t, pri, level, flags, handler, arg) if ((vec & INTMAP_OBIO) == 0) { /* We're in an SBUS slot */ /* Register the map and clear intr registers */ - + bus_space_handle_t maph; int slot = INTSLOT(pri); - ih->ih_map = &(&sc->sc_sysio->sbus_slot0_int)[slot]; - ih->ih_clr = &sc->sc_sysio->sbus0_clr_int[vec]; + ih->ih_map = &(&sysio->sbus_slot0_int)[slot]; + ih->ih_clr = &sysio->sbus0_clr_int[vec]; #ifdef DEBUG if (sbus_debug & SDB_INTR) { int64_t intrmap = *ih->ih_map; @@ -753,17 +708,26 @@ sbus_intr_establish(t, pri, level, flags, handler, arg) vec |= INTMAP_V; /* Insert IGN */ vec |= sc->sc_ign; - bus_space_write_8(sc->sc_bustag, - (bus_space_handle_t)(u_long)ih->ih_map, 0, vec); + /* + * This would be cleaner if the underlying interrupt + * infrastructure took a bus tag/handle pair. Even + * if not, the following could be done with a write + * to the appropriate offset from sc->sc_bustag and + * sc->sc_bh. + */ + bus_space_map(sc->sc_bustag, (bus_addr_t)ih->ih_map, 8, + BUS_SPACE_MAP_PROMADDRESS, &maph); + bus_space_write_8(sc->sc_bustag, maph, 0, vec); } else { - int64_t *intrptr = &sc->sc_sysio->scsi_int_map; + bus_space_handle_t maph; + volatile int64_t *intrptr = &sysio->scsi_int_map; int64_t intrmap = 0; int i; /* Insert IGN */ vec |= sc->sc_ign; for (i = 0; &intrptr[i] <= - (int64_t *)&sc->sc_sysio->reserved_int_map && + (int64_t *)&sysio->reserved_int_map && INTVEC(intrmap = intrptr[i]) != INTVEC(vec); i++) ; if (INTVEC(intrmap) == INTVEC(vec)) { @@ -772,12 +736,22 @@ sbus_intr_establish(t, pri, level, flags, handler, arg) vec, (long)intrmap, i)); /* Register the map and clear intr registers */ ih->ih_map = &intrptr[i]; - intrptr = (int64_t *)&sc->sc_sysio->scsi_clr_int; + intrptr = (int64_t *)&sysio->scsi_clr_int; ih->ih_clr = &intrptr[i]; /* Enable the interrupt */ intrmap |= INTMAP_V; - bus_space_write_8(sc->sc_bustag, - (bus_space_handle_t)(u_long)ih->ih_map, 0, + /* + * This would be cleaner if the underlying + * interrupt infrastructure took a bus tag/ + * handle pair. Even if not, the following + * could be done with a write to the + * appropriate offset from sc->sc_bustag and + * sc->sc_bh. + */ + bus_space_map(sc->sc_bustag, + (bus_addr_t)ih->ih_map, 8, + BUS_SPACE_MAP_PROMADDRESS, &maph); + bus_space_write_8(sc->sc_bustag, maph, 0, (u_long)intrmap); } else panic("IRQ not found!"); @@ -796,20 +770,22 @@ sbus_intr_establish(t, pri, level, flags, handler, arg) } static bus_space_tag_t -sbus_alloc_bustag(sc) - struct sbus_softc *sc; +sbus_alloc_bustag(struct sbus_softc *sc) { - bus_space_tag_t sbt; + struct sparc_bus_space_tag *sbt; - sbt = (bus_space_tag_t) - malloc(sizeof(struct sparc_bus_space_tag), M_DEVBUF, M_NOWAIT); + sbt = malloc(sizeof(*sbt), M_DEVBUF, M_NOWAIT); if (sbt == NULL) return (NULL); bzero(sbt, sizeof *sbt); + snprintf(sbt->name, sizeof(sbt->name), "%s", + sc->sc_dev.dv_xname); sbt->cookie = sc; sbt->parent = sc->sc_bustag; - sbt->type = SBUS_BUS_SPACE; + sbt->default_type = SBUS_BUS_SPACE; + sbt->asi = ASI_PRIMARY; + sbt->sasi = ASI_PRIMARY; sbt->sparc_bus_map = _sbus_bus_map; sbt->sparc_bus_mmap = sc->sc_bustag->sparc_bus_mmap; sbt->sparc_intr_establish = sbus_intr_establish; @@ -818,8 +794,7 @@ sbus_alloc_bustag(sc) static bus_dma_tag_t -sbus_alloc_dmatag(sc) - struct sbus_softc *sc; +sbus_alloc_dmatag(struct sbus_softc *sc) { bus_dma_tag_t sdt, psdt = sc->sc_dmatag; @@ -851,59 +826,45 @@ sbus_alloc_dmatag(sc) } int -sbus_dmamap_load(tag, map, buf, buflen, p, flags) - bus_dma_tag_t tag; - bus_dmamap_t map; - void *buf; - bus_size_t buflen; - struct proc *p; - int flags; +sbus_dmamap_load(bus_dma_tag_t tag, bus_dmamap_t map, void *buf, + bus_size_t buflen, struct proc *p, int flags) { - struct sbus_softc *sc = (struct sbus_softc *)tag->_cookie; + struct sbus_softc *sc = tag->_cookie; - return (iommu_dvmamap_load(tag, &sc->sc_is, map, buf, buflen, p, flags)); + return (iommu_dvmamap_load(tag, &sc->sc_is, map, buf, buflen, + p, flags)); } int -sbus_dmamap_load_raw(tag, map, segs, nsegs, size, flags) - bus_dma_tag_t tag; - bus_dmamap_t map; - bus_dma_segment_t *segs; - int nsegs; - bus_size_t size; - int flags; +sbus_dmamap_load_raw(bus_dma_tag_t tag, bus_dmamap_t map, + bus_dma_segment_t *segs, int nsegs, bus_size_t size, int flags) { - struct sbus_softc *sc = (struct sbus_softc *)tag->_cookie; + struct sbus_softc *sc = tag->_cookie; - return (iommu_dvmamap_load_raw(tag, &sc->sc_is, map, segs, nsegs, flags, size)); + return (iommu_dvmamap_load_raw(tag, &sc->sc_is, map, segs, + nsegs, flags, size)); } void -sbus_dmamap_unload(tag, map) - bus_dma_tag_t tag; - bus_dmamap_t map; +sbus_dmamap_unload(bus_dma_tag_t tag, bus_dmamap_t map) { - struct sbus_softc *sc = (struct sbus_softc *)tag->_cookie; + struct sbus_softc *sc = tag->_cookie; iommu_dvmamap_unload(tag, &sc->sc_is, map); } void -sbus_dmamap_sync(tag, map, offset, len, ops) - bus_dma_tag_t tag; - bus_dmamap_t map; - bus_addr_t offset; - bus_size_t len; - int ops; +sbus_dmamap_sync(bus_dma_tag_t tag, bus_dmamap_t map, bus_addr_t offset, + bus_size_t len, int ops) { - struct sbus_softc *sc = (struct sbus_softc *)tag->_cookie; + struct sbus_softc *sc = tag->_cookie; - if (ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) { + if (ops & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)) { /* Flush the CPU then the IOMMU */ bus_dmamap_sync(tag->_parent, map, offset, len, ops); iommu_dvmamap_sync(tag, &sc->sc_is, map, offset, len, ops); } - if (ops & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)) { + if (ops & (BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE)) { /* Flush the IOMMU then the CPU */ iommu_dvmamap_sync(tag, &sc->sc_is, map, offset, len, ops); bus_dmamap_sync(tag->_parent, map, offset, len, ops); @@ -911,27 +872,18 @@ sbus_dmamap_sync(tag, map, offset, len, ops) } int -sbus_dmamem_alloc(tag, size, alignment, boundary, segs, nsegs, rsegs, flags) - bus_dma_tag_t tag; - bus_size_t size; - bus_size_t alignment; - bus_size_t boundary; - bus_dma_segment_t *segs; - int nsegs; - int *rsegs; - int flags; +sbus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size, bus_size_t alignment, + bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, + int flags) { - struct sbus_softc *sc = (struct sbus_softc *)tag->_cookie; + struct sbus_softc *sc = tag->_cookie; return (iommu_dvmamem_alloc(tag, &sc->sc_is, size, alignment, boundary, segs, nsegs, rsegs, flags)); } void -sbus_dmamem_free(tag, segs, nsegs) - bus_dma_tag_t tag; - bus_dma_segment_t *segs; - int nsegs; +sbus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs, int nsegs) { struct sbus_softc *sc = (struct sbus_softc *)tag->_cookie; @@ -939,24 +891,17 @@ sbus_dmamem_free(tag, segs, nsegs) } int -sbus_dmamem_map(tag, segs, nsegs, size, kvap, flags) - bus_dma_tag_t tag; - bus_dma_segment_t *segs; - int nsegs; - size_t size; - caddr_t *kvap; - int flags; +sbus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs, int nsegs, + size_t size, caddr_t *kvap, int flags) { - struct sbus_softc *sc = (struct sbus_softc *)tag->_cookie; + struct sbus_softc *sc = tag->_cookie; - return (iommu_dvmamem_map(tag, &sc->sc_is, segs, nsegs, size, kvap, flags)); + return (iommu_dvmamem_map(tag, &sc->sc_is, segs, nsegs, size, + kvap, flags)); } void -sbus_dmamem_unmap(tag, kva, size) - bus_dma_tag_t tag; - caddr_t kva; - size_t size; +sbus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva, size_t size) { struct sbus_softc *sc = (struct sbus_softc *)tag->_cookie; diff --git a/sys/arch/sparc64/dev/sbusvar.h b/sys/arch/sparc64/dev/sbusvar.h index 1794644d80e..63249b64984 100644 --- a/sys/arch/sparc64/dev/sbusvar.h +++ b/sys/arch/sparc64/dev/sbusvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sbusvar.h,v 1.4 2002/03/14 01:26:44 millert Exp $ */ +/* $OpenBSD: sbusvar.h,v 1.5 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: sbusvar.h,v 1.7 1999/06/05 05:30:43 mrg Exp $ */ /*- @@ -101,6 +101,7 @@ struct sbus_softc { struct device sc_dev; /* base device */ bus_space_tag_t sc_bustag; + bus_space_handle_t sc_bh; bus_dma_tag_t sc_dmatag; int sc_clockfreq; /* clock frequency (in Hz) */ struct sbusdev *sc_sbdev; /* list of all children */ @@ -110,11 +111,13 @@ struct sbus_softc { int *sc_intr2ipl; /* Interrupt level translation */ int *sc_intr_compat;/* `intr' property to sbus compat */ - struct sysioreg *sc_sysio; /* SBUS control registers */ int sc_ign; /* Interrupt group number for this sysio */ struct iommu_state sc_is; /* IOMMU state, see iommureg.h */ + struct strbuf_ctl sc_sb; /* Streaming buffer control */ + int64_t sc_flush; /* Streaming buffer flush */ }; bus_addr_t sbus_bus_addr(bus_space_tag_t, u_int, u_int); #endif /* _SBUS_VAR_SPARC64_H_ */ + diff --git a/sys/arch/sparc64/dev/schizo.c b/sys/arch/sparc64/dev/schizo.c index beb43cce579..931ebc48669 100644 --- a/sys/arch/sparc64/dev/schizo.c +++ b/sys/arch/sparc64/dev/schizo.c @@ -1,7 +1,8 @@ -/* $OpenBSD: schizo.c,v 1.8 2003/01/13 16:04:38 jason Exp $ */ +/* $OpenBSD: schizo.c,v 1.9 2003/02/17 01:29:20 henric Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) + * Copyright (c) 2003 Henric Jungheim * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,6 +55,17 @@ #include <sparc64/dev/schizovar.h> #include <sparc64/sparc64/cache.h> +#ifdef DEBUG +#define SDB_PROM 0x01 +#define SDB_BUSMAP 0x02 +#define SDB_INTR 0x04 +#define SDB_CONF 0x08 +int schizo_debug = ~0; +#define DPRINTF(l, s) do { if (schizo_debug & l) printf s; } while (0) +#else +#define DPRINTF(l, s) +#endif + extern struct sparc_pci_chipset _sparc_pci_chipset; int schizo_match(struct device *, void *, void *); @@ -64,17 +76,19 @@ int schizo_print(void *, const char *); pci_chipset_tag_t schizo_alloc_chipset(struct schizo_pbm *, int, pci_chipset_tag_t); -bus_space_tag_t schizo_alloc_bus_tag(struct schizo_pbm *, int); +bus_space_tag_t schizo_alloc_mem_tag(struct schizo_pbm *); +bus_space_tag_t schizo_alloc_io_tag(struct schizo_pbm *); +bus_space_tag_t schizo_alloc_config_tag(struct schizo_pbm *); +bus_space_tag_t _schizo_alloc_bus_tag(struct schizo_pbm *, const char *, + int, int, int); bus_dma_tag_t schizo_alloc_dma_tag(struct schizo_pbm *); -pcireg_t schizo_pci_conf_read(pci_chipset_tag_t pc, pcitag_t, int); -void schizo_pci_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t); paddr_t schizo_bus_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int); -int _schizo_bus_map(bus_space_tag_t, bus_type_t, bus_addr_t, - bus_size_t, int, vaddr_t, bus_space_handle_t *); -void *_schizo_intr_establish(bus_space_tag_t, int, int, int, +int _schizo_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t, + bus_size_t, int, bus_space_handle_t *); +void *_schizo_intr_establish(bus_space_tag_t, bus_space_tag_t, int, int, int, int (*)(void *), void *); -paddr_t _schizo_bus_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int); +paddr_t _schizo_bus_mmap(bus_space_tag_t, bus_space_tag_t, bus_addr_t, off_t, int, int); int schizo_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t, struct proc *, int); @@ -89,12 +103,9 @@ void schizo_dmamem_free(bus_dma_tag_t, bus_dma_segment_t *, int); int schizo_dmamem_map(bus_dma_tag_t, bus_dma_segment_t *, int, size_t, caddr_t *, int); void schizo_dmamem_unmap(bus_dma_tag_t, caddr_t, size_t); -int schizo_get_childspace(int); int -schizo_match(parent, match, aux) - struct device *parent; - void *match, *aux; +schizo_match(struct device *parent, void *match, void *aux) { struct mainbus_attach_args *ma = aux; char *str; @@ -114,9 +125,7 @@ schizo_match(parent, match, aux) } void -schizo_attach(parent, self, aux) - struct device *parent, *self; - void *aux; +schizo_attach(struct device *parent, struct device *self, void *aux) { struct schizo_softc *sc = (struct schizo_softc *)self; struct mainbus_attach_args *ma = aux; @@ -132,21 +141,17 @@ schizo_attach(parent, self, aux) else busa = 0; - if (bus_space_map(sc->sc_bust, ma->ma_reg[1].ur_paddr - 0x10000, + if (bus_space_map(sc->sc_bust, sc->sc_ctrl, sizeof(struct schizo_regs), 0, &sc->sc_ctrlh)) { printf(": failed to map registers\n"); return; } - sc->sc_regs = (struct schizo_regs *)bus_space_vaddr(sc->sc_bust, - sc->sc_ctrlh); schizo_init(sc, busa); } void -schizo_init(sc, busa) - struct schizo_softc *sc; - int busa; +schizo_init(struct schizo_softc *sc, int busa) { struct schizo_pbm *pbm; struct pcibus_attach_args pba; @@ -177,20 +182,29 @@ schizo_init(sc, busa) (busa ? SCZ_PCIA_IO_MATCH : SCZ_PCIB_IO_MATCH)); pbm->sp_confpaddr = match & ~0x8000000000000000UL; - pbm->sp_memt = schizo_alloc_bus_tag(pbm, PCI_MEMORY_BUS_SPACE); - pbm->sp_iot = schizo_alloc_bus_tag(pbm, PCI_IO_BUS_SPACE); - pbm->sp_cfgt = schizo_alloc_bus_tag(pbm, PCI_CONFIG_BUS_SPACE); + pbm->sp_regt = sc->sc_bust; + if (bus_space_subregion(pbm->sp_regt, sc->sc_ctrlh, + busa ? offsetof(struct schizo_regs, pbm_a) : + offsetof(struct schizo_regs, pbm_b), + sizeof(struct schizo_pbm_regs), + &pbm->sp_regh)) { + panic("schizo: unable to create PBM handle"); + } + + pbm->sp_memt = schizo_alloc_mem_tag(pbm); + pbm->sp_iot = schizo_alloc_io_tag(pbm); + pbm->sp_cfgt = schizo_alloc_config_tag(pbm); pbm->sp_dmat = schizo_alloc_dma_tag(pbm); - if (bus_space_map2(sc->sc_bust, PCI_CONFIG_BUS_SPACE, - pbm->sp_confpaddr, 0x1000000, 0, 0, &pbm->sp_cfgh)) + if (bus_space_map(pbm->sp_cfgt, pbm->sp_confpaddr, 0x1000000, + 0, &pbm->sp_cfgh)) panic("schizo: could not map config space"); pbm->sp_pc = schizo_alloc_chipset(pbm, sc->sc_node, &_sparc_pci_chipset); - pbm->sp_pc->conf_read = schizo_pci_conf_read; - pbm->sp_pc->conf_write = schizo_pci_conf_write; + pbm->sp_pc->bustag = pbm->sp_cfgt; + pbm->sp_pc->bushandle = pbm->sp_cfgh; pba.pba_busname = "pci"; pba.pba_bus = busranges[0]; @@ -208,28 +222,33 @@ schizo_init(sc, busa) } void -schizo_init_iommu(sc, pbm) - struct schizo_softc *sc; - struct schizo_pbm *pbm; +schizo_init_iommu(struct schizo_softc *sc, struct schizo_pbm *pbm) { struct iommu_state *is = &pbm->sp_is; char *name; - is->is_bustag = pbm->sp_sc->sc_bust; - if (pbm->sp_bus_a) { - is->is_iommu = &pbm->sp_sc->sc_regs->pbm_a.iommu; - is->is_sb[0] = &pbm->sp_sc->sc_regs->pbm_a.strbuf; - } else { - is->is_iommu = &pbm->sp_sc->sc_regs->pbm_b.iommu; - is->is_sb[0] = &pbm->sp_sc->sc_regs->pbm_b.strbuf; - } + is->is_bustag = pbm->sp_regt; + + if (bus_space_subregion(is->is_bustag, pbm->sp_regh, + offsetof(struct schizo_pbm_regs, iommu), + sizeof(struct iommureg), &is->is_iommu)) { + panic("schizo: unable to create iommu handle"); + } + + is->is_sb[0]->sb_bustag = is->is_bustag; + if (bus_space_subregion(is->is_bustag, pbm->sp_regh, + offsetof(struct schizo_pbm_regs, strbuf), + sizeof(struct iommu_strbuf), &is->is_sb[0]->sb_sb)) { + panic("schizo: unable to create streaming buffer handle"); + } #if 1 /* XXX disable the streaming buffers for now */ - is->is_sb[0]->strbuf_ctl &= ~STRBUF_EN; - is->is_sb[0] = NULL; + bus_space_write_8(is->is_bustag, is->is_sb[0]->sb_sb, + STRBUFREG(strbuf_ctl), + bus_space_read_8(is->is_bustag, is->is_sb[0]->sb_sb, + STRBUFREG(strbuf_ctl)) & ~STRBUF_EN); #endif - is->is_sb[1] = NULL; name = (char *)malloc(32, M_DEVBUF, M_NOWAIT); if (name == NULL) @@ -240,9 +259,7 @@ schizo_init_iommu(sc, pbm) } int -schizo_print(aux, p) - void *aux; - const char *p; +schizo_print(void *aux, const char *p) { if (p == NULL) return (UNCONF); @@ -250,22 +267,49 @@ schizo_print(aux, p) } bus_space_tag_t -schizo_alloc_bus_tag(pbm, type) - struct schizo_pbm *pbm; - int type; +schizo_alloc_mem_tag(struct schizo_pbm *sp) +{ + return (_schizo_alloc_bus_tag(sp, "mem", + 0x02, /* 32-bit mem space (where's the #define???) */ + ASI_PRIMARY, ASI_PRIMARY_LITTLE)); +} + +bus_space_tag_t +schizo_alloc_io_tag(struct schizo_pbm *sp) +{ + return (_schizo_alloc_bus_tag(sp, "io", + 0x01, /* IO space (where's the #define???) */ + ASI_PHYS_NON_CACHED_LITTLE, ASI_PHYS_NON_CACHED)); +} + +bus_space_tag_t +schizo_alloc_config_tag(struct schizo_pbm *sp) +{ + return (_schizo_alloc_bus_tag(sp, "cfg", + 0x00, /* Config space (where's the #define???) */ + ASI_PHYS_NON_CACHED_LITTLE, ASI_PHYS_NON_CACHED)); +} + +bus_space_tag_t +_schizo_alloc_bus_tag(struct schizo_pbm *pbm, const char *name, int ss, + int asi, int sasi) { struct schizo_softc *sc = pbm->sp_sc; - bus_space_tag_t bt; + struct sparc_bus_space_tag *bt; - bt = (bus_space_tag_t) - malloc(sizeof(struct sparc_bus_space_tag), M_DEVBUF, M_NOWAIT); + bt = malloc(sizeof(*bt), M_DEVBUF, M_NOWAIT); if (bt == NULL) panic("schizo: could not allocate bus tag"); bzero(bt, sizeof *bt); + snprintf(bt->name, sizeof(bt->name), "%s-pbm_%s(%d/%2.2x)", + sc->sc_dv.dv_xname, name, ss, asi); + bt->cookie = pbm; bt->parent = sc->sc_bust; - bt->type = type; + bt->default_type = ss; + bt->asi = asi; + bt->sasi = sasi; bt->sparc_bus_map = _schizo_bus_map; bt->sparc_bus_mmap = _schizo_bus_mmap; bt->sparc_intr_establish = _schizo_intr_establish; @@ -273,8 +317,7 @@ schizo_alloc_bus_tag(pbm, type) } bus_dma_tag_t -schizo_alloc_dma_tag(pbm) - struct schizo_pbm *pbm; +schizo_alloc_dma_tag(struct schizo_pbm *pbm) { struct schizo_softc *sc = pbm->sp_sc; bus_dma_tag_t dt, pdt = sc->sc_dmat; @@ -306,10 +349,7 @@ schizo_alloc_dma_tag(pbm) } pci_chipset_tag_t -schizo_alloc_chipset(pbm, node, pc) - struct schizo_pbm *pbm; - int node; - pci_chipset_tag_t pc; +schizo_alloc_chipset(struct schizo_pbm *pbm, int node, pci_chipset_tag_t pc) { pci_chipset_tag_t npc; @@ -324,52 +364,37 @@ schizo_alloc_chipset(pbm, node, pc) } int -schizo_dmamap_load(t, map, buf, buflen, p, flags) - bus_dma_tag_t t; - bus_dmamap_t map; - void *buf; - bus_size_t buflen; - struct proc *p; - int flags; +schizo_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf, + bus_size_t buflen, struct proc *p, int flags) { - struct schizo_pbm *pbm = (struct schizo_pbm *)t->_cookie; + struct schizo_pbm *pbm = t->_cookie; return (iommu_dvmamap_load(t, &pbm->sp_is, map, buf, buflen, p, flags)); } void -schizo_dmamap_unload(t, map) - bus_dma_tag_t t; - bus_dmamap_t map; +schizo_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map) { - struct schizo_pbm *pbm = (struct schizo_pbm *)t->_cookie; + struct schizo_pbm *pbm = t->_cookie; iommu_dvmamap_unload(t, &pbm->sp_is, map); } int -schizo_dmamap_load_raw(t, map, segs, nsegs, size, flags) - bus_dma_tag_t t; - bus_dmamap_t map; - bus_dma_segment_t *segs; - int nsegs, flags; - bus_size_t size; +schizo_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map, + bus_dma_segment_t *segs, int nsegs, bus_size_t size, int flags) { - struct schizo_pbm *pbm = (struct schizo_pbm *)t->_cookie; + struct schizo_pbm *pbm = t->_cookie; return (iommu_dvmamap_load_raw(t, &pbm->sp_is, map, segs, nsegs, flags, size)); } void -schizo_dmamap_sync(t, map, offset, len, ops) - bus_dma_tag_t t; - bus_dmamap_t map; - bus_addr_t offset; - bus_size_t len; - int ops; +schizo_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, + bus_size_t len, int ops) { - struct schizo_pbm *pbm = (struct schizo_pbm *)t->_cookie; + struct schizo_pbm *pbm = t->_cookie; if (ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) { /* Flush the CPU then the IOMMU */ @@ -384,94 +409,67 @@ schizo_dmamap_sync(t, map, offset, len, ops) } int -schizo_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags) - bus_dma_tag_t t; - bus_size_t size; - bus_size_t alignment; - bus_size_t boundary; - bus_dma_segment_t *segs; - int nsegs; - int *rsegs; - int flags; +schizo_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment, + bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, + int flags) { - struct schizo_pbm *pbm = (struct schizo_pbm *)t->_cookie; + struct schizo_pbm *pbm = t->_cookie; return (iommu_dvmamem_alloc(t, &pbm->sp_is, size, alignment, boundary, segs, nsegs, rsegs, flags)); } void -schizo_dmamem_free(t, segs, nsegs) - bus_dma_tag_t t; - bus_dma_segment_t *segs; - int nsegs; +schizo_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs) { - struct schizo_pbm *pbm = (struct schizo_pbm *)t->_cookie; + struct schizo_pbm *pbm = t->_cookie; iommu_dvmamem_free(t, &pbm->sp_is, segs, nsegs); } int -schizo_dmamem_map(t, segs, nsegs, size, kvap, flags) - bus_dma_tag_t t; - bus_dma_segment_t *segs; - int nsegs; - size_t size; - caddr_t *kvap; - int flags; +schizo_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, + size_t size, caddr_t *kvap, int flags) { - struct schizo_pbm *pbm = (struct schizo_pbm *)t->_cookie; + struct schizo_pbm *pbm = t->_cookie; return (iommu_dvmamem_map(t, &pbm->sp_is, segs, nsegs, size, kvap, flags)); } void -schizo_dmamem_unmap(t, kva, size) - bus_dma_tag_t t; - caddr_t kva; - size_t size; +schizo_dmamem_unmap(bus_dma_tag_t t, caddr_t kva, size_t size) { - struct schizo_pbm *pbm = (struct schizo_pbm *)t->_cookie; + struct schizo_pbm *pbm = t->_cookie; iommu_dvmamem_unmap(t, &pbm->sp_is, kva, size); } int -schizo_get_childspace(type) - int type; -{ - if (type == PCI_CONFIG_BUS_SPACE) - return (0x0); - if (type == PCI_IO_BUS_SPACE) - return (0x1); - if (type == PCI_MEMORY_BUS_SPACE) - return (0x2); -#if 0 - if (type == PCI_MEMORY64_BUS_SPACE) - return (0x3); -#endif - panic("schizo: unknown type %d", type); -} - -int -_schizo_bus_map(t, btype, offset, size, flags, vaddr, hp) - bus_space_tag_t t; - bus_type_t btype; - bus_addr_t offset; - bus_size_t size; - int flags; - vaddr_t vaddr; - bus_space_handle_t *hp; +_schizo_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) { struct schizo_pbm *pbm = t->cookie; - struct schizo_softc *sc = pbm->sp_sc; int i, ss; - ss = schizo_get_childspace(t->type); + DPRINTF(SDB_BUSMAP, ("_schizo_bus_map: type %d off %qx sz %qx flags %d", + t->default_type, + (unsigned long long)offset, + (unsigned long long)size, + flags)); - if (btype == 0) - btype = t->type; + ss = t->default_type; + DPRINTF(SDB_BUSMAP, (" cspace %d", ss)); + + if (t->parent == 0 || t->parent->sparc_bus_map == 0) { + printf("\n_psycho_bus_map: invalid parent"); + return (EINVAL); + } + + if (flags & BUS_SPACE_MAP_PROMADDRESS) { + return ((*t->parent->sparc_bus_map) + (t, t0, offset, size, flags, hp)); + } for (i = 0; i < pbm->sp_nrange; i++) { bus_addr_t paddr; @@ -481,27 +479,30 @@ _schizo_bus_map(t, btype, offset, size, flags, vaddr, hp) paddr = pbm->sp_range[i].phys_lo + offset; paddr |= ((bus_addr_t)pbm->sp_range[i].phys_hi) << 32; - return (bus_space_map2(sc->sc_bust, btype, paddr, - size, flags, vaddr, hp)); + return ((*t->parent->sparc_bus_map) + (t, t0, paddr, size, flags, hp)); } return (EINVAL); } paddr_t -_schizo_bus_mmap(t, paddr, off, prot, flags) - bus_space_tag_t t; - bus_addr_t paddr; - off_t off; - int prot; - int flags; +_schizo_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr, + off_t off, int prot, int flags) { bus_addr_t offset = paddr; struct schizo_pbm *pbm = t->cookie; - struct schizo_softc *sc = pbm->sp_sc; int i, ss; - ss = schizo_get_childspace(t->type); + ss = t->default_type; + + DPRINTF(SDB_BUSMAP, ("_schizo_bus_mmap: prot %d flags %d pa %qx\n", + prot, flags, (unsigned long long)paddr)); + + if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) { + printf("\n_schizo_bus_mmap: invalid parent"); + return (-1); + } for (i = 0; i < pbm->sp_nrange; i++) { bus_addr_t paddr; @@ -511,55 +512,18 @@ _schizo_bus_mmap(t, paddr, off, prot, flags) paddr = pbm->sp_range[i].phys_lo + offset; paddr |= ((bus_addr_t)pbm->sp_range[i].phys_hi<<32); - return (bus_space_mmap(sc->sc_bustag, paddr, off, - prot, flags)); + return ((*t->parent->sparc_bus_mmap) + (t, t0, paddr, off, prot, flags)); } return (-1); } -pcireg_t -schizo_pci_conf_read(pc, tag, reg) - pci_chipset_tag_t pc; - pcitag_t tag; - int reg; -{ - struct schizo_pbm *pbm = pc->cookie; - - if (PCITAG_NODE(tag) == -1) - return (~0); - - return (bus_space_read_4(pbm->sp_cfgt, pbm->sp_cfgh, - PCITAG_OFFSET(tag) + reg)); -} - -void -schizo_pci_conf_write(pc, tag, reg, data) - pci_chipset_tag_t pc; - pcitag_t tag; - int reg; - pcireg_t data; -{ - struct schizo_pbm *pbm = pc->cookie; - - if (PCITAG_NODE(tag) == -1) - return; - - bus_space_write_4(pbm->sp_cfgt, pbm->sp_cfgh, - PCITAG_OFFSET(tag) + reg, data); -} - void * -_schizo_intr_establish(t, ihandle, level, flags, handler, arg) - bus_space_tag_t t; - int ihandle; - int level; - int flags; - int (*handler)(void *); - void *arg; +_schizo_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int ihandle, + int level, int flags, int (*handler)(void *), void *arg) { struct schizo_pbm *pbm = t->cookie; - struct schizo_softc *sc = pbm->sp_sc; struct intrhand *ih = NULL; volatile u_int64_t *intrmapptr = NULL, *intrclrptr = NULL; int ino; @@ -583,8 +547,7 @@ _schizo_intr_establish(t, ihandle, level, flags, handler, arg) if ((flags & BUS_INTR_ESTABLISH_SOFTINTR) == 0) { struct schizo_pbm_regs *pbmreg; - pbmreg = pbm->sp_bus_a ? &sc->sc_regs->pbm_a : - &sc->sc_regs->pbm_b; + pbmreg = bus_space_vaddr(pbm->sp_regt, pbm->sp_regh); intrmapptr = &pbmreg->imap[ino]; intrclrptr = &pbmreg->iclr[ino]; } diff --git a/sys/arch/sparc64/dev/schizovar.h b/sys/arch/sparc64/dev/schizovar.h index b312b04bb90..d84b48d333f 100644 --- a/sys/arch/sparc64/dev/schizovar.h +++ b/sys/arch/sparc64/dev/schizovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: schizovar.h,v 1.2 2002/07/18 16:45:08 jason Exp $ */ +/* $OpenBSD: schizovar.h,v 1.3 2003/02/17 01:29:20 henric Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -42,6 +42,8 @@ struct schizo_pbm { bus_space_tag_t sp_memt; bus_space_tag_t sp_iot; + bus_space_tag_t sp_regt; + bus_space_handle_t sp_regh; bus_space_tag_t sp_cfgt; bus_space_handle_t sp_cfgh; bus_dma_tag_t sp_dmat; @@ -50,6 +52,8 @@ struct schizo_pbm { int sp_bus_a; bus_addr_t sp_confpaddr; struct iommu_state sp_is; + struct strbuf_ctl sp_sb; + char pp_flush[0x80]; }; struct schizo_softc { @@ -57,9 +61,6 @@ struct schizo_softc { int sc_node; bus_dma_tag_t sc_dmat; bus_space_tag_t sc_bust; - bus_space_tag_t sc_bustag; - struct iommu_state *sc_is; bus_addr_t sc_ctrl; bus_space_handle_t sc_ctrlh; - struct schizo_regs *sc_regs; }; diff --git a/sys/arch/sparc64/dev/upa.c b/sys/arch/sparc64/dev/upa.c index 9aa0722ea9a..0e7896a3b5d 100644 --- a/sys/arch/sparc64/dev/upa.c +++ b/sys/arch/sparc64/dev/upa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: upa.c,v 1.2 2002/06/11 11:03:07 jason Exp $ */ +/* $OpenBSD: upa.c,v 1.3 2003/02/17 01:29:20 henric Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -36,10 +36,6 @@ * */ -/* - * - */ - #include <sys/types.h> #include <sys/param.h> #include <sys/systm.h> @@ -92,14 +88,11 @@ struct cfdriver upa_cd = { int upa_print(void *, const char *); bus_space_tag_t upa_alloc_bus_tag(struct upa_softc *); -int __upa_bus_map(bus_space_tag_t, bus_type_t, bus_addr_t, - bus_size_t, int, vaddr_t, bus_space_handle_t *); +int __upa_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t, + bus_size_t, int, bus_space_handle_t *); int -upa_match(parent, match, aux) - struct device *parent; - void *match; - void *aux; +upa_match(struct device *parent, void *match, void *aux) { struct mainbus_attach_args *ma = aux; @@ -109,9 +102,7 @@ upa_match(parent, match, aux) } void -upa_attach(parent, self, aux) - struct device *parent, *self; - void *aux; +upa_attach(struct device *parent, struct device *self, void *aux) { struct upa_softc *sc = (void *)self; struct mainbus_attach_args *ma = aux; @@ -161,9 +152,7 @@ upa_attach(parent, self, aux) } int -upa_print(args, name) - void *args; - const char *name; +upa_print(void *args, const char *name) { struct mainbus_attach_args *ma = args; @@ -173,20 +162,21 @@ upa_print(args, name) } bus_space_tag_t -upa_alloc_bus_tag(sc) - struct upa_softc *sc; +upa_alloc_bus_tag(struct upa_softc *sc) { - bus_space_tag_t bt; + struct sparc_bus_space_tag *bt; - bt = (bus_space_tag_t)malloc(sizeof(struct sparc_bus_space_tag), - M_DEVBUF, M_NOWAIT); + bt = malloc(sizeof(*bt), M_DEVBUF, M_NOWAIT); if (bt == NULL) panic("upa: couldn't alloc bus tag"); bzero(bt, sizeof *bt); + snprintf(bt->name, sizeof(bt->name), "%s", + sc->sc_dev.dv_xname); bt->cookie = sc; bt->parent = sc->sc_bt; - bt->type = sc->sc_bt->type; + bt->asi = bt->parent->asi; + bt->sasi = bt->parent->sasi; bt->sparc_bus_map = __upa_bus_map; /* XXX bt->sparc_bus_mmap = upa_bus_mmap; */ /* XXX bt->sparc_intr_establish = upa_intr_establish; */ @@ -194,18 +184,24 @@ upa_alloc_bus_tag(sc) } int -__upa_bus_map(t, btype, offset, size, flags, vaddr, hp) - bus_space_tag_t t; - bus_type_t btype; - bus_addr_t offset; - bus_size_t size; - int flags; - vaddr_t vaddr; - bus_space_handle_t *hp; +__upa_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) { struct upa_softc *sc = t->cookie; int i; + if (t->parent == 0 || t->parent->sparc_bus_map == 0) { + printf("\n__upa_bus_map: invalid parent"); + return (EINVAL); + } + + t = t->parent; + + if (flags & BUS_SPACE_MAP_PROMADDRESS) { + return ((*t->sparc_bus_map) + (t, t0, offset, size, flags, hp)); + } + for (i = 0; i < sc->sc_nrange; i++) { if (offset < sc->sc_range[i].ur_space) continue; @@ -220,6 +216,7 @@ __upa_bus_map(t, btype, offset, size, flags, vaddr, hp) offset -= sc->sc_range[i].ur_space; offset += sc->sc_range[i].ur_addr; - return (bus_space_map2(sc->sc_bt, btype, offset, size, - flags, vaddr, hp)); + + return ((*t->sparc_bus_map)(t, t0, offset, size, flags, hp)); } + diff --git a/sys/arch/sparc64/dev/uperf_ebus.c b/sys/arch/sparc64/dev/uperf_ebus.c index 891b94b34cd..e4978d13e9f 100644 --- a/sys/arch/sparc64/dev/uperf_ebus.c +++ b/sys/arch/sparc64/dev/uperf_ebus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uperf_ebus.c,v 1.2 2002/04/08 17:49:42 jason Exp $ */ +/* $OpenBSD: uperf_ebus.c,v 1.3 2003/02/17 01:29:20 henric Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -128,7 +128,7 @@ uperf_ebus_attach(parent, self, aux) char *model; u_int32_t id; - sc->sc_bus_t = ea->ea_bustag; + sc->sc_bus_t = ea->ea_memtag; sc->sc_usc.usc_cookie = sc; sc->sc_usc.usc_getcntsrc = uperf_ebus_getcntsrc; sc->sc_usc.usc_setcntsrc = uperf_ebus_setcntsrc; diff --git a/sys/arch/sparc64/dev/zs.c b/sys/arch/sparc64/dev/zs.c index cdc35cb99a1..76f7643a15a 100644 --- a/sys/arch/sparc64/dev/zs.c +++ b/sys/arch/sparc64/dev/zs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zs.c,v 1.11 2002/10/12 01:09:43 krw Exp $ */ +/* $OpenBSD: zs.c,v 1.12 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: zs.c,v 1.29 2001/05/30 15:24:24 lukem Exp $ */ /*- @@ -253,7 +253,7 @@ zs_attach_mainbus(parent, self, aux) return; } zsaddr[zs_unit] = (struct zsdevice *) - (unsigned long int)kvaddr; + bus_space_vaddr(sa->sa_bustag, kvaddr); } } zsc->zsc_bustag = sa->sa_bustag; |