1 /*        $NetBSD: mainbus.c,v 1.14 2023/01/06 10:28:27 tsutsui 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  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.14 2023/01/06 10:28:27 tsutsui Exp $");
34 
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/kmem.h>
39 #include <machine/cpu.h>
40 #include <sys/bus.h>
41 
42 static int                    mb_bus_space_peek_1(bus_space_tag_t,
43                                         bus_space_handle_t, bus_size_t);
44 static int                    mb_bus_space_peek_2(bus_space_tag_t,
45                                         bus_space_handle_t, bus_size_t);
46 static int                    mb_bus_space_peek_4(bus_space_tag_t,
47                                         bus_space_handle_t, bus_size_t);
48 static int                    mb_bus_space_peek_8(bus_space_tag_t,
49                                         bus_space_handle_t, bus_size_t);
50 static uint8_t                mb_bus_space_read_1(bus_space_tag_t,
51                                         bus_space_handle_t, bus_size_t);
52 static uint16_t               mb_bus_space_read_2(bus_space_tag_t,
53                                         bus_space_handle_t, bus_size_t);
54 static uint32_t               mb_bus_space_read_4(bus_space_tag_t,
55                                         bus_space_handle_t, bus_size_t);
56 static uint64_t               mb_bus_space_read_8(bus_space_tag_t,
57                                         bus_space_handle_t, bus_size_t);
58 static void                   mb_bus_space_write_1(bus_space_tag_t,
59                                         bus_space_handle_t, bus_size_t, uint8_t);
60 static void                   mb_bus_space_write_2(bus_space_tag_t,
61                                         bus_space_handle_t, bus_size_t, uint16_t);
62 static void                   mb_bus_space_write_4(bus_space_tag_t,
63                                         bus_space_handle_t, bus_size_t, uint32_t);
64 static void                   mb_bus_space_write_8(bus_space_tag_t,
65                                         bus_space_handle_t, bus_size_t, uint64_t);
66 static void                   mb_bus_space_read_multi_1(bus_space_tag_t,
67                                         bus_space_handle_t, bus_size_t, uint8_t *,
68                                         bus_size_t);
69 static void                   mb_bus_space_read_multi_2(bus_space_tag_t,
70                                         bus_space_handle_t, bus_size_t, uint16_t *,
71                                         bus_size_t);
72 static void                   mb_bus_space_read_multi_4(bus_space_tag_t,
73                                         bus_space_handle_t, bus_size_t, uint32_t *,
74                                         bus_size_t);
75 static void                   mb_bus_space_read_multi_8(bus_space_tag_t,
76                                         bus_space_handle_t, bus_size_t, uint64_t *,
77                                         bus_size_t);
78 static void                   mb_bus_space_write_multi_1(bus_space_tag_t,
79                                         bus_space_handle_t, bus_size_t,
80                                         const uint8_t *, bus_size_t);
81 static void                   mb_bus_space_write_multi_2(bus_space_tag_t,
82                                         bus_space_handle_t, bus_size_t,
83                                         const uint16_t *, bus_size_t);
84 static void                   mb_bus_space_write_multi_4(bus_space_tag_t,
85                                         bus_space_handle_t, bus_size_t,
86                                         const uint32_t *, bus_size_t);
87 static void                   mb_bus_space_write_multi_8(bus_space_tag_t,
88                                         bus_space_handle_t, bus_size_t,
89                                         const uint64_t *, bus_size_t);
90 static void                   mb_bus_space_read_region_1(bus_space_tag_t,
91                                         bus_space_handle_t, bus_size_t, uint8_t *,
92                                         bus_size_t);
93 static void                   mb_bus_space_read_region_2(bus_space_tag_t,
94                                         bus_space_handle_t, bus_size_t, uint16_t *,
95                                         bus_size_t);
96 static void                   mb_bus_space_read_region_4(bus_space_tag_t,
97                                         bus_space_handle_t, bus_size_t, uint32_t *,
98                                         bus_size_t);
99 static void                   mb_bus_space_read_region_8(bus_space_tag_t,
100                                         bus_space_handle_t, bus_size_t, uint64_t *,
101                                         bus_size_t);
102 static void                   mb_bus_space_write_region_1(bus_space_tag_t,
103                                         bus_space_handle_t, bus_size_t,
104                                         const uint8_t *, bus_size_t);
105 static void                   mb_bus_space_write_region_2(bus_space_tag_t,
106                                         bus_space_handle_t, bus_size_t,
107                                         const uint16_t *, bus_size_t);
108 static void                   mb_bus_space_write_region_4(bus_space_tag_t,
109                                         bus_space_handle_t, bus_size_t,
110                                         const uint32_t *, bus_size_t);
111 static void                   mb_bus_space_write_region_8(bus_space_tag_t,
112                                         bus_space_handle_t, bus_size_t,
113                                         const uint64_t *, bus_size_t);
114 static void                   mb_bus_space_set_multi_1(bus_space_tag_t,
115                                         bus_space_handle_t, bus_size_t, uint8_t,
116                                         bus_size_t);
117 static void                   mb_bus_space_set_multi_2(bus_space_tag_t,
118                                         bus_space_handle_t, bus_size_t, uint16_t,
119                                         bus_size_t);
120 static void                   mb_bus_space_set_multi_4(bus_space_tag_t,
121                                         bus_space_handle_t, bus_size_t, uint32_t,
122                                         bus_size_t);
123 static void                   mb_bus_space_set_multi_8(bus_space_tag_t,
124                                         bus_space_handle_t, bus_size_t, uint64_t,
125                                         bus_size_t);
126 static void                   mb_bus_space_set_region_1(bus_space_tag_t,
127                                         bus_space_handle_t, bus_size_t, uint8_t,
128                                         bus_size_t);
129 static void                   mb_bus_space_set_region_2(bus_space_tag_t,
130                                         bus_space_handle_t, bus_size_t, uint16_t,
131                                         bus_size_t);
132 static void                   mb_bus_space_set_region_4(bus_space_tag_t,
133                                         bus_space_handle_t, bus_size_t, uint32_t,
134                                         bus_size_t);
135 static void                   mb_bus_space_set_region_8(bus_space_tag_t,
136                                         bus_space_handle_t, bus_size_t, uint64_t,
137                                         bus_size_t);
138 /*
139  * Calculate offset on the mainbus given a stride_shift and width_offset
140  */
141 #define calc_addr(base, off, stride, wm)          \
142           ((u_long)(base) + ((off) << (stride)) + (wm))
143 
144 #define __read_1(t, h, o)     \
145           (*((volatile uint8_t *)(calc_addr(h, o, (t)->stride, (t)->wo_1))))
146 #define __read_2(t, h, o)     \
147           (*((volatile uint16_t *)(calc_addr(h, o, (t)->stride, (t)->wo_2))))
148 #define   __read_4(t, h, o)   \
149           (*((volatile uint32_t *)(calc_addr(h, o, (t)->stride, (t)->wo_4))))
150 #define   __read_8(t, h, o)   \
151           (*((volatile uint64_t *)(calc_addr(h, o, (t)->stride, (t)->wo_8))))
152 
153 #define __write_1(t, h, o, v) \
154     *((volatile uint8_t *)(calc_addr(h, o, (t)->stride, (t)->wo_1))) = v
155 
156 #define __write_2(t, h, o, v) \
157     *((volatile uint16_t *)(calc_addr(h, o, (t)->stride, (t)->wo_2))) = v
158 
159 #define __write_4(t, h, o, v) \
160     *((volatile uint32_t *)(calc_addr(h, o, (t)->stride, (t)->wo_4))) = v
161 
162 #define __write_8(t, h, o, v) \
163     *((volatile uint64_t *)(calc_addr(h, o, (t)->stride, (t)->wo_8))) = v
164 
165 bus_space_tag_t
mb_alloc_bus_space_tag(void)166 mb_alloc_bus_space_tag(void)
167 {
168           bus_space_tag_t     mb_t;
169 
170           mb_t = kmem_zalloc(sizeof(*mb_t), KM_SLEEP);
171           mb_t->abs_p_1   = mb_bus_space_peek_1;
172           mb_t->abs_p_2   = mb_bus_space_peek_2;
173           mb_t->abs_p_4   = mb_bus_space_peek_4;
174           mb_t->abs_p_8   = mb_bus_space_peek_8;
175           mb_t->abs_r_1   = mb_bus_space_read_1;
176           mb_t->abs_r_2   = mb_bus_space_read_2;
177           mb_t->abs_r_4   = mb_bus_space_read_4;
178           mb_t->abs_r_8   = mb_bus_space_read_8;
179           mb_t->abs_rs_1  = mb_bus_space_read_1;
180           mb_t->abs_rs_2  = mb_bus_space_read_2;
181           mb_t->abs_rs_4  = mb_bus_space_read_4;
182           mb_t->abs_rs_8  = mb_bus_space_read_8;
183           mb_t->abs_rm_1  = mb_bus_space_read_multi_1;
184           mb_t->abs_rm_2  = mb_bus_space_read_multi_2;
185           mb_t->abs_rm_4  = mb_bus_space_read_multi_4;
186           mb_t->abs_rm_8  = mb_bus_space_read_multi_8;
187           mb_t->abs_rms_1 = mb_bus_space_read_multi_1;
188           mb_t->abs_rms_2 = mb_bus_space_read_multi_2;
189           mb_t->abs_rms_4 = mb_bus_space_read_multi_4;
190           mb_t->abs_rms_8 = mb_bus_space_read_multi_8;
191           mb_t->abs_rr_1  = mb_bus_space_read_region_1;
192           mb_t->abs_rr_2  = mb_bus_space_read_region_2;
193           mb_t->abs_rr_4  = mb_bus_space_read_region_4;
194           mb_t->abs_rr_8  = mb_bus_space_read_region_8;
195           mb_t->abs_rrs_1 = mb_bus_space_read_region_1;
196           mb_t->abs_rrs_2 = mb_bus_space_read_region_2;
197           mb_t->abs_rrs_4 = mb_bus_space_read_region_4;
198           mb_t->abs_rrs_8 = mb_bus_space_read_region_8;
199           mb_t->abs_w_1   = mb_bus_space_write_1;
200           mb_t->abs_w_2   = mb_bus_space_write_2;
201           mb_t->abs_w_4   = mb_bus_space_write_4;
202           mb_t->abs_w_8   = mb_bus_space_write_8;
203           mb_t->abs_ws_1  = mb_bus_space_write_1;
204           mb_t->abs_ws_2  = mb_bus_space_write_2;
205           mb_t->abs_ws_4  = mb_bus_space_write_4;
206           mb_t->abs_ws_8  = mb_bus_space_write_8;
207           mb_t->abs_wm_1  = mb_bus_space_write_multi_1;
208           mb_t->abs_wm_2  = mb_bus_space_write_multi_2;
209           mb_t->abs_wm_4  = mb_bus_space_write_multi_4;
210           mb_t->abs_wm_8  = mb_bus_space_write_multi_8;
211           mb_t->abs_wms_1 = mb_bus_space_write_multi_1;
212           mb_t->abs_wms_2 = mb_bus_space_write_multi_2;
213           mb_t->abs_wms_4 = mb_bus_space_write_multi_4;
214           mb_t->abs_wms_8 = mb_bus_space_write_multi_8;
215           mb_t->abs_wr_1  = mb_bus_space_write_region_1;
216           mb_t->abs_wr_2  = mb_bus_space_write_region_2;
217           mb_t->abs_wr_4  = mb_bus_space_write_region_4;
218           mb_t->abs_wr_8  = mb_bus_space_write_region_8;
219           mb_t->abs_wrs_1 = mb_bus_space_write_region_1;
220           mb_t->abs_wrs_2 = mb_bus_space_write_region_2;
221           mb_t->abs_wrs_4 = mb_bus_space_write_region_4;
222           mb_t->abs_wrs_8 = mb_bus_space_write_region_8;
223           mb_t->abs_sm_1  = mb_bus_space_set_multi_1;
224           mb_t->abs_sm_2  = mb_bus_space_set_multi_2;
225           mb_t->abs_sm_4  = mb_bus_space_set_multi_4;
226           mb_t->abs_sm_8  = mb_bus_space_set_multi_8;
227           mb_t->abs_sr_1  = mb_bus_space_set_region_1;
228           mb_t->abs_sr_2  = mb_bus_space_set_region_2;
229           mb_t->abs_sr_4  = mb_bus_space_set_region_4;
230           mb_t->abs_sr_8  = mb_bus_space_set_region_8;
231 
232           return mb_t;
233 }
234 
235 void
mb_free_bus_space_tag(bus_space_tag_t mb_t)236 mb_free_bus_space_tag(bus_space_tag_t mb_t)
237 {
238 
239           kmem_free(mb_t, sizeof(*mb_t));
240 }
241 
242 static int
mb_bus_space_peek_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)243 mb_bus_space_peek_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
244 {
245 
246           return !badbaddr((void *)(calc_addr(h, o, t->stride, t->wo_1)), 1);
247 }
248 
249 static int
mb_bus_space_peek_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)250 mb_bus_space_peek_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
251 {
252 
253           return !badbaddr((void *)(calc_addr(h, o, t->stride, t->wo_2)), 2);
254 }
255 
256 static int
mb_bus_space_peek_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)257 mb_bus_space_peek_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
258 {
259 
260           return !badbaddr((void *)(calc_addr(h, o, t->stride, t->wo_4)), 4);
261 }
262 
263 static int
mb_bus_space_peek_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)264 mb_bus_space_peek_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
265 {
266 
267           return !badbaddr((void *)(calc_addr(h, o, t->stride, t->wo_8)), 8);
268 }
269 
270 static uint8_t
mb_bus_space_read_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)271 mb_bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
272 {
273 
274           return __read_1(t, h, o);
275 }
276 
277 static uint16_t
mb_bus_space_read_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)278 mb_bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
279 {
280 
281           return __read_2(t, h, o);
282 }
283 
284 static uint32_t
mb_bus_space_read_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)285 mb_bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
286 {
287 
288           return __read_4(t, h, o);
289 }
290 
291 static uint64_t
mb_bus_space_read_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)292 mb_bus_space_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
293 {
294 
295           return __read_8(t, h, o);
296 }
297 
298 static void
mb_bus_space_write_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint8_t v)299 mb_bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
300     uint8_t v)
301 {
302 
303           __write_1(t, h, o, v);
304 }
305 
306 static void
mb_bus_space_write_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t v)307 mb_bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
308     uint16_t v)
309 {
310 
311           __write_2(t, h, o, v);
312 }
313 
314 static void
mb_bus_space_write_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t v)315 mb_bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
316     uint32_t v)
317 {
318 
319           __write_4(t, h, o, v);
320 }
321 
322 static void
mb_bus_space_write_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t v)323 mb_bus_space_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
324     uint64_t v)
325 {
326 
327           __write_8(t, h, o, v);
328 }
329 
330 
331 static void
mb_bus_space_read_multi_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint8_t * a,bus_size_t c)332 mb_bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h,
333     bus_size_t o, uint8_t *a, bus_size_t c)
334 {
335           volatile uint8_t    *ba;
336 
337           ba = (volatile uint8_t *)calc_addr(h, o, t->stride, t->wo_1);
338           for (; c; a++, c--)
339                     *a = *ba;
340 }
341 
342 static void
mb_bus_space_read_multi_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t * a,bus_size_t c)343 mb_bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h,
344     bus_size_t o, uint16_t *a, bus_size_t c)
345 {
346           volatile uint16_t   *ba;
347 
348           ba = (volatile uint16_t *)calc_addr(h, o, t->stride, t->wo_2);
349           for (; c; a++, c--)
350                     *a = *ba;
351 }
352 
353 static void
mb_bus_space_read_multi_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t * a,bus_size_t c)354 mb_bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h,
355     bus_size_t o, uint32_t *a, bus_size_t c)
356 {
357           volatile uint32_t   *ba;
358 
359           ba = (volatile uint32_t *)calc_addr(h, o, t->stride, t->wo_4);
360           for (; c; a++, c--)
361                     *a = *ba;
362 }
363 
364 static void
mb_bus_space_read_multi_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t * a,bus_size_t c)365 mb_bus_space_read_multi_8(bus_space_tag_t t, bus_space_handle_t h,
366     bus_size_t o, uint64_t *a, bus_size_t c)
367 {
368           volatile uint64_t   *ba;
369 
370           ba = (volatile uint64_t *)calc_addr(h, o, t->stride, t->wo_8);
371           for (; c; a++, c--)
372                     *a = *ba;
373 }
374 
375 static void
mb_bus_space_write_multi_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint8_t * a,bus_size_t c)376 mb_bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h,
377     bus_size_t o, const uint8_t *a, bus_size_t c)
378 {
379           volatile uint8_t    *ba;
380 
381           ba = (volatile uint8_t *)calc_addr(h, o, t->stride, t->wo_1);
382           for (; c; a++, c--)
383                     *ba = *a;
384 }
385 
386 static void
mb_bus_space_write_multi_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint16_t * a,bus_size_t c)387 mb_bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h,
388     bus_size_t o, const uint16_t *a, bus_size_t c)
389 {
390           volatile uint16_t   *ba;
391 
392           ba = (volatile uint16_t *)calc_addr(h, o, t->stride, t->wo_2);
393           for (; c; a++, c--)
394                     *ba = *a;
395 }
396 
397 static void
mb_bus_space_write_multi_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint32_t * a,bus_size_t c)398 mb_bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h,
399     bus_size_t o, const uint32_t *a, bus_size_t c)
400 {
401           volatile uint32_t   *ba;
402 
403           ba = (volatile uint32_t *)calc_addr(h, o, t->stride, t->wo_4);
404           for (; c; a++, c--)
405                     *ba = *a;
406 }
407 
408 static void
mb_bus_space_write_multi_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint64_t * a,bus_size_t c)409 mb_bus_space_write_multi_8(bus_space_tag_t t, bus_space_handle_t h,
410     bus_size_t o, const uint64_t *a, bus_size_t c)
411 {
412           volatile uint64_t   *ba;
413 
414           ba = (volatile uint64_t *)calc_addr(h, o, t->stride, t->wo_8);
415           for (; c; a++, c--)
416                     *ba = *a;
417 }
418 
419 /*
420  *        void bus_space_read_region_N(bus_space_tag_t tag,
421  *                  bus_space_handle_t bsh, bus_size_t offset,
422  *                  uintN_t *addr, size_t count);
423  *
424  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
425  * described by tag/handle and starting at `offset' and copy into
426  * buffer provided.
427  */
428 static void
mb_bus_space_read_region_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint8_t * a,bus_size_t c)429 mb_bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h,
430     bus_size_t o, uint8_t *a, bus_size_t c)
431 {
432 
433           for (; c; a++, o++, c--)
434                     *a = __read_1(t, h, o);
435 }
436 
437 static void
mb_bus_space_read_region_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t * a,bus_size_t c)438 mb_bus_space_read_region_2(bus_space_tag_t t, bus_space_handle_t h,
439     bus_size_t o, uint16_t *a, bus_size_t c)
440 {
441 
442           for (; c; a++, o += 2, c--)
443                     *a = __read_2(t, h, o);
444 }
445 
446 static void
mb_bus_space_read_region_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t * a,bus_size_t c)447 mb_bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h,
448     bus_size_t o, uint32_t *a, bus_size_t c)
449 {
450 
451           for (; c; a++, o += 4, c--)
452                     *a = __read_4(t, h, o);
453 }
454 
455 static void
mb_bus_space_read_region_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t * a,bus_size_t c)456 mb_bus_space_read_region_8(bus_space_tag_t t, bus_space_handle_t h,
457     bus_size_t o, uint64_t *a, bus_size_t c)
458 {
459 
460           for (; c; a++, o += 8, c--)
461                     *a = __read_8(t, h, o);
462 }
463 
464 /*
465  *        void bus_space_write_region_N(bus_space_tag_t tag,
466  *                  bus_space_handle_t bsh, bus_size_t offset,
467  *                  uintN_t *addr, size_t count);
468  *
469  * Copy `count' 1, 2, 4, or 8 byte quantities from the buffer provided
470  * into the bus space described by tag/handle and starting at `offset'.
471  */
472 static void
mb_bus_space_write_region_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint8_t * a,bus_size_t c)473 mb_bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h,
474     bus_size_t o, const uint8_t *a, bus_size_t c)
475 {
476 
477           for (; c; a++, o++, c--)
478                     __write_1(t, h, o, *a);
479 }
480 
481 static void
mb_bus_space_write_region_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint16_t * a,bus_size_t c)482 mb_bus_space_write_region_2(bus_space_tag_t t, bus_space_handle_t h,
483     bus_size_t o, const uint16_t *a, bus_size_t c)
484 {
485 
486           for (; c; a++, o += 2, c--)
487                     __write_2(t, h, o, *a);
488 }
489 
490 static void
mb_bus_space_write_region_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint32_t * a,bus_size_t c)491 mb_bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h,
492     bus_size_t o, const uint32_t *a, bus_size_t c)
493 {
494 
495           for (; c; a++, o += 4, c--)
496                     __write_4(t, h, o, *a);
497 }
498 
499 static void
mb_bus_space_write_region_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,const uint64_t * a,bus_size_t c)500 mb_bus_space_write_region_8(bus_space_tag_t t, bus_space_handle_t h,
501     bus_size_t o, const uint64_t *a, bus_size_t c)
502 {
503 
504           for (; c; a++, o += 8, c--)
505                     __write_8(t, h, o, *a);
506 }
507 
508 /*
509  *        void bus_space_set_multi_N(bus_space_tag_t tag,
510  *                  bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
511  *                  size_t count);
512  *
513  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
514  * by tag/handle/offset `count' times.
515  */
516 
517 static void
mb_bus_space_set_multi_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint8_t v,bus_size_t c)518 mb_bus_space_set_multi_1(bus_space_tag_t t, bus_space_handle_t h,
519     bus_size_t o, uint8_t v, bus_size_t c)
520 {
521           volatile uint8_t    *ba;
522 
523           ba = (volatile uint8_t *)calc_addr(h, o, t->stride, t->wo_1);
524           for (; c; c--)
525                     *ba = v;
526 }
527 
528 static void
mb_bus_space_set_multi_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t v,bus_size_t c)529 mb_bus_space_set_multi_2(bus_space_tag_t t, bus_space_handle_t h,
530     bus_size_t o, uint16_t v, bus_size_t c)
531 {
532           volatile uint16_t   *ba;
533 
534           ba = (volatile uint16_t *)calc_addr(h, o, t->stride, t->wo_2);
535           for (; c; c--)
536                     *ba = v;
537 }
538 
539 static void
mb_bus_space_set_multi_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t v,bus_size_t c)540 mb_bus_space_set_multi_4(bus_space_tag_t t, bus_space_handle_t h,
541     bus_size_t o, uint32_t v, bus_size_t c)
542 {
543           volatile uint32_t   *ba;
544 
545           ba = (volatile uint32_t *)calc_addr(h, o, t->stride, t->wo_4);
546           for (; c; c--)
547                     *ba = v;
548 }
549 
550 static void
mb_bus_space_set_multi_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t v,bus_size_t c)551 mb_bus_space_set_multi_8(bus_space_tag_t t, bus_space_handle_t h,
552     bus_size_t o, uint64_t v, bus_size_t c)
553 {
554           volatile uint64_t   *ba;
555 
556           ba = (volatile uint64_t *)calc_addr(h, o, t->stride, t->wo_8);
557           for (; c; c--)
558                     *ba = v;
559 }
560 
561 /*
562  *        void bus_space_set_region_N(bus_space_tag_t tag,
563  *                  bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
564  *                  size_t count);
565  *
566  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
567  * by tag/handle starting at `offset'.
568  */
569 static void
mb_bus_space_set_region_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint8_t v,bus_size_t c)570 mb_bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h,
571     bus_size_t o, uint8_t v, bus_size_t c)
572 {
573 
574           for (; c; o++, c--)
575                     __write_1(t, h, o, v);
576 }
577 
578 static void
mb_bus_space_set_region_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint16_t v,bus_size_t c)579 mb_bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h,
580     bus_size_t o, uint16_t v, bus_size_t c)
581 {
582 
583           for (; c; o += 2, c--)
584                     __write_2(t, h, o, v);
585 }
586 
587 static void
mb_bus_space_set_region_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint32_t v,bus_size_t c)588 mb_bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h,
589     bus_size_t o, uint32_t v, bus_size_t c)
590 {
591 
592           for (; c; o += 4, c--)
593                     __write_4(t, h, o, v);
594 }
595 
596 static void
mb_bus_space_set_region_8(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o,uint64_t v,bus_size_t c)597 mb_bus_space_set_region_8(bus_space_tag_t t, bus_space_handle_t h,
598     bus_size_t o, uint64_t v, bus_size_t c)
599 {
600 
601           for (; c; o += 8, c--)
602                     __write_8(t, h, o, v);
603 }
604