2 * Copyright (c) 1998 Doug Rabson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/lib/libio/swiz.c,v 1.3.2.1 2000/12/11 01:03:20 obrien Exp $
29 #include <sys/param.h>
31 #include <sys/fcntl.h>
32 #include <sys/sysctl.h>
35 #include <machine/swiz.h>
36 #include <machine/sysarch.h>
40 #define mb() __asm__ __volatile__("mb" : : : "memory")
41 #define wmb() __asm__ __volatile__("wmb" : : : "memory")
43 static int mem_fd; /* file descriptor to /dev/mem */
44 static void *swiz_ports; /* mapped io ports */
45 static u_int64_t swiz_io_base; /* physical address of ports */
46 static u_int64_t swiz_mem_base; /* physical address of sparse mem */
47 static u_int64_t swiz_dense_base; /* physical address of dense mem */
48 static u_int64_t swiz_hae_mask; /* mask address bits for hae */
49 static u_int32_t swiz_hae; /* cache of current hae */
55 size_t len = sizeof(u_int64_t);
58 mem_fd = open(_PATH_MEM, O_RDWR);
61 swiz_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0);
63 if ((error = sysctlbyname("hw.chipset.ports", &swiz_io_base, &len,
65 err(1, "hw.chipset.ports");
66 if ((error = sysctlbyname("hw.chipset.memory", &swiz_mem_base, &len,
68 err(1, "hw.chipset.memory");
69 if ((error = sysctlbyname("hw.chipset.dense", &swiz_dense_base, &len,
71 err(1, "hw.chipset.memory");
72 if ((error = sysctlbyname("hw.chipset.hae_mask", &swiz_hae_mask, &len,
74 err(1, "hw.chipset.memory");
79 swiz_ioperm(u_int32_t from, u_int32_t num, int on)
88 return -1; /* XXX can't unmap yet */
90 start = trunc_page(from << 5);
91 end = round_page((from + num) << 5);
92 addr = swiz_ports + start;
93 munmap(addr, end - start);
94 mmap(addr, end - start, PROT_READ|PROT_WRITE, MAP_SHARED,
95 mem_fd, swiz_io_base + start);
100 swiz_inb(u_int32_t port)
103 return SPARSE_READ_BYTE(swiz_ports, port);
107 swiz_inw(u_int32_t port)
110 return SPARSE_READ_WORD(swiz_ports, port);
114 swiz_inl(u_int32_t port)
117 return SPARSE_READ_LONG(swiz_ports, port);
121 swiz_outb(u_int32_t port, u_int8_t val)
123 SPARSE_WRITE_BYTE(swiz_ports, port, val);
128 swiz_outw(u_int32_t port, u_int16_t val)
130 SPARSE_WRITE_WORD(swiz_ports, port, val);
135 swiz_outl(u_int32_t port, u_int32_t val)
137 SPARSE_WRITE_LONG(swiz_ports, port, val);
141 struct swiz_mem_handle {
142 u_int32_t phys; /* address in PCI address-space */
143 void *virt; /* address in user address-space */
144 u_int32_t size; /* size of mapped region */
148 swiz_map_memory(u_int32_t address, u_int32_t size)
150 struct swiz_mem_handle *h;
151 h = malloc(sizeof(struct swiz_mem_handle));
154 h->virt = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED,
156 swiz_mem_base + ((address & ~swiz_hae_mask) << 5));
157 if ((long) h->virt == -1) {
166 swiz_unmap_memory(void *handle, u_int32_t size)
168 struct swiz_mem_handle *h = handle;
169 munmap(h->virt, h->size);
174 swiz_sethae(vm_offset_t phys)
176 u_int32_t hae = phys & swiz_hae_mask;
177 if (hae != swiz_hae) {
184 swiz_readb(void *handle, u_int32_t offset)
186 struct swiz_mem_handle *h = handle;
187 swiz_sethae(h->phys + offset);
188 return SPARSE_READ_BYTE(h->virt, offset);
192 swiz_readw(void *handle, u_int32_t offset)
194 struct swiz_mem_handle *h = handle;
195 swiz_sethae(h->phys + offset);
196 return SPARSE_READ_WORD(h->virt, offset);
200 swiz_readl(void *handle, u_int32_t offset)
202 struct swiz_mem_handle *h = handle;
203 swiz_sethae(h->phys + offset);
204 return SPARSE_READ_LONG(h->virt, offset);
208 swiz_writeb(void *handle, u_int32_t offset, u_int8_t val)
210 struct swiz_mem_handle *h = handle;
211 swiz_sethae(h->phys + offset);
212 SPARSE_WRITE_BYTE(h->virt, offset, val);
216 swiz_writew(void *handle, u_int32_t offset, u_int16_t val)
218 struct swiz_mem_handle *h = handle;
219 swiz_sethae(h->phys + offset);
220 SPARSE_WRITE_WORD(h->virt, offset, val);
224 swiz_writel(void *handle, u_int32_t offset, u_int32_t val)
226 struct swiz_mem_handle *h = handle;
227 swiz_sethae(h->phys + offset);
228 SPARSE_WRITE_LONG(h->virt, offset, val);
231 struct io_ops swiz_io_ops = {