summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64/dev
diff options
context:
space:
mode:
authorHenric Jungheim <henric@cvs.openbsd.org>2003-02-17 01:29:22 +0000
committerHenric Jungheim <henric@cvs.openbsd.org>2003-02-17 01:29:22 +0000
commitecebaec0fd1a08a0975b8f756936722a40ae03a6 (patch)
tree59277d25c05e37b02700a112ccaf0a5859342f3b /sys/arch/sparc64/dev
parent914c2239132eb3f27af97793d1c7534d2e08045d (diff)
Add support for the Sun Enterprise 450
Reduce the size of a GENERIC kernel by ~190k Remove the nasty pointer/bus_space_handle_t casts Adds debug bus_space code including the ability to trace bus operations (it actually works now). The following rules are now followed (and verfified by the debug code): 1. A "bus_space_handle_t" may only be used with the "bus_space_tag_t" that created it. 2. Only "bus_space_map()" may create "bus_space_handle_t"s. 3. A "bus_space_handle_t" may not be modified after it has been created (other than being destroyed by "bus_space_unmap()"). Thanks to help from mcbride, marc, jason, drahn, to anyone that might have slipped my mind at the moment. ok jason@, deraadt@
Diffstat (limited to 'sys/arch/sparc64/dev')
-rw-r--r--sys/arch/sparc64/dev/auxio.c43
-rw-r--r--sys/arch/sparc64/dev/beeper.c14
-rw-r--r--sys/arch/sparc64/dev/ce4231.c18
-rw-r--r--sys/arch/sparc64/dev/com_ebus.c32
-rw-r--r--sys/arch/sparc64/dev/comkbd_ebus.c41
-rw-r--r--sys/arch/sparc64/dev/ebus.c247
-rw-r--r--sys/arch/sparc64/dev/ebusvar.h8
-rw-r--r--sys/arch/sparc64/dev/iommu.c589
-rw-r--r--sys/arch/sparc64/dev/iommureg.h7
-rw-r--r--sys/arch/sparc64/dev/iommuvar.h34
-rw-r--r--sys/arch/sparc64/dev/lpt_ebus.c15
-rw-r--r--sys/arch/sparc64/dev/pci_machdep.c42
-rw-r--r--sys/arch/sparc64/dev/pckbc_ebus.c13
-rw-r--r--sys/arch/sparc64/dev/psycho.c665
-rw-r--r--sys/arch/sparc64/dev/psychovar.h37
-rw-r--r--sys/arch/sparc64/dev/sab.c18
-rw-r--r--sys/arch/sparc64/dev/sbus.c379
-rw-r--r--sys/arch/sparc64/dev/sbusvar.h7
-rw-r--r--sys/arch/sparc64/dev/schizo.c351
-rw-r--r--sys/arch/sparc64/dev/schizovar.h9
-rw-r--r--sys/arch/sparc64/dev/upa.c63
-rw-r--r--sys/arch/sparc64/dev/uperf_ebus.c4
-rw-r--r--sys/arch/sparc64/dev/zs.c4
23 files changed, 1307 insertions, 1333 deletions
diff --git a/sys/arch/sparc64/dev/auxio.c b/sys/arch/sparc64/dev/auxio.c
index 5b23a0b0ad4..1e33b7298be 100644
--- a/sys/arch/sparc64/dev/auxio.c
+++ b/sys/arch/sparc64/dev/auxio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auxio.c,v 1.4 2002/03/14 01:26:44 millert Exp $ */
+/* $OpenBSD: auxio.c,v 1.5 2003/02/17 01:29:19 henric Exp $ */
/* $NetBSD: auxio.c,v 1.1 2000/04/15 03:08:13 mrg Exp $ */
/*
@@ -100,19 +100,39 @@ auxio_ebus_attach(parent, self, aux)
return;
}
+ sc->sc_tag = ea->ea_memtag;
+
if (ea->ea_nregs != 5 || ea->ea_nvaddrs != 5) {
printf(": not 5 (%d) registers, only setting led",
ea->ea_nregs);
sc->sc_flags = AUXIO_LEDONLY|AUXIO_EBUS;
} else {
sc->sc_flags = AUXIO_EBUS;
- sc->sc_pci = (bus_space_handle_t)(u_long)ea->ea_vaddrs[1];
- sc->sc_freq = (bus_space_handle_t)(u_long)ea->ea_vaddrs[1];
- sc->sc_scsi = (bus_space_handle_t)(u_long)ea->ea_vaddrs[1];
- sc->sc_temp = (bus_space_handle_t)(u_long)ea->ea_vaddrs[1];
+ if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[2],
+ sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS,
+ &sc->sc_freq)) {
+ printf(": unable to map freq\n");
+ return;
+ }
+ if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[3],
+ sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS,
+ &sc->sc_scsi)) {
+ printf(": unable to map SCSI\n");
+ return;
+ }
+ if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[4],
+ sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS,
+ &sc->sc_temp)) {
+ printf(": unable to map temp\n");
+ return;
+ }
+ }
+
+ if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[0], sizeof(u_int32_t),
+ BUS_SPACE_MAP_PROMADDRESS, &sc->sc_led)) {
+ printf(": unable to map LED\n");
+ return;
}
- sc->sc_led = (bus_space_handle_t)(u_long)ea->ea_vaddrs[0];
- sc->sc_tag = ea->ea_bustag;
auxio_attach_common(sc);
}
@@ -138,6 +158,8 @@ auxio_sbus_attach(parent, self, aux)
timeout_set(&sc->sc_to, auxio_led_blink, sc);
+ sc->sc_tag = sa->sa_bustag;
+
if (sa->sa_nreg < 1 || sa->sa_npromvaddrs < 1) {
printf(": no registers??\n");
return;
@@ -150,8 +172,11 @@ auxio_sbus_attach(parent, self, aux)
/* sbus auxio only has one set of registers */
sc->sc_flags = AUXIO_LEDONLY|AUXIO_SBUS;
- sc->sc_led = (bus_space_handle_t)(u_long)sa->sa_promvaddr;
- sc->sc_tag = sa->sa_bustag;
+ if (bus_space_map(sc->sc_tag, sa->sa_promvaddr, 1,
+ BUS_SPACE_MAP_PROMADDRESS, &sc->sc_led)) {
+ printf(": couldn't map registers\n");
+ return;
+ }
auxio_attach_common(sc);
}
diff --git a/sys/arch/sparc64/dev/beeper.c b/sys/arch/sparc64/dev/beeper.c
index b87e7144b0e..b8386f34bec 100644
--- a/sys/arch/sparc64/dev/beeper.c
+++ b/sys/arch/sparc64/dev/beeper.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: beeper.c,v 1.6 2002/08/19 20:19:13 jason Exp $ */
+/* $OpenBSD: beeper.c,v 1.7 2003/02/17 01:29:19 henric Exp $ */
/*
* Copyright (c) 2001 Jason L. Wright (jason@thought.net)
@@ -108,12 +108,16 @@ beeper_attach(parent, self, aux)
struct beeper_softc *sc = (void *)self;
struct ebus_attach_args *ea = aux;
- sc->sc_iot = ea->ea_bustag;
+ sc->sc_iot = ea->ea_iotag;
/* Use prom address if available, otherwise map it. */
- if (ea->ea_nvaddrs)
- sc->sc_ioh = (bus_space_handle_t)ea->ea_vaddrs[0];
- else if (ebus_bus_map(sc->sc_iot, 0,
+ if (ea->ea_nvaddrs) {
+ if (bus_space_map(sc->sc_iot, ea->ea_vaddrs[0], 0,
+ BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh)) {
+ printf(": can't map PROM register space\n");
+ return;
+ }
+ } else if (ebus_bus_map(sc->sc_iot, 0,
EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size,
BUS_SPACE_MAP_LINEAR, 0, &sc->sc_ioh) != 0) {
printf(": can't map register space\n");
diff --git a/sys/arch/sparc64/dev/ce4231.c b/sys/arch/sparc64/dev/ce4231.c
index 1983f7e8fe9..a09ad77b145 100644
--- a/sys/arch/sparc64/dev/ce4231.c
+++ b/sys/arch/sparc64/dev/ce4231.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ce4231.c,v 1.11 2002/09/10 17:27:27 jason Exp $ */
+/* $OpenBSD: ce4231.c,v 1.12 2003/02/17 01:29:19 henric Exp $ */
/*
* Copyright (c) 1999 Jason L. Wright (jason@thought.net)
@@ -237,7 +237,7 @@ ce4231_attach(parent, self, aux)
sc->sc_last_format = 0xffffffff;
/* Pass on the bus tags */
- sc->sc_bustag = ea->ea_bustag;
+ sc->sc_bustag = ea->ea_memtag;
sc->sc_dmatag = ea->ea_dmatag;
/* Make sure things are sane. */
@@ -251,13 +251,13 @@ ce4231_attach(parent, self, aux)
return;
}
- sc->sc_cih = bus_intr_establish(ea->ea_bustag, ea->ea_intrs[0],
+ sc->sc_cih = bus_intr_establish(sc->sc_bustag, ea->ea_intrs[0],
IPL_AUDIO, 0, ce4231_cintr, sc);
if (sc->sc_cih == NULL) {
printf(": couldn't establish capture interrupt\n");
return;
}
- sc->sc_pih = bus_intr_establish(ea->ea_bustag, ea->ea_intrs[1],
+ sc->sc_pih = bus_intr_establish(sc->sc_bustag, ea->ea_intrs[1],
IPL_AUDIO, 0, ce4231_pintr, sc);
if (sc->sc_pih == NULL) {
printf(": couldn't establish play interrupt1\n");
@@ -266,28 +266,28 @@ ce4231_attach(parent, self, aux)
/* XXX what if prom has already mapped?! */
- if (ebus_bus_map(ea->ea_bustag, 0,
+ if (ebus_bus_map(sc->sc_bustag, 0,
EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size,
BUS_SPACE_MAP_LINEAR, 0, &sc->sc_cshandle) != 0) {
printf(": couldn't map cs4231 registers\n");
return;
}
- if (ebus_bus_map(ea->ea_bustag, 0,
+ if (ebus_bus_map(sc->sc_bustag, 0,
EBUS_PADDR_FROM_REG(&ea->ea_regs[1]), ea->ea_regs[1].size,
BUS_SPACE_MAP_LINEAR, 0, &sc->sc_pdmahandle) != 0) {
printf(": couldn't map dma1 registers\n");
return;
}
- if (ebus_bus_map(ea->ea_bustag, 0,
+ if (ebus_bus_map(sc->sc_bustag, 0,
EBUS_PADDR_FROM_REG(&ea->ea_regs[2]), ea->ea_regs[2].size,
BUS_SPACE_MAP_LINEAR, 0, &sc->sc_cdmahandle) != 0) {
printf(": couldn't map dma2 registers\n");
return;
}
- if (ebus_bus_map(ea->ea_bustag, 0,
+ if (ebus_bus_map(sc->sc_bustag, 0,
EBUS_PADDR_FROM_REG(&ea->ea_regs[3]), ea->ea_regs[3].size,
BUS_SPACE_MAP_LINEAR, 0, &sc->sc_auxhandle) != 0) {
printf(": couldn't map aux registers\n");
@@ -1480,7 +1480,7 @@ ce4231_trigger_output(addr, start, end, blksize, intr, arg, param)
for (p = sc->sc_dmas; p->addr != start; p = p->next)
/*EMPTY*/;
if (p == NULL) {
- printf("%s: trigger_output: bad addr: %x\n",
+ printf("%s: trigger_output: bad addr: %p\n",
sc->sc_dev.dv_xname, start);
return (EINVAL);
}
diff --git a/sys/arch/sparc64/dev/com_ebus.c b/sys/arch/sparc64/dev/com_ebus.c
index 7b5b2ca7c02..1afdc6553c8 100644
--- a/sys/arch/sparc64/dev/com_ebus.c
+++ b/sys/arch/sparc64/dev/com_ebus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: com_ebus.c,v 1.7 2002/06/04 19:26:49 jason Exp $ */
+/* $OpenBSD: com_ebus.c,v 1.8 2003/02/17 01:29:20 henric Exp $ */
/* $NetBSD: com_ebus.c,v 1.6 2001/07/24 19:27:10 eeh Exp $ */
/*
@@ -106,10 +106,9 @@ com_ebus_attach(parent, self, aux)
struct ebus_attach_args *ea = aux;
int i, com_is_input, com_is_output;
- sc->sc_iot = ea->ea_bustag;
sc->sc_iobase = EBUS_PADDR_FROM_REG(&ea->ea_regs[0]);
/*
- * Addresses that shoud be supplied by the prom:
+ * Addresses that should be supplied by the prom:
* - normal com registers
* - ns873xx configuration registers
* - DMA space
@@ -119,22 +118,31 @@ com_ebus_attach(parent, self, aux)
*
* Use the prom address if there.
*/
- if (ea->ea_nvaddrs)
- sc->sc_ioh = (bus_space_handle_t)ea->ea_vaddrs[0];
- else if (ebus_bus_map(sc->sc_iot, 0,
- EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
- ea->ea_regs[0].size,
- BUS_SPACE_MAP_LINEAR,
- 0, &sc->sc_ioh) != 0) {
+ if (ea->ea_nvaddrs) {
+ if (bus_space_map(ea->ea_memtag, ea->ea_vaddrs[0], 0,
+ BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh) == 0) {
+ printf(": can't map register space\n");
+ return;
+ }
+ sc->sc_iot = ea->ea_memtag;
+ } else if (ebus_bus_map(ea->ea_memtag, 0,
+ EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
+ ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
+ sc->sc_iot = ea->ea_memtag;
+ } else if (ebus_bus_map(ea->ea_iotag, 0,
+ EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
+ ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
+ sc->sc_iot = ea->ea_iotag;
+ } else {
printf(": can't map register space\n");
- return;
+ return;
}
sc->sc_hwflags = 0;
sc->sc_swflags = 0;
sc->sc_frequency = BAUD_BASE;
for (i = 0; i < ea->ea_nintrs; i++)
- bus_intr_establish(ea->ea_bustag, ea->ea_intrs[i],
+ bus_intr_establish(sc->sc_iot, ea->ea_intrs[i],
IPL_TTY, 0, comintr, sc);
/* Figure out if we're the console. */
diff --git a/sys/arch/sparc64/dev/comkbd_ebus.c b/sys/arch/sparc64/dev/comkbd_ebus.c
index 4dd348f2769..68c0535b4a2 100644
--- a/sys/arch/sparc64/dev/comkbd_ebus.c
+++ b/sys/arch/sparc64/dev/comkbd_ebus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: comkbd_ebus.c,v 1.10 2002/12/22 16:13:30 miod Exp $ */
+/* $OpenBSD: comkbd_ebus.c,v 1.11 2003/02/17 01:29:20 henric Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -197,7 +197,7 @@ comkbd_attach(parent, self, aux)
timeout_set(&sc->sc_bellto, comkbd_bellstop, sc);
- sc->sc_iot = ea->ea_bustag;
+ sc->sc_iot = ea->ea_memtag;
sc->sc_rxget = sc->sc_rxput = sc->sc_rxbeg = sc->sc_rxbuf;
sc->sc_rxend = sc->sc_rxbuf + COMK_RX_RING;
@@ -215,34 +215,41 @@ comkbd_attach(parent, self, aux)
return;
}
- sc->sc_ih = bus_intr_establish(ea->ea_bustag,
+ /* Use prom address if available, otherwise map it. */
+ if (ea->ea_nvaddrs && bus_space_map(ea->ea_memtag, ea->ea_vaddrs[0], 0,
+ BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh) == 0) {
+ sc->sc_iot = ea->ea_memtag;
+ } else if (ebus_bus_map(ea->ea_memtag, 0,
+ EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
+ ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
+ sc->sc_iot = ea->ea_memtag;
+ } else if (ebus_bus_map(ea->ea_iotag, 0,
+ EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
+ ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
+ sc->sc_iot = ea->ea_iotag;
+ } else {
+ printf(": can't map register space\n");
+ return;
+ }
+
+ sc->sc_ih = bus_intr_establish(sc->sc_iot,
ea->ea_intrs[0], IPL_TTY, 0, comkbd_intr, sc);
if (sc->sc_ih == NULL) {
printf(": can't get hard intr\n");
return;
}
- /* Use prom address if available, otherwise map it. */
- if (ea->ea_nvaddrs)
- sc->sc_ioh = (bus_space_handle_t)ea->ea_vaddrs[0];
- else if (ebus_bus_map(sc->sc_iot, 0,
- EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
- ea->ea_regs[0].size,
- BUS_SPACE_MAP_LINEAR,
- 0, &sc->sc_ioh) != 0) {
- printf(": can't map register space\n");
- return;
- }
-
if (console) {
comkbd_init(sc);
cn_tab->cn_dev = makedev(77, sc->sc_dv.dv_unit); /* XXX */
cn_tab->cn_pollc = wskbd_cnpollc;
cn_tab->cn_getc = wskbd_cngetc;
if (ISTYPE5(sc->sc_layout)) {
- wskbd_cnattach(&comkbd_consops, sc, &sunkbd5_keymapdata);
+ wskbd_cnattach(&comkbd_consops, sc,
+ &sunkbd5_keymapdata);
} else {
- wskbd_cnattach(&comkbd_consops, sc, &sunkbd_keymapdata);
+ wskbd_cnattach(&comkbd_consops, sc,
+ &sunkbd_keymapdata);
}
sc->sc_ier = IER_ETXRDY | IER_ERXRDY;
COM_WRITE(sc, com_ier, sc->sc_ier);
diff --git a/sys/arch/sparc64/dev/ebus.c b/sys/arch/sparc64/dev/ebus.c
index cc3f022b634..8f802a40c69 100644
--- a/sys/arch/sparc64/dev/ebus.c
+++ b/sys/arch/sparc64/dev/ebus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ebus.c,v 1.9 2002/03/14 03:16:00 millert Exp $ */
+/* $OpenBSD: ebus.c,v 1.10 2003/02/17 01:29:20 henric Exp $ */
/* $NetBSD: ebus.c,v 1.24 2001/07/25 03:49:54 eeh Exp $ */
/*
@@ -99,30 +99,31 @@ int ebus_find_node(struct pci_attach_args *);
/*
* here are our bus space and bus dma routines.
*/
-static paddr_t ebus_bus_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);
-static int _ebus_bus_map(bus_space_tag_t, bus_type_t, bus_addr_t,
- bus_size_t, int, vaddr_t,
- bus_space_handle_t *);
-static void *ebus_intr_establish(bus_space_tag_t, int, int, int,
- int (*)(void *), void *);
-
-static int ebus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
- bus_size_t, struct proc *, int);
+static paddr_t ebus_bus_mmap(bus_space_tag_t, bus_space_tag_t, bus_addr_t,
+ off_t, int, int);
+static int _ebus_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t,
+ bus_size_t, int, bus_space_handle_t *);
+static void *ebus_intr_establish(bus_space_tag_t, bus_space_tag_t, int, int,
+ int, int (*)(void *), void *);
+static int ebus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t,
+ struct proc *, int);
static void ebus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
static void ebus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
- bus_size_t, int);
+ bus_size_t, int);
int ebus_dmamem_alloc(bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t,
- bus_dma_segment_t *, int, int *, int);
+ bus_dma_segment_t *, int, int *, int);
void ebus_dmamem_free(bus_dma_tag_t, bus_dma_segment_t *, int);
int ebus_dmamem_map(bus_dma_tag_t, bus_dma_segment_t *, int, size_t,
- caddr_t *, int);
+ caddr_t *, int);
void ebus_dmamem_unmap(bus_dma_tag_t, caddr_t, size_t);
+bus_space_tag_t ebus_alloc_mem_tag(struct ebus_softc *, bus_space_tag_t);
+bus_space_tag_t ebus_alloc_io_tag(struct ebus_softc *, bus_space_tag_t);
+bus_space_tag_t _ebus_alloc_bus_tag(struct ebus_softc *sc, const char *,
+ bus_space_tag_t, int);
+
int
-ebus_match(parent, match, aux)
- struct device *parent;
- void *match;
- void *aux;
+ebus_match(struct device *parent, void *match, void *aux)
{
struct pci_attach_args *pa = aux;
char name[10];
@@ -161,9 +162,7 @@ ebus_match(parent, match, aux)
* after the sbus code which does similar things.
*/
void
-ebus_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+ebus_attach(struct device *parent, struct device *self, void *aux)
{
struct ebus_softc *sc = (struct ebus_softc *)self;
struct pci_attach_args *pa = aux;
@@ -173,9 +172,8 @@ ebus_attach(parent, self, aux)
printf("\n");
- sc->sc_memtag = pa->pa_memt;
- sc->sc_iotag = pa->pa_iot;
- sc->sc_childbustag = ebus_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE);
+ sc->sc_memtag = ebus_alloc_mem_tag(sc, pa->pa_memt);
+ sc->sc_iotag = ebus_alloc_io_tag(sc, pa->pa_iot);
sc->sc_dmatag = ebus_alloc_dma_tag(sc, pa->pa_dmat);
node = PCITAG_NODE(pa->pa_tag);
@@ -235,10 +233,8 @@ ebus_attach(parent, self, aux)
}
int
-ebus_setup_attach_args(sc, node, ea)
- struct ebus_softc *sc;
- int node;
- struct ebus_attach_args *ea;
+ebus_setup_attach_args(struct ebus_softc *sc, int node,
+ struct ebus_attach_args *ea)
{
int n, rv;
@@ -249,7 +245,8 @@ ebus_setup_attach_args(sc, node, ea)
ea->ea_name[n] = '\0';
ea->ea_node = node;
- ea->ea_bustag = sc->sc_childbustag;
+ ea->ea_memtag = sc->sc_memtag;
+ ea->ea_iotag = sc->sc_iotag;
ea->ea_dmatag = sc->sc_dmatag;
rv = getprop(node, "reg", sizeof(struct ebus_regs), &ea->ea_nregs,
@@ -279,10 +276,8 @@ ebus_setup_attach_args(sc, node, ea)
}
void
-ebus_destroy_attach_args(ea)
- struct ebus_attach_args *ea;
+ebus_destroy_attach_args(struct ebus_attach_args *ea)
{
-
if (ea->ea_name)
free((void *)ea->ea_name, M_DEVBUF);
if (ea->ea_regs)
@@ -294,9 +289,7 @@ ebus_destroy_attach_args(ea)
}
int
-ebus_print(aux, p)
- void *aux;
- const char *p;
+ebus_print(void *aux, const char *p)
{
struct ebus_attach_args *ea = aux;
int i;
@@ -323,9 +316,7 @@ ebus_print(aux, p)
* to give the INO for this interrupt.
*/
void
-ebus_find_ino(sc, ea)
- struct ebus_softc *sc;
- struct ebus_attach_args *ea;
+ebus_find_ino(struct ebus_softc *sc, struct ebus_attach_args *ea)
{
u_int32_t hi, lo, intr;
int i, j, k;
@@ -376,26 +367,41 @@ next_intr:;
}
}
+bus_space_tag_t
+ebus_alloc_mem_tag(struct ebus_softc *sc, bus_space_tag_t parent)
+{
+ return (_ebus_alloc_bus_tag(sc, "mem", parent,
+ 0x02)); /* 32-bit mem space (where's the #define???) */
+}
+
+bus_space_tag_t
+ebus_alloc_io_tag(struct ebus_softc *sc, bus_space_tag_t parent)
+{
+ return (_ebus_alloc_bus_tag(sc, "io", parent,
+ 0x01)); /* IO space (where's the #define???) */
+}
/*
* bus space and bus dma below here
*/
bus_space_tag_t
-ebus_alloc_bus_tag(sc, type)
- struct ebus_softc *sc;
- int type;
+_ebus_alloc_bus_tag(struct ebus_softc *sc, const char *name,
+ bus_space_tag_t parent, int ss)
{
- bus_space_tag_t bt;
+ struct sparc_bus_space_tag *bt;
- bt = (bus_space_tag_t)
- malloc(sizeof(struct sparc_bus_space_tag), M_DEVBUF, M_NOWAIT);
+ bt = malloc(sizeof(*bt), M_DEVBUF, M_NOWAIT);
if (bt == NULL)
panic("could not allocate ebus bus tag");
bzero(bt, sizeof *bt);
+ snprintf(bt->name, sizeof(bt->name), "%s_%s",
+ sc->sc_dev.dv_xname, name);
bt->cookie = sc;
- bt->parent = sc->sc_memtag;
- bt->type = type;
+ bt->parent = parent;
+ bt->default_type = ss;
+ bt->asi = parent->asi;
+ bt->sasi = parent->sasi;
bt->sparc_bus_map = _ebus_bus_map;
bt->sparc_bus_mmap = ebus_bus_mmap;
bt->sparc_intr_establish = ebus_intr_establish;
@@ -403,9 +409,7 @@ ebus_alloc_bus_tag(sc, type)
}
bus_dma_tag_t
-ebus_alloc_dma_tag(sc, pdt)
- struct ebus_softc *sc;
- bus_dma_tag_t pdt;
+ebus_alloc_dma_tag(struct ebus_softc *sc, bus_dma_tag_t pdt)
{
bus_dma_tag_t dt;
@@ -441,26 +445,33 @@ ebus_alloc_dma_tag(sc, pdt)
* about PCI physical addresses, which also applies to ebus.
*/
static int
-_ebus_bus_map(t, btype, offset, size, flags, vaddr, hp)
- bus_space_tag_t t;
- bus_type_t btype;
- bus_addr_t offset;
- bus_size_t size;
- int flags;
- vaddr_t vaddr;
- bus_space_handle_t *hp;
+_ebus_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t offset,
+ bus_size_t size, int flags, bus_space_handle_t *hp)
{
struct ebus_softc *sc = t->cookie;
bus_addr_t hi, lo;
- int i, ss;
+ int i;
DPRINTF(EDB_BUSMAP,
- ("\n_ebus_bus_map: type %d off %016llx sz %x flags %d va %p",
- (int)t->type, (unsigned long long)offset, (int)size, (int)flags,
- (void *)vaddr));
+ ("\n_ebus_bus_map: type %d off %016llx sz %x flags %d",
+ (int)t->default_type, (unsigned long long)offset, (int)size,
+ (int)flags));
+
+ if (t->parent == 0 || t->parent->sparc_bus_map == 0) {
+ printf("\n_ebus_bus_map: invalid parent");
+ return (EINVAL);
+ }
+
+ t = t->parent;
+
+ if (flags & BUS_SPACE_MAP_PROMADDRESS) {
+ return ((*t->sparc_bus_map)
+ (t, t0, offset, size, flags, hp));
+ }
hi = offset >> 32UL;
lo = offset & 0xffffffff;
+
DPRINTF(EDB_BUSMAP, (" (hi %08x lo %08x)", (u_int)hi, (u_int)lo));
for (i = 0; i < sc->sc_nrange; i++) {
bus_addr_t pciaddr;
@@ -472,49 +483,41 @@ _ebus_bus_map(t, btype, offset, size, flags, vaddr, hp)
(sc->sc_range[i].child_lo + sc->sc_range[i].size))
continue;
- /* Isolate address space and find the right tag */
- ss = (sc->sc_range[i].phys_hi>>24)&3;
- switch (ss) {
- case 1: /* I/O space */
- t = sc->sc_iotag;
- break;
- case 2: /* Memory space */
- t = sc->sc_memtag;
- break;
- case 0: /* Config space */
- case 3: /* 64-bit Memory space */
- default: /* WTF? */
- /* We don't handle these */
- panic("_ebus_bus_map: illegal space %x", ss);
- break;
- }
+ if(((sc->sc_range[i].phys_hi >> 24) & 3) != t->default_type)
+ continue;
+
pciaddr = ((bus_addr_t)sc->sc_range[i].phys_mid << 32UL) |
sc->sc_range[i].phys_lo;
pciaddr += lo;
DPRINTF(EDB_BUSMAP,
- ("\n_ebus_bus_map: mapping space %x paddr offset %qx pciaddr %qx\n",
- ss, (unsigned long long)offset, (unsigned long long)pciaddr));
+ ("\n_ebus_bus_map: mapping space %x paddr offset %qx "
+ "pciaddr %qx\n", (int)t->default_type,
+ (unsigned long long)offset, (unsigned long long)pciaddr));
/* pass it onto the psycho */
- return (bus_space_map2(t, 0, pciaddr, size, flags, vaddr, hp));
+ return ((*t->sparc_bus_map)(t, t0, pciaddr, size, flags, hp));
}
DPRINTF(EDB_BUSMAP, (": FAILED\n"));
return (EINVAL);
}
static paddr_t
-ebus_bus_mmap(t, paddr, off, prot, flags)
- bus_space_tag_t t;
- bus_addr_t paddr;
- off_t off;
- int prot;
- int flags;
+ebus_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr,
+ off_t off, int prot, int flags)
{
bus_addr_t offset = paddr;
struct ebus_softc *sc = t->cookie;
int i;
+ if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) {
+ printf("\nebus_bus_mmap: invalid parent");
+ return (-1);
+ }
+
+ t = t->parent;
+
for (i = 0; i < sc->sc_nrange; i++) {
- bus_addr_t paddr = ((bus_addr_t)sc->sc_range[i].child_hi << 32) |
+ bus_addr_t paddr =
+ ((bus_addr_t)sc->sc_range[i].child_hi << 32) |
sc->sc_range[i].child_lo;
if (offset != paddr)
@@ -522,7 +525,7 @@ ebus_bus_mmap(t, paddr, off, prot, flags)
DPRINTF(EDB_BUSMAP, ("\n_ebus_bus_mmap: mapping paddr %qx\n",
(unsigned long long)paddr));
- return (bus_space_mmap(sc->sc_memtag, paddr, off, prot, flags));
+ return ((*t->sparc_bus_mmap)(t, t0, paddr, off, prot, flags));
}
return (-1);
@@ -532,15 +535,17 @@ ebus_bus_mmap(t, paddr, off, prot, flags)
* install an interrupt handler for a PCI device
*/
void *
-ebus_intr_establish(t, pri, level, flags, handler, arg)
- bus_space_tag_t t;
- int pri;
- int level;
- int flags;
- int (*handler)(void *);
- void *arg;
+ebus_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int pri, int level,
+ int flags, int (*handler)(void *), void *arg)
{
- return (bus_intr_establish(t->parent, pri, level, flags,
+ if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) {
+ printf("\nebus_bus_mmap: invalid parent");
+ return (NULL);
+ }
+
+ t = t->parent;
+
+ return ((*t->sparc_intr_establish)(t, t0, pri, level, flags,
handler, arg));
}
@@ -548,77 +553,49 @@ ebus_intr_establish(t, pri, level, flags, handler, arg)
* bus dma support
*/
int
-ebus_dmamap_load(t, map, buf, buflen, p, flags)
- bus_dma_tag_t t;
- bus_dmamap_t map;
- void *buf;
- bus_size_t buflen;
- struct proc *p;
- int flags;
+ebus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
+ bus_size_t buflen, struct proc *p, int flags)
{
return (bus_dmamap_load(t->_parent, map, buf, buflen, p, flags));
}
void
-ebus_dmamap_unload(t, map)
- bus_dma_tag_t t;
- bus_dmamap_t map;
+ebus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map)
{
bus_dmamap_unload(t->_parent, map);
}
void
-ebus_dmamap_sync(t, map, offset, len, ops)
- bus_dma_tag_t t;
- bus_dmamap_t map;
- bus_addr_t offset;
- bus_size_t len;
- int ops;
+ebus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
+ bus_size_t len, int ops)
{
bus_dmamap_sync(t->_parent, map, offset, len, ops);
}
int
-ebus_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags)
- bus_dma_tag_t t;
- bus_size_t size;
- bus_size_t alignment;
- bus_size_t boundary;
- bus_dma_segment_t *segs;
- int nsegs;
- int *rsegs;
- int flags;
+ebus_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
+ bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
+ int flags)
{
return (bus_dmamem_alloc(t->_parent, size, alignment, boundary, segs,
nsegs, rsegs, flags));
}
void
-ebus_dmamem_free(t, segs, nsegs)
- bus_dma_tag_t t;
- bus_dma_segment_t *segs;
- int nsegs;
+ebus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs)
{
bus_dmamem_free(t->_parent, segs, nsegs);
}
int
-ebus_dmamem_map(t, segs, nsegs, size, kvap, flags)
- bus_dma_tag_t t;
- bus_dma_segment_t *segs;
- int nsegs;
- size_t size;
- caddr_t *kvap;
- int flags;
+ebus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
+ size_t size, caddr_t *kvap, int flags)
{
return (bus_dmamem_map(t->_parent, segs, nsegs, size, kvap, flags));
}
void
-ebus_dmamem_unmap(t, kva, size)
- bus_dma_tag_t t;
- caddr_t kva;
- size_t size;
+ebus_dmamem_unmap(bus_dma_tag_t t, caddr_t kva, size_t size)
{
return (bus_dmamem_unmap(t->_parent, kva, size));
}
diff --git a/sys/arch/sparc64/dev/ebusvar.h b/sys/arch/sparc64/dev/ebusvar.h
index a2203c69dd9..023d8350ebb 100644
--- a/sys/arch/sparc64/dev/ebusvar.h
+++ b/sys/arch/sparc64/dev/ebusvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ebusvar.h,v 1.4 2002/03/14 01:26:44 millert Exp $ */
+/* $OpenBSD: ebusvar.h,v 1.5 2003/02/17 01:29:20 henric Exp $ */
/* $NetBSD: ebusvar.h,v 1.5 2001/07/20 00:07:13 eeh Exp $ */
/*
@@ -41,7 +41,8 @@ struct ebus_attach_args {
char *ea_name; /* PROM name */
int ea_node; /* PROM node */
- bus_space_tag_t ea_bustag;
+ bus_space_tag_t ea_memtag;
+ bus_space_tag_t ea_iotag;
bus_dma_tag_t ea_dmatag;
struct ebus_regs *ea_regs; /* registers */
@@ -60,7 +61,6 @@ struct ebus_softc {
bus_space_tag_t sc_memtag; /* from pci */
bus_space_tag_t sc_iotag; /* from pci */
- bus_space_tag_t sc_childbustag; /* pass to children */
bus_dma_tag_t sc_dmatag; /* XXX */
struct ebus_ranges *sc_range;
@@ -75,6 +75,6 @@ bus_dma_tag_t ebus_alloc_dma_tag(struct ebus_softc *, bus_dma_tag_t);
bus_space_tag_t ebus_alloc_bus_tag(struct ebus_softc *, int);
#define ebus_bus_map(t, bt, a, s, f, v, hp) \
- bus_space_map2(t, bt, a, s, f, v, hp)
+ bus_space_map(t, a, s, f, hp)
#endif /* _SPARC64_DEV_EBUSVAR_H_ */
diff --git a/sys/arch/sparc64/dev/iommu.c b/sys/arch/sparc64/dev/iommu.c
index e3829d1763e..9b75a86c311 100644
--- a/sys/arch/sparc64/dev/iommu.c
+++ b/sys/arch/sparc64/dev/iommu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: iommu.c,v 1.23 2002/10/12 01:09:43 krw Exp $ */
+/* $OpenBSD: iommu.c,v 1.24 2003/02/17 01:29:20 henric Exp $ */
/* $NetBSD: iommu.c,v 1.47 2002/02/08 20:03:45 eeh Exp $ */
/*
@@ -68,19 +68,21 @@ int iommudebug = 0x0;
int iommu_dvmamap_sync_seg(bus_dma_tag_t, struct iommu_state *,
bus_dma_segment_t *, bus_addr_t, bus_size_t, int);
+int iommu_dvmamap_sync_range(struct iommu_state *, vaddr_t, bus_size_t);
-#define iommu_strbuf_flush(i,v) do { \
- if ((i)->is_sb[0]) \
- bus_space_write_8((i)->is_bustag, \
- (bus_space_handle_t)(u_long) \
- &(i)->is_sb[0]->strbuf_pgflush, \
- 0, (v)); \
- if ((i)->is_sb[1]) \
- bus_space_write_8((i)->is_bustag, \
- (bus_space_handle_t)(u_long) \
- &(i)->is_sb[1]->strbuf_pgflush, \
- 0, (v)); \
- } while (0)
+static inline void
+iommu_strbuf_flush(struct iommu_state* is, vaddr_t va)
+{
+ int i;
+ for(i = 0; i < 2; ++i) {
+ struct strbuf_ctl *sb = is->is_sb[i];
+ if(sb == NULL || sb->sb_flush == NULL)
+ continue;
+
+ bus_space_write_8(sb->sb_bustag, sb->sb_sb,
+ STRBUFREG(strbuf_pgflush), va);
+ }
+}
static int iommu_strbuf_flush_done(struct iommu_state *);
int64_t iommu_tsb_entry(struct iommu_state *, vaddr_t);
@@ -94,11 +96,7 @@ static int iommu_tv_comp(struct timeval *, struct timeval *);
* - create a private DVMA map.
*/
void
-iommu_init(name, is, tsbsize, iovabase)
- char *name;
- struct iommu_state *is;
- int tsbsize;
- u_int32_t iovabase;
+iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase)
{
psize_t size;
vaddr_t va;
@@ -137,7 +135,7 @@ iommu_init(name, is, tsbsize, iovabase)
* contiguous.
*/
- size = NBPG<<(is->is_tsbsize);
+ size = NBPG << is->is_tsbsize;
TAILQ_INIT(&mlist);
if (uvm_pglistalloc((psize_t)size, (paddr_t)0, (paddr_t)-1,
(paddr_t)NBPG, (paddr_t)0, &mlist, 1, 0) != 0)
@@ -160,39 +158,39 @@ iommu_init(name, is, tsbsize, iovabase)
va += NBPG;
}
pmap_update(pmap_kernel());
- bzero(is->is_tsb, size);
+ memset(is->is_tsb, 0, size);
#ifdef DEBUG
- if (iommudebug & IDB_INFO)
- {
+ if (iommudebug & IDB_INFO) {
/* Probe the iommu */
- struct iommureg *regs = is->is_iommu;
-
+ /* The address or contents of the regs...? */
printf("iommu regs at: cr=%lx tsb=%lx flush=%lx\n",
- (u_long)&regs->iommu_cr,
- (u_long)&regs->iommu_tsb,
- (u_long)&regs->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;