bus.h revision 111524
180708Sjake/*-
286228Stmm * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
380708Sjake * All rights reserved.
480708Sjake *
586228Stmm * This code is derived from software contributed to The NetBSD Foundation
686228Stmm * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
786228Stmm * NASA Ames Research Center.
886228Stmm *
980708Sjake * Redistribution and use in source and binary forms, with or without
1080708Sjake * modification, are permitted provided that the following conditions
1180708Sjake * are met:
1280708Sjake * 1. Redistributions of source code must retain the above copyright
1380708Sjake *    notice, this list of conditions and the following disclaimer.
1480708Sjake * 2. Redistributions in binary form must reproduce the above copyright
1580708Sjake *    notice, this list of conditions and the following disclaimer in the
1680708Sjake *    documentation and/or other materials provided with the distribution.
1786228Stmm * 3. All advertising materials mentioning features or use of this software
1886228Stmm *    must display the following acknowledgement:
1986228Stmm *	This product includes software developed by the NetBSD
2086228Stmm *	Foundation, Inc. and its contributors.
2186228Stmm * 4. Neither the name of The NetBSD Foundation nor the names of its
2286228Stmm *    contributors may be used to endorse or promote products derived
2386228Stmm *    from this software without specific prior written permission.
2480708Sjake *
2586228Stmm * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2686228Stmm * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2786228Stmm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2886228Stmm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2986228Stmm * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3086228Stmm * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3186228Stmm * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3286228Stmm * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3386228Stmm * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3486228Stmm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3586228Stmm * POSSIBILITY OF SUCH DAMAGE.
3686228Stmm */
3786228Stmm/*
3886228Stmm * Copyright (c) 1997-1999 Eduardo E. Horvath. All rights reserved.
3986228Stmm * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
4086228Stmm * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
4180708Sjake *
4286228Stmm * Redistribution and use in source and binary forms, with or without
4386228Stmm * modification, are permitted provided that the following conditions
4486228Stmm * are met:
4586228Stmm * 1. Redistributions of source code must retain the above copyright
4686228Stmm *    notice, this list of conditions and the following disclaimer.
4786228Stmm * 2. Redistributions in binary form must reproduce the above copyright
4886228Stmm *    notice, this list of conditions and the following disclaimer in the
4986228Stmm *    documentation and/or other materials provided with the distribution.
5086228Stmm * 3. All advertising materials mentioning features or use of this software
5186228Stmm *    must display the following acknowledgement:
5286228Stmm *      This product includes software developed by Christopher G. Demetriou
5386228Stmm *	for the NetBSD Project.
5486228Stmm * 4. The name of the author may not be used to endorse or promote products
5586228Stmm *    derived from this software without specific prior written permission
5686228Stmm *
5786228Stmm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
5886228Stmm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5986228Stmm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
6086228Stmm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
6186228Stmm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
6286228Stmm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
6386228Stmm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
6486228Stmm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6586228Stmm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
6686228Stmm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6786228Stmm *
6886228Stmm * 	from: NetBSD: bus.h,v 1.28 2001/07/19 15:32:19 thorpej Exp
6986228Stmm *	and
7086228Stmm *	from: FreeBSD: src/sys/alpha/include/bus.h,v 1.9 2001/01/09
7186228Stmm *
7280708Sjake * $FreeBSD: head/sys/sparc64/include/bus.h 111524 2003-02-26 02:16:06Z mux $
7380708Sjake */
7480708Sjake
7580708Sjake#ifndef	_MACHINE_BUS_H_
7680708Sjake#define	_MACHINE_BUS_H_
7780708Sjake
7890615Stmm#ifdef BUS_SPACE_DEBUG
7990615Stmm#include <sys/ktr.h>
8090615Stmm#endif
8190615Stmm
8286228Stmm#include <machine/cpufunc.h>
8390615Stmm#include <machine/upa.h>
8480708Sjake
8586228Stmm/*
8686228Stmm * UPA and SBUS spaces are non-cached and big endian
8786228Stmm * (except for RAM and PROM)
8886228Stmm *
8986228Stmm * PCI spaces are non-cached and little endian
9086228Stmm */
9186228Stmm#define	UPA_BUS_SPACE		0
9286228Stmm#define	SBUS_BUS_SPACE		1
9386228Stmm#define	PCI_CONFIG_BUS_SPACE	2
9486228Stmm#define	PCI_IO_BUS_SPACE	3
9586228Stmm#define	PCI_MEMORY_BUS_SPACE	4
9686228Stmm#define	LAST_BUS_SPACE		5
9786228Stmm
9886228Stmmextern int bus_type_asi[];
9986228Stmmextern int bus_stream_asi[];
10086228Stmm
10186228Stmm#define __BUS_SPACE_HAS_STREAM_METHODS	1
10286228Stmm
10386228Stmm/*
10486228Stmm * Bus address and size types
10586228Stmm */
10686228Stmmtypedef	u_long		bus_space_handle_t;
10786228Stmmtypedef int		bus_type_t;
10886228Stmmtypedef u_long		bus_addr_t;
10986228Stmmtypedef u_long		bus_size_t;
11086228Stmm
11186228Stmm#define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
11286228Stmm#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
113111524Smux#define BUS_SPACE_MAXSIZE	0xFFFFFFFFFFFFFFFF
11486228Stmm#define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
11586228Stmm#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
11686228Stmm#define BUS_SPACE_MAXADDR	0xFFFFFFFF
11786228Stmm
11886228Stmm#define BUS_SPACE_UNRESTRICTED	(~0UL)
11986228Stmm
12086228Stmm/*
12186228Stmm * Access methods for bus resources and address space.
12286228Stmm */
12386228Stmmtypedef struct bus_space_tag	*bus_space_tag_t;
12486228Stmm
12586228Stmmstruct bus_space_tag {
126108815Stmm	void		*bst_cookie;
127108815Stmm	bus_space_tag_t	bst_parent;
128108815Stmm	int		bst_type;
12986228Stmm
130108815Stmm	void		(*bst_bus_barrier)(bus_space_tag_t, bus_space_handle_t,
13193052Stmm	    bus_size_t, bus_size_t, int);
13286228Stmm};
13386228Stmm
13486228Stmm/*
13586228Stmm * Helpers
13686228Stmm */
13793052Stmmint sparc64_bus_mem_map(bus_space_tag_t, bus_space_handle_t, bus_size_t,
13893052Stmm    int, vm_offset_t, void **);
13993052Stmmint sparc64_bus_mem_unmap(void *, bus_size_t);
14093052Stmmbus_space_handle_t sparc64_fake_bustag(int, bus_addr_t,
14193052Stmm    struct bus_space_tag *);
14290615Stmm
14386228Stmm/*
14486228Stmm * Bus space function prototypes.
14586228Stmm */
14693052Stmmstatic void bus_space_barrier(bus_space_tag_t, bus_space_handle_t, bus_size_t,
14793052Stmm    bus_size_t, int);
148108917Sjakestatic int bus_space_subregion(bus_space_tag_t, bus_space_handle_t,
149108917Sjake    bus_size_t, bus_size_t, bus_space_handle_t *);
150111347Sobrien/*
151111347Sobrien * Unmap a region of device bus space.
152111347Sobrien */
153111347Sobrienstatic __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
154111347Sobrien				     bus_size_t size);
15586228Stmm
156111347Sobrienstatic __inline void
157111347Sobrienbus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
158111347Sobrien		bus_size_t size __unused)
159111347Sobrien{
160111347Sobrien}
161111347Sobrien
16286228Stmm/* This macro finds the first "upstream" implementation of method `f' */
16393052Stmm#define _BS_CALL(t,f)							\
16493052Stmm	while (t->f == NULL)						\
165108815Stmm		t = t->bst_parent;						\
16686228Stmm	return (*(t)->f)
16786228Stmm
16893052Stmmstatic __inline void
16993052Stmmbus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
17093052Stmm    bus_size_t s, int f)
17186228Stmm{
172108815Stmm	_BS_CALL(t, bst_bus_barrier)(t, h, o, s, f);
17386228Stmm}
17486228Stmm
175108917Sjakestatic __inline int
176108917Sjakebus_space_subregion(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
177108917Sjake    bus_size_t s, bus_space_handle_t *hp)
178108917Sjake{
179108917Sjake	*hp = h + o;
180108917Sjake	return (0);
181108917Sjake}
182108917Sjake
18386228Stmm/* flags for bus space map functions */
18486228Stmm#define BUS_SPACE_MAP_CACHEABLE		0x0001
18586228Stmm#define BUS_SPACE_MAP_LINEAR		0x0002
18686228Stmm#define BUS_SPACE_MAP_READONLY		0x0004
18786228Stmm#define BUS_SPACE_MAP_PREFETCHABLE	0x0008
18886228Stmm/* placeholders for bus functions... */
18986228Stmm#define BUS_SPACE_MAP_BUS1		0x0100
19086228Stmm#define BUS_SPACE_MAP_BUS2		0x0200
19186228Stmm#define BUS_SPACE_MAP_BUS3		0x0400
19286228Stmm#define BUS_SPACE_MAP_BUS4		0x0800
19386228Stmm
19486228Stmm/* flags for bus_space_barrier() */
19586228Stmm#define	BUS_SPACE_BARRIER_READ		0x01	/* force read barrier */
19686228Stmm#define	BUS_SPACE_BARRIER_WRITE		0x02	/* force write barrier */
19786228Stmm
19890615Stmm#ifdef BUS_SPACE_DEBUG
19990615Stmm#define	KTR_BUS				KTR_CT2
20090615Stmm#define	BUS_HANDLE_MIN			UPA_MEMSTART
20190615Stmm#define	__BUS_DEBUG_ACCESS(h, o, desc, sz) do {				\
20290615Stmm	CTR4(KTR_BUS, "bus space: %s %d: handle %#lx, offset %#lx",	\
20390615Stmm	    (desc), (sz), (h), (o));					\
20490615Stmm	if ((h) + (o) < BUS_HANDLE_MIN)					\
20590615Stmm		panic("bus space access at %#lx out of range",		\
20690615Stmm		    (h) + (o));						\
20790615Stmm} while (0)
20890615Stmm#else
20990615Stmm#define	__BUS_DEBUG_ACCESS(h, o, desc, sz)
21090615Stmm#endif
21190615Stmm
212104304Sjakestatic __inline uint8_t
213104304Sjakebus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
214104304Sjake{
21586228Stmm
216104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read", 1);
217108815Stmm	return (lduba_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
218104304Sjake}
21986228Stmm
220104304Sjakestatic __inline uint16_t
221104304Sjakebus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
222104304Sjake{
22386228Stmm
224104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read", 2);
225108815Stmm	return (lduha_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
226104304Sjake}
22786228Stmm
228104304Sjakestatic __inline uint32_t
229104304Sjakebus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
230104304Sjake{
23186228Stmm
232104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read", 4);
233108815Stmm	return (lduwa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
234104304Sjake}
23586228Stmm
236104304Sjakestatic __inline uint64_t
237104304Sjakebus_space_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
238104304Sjake{
23986228Stmm
240104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read", 8);
241108815Stmm	return (ldxa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
242104304Sjake}
24386228Stmm
244104304Sjakestatic __inline void
245104304Sjakebus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
246104304Sjake    uint8_t *a, size_t c)
247104304Sjake{
24886228Stmm
249104304Sjake	while (c-- > 0)
250104304Sjake		*a++ = bus_space_read_1(t, h, o);
251104304Sjake}
25286228Stmm
253104304Sjakestatic __inline void
254104304Sjakebus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
255104304Sjake    uint16_t *a, size_t c)
256104304Sjake{
25786228Stmm
258104304Sjake	while (c-- > 0)
259104304Sjake		*a++ = bus_space_read_2(t, h, o);
260104304Sjake}
26186228Stmm
262104304Sjakestatic __inline void
263104304Sjakebus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
264104304Sjake    uint32_t *a, size_t c)
265104304Sjake{
26686228Stmm
267104304Sjake	while (c-- > 0)
268104304Sjake		*a++ = bus_space_read_4(t, h, o);
269104304Sjake}
27086228Stmm
271104304Sjakestatic __inline void
272104304Sjakebus_space_read_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
273104304Sjake    uint64_t *a, size_t c)
274104304Sjake{
27586228Stmm
276104304Sjake	while (c-- > 0)
277104304Sjake		*a++ = bus_space_read_8(t, h, o);
278104304Sjake}
27986228Stmm
280104304Sjakestatic __inline void
281104304Sjakebus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
282104304Sjake    uint8_t v)
283104304Sjake{
28486228Stmm
285104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write", 1);
286108815Stmm	stba_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
287104304Sjake}
28886228Stmm
289104304Sjakestatic __inline void
290104304Sjakebus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
291104304Sjake    uint16_t v)
292104304Sjake{
29386228Stmm
294104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write", 2);
295108815Stmm	stha_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
296104304Sjake}
29786228Stmm
29893052Stmmstatic __inline void
299104304Sjakebus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
300104304Sjake    uint32_t v)
301104304Sjake{
302104304Sjake
303104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write", 4);
304108815Stmm	stwa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
305104304Sjake}
306104304Sjake
307104304Sjakestatic __inline void
308104304Sjakebus_space_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
309104304Sjake    uint64_t v)
310104304Sjake{
311104304Sjake
312104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write", 8);
313108815Stmm	stxa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
314104304Sjake}
315104304Sjake
316104304Sjakestatic __inline void
317104304Sjakebus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
318104304Sjake    uint8_t *a, size_t c)
319104304Sjake{
320104304Sjake
321104304Sjake	while (c-- > 0)
322104304Sjake		bus_space_write_1(t, h, o, *a++);
323104304Sjake}
324104304Sjake
325104304Sjakestatic __inline void
326104304Sjakebus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
327104304Sjake    uint16_t *a, size_t c)
328104304Sjake{
329104304Sjake
330104304Sjake	while (c-- > 0)
331104304Sjake		bus_space_write_2(t, h, o, *a++);
332104304Sjake}
333104304Sjake
334104304Sjakestatic __inline void
335104304Sjakebus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
336104304Sjake    uint32_t *a, size_t c)
337104304Sjake{
338104304Sjake
339104304Sjake	while (c-- > 0)
340104304Sjake		bus_space_write_4(t, h, o, *a++);
341104304Sjake}
342104304Sjake
343104304Sjakestatic __inline void
344104304Sjakebus_space_write_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
345104304Sjake    uint64_t *a, size_t c)
346104304Sjake{
347104304Sjake
348104304Sjake	while (c-- > 0)
349104304Sjake		bus_space_write_8(t, h, o, *a++);
350104304Sjake}
351104304Sjake
352104304Sjakestatic __inline void
353104304Sjakebus_space_set_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
354104304Sjake    uint8_t v, size_t c)
355104304Sjake{
356104304Sjake
357104304Sjake	while (c-- > 0)
358104304Sjake		bus_space_write_1(t, h, o, v);
359104304Sjake}
360104304Sjake
361104304Sjakestatic __inline void
362104304Sjakebus_space_set_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
363104304Sjake    uint16_t v, size_t c)
364104304Sjake{
365104304Sjake
366104304Sjake	while (c-- > 0)
367104304Sjake		bus_space_write_2(t, h, o, v);
368104304Sjake}
369104304Sjake
370104304Sjakestatic __inline void
371104304Sjakebus_space_set_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
372104304Sjake    uint32_t v, size_t c)
373104304Sjake{
374104304Sjake
375104304Sjake	while (c-- > 0)
376104304Sjake		bus_space_write_4(t, h, o, v);
377104304Sjake}
378104304Sjake
379104304Sjakestatic __inline void
380104304Sjakebus_space_set_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
381104304Sjake    uint64_t v, size_t c)
382104304Sjake{
383104304Sjake
384104304Sjake	while (c-- > 0)
385104304Sjake		bus_space_write_8(t, h, o, v);
386104304Sjake}
387104304Sjake
388104304Sjakestatic __inline void
38993052Stmmbus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
39093052Stmm    u_int8_t *a, bus_size_t c)
39186228Stmm{
39286228Stmm	for (; c; a++, c--, o++)
39386228Stmm		*a = bus_space_read_1(t, h, o);
39486228Stmm}
39586228Stmm
39693052Stmmstatic __inline void
39793052Stmmbus_space_read_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
39893052Stmm    u_int16_t *a, bus_size_t c)
39986228Stmm{
40086228Stmm	for (; c; a++, c--, o+=2)
40186228Stmm		*a = bus_space_read_2(t, h, o);
40286228Stmm}
40386228Stmm
40493052Stmmstatic __inline void
40593052Stmmbus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
40693052Stmm    u_int32_t *a, bus_size_t c)
40786228Stmm{
40886228Stmm	for (; c; a++, c--, o+=4)
40986228Stmm		*a = bus_space_read_4(t, h, o);
41086228Stmm}
41186228Stmm
41293052Stmmstatic __inline void
41393052Stmmbus_space_read_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
41493052Stmm    u_int64_t *a, bus_size_t c)
41586228Stmm{
41686228Stmm	for (; c; a++, c--, o+=8)
41786228Stmm		*a = bus_space_read_8(t, h, o);
41886228Stmm}
41986228Stmm
42093052Stmmstatic __inline void
42193052Stmmbus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
42293052Stmm    const u_int8_t *a, bus_size_t c)
42386228Stmm{
42486228Stmm	for (; c; a++, c--, o++)
42586228Stmm		bus_space_write_1(t, h, o, *a);
42686228Stmm}
42786228Stmm
42893052Stmmstatic __inline void
42993052Stmmbus_space_write_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
43093052Stmm    const u_int16_t *a, bus_size_t c)
43186228Stmm{
43286228Stmm	for (; c; a++, c--, o+=2)
43386228Stmm		bus_space_write_2(t, h, o, *a);
43486228Stmm}
43586228Stmm
43693052Stmmstatic __inline void
43793052Stmmbus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
43893052Stmm    const u_int32_t *a, bus_size_t c)
43986228Stmm{
44086228Stmm	for (; c; a++, c--, o+=4)
44186228Stmm		bus_space_write_4(t, h, o, *a);
44286228Stmm}
44386228Stmm
44493052Stmmstatic __inline void
44593052Stmmbus_space_write_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
44693052Stmm    const u_int64_t *a, bus_size_t c)
44786228Stmm{
44886228Stmm	for (; c; a++, c--, o+=8)
44986228Stmm		bus_space_write_8(t, h, o, *a);
45086228Stmm}
45186228Stmm
45293052Stmmstatic __inline void
45393052Stmmbus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
45493052Stmm    const u_int8_t v, bus_size_t c)
45586228Stmm{
45686228Stmm	for (; c; c--, o++)
45786228Stmm		bus_space_write_1(t, h, o, v);
45886228Stmm}
45986228Stmm
46093052Stmmstatic __inline void
46193052Stmmbus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
46293052Stmm    const u_int16_t v, bus_size_t c)
46386228Stmm{
46486228Stmm	for (; c; c--, o+=2)
46586228Stmm		bus_space_write_2(t, h, o, v);
46686228Stmm}
46786228Stmm
46893052Stmmstatic __inline void
46993052Stmmbus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
47093052Stmm    const u_int32_t v, bus_size_t c)
47186228Stmm{
47286228Stmm	for (; c; c--, o+=4)
47386228Stmm		bus_space_write_4(t, h, o, v);
47486228Stmm}
47586228Stmm
47693052Stmmstatic __inline void
47793052Stmmbus_space_set_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
47893052Stmm    const u_int64_t v, bus_size_t c)
47986228Stmm{
48086228Stmm	for (; c; c--, o+=8)
48186228Stmm		bus_space_write_8(t, h, o, v);
48286228Stmm}
48386228Stmm
48493052Stmmstatic __inline void
48593052Stmmbus_space_copy_region_1(bus_space_tag_t t, bus_space_handle_t h1,
48693052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
48786228Stmm{
48886228Stmm	for (; c; c--, o1++, o2++)
48986228Stmm	    bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2));
49086228Stmm}
49186228Stmm
49293052Stmmstatic __inline void
49393052Stmmbus_space_copy_region_2(bus_space_tag_t t, bus_space_handle_t h1,
49493052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
49586228Stmm{
49686228Stmm	for (; c; c--, o1+=2, o2+=2)
49786228Stmm	    bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2));
49886228Stmm}
49986228Stmm
50093052Stmmstatic __inline void
50193052Stmmbus_space_copy_region_4(bus_space_tag_t t, bus_space_handle_t h1,
50293052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
50386228Stmm{
50486228Stmm	for (; c; c--, o1+=4, o2+=4)
50586228Stmm	    bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2));
50686228Stmm}
50786228Stmm
50893052Stmmstatic __inline void
50993052Stmmbus_space_copy_region_8(bus_space_tag_t t, bus_space_handle_t h1,
51093052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
51186228Stmm{
51286228Stmm	for (; c; c--, o1+=8, o2+=8)
51386228Stmm	    bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2));
51486228Stmm}
51586228Stmm
516104304Sjakestatic __inline uint8_t
517104304Sjakebus_space_read_stream_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
518104304Sjake{
51986228Stmm
520104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read stream", 1);
521108815Stmm	return (lduba_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
522104304Sjake}
52386228Stmm
524104304Sjakestatic __inline uint16_t
525104304Sjakebus_space_read_stream_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
526104304Sjake{
52786228Stmm
528104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read stream", 2);
529108815Stmm	return (lduha_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
530104304Sjake}
53186228Stmm
532104304Sjakestatic __inline uint32_t
533104304Sjakebus_space_read_stream_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
534104304Sjake{
53586228Stmm
536104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read stream", 4);
537108815Stmm	return (lduwa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
538104304Sjake}
53986228Stmm
540104304Sjakestatic __inline uint64_t
541104304Sjakebus_space_read_stream_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
542104304Sjake{
54386228Stmm
544104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read stream", 8);
545108815Stmm	return (ldxa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
546104304Sjake}
54786228Stmm
548104304Sjakestatic __inline void
549104304Sjakebus_space_read_multi_stream_1(bus_space_tag_t t, bus_space_handle_t h,
550104304Sjake    bus_size_t o, uint8_t *a, size_t c)
551104304Sjake{
55286228Stmm
553104304Sjake	while (c-- > 0)
554104304Sjake		*a++ = bus_space_read_stream_1(t, h, o);
555104304Sjake}
55686228Stmm
557104304Sjakestatic __inline void
558104304Sjakebus_space_read_multi_stream_2(bus_space_tag_t t, bus_space_handle_t h,
559104304Sjake    bus_size_t o, uint16_t *a, size_t c)
560104304Sjake{
56186228Stmm
562104304Sjake	while (c-- > 0)
563104304Sjake		*a++ = bus_space_read_stream_2(t, h, o);
564104304Sjake}
56586228Stmm
566104304Sjakestatic __inline void
567104304Sjakebus_space_read_multi_stream_4(bus_space_tag_t t, bus_space_handle_t h,
568104304Sjake    bus_size_t o, uint32_t *a, size_t c)
569104304Sjake{
57086228Stmm
571104304Sjake	while (c-- > 0)
572104304Sjake		*a++ = bus_space_read_stream_4(t, h, o);
573104304Sjake}
57486228Stmm
575104304Sjakestatic __inline void
576104304Sjakebus_space_read_multi_stream_8(bus_space_tag_t t, bus_space_handle_t h,
577104304Sjake    bus_size_t o, uint64_t *a, size_t c)
578104304Sjake{
57986228Stmm
580104304Sjake	while (c-- > 0)
581104304Sjake		*a++ = bus_space_read_stream_8(t, h, o);
582104304Sjake}
58386228Stmm
584104304Sjakestatic __inline void
585104304Sjakebus_space_write_stream_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
586104304Sjake    uint8_t v)
587104304Sjake{
58886228Stmm
589104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write stream", 1);
590108815Stmm	stba_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
591104304Sjake}
59286228Stmm
593104304Sjakestatic __inline void
594104304Sjakebus_space_write_stream_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
595104304Sjake    uint16_t v)
596104304Sjake{
59786228Stmm
598104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write stream", 2);
599108815Stmm	stha_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
600104304Sjake}
60186228Stmm
60293052Stmmstatic __inline void
603104304Sjakebus_space_write_stream_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
604104304Sjake    uint32_t v)
605104304Sjake{
606104304Sjake
607104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write stream", 4);
608108815Stmm	stwa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
609104304Sjake}
610104304Sjake
611104304Sjakestatic __inline void
612104304Sjakebus_space_write_stream_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
613104304Sjake    uint64_t v)
614104304Sjake{
615104304Sjake
616104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write stream", 8);
617108815Stmm	stxa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
618104304Sjake}
619104304Sjake
620104304Sjakestatic __inline void
621104304Sjakebus_space_write_multi_stream_1(bus_space_tag_t t, bus_space_handle_t h,
622111383Sobrien    bus_size_t o, const uint8_t *a, size_t c)
623104304Sjake{
624104304Sjake
625104304Sjake	while (c-- > 0)
626104304Sjake		bus_space_write_stream_1(t, h, o, *a++);
627104304Sjake}
628104304Sjake
629104304Sjakestatic __inline void
630104304Sjakebus_space_write_multi_stream_2(bus_space_tag_t t, bus_space_handle_t h,
631111353Sobrien    bus_size_t o, const uint16_t *a, size_t c)
632104304Sjake{
633104304Sjake
634104304Sjake	while (c-- > 0)
635104304Sjake		bus_space_write_stream_2(t, h, o, *a++);
636104304Sjake}
637104304Sjake
638104304Sjakestatic __inline void
639104304Sjakebus_space_write_multi_stream_4(bus_space_tag_t t, bus_space_handle_t h,
640111383Sobrien    bus_size_t o, const uint32_t *a, size_t c)
641104304Sjake{
642104304Sjake
643104304Sjake	while (c-- > 0)
644104304Sjake		bus_space_write_stream_4(t, h, o, *a++);
645104304Sjake}
646104304Sjake
647104304Sjakestatic __inline void
648104304Sjakebus_space_write_multi_stream_8(bus_space_tag_t t, bus_space_handle_t h,
649111383Sobrien    bus_size_t o, const uint64_t *a, size_t c)
650104304Sjake{
651104304Sjake
652104304Sjake	while (c-- > 0)
653104304Sjake		bus_space_write_stream_8(t, h, o, *a++);
654104304Sjake}
655104304Sjake
656104304Sjakestatic __inline void
657104304Sjakebus_space_set_multi_stream_1(bus_space_tag_t t, bus_space_handle_t h,
658104304Sjake    bus_size_t o, uint8_t v, size_t c)
659104304Sjake{
660104304Sjake
661104304Sjake	while (c-- > 0)
662104304Sjake		bus_space_write_stream_1(t, h, o, v);
663104304Sjake}
664104304Sjake
665104304Sjakestatic __inline void
666104304Sjakebus_space_set_multi_stream_2(bus_space_tag_t t, bus_space_handle_t h,
667104304Sjake    bus_size_t o, uint16_t v, size_t c)
668104304Sjake{
669104304Sjake
670104304Sjake	while (c-- > 0)
671104304Sjake		bus_space_write_stream_2(t, h, o, v);
672104304Sjake}
673104304Sjake
674104304Sjakestatic __inline void
675104304Sjakebus_space_set_multi_stream_4(bus_space_tag_t t, bus_space_handle_t h,
676104304Sjake    bus_size_t o, uint32_t v, size_t c)
677104304Sjake{
678104304Sjake
679104304Sjake	while (c-- > 0)
680104304Sjake		bus_space_write_stream_4(t, h, o, v);
681104304Sjake}
682104304Sjake
683104304Sjakestatic __inline void
684104304Sjakebus_space_set_multi_stream_8(bus_space_tag_t t, bus_space_handle_t h,
685104304Sjake    bus_size_t o, uint64_t v, size_t c)
686104304Sjake{
687104304Sjake
688104304Sjake	while (c-- > 0)
689104304Sjake		bus_space_write_stream_8(t, h, o, v);
690104304Sjake}
691104304Sjake
692104304Sjakestatic __inline void
69393052Stmmbus_space_read_region_stream_1(bus_space_tag_t t, bus_space_handle_t h,
69493052Stmm    bus_size_t o, u_int8_t *a, bus_size_t c)
69586228Stmm{
69686228Stmm	for (; c; a++, c--, o++)
69786228Stmm		*a = bus_space_read_stream_1(t, h, o);
69886228Stmm}
69986228Stmm
70093052Stmmstatic __inline void
70193052Stmmbus_space_read_region_stream_2(bus_space_tag_t t, bus_space_handle_t h,
70293052Stmm    bus_size_t o, u_int16_t *a, bus_size_t c)
70386228Stmm{
70486228Stmm	for (; c; a++, c--, o+=2)
70586228Stmm		*a = bus_space_read_stream_2(t, h, o);
70686228Stmm}
70786228Stmm
70893052Stmmstatic __inline void
70993052Stmmbus_space_read_region_stream_4(bus_space_tag_t t, bus_space_handle_t h,
71093052Stmm    bus_size_t o, u_int32_t *a, bus_size_t c)
71186228Stmm{
71286228Stmm	for (; c; a++, c--, o+=4)
71386228Stmm		*a = bus_space_read_stream_4(t, h, o);
71486228Stmm}
71586228Stmm
71693052Stmmstatic __inline void
71793052Stmmbus_space_read_region_stream_8(bus_space_tag_t t, bus_space_handle_t h,
71893052Stmm    bus_size_t o, u_int64_t *a, bus_size_t c)
71986228Stmm{
72086228Stmm	for (; c; a++, c--, o+=8)
72186228Stmm		*a = bus_space_read_stream_8(t, h, o);
72286228Stmm}
72386228Stmm
72493052Stmmstatic __inline void
72593052Stmmbus_space_write_region_stream_1(bus_space_tag_t t, bus_space_handle_t h,
72693052Stmm    bus_size_t o, const u_int8_t *a, bus_size_t c)
72786228Stmm{
72886228Stmm	for (; c; a++, c--, o++)
72986228Stmm		bus_space_write_stream_1(t, h, o, *a);
73086228Stmm}
73186228Stmm
73293052Stmmstatic __inline void
73393052Stmmbus_space_write_region_stream_2(bus_space_tag_t t, bus_space_handle_t h,
73493052Stmm    bus_size_t o, const u_int16_t *a, bus_size_t c)
73586228Stmm{
73686228Stmm	for (; c; a++, c--, o+=2)
73786228Stmm		bus_space_write_stream_2(t, h, o, *a);
73886228Stmm}
73986228Stmm
74093052Stmmstatic __inline void
74193052Stmmbus_space_write_region_stream_4(bus_space_tag_t t, bus_space_handle_t h,
74293052Stmm    bus_size_t o, const u_int32_t *a, bus_size_t c)
74386228Stmm{
74486228Stmm	for (; c; a++, c--, o+=4)
74586228Stmm		bus_space_write_stream_4(t, h, o, *a);
74686228Stmm}
74786228Stmm
74893052Stmmstatic __inline void
74993052Stmmbus_space_write_region_stream_8(bus_space_tag_t t, bus_space_handle_t h,
75093052Stmm    bus_size_t o, const u_int64_t *a, bus_size_t c)
75186228Stmm{
75286228Stmm	for (; c; a++, c--, o+=8)
75386228Stmm		bus_space_write_stream_8(t, h, o, *a);
75486228Stmm}
75586228Stmm
75693052Stmmstatic __inline void
75793052Stmmbus_space_set_region_stream_1(bus_space_tag_t t, bus_space_handle_t h,
75893052Stmm    bus_size_t o, const u_int8_t v, bus_size_t c)
75986228Stmm{
76086228Stmm	for (; c; c--, o++)
76186228Stmm		bus_space_write_stream_1(t, h, o, v);
76286228Stmm}
76386228Stmm
76493052Stmmstatic __inline void
76593052Stmmbus_space_set_region_stream_2(bus_space_tag_t t, bus_space_handle_t h,
76693052Stmm    bus_size_t o, const u_int16_t v, bus_size_t c)
76786228Stmm{
76886228Stmm	for (; c; c--, o+=2)
76986228Stmm		bus_space_write_stream_2(t, h, o, v);
77086228Stmm}
77186228Stmm
77293052Stmmstatic __inline void
77393052Stmmbus_space_set_region_stream_4(bus_space_tag_t t, bus_space_handle_t h,
77493052Stmm    bus_size_t o, const u_int32_t v, bus_size_t c)
77586228Stmm{
77686228Stmm	for (; c; c--, o+=4)
77786228Stmm		bus_space_write_stream_4(t, h, o, v);
77886228Stmm}
77986228Stmm
78093052Stmmstatic __inline void
78193052Stmmbus_space_set_region_stream_8(bus_space_tag_t t, bus_space_handle_t h,
78293052Stmm    bus_size_t o, const u_int64_t v, bus_size_t c)
78386228Stmm{
78486228Stmm	for (; c; c--, o+=8)
78586228Stmm		bus_space_write_stream_8(t, h, o, v);
78686228Stmm}
78786228Stmm
78893052Stmmstatic __inline void
78993052Stmmbus_space_copy_region_stream_1(bus_space_tag_t t, bus_space_handle_t h1,
79093052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
79186228Stmm{
79286228Stmm	for (; c; c--, o1++, o2++)
79386228Stmm	    bus_space_write_stream_1(t, h1, o1, bus_space_read_stream_1(t, h2,
79486228Stmm		o2));
79586228Stmm}
79686228Stmm
79793052Stmmstatic __inline void
79893052Stmmbus_space_copy_region_stream_2(bus_space_tag_t t, bus_space_handle_t h1,
79993052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
80086228Stmm{
80186228Stmm	for (; c; c--, o1+=2, o2+=2)
80286228Stmm	    bus_space_write_stream_2(t, h1, o1, bus_space_read_stream_2(t, h2,
80386228Stmm		o2));
80486228Stmm}
80586228Stmm
80693052Stmmstatic __inline void
80793052Stmmbus_space_copy_region_stream_4(bus_space_tag_t t, bus_space_handle_t h1,
80893052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
80986228Stmm{
81086228Stmm	for (; c; c--, o1+=4, o2+=4)
81186228Stmm	    bus_space_write_stream_4(t, h1, o1, bus_space_read_stream_4(t, h2,
81286228Stmm		o2));
81386228Stmm}
81486228Stmm
81593052Stmmstatic __inline void
81693052Stmmbus_space_copy_region_stream_8(bus_space_tag_t t, bus_space_handle_t h1,
81793052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
81886228Stmm{
81986228Stmm	for (; c; c--, o1+=8, o2+=8)
82086228Stmm	    bus_space_write_stream_8(t, h1, o1, bus_space_read_8(t, h2, o2));
82186228Stmm}
82286228Stmm
82386228Stmm/* Back-compat functions for old ISA drivers */
82486228Stmmextern bus_space_tag_t isa_io_bt;
82586228Stmmextern bus_space_handle_t isa_io_hdl;
82686228Stmmextern bus_space_tag_t isa_mem_bt;
82786228Stmmextern bus_space_handle_t isa_mem_hdl;
82886228Stmm
82986228Stmm#define inb(o)		bus_space_read_1(isa_io_bt, isa_io_hdl, o)
83086228Stmm#define inw(o)		bus_space_read_2(isa_io_bt, isa_io_hdl, o)
83186228Stmm#define inl(o)		bus_space_read_4(isa_io_bt, isa_io_hdl, o)
83290615Stmm#define outb(o, v)	bus_space_write_1(isa_io_bt, isa_io_hdl, o, v)
83386228Stmm#define outw(o, v)	bus_space_write_2(isa_io_bt, isa_io_hdl, o, v)
83486228Stmm#define outl(o, v)	bus_space_write_4(isa_io_bt, isa_io_hdl, o, v)
83586228Stmm
83686228Stmm#define readb(o)	bus_space_read_1(isa_mem_bt, isa_mem_hdl, o)
83786228Stmm#define readw(o)	bus_space_read_2(isa_mem_bt, isa_mem_hdl, o)
83886228Stmm#define readl(o)	bus_space_read_4(isa_mem_bt, isa_mem_hdl, o)
83986228Stmm#define writeb(o, v)	bus_space_write_1(isa_mem_bt, isa_mem_hdl, o, v)
84086228Stmm#define writew(o, v)	bus_space_write_2(isa_mem_bt, isa_mem_hdl, o, v)
84186228Stmm#define writel(o, v)	bus_space_write_4(isa_mem_bt, isa_mem_hdl, o, v)
84286228Stmm
84386228Stmm#define insb(o, a, c) \
84486228Stmm	bus_space_read_multi_1(isa_io_bt, isa_io_hdl, o, (void*)a, c)
84586228Stmm#define insw(o, a, c) \
84686228Stmm	bus_space_read_multi_2(isa_io_bt, isa_io_hdl, o, (void*)a, c)
84786228Stmm#define insl(o, a, c) \
84886228Stmm	bus_space_read_multi_4(isa_io_bt, isa_io_hdl, o, (void*)a, c)
84986228Stmm#define outsb(o, a, c) \
85086228Stmm	bus_space_write_multi_1(isa_io_bt, isa_io_hdl, o, (void*)a, c)
85186228Stmm#define outsw(o, a, c) \
85286228Stmm	bus_space_write_multi_2(isa_io_bt, isa_io_hdl, o, (void*)a, c)
85386228Stmm#define outsl(o, a, c) \
85486228Stmm	bus_space_write_multi_4(isa_io_bt, isa_io_hdl, o, (void*)a, c)
85586228Stmm
85686228Stmm#define memcpy_fromio(d, s, c) \
85786228Stmm	bus_space_read_region_1(isa_mem_bt, isa_mem_hdl, s, d, c)
85886228Stmm#define memcpy_toio(d, s, c) \
85986228Stmm	bus_space_write_region_1(isa_mem_bt, isa_mem_hdl, d, s, c)
86086228Stmm#define memcpy_io(d, s, c) \
86186228Stmm	bus_space_copy_region_1(isa_mem_bt, isa_mem_hdl, s, isa_mem_hdl, d, c)
86286228Stmm#define memset_io(d, v, c) \
86386228Stmm	bus_space_set_region_1(isa_mem_bt, isa_mem_hdl, d, v, c)
86486228Stmm#define memsetw_io(d, v, c) \
86586228Stmm	bus_space_set_region_2(isa_mem_bt, isa_mem_hdl, d, v, c)
86686228Stmm
86786228Stmmstatic __inline void
86886228Stmmmemsetw(void *d, int val, size_t size)
86986228Stmm{
87086228Stmm    u_int16_t *sp = d;
87186228Stmm
87286228Stmm    while (size--)
87386228Stmm	*sp++ = val;
87486228Stmm}
87586228Stmm
87686228Stmm/* DMA support */
87786228Stmm
87886228Stmm/*
87986228Stmm * Flags used in various bus DMA methods.
88086228Stmm */
88186228Stmm#define	BUS_DMA_WAITOK		0x000	/* safe to sleep (pseudo-flag) */
88286228Stmm#define	BUS_DMA_NOWAIT		0x001	/* not safe to sleep */
88386228Stmm#define	BUS_DMA_ALLOCNOW	0x002	/* perform resource allocation now */
88486228Stmm#define	BUS_DMAMEM_NOSYNC	0x004	/* map memory to not require sync */
88586228Stmm#define	BUS_DMA_NOWRITE		0x008
88690615Stmm#define	BUS_DMA_BUS1		0x010
88786228Stmm#define	BUS_DMA_BUS2		0x020
88886228Stmm#define	BUS_DMA_BUS3		0x040
88986228Stmm#define	BUS_DMA_BUS4		0x080
89086228Stmm/*
89186228Stmm * The following flags are from NetBSD, but are not implemented for all
89286228Stmm * architetures, and should therefore not be used in MI code.
89386228Stmm * Some have different values than under NetBSD.
89486228Stmm */
89586228Stmm#define	BUS_DMA_STREAMING	0x100	/* hint: sequential, unidirectional */
89686228Stmm#define	BUS_DMA_READ		0x200	/* mapping is device -> memory only */
89786228Stmm#define	BUS_DMA_WRITE		0x400	/* mapping is memory -> device only */
89886228Stmm#define	BUS_DMA_COHERENT	0x800	/* hint: map memory DMA coherent */
89986228Stmm
90086228Stmm#define	BUS_DMA_NOCACHE		BUS_DMA_BUS1
90186228Stmm/* Don't bother with alignment */
90286228Stmm#define	BUS_DMA_DVMA		BUS_DMA_BUS2
90386228Stmm
90486228Stmm/* Forwards needed by prototypes below. */
90586228Stmmstruct mbuf;
90686228Stmmstruct uio;
90786228Stmm
90886228Stmmtypedef enum {
90986228Stmm	BUS_DMASYNC_PREREAD,
91086228Stmm	BUS_DMASYNC_POSTREAD,
91186228Stmm	BUS_DMASYNC_PREWRITE,
91286228Stmm	BUS_DMASYNC_POSTWRITE,
91386228Stmm} bus_dmasync_op_t;
91486228Stmm
91586228Stmm/*
91686228Stmm * A function that returns 1 if the address cannot be accessed by
91786228Stmm * a device and 0 if it can be.
91886228Stmm */
91986228Stmmtypedef int bus_dma_filter_t(void *, bus_addr_t);
92086228Stmm
92186228Stmmtypedef struct bus_dma_tag	*bus_dma_tag_t;
92286228Stmmtypedef struct bus_dmamap	*bus_dmamap_t;
92386228Stmm
92486228Stmmstruct bus_dma_segment {
92586228Stmm	bus_addr_t	ds_addr;	/* DVMA address */
92686228Stmm	bus_size_t	ds_len;		/* length of transfer */
92786228Stmm};
92886228Stmmtypedef struct bus_dma_segment	bus_dma_segment_t;
92986228Stmm
93086228Stmm/*
93186228Stmm * A function that processes a successfully loaded dma map or an error
93286228Stmm * from a delayed load map.
93386228Stmm */
93486228Stmmtypedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
93586228Stmm
93686228Stmm/*
937104486Ssam * Like bus_dmamap_callback but includes map size in bytes.  This is
938104486Ssam * defined as a separate interface to maintain compatiiblity for users
939104486Ssam * of bus_dmamap_callback_t--at some point these interfaces should be merged.
940104486Ssam */
941104486Ssamtypedef void bus_dmamap_callback2_t(void *, bus_dma_segment_t *, int, bus_size_t, int);
942104486Ssam
943104486Ssam/*
94486228Stmm *	bus_dma_tag_t
94586228Stmm *
94686228Stmm *	A machine-dependent opaque type describing the implementation of
94786228Stmm *	DMA for a given bus.
94886228Stmm */
94986228Stmmstruct bus_dma_tag {
950108815Stmm	void		*dt_cookie;		/* cookie used in the guts */
951108815Stmm	bus_dma_tag_t	dt_parent;
952108815Stmm	bus_size_t	dt_alignment;
953108815Stmm	bus_size_t	dt_boundary;
954108815Stmm	bus_addr_t	dt_lowaddr;
955108815Stmm	bus_addr_t	dt_highaddr;
956108815Stmm	bus_dma_filter_t	*dt_filter;
957108815Stmm	void		*dt_filterarg;
958108815Stmm	bus_size_t	dt_maxsize;
959108815Stmm	int		dt_nsegments;
960108815Stmm	bus_size_t	dt_maxsegsz;
961108815Stmm	int		dt_flags;
962108815Stmm	int		dt_ref_count;
963108815Stmm	int		dt_map_count;
96486228Stmm
96586228Stmm	/*
96686228Stmm	 * DMA mapping methods.
96786228Stmm	 */
968108815Stmm	int	(*dt_dmamap_create)(bus_dma_tag_t, bus_dma_tag_t, int,
96993070Stmm	    bus_dmamap_t *);
970108815Stmm	int	(*dt_dmamap_destroy)(bus_dma_tag_t, bus_dma_tag_t,
971108815Stmm	    bus_dmamap_t);
972108815Stmm	int	(*dt_dmamap_load)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
97393070Stmm	    void *, bus_size_t, bus_dmamap_callback_t *, void *, int);
974108815Stmm	int	(*dt_dmamap_load_mbuf)(bus_dma_tag_t, bus_dma_tag_t,
975108815Stmm	    bus_dmamap_t, struct mbuf *, bus_dmamap_callback2_t *, void *, int);
976108815Stmm	int	(*dt_dmamap_load_uio)(bus_dma_tag_t, bus_dma_tag_t,
977108815Stmm	    bus_dmamap_t, struct uio *, bus_dmamap_callback2_t *, void *, int);
978108815Stmm	void	(*dt_dmamap_unload)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t);
979108815Stmm	void	(*dt_dmamap_sync)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
98093052Stmm	    bus_dmasync_op_t);
98186228Stmm
98286228Stmm	/*
98386228Stmm	 * DMA memory utility functions.
98486228Stmm	 */
985110030Sscottl	int	(*dt_dmamem_alloc_size)(bus_dma_tag_t, bus_dma_tag_t, void **,
986110030Sscottl	    int, bus_dmamap_t *, bus_size_t size);
987108815Stmm	int	(*dt_dmamem_alloc)(bus_dma_tag_t, bus_dma_tag_t, void **, int,
98893070Stmm	    bus_dmamap_t *);
989110030Sscottl	void	(*dt_dmamem_free_size)(bus_dma_tag_t, bus_dma_tag_t, void *,
990110030Sscottl	    bus_dmamap_t, bus_size_t size);
991108815Stmm	void	(*dt_dmamem_free)(bus_dma_tag_t, bus_dma_tag_t, void *,
99293070Stmm	    bus_dmamap_t);
99386228Stmm};
99486228Stmm
99586228Stmm/*
99686228Stmm * XXX: This is a kluge. It would be better to handle dma tags in a hierarchical
99786228Stmm * way, and have a BUS_GET_DMA_TAG(); however, since this is not currently the
99886228Stmm * case, save a root tag in the relevant bus attach function and use that.
99986228Stmm * Keep the hierarchical structure, it might become needed in the future.
100086228Stmm */
100186228Stmmextern bus_dma_tag_t sparc64_root_dma_tag;
100286228Stmm
100386228Stmmint bus_dma_tag_create(bus_dma_tag_t, bus_size_t, bus_size_t, bus_addr_t,
100493052Stmm    bus_addr_t, bus_dma_filter_t *, void *, bus_size_t, int, bus_size_t,
100593052Stmm    int, bus_dma_tag_t *);
100686228Stmm
100786228Stmmint bus_dma_tag_destroy(bus_dma_tag_t);
100886228Stmm
100986228Stmmint sparc64_dmamem_alloc_map(bus_dma_tag_t dmat, bus_dmamap_t *mapp);
101086228Stmmvoid sparc64_dmamem_free_map(bus_dma_tag_t dmat, bus_dmamap_t map);
101186228Stmm
101293070Stmmstatic __inline int
101393070Stmmsparc64_dmamap_create(bus_dma_tag_t pt, bus_dma_tag_t dt, int f,
101493070Stmm    bus_dmamap_t *p)
101593070Stmm{
101693070Stmm	bus_dma_tag_t lt;
101793070Stmm
1018108815Stmm	for (lt = pt; lt->dt_dmamap_create == NULL; lt = lt->dt_parent)
101993070Stmm		;
1020108815Stmm	return ((*lt->dt_dmamap_create)(lt, dt, f, p));
102193070Stmm}
102286228Stmm#define	bus_dmamap_create(t, f, p)					\
102393070Stmm	sparc64_dmamap_create((t), (t), (f), (p))
102493070Stmm
102593070Stmmstatic __inline int
102693070Stmmsparc64_dmamap_destroy(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t p)
102793070Stmm{
102893070Stmm	bus_dma_tag_t lt;
102993070Stmm
1030108815Stmm	for (lt = pt; lt->dt_dmamap_destroy == NULL; lt = lt->dt_parent)
103193070Stmm		;
1032108815Stmm	return ((*lt->dt_dmamap_destroy)(lt, dt, p));
103393070Stmm}
103486228Stmm#define	bus_dmamap_destroy(t, p)					\
103593070Stmm	sparc64_dmamap_destroy((t), (t), (p))
103693070Stmm
103793070Stmmstatic __inline int
103893070Stmmsparc64_dmamap_load(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t m,
103993070Stmm    void *p, bus_size_t s, bus_dmamap_callback_t *cb, void *cba, int f)
104093070Stmm{
104193070Stmm	bus_dma_tag_t lt;
104293070Stmm
1043108815Stmm	for (lt = pt; lt->dt_dmamap_load == NULL; lt = lt->dt_parent)
104493070Stmm		;
1045108815Stmm	return ((*lt->dt_dmamap_load)(lt, dt, m, p, s, cb, cba, f));
104693070Stmm}
104786228Stmm#define	bus_dmamap_load(t, m, p, s, cb, cba, f)				\
104893070Stmm	sparc64_dmamap_load((t), (t), (m), (p), (s), (cb), (cba), (f))
104993070Stmm
1050104486Ssamstatic __inline int
1051104486Ssamsparc64_dmamap_load_mbuf(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t m,
1052104486Ssam    struct mbuf *mb, bus_dmamap_callback2_t *cb, void *cba, int f)
1053104486Ssam{
1054104486Ssam	bus_dma_tag_t lt;
1055104486Ssam
1056108815Stmm	for (lt = pt; lt->dt_dmamap_load_mbuf == NULL; lt = lt->dt_parent)
1057104486Ssam		;
1058108815Stmm	return ((*lt->dt_dmamap_load_mbuf)(lt, dt, m, mb, cb, cba, f));
1059104486Ssam}
1060104486Ssam#define	bus_dmamap_load_mbuf(t, m, mb, cb, cba, f)				\
1061104486Ssam	sparc64_dmamap_load_mbuf((t), (t), (m), (mb), (cb), (cba), (f))
1062104486Ssam
1063104486Ssamstatic __inline int
1064104486Ssamsparc64_dmamap_load_uio(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t m,
1065104486Ssam    struct uio *ui, bus_dmamap_callback2_t *cb, void *cba, int f)
1066104486Ssam{
1067104486Ssam	bus_dma_tag_t lt;
1068104486Ssam
1069108815Stmm	for (lt = pt; lt->dt_dmamap_load_uio == NULL; lt = lt->dt_parent)
1070104486Ssam		;
1071108815Stmm	return ((*lt->dt_dmamap_load_uio)(lt, dt, m, ui, cb, cba, f));
1072104486Ssam}
1073104486Ssam#define	bus_dmamap_load_uio(t, m, ui, cb, cba, f)				\
1074104486Ssam	sparc64_dmamap_load_uio((t), (t), (m), (ui), (cb), (cba), (f))
1075104486Ssam
107693070Stmmstatic __inline void
107793070Stmmsparc64_dmamap_unload(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t p)
107893070Stmm{
107993070Stmm	bus_dma_tag_t lt;
108093070Stmm
1081108815Stmm	for (lt = pt; lt->dt_dmamap_unload == NULL; lt = lt->dt_parent)
108293070Stmm		;
1083108815Stmm	(*lt->dt_dmamap_unload)(lt, dt, p);
108493070Stmm}
108586228Stmm#define	bus_dmamap_unload(t, p)						\
108693070Stmm	sparc64_dmamap_unload((t), (t), (p))
108793070Stmm
108893070Stmmstatic __inline void
108993070Stmmsparc64_dmamap_sync(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t m,
109093070Stmm    bus_dmasync_op_t op)
109193070Stmm{
109293070Stmm	bus_dma_tag_t lt;
109393070Stmm
1094108815Stmm	for (lt = pt; lt->dt_dmamap_sync == NULL; lt = lt->dt_parent)
109593070Stmm		;
1096108815Stmm	(*lt->dt_dmamap_sync)(lt, dt, m, op);
109793070Stmm}
109886228Stmm#define	bus_dmamap_sync(t, m, op)					\
109993070Stmm	sparc64_dmamap_sync((t), (t), (m), (op))
110086228Stmm
110193070Stmmstatic __inline int
1102110030Sscottlsparc64_dmamem_alloc_size(bus_dma_tag_t pt, bus_dma_tag_t dt, void **v, int f,
1103110030Sscottl    bus_dmamap_t *m, bus_size_t s)
1104110030Sscottl{
1105110030Sscottl	bus_dma_tag_t lt;
1106110030Sscottl
1107110053Sscottl	for (lt = pt; lt->dt_dmamem_alloc_size == NULL; lt = lt->dt_parent)
1108110030Sscottl		;
1109110047Sscottl	return ((*lt->dt_dmamem_alloc_size)(lt, dt, v, f, m, s));
1110110030Sscottl}
1111110030Sscottl#define	bus_dmamem_alloc_size(t, v, f, m, s)				\
1112110030Sscottl	sparc64_dmamem_alloc_size((t), (t), (v), (f), (m), (s))
1113110030Sscottl
1114110030Sscottlstatic __inline int
111593070Stmmsparc64_dmamem_alloc(bus_dma_tag_t pt, bus_dma_tag_t dt, void **v, int f,
111693070Stmm    bus_dmamap_t *m)
111793070Stmm{
111893070Stmm	bus_dma_tag_t lt;
111993070Stmm
1120108815Stmm	for (lt = pt; lt->dt_dmamem_alloc == NULL; lt = lt->dt_parent)
112193070Stmm		;
1122108815Stmm	return ((*lt->dt_dmamem_alloc)(lt, dt, v, f, m));
112393070Stmm}
112486228Stmm#define	bus_dmamem_alloc(t, v, f, m)					\
112593070Stmm	sparc64_dmamem_alloc((t), (t), (v), (f), (m))
112693070Stmm
112793070Stmmstatic __inline void
1128110030Sscottlsparc64_dmamem_free_size(bus_dma_tag_t pt, bus_dma_tag_t dt, void *v,
1129110030Sscottl    bus_dmamap_t m, bus_size_t s)
1130110030Sscottl{
1131110030Sscottl	bus_dma_tag_t lt;
1132110030Sscottl
1133110053Sscottl	for (lt = pt; lt->dt_dmamem_free_size == NULL; lt = lt->dt_parent)
1134110030Sscottl		;
1135110047Sscottl	(*lt->dt_dmamem_free_size)(lt, dt, v, m, s);
1136110030Sscottl}
1137110030Sscottl#define	bus_dmamem_free_size(t, v, m, s)				\
1138110030Sscottl	sparc64_dmamem_free_size((t), (t), (v), (m), (s))
1139110030Sscottl
1140110030Sscottlstatic __inline void
114193070Stmmsparc64_dmamem_free(bus_dma_tag_t pt, bus_dma_tag_t dt, void *v,
114293070Stmm    bus_dmamap_t m)
114393070Stmm{
114493070Stmm	bus_dma_tag_t lt;
114593070Stmm
1146108815Stmm	for (lt = pt; lt->dt_dmamem_free == NULL; lt = lt->dt_parent)
114793070Stmm		;
1148108815Stmm	(*lt->dt_dmamem_free)(lt, dt, v, m);
114993070Stmm}
115086228Stmm#define	bus_dmamem_free(t, v, m)					\
115193070Stmm	sparc64_dmamem_free((t), (t), (v), (m))
115286228Stmm
115380708Sjake#endif /* !_MACHINE_BUS_H_ */
1154