bus.h revision 190515
1/*      $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $    */
2/*-
3 * $Id: bus.h,v 1.6 2007/08/09 11:23:32 katta Exp $
4 *
5 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10 * NASA Ames Research Center.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 *    must display the following acknowledgement:
22 *	This product includes software developed by the NetBSD
23 *	Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 *    contributors may be used to endorse or promote products derived
26 *    from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41/*
42 * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
43 * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
44 *
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
47 * are met:
48 * 1. Redistributions of source code must retain the above copyright
49 *    notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 *    notice, this list of conditions and the following disclaimer in the
52 *    documentation and/or other materials provided with the distribution.
53 * 3. All advertising materials mentioning features or use of this software
54 *    must display the following acknowledgement:
55 *      This product includes software developed by Christopher G. Demetriou
56 *	for the NetBSD Project.
57 * 4. The name of the author may not be used to endorse or promote products
58 *    derived from this software without specific prior written permission
59 *
60 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
61 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
62 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
63 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
64 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
65 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
66 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
67 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
68 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
69 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70 *
71 *	from: src/sys/alpha/include/bus.h,v 1.5 1999/08/28 00:38:40 peter
72 * $FreeBSD: head/sys/mips/include/bus.h 190515 2009-03-28 23:24:34Z bz $
73*/
74
75#ifndef _MACHINE_BUS_H_
76#define	_MACHINE_BUS_H_
77
78#ifdef TARGET_OCTEON
79#include <machine/bus_octeon.h>
80#else
81#include <machine/_bus.h>
82#include <machine/cpufunc.h>
83
84/*
85 * Values for the mips bus space tag, not to be used directly by MI code.
86 */
87#define	MIPS_BUS_SPACE_IO	0	/* space is i/o space */
88#define	MIPS_BUS_SPACE_MEM	1	/* space is mem space */
89
90
91#define	BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
92#define	BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
93#define	BUS_SPACE_MAXSIZE	0xFFFFFFFF /* Maximum supported size */
94#define	BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
95#define	BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
96#define	BUS_SPACE_MAXADDR	0xFFFFFFFF
97
98#define	BUS_SPACE_UNRESTRICTED	(~0)
99
100/*
101 * Map a region of device bus space into CPU virtual address space.
102 */
103
104static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
105				  bus_size_t size, int flags,
106				  bus_space_handle_t *bshp);
107
108static __inline int
109bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
110	      bus_size_t size __unused, int flags __unused,
111	      bus_space_handle_t *bshp)
112{
113
114	*bshp = addr;
115	return (0);
116}
117
118/*
119 * Unmap a region of device bus space.
120 */
121
122void	bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
123	    bus_size_t size);
124
125/*
126 * Get a new handle for a subregion of an already-mapped area of bus space.
127 */
128
129int	bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
130	    bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
131
132/*
133 * Allocate a region of memory that is accessible to devices in bus space.
134 */
135
136int	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
137	    bus_addr_t rend, bus_size_t size, bus_size_t align,
138	    bus_size_t boundary, int flags, bus_addr_t *addrp,
139	    bus_space_handle_t *bshp);
140
141/*
142 * Free a region of bus space accessible memory.
143 */
144
145void	bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
146	    bus_size_t size);
147
148
149/*
150 * Read a 1, 2, 4, or 8 byte quantity from bus space
151 * described by tag/handle/offset.
152 */
153static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
154					  bus_space_handle_t handle,
155					  bus_size_t offset);
156
157static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
158					   bus_space_handle_t handle,
159					   bus_size_t offset);
160
161static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
162					   bus_space_handle_t handle,
163					   bus_size_t offset);
164
165static __inline u_int8_t
166bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
167    bus_size_t offset)
168{
169
170	if (tag == MIPS_BUS_SPACE_IO)
171		return (inb(handle + offset));
172	return (readb(handle + offset));
173}
174
175static __inline u_int16_t
176bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
177    bus_size_t offset)
178{
179
180	if (tag == MIPS_BUS_SPACE_IO)
181		return (inw(handle + offset));
182	return (readw(handle + offset));
183}
184
185static __inline u_int32_t
186bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
187    bus_size_t offset)
188{
189
190	if (tag == MIPS_BUS_SPACE_IO)
191		return (inl(handle + offset));
192	return (readl(handle + offset));
193}
194
195#if 0	/* Cause a link error for bus_space_read_8 */
196#define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
197#endif
198
199/*
200 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
201 * described by tag/handle/offset and copy into buffer provided.
202 */
203static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
204					    bus_space_handle_t bsh,
205					    bus_size_t offset, u_int8_t *addr,
206					    size_t count);
207
208static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
209					    bus_space_handle_t bsh,
210					    bus_size_t offset, u_int16_t *addr,
211					    size_t count);
212
213static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
214					    bus_space_handle_t bsh,
215					    bus_size_t offset, u_int32_t *addr,
216					    size_t count);
217
218static __inline void
219bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
220    bus_size_t offset, u_int8_t *addr, size_t count)
221{
222
223	if (tag == MIPS_BUS_SPACE_IO)
224		while (count--)
225			*addr++ = inb(bsh + offset);
226	else
227	while (count--)
228		*addr++ = readb(bsh + offset);
229}
230
231static __inline void
232bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
233    bus_size_t offset, u_int16_t *addr, size_t count)
234{
235	bus_addr_t baddr = bsh + offset;
236
237	if (tag == MIPS_BUS_SPACE_IO)
238		while (count--)
239			*addr++ = inw(baddr);
240	else
241		while (count--)
242			*addr++ = readw(baddr);
243}
244
245static __inline void
246bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
247    bus_size_t offset, u_int32_t *addr, size_t count)
248{
249	bus_addr_t baddr = bsh + offset;
250
251	if (tag == MIPS_BUS_SPACE_IO)
252		while (count--)
253			*addr++ = inl(baddr);
254	else
255		while (count--)
256			*addr++ = readl(baddr);
257}
258
259#if 0	/* Cause a link error for bus_space_read_multi_8 */
260#define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
261#endif
262
263/*
264 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
265 * described by tag/handle and starting at `offset' and copy into
266 * buffer provided.
267 */
268static __inline void bus_space_read_region_1(bus_space_tag_t tag,
269					     bus_space_handle_t bsh,
270					     bus_size_t offset, u_int8_t *addr,
271					     size_t count);
272
273static __inline void bus_space_read_region_2(bus_space_tag_t tag,
274					     bus_space_handle_t bsh,
275					     bus_size_t offset, u_int16_t *addr,
276					     size_t count);
277
278static __inline void bus_space_read_region_4(bus_space_tag_t tag,
279					     bus_space_handle_t bsh,
280					     bus_size_t offset, u_int32_t *addr,
281					     size_t count);
282
283
284static __inline void
285bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
286    bus_size_t offset, u_int8_t *addr, size_t count)
287{
288	bus_addr_t baddr = bsh + offset;
289
290	if (tag == MIPS_BUS_SPACE_IO)
291		while (count--) {
292			*addr++ = inb(baddr);
293			baddr += 1;
294		}
295	else
296		while (count--) {
297			*addr++ = readb(baddr);
298			baddr += 1;
299		}
300}
301
302static __inline void
303bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
304    bus_size_t offset, u_int16_t *addr, size_t count)
305{
306	bus_addr_t baddr = bsh + offset;
307
308	if (tag == MIPS_BUS_SPACE_IO)
309		while (count--) {
310			*addr++ = inw(baddr);
311			baddr += 2;
312		}
313	else
314		while (count--) {
315			*addr++ = readw(baddr);
316			baddr += 2;
317		}
318}
319
320static __inline void
321bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
322    bus_size_t offset, u_int32_t *addr, size_t count)
323{
324	bus_addr_t baddr = bsh + offset;
325
326	if (tag == MIPS_BUS_SPACE_IO)
327		while (count--) {
328			*addr++ = inl(baddr);
329			baddr += 4;
330		}
331	else
332		while (count--) {
333			*addr++ = readb(baddr);
334			baddr += 4;
335		}
336}
337
338#if 0	/* Cause a link error for bus_space_read_region_8 */
339#define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
340#endif
341
342/*
343 * Write the 1, 2, 4, or 8 byte value `value' to bus space
344 * described by tag/handle/offset.
345 */
346
347static __inline void bus_space_write_1(bus_space_tag_t tag,
348				       bus_space_handle_t bsh,
349				       bus_size_t offset, u_int8_t value);
350
351static __inline void bus_space_write_2(bus_space_tag_t tag,
352				       bus_space_handle_t bsh,
353				       bus_size_t offset, u_int16_t value);
354
355static __inline void bus_space_write_4(bus_space_tag_t tag,
356				       bus_space_handle_t bsh,
357				       bus_size_t offset, u_int32_t value);
358
359static __inline void
360bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
361    bus_size_t offset, u_int8_t value)
362{
363
364	if (tag == MIPS_BUS_SPACE_IO)
365		outb(bsh + offset, value);
366	else
367		writeb(bsh + offset, value);
368}
369
370static __inline void
371bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
372    bus_size_t offset, u_int16_t value)
373{
374
375	if (tag == MIPS_BUS_SPACE_IO)
376		outw(bsh + offset, value);
377	else
378		writew(bsh + offset, value);
379}
380
381static __inline void
382bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
383    bus_size_t offset, u_int32_t value)
384{
385
386	if (tag == MIPS_BUS_SPACE_IO)
387		outl(bsh + offset, value);
388	else
389		writel(bsh + offset, value);
390}
391
392#if 0	/* Cause a link error for bus_space_write_8 */
393#define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
394#endif
395
396/*
397 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
398 * provided to bus space described by tag/handle/offset.
399 */
400
401static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
402					     bus_space_handle_t bsh,
403					     bus_size_t offset,
404					     const u_int8_t *addr,
405					     size_t count);
406static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
407					     bus_space_handle_t bsh,
408					     bus_size_t offset,
409					     const u_int16_t *addr,
410					     size_t count);
411
412static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
413					     bus_space_handle_t bsh,
414					     bus_size_t offset,
415					     const u_int32_t *addr,
416					     size_t count);
417
418static __inline void
419bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
420    bus_size_t offset, const u_int8_t *addr, size_t count)
421{
422	bus_addr_t baddr = bsh + offset;
423
424	if (tag == MIPS_BUS_SPACE_IO)
425		while (count--)
426			outb(baddr, *addr++);
427	else
428		while (count--)
429			writeb(baddr, *addr++);
430}
431
432static __inline void
433bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
434    bus_size_t offset, const u_int16_t *addr, size_t count)
435{
436	bus_addr_t baddr = bsh + offset;
437
438	if (tag == MIPS_BUS_SPACE_IO)
439		while (count--)
440			outw(baddr, *addr++);
441	else
442		while (count--)
443			writew(baddr, *addr++);
444}
445
446static __inline void
447bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
448    bus_size_t offset, const u_int32_t *addr, size_t count)
449{
450	bus_addr_t baddr = bsh + offset;
451
452	if (tag == MIPS_BUS_SPACE_IO)
453		while (count--)
454			outl(baddr, *addr++);
455	else
456		while (count--)
457			writel(baddr, *addr++);
458}
459
460#if 0	/* Cause a link error for bus_space_write_multi_8 */
461#define	bus_space_write_multi_8(t, h, o, a, c)				\
462			!!! bus_space_write_multi_8 unimplemented !!!
463#endif
464
465/*
466 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
467 * to bus space described by tag/handle starting at `offset'.
468 */
469
470static __inline void bus_space_write_region_1(bus_space_tag_t tag,
471					      bus_space_handle_t bsh,
472					      bus_size_t offset,
473					      const u_int8_t *addr,
474					      size_t count);
475static __inline void bus_space_write_region_2(bus_space_tag_t tag,
476					      bus_space_handle_t bsh,
477					      bus_size_t offset,
478					      const u_int16_t *addr,
479					      size_t count);
480static __inline void bus_space_write_region_4(bus_space_tag_t tag,
481					      bus_space_handle_t bsh,
482					      bus_size_t offset,
483					      const u_int32_t *addr,
484					      size_t count);
485
486static __inline void
487bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
488    bus_size_t offset, const u_int8_t *addr, size_t count)
489{
490	bus_addr_t baddr = bsh + offset;
491
492	if (tag == MIPS_BUS_SPACE_IO)
493		while (count--) {
494			outb(baddr, *addr++);
495			baddr += 1;
496		}
497	else
498		while (count--) {
499			writeb(baddr, *addr++);
500			baddr += 1;
501		}
502}
503
504static __inline void
505bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
506    bus_size_t offset, const u_int16_t *addr, size_t count)
507{
508	bus_addr_t baddr = bsh + offset;
509
510	if (tag == MIPS_BUS_SPACE_IO)
511		while (count--) {
512			outw(baddr, *addr++);
513			baddr += 2;
514		}
515	else
516		while (count--) {
517			writew(baddr, *addr++);
518			baddr += 2;
519		}
520}
521
522static __inline void
523bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
524    bus_size_t offset, const u_int32_t *addr, size_t count)
525{
526	bus_addr_t baddr = bsh + offset;
527
528	if (tag == MIPS_BUS_SPACE_IO)
529		while (count--) {
530			outl(baddr, *addr++);
531			baddr += 4;
532		}
533	else
534		while (count--) {
535			writel(baddr, *addr++);
536			baddr += 4;
537		}
538}
539
540#if 0	/* Cause a link error for bus_space_write_region_8 */
541#define	bus_space_write_region_8					\
542			!!! bus_space_write_region_8 unimplemented !!!
543#endif
544
545/*
546 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
547 * by tag/handle/offset `count' times.
548 */
549
550static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
551					   bus_space_handle_t bsh,
552					   bus_size_t offset,
553					   u_int8_t value, size_t count);
554static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
555					   bus_space_handle_t bsh,
556					   bus_size_t offset,
557					   u_int16_t value, size_t count);
558static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
559					   bus_space_handle_t bsh,
560					   bus_size_t offset,
561					   u_int32_t value, size_t count);
562
563static __inline void
564bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
565    bus_size_t offset, u_int8_t value, size_t count)
566{
567	bus_addr_t addr = bsh + offset;
568
569	if (tag == MIPS_BUS_SPACE_IO)
570		while (count--)
571			outb(addr, value);
572	else
573		while (count--)
574			writeb(addr, value);
575}
576
577static __inline void
578bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
579    bus_size_t offset, u_int16_t value, size_t count)
580{
581	bus_addr_t addr = bsh + offset;
582
583	if (tag == MIPS_BUS_SPACE_IO)
584		while (count--)
585			outw(addr, value);
586	else
587		while (count--)
588			writew(addr, value);
589}
590
591static __inline void
592bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
593    bus_size_t offset, u_int32_t value, size_t count)
594{
595	bus_addr_t addr = bsh + offset;
596
597	if (tag == MIPS_BUS_SPACE_IO)
598		while (count--)
599			outl(addr, value);
600	else
601		while (count--)
602			writel(addr, value);
603}
604
605#if 0	/* Cause a link error for bus_space_set_multi_8 */
606#define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
607#endif
608
609/*
610 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
611 * by tag/handle starting at `offset'.
612 */
613
614static __inline void bus_space_set_region_1(bus_space_tag_t tag,
615					    bus_space_handle_t bsh,
616					    bus_size_t offset, u_int8_t value,
617					    size_t count);
618static __inline void bus_space_set_region_2(bus_space_tag_t tag,
619					    bus_space_handle_t bsh,
620					    bus_size_t offset, u_int16_t value,
621					    size_t count);
622static __inline void bus_space_set_region_4(bus_space_tag_t tag,
623					    bus_space_handle_t bsh,
624					    bus_size_t offset, u_int32_t value,
625					    size_t count);
626
627static __inline void
628bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
629    bus_size_t offset, u_int8_t value, size_t count)
630{
631	bus_addr_t addr = bsh + offset;
632
633	if (tag == MIPS_BUS_SPACE_IO)
634		for (; count != 0; count--, addr++)
635			outb(addr, value);
636	else
637		for (; count != 0; count--, addr++)
638			writeb(addr, value);
639}
640
641static __inline void
642bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
643		       bus_size_t offset, u_int16_t value, size_t count)
644{
645	bus_addr_t addr = bsh + offset;
646
647	if (tag == MIPS_BUS_SPACE_IO)
648		for (; count != 0; count--, addr += 2)
649			outw(addr, value);
650	else
651		for (; count != 0; count--, addr += 2)
652			writew(addr, value);
653}
654
655static __inline void
656bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
657    bus_size_t offset, u_int32_t value, size_t count)
658{
659	bus_addr_t addr = bsh + offset;
660
661	if (tag == MIPS_BUS_SPACE_IO)
662		for (; count != 0; count--, addr += 4)
663			outl(addr, value);
664	else
665		for (; count != 0; count--, addr += 4)
666			writel(addr, value);
667}
668
669#if 0	/* Cause a link error for bus_space_set_region_8 */
670#define	bus_space_set_region_8	!!! bus_space_set_region_8 unimplemented !!!
671#endif
672
673/*
674 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
675 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
676 */
677
678static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
679					     bus_space_handle_t bsh1,
680					     bus_size_t off1,
681					     bus_space_handle_t bsh2,
682					     bus_size_t off2, size_t count);
683
684static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
685					     bus_space_handle_t bsh1,
686					     bus_size_t off1,
687					     bus_space_handle_t bsh2,
688					     bus_size_t off2, size_t count);
689
690static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
691					     bus_space_handle_t bsh1,
692					     bus_size_t off1,
693					     bus_space_handle_t bsh2,
694					     bus_size_t off2, size_t count);
695
696static __inline void
697bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
698    bus_size_t off1, bus_space_handle_t bsh2,
699    bus_size_t off2, size_t count)
700{
701	bus_addr_t addr1 = bsh1 + off1;
702	bus_addr_t addr2 = bsh2 + off2;
703
704	if (tag == MIPS_BUS_SPACE_IO)
705	{
706		if (addr1 >= addr2) {
707			/* src after dest: copy forward */
708			for (; count != 0; count--, addr1++, addr2++)
709				outb(addr2, inb(addr1));
710		} else {
711			/* dest after src: copy backwards */
712			for (addr1 += (count - 1), addr2 += (count - 1);
713			    count != 0; count--, addr1--, addr2--)
714				outb(addr2, inb(addr1));
715		}
716	} else {
717		if (addr1 >= addr2) {
718			/* src after dest: copy forward */
719			for (; count != 0; count--, addr1++, addr2++)
720				writeb(addr2, readb(addr1));
721		} else {
722			/* dest after src: copy backwards */
723			for (addr1 += (count - 1), addr2 += (count - 1);
724			    count != 0; count--, addr1--, addr2--)
725				writeb(addr2, readb(addr1));
726		}
727	}
728}
729
730static __inline void
731bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
732    bus_size_t off1, bus_space_handle_t bsh2,
733    bus_size_t off2, size_t count)
734{
735	bus_addr_t addr1 = bsh1 + off1;
736	bus_addr_t addr2 = bsh2 + off2;
737
738	if (tag == MIPS_BUS_SPACE_IO)
739	{
740		if (addr1 >= addr2) {
741			/* src after dest: copy forward */
742			for (; count != 0; count--, addr1 += 2, addr2 += 2)
743				outw(addr2, inw(addr1));
744		} else {
745			/* dest after src: copy backwards */
746			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
747			    count != 0; count--, addr1 -= 2, addr2 -= 2)
748				outw(addr2, inw(addr1));
749		}
750	} else {
751		if (addr1 >= addr2) {
752			/* src after dest: copy forward */
753			for (; count != 0; count--, addr1 += 2, addr2 += 2)
754				writew(addr2, readw(addr1));
755		} else {
756			/* dest after src: copy backwards */
757			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
758			    count != 0; count--, addr1 -= 2, addr2 -= 2)
759				writew(addr2, readw(addr1));
760		}
761	}
762}
763
764static __inline void
765bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
766    bus_size_t off1, bus_space_handle_t bsh2,
767    bus_size_t off2, size_t count)
768{
769	bus_addr_t addr1 = bsh1 + off1;
770	bus_addr_t addr2 = bsh2 + off2;
771
772	if (tag == MIPS_BUS_SPACE_IO)
773	{
774		if (addr1 >= addr2) {
775			/* src after dest: copy forward */
776			for (; count != 0; count--, addr1 += 4, addr2 += 4)
777				outl(addr2, inl(addr1));
778		} else {
779			/* dest after src: copy backwards */
780			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
781			    count != 0; count--, addr1 -= 4, addr2 -= 4)
782				outl(addr2, inl(addr1));
783		}
784	} else {
785		if (addr1 >= addr2) {
786			/* src after dest: copy forward */
787			for (; count != 0; count--, addr1 += 4, addr2 += 4)
788				writel(addr2, readl(addr1));
789		} else {
790			/* dest after src: copy backwards */
791			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
792			    count != 0; count--, addr1 -= 4, addr2 -= 4)
793				writel(addr2, readl(addr1));
794		}
795	}
796}
797
798
799#if 0	/* Cause a link error for bus_space_copy_8 */
800#define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
801#endif
802
803
804/*
805 * Bus read/write barrier methods.
806 *
807 *	void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
808 *			       bus_size_t offset, bus_size_t len, int flags);
809 *
810 *
811 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
812 * prevent reordering by the compiler; all Intel x86 processors currently
813 * retire operations outside the CPU in program order.
814 */
815#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
816#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
817
818static __inline void
819bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
820		  bus_size_t offset __unused, bus_size_t len __unused, int flags)
821{
822#if 0
823#ifdef __GNUCLIKE_ASM
824	if (flags & BUS_SPACE_BARRIER_READ)
825		__asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
826	else
827		__asm __volatile("" : : : "memory");
828#endif
829#endif
830}
831
832#ifdef BUS_SPACE_NO_LEGACY
833#undef inb
834#undef outb
835#define inb(a) compiler_error
836#define inw(a) compiler_error
837#define inl(a) compiler_error
838#define outb(a, b) compiler_error
839#define outw(a, b) compiler_error
840#define outl(a, b) compiler_error
841#endif
842
843#include <machine/bus_dma.h>
844
845/*
846 * Stream accesses are the same as normal accesses on amd64; there are no
847 * supported bus systems with an endianess different from the host one.
848 */
849#define	bus_space_read_stream_1(t, h, o)	bus_space_read_1((t), (h), (o))
850#define	bus_space_read_stream_2(t, h, o)	bus_space_read_2((t), (h), (o))
851#define	bus_space_read_stream_4(t, h, o)	bus_space_read_4((t), (h), (o))
852
853#define	bus_space_read_multi_stream_1(t, h, o, a, c) \
854	bus_space_read_multi_1((t), (h), (o), (a), (c))
855#define	bus_space_read_multi_stream_2(t, h, o, a, c) \
856	bus_space_read_multi_2((t), (h), (o), (a), (c))
857#define	bus_space_read_multi_stream_4(t, h, o, a, c) \
858	bus_space_read_multi_4((t), (h), (o), (a), (c))
859
860#define	bus_space_write_stream_1(t, h, o, v) \
861	bus_space_write_1((t), (h), (o), (v))
862#define	bus_space_write_stream_2(t, h, o, v) \
863	bus_space_write_2((t), (h), (o), (v))
864#define	bus_space_write_stream_4(t, h, o, v) \
865	bus_space_write_4((t), (h), (o), (v))
866
867#define	bus_space_write_multi_stream_1(t, h, o, a, c) \
868	bus_space_write_multi_1((t), (h), (o), (a), (c))
869#define	bus_space_write_multi_stream_2(t, h, o, a, c) \
870	bus_space_write_multi_2((t), (h), (o), (a), (c))
871#define	bus_space_write_multi_stream_4(t, h, o, a, c) \
872	bus_space_write_multi_4((t), (h), (o), (a), (c))
873
874#define	bus_space_set_multi_stream_1(t, h, o, v, c) \
875	bus_space_set_multi_1((t), (h), (o), (v), (c))
876#define	bus_space_set_multi_stream_2(t, h, o, v, c) \
877	bus_space_set_multi_2((t), (h), (o), (v), (c))
878#define	bus_space_set_multi_stream_4(t, h, o, v, c) \
879	bus_space_set_multi_4((t), (h), (o), (v), (c))
880
881#define	bus_space_read_region_stream_1(t, h, o, a, c) \
882	bus_space_read_region_1((t), (h), (o), (a), (c))
883#define	bus_space_read_region_stream_2(t, h, o, a, c) \
884	bus_space_read_region_2((t), (h), (o), (a), (c))
885#define	bus_space_read_region_stream_4(t, h, o, a, c) \
886	bus_space_read_region_4((t), (h), (o), (a), (c))
887
888#define	bus_space_write_region_stream_1(t, h, o, a, c) \
889	bus_space_write_region_1((t), (h), (o), (a), (c))
890#define	bus_space_write_region_stream_2(t, h, o, a, c) \
891	bus_space_write_region_2((t), (h), (o), (a), (c))
892#define	bus_space_write_region_stream_4(t, h, o, a, c) \
893	bus_space_write_region_4((t), (h), (o), (a), (c))
894
895#define	bus_space_set_region_stream_1(t, h, o, v, c) \
896	bus_space_set_region_1((t), (h), (o), (v), (c))
897#define	bus_space_set_region_stream_2(t, h, o, v, c) \
898	bus_space_set_region_2((t), (h), (o), (v), (c))
899#define	bus_space_set_region_stream_4(t, h, o, v, c) \
900	bus_space_set_region_4((t), (h), (o), (v), (c))
901
902#define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
903	bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
904#define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
905	bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
906#define	bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
907	bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
908
909#endif /* !TARGET_OCTEON */
910#endif /* !_MACHINE_BUS_H_ */
911