diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-08-04 16:44:16 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-08-04 16:44:16 +0000 |
commit | dc7c80119a0844956f4662be2c398d8b16b22dff (patch) | |
tree | 9d326c36b6b4334afcf149635ef981704cd1691e /sys | |
parent | 84b496c7b4bd76bcd44c9f379fc27c7aa4ef3759 (diff) |
Add sparc_bus_addr member to struct sparc_bus_space_tag. This function maps
a bus_space_handle_t back to a bus_addr_t. Needed for rbus.
Only implemented for mainbus(4) and psycho(4) for now; schizo(4) and pyro(4)
will follow soon.
ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sparc64/dev/psycho.c | 61 | ||||
-rw-r--r-- | sys/arch/sparc64/include/bus.h | 4 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/machdep.c | 20 |
3 files changed, 68 insertions, 17 deletions
diff --git a/sys/arch/sparc64/dev/psycho.c b/sys/arch/sparc64/dev/psycho.c index b99f089c15c..0f1d483e4c7 100644 --- a/sys/arch/sparc64/dev/psycho.c +++ b/sys/arch/sparc64/dev/psycho.c @@ -1,4 +1,4 @@ -/* $OpenBSD: psycho.c,v 1.51 2007/04/10 17:47:55 miod Exp $ */ +/* $OpenBSD: psycho.c,v 1.52 2007/08/04 16:44:15 kettenis Exp $ */ /* $NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp $ */ /* @@ -77,7 +77,7 @@ 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 *, const char *); -bus_space_tag_t _psycho_alloc_bus_tag(struct psycho_pbm *, +bus_space_tag_t psycho_alloc_bus_tag(struct psycho_pbm *, const char *, int, int, int); /* Interrupt handlers */ @@ -96,10 +96,12 @@ 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. */ +int psycho_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t, + bus_size_t, int, bus_space_handle_t *); 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 *); +bus_addr_t psycho_bus_addr(bus_space_tag_t, bus_space_tag_t, + bus_space_handle_t); void *psycho_intr_establish(bus_space_tag_t, bus_space_tag_t, int, int, int, int (*)(void *), void *, const char *); @@ -854,7 +856,7 @@ psycho_iommu_init(struct psycho_softc *sc, int tsbsize) bus_space_tag_t psycho_alloc_mem_tag(struct psycho_pbm *pp) { - return (_psycho_alloc_bus_tag(pp, "mem", + return (psycho_alloc_bus_tag(pp, "mem", 0x02, /* 32-bit mem space (where's the #define???) */ ASI_PRIMARY, ASI_PRIMARY_LITTLE)); } @@ -862,7 +864,7 @@ psycho_alloc_mem_tag(struct psycho_pbm *pp) bus_space_tag_t psycho_alloc_io_tag(struct psycho_pbm *pp) { - return (_psycho_alloc_bus_tag(pp, "io", + return (psycho_alloc_bus_tag(pp, "io", 0x01, /* IO space (where's the #define???) */ ASI_PHYS_NON_CACHED_LITTLE, ASI_PHYS_NON_CACHED)); } @@ -870,13 +872,13 @@ psycho_alloc_io_tag(struct psycho_pbm *pp) bus_space_tag_t psycho_alloc_config_tag(struct psycho_pbm *pp) { - return (_psycho_alloc_bus_tag(pp, "cfg", + 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, +psycho_alloc_bus_tag(struct psycho_pbm *pp, const char *name, int ss, int asi, int sasi) { struct psycho_softc *sc = pp->pp_sc; @@ -896,8 +898,9 @@ _psycho_alloc_bus_tag(struct psycho_pbm *pp, bt->default_type = ss; bt->asi = asi; bt->sasi = sasi; - bt->sparc_bus_map = _psycho_bus_map; + bt->sparc_bus_map = psycho_bus_map; bt->sparc_bus_mmap = psycho_bus_mmap; + bt->sparc_bus_addr = psycho_bus_addr; bt->sparc_intr_establish = psycho_intr_establish; return (bt); @@ -940,13 +943,13 @@ psycho_alloc_dma_tag(struct psycho_pbm *pp) */ int -_psycho_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t offset, +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; int i, ss; - DPRINTF(PDB_BUSMAP, ("\n_psycho_bus_map: type %d off %qx sz %qx " + DPRINTF(PDB_BUSMAP, ("\npsycho_bus_map: type %d off %qx sz %qx " "flags %d", t->default_type, (unsigned long long)offset, (unsigned long long)size, flags)); @@ -954,7 +957,7 @@ _psycho_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t offset, DPRINTF(PDB_BUSMAP, (" cspace %d", ss)); if (t->parent == 0 || t->parent->sparc_bus_map == 0) { - printf("\n_psycho_bus_map: invalid parent"); + printf("\npsycho_bus_map: invalid parent"); return (EINVAL); } @@ -998,7 +1001,7 @@ psycho_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr, prot, flags, (unsigned long long)paddr)); if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) { - printf("\n_psycho_bus_mmap: invalid parent"); + printf("\npsycho_bus_mmap: invalid parent"); return (-1); } @@ -1012,7 +1015,7 @@ psycho_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr, 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_mmap: mapping paddr " + DPRINTF(PDB_BUSMAP, ("\npsycho_bus_mmap: mapping paddr " "space %lx offset %lx paddr %qx", (long)ss, (long)offset, (unsigned long long)paddr)); @@ -1022,6 +1025,36 @@ psycho_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr, return (-1); } +bus_addr_t +psycho_bus_addr(bus_space_tag_t t, bus_space_tag_t t0, bus_space_handle_t h) +{ + struct psycho_pbm *pp = t->cookie; + bus_addr_t addr; + int i, ss; + + ss = t->default_type; + + if (t->parent == 0 || t->parent->sparc_bus_addr == 0) { + printf("\npsycho_bus_addr: invalid parent"); + return (-1); + } + + t = t->parent; + + addr = ((*t->sparc_bus_addr)(t, t0, h)); + if (addr == -1) + return (-1); + + for (i = 0; i < pp->pp_nrange; i++) { + if (((pp->pp_range[i].cspace >> 24) & 0x03) != ss) + continue; + + return (BUS_ADDR_PADDR(addr) - pp->pp_range[i].phys_lo); + } + + return (-1); +} + /* * Bus-specific interrupt mapping */ diff --git a/sys/arch/sparc64/include/bus.h b/sys/arch/sparc64/include/bus.h index ac7a66aaa49..ca523176dd2 100644 --- a/sys/arch/sparc64/include/bus.h +++ b/sys/arch/sparc64/include/bus.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bus.h,v 1.22 2007/05/29 09:54:25 sobrado Exp $ */ +/* $OpenBSD: bus.h,v 1.23 2007/08/04 16:44:15 kettenis Exp $ */ /* $NetBSD: bus.h,v 1.31 2001/09/21 15:30:41 wiz Exp $ */ /*- @@ -219,6 +219,8 @@ struct sparc_bus_space_tag { int (*)(void *), void *, const char *); + bus_addr_t (*sparc_bus_addr)(bus_space_tag_t, + bus_space_tag_t, bus_space_handle_t); }; /* diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c index c410ef0bc20..4da4ca9d16c 100644 --- a/sys/arch/sparc64/sparc64/machdep.c +++ b/sys/arch/sparc64/sparc64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.92 2007/07/22 21:33:04 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.93 2007/08/04 16:44:15 kettenis Exp $ */ /* $NetBSD: machdep.c,v 1.108 2001/07/24 19:30:14 eeh Exp $ */ /*- @@ -1570,6 +1570,8 @@ int sparc_bus_protect(bus_space_tag_t, bus_space_tag_t, bus_space_handle_t, bus_size_t, int); int sparc_bus_unmap(bus_space_tag_t, bus_space_tag_t, bus_space_handle_t, bus_size_t); +bus_addr_t sparc_bus_addr(bus_space_tag_t, bus_space_tag_t, + bus_space_handle_t); int sparc_bus_subregion(bus_space_tag_t, bus_space_tag_t, bus_space_handle_t, bus_size_t, bus_size_t, bus_space_handle_t *); paddr_t sparc_bus_mmap(bus_space_tag_t, bus_space_tag_t, bus_addr_t, off_t, @@ -1774,6 +1776,19 @@ sparc_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr, return ((paddr + off) | PMAP_NC); } +bus_addr_t +sparc_bus_addr(bus_space_tag_t t, bus_space_tag_t t0, bus_space_handle_t h) +{ + paddr_t addr; + + if (PHYS_ASI(t0->asi)) + return h.bh_ptr; + + if (!pmap_extract(pmap_kernel(), h.bh_ptr, &addr)) + return (-1); + return addr; +} + void * bus_intr_allocate(bus_space_tag_t t, int (*handler)(void *), void *arg, int number, int pil, @@ -1872,7 +1887,8 @@ static const struct sparc_bus_space_tag _mainbus_space_tag = { sparc_bus_subregion, /* bus_space_subregion */ sparc_bus_barrier, /* bus_space_barrier */ sparc_bus_mmap, /* bus_space_mmap */ - sparc_mainbus_intr_establish /* bus_intr_establish */ + sparc_mainbus_intr_establish, /* bus_intr_establish */ + sparc_bus_addr /* bus_space_addr */ }; const bus_space_tag_t mainbus_space_tag = &_mainbus_space_tag; |