summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authoreeh <eeh@NetBSD.org>2002-03-20 18:54:46 +0000
committereeh <eeh@NetBSD.org>2002-03-20 18:54:46 +0000
commit47ef6a51461b4e2ea69b8e327ef04f2e3c835f1c (patch)
tree76cd3e1f17759772b5418aaeeec7fe4470603a2e /sys
parentbd48e83999f624694fd27ac6e9f362612aa07d3f (diff)
Overhaul bus space.
bus_space_handle_t now holds an address and two ASIs, one for normal accesses and one for streaming accesses. This allows to map individual handles different ways, so some can use MMU bypass accesses and others use virtual addresses. bus_space_map() will now create handles that use bypass accesses unles BUS_SPACE_MAP_LINEAR is passed in. So only pass in BUS_SPACE_MAP_LINEAR if you absolutely *need* to use bus_space_vaddr(). This removes at least one extra level of indirection and should reduce TLB misses. 32-bit kernels have problems accessing 64-bit addresses, so they always use virtual addresses.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc64/dev/auxio.c57
-rw-r--r--sys/arch/sparc64/dev/com_ebus.c6
-rw-r--r--sys/arch/sparc64/dev/iommu.c141
-rw-r--r--sys/arch/sparc64/dev/iommureg.h4
-rw-r--r--sys/arch/sparc64/dev/iommuvar.h9
-rw-r--r--sys/arch/sparc64/dev/lpt_ebus.c9
-rw-r--r--sys/arch/sparc64/dev/pci_machdep.c10
-rw-r--r--sys/arch/sparc64/dev/psycho.c101
-rw-r--r--sys/arch/sparc64/dev/psychovar.h8
-rw-r--r--sys/arch/sparc64/dev/sbus.c92
-rw-r--r--sys/arch/sparc64/dev/zs.c18
-rw-r--r--sys/arch/sparc64/include/bus.h156
-rw-r--r--sys/arch/sparc64/sparc64/clock.c5
-rw-r--r--sys/arch/sparc64/sparc64/machdep.c90
14 files changed, 370 insertions, 336 deletions
diff --git a/sys/arch/sparc64/dev/auxio.c b/sys/arch/sparc64/dev/auxio.c
index 8f690e7fe9c..68610d331bf 100644
--- a/sys/arch/sparc64/dev/auxio.c
+++ b/sys/arch/sparc64/dev/auxio.c
@@ -1,4 +1,4 @@
-/* $NetBSD: auxio.c,v 1.4 2002/03/16 14:00:00 mrg Exp $ */
+/* $NetBSD: auxio.c,v 1.5 2002/03/20 18:54:46 eeh Exp $ */
/*
* Copyright (c) 2000, 2001 Matthew R. Green
@@ -164,26 +164,47 @@ auxio_ebus_attach(parent, self, aux)
struct auxio_softc *sc = (struct auxio_softc *)self;
struct ebus_attach_args *ea = aux;
- if (ea->ea_nreg < 1 || ea->ea_nvaddr < 1) {
+ sc->sc_tag = ea->ea_bustag;
+
+ if (ea->ea_nreg < 1) {
printf(": no registers??\n");
return;
}
- if (ea->ea_nreg != 5 || ea->ea_nvaddr != 5) {
+ if (ea->ea_nreg != 5) {
printf(": not 5 (%d) registers, only setting led",
ea->ea_nreg);
sc->sc_flags = AUXIO_LEDONLY|AUXIO_EBUS;
+ } else if (ea->ea_nvaddr == 5) {
+ sc->sc_flags = AUXIO_EBUS;
+
+ sparc_promaddr_to_handle(sc->sc_tag,
+ ea->ea_vaddr[1], &sc->sc_pci);
+ sparc_promaddr_to_handle(sc->sc_tag,
+ ea->ea_vaddr[2], &sc->sc_freq);
+ sparc_promaddr_to_handle(sc->sc_tag,
+ ea->ea_vaddr[3], &sc->sc_scsi);
+ sparc_promaddr_to_handle(sc->sc_tag,
+ ea->ea_vaddr[4], &sc->sc_temp);
} else {
sc->sc_flags = AUXIO_EBUS;
- sc->sc_pci = (bus_space_handle_t)(u_long)ea->ea_vaddr[1];
- sc->sc_freq = (bus_space_handle_t)(u_long)ea->ea_vaddr[2];
- sc->sc_scsi = (bus_space_handle_t)(u_long)ea->ea_vaddr[3];
- sc->sc_temp = (bus_space_handle_t)(u_long)ea->ea_vaddr[4];
+ bus_space_map(sc->sc_tag, EBUS_ADDR_FROM_REG(&ea->ea_reg[1]),
+ ea->ea_reg[1].size, 0, &sc->sc_pci);
+ bus_space_map(sc->sc_tag, EBUS_ADDR_FROM_REG(&ea->ea_reg[2]),
+ ea->ea_reg[2].size, 0, &sc->sc_freq);
+ bus_space_map(sc->sc_tag, EBUS_ADDR_FROM_REG(&ea->ea_reg[3]),
+ ea->ea_reg[3].size, 0, &sc->sc_scsi);
+ bus_space_map(sc->sc_tag, EBUS_ADDR_FROM_REG(&ea->ea_reg[4]),
+ ea->ea_reg[4].size, 0, &sc->sc_temp);
}
- sc->sc_led = (bus_space_handle_t)(u_long)ea->ea_vaddr[0];
-
- sc->sc_tag = ea->ea_bustag;
+ if (ea->ea_nvaddr > 0) {
+ sparc_promaddr_to_handle(sc->sc_tag,
+ ea->ea_vaddr[0], &sc->sc_led);
+ } else {
+ bus_space_map(sc->sc_tag, EBUS_ADDR_FROM_REG(&ea->ea_reg[0]),
+ ea->ea_reg[0].size, 0, &sc->sc_led);
+
auxio_attach_common(sc);
}
@@ -206,12 +227,14 @@ auxio_sbus_attach(parent, self, aux)
struct auxio_softc *sc = (struct auxio_softc *)self;
struct sbus_attach_args *sa = aux;
- if (sa->sa_nreg < 1 || sa->sa_npromvaddrs < 1) {
+ sc->sc_tag = sa->sa_bustag;
+
+ if (sa->sa_nreg < 1) {
printf(": no registers??\n");
return;
}
- if (sa->sa_nreg != 1 || sa->sa_npromvaddrs != 1) {
+ if (sa->sa_nreg != 1) {
printf(": not 1 (%d/%d) registers??", sa->sa_nreg,
sa->sa_npromvaddrs);
return;
@@ -219,9 +242,13 @@ 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 (sa->sa_npromvaddrs > 0) {
+ sbus_promaddr_to_handle(sc->sc_tag,
+ sa->sa_promvaddr, &sc->sc_led);
+ } else {
+ sbus_bus_map(sc->sc_tag, sa->sa_slot, sa->sa_offset,
+ sa->sa_size, 0, &sc->sc_led);
+ }
auxio_attach_common(sc);
}
diff --git a/sys/arch/sparc64/dev/com_ebus.c b/sys/arch/sparc64/dev/com_ebus.c
index 451a876a69a..d376d9c5e9b 100644
--- a/sys/arch/sparc64/dev/com_ebus.c
+++ b/sys/arch/sparc64/dev/com_ebus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: com_ebus.c,v 1.11 2002/03/16 14:00:00 mrg Exp $ */
+/* $NetBSD: com_ebus.c,v 1.12 2002/03/20 18:54:46 eeh Exp $ */
/*
* Copyright (c) 1999, 2000 Matthew R. Green
@@ -127,8 +127,10 @@ com_ebus_attach(parent, self, aux)
*
* Use the prom address if there.
*/
+
if (ea->ea_nvaddr)
- sc->sc_ioh = (bus_space_handle_t)ea->ea_vaddr[0];
+ sparc_promaddr_to_handle(sc->sc_iot, ea->ea_vaddr[0],
+ &sc->sc_ioh);
else if (bus_space_map(sc->sc_iot, EBUS_ADDR_FROM_REG(&ea->ea_reg[0]),
ea->ea_reg[0].size, 0, &sc->sc_ioh) != 0) {
printf(": can't map register space\n");
diff --git a/sys/arch/sparc64/dev/iommu.c b/sys/arch/sparc64/dev/iommu.c
index 19261fb1ed1..d39ed2c5665 100644
--- a/sys/arch/sparc64/dev/iommu.c
+++ b/sys/arch/sparc64/dev/iommu.c
@@ -1,4 +1,4 @@
-/* $NetBSD: iommu.c,v 1.49 2002/03/06 17:12:51 tsutsui Exp $ */
+/* $NetBSD: iommu.c,v 1.50 2002/03/20 18:54:47 eeh Exp $ */
/*
* Copyright (c) 2001, 2002 Eduardo Horvath
@@ -62,17 +62,13 @@ int iommudebug = 0x0;
#define DPRINTF(l, s)
#endif
-#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)); \
+#define iommu_strbuf_flush(i,v) do { \
+ if ((i)->is_sbvalid[0]) \
+ bus_space_write_8((i)->is_bustag, (i)->is_sb[0], \
+ STRBUFREG(strbuf_pgflush), (v)); \
+ if ((i)->is_sbvalid[1]) \
+ bus_space_write_8((i)->is_bustag, (i)->is_sb[1], \
+ STRBUFREG(strbuf_pgflush), (v)); \
} while (0)
static int iommu_strbuf_flush_done __P((struct iommu_state *));
@@ -157,14 +153,23 @@ iommu_init(name, is, tsbsize, iovabase)
if (iommudebug & IDB_INFO)
{
/* Probe the iommu */
- struct iommureg *regs = is->is_iommu;
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_read_8(is->is_bustag, is->is_iommu,
+ offsetof (struct iommureg, iommu_cr)),
+ (u_long)bus_space_read_8(is->is_bustag, is->is_iommu,
+ offsetof (struct iommureg, iommu_tsb)),
+ (u_long)bus_space_read_8(is->is_bustag, is->is_iommu,
+ offsetof (struct iommureg, iommu_flush)));
+ printf("iommu cr=%llx tsb=%llx\n",
+ (unsigned long long)bus_space_read_8(is->is_bustag,
+ is->is_iommu,
+ offsetof (struct iommureg, iommu_cr)),
+ (unsigned long long)bus_space_read_8(is->is_bustag,
+ is->is_iommu,
+ offsetof (struct iommureg, iommu_tsb)));
+ printf("TSB base %p phys %llx\n", (void *)is->is_tsb,
+ (unsigned long long)is->is_ptsb);
delay(1000000); /* 1 s */
}
#endif
@@ -172,7 +177,7 @@ iommu_init(name, is, tsbsize, iovabase)
/*
* Initialize streaming buffer, if it is there.
*/
- if (is->is_sb[0] || is->is_sb[1])
+ if (is->is_sbvalid[0] || is->is_sbvalid[1])
(void)pmap_extract(pmap_kernel(), (vaddr_t)&is->is_flush[0],
(paddr_t *)&is->is_flushpa);
@@ -204,31 +209,27 @@ void
iommu_reset(is)
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);
+ bus_space_write_8(is->is_bustag, is->is_iommu, IOMMUREG(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);
+ bus_space_write_8(is->is_bustag, is->is_iommu, IOMMUREG(iommu_cr),
+ is->is_cr|IOMMUCR_DE);
for (i=0; i<2; i++) {
- if ((sb = is->is_sb[i]) != NULL) {
+ if (is->is_sbvalid[i]) {
/* Enable diagnostics mode? */
- bus_space_write_8(is->is_bustag,
- (bus_space_handle_t)(u_long)&sb->strbuf_ctl,
- 0, STRBUF_EN);
+ bus_space_write_8(is->is_bustag, is->is_sb[i],
+ STRBUFREG(strbuf_ctl), 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;
+ if (bus_space_read_8(is->is_bustag, is->is_sb[i],
+ STRBUFREG(strbuf_ctl)) == 0)
+ is->is_sbvalid[i] = 0;
}
}
}
@@ -252,22 +253,24 @@ iommu_enter(is, va, pa, flags)
tte = MAKEIOTTE(pa, !(flags&BUS_DMA_NOWRITE), !(flags&BUS_DMA_NOCACHE),
(flags&BUS_DMA_STREAMING));
-tte |= (flags & 0xff000LL)<<(4*8);/* DEBUG */
+#ifdef DEBUG
+ tte |= (flags & 0xff000LL)<<(4*8);
+#endif
/* Is the streamcache flush really needed? */
- if (is->is_sb[0] || is->is_sb[1]) {
+ if (is->is_sbvalid[0] || is->is_sbvalid[1]) {
iommu_strbuf_flush(is, va);
iommu_strbuf_flush_done(is);
}
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);
+ bus_space_write_8(is->is_bustag, is->is_iommu,
+ IOMMUREG(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)],
- (u_long)tte));
+ va, (long)pa, (u_long)IOTSBSLOT(va,is->is_tsbsize),
+ (void *)(u_long)&is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)],
+ (u_long)tte));
}
@@ -315,17 +318,23 @@ iommu_remove(is, va, len)
va = trunc_page(va);
DPRINTF(IDB_IOMMU, ("iommu_remove: va %lx TSB[%lx]@%p\n",
- va, (u_long)IOTSBSLOT(va,is->is_tsbsize),
- &is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)]));
+ 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)]),
- (u_long)len));
+ 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_sbvalid[0] || is->is_sbvalid[1]) {
+ 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);
@@ -343,8 +352,8 @@ iommu_remove(is, va, len)
/* 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);
+ bus_space_write_8(is->is_bustag, is->is_iommu,
+ IOMMUREG(iommu_flush), va);
va += NBPG;
}
}
@@ -366,7 +375,7 @@ iommu_strbuf_flush_done(is)
} \
}
- if (!is->is_sb[0] && !is->is_sb[1])
+ if (!is->is_sbvalid[0] && !is->is_sbvalid[1])
return (0);
/*
@@ -384,15 +393,15 @@ iommu_strbuf_flush_done(is)
is->is_flush[0] = 1;
is->is_flush[1] = 1;
- if (is->is_sb[0]) {
+ if (is->is_sbvalid[0]) {
is->is_flush[0] = 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_write_8(is->is_bustag, is->is_sb[0],
+ STRBUFREG(strbuf_flushsync), is->is_flushpa);
}
- if (is->is_sb[1]) {
+ if (is->is_sbvalid[1]) {
is->is_flush[0] = 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_write_8(is->is_bustag, is->is_sb[1],
+ STRBUFREG(strbuf_flushsync), is->is_flushpa + 8);
}
microtime(&flushtimeout);
@@ -948,11 +957,12 @@ iommu_dvmamap_sync(t, is, map, offset, len, ops)
("iommu_dvmamap_sync: 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])
+ if (is->is_sbvalid[0] || is->is_sbvalid[1])
while (len > 0) {
DPRINTF(IDB_BUSDMA,
- ("iommu_dvmamap_sync: flushing va %p, %lu "
- "bytes left\n", (void *)(u_long)va, (u_long)len));
+ ("iommu_dvmamap_sync: flushing va %p, "
+ "%lu bytes left\n", (void *)(u_long)va,
+ (u_long)len));
iommu_strbuf_flush(is, va);
if (len <= NBPG) {
iommu_strbuf_flush_done(is);
@@ -967,11 +977,12 @@ iommu_dvmamap_sync(t, is, map, offset, len, ops)
("iommu_dvmamap_sync: 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])
+ if (is->is_sbvalid[0] || is->is_sbvalid[1])
while (len > 0) {
DPRINTF(IDB_BUSDMA,
("iommu_dvmamap_sync: flushing va %p, %lu "
- "bytes left\n", (void *)(u_long)va, (u_long)len));
+ "bytes left\n", (void *)(u_long)va,
+ (u_long)len));
iommu_strbuf_flush(is, va);
if (len <= NBPG) {
iommu_strbuf_flush_done(is);
diff --git a/sys/arch/sparc64/dev/iommureg.h b/sys/arch/sparc64/dev/iommureg.h
index 373d321d1eb..34dbf8afdf8 100644
--- a/sys/arch/sparc64/dev/iommureg.h
+++ b/sys/arch/sparc64/dev/iommureg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: iommureg.h,v 1.7 2002/02/07 21:35:26 eeh Exp $ */
+/* $NetBSD: iommureg.h,v 1.8 2002/03/20 18:54:47 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -66,6 +66,8 @@ struct iommu_strbuf {
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
diff --git a/sys/arch/sparc64/dev/iommuvar.h b/sys/arch/sparc64/dev/iommuvar.h
index 5675629f232..a3e2bcbfd74 100644
--- a/sys/arch/sparc64/dev/iommuvar.h
+++ b/sys/arch/sparc64/dev/iommuvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: iommuvar.h,v 1.10 2002/02/07 21:35:27 eeh Exp $ */
+/* $NetBSD: iommuvar.h,v 1.11 2002/03/20 18:54:47 eeh Exp $ */
/*
* Copyright (c) 1999 Matthew R. Green
@@ -47,10 +47,11 @@ struct iommu_state {
/* Needs to be volatile or egcs optimizes away loads */
volatile int64_t is_flush[2];
- /* copies of our parents state, to allow us to be self contained */
+ /* copies of our piarents 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 */
+ bus_space_handle_t is_sb[2]; /* streaming buffer(s) */
+ int is_sbvalid[2];
};
/* interfaces for PCI/SBUS code */
diff --git a/sys/arch/sparc64/dev/lpt_ebus.c b/sys/arch/sparc64/dev/lpt_ebus.c
index 8adc87359b2..472b13e5adb 100644
--- a/sys/arch/sparc64/dev/lpt_ebus.c
+++ b/sys/arch/sparc64/dev/lpt_ebus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: lpt_ebus.c,v 1.10 2002/03/16 14:00:00 mrg Exp $ */
+/* $NetBSD: lpt_ebus.c,v 1.11 2002/03/20 18:54:47 eeh Exp $ */
/*
* Copyright (c) 1999, 2000 Matthew R. Green
@@ -90,11 +90,12 @@ lpt_ebus_attach(parent, self, aux)
* Use the prom address if there.
*/
if (ea->ea_nvaddr)
- sc->sc_ioh = (bus_space_handle_t)ea->ea_vaddr[0];
+ sparc_promaddr_to_handle(sc->sc_iot, ea->ea_vaddr[0],
+ &sc->sc_ioh);
else if (bus_space_map(sc->sc_iot,
EBUS_ADDR_FROM_REG(&ea->ea_reg[0]),
- ea->ea_reg[0].size,
- BUS_SPACE_MAP_LINEAR,
+ ea->ea_regs[0].size,
+ 0,
&sc->sc_ioh) != 0) {
printf(": can't map register space\n");
return;
diff --git a/sys/arch/sparc64/dev/pci_machdep.c b/sys/arch/sparc64/dev/pci_machdep.c
index c881a4b3cc4..3c778ff2447 100644
--- a/sys/arch/sparc64/dev/pci_machdep.c
+++ b/sys/arch/sparc64/dev/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_machdep.c,v 1.25 2001/10/17 22:16:41 thorpej Exp $ */
+/* $NetBSD: pci_machdep.c,v 1.26 2002/03/20 18:54:47 eeh Exp $ */
/*
* Copyright (c) 1999, 2000 Matthew R. Green
@@ -351,8 +351,8 @@ pci_conf_read(pc, tag, reg)
(long)tag, reg));
if (PCITAG_NODE(tag) != -1) {
DPRINTF(SPDB_CONF, ("asi=%x addr=%qx (offset=%x) ...",
- bus_type_asi[sc->sc_configtag->type],
- (long long)(sc->sc_configaddr +
+ sc->sc_configaddr._asi,
+ (long long)(sc->sc_configaddr._ptr +
PCITAG_OFFSET(tag) + reg),
(int)PCITAG_OFFSET(tag) + reg));
@@ -381,8 +381,8 @@ pci_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));
DPRINTF(SPDB_CONF, ("asi = %x; readaddr = %qx (offset = %x)\n",
- bus_type_asi[sc->sc_configtag->type],
- (long long)(sc->sc_configaddr + PCITAG_OFFSET(tag) + reg),
+ sc->sc_configaddr._asi,
+ (long long)(sc->sc_configaddr._ptr + PCITAG_OFFSET(tag) + reg),
(int)PCITAG_OFFSET(tag) + reg));
/* If we don't know it, just punt it. */
diff --git a/sys/arch/sparc64/dev/psycho.c b/sys/arch/sparc64/dev/psycho.c
index 8c4295dbad5..a95e31b380c 100644
--- a/sys/arch/sparc64/dev/psycho.c
+++ b/sys/arch/sparc64/dev/psycho.c
@@ -1,4 +1,4 @@
-/* $NetBSD: psycho.c,v 1.44 2002/03/15 07:06:24 eeh Exp $ */
+/* $NetBSD: psycho.c,v 1.45 2002/03/20 18:54:47 eeh Exp $ */
/*
* Copyright (c) 1999, 2000 Matthew R. Green
@@ -229,7 +229,7 @@ psycho_attach(parent, self, aux)
bus_space_handle_t bh;
u_int64_t csr;
int psycho_br[2], n, i;
- struct pci_ctl *pci_ctl;
+ bus_space_handle_t pci_ctl;
char *model = PROM_getpropstring(ma->ma_node, "model");
printf("\n");
@@ -239,7 +239,7 @@ psycho_attach(parent, self, aux)
sc->sc_dmatag = ma->ma_dmatag;
/*
- * call the model-specific initialisation routine.
+ * Identify the device.
*/
for (i=0; psycho_names[i].p_name; i++)
if (strcmp(model, psycho_names[i].p_name) == 0) {
@@ -263,8 +263,6 @@ found:
* (1) per-PBM PCI configuration space, containing only the
* PBM 256-byte PCI header
* (2) the shared psycho configuration registers (struct psychoreg)
- *
- * XXX use the prom address for the psycho registers? we do so far.
*/
/* Register layouts are different. stuupid. */
@@ -272,27 +270,29 @@ found:
sc->sc_basepaddr = (paddr_t)ma->ma_reg[2].ur_paddr;
if (ma->ma_naddress > 2) {
+ sparc_promaddr_to_handle(sc->sc_bustag,
+ ma->ma_address[2], &sc->sc_bh);
+ sparc_promaddr_to_handle(sc->sc_bustag,
+ ma->ma_address[0], &pci_ctl);
+
sc->sc_regs = (struct psychoreg *)
- (u_long)ma->ma_address[2];
- pci_ctl = (struct pci_ctl *)
- (u_long)ma->ma_address[0];
+ bus_space_vaddr(sc->sc_bustag, sc->sc_bh);
} else if (ma->ma_nreg > 2) {
- bus_space_handle_t handle;
/* We need to map this in ourselves. */
if (bus_space_map(sc->sc_bustag,
ma->ma_reg[2].ur_paddr,
- ma->ma_reg[2].ur_len, 0, &handle))
+ ma->ma_reg[2].ur_len, BUS_SPACE_MAP_LINEAR,
+ &sc->sc_bh))
panic("psycho_attach: cannot map regs");
- sc->sc_regs = (struct psychoreg *)(u_long)handle;
+ sc->sc_regs = (struct psychoreg *)
+ bus_space_vaddr(sc->sc_bustag, sc->sc_bh);
if (bus_space_map(sc->sc_bustag,
ma->ma_reg[0].ur_paddr,
- ma->ma_reg[0].ur_len, 0, &handle))
+ ma->ma_reg[0].ur_len, BUS_SPACE_MAP_LINEAR,
+ &pci_ctl))
panic("psycho_attach: cannot map ctl");
-/* XXX -- this is lost but never unmapped */
- pci_ctl = (struct pci_ctl *)(u_long)handle;
-
} else
panic("psycho_attach: %d not enough registers",
ma->ma_nreg);
@@ -300,25 +300,35 @@ found:
sc->sc_basepaddr = (paddr_t)ma->ma_reg[0].ur_paddr;
if (ma->ma_naddress) {
+ sparc_promaddr_to_handle(sc->sc_bustag,
+ ma->ma_address[0], &sc->sc_bh);
sc->sc_regs = (struct psychoreg *)
- (u_long)ma->ma_address[0];
- pci_ctl = (struct pci_ctl *)&sc->sc_regs->psy_pcictl[0];
+ bus_space_vaddr(sc->sc_bustag, sc->sc_bh);
+ bus_space_subregion(sc->sc_bustag, sc->sc_bh,
+ offsetof(struct psychoreg, psy_pcictl),
+ sizeof(struct pci_ctl), &pci_ctl);
} else if (ma->ma_nreg) {
- bus_space_handle_t handle;
/* We need to map this in ourselves. */
if (bus_space_map(sc->sc_bustag,
ma->ma_reg[0].ur_paddr,
- ma->ma_reg[0].ur_len, 0, &handle))
+ ma->ma_reg[0].ur_len, BUS_SPACE_MAP_LINEAR,
+ &sc->sc_bh))
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];
+ sc->sc_regs = (struct psychoreg *)
+ bus_space_vaddr(sc->sc_bustag, sc->sc_bh);
+
+ bus_space_subregion(sc->sc_bustag, sc->sc_bh,
+ offsetof(struct psychoreg, psy_pcictl),
+ sizeof(struct pci_ctl), &pci_ctl);
} else
panic("psycho_attach: %d not enough registers",
ma->ma_nreg);
}
- csr = sc->sc_regs->psy_csr;
+
+ csr = bus_space_read_8(sc->sc_bustag, sc->sc_bh,
+ offsetof(struct psychoreg, 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;
@@ -355,8 +365,8 @@ found:
/*
* 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 = bus_space_read_8(sc->sc_bustag, pci_ctl,
+ offsetof(struct pci_ctl, pci_csr));
csr |= PCICTL_MRLM |
PCICTL_ARB_PARK |
PCICTL_ERRINTEN |
@@ -365,8 +375,8 @@ found:
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);
+ bus_space_write_8(sc->sc_bustag, pci_ctl,
+ offsetof(struct pci_ctl, pci_csr), csr);
/*
@@ -391,7 +401,7 @@ found:
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 = pci_ctl;
/* allocate our tags */
pp->pp_memt = psycho_alloc_mem_tag(pp);
@@ -451,18 +461,13 @@ found:
* a retry of 3-6 usec (which is what sysio is set to) for the
* moment, which seems to help alleviate this problem.
*/
- timeo = bus_space_read_8(sc->sc_bustag,
- (bus_space_handle_t)
- (u_long)&sc->sc_regs->intr_retry_timer, 0);
+ timeo = sc->sc_regs->intr_retry_timer;
if (timeo > 0xfff) {
#ifdef DEBUG
printf("decreasing interrupt retry timeout "
"from %lx to 0xff\n", (long)timeo);
#endif
- bus_space_write_8(sc->sc_bustag,
- (bus_space_handle_t)
- (u_long)&sc->sc_regs->intr_retry_timer, 0,
- 0xff);
+ sc->sc_regs->intr_retry_timer = 0xff;
}
/*
@@ -479,12 +484,16 @@ found:
M_DEVBUF, M_NOWAIT);
if (sc->sc_is == NULL)
panic("psycho_attach: malloc iommu_state");
+ sc->sc_is->is_sbvalid[0] = sc->sc_is->is_sbvalid[1] = 0;
- sc->sc_is->is_sb[0] = 0;
- sc->sc_is->is_sb[1] = 0;
- if (PROM_getproplen(sc->sc_node, "no-streaming-cache") >= 0)
- sc->sc_is->is_sb[0] = &pci_ctl->pci_strbuf;
+ if (PROM_getproplen(sc->sc_node, "no-streaming-cache") < 0) {
+ bus_space_subregion(sc->sc_bustag, sc->sc_bh,
+ offsetof(struct pci_ctl, pci_strbuf),
+ sizeof (struct iommu_strbuf),
+ &sc->sc_is->is_sb[0]);
+ sc->sc_is->is_sbvalid[0] = 1;
+ }
psycho_iommu_init(sc, 2);
@@ -500,15 +509,20 @@ found:
0x0100000, 0, &bh))
panic("could not map psycho PCI configuration space");
sc->sc_bustag->type = i;
- sc->sc_configaddr = (off_t)bh;
+ sc->sc_configaddr = 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 (PROM_getproplen(sc->sc_node, "no-streaming-cache") >= 0)
- sc->sc_is->is_sb[1] = &pci_ctl->pci_strbuf;
+ if (PROM_getproplen(sc->sc_node, "no-streaming-cache") < 0) {
+ bus_space_subregion(sc->sc_bustag, sc->sc_bh,
+ offsetof(struct pci_ctl, pci_strbuf),
+ sizeof (struct iommu_strbuf),
+ &sc->sc_is->is_sb[1]);
+ sc->sc_is->is_sbvalid[1] = 1;
+ }
iommu_reset(sc->sc_is);
}
@@ -744,7 +758,10 @@ 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_bh,
+ offsetof(struct psychoreg, psy_iommu),
+ sizeof (struct iommureg),
+ &is->is_iommu);
/*
* Separate the men from the boys. Get the `virtual-dma'
diff --git a/sys/arch/sparc64/dev/psychovar.h b/sys/arch/sparc64/dev/psychovar.h
index de28ee21bd2..98714b79134 100644
--- a/sys/arch/sparc64/dev/psychovar.h
+++ b/sys/arch/sparc64/dev/psychovar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: psychovar.h,v 1.6 2001/07/20 00:07:13 eeh Exp $ */
+/* $NetBSD: psychovar.h,v 1.7 2002/03/20 18:54:48 eeh Exp $ */
/*
* Copyright (c) 1999, 2000 Matthew R. Green
@@ -62,7 +62,7 @@ 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;
};
/*
@@ -93,7 +93,9 @@ struct psycho_softc {
/* our tags (from parent) */
bus_space_tag_t sc_bustag;
- bus_dma_tag_t sc_dmatag;
+ bus_dma_tag_t sc_dmatag;
+
+ bus_space_handle_t sc_bh;
/* config space */
bus_space_tag_t sc_configtag;
diff --git a/sys/arch/sparc64/dev/sbus.c b/sys/arch/sparc64/dev/sbus.c
index 8b5fb26b2b6..9192e11a768 100644
--- a/sys/arch/sparc64/dev/sbus.c
+++ b/sys/arch/sparc64/dev/sbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sbus.c,v 1.47 2002/03/14 20:51:35 eeh Exp $ */
+/* $NetBSD: sbus.c,v 1.48 2002/03/20 18:54:48 eeh Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -144,8 +144,6 @@ static bus_space_tag_t sbus_alloc_bustag __P((struct sbus_softc *));
static bus_dma_tag_t sbus_alloc_dmatag __P((struct sbus_softc *));
static int sbus_get_intr __P((struct sbus_softc *, int,
struct sbus_intr **, int *, int));
-int sbus_bus_mmap __P((bus_space_tag_t, bus_type_t, bus_addr_t,
- int, bus_space_handle_t *));
static int sbus_overtemp __P((void *));
static int _sbus_bus_map __P((
bus_space_tag_t,
@@ -206,14 +204,6 @@ void sbus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
* fall back on the `intr' property which contains the CPU IPL.
*/
-/* Translate Sbus interrupt level to processor IPL */
-static int intr_sbus2ipl_4c[] = {
- 0, 1, 2, 3, 5, 7, 8, 9
-};
-static int intr_sbus2ipl_4m[] = {
- 0, 2, 3, 5, 7, 9, 11, 13
-};
-
/*
* This value is or'ed into the attach args' interrupt level cookie
* if the interrupt level comes from an `intr' property, i.e. it is
@@ -283,19 +273,34 @@ sbus_attach(parent, self, aux)
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 */
-
- /* Setup interrupt translation tables */
- sc->sc_intr2ipl = CPU_ISSUN4C
- ? intr_sbus2ipl_4c
- : intr_sbus2ipl_4m;
+ sc->sc_ign = ma->ma_interrupts[0] & INTMAP_IGN;
+
+ /* XXXX Use sysio PROM mappings for interrupt vector regs. */
+ sparc_promaddr_to_handle(sc->sc_bustag, ma->ma_address[0], &sc->sc_bh);
+ sc->sc_sysio = (struct sysioreg *)bus_space_vaddr(sc->sc_bustag,
+ &sc->sc_bh);
+
+#ifdef _LP64
+ /*
+ * 32-bit kernels use virtual addresses for bus space operations
+ * so we may as well use the prom VA.
+ *
+ * 64-bit kernels use physical addresses for bus space operations
+ * so mapping this in again will reduce TLB thrashing.
+ */
+ if (bus_space_map(sc->sc_bustag, ma->ma_reg[0].ur_paddr,
+ ma->ma_reg[0].ur_len, 0, &sc->sc_bh) != 0) {
+ printf("%s: cannot map registers\n", self->dv_xname);
+ return;
+ }
+#endif
/*
* Record clock frequency for synchronous SCSI.
* IS THIS THE CORRECT DEFAULT??
*/
- sc->sc_clockfreq = PROM_getpropint(node, "clock-frequency", 25*1000*1000);
+ sc->sc_clockfreq = PROM_getpropint(node, "clock-frequency",
+ 25*1000*1000);
printf(": clock = %s MHz\n", clockfreq(sc->sc_clockfreq));
sbt = sbus_alloc_bustag(sc);
@@ -314,13 +319,18 @@ 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,
+ (vaddr_t)&((struct sysioreg *)NULL)->sys_iommu,
+ sizeof (struct iommureg), &sc->sc_is.is_iommu);
+ bus_space_subregion(sc->sc_bustag, sc->sc_bh,
+ (vaddr_t)&((struct sysioreg *)NULL)->sys_strbuf,
+ sizeof (struct iommu_strbuf), &sc->sc_is.is_sb[0]);
+ sc->sc_is.is_sbvalid[0] = 1;
+ sc->sc_is.is_sbvalid[1] = 0;
/* give us a nice name.. */
name = (char *)malloc(32, M_DEVBUF, M_NOWAIT);
@@ -484,33 +494,6 @@ _sbus_bus_map(t, addr, size, flags, v, 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)
@@ -740,8 +723,8 @@ 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);
+ /* XXXX */
+ *(ih->ih_map) = vec;
} else {
int64_t *intrptr = &sc->sc_sysio->scsi_int_map;
int64_t intrmap = 0;
@@ -763,9 +746,8 @@ sbus_intr_establish(t, pri, level, flags, handler, arg)
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,
- (u_long)intrmap);
+ /* XXXX */
+ *(ih->ih_map) = intrmap;
} else
panic("IRQ not found!");
}
diff --git a/sys/arch/sparc64/dev/zs.c b/sys/arch/sparc64/dev/zs.c
index d3d39a24ad8..e8db9296778 100644
--- a/sys/arch/sparc64/dev/zs.c
+++ b/sys/arch/sparc64/dev/zs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: zs.c,v 1.32 2002/03/14 20:54:18 eeh Exp $ */
+/* $NetBSD: zs.c,v 1.33 2002/03/20 18:54:48 eeh Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -215,6 +215,7 @@ zs_attach_mainbus(parent, self, aux)
{
struct zsc_softc *zsc = (void *) self;
struct sbus_attach_args *sa = aux;
+ bus_space_handle_t bh;
int zs_unit = zsc->zsc_dev.dv_unit;
if (sa->sa_nintr == 0) {
@@ -222,7 +223,7 @@ zs_attach_mainbus(parent, self, aux)
return;
}
- /* Use the mapping setup by the Sun PROM. */
+ /* Use the mapping setup by the Sun PROM if possible. */
if (zsaddr[zs_unit] == NULL) {
/* Only map registers once. */
if (sa->sa_npromvaddrs) {
@@ -236,24 +237,23 @@ zs_attach_mainbus(parent, self, aux)
* high 4GB range, this needs to be changed to
* sign-extend the address.
*/
- zsaddr[zs_unit] =
- (struct zsdevice *)
- (uintptr_t)sa->sa_promvaddrs[0];
+ sparc_promaddr_to_handle(sa->sa_bustag,
+ sa->sa_promvaddrs[0], &bh)
+
} else {
- bus_space_handle_t kvaddr;
if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
sa->sa_offset,
sa->sa_size,
BUS_SPACE_MAP_LINEAR,
- &kvaddr) != 0) {
+ &bh) != 0) {
printf("%s @ sbus: cannot map registers\n",
self->dv_xname);
return;
}
- zsaddr[zs_unit] = (struct zsdevice *)
- (uintptr_t)kvaddr;
}
+ zsaddr[zs_unit] = (struct zsdevice *)
+ bus_space_vaddr(sa->sa_bustag, bh);
}
zsc->zsc_bustag = sa->sa_bustag;
zsc->zsc_dmatag = sa->sa_dmatag;
diff --git a/sys/arch/sparc64/include/bus.h b/sys/arch/sparc64/include/bus.h
index 3954bbe7ec5..60f2525e037 100644
--- a/sys/arch/sparc64/include/bus.h
+++ b/sys/arch/sparc64/include/bus.h
@@ -1,4 +1,4 @@
-/* $NetBSD: bus.h,v 1.37 2002/03/15 07:06:23 eeh Exp $ */
+/* $NetBSD: bus.h,v 1.38 2002/03/20 18:54:49 eeh Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
@@ -98,8 +98,6 @@ enum bus_type {
PCI_MEMORY_BUS_SPACE,
LAST_BUS_SPACE
};
-extern int bus_type_asi[];
-extern int bus_stream_asi[];
/* For backwards compatibility */
#define SPARC_BUS_SPACE UPA_BUS_SPACE
@@ -108,11 +106,26 @@ extern int bus_stream_asi[];
/*
* Bus address and size types
*/
-typedef u_int64_t bus_space_handle_t;
+typedef struct _bus_space_handle {
+ uint64_t _ptr;
+ int8_t _asi;
+ int8_t _sasi;
+ char _virtual;
+} bus_space_handle_t;
typedef enum bus_type bus_type_t;
typedef u_int64_t bus_addr_t;
typedef u_int64_t bus_size_t;
+/*
+ * XXXX -- convert prom virtual address to bus_space_handle_t
+ */
+#define sparc_promaddr_to_handle(tag, promaddr, hp) \
+ do { \
+ hp->_ptr = (uint64_t)promaddr; \
+ hp->_asi = ASI_PRIMARY; \
+ hp->_sasi = ASI_PRIMARY; \
+ } while (0)
+
/* For buses which have an iospace. */
#define BUS_ADDR_IOSPACE(x) ((x)>>32)
#define BUS_ADDR_PADDR(x) ((x)&0xffffffff)
@@ -309,12 +322,9 @@ bus_intr_establish(t, p, l, f, h, a)
_BS_CALL(t, sparc_intr_establish)(t, p, l, f, h, a);
}
-#if 1
/* XXXX Things get complicated if we use unmapped register accesses. */
-#define bus_space_vaddr(t, h) (vaddr_t)(h)
-#else
-void * bus_space_vaddr __P((bus_space_tag_t space, bus_space_handle_t handle));
-#endif
+#define bus_space_vaddr(t, h) (PHYS_ASI((h)._asi) ? \
+ NULL : (void *)(vaddr_t)((h)._ptr))
/* flags for bus space map functions */
#define BUS_SPACE_MAP_CACHEABLE 0x0001
@@ -369,51 +379,51 @@ bus_space_barrier(t, h, o, s, f)
*/
#ifndef BUS_SPACE_DEBUG
#define bus_space_read_1(t, h, o) \
- lduba((h) + (o), bus_type_asi[(t)->type])
+ (0 ? (t)->type : lduba((h)._ptr + (o), (h)._asi))
#define bus_space_read_2(t, h, o) \
- lduha((h) + (o), bus_type_asi[(t)->type])
+ (0 ? (t)->type : lduha((h)._ptr + (o), (h)._asi))
#define bus_space_read_4(t, h, o) \
- lda((h) + (o), bus_type_asi[(t)->type])
+ (0 ? (t)->type : lda((h)._ptr + (o), (h)._asi))
#define bus_space_read_8(t, h, o) \
- ldxa((h) + (o), bus_type_asi[(t)->type])
+ (0 ? (t)->type : ldxa((h)._ptr + (o), (h)._asi))
#else
#define bus_space_read_1(t, h, o) ({ \
unsigned char __bv = \
- lduba((h) + (o), bus_type_asi[(t)->type]); \
+ lduba((h)._ptr + (o), (h)._asi); \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsr1(%llx + %llx, %x) -> %x\n", (long long)(h), \
+ printf("bsr1(%llx + %llx, %x) -> %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_type_asi[(t)->type], (unsigned int) __bv); \
+ (h)._asi, (unsigned int) __bv); \
__bv; })
#define bus_space_read_2(t, h, o) ({ \
unsigned short __bv = \
- lduha((h) + (o), bus_type_asi[(t)->type]); \
+ lduha((h)._ptr + (o), (h)._asi); \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsr2(%llx + %llx, %x) -> %x\n", (long long)(h), \
+ printf("bsr2(%llx + %llx, %x) -> %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_type_asi[(t)->type], (unsigned int)__bv); \
+ (h)._asi, (unsigned int)__bv); \
__bv; })
#define bus_space_read_4(t, h, o) ({ \
unsigned int __bv = \
- lda((h) + (o), bus_type_asi[(t)->type]); \
+ lda((h)._ptr + (o), (h)._asi); \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsr4(%llx + %llx, %x) -> %x\n", (long long)(h), \
+ printf("bsr4(%llx + %llx, %x) -> %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_type_asi[(t)->type], __bv); \
+ (h)._asi, __bv); \
__bv; })
#define bus_space_read_8(t, h, o) ({ \
u_int64_t __bv = \
- ldxa((h) + (o), bus_type_asi[(t)->type]); \
+ ldxa((h)._ptr + (o), (h)._asi); \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsr8(%llx + %llx, %x) -> %llx\n", (long long)(h), \
+ printf("bsr8(%llx + %llx, %x) -> %llx\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_type_asi[(t)->type], (long long)__bv); \
+ (h)._asi, (long long)__bv); \
__bv; })
#endif
/*
@@ -463,44 +473,44 @@ bus_space_barrier(t, h, o, s, f)
*/
#ifndef BUS_SPACE_DEBUG
#define bus_space_write_1(t, h, o, v) \
- ((void)(stba((h) + (o), bus_type_asi[(t)->type], (v))))
+ (0 ? (t)->type : ((void)(stba((h)._ptr + (o), (h)._asi, (v)))))
#define bus_space_write_2(t, h, o, v) \
- ((void)(stha((h) + (o), bus_type_asi[(t)->type], (v))))
+ (0 ? (t)->type : ((void)(stha((h)._ptr + (o), (h)._asi, (v)))))
#define bus_space_write_4(t, h, o, v) \
- ((void)(sta((h) + (o), bus_type_asi[(t)->type], (v))))
+ (0 ? (t)->type : ((void)(sta((h)._ptr + (o), (h)._asi, (v)))))
#define bus_space_write_8(t, h, o, v) \
- ((void)(stxa((h) + (o), bus_type_asi[(t)->type], (v))))
+ (0 ? (t)->type : ((void)(stxa((h)._ptr + (o), (h)._asi, (v)))))
#else
#define bus_space_write_1(t, h, o, v) ({ \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsw1(%llx + %llx, %x) <- %x\n", (long long)(h), \
+ printf("bsw1(%llx + %llx, %x) <- %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_type_asi[(t)->type], (unsigned int) v); \
- ((void)(stba((h) + (o), bus_type_asi[(t)->type], (v)))); })
+ (h)._asi, (unsigned int) v); \
+ ((void)(stba((h)._ptr + (o), (h)._asi, (v)))); })
#define bus_space_write_2(t, h, o, v) ({ \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsw2(%llx + %llx, %x) <- %x\n", (long long)(h), \
+ printf("bsw2(%llx + %llx, %x) <- %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_type_asi[(t)->type], (unsigned int) v); \
- ((void)(stha((h) + (o), bus_type_asi[(t)->type], (v)))); })
+ (h)._asi, (unsigned int) v); \
+ ((void)(stha((h)._ptr + (o), (h)._asi, (v)))); })
#define bus_space_write_4(t, h, o, v) ({ \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsw4(%llx + %llx, %x) <- %x\n", (long long)(h), \
+ printf("bsw4(%llx + %llx, %x) <- %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_type_asi[(t)->type], (unsigned int) v); \
- ((void)(sta((h) + (o), bus_type_asi[(t)->type], (v)))); })
+ (h)._asi, (unsigned int) v); \
+ ((void)(sta((h)._ptr + (o), (h)._asi, (v)))); })
#define bus_space_write_8(t, h, o, v) ({ \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsw8(%llx + %llx, %x) <- %llx\n", (long long)(h), \
+ printf("bsw8(%llx + %llx, %x) <- %llx\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_type_asi[(t)->type], (long long) v); \
- ((void)(stxa((h) + (o), bus_type_asi[(t)->type], (v)))); })
+ (h)._asi, (long long) v); \
+ ((void)(stxa((h)._ptr + (o), (h)._asi, (v)))); })
#endif
/*
* void bus_space_write_multi_N __P((bus_space_tag_t tag,
@@ -871,51 +881,51 @@ bus_space_copy_region_8(t, h1, o1, h2, o2, c)
*/
#ifndef BUS_SPACE_DEBUG
#define bus_space_read_stream_1(t, h, o) \
- lduba((h) + (o), bus_stream_asi[(t)->type])
+ (0 ? (t)->type : lduba((h)._ptr + (o), (h)._sasi))
#define bus_space_read_stream_2(t, h, o) \
- lduha((h) + (o), bus_stream_asi[(t)->type])
+ (0 ? (t)->type : lduha((h)._ptr + (o), (h)._sasi))
#define bus_space_read_stream_4(t, h, o) \
- lda((h) + (o), bus_stream_asi[(t)->type])
+ (0 ? (t)->type : lda((h)._ptr + (o), (h)._sasi))
#define bus_space_read_stream_8(t, h, o) \
- ldxa((h) + (o), bus_stream_asi[(t)->type])
+ (0 ? (t)->type : ldxa((h)._ptr + (o), (h)._sasi))
#else
#define bus_space_read_stream_1(t, h, o) ({ \
unsigned char __bv = \
- lduba((h) + (o), bus_stream_asi[(t)->type]); \
+ lduba((h)._ptr + (o), (h)._sasi); \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsr1(%llx + %llx, %x) -> %x\n", (long long)(h), \
+ printf("bsr1(%llx + %llx, %x) -> %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_stream_asi[(t)->type], (unsigned int) __bv); \
+ (h)._sasi, (unsigned int) __bv); \
__bv; })
#define bus_space_read_stream_2(t, h, o) ({ \
unsigned short __bv = \
- lduha((h) + (o), bus_stream_asi[(t)->type]); \
+ lduha((h)._ptr + (o), (h)._sasi); \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsr2(%llx + %llx, %x) -> %x\n", (long long)(h), \
+ printf("bsr2(%llx + %llx, %x) -> %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_stream_asi[(t)->type], (unsigned int)__bv); \
+ (h)._sasi, (unsigned int)__bv); \
__bv; })
#define bus_space_read_stream_4(t, h, o) ({ \
unsigned int __bv = \
- lda((h) + (o), bus_stream_asi[(t)->type]); \
+ lda((h)._ptr + (o), (h)._sasi); \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsr4(%llx + %llx, %x) -> %x\n", (long long)(h), \
+ printf("bsr4(%llx + %llx, %x) -> %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_stream_asi[(t)->type], __bv); \
+ (h)._sasi, __bv); \
__bv; })
#define bus_space_read_stream_8(t, h, o) ({ \
u_int64_t __bv = \
- ldxa((h) + (o), bus_stream_asi[(t)->type]); \
+ ldxa((h)._ptr + (o), (h)._sasi); \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsr8(%llx + %llx, %x) -> %llx\n", (long long)(h), \
+ printf("bsr8(%llx + %llx, %x) -> %llx\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_stream_asi[(t)->type], (long long)__bv); \
+ (h)._sasi, (long long)__bv); \
__bv; })
#endif
/*
@@ -965,44 +975,44 @@ bus_space_copy_region_8(t, h1, o1, h2, o2, c)
*/
#ifndef BUS_SPACE_DEBUG
#define bus_space_write_stream_1(t, h, o, v) \
- ((void)(stba((h) + (o), bus_stream_asi[(t)->type], (v))))
+ (0 ? (t)->type : ((void)(stba((h)._ptr + (o), (h)._sasi, (v)))))
#define bus_space_write_stream_2(t, h, o, v) \
- ((void)(stha((h) + (o), bus_stream_asi[(t)->type], (v))))
+ (0 ? (t)->type : ((void)(stha((h)._ptr + (o), (h)._sasi, (v)))))
#define bus_space_write_stream_4(t, h, o, v) \
- ((void)(sta((h) + (o), bus_stream_asi[(t)->type], (v))))
+ (0 ? (t)->type : ((void)(sta((h)._ptr + (o), (h)._sasi, (v)))))
#define bus_space_write_stream_8(t, h, o, v) \
- ((void)(stxa((h) + (o), bus_stream_asi[(t)->type], (v))))
+ (0 ? (t)->type : ((void)(stxa((h)._ptr + (o), (h)._sasi, (v)))))
#else
#define bus_space_write_stream_1(t, h, o, v) ({ \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsw1(%llx + %llx, %x) <- %x\n", (long long)(h), \
+ printf("bsw1(%llx + %llx, %x) <- %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_stream_asi[(t)->type], (unsigned int) v); \
- ((void)(stba((h) + (o), bus_stream_asi[(t)->type], (v)))); })
+ (h)._sasi, (unsigned int) v); \
+ ((void)(stba((h)._ptr + (o), (h)._sasi, (v)))); })
#define bus_space_write_stream_2(t, h, o, v) ({ \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsw2(%llx + %llx, %x) <- %x\n", (long long)(h), \
+ printf("bsw2(%llx + %llx, %x) <- %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_stream_asi[(t)->type], (unsigned int) v); \
- ((void)(stha((h) + (o), bus_stream_asi[(t)->type], (v)))); })
+ (h)._sasi, (unsigned int) v); \
+ ((void)(stha((h)._ptr + (o), (h)._sasi, (v)))); })
#define bus_space_write_stream_4(t, h, o, v) ({ \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsw4(%llx + %llx, %x) <- %x\n", (long long)(h), \
+ printf("bsw4(%llx + %llx, %x) <- %x\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_stream_asi[(t)->type], (unsigned int) v); \
- ((void)(sta((h) + (o), bus_stream_asi[(t)->type], (v)))); })
+ (h)._sasi, (unsigned int) v); \
+ ((void)(sta((h)._ptr + (o), (h)._sasi, (v)))); })
#define bus_space_write_stream_8(t, h, o, v) ({ \
if (bus_space_debug & BSDB_ACCESS) \
- printf("bsw8(%llx + %llx, %x) <- %llx\n", (long long)(h), \
+ printf("bsw8(%llx + %llx, %x) <- %llx\n", (long long)(h)._ptr, \
(long long)(o), \
- bus_stream_asi[(t)->type], (long long) v); \
- ((void)(stxa((h) + (o), bus_stream_asi[(t)->type], (v)))); })
+ (h)._sasi, (long long) v); \
+ ((void)(stxa((h)._ptr + (o), (h)._sasi, (v)))); })
#endif
/*
* void bus_space_write_multi_stream_N __P((bus_space_tag_t tag,
diff --git a/sys/arch/sparc64/sparc64/clock.c b/sys/arch/sparc64/sparc64/clock.c
index 6489191264d..fc7421b73ae 100644
--- a/sys/arch/sparc64/sparc64/clock.c
+++ b/sys/arch/sparc64/sparc64/clock.c
@@ -1,4 +1,4 @@
-/* $NetBSD: clock.c,v 1.48 2002/03/16 14:00:01 mrg Exp $ */
+/* $NetBSD: clock.c,v 1.49 2002/03/20 18:54:49 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -365,7 +365,8 @@ clockattach(node, bt, bh)
panic("Can't attach %s tod clock", model);
#define IDPROM_OFFSET (8*1024 - 40) /* XXX - get nvram sz from driver */
- idp = (struct idprom *)((u_long)bh + IDPROM_OFFSET);
+ idp = (struct idprom *)((vaddr_t)bus_space_vaddr(bt, bh) +
+ IDPROM_OFFSET);
h = idp->id_machine << 24;
h |= idp->id_hostid[0] << 16;
diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c
index 3fe35b23ebe..c98bd3a9212 100644
--- a/sys/arch/sparc64/sparc64/machdep.c
+++ b/sys/arch/sparc64/sparc64/machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.118 2002/03/20 17:59:25 christos Exp $ */
+/* $NetBSD: machdep.c,v 1.119 2002/03/20 18:54:49 eeh Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -164,53 +164,6 @@ int safepri = 0;
void dumpsys __P((void));
void stackdump __P((void));
-/*
- * This is the table that tells us how to access different bus space types.
- */
-#define BUS_BYPASS_ACCESS_ENABLED 0
-#if BUS_BYPASS_ACCESS_ENABLED == 1
-/*
- * Bypass access
- */
-int bus_type_asi[] = {
- ASI_PHYS_NON_CACHED, /* UPA */
- ASI_PHYS_NON_CACHED, /* SBUS */
- ASI_PHYS_NON_CACHED_LITTLE, /* PCI configuration space */
- ASI_PHYS_NON_CACHED_LITTLE, /* PCI memory space */
- ASI_PHYS_NON_CACHED_LITTLE, /* PCI I/O space */
- 0
-};
-
-int bus_stream_asi[] = {
- ASI_PHYS_NON_CACHED, /* UPA */
- ASI_PHYS_NON_CACHED, /* SBUS */
- ASI_PHYS_NON_CACHED, /* PCI configuration space */
- ASI_PHYS_NON_CACHED, /* PCI memory space */
- ASI_PHYS_NON_CACHED, /* PCI I/O space */
- 0
-};
-#else
-/*
- * MMU access - we want to use the MMU for all this..
- */
-int bus_type_asi[] = {
- ASI_PRIMARY, /* UPA */
- ASI_PRIMARY, /* SBUS */
- ASI_PHYS_NON_CACHED_LITTLE, /* PCI configuration space */
- ASI_PRIMARY, /* PCI memory space */
- ASI_PRIMARY, /* PCI I/O space */
- 0
-};
-
-int bus_stream_asi[] = {
- ASI_PRIMARY, /* UPA */
- ASI_PRIMARY, /* SBUS */
- ASI_PHYS_NON_CACHED, /* PCI configuration space */
- ASI_PRIMARY_LITTLE, /* PCI memory space */
- ASI_PRIMARY_LITTLE, /* PCI I/O space */
- 0
-};
-#endif
/*
* Machine-dependent startup code
@@ -1811,11 +1764,13 @@ sparc_bus_map(t, addr, size, flags, unused, hp)
* rather it will be accessed through MMU bypass ASI accesses.
*/
if (flags & BUS_SPACE_MAP_LINEAR) return (-1);
- *hp = (bus_space_handle_t)addr;
+ hp->_ptr = addr;
+ hp->_asi = ASI_PHYS_NON_CACHED_LITTLE;
+ hp->_sasi = ASI_PHYS_NON_CACHED;
DPRINTF(BSDB_MAP, ("\nsparc_bus_map: type %x flags %x "
"addr %016llx size %016llx virt %llx paddr %016llx\n",
(int)t->type, (int) flags, (unsigned long long)addr,
- (unsigned long long)size, (unsigned long long)*hp,
+ (unsigned long long)size, (unsigned long long)hp->_ptr,
(unsigned long long)pa));
return (0);
/* FALLTHROUGH */
@@ -1830,6 +1785,19 @@ sparc_bus_map(t, addr, size, flags, unused, hp)
break;
}
+#ifdef _LP64
+ /* If it's not LINEAR don't bother to map it. Use phys accesses. */
+ if ((flags & BUS_SPACE_MAP_LINEAR) == 0) {
+ hp->_ptr = addr;
+ if (pm_flags & PMAP_LITTLE)
+ hp->_asi = ASI_PHYS_NON_CACHED_LITTLE;
+ else
+ hp->_asi = ASI_PHYS_NON_CACHED;
+ hp->_sasi = ASI_PHYS_NON_CACHED;
+ return (0);
+ }
+#endif
+
if (!(flags & BUS_SPACE_MAP_CACHEABLE)) pm_flags |= PMAP_NC;
if ((err = extent_alloc(io_space, size, NBPG,
@@ -1837,7 +1805,12 @@ sparc_bus_map(t, addr, size, flags, unused, hp)
panic("sparc_bus_map: cannot allocate io_space: %d\n", err);
/* note: preserve page offset */
- *hp = (bus_space_handle_t)(v | ((u_long)addr & PGOFSET));
+ hp->_ptr = (v | ((u_long)addr & PGOFSET));
+ hp->_asi = ASI_PRIMARY;
+ if (pm_flags & PMAP_LITTLE)
+ hp->_sasi = ASI_PRIMARY_LITTLE;
+ else
+ hp->_sasi = ASI_PRIMARY;
pa = addr & ~PAGE_MASK; /* = trunc_page(addr); Will drop high bits */
if (!(flags&BUS_SPACE_MAP_READONLY)) pm_prot |= VM_PROT_WRITE;
@@ -1845,13 +1818,13 @@ sparc_bus_map(t, addr, size, flags, unused, hp)
DPRINTF(BSDB_MAP, ("\nsparc_bus_map: type %x flags %x "
"addr %016llx size %016llx virt %llx paddr %016llx\n",
(int)t->type, (int) flags, (unsigned long long)addr,
- (unsigned long long)size, (unsigned long long)*hp,
+ (unsigned long long)size, (unsigned long long)hp->_ptr,
(unsigned long long)pa));
do {
DPRINTF(BSDB_MAP, ("sparc_bus_map: phys %llx virt %p hp %llx\n",
(unsigned long long)pa, (char *)v,
- (unsigned long long)*hp));
+ (unsigned long long)hp->_ptr));
pmap_enter(pmap_kernel(), v, pa | pm_flags, pm_prot,
pm_prot|PMAP_WIRED);
v += PAGE_SIZE;
@@ -1869,7 +1842,9 @@ sparc_bus_subregion(tag, handle, offset, size, nhandlep)
bus_size_t size;
bus_space_handle_t *nhandlep;
{
- *nhandlep = handle + offset;
+ nhandlep->_ptr = handle._ptr + offset;
+ nhandlep->_asi = handle._asi;
+ nhandlep->_sasi = handle._sasi;
return (0);
}
@@ -1879,10 +1854,13 @@ sparc_bus_unmap(t, bh, size)
bus_size_t size;
bus_space_handle_t bh;
{
- vaddr_t va = trunc_page((vaddr_t)bh);
+ vaddr_t va = trunc_page((vaddr_t)bh._ptr);
vaddr_t endva = va + round_page(size);
+ int error = 0;
+
+ if (PHYS_ASI(bh._asi)) return (0);
- int error = extent_free(io_space, va, size, EX_NOWAIT);
+ error = extent_free(io_space, va, size, EX_NOWAIT);
if (error) printf("sparc_bus_unmap: extent free sez %d\n", error);
pmap_remove(pmap_kernel(), va, endva);