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