1 /* $NetBSD: bus_space_alignstride_chipdep.c,v 1.12 2009/12/15 06:07:14 rmind Exp $ */
2 
3 /*-
4  * Copyright (c) 1998, 2000, 2001 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  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
35  * All rights reserved.
36  *
37  * Author: Chris G. Demetriou
38  *
39  * Permission to use, copy, modify and distribute this software and
40  * its documentation is hereby granted, provided that both the copyright
41  * notice and this permission notice appear in all copies of the
42  * software, derivative works or modified versions, and any portions
43  * thereof, and that both notices appear in supporting documentation.
44  *
45  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
46  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
47  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
48  *
49  * Carnegie Mellon requests users of this software to return to
50  *
51  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
52  *  School of Computer Science
53  *  Carnegie Mellon University
54  *  Pittsburgh PA 15213-3890
55  *
56  * any improvements or extensions that they make and grant Carnegie the
57  * rights to redistribute these changes.
58  */
59 
60 /*
61  * Common Chipset "bus I/O" functions.
62  *
63  * uses:
64  *	CHIP		name of the 'chip' it's being compiled for.
65  *	CHIP_BASE	memory or I/O space base to use.
66  *	CHIP_EX_STORE
67  *			If defined, device-provided static storage area
68  *			for the memory or I/O space extent.  If this is
69  *			defined, CHIP_EX_STORE_SIZE must also be defined.
70  *			If this is not defined, a static area will be
71  *			declared.
72  *	CHIP_EX_STORE_SIZE
73  *			Size of the device-provided static storage area
74  *			for the memory or I/O memory space extent.
75  *	CHIP_LITTLE_ENDIAN | CHIP_BIG_ENDIAN
76  *			For endian-specific busses, like PCI (little).
77  *	CHIP_ACCESS_SIZE
78  *			Size (in bytes) of minimum bus access, e.g. 4
79  *			to indicate all bus cycles are 32-bits.  Defaults
80  *			to 1, indicating any access size is valid.
81  */
82 
83 #include <sys/cdefs.h>
84 __KERNEL_RCSID(0, "$NetBSD: bus_space_alignstride_chipdep.c,v 1.12 2009/12/15 06:07:14 rmind Exp $");
85 
86 #ifdef CHIP_EXTENT
87 #include <sys/extent.h>
88 #endif
89 #include <sys/malloc.h>
90 
91 #include <machine/locore.h>
92 
93 #include <uvm/uvm_extern.h>
94 
95 #define	__C(A,B)	__CONCAT(A,B)
96 #define	__S(S)		__STRING(S)
97 
98 #ifdef CHIP_IO
99 #define	__BS(A)		__C(__C(CHIP,_bus_io_),A)
100 #endif
101 #ifdef CHIP_MEM
102 #define	__BS(A)		__C(__C(CHIP,_bus_mem_),A)
103 #endif
104 
105 #if defined(CHIP_LITTLE_ENDIAN)
106 #define	CHIP_SWAP16(x)	le16toh(x)
107 #define	CHIP_SWAP32(x)	le32toh(x)
108 #define	CHIP_SWAP64(x)	le64toh(x)
109 #define	CHIP_NEED_STREAM	1
110 #elif defined(CHIP_BIG_ENDIAN)
111 #define	CHIP_SWAP16(x)	be16toh(x)
112 #define	CHIP_SWAP32(x)	be32toh(x)
113 #define	CHIP_SWAP64(x)	be64toh(x)
114 #define	CHIP_NEED_STREAM	1
115 #else
116 #define	CHIP_SWAP16(x)	(x)
117 #define	CHIP_SWAP32(x)	(x)
118 #define	CHIP_SWAP64(x)	(x)
119 #endif
120 
121 #ifndef	CHIP_ACCESS_SIZE
122 #define	CHIP_ACCESS_SIZE	1
123 #endif
124 
125 #if CHIP_ACCESS_SIZE==1
126 # define CHIP_SWAP_ACCESS(x)	(x)
127 #elif CHIP_ACCESS_SIZE==2
128 # define CHIP_SWAP_ACCESS(x)	CHIP_SWAP16(x)
129 #elif CHIP_ACCESS_SIZE==4
130 # define CHIP_SWAP_ACCESS(x)	CHIP_SWAP32(x)
131 #elif CHIP_ACCESS_SIZE==8
132 # define CHIP_SWAP_ACCESS(x)	CHIP_SWAP64(x)
133 #else
134 # error your access size not implemented
135 #endif
136 
137 /*
138  * The logic here determines a few macros to support requirements for
139  * whole-word accesses:
140  *
141  * CHIP_TYPE is a uintXX_t that represents the native access type for the bus.
142  *
143  * CHIP_SHIFTXX is the number of bits to shift a big-endian value to convert
144  * convert between the CHIP_TYPE and uintXX_t.
145  *
146  * The idea is that if we want to do a 16bit load from a bus that only
147  * supports 32-bit accesses, we will access the first 16 bits of the
148  * addressed 32-bit word.
149  *
150  * Obviously (hopefully) this method is inadequate to support addressing the
151  * second half of a 16-bit word, or the upper 3/4 of a 32-bit value, etc.
152  * In other words, the drivers should probably not be relying on this!
153  *
154  * We should probably come back in here some day and handle offsets properly.
155  * to do that, we need to mask off the low order bits of the address, and
156  * then figure out which bits they correspond to.
157  *
158  * If we have fixed access size limitations, we need to make sure that
159  * handle shifting required for big-endian storage.  The reality is
160  * that if the bus only supports size "n", then drivers should
161  * probably only access it using "n" sized (or bigger) accesses.
162  */
163 
164 #if	CHIP_ACCESS_SIZE == 1
165 #define	CHIP_TYPE	uint8_t
166 #endif
167 
168 #if	CHIP_ACCESS_SIZE == 2
169 #define	CHIP_TYPE	uint16_t
170 #endif
171 
172 #if	CHIP_ACCESS_SIZE == 4
173 #define	CHIP_TYPE	uint32_t
174 #endif
175 
176 #if	CHIP_ACCESS_SIZE == 8
177 #define	CHIP_TYPE	uint64_t
178 #endif
179 
180 #ifndef CHIP_TYPE
181 #error	"Invalid chip access size!"
182 #endif
183 
184 /* mapping/unmapping */
185 int		__BS(map)(void *, bus_addr_t, bus_size_t, int,
186 		    bus_space_handle_t *, int);
187 void		__BS(unmap)(void *, bus_space_handle_t, bus_size_t, int);
188 int		__BS(subregion)(void *, bus_space_handle_t, bus_size_t,
189 		    bus_size_t, bus_space_handle_t *);
190 
191 int		__BS(translate)(void *, bus_addr_t, bus_size_t, int,
192 		    struct mips_bus_space_translation *);
193 int		__BS(get_window)(void *, int,
194 		    struct mips_bus_space_translation *);
195 
196 /* allocation/deallocation */
197 int		__BS(alloc)(void *, bus_addr_t, bus_addr_t, bus_size_t,
198 		    bus_size_t, bus_addr_t, int, bus_addr_t *,
199 		    bus_space_handle_t *);
200 void		__BS(free)(void *, bus_space_handle_t, bus_size_t);
201 
202 /* get kernel virtual address */
203 void *		__BS(vaddr)(void *, bus_space_handle_t);
204 
205 /* mmap for user */
206 paddr_t		__BS(mmap)(void *, bus_addr_t, off_t, int, int);
207 
208 /* barrier */
209 inline void	__BS(barrier)(void *, bus_space_handle_t, bus_size_t,
210 		    bus_size_t, int);
211 
212 /* read (single) */
213 inline uint8_t	__BS(read_1)(void *, bus_space_handle_t, bus_size_t);
214 inline uint16_t	__BS(read_2)(void *, bus_space_handle_t, bus_size_t);
215 inline uint32_t	__BS(read_4)(void *, bus_space_handle_t, bus_size_t);
216 inline uint64_t	__BS(read_8)(void *, bus_space_handle_t, bus_size_t);
217 
218 /* read multiple */
219 void		__BS(read_multi_1)(void *, bus_space_handle_t, bus_size_t,
220 		    uint8_t *, bus_size_t);
221 void		__BS(read_multi_2)(void *, bus_space_handle_t, bus_size_t,
222 		    uint16_t *, bus_size_t);
223 void		__BS(read_multi_4)(void *, bus_space_handle_t, bus_size_t,
224 		    uint32_t *, bus_size_t);
225 void		__BS(read_multi_8)(void *, bus_space_handle_t, bus_size_t,
226 		    uint64_t *, bus_size_t);
227 
228 /* read region */
229 void		__BS(read_region_1)(void *, bus_space_handle_t, bus_size_t,
230 		    uint8_t *, bus_size_t);
231 void		__BS(read_region_2)(void *, bus_space_handle_t, bus_size_t,
232 		    uint16_t *, bus_size_t);
233 void		__BS(read_region_4)(void *, bus_space_handle_t, bus_size_t,
234 		    uint32_t *, bus_size_t);
235 void		__BS(read_region_8)(void *, bus_space_handle_t, bus_size_t,
236 		    uint64_t *, bus_size_t);
237 
238 /* write (single) */
239 inline void	__BS(write_1)(void *, bus_space_handle_t, bus_size_t, uint8_t);
240 inline void	__BS(write_2)(void *, bus_space_handle_t, bus_size_t, uint16_t);
241 inline void	__BS(write_4)(void *, bus_space_handle_t, bus_size_t, uint32_t);
242 inline void	__BS(write_8)(void *, bus_space_handle_t, bus_size_t, uint64_t);
243 
244 /* write multiple */
245 void		__BS(write_multi_1)(void *, bus_space_handle_t, bus_size_t,
246 		    const uint8_t *, bus_size_t);
247 void		__BS(write_multi_2)(void *, bus_space_handle_t, bus_size_t,
248 		    const uint16_t *, bus_size_t);
249 void		__BS(write_multi_4)(void *, bus_space_handle_t, bus_size_t,
250 		    const uint32_t *, bus_size_t);
251 void		__BS(write_multi_8)(void *, bus_space_handle_t, bus_size_t,
252 		    const uint64_t *, bus_size_t);
253 
254 /* write region */
255 void		__BS(write_region_1)(void *, bus_space_handle_t, bus_size_t,
256 		    const uint8_t *, bus_size_t);
257 void		__BS(write_region_2)(void *, bus_space_handle_t, bus_size_t,
258 		    const uint16_t *, bus_size_t);
259 void		__BS(write_region_4)(void *, bus_space_handle_t, bus_size_t,
260 		    const uint32_t *, bus_size_t);
261 void		__BS(write_region_8)(void *, bus_space_handle_t, bus_size_t,
262 		    const uint64_t *, bus_size_t);
263 
264 /* set multiple */
265 void		__BS(set_multi_1)(void *, bus_space_handle_t, bus_size_t,
266 		    uint8_t, bus_size_t);
267 void		__BS(set_multi_2)(void *, bus_space_handle_t, bus_size_t,
268 		    uint16_t, bus_size_t);
269 void		__BS(set_multi_4)(void *, bus_space_handle_t, bus_size_t,
270 		    uint32_t, bus_size_t);
271 void		__BS(set_multi_8)(void *, bus_space_handle_t, bus_size_t,
272 		    uint64_t, bus_size_t);
273 
274 /* set region */
275 void		__BS(set_region_1)(void *, bus_space_handle_t, bus_size_t,
276 		    uint8_t, bus_size_t);
277 void		__BS(set_region_2)(void *, bus_space_handle_t, bus_size_t,
278 		    uint16_t, bus_size_t);
279 void		__BS(set_region_4)(void *, bus_space_handle_t, bus_size_t,
280 		    uint32_t, bus_size_t);
281 void		__BS(set_region_8)(void *, bus_space_handle_t, bus_size_t,
282 		    uint64_t, bus_size_t);
283 
284 /* copy */
285 void		__BS(copy_region_1)(void *, bus_space_handle_t, bus_size_t,
286 		    bus_space_handle_t, bus_size_t, bus_size_t);
287 void		__BS(copy_region_2)(void *, bus_space_handle_t, bus_size_t,
288 		    bus_space_handle_t, bus_size_t, bus_size_t);
289 void		__BS(copy_region_4)(void *, bus_space_handle_t, bus_size_t,
290 		    bus_space_handle_t, bus_size_t, bus_size_t);
291 void		__BS(copy_region_8)(void *, bus_space_handle_t, bus_size_t,
292 		    bus_space_handle_t, bus_size_t, bus_size_t);
293 
294 #ifdef	CHIP_NEED_STREAM
295 
296 /* read (single), stream */
297 inline uint8_t	__BS(read_stream_1)(void *, bus_space_handle_t, bus_size_t);
298 inline uint16_t	__BS(read_stream_2)(void *, bus_space_handle_t, bus_size_t);
299 inline uint32_t	__BS(read_stream_4)(void *, bus_space_handle_t, bus_size_t);
300 inline uint64_t	__BS(read_stream_8)(void *, bus_space_handle_t, bus_size_t);
301 
302 /* read multiple, stream */
303 void	__BS(read_multi_stream_1)(void *, bus_space_handle_t, bus_size_t,
304 			   uint8_t *, bus_size_t);
305 void	__BS(read_multi_stream_2)(void *, bus_space_handle_t, bus_size_t,
306 				  uint16_t *, bus_size_t);
307 void	__BS(read_multi_stream_4)(void *, bus_space_handle_t, bus_size_t,
308 				  uint32_t *, bus_size_t);
309 void	__BS(read_multi_stream_8)(void *, bus_space_handle_t, bus_size_t,
310 				  uint64_t *, bus_size_t);
311 
312 /* read region, stream */
313 void	__BS(read_region_stream_1)(void *, bus_space_handle_t, bus_size_t,
314 				   uint8_t *, bus_size_t);
315 void	__BS(read_region_stream_2)(void *, bus_space_handle_t, bus_size_t,
316 				   uint16_t *, bus_size_t);
317 void	__BS(read_region_stream_4)(void *, bus_space_handle_t, bus_size_t,
318 				   uint32_t *, bus_size_t);
319 void	__BS(read_region_stream_8)(void *, bus_space_handle_t, bus_size_t,
320 				   uint64_t *, bus_size_t);
321 
322 /* write (single), stream */
323 inline void	__BS(write_stream_1)(void *, bus_space_handle_t, bus_size_t, uint8_t);
324 inline void	__BS(write_stream_2)(void *, bus_space_handle_t, bus_size_t, uint16_t);
325 inline void	__BS(write_stream_4)(void *, bus_space_handle_t, bus_size_t, uint32_t);
326 inline void	__BS(write_stream_8)(void *, bus_space_handle_t, bus_size_t, uint64_t);
327 
328 /* write multiple, stream */
329 void	__BS(write_multi_stream_1)(void *, bus_space_handle_t, bus_size_t,
330 				   const uint8_t *, bus_size_t);
331 void	__BS(write_multi_stream_2)(void *, bus_space_handle_t, bus_size_t,
332 				   const uint16_t *, bus_size_t);
333 void	__BS(write_multi_stream_4)(void *, bus_space_handle_t, bus_size_t,
334 				   const uint32_t *, bus_size_t);
335 void	__BS(write_multi_stream_8)(void *, bus_space_handle_t, bus_size_t,
336 				   const uint64_t *, bus_size_t);
337 
338 /* write region, stream */
339 void	__BS(write_region_stream_1)(void *, bus_space_handle_t, bus_size_t,
340 				    const uint8_t *, bus_size_t);
341 void	__BS(write_region_stream_2)(void *, bus_space_handle_t, bus_size_t,
342 				    const uint16_t *, bus_size_t);
343 void	__BS(write_region_stream_4)(void *, bus_space_handle_t, bus_size_t,
344 				    const uint32_t *, bus_size_t);
345 void	__BS(write_region_stream_8)(void *, bus_space_handle_t, bus_size_t,
346 				    const uint64_t *, bus_size_t);
347 
348 #endif	/* CHIP_NEED_STREAM */
349 
350 #ifdef CHIP_EXTENT
351 #ifndef	CHIP_EX_STORE
352 static long
353     __BS(ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
354 #define	CHIP_EX_STORE(v)	(__BS(ex_storage))
355 #define	CHIP_EX_STORE_SIZE(v)	(sizeof __BS(ex_storage))
356 #endif
357 #endif /* CHIP_EXTENT */
358 
359 #ifndef CHIP_ALIGN_STRIDE
360 #define	CHIP_ALIGN_STRIDE	0
361 #endif
362 
363 #if CHIP_ALIGN_STRIDE > 0
364 #define	CHIP_OFF8(o)	((o) << (CHIP_ALIGN_STRIDE))
365 #else
366 #define	CHIP_OFF8(o)	(o)
367 #endif
368 
369 #if CHIP_ALIGN_STRIDE > 1
370 #define	CHIP_OFF16(o)	((o) << (CHIP_ALIGN_STRIDE - 1))
371 #else
372 #define	CHIP_OFF16(o)	(o)
373 #endif
374 
375 #if CHIP_ALIGN_STRIDE > 2
376 #define	CHIP_OFF32(o)	((o) << (CHIP_ALIGN_STRIDE - 2))
377 #else
378 #define	CHIP_OFF32(o)	(o)
379 #endif
380 
381 #if CHIP_ALIGN_STRIDE > 3
382 #define	CHIP_OFF64(o)	((o) << (CHIP_ALIGN_STRIDE - 3))
383 #else
384 #define	CHIP_OFF64(o)	(o)
385 #endif
386 
387 
388 void
389 __BS(init)(bus_space_tag_t t, void *v)
390 {
391 #ifdef CHIP_EXTENT
392 	struct extent *ex;
393 #endif
394 
395 	/*
396 	 * Initialize the bus space tag.
397 	 */
398 
399 	/* cookie */
400 	t->bs_cookie =		v;
401 
402 	/* mapping/unmapping */
403 	t->bs_map =		__BS(map);
404 	t->bs_unmap =		__BS(unmap);
405 	t->bs_subregion =	__BS(subregion);
406 
407 	t->bs_translate =	__BS(translate);
408 	t->bs_get_window =	__BS(get_window);
409 
410 	/* allocation/deallocation */
411 	t->bs_alloc =		__BS(alloc);
412 	t->bs_free =		__BS(free);
413 
414 	/* get kernel virtual address */
415 	t->bs_vaddr =		__BS(vaddr);
416 
417 	/* mmap for user */
418 	t->bs_mmap =		__BS(mmap);
419 
420 	/* barrier */
421 	t->bs_barrier =		__BS(barrier);
422 
423 	/* read (single) */
424 	t->bs_r_1 =		__BS(read_1);
425 	t->bs_r_2 =		__BS(read_2);
426 	t->bs_r_4 =		__BS(read_4);
427 	t->bs_r_8 =		__BS(read_8);
428 
429 	/* read multiple */
430 	t->bs_rm_1 =		__BS(read_multi_1);
431 	t->bs_rm_2 =		__BS(read_multi_2);
432 	t->bs_rm_4 =		__BS(read_multi_4);
433 	t->bs_rm_8 =		__BS(read_multi_8);
434 
435 	/* read region */
436 	t->bs_rr_1 =		__BS(read_region_1);
437 	t->bs_rr_2 =		__BS(read_region_2);
438 	t->bs_rr_4 =		__BS(read_region_4);
439 	t->bs_rr_8 =		__BS(read_region_8);
440 
441 	/* write (single) */
442 	t->bs_w_1 =		__BS(write_1);
443 	t->bs_w_2 =		__BS(write_2);
444 	t->bs_w_4 =		__BS(write_4);
445 	t->bs_w_8 =		__BS(write_8);
446 
447 	/* write multiple */
448 	t->bs_wm_1 =		__BS(write_multi_1);
449 	t->bs_wm_2 =		__BS(write_multi_2);
450 	t->bs_wm_4 =		__BS(write_multi_4);
451 	t->bs_wm_8 =		__BS(write_multi_8);
452 
453 	/* write region */
454 	t->bs_wr_1 =		__BS(write_region_1);
455 	t->bs_wr_2 =		__BS(write_region_2);
456 	t->bs_wr_4 =		__BS(write_region_4);
457 	t->bs_wr_8 =		__BS(write_region_8);
458 
459 	/* set multiple */
460 	t->bs_sm_1 =		__BS(set_multi_1);
461 	t->bs_sm_2 =		__BS(set_multi_2);
462 	t->bs_sm_4 =		__BS(set_multi_4);
463 	t->bs_sm_8 =		__BS(set_multi_8);
464 
465 	/* set region */
466 	t->bs_sr_1 =		__BS(set_region_1);
467 	t->bs_sr_2 =		__BS(set_region_2);
468 	t->bs_sr_4 =		__BS(set_region_4);
469 	t->bs_sr_8 =		__BS(set_region_8);
470 
471 	/* copy */
472 	t->bs_c_1 =		__BS(copy_region_1);
473 	t->bs_c_2 =		__BS(copy_region_2);
474 	t->bs_c_4 =		__BS(copy_region_4);
475 	t->bs_c_8 =		__BS(copy_region_8);
476 
477 #ifdef CHIP_NEED_STREAM
478 	/* read (single), stream */
479 	t->bs_rs_1 =		__BS(read_stream_1);
480 	t->bs_rs_2 =		__BS(read_stream_2);
481 	t->bs_rs_4 =		__BS(read_stream_4);
482 	t->bs_rs_8 =		__BS(read_stream_8);
483 
484 	/* read multiple, stream */
485 	t->bs_rms_1 =		__BS(read_multi_stream_1);
486 	t->bs_rms_2 =		__BS(read_multi_stream_2);
487 	t->bs_rms_4 =		__BS(read_multi_stream_4);
488 	t->bs_rms_8 =		__BS(read_multi_stream_8);
489 
490 	/* read region, stream */
491 	t->bs_rrs_1 =		__BS(read_region_stream_1);
492 	t->bs_rrs_2 =		__BS(read_region_stream_2);
493 	t->bs_rrs_4 =		__BS(read_region_stream_4);
494 	t->bs_rrs_8 =		__BS(read_region_stream_8);
495 
496 	/* write (single), stream */
497 	t->bs_ws_1 =		__BS(write_stream_1);
498 	t->bs_ws_2 =		__BS(write_stream_2);
499 	t->bs_ws_4 =		__BS(write_stream_4);
500 	t->bs_ws_8 =		__BS(write_stream_8);
501 
502 	/* write multiple, stream */
503 	t->bs_wms_1 =		__BS(write_multi_stream_1);
504 	t->bs_wms_2 =		__BS(write_multi_stream_2);
505 	t->bs_wms_4 =		__BS(write_multi_stream_4);
506 	t->bs_wms_8 =		__BS(write_multi_stream_8);
507 
508 	/* write region, stream */
509 	t->bs_wrs_1 =		__BS(write_region_stream_1);
510 	t->bs_wrs_2 =		__BS(write_region_stream_2);
511 	t->bs_wrs_4 =		__BS(write_region_stream_4);
512 	t->bs_wrs_8 =		__BS(write_region_stream_8);
513 
514 #else	/* CHIP_NEED_STREAM */
515 
516 	/* read (single), stream */
517 	t->bs_rs_1 =		__BS(read_1);
518 	t->bs_rs_2 =		__BS(read_2);
519 	t->bs_rs_4 =		__BS(read_4);
520 	t->bs_rs_8 =		__BS(read_8);
521 
522 	/* read multiple, stream */
523 	t->bs_rms_1 =		__BS(read_multi_1);
524 	t->bs_rms_2 =		__BS(read_multi_2);
525 	t->bs_rms_4 =		__BS(read_multi_4);
526 	t->bs_rms_8 =		__BS(read_multi_8);
527 
528 	/* read region, stream */
529 	t->bs_rrs_1 =		__BS(read_region_1);
530 	t->bs_rrs_2 =		__BS(read_region_2);
531 	t->bs_rrs_4 =		__BS(read_region_4);
532 	t->bs_rrs_8 =		__BS(read_region_8);
533 
534 	/* write (single), stream */
535 	t->bs_ws_1 =		__BS(write_1);
536 	t->bs_ws_2 =		__BS(write_2);
537 	t->bs_ws_4 =		__BS(write_4);
538 	t->bs_ws_8 =		__BS(write_8);
539 
540 	/* write multiple, stream */
541 	t->bs_wms_1 =		__BS(write_multi_1);
542 	t->bs_wms_2 =		__BS(write_multi_2);
543 	t->bs_wms_4 =		__BS(write_multi_4);
544 	t->bs_wms_8 =		__BS(write_multi_8);
545 
546 	/* write region, stream */
547 	t->bs_wrs_1 =		__BS(write_region_1);
548 	t->bs_wrs_2 =		__BS(write_region_2);
549 	t->bs_wrs_4 =		__BS(write_region_4);
550 	t->bs_wrs_8 =		__BS(write_region_8);
551 #endif	/* CHIP_NEED_STREAM */
552 
553 #ifdef CHIP_EXTENT
554 	/* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */
555 	ex = extent_create(__S(__BS(bus)), 0x0UL, ~0UL, M_DEVBUF,
556 	    (void *)CHIP_EX_STORE(v), CHIP_EX_STORE_SIZE(v), EX_NOWAIT);
557 	extent_alloc_region(ex, 0, ~0UL, EX_NOWAIT);
558 
559 #ifdef CHIP_W1_BUS_START
560 	/*
561 	 * The window may be disabled.  We notice this by seeing
562 	 * -1 as the bus base address.
563 	 */
564 	if (CHIP_W1_BUS_START(v) == (bus_addr_t) -1) {
565 #ifdef EXTENT_DEBUG
566 		printf("%s: this space is disabled\n", __S(__BS(init)));
567 #endif
568 		return;
569 	}
570 
571 #ifdef EXTENT_DEBUG
572 	printf("%s: freeing from %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n",
573 	    __S(__BS(init)), (bus_addr_t)CHIP_W1_BUS_START(v),
574 	    (bus_addr_t)CHIP_W1_BUS_END(v));
575 #endif
576 	extent_free(ex, CHIP_W1_BUS_START(v),
577 	    CHIP_W1_BUS_END(v) - CHIP_W1_BUS_START(v) + 1, EX_NOWAIT);
578 #endif
579 #ifdef CHIP_W2_BUS_START
580 	if (CHIP_W2_BUS_START(v) != CHIP_W1_BUS_START(v)) {
581 #ifdef EXTENT_DEBUG
582 		printf("xxx: freeing from 0x%lx to 0x%lx\n",
583 		    (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v));
584 #endif
585 		extent_free(ex, CHIP_W2_BUS_START(v),
586 		    CHIP_W2_BUS_END(v) - CHIP_W2_BUS_START(v) + 1, EX_NOWAIT);
587 	} else {
588 #ifdef EXTENT_DEBUG
589 		printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n",
590 		    (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v));
591 #endif
592 	}
593 #endif
594 #ifdef CHIP_W3_BUS_START
595 	if (CHIP_W3_BUS_START(v) != CHIP_W1_BUS_START(v) &&
596 	    CHIP_W3_BUS_START(v) != CHIP_W2_BUS_START(v)) {
597 #ifdef EXTENT_DEBUG
598 		printf("xxx: freeing from 0x%lx to 0x%lx\n",
599 		    (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v));
600 #endif
601 		extent_free(ex, CHIP_W3_BUS_START(v),
602 		    CHIP_W3_BUS_END(v) - CHIP_W3_BUS_START(v) + 1, EX_NOWAIT);
603 	} else {
604 #ifdef EXTENT_DEBUG
605 		printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n",
606 		    (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v));
607 #endif
608 	}
609 #endif
610 
611 #ifdef EXTENT_DEBUG
612 	extent_print(ex);
613 #endif
614 	CHIP_EXTENT(v) = ex;
615 #endif /* CHIP_EXTENT */
616 }
617 
618 int
619 __BS(translate)(void *v, bus_addr_t addr, bus_size_t len, int flags,
620     struct mips_bus_space_translation *mbst)
621 {
622 	bus_addr_t end = addr + (len - 1);
623 #if CHIP_ALIGN_STRIDE != 0
624 	int linear = flags & BUS_SPACE_MAP_LINEAR;
625 
626 	/*
627 	 * Can't map xxx space linearly.
628 	 */
629 	if (linear)
630 		return (EOPNOTSUPP);
631 #endif
632 
633 #ifdef CHIP_W1_BUS_START
634 	if (addr >= CHIP_W1_BUS_START(v) && end <= CHIP_W1_BUS_END(v))
635 		return (__BS(get_window)(v, 0, mbst));
636 #endif
637 
638 #ifdef CHIP_W2_BUS_START
639 	if (addr >= CHIP_W2_BUS_START(v) && end <= CHIP_W2_BUS_END(v))
640 		return (__BS(get_window)(v, 1, mbst));
641 #endif
642 
643 #ifdef CHIP_W3_BUS_START
644 	if (addr >= CHIP_W3_BUS_START(v) && end <= CHIP_W3_BUS_END(v))
645 		return (__BS(get_window)(v, 2, mbst));
646 #endif
647 
648 #ifdef EXTENT_DEBUG
649 	printf("\n");
650 #ifdef CHIP_W1_BUS_START
651 	printf("%s: window[1]=0x%lx-0x%lx\n", __S(__BS(map)),
652 	    (u_long)CHIP_W1_BUS_START(v), (u_long)CHIP_W1_BUS_END(v));
653 #endif
654 #ifdef CHIP_W2_BUS_START
655 	printf("%s: window[2]=0x%lx-0x%lx\n", __S(__BS(map)),
656 	    (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v));
657 #endif
658 #ifdef CHIP_W3_BUS_START
659 	printf("%s: window[3]=0x%lx-0x%lx\n", __S(__BS(map)),
660 	    (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v));
661 #endif
662 #endif /* EXTENT_DEBUG */
663 	/* No translation. */
664 	return (EINVAL);
665 }
666 
667 int
668 __BS(get_window)(void *v, int window, struct mips_bus_space_translation *mbst)
669 {
670 
671 	switch (window) {
672 #ifdef CHIP_W1_BUS_START
673 	case 0:
674 		mbst->mbst_bus_start = CHIP_W1_BUS_START(v);
675 		mbst->mbst_bus_end = CHIP_W1_BUS_END(v);
676 		mbst->mbst_sys_start = CHIP_W1_SYS_START(v);
677 		mbst->mbst_sys_end = CHIP_W1_SYS_END(v);
678 		mbst->mbst_align_stride = CHIP_ALIGN_STRIDE;
679 		mbst->mbst_flags = 0;
680 		break;
681 #endif
682 
683 #ifdef CHIP_W2_BUS_START
684 	case 1:
685 		mbst->mbst_bus_start = CHIP_W2_BUS_START(v);
686 		mbst->mbst_bus_end = CHIP_W2_BUS_END(v);
687 		mbst->mbst_sys_start = CHIP_W2_SYS_START(v);
688 		mbst->mbst_sys_end = CHIP_W2_SYS_END(v);
689 		mbst->mbst_align_stride = CHIP_ALIGN_STRIDE;
690 		mbst->mbst_flags = 0;
691 		break;
692 #endif
693 
694 #ifdef CHIP_W3_BUS_START
695 	case 2:
696 		mbst->mbst_bus_start = CHIP_W3_BUS_START(v);
697 		mbst->mbst_bus_end = CHIP_W3_BUS_END(v);
698 		mbst->mbst_sys_start = CHIP_W3_SYS_START(v);
699 		mbst->mbst_sys_end = CHIP_W3_SYS_END(v);
700 		mbst->mbst_align_stride = CHIP_ALIGN_STRIDE;
701 		mbst->mbst_flags = 0;
702 		break;
703 #endif
704 
705 	default:
706 		panic(__S(__BS(get_window)) ": invalid window %d",
707 		    window);
708 	}
709 
710 	return (0);
711 }
712 
713 int
714 __BS(map)(void *v, bus_addr_t addr, bus_size_t size, int flags,
715     bus_space_handle_t *hp, int acct)
716 {
717 	struct mips_bus_space_translation mbst;
718 	int error;
719 
720 	/*
721 	 * Get the translation for this address.
722 	 */
723 	error = __BS(translate)(v, addr, size, flags, &mbst);
724 	if (error)
725 		return (error);
726 
727 #ifdef CHIP_EXTENT
728 	if (acct == 0)
729 		goto mapit;
730 
731 #ifdef EXTENT_DEBUG
732 	printf("%s: allocating %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n",
733 		__S(__BS(map)), addr, addr + size - 1);
734 #endif
735         error = extent_alloc_region(CHIP_EXTENT(v), addr, size,
736             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
737 	if (error) {
738 #ifdef EXTENT_DEBUG
739 		printf("%s: allocation failed (%d)\n", __S(__BS(map)), error);
740 		extent_print(CHIP_EXTENT(v));
741 #endif
742 		return (error);
743 	}
744 
745  mapit:
746 #endif /* CHIP_EXTENT */
747 
748 	addr = mbst.mbst_sys_start + (addr - mbst.mbst_bus_start);
749 
750 #ifdef _LP64
751 	if (flags & BUS_SPACE_MAP_CACHEABLE)
752 		*hp = MIPS_PHYS_TO_XKPHYS_CACHED(addr);
753 	else
754 		*hp = MIPS_PHYS_TO_XKPHYS_UNCACHED(addr);
755 #else
756 	if (((addr + size) & ~MIPS_PHYS_MASK) != 0) {
757 		vaddr_t va;
758 		paddr_t pa;
759 		int s;
760 
761 		size = round_page((addr % PAGE_SIZE) + size);
762 		va = uvm_km_alloc(kernel_map, size, PAGE_SIZE,
763 			UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
764 		if (va == 0)
765 			return ENOMEM;
766 
767 		/* check use of handle_is_kseg2 in BS(unmap) */
768 		KASSERT((va & ~MIPS_PHYS_MASK) == MIPS_KSEG2_START);
769 
770 		*hp = va + (addr & PAGE_MASK);
771 		pa = trunc_page(addr);
772 
773 		s = splhigh();
774 		while (size != 0) {
775 			pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0);
776 			pa += PAGE_SIZE;
777 			va += PAGE_SIZE;
778 			size -= PAGE_SIZE;
779 		}
780 		pmap_update(pmap_kernel());
781 		splx(s);
782 	} else {
783 		if (flags & BUS_SPACE_MAP_CACHEABLE)
784 			*hp = MIPS_PHYS_TO_KSEG0(addr);
785 		else
786 			*hp = MIPS_PHYS_TO_KSEG1(addr);
787 	}
788 #endif
789 
790 	return (0);
791 }
792 
793 void
794 __BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct)
795 {
796 #if !defined(_LP64) || defined(CHIP_EXTENT)
797 	bus_addr_t addr = 0;	/* initialize to appease gcc */
798 #endif
799 #ifndef _LP64
800 	bool handle_is_kseg2;
801 
802 	/* determine if h is addr obtained from uvm_km_alloc */
803 	handle_is_kseg2 = ((h & ~MIPS_PHYS_MASK) == MIPS_KSEG2_START);
804 #if 0
805 	printf("%s:%d: is_kseg2 %d\n", __func__, __LINE__, handle_is_kseg2);
806 #endif
807 	if (handle_is_kseg2 == true) {
808 		paddr_t pa;
809 		vaddr_t va = (vaddr_t)trunc_page(h);
810 		vsize_t sz = (vsize_t)round_page((h % PAGE_SIZE) + size);
811 		int s;
812 
813 		s = splhigh();
814 
815 		if (pmap_extract(pmap_kernel(), (vaddr_t)h, &pa) == false)
816 			panic("%s: pmap_extract failed", __func__);
817 		addr = (bus_addr_t)pa;
818 #if 0
819 		printf("%s:%d: addr %#"PRIxBUSADDR", sz %#"PRIxVSIZE"\n",
820 			__func__, __LINE__, addr, sz);
821 #endif
822 		/* sanity check: this is why we couldn't map w/ kseg[0,1] */
823 		KASSERT (((addr + sz) & ~MIPS_PHYS_MASK) != 0);
824 
825 		pmap_kremove(va, sz);
826 		pmap_update(pmap_kernel());
827 		uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY);
828 
829 		splx(s);
830 	}
831 #endif	/* _LP64 */
832 
833 #ifdef CHIP_EXTENT
834 
835 	if (acct == 0)
836 		return;
837 
838 #ifdef EXTENT_DEBUG
839 	printf("%s: freeing handle %#"PRIxBSH" for %#"PRIxBUSSIZE"\n",
840 		__S(__BS(unmap)), h, size);
841 #endif
842 
843 #ifdef _LP64
844 	KASSERT(MIPS_XKPHYS_P(h));
845 	addr = MIPS_XKPHYS_TO_PHYS(h);
846 #else
847 	if (handle_is_kseg2 == false) {
848 		if (MIPS_KSEG0_P(h))
849 			addr = MIPS_KSEG0_TO_PHYS(h);
850 		else
851 			addr = MIPS_KSEG1_TO_PHYS(h);
852 	}
853 #endif
854 
855 #ifdef CHIP_W1_BUS_START
856 	if (addr >= CHIP_W1_SYS_START(v) && addr <= CHIP_W1_SYS_END(v)) {
857 		addr = CHIP_W1_BUS_START(v) + (addr - CHIP_W1_SYS_START(v));
858 	} else
859 #endif
860 #ifdef CHIP_W2_BUS_START
861 	if (addr >= CHIP_W2_SYS_START(v) && addr <= CHIP_W2_SYS_END(v)) {
862 		addr = CHIP_W2_BUS_START(v) + (addr - CHIP_W2_SYS_START(v));
863 	} else
864 #endif
865 #ifdef CHIP_W3_BUS_START
866 	if (addr >= CHIP_W3_SYS_START(v) && addr <= CHIP_W3_SYS_END(v)) {
867 		addr = CHIP_W3_BUS_START(v) + (addr - CHIP_W3_SYS_START(v));
868 	} else
869 #endif
870 	{
871 		printf("\n");
872 #ifdef CHIP_W1_BUS_START
873 		printf("%s: sys window[1]=0x%lx-0x%lx\n",
874 		    __S(__BS(map)), (u_long)CHIP_W1_SYS_START(v),
875 		    (u_long)CHIP_W1_SYS_END(v));
876 #endif
877 #ifdef CHIP_W2_BUS_START
878 		printf("%s: sys window[2]=0x%lx-0x%lx\n",
879 		    __S(__BS(map)), (u_long)CHIP_W2_SYS_START(v),
880 		    (u_long)CHIP_W2_SYS_END(v));
881 #endif
882 #ifdef CHIP_W3_BUS_START
883 		printf("%s: sys window[3]=0x%lx-0x%lx\n",
884 		    __S(__BS(unmap)), (u_long)CHIP_W3_SYS_START(v),
885 		    (u_long)CHIP_W3_SYS_END(v));
886 #endif
887 		panic("%s: don't know how to unmap %#"PRIxBSH, __S(__BS(unmap)), h);
888 	}
889 
890 #ifdef EXTENT_DEBUG
891 	printf("%s: freeing %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n",
892 	    __S(__BS(unmap)), addr, addr + size - 1);
893 #endif
894         int error = extent_free(CHIP_EXTENT(v), addr, size,
895             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
896 	if (error) {
897 		printf("%s: WARNING: could not unmap"
898 		    " %#"PRIxBUSADDR"-%#"PRIxBUSADDR" (error %d)\n",
899 		    __S(__BS(unmap)), addr, addr + size - 1, error);
900 #ifdef EXTENT_DEBUG
901 		extent_print(CHIP_EXTENT(v));
902 #endif
903 	}
904 #endif /* CHIP_EXTENT */
905 }
906 
907 int
908 __BS(subregion)(void *v, bus_space_handle_t h, bus_size_t offset,
909     bus_size_t size, bus_space_handle_t *nh)
910 {
911 
912 	*nh = h + (offset << CHIP_ALIGN_STRIDE);
913 	return (0);
914 }
915 
916 int
917 __BS(alloc)(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
918     bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
919     bus_space_handle_t *bshp)
920 {
921 #ifdef CHIP_EXTENT
922 	struct mips_bus_space_translation mbst;
923 	u_long addr;	/* bogus but makes extent happy */
924 	int error;
925 #if CHIP_ALIGN_STRIDE != 0
926 	int linear = flags & BUS_SPACE_MAP_LINEAR;
927 
928 	/*
929 	 * Can't map xxx space linearly.
930 	 */
931 	if (linear)
932 		return (EOPNOTSUPP);
933 #endif
934 
935 	/*
936 	 * Do the requested allocation.
937 	 */
938 #ifdef EXTENT_DEBUG
939 	printf("%s: allocating from %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n",
940 		__S(__BS(alloc)), rstart, rend);
941 #endif
942 	error = extent_alloc_subregion(CHIP_EXTENT(v), rstart, rend, size,
943 	    align, boundary,
944 	    EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0),
945 	    &addr);
946 	if (error) {
947 #ifdef EXTENT_DEBUG
948 		printf("%s: allocation failed (%d)\n", __S(__BS(alloc)), error);
949 		extent_print(CHIP_EXTENT(v));
950 #endif
951 		return (error);
952 	}
953 
954 #ifdef EXTENT_DEBUG
955 	printf("%s: allocated 0x%lx to %#"PRIxBUSSIZE"\n",
956 		__S(__BS(alloc)), addr, addr + size - 1);
957 #endif
958 
959 	error = __BS(translate)(v, addr, size, flags, &mbst);
960 	if (error) {
961 		(void) extent_free(CHIP_EXTENT(v), addr, size,
962 		    EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
963 		return (error);
964 	}
965 
966 	*addrp = addr;
967 #ifdef _LP64
968 	if (flags & BUS_SPACE_MAP_CACHEABLE)
969 		*bshp = MIPS_PHYS_TO_XKPHYS_CACHED(mbst.mbst_sys_start +
970 		    (addr - mbst.mbst_bus_start));
971 	else
972 		*bshp = MIPS_PHYS_TO_XKPHYS_UNCACHED(mbst.mbst_sys_start +
973 		    (addr - mbst.mbst_bus_start));
974 #else
975 	if (flags & BUS_SPACE_MAP_CACHEABLE)
976 		*bshp = MIPS_PHYS_TO_KSEG0(mbst.mbst_sys_start +
977 		    (addr - mbst.mbst_bus_start));
978 	else
979 		*bshp = MIPS_PHYS_TO_KSEG1(mbst.mbst_sys_start +
980 		    (addr - mbst.mbst_bus_start));
981 #endif
982 
983 	return (0);
984 #else /* ! CHIP_EXTENT */
985 	return (EOPNOTSUPP);
986 #endif /* CHIP_EXTENT */
987 }
988 
989 void
990 __BS(free)(void *v, bus_space_handle_t bsh, bus_size_t size)
991 {
992 
993 	/* Unmap does all we need to do. */
994 	__BS(unmap)(v, bsh, size, 1);
995 }
996 
997 void *
998 __BS(vaddr)(void *v, bus_space_handle_t bsh)
999 {
1000 
1001 #if CHIP_ALIGN_STRIDE != 0
1002 	/* Linear mappings not possible. */
1003 	return (NULL);
1004 #else
1005 	return ((void *)bsh);
1006 #endif
1007 }
1008 
1009 paddr_t
1010 __BS(mmap)(void *v, bus_addr_t addr, off_t off, int prot, int flags)
1011 {
1012 #ifdef CHIP_IO
1013 
1014 	/* Not supported for I/O space. */
1015 	return (-1);
1016 #elif defined(CHIP_MEM)
1017 	struct mips_bus_space_translation mbst;
1018 	int error;
1019 
1020 	/*
1021 	 * Get the translation for this address.
1022 	 */
1023 	error = __BS(translate)(v, addr, off + PAGE_SIZE, flags,
1024 	    &mbst);
1025 	if (error)
1026 		return (-1);
1027 
1028 	return (mips_btop(mbst.mbst_sys_start +
1029 	    (addr - mbst.mbst_bus_start) + off));
1030 #else
1031 # error must define one of CHIP_IO or CHIP_MEM
1032 #endif
1033 }
1034 
1035 inline void
1036 __BS(barrier)(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int f)
1037 {
1038 
1039 	/* XXX XXX XXX */
1040 	if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
1041 		wbflush();
1042 }
1043 
1044 inline uint8_t
1045 __BS(read_1)(void *v, bus_space_handle_t h, bus_size_t off)
1046 {
1047 #if CHIP_ACCESS_SIZE > 1
1048 	volatile CHIP_TYPE *ptr;
1049 #else	/* CHIP_ACCESS_SIZE > 1 */
1050 	volatile uint8_t *ptr;
1051 #endif	/* CHIP_ACCESS_SIZE > 1 */
1052 	uint8_t r;
1053         int shift;
1054 
1055         h += CHIP_OFF8(off);
1056         shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
1057         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
1058         r = (uint8_t)(CHIP_SWAP_ACCESS(*ptr) >> shift);
1059 
1060         return r;
1061 }
1062 
1063 inline uint16_t
1064 __BS(read_2)(void *v, bus_space_handle_t h, bus_size_t off)
1065 {
1066 #if CHIP_ACCESS_SIZE > 2
1067 	volatile CHIP_TYPE *ptr;
1068 #else	/* CHIP_ACCESS_SIZE > 2 */
1069 	volatile uint16_t *ptr;
1070 #endif	/* CHIP_ACCESS_SIZE > 2 */
1071 	uint16_t r;
1072         int shift;
1073 
1074 	KASSERT((off & 1) == 0);
1075         h += CHIP_OFF16(off);
1076         shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
1077         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
1078 	r = (uint16_t)CHIP_SWAP16(*ptr >> shift);
1079 
1080 	return r;
1081 }
1082 
1083 inline uint32_t
1084 __BS(read_4)(void *v, bus_space_handle_t h, bus_size_t off)
1085 {
1086 #if CHIP_ACCESS_SIZE > 4
1087 	volatile CHIP_TYPE *ptr;
1088 #else	/* CHIP_ACCESS_SIZE > 4 */
1089 	volatile uint32_t *ptr;
1090 #endif
1091 	uint32_t r;
1092         int shift;
1093 
1094 	KASSERT((off & 3) == 0);
1095         h += CHIP_OFF32(off);
1096         shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
1097         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
1098 	r = (uint32_t)CHIP_SWAP32(*ptr >> shift);
1099 
1100 	return r;
1101 }
1102 
1103 inline uint64_t
1104 __BS(read_8)(void *v, bus_space_handle_t h, bus_size_t off)
1105 {
1106 	volatile uint64_t *ptr;
1107 	volatile uint64_t r;
1108         int shift;
1109 
1110 	KASSERT((off & 7) == 0);
1111         h += CHIP_OFF64(off);
1112         shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
1113         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
1114 	r =  CHIP_SWAP64(*ptr >> shift);
1115 
1116 	return r;
1117 }
1118 
1119 
1120 #define CHIP_read_multi_N(BYTES,TYPE)					\
1121 void									\
1122 __C(__BS(read_multi_),BYTES)(void *v, bus_space_handle_t h,		\
1123     bus_size_t o, TYPE *a, bus_size_t c)				\
1124 {									\
1125 									\
1126 	while (c-- > 0) {						\
1127 		__BS(barrier)(v, h, o, sizeof *a,			\
1128 		    BUS_SPACE_BARRIER_READ);				\
1129 		*a++ = __C(__BS(read_),BYTES)(v, h, o);			\
1130 	}								\
1131 }
1132 CHIP_read_multi_N(1,uint8_t)
1133 CHIP_read_multi_N(2,uint16_t)
1134 CHIP_read_multi_N(4,uint32_t)
1135 CHIP_read_multi_N(8,uint64_t)
1136 
1137 #define CHIP_read_region_N(BYTES,TYPE)					\
1138 void									\
1139 __C(__BS(read_region_),BYTES)(void *v, bus_space_handle_t h,		\
1140     bus_size_t o, TYPE *a, bus_size_t c)				\
1141 {									\
1142 									\
1143 	while (c-- > 0) {						\
1144 		*a++ = __C(__BS(read_),BYTES)(v, h, o);			\
1145 		o += sizeof *a;						\
1146 	}								\
1147 }
1148 CHIP_read_region_N(1,uint8_t)
1149 CHIP_read_region_N(2,uint16_t)
1150 CHIP_read_region_N(4,uint32_t)
1151 CHIP_read_region_N(8,uint64_t)
1152 
1153 
1154 inline void
1155 __BS(write_1)(void *v, bus_space_handle_t h, bus_size_t off, uint8_t val)
1156 {
1157 #if CHIP_ACCESS_SIZE > 1
1158 	volatile CHIP_TYPE *ptr;
1159 #else	/* CHIP_ACCESS_SIZE > 1 */
1160 	volatile uint8_t *ptr;
1161 #endif	/* CHIP_ACCESS_SIZE > 1 */
1162 	int shift;
1163 
1164 	h += CHIP_OFF8(off);
1165 	shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
1166 	ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
1167 	*ptr = CHIP_SWAP_ACCESS(((CHIP_TYPE)val) << shift);
1168 }
1169 
1170 inline void
1171 __BS(write_2)(void *v, bus_space_handle_t h, bus_size_t off, uint16_t val)
1172 {
1173 #if CHIP_ACCESS_SIZE > 2
1174 	volatile CHIP_TYPE *ptr;
1175 #else	/* CHIP_ACCESS_SIZE > 2 */
1176 	volatile uint16_t *ptr;
1177 #endif	/* CHIP_ACCESS_SIZE > 2 */
1178 	int shift;
1179 
1180 	KASSERT((off & 1) == 0);
1181 	h += CHIP_OFF16(off);
1182 	shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
1183 	ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
1184 	if (CHIP_ACCESS_SIZE > 2)
1185 		*ptr = (CHIP_TYPE)(CHIP_SWAP16(val)) << shift;
1186 	else
1187 		*ptr = CHIP_SWAP16(val);
1188 }
1189 
1190 inline void
1191 __BS(write_4)(void *v, bus_space_handle_t h, bus_size_t off, uint32_t val)
1192 {
1193 #if CHIP_ACCESS_SIZE > 4
1194 	volatile CHIP_TYPE *ptr;
1195 #else	/* CHIP_ACCESS_SIZE > 4 */
1196 	volatile uint32_t *ptr;
1197 #endif	/* CHIP_ACCESS_SIZE > 4 */
1198         int shift;
1199 
1200 	KASSERT((off & 3) == 0);
1201         h += CHIP_OFF32(off);
1202         shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
1203         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
1204         if (CHIP_ACCESS_SIZE > 4)
1205 		*ptr = (CHIP_TYPE)(CHIP_SWAP32(val)) << shift;
1206         else
1207                 *ptr = CHIP_SWAP32(val);
1208 }
1209 
1210 inline void
1211 __BS(write_8)(void *v, bus_space_handle_t h, bus_size_t off, uint64_t val)
1212 {
1213 	volatile uint64_t *ptr;
1214         int shift;
1215 
1216 	KASSERT((off & 7) == 0);
1217         h += CHIP_OFF64(off);
1218         shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
1219         ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
1220 	*ptr = CHIP_SWAP64(val) << shift;
1221 }
1222 
1223 #define CHIP_write_multi_N(BYTES,TYPE)					\
1224 void									\
1225 __C(__BS(write_multi_),BYTES)(void *v, bus_space_handle_t h,		\
1226     bus_size_t o, const TYPE *a, bus_size_t c)				\
1227 {									\
1228 									\
1229 	while (c-- > 0) {						\
1230 		__C(__BS(write_),BYTES)(v, h, o, *a++);			\
1231 		__BS(barrier)(v, h, o, sizeof *a,			\
1232 		    BUS_SPACE_BARRIER_WRITE);				\
1233 	}								\
1234 }
1235 CHIP_write_multi_N(1,uint8_t)
1236 CHIP_write_multi_N(2,uint16_t)
1237 CHIP_write_multi_N(4,uint32_t)
1238 CHIP_write_multi_N(8,uint64_t)
1239 
1240 #define CHIP_write_region_N(BYTES,TYPE)					\
1241 void									\
1242 __C(__BS(write_region_),BYTES)(void *v, bus_space_handle_t h,		\
1243     bus_size_t o, const TYPE *a, bus_size_t c)				\
1244 {									\
1245 									\
1246 	while (c-- > 0) {						\
1247 		__C(__BS(write_),BYTES)(v, h, o, *a++);			\
1248 		o += sizeof *a;						\
1249 	}								\
1250 }
1251 CHIP_write_region_N(1,uint8_t)
1252 CHIP_write_region_N(2,uint16_t)
1253 CHIP_write_region_N(4,uint32_t)
1254 CHIP_write_region_N(8,uint64_t)
1255 
1256 #define CHIP_set_multi_N(BYTES,TYPE)					\
1257 void									\
1258 __C(__BS(set_multi_),BYTES)(void *v, bus_space_handle_t h,		\
1259     bus_size_t o, TYPE val, bus_size_t c)				\
1260 {									\
1261 									\
1262 	while (c-- > 0) {						\
1263 		__C(__BS(write_),BYTES)(v, h, o, val);			\
1264 		__BS(barrier)(v, h, o, sizeof val,			\
1265 		    BUS_SPACE_BARRIER_WRITE);				\
1266 	}								\
1267 }
1268 CHIP_set_multi_N(1,uint8_t)
1269 CHIP_set_multi_N(2,uint16_t)
1270 CHIP_set_multi_N(4,uint32_t)
1271 CHIP_set_multi_N(8,uint64_t)
1272 
1273 #define CHIP_set_region_N(BYTES,TYPE)					\
1274 void									\
1275 __C(__BS(set_region_),BYTES)(void *v, bus_space_handle_t h,		\
1276     bus_size_t o, TYPE val, bus_size_t c)				\
1277 {									\
1278 									\
1279 	while (c-- > 0) {						\
1280 		__C(__BS(write_),BYTES)(v, h, o, val);			\
1281 		o += sizeof val;					\
1282 	}								\
1283 }
1284 CHIP_set_region_N(1,uint8_t)
1285 CHIP_set_region_N(2,uint16_t)
1286 CHIP_set_region_N(4,uint32_t)
1287 CHIP_set_region_N(8,uint64_t)
1288 
1289 #define	CHIP_copy_region_N(BYTES)					\
1290 void									\
1291 __C(__BS(copy_region_),BYTES)(void *v, bus_space_handle_t h1,		\
1292     bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)	\
1293 {									\
1294 	bus_size_t o;							\
1295 									\
1296 	if ((h1 + o1) >= (h2 + o2)) {					\
1297 		/* src after dest: copy forward */			\
1298 		for (o = 0; c != 0; c--, o += BYTES)			\
1299 			__C(__BS(write_),BYTES)(v, h2, o2 + o,		\
1300 			    __C(__BS(read_),BYTES)(v, h1, o1 + o));	\
1301 	} else {							\
1302 		/* dest after src: copy backwards */			\
1303 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
1304 			__C(__BS(write_),BYTES)(v, h2, o2 + o,		\
1305 			    __C(__BS(read_),BYTES)(v, h1, o1 + o));	\
1306 	}								\
1307 }
1308 CHIP_copy_region_N(1)
1309 CHIP_copy_region_N(2)
1310 CHIP_copy_region_N(4)
1311 CHIP_copy_region_N(8)
1312 
1313 #ifdef	CHIP_NEED_STREAM
1314 
1315 inline uint8_t
1316 __BS(read_stream_1)(void *v, bus_space_handle_t h, bus_size_t off)
1317 {
1318 #if CHIP_ACCESS_SIZE > 1
1319 	volatile CHIP_TYPE *ptr;
1320 #else	/* CHIP_ACCESS_SIZE > 1 */
1321 	volatile uint8_t *ptr;
1322 #endif	/* CHIP_ACCESS_SIZE > 1 */
1323 
1324 	ptr = (void *)(intptr_t)(h + CHIP_OFF8(off));
1325 	return *ptr & 0xff;
1326 }
1327 
1328 inline uint16_t
1329 __BS(read_stream_2)(void *v, bus_space_handle_t h, bus_size_t off)
1330 {
1331 #if CHIP_ACCESS_SIZE > 2
1332 	volatile CHIP_TYPE *ptr;
1333 #else	/* CHIP_ACCESS_SIZE > 2 */
1334 	volatile uint16_t *ptr;
1335 #endif	/* CHIP_ACCESS_SIZE > 2 */
1336 
1337 	ptr = (void *)(intptr_t)(h + CHIP_OFF16(off));
1338 	return *ptr & 0xffff;
1339 }
1340 
1341 inline uint32_t
1342 __BS(read_stream_4)(void *v, bus_space_handle_t h, bus_size_t off)
1343 {
1344 #if CHIP_ACCESS_SIZE > 4
1345 	volatile CHIP_TYPE *ptr;
1346 #else	/* CHIP_ACCESS_SIZE > 4 */
1347 	volatile uint32_t *ptr;
1348 #endif
1349 
1350 	ptr = (void *)(intptr_t)(h + CHIP_OFF32(off));
1351 	return *ptr & 0xffffffff;
1352 }
1353 
1354 inline uint64_t
1355 __BS(read_stream_8)(void *v, bus_space_handle_t h, bus_size_t off)
1356 {
1357 	volatile uint64_t *ptr;
1358 
1359 	ptr = (void *)(intptr_t)(h + CHIP_OFF64(off));
1360 	return *ptr;
1361 }
1362 
1363 #define CHIP_read_multi_stream_N(BYTES,TYPE)				\
1364 void									\
1365 __C(__BS(read_multi_stream_),BYTES)(void *v, bus_space_handle_t h,	\
1366     bus_size_t o, TYPE *a, bus_size_t c)				\
1367 {									\
1368 									\
1369 	while (c-- > 0) {						\
1370 		__BS(barrier)(v, h, o, sizeof *a,			\
1371 		    BUS_SPACE_BARRIER_READ);				\
1372 		*a++ = __C(__BS(read_stream_),BYTES)(v, h, o);		\
1373 	}								\
1374 }
1375 CHIP_read_multi_stream_N(1,uint8_t)
1376 CHIP_read_multi_stream_N(2,uint16_t)
1377 CHIP_read_multi_stream_N(4,uint32_t)
1378 CHIP_read_multi_stream_N(8,uint64_t)
1379 
1380 #define CHIP_read_region_stream_N(BYTES,TYPE)				\
1381 void									\
1382 __C(__BS(read_region_stream_),BYTES)(void *v, bus_space_handle_t h,	\
1383     bus_size_t o, TYPE *a, bus_size_t c)				\
1384 {									\
1385 									\
1386 	while (c-- > 0) {						\
1387 		*a++ = __C(__BS(read_stream_),BYTES)(v, h, o);		\
1388 		o += sizeof *a;						\
1389 	}								\
1390 }
1391 CHIP_read_region_stream_N(1,uint8_t)
1392 CHIP_read_region_stream_N(2,uint16_t)
1393 CHIP_read_region_stream_N(4,uint32_t)
1394 CHIP_read_region_stream_N(8,uint64_t)
1395 
1396 inline void
1397 __BS(write_stream_1)(void *v, bus_space_handle_t h, bus_size_t off,
1398 		     uint8_t val)
1399 {
1400 #if CHIP_ACCESS_SIZE > 1
1401 	volatile CHIP_TYPE *ptr;
1402 #else	/* CHIP_ACCESS_SIZE > 1 */
1403 	volatile uint8_t *ptr;
1404 #endif	/* CHIP_ACCESS_SIZE > 1 */
1405 
1406 	ptr = (void *)(intptr_t)(h + CHIP_OFF8(off));
1407 	*ptr = val;
1408 }
1409 
1410 inline void
1411 __BS(write_stream_2)(void *v, bus_space_handle_t h, bus_size_t off,
1412 	      uint16_t val)
1413 {
1414 #if CHIP_ACCESS_SIZE > 2
1415 	volatile CHIP_TYPE *ptr;
1416 #else	/* CHIP_ACCESS_SIZE > 2 */
1417 	volatile uint16_t *ptr;
1418 #endif	/* CHIP_ACCESS_SIZE > 2 */
1419 
1420 	ptr = (void *)(intptr_t)(h + CHIP_OFF16(off));
1421 	*ptr = val;
1422 }
1423 
1424 inline void
1425 __BS(write_stream_4)(void *v, bus_space_handle_t h, bus_size_t off,
1426 		     uint32_t val)
1427 {
1428 #if CHIP_ACCESS_SIZE > 4
1429 	volatile CHIP_TYPE *ptr;
1430 #else	/* CHIP_ACCESS_SIZE > 4 */
1431 	volatile uint32_t *ptr;
1432 #endif	/* CHIP_ACCESS_SIZE > 4 */
1433 
1434 	ptr = (void *)(intptr_t)(h + CHIP_OFF32(off));
1435 	*ptr = val;
1436 }
1437 
1438 inline void
1439 __BS(write_stream_8)(void *v, bus_space_handle_t h, bus_size_t off,
1440 		     uint64_t val)
1441 {
1442 	volatile uint64_t *ptr;
1443 
1444 	ptr = (void *)(intptr_t)(h + CHIP_OFF64(off));
1445 	*ptr = val;
1446 }
1447 
1448 #define CHIP_write_multi_stream_N(BYTES,TYPE)				\
1449 void									\
1450 __C(__BS(write_multi_stream_),BYTES)(void *v, bus_space_handle_t h,	\
1451     bus_size_t o, const TYPE *a, bus_size_t c)				\
1452 {									\
1453 									\
1454 	while (c-- > 0) {						\
1455 		__C(__BS(write_stream_),BYTES)(v, h, o, *a++);		\
1456 		__BS(barrier)(v, h, o, sizeof *a,			\
1457 		    BUS_SPACE_BARRIER_WRITE);				\
1458 	}								\
1459 }
1460 CHIP_write_multi_stream_N(1,uint8_t)
1461 CHIP_write_multi_stream_N(2,uint16_t)
1462 CHIP_write_multi_stream_N(4,uint32_t)
1463 CHIP_write_multi_stream_N(8,uint64_t)
1464 
1465 #define CHIP_write_region_stream_N(BYTES,TYPE)				\
1466 void									\
1467 __C(__BS(write_region_stream_),BYTES)(void *v, bus_space_handle_t h,	\
1468     bus_size_t o, const TYPE *a, bus_size_t c)				\
1469 {									\
1470 									\
1471 	while (c-- > 0) {						\
1472 		__C(__BS(write_stream_),BYTES)(v, h, o, *a++);		\
1473 		o += sizeof *a;						\
1474 	}								\
1475 }
1476 CHIP_write_region_stream_N(1,uint8_t)
1477 CHIP_write_region_stream_N(2,uint16_t)
1478 CHIP_write_region_stream_N(4,uint32_t)
1479 CHIP_write_region_stream_N(8,uint64_t)
1480 
1481 #endif	/* CHIP_NEED_STREAM */
1482