Annotation of src/sys/arch/powerpc/powerpc/bus_space.c, Revision 1.2
1.2 ! matt 1: /* $NetBSD: bus_space.c,v 1.1 2003/03/15 08:03:19 matt Exp $ */
1.1 matt 2:
3: /*-
4: * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9: * NASA Ames Research Center.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the NetBSD
22: * Foundation, Inc. and its contributors.
23: * 4. Neither the name of The NetBSD Foundation nor the names of its
24: * contributors may be used to endorse or promote products derived
25: * from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: * POSSIBILITY OF SUCH DAMAGE.
38: */
39:
40: #include <sys/param.h>
41: #include <sys/systm.h>
42: #include <sys/kernel.h>
43: #include <sys/device.h>
44: #include <sys/endian.h>
45: #include <sys/extent.h>
46: #include <sys/malloc.h>
47:
48: #include <uvm/uvm_extern.h>
49:
50: #define _POWERPC_BUS_SPACE_PRIVATE
51: #include <machine/bus.h>
52:
53: #ifdef PPC_OEA
54: #include <powerpc/oea/bat.h>
55: #include <powerpc/oea/pte.h>
56: #endif
57:
58: /* read_N */
59: u_int8_t bsr1(bus_space_tag_t, bus_space_handle_t, bus_size_t);
60: u_int16_t bsr2(bus_space_tag_t, bus_space_handle_t, bus_size_t);
61: u_int32_t bsr4(bus_space_tag_t, bus_space_handle_t, bus_size_t);
62: u_int64_t bsr8(bus_space_tag_t, bus_space_handle_t, bus_size_t);
63:
64: /* write_N */
65: void bsw1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t);
66: void bsw2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
67: void bsw4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
68: void bsw8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
69:
70: static const struct powerpc_bus_space_scalar scalar_ops = {
71: bsr1, bsr2, bsr4, bsr8,
72: bsw1, bsw2, bsw4, bsw8
73: };
74:
75: /* read_N byte reverse */
76: u_int16_t bsr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
77: u_int32_t bsr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
78: u_int64_t bsr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
79:
80: /* write_N byte reverse */
81: void bsw2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
82: void bsw4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
83: void bsw8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
84:
85: static const struct powerpc_bus_space_scalar scalar_rb_ops = {
86: bsr1, bsr2rb, bsr4rb, bsr8rb,
87: bsw1, bsw2rb, bsw4rb, bsw8rb
88: };
89:
90: /* read_multi_N */
91: void bsrm1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
92: size_t);
93: void bsrm2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
94: size_t);
95: void bsrm4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
96: size_t);
97: void bsrm8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
98: size_t);
99:
100: /* write_multi_N */
101: void bswm1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
102: const u_int8_t *, size_t);
103: void bswm2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
104: const u_int16_t *, size_t);
105: void bswm4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
106: const u_int32_t *, size_t);
107: void bswm8(bus_space_tag_t, bus_space_handle_t, bus_size_t,
108: const u_int64_t *, size_t);
109:
110: static const struct powerpc_bus_space_group multi_ops = {
111: bsrm1, bsrm2, bsrm4, bsrm8,
112: bswm1, bswm2, bswm4, bswm8
113: };
114:
115: /* read_multi_N byte reversed */
116: void bsrm2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
117: size_t);
118: void bsrm4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
119: size_t);
120: void bsrm8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
121: size_t);
122:
123: /* write_multi_N byte reversed */
124: void bswm2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
125: const u_int16_t *, size_t);
126: void bswm4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
127: const u_int32_t *, size_t);
128: void bswm8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
129: const u_int64_t *, size_t);
130:
131: static const struct powerpc_bus_space_group multi_rb_ops = {
132: bsrm1, bsrm2rb, bsrm4rb, bsrm8rb,
133: bswm1, bswm2rb, bswm4rb, bswm8rb
134: };
135:
136: /* read_region_N */
137: void bsrr1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
138: size_t);
139: void bsrr2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
140: size_t);
141: void bsrr4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
142: size_t);
143: void bsrr8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
144: size_t);
145:
146: /* write_region_N */
147: void bswr1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
148: const u_int8_t *, size_t);
149: void bswr2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
150: const u_int16_t *, size_t);
151: void bswr4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
152: const u_int32_t *, size_t);
153: void bswr8(bus_space_tag_t, bus_space_handle_t, bus_size_t,
154: const u_int64_t *, size_t);
155:
156: static const struct powerpc_bus_space_group region_ops = {
157: bsrr1, bsrr2, bsrr4, bsrr8,
158: bswr1, bswr2, bswr4, bswr8
159: };
160:
161: void bsrr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
162: size_t);
163: void bsrr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
164: size_t);
165: void bsrr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
166: size_t);
167:
168: void bswr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
169: const u_int16_t *, size_t);
170: void bswr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
171: const u_int32_t *, size_t);
172: void bswr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
173: const u_int64_t *, size_t);
174:
175: static const struct powerpc_bus_space_group region_rb_ops = {
176: bsrr1, bsrr2rb, bsrr4rb, bsrr8rb,
177: bswr1, bswr2rb, bswr4rb, bswr8rb
178: };
179:
180: /* set_region_n */
181: void bssr1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t,
182: size_t);
183: void bssr2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
184: size_t);
185: void bssr4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
186: size_t);
187: void bssr8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
188: size_t);
189:
190: static const struct powerpc_bus_space_set set_ops = {
191: bssr1, bssr2, bssr4, bssr8,
192: };
193:
194: void bssr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
195: size_t);
196: void bssr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
197: size_t);
198: void bssr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
199: size_t);
200:
201: static const struct powerpc_bus_space_set set_rb_ops = {
202: bssr1, bssr2rb, bssr4rb, bssr8rb,
203: };
204:
205: /* copy_region_N */
206: void bscr1(bus_space_tag_t, bus_space_handle_t,
207: bus_size_t, bus_space_handle_t, bus_size_t, size_t);
208: void bscr2(bus_space_tag_t, bus_space_handle_t,
209: bus_size_t, bus_space_handle_t, bus_size_t, size_t);
210: void bscr4(bus_space_tag_t, bus_space_handle_t,
211: bus_size_t, bus_space_handle_t, bus_size_t, size_t);
212: void bscr8(bus_space_tag_t, bus_space_handle_t,
213: bus_size_t, bus_space_handle_t, bus_size_t, size_t);
214:
215: static const struct powerpc_bus_space_copy copy_ops = {
216: bscr1, bscr2, bscr4, bscr8
217: };
218:
219: /*
220: * Strided versions
221: */
222: /* read_N */
223: u_int8_t bsr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
224: u_int16_t bsr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
225: u_int32_t bsr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
226: u_int64_t bsr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
227:
228: /* write_N */
229: void bsw1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t);
230: void bsw2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
231: void bsw4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
232: void bsw8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
233:
234: static const struct powerpc_bus_space_scalar scalar_strided_ops = {
235: bsr1_s, bsr2_s, bsr4_s, bsr8_s,
236: bsw1_s, bsw2_s, bsw4_s, bsw8_s
237: };
238:
239: /* read_N */
240: u_int16_t bsr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
241: u_int32_t bsr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
242: u_int64_t bsr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
243:
244: /* write_N */
245: void bsw2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
246: void bsw4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
247: void bsw8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
248:
249: static const struct powerpc_bus_space_scalar scalar_rb_strided_ops = {
250: bsr1_s, bsr2rb_s, bsr4rb_s, bsr8rb_s,
251: bsw1_s, bsw2rb_s, bsw4rb_s, bsw8rb_s
252: };
253:
254: /* read_multi_N */
255: void bsrm1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
256: size_t);
257: void bsrm2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
258: size_t);
259: void bsrm4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
260: size_t);
261: void bsrm8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
262: size_t);
263:
264: /* write_multi_N */
265: void bswm1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
266: const u_int8_t *, size_t);
267: void bswm2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
268: const u_int16_t *, size_t);
269: void bswm4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
270: const u_int32_t *, size_t);
271: void bswm8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
272: const u_int64_t *, size_t);
273:
274: static const struct powerpc_bus_space_group multi_strided_ops = {
275: bsrm1_s, bsrm2_s, bsrm4_s, bsrm8_s,
276: bswm1_s, bswm2_s, bswm4_s, bswm8_s
277: };
278:
279: /* read_multi_N */
280: void bsrm2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
281: size_t);
282: void bsrm4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
283: size_t);
284: void bsrm8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
285: size_t);
286:
287: /* write_multi_N */
288: void bswm2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
289: const u_int16_t *, size_t);
290: void bswm4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
291: const u_int32_t *, size_t);
292: void bswm8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
293: const u_int64_t *, size_t);
294:
295: static const struct powerpc_bus_space_group multi_rb_strided_ops = {
296: bsrm1_s, bsrm2rb_s, bsrm4rb_s, bsrm8rb_s,
297: bswm1_s, bswm2rb_s, bswm4rb_s, bswm8rb_s
298: };
299:
300: /* read_region_N */
301: void bsrr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
302: size_t);
303: void bsrr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
304: size_t);
305: void bsrr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
306: size_t);
307: void bsrr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
308: size_t);
309:
310: /* write_region_N */
311: void bswr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
312: const u_int8_t *, size_t);
313: void bswr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
314: const u_int16_t *, size_t);
315: void bswr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
316: const u_int32_t *, size_t);
317: void bswr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
318: const u_int64_t *, size_t);
319:
320: static const struct powerpc_bus_space_group region_strided_ops = {
321: bsrr1_s, bsrr2_s, bsrr4_s, bsrr8_s,
322: bswr1_s, bswr2_s, bswr4_s, bswr8_s
323: };
324:
325: /* read_region_N */
326: void bsrr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
327: size_t);
328: void bsrr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
329: size_t);
330: void bsrr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
331: size_t);
332:
333: /* write_region_N */
334: void bswr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
335: const u_int16_t *, size_t);
336: void bswr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
337: const u_int32_t *, size_t);
338: void bswr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
339: const u_int64_t *, size_t);
340:
341: static const struct powerpc_bus_space_group region_rb_strided_ops = {
342: bsrr1_s, bsrr2rb_s, bsrr4rb_s, bsrr8rb_s,
343: bswr1_s, bswr2rb_s, bswr4rb_s, bswr8rb_s
344: };
345:
346: /* set_region_N */
347: void bssr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t,
348: size_t);
349: void bssr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
350: size_t);
351: void bssr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
352: size_t);
353: void bssr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
354: size_t);
355:
356: static const struct powerpc_bus_space_set set_strided_ops = {
357: bssr1_s, bssr2_s, bssr4_s, bssr8_s,
358: };
359:
360: /* set_region_N */
361: void bssr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
362: size_t);
363: void bssr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
364: size_t);
365: void bssr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
366: size_t);
367:
368: static const struct powerpc_bus_space_set set_rb_strided_ops = {
369: bssr1_s, bssr2rb_s, bssr4rb_s, bssr8rb_s,
370: };
371:
372: /* copy_region_N */
373: void bscr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
374: bus_space_handle_t, bus_size_t, size_t);
375: void bscr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
376: bus_space_handle_t, bus_size_t, size_t);
377: void bscr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
378: bus_space_handle_t, bus_size_t, size_t);
379: void bscr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
380: bus_space_handle_t, bus_size_t, size_t);
381:
382: static const struct powerpc_bus_space_copy copy_strided_ops = {
383: bscr1_s, bscr2_s, bscr4_s, bscr8_s
384: };
385:
386: static paddr_t memio_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);
387: static int memio_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
388: bus_space_handle_t *);
389: static int memio_subregion(bus_space_tag_t, bus_space_handle_t, bus_size_t,
390: bus_size_t, bus_space_handle_t *);
391: static void memio_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
392: static int memio_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t, bus_size_t,
393: bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
394: static void memio_free(bus_space_tag_t, bus_space_handle_t, bus_size_t);
395:
396: static int extent_flags;
397:
398: int
399: bus_space_init(struct powerpc_bus_space *t, const char *extent_name,
400: caddr_t storage, size_t storage_size)
401: {
402: if (t->pbs_extent == NULL) {
403: t->pbs_extent = extent_create(extent_name, t->pbs_base,
404: t->pbs_limit-1, M_DEVBUF, storage, storage_size,
405: EX_NOCOALESCE|EX_NOWAIT);
406: if (t->pbs_extent == NULL)
407: return ENOMEM;
408: }
409:
410: t->pbs_mmap = memio_mmap;
411: t->pbs_map = memio_map;
412: t->pbs_subregion = memio_subregion;
413: t->pbs_unmap = memio_unmap;
414: t->pbs_alloc = memio_alloc;
415: t->pbs_free = memio_free;
416:
417: if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
418: t->pbs_scalar_stream = scalar_strided_ops;
419: t->pbs_multi_stream = &multi_strided_ops;
420: t->pbs_region_stream = ®ion_strided_ops;
421: t->pbs_set_stream = &set_strided_ops;
422: t->pbs_copy = ©_strided_ops;
423: } else {
424: t->pbs_scalar_stream = scalar_ops;
425: t->pbs_multi_stream = &multi_ops;
426: t->pbs_region_stream = ®ion_ops;
427: t->pbs_set_stream = &set_ops;
428: t->pbs_copy = ©_ops;
429: }
430:
431: #if BYTE_ORDER == BIG_ENDIAN
432: if (t->pbs_flags & _BUS_SPACE_BIG_ENDIAN) {
433: if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
434: t->pbs_scalar = scalar_strided_ops;
435: t->pbs_multi = &multi_strided_ops;
436: t->pbs_region = ®ion_strided_ops;
437: t->pbs_set = &set_strided_ops;
438: } else {
439: t->pbs_scalar = scalar_ops;
440: t->pbs_multi = &multi_ops;
441: t->pbs_region = ®ion_ops;
442: t->pbs_set = &set_ops;
443: }
444: } else {
445: if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
446: t->pbs_scalar = scalar_rb_strided_ops;
447: t->pbs_multi = &multi_rb_strided_ops;
448: t->pbs_region = ®ion_rb_strided_ops;
449: t->pbs_set = &set_rb_strided_ops;
450: } else {
451: t->pbs_scalar = scalar_rb_ops;
452: t->pbs_multi = &multi_rb_ops;
453: t->pbs_region = ®ion_rb_ops;
454: t->pbs_set = &set_rb_ops;
455: }
456: }
457: #else
458: if (t->pbs_flags & _BUS_SPACE_LITTLE_ENDIAN) {
459: if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
460: t->pbs_scalar = scalar_strided_ops;
461: t->pbs_multi = &multi_strided_ops;
462: t->pbs_region = ®ion_strided_ops;
463: t->pbs_set = &set_strided_ops;
464: } else {
465: t->pbs_scalar = scalar_ops;
466: t->pbs_multi = &multi_ops;
467: t->pbs_region = ®ion_ops;
468: t->pbs_set = &set_ops;
469: }
470: } else {
471: if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
472: t->pbs_scalar = scalar_rb_strided_ops;
473: t->pbs_multi = &multi_rb_strided_ops;
474: t->pbs_region = ®ion_rb_strided_ops;
475: t->pbs_set = &set_rb_strided_ops;
476: } else {
477: t->pbs_scalar = scalar_rb_ops;
478: t->pbs_multi = &multi_rb_ops;
479: t->pbs_region = ®ion_rb_ops;
480: t->pbs_set = &set_rb_ops;
481: }
482: }
483: #endif
484: return 0;
485: }
486:
487: void
488: bus_space_mallocok(void)
489: {
490: extent_flags = EX_MALLOCOK;
491: }
492:
493: /* ARGSUSED */
494: paddr_t
495: memio_mmap(bus_space_tag_t t, bus_addr_t bpa, off_t offset, int prot, int flags)
496: {
497: return (trunc_page(bpa + offset));
498: }
499:
500: int
501: memio_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
502: bus_space_handle_t *bshp)
503: {
504: int error;
505: paddr_t pa;
506:
507: size = _BUS_SPACE_STRIDE(t, size);
508:
1.2 ! matt 509: if (bpa + size > t->pbs_limit) {
! 510: #ifdef DEBUG
! 511: printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: EINVAL\n",
! 512: t, t->pbs_base, t->pbs_limit, bpa, size);
! 513: #endif
1.1 matt 514: return (EINVAL);
1.2 ! matt 515: }
1.1 matt 516:
517: /*
518: * Can't map I/O space as linear.
519: */
520: if ((flags & BUS_SPACE_MAP_LINEAR) &&
521: (t->pbs_flags & _BUS_SPACE_IO_TYPE))
522: return (EOPNOTSUPP);
523:
524: /*
525: * Before we go any further, let's make sure that this
526: * region is available.
527: */
528: error = extent_alloc_region(t->pbs_extent, bpa, size,
529: EX_NOWAIT | extent_flags);
1.2 ! matt 530: if (error) {
! 531: #ifdef DEBUG
! 532: printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: %d\n",
! 533: t, t->pbs_base, t->pbs_limit, bpa, size, error);
! 534: #endif
1.1 matt 535: return (error);
1.2 ! matt 536: }
1.1 matt 537:
538: pa = t->pbs_offset + bpa;
539: #ifdef PPC_OEA
540: {
541: /*
542: * Let's try to BAT map this address if possible
543: */
544: register_t batu = battable[pa >> ADDR_SR_SHFT].batu;
545: if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, pa) &&
546: BAT_VA_MATCH_P(batu, pa + size - 1)) {
547: *bshp = pa;
548: return (0);
549: }
550: }
551: #endif
552: if (extent_flags == 0) {
553: extent_free(t->pbs_extent, bpa, size, EX_NOWAIT);
1.2 ! matt 554: #ifdef DEBUG
! 555: printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: ENOMEM\n",
! 556: t, t->pbs_base, t->pbs_limit, bpa, size);
! 557: #endif
1.1 matt 558: return (ENOMEM);
559: }
560: /*
561: * Map this into the kernel pmap.
562: */
563: *bshp = (bus_space_handle_t) mapiodev(pa, size);
564: if (*bshp == 0) {
565: extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags);
1.2 ! matt 566: #ifdef DEBUG
! 567: printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: ENOMEM\n",
! 568: t, t->pbs_base, t->pbs_limit, bpa, size);
! 569: #endif
1.1 matt 570: return (ENOMEM);
571: }
572:
573: return (0);
574: }
575:
576: int
577: memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset,
578: bus_size_t size, bus_space_handle_t *bshp)
579: {
580: *bshp = bsh + _BUS_SPACE_STRIDE(t, offset);
581: return (0);
582: }
583:
584: void
585: memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
586: {
587: bus_addr_t bpa;
588: vaddr_t va = bsh;
589: paddr_t pa;
590:
591: size = _BUS_SPACE_STRIDE(t, size);
592:
593: #ifdef PPC_OEA
594: {
595: register_t batu = battable[va >> ADDR_SR_SHFT].batu;
596: if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, va) &&
597: BAT_VA_MATCH_P(batu, va + size - 1)) {
598: pa = va;
599: } else {
600: pmap_extract(pmap_kernel(), va, &pa);
601: }
602: }
603: #else
604: pmap_extract(pmap_kernel(), va, &pa);
605: #endif
606: bpa = pa - t->pbs_offset;
607:
608: if (extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags)) {
609: printf("memio_unmap: %s 0x%lx, size 0x%lx\n",
610: (t->pbs_flags & _BUS_SPACE_IO_TYPE) ? "port" : "mem",
611: (unsigned long)bpa, (unsigned long)size);
612: printf("memio_unmap: can't free region\n");
613: }
614: }
615:
616: int
617: memio_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend,
618: bus_size_t size, bus_size_t alignment, bus_size_t boundary,
619: int flags, bus_addr_t *bpap, bus_space_handle_t *bshp)
620: {
621: u_long bpa;
622: paddr_t pa;
623: int error;
624:
625: size = _BUS_SPACE_STRIDE(t, size);
626:
627: if (rstart + size > t->pbs_limit)
628: return (EINVAL);
629:
630: /*
631: * Can't map I/O space as linear.
632: */
633: if ((flags & BUS_SPACE_MAP_LINEAR) &&
634: (t->pbs_flags & _BUS_SPACE_IO_TYPE))
635: return (EOPNOTSUPP);
636:
637: if (rstart < t->pbs_extent->ex_start || rend > t->pbs_extent->ex_end)
638: panic("memio_alloc: bad region start/end");
639:
640: error = extent_alloc_subregion(t->pbs_extent, rstart, rend, size,
641: alignment, boundary, EX_FAST | EX_NOWAIT | extent_flags, &bpa);
642:
643: if (error)
644: return (error);
645:
646: *bpap = bpa;
647: pa = t->pbs_offset + bpa;
648: #ifdef PPC_OEA
649: {
650: register_t batu = battable[pa >> ADDR_SR_SHFT].batu;
651: if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, pa) &&
652: BAT_VA_MATCH_P(batu, pa + size - 1)) {
653: *bshp = pa;
654: return (0);
655: }
656: }
657: #endif
658: *bshp = (bus_space_handle_t) mapiodev(pa, size);
659: if (*bshp == 0) {
660: extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags);
661: return (ENOMEM);
662: }
663:
664: return (0);
665: }
666:
667: void
668: memio_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
669: {
670: /* memio_unmap() does all that we need to do. */
671: memio_unmap(t, bsh, size);
672: }
CVSweb <webmaster@jp.NetBSD.org>