xref: /freebsd/sys/powerpc/powerpc/bus_machdep.c (revision f05cddf9)
1 /*-
2  * Copyright (c) 2006 Semihalf, Rafal Jaworowski <raj@semihalf.com>
3  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to The NetBSD Foundation
7  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
8  * NASA Ames Research Center.
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 
39 #include <sys/cdefs.h>
40 __FBSDID("$FreeBSD$");
41 
42 #define	KTR_BE_IO	0
43 #define	KTR_LE_IO	0
44 
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/bus.h>
48 #include <sys/ktr.h>
49 #include <vm/vm.h>
50 #include <vm/pmap.h>
51 
52 #include <machine/bus.h>
53 #include <machine/pio.h>
54 #include <machine/md_var.h>
55 
56 #define TODO panic("%s: not implemented", __func__)
57 
58 #define	MAX_EARLYBOOT_MAPPINGS	6
59 
60 static struct {
61 	bus_addr_t addr;
62 	bus_size_t size;
63 	int flags;
64 } earlyboot_mappings[MAX_EARLYBOOT_MAPPINGS];
65 static int earlyboot_map_idx = 0;
66 
67 void bs_remap_earlyboot(void);
68 
69 static __inline void *
70 __ppc_ba(bus_space_handle_t bsh, bus_size_t ofs)
71 {
72 	return ((void *)(bsh + ofs));
73 }
74 
75 static int
76 bs_gen_map(bus_addr_t addr, bus_size_t size, int flags,
77     bus_space_handle_t *bshp)
78 {
79 	vm_memattr_t ma;
80 
81 	/*
82 	 * Record what we did if we haven't enabled the MMU yet. We
83 	 * will need to remap it as soon as the MMU comes up.
84 	 */
85 	if (!pmap_bootstrapped) {
86 		KASSERT(earlyboot_map_idx < MAX_EARLYBOOT_MAPPINGS,
87 		    ("%s: too many early boot mapping requests", __func__));
88 		earlyboot_mappings[earlyboot_map_idx].addr = addr;
89 		earlyboot_mappings[earlyboot_map_idx].size = size;
90 		earlyboot_mappings[earlyboot_map_idx].flags = flags;
91 		earlyboot_map_idx++;
92 		*bshp = addr;
93 	} else {
94 		ma = VM_MEMATTR_DEFAULT;
95 		switch (flags) {
96 			case BUS_SPACE_MAP_CACHEABLE:
97 				ma = VM_MEMATTR_CACHEABLE;
98 				break;
99 			case BUS_SPACE_MAP_PREFETCHABLE:
100 				ma = VM_MEMATTR_PREFETCHABLE;
101 				break;
102 		}
103 		*bshp = (bus_space_handle_t)pmap_mapdev_attr(addr, size, ma);
104 	}
105 
106 	return (0);
107 }
108 
109 void
110 bs_remap_earlyboot(void)
111 {
112 	int i;
113 	vm_offset_t pa, spa;
114 	vm_memattr_t ma;
115 
116 	for (i = 0; i < earlyboot_map_idx; i++) {
117 		spa = earlyboot_mappings[i].addr;
118 		if (pmap_dev_direct_mapped(spa, earlyboot_mappings[i].size)
119 		    == 0)
120 			continue;
121 
122 		ma = VM_MEMATTR_DEFAULT;
123 		switch (earlyboot_mappings[i].flags) {
124 			case BUS_SPACE_MAP_CACHEABLE:
125 				ma = VM_MEMATTR_CACHEABLE;
126 				break;
127 			case BUS_SPACE_MAP_PREFETCHABLE:
128 				ma = VM_MEMATTR_PREFETCHABLE;
129 				break;
130 		}
131 
132 		pa = trunc_page(spa);
133 		while (pa < spa + earlyboot_mappings[i].size) {
134 			pmap_kenter_attr(pa, pa, ma);
135 			pa += PAGE_SIZE;
136 		}
137 	}
138 }
139 
140 static void
141 bs_gen_unmap(bus_size_t size __unused)
142 {
143 }
144 
145 static int
146 bs_gen_subregion(bus_space_handle_t bsh, bus_size_t ofs,
147     bus_size_t size __unused, bus_space_handle_t *nbshp)
148 {
149 	*nbshp = bsh + ofs;
150 	return (0);
151 }
152 
153 static int
154 bs_gen_alloc(bus_addr_t rstart __unused, bus_addr_t rend __unused,
155     bus_size_t size __unused, bus_size_t alignment __unused,
156     bus_size_t boundary __unused, int flags __unused,
157     bus_addr_t *bpap __unused, bus_space_handle_t *bshp __unused)
158 {
159 	TODO;
160 }
161 
162 static void
163 bs_gen_free(bus_space_handle_t bsh __unused, bus_size_t size __unused)
164 {
165 	TODO;
166 }
167 
168 static void
169 bs_gen_barrier(bus_space_handle_t bsh __unused, bus_size_t ofs __unused,
170     bus_size_t size __unused, int flags __unused)
171 {
172 
173 	powerpc_iomb();
174 }
175 
176 /*
177  * Big-endian access functions
178  */
179 static uint8_t
180 bs_be_rs_1(bus_space_handle_t bsh, bus_size_t ofs)
181 {
182 	volatile uint8_t *addr;
183 	uint8_t res;
184 
185 	addr = __ppc_ba(bsh, ofs);
186 	res = *addr;
187 	powerpc_iomb();
188 	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
189 	return (res);
190 }
191 
192 static uint16_t
193 bs_be_rs_2(bus_space_handle_t bsh, bus_size_t ofs)
194 {
195 	volatile uint16_t *addr;
196 	uint16_t res;
197 
198 	addr = __ppc_ba(bsh, ofs);
199 	res = *addr;
200 	powerpc_iomb();
201 	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
202 	return (res);
203 }
204 
205 static uint32_t
206 bs_be_rs_4(bus_space_handle_t bsh, bus_size_t ofs)
207 {
208 	volatile uint32_t *addr;
209 	uint32_t res;
210 
211 	addr = __ppc_ba(bsh, ofs);
212 	res = *addr;
213 	powerpc_iomb();
214 	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
215 	return (res);
216 }
217 
218 static uint64_t
219 bs_be_rs_8(bus_space_handle_t bsh, bus_size_t ofs)
220 {
221 	volatile uint64_t *addr;
222 	uint64_t res;
223 
224 	addr = __ppc_ba(bsh, ofs);
225 	res = *addr;
226 	powerpc_iomb();
227 	return (res);
228 }
229 
230 static void
231 bs_be_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
232 {
233 	ins8(__ppc_ba(bsh, ofs), addr, cnt);
234 }
235 
236 static void
237 bs_be_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
238 {
239 	ins16(__ppc_ba(bsh, ofs), addr, cnt);
240 }
241 
242 static void
243 bs_be_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
244 {
245 	ins32(__ppc_ba(bsh, ofs), addr, cnt);
246 }
247 
248 static void
249 bs_be_rm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
250 {
251 	ins64(__ppc_ba(bsh, ofs), addr, cnt);
252 }
253 
254 static void
255 bs_be_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
256 {
257 	volatile uint8_t *s = __ppc_ba(bsh, ofs);
258 
259 	while (cnt--)
260 		*addr++ = *s++;
261 	powerpc_iomb();
262 }
263 
264 static void
265 bs_be_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
266 {
267 	volatile uint16_t *s = __ppc_ba(bsh, ofs);
268 
269 	while (cnt--)
270 		*addr++ = *s++;
271 	powerpc_iomb();
272 }
273 
274 static void
275 bs_be_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
276 {
277 	volatile uint32_t *s = __ppc_ba(bsh, ofs);
278 
279 	while (cnt--)
280 		*addr++ = *s++;
281 	powerpc_iomb();
282 }
283 
284 static void
285 bs_be_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
286 {
287 	volatile uint64_t *s = __ppc_ba(bsh, ofs);
288 
289 	while (cnt--)
290 		*addr++ = *s++;
291 	powerpc_iomb();
292 }
293 
294 static void
295 bs_be_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val)
296 {
297 	volatile uint8_t *addr;
298 
299 	addr = __ppc_ba(bsh, ofs);
300 	*addr = val;
301 	powerpc_iomb();
302 	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
303 }
304 
305 static void
306 bs_be_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val)
307 {
308 	volatile uint16_t *addr;
309 
310 	addr = __ppc_ba(bsh, ofs);
311 	*addr = val;
312 	powerpc_iomb();
313 	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
314 }
315 
316 static void
317 bs_be_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val)
318 {
319 	volatile uint32_t *addr;
320 
321 	addr = __ppc_ba(bsh, ofs);
322 	*addr = val;
323 	powerpc_iomb();
324 	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
325 }
326 
327 static void
328 bs_be_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val)
329 {
330 	volatile uint64_t *addr;
331 
332 	addr = __ppc_ba(bsh, ofs);
333 	*addr = val;
334 	powerpc_iomb();
335 }
336 
337 static void
338 bs_be_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
339     bus_size_t cnt)
340 {
341 	outsb(__ppc_ba(bsh, ofs), addr, cnt);
342 }
343 
344 static void
345 bs_be_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
346     bus_size_t cnt)
347 {
348 	outsw(__ppc_ba(bsh, ofs), addr, cnt);
349 }
350 
351 static void
352 bs_be_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
353     bus_size_t cnt)
354 {
355 	outsl(__ppc_ba(bsh, ofs), addr, cnt);
356 }
357 
358 static void
359 bs_be_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
360     bus_size_t cnt)
361 {
362 	outsll(__ppc_ba(bsh, ofs), addr, cnt);
363 }
364 
365 static void
366 bs_be_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
367     size_t cnt)
368 {
369 	volatile uint8_t *d = __ppc_ba(bsh, ofs);
370 
371 	while (cnt--)
372 		*d++ = *addr++;
373 	powerpc_iomb();
374 }
375 
376 static void
377 bs_be_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
378     size_t cnt)
379 {
380 	volatile uint16_t *d = __ppc_ba(bsh, ofs);
381 
382 	while (cnt--)
383 		*d++ = *addr++;
384 	powerpc_iomb();
385 }
386 
387 static void
388 bs_be_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
389     size_t cnt)
390 {
391 	volatile uint32_t *d = __ppc_ba(bsh, ofs);
392 
393 	while (cnt--)
394 		*d++ = *addr++;
395 	powerpc_iomb();
396 }
397 
398 static void
399 bs_be_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
400     size_t cnt)
401 {
402 	volatile uint64_t *d = __ppc_ba(bsh, ofs);
403 
404 	while (cnt--)
405 		*d++ = *addr++;
406 	powerpc_iomb();
407 }
408 
409 static void
410 bs_be_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
411 {
412 	volatile uint8_t *d = __ppc_ba(bsh, ofs);
413 
414 	while (cnt--)
415 		*d = val;
416 	powerpc_iomb();
417 }
418 
419 static void
420 bs_be_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
421 {
422 	volatile uint16_t *d = __ppc_ba(bsh, ofs);
423 
424 	while (cnt--)
425 		*d = val;
426 	powerpc_iomb();
427 }
428 
429 static void
430 bs_be_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
431 {
432 	volatile uint32_t *d = __ppc_ba(bsh, ofs);
433 
434 	while (cnt--)
435 		*d = val;
436 	powerpc_iomb();
437 }
438 
439 static void
440 bs_be_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
441 {
442 	volatile uint64_t *d = __ppc_ba(bsh, ofs);
443 
444 	while (cnt--)
445 		*d = val;
446 	powerpc_iomb();
447 }
448 
449 static void
450 bs_be_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
451 {
452 	volatile uint8_t *d = __ppc_ba(bsh, ofs);
453 
454 	while (cnt--)
455 		*d++ = val;
456 	powerpc_iomb();
457 }
458 
459 static void
460 bs_be_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
461 {
462 	volatile uint16_t *d = __ppc_ba(bsh, ofs);
463 
464 	while (cnt--)
465 		*d++ = val;
466 	powerpc_iomb();
467 }
468 
469 static void
470 bs_be_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
471 {
472 	volatile uint32_t *d = __ppc_ba(bsh, ofs);
473 
474 	while (cnt--)
475 		*d++ = val;
476 	powerpc_iomb();
477 }
478 
479 static void
480 bs_be_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
481 {
482 	volatile uint64_t *d = __ppc_ba(bsh, ofs);
483 
484 	while (cnt--)
485 		*d++ = val;
486 	powerpc_iomb();
487 }
488 
489 /*
490  * Little-endian access functions
491  */
492 static uint8_t
493 bs_le_rs_1(bus_space_handle_t bsh, bus_size_t ofs)
494 {
495 	volatile uint8_t *addr;
496 	uint8_t res;
497 
498 	addr = __ppc_ba(bsh, ofs);
499 	res = *addr;
500 	powerpc_iomb();
501 	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
502 	return (res);
503 }
504 
505 static uint16_t
506 bs_le_rs_2(bus_space_handle_t bsh, bus_size_t ofs)
507 {
508 	volatile uint16_t *addr;
509 	uint16_t res;
510 
511 	addr = __ppc_ba(bsh, ofs);
512 	__asm __volatile("lhbrx %0, 0, %1" : "=r"(res) : "r"(addr));
513 	powerpc_iomb();
514 	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
515 	return (res);
516 }
517 
518 static uint32_t
519 bs_le_rs_4(bus_space_handle_t bsh, bus_size_t ofs)
520 {
521 	volatile uint32_t *addr;
522 	uint32_t res;
523 
524 	addr = __ppc_ba(bsh, ofs);
525 	__asm __volatile("lwbrx %0, 0, %1" : "=r"(res) : "r"(addr));
526 	powerpc_iomb();
527 	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
528 	return (res);
529 }
530 
531 static uint64_t
532 bs_le_rs_8(bus_space_handle_t bsh, bus_size_t ofs)
533 {
534 	TODO;
535 }
536 
537 static void
538 bs_le_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
539 {
540 	ins8(__ppc_ba(bsh, ofs), addr, cnt);
541 }
542 
543 static void
544 bs_le_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
545 {
546 	ins16rb(__ppc_ba(bsh, ofs), addr, cnt);
547 }
548 
549 static void
550 bs_le_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
551 {
552 	ins32rb(__ppc_ba(bsh, ofs), addr, cnt);
553 }
554 
555 static void
556 bs_le_rm_8(bus_space_handle_t bshh, bus_size_t ofs, uint64_t *addr, size_t cnt)
557 {
558 	TODO;
559 }
560 
561 static void
562 bs_le_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
563 {
564 	volatile uint8_t *s = __ppc_ba(bsh, ofs);
565 
566 	while (cnt--)
567 		*addr++ = *s++;
568 	powerpc_iomb();
569 }
570 
571 static void
572 bs_le_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
573 {
574 	volatile uint16_t *s = __ppc_ba(bsh, ofs);
575 
576 	while (cnt--)
577 		*addr++ = in16rb(s++);
578 	powerpc_iomb();
579 }
580 
581 static void
582 bs_le_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
583 {
584 	volatile uint32_t *s = __ppc_ba(bsh, ofs);
585 
586 	while (cnt--)
587 		*addr++ = in32rb(s++);
588 	powerpc_iomb();
589 }
590 
591 static void
592 bs_le_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
593 {
594 	TODO;
595 }
596 
597 static void
598 bs_le_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val)
599 {
600 	volatile uint8_t *addr;
601 
602 	addr = __ppc_ba(bsh, ofs);
603 	*addr = val;
604 	powerpc_iomb();
605 	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
606 }
607 
608 static void
609 bs_le_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val)
610 {
611 	volatile uint16_t *addr;
612 
613 	addr = __ppc_ba(bsh, ofs);
614 	__asm __volatile("sthbrx %0, 0, %1" :: "r"(val), "r"(addr));
615 	powerpc_iomb();
616 	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
617 }
618 
619 static void
620 bs_le_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val)
621 {
622 	volatile uint32_t *addr;
623 
624 	addr = __ppc_ba(bsh, ofs);
625 	__asm __volatile("stwbrx %0, 0, %1" :: "r"(val), "r"(addr));
626 	powerpc_iomb();
627 	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
628 }
629 
630 static void
631 bs_le_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val)
632 {
633 	TODO;
634 }
635 
636 static void
637 bs_le_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
638     bus_size_t cnt)
639 {
640 	outs8(__ppc_ba(bsh, ofs), addr, cnt);
641 }
642 
643 static void
644 bs_le_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
645     bus_size_t cnt)
646 {
647 	outs16rb(__ppc_ba(bsh, ofs), addr, cnt);
648 }
649 
650 static void
651 bs_le_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
652     bus_size_t cnt)
653 {
654 	outs32rb(__ppc_ba(bsh, ofs), addr, cnt);
655 }
656 
657 static void
658 bs_le_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
659     bus_size_t cnt)
660 {
661 	TODO;
662 }
663 
664 static void
665 bs_le_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
666     size_t cnt)
667 {
668 	volatile uint8_t *d = __ppc_ba(bsh, ofs);
669 
670 	while (cnt--)
671 		*d++ = *addr++;
672 	powerpc_iomb();
673 }
674 
675 static void
676 bs_le_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
677     size_t cnt)
678 {
679 	volatile uint16_t *d = __ppc_ba(bsh, ofs);
680 
681 	while (cnt--)
682 		out16rb(d++, *addr++);
683 	powerpc_iomb();
684 }
685 
686 static void
687 bs_le_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
688     size_t cnt)
689 {
690 	volatile uint32_t *d = __ppc_ba(bsh, ofs);
691 
692 	while (cnt--)
693 		out32rb(d++, *addr++);
694 	powerpc_iomb();
695 }
696 
697 static void
698 bs_le_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
699     size_t cnt)
700 {
701 	TODO;
702 }
703 
704 static void
705 bs_le_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
706 {
707 	volatile uint8_t *d = __ppc_ba(bsh, ofs);
708 
709 	while (cnt--)
710 		*d = val;
711 	powerpc_iomb();
712 }
713 
714 static void
715 bs_le_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
716 {
717 	volatile uint16_t *d = __ppc_ba(bsh, ofs);
718 
719 	while (cnt--)
720 		out16rb(d, val);
721 	powerpc_iomb();
722 }
723 
724 static void
725 bs_le_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
726 {
727 	volatile uint32_t *d = __ppc_ba(bsh, ofs);
728 
729 	while (cnt--)
730 		out32rb(d, val);
731 	powerpc_iomb();
732 }
733 
734 static void
735 bs_le_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
736 {
737 	TODO;
738 }
739 
740 static void
741 bs_le_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
742 {
743 	volatile uint8_t *d = __ppc_ba(bsh, ofs);
744 
745 	while (cnt--)
746 		*d++ = val;
747 	powerpc_iomb();
748 }
749 
750 static void
751 bs_le_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
752 {
753 	volatile uint16_t *d = __ppc_ba(bsh, ofs);
754 
755 	while (cnt--)
756 		out16rb(d++, val);
757 	powerpc_iomb();
758 }
759 
760 static void
761 bs_le_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
762 {
763 	volatile uint32_t *d = __ppc_ba(bsh, ofs);
764 
765 	while (cnt--)
766 		out32rb(d++, val);
767 	powerpc_iomb();
768 }
769 
770 static void
771 bs_le_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
772 {
773 	TODO;
774 }
775 
776 struct bus_space bs_be_tag = {
777 	/* mapping/unmapping */
778 	bs_gen_map,
779 	bs_gen_unmap,
780 	bs_gen_subregion,
781 
782 	/* allocation/deallocation */
783 	bs_gen_alloc,
784 	bs_gen_free,
785 
786 	/* barrier */
787 	bs_gen_barrier,
788 
789 	/* read (single) */
790 	bs_be_rs_1,
791 	bs_be_rs_2,
792 	bs_be_rs_4,
793 	bs_be_rs_8,
794 
795 	bs_be_rs_2,
796 	bs_be_rs_4,
797 	bs_be_rs_8,
798 
799 	/* read multiple */
800 	bs_be_rm_1,
801 	bs_be_rm_2,
802 	bs_be_rm_4,
803 	bs_be_rm_8,
804 
805 	bs_be_rm_2,
806 	bs_be_rm_4,
807 	bs_be_rm_8,
808 
809 	/* read region */
810 	bs_be_rr_1,
811 	bs_be_rr_2,
812 	bs_be_rr_4,
813 	bs_be_rr_8,
814 
815 	bs_be_rr_2,
816 	bs_be_rr_4,
817 	bs_be_rr_8,
818 
819 	/* write (single) */
820 	bs_be_ws_1,
821 	bs_be_ws_2,
822 	bs_be_ws_4,
823 	bs_be_ws_8,
824 
825 	bs_be_ws_2,
826 	bs_be_ws_4,
827 	bs_be_ws_8,
828 
829 	/* write multiple */
830 	bs_be_wm_1,
831 	bs_be_wm_2,
832 	bs_be_wm_4,
833 	bs_be_wm_8,
834 
835 	bs_be_wm_2,
836 	bs_be_wm_4,
837 	bs_be_wm_8,
838 
839 	/* write region */
840 	bs_be_wr_1,
841 	bs_be_wr_2,
842 	bs_be_wr_4,
843 	bs_be_wr_8,
844 
845 	bs_be_wr_2,
846 	bs_be_wr_4,
847 	bs_be_wr_8,
848 
849 	/* set multiple */
850 	bs_be_sm_1,
851 	bs_be_sm_2,
852 	bs_be_sm_4,
853 	bs_be_sm_8,
854 
855 	bs_be_sm_2,
856 	bs_be_sm_4,
857 	bs_be_sm_8,
858 
859 	/* set region */
860 	bs_be_sr_1,
861 	bs_be_sr_2,
862 	bs_be_sr_4,
863 	bs_be_sr_8,
864 
865 	bs_be_sr_2,
866 	bs_be_sr_4,
867 	bs_be_sr_8,
868 };
869 
870 struct bus_space bs_le_tag = {
871 	/* mapping/unmapping */
872 	bs_gen_map,
873 	bs_gen_unmap,
874 	bs_gen_subregion,
875 
876 	/* allocation/deallocation */
877 	bs_gen_alloc,
878 	bs_gen_free,
879 
880 	/* barrier */
881 	bs_gen_barrier,
882 
883 	/* read (single) */
884 	bs_le_rs_1,
885 	bs_le_rs_2,
886 	bs_le_rs_4,
887 	bs_le_rs_8,
888 
889 	bs_be_rs_2,
890 	bs_be_rs_4,
891 	bs_be_rs_8,
892 
893 	/* read multiple */
894 	bs_le_rm_1,
895 	bs_le_rm_2,
896 	bs_le_rm_4,
897 	bs_le_rm_8,
898 
899 	bs_be_rm_2,
900 	bs_be_rm_4,
901 	bs_be_rm_8,
902 
903 	/* read region */
904 	bs_le_rr_1,
905 	bs_le_rr_2,
906 	bs_le_rr_4,
907 	bs_le_rr_8,
908 
909 	bs_be_rr_2,
910 	bs_be_rr_4,
911 	bs_be_rr_8,
912 
913 	/* write (single) */
914 	bs_le_ws_1,
915 	bs_le_ws_2,
916 	bs_le_ws_4,
917 	bs_le_ws_8,
918 
919 	bs_be_ws_2,
920 	bs_be_ws_4,
921 	bs_be_ws_8,
922 
923 	/* write multiple */
924 	bs_le_wm_1,
925 	bs_le_wm_2,
926 	bs_le_wm_4,
927 	bs_le_wm_8,
928 
929 	bs_be_wm_2,
930 	bs_be_wm_4,
931 	bs_be_wm_8,
932 
933 	/* write region */
934 	bs_le_wr_1,
935 	bs_le_wr_2,
936 	bs_le_wr_4,
937 	bs_le_wr_8,
938 
939 	bs_be_wr_2,
940 	bs_be_wr_4,
941 	bs_be_wr_8,
942 
943 	/* set multiple */
944 	bs_le_sm_1,
945 	bs_le_sm_2,
946 	bs_le_sm_4,
947 	bs_le_sm_8,
948 
949 	bs_be_sm_2,
950 	bs_be_sm_4,
951 	bs_be_sm_8,
952 
953 	/* set region */
954 	bs_le_sr_1,
955 	bs_le_sr_2,
956 	bs_le_sr_4,
957 	bs_le_sr_8,
958 
959 	bs_be_sr_2,
960 	bs_be_sr_4,
961 	bs_be_sr_8,
962 };
963