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 | |
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')
55 files changed, 4646 insertions, 3199 deletions
diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64 index ccfe24ae2dc..3ed37db9f90 100644 --- a/sys/arch/sparc64/conf/files.sparc64 +++ b/sys/arch/sparc64/conf/files.sparc64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.sparc64,v 1.42 2003/01/14 19:56:32 jason Exp $ +# $OpenBSD: files.sparc64,v 1.43 2003/02/17 01:29:19 henric Exp $ # $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $ # maxpartitions must be first item in files.${ARCH} @@ -169,6 +169,7 @@ file arch/sparc64/fpu/fpu_subr.c # N.B.: optimizer breaks pmap.c and/or cache.c somehow -- have not # identified the exact problem yet. NOOPT_C suffices for now. file arch/sparc64/sparc64/autoconf.c +file arch/sparc64/sparc64/busop.c file arch/sparc64/sparc64/cache.c file arch/sparc64/sparc64/conf.c file arch/sparc64/sparc64/emul.c 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; diff --git a/sys/arch/sparc64/include/bus.h b/sys/arch/sparc64/include/bus.h index a01850b5a1a..20a2e36f925 100644 --- a/sys/arch/sparc64/include/bus.h +++ b/sys/arch/sparc64/include/bus.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bus.h,v 1.13 2002/05/13 19:31:32 jason Exp $ */ +/* $OpenBSD: bus.h,v 1.14 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: bus.h,v 1.31 2001/09/21 15:30:41 wiz Exp $ */ /*- @@ -84,8 +84,47 @@ #define BSDB_ACCESS 0x01 #define BSDB_MAP 0x02 +#define BSDB_ASSERT 0x04 +#define BSDB_MAPDETAIL 0x08 +#define BSDB_ALL_ACCESS 0x10 extern int bus_space_debug; +#define BSHDB_ACCESS 0x01 +#define BSHDB_NO_ACCESS 0x02 + +#if defined(BUS_SPACE_DEBUG) +#ifndef __SYSTM_H__ +#include <sys/systm.h> +#endif +#define BUS_SPACE_PRINTF(l, s) do { if(bus_space_debug & (l)) printf s; } while(0) +#define BUS_SPACE_TRACE(t, h, s) do { \ + if ( (((bus_space_debug & BSDB_ALL_ACCESS) != 0) && \ + (((h).bh_flags & BSHDB_NO_ACCESS) == 0)) || \ + (((bus_space_debug & BSDB_ACCESS) != 0) && \ + (((h).bh_flags & BSHDB_ACCESS) != 0))) \ + printf s; \ + } while(0) +#define BUS_SPACE_SET_FLAGS(t, h, f) ((h).bh_flags |= (f)) +#define BUS_SPACE_CLEAR_FLAGS(t, h, f) ((h).bh_flags &= ~(f)) +#define BUS_SPACE_FLAG_DECL(s) int s +#define BUS_SPACE_SAVE_FLAGS(t, h, s) (s = (h).bh_flags) +#define BUS_SPACE_RESTORE_FLAGS(t, h, s) (s = (h).bh_flags) +#define BUS_SPACE_ASSERT(t, h, o, n) do { \ + if (bus_space_debug & BSDB_ASSERT) \ + bus_space_assert(t, &(h), o, n); \ + } while(0) +#else +#define BUS_SPACE_PRINTF(l, s) +#define BUS_SPACE_TRACE(t, h, s) +#define BUS_SPACE_SET_FLAGS(t, h, f) +#define BUS_SPACE_CLEAR_FLAGS(t, h, f) +#define BUS_SPACE_FLAG_DECL(s) +#define BUS_SPACE_SAVE_FLAGS(t, h, s) +#define BUS_SPACE_RESTORE_FLAGS(t, h, s) +#define BUS_SPACE_ASSERT(t, h, o, n) +#endif + + /* * UPA and SBUS spaces are non-cached and big endian * (except for RAM and PROM) @@ -101,8 +140,6 @@ enum bus_type { PCI_MEMORY_BUS_SPACE, LAST_BUS_SPACE }; -extern int bus_type_asi[]; -extern int bus_stream_asi[]; /* For backwards compatibility */ #define SPARC_BUS_SPACE UPA_BUS_SPACE @@ -111,79 +148,91 @@ extern int bus_stream_asi[]; /* * Bus address and size types */ -typedef u_int64_t bus_space_handle_t; -typedef enum bus_type bus_type_t; +typedef const struct sparc_bus_space_tag *bus_space_tag_t; typedef u_int64_t bus_addr_t; typedef u_int64_t bus_size_t; + +typedef struct _bus_space_handle { + paddr_t bh_ptr; +#ifdef BUS_SPACE_DEBUG + bus_space_tag_t bh_tag; + bus_size_t bh_size; + int bh_flags; +#endif +} bus_space_handle_t; + /* For buses which have an iospace. */ -#define BUS_ADDR_IOSPACE(x) ((x)>>32) -#define BUS_ADDR_PADDR(x) ((x)&0xffffffff) -#define BUS_ADDR(io, pa) (((io)<<32)|(pa)) +#define BUS_ADDR_IOSPACE(x) ((x)>>32) +#define BUS_ADDR_PADDR(x) ((x)&0xffffffff) +#define BUS_ADDR(io, pa) ((((bus_addr_t)io)<<32)|(pa)) /* * Access methods for bus resources and address space. */ -typedef struct sparc_bus_space_tag *bus_space_tag_t; struct sparc_bus_space_tag { - void *cookie; + void *cookie; bus_space_tag_t parent; - int type; + enum bus_type default_type; + u_int8_t asi; + u_int8_t sasi; + char name[32]; int (*sparc_bus_alloc)(bus_space_tag_t, + bus_space_tag_t, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *); void (*sparc_bus_free)(bus_space_tag_t, + bus_space_tag_t, bus_space_handle_t, bus_size_t); int (*sparc_bus_map)(bus_space_tag_t, - bus_type_t, bus_addr_t, bus_size_t, - int, vaddr_t, bus_space_handle_t *); + bus_space_tag_t, + bus_addr_t, bus_size_t, + int, bus_space_handle_t *); + + int (*sparc_bus_protect)(bus_space_tag_t, + bus_space_tag_t, + bus_space_handle_t, bus_size_t, int); int (*sparc_bus_unmap)(bus_space_tag_t, + bus_space_tag_t, bus_space_handle_t, bus_size_t); int (*sparc_bus_subregion)(bus_space_tag_t, + bus_space_tag_t, bus_space_handle_t, bus_size_t, bus_size_t, bus_space_handle_t *); void (*sparc_bus_barrier)(bus_space_tag_t, + bus_space_tag_t, bus_space_handle_t, bus_size_t, bus_size_t, int); paddr_t (*sparc_bus_mmap)(bus_space_tag_t, + bus_space_tag_t, bus_addr_t, off_t, int, int); void *(*sparc_intr_establish)(bus_space_tag_t, + bus_space_tag_t, int, int, int, int (*)(void *), void *); }; -#if 0 -/* - * The following macro could be used to generate the bus_space*() functions - * but it uses a gcc extension and is ANSI-only. -#define PROTO_bus_space_xxx(bus_space_tag_t t, ...) -#define RETURNTYPE_bus_space_xxx void * -#define BUSFUN(name, returntype, t, args...) \ - __inline__ RETURNTYPE_##name \ - bus_##name PROTO_##name \ - { \ - while (t->sparc_##name == NULL) \ - t = t->parent; \ - return (*(t)->sparc_##name)(t, args); \ - } - */ -#endif - +#ifdef BUS_SPACE_DEBUG +void bus_space_assert(bus_space_tag_t, + const bus_space_handle_t *, + bus_size_t, int); +void bus_space_render_tag(bus_space_tag_t, char*, size_t); +#endif /* BUS_SPACE_DEBUG */ /* * Bus space function prototypes. */ -static int bus_space_alloc( +int bus_space_alloc( bus_space_tag_t, bus_addr_t, /* reg start */ bus_addr_t, /* reg end */ @@ -193,29 +242,26 @@ static int bus_space_alloc( int, /* flags */ bus_addr_t *, bus_space_handle_t *); -static void bus_space_free( +void bus_space_free( bus_space_tag_t, bus_space_handle_t, bus_size_t); -static int bus_space_map( +int bus_space_map( bus_space_tag_t, bus_addr_t, bus_size_t, int, /*flags*/ bus_space_handle_t *); -static int bus_space_map2( +int bus_space_protect( bus_space_tag_t, - bus_type_t, - bus_addr_t, + bus_space_handle_t, bus_size_t, - int, /*flags*/ - vaddr_t, /*preferred vaddr*/ - bus_space_handle_t *); -static int bus_space_unmap( + int); /*flags*/ +int bus_space_unmap( bus_space_tag_t, bus_space_handle_t, bus_size_t); -static int bus_space_subregion( +int bus_space_subregion( bus_space_tag_t, bus_space_handle_t, bus_size_t, @@ -227,13 +273,13 @@ static void bus_space_barrier( bus_size_t, bus_size_t, int); -static paddr_t bus_space_mmap( +paddr_t bus_space_mmap( bus_space_tag_t, bus_addr_t, /*addr*/ off_t, /*offset*/ int, /*prot*/ int); /*flags*/ -static void *bus_intr_establish( +void *bus_intr_establish( bus_space_tag_t, int, /*bus-specific intr*/ int, /*device class level, @@ -241,106 +287,23 @@ static void *bus_intr_establish( int, /*flags*/ int (*)(void *), /*handler*/ void *); /*handler arg*/ +void bus_space_render_tag( + bus_space_tag_t, + char *, + size_t); +void *bus_space_vaddr( + bus_space_tag_t, + bus_space_handle_t); - -/* This macro finds the first "upstream" implementation of method `f' */ -#define _BS_CALL(t,f) \ +#define _BS_PRECALL(t,f) \ while (t->f == NULL) \ - t = t->parent; \ - return (*(t)->f) - -__inline__ int -bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) - bus_space_tag_t t; - bus_addr_t rs; - bus_addr_t re; - bus_size_t s; - bus_size_t a; - bus_size_t b; - int f; - bus_addr_t *ap; - bus_space_handle_t *hp; -{ - _BS_CALL(t, sparc_bus_alloc)(t, rs, re, s, a, b, f, ap, hp); -} - -__inline__ void -bus_space_free(t, h, s) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t s; -{ - _BS_CALL(t, sparc_bus_free)(t, h, s); -} + t = t->parent; +#define _BS_POSTCALL -__inline__ int -bus_space_map(t, a, s, f, hp) - bus_space_tag_t t; - bus_addr_t a; - bus_size_t s; - int f; - bus_space_handle_t *hp; -{ - _BS_CALL(t, sparc_bus_map)(t, 0, a, s, f, 0, hp); -} - -__inline__ int -bus_space_map2(t, bt, a, s, f, v, hp) - bus_space_tag_t t; - bus_type_t bt; - bus_addr_t a; - bus_size_t s; - int f; - vaddr_t v; - bus_space_handle_t *hp; -{ - _BS_CALL(t, sparc_bus_map)(t, bt, a, s, f, v, hp); -} - -__inline__ int -bus_space_unmap(t, h, s) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t s; -{ - _BS_CALL(t, sparc_bus_unmap)(t, h, s); -} - -__inline__ int -bus_space_subregion(t, h, o, s, hp) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o; - bus_size_t s; - bus_space_handle_t *hp; -{ - _BS_CALL(t, sparc_bus_subregion)(t, h, o, s, hp); -} - -__inline__ paddr_t -bus_space_mmap(t, a, o, p, f) - bus_space_tag_t t; - bus_addr_t a; - off_t o; - int p; - int f; -{ - _BS_CALL(t, sparc_bus_mmap)(t, a, o, p, f); -} - -__inline__ void * -bus_intr_establish(t, p, l, f, h, a) - bus_space_tag_t t; - int p; - int l; - int f; - int (*h)(void *); - void *a; -{ - _BS_CALL(t, sparc_intr_establish)(t, p, l, f, h, a); -} +#define _BS_CALL(t,f) \ + (*(t)->f) -__inline__ void +static inline void bus_space_barrier(t, h, o, s, f) bus_space_tag_t t; bus_space_handle_t h; @@ -348,21 +311,20 @@ bus_space_barrier(t, h, o, s, f) bus_size_t s; int f; { - _BS_CALL(t, sparc_bus_barrier)(t, h, o, s, f); + const bus_space_tag_t t0 = t; + _BS_PRECALL(t, sparc_bus_barrier); + _BS_CALL(t, sparc_bus_barrier)(t, t0, h, o, s, f); + _BS_POSTCALL; } -#if 1 -/* XXXX Things get complicated if we use unmapped register accesses. */ -#define bus_space_vaddr(t, h) (vaddr_t)(h) -#else -void * bus_space_vaddr(bus_space_tag_t space, bus_space_handle_t handle); -#endif +#include <sparc64/sparc64/busop.h> /* flags for bus space map functions */ #define BUS_SPACE_MAP_CACHEABLE 0x0001 #define BUS_SPACE_MAP_LINEAR 0x0002 #define BUS_SPACE_MAP_READONLY 0x0004 #define BUS_SPACE_MAP_PREFETCHABLE 0x0008 +#define BUS_SPACE_MAP_PROMADDRESS 0x0010 #define BUS_SPACE_MAP_BUS1 0x0100 /* placeholders for bus functions... */ #define BUS_SPACE_MAP_BUS2 0x0200 #define BUS_SPACE_MAP_BUS3 0x0400 @@ -385,7 +347,6 @@ void * bus_space_vaddr(bus_space_tag_t space, bus_space_handle_t handle); */ int bus_space_probe( bus_space_tag_t, - bus_type_t, bus_addr_t, bus_size_t, /* probe size */ size_t, /* offset */ @@ -394,1022 +355,6 @@ int bus_space_probe( void *); /* callback arg */ -/* - * u_intN_t bus_space_read_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t offset); - * - * Read a 1, 2, 4, or 8 byte quantity from bus space - * described by tag/handle/offset. - */ -#ifndef BUS_SPACE_DEBUG -#define bus_space_read_1(t, h, o) \ - lduba((h) + (o), bus_type_asi[(t)->type]) - -#define bus_space_read_2(t, h, o) \ - lduha((h) + (o), bus_type_asi[(t)->type]) - -#define bus_space_read_4(t, h, o) \ - lda((h) + (o), bus_type_asi[(t)->type]) - -#define bus_space_read_8(t, h, o) \ - ldxa((h) + (o), bus_type_asi[(t)->type]) -#else -#define bus_space_read_1(t, h, o) ({ \ - unsigned char __bv = \ - lduba((h) + (o), bus_type_asi[(t)->type]); \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsr1(%llx + %llx, %x) -> %x\n", (long long)(h), \ - (long long)(o), \ - bus_type_asi[(t)->type], (unsigned int) __bv); \ - __bv; }) - -#define bus_space_read_2(t, h, o) ({ \ - unsigned short __bv = \ - lduha((h) + (o), bus_type_asi[(t)->type]); \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsr2(%llx + %llx, %x) -> %x\n", (long long)(h), \ - (long long)(o), \ - bus_type_asi[(t)->type], (unsigned int)__bv); \ - __bv; }) - -#define bus_space_read_4(t, h, o) ({ \ - unsigned int __bv = \ - lda((h) + (o), bus_type_asi[(t)->type]); \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsr4(%llx + %llx, %x) -> %x\n", (long long)(h), \ - (long long)(o), \ - bus_type_asi[(t)->type], __bv); \ - __bv; }) - -#define bus_space_read_8(t, h, o) ({ \ - u_int64_t __bv = \ - ldxa((h) + (o), bus_type_asi[(t)->type]); \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsr8(%llx + %llx, %x) -> %llx\n", (long long)(h), \ - (long long)(o), \ - bus_type_asi[(t)->type], (long long)__bv); \ - __bv; }) -#endif -/* - * void bus_space_read_multi_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t offset, - * u_intN_t *addr, size_t count); - * - * Read `count' 1, 2, 4, or 8 byte quantities from bus space - * described by tag/handle/offset and copy into buffer provided. - */ - -#define bus_space_read_multi_1(t, h, o, a, c) do { \ - int i = c; \ - u_int8_t *p = (u_int8_t *)a; \ - while (i-- > 0) \ - *p++ = bus_space_read_1(t, h, o); \ -} while (0) - -#define bus_space_read_multi_2(t, h, o, a, c) do { \ - int i = c; \ - u_int16_t *p = (u_int16_t *)a; \ - while (i-- > 0) \ - *p++ = bus_space_read_2(t, h, o); \ -} while (0) - -#define bus_space_read_multi_4(t, h, o, a, c) do { \ - int i = c; \ - u_int32_t *p = (u_int32_t *)a; \ - while (i-- > 0) \ - *p++ = bus_space_read_4(t, h, o); \ -} while (0) - -#define bus_space_read_multi_8(t, h, o, a, c) do { \ - int i = c; \ - u_int64_t *p = (u_int64_t *)a; \ - while (i-- > 0) \ - *p++ = bus_space_read_8(t, h, o); \ -} while (0) - -/* - * void bus_space_write_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t offset, - * u_intN_t value); - * - * Write the 1, 2, 4, or 8 byte value `value' to bus space - * described by tag/handle/offset. - */ -#ifndef BUS_SPACE_DEBUG -#define bus_space_write_1(t, h, o, v) \ - ((void)(stba((h) + (o), bus_type_asi[(t)->type], (v)))) - -#define bus_space_write_2(t, h, o, v) \ - ((void)(stha((h) + (o), bus_type_asi[(t)->type], (v)))) - -#define bus_space_write_4(t, h, o, v) \ - ((void)(sta((h) + (o), bus_type_asi[(t)->type], (v)))) - -#define bus_space_write_8(t, h, o, v) \ - ((void)(stxa((h) + (o), bus_type_asi[(t)->type], (v)))) -#else -#define bus_space_write_1(t, h, o, v) ({ \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsw1(%llx + %llx, %x) <- %x\n", (long long)(h), \ - (long long)(o), \ - bus_type_asi[(t)->type], (unsigned int) v); \ - ((void)(stba((h) + (o), bus_type_asi[(t)->type], (v)))); }) - -#define bus_space_write_2(t, h, o, v) ({ \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsw2(%llx + %llx, %x) <- %x\n", (long long)(h), \ - (long long)(o), \ - bus_type_asi[(t)->type], (unsigned int) v); \ - ((void)(stha((h) + (o), bus_type_asi[(t)->type], (v)))); }) - -#define bus_space_write_4(t, h, o, v) ({ \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsw4(%llx + %llx, %x) <- %x\n", (long long)(h), \ - (long long)(o), \ - bus_type_asi[(t)->type], (unsigned int) v); \ - ((void)(sta((h) + (o), bus_type_asi[(t)->type], (v)))); }) - -#define bus_space_write_8(t, h, o, v) ({ \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsw8(%llx + %llx, %x) <- %llx\n", (long long)(h), \ - (long long)(o), \ - bus_type_asi[(t)->type], (long long) v); \ - ((void)(stxa((h) + (o), bus_type_asi[(t)->type], (v)))); }) -#endif -/* - * void bus_space_write_multi_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t offset, - * const u_intN_t *addr, size_t count); - * - * Write `count' 1, 2, 4, or 8 byte quantities from the buffer - * provided to bus space described by tag/handle/offset. - */ - -#define bus_space_write_multi_1(t, h, o, a, c) do { \ - int i = c; \ - u_int8_t *p = (u_int8_t *)a; \ - while (i-- > 0) \ - bus_space_write_1(t, h, o, *p++); \ -} while (0) - -#define bus_space_write_multi_2(t, h, o, a, c) do { \ - int i = c; \ - u_int16_t *p = (u_int16_t *)a; \ - while (i-- > 0) \ - bus_space_write_2(t, h, o, *p++); \ -} while (0) - -#define bus_space_write_multi_4(t, h, o, a, c) do { \ - int i = c; \ - u_int32_t *p = (u_int32_t *)a; \ - while (i-- > 0) \ - bus_space_write_4(t, h, o, *p++); \ -} while (0) - -#define bus_space_write_multi_8(t, h, o, a, c) do { \ - int i = c; \ - u_int64_t *p = (u_int64_t *)a; \ - while (i-- > 0) \ - bus_space_write_8(t, h, o, *p++); \ -} while (0) - -/* - * void bus_space_set_multi_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, - * size_t count); - * - * Write the 1, 2, 4, or 8 byte value `val' to bus space described - * by tag/handle/offset `count' times. - */ - -#define bus_space_set_multi_1(t, h, o, v, c) do { \ - int i = c; \ - while (i-- > 0) \ - bus_space_write_1(t, h, o, v); \ -} while (0) - -#define bus_space_set_multi_2(t, h, o, v, c) do { \ - int i = c; \ - while (i-- > 0) \ - bus_space_write_2(t, h, o, v); \ -} while (0) - -#define bus_space_set_multi_4(t, h, o, v, c) do { \ - int i = c; \ - while (i-- > 0) \ - bus_space_write_4(t, h, o, v); \ -} while (0) - -#define bus_space_set_multi_8(t, h, o, v, c) do { \ - int i = c; \ - while (i-- > 0) \ - bus_space_write_8(t, h, o, v); \ -} while (0) - -/* - * void bus_space_read_region_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t off, - * u_intN_t *addr, bus_size_t count); - * - */ -static void bus_space_read_region_1(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - u_int8_t *, - bus_size_t); -static void bus_space_read_region_2(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - u_int16_t *, - bus_size_t); -static void bus_space_read_region_4(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - u_int32_t *, - bus_size_t); -static void bus_space_read_region_8(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - u_int64_t *, - bus_size_t); - -static __inline__ void -bus_space_read_region_1(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - u_int8_t *a; -{ - for (; c; a++, c--, o++) - *a = bus_space_read_1(t, h, o); -} -static __inline__ void -bus_space_read_region_2(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - u_int16_t *a; -{ - for (; c; a++, c--, o+=2) - *a = bus_space_read_2(t, h, o); - } -static __inline__ void -bus_space_read_region_4(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - u_int32_t *a; -{ - for (; c; a++, c--, o+=4) - *a = bus_space_read_4(t, h, o); -} -static __inline__ void -bus_space_read_region_8(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - u_int64_t *a; -{ - for (; c; a++, c--, o+=8) - *a = bus_space_read_8(t, h, o); -} - -/* - * void bus_space_write_region_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t off, - * u_intN_t *addr, bus_size_t count); - * - */ -static void bus_space_write_region_1(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int8_t *, - bus_size_t); -static void bus_space_write_region_2(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int16_t *, - bus_size_t); -static void bus_space_write_region_4(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int32_t *, - bus_size_t); -static void bus_space_write_region_8(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int64_t *, - bus_size_t); -static __inline__ void -bus_space_write_region_1(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int8_t *a; -{ - for (; c; a++, c--, o++) - bus_space_write_1(t, h, o, *a); -} - -static __inline__ void -bus_space_write_region_2(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int16_t *a; -{ - for (; c; a++, c--, o+=2) - bus_space_write_2(t, h, o, *a); -} - -static __inline__ void -bus_space_write_region_4(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int32_t *a; -{ - for (; c; a++, c--, o+=4) - bus_space_write_4(t, h, o, *a); -} - -static __inline__ void -bus_space_write_region_8(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int64_t *a; -{ - for (; c; a++, c--, o+=8) - bus_space_write_8(t, h, o, *a); -} - - -/* - * void bus_space_set_region_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t off, - * u_intN_t *addr, bus_size_t count); - * - */ -static void bus_space_set_region_1(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int8_t, - bus_size_t); -static void bus_space_set_region_2(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int16_t, - bus_size_t); -static void bus_space_set_region_4(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int32_t, - bus_size_t); -static void bus_space_set_region_8(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int64_t, - bus_size_t); - -static __inline__ void -bus_space_set_region_1(t, h, o, v, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int8_t v; -{ - for (; c; c--, o++) - bus_space_write_1(t, h, o, v); -} - -static __inline__ void -bus_space_set_region_2(t, h, o, v, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int16_t v; -{ - for (; c; c--, o+=2) - bus_space_write_2(t, h, o, v); -} - -static __inline__ void -bus_space_set_region_4(t, h, o, v, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int32_t v; -{ - for (; c; c--, o+=4) - bus_space_write_4(t, h, o, v); -} - -static __inline__ void -bus_space_set_region_8(t, h, o, v, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int64_t v; -{ - for (; c; c--, o+=8) - bus_space_write_8(t, h, o, v); -} - - -/* - * void bus_space_copy_region_N(bus_space_tag_t tag, - * bus_space_handle_t bsh1, bus_size_t off1, - * bus_space_handle_t bsh2, bus_size_t off2, - * bus_size_t count); - * - * Copy `count' 1, 2, 4, or 8 byte values from bus space starting - * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. - */ -static void bus_space_copy_region_1(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - bus_space_handle_t, - bus_size_t, - bus_size_t); -static void bus_space_copy_region_2(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - bus_space_handle_t, - bus_size_t, - bus_size_t); -static void bus_space_copy_region_4(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - bus_space_handle_t, - bus_size_t, - bus_size_t); -static void bus_space_copy_region_8(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - bus_space_handle_t, - bus_size_t, - bus_size_t); - - -static __inline__ void -bus_space_copy_region_1(t, h1, o1, h2, o2, c) - bus_space_tag_t t; - bus_space_handle_t h1, h2; - bus_size_t o1, o2; - bus_size_t c; -{ - for (; c; c--, o1++, o2++) - bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2)); -} - -static __inline__ void -bus_space_copy_region_2(t, h1, o1, h2, o2, c) - bus_space_tag_t t; - bus_space_handle_t h1, h2; - bus_size_t o1, o2; - bus_size_t c; -{ - for (; c; c--, o1+=2, o2+=2) - bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2)); -} - -static __inline__ void -bus_space_copy_region_4(t, h1, o1, h2, o2, c) - bus_space_tag_t t; - bus_space_handle_t h1, h2; - bus_size_t o1, o2; - bus_size_t c; -{ - for (; c; c--, o1+=4, o2+=4) - bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2)); -} - -static __inline__ void -bus_space_copy_region_8(t, h1, o1, h2, o2, c) - bus_space_tag_t t; - bus_space_handle_t h1, h2; - bus_size_t o1, o2; - bus_size_t c; -{ - for (; c; c--, o1+=8, o2+=8) - bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2)); -} - -/* - * u_intN_t bus_space_read_stream_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t offset); - * - * Read a 1, 2, 4, or 8 byte quantity from bus space - * described by tag/handle/offset. - */ -#ifndef BUS_SPACE_DEBUG -#define bus_space_read_stream_1(t, h, o) \ - lduba((h) + (o), bus_stream_asi[(t)->type]) - -#define bus_space_read_stream_2(t, h, o) \ - lduha((h) + (o), bus_stream_asi[(t)->type]) - -#define bus_space_read_stream_4(t, h, o) \ - lda((h) + (o), bus_stream_asi[(t)->type]) - -#define bus_space_read_stream_8(t, h, o) \ - ldxa((h) + (o), bus_stream_asi[(t)->type]) -#else -#define bus_space_read_stream_1(t, h, o) ({ \ - unsigned char __bv = \ - lduba((h) + (o), bus_stream_asi[(t)->type]); \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsr1(%llx + %llx, %x) -> %x\n", (long long)(h), \ - (long long)(o), \ - bus_stream_asi[(t)->type], (unsigned int) __bv); \ - __bv; }) - -#define bus_space_read_stream_2(t, h, o) ({ \ - unsigned short __bv = \ - lduha((h) + (o), bus_stream_asi[(t)->type]); \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsr2(%llx + %llx, %x) -> %x\n", (long long)(h), \ - (long long)(o), \ - bus_stream_asi[(t)->type], (unsigned int)__bv); \ - __bv; }) - -#define bus_space_read_stream_4(t, h, o) ({ \ - unsigned int __bv = \ - lda((h) + (o), bus_stream_asi[(t)->type]); \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsr4(%llx + %llx, %x) -> %x\n", (long long)(h), \ - (long long)(o), \ - bus_stream_asi[(t)->type], __bv); \ - __bv; }) - -#define bus_space_read_stream_8(t, h, o) ({ \ - u_int64_t __bv = \ - ldxa((h) + (o), bus_stream_asi[(t)->type]); \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsr8(%llx + %llx, %x) -> %llx\n", (long long)(h), \ - (long long)(o), \ - bus_stream_asi[(t)->type], (long long)__bv); \ - __bv; }) -#endif -/* - * void bus_space_read_multi_stream_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t offset, - * u_intN_t *addr, size_t count); - * - * Read `count' 1, 2, 4, or 8 byte quantities from bus space - * described by tag/handle/offset and copy into buffer provided. - */ - -#define bus_space_read_multi_stream_1(t, h, o, a, c) do { \ - int i = c; \ - u_int8_t *p = (u_int8_t *)a; \ - while (i-- > 0) \ - *p++ = bus_space_read_stream_1(t, h, o); \ -} while (0) - -#define bus_space_read_multi_stream_2(t, h, o, a, c) do { \ - int i = c; \ - u_int16_t *p = (u_int16_t *)a; \ - while (i-- > 0) \ - *p++ = bus_space_read_stream_2(t, h, o); \ -} while (0) - -#define bus_space_read_multi_stream_4(t, h, o, a, c) do { \ - int i = c; \ - u_int32_t *p = (u_int32_t *)a; \ - while (i-- > 0) \ - *p++ = bus_space_read_stream_4(t, h, o); \ -} while (0) - -#define bus_space_read_multi_stream_8(t, h, o, a, c) do { \ - int i = c; \ - u_int64_t *p = (u_int64_t *)a; \ - while (i-- > 0) \ - *p++ = bus_space_read_stream_8(t, h, o); \ -} while (0) - -/* - * void bus_space_write_stream_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t offset, - * u_intN_t value); - * - * Write the 1, 2, 4, or 8 byte value `value' to bus space - * described by tag/handle/offset. - */ -#ifndef BUS_SPACE_DEBUG -#define bus_space_write_stream_1(t, h, o, v) \ - ((void)(stba((h) + (o), bus_stream_asi[(t)->type], (v)))) - -#define bus_space_write_stream_2(t, h, o, v) \ - ((void)(stha((h) + (o), bus_stream_asi[(t)->type], (v)))) - -#define bus_space_write_stream_4(t, h, o, v) \ - ((void)(sta((h) + (o), bus_stream_asi[(t)->type], (v)))) - -#define bus_space_write_stream_8(t, h, o, v) \ - ((void)(stxa((h) + (o), bus_stream_asi[(t)->type], (v)))) -#else -#define bus_space_write_stream_1(t, h, o, v) ({ \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsw1(%llx + %llx, %x) <- %x\n", (long long)(h), \ - (long long)(o), \ - bus_stream_asi[(t)->type], (unsigned int) v); \ - ((void)(stba((h) + (o), bus_stream_asi[(t)->type], (v)))); }) - -#define bus_space_write_stream_2(t, h, o, v) ({ \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsw2(%llx + %llx, %x) <- %x\n", (long long)(h), \ - (long long)(o), \ - bus_stream_asi[(t)->type], (unsigned int) v); \ - ((void)(stha((h) + (o), bus_stream_asi[(t)->type], (v)))); }) - -#define bus_space_write_stream_4(t, h, o, v) ({ \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsw4(%llx + %llx, %x) <- %x\n", (long long)(h), \ - (long long)(o), \ - bus_stream_asi[(t)->type], (unsigned int) v); \ - ((void)(sta((h) + (o), bus_stream_asi[(t)->type], (v)))); }) - -#define bus_space_write_stream_8(t, h, o, v) ({ \ - if (bus_space_debug & BSDB_ACCESS) \ - printf("bsw8(%llx + %llx, %x) <- %llx\n", (long long)(h), \ - (long long)(o), \ - bus_stream_asi[(t)->type], (long long) v); \ - ((void)(stxa((h) + (o), bus_stream_asi[(t)->type], (v)))); }) -#endif -/* - * void bus_space_write_multi_stream_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t offset, - * const u_intN_t *addr, size_t count); - * - * Write `count' 1, 2, 4, or 8 byte quantities from the buffer - * provided to bus space described by tag/handle/offset. - */ - -#define bus_space_write_multi_stream_1(t, h, o, a, c) do { \ - int i = c; \ - u_int8_t *p = (u_int8_t *)a; \ - while (i-- > 0) \ - bus_space_write_stream_1(t, h, o, *p++); \ -} while (0) - -#define bus_space_write_multi_stream_2(t, h, o, a, c) do { \ - int i = c; \ - u_int16_t *p = (u_int16_t *)a; \ - while (i-- > 0) \ - bus_space_write_stream_2(t, h, o, *p++); \ -} while (0) - -#define bus_space_write_multi_stream_4(t, h, o, a, c) do { \ - int i = c; \ - u_int32_t *p = (u_int32_t *)a; \ - while (i-- > 0) \ - bus_space_write_stream_4(t, h, o, *p++); \ -} while (0) - -#define bus_space_write_multi_stream_8(t, h, o, a, c) do { \ - int i = c; \ - u_int64_t *p = (u_int64_t *)a; \ - while (i-- > 0) \ - bus_space_write_stream_8(t, h, o, *p++); \ -} while (0) - -/* - * void bus_space_set_multi_stream_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, - * size_t count); - * - * Write the 1, 2, 4, or 8 byte value `val' to bus space described - * by tag/handle/offset `count' times. - */ - -#define bus_space_set_multi_stream_1(t, h, o, v, c) do { \ - int i = c; \ - while (i-- > 0) \ - bus_space_write_stream_1(t, h, o, v); \ -} while (0) - -#define bus_space_set_multi_stream_2(t, h, o, v, c) do { \ - int i = c; \ - while (i-- > 0) \ - bus_space_write_stream_2(t, h, o, v); \ -} while (0) - -#define bus_space_set_multi_stream_4(t, h, o, v, c) do { \ - int i = c; \ - while (i-- > 0) \ - bus_space_write_stream_4(t, h, o, v); \ -} while (0) - -#define bus_space_set_multi_stream_8(t, h, o, v, c) do { \ - int i = c; \ - while (i-- > 0) \ - bus_space_write_stream_8(t, h, o, v); \ -} while (0) - -/* - * void bus_space_read_region_stream_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t off, - * u_intN_t *addr, bus_size_t count); - * - */ -static void bus_space_read_region_stream_1(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - u_int8_t *, - bus_size_t); -static void bus_space_read_region_stream_2(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - u_int16_t *, - bus_size_t); -static void bus_space_read_region_stream_4(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - u_int32_t *, - bus_size_t); -static void bus_space_read_region_stream_8(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - u_int64_t *, - bus_size_t); - -static __inline__ void -bus_space_read_region_stream_1(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - u_int8_t *a; -{ - for (; c; a++, c--, o++) - *a = bus_space_read_stream_1(t, h, o); -} -static __inline__ void -bus_space_read_region_stream_2(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - u_int16_t *a; -{ - for (; c; a++, c--, o+=2) - *a = bus_space_read_stream_2(t, h, o); - } -static __inline__ void -bus_space_read_region_stream_4(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - u_int32_t *a; -{ - for (; c; a++, c--, o+=4) - *a = bus_space_read_stream_4(t, h, o); -} -static __inline__ void -bus_space_read_region_stream_8(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - u_int64_t *a; -{ - for (; c; a++, c--, o+=8) - *a = bus_space_read_stream_8(t, h, o); -} - -/* - * void bus_space_write_region_stream_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t off, - * u_intN_t *addr, bus_size_t count); - * - */ -static void bus_space_write_region_stream_1(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int8_t *, - bus_size_t); -static void bus_space_write_region_stream_2(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int16_t *, - bus_size_t); -static void bus_space_write_region_stream_4(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int32_t *, - bus_size_t); -static void bus_space_write_region_stream_8(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int64_t *, - bus_size_t); -static __inline__ void -bus_space_write_region_stream_1(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int8_t *a; -{ - for (; c; a++, c--, o++) - bus_space_write_stream_1(t, h, o, *a); -} - -static __inline__ void -bus_space_write_region_stream_2(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int16_t *a; -{ - for (; c; a++, c--, o+=2) - bus_space_write_stream_2(t, h, o, *a); -} - -static __inline__ void -bus_space_write_region_stream_4(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int32_t *a; -{ - for (; c; a++, c--, o+=4) - bus_space_write_stream_4(t, h, o, *a); -} - -static __inline__ void -bus_space_write_region_stream_8(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int64_t *a; -{ - for (; c; a++, c--, o+=8) - bus_space_write_stream_8(t, h, o, *a); -} - - -/* - * void bus_space_set_region_stream_N(bus_space_tag_t tag, - * bus_space_handle_t bsh, bus_size_t off, - * u_intN_t *addr, bus_size_t count); - * - */ -static void bus_space_set_region_stream_1(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int8_t, - bus_size_t); -static void bus_space_set_region_stream_2(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int16_t, - bus_size_t); -static void bus_space_set_region_stream_4(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int32_t, - bus_size_t); -static void bus_space_set_region_stream_8(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - const u_int64_t, - bus_size_t); - -static __inline__ void -bus_space_set_region_stream_1(t, h, o, v, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int8_t v; -{ - for (; c; c--, o++) - bus_space_write_stream_1(t, h, o, v); -} - -static __inline__ void -bus_space_set_region_stream_2(t, h, o, v, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int16_t v; -{ - for (; c; c--, o+=2) - bus_space_write_stream_2(t, h, o, v); -} - -static __inline__ void -bus_space_set_region_stream_4(t, h, o, v, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int32_t v; -{ - for (; c; c--, o+=4) - bus_space_write_stream_4(t, h, o, v); -} - -static __inline__ void -bus_space_set_region_stream_8(t, h, o, v, c) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t o, c; - const u_int64_t v; -{ - for (; c; c--, o+=8) - bus_space_write_stream_8(t, h, o, v); -} - - -/* - * void bus_space_copy_region_stream_N(bus_space_tag_t tag, - * bus_space_handle_t bsh1, bus_size_t off1, - * bus_space_handle_t bsh2, bus_size_t off2, - * bus_size_t count); - * - * Copy `count' 1, 2, 4, or 8 byte values from bus space starting - * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. - */ -static void bus_space_copy_region_stream_1(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - bus_space_handle_t, - bus_size_t, - bus_size_t); -static void bus_space_copy_region_stream_2(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - bus_space_handle_t, - bus_size_t, - bus_size_t); -static void bus_space_copy_region_stream_4(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - bus_space_handle_t, - bus_size_t, - bus_size_t); -static void bus_space_copy_region_stream_8(bus_space_tag_t, - bus_space_handle_t, - bus_size_t, - bus_space_handle_t, - bus_size_t, - bus_size_t); - - -static __inline__ void -bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) - bus_space_tag_t t; - bus_space_handle_t h1, h2; - bus_size_t o1, o2; - bus_size_t c; -{ - for (; c; c--, o1++, o2++) - bus_space_write_stream_1(t, h1, o1, bus_space_read_stream_1(t, h2, o2)); -} - -static __inline__ void -bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) - bus_space_tag_t t; - bus_space_handle_t h1, h2; - bus_size_t o1, o2; - bus_size_t c; -{ - for (; c; c--, o1+=2, o2+=2) - bus_space_write_stream_2(t, h1, o1, bus_space_read_stream_2(t, h2, o2)); -} - -static __inline__ void -bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) - bus_space_tag_t t; - bus_space_handle_t h1, h2; - bus_size_t o1, o2; - bus_size_t c; -{ - for (; c; c--, o1+=4, o2+=4) - bus_space_write_stream_4(t, h1, o1, bus_space_read_stream_4(t, h2, o2)); -} - -static __inline__ void -bus_space_copy_region_stream_8(t, h1, o1, h2, o2, c) - bus_space_tag_t t; - bus_space_handle_t h1, h2; - bus_size_t o1, o2; - bus_size_t c; -{ - for (; c; c--, o1+=8, o2+=8) - bus_space_write_stream_8(t, h1, o1, bus_space_read_8(t, h2, o2)); -} - -/* OpenBSD "raw" wrappers around the NetBSD "stream" methods. */ -/* XXXART - I'm lazy so I'll only implement the ones I need. */ -#define BUS_DMA_RAW BUS_DMA_STREAMING -#define bus_space_read_raw_multi_2(t, h, o, a, c) \ - bus_space_read_multi_stream_2(t, h, o, (u_int8_t *)(a), c/2) -#define bus_space_write_raw_multi_2(t, h, o, a, c) \ - bus_space_write_multi_stream_2(t, h, o, (u_int8_t *)(a), c/2) -#define bus_space_read_raw_multi_4(t, h, o, a, c) \ - bus_space_read_multi_stream_4(t, h, o, (u_int8_t *)(a), c/4) -#define bus_space_write_raw_multi_4(t, h, o, a, c) \ - bus_space_write_multi_stream_4(t, h, o, (u_int8_t *)(a), c/4) - #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) /* @@ -1432,6 +377,8 @@ bus_space_copy_region_stream_8(t, h1, o1, h2, o2, c) #define BUS_DMA_DVMA BUS_DMA_BUS2 /* Don't bother with alignment */ #define BUS_DMA_24BIT BUS_DMA_BUS3 /* 24bit device */ +#define BUS_DMA_RAW BUS_DMA_STREAMING + /* Forwards needed by prototypes below. */ struct mbuf; struct uio; @@ -1605,3 +552,4 @@ int _bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size, #endif /* _SPARC_BUS_DMA_PRIVATE */ #endif /* _SPARC_BUS_H_ */ + diff --git a/sys/arch/sparc64/include/ctlreg.h b/sys/arch/sparc64/include/ctlreg.h index c6ffe50060b..c592f3aff9a 100644 --- a/sys/arch/sparc64/include/ctlreg.h +++ b/sys/arch/sparc64/include/ctlreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ctlreg.h,v 1.7 2002/06/15 17:23:31 art Exp $ */ +/* $OpenBSD: ctlreg.h,v 1.8 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: ctlreg.h,v 1.28 2001/08/06 23:55:34 eeh Exp $ */ /* @@ -23,6 +23,32 @@ * SUCH DAMAGE. * */ +/* + * Copyright (c) 2001 Jake Burkholder. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + /* * Sun 4u control registers. (includes address space definitions @@ -30,6 +56,48 @@ */ /* + * membar operand macros for use in other macros when # is a special + * character. Keep these in sync with what the hardware expects. + */ +#define C_Lookaside (0) +#define C_MemIssue (1) +#define C_Sync (2) +#define M_LoadLoad (0) +#define M_StoreLoad (1) +#define M_LoadStore (2) +#define M_StoreStore (3) + +#define CMASK_SHIFT (4) +#define MMASK_SHIFT (0) + +#define CMASK_GEN(bit) ((1 << (bit)) << CMASK_SHIFT) +#define MMASK_GEN(bit) ((1 << (bit)) << MMASK_SHIFT) + +#ifndef __ASSEMBLER__ +#define Lookaside CMASK_GEN(C_Lookaside) +#define MemIssue CMASK_GEN(C_MemIssue) +#define Sync CMASK_GEN(C_Sync) +#define LoadLoad MMASK_GEN(M_LoadLoad) +#define StoreLoad MMASK_GEN(M_StoreLoad) +#define LoadStore MMASK_GEN(M_LoadStore) +#define StoreStore MMASK_GEN(M_StoreStore) +#endif + +#define casa(rs1, rs2, rd, asi) ({ \ + u_int __rd = (u_int32_t)(rd); \ + __asm __volatile("casa [%1] %2, %3, %0" \ + : "+r" (__rd) : "r" (rs1), "n" (asi), "r" (rs2)); \ + __rd; \ +}) + +#define casxa(rs1, rs2, rd, asi) ({ \ + u_long __rd = (u_int64_t)(rd); \ + __asm __volatile("casxa [%1] %2, %3, %0" \ + : "+r" (__rd) : "r" (rs1), "n" (asi), "r" (rs2)); \ + __rd; \ +}) + +/* * The Alternate address spaces. * * 0x00-0x7f are privileged @@ -179,7 +247,7 @@ #define ASI_SECONDARY_NO_FAULT ASI_SECONDARY_NOFAULT #define ASI_SECONDARY_NO_FAULT_LITTLE ASI_SECONDARY_NOFAULT_LITTLE -#define PHYS_ASI(x) (((x) | 0x08) == 0x1c) +#define PHYS_ASI(x) (((x) | 0x09) == 0x1d) #define LITTLE_ASI(x) ((x) & ASI_LITTLE) /* @@ -453,257 +521,193 @@ * D$ so we need to flush the D$ to make sure we don't get data pollution. */ -static __inline__ u_char lduba(paddr_t loc, int asi); -static __inline__ u_short lduha(paddr_t loc, int asi); -static __inline__ u_int lda(paddr_t loc, int asi); -static __inline__ int ldswa(paddr_t loc, int asi); -static __inline__ u_int64_t ldxa(paddr_t loc, int asi); -static __inline__ u_int64_t ldda(paddr_t loc, int asi); - -static __inline__ void stba(paddr_t loc, int asi, u_char value); -static __inline__ void stha(paddr_t loc, int asi, u_short value); -static __inline__ void sta(paddr_t loc, int asi, u_int value); -static __inline__ void stxa(paddr_t loc, int asi, u_int64_t value); -static __inline__ void stda(paddr_t loc, int asi, u_int64_t value); - -#if 0 -static __inline__ unsigned int casa(paddr_t loc, int asi, - unsigned int value, unsigned int oldvalue); -static __inline__ u_int64_t casxa(paddr_t loc, int asi, - u_int64_t value, u_int64_t oldvalue); +/* Generate ld*a/st*a functions for non-constant ASI's. */ +#define LDNC_GEN(tp, o) \ + extern __inline tp o ## _nc(paddr_t, int); \ + extern __inline tp \ + o ## _nc(paddr_t va, int asi) \ + { \ + tp r; \ + __asm __volatile( \ + "wr %2, 0, %%asi;" #o " [%1] %%asi, %0" \ + : "=r" (r) \ + : "r" ((volatile tp *)va), "r" (asi)); \ + return (r); \ + } \ + extern __inline tp o ## _asi(paddr_t); \ + extern __inline tp \ + o ## _asi(paddr_t va) \ + { \ + tp r; \ + __asm __volatile( \ + #o " [%1] %%asi, %0" \ + : "=r" (r) \ + : "r" ((volatile tp *)va)); \ + return (r); \ + } + +LDNC_GEN(u_char, lduba); +LDNC_GEN(u_short, lduha); +LDNC_GEN(u_int, lduwa); +LDNC_GEN(u_int64_t, ldxa); + +LDNC_GEN(int, lda); + +#define LDC_GEN(va, asi, op, opa, type) ({ \ + type __r ## op ## type; \ + if(asi == ASI_PRIMARY || \ + (sizeof(type) == 1 && asi == ASI_PRIMARY_LITTLE)) \ + __r ## op ## type = *((volatile type *)va); \ + /*__asm __volatile(#op " [%1], %0" \ + : "=r" (__r ## op ## type) : "r" (va));*/ \ + else \ + __asm __volatile(#opa " [%1] " #asi ", %0" \ + : "=r" (__r ## op ## type) \ + : "r" ((volatile type *)va)); \ + __r ## op ## type; \ +}) + +#ifdef __OPTIMIZE__ +#define LD_GENERIC(va, asi, op, type) (__builtin_constant_p(asi) ? \ + LDC_GEN(va, asi, op, op ## a, type) : op ## a_nc(va, asi)) +#else +#define LD_GENERIC(va, asi, op, type) (op ## a_nc(va, asi)) #endif -static __inline__ u_char -lduba(paddr_t loc, int asi) -{ - register unsigned int _lduba_v; - - if (PHYS_ASI(asi)) { - __asm __volatile("wr %3,%%g0,%%asi; " -" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; " -" lduba [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; " -" stxa %%g0,[%1] %4; membar #Sync; wr %%g0, 0x82, %%asi" : - "=&r" (_lduba_v), "=r" (loc): - "r" ((unsigned long)(loc)), - "r" (asi), "n" (ASI_DCACHE_TAG)); - } else { - __asm __volatile("wr %2,%%g0,%%asi; " -" lduba [%1]%%asi,%0; wr %%g0, 0x82, %%asi" : - "=r" (_lduba_v) : - "r" ((unsigned long)(loc)), "r" (asi)); +#define lduba(va, asi) LD_GENERIC(va, asi, ldub, u_char) +#define lduha(va, asi) LD_GENERIC(va, asi, lduh, u_short) +#define lduwa(va, asi) LD_GENERIC(va, asi, lduw, u_int) +#define ldxa(va, asi) LD_GENERIC(va, asi, ldx, u_int64_t) + +#define ldua(va, asi) LD_GENERIC(va, asi, ldu, u_int) +#define lda(va, asi) LD_GENERIC(va, asi, ld, int) + +#define STNC_GEN(tp, o) \ + extern __inline void o ## _nc(paddr_t, int, tp); \ + extern __inline void \ + o ## _nc(paddr_t va, int asi, tp val) \ + { \ + __asm __volatile( \ + "wr %2, 0, %%asi;" #o " %0, [%1] %%asi" \ + : \ + : "r" (val), "r" ((volatile tp *)va), "r" (asi)); \ + } \ + extern __inline void o ## _asi(paddr_t, tp); \ + extern __inline void \ + o ## _asi(paddr_t va, tp val) \ + { \ + __asm __volatile( \ + #o " %0, [%1] %%asi" \ + : \ + : "r" (val), "r" ((volatile tp *)va) ); \ } - return (_lduba_v); -} -/* load half-word from alternate address space */ -static __inline__ u_short -lduha(paddr_t loc, int asi) -{ - register unsigned int _lduha_v; - - if (PHYS_ASI(asi)) { - __asm __volatile("wr %3,%%g0,%%asi; " -" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; " -" lduha [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; " -" stxa %%g0,[%1] %4; membar #Sync; " -" wr %%g0, 0x82, %%asi" : "=&r" (_lduha_v), "=r" (loc) : - "r" ((unsigned long)(loc)), - "r" (asi), "n" (ASI_DCACHE_TAG)); - } else { - __asm __volatile("wr %2,%%g0,%%asi; lduha [%1]%%asi,%0; " -" wr %%g0, 0x82, %%asi" : - "=r" (_lduha_v) : - "r" ((unsigned long)(loc)), "r" (asi)); - } - return (_lduha_v); -} +STNC_GEN(u_char, stba); +STNC_GEN(u_short, stha); +STNC_GEN(u_int, stwa); +STNC_GEN(u_int64_t, stxa); + +STNC_GEN(u_int, sta); + +#define STC_GEN(va, asi, val, op, opa, type) ({ \ + if(asi == ASI_PRIMARY || \ + (sizeof(type) == 1 && asi == ASI_PRIMARY_LITTLE)) \ + *((volatile type *)va) = val; \ + /*__asm __volatile(#op " %0, [%1] " \ + : : "r" (val), "r" ((volatile type *)va));*/ \ + else \ + __asm __volatile(#opa " %0, [%1] " #asi \ + : : "r" (val), "r" ((volatile type *)va)); \ + }) + +#ifdef __OPTIMIZE__ +#define ST_GENERIC(va, asi, val, op, type) (__builtin_constant_p(asi) ? \ + STC_GEN(va, asi, val, op, op ## a, type) : op ## a_nc(va, asi, val)) +#else +#define ST_GENERIC(va, asi, val, op, type) (op ## a_nc(va, asi, val)) +#endif -/* load unsigned int from alternate address space */ -static __inline__ u_int -lda(paddr_t loc, int asi) -{ - register unsigned int _lda_v; - - if (PHYS_ASI(asi)) { - __asm __volatile("wr %3,%%g0,%%asi; " -" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; " -" lda [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; " -" stxa %%g0,[%1] %4; membar #Sync; " -" wr %%g0, 0x82, %%asi" : "=&r" (_lda_v), "=r" (loc) : - "r" ((unsigned long)(loc)), - "r" (asi), "n" (ASI_DCACHE_TAG)); - } else { - __asm __volatile("wr %2,%%g0,%%asi; lda [%1]%%asi,%0" : - "=r" (_lda_v) : - "r" ((unsigned long)(loc)), "r" (asi)); - } - return (_lda_v); -} +#define stba(va, asi, val) ST_GENERIC(va, asi, val, stb, u_int8_t) +#define stha(va, asi, val) ST_GENERIC(va, asi, val, sth, u_int16_t) +#define stwa(va, asi, val) ST_GENERIC(va, asi, val, stw, u_int32_t) +#define stxa(va, asi, val) ST_GENERIC(va, asi, val, stx, u_int64_t) -/* load signed int from alternate address space */ -static __inline__ int -ldswa(paddr_t loc, int asi) -{ - register int _lda_v; - - if (PHYS_ASI(asi)) { - __asm __volatile("wr %3,%%g0,%%asi; " -" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; " -" ldswa [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; " -" stxa %%g0,[%1] %4; membar #Sync; " -" wr %%g0, 0x82, %%asi" : "=&r" (_lda_v), "=r" (loc) : - "r" ((unsigned long)(loc)), - "r" (asi), "n" (ASI_DCACHE_TAG)); - } else { - __asm __volatile("wr %2,%%g0,%%asi; " -" ldswa [%1]%%asi,%0; wr %%g0, 0x82, %%asi" : - "=r" (_lda_v) : - "r" ((unsigned long)(loc)), "r" (asi)); - } - return (_lda_v); -} +#define sta(va, asi, val) ST_GENERIC(va, asi, val, st, u_int) -/* load 64-bit int from alternate address space -- these should never be used */ -static __inline__ u_int64_t -ldda(paddr_t loc, int asi) -{ - register long long _lda_v; - - if (PHYS_ASI(asi)) { - __asm __volatile("wr %3,%%g0,%%asi; " -" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; " -" ldda [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; " -" stxa %%g0,[%1] %4; membar #Sync; " -" wr %%g0, 0x82, %%asi" : "=&r" (_lda_v), "=&r" (loc) : - "r" ((unsigned long)(loc)), - "r" (asi), "n" (ASI_DCACHE_TAG)); - } else { - __asm __volatile("wr %2,%%g0,%%asi; " -" ldda [%1]%%asi,%0; wr %%g0, 0x82, %%asi" : - "=r" (_lda_v) : - "r" ((unsigned long)(loc)), "r" (asi)); - } - return (_lda_v); -} +#define membar(mask) do { \ + __asm __volatile("membar %0" : : "n" (mask) : "memory"); \ +} while (0) -/* native load 64-bit int from alternate address space w/64-bit compiler*/ -static __inline__ u_int64_t -ldxa(paddr_t loc, int asi) -{ - register unsigned long _lda_v; - - if (PHYS_ASI(asi)) { - __asm __volatile("wr %3,%%g0,%%asi; " -" andn %2,0x1f,%0; stxa %%g0,[%0] %4; membar #Sync; " -" ldxa [%2]%%asi,%0; andn %2,0x1f,%1; membar #Sync; " -" stxa %%g0,[%1] %4; membar #Sync; " -" wr %%g0, 0x82, %%asi" : "=&r" (_lda_v), "=r" (loc) : - "r" ((unsigned long)(loc)), - "r" (asi), "n" (ASI_DCACHE_TAG)); - } else { - __asm __volatile("wr %2,%%g0,%%asi; " -" ldxa [%1]%%asi,%0; wr %%g0, 0x82, %%asi" : - "=r" (_lda_v) : - "r" ((unsigned long)(loc)), "r" (asi)); - } - return (_lda_v); -} +#define rd(name) ({ \ + u_int64_t __sr; \ + __asm __volatile("rd %%" #name ", %0" : "=r" (__sr) :); \ + __sr; \ +}) -/* store byte to alternate address space */ -static __inline__ void -stba(paddr_t loc, int asi, u_char value) -{ - if (PHYS_ASI(asi)) { - __asm __volatile("wr %3,%%g0,%%asi; stba %1,[%2]%%asi;" -" andn %2,0x1f,%0; membar #Sync; stxa %%g0,[%0] %4; membar #Sync; " -" wr %%g0, 0x82, %%asi" : - "=&r" (loc) : - "r" ((int)(value)), "r" ((unsigned long)(loc)), - "r" (asi), "n" (ASI_DCACHE_TAG)); - } else { - __asm __volatile("wr %2,%%g0,%%asi; stba %0,[%1]%%asi; " -" wr %%g0, 0x82, %%asi" : : - "r" ((int)(value)), "r" ((unsigned long)(loc)), - "r" (asi)); - } -} +#define wr(name, val, xor) do { \ + __asm __volatile("wr %0, %1, %%" #name \ + : : "r" (val), "rI" (xor)); \ +} while (0) -/* store half-word to alternate address space */ -static __inline__ void -stha(paddr_t loc, int asi, u_short value) -{ - if (PHYS_ASI(asi)) { - __asm __volatile("wr %3,%%g0,%%asi; stha %1,[%2]%%asi;" -" andn %2,0x1f,%0; membar #Sync; stxa %%g0,[%0] %4; membar #Sync; " -" wr %%g0, 0x82, %%asi" : - "=&r" (loc) : - "r" ((int)(value)), "r" ((unsigned long)(loc)), - "r" (asi), "n" (ASI_DCACHE_TAG) : "memory"); - } else { - __asm __volatile("wr %2,%%g0,%%asi; stha %0,[%1]%%asi; " -" wr %%g0, 0x82, %%asi" : : - "r" ((int)(value)), "r" ((unsigned long)(loc)), - "r" (asi) : "memory"); - } -} +#define rdpr(name) ({ \ + u_int64_t __pr; \ + __asm __volatile("rdpr %%" #name", %0" : "=r" (__pr) :); \ + __pr; \ +}) -/* store int to alternate address space */ -static __inline__ void -sta(paddr_t loc, int asi, u_int value) +#define wrpr(name, val, xor) do { \ + __asm __volatile("wrpr %0, %1, %%" #name \ + : : "r" (val), "rI" (xor)); \ +} while (0) + +extern __inline void asi_set(int); +extern __inline +void asi_set(int asi) { - if (PHYS_ASI(asi)) { - __asm __volatile("wr %3,%%g0,%%asi; sta %1,[%2]%%asi;" -" andn %2,0x1f,%0; membar #Sync; stxa %%g0,[%0] %4; membar #Sync; " -" wr %%g0, 0x82, %%asi" : - "=&r" (loc) : - "r" ((int)(value)), "r" ((unsigned long)(loc)), - "r" (asi), "n" (ASI_DCACHE_TAG) : "memory"); - } else { - __asm __volatile("wr %2,%%g0,%%asi; sta %0,[%1]%%asi; " -" wr %%g0, 0x82, %%asi" : : - "r" ((int)(value)), "r" ((unsigned long)(loc)), - "r" (asi) : "memory"); - } + wr(asi, asi, 0); } -/* store 64-bit int to alternate address space */ -static __inline__ void -stda(paddr_t loc, int asi, u_int64_t value) +extern __inline u_int8_t asi_get(void); +extern __inline +u_int8_t asi_get() { - if (PHYS_ASI(asi)) { - __asm __volatile("wr %3,%%g0,%%asi; stda %1,[%2]%%asi;" -" andn %2,0x1f,%0; membar #Sync; stxa %%g0,[%0] %4; membar #Sync; " -" wr %%g0, 0x82, %%asi" : - "=&r" (loc) : - "r" ((long long)(value)), "r" ((unsigned long)(loc)), - "r" (asi), "n" (ASI_DCACHE_TAG) : "memory"); - } else { - __asm __volatile("wr %2,%%g0,%%asi; stda %0,[%1]%%asi; " -" wr %%g0, 0x82, %%asi" : : - "r" ((long long)(value)), "r" ((unsigned long)(loc)), - "r" (asi) : "memory"); - } + return rd(asi); } -/* native store 64-bit int to alternate address space w/64-bit compiler*/ -static __inline__ void -stxa(paddr_t loc, int asi, u_int64_t value) + +static __inline u_long +intr_disable(void) { - if (PHYS_ASI(asi)) { - __asm __volatile("wr %3,%%g0,%%asi; stxa %1,[%2]%%asi;" -" andn %2,0x1f,%0; membar #Sync; stxa %%g0,[%0] %4; membar #Sync; " -" wr %%g0, 0x82, %%asi" : - "=&r" (asi) : - "r" ((unsigned long)(value)), - "r" ((unsigned long)(loc)), - "r" (asi), "n" (ASI_DCACHE_TAG) : "memory"); - } else { - __asm __volatile("wr %2,%%g0,%%asi; stxa %0,[%1]%%asi; " -" wr %%g0, 0x82, %%asi" : : - "r" ((unsigned long)(value)), - "r" ((unsigned long)(loc)), "r" (asi) : "memory"); - } + u_long s; + + s = rdpr(pstate); + wrpr(pstate, s & ~PSTATE_IE, 0); + return (s); } +#define intr_restore(s) wrpr(pstate, (s), 0) + +/* + * In some places, it is required that the store is directly followed by a + * membar #Sync. Don't trust the compiler to not insert instructions in + * between. We also need to disable interrupts completely. + */ +#define stxa_sync(va, asi, val) do { \ + u_long stxa_sync_s; \ + stxa_sync_s = intr_disable(); \ + if(PHYS_ASI(asi)) { \ + __asm __volatile( \ + "stxa %g0, [%0] #ASI_DCACHE_TAG; membar #Sync" \ + : : "r" (va & ~0x1f)); \ + } \ + __asm __volatile("stxa %0, [%1] %2; membar #Sync" \ + : : "r" (val), "r" (va), "n" (asi)); \ + if(PHYS_ASI(asi)) { \ + __asm __volatile( \ + "stxa %g0, [%0] #ASI_DCACHE_TAG; membar #Sync" \ + : : "r" (va & ~0x1f)); \ + } \ + intr_restore(stxa_sync_s); \ +} while (0) /* flush address from data cache */ #define flush(loc) ({ \ @@ -711,16 +715,6 @@ stxa(paddr_t loc, int asi, u_int64_t value) "r" ((unsigned long)(loc))); \ }) -/* Flush a D$ line */ -#if 0 -#define flushline(loc) ({ \ - stxa(((paddr_t)loc)&(~0x1f), (ASI_DCACHE_TAG), 0); \ - membar_sync(); \ -}) -#else -#define flushline(loc) -#endif - /* The following two enable or disable the dcache in the LSU control register */ #define dcenable() ({ \ int res; \ @@ -737,19 +731,19 @@ stxa(paddr_t loc, int asi, u_int64_t value) * SPARC V9 memory barrier instructions. */ /* Make all stores complete before next store */ -#define membar_storestore() __asm __volatile("membar #StoreStore" : :) +#define membar_storestore() membar(StoreStore) /* Make all loads complete before next store */ -#define membar_loadstore() __asm __volatile("membar #LoadStore" : :) +#define membar_loadstore() membar(LoadStore) /* Make all stores complete before next load */ -#define membar_storeload() __asm __volatile("membar #StoreLoad" : :) +#define membar_storeload() membar(StoreLoad) /* Make all loads complete before next load */ -#define membar_loadload() __asm __volatile("membar #LoadLoad" : :) +#define membar_loadload() membar(LoadLoad) /* Complete all outstanding memory operations and exceptions */ -#define membar_sync() __asm __volatile("membar #Sync" : :) +#define membar_sync() membar(Sync) /* Complete all outstanding memory operations */ -#define membar_memissue() __asm __volatile("membar #MemIssue" : :) +#define membar_memissue() membar(MemIssue) /* Complete all outstanding stores before any new loads */ -#define membar_lookaside() __asm __volatile("membar #Lookaside" : :) +#define membar_lookaside() membar(Lookaside) /* read 64-bit %tick register */ #define tick() ({ \ diff --git a/sys/arch/sparc64/include/frame.h b/sys/arch/sparc64/include/frame.h index 560db9c3010..cff65de71d4 100644 --- a/sys/arch/sparc64/include/frame.h +++ b/sys/arch/sparc64/include/frame.h @@ -1,4 +1,4 @@ -/* $OpenBSD: frame.h,v 1.2 2001/08/20 20:23:52 jason Exp $ */ +/* $OpenBSD: frame.h,v 1.3 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: frame.h,v 1.9 2001/03/04 09:28:35 mrg Exp $ */ /* @@ -45,6 +45,9 @@ * @(#)frame.h 8.1 (Berkeley) 6/11/93 */ +#ifndef _SPARC64_FRAME_H_ +#define _SPARC64_FRAME_H_ + /* * Sparc stack frame format. * @@ -133,3 +136,4 @@ struct frame64 { */ #define BIAS (2048-1) +#endif /* _SPARC64_FRAME_H_ */ diff --git a/sys/arch/sparc64/include/pci_machdep.h b/sys/arch/sparc64/include/pci_machdep.h index 40e1177ef00..e4ec48540ac 100644 --- a/sys/arch/sparc64/include/pci_machdep.h +++ b/sys/arch/sparc64/include/pci_machdep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_machdep.h,v 1.10 2003/01/13 16:04:38 jason Exp $ */ +/* $OpenBSD: pci_machdep.h,v 1.11 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: pci_machdep.h,v 1.7 2001/07/20 00:07:14 eeh Exp $ */ /* @@ -70,8 +70,8 @@ typedef u_int64_t pcitag_t; struct sparc_pci_chipset { void *cookie; /* psycho_pbm, but sssh! */ - pcireg_t (*conf_read)(pci_chipset_tag_t, pcitag_t, int); - void (*conf_write)(pci_chipset_tag_t, pcitag_t, int, pcireg_t); + bus_space_tag_t bustag; + bus_space_handle_t bushandle; int rootnode; /* PCI controller */ int curnode; /* Current OFW node */ diff --git a/sys/arch/sparc64/sparc64/Makefile b/sys/arch/sparc64/sparc64/Makefile new file mode 100644 index 00000000000..7319a75d90f --- /dev/null +++ b/sys/arch/sparc64/sparc64/Makefile @@ -0,0 +1,9 @@ +# $OpenBSD: Makefile,v 1.1 2003/02/17 01:29:20 henric Exp $ + +DEP= busop.awk busop_h.in busop_c.in +OBJS= busop.h busop.c + +${OBJS}: ${DEP} + awk -f busop.awk < busop_h.in > busop.h + awk -f busop.awk < busop_c.in > busop.c + diff --git a/sys/arch/sparc64/sparc64/autoconf.c b/sys/arch/sparc64/sparc64/autoconf.c index 6daa9e3f151..4bd3a3e7f09 100644 --- a/sys/arch/sparc64/sparc64/autoconf.c +++ b/sys/arch/sparc64/sparc64/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.29 2002/11/20 04:26:44 jason Exp $ */ +/* $OpenBSD: autoconf.c,v 1.30 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: autoconf.c,v 1.51 2001/07/24 19:32:11 eeh Exp $ */ /* @@ -1005,7 +1005,7 @@ mainbus_attach(parent, dev, aux) void *aux; { extern struct sparc_bus_dma_tag mainbus_dma_tag; -extern struct sparc_bus_space_tag mainbus_space_tag; +extern bus_space_tag_t mainbus_space_tag; struct mainbus_attach_args ma; char buf[32]; @@ -1061,7 +1061,7 @@ extern struct sparc_bus_space_tag mainbus_space_tag; continue; if (strcmp(buf, "cpu") == 0) { bzero(&ma, sizeof(ma)); - ma.ma_bustag = &mainbus_space_tag; + ma.ma_bustag = mainbus_space_tag; ma.ma_dmatag = &mainbus_dma_tag; ma.ma_node = node; ma.ma_name = "cpu"; @@ -1103,7 +1103,7 @@ extern struct sparc_bus_space_tag mainbus_space_tag; continue; /* an "early" device already configured */ bzero(&ma, sizeof ma); - ma.ma_bustag = &mainbus_space_tag; + ma.ma_bustag = mainbus_space_tag; ma.ma_dmatag = &mainbus_dma_tag; ma.ma_name = buf; ma.ma_node = node; diff --git a/sys/arch/sparc64/sparc64/busop.awk b/sys/arch/sparc64/sparc64/busop.awk new file mode 100644 index 00000000000..7214a7eb018 --- /dev/null +++ b/sys/arch/sparc64/sparc64/busop.awk @@ -0,0 +1,106 @@ +#! /usr/bin/awk -f +# $OpenBSD: busop.awk,v 1.1 2003/02/17 01:29:20 henric Exp $ +# +# Copyright (c) 2003 Henric Jungheim +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +function generate_code(text, lines, key2, value2) { + for(r in row) { + print "/*" + print " * Implementing", value[r,"<TYPE>"] + print " */" + print + for(i = 1; i <= lines; ++i) { + out = text[i]; + for(k in key) + gsub(key[k], value[r,key[k]], out); + for(k in key2) + gsub(key2[k], value2[key2[k]], out); + + print out; + } + } +} + +BEGIN { + lines = 1; + raw_lines = 1; + split("<NUM> <TYPE> <FMT> <LOAD> <STORE>", key); + n = split( \ + "1,u_int8_t,%2.2x,lduba,stba;" \ + "2,u_int16_t,%4.4x,lduha,stha;" \ + "4,u_int32_t,%8.8x,lduwa,stwa;" \ + "8,u_int64_t,%16.16llx,ldxa,stxa", row, ";"); + for(r in row) { + if(split(row[r], tmp, ",") != length(key)) { + print "bad column at ", r; + print "row =", row[r]; + exit; + } + for(k in key) + value[r,key[k]] = tmp[k]; + delete tmp; + } + print "/*" + print " * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT." + print " */" + print +} + +match($0, "^ECHO:") { + print substr($0, RLENGTH + 1); + next; +} + +match($0, "^NRAW:") { + text[lines] = substr($0, RLENGTH + 1); + lines++; + next; +} + +match($0, "^RAW:") { + raw_text[raw_lines] = substr($0, RLENGTH + 1); + raw_lines++; + next; +} + +{ + text[lines] = $0; + lines++; + raw_text[raw_lines] = $0; + raw_lines++; +} + +END { + k2[1] = "<RAW>"; k2[2] = "<ASI>"; + v2[k2[1]] = ""; + v2[k2[2]] = "asi"; + generate_code(text, lines, k2, v2); + v2[k2[1]] = "raw_"; + v2[k2[2]] = "sasi"; + generate_code(raw_text, raw_lines, k2, v2); +} + diff --git a/sys/arch/sparc64/sparc64/busop.c b/sys/arch/sparc64/sparc64/busop.c new file mode 100644 index 00000000000..e52d82ada97 --- /dev/null +++ b/sys/arch/sparc64/sparc64/busop.c @@ -0,0 +1,1315 @@ +/* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/* $OpenBSD: busop.c,v 1.1 2003/02/17 01:29:20 henric Exp $ */ + +/* + * Copyright (c) 2003 Henric Jungheim + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> + +#include <machine/bus.h> + +/* + * Implementing u_int16_t + */ + + +void +bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + u_int16_t *a, bus_size_t c) +{ + u_int16_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bsrm2(%llx + %llx, %x, %x) ->", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) { + u_int16_t r = lduha_asi(h.bh_ptr + o); + BUS_SPACE_TRACE(t, h, (" %4.4x", r)); + *p++ = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const u_int16_t *a, bus_size_t c) +{ + const u_int16_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bswm2(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) { + u_int16_t r = *p++; + BUS_SPACE_TRACE(t, h, (" %4.4x", r)); + stha_asi(h.bh_ptr + o, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_multi_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int16_t v, + bus_size_t c) +{ + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bssm2(%llx + %llx, %x, %x) <- %4.4x\n", (long long)h.bh_ptr, + (long long)o, t->asi, c, v)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) + stha_asi(h.bh_ptr + o, v); +} + +void +bus_space_read_region_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + u_int16_t *a, bus_size_t c) +{ + u_int16_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bsrr2(%llx + %llx, %x, %x) <- \n", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + asi_set(t->asi); + for (; c; p++, c--, ptr += 2) { + u_int16_t r = lduha_asi(ptr); + BUS_SPACE_TRACE(t, h, (" %4.4x", r)); + *p = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_region_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const u_int16_t *a, bus_size_t c) +{ + const u_int16_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bswr2(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + asi_set(t->asi); + for (; c; p++, c--, ptr += 2) { + u_int16_t r = *p; + BUS_SPACE_TRACE(t, h, (" %4.4x", r)); + stha_asi(ptr, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int16_t v, + bus_size_t c) +{ + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bssr2(%llx + %llx, %x, %x) <- %4.4x\n", (long long)h.bh_ptr, + (long long)o, t->asi, c, v)); + + asi_set(t->asi); + for (; c; c--, ptr += 2) + stha_asi(ptr, v); +} + +void +bus_space_copy_region_2(bus_space_tag_t t, bus_space_handle_t h1, + bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, + bus_size_t c) +{ + paddr_t ptr1 = h1.bh_ptr + o1; + paddr_t ptr2 = h2.bh_ptr + o2; + + BUS_SPACE_ASSERT(t, h1, o2, 2); + BUS_SPACE_ASSERT(t, h2, o2, 2); + BUS_SPACE_TRACE(t, h1, + ("bscr2(%llx + %llx, %llx + %llx, %x, %x) <-> \n", + (long long)h1.bh_ptr, (long long)o1, + (long long)h2.bh_ptr, (long long)o2, + t->asi, c)); + + asi_set(t->asi); + for (; c; c--, ptr1 += 2, ptr2 += 2) { + u_int16_t r = lduha_asi(ptr2); + BUS_SPACE_TRACE(t, h1, (" %4.4x", r)); + stha_asi(ptr1, r); + } + BUS_SPACE_TRACE(t, h1, ("\n")); +} + + +/* + * Implementing u_int32_t + */ + + +void +bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + u_int32_t *a, bus_size_t c) +{ + u_int32_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bsrm4(%llx + %llx, %x, %x) ->", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) { + u_int32_t r = lduwa_asi(h.bh_ptr + o); + BUS_SPACE_TRACE(t, h, (" %8.8x", r)); + *p++ = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const u_int32_t *a, bus_size_t c) +{ + const u_int32_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bswm4(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) { + u_int32_t r = *p++; + BUS_SPACE_TRACE(t, h, (" %8.8x", r)); + stwa_asi(h.bh_ptr + o, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_multi_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int32_t v, + bus_size_t c) +{ + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bssm4(%llx + %llx, %x, %x) <- %8.8x\n", (long long)h.bh_ptr, + (long long)o, t->asi, c, v)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) + stwa_asi(h.bh_ptr + o, v); +} + +void +bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + u_int32_t *a, bus_size_t c) +{ + u_int32_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bsrr4(%llx + %llx, %x, %x) <- \n", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + asi_set(t->asi); + for (; c; p++, c--, ptr += 4) { + u_int32_t r = lduwa_asi(ptr); + BUS_SPACE_TRACE(t, h, (" %8.8x", r)); + *p = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const u_int32_t *a, bus_size_t c) +{ + const u_int32_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bswr4(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + asi_set(t->asi); + for (; c; p++, c--, ptr += 4) { + u_int32_t r = *p; + BUS_SPACE_TRACE(t, h, (" %8.8x", r)); + stwa_asi(ptr, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int32_t v, + bus_size_t c) +{ + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bssr4(%llx + %llx, %x, %x) <- %8.8x\n", (long long)h.bh_ptr, + (long long)o, t->asi, c, v)); + + asi_set(t->asi); + for (; c; c--, ptr += 4) + stwa_asi(ptr, v); +} + +void +bus_space_copy_region_4(bus_space_tag_t t, bus_space_handle_t h1, + bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, + bus_size_t c) +{ + paddr_t ptr1 = h1.bh_ptr + o1; + paddr_t ptr2 = h2.bh_ptr + o2; + + BUS_SPACE_ASSERT(t, h1, o2, 4); + BUS_SPACE_ASSERT(t, h2, o2, 4); + BUS_SPACE_TRACE(t, h1, + ("bscr4(%llx + %llx, %llx + %llx, %x, %x) <-> \n", + (long long)h1.bh_ptr, (long long)o1, + (long long)h2.bh_ptr, (long long)o2, + t->asi, c)); + + asi_set(t->asi); + for (; c; c--, ptr1 += 4, ptr2 += 4) { + u_int32_t r = lduwa_asi(ptr2); + BUS_SPACE_TRACE(t, h1, (" %8.8x", r)); + stwa_asi(ptr1, r); + } + BUS_SPACE_TRACE(t, h1, ("\n")); +} + + +/* + * Implementing u_int64_t + */ + + +void +bus_space_read_multi_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + u_int64_t *a, bus_size_t c) +{ + u_int64_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bsrm8(%llx + %llx, %x, %x) ->", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) { + u_int64_t r = ldxa_asi(h.bh_ptr + o); + BUS_SPACE_TRACE(t, h, (" %16.16llx", r)); + *p++ = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_multi_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const u_int64_t *a, bus_size_t c) +{ + const u_int64_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bswm8(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) { + u_int64_t r = *p++; + BUS_SPACE_TRACE(t, h, (" %16.16llx", r)); + stxa_asi(h.bh_ptr + o, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_multi_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int64_t v, + bus_size_t c) +{ + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bssm8(%llx + %llx, %x, %x) <- %16.16llx\n", (long long)h.bh_ptr, + (long long)o, t->asi, c, v)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) + stxa_asi(h.bh_ptr + o, v); +} + +void +bus_space_read_region_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + u_int64_t *a, bus_size_t c) +{ + u_int64_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bsrr8(%llx + %llx, %x, %x) <- \n", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + asi_set(t->asi); + for (; c; p++, c--, ptr += 8) { + u_int64_t r = ldxa_asi(ptr); + BUS_SPACE_TRACE(t, h, (" %16.16llx", r)); + *p = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_region_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const u_int64_t *a, bus_size_t c) +{ + const u_int64_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bswr8(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + asi_set(t->asi); + for (; c; p++, c--, ptr += 8) { + u_int64_t r = *p; + BUS_SPACE_TRACE(t, h, (" %16.16llx", r)); + stxa_asi(ptr, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_region_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int64_t v, + bus_size_t c) +{ + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bssr8(%llx + %llx, %x, %x) <- %16.16llx\n", (long long)h.bh_ptr, + (long long)o, t->asi, c, v)); + + asi_set(t->asi); + for (; c; c--, ptr += 8) + stxa_asi(ptr, v); +} + +void +bus_space_copy_region_8(bus_space_tag_t t, bus_space_handle_t h1, + bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, + bus_size_t c) +{ + paddr_t ptr1 = h1.bh_ptr + o1; + paddr_t ptr2 = h2.bh_ptr + o2; + + BUS_SPACE_ASSERT(t, h1, o2, 8); + BUS_SPACE_ASSERT(t, h2, o2, 8); + BUS_SPACE_TRACE(t, h1, + ("bscr8(%llx + %llx, %llx + %llx, %x, %x) <-> \n", + (long long)h1.bh_ptr, (long long)o1, + (long long)h2.bh_ptr, (long long)o2, + t->asi, c)); + + asi_set(t->asi); + for (; c; c--, ptr1 += 8, ptr2 += 8) { + u_int64_t r = ldxa_asi(ptr2); + BUS_SPACE_TRACE(t, h1, (" %16.16llx", r)); + stxa_asi(ptr1, r); + } + BUS_SPACE_TRACE(t, h1, ("\n")); +} + + +/* + * Implementing u_int8_t + */ + + +void +bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + u_int8_t *a, bus_size_t c) +{ + u_int8_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bsrm1(%llx + %llx, %x, %x) ->", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) { + u_int8_t r = lduba_asi(h.bh_ptr + o); + BUS_SPACE_TRACE(t, h, (" %2.2x", r)); + *p++ = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const u_int8_t *a, bus_size_t c) +{ + const u_int8_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bswm1(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) { + u_int8_t r = *p++; + BUS_SPACE_TRACE(t, h, (" %2.2x", r)); + stba_asi(h.bh_ptr + o, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_multi_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int8_t v, + bus_size_t c) +{ + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bssm1(%llx + %llx, %x, %x) <- %2.2x\n", (long long)h.bh_ptr, + (long long)o, t->asi, c, v)); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->asi); + while (--c > 0) + stba_asi(h.bh_ptr + o, v); +} + +void +bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + u_int8_t *a, bus_size_t c) +{ + u_int8_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bsrr1(%llx + %llx, %x, %x) <- \n", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + asi_set(t->asi); + for (; c; p++, c--, ptr += 1) { + u_int8_t r = lduba_asi(ptr); + BUS_SPACE_TRACE(t, h, (" %2.2x", r)); + *p = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const u_int8_t *a, bus_size_t c) +{ + const u_int8_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bswr1(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->asi, c)); + + asi_set(t->asi); + for (; c; p++, c--, ptr += 1) { + u_int8_t r = *p; + BUS_SPACE_TRACE(t, h, (" %2.2x", r)); + stba_asi(ptr, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int8_t v, + bus_size_t c) +{ + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bssr1(%llx + %llx, %x, %x) <- %2.2x\n", (long long)h.bh_ptr, + (long long)o, t->asi, c, v)); + + asi_set(t->asi); + for (; c; c--, ptr += 1) + stba_asi(ptr, v); +} + +void +bus_space_copy_region_1(bus_space_tag_t t, bus_space_handle_t h1, + bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, + bus_size_t c) +{ + paddr_t ptr1 = h1.bh_ptr + o1; + paddr_t ptr2 = h2.bh_ptr + o2; + + BUS_SPACE_ASSERT(t, h1, o2, 1); + BUS_SPACE_ASSERT(t, h2, o2, 1); + BUS_SPACE_TRACE(t, h1, + ("bscr1(%llx + %llx, %llx + %llx, %x, %x) <-> \n", + (long long)h1.bh_ptr, (long long)o1, + (long long)h2.bh_ptr, (long long)o2, + t->asi, c)); + + asi_set(t->asi); + for (; c; c--, ptr1 += 1, ptr2 += 1) { + u_int8_t r = lduba_asi(ptr2); + BUS_SPACE_TRACE(t, h1, (" %2.2x", r)); + stba_asi(ptr1, r); + } + BUS_SPACE_TRACE(t, h1, ("\n")); +} + + +/* + * Implementing u_int16_t + */ + + +void +bus_space_read_raw_multi_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + void *a, size_t c) +{ + u_int16_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bsrm2(%llx + %llx, %x, %x) ->", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int16_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) { + u_int16_t r = lduha_asi(h.bh_ptr + o); + BUS_SPACE_TRACE(t, h, (" %4.4x", r)); + *p++ = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_raw_multi_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const void *a, size_t c) +{ + const u_int16_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bswm2(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int16_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) { + u_int16_t r = *p++; + BUS_SPACE_TRACE(t, h, (" %4.4x", r)); + stha_asi(h.bh_ptr + o, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_raw_multi_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int16_t v, + size_t c) +{ + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bssm2(%llx + %llx, %x, %x) <- %4.4x\n", (long long)h.bh_ptr, + (long long)o, t->sasi, c, v)); + c /= sizeof(u_int16_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) + stha_asi(h.bh_ptr + o, v); +} + +void +bus_space_read_raw_region_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + void *a, size_t c) +{ + u_int16_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bsrr2(%llx + %llx, %x, %x) <- \n", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int16_t); + + asi_set(t->sasi); + for (; c; p++, c--, ptr += 2) { + u_int16_t r = lduha_asi(ptr); + BUS_SPACE_TRACE(t, h, (" %4.4x", r)); + *p = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_raw_region_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const void *a, size_t c) +{ + const u_int16_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bswr2(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int16_t); + + asi_set(t->sasi); + for (; c; p++, c--, ptr += 2) { + u_int16_t r = *p; + BUS_SPACE_TRACE(t, h, (" %4.4x", r)); + stha_asi(ptr, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_raw_region_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int16_t v, + size_t c) +{ + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bssr2(%llx + %llx, %x, %x) <- %4.4x\n", (long long)h.bh_ptr, + (long long)o, t->sasi, c, v)); + c /= sizeof(u_int16_t); + + asi_set(t->sasi); + for (; c; c--, ptr += 2) + stha_asi(ptr, v); +} + +void +bus_space_copy_raw_region_2(bus_space_tag_t t, bus_space_handle_t h1, + bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, + size_t c) +{ + paddr_t ptr1 = h1.bh_ptr + o1; + paddr_t ptr2 = h2.bh_ptr + o2; + + BUS_SPACE_ASSERT(t, h1, o2, 2); + BUS_SPACE_ASSERT(t, h2, o2, 2); + BUS_SPACE_TRACE(t, h1, + ("bscr2(%llx + %llx, %llx + %llx, %x, %x) <-> \n", + (long long)h1.bh_ptr, (long long)o1, + (long long)h2.bh_ptr, (long long)o2, + t->sasi, c)); + c /= sizeof(u_int16_t); + + asi_set(t->sasi); + for (; c; c--, ptr1 += 2, ptr2 += 2) { + u_int16_t r = lduha_asi(ptr2); + BUS_SPACE_TRACE(t, h1, (" %4.4x", r)); + stha_asi(ptr1, r); + } + BUS_SPACE_TRACE(t, h1, ("\n")); +} + + +/* + * Implementing u_int32_t + */ + + +void +bus_space_read_raw_multi_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + void *a, size_t c) +{ + u_int32_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bsrm4(%llx + %llx, %x, %x) ->", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int32_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) { + u_int32_t r = lduwa_asi(h.bh_ptr + o); + BUS_SPACE_TRACE(t, h, (" %8.8x", r)); + *p++ = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_raw_multi_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const void *a, size_t c) +{ + const u_int32_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bswm4(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int32_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) { + u_int32_t r = *p++; + BUS_SPACE_TRACE(t, h, (" %8.8x", r)); + stwa_asi(h.bh_ptr + o, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_raw_multi_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int32_t v, + size_t c) +{ + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bssm4(%llx + %llx, %x, %x) <- %8.8x\n", (long long)h.bh_ptr, + (long long)o, t->sasi, c, v)); + c /= sizeof(u_int32_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) + stwa_asi(h.bh_ptr + o, v); +} + +void +bus_space_read_raw_region_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + void *a, size_t c) +{ + u_int32_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bsrr4(%llx + %llx, %x, %x) <- \n", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int32_t); + + asi_set(t->sasi); + for (; c; p++, c--, ptr += 4) { + u_int32_t r = lduwa_asi(ptr); + BUS_SPACE_TRACE(t, h, (" %8.8x", r)); + *p = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_raw_region_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const void *a, size_t c) +{ + const u_int32_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bswr4(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int32_t); + + asi_set(t->sasi); + for (; c; p++, c--, ptr += 4) { + u_int32_t r = *p; + BUS_SPACE_TRACE(t, h, (" %8.8x", r)); + stwa_asi(ptr, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_raw_region_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int32_t v, + size_t c) +{ + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bssr4(%llx + %llx, %x, %x) <- %8.8x\n", (long long)h.bh_ptr, + (long long)o, t->sasi, c, v)); + c /= sizeof(u_int32_t); + + asi_set(t->sasi); + for (; c; c--, ptr += 4) + stwa_asi(ptr, v); +} + +void +bus_space_copy_raw_region_4(bus_space_tag_t t, bus_space_handle_t h1, + bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, + size_t c) +{ + paddr_t ptr1 = h1.bh_ptr + o1; + paddr_t ptr2 = h2.bh_ptr + o2; + + BUS_SPACE_ASSERT(t, h1, o2, 4); + BUS_SPACE_ASSERT(t, h2, o2, 4); + BUS_SPACE_TRACE(t, h1, + ("bscr4(%llx + %llx, %llx + %llx, %x, %x) <-> \n", + (long long)h1.bh_ptr, (long long)o1, + (long long)h2.bh_ptr, (long long)o2, + t->sasi, c)); + c /= sizeof(u_int32_t); + + asi_set(t->sasi); + for (; c; c--, ptr1 += 4, ptr2 += 4) { + u_int32_t r = lduwa_asi(ptr2); + BUS_SPACE_TRACE(t, h1, (" %8.8x", r)); + stwa_asi(ptr1, r); + } + BUS_SPACE_TRACE(t, h1, ("\n")); +} + + +/* + * Implementing u_int64_t + */ + + +void +bus_space_read_raw_multi_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + void *a, size_t c) +{ + u_int64_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bsrm8(%llx + %llx, %x, %x) ->", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int64_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) { + u_int64_t r = ldxa_asi(h.bh_ptr + o); + BUS_SPACE_TRACE(t, h, (" %16.16llx", r)); + *p++ = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_raw_multi_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const void *a, size_t c) +{ + const u_int64_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bswm8(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int64_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) { + u_int64_t r = *p++; + BUS_SPACE_TRACE(t, h, (" %16.16llx", r)); + stxa_asi(h.bh_ptr + o, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_raw_multi_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int64_t v, + size_t c) +{ + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bssm8(%llx + %llx, %x, %x) <- %16.16llx\n", (long long)h.bh_ptr, + (long long)o, t->sasi, c, v)); + c /= sizeof(u_int64_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) + stxa_asi(h.bh_ptr + o, v); +} + +void +bus_space_read_raw_region_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + void *a, size_t c) +{ + u_int64_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bsrr8(%llx + %llx, %x, %x) <- \n", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int64_t); + + asi_set(t->sasi); + for (; c; p++, c--, ptr += 8) { + u_int64_t r = ldxa_asi(ptr); + BUS_SPACE_TRACE(t, h, (" %16.16llx", r)); + *p = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_raw_region_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const void *a, size_t c) +{ + const u_int64_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bswr8(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int64_t); + + asi_set(t->sasi); + for (; c; p++, c--, ptr += 8) { + u_int64_t r = *p; + BUS_SPACE_TRACE(t, h, (" %16.16llx", r)); + stxa_asi(ptr, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_raw_region_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int64_t v, + size_t c) +{ + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bssr8(%llx + %llx, %x, %x) <- %16.16llx\n", (long long)h.bh_ptr, + (long long)o, t->sasi, c, v)); + c /= sizeof(u_int64_t); + + asi_set(t->sasi); + for (; c; c--, ptr += 8) + stxa_asi(ptr, v); +} + +void +bus_space_copy_raw_region_8(bus_space_tag_t t, bus_space_handle_t h1, + bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, + size_t c) +{ + paddr_t ptr1 = h1.bh_ptr + o1; + paddr_t ptr2 = h2.bh_ptr + o2; + + BUS_SPACE_ASSERT(t, h1, o2, 8); + BUS_SPACE_ASSERT(t, h2, o2, 8); + BUS_SPACE_TRACE(t, h1, + ("bscr8(%llx + %llx, %llx + %llx, %x, %x) <-> \n", + (long long)h1.bh_ptr, (long long)o1, + (long long)h2.bh_ptr, (long long)o2, + t->sasi, c)); + c /= sizeof(u_int64_t); + + asi_set(t->sasi); + for (; c; c--, ptr1 += 8, ptr2 += 8) { + u_int64_t r = ldxa_asi(ptr2); + BUS_SPACE_TRACE(t, h1, (" %16.16llx", r)); + stxa_asi(ptr1, r); + } + BUS_SPACE_TRACE(t, h1, ("\n")); +} + + +/* + * Implementing u_int8_t + */ + + +void +bus_space_read_raw_multi_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + void *a, size_t c) +{ + u_int8_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bsrm1(%llx + %llx, %x, %x) ->", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int8_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) { + u_int8_t r = lduba_asi(h.bh_ptr + o); + BUS_SPACE_TRACE(t, h, (" %2.2x", r)); + *p++ = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_raw_multi_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const void *a, size_t c) +{ + const u_int8_t *p = a; + + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bswm1(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int8_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) { + u_int8_t r = *p++; + BUS_SPACE_TRACE(t, h, (" %2.2x", r)); + stba_asi(h.bh_ptr + o, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_raw_multi_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int8_t v, + size_t c) +{ + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bssm1(%llx + %llx, %x, %x) <- %2.2x\n", (long long)h.bh_ptr, + (long long)o, t->sasi, c, v)); + c /= sizeof(u_int8_t); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t->sasi); + while (--c > 0) + stba_asi(h.bh_ptr + o, v); +} + +void +bus_space_read_raw_region_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + void *a, size_t c) +{ + u_int8_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bsrr1(%llx + %llx, %x, %x) <- \n", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int8_t); + + asi_set(t->sasi); + for (; c; p++, c--, ptr += 1) { + u_int8_t r = lduba_asi(ptr); + BUS_SPACE_TRACE(t, h, (" %2.2x", r)); + *p = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_raw_region_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, + const void *a, size_t c) +{ + const u_int8_t *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bswr1(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t->sasi, c)); + c /= sizeof(u_int8_t); + + asi_set(t->sasi); + for (; c; p++, c--, ptr += 1) { + u_int8_t r = *p; + BUS_SPACE_TRACE(t, h, (" %2.2x", r)); + stba_asi(ptr, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_raw_region_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int8_t v, + size_t c) +{ + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bssr1(%llx + %llx, %x, %x) <- %2.2x\n", (long long)h.bh_ptr, + (long long)o, t->sasi, c, v)); + c /= sizeof(u_int8_t); + + asi_set(t->sasi); + for (; c; c--, ptr += 1) + stba_asi(ptr, v); +} + +void +bus_space_copy_raw_region_1(bus_space_tag_t t, bus_space_handle_t h1, + bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, + size_t c) +{ + paddr_t ptr1 = h1.bh_ptr + o1; + paddr_t ptr2 = h2.bh_ptr + o2; + + BUS_SPACE_ASSERT(t, h1, o2, 1); + BUS_SPACE_ASSERT(t, h2, o2, 1); + BUS_SPACE_TRACE(t, h1, + ("bscr1(%llx + %llx, %llx + %llx, %x, %x) <-> \n", + (long long)h1.bh_ptr, (long long)o1, + (long long)h2.bh_ptr, (long long)o2, + t->sasi, c)); + c /= sizeof(u_int8_t); + + asi_set(t->sasi); + for (; c; c--, ptr1 += 1, ptr2 += 1) { + u_int8_t r = lduba_asi(ptr2); + BUS_SPACE_TRACE(t, h1, (" %2.2x", r)); + stba_asi(ptr1, r); + } + BUS_SPACE_TRACE(t, h1, ("\n")); +} + + diff --git a/sys/arch/sparc64/sparc64/busop.h b/sys/arch/sparc64/sparc64/busop.h new file mode 100644 index 00000000000..b4fb2e38d07 --- /dev/null +++ b/sys/arch/sparc64/sparc64/busop.h @@ -0,0 +1,537 @@ +/* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/* $OpenBSD: busop.h,v 1.1 2003/02/17 01:29:20 henric Exp $ */ + +/* + * Copyright (c) 2003 Henric Jungheim + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Implementing u_int16_t + */ + + +static inline u_int16_t bus_space_read_2(bus_space_tag_t, + bus_space_handle_t, bus_size_t); +static inline void bus_space_write_2(bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int16_t); +void bus_space_read_multi_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + u_int16_t *, bus_size_t); +void bus_space_write_multi_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const u_int16_t *, bus_size_t); +void bus_space_set_multi_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int16_t, + bus_size_t); +void bus_space_read_region_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + u_int16_t *, bus_size_t); +void bus_space_write_region_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const u_int16_t *, bus_size_t); +void bus_space_set_region_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int16_t, + bus_size_t); +void bus_space_copy_region_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, bus_space_handle_t, bus_size_t, + bus_size_t); + +static inline +u_int16_t bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o) +{ + u_int16_t r; + + BUS_SPACE_ASSERT(t, h, o, 2); + r = lduha(h.bh_ptr + o, t->asi); + BUS_SPACE_TRACE(t, h, + ("bsr2(%llx + %llx, %x) -> %4.4x\n", + (long long)h.bh_ptr, + (long long)o, + t->asi, + r)); + return (r); +} + +static inline +void bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int16_t v) +{ + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bsw2(%llx + %llx, %x) <- %4.4x\n", + (long long)h.bh_ptr, + (long long)o, + t->asi, + v)); + stha(h.bh_ptr + o, t->asi, v); +} + + +/* + * Implementing u_int32_t + */ + + +static inline u_int32_t bus_space_read_4(bus_space_tag_t, + bus_space_handle_t, bus_size_t); +static inline void bus_space_write_4(bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int32_t); +void bus_space_read_multi_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + u_int32_t *, bus_size_t); +void bus_space_write_multi_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const u_int32_t *, bus_size_t); +void bus_space_set_multi_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int32_t, + bus_size_t); +void bus_space_read_region_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + u_int32_t *, bus_size_t); +void bus_space_write_region_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const u_int32_t *, bus_size_t); +void bus_space_set_region_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int32_t, + bus_size_t); +void bus_space_copy_region_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, bus_space_handle_t, bus_size_t, + bus_size_t); + +static inline +u_int32_t bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o) +{ + u_int32_t r; + + BUS_SPACE_ASSERT(t, h, o, 4); + r = lduwa(h.bh_ptr + o, t->asi); + BUS_SPACE_TRACE(t, h, + ("bsr4(%llx + %llx, %x) -> %8.8x\n", + (long long)h.bh_ptr, + (long long)o, + t->asi, + r)); + return (r); +} + +static inline +void bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int32_t v) +{ + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bsw4(%llx + %llx, %x) <- %8.8x\n", + (long long)h.bh_ptr, + (long long)o, + t->asi, + v)); + stwa(h.bh_ptr + o, t->asi, v); +} + + +/* + * Implementing u_int64_t + */ + + +static inline u_int64_t bus_space_read_8(bus_space_tag_t, + bus_space_handle_t, bus_size_t); +static inline void bus_space_write_8(bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int64_t); +void bus_space_read_multi_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + u_int64_t *, bus_size_t); +void bus_space_write_multi_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const u_int64_t *, bus_size_t); +void bus_space_set_multi_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int64_t, + bus_size_t); +void bus_space_read_region_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + u_int64_t *, bus_size_t); +void bus_space_write_region_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const u_int64_t *, bus_size_t); +void bus_space_set_region_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int64_t, + bus_size_t); +void bus_space_copy_region_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, bus_space_handle_t, bus_size_t, + bus_size_t); + +static inline +u_int64_t bus_space_read_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o) +{ + u_int64_t r; + + BUS_SPACE_ASSERT(t, h, o, 8); + r = ldxa(h.bh_ptr + o, t->asi); + BUS_SPACE_TRACE(t, h, + ("bsr8(%llx + %llx, %x) -> %16.16llx\n", + (long long)h.bh_ptr, + (long long)o, + t->asi, + r)); + return (r); +} + +static inline +void bus_space_write_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int64_t v) +{ + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bsw8(%llx + %llx, %x) <- %16.16llx\n", + (long long)h.bh_ptr, + (long long)o, + t->asi, + v)); + stxa(h.bh_ptr + o, t->asi, v); +} + + +/* + * Implementing u_int8_t + */ + + +static inline u_int8_t bus_space_read_1(bus_space_tag_t, + bus_space_handle_t, bus_size_t); +static inline void bus_space_write_1(bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int8_t); +void bus_space_read_multi_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + u_int8_t *, bus_size_t); +void bus_space_write_multi_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const u_int8_t *, bus_size_t); +void bus_space_set_multi_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int8_t, + bus_size_t); +void bus_space_read_region_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + u_int8_t *, bus_size_t); +void bus_space_write_region_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const u_int8_t *, bus_size_t); +void bus_space_set_region_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int8_t, + bus_size_t); +void bus_space_copy_region_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, bus_space_handle_t, bus_size_t, + bus_size_t); + +static inline +u_int8_t bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o) +{ + u_int8_t r; + + BUS_SPACE_ASSERT(t, h, o, 1); + r = lduba(h.bh_ptr + o, t->asi); + BUS_SPACE_TRACE(t, h, + ("bsr1(%llx + %llx, %x) -> %2.2x\n", + (long long)h.bh_ptr, + (long long)o, + t->asi, + r)); + return (r); +} + +static inline +void bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int8_t v) +{ + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bsw1(%llx + %llx, %x) <- %2.2x\n", + (long long)h.bh_ptr, + (long long)o, + t->asi, + v)); + stba(h.bh_ptr + o, t->asi, v); +} + + +/* + * Implementing u_int16_t + */ + + +static inline u_int16_t bus_space_read_raw_2(bus_space_tag_t, + bus_space_handle_t, bus_size_t); +static inline void bus_space_write_raw_2(bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int16_t); +void bus_space_read_raw_multi_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + void *, size_t); +void bus_space_write_raw_multi_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const void *, size_t); +void bus_space_set_raw_multi_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int16_t, + size_t); +void bus_space_read_raw_region_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + void *, size_t); +void bus_space_write_raw_region_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const void *, size_t); +void bus_space_set_raw_region_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int16_t, + size_t); +void bus_space_copy_raw_region_2(bus_space_tag_t, bus_space_handle_t, + bus_size_t, bus_space_handle_t, bus_size_t, + size_t); + +static inline +u_int16_t bus_space_read_raw_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o) +{ + u_int16_t r; + + BUS_SPACE_ASSERT(t, h, o, 2); + r = lduha(h.bh_ptr + o, t->sasi); + BUS_SPACE_TRACE(t, h, + ("bsr2(%llx + %llx, %x) -> %4.4x\n", + (long long)h.bh_ptr, + (long long)o, + t->sasi, + r)); + return (r); +} + +static inline +void bus_space_write_raw_2(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int16_t v) +{ + BUS_SPACE_ASSERT(t, h, o, 2); + BUS_SPACE_TRACE(t, h, + ("bsw2(%llx + %llx, %x) <- %4.4x\n", + (long long)h.bh_ptr, + (long long)o, + t->sasi, + v)); + stha(h.bh_ptr + o, t->sasi, v); +} + + +/* + * Implementing u_int32_t + */ + + +static inline u_int32_t bus_space_read_raw_4(bus_space_tag_t, + bus_space_handle_t, bus_size_t); +static inline void bus_space_write_raw_4(bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int32_t); +void bus_space_read_raw_multi_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + void *, size_t); +void bus_space_write_raw_multi_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const void *, size_t); +void bus_space_set_raw_multi_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int32_t, + size_t); +void bus_space_read_raw_region_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + void *, size_t); +void bus_space_write_raw_region_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const void *, size_t); +void bus_space_set_raw_region_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int32_t, + size_t); +void bus_space_copy_raw_region_4(bus_space_tag_t, bus_space_handle_t, + bus_size_t, bus_space_handle_t, bus_size_t, + size_t); + +static inline +u_int32_t bus_space_read_raw_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o) +{ + u_int32_t r; + + BUS_SPACE_ASSERT(t, h, o, 4); + r = lduwa(h.bh_ptr + o, t->sasi); + BUS_SPACE_TRACE(t, h, + ("bsr4(%llx + %llx, %x) -> %8.8x\n", + (long long)h.bh_ptr, + (long long)o, + t->sasi, + r)); + return (r); +} + +static inline +void bus_space_write_raw_4(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int32_t v) +{ + BUS_SPACE_ASSERT(t, h, o, 4); + BUS_SPACE_TRACE(t, h, + ("bsw4(%llx + %llx, %x) <- %8.8x\n", + (long long)h.bh_ptr, + (long long)o, + t->sasi, + v)); + stwa(h.bh_ptr + o, t->sasi, v); +} + + +/* + * Implementing u_int64_t + */ + + +static inline u_int64_t bus_space_read_raw_8(bus_space_tag_t, + bus_space_handle_t, bus_size_t); +static inline void bus_space_write_raw_8(bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int64_t); +void bus_space_read_raw_multi_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + void *, size_t); +void bus_space_write_raw_multi_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const void *, size_t); +void bus_space_set_raw_multi_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int64_t, + size_t); +void bus_space_read_raw_region_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + void *, size_t); +void bus_space_write_raw_region_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const void *, size_t); +void bus_space_set_raw_region_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int64_t, + size_t); +void bus_space_copy_raw_region_8(bus_space_tag_t, bus_space_handle_t, + bus_size_t, bus_space_handle_t, bus_size_t, + size_t); + +static inline +u_int64_t bus_space_read_raw_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o) +{ + u_int64_t r; + + BUS_SPACE_ASSERT(t, h, o, 8); + r = ldxa(h.bh_ptr + o, t->sasi); + BUS_SPACE_TRACE(t, h, + ("bsr8(%llx + %llx, %x) -> %16.16llx\n", + (long long)h.bh_ptr, + (long long)o, + t->sasi, + r)); + return (r); +} + +static inline +void bus_space_write_raw_8(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int64_t v) +{ + BUS_SPACE_ASSERT(t, h, o, 8); + BUS_SPACE_TRACE(t, h, + ("bsw8(%llx + %llx, %x) <- %16.16llx\n", + (long long)h.bh_ptr, + (long long)o, + t->sasi, + v)); + stxa(h.bh_ptr + o, t->sasi, v); +} + + +/* + * Implementing u_int8_t + */ + + +static inline u_int8_t bus_space_read_raw_1(bus_space_tag_t, + bus_space_handle_t, bus_size_t); +static inline void bus_space_write_raw_1(bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int8_t); +void bus_space_read_raw_multi_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + void *, size_t); +void bus_space_write_raw_multi_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const void *, size_t); +void bus_space_set_raw_multi_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int8_t, + size_t); +void bus_space_read_raw_region_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + void *, size_t); +void bus_space_write_raw_region_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, + const void *, size_t); +void bus_space_set_raw_region_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int8_t, + size_t); +void bus_space_copy_raw_region_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, bus_space_handle_t, bus_size_t, + size_t); + +static inline +u_int8_t bus_space_read_raw_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o) +{ + u_int8_t r; + + BUS_SPACE_ASSERT(t, h, o, 1); + r = lduba(h.bh_ptr + o, t->sasi); + BUS_SPACE_TRACE(t, h, + ("bsr1(%llx + %llx, %x) -> %2.2x\n", + (long long)h.bh_ptr, + (long long)o, + t->sasi, + r)); + return (r); +} + +static inline +void bus_space_write_raw_1(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, u_int8_t v) +{ + BUS_SPACE_ASSERT(t, h, o, 1); + BUS_SPACE_TRACE(t, h, + ("bsw1(%llx + %llx, %x) <- %2.2x\n", + (long long)h.bh_ptr, + (long long)o, + t->sasi, + v)); + stba(h.bh_ptr + o, t->sasi, v); +} + + diff --git a/sys/arch/sparc64/sparc64/busop_c.in b/sys/arch/sparc64/sparc64/busop_c.in new file mode 100644 index 00000000000..4341694d494 --- /dev/null +++ b/sys/arch/sparc64/sparc64/busop_c.in @@ -0,0 +1,200 @@ +ECHO:/* $OpenBSD: busop_c.in,v 1.1 2003/02/17 01:29:20 henric Exp $ */ +ECHO: +ECHO:/* +ECHO: * Copyright (c) 2003 Henric Jungheim +ECHO: * All rights reserved. +ECHO: * +ECHO: * Redistribution and use in source and binary forms, with or without +ECHO: * modification, are permitted provided that the following conditions +ECHO: * are met: +ECHO: * 1. Redistributions of source code must retain the above copyright +ECHO: * notice, this list of conditions and the following disclaimer. +ECHO: * 2. Redistributions in binary form must reproduce the above copyright +ECHO: * notice, this list of conditions and the following disclaimer in the +ECHO: * documentation and/or other materials provided with the distribution. +ECHO: * 3. The name of the author may not be used to endorse or promote products +ECHO: * derived from this software without specific prior written permission. +ECHO: * +ECHO: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +ECHO: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +ECHO: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +ECHO: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +ECHO: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +ECHO: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +ECHO: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +ECHO: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +ECHO: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +ECHO: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +ECHO: */ +ECHO: +ECHO:#include <sys/param.h> +ECHO:#include <sys/systm.h> +ECHO:#include <sys/kernel.h> +ECHO: +ECHO:#include <machine/bus.h> +ECHO: + +void +bus_space_read_<RAW>multi_<NUM>(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, +NRAW: <TYPE> *a, bus_size_t c) +RAW: void *a, size_t c) +{ + <TYPE> *p = a; + + BUS_SPACE_ASSERT(t, h, o, <NUM>); + BUS_SPACE_TRACE(t, h, + ("bsrm<NUM>(%llx + %llx, %x, %x) ->", (long long)h.bh_ptr, + (long long)o, t-><ASI>, c)); +RAW: c /= sizeof(<TYPE>); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t-><ASI>); + while (--c > 0) { + <TYPE> r = <LOAD>_asi(h.bh_ptr + o); + BUS_SPACE_TRACE(t, h, (" <FMT>", r)); + *p++ = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_<RAW>multi_<NUM>(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, +NRAW: const <TYPE> *a, bus_size_t c) +RAW: const void *a, size_t c) +{ + const <TYPE> *p = a; + + BUS_SPACE_ASSERT(t, h, o, <NUM>); + BUS_SPACE_TRACE(t, h, + ("bswm<NUM>(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t-><ASI>, c)); +RAW: c /= sizeof(<TYPE>); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t-><ASI>); + while (--c > 0) { + <TYPE> r = *p++; + BUS_SPACE_TRACE(t, h, (" <FMT>", r)); + <STORE>_asi(h.bh_ptr + o, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_<RAW>multi_<NUM>(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, <TYPE> v, +NRAW: bus_size_t c) +RAW: size_t c) +{ + BUS_SPACE_ASSERT(t, h, o, <NUM>); + BUS_SPACE_TRACE(t, h, + ("bssm<NUM>(%llx + %llx, %x, %x) <- <FMT>\n", (long long)h.bh_ptr, + (long long)o, t-><ASI>, c, v)); +RAW: c /= sizeof(<TYPE>); + + ++c; /* Looping on "--c" is slightly faster than on "c--" */ + asi_set(t-><ASI>); + while (--c > 0) + <STORE>_asi(h.bh_ptr + o, v); +} + +void +bus_space_read_<RAW>region_<NUM>(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, +NRAW: <TYPE> *a, bus_size_t c) +RAW: void *a, size_t c) +{ + <TYPE> *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, <NUM>); + BUS_SPACE_TRACE(t, h, + ("bsrr<NUM>(%llx + %llx, %x, %x) <- \n", (long long)h.bh_ptr, + (long long)o, t-><ASI>, c)); +RAW: c /= sizeof(<TYPE>); + + asi_set(t-><ASI>); + for (; c; p++, c--, ptr += <NUM>) { + <TYPE> r = <LOAD>_asi(ptr); + BUS_SPACE_TRACE(t, h, (" <FMT>", r)); + *p = r; + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_write_<RAW>region_<NUM>(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, +NRAW: const <TYPE> *a, bus_size_t c) +RAW: const void *a, size_t c) +{ + const <TYPE> *p = a; + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, <NUM>); + BUS_SPACE_TRACE(t, h, + ("bswr<NUM>(%llx + %llx, %x, %x) <-", (long long)h.bh_ptr, + (long long)o, t-><ASI>, c)); +RAW: c /= sizeof(<TYPE>); + + asi_set(t-><ASI>); + for (; c; p++, c--, ptr += <NUM>) { + <TYPE> r = *p; + BUS_SPACE_TRACE(t, h, (" <FMT>", r)); + <STORE>_asi(ptr, r); + } + + BUS_SPACE_TRACE(t, h, ("\n")); +} + +void +bus_space_set_<RAW>region_<NUM>(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, <TYPE> v, +NRAW: bus_size_t c) +RAW: size_t c) +{ + paddr_t ptr = h.bh_ptr + o; + + BUS_SPACE_ASSERT(t, h, o, <NUM>); + BUS_SPACE_TRACE(t, h, + ("bssr<NUM>(%llx + %llx, %x, %x) <- <FMT>\n", (long long)h.bh_ptr, + (long long)o, t-><ASI>, c, v)); +RAW: c /= sizeof(<TYPE>); + + asi_set(t-><ASI>); + for (; c; c--, ptr += <NUM>) + <STORE>_asi(ptr, v); +} + +void +bus_space_copy_<RAW>region_<NUM>(bus_space_tag_t t, bus_space_handle_t h1, + bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, +NRAW: bus_size_t c) +RAW: size_t c) +{ + paddr_t ptr1 = h1.bh_ptr + o1; + paddr_t ptr2 = h2.bh_ptr + o2; + + BUS_SPACE_ASSERT(t, h1, o2, <NUM>); + BUS_SPACE_ASSERT(t, h2, o2, <NUM>); + BUS_SPACE_TRACE(t, h1, + ("bscr<NUM>(%llx + %llx, %llx + %llx, %x, %x) <-> \n", + (long long)h1.bh_ptr, (long long)o1, + (long long)h2.bh_ptr, (long long)o2, + t-><ASI>, c)); +RAW: c /= sizeof(<TYPE>); + + asi_set(t-><ASI>); + for (; c; c--, ptr1 += <NUM>, ptr2 += <NUM>) { + <TYPE> r = <LOAD>_asi(ptr2); + BUS_SPACE_TRACE(t, h1, (" <FMT>", r)); + <STORE>_asi(ptr1, r); + } + BUS_SPACE_TRACE(t, h1, ("\n")); +} + diff --git a/sys/arch/sparc64/sparc64/busop_h.in b/sys/arch/sparc64/sparc64/busop_h.in new file mode 100644 index 00000000000..88ce8e150ce --- /dev/null +++ b/sys/arch/sparc64/sparc64/busop_h.in @@ -0,0 +1,94 @@ +ECHO:/* $OpenBSD: busop_h.in,v 1.1 2003/02/17 01:29:20 henric Exp $ */ +ECHO: +ECHO:/* +ECHO: * Copyright (c) 2003 Henric Jungheim +ECHO: * All rights reserved. +ECHO: * +ECHO: * Redistribution and use in source and binary forms, with or without +ECHO: * modification, are permitted provided that the following conditions +ECHO: * are met: +ECHO: * 1. Redistributions of source code must retain the above copyright +ECHO: * notice, this list of conditions and the following disclaimer. +ECHO: * 2. Redistributions in binary form must reproduce the above copyright +ECHO: * notice, this list of conditions and the following disclaimer in the +ECHO: * documentation and/or other materials provided with the distribution. +ECHO: * 3. The name of the author may not be used to endorse or promote products +ECHO: * derived from this software without specific prior written permission. +ECHO: * +ECHO: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +ECHO: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +ECHO: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +ECHO: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +ECHO: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +ECHO: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +ECHO: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +ECHO: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +ECHO: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +ECHO: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +ECHO: */ +ECHO: + +static inline <TYPE> bus_space_read_<RAW><NUM>(bus_space_tag_t, + bus_space_handle_t, bus_size_t); +static inline void bus_space_write_<RAW><NUM>(bus_space_tag_t, + bus_space_handle_t, bus_size_t, <TYPE>); +void bus_space_read_<RAW>multi_<NUM>(bus_space_tag_t, bus_space_handle_t, + bus_size_t, +NRAW: <TYPE> *, bus_size_t); +RAW: void *, size_t); +void bus_space_write_<RAW>multi_<NUM>(bus_space_tag_t, bus_space_handle_t, + bus_size_t, +NRAW: const <TYPE> *, bus_size_t); +RAW: const void *, size_t); +void bus_space_set_<RAW>multi_<NUM>(bus_space_tag_t, bus_space_handle_t, + bus_size_t, <TYPE>, +NRAW: bus_size_t); +RAW: size_t); +void bus_space_read_<RAW>region_<NUM>(bus_space_tag_t, bus_space_handle_t, + bus_size_t, +NRAW: <TYPE> *, bus_size_t); +RAW: void *, size_t); +void bus_space_write_<RAW>region_<NUM>(bus_space_tag_t, bus_space_handle_t, + bus_size_t, +NRAW: const <TYPE> *, bus_size_t); +RAW: const void *, size_t); +void bus_space_set_<RAW>region_<NUM>(bus_space_tag_t, bus_space_handle_t, + bus_size_t, <TYPE>, +NRAW: bus_size_t); +RAW: size_t); +void bus_space_copy_<RAW>region_<NUM>(bus_space_tag_t, bus_space_handle_t, + bus_size_t, bus_space_handle_t, bus_size_t, +NRAW: bus_size_t); +RAW: size_t); + +static inline +<TYPE> bus_space_read_<RAW><NUM>(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o) +{ + <TYPE> r; + + BUS_SPACE_ASSERT(t, h, o, <NUM>); + r = <LOAD>(h.bh_ptr + o, t-><ASI>); + BUS_SPACE_TRACE(t, h, + ("bsr<NUM>(%llx + %llx, %x) -> <FMT>\n", + (long long)h.bh_ptr, + (long long)o, + t-><ASI>, + r)); + return (r); +} + +static inline +void bus_space_write_<RAW><NUM>(bus_space_tag_t t, bus_space_handle_t h, + bus_size_t o, <TYPE> v) +{ + BUS_SPACE_ASSERT(t, h, o, <NUM>); + BUS_SPACE_TRACE(t, h, + ("bsw<NUM>(%llx + %llx, %x) <- <FMT>\n", + (long long)h.bh_ptr, + (long long)o, + t-><ASI>, + v)); + <STORE>(h.bh_ptr + o, t-><ASI>, v); +} + diff --git a/sys/arch/sparc64/sparc64/cache.c b/sys/arch/sparc64/sparc64/cache.c index 9d7202fe6d5..4a19e10c028 100644 --- a/sys/arch/sparc64/sparc64/cache.c +++ b/sys/arch/sparc64/sparc64/cache.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cache.c,v 1.2 2001/08/20 20:23:53 jason Exp $ */ +/* $OpenBSD: cache.c,v 1.3 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: cache.c,v 1.5 2000/12/06 01:47:50 mrg Exp $ */ /* @@ -85,7 +85,7 @@ cache_enable() * Anyway, sun4u ECC is generated in the E$, so we can't disable that * and expect to use any RAM. */ - cacheinfo.c_enabled = 1; /* enable cache flusing */ + cacheinfo.c_enabled = 1; /* enable cache flushing */ } /* diff --git a/sys/arch/sparc64/sparc64/clock.c b/sys/arch/sparc64/sparc64/clock.c index 110652d6b60..a757e1374f6 100644 --- a/sys/arch/sparc64/sparc64/clock.c +++ b/sys/arch/sparc64/sparc64/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.14 2002/10/12 01:09:43 krw Exp $ */ +/* $OpenBSD: clock.c,v 1.15 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: clock.c,v 1.41 2001/07/24 19:29:25 eeh Exp $ */ /* @@ -103,6 +103,12 @@ struct rtc_info { bus_space_handle_t rtc_bh; /* */ }; +struct clock_wenable_info { + bus_space_tag_t cwi_bt; + bus_space_handle_t cwi_bh; + bus_size_t cwi_size; +}; + struct cfdriver clock_cd = { NULL, "clock", DV_DULL }; @@ -172,8 +178,7 @@ struct cfdriver timer_cd = { NULL, "timer", DV_DULL }; -int sbus_wenable(struct todr_chip_handle *, int); -int ebus_wenable(struct todr_chip_handle *, int); +int clock_bus_wenable(struct todr_chip_handle *, int); struct chiptime; void myetheraddr(u_char *); struct idprom *getidprom(void); @@ -252,13 +257,6 @@ clockmatch_rtc(parent, cf, aux) * a non-trivial operation. */ -/* Somewhere to keep info that sbus_wenable() needs */ -struct sbus_info { - bus_space_tag_t si_bt; - bus_space_handle_t si_bh; - struct sbus_reg si_reg; -}; - /* ARGSUSED */ static void clockattach_sbus(parent, self, aux) @@ -268,7 +266,7 @@ clockattach_sbus(parent, self, aux) struct sbus_attach_args *sa = aux; bus_space_tag_t bt = sa->sa_bustag; int sz; - static struct sbus_info sbi; + static struct clock_wenable_info cwi; /* use sa->sa_regs[0].size? */ sz = 8192; @@ -277,64 +275,55 @@ clockattach_sbus(parent, self, aux) sa->sa_slot, (sa->sa_offset & ~NBPG), sz, - BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_READONLY, - 0, - &sbi.si_bh) != 0) { + BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_READONLY, + 0, &cwi.cwi_bh) != 0) { printf("%s: can't map register\n", self->dv_xname); return; } - clockattach(sa->sa_node, bt, sbi.si_bh); + clockattach(sa->sa_node, bt, cwi.cwi_bh); /* Save info for the clock wenable call. */ - sbi.si_bt = bt; - sbi.si_reg = sa->sa_reg[0]; - todr_handle->bus_cookie = &sbi; - todr_handle->todr_setwen = sbus_wenable; + cwi.cwi_bt = bt; + cwi.cwi_size = sz; + todr_handle->bus_cookie = &cwi; + todr_handle->todr_setwen = clock_bus_wenable; } /* * Write en/dis-able clock registers. We coordinate so that several * writers can run simultaneously. + * XXX There is still a race here. The page change and the "writers" + * change are not atomic. */ int -sbus_wenable(handle, onoff) +clock_bus_wenable(handle, onoff) struct todr_chip_handle *handle; int onoff; { - register int s, err = 0; - register int prot;/* nonzero => change prot */ - static int writers; + int s, err = 0; + int prot; /* nonzero => change prot */ + volatile static int writers; + struct clock_wenable_info *cwi = handle->bus_cookie; s = splhigh(); if (onoff) - prot = writers++ == 0 ? BUS_SPACE_MAP_LINEAR : 0; + prot = writers++ == 0 ? + VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED : 0; else - prot = --writers == 0 ? - BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_READONLY : 0; + prot = --writers == 0 ? + VM_PROT_READ | PMAP_WIRED : 0; splx(s); + if (prot) { - struct sbus_info *sbi = (struct sbus_info *)handle->bus_cookie; - bus_space_handle_t newaddr; - - err = sbus_bus_map(sbi->si_bt, sbi->si_reg.sbr_slot, - (sbi->si_reg.sbr_offset & ~NBPG), - 8192, prot, (vaddr_t)sbi->si_bh, &newaddr); - /* We can panic now or take a datafault later... */ - if (sbi->si_bh != newaddr) - panic("sbus_wenable: address %p changed to %p", - (void *)(u_long)sbi->si_bh, - (void *)(u_long)newaddr); + err = bus_space_protect(cwi->cwi_bt, cwi->cwi_bh, cwi->cwi_size, + onoff ? 0 : BUS_SPACE_MAP_READONLY); + if (err) + printf("clock_wenable_info: WARNING -- cannot %s " + "page protection\n", onoff ? "disable" : "enable"); } return (err); } - -struct ebus_info { - bus_space_tag_t ei_bt; - bus_space_handle_t ei_bh; - struct ebus_regs ei_reg; -}; - /* ARGSUSED */ static void clockattach_ebus(parent, self, aux) @@ -342,69 +331,36 @@ clockattach_ebus(parent, self, aux) void *aux; { struct ebus_attach_args *ea = aux; - bus_space_tag_t bt = ea->ea_bustag; + bus_space_tag_t bt; int sz; - static struct ebus_info ebi; + static struct clock_wenable_info cwi; /* hard code to 8K? */ sz = ea->ea_regs[0].size; - if (ebus_bus_map(bt, - 0, - EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), - sz, - BUS_SPACE_MAP_LINEAR, - 0, - &ebi.ei_bh) != 0) { + if (ebus_bus_map(ea->ea_iotag, 0, + EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), sz, 0, 0, &cwi.cwi_bh) == 0) { + bt = ea->ea_iotag; + } else if (ebus_bus_map(ea->ea_memtag, 0, + EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), sz, + BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_READONLY, + 0, &cwi.cwi_bh) == 0) { + bt = ea->ea_memtag; + } else { printf("%s: can't map register\n", self->dv_xname); return; } - clockattach(ea->ea_node, bt, ebi.ei_bh); - /* Save info for the clock wenable call. */ - ebi.ei_bt = bt; - ebi.ei_reg = ea->ea_regs[0]; - todr_handle->bus_cookie = &ebi; - todr_handle->todr_setwen = ebus_wenable; -} - -/* - * Write en/dis-able clock registers. We coordinate so that several - * writers can run simultaneously. - */ -int -ebus_wenable(handle, onoff) - struct todr_chip_handle *handle; - int onoff; -{ - register int s, err = 0; - register int prot;/* nonzero => change prot */ - static int writers; + clockattach(ea->ea_node, bt, cwi.cwi_bh); - s = splhigh(); - if (onoff) - prot = writers++ == 0 ? BUS_SPACE_MAP_LINEAR : 0; - else - prot = --writers == 0 ? - BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_READONLY : 0; - splx(s); - if (prot) { - struct ebus_info *ebi = (struct ebus_info *)handle->bus_cookie; - bus_space_handle_t newaddr; - - err = sbus_bus_map(ebi->ei_bt, 0, - EBUS_PADDR_FROM_REG(&ebi->ei_reg), 8192, prot, - (vaddr_t)ebi->ei_bh, &newaddr); - /* We can panic now or take a datafault later... */ - if (ebi->ei_bh != newaddr) - panic("ebus_wenable: address %p changed to %p", - (void *)(u_long)ebi->ei_bh, - (void *)(u_long)newaddr); - } - return (err); + /* Save info for the clock wenable call. */ + cwi.cwi_bt = bt; + cwi.cwi_size = sz; + todr_handle->bus_cookie = &cwi; + todr_handle->todr_setwen = (ea->ea_memtag == bt) ? + clock_bus_wenable : NULL; } - static void clockattach(node, bt, bh) int node; @@ -430,7 +386,8 @@ clockattach(node, bt, bh) if (idprom == NULL) { idp = getidprom(); if (idp == NULL) - idp = (struct idprom *)((u_long)bh + IDPROM_OFFSET); + idp = (struct idprom *)(bus_space_vaddr(bt, bh) + + IDPROM_OFFSET); idprom = idp; } else idp = idprom; @@ -494,23 +451,25 @@ clockattach_rtc(parent, self, aux) void *aux; { struct ebus_attach_args *ea = aux; - bus_space_tag_t bt = ea->ea_bustag; + bus_space_tag_t bt; todr_chip_handle_t handle; struct rtc_info *rtc; char *model; int sz; - static struct ebus_info ebi; + static struct clock_wenable_info cwi; /* hard code to 8K? */ sz = ea->ea_regs[0].size; - if (ebus_bus_map(bt, - 0, - EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), - sz, - BUS_SPACE_MAP_LINEAR, - 0, - &ebi.ei_bh) != 0) { + if (ebus_bus_map(ea->ea_iotag, 0, + EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), sz, 0, 0, &cwi.cwi_bh) == 0) { + bt = ea->ea_iotag; + } else if (ebus_bus_map(ea->ea_memtag, 0, + EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), sz, + BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_READONLY, + 0, &cwi.cwi_bh) == 0) { + bt = ea->ea_memtag; + } else { printf("%s: can't map register\n", self->dv_xname); return; } @@ -526,7 +485,7 @@ clockattach_rtc(parent, self, aux) * Turn interrupts off, just in case. (Although they shouldn't * be wired to an interrupt controller on sparcs). */ - rtc_write_reg(bt, ebi.ei_bh, + rtc_write_reg(bt, cwi.cwi_bh, MC_REGB, MC_REGB_BINARY | MC_REGB_24HR); /* Setup our todr_handle */ @@ -541,15 +500,15 @@ clockattach_rtc(parent, self, aux) handle->todr_settime = rtc_settime; handle->todr_getcal = rtc_getcal; handle->todr_setcal = rtc_setcal; - handle->todr_setwen = NULL; rtc->rtc_bt = bt; - rtc->rtc_bh = ebi.ei_bh; + rtc->rtc_bh = cwi.cwi_bh; /* Save info for the clock wenable call. */ - ebi.ei_bt = bt; - ebi.ei_reg = ea->ea_regs[0]; - handle->bus_cookie = &ebi; - handle->todr_setwen = ebus_wenable; + cwi.cwi_bt = bt; + cwi.cwi_size = sz; + handle->bus_cookie = &cwi; + handle->todr_setwen = (ea->ea_memtag == bt) ? + clock_bus_wenable : NULL; todr_handle = handle; } @@ -575,9 +534,6 @@ timerattach(parent, self, aux) { struct mainbus_attach_args *ma = aux; u_int *va = ma->ma_address; -#if 0 - volatile int64_t *cnt = NULL, *lim = NULL; -#endif /* * What we should have are 3 sets of registers that reside on @@ -592,11 +548,14 @@ timerattach(parent, self, aux) /* Install the appropriate interrupt vector here */ level10.ih_number = ma->ma_interrupts[0]; level10.ih_clr = (void *)&timerreg_4u.t_clrintr[0]; + level10.ih_map = (void *)&timerreg_4u.t_mapintr[0]; intr_establish(10, &level10); + level14.ih_number = ma->ma_interrupts[1]; level14.ih_clr = (void *)&timerreg_4u.t_clrintr[1]; - + level14.ih_map = (void *)&timerreg_4u.t_mapintr[1]; intr_establish(14, &level14); + printf(" irq vectors %lx and %lx", (u_long)level10.ih_number, (u_long)level14.ih_number); @@ -701,8 +660,8 @@ cpu_initclocks() if (!timerreg_4u.t_timer || !timerreg_4u.t_clrintr) { - printf("No counter-timer -- using %%tick at %ldMHz as system clock.\n", - (long)(cpu_clockrate/1000000)); + printf("No counter-timer -- using %%tick at %ldMHz as " + "system clock.\n", (long)(cpu_clockrate/1000000)); /* We don't have a counter-timer -- use %tick */ level0.ih_clr = 0; /* @@ -719,7 +678,8 @@ cpu_initclocks() /* set the next interrupt time */ tick_increment = cpu_clockrate / hz; #ifdef DEBUG - printf("Using %%tick -- intr in %ld cycles...", tick_increment); + printf("Using %%tick -- intr in %ld cycles...", + tick_increment); #endif next_tick(tick_increment); #ifdef DEBUG @@ -816,8 +776,9 @@ clockintr(cap) t = t * 1000000LL / cpu_clockrate; if (t - clk > hz) { printf("Clock lost an interrupt!\n"); - printf("Actual: %llx Expected: %llx tick %llx tick_base %llx\n", - (long long)t, (long long)clk, (long long)tk, (long long)tick_base); + printf("Actual: %llx Expected: %llx tick %llx " + "tick_base %llx\n", (long long)t, (long long)clk, + (long long)tk, (long long)tick_base); #ifdef DDB Debugger(); #endif @@ -867,7 +828,7 @@ int statintr(cap) void *cap; { - register u_long newint, r, var; + u_long newint, r, var; struct cpu_info *ci = curcpu(); #ifdef NOT_DEBUG @@ -959,7 +920,7 @@ inittodr(base) deltat = -deltat; if (waszero || deltat < 2 * SECDAY) return; - printf("WARNING: clock %s %d days", + printf("WARNING: clock %s %ld days", time.tv_sec < base ? "lost" : "gained", deltat / SECDAY); } printf(" -- CHECK AND RESET THE DATE!\n"); diff --git a/sys/arch/sparc64/sparc64/intr.c b/sys/arch/sparc64/sparc64/intr.c index 7c5ee69c59f..f7d5505d441 100644 --- a/sys/arch/sparc64/sparc64/intr.c +++ b/sys/arch/sparc64/sparc64/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.11 2002/07/23 13:58:23 art Exp $ */ +/* $OpenBSD: intr.c,v 1.12 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: intr.c,v 1.39 2001/07/19 23:38:11 eeh Exp $ */ /* @@ -61,6 +61,9 @@ #include <machine/instr.h> #include <machine/trap.h> +/* Grab interrupt map stuff (what is it doing there???) */ +#include <sparc64/dev/iommureg.h> + /* * The following array is to used by locore.s to map interrupt packets * to the proper IPL to send ourselves a softint. It should be filled @@ -103,8 +106,8 @@ strayintr(fp, vectored) /* If we're in polled mode ignore spurious interrupts */ if ((fp->tf_pil == PIL_SER) /* && swallow_zsintrs */) return; - printf("stray interrupt ipl %u pc=%llx npc=%llx pstate=%b vecttored=%d\n", - fp->tf_pil, (unsigned long long)fp->tf_pc, + printf("stray interrupt ipl %u pc=%llx npc=%llx pstate=%b " + "vecttored=%d\n", fp->tf_pil, (unsigned long long)fp->tf_pc, (unsigned long long)fp->tf_npc, fp->tf_tstate>>TSTATE_PSTATE_SHIFT, PSTATE_BITS, vectored); @@ -238,6 +241,7 @@ intr_establish(level, ih) struct intrhand *ih; { register struct intrhand **p, *q; + u_int64_t m, id; int s; s = splhigh(); @@ -257,7 +261,7 @@ intr_establish(level, ih) */ #ifdef NOT_DEBUG if (!ih->ih_number) { - printf("\nintr_establish: NULL vector fun %p arg %p pil %p\n", + printf("\nintr_establish: NULL vector fun %p arg %p pil %p", ih->ih_fun, ih->ih_arg, ih->ih_number, ih->ih_pil); Debugger(); } @@ -278,7 +282,7 @@ intr_establish(level, ih) * new interrupt handler and interpose it. */ #ifdef DEBUG - printf("intr_establish: intr reused %x\n", ih->ih_number); + printf("\nintr_establish: intr reused %x", ih->ih_number); #endif if (q->ih_fun != intr_list_handler) { @@ -301,14 +305,31 @@ intr_establish(level, ih) nih->ih_next = (struct intrhand *)q->ih_arg; q->ih_arg = (void *)nih; } - -#ifdef NOT_DEBUG +#ifdef DEBUG printf("\nintr_establish: vector %x pil %x mapintr %p " - "clrintr %p fun %p arg %p\n", + "clrintr %p fun %p arg %p target %d", ih->ih_number, ih->ih_pil, (void *)ih->ih_map, (void *)ih->ih_clr, (void *)ih->ih_fun, - (void *)ih->ih_arg); + (void *)ih->ih_arg, (int)(ih->ih_map ? INTTID(*ih->ih_map) : -1)); +#endif + + if(ih->ih_map) { + id = CPU_UPAID; + m = *ih->ih_map; + if(INTTID(m) != id) { + printf("\nintr_establish: changing map 0x%llx -> ", m); + m = (m & ~INTMAP_TID) | (id << INTTID_SHIFT); + *ih->ih_map = m; + printf("0x%llx (id=%llx) ", m, id); + } + } + else { +#ifdef DEBUG + printf( "\n**********************\n" + "********************** intr_establish: no map register\n" + "**********************\n"); #endif + } splx(s); } diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s index 7252612fa5c..cce1da309dc 100644 --- a/sys/arch/sparc64/sparc64/locore.s +++ b/sys/arch/sparc64/sparc64/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.27 2003/01/11 07:07:49 jason Exp $ */ +/* $OpenBSD: locore.s,v 1.28 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $ */ /* @@ -71,6 +71,9 @@ #undef NO_TSB /* Don't use TSB */ #undef SCHED_DEBUG +.register %g2, +.register %g3, + #include "assym.h" #include "ksyms.h" #include <machine/param.h> diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c index bc85519af57..24a97dab2d0 100644 --- a/sys/arch/sparc64/sparc64/machdep.c +++ b/sys/arch/sparc64/sparc64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.54 2002/12/17 23:11:32 millert Exp $ */ +/* $OpenBSD: machdep.c,v 1.55 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: machdep.c,v 1.108 2001/07/24 19:30:14 eeh Exp $ */ /*- @@ -131,14 +131,8 @@ #include <dev/ic/pckbcvar.h> #endif -/* #include "fb.h" */ - -int bus_space_debug = 0; /* This may be used by macros elsewhere. */ -#ifdef DEBUG -#define DPRINTF(l, s) do { if (bus_space_debug & l) printf s; } while (0) -#else -#define DPRINTF(l, s) -#endif +/* This may be used by macros elsewhere. */ +int bus_space_debug = BSDB_ACCESS | BSDB_ASSERT | BSDB_MAP; struct vm_map *exec_map = NULL; extern vaddr_t avail_end; @@ -198,54 +192,6 @@ caddr_t allocsys(caddr_t); void dumpsys(void); void stackdump(void); -/* - * This is the table that tells us how to access different bus space types. - */ -#define BUS_BYPASS_ACCESS_ENABLED 0 -#if BUS_BYPASS_ACCESS_ENABLED == 1 -/* - * Bypass access - */ -int bus_type_asi[] = { - ASI_PHYS_NON_CACHED, /* UPA */ - ASI_PHYS_NON_CACHED, /* SBUS */ - ASI_PHYS_NON_CACHED_LITTLE, /* PCI configuration space */ - ASI_PHYS_NON_CACHED_LITTLE, /* PCI memory space */ - ASI_PHYS_NON_CACHED_LITTLE, /* PCI I/O space */ - 0 -}; - -int bus_stream_asi[] = { - ASI_PHYS_NON_CACHED, /* UPA */ - ASI_PHYS_NON_CACHED, /* SBUS */ - ASI_PHYS_NON_CACHED, /* PCI configuration space */ - ASI_PHYS_NON_CACHED, /* PCI memory space */ - ASI_PHYS_NON_CACHED, /* PCI I/O space */ - 0 -}; -#else -/* - * MMU access - we want to use the MMU for all this.. - */ -int bus_type_asi[] = { - ASI_PRIMARY, /* UPA */ - ASI_PRIMARY, /* SBUS */ - ASI_PHYS_NON_CACHED_LITTLE, /* PCI configuration space */ - ASI_PRIMARY, /* PCI memory space */ - ASI_PRIMARY, /* PCI I/O space */ - 0 -}; - -int bus_stream_asi[] = { - ASI_PRIMARY, /* UPA */ - ASI_PRIMARY, /* SBUS */ - ASI_PHYS_NON_CACHED, /* PCI configuration space */ - ASI_PRIMARY_LITTLE, /* PCI memory space */ - ASI_PRIMARY_LITTLE, /* PCI I/O space */ - 0 -}; -#endif - #if (NPCKBC > 0) && (NPCKBD == 0) /* * This is called by the pckbc driver if no pckbd is configured. @@ -291,7 +237,6 @@ cpu_startup() printf(version); /*identifycpu();*/ printf("total memory = %ld\n", (long)physmem * PAGE_SIZE); - /* * Find out how much space we need, allocate it, * and then give everything true virtual addresses. @@ -400,8 +345,8 @@ allocsys(caddr_t v) } /* Restrict to at most 30% filled kvm */ if (nbuf * MAXBSIZE > - (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) * 3 / 10) - nbuf = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / + (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) * 3 / 10) + nbuf = (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) / MAXBSIZE * 3 / 10; /* More buffer pages than fits into the buffers is senseless. */ @@ -543,14 +488,14 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) >= 0)) { /* * bootargs is of the form: [kernelname] [args...] - * It can be the empty string if we booted from the default - * kernel name. + * It can be the empty string if we booted from the + * default kernel name. */ for (cp = bootargs; *cp && *cp != ' ' && *cp != '\t' && *cp != '\n'; cp++); *cp = 0; - /* Now we've separated out the kernel name from the args */ + /* Now we've separated the kernel name from the args */ cp = bootargs; if (*cp == 0 || *cp == '-') /* @@ -683,7 +628,8 @@ sendsig(catcher, sig, mask, code, type, val) * instruction to halt it in its tracks. */ #ifdef DEBUG - printf("sendsig: stack was trashed trying to send sig %d, sending SIGILL\n", sig); + printf("sendsig: stack was trashed trying to send sig %d, " + "sending SIGILL\n", sig); #endif sigexit(p, SIGILL); /* NOTREACHED */ @@ -719,7 +665,7 @@ sendsig(catcher, sig, mask, code, type, val) /* ARGSUSED */ int sys_sigreturn(p, v, retval) - register struct proc *p; + struct proc *p; void *v; register_t *retval; { @@ -727,7 +673,7 @@ sys_sigreturn(p, v, retval) syscallarg(struct sigcontext *) sigcntxp; } */ *uap = v; struct sigcontext sc, *scp; - register struct trapframe64 *tf; + struct trapframe64 *tf; int error = EINVAL; /* First ensure consistent stack state (see sendsig). */ @@ -735,7 +681,8 @@ sys_sigreturn(p, v, retval) if (rwindow_save(p)) { #ifdef DEBUG - printf("sigreturn: rwindow_save(%p) failed, sending SIGILL\n", p); + printf("sigreturn: rwindow_save(%p) failed, sending SIGILL\n", + p); #endif sigexit(p, SIGILL); } @@ -934,11 +881,11 @@ reserve_dumppages(p) void dumpsys() { - register int psize; + int psize; daddr_t blkno; - register int (*dump)(dev_t, daddr_t, caddr_t, size_t); + int (*dump)(dev_t, daddr_t, caddr_t, size_t); int error = 0; - register struct mem_region *mp; + struct mem_region *mp; extern struct mem_region *mem; /* copy registers to memory */ @@ -1454,7 +1401,7 @@ _bus_dmamap_sync(t, map, offset, len, ops) * Don't really need to do anything, but flush any pending * writes anyway. */ - __asm("membar #Sync" : ); + membar(Sync); } if (ops & BUS_DMASYNC_POSTREAD) { /* Invalidate the vcache */ @@ -1688,44 +1635,43 @@ struct sparc_bus_dma_tag mainbus_dma_tag = { /* * Base bus space handlers. */ -static int sparc_bus_map( bus_space_tag_t, bus_type_t, bus_addr_t, - bus_size_t, int, vaddr_t, - bus_space_handle_t *); -static int sparc_bus_unmap(bus_space_tag_t, bus_space_handle_t, - bus_size_t); -static int sparc_bus_subregion(bus_space_tag_t, bus_space_handle_t, - bus_size_t, bus_size_t, - bus_space_handle_t *); -static paddr_t sparc_bus_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int); -static void *sparc_mainbus_intr_establish(bus_space_tag_t, int, int, - int, int (*)(void *), - void *); -static void sparc_bus_barrier(bus_space_tag_t, bus_space_handle_t, - bus_size_t, bus_size_t, int); -static int sparc_bus_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t, - bus_size_t, bus_size_t, bus_size_t, int, - bus_addr_t *, bus_space_handle_t *); -static void sparc_bus_free(bus_space_tag_t, bus_space_handle_t, - bus_size_t); +int sparc_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t, bus_size_t, + int, bus_space_handle_t *); +int sparc_bus_protect(bus_space_tag_t, bus_space_tag_t, bus_space_handle_t, + bus_size_t, int); +int sparc_bus_unmap(bus_space_tag_t, bus_space_tag_t, bus_space_handle_t, + bus_size_t); +int sparc_bus_subregion(bus_space_tag_t, bus_space_tag_t, bus_space_handle_t, + bus_size_t, bus_size_t, bus_space_handle_t *); +paddr_t sparc_bus_mmap(bus_space_tag_t, bus_space_tag_t, bus_addr_t, off_t, + int, int); +void *sparc_mainbus_intr_establish(bus_space_tag_t, bus_space_tag_t, int, int, + int, int (*)(void *), void *); +void sparc_bus_barrier(bus_space_tag_t, bus_space_tag_t, bus_space_handle_t, + bus_size_t, bus_size_t, int); +int sparc_bus_alloc(bus_space_tag_t, bus_space_tag_t, bus_addr_t, bus_addr_t, + bus_size_t, bus_size_t, bus_size_t, int, bus_addr_t *, + bus_space_handle_t *); +void sparc_bus_free(bus_space_tag_t, bus_space_tag_t, bus_space_handle_t, + bus_size_t); vaddr_t iobase = IODEV_BASE; struct extent *io_space = NULL; int -sparc_bus_map(t, iospace, addr, size, flags, vaddr, hp) - bus_space_tag_t t; - bus_type_t iospace; - bus_addr_t addr; - bus_size_t size; - vaddr_t vaddr; - bus_space_handle_t *hp; +sparc_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) { vaddr_t v; u_int64_t pa; paddr_t pm_flags = 0; vm_prot_t pm_prot = VM_PROT_READ; - t->type = iospace; + if (flags & BUS_SPACE_MAP_PROMADDRESS) { + hp->bh_ptr = addr; + return (0); + } + if (iobase == NULL) iobase = IODEV_BASE; if (io_space == NULL) @@ -1733,67 +1679,83 @@ sparc_bus_map(t, iospace, addr, size, flags, vaddr, hp) * And set up IOSPACE extents. */ io_space = extent_create("IOSPACE", - (u_long)IODEV_BASE, (u_long)IODEV_END, - M_DEVBUF, 0, 0, EX_NOWAIT); - - + (u_long)IODEV_BASE, (u_long)IODEV_END, M_DEVBUF, 0, 0, + EX_NOWAIT); size = round_page(size); if (size == 0) { - printf("sparc_bus_map: zero size\n"); + char buf[80]; + bus_space_render_tag(t0, buf, sizeof buf); + printf("\nsparc_bus_map: zero size on %s", buf); return (EINVAL); } - switch (iospace) { - case PCI_CONFIG_BUS_SPACE: - /* - * PCI config space is special. - * - * It's really big and seldom used. In order not to run - * out of IO mappings, config space will not be mapped in, - * rather it will be accessed through MMU bypass ASI accesses. - */ - if (flags & BUS_SPACE_MAP_LINEAR) return (-1); - *hp = (bus_space_handle_t)addr; - if (!vaddr) return (0); - /* FALLTHROUGH */ - case PCI_IO_BUS_SPACE: - pm_flags = PMAP_LITTLE; - break; - case PCI_MEMORY_BUS_SPACE: - pm_flags = PMAP_LITTLE; - break; - default: - pm_flags = 0; - break; + + if ( (LITTLE_ASI(t0->asi) && LITTLE_ASI(t0->sasi)) || + (PHYS_ASI(t0->asi) != PHYS_ASI(t0->sasi)) ) { + char buf[80]; + bus_space_render_tag(t0, buf, sizeof buf); + printf("\nsparc_bus_map: mismatched ASIs on %s: asi=%x sasi=%x", + buf, t0->asi, t0->sasi); + } + + if (PHYS_ASI(t0->asi)) { +#ifdef BUS_SPACE_DEBUG + char buf[80]; + bus_space_render_tag(t0, buf, sizeof buf); + BUS_SPACE_PRINTF(BSDB_MAP, + ("\nsparc_bus_map: physical tag %s asi %x sasi %x flags %x " + "paddr %016llx size %016llx", + buf, + (int)t0->asi, (int)t0->sasi, (int)flags, + (unsigned long long)addr, (unsigned long long)size)); +#endif /* BUS_SPACE_DEBUG */ + if (flags & BUS_SPACE_MAP_LINEAR) { + char buf[80]; + bus_space_render_tag(t0, buf, sizeof buf); + printf("\nsparc_bus_map: linear mapping requested on physical bus %s", buf); + return (EINVAL); + } + + hp->bh_ptr = addr; + return (0); } - if (!(flags & BUS_SPACE_MAP_CACHEABLE)) pm_flags |= PMAP_NC; + if (LITTLE_ASI(t0->sasi) && !LITTLE_ASI(t0->asi)) + pm_flags |= PMAP_LITTLE; - if (vaddr) - v = trunc_page(vaddr); - else { - int err; - if ((err = extent_alloc(io_space, size, NBPG, - 0, 0, EX_NOWAIT|EX_BOUNDZERO, - (u_long *)&v))) - panic("sparc_bus_map: cannot allocate io_space: %d", err); + if ((flags & BUS_SPACE_MAP_CACHEABLE) == 0) + pm_flags |= PMAP_NC; + + { /* scope */ + int err = extent_alloc(io_space, size, NBPG, 0, 0, + EX_NOWAIT | EX_BOUNDZERO, (u_long *)&v); + if (err) + panic("sparc_bus_map: cannot allocate io_space: %d", + err); } /* note: preserve page offset */ - *hp = (bus_space_handle_t)(v | ((u_long)addr & PGOFSET)); + hp->bh_ptr = v | ((u_long)addr & PGOFSET); pa = addr & ~PAGE_MASK; /* = trunc_page(addr); Will drop high bits */ - if (!(flags&BUS_SPACE_MAP_READONLY)) pm_prot |= VM_PROT_WRITE; - - DPRINTF(BSDB_MAP, ("\nsparc_bus_map: type %x flags %x " - "addr %016llx size %016llx virt %llx paddr %016llx\n", - (int)iospace, (int) flags, (unsigned long long)addr, - (unsigned long long)size, (unsigned long long)*hp, - (unsigned long long)pa)); + if ((flags & BUS_SPACE_MAP_READONLY) == 0) + pm_prot |= VM_PROT_WRITE; + +#ifdef BUS_SPACE_DEBUG + { /* scope */ + char buf[80]; + bus_space_render_tag(t0, buf, sizeof buf); + BUS_SPACE_PRINTF(BSDB_MAP, ("\nsparc_bus_map: tag %s type %x " + "flags %x addr %016llx size %016llx virt %llx paddr " + "%016llx", buf, (int)t->default_type, (int) flags, + (unsigned long long)addr, (unsigned long long)size, + (unsigned long long)hp->bh_ptr, (unsigned long long)pa)); + } +#endif /* BUS_SPACE_DEBUG */ do { - DPRINTF(BSDB_MAP, ("sparc_bus_map: phys %llx virt %p hp %llx\n", - (unsigned long long)pa, (char *)v, - (unsigned long long)*hp)); + BUS_SPACE_PRINTF(BSDB_MAPDETAIL, ("\nsparc_bus_map: phys %llx " + "virt %p hp->bh_ptr %llx", (unsigned long long)pa, + (char *)v, (unsigned long long)hp->bh_ptr)); pmap_enter(pmap_kernel(), v, pa | pm_flags, pm_prot, pm_prot|PMAP_WIRED); v += PAGE_SIZE; @@ -1804,67 +1766,117 @@ sparc_bus_map(t, iospace, addr, size, flags, vaddr, hp) } int -sparc_bus_subregion(tag, handle, offset, size, nhandlep) - bus_space_tag_t tag; - bus_space_handle_t handle; - bus_size_t offset; - bus_size_t size; - bus_space_handle_t *nhandlep; +sparc_bus_subregion(bus_space_tag_t tag, bus_space_tag_t tag0, + bus_space_handle_t handle, bus_size_t offset, bus_size_t size, + bus_space_handle_t *nhandlep) { - *nhandlep = handle + offset; + *nhandlep = handle; + nhandlep->bh_ptr += offset; return (0); } +/* stolen from uvm_chgkprot() */ +/* + * Change protections on kernel pages from addr to addr+len + * (presumably so debugger can plant a breakpoint). + * + * We force the protection change at the pmap level. If we were + * to use vm_map_protect a change to allow writing would be lazily- + * applied meaning we would still take a protection fault, something + * we really don't want to do. It would also fragment the kernel + * map unnecessarily. We cannot use pmap_protect since it also won't + * enforce a write-enable request. Using pmap_enter is the only way + * we can ensure the change takes place properly. + */ int -sparc_bus_unmap(t, bh, size) - bus_space_tag_t t; - bus_size_t size; - bus_space_handle_t bh; +sparc_bus_protect(bus_space_tag_t t, bus_space_tag_t t0, bus_space_handle_t h, + bus_size_t size, int flags) { - vaddr_t va = trunc_page((vaddr_t)bh); + vm_prot_t prot; + paddr_t pm_flags = 0; + paddr_t pa; + vaddr_t sva, eva; + void* addr = bus_space_vaddr(t0, h); + + if (addr == 0) { + printf("\nsparc_bus_protect: null address"); + return (EINVAL); + } + + if (PHYS_ASI(t0->asi)) { + printf("\nsparc_bus_protect: physical ASI"); + return (EINVAL); + } + + prot = (flags & BUS_SPACE_MAP_READONLY) ? + VM_PROT_READ : VM_PROT_READ | VM_PROT_WRITE; + if ((flags & BUS_SPACE_MAP_CACHEABLE) == 0) + pm_flags |= PMAP_NC; + + eva = round_page((vaddr_t)addr + size); + for (sva = trunc_page((vaddr_t)addr); sva < eva; sva += PAGE_SIZE) { + /* + * Extract physical address for the page. + * We use a cheezy hack to differentiate physical + * page 0 from an invalid mapping, not that it + * really matters... + */ + if (pmap_extract(pmap_kernel(), sva, &pa) == FALSE) + panic("bus_space_protect(): invalid page"); + pmap_enter(pmap_kernel(), sva, pa | pm_flags, prot, prot | PMAP_WIRED); + } + pmap_update(pmap_kernel()); + + return (0); +} + +int +sparc_bus_unmap(bus_space_tag_t t, bus_space_tag_t t0, bus_space_handle_t bh, + bus_size_t size) +{ + vaddr_t va = trunc_page((vaddr_t)bh.bh_ptr); vaddr_t endva = va + round_page(size); + int error; - int error = extent_free(io_space, va, size, EX_NOWAIT); - if (error) printf("sparc_bus_unmap: extent free says %d\n", error); + if (PHYS_ASI(t0->asi)) + return (0); + + error = extent_free(io_space, va, size, EX_NOWAIT); + if (error) + printf("\nsparc_bus_unmap: extent free says %d", error); pmap_remove(pmap_kernel(), va, endva); return (0); } paddr_t -sparc_bus_mmap(t, paddr, off, prot, flags) - bus_space_tag_t t; - bus_addr_t paddr; - off_t off; - int prot; - int flags; +sparc_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr, + off_t off, int prot, int flags) { + if (PHYS_ASI(t0->asi)) { + printf("\nsparc_bus_mmap: physical ASI"); + return (NULL); + } + /* Devices are un-cached... although the driver should do that */ - return ((paddr+off)|PMAP_NC); + return ((paddr + off) | PMAP_NC); } /* * Establish a temporary bus mapping for device probing. */ int -bus_space_probe(tag, btype, paddr, size, offset, flags, callback, arg) - bus_space_tag_t tag; - bus_type_t btype; - bus_addr_t paddr; - bus_size_t size; - size_t offset; - int flags; - int (*callback)(void *, void *); - void *arg; +bus_space_probe(bus_space_tag_t tag, bus_addr_t paddr, bus_size_t size, + size_t offset, int flags, int (*callback)(void *, void *), void *arg) { bus_space_handle_t bh; paddr_t tmp; int result; - if (bus_space_map2(tag, btype, paddr, size, flags, NULL, &bh) != 0) + if (bus_space_map(tag, paddr, size, flags, &bh) != 0) return (0); - tmp = (paddr_t)bh; - result = (probeget(tmp + offset, bus_type_asi[tag->type], size) != -1); + tmp = bh.bh_ptr; + result = (probeget(tmp + offset, tag->asi, size) != -1); if (result && callback != NULL) result = (*callback)((char *)(u_long)tmp, arg); bus_space_unmap(tag, bh, size); @@ -1873,13 +1885,8 @@ bus_space_probe(tag, btype, paddr, size, offset, flags, callback, arg) void * -sparc_mainbus_intr_establish(t, pil, level, flags, handler, arg) - bus_space_tag_t t; - int pil; - int level; - int flags; - int (*handler)(void *); - void *arg; +sparc_mainbus_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int pil, + int level, int flags, int (*handler)(void *), void *arg) { struct intrhand *ih; @@ -1895,12 +1902,8 @@ sparc_mainbus_intr_establish(t, pil, level, flags, handler, arg) } void -sparc_bus_barrier (t, h, offset, size, flags) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t offset; - bus_size_t size; - int flags; +sparc_bus_barrier(bus_space_tag_t t, bus_space_tag_t t0, bus_space_handle_t h, + bus_size_t offset, bus_size_t size, int flags) { /* * We have lots of alternatives depending on whether we're @@ -1909,55 +1912,270 @@ sparc_bus_barrier (t, h, offset, size, flags) * generic are #Sync and #MemIssue. I'll use #Sync for safety. */ if (flags == (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)) - __asm("membar #Sync" : ); + membar(Sync); else if (flags == BUS_SPACE_BARRIER_READ) - __asm("membar #Sync" : ); + membar(Sync); else if (flags == BUS_SPACE_BARRIER_WRITE) - __asm("membar #Sync" : ); + membar(Sync); else printf("sparc_bus_barrier: unknown flags\n"); return; } int -sparc_bus_alloc(t, rs, re, s, a, b, f, ap, hp) - bus_space_tag_t t; - bus_addr_t rs; - bus_addr_t re; - bus_size_t s; - bus_size_t a; - bus_size_t b; - int f; - bus_addr_t *ap; - bus_space_handle_t *hp; +sparc_bus_alloc(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t rs, + bus_addr_t re, bus_size_t s, bus_size_t a, bus_size_t b, int f, + bus_addr_t *ap, bus_space_handle_t *hp) { return (ENOTTY); } void -sparc_bus_free(t, h, s) - bus_space_tag_t t; - bus_space_handle_t h; - bus_size_t s; +sparc_bus_free(bus_space_tag_t t, bus_space_tag_t t0, bus_space_handle_t h, + bus_size_t s) { return; } - -struct sparc_bus_space_tag mainbus_space_tag = { +static const struct sparc_bus_space_tag _mainbus_space_tag = { NULL, /* cookie */ NULL, /* parent bus tag */ UPA_BUS_SPACE, /* type */ + ASI_PRIMARY, + ASI_PRIMARY, + "mainbus", sparc_bus_alloc, sparc_bus_free, sparc_bus_map, /* bus_space_map */ + sparc_bus_protect, /* bus_space_protect */ sparc_bus_unmap, /* bus_space_unmap */ sparc_bus_subregion, /* bus_space_subregion */ sparc_bus_barrier, /* bus_space_barrier */ sparc_bus_mmap, /* bus_space_mmap */ sparc_mainbus_intr_establish /* bus_intr_establish */ }; +const bus_space_tag_t mainbus_space_tag = &_mainbus_space_tag; struct cfdriver mainbus_cd = { NULL, "mainbus", DV_DULL }; + +#define _BS_PRECALL(t,f) \ + while (t->f == NULL) \ + t = t->parent; +#define _BS_POSTCALL + +#define _BS_CALL(t,f) \ + (*(t)->f) + +int +bus_space_alloc(bus_space_tag_t t, bus_addr_t rs, bus_addr_t re, bus_size_t s, + bus_size_t a, bus_size_t b, int f, bus_addr_t *ap, bus_space_handle_t *hp) +{ + const bus_space_tag_t t0 = t; + int ret; + + _BS_PRECALL(t, sparc_bus_alloc); + ret = _BS_CALL(t, sparc_bus_alloc)(t, t0, rs, re, s, a, b, f, ap, hp); + _BS_POSTCALL; + return ret; +} + +void +bus_space_free(bus_space_tag_t t, bus_space_handle_t h, bus_size_t s) +{ + const bus_space_tag_t t0 = t; + + _BS_PRECALL(t, sparc_bus_free); + _BS_CALL(t, sparc_bus_free)(t, t0, h, s); + _BS_POSTCALL; +} + +int +bus_space_map(bus_space_tag_t t, bus_addr_t a, bus_size_t s, int f, + bus_space_handle_t *hp) +{ + const bus_space_tag_t t0 = t; + int ret; + + _BS_PRECALL(t, sparc_bus_map); + ret = _BS_CALL(t, sparc_bus_map)(t, t0, a, s, f, hp); + _BS_POSTCALL; +#ifdef BUS_SPACE_DEBUG + if(s == 0) { + char buf[128]; + bus_space_render_tag(t, buf, sizeof buf); + printf("\n********** bus_space_map: requesting " + "zero-length mapping on bus %p:%s", + t, buf); + } + hp->bh_flags = 0; + if (ret == 0) { + hp->bh_size = s; + hp->bh_tag = t0; + } else { + hp->bh_size = 0; + hp->bh_tag = NULL; + } +#endif /* BUS_SPACE_DEBUG */ + return (ret); +} + +int +bus_space_protect(bus_space_tag_t t, bus_space_handle_t h, bus_size_t s, int f) +{ + const bus_space_tag_t t0 = t; + int ret; + + _BS_PRECALL(t, sparc_bus_protect); + ret = _BS_CALL(t, sparc_bus_protect)(t, t0, h, s, f); + _BS_POSTCALL; + + return (ret); +} + +int +bus_space_unmap(bus_space_tag_t t, bus_space_handle_t h, bus_size_t s) +{ + const bus_space_tag_t t0 = t; + int ret; + + _BS_PRECALL(t, sparc_bus_unmap); + BUS_SPACE_ASSERT(t0, h, 0, 1); +#ifdef BUS_SPACE_DEBUG + if(h.bh_size != s) { + char buf[128]; + bus_space_render_tag(t0, buf, sizeof buf); + printf("\n********* bus_space_unmap: %p:%s, map/unmap " + "size mismatch (%llx != %llx)", + t, buf, h.bh_size, s); + } +#endif /* BUS_SPACE_DEBUG */ + ret = _BS_CALL(t, sparc_bus_unmap)(t, t0, h, s); + _BS_POSTCALL; + return (ret); +} + +int +bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, + bus_size_t s, bus_space_handle_t *hp) +{ + const bus_space_tag_t t0 = t; + int ret; + + _BS_PRECALL(t, sparc_bus_subregion); + BUS_SPACE_ASSERT(t0, h, o, 1); +#ifdef BUS_SPACE_DEBUG + if(h.bh_size < o + s) { + char buf[128]; + bus_space_render_tag(t0, buf, sizeof buf); + printf("\n********** bus_space_subregion: " + "%p:%s, %llx < %llx + %llx", + t0, buf, h.bh_size, o, s); + hp->bh_size = 0; + hp->bh_tag = NULL; + return (EINVAL); + } +#endif /* BUS_SPACE_DEBUG */ + ret = _BS_CALL(t, sparc_bus_subregion)(t, t0, h, o, s, hp); + _BS_POSTCALL; +#ifdef BUS_SPACE_DEBUG + if (ret == 0) { + hp->bh_size = s; + hp->bh_tag = t0; + } else { + hp->bh_size = 0; + hp->bh_tag = NULL; + } +#endif /* BUS_SPACE_DEBUG */ + return (ret); +} + +paddr_t +bus_space_mmap(bus_space_tag_t t, bus_addr_t a, off_t o, int p, int f) +{ + const bus_space_tag_t t0 = t; + paddr_t ret; + + _BS_PRECALL(t, sparc_bus_mmap); + ret = _BS_CALL(t, sparc_bus_mmap)(t, t0, a, o, p, f); + _BS_POSTCALL; + return (ret); +} + +void * +bus_intr_establish(bus_space_tag_t t, int p, int l, int f, int (*h)(void *), + void *a) +{ + const bus_space_tag_t t0 = t; + void *ret; + + _BS_PRECALL(t, sparc_intr_establish); + ret = _BS_CALL(t, sparc_intr_establish)(t, t0, p, l, f, h, a); + _BS_POSTCALL; + return (ret); +} + +/* XXXX Things get complicated if we use unmapped register accesses. */ +void * +bus_space_vaddr(bus_space_tag_t t, bus_space_handle_t h) +{ + BUS_SPACE_ASSERT(t, h, 0, 1); + if(t->asi == ASI_PRIMARY || t->asi == ASI_PRIMARY_LITTLE) + return ((void *)(vaddr_t)(h.bh_ptr)); + +#ifdef BUS_SPACE_DEBUG + { /* Scope */ + char buf[64]; + bus_space_render_tag(t, buf, sizeof buf); + printf("\nbus_space_vaddr: no vaddr for %p:%s (asi=%x)", + t, buf, t->asi); + } +#endif + + return (NULL); +} + +void +bus_space_render_tag(bus_space_tag_t t, char* buf, size_t len) +{ + buf[0] = '\0'; + if (t->parent) + bus_space_render_tag(t->parent, buf, len); + + strlcat(buf, "/", len); + strlcat(buf, t->name, len); +} + +#ifdef BUS_SPACE_DEBUG + +void +bus_space_assert(bus_space_tag_t t, const bus_space_handle_t *h, bus_size_t o, + int n) +{ + if (h->bh_tag != t) { + char buf1[128]; + char buf2[128]; + bus_space_render_tag(t, buf1, sizeof buf1); + bus_space_render_tag(h->bh_tag, buf2, sizeof buf2); + printf("\n********** bus_space_assert: wrong tag (%p:%s, " + "expecting %p:%s) ", t, buf1, h->bh_tag, buf2); + } + + if (o >= h->bh_size) { + char buf[128]; + bus_space_render_tag(t, buf, sizeof buf); + printf("\n********** bus_space_assert: bus %p:%s, offset " + "(%llx) out of mapping range (%llx) ", t, buf, o, + h->bh_size); + } + + if (o & (n - 1)) { + char buf[128]; + bus_space_render_tag(t, buf, sizeof buf); + printf("\n********** bus_space_assert: bus %p:%s, offset " + "(%llx) incorrect alignment (%d) ", t, buf, o, n); + } +} + +#endif /* BUS_SPACE_DEBUG */ diff --git a/sys/arch/sparc64/sparc64/pmap.c b/sys/arch/sparc64/sparc64/pmap.c index 105cf046ed2..41ca26556b9 100644 --- a/sys/arch/sparc64/sparc64/pmap.c +++ b/sys/arch/sparc64/sparc64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.21 2002/10/12 02:03:45 krw Exp $ */ +/* $OpenBSD: pmap.c,v 1.22 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: pmap.c,v 1.107 2001/08/31 16:47:41 eeh Exp $ */ #undef NO_VCACHE /* Don't forget the locked TLB in dostart */ /* @@ -134,17 +134,17 @@ static int pseg_set(struct pmap* pm, vaddr_t addr, int64_t tte, paddr_t spare) { if (!(pdir = (paddr_t *)ldda(&pm->pm_segs[va_to_seg(addr)], ASI_PHYS_CACHED))) { if (!spare) return (1); - stda(&pm->pm_segs[va_to_seg(addr)], ASI_PHYS_CACHED, spare); + stxa_sync(&pm->pm_segs[va_to_seg(addr)], ASI_PHYS_CACHED, spare); pdir = spare; spare = NULL; } if (!(ptbl = (paddr_t *)ldda(&pdir[va_to_dir(addr)], ASI_PHYS_CACHED))) { if (!spare) return (1); - stda(&pdir[va_to_dir(addr)], ASI_PHYS_CACHED, spare); + stxa_sync(&pdir[va_to_dir(addr)], ASI_PHYS_CACHED, spare); ptbl = spare; spare = NULL; } - stda(&ptbl[va_to_pte(addr)], ASI_PHYS_CACHED, tte); + stxa_sync(&ptbl[va_to_pte(addr)], ASI_PHYS_CACHED, tte); return (0); } @@ -155,13 +155,13 @@ static paddr_t pseg_find(struct pmap* pm, vaddr_t addr, paddr_t spare) { if (!(pdir = (paddr_t *)ldda(&pm->pm_segs[va_to_seg(addr)], ASI_PHYS_CACHED))) { if (!spare) return (1); - stda(&pm->pm_segs[va_to_seg(addr)], ASI_PHYS_CACHED, spare); + stxa_sync(&pm->pm_segs[va_to_seg(addr)], ASI_PHYS_CACHED, spare); pdir = spare; spare = NULL; } if (!(ptbl = (paddr_t *)ldda(&pdir[va_to_dir(addr)], ASI_PHYS_CACHED))) { if (!spare) return (1); - stda(&pdir[va_to_dir(addr)], ASI_PHYS_CACHED, spare); + stxa_sync(&pdir[va_to_dir(addr)], ASI_PHYS_CACHED, spare); ptbl = spare; spare = NULL; } @@ -1100,7 +1100,7 @@ remap_data: bzero(tsb_immu, TSBSIZE); BDPRINTF(PDB_BOOT1, ("firstaddr after TSB=%lx\r\n", (u_long)firstaddr)); - BDPRINTF(PDB_BOOT1, ("TSB allocated at %p size %08x\r\n", (void *)tsb, + BDPRINTF(PDB_BOOT1, ("TSB allocated at %p size %08x\r\n", (void *)tsb_dmmu, (int)TSBSIZE)); first_phys_addr = mem->start; @@ -2190,7 +2190,8 @@ pmap_enter(pm, va, pa, prot, flags) */ s = splvm(); simple_lock(&pm->pm_lock); - if ((tte.data = pseg_get(pm, va))<0) { + tte.data = pseg_get(pm, va); + if (tte.data & TLB_V) { simple_unlock(&pm->pm_lock); pmap_remove(pm, va, va+NBPG-1); simple_lock(&pm->pm_lock); diff --git a/sys/arch/sparc64/sparc64/trap.c b/sys/arch/sparc64/sparc64/trap.c index 5c8f0273ceb..654c40133ff 100644 --- a/sys/arch/sparc64/sparc64/trap.c +++ b/sys/arch/sparc64/sparc64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.23 2002/10/12 01:09:43 krw Exp $ */ +/* $OpenBSD: trap.c,v 1.24 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: trap.c,v 1.73 2001/08/09 01:03:01 eeh Exp $ */ /* @@ -928,8 +928,6 @@ data_access_error(tf, type, afva, afsr, sfva, sfsr) u_quad_t sticks; union sigval sv; - sv.sival_ptr = (void *)pc; - uvmexp.traps++; if ((p = curproc) == NULL) /* safety check */ p = &proc0; @@ -938,6 +936,8 @@ data_access_error(tf, type, afva, afsr, sfva, sfsr) pc = tf->tf_pc; tstate = tf->tf_tstate; + sv.sival_ptr = (void *)pc; + onfault = p->p_addr ? (long)p->p_addr->u_pcb.pcb_onfault : 0; printf("data error type %x sfsr=%lx sfva=%lx afsr=%lx afva=%lx tf=%p\n", type, sfsr, sfva, afsr, afva, tf); diff --git a/sys/dev/sbus/apio.c b/sys/dev/sbus/apio.c index 239ad949dd5..bde2325a5e1 100644 --- a/sys/dev/sbus/apio.c +++ b/sys/dev/sbus/apio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: apio.c,v 1.2 2002/04/08 17:49:42 jason Exp $ */ +/* $OpenBSD: apio.c,v 1.3 2003/02/17 01:29:20 henric Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -175,7 +175,7 @@ apio_print(aux, name) void *aux; const char *name; { - struct apio_attach_args *aaa; + struct apio_attach_args *aaa = aux; if (name != NULL) printf("%s at %s", aaa->aaa_name, name); diff --git a/sys/dev/sbus/asio.c b/sys/dev/sbus/asio.c index 7d42e909f29..ed4dc00f389 100644 --- a/sys/dev/sbus/asio.c +++ b/sys/dev/sbus/asio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asio.c,v 1.5 2002/04/08 17:49:42 jason Exp $ */ +/* $OpenBSD: asio.c,v 1.6 2003/02/17 01:29:20 henric Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -182,7 +182,7 @@ asio_print(aux, name) void *aux; const char *name; { - struct asio_attach_args *aaa; + struct asio_attach_args *aaa = aux; if (name != NULL) printf("%s at %s", aaa->aaa_name, name); @@ -231,7 +231,7 @@ com_asio_attach(parent, self, aux) sc->sc_iot = aaa->aaa_iot; sc->sc_ioh = aaa->aaa_ioh; - sc->sc_iobase = sc->sc_ioh; + sc->sc_iobase = 0; /* XXX WTF is iobase for? It used to be the lower 32 bits of ioh's vaddr... */ sc->sc_hwflags = 0; sc->sc_swflags = 0; sc->sc_frequency = BAUD_BASE; diff --git a/sys/dev/sbus/be.c b/sys/dev/sbus/be.c index ce8734d2464..998e81a56ab 100644 --- a/sys/dev/sbus/be.c +++ b/sys/dev/sbus/be.c @@ -1,4 +1,4 @@ -/* $OpenBSD: be.c,v 1.9 2002/06/14 21:34:59 todd Exp $ */ +/* $OpenBSD: be.c,v 1.10 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: be.c,v 1.26 2001/03/20 15:39:20 pk Exp $ */ /*- @@ -251,8 +251,8 @@ beattach(parent, self, aux) return; } - if (bus_space_map2(sa->sa_bustag, - (bus_type_t)sa->sa_reg[0].sbr_slot, + if (sbus_bus_map(sa->sa_bustag, + sa->sa_reg[0].sbr_slot, (bus_addr_t)sa->sa_reg[0].sbr_offset, (bus_size_t)sa->sa_reg[0].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_cr) != 0) { @@ -260,8 +260,8 @@ beattach(parent, self, aux) return; } - if (bus_space_map2(sa->sa_bustag, - (bus_type_t)sa->sa_reg[1].sbr_slot, + if (sbus_bus_map(sa->sa_bustag, + sa->sa_reg[1].sbr_slot, (bus_addr_t)sa->sa_reg[1].sbr_offset, (bus_size_t)sa->sa_reg[1].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_br) != 0) { @@ -269,8 +269,8 @@ beattach(parent, self, aux) return; } - if (bus_space_map2(sa->sa_bustag, - (bus_type_t)sa->sa_reg[2].sbr_slot, + if (sbus_bus_map(sa->sa_bustag, + sa->sa_reg[2].sbr_slot, (bus_addr_t)sa->sa_reg[2].sbr_offset, (bus_size_t)sa->sa_reg[2].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_tr) != 0) { diff --git a/sys/dev/sbus/cs4231.c b/sys/dev/sbus/cs4231.c index 88d8b47c1ff..c530986f2c6 100644 --- a/sys/dev/sbus/cs4231.c +++ b/sys/dev/sbus/cs4231.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cs4231.c,v 1.15 2002/10/04 01:51:45 jason Exp $ */ +/* $OpenBSD: cs4231.c,v 1.16 2003/02/17 01:29:20 henric Exp $ */ /* * Copyright (c) 1999 Jason L. Wright (jason@thought.net) @@ -250,11 +250,11 @@ cs4231_attach(parent, self, aux) } if (sbus_bus_map(sa->sa_bustag, - (bus_type_t)sa->sa_reg[0].sbr_slot, + sa->sa_reg[0].sbr_slot, (bus_addr_t)sa->sa_reg[0].sbr_offset, (bus_size_t)sa->sa_reg[0].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_regs) != 0) { - printf(": couldn't map registers\n", self->dv_xname); + printf(": couldn't map registers\n"); return; } @@ -1548,7 +1548,7 @@ cs4231_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); } @@ -1613,7 +1613,7 @@ cs4231_trigger_input(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_input: bad addr: %x\n", + printf("%s: trigger_input: bad addr: %p\n", sc->sc_dev.dv_xname, start); return (EINVAL); } diff --git a/sys/dev/sbus/dma_sbus.c b/sys/dev/sbus/dma_sbus.c index 1f6420f80c7..7feaed06a80 100644 --- a/sys/dev/sbus/dma_sbus.c +++ b/sys/dev/sbus/dma_sbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dma_sbus.c,v 1.7 2002/03/14 03:16:07 millert Exp $ */ +/* $OpenBSD: dma_sbus.c,v 1.8 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: dma_sbus.c,v 1.5 2000/07/09 20:57:42 pk Exp $ */ /*- @@ -101,6 +101,7 @@ int dmaprint_sbus(void *, const char *); void *dmabus_intr_establish( bus_space_tag_t, + bus_space_tag_t, int, /*bus interrupt priority*/ int, /*`device class' level*/ int, /*flags*/ @@ -172,18 +173,23 @@ dmaattach_sbus(parent, self, aux) sc->sc_dmatag = sa->sa_dmatag; /* Map registers */ - if (sa->sa_npromvaddrs != 0) - sc->sc_regs = (bus_space_handle_t)sa->sa_promvaddrs[0]; - else { - if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, - sa->sa_offset, - sa->sa_size, - 0, 0, &bh) != 0) { + if (sa->sa_npromvaddrs != 0) { + if (sbus_bus_map(sa->sa_bustag, 0, + sa->sa_promvaddrs[0], + sa->sa_size, /* ???? */ + BUS_SPACE_MAP_PROMADDRESS, + 0, &bh) != 0) { printf("%s: cannot map registers\n", self->dv_xname); return; } - sc->sc_regs = bh; + } else if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, + sa->sa_offset, + sa->sa_size, + 0, 0, &bh) != 0) { + printf("%s: cannot map registers\n", self->dv_xname); + return; } + sc->sc_regs = bh; /* * Get transfer burst size from PROM and plug it into the @@ -246,13 +252,14 @@ dmaattach_sbus(parent, self, aux) } void * -dmabus_intr_establish(t, pri, level, flags, handler, arg) - bus_space_tag_t t; - int pri; - int level; - int flags; - int (*handler)(void *); - void *arg; +dmabus_intr_establish( + bus_space_tag_t t, + bus_space_tag_t t0, + int pri, + int level, + int flags, + int (*handler)(void *), + void *arg) { struct lsi64854_softc *sc = t->cookie; @@ -263,24 +270,32 @@ dmabus_intr_establish(t, pri, level, flags, handler, arg) handler = lsi64854_enet_intr; arg = sc; } - return (bus_intr_establish(sc->sc_bustag, pri, level, flags, - handler, arg)); + + for (t = t->parent; t; t = t->parent) { + if (t->sparc_intr_establish != NULL) + return ((*t->sparc_intr_establish) + (t, t0, pri, level, flags, handler, arg)); + + } + + return (NULL); } bus_space_tag_t dma_alloc_bustag(sc) struct dma_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); sbt->cookie = sc; sbt->parent = sc->sc_lsi64854.sc_bustag; + sbt->asi = sbt->parent->asi; + sbt->sasi = sbt->parent->sasi; sbt->sparc_intr_establish = dmabus_intr_establish; return (sbt); } diff --git a/sys/dev/sbus/esp_sbus.c b/sys/dev/sbus/esp_sbus.c index 61cdfd24bc6..ecb90505f71 100644 --- a/sys/dev/sbus/esp_sbus.c +++ b/sys/dev/sbus/esp_sbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: esp_sbus.c,v 1.10 2003/02/11 19:20:28 mickey Exp $ */ +/* $OpenBSD: esp_sbus.c,v 1.11 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: esp_sbus.c,v 1.14 2001/04/25 17:53:37 bouyer Exp $ */ /*- @@ -226,7 +226,7 @@ espattach_sbus(parent, self, aux) sizeof (lsc->sc_dev.dv_xname)); /* Map dma registers */ - if (bus_space_map2(sa->sa_bustag, + if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size, @@ -332,9 +332,16 @@ espattach_sbus(parent, self, aux) * Map my registers in, if they aren't already in virtual * address space. */ - if (sa->sa_npromvaddrs) - esc->sc_reg = (bus_space_handle_t)sa->sa_promvaddrs[0]; - else { + if (sa->sa_npromvaddrs) { + if (bus_space_map(sa->sa_bustag, sa->sa_promvaddrs[0], + sa->sa_size, + BUS_SPACE_MAP_PROMADDRESS | BUS_SPACE_MAP_LINEAR, + &esc->sc_reg) != 0) { + printf("%s @ sbus: cannot map registers\n", + self->dv_xname); + return; + } + } else { if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset, sa->sa_size, @@ -394,10 +401,18 @@ espattach_dma(parent, self, aux) * Map my registers in, if they aren't already in virtual * address space. */ - if (sa->sa_npromvaddrs) - esc->sc_reg = (bus_space_handle_t)sa->sa_promvaddrs[0]; - else { - if (bus_space_map2(sa->sa_bustag, + if (sa->sa_npromvaddrs) { + if (bus_space_map(sa->sa_bustag, + sa->sa_promvaddrs[0], + sa->sa_size, /* ??? */ + BUS_SPACE_MAP_PROMADDRESS | BUS_SPACE_MAP_LINEAR, + &esc->sc_reg) != 0) { + printf("%s @ dma: cannot map registers\n", + self->dv_xname); + return; + } + } else { + if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset, sa->sa_size, diff --git a/sys/dev/sbus/if_hme_sbus.c b/sys/dev/sbus/if_hme_sbus.c index e3f36e74ced..7d0cb7375d4 100644 --- a/sys/dev/sbus/if_hme_sbus.c +++ b/sys/dev/sbus/if_hme_sbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_hme_sbus.c,v 1.3 2002/03/14 01:27:02 millert Exp $ */ +/* $OpenBSD: if_hme_sbus.c,v 1.4 2003/02/17 01:29:20 henric Exp $ */ /* $NetBSD: if_hme_sbus.c,v 1.6 2001/02/28 14:52:48 mrg Exp $ */ /*- @@ -134,7 +134,7 @@ hmeattach_sbus(parent, self, aux) * */ if (sbus_bus_map(sa->sa_bustag, - (bus_type_t)sa->sa_reg[0].sbr_slot, + sa->sa_reg[0].sbr_slot, (bus_addr_t)sa->sa_reg[0].sbr_offset, (bus_size_t)sa->sa_reg[0].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_seb) != 0) { @@ -142,7 +142,7 @@ hmeattach_sbus(parent, self, aux) return; } if (sbus_bus_map(sa->sa_bustag, - (bus_type_t)sa->sa_reg[1].sbr_slot, + sa->sa_reg[1].sbr_slot, (bus_addr_t)sa->sa_reg[1].sbr_offset, (bus_size_t)sa->sa_reg[1].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_etx) != 0) { @@ -150,7 +150,7 @@ hmeattach_sbus(parent, self, aux) return; } if (sbus_bus_map(sa->sa_bustag, - (bus_type_t)sa->sa_reg[2].sbr_slot, + sa->sa_reg[2].sbr_slot, (bus_addr_t)sa->sa_reg[2].sbr_offset, (bus_size_t)sa->sa_reg[2].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_erx) != 0) { @@ -158,7 +158,7 @@ hmeattach_sbus(parent, self, aux) return; } if (sbus_bus_map(sa->sa_bustag, - (bus_type_t)sa->sa_reg[3].sbr_slot, + sa->sa_reg[3].sbr_slot, (bus_addr_t)sa->sa_reg[3].sbr_offset, (bus_size_t)sa->sa_reg[3].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_mac) != 0) { @@ -166,7 +166,7 @@ hmeattach_sbus(parent, self, aux) return; } if (sbus_bus_map(sa->sa_bustag, - (bus_type_t)sa->sa_reg[4].sbr_slot, + sa->sa_reg[4].sbr_slot, (bus_addr_t)sa->sa_reg[4].sbr_offset, (bus_size_t)sa->sa_reg[4].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_mif) != 0) { diff --git a/sys/dev/sbus/if_le_ledma.c b/sys/dev/sbus/if_le_ledma.c index 9cb22328524..598bf78490a 100644 --- a/sys/dev/sbus/if_le_ledma.c +++ b/sys/dev/sbus/if_le_ledma.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_le_ledma.c,v 1.6 2002/03/14 01:27:02 millert Exp $ */ +/* $OpenBSD: if_le_ledma.c,v 1.7 2003/02/17 01:29:21 henric Exp $ */ /* $NetBSD: if_le_ledma.c,v 1.14 2001/05/30 11:46:35 mrg Exp $ */ /*- @@ -354,7 +354,7 @@ leattach_ledma(parent, self, aux) lesc->sc_dma->sc_client = lesc; /* Map device registers */ - if (bus_space_map2(sa->sa_bustag, + if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset, sa->sa_size, diff --git a/sys/dev/sbus/isp_sbus.c b/sys/dev/sbus/isp_sbus.c index 391f8bfd1b5..d1183f8fa76 100644 --- a/sys/dev/sbus/isp_sbus.c +++ b/sys/dev/sbus/isp_sbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isp_sbus.c,v 1.4 2002/10/12 01:09:44 krw Exp $ */ +/* $OpenBSD: isp_sbus.c,v 1.5 2003/02/17 01:29:21 henric Exp $ */ /* $NetBSD: isp_sbus.c,v 1.46 2001/09/26 20:53:14 eeh Exp $ */ /* @@ -169,7 +169,13 @@ isp_sbus_attach(struct device *parent, struct device *self, void *aux) sbc->sbus_mdvec = mdvec; if (sa->sa_npromvaddrs != 0) { - sbc->sbus_reg = (bus_space_handle_t)sa->sa_promvaddrs[0]; + if (bus_space_map(sa->sa_bustag, sa->sa_promvaddrs[0], + sa->sa_size, + BUS_SPACE_MAP_PROMADDRESS | BUS_SPACE_MAP_LINEAR, + &sbc->sbus_reg) == 0) { + printf("%s: cannot map registers\n", self->dv_xname); + return; + } } else { if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset, sa->sa_size, BUS_SPACE_MAP_LINEAR, 0, diff --git a/sys/dev/sbus/lebuffer.c b/sys/dev/sbus/lebuffer.c index a73dd9bf5b5..6a8618914b5 100644 --- a/sys/dev/sbus/lebuffer.c +++ b/sys/dev/sbus/lebuffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lebuffer.c,v 1.2 2002/05/13 18:16:38 jason Exp $ */ +/* $OpenBSD: lebuffer.c,v 1.3 2003/02/17 01:29:21 henric Exp $ */ /* $NetBSD: lebuffer.c,v 1.12 2002/03/11 16:00:57 pk Exp $ */ /*- @@ -99,7 +99,7 @@ lebufattach(parent, self, aux) struct lebuf_softc *sc = (void *)self; int node; int sbusburst; - bus_space_tag_t sbt; + struct sparc_bus_space_tag *sbt; bus_space_handle_t bh; sc->sc_bustag = sa->sa_bustag; @@ -140,13 +140,12 @@ lebufattach(parent, self, aux) sbus_establish(&sc->sc_sd, &sc->sc_dev); /* Allocate a bus tag */ - 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) { printf("%s: attach: out of memory\n", self->dv_xname); return; } - bzero(sbt, sizeof(struct sparc_bus_space_tag)); + bzero(sbt, sizeof(*sbt)); printf(": %dK memory\n", sc->sc_bufsiz / 1024); diff --git a/sys/dev/sbus/qe.c b/sys/dev/sbus/qe.c index 79df101ba4b..3f8dae7a0cd 100644 --- a/sys/dev/sbus/qe.c +++ b/sys/dev/sbus/qe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: qe.c,v 1.9 2002/03/14 01:27:02 millert Exp $ */ +/* $OpenBSD: qe.c,v 1.10 2003/02/17 01:29:21 henric Exp $ */ /* $NetBSD: qe.c,v 1.16 2001/03/30 17:30:18 christos Exp $ */ /*- @@ -218,8 +218,8 @@ qeattach(parent, self, aux) return; } - if (bus_space_map2(sa->sa_bustag, - (bus_type_t)sa->sa_reg[0].sbr_slot, + if (sbus_bus_map(sa->sa_bustag, + sa->sa_reg[0].sbr_slot, (bus_addr_t)sa->sa_reg[0].sbr_offset, (bus_size_t)sa->sa_reg[0].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_cr) != 0) { @@ -227,8 +227,8 @@ qeattach(parent, self, aux) return; } - if (bus_space_map2(sa->sa_bustag, - (bus_type_t)sa->sa_reg[1].sbr_slot, + if (sbus_bus_map(sa->sa_bustag, + sa->sa_reg[1].sbr_slot, (bus_addr_t)sa->sa_reg[1].sbr_offset, (bus_size_t)sa->sa_reg[1].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_mr) != 0) { diff --git a/sys/dev/sbus/qec.c b/sys/dev/sbus/qec.c index 969f430b166..e11e836ef85 100644 --- a/sys/dev/sbus/qec.c +++ b/sys/dev/sbus/qec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: qec.c,v 1.4 2002/03/14 03:16:08 millert Exp $ */ +/* $OpenBSD: qec.c,v 1.5 2003/02/17 01:29:21 henric Exp $ */ /* $NetBSD: qec.c,v 1.12 2000/12/04 20:12:55 fvdl Exp $ */ /*- @@ -60,14 +60,14 @@ void qec_init(struct qec_softc *); static int qec_bus_map( bus_space_tag_t, - bus_type_t, /*slot*/ + bus_space_tag_t, bus_addr_t, /*offset*/ bus_size_t, /*size*/ int, /*flags*/ - vaddr_t, /*preferred virtual address */ bus_space_handle_t *); static void *qec_intr_establish( bus_space_tag_t, + bus_space_tag_t, int, /*bus interrupt priority*/ int, /*`device class' interrupt level*/ int, /*flags*/ @@ -121,7 +121,7 @@ qecattach(parent, self, aux) struct qec_softc *sc = (void *)self; int node; int sbusburst; - bus_space_tag_t sbt; + struct sparc_bus_space_tag *sbt; bus_space_handle_t bh; int error; @@ -157,7 +157,7 @@ qecattach(parent, self, aux) printf("%s: attach: cannot map registers\n", self->dv_xname); return; } - sc->sc_buffer = (caddr_t)(u_long)bh; + sc->sc_buffer = (caddr_t)bus_space_vaddr(sc->sc_bustag, bh); sc->sc_bufsiz = (bus_size_t)sa->sa_reg[1].sbr_size; /* Get number of on-board channels */ @@ -198,16 +198,18 @@ qecattach(parent, self, aux) } /* Allocate a bus tag */ - 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) { printf("%s: attach: out of memory\n", self->dv_xname); return; } bzero(sbt, sizeof *sbt); + strlcpy(sbt->name, sc->sc_dev.dv_xname, sizeof(sbt->name)); sbt->cookie = sc; sbt->parent = sc->sc_bustag; + sbt->asi = sbt->parent->asi; + sbt->sasi = sbt->parent->sasi; sbt->sparc_bus_map = qec_bus_map; sbt->sparc_intr_establish = qec_intr_establish; @@ -238,22 +240,37 @@ qecattach(parent, self, aux) } int -qec_bus_map(t, btype, offset, size, flags, vaddr, hp) +qec_bus_map(t, t0, addr, size, flags, hp) bus_space_tag_t t; - bus_type_t btype; - bus_addr_t offset; + bus_space_tag_t t0; + bus_addr_t addr; bus_size_t size; int flags; - vaddr_t vaddr; bus_space_handle_t *hp; { struct qec_softc *sc = t->cookie; - int slot = btype; + int slot = BUS_ADDR_IOSPACE(addr); + bus_addr_t offset = BUS_ADDR_PADDR(addr); int i; + for (t = t->parent; t; t = t->parent) { + if (t->sparc_bus_map != NULL) + break; + } + + if (t == NULL) { + printf("\nqec_bus_map: invalid parent"); + return (EINVAL); + } + + 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++) { bus_addr_t paddr; - bus_type_t iospace; + int iospace; if (sc->sc_range[i].cspace != slot) continue; @@ -261,16 +278,17 @@ qec_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; iospace = sc->sc_range[i].pspace; - return (bus_space_map2(sc->sc_bustag, iospace, paddr, - size, flags, vaddr, hp)); + return ((*t->sparc_bus_map) + (t, t0, BUS_ADDR(iospace, paddr), size, flags, hp)); } return (EINVAL); } void * -qec_intr_establish(t, pri, level, flags, handler, arg) +qec_intr_establish(t, t0, pri, level, flags, handler, arg) bus_space_tag_t t; + bus_space_tag_t t0; int pri; int level; int flags; @@ -292,7 +310,15 @@ qec_intr_establish(t, pri, level, flags, handler, arg) pri = sc->sc_intr->sbi_pri; } - return (bus_intr_establish(t->parent, pri, level, flags, handler, arg)); + 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)); } void diff --git a/sys/dev/sbus/sbusvar.h b/sys/dev/sbus/sbusvar.h index 7784d8ff847..712e958c1d1 100644 --- a/sys/dev/sbus/sbusvar.h +++ b/sys/dev/sbus/sbusvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sbusvar.h,v 1.6 2002/06/14 21:34:59 todd Exp $ */ +/* $OpenBSD: sbusvar.h,v 1.7 2003/02/17 01:29:21 henric Exp $ */ /* $NetBSD: sbusvar.h,v 1.11 2000/11/01 06:18:45 eeh Exp $ */ /*- @@ -115,8 +115,8 @@ int sbus_setup_attach_args( void sbus_destroy_attach_args(struct sbus_attach_args *); -#define sbus_bus_map(t, bt, a, s, f, v, hp) \ - bus_space_map2(t, bt, a, s, f, v, hp) +#define sbus_bus_map(t, slot, offset, sz, flags, unused, hp) \ + bus_space_map(t, BUS_ADDR(slot, offset), sz, flags, hp) #if notyet /* variables per Sbus */ |