xref: /netbsd/sys/arch/atari/atari/le_bus.c (revision bf9ec67e)
1 /*	$NetBSD: le_bus.c,v 1.5 2000/01/19 13:12:55 leo Exp $	*/
2 
3 /*-
4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Leo Weppelman.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/malloc.h>
42 #include <machine/bswap.h>
43 #include <machine/cpu.h>
44 #include <machine/bus.h>
45 
46 /*
47  * This file contains the common functions for using a litte endian (linear)
48  * bus on a big endian atari.
49  */
50 
51 	/* Autoconf detection stuff */
52 static int		leb_bus_space_peek_1 __P((bus_space_tag_t,
53 				bus_space_handle_t, bus_size_t));
54 static int		leb_bus_space_peek_2 __P((bus_space_tag_t,
55 				bus_space_handle_t, bus_size_t));
56 static int		leb_bus_space_peek_4 __P((bus_space_tag_t,
57 				bus_space_handle_t, bus_size_t));
58 static int		leb_bus_space_peek_8 __P((bus_space_tag_t,
59 				bus_space_handle_t, bus_size_t));
60 
61 	/* read (single) */
62 static u_int8_t		leb_bus_space_read_1 __P((bus_space_tag_t,
63 				bus_space_handle_t, bus_size_t));
64 static u_int16_t	leb_bus_space_read_2 __P((bus_space_tag_t,
65 				bus_space_handle_t, bus_size_t));
66 static u_int32_t	leb_bus_space_read_4 __P((bus_space_tag_t,
67 				bus_space_handle_t, bus_size_t));
68 static u_int64_t	leb_bus_space_read_8 __P((bus_space_tag_t,
69 				bus_space_handle_t, bus_size_t));
70 
71 	/* write (single) */
72 static void		leb_bus_space_write_1 __P((bus_space_tag_t,
73 				bus_space_handle_t, bus_size_t, u_int8_t));
74 static void		leb_bus_space_write_2 __P((bus_space_tag_t,
75 				bus_space_handle_t, bus_size_t, u_int16_t));
76 static void		leb_bus_space_write_4 __P((bus_space_tag_t,
77 				bus_space_handle_t, bus_size_t, u_int32_t));
78 static void		leb_bus_space_write_8 __P((bus_space_tag_t,
79 				bus_space_handle_t, bus_size_t, u_int64_t));
80 
81 	/* read (single) stream */
82 static u_int16_t	leb_bus_space_read_stream_2 __P((bus_space_tag_t,
83 				bus_space_handle_t, bus_size_t));
84 static u_int32_t	leb_bus_space_read_stream_4 __P((bus_space_tag_t,
85 				bus_space_handle_t, bus_size_t));
86 static u_int64_t	leb_bus_space_read_stream_8 __P((bus_space_tag_t,
87 				bus_space_handle_t, bus_size_t));
88 
89 	/* write (single) stream */
90 static void		leb_bus_space_write_stream_2 __P((bus_space_tag_t,
91 				bus_space_handle_t, bus_size_t, u_int16_t));
92 static void		leb_bus_space_write_stream_4 __P((bus_space_tag_t,
93 				bus_space_handle_t, bus_size_t, u_int32_t));
94 static void		leb_bus_space_write_stream_8 __P((bus_space_tag_t,
95 				bus_space_handle_t, bus_size_t, u_int64_t));
96 
97 	/* read multiple */
98 static void		leb_bus_space_read_multi_1 __P((bus_space_tag_t,
99 				bus_space_handle_t, bus_size_t, u_int8_t *,
100 				bus_size_t));
101 static void		leb_bus_space_read_multi_2 __P((bus_space_tag_t,
102 				bus_space_handle_t, bus_size_t, u_int16_t *,
103 				bus_size_t));
104 static void		leb_bus_space_read_multi_4 __P((bus_space_tag_t,
105 				bus_space_handle_t, bus_size_t, u_int32_t *,
106 				bus_size_t));
107 static void		leb_bus_space_read_multi_8 __P((bus_space_tag_t,
108 				bus_space_handle_t, bus_size_t, u_int64_t *,
109 				bus_size_t));
110 
111 	/* write multiple */
112 static void		leb_bus_space_write_multi_1 __P((bus_space_tag_t,
113 				bus_space_handle_t, bus_size_t,
114 				const u_int8_t *, bus_size_t));
115 static void		leb_bus_space_write_multi_2 __P((bus_space_tag_t,
116 				bus_space_handle_t, bus_size_t,
117 				const u_int16_t *, bus_size_t));
118 static void		leb_bus_space_write_multi_4 __P((bus_space_tag_t,
119 				bus_space_handle_t, bus_size_t,
120 				const u_int32_t *, bus_size_t));
121 static void		leb_bus_space_write_multi_8 __P((bus_space_tag_t,
122 				bus_space_handle_t, bus_size_t,
123 				const u_int64_t *, bus_size_t));
124 
125 	/* read multiple stream */
126 static void		leb_bus_space_read_multi_stream_2 __P((bus_space_tag_t,
127 				bus_space_handle_t, bus_size_t, u_int16_t *,
128 				bus_size_t));
129 static void		leb_bus_space_read_multi_stream_4 __P((bus_space_tag_t,
130 				bus_space_handle_t, bus_size_t, u_int32_t *,
131 				bus_size_t));
132 static void		leb_bus_space_read_multi_stream_8 __P((bus_space_tag_t,
133 				bus_space_handle_t, bus_size_t, u_int64_t *,
134 				bus_size_t));
135 
136 	/* write multiple stream */
137 static void		leb_bus_space_write_multi_stream_2 __P((bus_space_tag_t,
138 				bus_space_handle_t, bus_size_t,
139 				const u_int16_t *, bus_size_t));
140 static void		leb_bus_space_write_multi_stream_4 __P((bus_space_tag_t,
141 				bus_space_handle_t, bus_size_t,
142 				const u_int32_t *, bus_size_t));
143 static void		leb_bus_space_write_multi_stream_8 __P((bus_space_tag_t,
144 				bus_space_handle_t, bus_size_t,
145 				const u_int64_t *, bus_size_t));
146 
147 	/* read region */
148 static void		leb_bus_space_read_region_1 __P((bus_space_tag_t,
149 				bus_space_handle_t, bus_size_t, u_int8_t *,
150 				bus_size_t));
151 static void		leb_bus_space_read_region_2 __P((bus_space_tag_t,
152 				bus_space_handle_t, bus_size_t, u_int16_t *,
153 				bus_size_t));
154 static void		leb_bus_space_read_region_4 __P((bus_space_tag_t,
155 				bus_space_handle_t, bus_size_t, u_int32_t *,
156 				bus_size_t));
157 static void		leb_bus_space_read_region_8 __P((bus_space_tag_t,
158 				bus_space_handle_t, bus_size_t, u_int64_t *,
159 				bus_size_t));
160 
161 	/* write region */
162 static void		leb_bus_space_write_region_1 __P((bus_space_tag_t,
163 				bus_space_handle_t, bus_size_t,
164 				const u_int8_t *, bus_size_t));
165 static void		leb_bus_space_write_region_2 __P((bus_space_tag_t,
166 				bus_space_handle_t, bus_size_t,
167 				const u_int16_t *, bus_size_t));
168 static void		leb_bus_space_write_region_4 __P((bus_space_tag_t,
169 				bus_space_handle_t, bus_size_t,
170 				const u_int32_t *, bus_size_t));
171 static void		leb_bus_space_write_region_8 __P((bus_space_tag_t,
172 				bus_space_handle_t, bus_size_t,
173 				const u_int64_t *, bus_size_t));
174 
175 	/* read region stream */
176 static void		leb_bus_space_read_region_stream_2 __P((
177 				bus_space_tag_t, bus_space_handle_t,
178 				bus_size_t, u_int16_t *, bus_size_t));
179 static void		leb_bus_space_read_region_stream_4 __P((
180 				bus_space_tag_t, bus_space_handle_t,
181 				bus_size_t, u_int32_t *, bus_size_t));
182 static void		leb_bus_space_read_region_stream_8 __P((
183 				bus_space_tag_t, bus_space_handle_t,
184 				bus_size_t, u_int64_t *, bus_size_t));
185 
186 	/* write region */
187 static void		leb_bus_space_write_region_stream_2 __P((
188 				bus_space_tag_t, bus_space_handle_t,
189 				bus_size_t, const u_int16_t *, bus_size_t));
190 static void		leb_bus_space_write_region_stream_4 __P((
191 				bus_space_tag_t, bus_space_handle_t,
192 				bus_size_t, const u_int32_t *, bus_size_t));
193 static void		leb_bus_space_write_region_stream_8 __P((
194 				bus_space_tag_t, bus_space_handle_t,
195 				bus_size_t, const u_int64_t *, bus_size_t));
196 
197 	/* set multi */
198 static void		leb_bus_space_set_multi_1 __P((bus_space_tag_t,
199 				bus_space_handle_t, bus_size_t, u_int8_t,
200 				bus_size_t));
201 static void		leb_bus_space_set_multi_2 __P((bus_space_tag_t,
202 				bus_space_handle_t, bus_size_t, u_int16_t,
203 				bus_size_t));
204 static void		leb_bus_space_set_multi_4 __P((bus_space_tag_t,
205 				bus_space_handle_t, bus_size_t, u_int32_t,
206 				bus_size_t));
207 static void		leb_bus_space_set_multi_8 __P((bus_space_tag_t,
208 				bus_space_handle_t, bus_size_t, u_int64_t,
209 				bus_size_t));
210 
211 	/* set region */
212 static void		leb_bus_space_set_region_1 __P((bus_space_tag_t,
213 				bus_space_handle_t, bus_size_t, u_int8_t,
214 				bus_size_t));
215 static void		leb_bus_space_set_region_2 __P((bus_space_tag_t,
216 				bus_space_handle_t, bus_size_t, u_int16_t,
217 				bus_size_t));
218 static void		leb_bus_space_set_region_4 __P((bus_space_tag_t,
219 				bus_space_handle_t, bus_size_t, u_int32_t,
220 				bus_size_t));
221 static void		leb_bus_space_set_region_8 __P((bus_space_tag_t,
222 				bus_space_handle_t, bus_size_t, u_int64_t,
223 				bus_size_t));
224 
225 /*
226  * Define these inline, to avoid function call overhead.
227  * XXX: Maybe move to an m68k include file?
228  */
229 static u_int16_t swap16 __P((u_int16_t v));
230 static u_int32_t swap32 __P((u_int32_t v));
231 
232 static __inline__ u_int16_t swap16(u_int16_t v)
233 {
234 	__asm volatile ("rolw	#8, %0" : "=d"(v) : "0"(v));
235 	return(v);
236 }
237 
238 static __inline__ u_int32_t swap32(u_int32_t v)
239 {
240 	__asm volatile ("	rolw	#8, %0
241 				swap	%0
242 				rolw	#8, %0" : "=d"(v) : "0"(v));
243 	return(v);
244 }
245 
246 /*
247  * Don't force a function call overhead on these primitives...
248  */
249 #define __read_1(h, o)		*((u_int8_t *)((h) + (o)))
250 #define __read_2(h, o)		swap16(*((u_int16_t *)((h) + (o))))
251 #define __read_4(h, o)		swap32(*((u_int32_t *)((h) + (o))))
252 #define __read_8(h, o)		bswap64(*((u_int64_t *)((h) + (o))))
253 
254 #define __write_1(h, o, v)	*((u_int8_t *)((h) + (o))) = (v)
255 #define __write_2(h, o, v)	*((u_int16_t *)((h) + (o))) = swap16(v)
256 #define __write_4(h, o, v)	*((u_int32_t *)((h) + (o))) = swap32(v)
257 #define __write_8(h, o, v)	*((u_int64_t *)((h) + (o))) = bswap64(v)
258 
259 bus_space_tag_t
260 leb_alloc_bus_space_tag(storage)
261 bus_space_tag_t	storage;
262 {
263 	bus_space_tag_t			leb_t;
264 
265 	/*
266 	 * Allow the caller to specify storage space for the tag. This
267 	 * is used during console config (when malloc() can't be used).
268 	 */
269 	if (storage != NULL)
270 		leb_t = storage;
271 	else {
272 	    if ((leb_t = malloc(sizeof(*leb_t), M_TEMP, M_NOWAIT)) == NULL)
273 		return(NULL);
274 	}
275 	bzero(leb_t, sizeof(*leb_t));
276 
277 	leb_t->abs_p_1   = leb_bus_space_peek_1;
278 	leb_t->abs_p_2   = leb_bus_space_peek_2;
279 	leb_t->abs_p_4   = leb_bus_space_peek_4;
280 	leb_t->abs_p_8   = leb_bus_space_peek_8;
281 	leb_t->abs_r_1   = leb_bus_space_read_1;
282 	leb_t->abs_r_2   = leb_bus_space_read_2;
283 	leb_t->abs_r_4   = leb_bus_space_read_4;
284 	leb_t->abs_r_8   = leb_bus_space_read_8;
285 	leb_t->abs_rs_1  = leb_bus_space_read_1;
286 	leb_t->abs_rs_2  = leb_bus_space_read_stream_2;
287 	leb_t->abs_rs_4  = leb_bus_space_read_stream_4;
288 	leb_t->abs_rs_8  = leb_bus_space_read_stream_8;
289 	leb_t->abs_rm_1  = leb_bus_space_read_multi_1;
290 	leb_t->abs_rm_2  = leb_bus_space_read_multi_2;
291 	leb_t->abs_rm_4  = leb_bus_space_read_multi_4;
292 	leb_t->abs_rm_8  = leb_bus_space_read_multi_8;
293 	leb_t->abs_rms_1 = leb_bus_space_read_multi_1;
294 	leb_t->abs_rms_2 = leb_bus_space_read_multi_stream_2;
295 	leb_t->abs_rms_4 = leb_bus_space_read_multi_stream_4;
296 	leb_t->abs_rms_8 = leb_bus_space_read_multi_stream_8;
297 	leb_t->abs_rr_1  = leb_bus_space_read_region_1;
298 	leb_t->abs_rr_2  = leb_bus_space_read_region_2;
299 	leb_t->abs_rr_4  = leb_bus_space_read_region_4;
300 	leb_t->abs_rr_8  = leb_bus_space_read_region_8;
301 	leb_t->abs_rrs_1 = leb_bus_space_read_region_1;
302 	leb_t->abs_rrs_2 = leb_bus_space_read_region_stream_2;
303 	leb_t->abs_rrs_4 = leb_bus_space_read_region_stream_4;
304 	leb_t->abs_rrs_8 = leb_bus_space_read_region_stream_8;
305 	leb_t->abs_w_1   = leb_bus_space_write_1;
306 	leb_t->abs_w_2   = leb_bus_space_write_2;
307 	leb_t->abs_w_4   = leb_bus_space_write_4;
308 	leb_t->abs_w_8   = leb_bus_space_write_8;
309 	leb_t->abs_ws_1  = leb_bus_space_write_1;
310 	leb_t->abs_ws_2  = leb_bus_space_write_stream_2;
311 	leb_t->abs_ws_4  = leb_bus_space_write_stream_4;
312 	leb_t->abs_ws_8  = leb_bus_space_write_stream_8;
313 	leb_t->abs_wm_1  = leb_bus_space_write_multi_1;
314 	leb_t->abs_wm_2  = leb_bus_space_write_multi_2;
315 	leb_t->abs_wm_4  = leb_bus_space_write_multi_4;
316 	leb_t->abs_wm_8  = leb_bus_space_write_multi_8;
317 	leb_t->abs_wms_1 = leb_bus_space_write_multi_1;
318 	leb_t->abs_wms_2 = leb_bus_space_write_multi_stream_2;
319 	leb_t->abs_wms_4 = leb_bus_space_write_multi_stream_4;
320 	leb_t->abs_wms_8 = leb_bus_space_write_multi_stream_8;
321 	leb_t->abs_wr_1  = leb_bus_space_write_region_1;
322 	leb_t->abs_wr_2  = leb_bus_space_write_region_2;
323 	leb_t->abs_wr_4  = leb_bus_space_write_region_4;
324 	leb_t->abs_wr_8  = leb_bus_space_write_region_8;
325 	leb_t->abs_wrs_1 = leb_bus_space_write_region_1;
326 	leb_t->abs_wrs_2 = leb_bus_space_write_region_stream_2;
327 	leb_t->abs_wrs_4 = leb_bus_space_write_region_stream_4;
328 	leb_t->abs_wrs_8 = leb_bus_space_write_region_stream_8;
329 	leb_t->abs_sm_1  = leb_bus_space_set_multi_1;
330 	leb_t->abs_sm_2  = leb_bus_space_set_multi_2;
331 	leb_t->abs_sm_4  = leb_bus_space_set_multi_4;
332 	leb_t->abs_sm_8  = leb_bus_space_set_multi_8;
333 	leb_t->abs_sr_1  = leb_bus_space_set_region_1;
334 	leb_t->abs_sr_2  = leb_bus_space_set_region_2;
335 	leb_t->abs_sr_4  = leb_bus_space_set_region_4;
336 	leb_t->abs_sr_8  = leb_bus_space_set_region_8;
337 
338 	return(leb_t);
339 }
340 
341 
342 /*
343  * The various access functions
344  */
345 
346 /*
347  *	int bus_space_peek_N __P((bus_space_tag_t tag,
348  *		bus_space_handle_t sh, bus_size_t offset));
349  *
350  * Check if the address is suitable for reading N-byte quantities.
351  */
352 static int
353 leb_bus_space_peek_1(t, h, o)
354     bus_space_tag_t	t;
355     bus_space_handle_t	h;
356     bus_size_t		o;
357 {
358     return(!badbaddr((caddr_t)(h + o), 1));
359 }
360 
361 static int
362 leb_bus_space_peek_2(t, h, o)
363     bus_space_tag_t	t;
364     bus_space_handle_t	h;
365     bus_size_t		o;
366 {
367     return(!badbaddr((caddr_t)(h + o), 2));
368 }
369 
370 static int
371 leb_bus_space_peek_4(t, h, o)
372     bus_space_tag_t	t;
373     bus_space_handle_t	h;
374     bus_size_t		o;
375 {
376     return(!badbaddr((caddr_t)(h + o), 4));
377 }
378 
379 static int
380 leb_bus_space_peek_8(t, h, o)
381     bus_space_tag_t	t;
382     bus_space_handle_t	h;
383     bus_size_t		o;
384 {
385     return(!badbaddr((caddr_t)(h + o), 8));
386 }
387 
388 /*
389  *	u_intX_t bus_space_read_N __P((bus_space_tag_t tag,
390  *		bus_space_handle_t bsh, bus_size_t offset));
391  *
392  * Return an 1, 2, 4, or 8 byte value read from the bus_space described
393  * by tag/handle at `offset'. The value is converted to host-endian.
394  */
395 static u_int8_t
396 leb_bus_space_read_1(t, h, o)
397     bus_space_tag_t	t;
398     bus_space_handle_t	h;
399     bus_size_t		o;
400 {
401     return(__read_1(h, o));
402 }
403 
404 static u_int16_t
405 leb_bus_space_read_2(t, h, o)
406     bus_space_tag_t	t;
407     bus_space_handle_t	h;
408     bus_size_t		o;
409 {
410     return(__read_2(h, o));
411 }
412 
413 static u_int32_t
414 leb_bus_space_read_4(t, h, o)
415     bus_space_tag_t	t;
416     bus_space_handle_t	h;
417     bus_size_t		o;
418 {
419     return(__read_4(h, o));
420 }
421 
422 static u_int64_t
423 leb_bus_space_read_8(t, h, o)
424     bus_space_tag_t	t;
425     bus_space_handle_t	h;
426     bus_size_t		o;
427 {
428     return(__read_8(h, o));
429 }
430 
431 /*
432  *	u_intX_t bus_space_write_N __P((bus_space_tag_t tag,
433  *		bus_space_handle_t bsh, bus_size_t offset, u_intX_t val));
434  *
435  * Write an 1, 2, 4, or 8 byte value to the bus_space described by tag/handle
436  * at `offset'. The value `val' is converted from host to bus endianness
437  * before being written.
438  */
439 static void
440 leb_bus_space_write_1(t, h, o, v)
441     bus_space_tag_t	t;
442     bus_space_handle_t	h;
443     bus_size_t		o;
444     u_int8_t		v;
445 {
446     __write_1(h, o, v);
447 }
448 
449 static void
450 leb_bus_space_write_2(t, h, o, v)
451     bus_space_tag_t	t;
452     bus_space_handle_t	h;
453     bus_size_t		o;
454     u_int16_t		v;
455 {
456     __write_2(h, o, v);
457 }
458 
459 static void
460 leb_bus_space_write_4(t, h, o, v)
461     bus_space_tag_t	t;
462     bus_space_handle_t	h;
463     bus_size_t		o;
464     u_int32_t		v;
465 {
466     __write_4(h, o, v);
467 }
468 
469 static void
470 leb_bus_space_write_8(t, h, o, v)
471     bus_space_tag_t	t;
472     bus_space_handle_t	h;
473     bus_size_t		o;
474     u_int64_t		v;
475 {
476     __write_8(h, o, v);
477 }
478 
479 /*
480  *	u_intX_t bus_space_read_stream_N __P((bus_space_tag_t tag,
481  *		bus_space_handle_t bsh, bus_size_t offset));
482  *
483  * Return an 1, 2, 4, or 8 byte value read from the bus_space described
484  * by tag/handle at `offset'. No endian conversion is done.
485  */
486 static u_int16_t
487 leb_bus_space_read_stream_2(t, h, o)
488 	bus_space_tag_t		t;
489 	bus_space_handle_t	h;
490 	bus_size_t		o;
491 {
492 	return(*((u_int16_t *)(h + o)));
493 }
494 
495 static u_int32_t
496 leb_bus_space_read_stream_4(t, h, o)
497 	bus_space_tag_t		t;
498 	bus_space_handle_t	h;
499 	bus_size_t		o;
500 {
501 	return(*((u_int32_t *)(h + o)));
502 }
503 
504 static u_int64_t
505 leb_bus_space_read_stream_8(t, h, o)
506 	bus_space_tag_t		t;
507 	bus_space_handle_t	h;
508 	bus_size_t		o;
509 {
510 	return(*((u_int64_t *)(h + o)));
511 }
512 
513 /*
514  *	u_intX_t bus_space_write_stream_N __P((bus_space_tag_t tag,
515  *		bus_space_handle_t bsh, bus_size_t offset, u_intX_t val));
516  *
517  * Write an 1, 2, 4, or 8 byte value to the bus_space described by tag/handle
518  * at `offset'. No endian conversion is done.
519  */
520 static void
521 leb_bus_space_write_stream_2(t, h, o, v)
522 	bus_space_tag_t		t;
523 	bus_space_handle_t	h;
524 	bus_size_t		o;
525 	u_int16_t		v;
526 {
527 	*((u_int16_t *)(h + o)) = v;
528 }
529 
530 static void
531 leb_bus_space_write_stream_4(t, h, o, v)
532 	bus_space_tag_t		t;
533 	bus_space_handle_t	h;
534 	bus_size_t		o;
535 	u_int32_t		v;
536 {
537 	*((u_int32_t *)(h + o)) = v;
538 }
539 
540 static void
541 leb_bus_space_write_stream_8(t, h, o, v)
542 	bus_space_tag_t		t;
543 	bus_space_handle_t	h;
544 	bus_size_t		o;
545 	u_int64_t		v;
546 {
547 	*((u_int64_t *)(h + o)) = v;
548 }
549 
550 /*
551  *	void bus_space_read_multi_N __P((bus_space_tag_t tag,
552  *		bus_space_handle_t bsh, bus_size_t offset, u_intX_t *address,
553  *	 	bus_size_t count));
554  *
555  * Read 'count' 1, 2, 4, or 8 byte values from the bus_space described by
556  * tag/handle at `offset' and store them in the address range starting at
557  * 'address'. The values are converted to cpu endian order before being
558  * being stored.
559  */
560 static void
561 leb_bus_space_read_multi_1(t, h, o, a, c)
562 	bus_space_tag_t		t;
563 	bus_space_handle_t	h;
564 	bus_size_t		o, c;
565 	u_int8_t		*a;
566 {
567 	for (; c; a++, c--)
568 		*a = __read_1(h, o);
569 }
570 static void
571 leb_bus_space_read_multi_2(t, h, o, a, c)
572 	bus_space_tag_t		t;
573 	bus_space_handle_t	h;
574 	bus_size_t		o, c;
575 	u_int16_t		*a;
576 {
577 	for (; c; a++, c--)
578 		*a = __read_2(h, o);
579 }
580 
581 static void
582 leb_bus_space_read_multi_4(t, h, o, a, c)
583 	bus_space_tag_t		t;
584 	bus_space_handle_t	h;
585 	bus_size_t		o, c;
586 	u_int32_t		*a;
587 {
588 	for (; c; a++, c--)
589 		*a = __read_4(h, o);
590 }
591 
592 static void
593 leb_bus_space_read_multi_8(t, h, o, a, c)
594 	bus_space_tag_t		t;
595 	bus_space_handle_t	h;
596 	bus_size_t		o, c;
597 	u_int64_t		*a;
598 {
599 	for (; c; a++, c--)
600 		*a = __read_8(h, o);
601 }
602 
603 /*
604  *	void bus_space_write_multi_N __P((bus_space_tag_t tag,
605  *		bus_space_handle_t bsh, bus_size_t offset,
606  *		const u_intX_t *address, bus_size_t count));
607  *
608  * Write 'count' 1, 2, 4, or 8 byte values from the address range starting
609  * at 'address' to the bus_space described by tag/handle at `offset'.
610  * The values are converted to bus endian order before being written to
611  * the bus.
612  */
613 static void
614 leb_bus_space_write_multi_1(t, h, o, a, c)
615 	bus_space_tag_t		t;
616 	bus_space_handle_t	h;
617 	bus_size_t		o, c;
618 	const u_int8_t		*a;
619 {
620 	for (; c; a++, c--)
621 		__write_1(h, o, *a);
622 }
623 
624 static void
625 leb_bus_space_write_multi_2(t, h, o, a, c)
626 	bus_space_tag_t		t;
627 	bus_space_handle_t	h;
628 	bus_size_t		o, c;
629 	const u_int16_t		*a;
630 {
631 	for (; c; a++, c--)
632 		__write_2(h, o, *a);
633 }
634 
635 static void
636 leb_bus_space_write_multi_4(t, h, o, a, c)
637 	bus_space_tag_t		t;
638 	bus_space_handle_t	h;
639 	bus_size_t		o, c;
640 	const u_int32_t		*a;
641 {
642 	for (; c; a++, c--)
643 		__write_4(h, o, *a);
644 }
645 
646 static void
647 leb_bus_space_write_multi_8(t, h, o, a, c)
648 	bus_space_tag_t		t;
649 	bus_space_handle_t	h;
650 	bus_size_t		o, c;
651 	const u_int64_t		*a;
652 {
653 	for (; c; a++, c--)
654 		__write_8(h, o, *a);
655 }
656 
657 /*
658  *	void bus_space_read_multi_stream_N __P((bus_space_tag_t tag,
659  *		bus_space_handle_t bsh, bus_size_t offset, u_intX_t *address,
660  *	 	bus_size_t count));
661  *
662  * Read 'count' 1, 2, 4, or 8 byte values from the bus_space described by
663  * tag/handle at `offset' and store them in the address range starting at
664  * 'address'. No endian conversion is being done.
665  */
666 static void
667 leb_bus_space_read_multi_stream_2(t, h, o, a, c)
668 	bus_space_tag_t		t;
669 	bus_space_handle_t	h;
670 	bus_size_t		o, c;
671 	u_int16_t		*a;
672 {
673 	for (; c; a++, c--)
674 		*a = *((u_int16_t *)(h + o));
675 }
676 
677 static void
678 leb_bus_space_read_multi_stream_4(t, h, o, a, c)
679 	bus_space_tag_t		t;
680 	bus_space_handle_t	h;
681 	bus_size_t		o, c;
682 	u_int32_t		*a;
683 {
684 	for (; c; a++, c--)
685 		*a = *((u_int32_t *)(h + o));
686 }
687 
688 static void
689 leb_bus_space_read_multi_stream_8(t, h, o, a, c)
690 	bus_space_tag_t		t;
691 	bus_space_handle_t	h;
692 	bus_size_t		o, c;
693 	u_int64_t		*a;
694 {
695 	for (; c; a++, c--)
696 		*a = *((u_int64_t *)(h + o));
697 }
698 
699 /*
700  *	void bus_space_write_multi_stream_N __P((bus_space_tag_t tag,
701  *		bus_space_handle_t bsh, bus_size_t offset,
702  *		const u_intX_t *address, bus_size_t count));
703  *
704  * Write 'count' 1, 2, 4, or 8 byte values from the address range starting
705  * at 'address' to the bus_space described by tag/handle at `offset'.
706  * No endian conversion is being done.
707  */
708 static void
709 leb_bus_space_write_multi_stream_2(t, h, o, a, c)
710 	bus_space_tag_t		t;
711 	bus_space_handle_t	h;
712 	bus_size_t		o, c;
713 	const u_int16_t		*a;
714 {
715 	for (; c; a++, c--)
716 		*((u_int16_t *)(h + o)) = *a;
717 }
718 
719 static void
720 leb_bus_space_write_multi_stream_4(t, h, o, a, c)
721 	bus_space_tag_t		t;
722 	bus_space_handle_t	h;
723 	bus_size_t		o, c;
724 	const u_int32_t		*a;
725 {
726 	for (; c; a++, c--)
727 		*((u_int32_t *)(h + o)) = *a;
728 }
729 
730 static void
731 leb_bus_space_write_multi_stream_8(t, h, o, a, c)
732 	bus_space_tag_t		t;
733 	bus_space_handle_t	h;
734 	bus_size_t		o, c;
735 	const u_int64_t		*a;
736 {
737 	for (; c; a++, c--)
738 		*((u_int64_t *)(h + o)) = *a;
739 }
740 
741 /*
742  *	void bus_space_read_region_N __P((bus_space_tag_t tag,
743  *		bus_space_handle_t bsh, bus_size_t offset,
744  *		u_intN_t *addr, bus_size_t count));
745  *
746  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
747  * described by tag/handle and starting at `offset' and copy into
748  * buffer provided.
749  */
750 static void
751 leb_bus_space_read_region_1(t, h, o, a, c)
752 	bus_space_tag_t		t;
753 	bus_space_handle_t	h;
754 	bus_size_t		o, c;
755 	u_int8_t		*a;
756 {
757 	for (; c; a++, o++, c--)
758 		*a = __read_1(h, o);
759 }
760 
761 static void
762 leb_bus_space_read_region_2(t, h, o, a, c)
763 	bus_space_tag_t		t;
764 	bus_space_handle_t	h;
765 	bus_size_t		o, c;
766 	u_int16_t		*a;
767 {
768 	for (; c; a++, o += 2, c--)
769 		*a = __read_2(h, o);
770 }
771 
772 static void
773 leb_bus_space_read_region_4(t, h, o, a, c)
774 	bus_space_tag_t		t;
775 	bus_space_handle_t	h;
776 	bus_size_t		o, c;
777 	u_int32_t		*a;
778 {
779 	for (; c; a++, o += 4, c--)
780 		*a = __read_4(h, o);
781 }
782 
783 static void
784 leb_bus_space_read_region_8(t, h, o, a, c)
785 	bus_space_tag_t		t;
786 	bus_space_handle_t	h;
787 	bus_size_t		o, c;
788 	u_int64_t		*a;
789 {
790 	for (; c; a++, o += 8, c--)
791 		*a = __read_8(h, o);
792 }
793 
794 /*
795  *	void bus_space_write_region_N __P((bus_space_tag_t tag,
796  *		bus_space_handle_t bsh, bus_size_t offset,
797  *		u_intN_t *addr, bus_size_t count));
798  *
799  * Copy `count' 1, 2, 4, or 8 byte quantities from the buffer provided
800  * into the bus space described by tag/handle and starting at `offset'.
801  */
802 static void
803 leb_bus_space_write_region_1(t, h, o, a, c)
804 	bus_space_tag_t		t;
805 	bus_space_handle_t	h;
806 	bus_size_t		o, c;
807 	const u_int8_t		*a;
808 {
809 	for (; c; a++, o++, c--)
810 		__write_1(h, o, *a);
811 }
812 
813 static void
814 leb_bus_space_write_region_2(t, h, o, a, c)
815 	bus_space_tag_t		t;
816 	bus_space_handle_t	h;
817 	bus_size_t		o, c;
818 	const u_int16_t		*a;
819 {
820 	for (; c; a++, o += 2, c--)
821 		__write_2(h, o, *a);
822 }
823 
824 static void
825 leb_bus_space_write_region_4(t, h, o, a, c)
826 	bus_space_tag_t		t;
827 	bus_space_handle_t	h;
828 	bus_size_t		o, c;
829 	const u_int32_t		*a;
830 {
831 	for (; c; a++, o += 4, c--)
832 		__write_4(h, o, *a);
833 }
834 
835 static void
836 leb_bus_space_write_region_8(t, h, o, a, c)
837 	bus_space_tag_t		t;
838 	bus_space_handle_t	h;
839 	bus_size_t		o, c;
840 	const u_int64_t		*a;
841 {
842 	for (; c; a++, o += 8, c--)
843 		__write_8(h, o, *a);
844 }
845 
846 /*
847  *	void bus_space_read_region_stream_N __P((bus_space_tag_t tag,
848  *		bus_space_handle_t bsh, bus_size_t offset,
849  *		u_intN_t *addr, bus_size_t count));
850  *
851  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
852  * described by tag/handle and starting at `offset' and copy into
853  * buffer provided.
854  * No endian conversion is being done.
855  */
856 static void
857 leb_bus_space_read_region_stream_2(t, h, o, a, c)
858 	bus_space_tag_t		t;
859 	bus_space_handle_t	h;
860 	bus_size_t		o, c;
861 	u_int16_t		*a;
862 {
863 	for (; c; a++, o += 2, c--)
864 		*a = *(u_int16_t *)(h + o);
865 }
866 
867 static void
868 leb_bus_space_read_region_stream_4(t, h, o, a, c)
869 	bus_space_tag_t		t;
870 	bus_space_handle_t	h;
871 	bus_size_t		o, c;
872 	u_int32_t		*a;
873 {
874 	for (; c; a++, o += 4, c--)
875 		*a = *(u_int32_t *)(h + o);
876 }
877 
878 static void
879 leb_bus_space_read_region_stream_8(t, h, o, a, c)
880 	bus_space_tag_t		t;
881 	bus_space_handle_t	h;
882 	bus_size_t		o, c;
883 	u_int64_t		*a;
884 {
885 	for (; c; a++, o += 8, c--)
886 		*a = *(u_int64_t *)(h + o);
887 }
888 
889 /*
890  *	void bus_space_write_region_stream_N __P((bus_space_tag_t tag,
891  *		bus_space_handle_t bsh, bus_size_t offset,
892  *		u_intN_t *addr, bus_size_t count));
893  *
894  * Copy `count' 1, 2, 4, or 8 byte quantities from the buffer provided
895  * into the bus space described by tag/handle and starting at `offset'.
896  * No endian conversion is being done.
897  */
898 static void
899 leb_bus_space_write_region_stream_2(t, h, o, a, c)
900 	bus_space_tag_t		t;
901 	bus_space_handle_t	h;
902 	bus_size_t		o, c;
903 	const u_int16_t		*a;
904 {
905 	for (; c; a++, o += 2, c--)
906 		*((u_int16_t *)(h + o)) = *a;
907 }
908 
909 static void
910 leb_bus_space_write_region_stream_4(t, h, o, a, c)
911 	bus_space_tag_t		t;
912 	bus_space_handle_t	h;
913 	bus_size_t		o, c;
914 	const u_int32_t		*a;
915 {
916 	for (; c; a++, o += 4, c--)
917 		*((u_int32_t *)(h + o)) = *a;
918 }
919 
920 static void
921 leb_bus_space_write_region_stream_8(t, h, o, a, c)
922 	bus_space_tag_t		t;
923 	bus_space_handle_t	h;
924 	bus_size_t		o, c;
925 	const u_int64_t		*a;
926 {
927 	for (; c; a++, o += 8, c--)
928 		*((u_int64_t *)(h + o)) = *a;
929 }
930 
931 /*
932  *	void bus_space_set_multi_N __P((bus_space_tag_t tag,
933  *		bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
934  *		bus_size_t count));
935  *
936  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
937  * by tag/handle/offset `count' times.
938  */
939 
940 static void
941 leb_bus_space_set_multi_1(t, h, o, v, c)
942 	bus_space_tag_t		t;
943 	bus_space_handle_t	h;
944 	bus_size_t		o, c;
945 	u_int8_t		v;
946 {
947 	for (; c; c--)
948 		__write_1(h, o, v);
949 }
950 
951 static void
952 leb_bus_space_set_multi_2(t, h, o, v, c)
953 	bus_space_tag_t		t;
954 	bus_space_handle_t	h;
955 	bus_size_t		o, c;
956 	u_int16_t		v;
957 {
958 	v = swap16(v);
959 	for (; c; c--)
960 		*((u_int16_t *)(h + o)) = v;
961 }
962 
963 static void
964 leb_bus_space_set_multi_4(t, h, o, v, c)
965 	bus_space_tag_t		t;
966 	bus_space_handle_t	h;
967 	bus_size_t		o, c;
968 	u_int32_t		v;
969 {
970 	v = swap32(v);
971 	for (; c; c--)
972 		*((u_int32_t *)(h + o)) = v;
973 }
974 
975 static void
976 leb_bus_space_set_multi_8(t, h, o, v, c)
977 	bus_space_tag_t		t;
978 	bus_space_handle_t	h;
979 	bus_size_t		o, c;
980 	u_int64_t		v;
981 {
982 	v = bswap64(v);
983 	for (; c; c--)
984 		*((u_int64_t *)(h + o)) = v;
985 }
986 
987 /*
988  *	void bus_space_set_region_N __P((bus_space_tag_t tag,
989  *		bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
990  *		bus_size_t count));
991  *
992  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
993  * by tag/handle starting at `offset'.
994  */
995 static void
996 leb_bus_space_set_region_1(t, h, o, v, c)
997 	bus_space_tag_t		t;
998 	bus_space_handle_t	h;
999 	bus_size_t		o, c;
1000 	u_int8_t		v;
1001 {
1002 	for (; c; o++, c--)
1003 		__write_1(h, o, v);
1004 }
1005 
1006 static void
1007 leb_bus_space_set_region_2(t, h, o, v, c)
1008 	bus_space_tag_t		t;
1009 	bus_space_handle_t	h;
1010 	bus_size_t		o, c;
1011 	u_int16_t		v;
1012 {
1013 	v = swap16(v);
1014 	for (; c; o += 2, c--)
1015 		*((u_int16_t *)(h + o)) = v;
1016 }
1017 
1018 static void
1019 leb_bus_space_set_region_4(t, h, o, v, c)
1020 	bus_space_tag_t		t;
1021 	bus_space_handle_t	h;
1022 	bus_size_t		o, c;
1023 	u_int32_t		v;
1024 {
1025 	v = swap32(v);
1026 	for (; c; o += 4, c--)
1027 		*((u_int32_t *)(h + o)) = v;
1028 }
1029 
1030 static void
1031 leb_bus_space_set_region_8(t, h, o, v, c)
1032 	bus_space_tag_t		t;
1033 	bus_space_handle_t	h;
1034 	bus_size_t		o, c;
1035 	u_int64_t		v;
1036 {
1037 	v = bswap64(v);
1038 	for (; c; o += 8, c--)
1039 		*((u_int64_t *)(h + o)) = v;
1040 }
1041