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