Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / lib / libio / bwx.c
1 /*-
2  * Copyright (c) 1998 Doug Rabson
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: src/lib/libio/bwx.c,v 1.4.2.1 2000/12/11 01:03:20 obrien Exp $
27  * $DragonFly: src/lib/libio/Attic/bwx.c,v 1.2 2003/06/17 04:26:49 dillon Exp $
28  */
29
30 #include <sys/param.h>
31 #include <sys/mman.h>
32 #include <sys/fcntl.h>
33 #include <sys/sysctl.h>
34 #include <err.h>
35 #include <paths.h>
36 #include <machine/bwx.h>
37 #include <machine/sysarch.h>
38 #include <stdlib.h>
39 #include "io.h"
40
41 #define mb()    __asm__ __volatile__("mb"  : : : "memory")
42 #define wmb()   __asm__ __volatile__("wmb" : : : "memory")
43
44 static int              mem_fd;         /* file descriptor to /dev/mem */
45 static void            *bwx_int1_ports; /* mapped int1 io ports */
46 static void            *bwx_int2_ports; /* mapped int2 io ports */
47 static void            *bwx_int4_ports; /* mapped int4 io ports */
48 static u_int64_t        bwx_io_base;    /* physical address of ports */
49 static u_int64_t        bwx_mem_base;   /* physical address of bwx mem */
50
51 static void
52 bwx_init()
53 {
54     size_t len = sizeof(u_int64_t);
55     int error;
56
57     mem_fd = open(_PATH_MEM, O_RDWR);
58     if (mem_fd < 0)
59         err(1, _PATH_MEM);
60     bwx_int1_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0);
61     bwx_int2_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0);
62     bwx_int4_ports = mmap(0, 1L<<32, PROT_READ, MAP_ANON, -1, 0);
63
64     if ((error = sysctlbyname("hw.chipset.ports", &bwx_io_base, &len,
65                               0, 0)) < 0)
66         err(1, "hw.chipset.ports");
67     if ((error = sysctlbyname("hw.chipset.memory", &bwx_mem_base, &len,
68                               0, 0)) < 0)
69         err(1, "hw.chipset.memory");
70 }
71
72 static int
73 bwx_ioperm(u_int32_t from, u_int32_t num, int on)
74 {
75     u_int32_t start, end;
76
77     if (!bwx_int1_ports)
78         bwx_init();
79
80     if (!on)
81         return -1;              /* XXX can't unmap yet */
82    
83     start = trunc_page(from);
84     end = round_page(from + num);
85     
86     munmap(bwx_int1_ports + start, end-start);
87     munmap(bwx_int2_ports + start, end-start);
88     munmap(bwx_int4_ports + start, end-start);
89     mmap(bwx_int1_ports + start, end-start, PROT_READ|PROT_WRITE, MAP_SHARED,
90          mem_fd, bwx_io_base + BWX_EV56_INT1 + start);
91     mmap(bwx_int2_ports + start, end-start, PROT_READ|PROT_WRITE, MAP_SHARED,
92          mem_fd, bwx_io_base + BWX_EV56_INT2 + start);
93     mmap(bwx_int4_ports + start, end-start, PROT_READ|PROT_WRITE, MAP_SHARED,
94          mem_fd, bwx_io_base + BWX_EV56_INT4 + start);
95     return 0;
96 }
97
98 static u_int8_t
99 bwx_inb(u_int32_t port)
100 {
101     mb();
102     return ldbu((vm_offset_t)bwx_int1_ports + port);
103 }
104
105 static u_int16_t
106 bwx_inw(u_int32_t port)
107 {
108     mb();
109     return ldwu((vm_offset_t)bwx_int2_ports + port);
110 }
111
112 static u_int32_t
113 bwx_inl(u_int32_t port)
114 {
115     mb();
116     return ldl((vm_offset_t)bwx_int4_ports + port);
117 }
118
119 static void
120 bwx_outb(u_int32_t port, u_int8_t val)
121 {
122     stb((vm_offset_t)bwx_int1_ports + port, val);
123     wmb();
124 }
125
126 static void
127 bwx_outw(u_int32_t port, u_int16_t val)
128 {
129     stw((vm_offset_t)bwx_int2_ports + port, val);
130     wmb();
131 }
132
133 static void
134 bwx_outl(u_int32_t port, u_int32_t val)
135 {
136     stl((vm_offset_t)bwx_int4_ports + port, val);
137     wmb();
138 }
139
140 struct bwx_mem_handle {
141     void        *virt1;         /* int1 address in user address-space */
142     void        *virt2;         /* int2 address in user address-space */
143     void        *virt4;         /* int4 address in user address-space */
144 };
145
146 static void *
147 bwx_map_memory(u_int32_t address, u_int32_t size)
148 {
149     struct bwx_mem_handle *h;
150     h = malloc(sizeof(struct bwx_mem_handle));
151     if (!h) return 0;
152     h->virt1 = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED,
153                     mem_fd, bwx_mem_base + BWX_EV56_INT1 + address);
154     if ((long) h->virt1 == -1) {
155         free(h);
156         return 0;
157     }
158     h->virt2 = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED,
159                     mem_fd, bwx_mem_base + BWX_EV56_INT2 + address);
160     if ((long) h->virt2 == -1) {
161         munmap(h->virt1, size);
162         free(h);
163         return 0;
164     }
165     h->virt4 = mmap(0, size << 5, PROT_READ|PROT_WRITE, MAP_SHARED,
166                     mem_fd, bwx_mem_base + BWX_EV56_INT4 + address);
167     if ((long) h->virt4 == -1) {
168         munmap(h->virt1, size);
169         munmap(h->virt2, size);
170         free(h);
171         return 0;
172     }
173     return h;
174 }
175
176 static void
177 bwx_unmap_memory(void *handle, u_int32_t size)
178 {
179     struct bwx_mem_handle *h = handle;
180     munmap(h->virt1, size);
181     munmap(h->virt2, size);
182     munmap(h->virt4, size);
183     free(h);
184 }
185
186 static u_int8_t
187 bwx_readb(void *handle, u_int32_t offset)
188 {
189     struct bwx_mem_handle *h = handle;
190     return ldbu((vm_offset_t)h->virt1 + offset);
191 }
192
193 static u_int16_t
194 bwx_readw(void *handle, u_int32_t offset)
195 {
196     struct bwx_mem_handle *h = handle;
197     return ldwu((vm_offset_t)h->virt2 + offset);
198 }
199
200 static u_int32_t
201 bwx_readl(void *handle, u_int32_t offset)
202 {
203     struct bwx_mem_handle *h = handle;
204     return ldl((vm_offset_t)h->virt4 + offset);
205 }
206
207 static void
208 bwx_writeb(void *handle, u_int32_t offset, u_int8_t val)
209 {
210     struct bwx_mem_handle *h = handle;
211     stb_nb((vm_offset_t)h->virt1 + offset, val);
212 }
213
214 static void
215 bwx_writew(void *handle, u_int32_t offset, u_int16_t val)
216 {
217     struct bwx_mem_handle *h = handle;
218     stw_nb((vm_offset_t)h->virt2 + offset, val);
219 }
220
221 static void
222 bwx_writel(void *handle, u_int32_t offset, u_int32_t val)
223 {
224     struct bwx_mem_handle *h = handle;
225     stl_nb((vm_offset_t)h->virt4 + offset, val);
226 }
227
228 struct io_ops bwx_io_ops = {
229     bwx_ioperm,
230     bwx_inb,
231     bwx_inw,
232     bwx_inl,
233     bwx_outb,
234     bwx_outw,
235     bwx_outl,
236     bwx_map_memory,
237     bwx_unmap_memory,
238     bwx_readb,
239     bwx_readw,
240     bwx_readl,
241     bwx_writeb,
242     bwx_writew,
243     bwx_writel,
244 };