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