]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - sys/ia64/include/bus.h
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / sys / ia64 / include / bus.h
1 /*-
2  * Copyright (c) 2009 Marcel Moolenaar
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 /*      $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $    */
28
29 /*-
30  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
31  * All rights reserved.
32  *
33  * This code is derived from software contributed to The NetBSD Foundation
34  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
35  * NASA Ames Research Center.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  *
46  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
47  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
48  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
50  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
51  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
52  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
53  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
54  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56  * POSSIBILITY OF SUCH DAMAGE.
57  */
58
59 /*-
60  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
61  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
62  *
63  * Redistribution and use in source and binary forms, with or without
64  * modification, are permitted provided that the following conditions
65  * are met:
66  * 1. Redistributions of source code must retain the above copyright
67  *    notice, this list of conditions and the following disclaimer.
68  * 2. Redistributions in binary form must reproduce the above copyright
69  *    notice, this list of conditions and the following disclaimer in the
70  *    documentation and/or other materials provided with the distribution.
71  * 3. All advertising materials mentioning features or use of this software
72  *    must display the following acknowledgement:
73  *      This product includes software developed by Christopher G. Demetriou
74  *      for the NetBSD Project.
75  * 4. The name of the author may not be used to endorse or promote products
76  *    derived from this software without specific prior written permission
77  *
78  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
79  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
80  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
81  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
82  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
83  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
84  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
85  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
86  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
87  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88  */
89 /* $FreeBSD$ */
90
91 #ifndef _MACHINE_BUS_H_
92 #define _MACHINE_BUS_H_
93
94 #include <machine/_bus.h>
95 #include <machine/cpufunc.h>
96
97 /*
98  * I/O port reads with ia32 semantics.
99  */
100 #define inb     bus_space_read_io_1
101 #define inw     bus_space_read_io_2
102 #define inl     bus_space_read_io_4
103
104 #define outb    bus_space_write_io_1
105 #define outw    bus_space_write_io_2
106 #define outl    bus_space_write_io_4
107
108 /*
109  * Values for the ia64 bus space tag, not to be used directly by MI code.
110  */
111 #define IA64_BUS_SPACE_IO       0       /* space is i/o space */
112 #define IA64_BUS_SPACE_MEM      1       /* space is mem space */
113
114 #define BUS_SPACE_BARRIER_READ  0x01    /* force read barrier */
115 #define BUS_SPACE_BARRIER_WRITE 0x02    /* force write barrier */
116
117 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
118 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
119 #define BUS_SPACE_MAXSIZE       0xFFFFFFFFFFFFFFFF
120 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
121 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
122 #define BUS_SPACE_MAXADDR       0xFFFFFFFFFFFFFFFF
123
124 #define BUS_SPACE_UNRESTRICTED  (~0)
125
126 #ifdef _KERNEL
127
128 /*
129  * Map and unmap a region of device bus space into CPU virtual address space.
130  */
131 int
132 bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
133     bus_space_handle_t *);
134
135 void
136 bus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t size);
137
138 /*
139  * Get a new handle for a subregion of an already-mapped area of bus space.
140  */
141 static __inline int
142 bus_space_subregion(bus_space_tag_t bst, bus_space_handle_t bsh,
143     bus_size_t ofs, bus_size_t size __unused, bus_space_handle_t *nbshp)
144 {
145         *nbshp = bsh + ofs;
146         return (0);
147 }
148
149
150 /*
151  * Allocate a region of memory that is accessible to devices in bus space.
152  */
153 int
154 bus_space_alloc(bus_space_tag_t bst, bus_addr_t rstart, bus_addr_t rend,
155     bus_size_t size, bus_size_t align, bus_size_t boundary, int flags,
156     bus_addr_t *addrp, bus_space_handle_t *bshp);
157
158
159 /*
160  * Free a region of bus space accessible memory.
161  */
162 void
163 bus_space_free(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t size);
164
165
166 /*
167  * Bus read/write barrier method.
168  */
169 static __inline void
170 bus_space_barrier(bus_space_tag_t bst __unused, bus_space_handle_t bsh __unused,
171     bus_size_t ofs __unused, bus_size_t size __unused, int flags __unused)
172 {
173         ia64_mf_a();
174         ia64_mf();
175 }
176
177
178 /*
179  * Read 1 unit of data from bus space described by the tag, handle and ofs
180  * tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
181  * data is returned.
182  */
183 uint8_t  bus_space_read_io_1(u_long);
184 uint16_t bus_space_read_io_2(u_long);
185 uint32_t bus_space_read_io_4(u_long);
186 uint64_t bus_space_read_io_8(u_long);
187
188 static __inline uint8_t
189 bus_space_read_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
190 {
191         uint8_t val;
192
193         val = (__predict_false(bst == IA64_BUS_SPACE_IO))
194             ? bus_space_read_io_1(bsh + ofs)
195             : ia64_ld1((void *)(bsh + ofs));
196         return (val);
197 }
198
199 static __inline uint16_t
200 bus_space_read_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
201 {
202         uint16_t val;
203
204         val = (__predict_false(bst == IA64_BUS_SPACE_IO))
205             ? bus_space_read_io_2(bsh + ofs)
206             : ia64_ld2((void *)(bsh + ofs));
207         return (val);
208 }
209
210 static __inline uint32_t
211 bus_space_read_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
212 {
213         uint32_t val;
214
215         val = (__predict_false(bst == IA64_BUS_SPACE_IO))
216             ? bus_space_read_io_4(bsh + ofs)
217             : ia64_ld4((void *)(bsh + ofs));
218         return (val);
219 }
220
221 static __inline uint64_t
222 bus_space_read_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs)
223 {
224         uint64_t val;
225
226         val = (__predict_false(bst == IA64_BUS_SPACE_IO))
227             ? bus_space_read_io_8(bsh + ofs)
228             : ia64_ld8((void *)(bsh + ofs));
229         return (val);
230 }
231
232
233 /*
234  * Write 1 unit of data to bus space described by the tag, handle and ofs
235  * tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
236  * data is passed by value.
237  */
238 void bus_space_write_io_1(u_long, uint8_t);
239 void bus_space_write_io_2(u_long, uint16_t);
240 void bus_space_write_io_4(u_long, uint32_t);
241 void bus_space_write_io_8(u_long, uint64_t);
242
243 static __inline void
244 bus_space_write_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
245     uint8_t val)
246 {
247
248         if (__predict_false(bst == IA64_BUS_SPACE_IO))
249                 bus_space_write_io_1(bsh + ofs, val);
250         else
251                 ia64_st1((void *)(bsh + ofs), val);
252 }
253
254 static __inline void
255 bus_space_write_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
256     uint16_t val)
257 {
258
259         if (__predict_false(bst == IA64_BUS_SPACE_IO))
260                 bus_space_write_io_2(bsh + ofs, val);
261         else
262                 ia64_st2((void *)(bsh + ofs), val);
263 }
264
265 static __inline void
266 bus_space_write_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
267     uint32_t val)
268 {
269
270         if (__predict_false(bst == IA64_BUS_SPACE_IO))
271                 bus_space_write_io_4(bsh + ofs, val);
272         else
273                 ia64_st4((void *)(bsh + ofs), val);
274 }
275
276 static __inline void
277 bus_space_write_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs,
278     uint64_t val)
279 {
280
281         if (__predict_false(bst == IA64_BUS_SPACE_IO))
282                 bus_space_write_io_8(bsh + ofs, val);
283         else
284                 ia64_st8((void *)(bsh + ofs), val);
285 }
286
287
288 /*
289  * Read count units of data from bus space described by the tag, handle and
290  * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
291  * data is returned in the buffer passed by reference.
292  */
293 void bus_space_read_multi_io_1(u_long, uint8_t *, size_t);
294 void bus_space_read_multi_io_2(u_long, uint16_t *, size_t);
295 void bus_space_read_multi_io_4(u_long, uint32_t *, size_t);
296 void bus_space_read_multi_io_8(u_long, uint64_t *, size_t);
297
298 static __inline void
299 bus_space_read_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh,
300     bus_size_t ofs, uint8_t *bufp, size_t count)
301 {
302
303         if (__predict_false(bst == IA64_BUS_SPACE_IO))
304                 bus_space_read_multi_io_1(bsh + ofs, bufp, count);
305         else {
306                 while (count-- > 0)
307                         *bufp++ = ia64_ld1((void *)(bsh + ofs));
308         }
309 }
310
311 static __inline void
312 bus_space_read_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
313     bus_size_t ofs, uint16_t *bufp, size_t count)
314 {
315
316         if (__predict_false(bst == IA64_BUS_SPACE_IO))
317                 bus_space_read_multi_io_2(bsh + ofs, bufp, count);
318         else {
319                 while (count-- > 0)
320                         *bufp++ = ia64_ld2((void *)(bsh + ofs));
321         }
322 }
323
324 static __inline void
325 bus_space_read_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
326     bus_size_t ofs, uint32_t *bufp, size_t count)
327 {
328
329         if (__predict_false(bst == IA64_BUS_SPACE_IO))
330                 bus_space_read_multi_io_4(bsh + ofs, bufp, count);
331         else {
332                 while (count-- > 0)
333                         *bufp++ = ia64_ld4((void *)(bsh + ofs));
334         }
335 }
336
337 static __inline void
338 bus_space_read_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
339     bus_size_t ofs, uint64_t *bufp, size_t count)
340 {
341
342         if (__predict_false(bst == IA64_BUS_SPACE_IO))
343                 bus_space_read_multi_io_8(bsh + ofs, bufp, count);
344         else {
345                 while (count-- > 0)
346                         *bufp++ = ia64_ld8((void *)(bsh + ofs));
347         }
348 }
349
350
351 /*
352  * Write count units of data to bus space described by the tag, handle and
353  * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
354  * data is read from the buffer passed by reference.
355  */
356 void bus_space_write_multi_io_1(u_long, const uint8_t *, size_t);
357 void bus_space_write_multi_io_2(u_long, const uint16_t *, size_t);
358 void bus_space_write_multi_io_4(u_long, const uint32_t *, size_t);
359 void bus_space_write_multi_io_8(u_long, const uint64_t *, size_t);
360
361 static __inline void
362 bus_space_write_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh,
363     bus_size_t ofs, const uint8_t *bufp, size_t count)
364 {
365
366         if (__predict_false(bst == IA64_BUS_SPACE_IO))
367                 bus_space_write_multi_io_1(bsh + ofs, bufp, count);
368         else {
369                 while (count-- > 0)
370                         ia64_st1((void *)(bsh + ofs), *bufp++);
371         }
372 }
373
374 static __inline void
375 bus_space_write_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
376     bus_size_t ofs, const uint16_t *bufp, size_t count)
377 {
378
379         if (__predict_false(bst == IA64_BUS_SPACE_IO))
380                 bus_space_write_multi_io_2(bsh + ofs, bufp, count);
381         else {
382                 while (count-- > 0)
383                         ia64_st2((void *)(bsh + ofs), *bufp++);
384         }
385 }
386
387 static __inline void
388 bus_space_write_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
389     bus_size_t ofs, const uint32_t *bufp, size_t count)
390 {
391
392         if (__predict_false(bst == IA64_BUS_SPACE_IO))
393                 bus_space_write_multi_io_4(bsh + ofs, bufp, count);
394         else {
395                 while (count-- > 0)
396                         ia64_st4((void *)(bsh + ofs), *bufp++);
397         }
398 }
399
400 static __inline void
401 bus_space_write_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
402     bus_size_t ofs, const uint64_t *bufp, size_t count)
403 {
404
405         if (__predict_false(bst == IA64_BUS_SPACE_IO))
406                 bus_space_write_multi_io_8(bsh + ofs, bufp, count);
407         else {
408                 while (count-- > 0)
409                         ia64_st8((void *)(bsh + ofs), *bufp++);
410         }
411 }
412
413
414 /*
415  * Read count units of data from bus space described by the tag, handle and
416  * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
417  * data is written to the buffer passed by reference and read from successive
418  * bus space addresses. Access is unordered.
419  */
420 void bus_space_read_region_io_1(u_long, uint8_t *, size_t);
421 void bus_space_read_region_io_2(u_long, uint16_t *, size_t);
422 void bus_space_read_region_io_4(u_long, uint32_t *, size_t);
423 void bus_space_read_region_io_8(u_long, uint64_t *, size_t);
424
425 static __inline void
426 bus_space_read_region_1(bus_space_tag_t bst, bus_space_handle_t bsh,
427     bus_size_t ofs, uint8_t *bufp, size_t count)
428 {
429
430         if (__predict_false(bst == IA64_BUS_SPACE_IO))
431                 bus_space_read_region_io_1(bsh + ofs, bufp, count);
432         else {
433                 uint8_t *bsp = (void *)(bsh + ofs);
434                 while (count-- > 0)
435                         *bufp++ = ia64_ld1(bsp++);
436         }
437 }
438
439 static __inline void
440 bus_space_read_region_2(bus_space_tag_t bst, bus_space_handle_t bsh,
441     bus_size_t ofs, uint16_t *bufp, size_t count)
442 {
443
444         if (__predict_false(bst == IA64_BUS_SPACE_IO))
445                 bus_space_read_region_io_2(bsh + ofs, bufp, count);
446         else {
447                 uint16_t *bsp = (void *)(bsh + ofs);
448                 while (count-- > 0)
449                         *bufp++ = ia64_ld2(bsp++);
450         }
451 }
452
453 static __inline void
454 bus_space_read_region_4(bus_space_tag_t bst, bus_space_handle_t bsh,
455     bus_size_t ofs, uint32_t *bufp, size_t count)
456 {
457
458         if (__predict_false(bst == IA64_BUS_SPACE_IO))
459                 bus_space_read_region_io_4(bsh + ofs, bufp, count);
460         else {
461                 uint32_t *bsp = (void *)(bsh + ofs);
462                 while (count-- > 0)
463                         *bufp++ = ia64_ld4(bsp++);
464         }
465 }
466
467 static __inline void
468 bus_space_read_region_8(bus_space_tag_t bst, bus_space_handle_t bsh,
469     bus_size_t ofs, uint64_t *bufp, size_t count)
470 {
471
472         if (__predict_false(bst == IA64_BUS_SPACE_IO))
473                 bus_space_read_region_io_8(bsh + ofs, bufp, count);
474         else {
475                 uint64_t *bsp = (void *)(bsh + ofs);
476                 while (count-- > 0)
477                         *bufp++ = ia64_ld8(bsp++);
478         }
479 }
480
481
482 /*
483  * Write count units of data from bus space described by the tag, handle and
484  * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
485  * data is read from the buffer passed by reference and written to successive
486  * bus space addresses. Access is unordered.
487  */
488 void bus_space_write_region_io_1(u_long, const uint8_t *, size_t);
489 void bus_space_write_region_io_2(u_long, const uint16_t *, size_t);
490 void bus_space_write_region_io_4(u_long, const uint32_t *, size_t);
491 void bus_space_write_region_io_8(u_long, const uint64_t *, size_t);
492
493 static __inline void
494 bus_space_write_region_1(bus_space_tag_t bst, bus_space_handle_t bsh,
495     bus_size_t ofs, const uint8_t *bufp, size_t count)
496 {
497
498         if (__predict_false(bst == IA64_BUS_SPACE_IO))
499                 bus_space_write_region_io_1(bsh + ofs, bufp, count);
500         else {
501                 uint8_t *bsp = (void *)(bsh + ofs);
502                 while (count-- > 0)
503                         ia64_st1(bsp++, *bufp++);
504         }
505 }
506
507 static __inline void
508 bus_space_write_region_2(bus_space_tag_t bst, bus_space_handle_t bsh,
509     bus_size_t ofs, const uint16_t *bufp, size_t count)
510 {
511
512         if (__predict_false(bst == IA64_BUS_SPACE_IO))
513                 bus_space_write_region_io_2(bsh + ofs, bufp, count);
514         else {
515                 uint16_t *bsp = (void *)(bsh + ofs);
516                 while (count-- > 0)
517                         ia64_st2(bsp++, *bufp++);
518         }
519 }
520
521 static __inline void
522 bus_space_write_region_4(bus_space_tag_t bst, bus_space_handle_t bsh,
523     bus_size_t ofs, const uint32_t *bufp, size_t count)
524 {
525
526         if (__predict_false(bst == IA64_BUS_SPACE_IO))
527                 bus_space_write_region_io_4(bsh + ofs, bufp, count);
528         else {
529                 uint32_t *bsp = (void *)(bsh + ofs);
530                 while (count-- > 0)
531                         ia64_st4(bsp++, *bufp++);
532         }
533 }
534
535 static __inline void
536 bus_space_write_region_8(bus_space_tag_t bst, bus_space_handle_t bsh,
537     bus_size_t ofs, const uint64_t *bufp, size_t count)
538 {
539
540         if (__predict_false(bst == IA64_BUS_SPACE_IO))
541                 bus_space_write_region_io_8(bsh + ofs, bufp, count);
542         else {
543                 uint64_t *bsp = (void *)(bsh + ofs);
544                 while (count-- > 0)
545                         ia64_st8(bsp++, *bufp++);
546         }
547 }
548
549
550 /*
551  * Write count units of data from bus space described by the tag, handle and
552  * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
553  * data is passed by value. Writes are unordered.
554  */
555 static __inline void
556 bus_space_set_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh,
557     bus_size_t ofs, uint8_t val, size_t count)
558 {
559
560         while (count-- > 0)
561                 bus_space_write_1(bst, bsh, ofs, val);
562 }
563
564 static __inline void
565 bus_space_set_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
566     bus_size_t ofs, uint16_t val, size_t count)
567 {
568
569         while (count-- > 0)
570                 bus_space_write_2(bst, bsh, ofs, val);
571 }
572
573 static __inline void
574 bus_space_set_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
575     bus_size_t ofs, uint32_t val, size_t count)
576 {
577
578         while (count-- > 0)
579                 bus_space_write_4(bst, bsh, ofs, val);
580 }
581
582 static __inline void
583 bus_space_set_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh,
584     bus_size_t ofs, uint64_t val, size_t count)
585 {
586
587         while (count-- > 0)
588                 bus_space_write_8(bst, bsh, ofs, val);
589 }
590
591
592 /*
593  * Write count units of data from bus space described by the tag, handle and
594  * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The
595  * data is passed by value and written to successive bus space addresses.
596  * Writes are unordered.
597  */
598 void bus_space_set_region_io_1(u_long, uint8_t, size_t);
599 void bus_space_set_region_io_2(u_long, uint16_t, size_t);
600 void bus_space_set_region_io_4(u_long, uint32_t, size_t);
601 void bus_space_set_region_io_8(u_long, uint64_t, size_t);
602
603 static __inline void
604 bus_space_set_region_1(bus_space_tag_t bst, bus_space_handle_t bsh,
605     bus_size_t ofs, uint8_t val, size_t count)
606 {
607
608         if (__predict_false(bst == IA64_BUS_SPACE_IO))
609                 bus_space_set_region_io_1(bsh + ofs, val, count);
610         else {
611                 uint8_t *bsp = (void *)(bsh + ofs);
612                 while (count-- > 0)
613                         ia64_st1(bsp++, val);
614         }
615 }
616
617 static __inline void
618 bus_space_set_region_2(bus_space_tag_t bst, bus_space_handle_t bsh,
619     bus_size_t ofs, uint16_t val, size_t count)
620 {
621
622         if (__predict_false(bst == IA64_BUS_SPACE_IO))
623                 bus_space_set_region_io_2(bsh + ofs, val, count);
624         else {
625                 uint16_t *bsp = (void *)(bsh + ofs);
626                 while (count-- > 0)
627                         ia64_st2(bsp++, val);
628         }
629 }
630
631 static __inline void
632 bus_space_set_region_4(bus_space_tag_t bst, bus_space_handle_t bsh,
633     bus_size_t ofs, uint32_t val, size_t count)
634 {
635
636         if (__predict_false(bst == IA64_BUS_SPACE_IO))
637                 bus_space_set_region_io_4(bsh + ofs, val, count);
638         else {
639                 uint32_t *bsp = (void *)(bsh + ofs);
640                 while (count-- > 0)
641                         ia64_st4(bsp++, val);
642         }
643 }
644
645 static __inline void
646 bus_space_set_region_8(bus_space_tag_t bst, bus_space_handle_t bsh,
647     bus_size_t ofs, uint64_t val, size_t count)
648 {
649
650         if (__predict_false(bst == IA64_BUS_SPACE_IO))
651                 bus_space_set_region_io_4(bsh + ofs, val, count);
652         else {
653                 uint64_t *bsp = (void *)(bsh + ofs);
654                 while (count-- > 0)
655                         ia64_st8(bsp++, val);
656         }
657 }
658
659
660 /*
661  * Copy count units of data from bus space described by the tag and the first
662  * handle and ofs pair to bus space described by the tag and the second handle
663  * and ofs pair. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes.
664  * The data is read from successive bus space addresses and also written to
665  * successive bus space addresses. Both reads and writes are unordered.
666  */
667 void bus_space_copy_region_io_1(u_long, u_long, size_t);
668 void bus_space_copy_region_io_2(u_long, u_long, size_t);
669 void bus_space_copy_region_io_4(u_long, u_long, size_t);
670 void bus_space_copy_region_io_8(u_long, u_long, size_t);
671
672 static __inline void
673 bus_space_copy_region_1(bus_space_tag_t bst, bus_space_handle_t sbsh,
674     bus_size_t sofs, bus_space_handle_t dbsh, bus_size_t dofs, size_t count)
675 {
676         uint8_t *dst, *src;
677
678         if (__predict_false(bst == IA64_BUS_SPACE_IO)) {
679                 bus_space_copy_region_io_1(sbsh + sofs, dbsh + dofs, count);
680                 return;
681         }
682
683         src = (void *)(sbsh + sofs);
684         dst = (void *)(dbsh + dofs);
685         if (src < dst) {
686                 src += count - 1;
687                 dst += count - 1;
688                 while (count-- > 0)
689                         ia64_st1(dst--, ia64_ld1(src--));
690         } else {
691                 while (count-- > 0)
692                         ia64_st1(dst++, ia64_ld1(src++));
693         }
694 }
695
696 static __inline void
697 bus_space_copy_region_2(bus_space_tag_t bst, bus_space_handle_t sbsh,
698     bus_size_t sofs, bus_space_handle_t dbsh, bus_size_t dofs, size_t count)
699 {
700         uint16_t *dst, *src;
701
702         if (__predict_false(bst == IA64_BUS_SPACE_IO)) {
703                 bus_space_copy_region_io_2(sbsh + sofs, dbsh + dofs, count);
704                 return;
705         }
706
707         src = (void *)(sbsh + sofs);
708         dst = (void *)(dbsh + dofs);
709         if (src < dst) {
710                 src += count - 1;
711                 dst += count - 1;
712                 while (count-- > 0)
713                         ia64_st2(dst--, ia64_ld2(src--));
714         } else {
715                 while (count-- > 0)
716                         ia64_st2(dst++, ia64_ld2(src++));
717         }
718 }
719
720 static __inline void
721 bus_space_copy_region_4(bus_space_tag_t bst, bus_space_handle_t sbsh,
722     bus_size_t sofs, bus_space_handle_t dbsh, bus_size_t dofs, size_t count)
723 {
724         uint32_t *dst, *src;
725
726         if (__predict_false(bst == IA64_BUS_SPACE_IO)) {
727                 bus_space_copy_region_io_4(sbsh + sofs, dbsh + dofs, count);
728                 return;
729         }
730
731         src = (void *)(sbsh + sofs);
732         dst = (void *)(dbsh + dofs);
733         if (src < dst) {
734                 src += count - 1;
735                 dst += count - 1;
736                 while (count-- > 0)
737                         ia64_st4(dst--, ia64_ld4(src--));
738         } else {
739                 while (count-- > 0)
740                         ia64_st4(dst++, ia64_ld4(src++));
741         }
742 }
743
744 static __inline void
745 bus_space_copy_region_8(bus_space_tag_t bst, bus_space_handle_t sbsh,
746     bus_size_t sofs, bus_space_handle_t dbsh, bus_size_t dofs, size_t count)
747 {
748         uint64_t *dst, *src;
749
750         if (__predict_false(bst == IA64_BUS_SPACE_IO)) {
751                 bus_space_copy_region_io_8(sbsh + sofs, dbsh + dofs, count);
752                 return;
753         }
754
755         src = (void *)(sbsh + sofs);
756         dst = (void *)(dbsh + dofs);
757         if (src < dst) {
758                 src += count - 1;
759                 dst += count - 1;
760                 while (count-- > 0)
761                         ia64_st8(dst--, ia64_ld8(src--));
762         } else {
763                 while (count-- > 0)
764                         ia64_st8(dst++, ia64_ld8(src++));
765         }
766 }
767
768
769 /*
770  * Stream accesses are the same as normal accesses on ia64; there are no
771  * supported bus systems with an endianess different from the host one.
772  */
773
774 #define bus_space_read_stream_1         bus_space_read_1
775 #define bus_space_read_stream_2         bus_space_read_2
776 #define bus_space_read_stream_4         bus_space_read_4
777 #define bus_space_read_stream_8         bus_space_read_8
778
779 #define bus_space_write_stream_1        bus_space_write_1
780 #define bus_space_write_stream_2        bus_space_write_2
781 #define bus_space_write_stream_4        bus_space_write_4
782 #define bus_space_write_stream_8        bus_space_write_8
783
784 #define bus_space_read_multi_stream_1   bus_space_read_multi_1
785 #define bus_space_read_multi_stream_2   bus_space_read_multi_2
786 #define bus_space_read_multi_stream_4   bus_space_read_multi_4
787 #define bus_space_read_multi_stream_8   bus_space_read_multi_8
788
789 #define bus_space_write_multi_stream_1  bus_space_write_multi_1
790 #define bus_space_write_multi_stream_2  bus_space_write_multi_2
791 #define bus_space_write_multi_stream_4  bus_space_write_multi_4
792 #define bus_space_write_multi_stream_8  bus_space_write_multi_8
793
794 #define bus_space_read_region_stream_1  bus_space_read_region_1
795 #define bus_space_read_region_stream_2  bus_space_read_region_2
796 #define bus_space_read_region_stream_4  bus_space_read_region_4
797 #define bus_space_read_region_stream_8  bus_space_read_region_8
798
799 #define bus_space_write_region_stream_1 bus_space_write_region_1
800 #define bus_space_write_region_stream_2 bus_space_write_region_2
801 #define bus_space_write_region_stream_4 bus_space_write_region_4
802 #define bus_space_write_region_stream_8 bus_space_write_region_8
803
804 #define bus_space_set_multi_stream_1    bus_space_set_multi_1
805 #define bus_space_set_multi_stream_2    bus_space_set_multi_2
806 #define bus_space_set_multi_stream_4    bus_space_set_multi_4
807 #define bus_space_set_multi_stream_8    bus_space_set_multi_8
808
809 #define bus_space_set_region_stream_1   bus_space_set_region_1
810 #define bus_space_set_region_stream_2   bus_space_set_region_2
811 #define bus_space_set_region_stream_4   bus_space_set_region_4
812 #define bus_space_set_region_stream_8   bus_space_set_region_8
813
814 #define bus_space_copy_region_stream_1  bus_space_copy_region_1
815 #define bus_space_copy_region_stream_2  bus_space_copy_region_2
816 #define bus_space_copy_region_stream_4  bus_space_copy_region_4
817 #define bus_space_copy_region_stream_8  bus_space_copy_region_8
818
819 #endif /* _KERNEL */
820
821 #include <machine/bus_dma.h>
822
823 #endif /* _MACHINE_BUS_H_ */