bus.h revision 99657
177957Sbenno/*-
277957Sbenno * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
377957Sbenno * All rights reserved.
477957Sbenno *
577957Sbenno * This code is derived from software contributed to The NetBSD Foundation
677957Sbenno * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
777957Sbenno * NASA Ames Research Center.
877957Sbenno *
977957Sbenno * Redistribution and use in source and binary forms, with or without
1077957Sbenno * modification, are permitted provided that the following conditions
1177957Sbenno * are met:
1277957Sbenno * 1. Redistributions of source code must retain the above copyright
1377957Sbenno *    notice, this list of conditions and the following disclaimer.
1477957Sbenno * 2. Redistributions in binary form must reproduce the above copyright
1577957Sbenno *    notice, this list of conditions and the following disclaimer in the
1677957Sbenno *    documentation and/or other materials provided with the distribution.
1777957Sbenno * 3. All advertising materials mentioning features or use of this software
1877957Sbenno *    must display the following acknowledgement:
1977957Sbenno *	This product includes software developed by the NetBSD
2077957Sbenno *	Foundation, Inc. and its contributors.
2177957Sbenno * 4. Neither the name of The NetBSD Foundation nor the names of its
2277957Sbenno *    contributors may be used to endorse or promote products derived
2377957Sbenno *    from this software without specific prior written permission.
2477957Sbenno *
2577957Sbenno * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2677957Sbenno * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2777957Sbenno * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2877957Sbenno * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2977957Sbenno * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3077957Sbenno * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3177957Sbenno * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3277957Sbenno * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3377957Sbenno * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3477957Sbenno * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3577957Sbenno * POSSIBILITY OF SUCH DAMAGE.
3677957Sbenno */
3777957Sbenno
3877957Sbenno/*
3977957Sbenno * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
4077957Sbenno * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
4177957Sbenno *
4277957Sbenno * Redistribution and use in source and binary forms, with or without
4377957Sbenno * modification, are permitted provided that the following conditions
4477957Sbenno * are met:
4577957Sbenno * 1. Redistributions of source code must retain the above copyright
4677957Sbenno *    notice, this list of conditions and the following disclaimer.
4777957Sbenno * 2. Redistributions in binary form must reproduce the above copyright
4877957Sbenno *    notice, this list of conditions and the following disclaimer in the
4977957Sbenno *    documentation and/or other materials provided with the distribution.
5077957Sbenno * 3. All advertising materials mentioning features or use of this software
5177957Sbenno *    must display the following acknowledgement:
5277957Sbenno *      This product includes software developed by Christopher G. Demetriou
5377957Sbenno *	for the NetBSD Project.
5477957Sbenno * 4. The name of the author may not be used to endorse or promote products
5577957Sbenno *    derived from this software without specific prior written permission
5677957Sbenno *
5777957Sbenno * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
5877957Sbenno * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5977957Sbenno * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
6077957Sbenno * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
6177957Sbenno * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
6277957Sbenno * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
6377957Sbenno * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
6477957Sbenno * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6577957Sbenno * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
6677957Sbenno * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6777957Sbenno *
6877957Sbenno *	$NetBSD: bus.h,v 1.9.4.1 2000/06/30 16:27:30 simonb Exp $
6977957Sbenno * $FreeBSD: head/sys/powerpc/include/bus.h 99657 2002-07-09 12:47:14Z benno $
7077957Sbenno */
7177957Sbenno
7277957Sbenno#ifndef	_MACPPC_BUS_H_
7377957Sbenno#define	_MACPPC_BUS_H_
7477957Sbenno
7577957Sbenno#include <machine/pio.h>
7677957Sbenno
7799657Sbenno#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
7899657Sbenno#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
7999657Sbenno#define BUS_SPACE_MAXSIZE       (128 * 1024) /* Maximum supported size */
8099657Sbenno#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
8199657Sbenno#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
8299657Sbenno#define BUS_SPACE_MAXADDR       0xFFFFFFFF
8399657Sbenno
8499657Sbenno#define BUS_SPACE_UNRESTRICTED  (~0)
8599657Sbenno
8677957Sbenno/*
8777957Sbenno * Values for the macppc bus space tag, not to be used directly by MI code.
8877957Sbenno */
8977957Sbenno
9077957Sbenno#define	__BUS_SPACE_HAS_STREAM_METHODS
9177957Sbenno
9299657Sbenno/*
9399657Sbenno * Values for the ppc bus space tag, not to be used directly by MI code.
9499657Sbenno */
9599657Sbenno#define PPC_BUS_SPACE_MEM      1       /* space is mem space */
9677957Sbenno
9777957Sbenno
9899657Sbenno#define	__BA(t, h, o) ((void *)((h) + (o)))
9999657Sbenno
10077957Sbenno/*
10177957Sbenno * Bus address and size types
10277957Sbenno */
10377957Sbennotypedef u_int32_t bus_addr_t;
10477957Sbennotypedef u_int32_t bus_size_t;
10577957Sbenno
10677957Sbenno/*
10777957Sbenno * Access methods for bus resources and address space.
10877957Sbenno */
10977957Sbennotypedef u_int32_t bus_space_tag_t;
11077957Sbennotypedef u_int32_t bus_space_handle_t;
11177957Sbenno
11299657Sbennostatic __inline void *
11399657Sbenno__ppc_ba(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset)
11499657Sbenno{
11599657Sbenno	return ((void *)(handle + offset));
11699657Sbenno}
11799657Sbenno
11899657Sbenno
11977957Sbenno/*
12092842Salfred *	int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
12177957Sbenno *	    bus_size_t size, int flags, bus_space_handle_t *bshp));
12277957Sbenno *
12377957Sbenno * Map a region of bus space.
12477957Sbenno */
12599657Sbenno#if 0
12699657Sbennobus_space_map(t, addr, size, flags, bshp) ! not implemented !
12799657Sbenno#endif
12877957Sbenno
12977957Sbenno/*
13092842Salfred *	int bus_space_unmap(bus_space_tag_t t,
13177957Sbenno *	    bus_space_handle_t bsh, bus_size_t size));
13277957Sbenno *
13377957Sbenno * Unmap a region of bus space.
13477957Sbenno */
13577957Sbenno
13677957Sbenno#define bus_space_unmap(t, bsh, size)
13777957Sbenno
13877957Sbenno/*
13992842Salfred *	int bus_space_subregion(bus_space_tag_t t,
14077957Sbenno *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
14177957Sbenno *	    bus_space_handle_t *nbshp));
14277957Sbenno *
14377957Sbenno * Get a new handle for a subregion of an already-mapped area of bus space.
14477957Sbenno */
14577957Sbenno
14677957Sbenno#define	bus_space_subregion(t, bsh, offset, size, bshp)			\
14799657Sbenno	((*(bshp) = (bus_space_handle_t)__ppc_ba(t, bsh, offset)), 0)
14877957Sbenno
14977957Sbenno/*
15092842Salfred *	int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
15177957Sbenno *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
15277957Sbenno *	    bus_size_t boundary, int flags, bus_addr_t *addrp,
15377957Sbenno *	    bus_space_handle_t *bshp));
15477957Sbenno *
15577957Sbenno * Allocate a region of bus space.
15677957Sbenno */
15777957Sbenno
15877957Sbenno#if 0
15977957Sbenno#define	bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)	!!! unimplemented !!!
16077957Sbenno#endif
16177957Sbenno
16277957Sbenno/*
16392842Salfred *	int bus_space_free(bus_space_tag_t t,
16477957Sbenno *	    bus_space_handle_t bsh, bus_size_t size));
16577957Sbenno *
16677957Sbenno * Free a region of bus space.
16777957Sbenno */
16877957Sbenno#if 0
16977957Sbenno#define	bus_space_free(t, h, s)		!!! unimplemented !!!
17077957Sbenno#endif
17177957Sbenno
17277957Sbenno/*
17392842Salfred *	u_intN_t bus_space_read_N(bus_space_tag_t tag,
17477957Sbenno *	    bus_space_handle_t bsh, bus_size_t offset));
17577957Sbenno *
17677957Sbenno * Read a 1, 2, 4, or 8 byte quantity from bus space
17777957Sbenno * described by tag/handle/offset.
17877957Sbenno */
17977957Sbenno
18099657Sbenno#define	bus_space_read_1(t, h, o)	(in8(__ppc_ba(t, h, o)))
18199657Sbenno#define	bus_space_read_2(t, h, o)	(in16rb(__ppc_ba(t, h, o)))
18299657Sbenno#define	bus_space_read_4(t, h, o)	(in32rb(__ppc_ba(t, h, o)))
18377957Sbenno#if 0	/* Cause a link error for bus_space_read_8 */
18477957Sbenno#define	bus_space_read_8(t, h, o)	!!! unimplemented !!!
18577957Sbenno#endif
18677957Sbenno
18799657Sbenno#define	bus_space_read_stream_1(t, h, o)	(in8(__ppc_ba(t, h, o)))
18899657Sbenno#define	bus_space_read_stream_2(t, h, o)	(in16(__ppc_ba(t, h, o)))
18999657Sbenno#define	bus_space_read_stream_4(t, h, o)	(in32(__ppc_ba(t, h, o)))
19077957Sbenno#if 0	/* Cause a link error for bus_space_read_stream_8 */
19177957Sbenno#define	bus_space_read_8(t, h, o)	!!! unimplemented !!!
19277957Sbenno#endif
19377957Sbenno
19477957Sbenno/*
19592842Salfred *	void bus_space_read_multi_N(bus_space_tag_t tag,
19677957Sbenno *	    bus_space_handle_t bsh, bus_size_t offset,
19777957Sbenno *	    u_intN_t *addr, size_t count));
19877957Sbenno *
19977957Sbenno * Read `count' 1, 2, 4, or 8 byte quantities from bus space
20077957Sbenno * described by tag/handle/offset and copy into buffer provided.
20177957Sbenno */
20277957Sbenno
20377957Sbenno#define	bus_space_read_multi_1(t, h, o, a, c) do {			\
20499657Sbenno		ins8(__ppc_ba(t, h, o), (a), (c));		       	\
20577957Sbenno	} while (0)
20677957Sbenno
20777957Sbenno#define	bus_space_read_multi_2(t, h, o, a, c) do {			\
20899657Sbenno		ins16rb(__ppc_ba(t, h, o), (a), (c));			\
20977957Sbenno	} while (0)
21077957Sbenno
21177957Sbenno#define	bus_space_read_multi_4(t, h, o, a, c) do {			\
21299657Sbenno		ins32rb(__ppc_ba(t, h, o), (a), (c));			\
21377957Sbenno	} while (0)
21477957Sbenno
21577957Sbenno#if 0	/* Cause a link error for bus_space_read_multi_8 */
21677957Sbenno#define	bus_space_read_multi_8		!!! unimplemented !!!
21777957Sbenno#endif
21877957Sbenno
21977957Sbenno#define	bus_space_read_multi_stream_1(t, h, o, a, c) do {		\
22099657Sbenno		ins8(__ppc_ba(t, h, o), (a), (c));		       	\
22177957Sbenno	} while (0)
22277957Sbenno
22377957Sbenno#define	bus_space_read_multi_stream_2(t, h, o, a, c) do {		\
22499657Sbenno		ins16(__ppc_ba(t, h, o), (a), (c));		       	\
22577957Sbenno	} while (0)
22677957Sbenno
22777957Sbenno#define	bus_space_read_multi_stream_4(t, h, o, a, c) do {		\
22899657Sbenno		ins32(__ppc_ba(t, h, o), (a), (c));		       	\
22977957Sbenno	} while (0)
23077957Sbenno
23177957Sbenno#if 0	/* Cause a link error for bus_space_read_multi_stream_8 */
23277957Sbenno#define	bus_space_read_multi_stream_8	!!! unimplemented !!!
23377957Sbenno#endif
23477957Sbenno
23577957Sbenno/*
23692842Salfred *	void bus_space_read_region_N(bus_space_tag_t tag,
23777957Sbenno *	    bus_space_handle_t bsh, bus_size_t offset,
23877957Sbenno *	    u_intN_t *addr, size_t count));
23977957Sbenno *
24077957Sbenno * Read `count' 1, 2, 4, or 8 byte quantities from bus space
24177957Sbenno * described by tag/handle and starting at `offset' and copy into
24277957Sbenno * buffer provided.
24377957Sbenno */
24477957Sbenno
24577957Sbennostatic __inline void
24677957Sbennobus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
24777957Sbenno    bus_size_t offset, u_int8_t *addr, size_t count)
24877957Sbenno{
24999657Sbenno	volatile u_int8_t *s = __ppc_ba(tag, bsh, offset);
25077957Sbenno
25177957Sbenno	while (count--)
25277957Sbenno		*addr++ = *s++;
25377957Sbenno	__asm __volatile("eieio; sync");
25477957Sbenno}
25577957Sbenno
25677957Sbennostatic __inline void
25777957Sbennobus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
25877957Sbenno    bus_size_t offset, u_int16_t *addr, size_t count)
25977957Sbenno{
26099657Sbenno	volatile u_int16_t *s = __ppc_ba(tag, bsh, offset);
26177957Sbenno
26277957Sbenno	while (count--)
26377957Sbenno		__asm __volatile("lhbrx %0, 0, %1" :
26477957Sbenno			"=r"(*addr++) : "r"(s++));
26577957Sbenno	__asm __volatile("eieio; sync");
26677957Sbenno}
26777957Sbenno
26877957Sbennostatic __inline void
26977957Sbennobus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
27077957Sbenno    bus_size_t offset, u_int32_t *addr, size_t count)
27177957Sbenno{
27299657Sbenno	volatile u_int32_t *s = __ppc_ba(tag, bsh, offset);
27377957Sbenno
27477957Sbenno	while (count--)
27577957Sbenno		__asm __volatile("lwbrx %0, 0, %1" :
27677957Sbenno			"=r"(*addr++) : "r"(s++));
27777957Sbenno	__asm __volatile("eieio; sync");
27877957Sbenno}
27977957Sbenno
28077957Sbenno#if 0	/* Cause a link error for bus_space_read_region_8 */
28177957Sbenno#define	bus_space_read_region_8		!!! unimplemented !!!
28277957Sbenno#endif
28377957Sbenno
28477957Sbennostatic __inline void
28577957Sbennobus_space_read_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
28677957Sbenno    bus_size_t offset, u_int16_t *addr, size_t count)
28777957Sbenno{
28899657Sbenno	volatile u_int16_t *s = __ppc_ba(tag, bsh, offset);
28977957Sbenno
29077957Sbenno	while (count--)
29177957Sbenno		*addr++ = *s++;
29277957Sbenno	__asm __volatile("eieio; sync");
29377957Sbenno}
29477957Sbenno
29577957Sbennostatic __inline void
29677957Sbennobus_space_read_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
29777957Sbenno    bus_size_t offset, u_int32_t *addr, size_t count)
29877957Sbenno{
29999657Sbenno	volatile u_int32_t *s = __ppc_ba(tag, bsh, offset);
30077957Sbenno
30177957Sbenno	while (count--)
30277957Sbenno		*addr++ = *s++;
30377957Sbenno	__asm __volatile("eieio; sync");
30477957Sbenno}
30577957Sbenno
30677957Sbenno#if 0	/* Cause a link error */
30777957Sbenno#define	bus_space_read_region_stream_8		!!! unimplemented !!!
30877957Sbenno#endif
30977957Sbenno
31077957Sbenno/*
31192842Salfred *	void bus_space_write_N(bus_space_tag_t tag,
31277957Sbenno *	    bus_space_handle_t bsh, bus_size_t offset,
31377957Sbenno *	    u_intN_t value));
31477957Sbenno *
31577957Sbenno * Write the 1, 2, 4, or 8 byte value `value' to bus space
31677957Sbenno * described by tag/handle/offset.
31777957Sbenno */
31877957Sbenno
31999657Sbenno#define bus_space_write_1(t, h, o, v)	out8(__ppc_ba(t, h, o), (v))
32099657Sbenno#define bus_space_write_2(t, h, o, v)	out16rb(__ppc_ba(t, h, o), (v))
32199657Sbenno#define bus_space_write_4(t, h, o, v)	out32rb(__ppc_ba(t, h, o), (v))
32277957Sbenno
32399657Sbenno#define bus_space_write_stream_1(t, h, o, v)	out8(__ppc_ba(t, h, o), (v))
32499657Sbenno#define bus_space_write_stream_2(t, h, o, v)	out16(__ppc_ba(t, h, o), (v))
32599657Sbenno#define bus_space_write_stream_4(t, h, o, v)	out32(__ppc_ba(t, h, o), (v))
32677957Sbenno
32777957Sbenno#if 0	/* Cause a link error for bus_space_write_8 */
32877957Sbenno#define bus_space_write_8		!!! unimplemented !!!
32977957Sbenno#endif
33077957Sbenno
33177957Sbenno/*
33292842Salfred *	void bus_space_write_multi_N(bus_space_tag_t tag,
33377957Sbenno *	    bus_space_handle_t bsh, bus_size_t offset,
33477957Sbenno *	    const u_intN_t *addr, size_t count));
33577957Sbenno *
33677957Sbenno * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
33777957Sbenno * provided to bus space described by tag/handle/offset.
33877957Sbenno */
33977957Sbenno
34077957Sbenno#define bus_space_write_multi_1(t, h, o, a, c) do {			\
34199657Sbenno		outsb(__ppc_ba(t, h, o), (a), (c));		       	\
34277957Sbenno	} while (0)
34377957Sbenno
34477957Sbenno#define bus_space_write_multi_2(t, h, o, a, c) do {			\
34599657Sbenno		outsw(__ppc_ba(t, h, o), (a), (c));		       	\
34677957Sbenno	} while (0)
34777957Sbenno
34877957Sbenno#define bus_space_write_multi_4(t, h, o, a, c) do {			\
34999657Sbenno		outsl(__ppc_ba(t, h, o), (a), (c));		       	\
35077957Sbenno	} while (0)
35177957Sbenno
35277957Sbenno#if 0
35377957Sbenno#define bus_space_write_multi_8		!!! unimplemented !!!
35477957Sbenno#endif
35577957Sbenno
35677957Sbenno#define bus_space_write_multi_stream_2(t, h, o, a, c) do {		\
35799657Sbenno		outsw(__ppc_ba(t, h, o), (a), (c));		       	\
35877957Sbenno	} while (0)
35977957Sbenno
36077957Sbenno#define bus_space_write_multi_stream_4(t, h, o, a, c) do {		\
36199657Sbenno		outsl(__ppc_ba(t, h, o), (a), (c));		       	\
36277957Sbenno	} while (0)
36377957Sbenno
36477957Sbenno#if 0
36577957Sbenno#define bus_space_write_multi_stream_8	!!! unimplemented !!!
36677957Sbenno#endif
36777957Sbenno
36877957Sbenno/*
36992842Salfred *	void bus_space_write_region_N(bus_space_tag_t tag,
37077957Sbenno *	    bus_space_handle_t bsh, bus_size_t offset,
37177957Sbenno *	    const u_intN_t *addr, size_t count));
37277957Sbenno *
37377957Sbenno * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
37477957Sbenno * to bus space described by tag/handle starting at `offset'.
37577957Sbenno */
37677957Sbenno
37777957Sbennostatic __inline void
37877957Sbennobus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
37977957Sbenno    bus_size_t offset, const u_int8_t *addr, size_t count)
38077957Sbenno{
38199657Sbenno	volatile u_int8_t *d = __ppc_ba(tag, bsh, offset);
38277957Sbenno
38377957Sbenno	while (count--)
38477957Sbenno		*d++ = *addr++;
38577957Sbenno	__asm __volatile("eieio; sync");
38677957Sbenno}
38777957Sbenno
38877957Sbennostatic __inline void
38977957Sbennobus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
39077957Sbenno    bus_size_t offset, const u_int16_t *addr, size_t count)
39177957Sbenno{
39299657Sbenno	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
39377957Sbenno
39477957Sbenno	while (count--)
39577957Sbenno		__asm __volatile("sthbrx %0, 0, %1" ::
39677957Sbenno			"r"(*addr++), "r"(d++));
39777957Sbenno	__asm __volatile("eieio; sync");
39877957Sbenno}
39977957Sbenno
40077957Sbennostatic __inline void
40177957Sbennobus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
40277957Sbenno    bus_size_t offset, const u_int32_t *addr, size_t count)
40377957Sbenno{
40499657Sbenno	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
40577957Sbenno
40677957Sbenno	while (count--)
40777957Sbenno		__asm __volatile("stwbrx %0, 0, %1" ::
40877957Sbenno			"r"(*addr++), "r"(d++));
40977957Sbenno	__asm __volatile("eieio; sync");
41077957Sbenno}
41177957Sbenno
41277957Sbenno#if 0
41377957Sbenno#define	bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!!
41477957Sbenno#endif
41577957Sbenno
41677957Sbennostatic __inline void
41777957Sbennobus_space_write_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
41877957Sbenno    bus_size_t offset, const u_int16_t *addr, size_t count)
41977957Sbenno{
42099657Sbenno	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
42177957Sbenno
42277957Sbenno	while (count--)
42377957Sbenno		*d++ = *addr++;
42477957Sbenno	__asm __volatile("eieio; sync");
42577957Sbenno}
42677957Sbenno
42777957Sbennostatic __inline void
42877957Sbennobus_space_write_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
42977957Sbenno    bus_size_t offset, const u_int32_t *addr, size_t count)
43077957Sbenno{
43199657Sbenno	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
43277957Sbenno
43377957Sbenno	while (count--)
43477957Sbenno		*d++ = *addr++;
43577957Sbenno	__asm __volatile("eieio; sync");
43677957Sbenno}
43777957Sbenno
43877957Sbenno#if 0
43977957Sbenno#define	bus_space_write_region_stream_8	!!! unimplemented !!!
44077957Sbenno#endif
44177957Sbenno
44277957Sbenno/*
44392842Salfred *	void bus_space_set_multi_N(bus_space_tag_t tag,
44477957Sbenno *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
44577957Sbenno *	    size_t count));
44677957Sbenno *
44777957Sbenno * Write the 1, 2, 4, or 8 byte value `val' to bus space described
44877957Sbenno * by tag/handle/offset `count' times.
44977957Sbenno */
45077957Sbenno
45177957Sbennostatic __inline void
45277957Sbennobus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
45377957Sbenno    bus_size_t offset, u_int8_t val, size_t count)
45477957Sbenno{
45599657Sbenno	volatile u_int8_t *d = __ppc_ba(tag, bsh, offset);
45677957Sbenno
45777957Sbenno	while (count--)
45877957Sbenno		*d = val;
45977957Sbenno	__asm __volatile("eieio; sync");
46077957Sbenno}
46177957Sbenno
46277957Sbennostatic __inline void
46377957Sbennobus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
46477957Sbenno    bus_size_t offset, u_int16_t val, size_t count)
46577957Sbenno{
46699657Sbenno	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
46777957Sbenno
46877957Sbenno	while (count--)
46977957Sbenno		__asm __volatile("sthbrx %0, 0, %1" ::
47077957Sbenno			"r"(val), "r"(d));
47177957Sbenno	__asm __volatile("eieio; sync");
47277957Sbenno}
47377957Sbenno
47477957Sbennostatic __inline void
47577957Sbennobus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
47677957Sbenno    bus_size_t offset, u_int32_t val, size_t count)
47777957Sbenno{
47899657Sbenno	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
47977957Sbenno
48077957Sbenno	while (count--)
48177957Sbenno		__asm __volatile("stwbrx %0, 0, %1" ::
48277957Sbenno			"r"(val), "r"(d));
48377957Sbenno	__asm __volatile("eieio; sync");
48477957Sbenno}
48577957Sbenno
48677957Sbenno#if 0
48777957Sbenno#define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
48877957Sbenno#endif
48977957Sbenno
49077957Sbennostatic __inline void
49177957Sbennobus_space_set_multi_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
49277957Sbenno    bus_size_t offset, u_int16_t val, size_t count)
49377957Sbenno{
49499657Sbenno	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
49577957Sbenno
49677957Sbenno	while (count--)
49777957Sbenno		*d = val;
49877957Sbenno	__asm __volatile("eieio; sync");
49977957Sbenno}
50077957Sbenno
50177957Sbennostatic __inline void
50277957Sbennobus_space_set_multi_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
50377957Sbenno    bus_size_t offset, u_int32_t val, size_t count)
50477957Sbenno{
50599657Sbenno	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
50677957Sbenno
50777957Sbenno	while (count--)
50877957Sbenno		*d = val;
50977957Sbenno	__asm __volatile("eieio; sync");
51077957Sbenno}
51177957Sbenno
51277957Sbenno#if 0
51377957Sbenno#define	bus_space_set_multi_stream_8	!!! unimplemented !!!
51477957Sbenno#endif
51577957Sbenno
51677957Sbenno/*
51792842Salfred *	void bus_space_set_region_N(bus_space_tag_t tag,
51877957Sbenno *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
51977957Sbenno *	    size_t count));
52077957Sbenno *
52177957Sbenno * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
52277957Sbenno * by tag/handle starting at `offset'.
52377957Sbenno */
52477957Sbenno
52577957Sbennostatic __inline void
52677957Sbennobus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
52777957Sbenno    bus_size_t offset, u_int8_t val, size_t count)
52877957Sbenno{
52999657Sbenno	volatile u_int8_t *d = __ppc_ba(tag, bsh, offset);
53077957Sbenno
53177957Sbenno	while (count--)
53277957Sbenno		*d++ = val;
53377957Sbenno	__asm __volatile("eieio; sync");
53477957Sbenno}
53577957Sbenno
53677957Sbennostatic __inline void
53777957Sbennobus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
53877957Sbenno    bus_size_t offset, u_int16_t val, size_t count)
53977957Sbenno{
54099657Sbenno	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
54177957Sbenno
54277957Sbenno	while (count--)
54377957Sbenno		__asm __volatile("sthbrx %0, 0, %1" ::
54477957Sbenno			"r"(val), "r"(d++));
54577957Sbenno	__asm __volatile("eieio; sync");
54677957Sbenno}
54777957Sbenno
54877957Sbennostatic __inline void
54977957Sbennobus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
55077957Sbenno    bus_size_t offset, u_int32_t val, size_t count)
55177957Sbenno{
55299657Sbenno	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
55377957Sbenno
55477957Sbenno	while (count--)
55577957Sbenno		__asm __volatile("stwbrx %0, 0, %1" ::
55677957Sbenno			"r"(val), "r"(d++));
55777957Sbenno	__asm __volatile("eieio; sync");
55877957Sbenno}
55977957Sbenno
56077957Sbenno#if 0
56177957Sbenno#define	bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
56277957Sbenno#endif
56377957Sbenno
56477957Sbennostatic __inline void
56577957Sbennobus_space_set_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
56677957Sbenno    bus_size_t offset, u_int16_t val, size_t count)
56777957Sbenno{
56899657Sbenno	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
56977957Sbenno
57077957Sbenno	while (count--)
57177957Sbenno		*d++ = val;
57277957Sbenno	__asm __volatile("eieio; sync");
57377957Sbenno}
57477957Sbenno
57577957Sbennostatic __inline void
57677957Sbennobus_space_set_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
57777957Sbenno    bus_size_t offset, u_int32_t val, size_t count)
57877957Sbenno{
57999657Sbenno	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
58077957Sbenno
58177957Sbenno	while (count--)
58277957Sbenno		*d++ = val;
58377957Sbenno	__asm __volatile("eieio; sync");
58477957Sbenno}
58577957Sbenno
58677957Sbenno#if 0
58777957Sbenno#define	bus_space_set_region_stream_8	!!! unimplemented !!!
58877957Sbenno#endif
58977957Sbenno
59077957Sbenno/*
59192842Salfred *	void bus_space_copy_region_N(bus_space_tag_t tag,
59277957Sbenno *	    bus_space_handle_t bsh1, bus_size_t off1,
59377957Sbenno *	    bus_space_handle_t bsh2, bus_size_t off2,
59477957Sbenno *	    size_t count));
59577957Sbenno *
59677957Sbenno * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
59777957Sbenno * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
59877957Sbenno */
59977957Sbenno
60077957Sbenno	/* XXX IMPLEMENT bus_space_copy_N() XXX */
60177957Sbenno
60277957Sbenno/*
60377957Sbenno * Bus read/write barrier methods.
60477957Sbenno *
60592842Salfred *	void bus_space_barrier(bus_space_tag_t tag,
60677957Sbenno *	    bus_space_handle_t bsh, bus_size_t offset,
60777957Sbenno *	    bus_size_t len, int flags));
60877957Sbenno *
60977957Sbenno * Note: the macppc does not currently require barriers, but we must
61077957Sbenno * provide the flags to MI code.
61177957Sbenno */
61277957Sbenno
61377957Sbenno#define bus_space_barrier(t, h, o, l, f)	\
61477957Sbenno	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
61577957Sbenno#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
61677957Sbenno#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
61777957Sbenno
61877957Sbenno#define	BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
61977957Sbenno
62077957Sbenno/*
62177957Sbenno * Bus DMA methods.
62277957Sbenno */
62377957Sbenno
62477957Sbenno/*
62577957Sbenno * Flags used in various bus DMA methods.
62677957Sbenno */
62777957Sbenno#define	BUS_DMA_WAITOK		0x00	/* safe to sleep (pseudo-flag) */
62877957Sbenno#define	BUS_DMA_NOWAIT		0x01	/* not safe to sleep */
62977957Sbenno#define	BUS_DMA_ALLOCNOW	0x02	/* perform resource allocation now */
63077957Sbenno#define	BUS_DMA_COHERENT	0x04	/* hint: map memory DMA coherent */
63177957Sbenno#define	BUS_DMA_BUS1		0x10	/* placeholders for bus functions... */
63277957Sbenno#define	BUS_DMA_BUS2		0x20
63377957Sbenno#define	BUS_DMA_BUS3		0x40
63477957Sbenno#define	BUS_DMA_BUS4		0x80
63577957Sbenno
63677957Sbenno/* Forwards needed by prototypes below. */
63777957Sbennostruct mbuf;
63877957Sbennostruct uio;
63977957Sbenno
64077957Sbenno/*
64199657Sbenno *      bus_dmasync_op_t
64299657Sbenno *
64399657Sbenno *      Operations performed by bus_dmamap_sync().
64477957Sbenno */
64599657Sbennotypedef enum {
64699657Sbenno	BUS_DMASYNC_PREREAD,
64799657Sbenno	BUS_DMASYNC_POSTREAD,
64899657Sbenno	BUS_DMASYNC_PREWRITE,
64999657Sbenno	BUS_DMASYNC_POSTWRITE
65099657Sbenno} bus_dmasync_op_t;
65177957Sbenno
65299657Sbenno/*
65399657Sbenno *      bus_dma_tag_t
65499657Sbenno *
65599657Sbenno *      A machine-dependent opaque type describing the characteristics
65699657Sbenno *      of how to perform DMA mappings.  This structure encapsultes
65799657Sbenno *      information concerning address and alignment restrictions, number
65899657Sbenno *      of S/G  segments, amount of data per S/G segment, etc.
65999657Sbenno */
66099657Sbennotypedef struct bus_dma_tag	*bus_dma_tag_t;
66177957Sbenno
66277957Sbenno/*
66399657Sbenno *      bus_dmamap_t
66499657Sbenno *
66599657Sbenno *      DMA mapping instance information.
66699657Sbenno */
66799657Sbennotypedef struct bus_dmamap	*bus_dmamap_t;
66899657Sbenno
66999657Sbenno/*
67077957Sbenno *	bus_dma_segment_t
67177957Sbenno *
67277957Sbenno *	Describes a single contiguous DMA transaction.  Values
67377957Sbenno *	are suitable for programming into DMA registers.
67477957Sbenno */
67599657Sbennotypedef struct bus_dma_segment {
67677957Sbenno	bus_addr_t	ds_addr;	/* DMA address */
67777957Sbenno	bus_size_t	ds_len;		/* length of transfer */
67899657Sbenno} bus_dma_segment_t;
67977957Sbenno
68077957Sbenno/*
68199657Sbenno * A function that returns 1 if the address cannot be accessed by
68299657Sbenno * a device and 0 if it can be.
68399657Sbenno */
68499657Sbennotypedef int bus_dma_filter_t(void *, bus_addr_t);
68599657Sbenno
68699657Sbenno/*
68799657Sbenno * Allocate a device specific dma_tag encapsulating the constraints of
68899657Sbenno * the parent tag in addition to other restrictions specified:
68977957Sbenno *
69099657Sbenno *      alignment:      alignment for segments.
69199657Sbenno *      boundary:       Boundary that segments cannot cross.
69299657Sbenno *      lowaddr:        Low restricted address that cannot appear in a mapping.
69399657Sbenno *      highaddr:       High restricted address that cannot appear in a mapping.
69499657Sbenno *      filtfunc:       An optional function to further test if an address
69599657Sbenno *                      within the range of lowaddr and highaddr cannot appear
69699657Sbenno *                      in a mapping.
69799657Sbenno *      filtfuncarg:    An argument that will be passed to filtfunc in addition
69899657Sbenno *                      to the address to test.
69999657Sbenno *      maxsize:        Maximum mapping size supported by this tag.
70099657Sbenno *      nsegments:      Number of discontinuities allowed in maps.
70199657Sbenno *      maxsegsz:       Maximum size of a segment in the map.
70299657Sbenno *      flags:          Bus DMA flags.
70399657Sbenno *      dmat:           A pointer to set to a valid dma tag should the return
70499657Sbenno *                      value of this function indicate success.
70577957Sbenno */
70699657Sbennoint bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
70799657Sbenno		       bus_size_t boundary, bus_addr_t lowaddr,
70899657Sbenno		       bus_addr_t highaddr, bus_dma_filter_t *filtfunc,
70999657Sbenno		       void *filtfuncarg, bus_size_t maxsize, int nsegments,
71099657Sbenno		       bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat);
71177957Sbenno
71299657Sbennoint bus_dma_tag_destroy(bus_dma_tag_t dmat);
71377957Sbenno
71499657Sbenno/*
71599657Sbenno * Allocate a handle for mapping from kva/uva/physical
71699657Sbenno * address space into bus device space.
71799657Sbenno */
71899657Sbennoint bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp);
71977957Sbenno
72099657Sbenno/*
72199657Sbenno * Destroy  a handle for mapping from kva/uva/physical
72299657Sbenno * address space into bus device space.
72399657Sbenno */
72499657Sbennoint bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map);
72577957Sbenno
72699657Sbenno/*
72799657Sbenno * Allocate a piece of memory that can be efficiently mapped into
72899657Sbenno * bus device space based on the constraints lited in the dma tag.
72999657Sbenno * A dmamap to for use with dmamap_load is also allocated.
73099657Sbenno */
73199657Sbennoint bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
73299657Sbenno		     bus_dmamap_t *mapp);
73377957Sbenno
73499657Sbenno/*
73599657Sbenno * Free a piece of memory and it's allociated dmamap, that was allocated
73699657Sbenno * via bus_dmamem_alloc.
73799657Sbenno */
73899657Sbennovoid bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map);
73977957Sbenno
74077957Sbenno/*
74199657Sbenno * A function that processes a successfully loaded dma map or an error
74299657Sbenno * from a delayed load map.
74377957Sbenno */
74499657Sbennotypedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
74577957Sbenno
74699657Sbenno/*
74799657Sbenno * Map the buffer buf into bus space using the dmamap map.
74899657Sbenno */
74999657Sbennoint bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
75099657Sbenno		    bus_size_t buflen, bus_dmamap_callback_t *callback,
75199657Sbenno		    void *callback_arg, int flags);
75277957Sbenno
75399657Sbenno/*
75499657Sbenno * Perform a syncronization operation on the given map.
75599657Sbenno */
75699657Sbennovoid bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t);
75777957Sbenno
75899657Sbenno/*
75999657Sbenno * Release the mapping held by map.
76099657Sbenno */
76199657Sbennovoid bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map);
76277957Sbenno
76377957Sbenno#endif /* _MACPPC_BUS_H_ */
764