diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2006-05-11 19:50:31 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2006-05-11 19:50:31 +0000 |
commit | 2c14b365917c678b47d96b73b76191d9639b519a (patch) | |
tree | 10b958e8c5a49788c09c9d1c680e8bee644bb863 /sys | |
parent | 0337948d4a7971a374d0d53341960b25cda6116a (diff) |
Fix stupid bugs in mapping and unmapping of VME regions.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/aviion/dev/vme.c | 92 | ||||
-rw-r--r-- | sys/arch/aviion/include/av400.h | 13 |
2 files changed, 57 insertions, 48 deletions
diff --git a/sys/arch/aviion/dev/vme.c b/sys/arch/aviion/dev/vme.c index 514150dc19b..218159f9dff 100644 --- a/sys/arch/aviion/dev/vme.c +++ b/sys/arch/aviion/dev/vme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vme.c,v 1.1 2006/05/09 18:14:15 miod Exp $ */ +/* $OpenBSD: vme.c,v 1.2 2006/05/11 19:50:28 miod Exp $ */ /* * Copyright (c) 2006, Miodrag Vallat. * @@ -68,19 +68,17 @@ struct cfdriver vme_cd = { int vme16_map(bus_addr_t, bus_size_t, int, bus_space_handle_t *); void vme16_unmap(bus_space_handle_t, bus_size_t); -void * vme16_vaddr(bus_space_handle_t); int vme24_map(bus_addr_t, bus_size_t, int, bus_space_handle_t *); void vme24_unmap(bus_space_handle_t, bus_size_t); -void * vme24_vaddr(bus_space_handle_t); int vme32_map(bus_addr_t, bus_size_t, int, bus_space_handle_t *); void vme32_unmap(bus_space_handle_t, bus_size_t); -void * vme32_vaddr(bus_space_handle_t); int vme_subregion(bus_space_handle_t, bus_size_t, bus_size_t, bus_space_handle_t *); +void * vme_vaddr(bus_space_handle_t); -int vme_map(struct extent *, bus_addr_t, bus_size_t, int, +int vme_map(struct extent *, paddr_t, bus_addr_t, bus_size_t, int, bus_space_handle_t *); -void vme_unmap(struct extent *, bus_space_handle_t, bus_size_t); +void vme_unmap(struct extent *, vme_addr_t, vaddr_t, bus_size_t); int vmeprint(void *, const char *); int vmescan(struct device *, void *, void *); @@ -240,8 +238,9 @@ vme16_map(bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *ret) { struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; - if (AV400_ISVMEA32(addr) && AV400_ISVMEA32(addr + size - 1)) - return (vme_map(sc->sc_ext_a16, addr, size, flags, ret)); + if (AV400_ISVMEA16(addr) && AV400_ISVMEA16(addr + size - 1)) + return (vme_map(sc->sc_ext_a16, addr + AV400_VME16_BASE, addr, + size, flags, ret)); else return (EINVAL); } @@ -252,7 +251,8 @@ vme24_map(bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *ret) struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; if (AV400_ISVMEA24(addr) && AV400_ISVMEA24(addr + size - 1)) - return (vme_map(sc->sc_ext_a24, addr, size, flags, ret)); + return (vme_map(sc->sc_ext_a24, addr + AV400_VME24_BASE, addr, + size, flags, ret)); else return (EINVAL); } @@ -262,15 +262,16 @@ vme32_map(bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *ret) { struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; - if (AV400_ISVMEA16(addr) && AV400_ISVMEA16(addr + size - 1)) - return (vme_map(sc->sc_ext_a32, addr, size, flags, ret)); + if (AV400_ISVMEA32(addr) && AV400_ISVMEA32(addr + size - 1)) + return (vme_map(sc->sc_ext_a32, addr + AV400_VME32_BASE, addr, + size, flags, ret)); else return (EINVAL); } int -vme_map(struct extent *ext, bus_addr_t addr, bus_size_t size, int flags, - bus_space_handle_t *ret) +vme_map(struct extent *ext, paddr_t paddr, bus_addr_t addr, bus_size_t size, + int flags, bus_space_handle_t *ret) { int rc; paddr_t pa; @@ -279,11 +280,11 @@ vme_map(struct extent *ext, bus_addr_t addr, bus_size_t size, int flags, u_int pg; extern vaddr_t pmap_map(vaddr_t, paddr_t, paddr_t, vm_prot_t, u_int); - pa = trunc_page((paddr_t)addr); - len = round_page((paddr_t)addr + size) - pa; + pa = trunc_page(paddr); + len = round_page(paddr + size) - pa; if (ext != NULL) { - rc = extent_alloc_region(ext, atop(pa), atop(len), + rc = extent_alloc_region(ext, atop(addr), atop(len), EX_NOWAIT | EX_MALLOCOK); if (rc != 0) return (rc); @@ -310,7 +311,7 @@ vme_map(struct extent *ext, bus_addr_t addr, bus_size_t size, int flags, fail: if (ext != NULL) - extent_free(ext, atop(pa), atop(len), EX_NOWAIT | EX_MALLOCOK); + extent_free(ext, atop(addr), atop(len), EX_NOWAIT | EX_MALLOCOK); return (rc); } @@ -318,41 +319,57 @@ void vme16_unmap(bus_space_handle_t handle, bus_size_t size) { struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; + paddr_t pa; + + if (pmap_extract(pmap_kernel(), (vaddr_t)handle, &pa) == FALSE) + return; - return (vme_unmap(sc->sc_ext_a16, handle, size)); + pa -= AV400_VME16_BASE; + return (vme_unmap(sc->sc_ext_a16, pa, (vaddr_t)handle, size)); } void vme24_unmap(bus_space_handle_t handle, bus_size_t size) { struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; + paddr_t pa; - return (vme_unmap(sc->sc_ext_a24, handle, size)); + if (pmap_extract(pmap_kernel(), (vaddr_t)handle, &pa) == FALSE) + return; + + pa -= AV400_VME24_BASE; + return (vme_unmap(sc->sc_ext_a24, pa, (vaddr_t)handle, size)); } void vme32_unmap(bus_space_handle_t handle, bus_size_t size) { struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; + paddr_t pa; - return (vme_unmap(sc->sc_ext_a32, handle, size)); + if (pmap_extract(pmap_kernel(), (vaddr_t)handle, &pa) == FALSE) + return; + + pa -= AV400_VME32_BASE; + return (vme_unmap(sc->sc_ext_a32, pa, (vaddr_t)handle, size)); } void -vme_unmap(struct extent *ext, bus_space_handle_t handle, bus_size_t size) +vme_unmap(struct extent *ext, vme_addr_t addr, vaddr_t vaddr, bus_size_t size) { vaddr_t va; vsize_t len; - va = trunc_page((vaddr_t)handle); - len = round_page((vaddr_t)handle + size) - va; + va = trunc_page(vaddr); + len = round_page(vaddr + size) - va; pmap_kremove(va, len); pmap_update(pmap_kernel()); uvm_km_free(kernel_map, va, len); if (ext != NULL) - extent_free(ext, atop(va), atop(len), EX_NOWAIT | EX_MALLOCOK); + extent_free(ext, atop(addr), atop(len), + EX_NOWAIT | EX_MALLOCOK); } int @@ -365,21 +382,9 @@ vme_subregion(bus_space_handle_t handle, bus_addr_t offset, bus_size_t size, } void * -vme16_vaddr(bus_space_handle_t handle) -{ - return (void *)(AV400_VME16_START + (vaddr_t)handle); -} - -void * -vme24_vaddr(bus_space_handle_t handle) -{ - return (void *)(AV400_VME24_START + (vaddr_t)handle); -} - -void * -vme32_vaddr(bus_space_handle_t handle) +vme_vaddr(bus_space_handle_t handle) { - return (void *)(handle); + return ((void *)handle); } /* @@ -422,19 +427,19 @@ vmebus_get_bst(struct device *vsc, u_int aspace, u_int dspace, tag->bs_map = vme32_map; tag->bs_unmap = vme32_unmap; tag->bs_subregion = vme_subregion; - tag->bs_vaddr = vme32_vaddr; + tag->bs_vaddr = vme_vaddr; break; case VME_A24: tag->bs_map = vme24_map; tag->bs_unmap = vme24_unmap; tag->bs_subregion = vme_subregion; - tag->bs_vaddr = vme24_vaddr; + tag->bs_vaddr = vme_vaddr; break; case VME_A16: tag->bs_map = vme16_map; tag->bs_unmap = vme16_unmap; tag->bs_subregion = vme_subregion; - tag->bs_vaddr = vme16_vaddr; + tag->bs_vaddr = vme_vaddr; break; } @@ -533,16 +538,17 @@ vmemmap(dev_t dev, off_t off, int prot) case VME_A32: if (!AV400_ISVMEA32(pa)) return (-1); + pa += AV400_VME32_BASE; break; case VME_A24: - pa += AV400_VME24_START; if (!AV400_ISVMEA24(pa)) return (-1); + pa += AV400_VME24_BASE; break; case VME_A16: - pa += AV400_VME16_START; if (!AV400_ISVMEA16(pa)) return (-1); + pa += AV400_VME16_BASE; break; } diff --git a/sys/arch/aviion/include/av400.h b/sys/arch/aviion/include/av400.h index dd654b4a602..9a2487671c9 100644 --- a/sys/arch/aviion/include/av400.h +++ b/sys/arch/aviion/include/av400.h @@ -1,4 +1,4 @@ -/* $OpenBSD: av400.h,v 1.1 2006/05/09 18:23:59 miod Exp $ */ +/* $OpenBSD: av400.h,v 1.2 2006/05/11 19:50:30 miod Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * All rights reserved. @@ -58,14 +58,17 @@ * AV400 VME mappings */ +#define AV400_VME32_BASE 0x00000000 #define AV400_VME32_START1 0x10000000 #define AV400_VME32_END1 0x7fffffff #define AV400_VME32_START2 0x90000000 #define AV400_VME32_END2 0xfdffffff -#define AV400_VME24_START 0xfe000000 -#define AV400_VME24_END 0xfeffffff -#define AV400_VME16_START 0xffff0000 -#define AV400_VME16_END 0xffffffff +#define AV400_VME24_BASE 0xfe000000 +#define AV400_VME24_START 0x00000000 +#define AV400_VME24_END 0x00ffffff +#define AV400_VME16_BASE 0xffff0000 +#define AV400_VME16_START 0x00000000 +#define AV400_VME16_END 0x0000ffff #define AV400_ISVMEA32(addr) \ (((addr) >= AV400_VME32_START1 && (addr) < AV400_VME32_END1 + 1U) || \ |