bus.h revision 200051
1/*	$NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $	*/
2
3/*-
4 * Copyright (c) 1996, 1997 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/* $FreeBSD: head/sys/ia64/include/bus.h 200051 2009-12-03 04:06:48Z marcel $ */
71
72#ifndef _MACHINE_BUS_H_
73#define _MACHINE_BUS_H_
74
75#include <machine/_bus.h>
76#include <machine/cpufunc.h>
77
78/*
79 * Values for the ia64 bus space tag, not to be used directly by MI code.
80 */
81#define	IA64_BUS_SPACE_IO	0	/* space is i/o space */
82#define IA64_BUS_SPACE_MEM	1	/* space is mem space */
83
84#define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
85#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
86#define BUS_SPACE_MAXSIZE	0xFFFFFFFFFFFFFFFF
87#define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
88#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
89#define BUS_SPACE_MAXADDR	0xFFFFFFFF
90
91#define BUS_SPACE_UNRESTRICTED	(~0)
92
93/*
94 * Map a region of device bus space into CPU virtual address space.
95 */
96
97static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
98				  bus_size_t size, int flags,
99				  bus_space_handle_t *bshp);
100
101static __inline int
102bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
103	      bus_size_t size __unused, int flags __unused,
104	      bus_space_handle_t *bshp)
105{
106
107	*bshp = addr;
108	return (0);
109}
110
111/*
112 * Unmap a region of device bus space.
113 */
114static __inline void
115bus_space_unmap(bus_space_tag_t bst __unused, bus_space_handle_t bsh __unused,
116    bus_size_t size __unused)
117{
118}
119
120
121/*
122 * Get a new handle for a subregion of an already-mapped area of bus space.
123 */
124static __inline int
125bus_space_subregion(bus_space_tag_t bst, bus_space_handle_t bsh,
126    bus_size_t ofs, bus_size_t size, bus_space_handle_t *nbshp)
127{
128	*nbshp = bsh + ofs;
129	return (0);
130}
131
132
133/*
134 * Allocate a region of memory that is accessible to devices in bus space.
135 */
136int
137bus_space_alloc(bus_space_tag_t bst, bus_addr_t rstart, bus_addr_t rend,
138    bus_size_t size, bus_size_t align, bus_size_t boundary, int flags,
139    bus_addr_t *addrp, bus_space_handle_t *bshp);
140
141
142/*
143 * Free a region of bus space accessible memory.
144 */
145void
146bus_space_free(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t size);
147
148
149/*
150 * Bus read/write barrier method.
151 */
152#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
153#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
154
155static __inline void
156bus_space_barrier(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
157    bus_size_t size, int flags)
158{
159	ia64_mf_a();
160	ia64_mf();
161}
162
163
164/*
165 * Read 1 unit of data from bus space described by the tag, handle and ofs
166 * tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
167 * data is returned.
168 */
169static __inline uint8_t
170bus_space_read_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
171{
172	uint8_t *bsp;
173	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
174	    __MEMIO_ADDR(bsh + ofs);
175	return (ia64_ld1(bsp));
176}
177
178static __inline uint16_t
179bus_space_read_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
180{
181	uint16_t *bsp;
182	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
183	    __MEMIO_ADDR(bsh + ofs);
184	return (ia64_ld2(bsp));
185}
186
187static __inline uint32_t
188bus_space_read_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
189{
190	uint32_t *bsp;
191	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
192	    __MEMIO_ADDR(bsh + ofs);
193	return (ia64_ld4(bsp));
194}
195
196static __inline uint64_t
197bus_space_read_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
198{
199	uint64_t *bsp;
200	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
201	    __MEMIO_ADDR(bsh + ofs);
202	return (ia64_ld8(bsp));
203}
204
205
206/*
207 * Write 1 unit of data to bus space described by the tag, handle and ofs
208 * tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
209 * data is passed by value.
210 */
211static __inline void
212bus_space_write_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
213    uint8_t val)
214{
215	uint8_t *bsp;
216	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
217	    __MEMIO_ADDR(bsh + ofs);
218	ia64_st1(bsp, val);
219}
220
221static __inline void
222bus_space_write_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
223    uint16_t val)
224{
225	uint16_t *bsp;
226	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
227	    __MEMIO_ADDR(bsh + ofs);
228	ia64_st2(bsp, val);
229}
230
231static __inline void
232bus_space_write_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
233    uint32_t val)
234{
235	uint32_t *bsp;
236	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
237	    __MEMIO_ADDR(bsh + ofs);
238	ia64_st4(bsp, val);
239}
240
241static __inline void
242bus_space_write_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
243    uint64_t val)
244{
245	uint64_t *bsp;
246	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
247	    __MEMIO_ADDR(bsh + ofs);
248	ia64_st8(bsp, val);
249}
250
251
252/*
253 * Read count units of data from bus space described by the tag, handle and
254 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
255 * data is returned in the buffer passed by reference.
256 */
257static __inline void
258bus_space_read_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh,
259    bus_size_t ofs, uint8_t *bufp, size_t count)
260{
261	uint8_t *bsp;
262	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
263	    __MEMIO_ADDR(bsh + ofs);
264	while (count-- > 0)
265		*bufp++ = ia64_ld1(bsp);
266}
267
268static __inline void
269bus_space_read_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
270    bus_size_t ofs, uint16_t *bufp, size_t count)
271{
272	uint16_t *bsp;
273	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
274	    __MEMIO_ADDR(bsh + ofs);
275	while (count-- > 0)
276		*bufp++ = ia64_ld2(bsp);
277}
278
279static __inline void
280bus_space_read_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
281    bus_size_t ofs, uint32_t *bufp, size_t count)
282{
283	uint32_t *bsp;
284	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
285	    __MEMIO_ADDR(bsh + ofs);
286	while (count-- > 0)
287		*bufp++ = ia64_ld4(bsp);
288}
289
290static __inline void
291bus_space_read_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
292    bus_size_t ofs, uint64_t *bufp, size_t count)
293{
294	uint64_t *bsp;
295	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
296	    __MEMIO_ADDR(bsh + ofs);
297	while (count-- > 0)
298		*bufp++ = ia64_ld8(bsp);
299}
300
301
302/*
303 * Write count units of data to bus space described by the tag, handle and
304 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
305 * data is read from the buffer passed by reference.
306 */
307static __inline void
308bus_space_write_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh,
309    bus_size_t ofs, const uint8_t *bufp, size_t count)
310{
311	uint8_t *bsp;
312	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
313	    __MEMIO_ADDR(bsh + ofs);
314	while (count-- > 0)
315		ia64_st1(bsp, *bufp++);
316}
317
318static __inline void
319bus_space_write_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
320    bus_size_t ofs, const uint16_t *bufp, size_t count)
321{
322	uint16_t *bsp;
323	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
324	    __MEMIO_ADDR(bsh + ofs);
325	while (count-- > 0)
326		ia64_st2(bsp, *bufp++);
327}
328
329static __inline void
330bus_space_write_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
331    bus_size_t ofs, const uint32_t *bufp, size_t count)
332{
333	uint32_t *bsp;
334	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
335	    __MEMIO_ADDR(bsh + ofs);
336	while (count-- > 0)
337		ia64_st4(bsp, *bufp++);
338}
339
340static __inline void
341bus_space_write_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
342    bus_size_t ofs, const uint64_t *bufp, size_t count)
343{
344	uint64_t *bsp;
345	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
346	    __MEMIO_ADDR(bsh + ofs);
347	while (count-- > 0)
348		ia64_st8(bsp, *bufp++);
349}
350
351
352/*
353 * Read count units of data from bus space described by the tag, handle and
354 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
355 * data is written to the buffer passed by reference and read from successive
356 * bus space addresses. Access is unordered.
357 */
358static __inline void
359bus_space_read_region_1(bus_space_tag_t bst, bus_space_handle_t bsh,
360    bus_size_t ofs, uint8_t *bufp, size_t count)
361{
362	uint8_t *bsp;
363	while (count-- > 0) {
364		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
365		    __MEMIO_ADDR(bsh + ofs);
366		*bufp++ = ia64_ld1(bsp);
367		ofs += 1;
368	}
369}
370
371static __inline void
372bus_space_read_region_2(bus_space_tag_t bst, bus_space_handle_t bsh,
373    bus_size_t ofs, uint16_t *bufp, size_t count)
374{
375	uint16_t *bsp;
376	while (count-- > 0) {
377		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
378		    __MEMIO_ADDR(bsh + ofs);
379		*bufp++ = ia64_ld2(bsp);
380		ofs += 2;
381	}
382}
383
384static __inline void
385bus_space_read_region_4(bus_space_tag_t bst, bus_space_handle_t bsh,
386    bus_size_t ofs, uint32_t *bufp, size_t count)
387{
388	uint32_t *bsp;
389	while (count-- > 0) {
390		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
391		    __MEMIO_ADDR(bsh + ofs);
392		*bufp++ = ia64_ld4(bsp);
393		ofs += 4;
394	}
395}
396
397static __inline void
398bus_space_read_region_8(bus_space_tag_t bst, bus_space_handle_t bsh,
399    bus_size_t ofs, uint64_t *bufp, size_t count)
400{
401	uint64_t *bsp;
402	while (count-- > 0) {
403		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
404		    __MEMIO_ADDR(bsh + ofs);
405		*bufp++ = ia64_ld8(bsp);
406		ofs += 8;
407	}
408}
409
410
411/*
412 * Write count units of data from bus space described by the tag, handle and
413 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
414 * data is read from the buffer passed by reference and written to successive
415 * bus space addresses. Access is unordered.
416 */
417static __inline void
418bus_space_write_region_1(bus_space_tag_t bst, bus_space_handle_t bsh,
419    bus_size_t ofs, const uint8_t *bufp, size_t count)
420{
421	uint8_t *bsp;
422	while (count-- > 0) {
423		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
424		    __MEMIO_ADDR(bsh + ofs);
425		ia64_st1(bsp, *bufp++);
426		ofs += 1;
427	}
428}
429
430static __inline void
431bus_space_write_region_2(bus_space_tag_t bst, bus_space_handle_t bsh,
432    bus_size_t ofs, const uint16_t *bufp, size_t count)
433{
434	uint16_t *bsp;
435	while (count-- > 0) {
436		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
437		    __MEMIO_ADDR(bsh + ofs);
438		ia64_st2(bsp, *bufp++);
439		ofs += 2;
440	}
441}
442
443static __inline void
444bus_space_write_region_4(bus_space_tag_t bst, bus_space_handle_t bsh,
445    bus_size_t ofs, const uint32_t *bufp, size_t count)
446{
447	uint32_t *bsp;
448	while (count-- > 0) {
449		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
450		    __MEMIO_ADDR(bsh + ofs);
451		ia64_st4(bsp, *bufp++);
452		ofs += 4;
453	}
454}
455
456static __inline void
457bus_space_write_region_8(bus_space_tag_t bst, bus_space_handle_t bsh,
458    bus_size_t ofs, const uint64_t *bufp, size_t count)
459{
460	uint64_t *bsp;
461	while (count-- > 0) {
462		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
463		    __MEMIO_ADDR(bsh + ofs);
464		ia64_st8(bsp, *bufp++);
465		ofs += 8;
466	}
467}
468
469
470/*
471 * Write count units of data from bus space described by the tag, handle and
472 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
473 * data is passed by value. Writes are unordered.
474 */
475static __inline void
476bus_space_set_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh,
477    bus_size_t ofs, uint8_t val, size_t count)
478{
479	uint8_t *bsp;
480	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
481	    __MEMIO_ADDR(bsh + ofs);
482	while (count-- > 0)
483		ia64_st1(bsp, val);
484}
485
486static __inline void
487bus_space_set_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
488    bus_size_t ofs, uint16_t val, size_t count)
489{
490	uint16_t *bsp;
491	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
492	    __MEMIO_ADDR(bsh + ofs);
493	while (count-- > 0)
494		ia64_st2(bsp, val);
495}
496
497static __inline void
498bus_space_set_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
499    bus_size_t ofs, uint32_t val, size_t count)
500{
501	uint32_t *bsp;
502	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
503	    __MEMIO_ADDR(bsh + ofs);
504	while (count-- > 0)
505		ia64_st4(bsp, val);
506}
507
508static __inline void
509bus_space_set_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
510    bus_size_t ofs, uint64_t val, size_t count)
511{
512	uint64_t *bsp;
513	bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
514	    __MEMIO_ADDR(bsh + ofs);
515	while (count-- > 0)
516		ia64_st8(bsp, val);
517}
518
519
520/*
521 * Write count units of data from bus space described by the tag, handle and
522 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
523 * data is passed by value and written to successive bus space addresses.
524 * Writes are unordered.
525 */
526static __inline void
527bus_space_set_region_1(bus_space_tag_t bst, bus_space_handle_t bsh,
528    bus_size_t ofs, uint8_t val, size_t count)
529{
530	uint8_t *bsp;
531	while (count-- > 0) {
532		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
533		    __MEMIO_ADDR(bsh + ofs);
534		ia64_st1(bsp, val);
535		ofs += 1;
536	}
537}
538
539static __inline void
540bus_space_set_region_2(bus_space_tag_t bst, bus_space_handle_t bsh,
541    bus_size_t ofs, uint16_t val, size_t count)
542{
543	uint16_t *bsp;
544	while (count-- > 0) {
545		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
546		    __MEMIO_ADDR(bsh + ofs);
547		ia64_st2(bsp, val);
548		ofs += 2;
549	}
550}
551
552static __inline void
553bus_space_set_region_4(bus_space_tag_t bst, bus_space_handle_t bsh,
554    bus_size_t ofs, uint32_t val, size_t count)
555{
556	uint32_t *bsp;
557	while (count-- > 0) {
558		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
559		    __MEMIO_ADDR(bsh + ofs);
560		ia64_st4(bsp, val);
561		ofs += 4;
562	}
563}
564
565static __inline void
566bus_space_set_region_8(bus_space_tag_t bst, bus_space_handle_t bsh,
567    bus_size_t ofs, uint64_t val, size_t count)
568{
569	uint64_t *bsp;
570	while (count-- > 0) {
571		bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
572		    __MEMIO_ADDR(bsh + ofs);
573		ia64_st8(bsp, val);
574		ofs += 8;
575	}
576}
577
578
579/*
580 * Copy count units of data from bus space described by the tag and the first
581 * handle and ofs pair to bus space described by the tag and the second handle
582 * and ofs pair. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes.
583 * The data is read from successive bus space addresses and also written to
584 * successive bus space addresses. Both reads and writes are unordered.
585 */
586static __inline void
587bus_space_copy_region_1(bus_space_tag_t bst, bus_space_handle_t bsh1,
588    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count)
589{
590	bus_addr_t dst, src;
591	uint8_t *dstp, *srcp;
592	src = bsh1 + ofs1;
593	dst = bsh2 + ofs2;
594	if (dst > src) {
595		src += count - 1;
596		dst += count - 1;
597		while (count-- > 0) {
598			if (bst == IA64_BUS_SPACE_IO) {
599				srcp = __PIO_ADDR(src);
600				dstp = __PIO_ADDR(dst);
601			} else {
602				srcp = __MEMIO_ADDR(src);
603				dstp = __MEMIO_ADDR(dst);
604			}
605			ia64_st1(dstp, ia64_ld1(srcp));
606			src -= 1;
607			dst -= 1;
608		}
609	} else {
610		while (count-- > 0) {
611			if (bst == IA64_BUS_SPACE_IO) {
612				srcp = __PIO_ADDR(src);
613				dstp = __PIO_ADDR(dst);
614			} else {
615				srcp = __MEMIO_ADDR(src);
616				dstp = __MEMIO_ADDR(dst);
617			}
618			ia64_st1(dstp, ia64_ld1(srcp));
619			src += 1;
620			dst += 1;
621		}
622	}
623}
624
625static __inline void
626bus_space_copy_region_2(bus_space_tag_t bst, bus_space_handle_t bsh1,
627    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count)
628{
629	bus_addr_t dst, src;
630	uint16_t *dstp, *srcp;
631	src = bsh1 + ofs1;
632	dst = bsh2 + ofs2;
633	if (dst > src) {
634		src += (count - 1) << 1;
635		dst += (count - 1) << 1;
636		while (count-- > 0) {
637			if (bst == IA64_BUS_SPACE_IO) {
638				srcp = __PIO_ADDR(src);
639				dstp = __PIO_ADDR(dst);
640			} else {
641				srcp = __MEMIO_ADDR(src);
642				dstp = __MEMIO_ADDR(dst);
643			}
644			ia64_st2(dstp, ia64_ld2(srcp));
645			src -= 2;
646			dst -= 2;
647		}
648	} else {
649		while (count-- > 0) {
650			if (bst == IA64_BUS_SPACE_IO) {
651				srcp = __PIO_ADDR(src);
652				dstp = __PIO_ADDR(dst);
653			} else {
654				srcp = __MEMIO_ADDR(src);
655				dstp = __MEMIO_ADDR(dst);
656			}
657			ia64_st2(dstp, ia64_ld2(srcp));
658			src += 2;
659			dst += 2;
660		}
661	}
662}
663
664static __inline void
665bus_space_copy_region_4(bus_space_tag_t bst, bus_space_handle_t bsh1,
666    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count)
667{
668	bus_addr_t dst, src;
669	uint32_t *dstp, *srcp;
670	src = bsh1 + ofs1;
671	dst = bsh2 + ofs2;
672	if (dst > src) {
673		src += (count - 1) << 2;
674		dst += (count - 1) << 2;
675		while (count-- > 0) {
676			if (bst == IA64_BUS_SPACE_IO) {
677				srcp = __PIO_ADDR(src);
678				dstp = __PIO_ADDR(dst);
679			} else {
680				srcp = __MEMIO_ADDR(src);
681				dstp = __MEMIO_ADDR(dst);
682			}
683			ia64_st4(dstp, ia64_ld4(srcp));
684			src -= 4;
685			dst -= 4;
686		}
687	} else {
688		while (count-- > 0) {
689			if (bst == IA64_BUS_SPACE_IO) {
690				srcp = __PIO_ADDR(src);
691				dstp = __PIO_ADDR(dst);
692			} else {
693				srcp = __MEMIO_ADDR(src);
694				dstp = __MEMIO_ADDR(dst);
695			}
696			ia64_st4(dstp, ia64_ld4(srcp));
697			src += 4;
698			dst += 4;
699		}
700	}
701}
702
703static __inline void
704bus_space_copy_region_8(bus_space_tag_t bst, bus_space_handle_t bsh1,
705    bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count)
706{
707	bus_addr_t dst, src;
708	uint64_t *dstp, *srcp;
709	src = bsh1 + ofs1;
710	dst = bsh2 + ofs2;
711	if (dst > src) {
712		src += (count - 1) << 3;
713		dst += (count - 1) << 3;
714		while (count-- > 0) {
715			if (bst == IA64_BUS_SPACE_IO) {
716				srcp = __PIO_ADDR(src);
717				dstp = __PIO_ADDR(dst);
718			} else {
719				srcp = __MEMIO_ADDR(src);
720				dstp = __MEMIO_ADDR(dst);
721			}
722			ia64_st8(dstp, ia64_ld8(srcp));
723			src -= 8;
724			dst -= 8;
725		}
726	} else {
727		while (count-- > 0) {
728			if (bst == IA64_BUS_SPACE_IO) {
729				srcp = __PIO_ADDR(src);
730				dstp = __PIO_ADDR(dst);
731			} else {
732				srcp = __MEMIO_ADDR(src);
733				dstp = __MEMIO_ADDR(dst);
734			}
735			ia64_st8(dstp, ia64_ld8(srcp));
736			src += 8;
737			dst += 8;
738		}
739	}
740}
741
742
743/*
744 * Stream accesses are the same as normal accesses on ia64; there are no
745 * supported bus systems with an endianess different from the host one.
746 */
747#define	bus_space_read_stream_1(t, h, o)	\
748	bus_space_read_1(t, h, o)
749#define	bus_space_read_stream_2(t, h, o)	\
750	bus_space_read_2(t, h, o)
751#define	bus_space_read_stream_4(t, h, o)	\
752	bus_space_read_4(t, h, o)
753#define	bus_space_read_stream_8(t, h, o)	\
754	bus_space_read_8(t, h, o)
755
756#define	bus_space_read_multi_stream_1(t, h, o, a, c)	\
757	bus_space_read_multi_1(t, h, o, a, c)
758#define	bus_space_read_multi_stream_2(t, h, o, a, c)	\
759	bus_space_read_multi_2(t, h, o, a, c)
760#define	bus_space_read_multi_stream_4(t, h, o, a, c)	\
761	bus_space_read_multi_4(t, h, o, a, c)
762#define	bus_space_read_multi_stream_8(t, h, o, a, c)	\
763	bus_space_read_multi_8(t, h, o, a, c)
764
765#define	bus_space_write_stream_1(t, h, o, v)	\
766	bus_space_write_1(t, h, o, v)
767#define	bus_space_write_stream_2(t, h, o, v)	\
768	bus_space_write_2(t, h, o, v)
769#define	bus_space_write_stream_4(t, h, o, v)	\
770	bus_space_write_4(t, h, o, v)
771#define	bus_space_write_stream_8(t, h, o, v)	\
772	bus_space_write_8(t, h, o, v)
773
774#define	bus_space_write_multi_stream_1(t, h, o, a, c)	\
775	bus_space_write_multi_1(t, h, o, a, c)
776#define	bus_space_write_multi_stream_2(t, h, o, a, c)	\
777	bus_space_write_multi_2(t, h, o, a, c)
778#define	bus_space_write_multi_stream_4(t, h, o, a, c)	\
779	bus_space_write_multi_4(t, h, o, a, c)
780#define	bus_space_write_multi_stream_8(t, h, o, a, c)	\
781	bus_space_write_multi_8(t, h, o, a, c)
782
783#define	bus_space_set_multi_stream_1(t, h, o, v, c)	\
784	bus_space_set_multi_1(t, h, o, v, c)
785#define	bus_space_set_multi_stream_2(t, h, o, v, c)	\
786	bus_space_set_multi_2(t, h, o, v, c)
787#define	bus_space_set_multi_stream_4(t, h, o, v, c)	\
788	bus_space_set_multi_4(t, h, o, v, c)
789#define	bus_space_set_multi_stream_8(t, h, o, v, c)	\
790	bus_space_set_multi_8(t, h, o, v, c)
791
792#define	bus_space_read_region_stream_1(t, h, o, a, c)	\
793	bus_space_read_region_1(t, h, o, a, c)
794#define	bus_space_read_region_stream_2(t, h, o, a, c)	\
795	bus_space_read_region_2(t, h, o, a, c)
796#define	bus_space_read_region_stream_4(t, h, o, a, c)	\
797	bus_space_read_region_4(t, h, o, a, c)
798#define	bus_space_read_region_stream_8(t, h, o, a, c)	\
799	bus_space_read_region_8(t, h, o, a, c)
800
801#define	bus_space_write_region_stream_1(t, h, o, a, c)	\
802	bus_space_write_region_1(t, h, o, a, c)
803#define	bus_space_write_region_stream_2(t, h, o, a, c)	\
804	bus_space_write_region_2(t, h, o, a, c)
805#define	bus_space_write_region_stream_4(t, h, o, a, c)	\
806	bus_space_write_region_4(t, h, o, a, c)
807#define	bus_space_write_region_stream_8(t, h, o, a, c)	\
808	bus_space_write_region_8(t, h, o, a, c)
809
810#define	bus_space_set_region_stream_1(t, h, o, v, c)	\
811	bus_space_set_region_1(t, h, o, v, c)
812#define	bus_space_set_region_stream_2(t, h, o, v, c)	\
813	bus_space_set_region_2(t, h, o, v, c)
814#define	bus_space_set_region_stream_4(t, h, o, v, c)	\
815	bus_space_set_region_4(t, h, o, v, c)
816#define	bus_space_set_region_stream_8(t, h, o, v, c)	\
817	bus_space_set_region_8(t, h, o, v, c)
818
819#define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c)	\
820	bus_space_copy_region_1(t, h1, o1, h2, o2, c)
821#define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c)	\
822	bus_space_copy_region_2(t, h1, o1, h2, o2, c)
823#define	bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c)	\
824	bus_space_copy_region_4(t, h1, o1, h2, o2, c)
825#define	bus_space_copy_region_stream_8(t, h1, o1, h2, o2, c)	\
826	bus_space_copy_region_8(t, h1, o1, h2, o2, c)
827
828#include <machine/bus_dma.h>
829
830#endif /* _MACHINE_BUS_H_ */
831