diff options
author | dfr <dfr@FreeBSD.org> | 1998-12-12 18:05:06 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 1998-12-12 18:05:06 +0000 |
commit | 9d72935e7288817dc8948e0dcb0edd0d40c2c937 (patch) | |
tree | 315cf7bc6c4a9115ed898f338e5daef349713131 /lib | |
parent | a73a037fb6453c9131d32150d2bf135d2ca111c3 (diff) | |
download | FreeBSD-src-9d72935e7288817dc8948e0dcb0edd0d40c2c937.zip FreeBSD-src-9d72935e7288817dc8948e0dcb0edd0d40c2c937.tar.gz |
Add a simple library for accessing i/o ports and memory on the alpha.
This is only intended for use by the X server.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libio/Makefile | 11 | ||||
-rw-r--r-- | lib/libio/alpha_sethae.c | 50 | ||||
-rw-r--r-- | lib/libio/bwx.c | 237 | ||||
-rw-r--r-- | lib/libio/io.c | 151 | ||||
-rw-r--r-- | lib/libio/io.h | 48 | ||||
-rw-r--r-- | lib/libio/swiz.c | 246 |
6 files changed, 743 insertions, 0 deletions
diff --git a/lib/libio/Makefile b/lib/libio/Makefile new file mode 100644 index 0000000..b9aeebd --- /dev/null +++ b/lib/libio/Makefile @@ -0,0 +1,11 @@ +# $Id$ + +LIB= io +SHLIB_MAJOR= 1 +SRCS= io.c swiz.c bwx.c alpha_sethae.c + +CFLAGS+= -Wall -Wa,-mev56 + +NOMAN=1 + +.include <bsd.lib.mk> diff --git a/lib/libio/alpha_sethae.c b/lib/libio/alpha_sethae.c new file mode 100644 index 0000000..365b051 --- /dev/null +++ b/lib/libio/alpha_sethae.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 1998 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#if defined(LIBC_RCS) && !defined(lint) +static const char rcsid[] = "$Id$"; +#endif /* LIBC_RCS and not lint */ + +#include <sys/types.h> +#include <machine/sysarch.h> + +extern int sysarch(int, char *); + +struct parms { + u_int64_t hae; +}; + +int +alpha_sethae(u_int64_t hae) +{ + struct parms p; + + p.hae = hae; + + return (sysarch(ALPHA_SETHAE, (char *)&p)); +} diff --git a/lib/libio/bwx.c b/lib/libio/bwx.c new file mode 100644 index 0000000..5a9e778 --- /dev/null +++ b/lib/libio/bwx.c @@ -0,0 +1,237 @@ +/*- + * Copyright (c) 1998 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include <sys/param.h> +#include <sys/mman.h> +#include <sys/fcntl.h> +#include <sys/sysctl.h> +#include <err.h> +#include <machine/bwx.h> +#include <machine/sysarch.h> +#include <stdlib.h> +#include "io.h" + +#define mb() __asm__ __volatile__("mb" : : : "memory") +#define wmb() __asm__ __volatile__("wmb" : : : "memory") + +static int mem_fd; /* file descriptor to /dev/mem */ +static void *bwx_int1_ports; /* mapped int1 io ports */ +static void *bwx_int2_ports; /* mapped int2 io ports */ +static void *bwx_int4_ports; /* mapped int4 io ports */ +static u_int64_t bwx_io_base; /* physical address of ports */ +static u_int64_t bwx_mem_base; /* physical address of bwx mem */ + +static void +bwx_init() +{ + size_t len = sizeof(u_int64_t); + int error; + + mem_fd = open("/dev/mem", O_RDWR); + if (mem_fd < 0) + err(1, "/dev/mem"); + bwx_int1_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0); + bwx_int2_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0); + bwx_int4_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0); + + if ((error = sysctlbyname("hw.chipset.ports", &bwx_io_base, &len, + 0, 0)) < 0) + err(1, "hw.chipset.ports"); + if ((error = sysctlbyname("hw.chipset.memory", &bwx_mem_base, &len, + 0, 0)) < 0) + err(1, "hw.chipset.memory"); +} + +static int +bwx_ioperm(u_int32_t from, u_int32_t num, int on) +{ + if (!bwx_int1_ports) + bwx_init(); + + if (!on) + return -1; /* XXX can't unmap yet */ + + munmap(bwx_int1_ports + from, num); + munmap(bwx_int2_ports + from, num); + munmap(bwx_int4_ports + from, num); + mmap(bwx_int1_ports + from, num, PROT_READ|PROT_WRITE, MAP_SHARED, + mem_fd, bwx_io_base + BWX_EV56_INT1 + from); + mmap(bwx_int2_ports + from, num, PROT_READ|PROT_WRITE, MAP_SHARED, + mem_fd, bwx_io_base + BWX_EV56_INT2 + from); + mmap(bwx_int4_ports + from, num, PROT_READ|PROT_WRITE, MAP_SHARED, + mem_fd, bwx_io_base + BWX_EV56_INT4 + from); + return 0; +} + +static u_int8_t +bwx_inb(u_int32_t port) +{ + mb(); + return ldbu((vm_offset_t)bwx_int1_ports + port); +} + +static u_int16_t +bwx_inw(u_int32_t port) +{ + mb(); + return ldwu((vm_offset_t)bwx_int2_ports + port); +} + +static u_int32_t +bwx_inl(u_int32_t port) +{ + mb(); + return ldl((vm_offset_t)bwx_int4_ports + port); +} + +static void +bwx_outb(u_int32_t port, u_int8_t val) +{ + stb((vm_offset_t)bwx_int1_ports + port, val); + wmb(); +} + +static void +bwx_outw(u_int32_t port, u_int16_t val) +{ + stw((vm_offset_t)bwx_int2_ports + port, val); + wmb(); +} + +static void +bwx_outl(u_int32_t port, u_int32_t val) +{ + stl((vm_offset_t)bwx_int4_ports + port, val); + wmb(); +} + +struct bwx_mem_handle { + void *virt1; /* int1 address in user address-space */ + void *virt2; /* int2 address in user address-space */ + void *virt4; /* int4 address in user address-space */ +}; + +static void * +bwx_map_memory(u_int32_t address, u_int32_t size) +{ + struct bwx_mem_handle *h; + h = malloc(sizeof(struct bwx_mem_handle)); + if (!h) return 0; + h->virt1 = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED, + mem_fd, bwx_mem_base + BWX_EV56_INT1 + address); + if ((long) h->virt1 == -1) { + free(h); + return 0; + } + h->virt2 = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED, + mem_fd, bwx_mem_base + BWX_EV56_INT2 + address); + if ((long) h->virt2 == -1) { + munmap(h->virt1, size); + free(h); + return 0; + } + h->virt4 = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED, + mem_fd, bwx_mem_base + BWX_EV56_INT4 + address); + if ((long) h->virt4 == -1) { + munmap(h->virt1, size); + munmap(h->virt2, size); + free(h); + return 0; + } + return h; +} + +static void +bwx_unmap_memory(void *handle, u_int32_t size) +{ + struct bwx_mem_handle *h = handle; + munmap(h->virt1, size); + munmap(h->virt2, size); + munmap(h->virt4, size); + free(h); +} + +static u_int8_t +bwx_readb(void *handle, u_int32_t offset) +{ + struct bwx_mem_handle *h = handle; + return ldbu((vm_offset_t)h->virt1 + offset); +} + +static u_int16_t +bwx_readw(void *handle, u_int32_t offset) +{ + struct bwx_mem_handle *h = handle; + return ldwu((vm_offset_t)h->virt2 + offset); +} + +static u_int32_t +bwx_readl(void *handle, u_int32_t offset) +{ + struct bwx_mem_handle *h = handle; + return ldl((vm_offset_t)h->virt4 + offset); +} + +static void +bwx_writeb(void *handle, u_int32_t offset, u_int8_t val) +{ + struct bwx_mem_handle *h = handle; + stb((vm_offset_t)h->virt1 + offset, val); +} + +static void +bwx_writew(void *handle, u_int32_t offset, u_int16_t val) +{ + struct bwx_mem_handle *h = handle; + stw((vm_offset_t)h->virt2 + offset, val); +} + +static void +bwx_writel(void *handle, u_int32_t offset, u_int32_t val) +{ + struct bwx_mem_handle *h = handle; + stl((vm_offset_t)h->virt4 + offset, val); +} + +struct io_ops bwx_io_ops = { + bwx_ioperm, + bwx_inb, + bwx_inw, + bwx_inl, + bwx_outb, + bwx_outw, + bwx_outl, + bwx_map_memory, + bwx_unmap_memory, + bwx_readb, + bwx_readw, + bwx_readl, + bwx_writeb, + bwx_writew, + bwx_writel, +}; diff --git a/lib/libio/io.c b/lib/libio/io.c new file mode 100644 index 0000000..f847755 --- /dev/null +++ b/lib/libio/io.c @@ -0,0 +1,151 @@ +/*- + * Copyright (c) 1998 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include <sys/types.h> +#include <sys/sysctl.h> +#include <err.h> +#include "io.h" + +static struct io_ops *ops; + +int +ioperm(unsigned long from, unsigned long num, int on) +{ + int error; + int bwx; + size_t len = sizeof(bwx); + + if ((error = sysctlbyname("hw.chipset.bwx", &bwx, &len, 0, 0)) < 0) + return error; + if (bwx) + ops = &bwx_io_ops; + else + ops = &swiz_io_ops; + + return ops->ioperm(from, num, on); +} + +u_int8_t +inb(u_int32_t port) +{ + return ops->inb(port); +} + +u_int16_t +inw(u_int32_t port) +{ + return ops->inw(port); +} + +u_int32_t +inl(u_int32_t port) +{ + return ops->inl(port); +} + +void +outb(u_int32_t port, u_int8_t val) +{ + ops->outb(port, val); +} + +void +outw(u_int32_t port, u_int16_t val) +{ + ops->outw(port, val); +} + +void +outl(u_int32_t port, u_int32_t val) +{ + ops->outl(port, val); +} + +void * +map_memory(u_int32_t address, u_int32_t size) +{ + return ops->map_memory(address, size); +} + +void +unmap_memory(void *handle, u_int32_t size) +{ + ops->unmap_memory(handle, size); +} + +u_int8_t +readb(void *handle, u_int32_t offset) +{ + return ops->readb(handle, offset); +} + +u_int16_t +readw(void *handle, u_int32_t offset) +{ + return ops->readw(handle, offset); +} + +u_int32_t +readl(void *handle, u_int32_t offset) +{ + return ops->readl(handle, offset); +} + +void +writeb(void *handle, u_int32_t offset, u_int8_t val) +{ + return ops->writeb(handle, offset, val); +} + +void +writew(void *handle, u_int32_t offset, u_int16_t val) +{ + return ops->writew(handle, offset, val); +} + +void +writel(void *handle, u_int32_t offset, u_int32_t val) +{ + return ops->writel(handle, offset, val); +} + +u_int64_t +dense_base(void) +{ + static u_int64_t base = 0; + + if (base == 0) { + size_t len = sizeof(base); + int error; + if ((error = sysctlbyname("hw.chipset.dense", &base, &len, + 0, 0)) < 0) + err(1, "hw.chipset.dense"); + } + + return base; +} diff --git a/lib/libio/io.h b/lib/libio/io.h new file mode 100644 index 0000000..a166355 --- /dev/null +++ b/lib/libio/io.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 1998 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +struct io_ops { + int (*ioperm)(u_int32_t, u_int32_t, int); + u_int8_t (*inb)(u_int32_t); + u_int16_t (*inw)(u_int32_t); + u_int32_t (*inl)(u_int32_t); + void (*outb)(u_int32_t, u_int8_t); + void (*outw)(u_int32_t, u_int16_t); + void (*outl)(u_int32_t, u_int32_t); + void * (*map_memory)(u_int32_t, u_int32_t); + void (*unmap_memory)(void *, u_int32_t); + u_int8_t (*readb)(void *, u_int32_t); + u_int16_t (*readw)(void *, u_int32_t); + u_int32_t (*readl)(void *, u_int32_t); + void (*writeb)(void *, u_int32_t, u_int8_t); + void (*writew)(void *, u_int32_t, u_int16_t); + void (*writel)(void *, u_int32_t, u_int32_t); +}; + +extern struct io_ops swiz_io_ops; +extern struct io_ops bwx_io_ops; diff --git a/lib/libio/swiz.c b/lib/libio/swiz.c new file mode 100644 index 0000000..d8bb7b5 --- /dev/null +++ b/lib/libio/swiz.c @@ -0,0 +1,246 @@ +/*- + * Copyright (c) 1998 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include <sys/param.h> +#include <sys/mman.h> +#include <sys/fcntl.h> +#include <sys/sysctl.h> +#include <err.h> +#include <machine/swiz.h> +#include <machine/sysarch.h> +#include <stdlib.h> +#include "io.h" + +#define mb() __asm__ __volatile__("mb" : : : "memory") +#define wmb() __asm__ __volatile__("wmb" : : : "memory") + +static int mem_fd; /* file descriptor to /dev/mem */ +static void *swiz_ports; /* mapped io ports */ +static u_int64_t swiz_io_base; /* physical address of ports */ +static u_int64_t swiz_mem_base; /* physical address of sparse mem */ +static u_int64_t swiz_dense_base; /* physical address of dense mem */ +static u_int64_t swiz_hae_mask; /* mask address bits for hae */ +static u_int32_t swiz_hae; /* cache of current hae */ + +static void +swiz_init() +{ + + size_t len = sizeof(u_int64_t); + int error; + + mem_fd = open("/dev/mem", O_RDWR); + if (mem_fd < 0) + err(1, "/dev/mem"); + swiz_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0); + + if ((error = sysctlbyname("hw.chipset.ports", &swiz_io_base, &len, + 0, 0)) < 0) + err(1, "hw.chipset.ports"); + if ((error = sysctlbyname("hw.chipset.memory", &swiz_mem_base, &len, + 0, 0)) < 0) + err(1, "hw.chipset.memory"); + if ((error = sysctlbyname("hw.chipset.dense", &swiz_dense_base, &len, + 0, 0)) < 0) + err(1, "hw.chipset.memory"); + if ((error = sysctlbyname("hw.chipset.hae_mask", &swiz_hae_mask, &len, + 0, 0)) < 0) + err(1, "hw.chipset.memory"); + +} + +static int +swiz_ioperm(u_int32_t from, u_int32_t num, int on) +{ + u_int64_t start, end; + void *addr; + + if (!swiz_ports) + swiz_init(); + + if (!on) + return -1; /* XXX can't unmap yet */ + + start = from << 5; + end = (from + num) << 5; + addr = swiz_ports + start; + munmap(addr, end - start); + mmap(addr, end - start, PROT_READ|PROT_WRITE, MAP_SHARED, + mem_fd, swiz_io_base + start); + return 0; +} + +static u_int8_t +swiz_inb(u_int32_t port) +{ + mb(); + return SPARSE_READ_BYTE(swiz_ports, port); +} + +static u_int16_t +swiz_inw(u_int32_t port) +{ + mb(); + return SPARSE_READ_WORD(swiz_ports, port); +} + +static u_int32_t +swiz_inl(u_int32_t port) +{ + mb(); + return SPARSE_READ_LONG(swiz_ports, port); +} + +static void +swiz_outb(u_int32_t port, u_int8_t val) +{ + SPARSE_WRITE_BYTE(swiz_ports, port, val); + wmb(); +} + +static void +swiz_outw(u_int32_t port, u_int16_t val) +{ + SPARSE_WRITE_WORD(swiz_ports, port, val); + wmb(); +} + +static void +swiz_outl(u_int32_t port, u_int32_t val) +{ + SPARSE_WRITE_LONG(swiz_ports, port, val); + wmb(); +} + +struct swiz_mem_handle { + u_int32_t phys; /* address in PCI address-space */ + void *virt; /* address in user address-space */ + u_int32_t size; /* size of mapped region */ +}; + +static void * +swiz_map_memory(u_int32_t address, u_int32_t size) +{ + struct swiz_mem_handle *h; + h = malloc(sizeof(struct swiz_mem_handle)); + if (!h) return 0; + h->phys = address; + h->virt = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED, + mem_fd, + swiz_mem_base + ((address & ~swiz_hae_mask) << 5)); + if ((long) h->virt == -1) { + free(h); + return 0; + } + h->size = size << 5; + return h; +} + +static void +swiz_unmap_memory(void *handle, u_int32_t size) +{ + struct swiz_mem_handle *h = handle; + munmap(h->virt, h->size); + free(h); +} + +static void +swiz_sethae(vm_offset_t phys) +{ + u_int32_t hae = phys & swiz_hae_mask; + if (hae != swiz_hae) { + alpha_sethae(hae); + swiz_hae = hae; + } +} + +static u_int8_t +swiz_readb(void *handle, u_int32_t offset) +{ + struct swiz_mem_handle *h = handle; + swiz_sethae(h->phys + offset); + return SPARSE_READ_BYTE(h->virt, offset); +} + +static u_int16_t +swiz_readw(void *handle, u_int32_t offset) +{ + struct swiz_mem_handle *h = handle; + swiz_sethae(h->phys + offset); + return SPARSE_READ_WORD(h->virt, offset); +} + +static u_int32_t +swiz_readl(void *handle, u_int32_t offset) +{ + struct swiz_mem_handle *h = handle; + swiz_sethae(h->phys + offset); + return SPARSE_READ_LONG(h->virt, offset); +} + +static void +swiz_writeb(void *handle, u_int32_t offset, u_int8_t val) +{ + struct swiz_mem_handle *h = handle; + swiz_sethae(h->phys + offset); + SPARSE_WRITE_BYTE(h->virt, offset, val); +} + +static void +swiz_writew(void *handle, u_int32_t offset, u_int16_t val) +{ + struct swiz_mem_handle *h = handle; + swiz_sethae(h->phys + offset); + SPARSE_WRITE_WORD(h->virt, offset, val); +} + +static void +swiz_writel(void *handle, u_int32_t offset, u_int32_t val) +{ + struct swiz_mem_handle *h = handle; + swiz_sethae(h->phys + offset); + SPARSE_WRITE_LONG(h->virt, offset, val); +} + +struct io_ops swiz_io_ops = { + swiz_ioperm, + swiz_inb, + swiz_inw, + swiz_inl, + swiz_outb, + swiz_outw, + swiz_outl, + swiz_map_memory, + swiz_unmap_memory, + swiz_readb, + swiz_readw, + swiz_readl, + swiz_writeb, + swiz_writew, + swiz_writel, +}; |