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