summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-05-11 19:50:31 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-05-11 19:50:31 +0000
commit2c14b365917c678b47d96b73b76191d9639b519a (patch)
tree10b958e8c5a49788c09c9d1c680e8bee644bb863 /sys
parent0337948d4a7971a374d0d53341960b25cda6116a (diff)
Fix stupid bugs in mapping and unmapping of VME regions.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/aviion/dev/vme.c92
-rw-r--r--sys/arch/aviion/include/av400.h13
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) || \