ifpga_io.c revision 1.4 1 /* $NetBSD: ifpga_io.c,v 1.4 2002/10/06 17:13:58 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1997 Causality Limited
5 * Copyright (c) 1997 Mark Brinicombe.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Mark Brinicombe
19 * for the NetBSD Project.
20 * 4. The name of the company nor the name of the author may be used to
21 * endorse or promote products derived from this software without specific
22 * prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * From arm/footbridge/footbridge_io.c
37 */
38
39 /*
40 * bus_space I/O functions for IFPGA
41 */
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <machine/bus.h>
46 #include <uvm/uvm_extern.h>
47
48 #include <evbarm/ifpga/ifpgavar.h>
49
50 /* Proto types for all the bus_space structure functions */
51
52 bs_protos(ifpga);
53 bs_protos(generic);
54 bs_protos(generic_armv4);
55 bs_protos(bs_notimpl);
56 bs_map_proto(ifpga_mem);
57 bs_unmap_proto(ifpga_mem);
58
59 /* Declare the ifpga bus space tag */
60
61 struct bus_space ifpga_bs_tag = {
62 /* cookie */
63 (void *) 0, /* Physical base address */
64
65 /* mapping/unmapping */
66 ifpga_bs_map,
67 ifpga_bs_unmap,
68 ifpga_bs_subregion,
69
70 /* allocation/deallocation */
71 ifpga_bs_alloc,
72 ifpga_bs_free,
73
74 /* get kernel virtual address */
75 ifpga_bs_vaddr,
76
77 /* mmap */
78 bs_notimpl_bs_mmap,
79
80 /* barrier */
81 ifpga_bs_barrier,
82
83 /* read (single) */
84 generic_bs_r_1,
85 generic_armv4_bs_r_2,
86 generic_bs_r_4,
87 bs_notimpl_bs_r_8,
88
89 /* read multiple */
90 generic_bs_rm_1,
91 generic_armv4_bs_rm_2,
92 generic_bs_rm_4,
93 bs_notimpl_bs_rm_8,
94
95 /* read region */
96 bs_notimpl_bs_rr_1,
97 generic_armv4_bs_rr_2,
98 generic_bs_rr_4,
99 bs_notimpl_bs_rr_8,
100
101 /* write (single) */
102 generic_bs_w_1,
103 generic_armv4_bs_w_2,
104 generic_bs_w_4,
105 bs_notimpl_bs_w_8,
106
107 /* write multiple */
108 generic_bs_wm_1,
109 generic_armv4_bs_wm_2,
110 generic_bs_wm_4,
111 bs_notimpl_bs_wm_8,
112
113 /* write region */
114 bs_notimpl_bs_wr_1,
115 generic_armv4_bs_wr_2,
116 generic_bs_wr_4,
117 bs_notimpl_bs_wr_8,
118
119 /* set multiple */
120 bs_notimpl_bs_sm_1,
121 bs_notimpl_bs_sm_2,
122 bs_notimpl_bs_sm_4,
123 bs_notimpl_bs_sm_8,
124
125 /* set region */
126 bs_notimpl_bs_sr_1,
127 generic_armv4_bs_sr_2,
128 bs_notimpl_bs_sr_4,
129 bs_notimpl_bs_sr_8,
130
131 /* copy */
132 bs_notimpl_bs_c_1,
133 generic_armv4_bs_c_2,
134 bs_notimpl_bs_c_4,
135 bs_notimpl_bs_c_8,
136 };
137
138 void ifpga_create_io_bs_tag(t, cookie)
139 struct bus_space *t;
140 void *cookie;
141 {
142 *t = ifpga_bs_tag;
143 t->bs_cookie = cookie;
144 }
145
146 void ifpga_create_mem_bs_tag(t, cookie)
147 struct bus_space *t;
148 void *cookie;
149 {
150 *t = ifpga_bs_tag;
151 t->bs_map = ifpga_mem_bs_map;
152 t->bs_unmap = ifpga_mem_bs_unmap;
153 t->bs_cookie = cookie;
154 }
155
156 /* bus space functions */
157
158 int
159 ifpga_bs_map(t, bpa, size, cacheable, bshp)
160 void *t;
161 bus_addr_t bpa;
162 bus_size_t size;
163 int cacheable;
164 bus_space_handle_t *bshp;
165 {
166 /* The cookie is the base address for the I/O area */
167 *bshp = bpa + (bus_addr_t)t;
168 return 0;
169 }
170
171 int
172 ifpga_mem_bs_map(t, bpa, size, cacheable, bshp)
173 void *t;
174 bus_addr_t bpa;
175 bus_size_t size;
176 int cacheable;
177 bus_space_handle_t *bshp;
178 {
179 bus_addr_t startpa, endpa;
180 vaddr_t va;
181
182 /* Round the allocation to page boundries */
183 startpa = trunc_page(bpa);
184 endpa = round_page(bpa + size);
185
186 /* Get some VM. */
187 va = uvm_km_valloc(kernel_map, endpa - startpa);
188 if (va == 0)
189 return ENOMEM;
190
191 /* Store the bus space handle */
192 *bshp = va + (bpa & PGOFSET);
193
194 /* Now map the pages */
195 /* The cookie is the physical base address for the I/O area */
196 while (startpa < endpa) {
197 /* XXX pmap_kenter_pa maps pages cacheable -- not what
198 we want. */
199 pmap_enter(pmap_kernel(), va, (bus_addr_t)t + startpa,
200 VM_PROT_READ | VM_PROT_WRITE, 0);
201 va += NBPG;
202 startpa += NBPG;
203 }
204 pmap_update(pmap_kernel());
205
206 return 0;
207 }
208
209 int
210 ifpga_bs_alloc(t, rstart, rend, size, alignment, boundary, cacheable,
211 bpap, bshp)
212 void *t;
213 bus_addr_t rstart, rend;
214 bus_size_t size, alignment, boundary;
215 int cacheable;
216 bus_addr_t *bpap;
217 bus_space_handle_t *bshp;
218 {
219 panic("ifpga_alloc(): Help!");
220 }
221
222
223 void
224 ifpga_bs_unmap(t, bsh, size)
225 void *t;
226 bus_space_handle_t bsh;
227 bus_size_t size;
228 {
229 /* Nothing to do for an io map. */
230 }
231
232 void
233 ifpga_mem_bs_unmap(t, bsh, size)
234 void *t;
235 bus_space_handle_t bsh;
236 bus_size_t size;
237 {
238 vaddr_t startva, endva;
239
240 startva = trunc_page(bsh);
241 endva = round_page(bsh + size);
242
243 uvm_km_free(kernel_map, startva, endva - startva);
244 }
245
246 void
247 ifpga_bs_free(t, bsh, size)
248 void *t;
249 bus_space_handle_t bsh;
250 bus_size_t size;
251 {
252
253 panic("ifpga_free(): Help!");
254 /* ifpga_bs_unmap() does all that we need to do. */
255 /* ifpga_bs_unmap(t, bsh, size);*/
256 }
257
258 int
259 ifpga_bs_subregion(t, bsh, offset, size, nbshp)
260 void *t;
261 bus_space_handle_t bsh;
262 bus_size_t offset, size;
263 bus_space_handle_t *nbshp;
264 {
265
266 *nbshp = bsh + (offset << ((int)t));
267 return (0);
268 }
269
270 void *
271 ifpga_bs_vaddr(t, bsh)
272 void *t;
273 bus_space_handle_t bsh;
274 {
275
276 return ((void *)bsh);
277 }
278
279 void
280 ifpga_bs_barrier(t, bsh, offset, len, flags)
281 void *t;
282 bus_space_handle_t bsh;
283 bus_size_t offset, len;
284 int flags;
285 {
286 }
287