1174782Smarcel/*-
2174782Smarcel * Copyright (c) 2006 Semihalf, Rafal Jaworowski <raj@semihalf.com>
3174782Smarcel * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
4174782Smarcel * All rights reserved.
5174782Smarcel *
6174782Smarcel * This code is derived from software contributed to The NetBSD Foundation
7174782Smarcel * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
8174782Smarcel * NASA Ames Research Center.
9174782Smarcel *
10174782Smarcel * Redistribution and use in source and binary forms, with or without
11174782Smarcel * modification, are permitted provided that the following conditions
12174782Smarcel * are met:
13174782Smarcel * 1. Redistributions of source code must retain the above copyright
14174782Smarcel *    notice, this list of conditions and the following disclaimer.
15174782Smarcel * 2. Redistributions in binary form must reproduce the above copyright
16174782Smarcel *    notice, this list of conditions and the following disclaimer in the
17174782Smarcel *    documentation and/or other materials provided with the distribution.
18174782Smarcel * 3. All advertising materials mentioning features or use of this software
19174782Smarcel *    must display the following acknowledgement:
20174782Smarcel *	This product includes software developed by the NetBSD
21174782Smarcel *	Foundation, Inc. and its contributors.
22174782Smarcel * 4. Neither the name of The NetBSD Foundation nor the names of its
23174782Smarcel *    contributors may be used to endorse or promote products derived
24174782Smarcel *    from this software without specific prior written permission.
25174782Smarcel *
26174782Smarcel * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27174782Smarcel * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28174782Smarcel * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29174782Smarcel * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30174782Smarcel * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31174782Smarcel * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32174782Smarcel * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33174782Smarcel * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34174782Smarcel * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35174782Smarcel * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36174782Smarcel * POSSIBILITY OF SUCH DAMAGE.
37174782Smarcel */
38174782Smarcel
39174782Smarcel#include <sys/cdefs.h>
40174782Smarcel__FBSDID("$FreeBSD$");
41174782Smarcel
42191447Smarcel#define	KTR_BE_IO	0
43191447Smarcel#define	KTR_LE_IO	0
44191447Smarcel
45174782Smarcel#include <sys/param.h>
46174782Smarcel#include <sys/systm.h>
47174782Smarcel#include <sys/bus.h>
48191447Smarcel#include <sys/ktr.h>
49190681Snwhitehorn#include <vm/vm.h>
50190681Snwhitehorn#include <vm/pmap.h>
51174782Smarcel
52174782Smarcel#include <machine/bus.h>
53174782Smarcel#include <machine/pio.h>
54190681Snwhitehorn#include <machine/md_var.h>
55174782Smarcel
56174782Smarcel#define TODO panic("%s: not implemented", __func__)
57174782Smarcel
58190681Snwhitehorn#define	MAX_EARLYBOOT_MAPPINGS	6
59190681Snwhitehorn
60190681Snwhitehornstatic struct {
61190681Snwhitehorn	bus_addr_t addr;
62190681Snwhitehorn	bus_size_t size;
63213307Snwhitehorn	int flags;
64190681Snwhitehorn} earlyboot_mappings[MAX_EARLYBOOT_MAPPINGS];
65190681Snwhitehornstatic int earlyboot_map_idx = 0;
66190681Snwhitehorn
67190681Snwhitehornvoid bs_remap_earlyboot(void);
68190681Snwhitehorn
69174782Smarcelstatic __inline void *
70174782Smarcel__ppc_ba(bus_space_handle_t bsh, bus_size_t ofs)
71174782Smarcel{
72174782Smarcel	return ((void *)(bsh + ofs));
73174782Smarcel}
74174782Smarcel
75174782Smarcelstatic int
76213307Snwhitehornbs_gen_map(bus_addr_t addr, bus_size_t size, int flags,
77174782Smarcel    bus_space_handle_t *bshp)
78174782Smarcel{
79213307Snwhitehorn	vm_memattr_t ma;
80213307Snwhitehorn
81190681Snwhitehorn	/*
82190681Snwhitehorn	 * Record what we did if we haven't enabled the MMU yet. We
83190681Snwhitehorn	 * will need to remap it as soon as the MMU comes up.
84190681Snwhitehorn	 */
85190681Snwhitehorn	if (!pmap_bootstrapped) {
86190681Snwhitehorn		KASSERT(earlyboot_map_idx < MAX_EARLYBOOT_MAPPINGS,
87190681Snwhitehorn		    ("%s: too many early boot mapping requests", __func__));
88190681Snwhitehorn		earlyboot_mappings[earlyboot_map_idx].addr = addr;
89190681Snwhitehorn		earlyboot_mappings[earlyboot_map_idx].size = size;
90213307Snwhitehorn		earlyboot_mappings[earlyboot_map_idx].flags = flags;
91190681Snwhitehorn		earlyboot_map_idx++;
92190681Snwhitehorn		*bshp = addr;
93190681Snwhitehorn	} else {
94213307Snwhitehorn		ma = VM_MEMATTR_DEFAULT;
95213307Snwhitehorn		switch (flags) {
96213307Snwhitehorn			case BUS_SPACE_MAP_CACHEABLE:
97213307Snwhitehorn				ma = VM_MEMATTR_CACHEABLE;
98213307Snwhitehorn				break;
99213307Snwhitehorn			case BUS_SPACE_MAP_PREFETCHABLE:
100213307Snwhitehorn				ma = VM_MEMATTR_PREFETCHABLE;
101213307Snwhitehorn				break;
102213307Snwhitehorn		}
103213307Snwhitehorn		*bshp = (bus_space_handle_t)pmap_mapdev_attr(addr, size, ma);
104190681Snwhitehorn	}
105190681Snwhitehorn
106174782Smarcel	return (0);
107174782Smarcel}
108174782Smarcel
109190681Snwhitehornvoid
110190681Snwhitehornbs_remap_earlyboot(void)
111190681Snwhitehorn{
112190681Snwhitehorn	int i;
113190681Snwhitehorn	vm_offset_t pa, spa;
114213307Snwhitehorn	vm_memattr_t ma;
115190681Snwhitehorn
116190681Snwhitehorn	for (i = 0; i < earlyboot_map_idx; i++) {
117190681Snwhitehorn		spa = earlyboot_mappings[i].addr;
118209849Snwhitehorn		if (pmap_dev_direct_mapped(spa, earlyboot_mappings[i].size)
119209849Snwhitehorn		    == 0)
120209849Snwhitehorn			continue;
121190681Snwhitehorn
122213307Snwhitehorn		ma = VM_MEMATTR_DEFAULT;
123213307Snwhitehorn		switch (earlyboot_mappings[i].flags) {
124213307Snwhitehorn			case BUS_SPACE_MAP_CACHEABLE:
125213307Snwhitehorn				ma = VM_MEMATTR_CACHEABLE;
126213307Snwhitehorn				break;
127213307Snwhitehorn			case BUS_SPACE_MAP_PREFETCHABLE:
128213307Snwhitehorn				ma = VM_MEMATTR_PREFETCHABLE;
129213307Snwhitehorn				break;
130213307Snwhitehorn		}
131213307Snwhitehorn
132190681Snwhitehorn		pa = trunc_page(spa);
133190681Snwhitehorn		while (pa < spa + earlyboot_mappings[i].size) {
134213307Snwhitehorn			pmap_kenter_attr(pa, pa, ma);
135190681Snwhitehorn			pa += PAGE_SIZE;
136190681Snwhitehorn		}
137190681Snwhitehorn	}
138190681Snwhitehorn}
139190681Snwhitehorn
140174782Smarcelstatic void
141174782Smarcelbs_gen_unmap(bus_size_t size __unused)
142174782Smarcel{
143174782Smarcel}
144174782Smarcel
145174782Smarcelstatic int
146174782Smarcelbs_gen_subregion(bus_space_handle_t bsh, bus_size_t ofs,
147174782Smarcel    bus_size_t size __unused, bus_space_handle_t *nbshp)
148174782Smarcel{
149174782Smarcel	*nbshp = bsh + ofs;
150174782Smarcel	return (0);
151174782Smarcel}
152174782Smarcel
153174782Smarcelstatic int
154174782Smarcelbs_gen_alloc(bus_addr_t rstart __unused, bus_addr_t rend __unused,
155174782Smarcel    bus_size_t size __unused, bus_size_t alignment __unused,
156174782Smarcel    bus_size_t boundary __unused, int flags __unused,
157174782Smarcel    bus_addr_t *bpap __unused, bus_space_handle_t *bshp __unused)
158174782Smarcel{
159174782Smarcel	TODO;
160174782Smarcel}
161174782Smarcel
162174782Smarcelstatic void
163174782Smarcelbs_gen_free(bus_space_handle_t bsh __unused, bus_size_t size __unused)
164174782Smarcel{
165174782Smarcel	TODO;
166174782Smarcel}
167174782Smarcel
168174782Smarcelstatic void
169174782Smarcelbs_gen_barrier(bus_space_handle_t bsh __unused, bus_size_t ofs __unused,
170174782Smarcel    bus_size_t size __unused, int flags __unused)
171174782Smarcel{
172191447Smarcel	__asm __volatile("eieio; sync" : : : "memory");
173174782Smarcel}
174174782Smarcel
175174782Smarcel/*
176174782Smarcel * Big-endian access functions
177174782Smarcel */
178174782Smarcelstatic uint8_t
179174782Smarcelbs_be_rs_1(bus_space_handle_t bsh, bus_size_t ofs)
180174782Smarcel{
181191447Smarcel	volatile uint8_t *addr;
182191447Smarcel	uint8_t res;
183191447Smarcel
184191447Smarcel	addr = __ppc_ba(bsh, ofs);
185191447Smarcel	res = *addr;
186191447Smarcel	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
187191447Smarcel	return (res);
188174782Smarcel}
189174782Smarcel
190174782Smarcelstatic uint16_t
191174782Smarcelbs_be_rs_2(bus_space_handle_t bsh, bus_size_t ofs)
192174782Smarcel{
193191447Smarcel	volatile uint16_t *addr;
194191447Smarcel	uint16_t res;
195191447Smarcel
196191447Smarcel	addr = __ppc_ba(bsh, ofs);
197191447Smarcel	res = *addr;
198191447Smarcel	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
199191447Smarcel	return (res);
200174782Smarcel}
201174782Smarcel
202174782Smarcelstatic uint32_t
203174782Smarcelbs_be_rs_4(bus_space_handle_t bsh, bus_size_t ofs)
204174782Smarcel{
205191447Smarcel	volatile uint32_t *addr;
206191447Smarcel	uint32_t res;
207191447Smarcel
208191447Smarcel	addr = __ppc_ba(bsh, ofs);
209191447Smarcel	res = *addr;
210191447Smarcel	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
211191447Smarcel	return (res);
212174782Smarcel}
213174782Smarcel
214174782Smarcelstatic uint64_t
215174782Smarcelbs_be_rs_8(bus_space_handle_t bsh, bus_size_t ofs)
216174782Smarcel{
217193578Sraj	volatile uint64_t *addr;
218193578Sraj	uint64_t res;
219193578Sraj
220193578Sraj	addr = __ppc_ba(bsh, ofs);
221193578Sraj	res = *addr;
222193578Sraj	return (res);
223174782Smarcel}
224174782Smarcel
225174782Smarcelstatic void
226174782Smarcelbs_be_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
227174782Smarcel{
228174782Smarcel	ins8(__ppc_ba(bsh, ofs), addr, cnt);
229174782Smarcel}
230174782Smarcel
231174782Smarcelstatic void
232174782Smarcelbs_be_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
233174782Smarcel{
234174782Smarcel	ins16(__ppc_ba(bsh, ofs), addr, cnt);
235174782Smarcel}
236174782Smarcel
237174782Smarcelstatic void
238174782Smarcelbs_be_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
239174782Smarcel{
240174782Smarcel	ins32(__ppc_ba(bsh, ofs), addr, cnt);
241174782Smarcel}
242174782Smarcel
243174782Smarcelstatic void
244193578Srajbs_be_rm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
245174782Smarcel{
246193578Sraj	ins64(__ppc_ba(bsh, ofs), addr, cnt);
247174782Smarcel}
248174782Smarcel
249174782Smarcelstatic void
250174782Smarcelbs_be_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
251174782Smarcel{
252174782Smarcel	volatile uint8_t *s = __ppc_ba(bsh, ofs);
253174782Smarcel
254174782Smarcel	while (cnt--)
255174782Smarcel		*addr++ = *s++;
256174782Smarcel	__asm __volatile("eieio; sync");
257174782Smarcel}
258174782Smarcel
259174782Smarcelstatic void
260174782Smarcelbs_be_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
261174782Smarcel{
262174782Smarcel	volatile uint16_t *s = __ppc_ba(bsh, ofs);
263174782Smarcel
264174782Smarcel	while (cnt--)
265174782Smarcel		*addr++ = *s++;
266174782Smarcel	__asm __volatile("eieio; sync");
267174782Smarcel}
268174782Smarcel
269174782Smarcelstatic void
270174782Smarcelbs_be_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
271174782Smarcel{
272174782Smarcel	volatile uint32_t *s = __ppc_ba(bsh, ofs);
273174782Smarcel
274174782Smarcel	while (cnt--)
275174782Smarcel		*addr++ = *s++;
276174782Smarcel	__asm __volatile("eieio; sync");
277174782Smarcel}
278174782Smarcel
279174782Smarcelstatic void
280174782Smarcelbs_be_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
281174782Smarcel{
282193578Sraj	volatile uint64_t *s = __ppc_ba(bsh, ofs);
283193578Sraj
284193578Sraj	while (cnt--)
285193578Sraj		*addr++ = *s++;
286193578Sraj	__asm __volatile("eieio; sync");
287174782Smarcel}
288174782Smarcel
289174782Smarcelstatic void
290174782Smarcelbs_be_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val)
291174782Smarcel{
292191447Smarcel	volatile uint8_t *addr;
293191447Smarcel
294191447Smarcel	addr = __ppc_ba(bsh, ofs);
295191447Smarcel	*addr = val;
296226567Snwhitehorn	__asm __volatile("eieio; sync");
297191447Smarcel	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
298174782Smarcel}
299174782Smarcel
300174782Smarcelstatic void
301174782Smarcelbs_be_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val)
302174782Smarcel{
303191447Smarcel	volatile uint16_t *addr;
304191447Smarcel
305191447Smarcel	addr = __ppc_ba(bsh, ofs);
306191447Smarcel	*addr = val;
307226567Snwhitehorn	__asm __volatile("eieio; sync");
308191447Smarcel	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
309174782Smarcel}
310174782Smarcel
311174782Smarcelstatic void
312174782Smarcelbs_be_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val)
313174782Smarcel{
314191447Smarcel	volatile uint32_t *addr;
315191447Smarcel
316191447Smarcel	addr = __ppc_ba(bsh, ofs);
317191447Smarcel	*addr = val;
318226567Snwhitehorn	__asm __volatile("eieio; sync");
319191447Smarcel	CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
320174782Smarcel}
321174782Smarcel
322174782Smarcelstatic void
323174782Smarcelbs_be_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val)
324174782Smarcel{
325193578Sraj	volatile uint64_t *addr;
326193578Sraj
327193578Sraj	addr = __ppc_ba(bsh, ofs);
328193578Sraj	*addr = val;
329226567Snwhitehorn	__asm __volatile("eieio; sync");
330174782Smarcel}
331174782Smarcel
332174782Smarcelstatic void
333174782Smarcelbs_be_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
334174782Smarcel    bus_size_t cnt)
335174782Smarcel{
336174782Smarcel	outsb(__ppc_ba(bsh, ofs), addr, cnt);
337174782Smarcel}
338174782Smarcel
339174782Smarcelstatic void
340174782Smarcelbs_be_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
341174782Smarcel    bus_size_t cnt)
342174782Smarcel{
343174782Smarcel	outsw(__ppc_ba(bsh, ofs), addr, cnt);
344174782Smarcel}
345174782Smarcel
346174782Smarcelstatic void
347174782Smarcelbs_be_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
348174782Smarcel    bus_size_t cnt)
349174782Smarcel{
350174782Smarcel	outsl(__ppc_ba(bsh, ofs), addr, cnt);
351174782Smarcel}
352174782Smarcel
353174782Smarcelstatic void
354174782Smarcelbs_be_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
355174782Smarcel    bus_size_t cnt)
356174782Smarcel{
357193578Sraj	outsll(__ppc_ba(bsh, ofs), addr, cnt);
358174782Smarcel}
359174782Smarcel
360174782Smarcelstatic void
361174782Smarcelbs_be_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
362174782Smarcel    size_t cnt)
363174782Smarcel{
364174782Smarcel	volatile uint8_t *d = __ppc_ba(bsh, ofs);
365174782Smarcel
366174782Smarcel	while (cnt--)
367174782Smarcel		*d++ = *addr++;
368174782Smarcel	__asm __volatile("eieio; sync");
369174782Smarcel}
370174782Smarcel
371174782Smarcelstatic void
372174782Smarcelbs_be_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
373174782Smarcel    size_t cnt)
374174782Smarcel{
375174782Smarcel	volatile uint16_t *d = __ppc_ba(bsh, ofs);
376174782Smarcel
377174782Smarcel	while (cnt--)
378174782Smarcel		*d++ = *addr++;
379174782Smarcel	__asm __volatile("eieio; sync");
380174782Smarcel}
381174782Smarcel
382174782Smarcelstatic void
383174782Smarcelbs_be_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
384174782Smarcel    size_t cnt)
385174782Smarcel{
386174782Smarcel	volatile uint32_t *d = __ppc_ba(bsh, ofs);
387174782Smarcel
388174782Smarcel	while (cnt--)
389174782Smarcel		*d++ = *addr++;
390174782Smarcel	__asm __volatile("eieio; sync");
391174782Smarcel}
392174782Smarcel
393174782Smarcelstatic void
394174782Smarcelbs_be_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
395174782Smarcel    size_t cnt)
396174782Smarcel{
397193578Sraj	volatile uint64_t *d = __ppc_ba(bsh, ofs);
398193578Sraj
399193578Sraj	while (cnt--)
400193578Sraj		*d++ = *addr++;
401193578Sraj	__asm __volatile("eieio; sync");
402174782Smarcel}
403174782Smarcel
404174782Smarcelstatic void
405174782Smarcelbs_be_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
406174782Smarcel{
407174782Smarcel	volatile uint8_t *d = __ppc_ba(bsh, ofs);
408174782Smarcel
409174782Smarcel	while (cnt--)
410174782Smarcel		*d = val;
411174782Smarcel	__asm __volatile("eieio; sync");
412174782Smarcel}
413174782Smarcel
414174782Smarcelstatic void
415174782Smarcelbs_be_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
416174782Smarcel{
417174782Smarcel	volatile uint16_t *d = __ppc_ba(bsh, ofs);
418174782Smarcel
419174782Smarcel	while (cnt--)
420174782Smarcel		*d = val;
421174782Smarcel	__asm __volatile("eieio; sync");
422174782Smarcel}
423174782Smarcel
424174782Smarcelstatic void
425174782Smarcelbs_be_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
426174782Smarcel{
427174782Smarcel	volatile uint32_t *d = __ppc_ba(bsh, ofs);
428174782Smarcel
429174782Smarcel	while (cnt--)
430174782Smarcel		*d = val;
431174782Smarcel	__asm __volatile("eieio; sync");
432174782Smarcel}
433174782Smarcel
434174782Smarcelstatic void
435174782Smarcelbs_be_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
436174782Smarcel{
437193578Sraj	volatile uint64_t *d = __ppc_ba(bsh, ofs);
438193578Sraj
439193578Sraj	while (cnt--)
440193578Sraj		*d = val;
441193578Sraj	__asm __volatile("eieio; sync");
442174782Smarcel}
443174782Smarcel
444174782Smarcelstatic void
445174782Smarcelbs_be_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
446174782Smarcel{
447174782Smarcel	volatile uint8_t *d = __ppc_ba(bsh, ofs);
448174782Smarcel
449174782Smarcel	while (cnt--)
450174782Smarcel		*d++ = val;
451174782Smarcel	__asm __volatile("eieio; sync");
452174782Smarcel}
453174782Smarcel
454174782Smarcelstatic void
455174782Smarcelbs_be_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
456174782Smarcel{
457174782Smarcel	volatile uint16_t *d = __ppc_ba(bsh, ofs);
458174782Smarcel
459174782Smarcel	while (cnt--)
460174782Smarcel		*d++ = val;
461174782Smarcel	__asm __volatile("eieio; sync");
462174782Smarcel}
463174782Smarcel
464174782Smarcelstatic void
465174782Smarcelbs_be_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
466174782Smarcel{
467174782Smarcel	volatile uint32_t *d = __ppc_ba(bsh, ofs);
468174782Smarcel
469174782Smarcel	while (cnt--)
470174782Smarcel		*d++ = val;
471174782Smarcel	__asm __volatile("eieio; sync");
472174782Smarcel}
473174782Smarcel
474174782Smarcelstatic void
475174782Smarcelbs_be_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
476174782Smarcel{
477193578Sraj	volatile uint64_t *d = __ppc_ba(bsh, ofs);
478193578Sraj
479193578Sraj	while (cnt--)
480193578Sraj		*d++ = val;
481193578Sraj	__asm __volatile("eieio; sync");
482174782Smarcel}
483174782Smarcel
484174782Smarcel/*
485174782Smarcel * Little-endian access functions
486174782Smarcel */
487174782Smarcelstatic uint8_t
488174782Smarcelbs_le_rs_1(bus_space_handle_t bsh, bus_size_t ofs)
489174782Smarcel{
490191447Smarcel	volatile uint8_t *addr;
491191447Smarcel	uint8_t res;
492191447Smarcel
493191447Smarcel	addr = __ppc_ba(bsh, ofs);
494191447Smarcel	res = *addr;
495226567Snwhitehorn	__asm __volatile("eieio; sync");
496191447Smarcel	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
497191447Smarcel	return (res);
498174782Smarcel}
499174782Smarcel
500174782Smarcelstatic uint16_t
501174782Smarcelbs_le_rs_2(bus_space_handle_t bsh, bus_size_t ofs)
502174782Smarcel{
503191447Smarcel	volatile uint16_t *addr;
504191447Smarcel	uint16_t res;
505191447Smarcel
506191447Smarcel	addr = __ppc_ba(bsh, ofs);
507191447Smarcel	__asm __volatile("lhbrx %0, 0, %1" : "=r"(res) : "r"(addr));
508226567Snwhitehorn	__asm __volatile("eieio; sync");
509191447Smarcel	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
510191447Smarcel	return (res);
511174782Smarcel}
512174782Smarcel
513174782Smarcelstatic uint32_t
514174782Smarcelbs_le_rs_4(bus_space_handle_t bsh, bus_size_t ofs)
515174782Smarcel{
516191447Smarcel	volatile uint32_t *addr;
517191447Smarcel	uint32_t res;
518191447Smarcel
519191447Smarcel	addr = __ppc_ba(bsh, ofs);
520191447Smarcel	__asm __volatile("lwbrx %0, 0, %1" : "=r"(res) : "r"(addr));
521226567Snwhitehorn	__asm __volatile("eieio; sync");
522191447Smarcel	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
523191447Smarcel	return (res);
524174782Smarcel}
525174782Smarcel
526174782Smarcelstatic uint64_t
527174782Smarcelbs_le_rs_8(bus_space_handle_t bsh, bus_size_t ofs)
528174782Smarcel{
529174782Smarcel	TODO;
530174782Smarcel}
531174782Smarcel
532174782Smarcelstatic void
533174782Smarcelbs_le_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
534174782Smarcel{
535174782Smarcel	ins8(__ppc_ba(bsh, ofs), addr, cnt);
536174782Smarcel}
537174782Smarcel
538174782Smarcelstatic void
539174782Smarcelbs_le_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
540174782Smarcel{
541174782Smarcel	ins16rb(__ppc_ba(bsh, ofs), addr, cnt);
542174782Smarcel}
543174782Smarcel
544174782Smarcelstatic void
545174782Smarcelbs_le_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
546174782Smarcel{
547174782Smarcel	ins32rb(__ppc_ba(bsh, ofs), addr, cnt);
548174782Smarcel}
549174782Smarcel
550174782Smarcelstatic void
551174782Smarcelbs_le_rm_8(bus_space_handle_t bshh, bus_size_t ofs, uint64_t *addr, size_t cnt)
552174782Smarcel{
553174782Smarcel	TODO;
554174782Smarcel}
555174782Smarcel
556174782Smarcelstatic void
557174782Smarcelbs_le_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
558174782Smarcel{
559174782Smarcel	volatile uint8_t *s = __ppc_ba(bsh, ofs);
560174782Smarcel
561174782Smarcel	while (cnt--)
562174782Smarcel		*addr++ = *s++;
563174782Smarcel	__asm __volatile("eieio; sync");
564174782Smarcel}
565174782Smarcel
566174782Smarcelstatic void
567174782Smarcelbs_le_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
568174782Smarcel{
569174782Smarcel	volatile uint16_t *s = __ppc_ba(bsh, ofs);
570174782Smarcel
571174782Smarcel	while (cnt--)
572174782Smarcel		*addr++ = in16rb(s++);
573174782Smarcel	__asm __volatile("eieio; sync");
574174782Smarcel}
575174782Smarcel
576174782Smarcelstatic void
577174782Smarcelbs_le_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
578174782Smarcel{
579174782Smarcel	volatile uint32_t *s = __ppc_ba(bsh, ofs);
580174782Smarcel
581174782Smarcel	while (cnt--)
582174782Smarcel		*addr++ = in32rb(s++);
583174782Smarcel	__asm __volatile("eieio; sync");
584174782Smarcel}
585174782Smarcel
586174782Smarcelstatic void
587174782Smarcelbs_le_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
588174782Smarcel{
589174782Smarcel	TODO;
590174782Smarcel}
591174782Smarcel
592174782Smarcelstatic void
593174782Smarcelbs_le_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val)
594174782Smarcel{
595191447Smarcel	volatile uint8_t *addr;
596191447Smarcel
597191447Smarcel	addr = __ppc_ba(bsh, ofs);
598191447Smarcel	*addr = val;
599191447Smarcel	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
600174782Smarcel}
601174782Smarcel
602174782Smarcelstatic void
603174782Smarcelbs_le_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val)
604174782Smarcel{
605191447Smarcel	volatile uint16_t *addr;
606191447Smarcel
607191447Smarcel	addr = __ppc_ba(bsh, ofs);
608191447Smarcel	__asm __volatile("sthbrx %0, 0, %1" :: "r"(val), "r"(addr));
609191447Smarcel	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
610174782Smarcel}
611174782Smarcel
612174782Smarcelstatic void
613174782Smarcelbs_le_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val)
614174782Smarcel{
615191447Smarcel	volatile uint32_t *addr;
616191447Smarcel
617191447Smarcel	addr = __ppc_ba(bsh, ofs);
618191447Smarcel	__asm __volatile("stwbrx %0, 0, %1" :: "r"(val), "r"(addr));
619191447Smarcel	CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
620174782Smarcel}
621174782Smarcel
622174782Smarcelstatic void
623174782Smarcelbs_le_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val)
624174782Smarcel{
625174782Smarcel	TODO;
626174782Smarcel}
627174782Smarcel
628174782Smarcelstatic void
629174782Smarcelbs_le_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
630174782Smarcel    bus_size_t cnt)
631174782Smarcel{
632174782Smarcel	outs8(__ppc_ba(bsh, ofs), addr, cnt);
633174782Smarcel}
634174782Smarcel
635174782Smarcelstatic void
636174782Smarcelbs_le_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
637174782Smarcel    bus_size_t cnt)
638174782Smarcel{
639174782Smarcel	outs16rb(__ppc_ba(bsh, ofs), addr, cnt);
640174782Smarcel}
641174782Smarcel
642174782Smarcelstatic void
643174782Smarcelbs_le_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
644174782Smarcel    bus_size_t cnt)
645174782Smarcel{
646174782Smarcel	outs32rb(__ppc_ba(bsh, ofs), addr, cnt);
647174782Smarcel}
648174782Smarcel
649174782Smarcelstatic void
650174782Smarcelbs_le_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
651174782Smarcel    bus_size_t cnt)
652174782Smarcel{
653174782Smarcel	TODO;
654174782Smarcel}
655174782Smarcel
656174782Smarcelstatic void
657174782Smarcelbs_le_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
658174782Smarcel    size_t cnt)
659174782Smarcel{
660174782Smarcel	volatile uint8_t *d = __ppc_ba(bsh, ofs);
661174782Smarcel
662174782Smarcel	while (cnt--)
663174782Smarcel		*d++ = *addr++;
664174782Smarcel	__asm __volatile("eieio; sync");
665174782Smarcel}
666174782Smarcel
667174782Smarcelstatic void
668174782Smarcelbs_le_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
669174782Smarcel    size_t cnt)
670174782Smarcel{
671174782Smarcel	volatile uint16_t *d = __ppc_ba(bsh, ofs);
672174782Smarcel
673174782Smarcel	while (cnt--)
674174782Smarcel		out16rb(d++, *addr++);
675174782Smarcel	__asm __volatile("eieio; sync");
676174782Smarcel}
677174782Smarcel
678174782Smarcelstatic void
679174782Smarcelbs_le_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
680174782Smarcel    size_t cnt)
681174782Smarcel{
682174782Smarcel	volatile uint32_t *d = __ppc_ba(bsh, ofs);
683174782Smarcel
684174782Smarcel	while (cnt--)
685174782Smarcel		out32rb(d++, *addr++);
686174782Smarcel	__asm __volatile("eieio; sync");
687174782Smarcel}
688174782Smarcel
689174782Smarcelstatic void
690174782Smarcelbs_le_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
691174782Smarcel    size_t cnt)
692174782Smarcel{
693174782Smarcel	TODO;
694174782Smarcel}
695174782Smarcel
696174782Smarcelstatic void
697174782Smarcelbs_le_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
698174782Smarcel{
699174782Smarcel	volatile uint8_t *d = __ppc_ba(bsh, ofs);
700174782Smarcel
701174782Smarcel	while (cnt--)
702174782Smarcel		*d = val;
703174782Smarcel	__asm __volatile("eieio; sync");
704174782Smarcel}
705174782Smarcel
706174782Smarcelstatic void
707174782Smarcelbs_le_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
708174782Smarcel{
709174782Smarcel	volatile uint16_t *d = __ppc_ba(bsh, ofs);
710174782Smarcel
711174782Smarcel	while (cnt--)
712174782Smarcel		out16rb(d, val);
713174782Smarcel	__asm __volatile("eieio; sync");
714174782Smarcel}
715174782Smarcel
716174782Smarcelstatic void
717174782Smarcelbs_le_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
718174782Smarcel{
719174782Smarcel	volatile uint32_t *d = __ppc_ba(bsh, ofs);
720174782Smarcel
721174782Smarcel	while (cnt--)
722174782Smarcel		out32rb(d, val);
723174782Smarcel	__asm __volatile("eieio; sync");
724174782Smarcel}
725174782Smarcel
726174782Smarcelstatic void
727174782Smarcelbs_le_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
728174782Smarcel{
729174782Smarcel	TODO;
730174782Smarcel}
731174782Smarcel
732174782Smarcelstatic void
733174782Smarcelbs_le_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
734174782Smarcel{
735174782Smarcel	volatile uint8_t *d = __ppc_ba(bsh, ofs);
736174782Smarcel
737174782Smarcel	while (cnt--)
738174782Smarcel		*d++ = val;
739174782Smarcel	__asm __volatile("eieio; sync");
740174782Smarcel}
741174782Smarcel
742174782Smarcelstatic void
743174782Smarcelbs_le_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
744174782Smarcel{
745174782Smarcel	volatile uint16_t *d = __ppc_ba(bsh, ofs);
746174782Smarcel
747174782Smarcel	while (cnt--)
748174782Smarcel		out16rb(d++, val);
749174782Smarcel	__asm __volatile("eieio; sync");
750174782Smarcel}
751174782Smarcel
752174782Smarcelstatic void
753174782Smarcelbs_le_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
754174782Smarcel{
755174782Smarcel	volatile uint32_t *d = __ppc_ba(bsh, ofs);
756174782Smarcel
757174782Smarcel	while (cnt--)
758174782Smarcel		out32rb(d++, val);
759174782Smarcel	__asm __volatile("eieio; sync");
760174782Smarcel}
761174782Smarcel
762174782Smarcelstatic void
763174782Smarcelbs_le_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
764174782Smarcel{
765174782Smarcel	TODO;
766174782Smarcel}
767174782Smarcel
768174782Smarcelstruct bus_space bs_be_tag = {
769174782Smarcel	/* mapping/unmapping */
770174782Smarcel	bs_gen_map,
771174782Smarcel	bs_gen_unmap,
772174782Smarcel	bs_gen_subregion,
773174782Smarcel
774174782Smarcel	/* allocation/deallocation */
775174782Smarcel	bs_gen_alloc,
776174782Smarcel	bs_gen_free,
777174782Smarcel
778174782Smarcel	/* barrier */
779174782Smarcel	bs_gen_barrier,
780174782Smarcel
781174782Smarcel	/* read (single) */
782174782Smarcel	bs_be_rs_1,
783174782Smarcel	bs_be_rs_2,
784174782Smarcel	bs_be_rs_4,
785174782Smarcel	bs_be_rs_8,
786174782Smarcel
787174782Smarcel	bs_be_rs_2,
788174782Smarcel	bs_be_rs_4,
789174782Smarcel	bs_be_rs_8,
790174782Smarcel
791174782Smarcel	/* read multiple */
792174782Smarcel	bs_be_rm_1,
793174782Smarcel	bs_be_rm_2,
794174782Smarcel	bs_be_rm_4,
795174782Smarcel	bs_be_rm_8,
796174782Smarcel
797174782Smarcel	bs_be_rm_2,
798174782Smarcel	bs_be_rm_4,
799174782Smarcel	bs_be_rm_8,
800174782Smarcel
801174782Smarcel	/* read region */
802174782Smarcel	bs_be_rr_1,
803174782Smarcel	bs_be_rr_2,
804174782Smarcel	bs_be_rr_4,
805174782Smarcel	bs_be_rr_8,
806174782Smarcel
807174782Smarcel	bs_be_rr_2,
808174782Smarcel	bs_be_rr_4,
809174782Smarcel	bs_be_rr_8,
810174782Smarcel
811174782Smarcel	/* write (single) */
812174782Smarcel	bs_be_ws_1,
813174782Smarcel	bs_be_ws_2,
814174782Smarcel	bs_be_ws_4,
815174782Smarcel	bs_be_ws_8,
816174782Smarcel
817174782Smarcel	bs_be_ws_2,
818174782Smarcel	bs_be_ws_4,
819174782Smarcel	bs_be_ws_8,
820174782Smarcel
821174782Smarcel	/* write multiple */
822174782Smarcel	bs_be_wm_1,
823174782Smarcel	bs_be_wm_2,
824174782Smarcel	bs_be_wm_4,
825174782Smarcel	bs_be_wm_8,
826174782Smarcel
827174782Smarcel	bs_be_wm_2,
828174782Smarcel	bs_be_wm_4,
829174782Smarcel	bs_be_wm_8,
830174782Smarcel
831174782Smarcel	/* write region */
832174782Smarcel	bs_be_wr_1,
833174782Smarcel	bs_be_wr_2,
834174782Smarcel	bs_be_wr_4,
835174782Smarcel	bs_be_wr_8,
836174782Smarcel
837174782Smarcel	bs_be_wr_2,
838174782Smarcel	bs_be_wr_4,
839174782Smarcel	bs_be_wr_8,
840174782Smarcel
841174782Smarcel	/* set multiple */
842174782Smarcel	bs_be_sm_1,
843174782Smarcel	bs_be_sm_2,
844174782Smarcel	bs_be_sm_4,
845174782Smarcel	bs_be_sm_8,
846174782Smarcel
847174782Smarcel	bs_be_sm_2,
848174782Smarcel	bs_be_sm_4,
849174782Smarcel	bs_be_sm_8,
850174782Smarcel
851174782Smarcel	/* set region */
852174782Smarcel	bs_be_sr_1,
853174782Smarcel	bs_be_sr_2,
854174782Smarcel	bs_be_sr_4,
855174782Smarcel	bs_be_sr_8,
856174782Smarcel
857174782Smarcel	bs_be_sr_2,
858174782Smarcel	bs_be_sr_4,
859174782Smarcel	bs_be_sr_8,
860174782Smarcel};
861174782Smarcel
862174782Smarcelstruct bus_space bs_le_tag = {
863174782Smarcel	/* mapping/unmapping */
864174782Smarcel	bs_gen_map,
865174782Smarcel	bs_gen_unmap,
866174782Smarcel	bs_gen_subregion,
867174782Smarcel
868174782Smarcel	/* allocation/deallocation */
869174782Smarcel	bs_gen_alloc,
870174782Smarcel	bs_gen_free,
871174782Smarcel
872174782Smarcel	/* barrier */
873174782Smarcel	bs_gen_barrier,
874174782Smarcel
875174782Smarcel	/* read (single) */
876174782Smarcel	bs_le_rs_1,
877174782Smarcel	bs_le_rs_2,
878174782Smarcel	bs_le_rs_4,
879174782Smarcel	bs_le_rs_8,
880174782Smarcel
881174782Smarcel	bs_be_rs_2,
882174782Smarcel	bs_be_rs_4,
883174782Smarcel	bs_be_rs_8,
884174782Smarcel
885174782Smarcel	/* read multiple */
886174782Smarcel	bs_le_rm_1,
887174782Smarcel	bs_le_rm_2,
888174782Smarcel	bs_le_rm_4,
889174782Smarcel	bs_le_rm_8,
890174782Smarcel
891174782Smarcel	bs_be_rm_2,
892174782Smarcel	bs_be_rm_4,
893174782Smarcel	bs_be_rm_8,
894174782Smarcel
895174782Smarcel	/* read region */
896174782Smarcel	bs_le_rr_1,
897174782Smarcel	bs_le_rr_2,
898174782Smarcel	bs_le_rr_4,
899174782Smarcel	bs_le_rr_8,
900174782Smarcel
901174782Smarcel	bs_be_rr_2,
902174782Smarcel	bs_be_rr_4,
903174782Smarcel	bs_be_rr_8,
904174782Smarcel
905174782Smarcel	/* write (single) */
906174782Smarcel	bs_le_ws_1,
907174782Smarcel	bs_le_ws_2,
908174782Smarcel	bs_le_ws_4,
909174782Smarcel	bs_le_ws_8,
910174782Smarcel
911174782Smarcel	bs_be_ws_2,
912174782Smarcel	bs_be_ws_4,
913174782Smarcel	bs_be_ws_8,
914174782Smarcel
915174782Smarcel	/* write multiple */
916174782Smarcel	bs_le_wm_1,
917174782Smarcel	bs_le_wm_2,
918174782Smarcel	bs_le_wm_4,
919174782Smarcel	bs_le_wm_8,
920174782Smarcel
921174782Smarcel	bs_be_wm_2,
922174782Smarcel	bs_be_wm_4,
923174782Smarcel	bs_be_wm_8,
924174782Smarcel
925174782Smarcel	/* write region */
926174782Smarcel	bs_le_wr_1,
927174782Smarcel	bs_le_wr_2,
928174782Smarcel	bs_le_wr_4,
929174782Smarcel	bs_le_wr_8,
930174782Smarcel
931174782Smarcel	bs_be_wr_2,
932174782Smarcel	bs_be_wr_4,
933174782Smarcel	bs_be_wr_8,
934174782Smarcel
935174782Smarcel	/* set multiple */
936174782Smarcel	bs_le_sm_1,
937174782Smarcel	bs_le_sm_2,
938174782Smarcel	bs_le_sm_4,
939174782Smarcel	bs_le_sm_8,
940174782Smarcel
941174782Smarcel	bs_be_sm_2,
942174782Smarcel	bs_be_sm_4,
943174782Smarcel	bs_be_sm_8,
944174782Smarcel
945174782Smarcel	/* set region */
946174782Smarcel	bs_le_sr_1,
947174782Smarcel	bs_le_sr_2,
948174782Smarcel	bs_le_sr_4,
949174782Smarcel	bs_le_sr_8,
950174782Smarcel
951174782Smarcel	bs_be_sr_2,
952174782Smarcel	bs_be_sr_4,
953174782Smarcel	bs_be_sr_8,
954174782Smarcel};
955