]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/ia64/include/bus.h
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / ia64 / include / bus.h
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$ */
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
97 static __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
101 static __inline int
102 bus_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  */
114 static __inline void
115 bus_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  */
124 static __inline int
125 bus_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  */
136 int
137 bus_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  */
145 void
146 bus_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
155 static __inline void
156 bus_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  */
169 static __inline uint8_t
170 bus_space_read_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
171 {
172         uint8_t __volatile *bsp;
173         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
174             __MEMIO_ADDR(bsh + ofs);
175         return (*bsp);
176 }
177
178 static __inline uint16_t
179 bus_space_read_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
180 {
181         uint16_t __volatile *bsp;
182         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
183             __MEMIO_ADDR(bsh + ofs);
184         return (*bsp);
185 }
186
187 static __inline uint32_t
188 bus_space_read_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
189 {
190         uint32_t __volatile *bsp;
191         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
192             __MEMIO_ADDR(bsh + ofs);
193         return (*bsp);
194 }
195
196 static __inline uint64_t
197 bus_space_read_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
198 {
199         uint64_t __volatile *bsp;
200         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
201             __MEMIO_ADDR(bsh + ofs);
202         return (*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  */
211 static __inline void
212 bus_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 __volatile *bsp;
216         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
217             __MEMIO_ADDR(bsh + ofs);
218         *bsp = val;
219 }
220
221 static __inline void
222 bus_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 __volatile *bsp;
226         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
227             __MEMIO_ADDR(bsh + ofs);
228         *bsp = val;
229 }
230
231 static __inline void
232 bus_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 __volatile *bsp;
236         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
237             __MEMIO_ADDR(bsh + ofs);
238         *bsp = val;
239 }
240
241 static __inline void
242 bus_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 __volatile *bsp;
246         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
247             __MEMIO_ADDR(bsh + ofs);
248         *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  */
257 static __inline void
258 bus_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 __volatile *bsp;
262         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
263             __MEMIO_ADDR(bsh + ofs);
264         while (count-- > 0)
265                 *bufp++ = *bsp;
266 }
267
268 static __inline void
269 bus_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 __volatile *bsp;
273         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
274             __MEMIO_ADDR(bsh + ofs);
275         while (count-- > 0)
276                 *bufp++ = *bsp;
277 }
278
279 static __inline void
280 bus_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 __volatile *bsp;
284         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
285             __MEMIO_ADDR(bsh + ofs);
286         while (count-- > 0)
287                 *bufp++ = *bsp;
288 }
289
290 static __inline void
291 bus_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 __volatile *bsp;
295         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
296             __MEMIO_ADDR(bsh + ofs);
297         while (count-- > 0)
298                 *bufp++ = *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  */
307 static __inline void
308 bus_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 __volatile *bsp;
312         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
313             __MEMIO_ADDR(bsh + ofs);
314         while (count-- > 0)
315                 *bsp = *bufp++;
316 }
317
318 static __inline void
319 bus_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 __volatile *bsp;
323         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
324             __MEMIO_ADDR(bsh + ofs);
325         while (count-- > 0)
326                 *bsp = *bufp++;
327 }
328
329 static __inline void
330 bus_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 __volatile *bsp;
334         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
335             __MEMIO_ADDR(bsh + ofs);
336         while (count-- > 0)
337                 *bsp = *bufp++;
338 }
339
340 static __inline void
341 bus_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 __volatile *bsp;
345         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
346             __MEMIO_ADDR(bsh + ofs);
347         while (count-- > 0)
348                 *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  */
358 static __inline void
359 bus_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 __volatile *bsp;
363         while (count-- > 0) {
364                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
365                     __MEMIO_ADDR(bsh + ofs);
366                 *bufp++ = *bsp;
367                 ofs += 1;
368         }
369 }
370
371 static __inline void
372 bus_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 __volatile *bsp;
376         while (count-- > 0) {
377                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
378                     __MEMIO_ADDR(bsh + ofs);
379                 *bufp++ = *bsp;
380                 ofs += 2;
381         }
382 }
383
384 static __inline void
385 bus_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 __volatile *bsp;
389         while (count-- > 0) {
390                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
391                     __MEMIO_ADDR(bsh + ofs);
392                 *bufp++ = *bsp;
393                 ofs += 4;
394         }
395 }
396
397 static __inline void
398 bus_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 __volatile *bsp;
402         while (count-- > 0) {
403                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
404                     __MEMIO_ADDR(bsh + ofs);
405                 *bufp++ = *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  */
417 static __inline void
418 bus_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 __volatile *bsp;
422         while (count-- > 0) {
423                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
424                     __MEMIO_ADDR(bsh + ofs);
425                 *bsp = *bufp++;
426                 ofs += 1;
427         }
428 }
429
430 static __inline void
431 bus_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 __volatile *bsp;
435         while (count-- > 0) {
436                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
437                     __MEMIO_ADDR(bsh + ofs);
438                 *bsp = *bufp++;
439                 ofs += 2;
440         }
441 }
442
443 static __inline void
444 bus_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 __volatile *bsp;
448         while (count-- > 0) {
449                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
450                     __MEMIO_ADDR(bsh + ofs);
451                 *bsp = *bufp++;
452                 ofs += 4;
453         }
454 }
455
456 static __inline void
457 bus_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 __volatile *bsp;
461         while (count-- > 0) {
462                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
463                     __MEMIO_ADDR(bsh + ofs);
464                 *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  */
475 static __inline void
476 bus_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 __volatile *bsp;
480         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
481             __MEMIO_ADDR(bsh + ofs);
482         while (count-- > 0)
483                 *bsp = val;
484 }
485
486 static __inline void
487 bus_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 __volatile *bsp;
491         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
492             __MEMIO_ADDR(bsh + ofs);
493         while (count-- > 0)
494                 *bsp = val;
495 }
496
497 static __inline void
498 bus_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 __volatile *bsp;
502         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
503             __MEMIO_ADDR(bsh + ofs);
504         while (count-- > 0)
505                 *bsp = val;
506 }
507
508 static __inline void
509 bus_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 __volatile *bsp;
513         bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
514             __MEMIO_ADDR(bsh + ofs);
515         while (count-- > 0)
516                 *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  */
526 static __inline void
527 bus_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 __volatile *bsp;
531         while (count-- > 0) {
532                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
533                     __MEMIO_ADDR(bsh + ofs);
534                 *bsp = val;
535                 ofs += 1;
536         }
537 }
538
539 static __inline void
540 bus_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 __volatile *bsp;
544         while (count-- > 0) {
545                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
546                     __MEMIO_ADDR(bsh + ofs);
547                 *bsp = val;
548                 ofs += 2;
549         }
550 }
551
552 static __inline void
553 bus_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 __volatile *bsp;
557         while (count-- > 0) {
558                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
559                     __MEMIO_ADDR(bsh + ofs);
560                 *bsp = val;
561                 ofs += 4;
562         }
563 }
564
565 static __inline void
566 bus_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 __volatile *bsp;
570         while (count-- > 0) {
571                 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) :
572                     __MEMIO_ADDR(bsh + ofs);
573                 *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  */
586 static __inline void
587 bus_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 __volatile *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                         *dstp = *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                         *dstp = *srcp;
619                         src += 1;
620                         dst += 1;
621                 }
622         }
623 }
624
625 static __inline void
626 bus_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 __volatile *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                         *dstp = *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                         *dstp = *srcp;
658                         src += 2;
659                         dst += 2;
660                 }
661         }
662 }
663
664 static __inline void
665 bus_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 __volatile *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                         *dstp = *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                         *dstp = *srcp;
697                         src += 4;
698                         dst += 4;
699                 }
700         }
701 }
702
703 static __inline void
704 bus_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 __volatile *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                         *dstp = *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                         *dstp = *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_ */