Annotation of src/sys/arch/powerpc/powerpc/bus_space.c, Revision 1.12.4.3
1.12.4.3! garbled 1: /* $NetBSD: bus_space.c,v 1.12.4.2 2007/08/02 21:59:35 macallan 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: */
1.3 lukem 39:
40: #include <sys/cdefs.h>
1.12.4.3! garbled 41: __KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.12.4.2 2007/08/02 21:59:35 macallan Exp $");
1.1 matt 42:
43: #include <sys/param.h>
44: #include <sys/systm.h>
45: #include <sys/kernel.h>
46: #include <sys/device.h>
47: #include <sys/endian.h>
48: #include <sys/extent.h>
49: #include <sys/malloc.h>
50:
51: #include <uvm/uvm_extern.h>
52:
53: #define _POWERPC_BUS_SPACE_PRIVATE
54: #include <machine/bus.h>
55:
1.7 sanjayl 56: #if defined (PPC_OEA) || defined (PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
1.1 matt 57: #include <powerpc/oea/bat.h>
58: #include <powerpc/oea/pte.h>
1.5 kleink 59: #include <powerpc/oea/sr_601.h>
60: #include <powerpc/spr.h>
1.1 matt 61: #endif
62:
63: /* read_N */
64: u_int8_t bsr1(bus_space_tag_t, bus_space_handle_t, bus_size_t);
65: u_int16_t bsr2(bus_space_tag_t, bus_space_handle_t, bus_size_t);
66: u_int32_t bsr4(bus_space_tag_t, bus_space_handle_t, bus_size_t);
67: u_int64_t bsr8(bus_space_tag_t, bus_space_handle_t, bus_size_t);
68:
69: /* write_N */
70: void bsw1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t);
71: void bsw2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
72: void bsw4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
73: void bsw8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
74:
75: static const struct powerpc_bus_space_scalar scalar_ops = {
76: bsr1, bsr2, bsr4, bsr8,
77: bsw1, bsw2, bsw4, bsw8
78: };
79:
80: /* read_N byte reverse */
81: u_int16_t bsr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
82: u_int32_t bsr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
83: u_int64_t bsr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
84:
85: /* write_N byte reverse */
86: void bsw2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
87: void bsw4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
88: void bsw8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
89:
90: static const struct powerpc_bus_space_scalar scalar_rb_ops = {
91: bsr1, bsr2rb, bsr4rb, bsr8rb,
92: bsw1, bsw2rb, bsw4rb, bsw8rb
93: };
94:
95: /* read_multi_N */
96: void bsrm1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
97: size_t);
98: void bsrm2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
99: size_t);
100: void bsrm4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
101: size_t);
102: void bsrm8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
103: size_t);
104:
105: /* write_multi_N */
106: void bswm1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
107: const u_int8_t *, size_t);
108: void bswm2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
109: const u_int16_t *, size_t);
110: void bswm4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
111: const u_int32_t *, size_t);
112: void bswm8(bus_space_tag_t, bus_space_handle_t, bus_size_t,
113: const u_int64_t *, size_t);
114:
115: static const struct powerpc_bus_space_group multi_ops = {
116: bsrm1, bsrm2, bsrm4, bsrm8,
117: bswm1, bswm2, bswm4, bswm8
118: };
119:
120: /* read_multi_N byte reversed */
121: void bsrm2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
122: size_t);
123: void bsrm4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
124: size_t);
125: void bsrm8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
126: size_t);
127:
128: /* write_multi_N byte reversed */
129: void bswm2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
130: const u_int16_t *, size_t);
131: void bswm4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
132: const u_int32_t *, size_t);
133: void bswm8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
134: const u_int64_t *, size_t);
135:
136: static const struct powerpc_bus_space_group multi_rb_ops = {
137: bsrm1, bsrm2rb, bsrm4rb, bsrm8rb,
138: bswm1, bswm2rb, bswm4rb, bswm8rb
139: };
140:
141: /* read_region_N */
142: void bsrr1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
143: size_t);
144: void bsrr2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
145: size_t);
146: void bsrr4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
147: size_t);
148: void bsrr8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
149: size_t);
150:
151: /* write_region_N */
152: void bswr1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
153: const u_int8_t *, size_t);
154: void bswr2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
155: const u_int16_t *, size_t);
156: void bswr4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
157: const u_int32_t *, size_t);
158: void bswr8(bus_space_tag_t, bus_space_handle_t, bus_size_t,
159: const u_int64_t *, size_t);
160:
161: static const struct powerpc_bus_space_group region_ops = {
162: bsrr1, bsrr2, bsrr4, bsrr8,
163: bswr1, bswr2, bswr4, bswr8
164: };
165:
166: void bsrr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
167: size_t);
168: void bsrr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
169: size_t);
170: void bsrr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
171: size_t);
172:
173: void bswr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
174: const u_int16_t *, size_t);
175: void bswr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
176: const u_int32_t *, size_t);
177: void bswr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
178: const u_int64_t *, size_t);
179:
180: static const struct powerpc_bus_space_group region_rb_ops = {
181: bsrr1, bsrr2rb, bsrr4rb, bsrr8rb,
182: bswr1, bswr2rb, bswr4rb, bswr8rb
183: };
184:
185: /* set_region_n */
186: void bssr1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t,
187: size_t);
188: void bssr2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
189: size_t);
190: void bssr4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
191: size_t);
192: void bssr8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
193: size_t);
194:
195: static const struct powerpc_bus_space_set set_ops = {
196: bssr1, bssr2, bssr4, bssr8,
197: };
198:
199: void bssr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
200: size_t);
201: void bssr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
202: size_t);
203: void bssr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
204: size_t);
205:
206: static const struct powerpc_bus_space_set set_rb_ops = {
207: bssr1, bssr2rb, bssr4rb, bssr8rb,
208: };
209:
210: /* copy_region_N */
211: void bscr1(bus_space_tag_t, bus_space_handle_t,
212: bus_size_t, bus_space_handle_t, bus_size_t, size_t);
213: void bscr2(bus_space_tag_t, bus_space_handle_t,
214: bus_size_t, bus_space_handle_t, bus_size_t, size_t);
215: void bscr4(bus_space_tag_t, bus_space_handle_t,
216: bus_size_t, bus_space_handle_t, bus_size_t, size_t);
217: void bscr8(bus_space_tag_t, bus_space_handle_t,
218: bus_size_t, bus_space_handle_t, bus_size_t, size_t);
219:
220: static const struct powerpc_bus_space_copy copy_ops = {
221: bscr1, bscr2, bscr4, bscr8
222: };
223:
224: /*
225: * Strided versions
226: */
227: /* read_N */
228: u_int8_t bsr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
229: u_int16_t bsr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
230: u_int32_t bsr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
231: u_int64_t bsr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
232:
233: /* write_N */
234: void bsw1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t);
235: void bsw2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
236: void bsw4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
237: void bsw8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
238:
239: static const struct powerpc_bus_space_scalar scalar_strided_ops = {
240: bsr1_s, bsr2_s, bsr4_s, bsr8_s,
241: bsw1_s, bsw2_s, bsw4_s, bsw8_s
242: };
243:
244: /* read_N */
245: u_int16_t bsr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
246: u_int32_t bsr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
247: u_int64_t bsr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
248:
249: /* write_N */
250: void bsw2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
251: void bsw4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
252: void bsw8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
253:
254: static const struct powerpc_bus_space_scalar scalar_rb_strided_ops = {
255: bsr1_s, bsr2rb_s, bsr4rb_s, bsr8rb_s,
256: bsw1_s, bsw2rb_s, bsw4rb_s, bsw8rb_s
257: };
258:
259: /* read_multi_N */
260: void bsrm1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
261: size_t);
262: void bsrm2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
263: size_t);
264: void bsrm4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
265: size_t);
266: void bsrm8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
267: size_t);
268:
269: /* write_multi_N */
270: void bswm1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
271: const u_int8_t *, size_t);
272: void bswm2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
273: const u_int16_t *, size_t);
274: void bswm4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
275: const u_int32_t *, size_t);
276: void bswm8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
277: const u_int64_t *, size_t);
278:
279: static const struct powerpc_bus_space_group multi_strided_ops = {
280: bsrm1_s, bsrm2_s, bsrm4_s, bsrm8_s,
281: bswm1_s, bswm2_s, bswm4_s, bswm8_s
282: };
283:
284: /* read_multi_N */
285: void bsrm2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
286: size_t);
287: void bsrm4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
288: size_t);
289: void bsrm8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
290: size_t);
291:
292: /* write_multi_N */
293: void bswm2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
294: const u_int16_t *, size_t);
295: void bswm4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
296: const u_int32_t *, size_t);
297: void bswm8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
298: const u_int64_t *, size_t);
299:
300: static const struct powerpc_bus_space_group multi_rb_strided_ops = {
301: bsrm1_s, bsrm2rb_s, bsrm4rb_s, bsrm8rb_s,
302: bswm1_s, bswm2rb_s, bswm4rb_s, bswm8rb_s
303: };
304:
305: /* read_region_N */
306: void bsrr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
307: size_t);
308: void bsrr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
309: size_t);
310: void bsrr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
311: size_t);
312: void bsrr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
313: size_t);
314:
315: /* write_region_N */
316: void bswr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
317: const u_int8_t *, size_t);
318: void bswr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
319: const u_int16_t *, size_t);
320: void bswr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
321: const u_int32_t *, size_t);
322: void bswr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
323: const u_int64_t *, size_t);
324:
325: static const struct powerpc_bus_space_group region_strided_ops = {
326: bsrr1_s, bsrr2_s, bsrr4_s, bsrr8_s,
327: bswr1_s, bswr2_s, bswr4_s, bswr8_s
328: };
329:
330: /* read_region_N */
331: void bsrr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
332: size_t);
333: void bsrr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
334: size_t);
335: void bsrr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
336: size_t);
337:
338: /* write_region_N */
339: void bswr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
340: const u_int16_t *, size_t);
341: void bswr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
342: const u_int32_t *, size_t);
343: void bswr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
344: const u_int64_t *, size_t);
345:
346: static const struct powerpc_bus_space_group region_rb_strided_ops = {
347: bsrr1_s, bsrr2rb_s, bsrr4rb_s, bsrr8rb_s,
348: bswr1_s, bswr2rb_s, bswr4rb_s, bswr8rb_s
349: };
350:
351: /* set_region_N */
352: void bssr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t,
353: size_t);
354: void bssr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
355: size_t);
356: void bssr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
357: size_t);
358: void bssr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
359: size_t);
360:
361: static const struct powerpc_bus_space_set set_strided_ops = {
362: bssr1_s, bssr2_s, bssr4_s, bssr8_s,
363: };
364:
365: /* set_region_N */
366: void bssr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
367: size_t);
368: void bssr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
369: size_t);
370: void bssr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
371: size_t);
372:
373: static const struct powerpc_bus_space_set set_rb_strided_ops = {
374: bssr1_s, bssr2rb_s, bssr4rb_s, bssr8rb_s,
375: };
376:
377: /* copy_region_N */
378: void bscr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
379: bus_space_handle_t, bus_size_t, size_t);
380: void bscr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
381: bus_space_handle_t, bus_size_t, size_t);
382: void bscr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
383: bus_space_handle_t, bus_size_t, size_t);
384: void bscr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
385: bus_space_handle_t, bus_size_t, size_t);
386:
387: static const struct powerpc_bus_space_copy copy_strided_ops = {
388: bscr1_s, bscr2_s, bscr4_s, bscr8_s
389: };
390:
391: static paddr_t memio_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);
392: static int memio_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
393: bus_space_handle_t *);
394: static int memio_subregion(bus_space_tag_t, bus_space_handle_t, bus_size_t,
395: bus_size_t, bus_space_handle_t *);
396: static void memio_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
397: static int memio_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t, bus_size_t,
398: bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
399: static void memio_free(bus_space_tag_t, bus_space_handle_t, bus_size_t);
400:
401: static int extent_flags;
402:
403: int
404: bus_space_init(struct powerpc_bus_space *t, const char *extent_name,
1.10 christos 405: void *storage, size_t storage_size)
1.1 matt 406: {
407: if (t->pbs_extent == NULL) {
408: t->pbs_extent = extent_create(extent_name, t->pbs_base,
409: t->pbs_limit-1, M_DEVBUF, storage, storage_size,
410: EX_NOCOALESCE|EX_NOWAIT);
411: if (t->pbs_extent == NULL)
412: return ENOMEM;
413: }
414:
415: t->pbs_mmap = memio_mmap;
416: t->pbs_map = memio_map;
417: t->pbs_subregion = memio_subregion;
418: t->pbs_unmap = memio_unmap;
419: t->pbs_alloc = memio_alloc;
420: t->pbs_free = memio_free;
421:
422: if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
423: t->pbs_scalar_stream = scalar_strided_ops;
424: t->pbs_multi_stream = &multi_strided_ops;
425: t->pbs_region_stream = ®ion_strided_ops;
426: t->pbs_set_stream = &set_strided_ops;
427: t->pbs_copy = ©_strided_ops;
428: } else {
429: t->pbs_scalar_stream = scalar_ops;
430: t->pbs_multi_stream = &multi_ops;
431: t->pbs_region_stream = ®ion_ops;
432: t->pbs_set_stream = &set_ops;
433: t->pbs_copy = ©_ops;
434: }
435:
436: #if BYTE_ORDER == BIG_ENDIAN
437: if (t->pbs_flags & _BUS_SPACE_BIG_ENDIAN) {
438: if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
439: t->pbs_scalar = scalar_strided_ops;
440: t->pbs_multi = &multi_strided_ops;
441: t->pbs_region = ®ion_strided_ops;
442: t->pbs_set = &set_strided_ops;
443: } else {
444: t->pbs_scalar = scalar_ops;
445: t->pbs_multi = &multi_ops;
446: t->pbs_region = ®ion_ops;
447: t->pbs_set = &set_ops;
448: }
449: } else {
450: if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
451: t->pbs_scalar = scalar_rb_strided_ops;
452: t->pbs_multi = &multi_rb_strided_ops;
453: t->pbs_region = ®ion_rb_strided_ops;
454: t->pbs_set = &set_rb_strided_ops;
455: } else {
456: t->pbs_scalar = scalar_rb_ops;
457: t->pbs_multi = &multi_rb_ops;
458: t->pbs_region = ®ion_rb_ops;
459: t->pbs_set = &set_rb_ops;
460: }
461: }
462: #else
463: if (t->pbs_flags & _BUS_SPACE_LITTLE_ENDIAN) {
464: if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
465: t->pbs_scalar = scalar_strided_ops;
466: t->pbs_multi = &multi_strided_ops;
467: t->pbs_region = ®ion_strided_ops;
468: t->pbs_set = &set_strided_ops;
469: } else {
470: t->pbs_scalar = scalar_ops;
471: t->pbs_multi = &multi_ops;
472: t->pbs_region = ®ion_ops;
473: t->pbs_set = &set_ops;
474: }
475: } else {
476: if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
477: t->pbs_scalar = scalar_rb_strided_ops;
478: t->pbs_multi = &multi_rb_strided_ops;
479: t->pbs_region = ®ion_rb_strided_ops;
480: t->pbs_set = &set_rb_strided_ops;
481: } else {
482: t->pbs_scalar = scalar_rb_ops;
483: t->pbs_multi = &multi_rb_ops;
484: t->pbs_region = ®ion_rb_ops;
485: t->pbs_set = &set_rb_ops;
486: }
487: }
488: #endif
489: return 0;
490: }
491:
492: void
493: bus_space_mallocok(void)
494: {
495: extent_flags = EX_MALLOCOK;
496: }
497:
498: /* ARGSUSED */
499: paddr_t
500: memio_mmap(bus_space_tag_t t, bus_addr_t bpa, off_t offset, int prot, int flags)
501: {
1.12.4.2 macallan 502: paddr_t ret;
1.12.4.1 macallan 503: /* XXX what about stride? */
1.12.4.2 macallan 504: ret = trunc_page(t->pbs_offset + bpa + offset);
505: #ifdef DEBUG
506: if (ret == 0) {
507: printf("%s: [%08x, %08x %08x] mmaps to 0?!\n", __func__,
508: (uint32_t)t->pbs_offset, (uint32_t)bpa, (uint32_t)offset);
509: return -1;
510: }
511: #endif
512: return ret;
1.1 matt 513: }
514:
515: int
516: memio_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
517: bus_space_handle_t *bshp)
518: {
519: int error;
520: paddr_t pa;
521:
522: size = _BUS_SPACE_STRIDE(t, size);
1.12.4.1 macallan 523: bpa = _BUS_SPACE_STRIDE(t, bpa);
1.1 matt 524:
1.2 matt 525: if (bpa + size > t->pbs_limit) {
526: #ifdef DEBUG
527: printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: EINVAL\n",
528: t, t->pbs_base, t->pbs_limit, bpa, size);
1.12.4.2 macallan 529:
1.2 matt 530: #endif
1.1 matt 531: return (EINVAL);
1.2 matt 532: }
1.1 matt 533:
534: /*
535: * Can't map I/O space as linear.
536: */
537: if ((flags & BUS_SPACE_MAP_LINEAR) &&
1.12.4.2 macallan 538: (t->pbs_flags & _BUS_SPACE_IO_TYPE)) {
1.1 matt 539: return (EOPNOTSUPP);
1.12.4.2 macallan 540: }
1.1 matt 541:
1.4 scw 542: #ifdef PPC_IBM4XX
543: /*
544: * XXX: Temporary kludge.
545: * Don't bother checking the extent during very early bootstrap.
546: */
547: if (extent_flags) {
548: #endif
1.1 matt 549: /*
550: * Before we go any further, let's make sure that this
551: * region is available.
552: */
553: error = extent_alloc_region(t->pbs_extent, bpa, size,
554: EX_NOWAIT | extent_flags);
1.2 matt 555: if (error) {
556: #ifdef DEBUG
557: printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: %d\n",
558: t, t->pbs_base, t->pbs_limit, bpa, size, error);
559: #endif
1.1 matt 560: return (error);
1.2 matt 561: }
1.4 scw 562: #ifdef PPC_IBM4XX
563: }
564: #endif
1.1 matt 565:
566: pa = t->pbs_offset + bpa;
567: #ifdef PPC_OEA
1.5 kleink 568: if ((mfpvr() >> 16) != MPC601) {
1.1 matt 569: /*
570: * Let's try to BAT map this address if possible
571: */
572: register_t batu = battable[pa >> ADDR_SR_SHFT].batu;
573: if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, pa) &&
574: BAT_VA_MATCH_P(batu, pa + size - 1)) {
575: *bshp = pa;
576: return (0);
577: }
1.5 kleink 578: } else {
579: /*
580: * Same as above, but via the MPC601's I/O segments
581: */
582: register_t sr = iosrtable[pa >> ADDR_SR_SHFT];
1.11 garbled 583: if (SR601_VALID_P(sr) && ((pa >> ADDR_SR_SHFT) ==
584: ((pa + size - 1) >> ADDR_SR_SHFT))) {
1.5 kleink 585: *bshp = pa;
586: return (0);
587: }
1.1 matt 588: }
589: #endif
1.4 scw 590: #ifndef PPC_IBM4XX
1.1 matt 591: if (extent_flags == 0) {
592: extent_free(t->pbs_extent, bpa, size, EX_NOWAIT);
1.2 matt 593: #ifdef DEBUG
594: printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: ENOMEM\n",
595: t, t->pbs_base, t->pbs_limit, bpa, size);
596: #endif
1.1 matt 597: return (ENOMEM);
598: }
1.4 scw 599: #endif
1.1 matt 600: /*
601: * Map this into the kernel pmap.
602: */
603: *bshp = (bus_space_handle_t) mapiodev(pa, size);
604: if (*bshp == 0) {
605: extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags);
1.2 matt 606: #ifdef DEBUG
607: printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: ENOMEM\n",
608: t, t->pbs_base, t->pbs_limit, bpa, size);
609: #endif
1.1 matt 610: return (ENOMEM);
611: }
612:
613: return (0);
614: }
615:
616: int
617: memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset,
618: bus_size_t size, bus_space_handle_t *bshp)
619: {
620: *bshp = bsh + _BUS_SPACE_STRIDE(t, offset);
621: return (0);
622: }
623:
624: void
625: memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
626: {
627: bus_addr_t bpa;
628: vaddr_t va = bsh;
629: paddr_t pa;
630:
631: size = _BUS_SPACE_STRIDE(t, size);
632:
1.7 sanjayl 633: #if defined (PPC_OEA) && !defined (PPC_OEA64) && !defined (PPC_OEA64_BRIDGE)
1.5 kleink 634: if ((mfpvr() >> 16) != MPC601) {
1.1 matt 635: register_t batu = battable[va >> ADDR_SR_SHFT].batu;
636: if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, va) &&
637: BAT_VA_MATCH_P(batu, va + size - 1)) {
638: pa = va;
1.8 matt 639: va = 0;
1.1 matt 640: } else {
641: pmap_extract(pmap_kernel(), va, &pa);
642: }
1.5 kleink 643: } else {
644: register_t sr = iosrtable[va >> ADDR_SR_SHFT];
1.12 garbled 645: if (SR601_VALID_P(sr) && ((pa >> ADDR_SR_SHFT) ==
646: ((pa + size - 1) >> ADDR_SR_SHFT))) {
1.5 kleink 647: pa = va;
1.8 matt 648: va = 0;
1.5 kleink 649: } else {
650: pmap_extract(pmap_kernel(), va, &pa);
651: }
1.1 matt 652: }
653: #else
654: pmap_extract(pmap_kernel(), va, &pa);
655: #endif
656: bpa = pa - t->pbs_offset;
657:
658: if (extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags)) {
659: printf("memio_unmap: %s 0x%lx, size 0x%lx\n",
660: (t->pbs_flags & _BUS_SPACE_IO_TYPE) ? "port" : "mem",
661: (unsigned long)bpa, (unsigned long)size);
662: printf("memio_unmap: can't free region\n");
663: }
1.8 matt 664:
1.9 freza 665: unmapiodev(va, size);
1.1 matt 666: }
667:
668: int
669: memio_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend,
670: bus_size_t size, bus_size_t alignment, bus_size_t boundary,
671: int flags, bus_addr_t *bpap, bus_space_handle_t *bshp)
672: {
673: u_long bpa;
674: paddr_t pa;
675: int error;
676:
677: size = _BUS_SPACE_STRIDE(t, size);
1.12.4.1 macallan 678: rstart = _BUS_SPACE_STRIDE(t, rstart);
1.1 matt 679:
680: if (rstart + size > t->pbs_limit)
681: return (EINVAL);
682:
683: /*
684: * Can't map I/O space as linear.
685: */
686: if ((flags & BUS_SPACE_MAP_LINEAR) &&
687: (t->pbs_flags & _BUS_SPACE_IO_TYPE))
688: return (EOPNOTSUPP);
689:
690: if (rstart < t->pbs_extent->ex_start || rend > t->pbs_extent->ex_end)
691: panic("memio_alloc: bad region start/end");
692:
693: error = extent_alloc_subregion(t->pbs_extent, rstart, rend, size,
694: alignment, boundary, EX_FAST | EX_NOWAIT | extent_flags, &bpa);
695:
696: if (error)
697: return (error);
698:
699: *bpap = bpa;
700: pa = t->pbs_offset + bpa;
1.7 sanjayl 701: #if defined (PPC_OEA) && !defined (PPC_OEA64) && !defined (PPC_OEA64_BRIDGE)
1.5 kleink 702: if ((mfpvr() >> 16) != MPC601) {
1.1 matt 703: register_t batu = battable[pa >> ADDR_SR_SHFT].batu;
704: if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, pa) &&
705: BAT_VA_MATCH_P(batu, pa + size - 1)) {
706: *bshp = pa;
707: return (0);
708: }
1.5 kleink 709: } else {
710: register_t sr = iosrtable[pa >> ADDR_SR_SHFT];
711: if (SR601_VALID_P(sr) && SR601_PA_MATCH_P(sr, pa) &&
712: SR601_PA_MATCH_P(sr, pa + size - 1)) {
713: *bshp = pa;
714: return (0);
715: }
1.1 matt 716: }
717: #endif
718: *bshp = (bus_space_handle_t) mapiodev(pa, size);
719: if (*bshp == 0) {
720: extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags);
721: return (ENOMEM);
722: }
723:
724: return (0);
725: }
726:
727: void
728: memio_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
729: {
730: /* memio_unmap() does all that we need to do. */
731: memio_unmap(t, bsh, size);
732: }
CVSweb <webmaster@jp.NetBSD.org>