bus.h revision 178172
1178172Simp/*      $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $    */
2178172Simp/*-
3178172Simp * $Id: bus.h,v 1.6 2007/08/09 11:23:32 katta Exp $
4178172Simp *
5178172Simp * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
6178172Simp * All rights reserved.
7178172Simp *
8178172Simp * This code is derived from software contributed to The NetBSD Foundation
9178172Simp * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10178172Simp * NASA Ames Research Center.
11178172Simp *
12178172Simp * Redistribution and use in source and binary forms, with or without
13178172Simp * modification, are permitted provided that the following conditions
14178172Simp * are met:
15178172Simp * 1. Redistributions of source code must retain the above copyright
16178172Simp *    notice, this list of conditions and the following disclaimer.
17178172Simp * 2. Redistributions in binary form must reproduce the above copyright
18178172Simp *    notice, this list of conditions and the following disclaimer in the
19178172Simp *    documentation and/or other materials provided with the distribution.
20178172Simp * 3. All advertising materials mentioning features or use of this software
21178172Simp *    must display the following acknowledgement:
22178172Simp *	This product includes software developed by the NetBSD
23178172Simp *	Foundation, Inc. and its contributors.
24178172Simp * 4. Neither the name of The NetBSD Foundation nor the names of its
25178172Simp *    contributors may be used to endorse or promote products derived
26178172Simp *    from this software without specific prior written permission.
27178172Simp *
28178172Simp * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29178172Simp * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30178172Simp * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31178172Simp * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32178172Simp * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33178172Simp * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34178172Simp * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35178172Simp * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36178172Simp * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37178172Simp * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38178172Simp * POSSIBILITY OF SUCH DAMAGE.
39178172Simp */
40178172Simp
41178172Simp/*
42178172Simp * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
43178172Simp * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
44178172Simp *
45178172Simp * Redistribution and use in source and binary forms, with or without
46178172Simp * modification, are permitted provided that the following conditions
47178172Simp * are met:
48178172Simp * 1. Redistributions of source code must retain the above copyright
49178172Simp *    notice, this list of conditions and the following disclaimer.
50178172Simp * 2. Redistributions in binary form must reproduce the above copyright
51178172Simp *    notice, this list of conditions and the following disclaimer in the
52178172Simp *    documentation and/or other materials provided with the distribution.
53178172Simp * 3. All advertising materials mentioning features or use of this software
54178172Simp *    must display the following acknowledgement:
55178172Simp *      This product includes software developed by Christopher G. Demetriou
56178172Simp *	for the NetBSD Project.
57178172Simp * 4. The name of the author may not be used to endorse or promote products
58178172Simp *    derived from this software without specific prior written permission
59178172Simp *
60178172Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
61178172Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
62178172Simp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
63178172Simp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
64178172Simp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
65178172Simp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
66178172Simp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
67178172Simp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
68178172Simp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
69178172Simp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70178172Simp *
71178172Simp *	from: src/sys/alpha/include/bus.h,v 1.5 1999/08/28 00:38:40 peter
72178172Simp * $FreeBSD: head/sys/mips/include/bus.h 178172 2008-04-13 07:27:37Z imp $
73178172Simp*/
74178172Simp
75178172Simp#ifndef _MACHINE_BUS_H_
76178172Simp#define	_MACHINE_BUS_H_
77178172Simp
78178172Simp#ifdef TARGET_OCTEON
79178172Simp#include <machine/bus_octeon.h>
80178172Simp#else
81178172Simp#include <machine/_bus.h>
82178172Simp#include <machine/cpufunc.h>
83178172Simp
84178172Simp/*
85178172Simp * Values for the mips bus space tag, not to be used directly by MI code.
86178172Simp */
87178172Simp#define	MIPS_BUS_SPACE_IO	0	/* space is i/o space */
88178172Simp#define	MIPS_BUS_SPACE_MEM	1	/* space is mem space */
89178172Simp
90178172Simp
91178172Simp#define	BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
92178172Simp#define	BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
93178172Simp#define	BUS_SPACE_MAXSIZE	0xFFFFFFFF /* Maximum supported size */
94178172Simp#define	BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
95178172Simp#define	BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
96178172Simp#define	BUS_SPACE_MAXADDR	0xFFFFFFFF
97178172Simp
98178172Simp#define	BUS_SPACE_UNRESTRICTED	(~0)
99178172Simp
100178172Simp/*
101178172Simp * Map a region of device bus space into CPU virtual address space.
102178172Simp */
103178172Simp
104178172Simp__inline int	bus_space_map(bus_space_tag_t t, bus_addr_t addr,
105178172Simp		    bus_size_t size, int flags, bus_space_handle_t *bshp);
106178172Simp
107178172Simpstatic __inline int
108178172Simpbus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
109178172Simp	      bus_size_t size __unused, int flags __unused,
110178172Simp	      bus_space_handle_t *bshp)
111178172Simp{
112178172Simp
113178172Simp	*bshp = addr;
114178172Simp	return (0);
115178172Simp}
116178172Simp
117178172Simp/*
118178172Simp * Unmap a region of device bus space.
119178172Simp */
120178172Simp
121178172Simpvoid	bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
122178172Simp	    bus_size_t size);
123178172Simp
124178172Simp/*
125178172Simp * Get a new handle for a subregion of an already-mapped area of bus space.
126178172Simp */
127178172Simp
128178172Simpint	bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
129178172Simp	    bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
130178172Simp
131178172Simp/*
132178172Simp * Allocate a region of memory that is accessible to devices in bus space.
133178172Simp */
134178172Simp
135178172Simpint	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
136178172Simp	    bus_addr_t rend, bus_size_t size, bus_size_t align,
137178172Simp	    bus_size_t boundary, int flags, bus_addr_t *addrp,
138178172Simp	    bus_space_handle_t *bshp);
139178172Simp
140178172Simp/*
141178172Simp * Free a region of bus space accessible memory.
142178172Simp */
143178172Simp
144178172Simpvoid	bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
145178172Simp	    bus_size_t size);
146178172Simp
147178172Simp
148178172Simp/*
149178172Simp * Read a 1, 2, 4, or 8 byte quantity from bus space
150178172Simp * described by tag/handle/offset.
151178172Simp */
152178172Simpstatic __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
153178172Simp					  bus_space_handle_t handle,
154178172Simp					  bus_size_t offset);
155178172Simp
156178172Simpstatic __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
157178172Simp					   bus_space_handle_t handle,
158178172Simp					   bus_size_t offset);
159178172Simp
160178172Simpstatic __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
161178172Simp					   bus_space_handle_t handle,
162178172Simp					   bus_size_t offset);
163178172Simp
164178172Simpstatic __inline u_int8_t
165178172Simpbus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
166178172Simp    bus_size_t offset)
167178172Simp{
168178172Simp
169178172Simp	if (tag == MIPS_BUS_SPACE_IO)
170178172Simp		return (inb(handle + offset));
171178172Simp	return (readb(handle + offset));
172178172Simp}
173178172Simp
174178172Simpstatic __inline u_int16_t
175178172Simpbus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
176178172Simp    bus_size_t offset)
177178172Simp{
178178172Simp
179178172Simp	if (tag == MIPS_BUS_SPACE_IO)
180178172Simp		return (inw(handle + offset));
181178172Simp	return (readw(handle + offset));
182178172Simp}
183178172Simp
184178172Simpstatic __inline u_int32_t
185178172Simpbus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
186178172Simp    bus_size_t offset)
187178172Simp{
188178172Simp
189178172Simp	if (tag == MIPS_BUS_SPACE_IO)
190178172Simp		return (inl(handle + offset));
191178172Simp	return (readl(handle + offset));
192178172Simp}
193178172Simp
194178172Simp#if 0	/* Cause a link error for bus_space_read_8 */
195178172Simp#define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
196178172Simp#endif
197178172Simp
198178172Simp/*
199178172Simp * Read `count' 1, 2, 4, or 8 byte quantities from bus space
200178172Simp * described by tag/handle/offset and copy into buffer provided.
201178172Simp */
202178172Simpstatic __inline void bus_space_read_multi_1(bus_space_tag_t tag,
203178172Simp					    bus_space_handle_t bsh,
204178172Simp					    bus_size_t offset, u_int8_t *addr,
205178172Simp					    size_t count);
206178172Simp
207178172Simpstatic __inline void bus_space_read_multi_2(bus_space_tag_t tag,
208178172Simp					    bus_space_handle_t bsh,
209178172Simp					    bus_size_t offset, u_int16_t *addr,
210178172Simp					    size_t count);
211178172Simp
212178172Simpstatic __inline void bus_space_read_multi_4(bus_space_tag_t tag,
213178172Simp					    bus_space_handle_t bsh,
214178172Simp					    bus_size_t offset, u_int32_t *addr,
215178172Simp					    size_t count);
216178172Simp
217178172Simpstatic __inline void
218178172Simpbus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
219178172Simp    bus_size_t offset, u_int8_t *addr, size_t count)
220178172Simp{
221178172Simp
222178172Simp	if (tag == MIPS_BUS_SPACE_IO)
223178172Simp		while (count--)
224178172Simp			*addr++ = inb(bsh + offset);
225178172Simp	else
226178172Simp	while (count--)
227178172Simp		*addr++ = readb(bsh + offset);
228178172Simp}
229178172Simp
230178172Simpstatic __inline void
231178172Simpbus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
232178172Simp    bus_size_t offset, u_int16_t *addr, size_t count)
233178172Simp{
234178172Simp	bus_addr_t baddr = bsh + offset;
235178172Simp
236178172Simp	if (tag == MIPS_BUS_SPACE_IO)
237178172Simp		while (count--)
238178172Simp			*addr++ = inw(baddr);
239178172Simp	else
240178172Simp		while (count--)
241178172Simp			*addr++ = readw(baddr);
242178172Simp}
243178172Simp
244178172Simpstatic __inline void
245178172Simpbus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
246178172Simp    bus_size_t offset, u_int32_t *addr, size_t count)
247178172Simp{
248178172Simp	bus_addr_t baddr = bsh + offset;
249178172Simp
250178172Simp	if (tag == MIPS_BUS_SPACE_IO)
251178172Simp		while (count--)
252178172Simp			*addr++ = inl(baddr);
253178172Simp	else
254178172Simp		while (count--)
255178172Simp			*addr++ = readl(baddr);
256178172Simp}
257178172Simp
258178172Simp#if 0	/* Cause a link error for bus_space_read_multi_8 */
259178172Simp#define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
260178172Simp#endif
261178172Simp
262178172Simp/*
263178172Simp * Read `count' 1, 2, 4, or 8 byte quantities from bus space
264178172Simp * described by tag/handle and starting at `offset' and copy into
265178172Simp * buffer provided.
266178172Simp */
267178172Simpstatic __inline void bus_space_read_region_1(bus_space_tag_t tag,
268178172Simp					     bus_space_handle_t bsh,
269178172Simp					     bus_size_t offset, u_int8_t *addr,
270178172Simp					     size_t count);
271178172Simp
272178172Simpstatic __inline void bus_space_read_region_2(bus_space_tag_t tag,
273178172Simp					     bus_space_handle_t bsh,
274178172Simp					     bus_size_t offset, u_int16_t *addr,
275178172Simp					     size_t count);
276178172Simp
277178172Simpstatic __inline void bus_space_read_region_4(bus_space_tag_t tag,
278178172Simp					     bus_space_handle_t bsh,
279178172Simp					     bus_size_t offset, u_int32_t *addr,
280178172Simp					     size_t count);
281178172Simp
282178172Simp
283178172Simpstatic __inline void
284178172Simpbus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
285178172Simp    bus_size_t offset, u_int8_t *addr, size_t count)
286178172Simp{
287178172Simp	bus_addr_t baddr = bsh + offset;
288178172Simp
289178172Simp	if (tag == MIPS_BUS_SPACE_IO)
290178172Simp		while (count--) {
291178172Simp			*addr++ = inb(baddr);
292178172Simp			baddr += 1;
293178172Simp		}
294178172Simp	else
295178172Simp		while (count--) {
296178172Simp			*addr++ = readb(baddr);
297178172Simp			baddr += 1;
298178172Simp		}
299178172Simp}
300178172Simp
301178172Simpstatic __inline void
302178172Simpbus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
303178172Simp    bus_size_t offset, u_int16_t *addr, size_t count)
304178172Simp{
305178172Simp	bus_addr_t baddr = bsh + offset;
306178172Simp
307178172Simp	if (tag == MIPS_BUS_SPACE_IO)
308178172Simp		while (count--) {
309178172Simp			*addr++ = inw(baddr);
310178172Simp			baddr += 2;
311178172Simp		}
312178172Simp	else
313178172Simp		while (count--) {
314178172Simp			*addr++ = readw(baddr);
315178172Simp			baddr += 2;
316178172Simp		}
317178172Simp}
318178172Simp
319178172Simpstatic __inline void
320178172Simpbus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
321178172Simp    bus_size_t offset, u_int32_t *addr, size_t count)
322178172Simp{
323178172Simp	bus_addr_t baddr = bsh + offset;
324178172Simp
325178172Simp	if (tag == MIPS_BUS_SPACE_IO)
326178172Simp		while (count--) {
327178172Simp			*addr++ = inl(baddr);
328178172Simp			baddr += 4;
329178172Simp		}
330178172Simp	else
331178172Simp		while (count--) {
332178172Simp			*addr++ = readb(baddr);
333178172Simp			baddr += 4;
334178172Simp		}
335178172Simp}
336178172Simp
337178172Simp#if 0	/* Cause a link error for bus_space_read_region_8 */
338178172Simp#define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
339178172Simp#endif
340178172Simp
341178172Simp/*
342178172Simp * Write the 1, 2, 4, or 8 byte value `value' to bus space
343178172Simp * described by tag/handle/offset.
344178172Simp */
345178172Simp
346178172Simpstatic __inline void bus_space_write_1(bus_space_tag_t tag,
347178172Simp				       bus_space_handle_t bsh,
348178172Simp				       bus_size_t offset, u_int8_t value);
349178172Simp
350178172Simpstatic __inline void bus_space_write_2(bus_space_tag_t tag,
351178172Simp				       bus_space_handle_t bsh,
352178172Simp				       bus_size_t offset, u_int16_t value);
353178172Simp
354178172Simpstatic __inline void bus_space_write_4(bus_space_tag_t tag,
355178172Simp				       bus_space_handle_t bsh,
356178172Simp				       bus_size_t offset, u_int32_t value);
357178172Simp
358178172Simpstatic __inline void
359178172Simpbus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
360178172Simp    bus_size_t offset, u_int8_t value)
361178172Simp{
362178172Simp
363178172Simp	if (tag == MIPS_BUS_SPACE_IO)
364178172Simp		outb(bsh + offset, value);
365178172Simp	else
366178172Simp		writeb(bsh + offset, value);
367178172Simp}
368178172Simp
369178172Simpstatic __inline void
370178172Simpbus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
371178172Simp    bus_size_t offset, u_int16_t value)
372178172Simp{
373178172Simp
374178172Simp	if (tag == MIPS_BUS_SPACE_IO)
375178172Simp		outw(bsh + offset, value);
376178172Simp	else
377178172Simp		writew(bsh + offset, value);
378178172Simp}
379178172Simp
380178172Simpstatic __inline void
381178172Simpbus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
382178172Simp    bus_size_t offset, u_int32_t value)
383178172Simp{
384178172Simp
385178172Simp	if (tag == MIPS_BUS_SPACE_IO)
386178172Simp		outl(bsh + offset, value);
387178172Simp	else
388178172Simp		writel(bsh + offset, value);
389178172Simp}
390178172Simp
391178172Simp#if 0	/* Cause a link error for bus_space_write_8 */
392178172Simp#define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
393178172Simp#endif
394178172Simp
395178172Simp/*
396178172Simp * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
397178172Simp * provided to bus space described by tag/handle/offset.
398178172Simp */
399178172Simp
400178172Simpstatic __inline void bus_space_write_multi_1(bus_space_tag_t tag,
401178172Simp					     bus_space_handle_t bsh,
402178172Simp					     bus_size_t offset,
403178172Simp					     const u_int8_t *addr,
404178172Simp					     size_t count);
405178172Simpstatic __inline void bus_space_write_multi_2(bus_space_tag_t tag,
406178172Simp					     bus_space_handle_t bsh,
407178172Simp					     bus_size_t offset,
408178172Simp					     const u_int16_t *addr,
409178172Simp					     size_t count);
410178172Simp
411178172Simpstatic __inline void bus_space_write_multi_4(bus_space_tag_t tag,
412178172Simp					     bus_space_handle_t bsh,
413178172Simp					     bus_size_t offset,
414178172Simp					     const u_int32_t *addr,
415178172Simp					     size_t count);
416178172Simp
417178172Simpstatic __inline void
418178172Simpbus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
419178172Simp    bus_size_t offset, const u_int8_t *addr, size_t count)
420178172Simp{
421178172Simp	bus_addr_t baddr = bsh + offset;
422178172Simp
423178172Simp	if (tag == MIPS_BUS_SPACE_IO)
424178172Simp		while (count--)
425178172Simp			outb(baddr, *addr++);
426178172Simp	else
427178172Simp		while (count--)
428178172Simp			writeb(baddr, *addr++);
429178172Simp}
430178172Simp
431178172Simpstatic __inline void
432178172Simpbus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
433178172Simp    bus_size_t offset, const u_int16_t *addr, size_t count)
434178172Simp{
435178172Simp	bus_addr_t baddr = bsh + offset;
436178172Simp
437178172Simp	if (tag == MIPS_BUS_SPACE_IO)
438178172Simp		while (count--)
439178172Simp			outw(baddr, *addr++);
440178172Simp	else
441178172Simp		while (count--)
442178172Simp			writew(baddr, *addr++);
443178172Simp}
444178172Simp
445178172Simpstatic __inline void
446178172Simpbus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
447178172Simp    bus_size_t offset, const u_int32_t *addr, size_t count)
448178172Simp{
449178172Simp	bus_addr_t baddr = bsh + offset;
450178172Simp
451178172Simp	if (tag == MIPS_BUS_SPACE_IO)
452178172Simp		while (count--)
453178172Simp			outl(baddr, *addr++);
454178172Simp	else
455178172Simp		while (count--)
456178172Simp			writel(baddr, *addr++);
457178172Simp}
458178172Simp
459178172Simp#if 0	/* Cause a link error for bus_space_write_multi_8 */
460178172Simp#define	bus_space_write_multi_8(t, h, o, a, c)				\
461178172Simp			!!! bus_space_write_multi_8 unimplemented !!!
462178172Simp#endif
463178172Simp
464178172Simp/*
465178172Simp * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
466178172Simp * to bus space described by tag/handle starting at `offset'.
467178172Simp */
468178172Simp
469178172Simpstatic __inline void bus_space_write_region_1(bus_space_tag_t tag,
470178172Simp					      bus_space_handle_t bsh,
471178172Simp					      bus_size_t offset,
472178172Simp					      const u_int8_t *addr,
473178172Simp					      size_t count);
474178172Simpstatic __inline void bus_space_write_region_2(bus_space_tag_t tag,
475178172Simp					      bus_space_handle_t bsh,
476178172Simp					      bus_size_t offset,
477178172Simp					      const u_int16_t *addr,
478178172Simp					      size_t count);
479178172Simpstatic __inline void bus_space_write_region_4(bus_space_tag_t tag,
480178172Simp					      bus_space_handle_t bsh,
481178172Simp					      bus_size_t offset,
482178172Simp					      const u_int32_t *addr,
483178172Simp					      size_t count);
484178172Simp
485178172Simpstatic __inline void
486178172Simpbus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
487178172Simp    bus_size_t offset, const u_int8_t *addr, size_t count)
488178172Simp{
489178172Simp	bus_addr_t baddr = bsh + offset;
490178172Simp
491178172Simp	if (tag == MIPS_BUS_SPACE_IO)
492178172Simp		while (count--) {
493178172Simp			outb(baddr, *addr++);
494178172Simp			baddr += 1;
495178172Simp		}
496178172Simp	else
497178172Simp		while (count--) {
498178172Simp			writeb(baddr, *addr++);
499178172Simp			baddr += 1;
500178172Simp		}
501178172Simp}
502178172Simp
503178172Simpstatic __inline void
504178172Simpbus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
505178172Simp    bus_size_t offset, const u_int16_t *addr, size_t count)
506178172Simp{
507178172Simp	bus_addr_t baddr = bsh + offset;
508178172Simp
509178172Simp	if (tag == MIPS_BUS_SPACE_IO)
510178172Simp		while (count--) {
511178172Simp			outw(baddr, *addr++);
512178172Simp			baddr += 2;
513178172Simp		}
514178172Simp	else
515178172Simp		while (count--) {
516178172Simp			writew(baddr, *addr++);
517178172Simp			baddr += 2;
518178172Simp		}
519178172Simp}
520178172Simp
521178172Simpstatic __inline void
522178172Simpbus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
523178172Simp    bus_size_t offset, const u_int32_t *addr, size_t count)
524178172Simp{
525178172Simp	bus_addr_t baddr = bsh + offset;
526178172Simp
527178172Simp	if (tag == MIPS_BUS_SPACE_IO)
528178172Simp		while (count--) {
529178172Simp			outl(baddr, *addr++);
530178172Simp			baddr += 4;
531178172Simp		}
532178172Simp	else
533178172Simp		while (count--) {
534178172Simp			writel(baddr, *addr++);
535178172Simp			baddr += 4;
536178172Simp		}
537178172Simp}
538178172Simp
539178172Simp#if 0	/* Cause a link error for bus_space_write_region_8 */
540178172Simp#define	bus_space_write_region_8					\
541178172Simp			!!! bus_space_write_region_8 unimplemented !!!
542178172Simp#endif
543178172Simp
544178172Simp/*
545178172Simp * Write the 1, 2, 4, or 8 byte value `val' to bus space described
546178172Simp * by tag/handle/offset `count' times.
547178172Simp */
548178172Simp
549178172Simpstatic __inline void bus_space_set_multi_1(bus_space_tag_t tag,
550178172Simp					   bus_space_handle_t bsh,
551178172Simp					   bus_size_t offset,
552178172Simp					   u_int8_t value, size_t count);
553178172Simpstatic __inline void bus_space_set_multi_2(bus_space_tag_t tag,
554178172Simp					   bus_space_handle_t bsh,
555178172Simp					   bus_size_t offset,
556178172Simp					   u_int16_t value, size_t count);
557178172Simpstatic __inline void bus_space_set_multi_4(bus_space_tag_t tag,
558178172Simp					   bus_space_handle_t bsh,
559178172Simp					   bus_size_t offset,
560178172Simp					   u_int32_t value, size_t count);
561178172Simp
562178172Simpstatic __inline void
563178172Simpbus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
564178172Simp    bus_size_t offset, u_int8_t value, size_t count)
565178172Simp{
566178172Simp	bus_addr_t addr = bsh + offset;
567178172Simp
568178172Simp	if (tag == MIPS_BUS_SPACE_IO)
569178172Simp		while (count--)
570178172Simp			outb(addr, value);
571178172Simp	else
572178172Simp		while (count--)
573178172Simp			writeb(addr, value);
574178172Simp}
575178172Simp
576178172Simpstatic __inline void
577178172Simpbus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
578178172Simp    bus_size_t offset, u_int16_t value, size_t count)
579178172Simp{
580178172Simp	bus_addr_t addr = bsh + offset;
581178172Simp
582178172Simp	if (tag == MIPS_BUS_SPACE_IO)
583178172Simp		while (count--)
584178172Simp			outw(addr, value);
585178172Simp	else
586178172Simp		while (count--)
587178172Simp			writew(addr, value);
588178172Simp}
589178172Simp
590178172Simpstatic __inline void
591178172Simpbus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
592178172Simp    bus_size_t offset, u_int32_t value, size_t count)
593178172Simp{
594178172Simp	bus_addr_t addr = bsh + offset;
595178172Simp
596178172Simp	if (tag == MIPS_BUS_SPACE_IO)
597178172Simp		while (count--)
598178172Simp			outl(addr, value);
599178172Simp	else
600178172Simp		while (count--)
601178172Simp			writel(addr, value);
602178172Simp}
603178172Simp
604178172Simp#if 0	/* Cause a link error for bus_space_set_multi_8 */
605178172Simp#define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
606178172Simp#endif
607178172Simp
608178172Simp/*
609178172Simp * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
610178172Simp * by tag/handle starting at `offset'.
611178172Simp */
612178172Simp
613178172Simpstatic __inline void bus_space_set_region_1(bus_space_tag_t tag,
614178172Simp					    bus_space_handle_t bsh,
615178172Simp					    bus_size_t offset, u_int8_t value,
616178172Simp					    size_t count);
617178172Simpstatic __inline void bus_space_set_region_2(bus_space_tag_t tag,
618178172Simp					    bus_space_handle_t bsh,
619178172Simp					    bus_size_t offset, u_int16_t value,
620178172Simp					    size_t count);
621178172Simpstatic __inline void bus_space_set_region_4(bus_space_tag_t tag,
622178172Simp					    bus_space_handle_t bsh,
623178172Simp					    bus_size_t offset, u_int32_t value,
624178172Simp					    size_t count);
625178172Simp
626178172Simpstatic __inline void
627178172Simpbus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
628178172Simp    bus_size_t offset, u_int8_t value, size_t count)
629178172Simp{
630178172Simp	bus_addr_t addr = bsh + offset;
631178172Simp
632178172Simp	if (tag == MIPS_BUS_SPACE_IO)
633178172Simp		for (; count != 0; count--, addr++)
634178172Simp			outb(addr, value);
635178172Simp	else
636178172Simp		for (; count != 0; count--, addr++)
637178172Simp			writeb(addr, value);
638178172Simp}
639178172Simp
640178172Simpstatic __inline void
641178172Simpbus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
642178172Simp		       bus_size_t offset, u_int16_t value, size_t count)
643178172Simp{
644178172Simp	bus_addr_t addr = bsh + offset;
645178172Simp
646178172Simp	if (tag == MIPS_BUS_SPACE_IO)
647178172Simp		for (; count != 0; count--, addr += 2)
648178172Simp			outw(addr, value);
649178172Simp	else
650178172Simp		for (; count != 0; count--, addr += 2)
651178172Simp			writew(addr, value);
652178172Simp}
653178172Simp
654178172Simpstatic __inline void
655178172Simpbus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
656178172Simp    bus_size_t offset, u_int32_t value, size_t count)
657178172Simp{
658178172Simp	bus_addr_t addr = bsh + offset;
659178172Simp
660178172Simp	if (tag == MIPS_BUS_SPACE_IO)
661178172Simp		for (; count != 0; count--, addr += 4)
662178172Simp			outl(addr, value);
663178172Simp	else
664178172Simp		for (; count != 0; count--, addr += 4)
665178172Simp			writel(addr, value);
666178172Simp}
667178172Simp
668178172Simp#if 0	/* Cause a link error for bus_space_set_region_8 */
669178172Simp#define	bus_space_set_region_8	!!! bus_space_set_region_8 unimplemented !!!
670178172Simp#endif
671178172Simp
672178172Simp/*
673178172Simp * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
674178172Simp * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
675178172Simp */
676178172Simp
677178172Simpstatic __inline void bus_space_copy_region_1(bus_space_tag_t tag,
678178172Simp					     bus_space_handle_t bsh1,
679178172Simp					     bus_size_t off1,
680178172Simp					     bus_space_handle_t bsh2,
681178172Simp					     bus_size_t off2, size_t count);
682178172Simp
683178172Simpstatic __inline void bus_space_copy_region_2(bus_space_tag_t tag,
684178172Simp					     bus_space_handle_t bsh1,
685178172Simp					     bus_size_t off1,
686178172Simp					     bus_space_handle_t bsh2,
687178172Simp					     bus_size_t off2, size_t count);
688178172Simp
689178172Simpstatic __inline void bus_space_copy_region_4(bus_space_tag_t tag,
690178172Simp					     bus_space_handle_t bsh1,
691178172Simp					     bus_size_t off1,
692178172Simp					     bus_space_handle_t bsh2,
693178172Simp					     bus_size_t off2, size_t count);
694178172Simp
695178172Simpstatic __inline void
696178172Simpbus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
697178172Simp    bus_size_t off1, bus_space_handle_t bsh2,
698178172Simp    bus_size_t off2, size_t count)
699178172Simp{
700178172Simp	bus_addr_t addr1 = bsh1 + off1;
701178172Simp	bus_addr_t addr2 = bsh2 + off2;
702178172Simp
703178172Simp	if (tag == MIPS_BUS_SPACE_IO)
704178172Simp	{
705178172Simp		if (addr1 >= addr2) {
706178172Simp			/* src after dest: copy forward */
707178172Simp			for (; count != 0; count--, addr1++, addr2++)
708178172Simp				outb(addr2, inb(addr1));
709178172Simp		} else {
710178172Simp			/* dest after src: copy backwards */
711178172Simp			for (addr1 += (count - 1), addr2 += (count - 1);
712178172Simp			    count != 0; count--, addr1--, addr2--)
713178172Simp				outb(addr2, inb(addr1));
714178172Simp		}
715178172Simp	} else {
716178172Simp		if (addr1 >= addr2) {
717178172Simp			/* src after dest: copy forward */
718178172Simp			for (; count != 0; count--, addr1++, addr2++)
719178172Simp				writeb(addr2, readb(addr1));
720178172Simp		} else {
721178172Simp			/* dest after src: copy backwards */
722178172Simp			for (addr1 += (count - 1), addr2 += (count - 1);
723178172Simp			    count != 0; count--, addr1--, addr2--)
724178172Simp				writeb(addr2, readb(addr1));
725178172Simp		}
726178172Simp	}
727178172Simp}
728178172Simp
729178172Simpstatic __inline void
730178172Simpbus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
731178172Simp    bus_size_t off1, bus_space_handle_t bsh2,
732178172Simp    bus_size_t off2, size_t count)
733178172Simp{
734178172Simp	bus_addr_t addr1 = bsh1 + off1;
735178172Simp	bus_addr_t addr2 = bsh2 + off2;
736178172Simp
737178172Simp	if (tag == MIPS_BUS_SPACE_IO)
738178172Simp	{
739178172Simp		if (addr1 >= addr2) {
740178172Simp			/* src after dest: copy forward */
741178172Simp			for (; count != 0; count--, addr1 += 2, addr2 += 2)
742178172Simp				outw(addr2, inw(addr1));
743178172Simp		} else {
744178172Simp			/* dest after src: copy backwards */
745178172Simp			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
746178172Simp			    count != 0; count--, addr1 -= 2, addr2 -= 2)
747178172Simp				outw(addr2, inw(addr1));
748178172Simp		}
749178172Simp	} else {
750178172Simp		if (addr1 >= addr2) {
751178172Simp			/* src after dest: copy forward */
752178172Simp			for (; count != 0; count--, addr1 += 2, addr2 += 2)
753178172Simp				writew(addr2, readw(addr1));
754178172Simp		} else {
755178172Simp			/* dest after src: copy backwards */
756178172Simp			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
757178172Simp			    count != 0; count--, addr1 -= 2, addr2 -= 2)
758178172Simp				writew(addr2, readw(addr1));
759178172Simp		}
760178172Simp	}
761178172Simp}
762178172Simp
763178172Simpstatic __inline void
764178172Simpbus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
765178172Simp    bus_size_t off1, bus_space_handle_t bsh2,
766178172Simp    bus_size_t off2, size_t count)
767178172Simp{
768178172Simp	bus_addr_t addr1 = bsh1 + off1;
769178172Simp	bus_addr_t addr2 = bsh2 + off2;
770178172Simp
771178172Simp	if (tag == MIPS_BUS_SPACE_IO)
772178172Simp	{
773178172Simp		if (addr1 >= addr2) {
774178172Simp			/* src after dest: copy forward */
775178172Simp			for (; count != 0; count--, addr1 += 4, addr2 += 4)
776178172Simp				outl(addr2, inl(addr1));
777178172Simp		} else {
778178172Simp			/* dest after src: copy backwards */
779178172Simp			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
780178172Simp			    count != 0; count--, addr1 -= 4, addr2 -= 4)
781178172Simp				outl(addr2, inl(addr1));
782178172Simp		}
783178172Simp	} else {
784178172Simp		if (addr1 >= addr2) {
785178172Simp			/* src after dest: copy forward */
786178172Simp			for (; count != 0; count--, addr1 += 4, addr2 += 4)
787178172Simp				writel(addr2, readl(addr1));
788178172Simp		} else {
789178172Simp			/* dest after src: copy backwards */
790178172Simp			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
791178172Simp			    count != 0; count--, addr1 -= 4, addr2 -= 4)
792178172Simp				writel(addr2, readl(addr1));
793178172Simp		}
794178172Simp	}
795178172Simp}
796178172Simp
797178172Simp
798178172Simp#if 0	/* Cause a link error for bus_space_copy_8 */
799178172Simp#define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
800178172Simp#endif
801178172Simp
802178172Simp
803178172Simp/*
804178172Simp * Bus read/write barrier methods.
805178172Simp *
806178172Simp *	void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
807178172Simp *			       bus_size_t offset, bus_size_t len, int flags);
808178172Simp *
809178172Simp *
810178172Simp * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
811178172Simp * prevent reordering by the compiler; all Intel x86 processors currently
812178172Simp * retire operations outside the CPU in program order.
813178172Simp */
814178172Simp#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
815178172Simp#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
816178172Simp
817178172Simpstatic __inline void
818178172Simpbus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
819178172Simp		  bus_size_t offset __unused, bus_size_t len __unused, int flags)
820178172Simp{
821178172Simp#if 0
822178172Simp#ifdef __GNUCLIKE_ASM
823178172Simp	if (flags & BUS_SPACE_BARRIER_READ)
824178172Simp		__asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
825178172Simp	else
826178172Simp		__asm __volatile("" : : : "memory");
827178172Simp#endif
828178172Simp#endif
829178172Simp}
830178172Simp
831178172Simp#ifdef BUS_SPACE_NO_LEGACY
832178172Simp#undef inb
833178172Simp#undef outb
834178172Simp#define inb(a) compiler_error
835178172Simp#define inw(a) compiler_error
836178172Simp#define inl(a) compiler_error
837178172Simp#define outb(a, b) compiler_error
838178172Simp#define outw(a, b) compiler_error
839178172Simp#define outl(a, b) compiler_error
840178172Simp#endif
841178172Simp
842178172Simp#include <machine/bus_dma.h>
843178172Simp
844178172Simp/*
845178172Simp * Stream accesses are the same as normal accesses on amd64; there are no
846178172Simp * supported bus systems with an endianess different from the host one.
847178172Simp */
848178172Simp#define	bus_space_read_stream_1(t, h, o)	bus_space_read_1((t), (h), (o))
849178172Simp#define	bus_space_read_stream_2(t, h, o)	bus_space_read_2((t), (h), (o))
850178172Simp#define	bus_space_read_stream_4(t, h, o)	bus_space_read_4((t), (h), (o))
851178172Simp
852178172Simp#define	bus_space_read_multi_stream_1(t, h, o, a, c) \
853178172Simp	bus_space_read_multi_1((t), (h), (o), (a), (c))
854178172Simp#define	bus_space_read_multi_stream_2(t, h, o, a, c) \
855178172Simp	bus_space_read_multi_2((t), (h), (o), (a), (c))
856178172Simp#define	bus_space_read_multi_stream_4(t, h, o, a, c) \
857178172Simp	bus_space_read_multi_4((t), (h), (o), (a), (c))
858178172Simp
859178172Simp#define	bus_space_write_stream_1(t, h, o, v) \
860178172Simp	bus_space_write_1((t), (h), (o), (v))
861178172Simp#define	bus_space_write_stream_2(t, h, o, v) \
862178172Simp	bus_space_write_2((t), (h), (o), (v))
863178172Simp#define	bus_space_write_stream_4(t, h, o, v) \
864178172Simp	bus_space_write_4((t), (h), (o), (v))
865178172Simp
866178172Simp#define	bus_space_write_multi_stream_1(t, h, o, a, c) \
867178172Simp	bus_space_write_multi_1((t), (h), (o), (a), (c))
868178172Simp#define	bus_space_write_multi_stream_2(t, h, o, a, c) \
869178172Simp	bus_space_write_multi_2((t), (h), (o), (a), (c))
870178172Simp#define	bus_space_write_multi_stream_4(t, h, o, a, c) \
871178172Simp	bus_space_write_multi_4((t), (h), (o), (a), (c))
872178172Simp
873178172Simp#define	bus_space_set_multi_stream_1(t, h, o, v, c) \
874178172Simp	bus_space_set_multi_1((t), (h), (o), (v), (c))
875178172Simp#define	bus_space_set_multi_stream_2(t, h, o, v, c) \
876178172Simp	bus_space_set_multi_2((t), (h), (o), (v), (c))
877178172Simp#define	bus_space_set_multi_stream_4(t, h, o, v, c) \
878178172Simp	bus_space_set_multi_4((t), (h), (o), (v), (c))
879178172Simp
880178172Simp#define	bus_space_read_region_stream_1(t, h, o, a, c) \
881178172Simp	bus_space_read_region_1((t), (h), (o), (a), (c))
882178172Simp#define	bus_space_read_region_stream_2(t, h, o, a, c) \
883178172Simp	bus_space_read_region_2((t), (h), (o), (a), (c))
884178172Simp#define	bus_space_read_region_stream_4(t, h, o, a, c) \
885178172Simp	bus_space_read_region_4((t), (h), (o), (a), (c))
886178172Simp
887178172Simp#define	bus_space_write_region_stream_1(t, h, o, a, c) \
888178172Simp	bus_space_write_region_1((t), (h), (o), (a), (c))
889178172Simp#define	bus_space_write_region_stream_2(t, h, o, a, c) \
890178172Simp	bus_space_write_region_2((t), (h), (o), (a), (c))
891178172Simp#define	bus_space_write_region_stream_4(t, h, o, a, c) \
892178172Simp	bus_space_write_region_4((t), (h), (o), (a), (c))
893178172Simp
894178172Simp#define	bus_space_set_region_stream_1(t, h, o, v, c) \
895178172Simp	bus_space_set_region_1((t), (h), (o), (v), (c))
896178172Simp#define	bus_space_set_region_stream_2(t, h, o, v, c) \
897178172Simp	bus_space_set_region_2((t), (h), (o), (v), (c))
898178172Simp#define	bus_space_set_region_stream_4(t, h, o, v, c) \
899178172Simp	bus_space_set_region_4((t), (h), (o), (v), (c))
900178172Simp
901178172Simp#define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
902178172Simp	bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
903178172Simp#define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
904178172Simp	bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
905178172Simp#define	bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
906178172Simp	bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
907178172Simp
908178172Simp#endif /* !TARGET_OCTEON */
909178172Simp#endif /* !_MACHINE_BUS_H_ */
910