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