1 /*        $NetBSD: bus_space.h,v 1.5 2021/01/23 19:38:07 christos Exp $ */
2 
3 /*-
4  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (C) 1997 Scott Reynolds.  All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  * 3. The name of the author may not be used to endorse or promote products
45  *    derived from this software without specific prior written permission
46  *
47  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
48  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
51  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
56  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57  */
58 
59 /*
60  * Lifted from the Next68k port.
61  * Modified for mvme68k by Steve Woodford.
62  * Modified for evbcf by Steve Woodford.
63  */
64 
65 #ifndef _EVBCF_BUS_SPACE_H_
66 #define   _EVBCF_BUS_SPACE_H_
67 
68 /*
69  * Addresses (in bus space).
70  */
71 typedef u_long bus_addr_t;
72 typedef u_long bus_size_t;
73 
74 #define PRIxBUSADDR "lx"
75 #define PRIxBUSSIZE "lx"
76 #define PRIuBUSSIZE "lu"
77 /*
78  * Access methods for bus resources and address space.
79  */
80 struct mvme68k_bus_space_tag;
81 typedef struct mvme68k_bus_space_tag    *bus_space_tag_t;
82 typedef u_long      bus_space_handle_t;
83 
84 #define PRIxBSH               "lx"
85 
86 struct mvme68k_bus_space_tag {
87           void                *bs_cookie;
88           int                 (*bs_map)(void *, bus_addr_t, bus_size_t,
89                                           int, bus_space_handle_t *);
90           void                (*bs_unmap)(void *, bus_space_handle_t, bus_size_t);
91           int                 (*bs_peek_1)(void *, bus_space_handle_t,
92                                              bus_size_t, uint8_t *);
93           int                 (*bs_peek_2)(void *, bus_space_handle_t,
94                                              bus_size_t, uint16_t *);
95           int                 (*bs_peek_4)(void *, bus_space_handle_t,
96                                              bus_size_t, uint32_t *);
97 #if 0
98           int                 (*bs_peek_8)(void *, bus_space_handle_t,
99                                              bus_size_t, uint64_t *);
100 #endif
101           int                 (*bs_poke_1)(void *, bus_space_handle_t,
102                                              bus_size_t, uint8_t);
103           int                 (*bs_poke_2)(void *, bus_space_handle_t,
104                                              bus_size_t, uint16_t);
105           int                 (*bs_poke_4)(void *, bus_space_handle_t,
106                                              bus_size_t, uint32_t);
107 #if 0
108           int                 (*bs_poke_8)(void *, bus_space_handle_t,
109                                              bus_size_t, uint64_t);
110 #endif
111 };
112 
113 /*
114  *        int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
115  *                          bus_size_t size, int flags,
116  *                        bus_space_handle_t *bshp);
117  *
118  * Map a region of bus space.
119  */
120 #define   bus_space_map(tag, offset, size, flags, handlep)            \
121     (*((tag)->bs_map))((tag)->bs_cookie, (offset), (size), (flags), (handlep))
122 
123 /*
124  * Possible values for the 'flags' parameter of bus_space_map()
125  */
126 #define   BUS_SPACE_MAP_CACHEABLE                 0x01
127 #define   BUS_SPACE_MAP_LINEAR                    0x02
128 #define   BUS_SPACE_MAP_PREFETCHABLE    0x04
129 
130 /*
131  *        void bus_space_unmap(bus_space_tag_t t,
132  *                           bus_space_handle_t bsh, bus_size_t size);
133  *
134  * Unmap a region of bus space.
135  */
136 #define bus_space_unmap(tag, handle, size)                                      \
137     (*((tag)->bs_unmap))((tag)->bs_cookie, (handle), (size))
138 
139 /*
140  *        int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h
141  *            bus_addr_t offset, bus_size_t size, bus_space_handle_t *newh);
142  *
143  * Allocate a sub-region of an existing map
144  */
145 #define   bus_space_subregion(t, h, o, s, hp)                                   \
146      ((*(hp)=(h)+(o)), 0)
147 
148 /*
149  * Allocation and deallocation operations.
150  */
151 #define   bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)              \
152      (-1)
153 
154 #define   bus_space_free(t, h, s)
155 
156 /*
157  *        int bus_space_peek_N(bus_space_tag_t tag,
158  *            bus_space_handle_t bsh, bus_size_t offset, uintN_t *valuep);
159  *
160  * Cautiously read 1, 2, 4 or 8 byte quantity from bus space described
161  * by tag/handle/offset.
162  * If no hardware responds to the read access, the function returns a
163  * non-zero value. Otherwise the value read is placed in `valuep'.
164  */
165 #define   bus_space_peek_1(t, h, o, vp)                                         \
166     (*((t)->bs_peek_1))((t)->bs_cookie, (h), (o), (vp))
167 
168 #define   bus_space_peek_2(t, h, o, vp)                                         \
169     (*((t)->bs_peek_2))((t)->bs_cookie, (h), (o), (vp))
170 
171 #define   bus_space_peek_4(t, h, o, vp)                                         \
172     (*((t)->bs_peek_4))((t)->bs_cookie, (h), (o), (vp))
173 
174 /*
175  *        int bus_space_poke_N(bus_space_tag_t tag,
176  *            bus_space_handle_t bsh, bus_size_t offset, uintN_t value);
177  *
178  * Cautiously write 1, 2, 4 or 8 byte quantity to bus space described
179  * by tag/handle/offset.
180  * If no hardware responds to the write access, the function returns a
181  * non-zero value.
182  */
183 #define   bus_space_poke_1(t, h, o, v)                                          \
184     (*((t)->bs_poke_1))((t)->bs_cookie, (h), (o), (v))
185 
186 #define   bus_space_poke_2(t, h, o, v)                                          \
187     (*((t)->bs_poke_2))((t)->bs_cookie, (h), (o), (v))
188 
189 #define   bus_space_poke_4(t, h, o, v)                                          \
190     (*((t)->bs_poke_4))((t)->bs_cookie, (h), (o), (v))
191 
192 /*
193  *        uintN_t bus_space_read_N(bus_space_tag_t tag,
194  *            bus_space_handle_t bsh, bus_size_t offset);
195  *
196  * Read a 1, 2, 4, or 8 byte quantity from bus space
197  * described by tag/handle/offset.
198  */
199 #define   bus_space_read_1(t,h,o)       \
200               (*((volatile uint8_t *)(intptr_t)((h) + (o))))
201 #define   bus_space_read_2(t,h,o)       \
202               (*((volatile uint16_t *)(intptr_t)((h) + (o))))
203 #define   bus_space_read_4(t,h,o)       \
204               (*((volatile uint32_t *)(intptr_t)((h) + (o))))
205 
206 /*
207  *        void bus_space_read_multi_N(bus_space_tag_t tag,
208  *            bus_space_handle_t bsh, bus_size_t offset,
209  *            uintN_t *addr, size_t count);
210  *
211  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
212  * described by tag/handle/offset and copy into buffer provided.
213  */
214 
215 #define   bus_space_read_multi_1(t, h, o, a, c) do {                            \
216           (void) t;                                                             \
217           __asm volatile ("                                                     \
218                     movl      %0,%%a0                                           ;         \
219                     movl      %1,%%a1                                           ;         \
220                     movl      %2,%%d0                                           ;         \
221           1:        movb      %%a0@,%%a1@+                                      ;         \
222                     subql     #1,%%d0                                           ;         \
223                     jne       1b"                                               :         \
224                                                                                 :         \
225                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
226                         "a0","a1","d0");                                                  \
227 } while (0);
228 
229 #define   bus_space_read_multi_2(t, h, o, a, c) do {                            \
230           (void) t;                                                             \
231           __asm volatile ("                                                     \
232                     movl      %0,%%a0                                           ;         \
233                     movl      %1,%%a1                                           ;         \
234                     movl      %2,%%d0                                           ;         \
235           1:        movw      %%a0@,%%a1@+                                      ;         \
236                     subql     #1,%%d0                                           ;         \
237                     jne       1b"                                               :         \
238                                                                                 :         \
239                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
240                         "a0","a1","d0");                                                  \
241 } while (0);
242 
243 #define   bus_space_read_multi_4(t, h, o, a, c) do {                            \
244           (void) t;                                                             \
245           __asm volatile ("                                                     \
246                     movl      %0,%%a0                                           ;         \
247                     movl      %1,%%a1                                           ;         \
248                     movl      %2,%%d0                                           ;         \
249           1:        movl      %%a0@,%%a1@+                                      ;         \
250                     subql     #1,%%d0                                           ;         \
251                     jne       1b"                                               :         \
252                                                                                 :         \
253                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
254                         "a0","a1","d0");                                                  \
255 } while (0);
256 
257 /*
258  *        void bus_space_read_region_N(bus_space_tag_t tag,
259  *            bus_space_handle_t bsh, bus_size_t offset,
260  *            uintN_t *addr, size_t count);
261  *
262  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
263  * described by tag/handle and starting at `offset' and copy into
264  * buffer provided.
265  */
266 
267 #define   bus_space_read_region_1(t, h, o, a, c) do {                           \
268           (void) t;                                                             \
269           __asm volatile ("                                                     \
270                     movl      %0,%%a0                                           ;         \
271                     movl      %1,%%a1                                           ;         \
272                     movl      %2,%%d0                                           ;         \
273           1:        movb      %%a0@+,%%a1@+                                     ;         \
274                     subql     #1,%%d0                                           ;         \
275                     jne       1b"                                               :         \
276                                                                                 :         \
277                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
278                         "a0","a1","d0");                                                  \
279 } while (0);
280 
281 #define   bus_space_read_region_2(t, h, o, a, c) do {                           \
282           (void) t;                                                             \
283           __asm volatile ("                                                     \
284                     movl      %0,%%a0                                           ;         \
285                     movl      %1,%%a1                                           ;         \
286                     movl      %2,%%d0                                           ;         \
287           1:        movw      %%a0@+,%%a1@+                                     ;         \
288                     subql     #1,%%d0                                           ;         \
289                     jne       1b"                                               :         \
290                                                                                 :         \
291                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
292                         "a0","a1","d0");                                                  \
293 } while (0);
294 
295 #define   bus_space_read_region_4(t, h, o, a, c) do {                           \
296           (void) t;                                                             \
297           __asm volatile ("                                                     \
298                     movl      %0,%%a0                                           ;         \
299                     movl      %1,%%a1                                           ;         \
300                     movl      %2,%%d0                                           ;         \
301           1:        movl      %%a0@+,%%a1@+                                     ;         \
302                     subql     #1,%%d0                                           ;         \
303                     jne       1b"                                               :         \
304                                                                                 :         \
305                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
306                         "a0","a1","d0");                                                  \
307 } while (0);
308 
309 /*
310  *        void bus_space_write_N(bus_space_tag_t tag,
311  *            bus_space_handle_t bsh, bus_size_t offset,
312  *            uintN_t value);
313  *
314  * Write the 1, 2, 4, or 8 byte value `value' to bus space
315  * described by tag/handle/offset.
316  */
317 #define   bus_space_write_1(t,h,o,v)                                            \
318           do {                                                                            \
319                     *((volatile uint8_t *)(intptr_t)((h) + (o))) = (v);         \
320           } while (/*CONSTCOND*/0)
321 #define   bus_space_write_2(t,h,o,v)                                            \
322           do {                                                                            \
323                     *((volatile uint16_t *)(intptr_t)((h) + (o))) = (v);        \
324           } while (/*CONSTCOND*/0)
325 #define   bus_space_write_4(t,h,o,v)                                            \
326           do {                                                                            \
327                     *((volatile uint32_t *)(intptr_t)((h) + (o))) = (v);        \
328           } while (/*CONSTCOND*/0)
329 
330 /*
331  *        void bus_space_write_multi_N(bus_space_tag_t tag,
332  *            bus_space_handle_t bsh, bus_size_t offset,
333  *            const uintN_t *addr, size_t count);
334  *
335  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
336  * provided to bus space described by tag/handle/offset.
337  */
338 
339 #define   bus_space_write_multi_1(t, h, o, a, c) do {                           \
340           (void) t;                                                             \
341           __asm volatile ("                                                     \
342                     movl      %0,%%a0                                           ;         \
343                     movl      %1,%%a1                                           ;         \
344                     movl      %2,%%d0                                           ;         \
345           1:        movb      %%a1@+,%%a0@                                      ;         \
346                     subql     #1,%%d0                                           ;         \
347                     jne       1b"                                               :         \
348                                                                                 :         \
349                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
350                         "a0","a1","d0");                                                  \
351 } while (0);
352 
353 #define   bus_space_write_multi_2(t, h, o, a, c) do {                           \
354           (void) t;                                                             \
355           __asm volatile ("                                                     \
356                     movl      %0,%%a0                                           ;         \
357                     movl      %1,%%a1                                           ;         \
358                     movl      %2,%%d0                                           ;         \
359           1:        movw      %%a1@+,%%a0@                                      ;         \
360                     subql     #1,%%d0                                           ;         \
361                     jne       1b"                                               :         \
362                                                                                 :         \
363                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
364                         "a0","a1","d0");                                                  \
365 } while (0);
366 
367 #define   bus_space_write_multi_4(t, h, o, a, c) do {                           \
368           (void) t;                                                             \
369           __asm volatile ("                                                     \
370                     movl      %0,%%a0                                           ;         \
371                     movl      %1,%%a1                                           ;         \
372                     movl      %2,%%d0                                           ;         \
373           1:        movl      a1@+,%%a0@                                        ;         \
374                     subql     #1,%%d0                                           ;         \
375                     jne       1b"                                               :         \
376                                                                                 :         \
377                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
378                         "a0","a1","d0");                                                  \
379 } while (0);
380 
381 /*
382  *        void bus_space_write_region_N(bus_space_tag_t tag,
383  *            bus_space_handle_t bsh, bus_size_t offset,
384  *            const uintN_t *addr, size_t count);
385  *
386  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
387  * to bus space described by tag/handle starting at `offset'.
388  */
389 
390 #define   bus_space_write_region_1(t, h, o, a, c) do {                          \
391           (void) t;                                                             \
392           __asm volatile ("                                                     \
393                     movl      %0,%%a0                                           ;         \
394                     movl      %1,%%a1                                           ;         \
395                     movl      %2,%%d0                                           ;         \
396           1:        movb      %%a1@+,%%a0@+                                     ;         \
397                     subql     #1,%%d0                                           ;         \
398                     jne       1b"                                               :         \
399                                                                                 :         \
400                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
401                         "a0","a1","d0");                                                  \
402 } while (0);
403 
404 #define   bus_space_write_region_2(t, h, o, a, c) do {                          \
405           (void) t;                                                             \
406           __asm volatile ("                                                     \
407                     movl      %0,%%a0                                           ;         \
408                     movl      %1,%%a1                                           ;         \
409                     movl      %2,%%d0                                           ;         \
410           1:        movw      %%a1@+,%%a0@+                                     ;         \
411                     subql     #1,%%d0                                           ;         \
412                     jne       1b"                                               :         \
413                                                                                 :         \
414                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
415                         "a0","a1","d0");                                                  \
416 } while (0);
417 
418 #define   bus_space_write_region_4(t, h, o, a, c) do {                          \
419           (void) t;                                                             \
420           __asm volatile ("                                                     \
421                     movl      %0,%%a0                                           ;         \
422                     movl      %1,%%a1                                           ;         \
423                     movl      %2,%%d0                                           ;         \
424           1:        movl      %%a1@+,%%a0@+                                     ;         \
425                     subql     #1,%%d0                                           ;         \
426                     jne       1b"                                               :         \
427                                                                                 :         \
428                         "r" ((h) + (o)), "g" (a), "g" (c)             :         \
429                         "a0","a1","d0");                                                  \
430 } while (0);
431 
432 /*
433  *        void bus_space_set_multi_N(bus_space_tag_t tag,
434  *            bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
435  *            size_t count);
436  *
437  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
438  * by tag/handle/offset `count' times.
439  */
440 
441 #define   bus_space_set_multi_1(t, h, o, val, c) do {                           \
442           (void) t;                                                             \
443           __asm volatile ("                                                     \
444                     movl      %0,%%a0                                           ;         \
445                     movl      %1,%%d1                                           ;         \
446                     movl      %2,%%d0                                           ;         \
447           1:        movb      %%d1,%%a0@                                        ;         \
448                     subql     #1,%%d0                                           ;         \
449                     jne       1b"                                               :         \
450                                                                                 :         \
451                         "r" ((h) + (o)), "g" (val), "g" (c)           :         \
452                         "a0","d0","d1");                                                  \
453 } while (0);
454 
455 #define   bus_space_set_multi_2(t, h, o, val, c) do {                           \
456           (void) t;                                                             \
457           __asm volatile ("                                                     \
458                     movl      %0,%%a0                                           ;         \
459                     movl      %1,%%d1                                           ;         \
460                     movl      %2,%%d0                                           ;         \
461           1:        movw      %%d1,%%a0@                                        ;         \
462                     subql     #1,%%d0                                           ;         \
463                     jne       1b"                                               :         \
464                                                                                 :         \
465                         "r" ((h) + (o)), "g" (val), "g" (c)           :         \
466                         "a0","d0","d1");                                                  \
467 } while (0);
468 
469 #define   bus_space_set_multi_4(t, h, o, val, c) do {                           \
470           (void) t;                                                             \
471           __asm volatile ("                                                     \
472                     movl      %0,%%a0                                           ;         \
473                     movl      %1,%%d1                                           ;         \
474                     movl      %2,%%d0                                           ;         \
475           1:        movl      %%d1,%%a0@                                        ;         \
476                     subql     #1,%%d0                                           ;         \
477                     jne       1b"                                               :         \
478                                                                                 :         \
479                         "r" ((h) + (o)), "g" (val), "g" (c)           :         \
480                         "a0","d0","d1");                                                  \
481 } while (0);
482 
483 /*
484  *        void bus_space_set_region_N(bus_space_tag_t tag,
485  *            bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
486  *            size_t count);
487  *
488  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
489  * by tag/handle starting at `offset'.
490  */
491 
492 #define   bus_space_set_region_1(t, h, o, val, c) do {                          \
493           (void) t;                                                             \
494           __asm volatile ("                                                     \
495                     movl      %0,%%a0                                           ;         \
496                     movl      %1,%%d1                                           ;         \
497                     movl      %2,%%d0                                           ;         \
498           1:        movb      %%d1,%%a0@+                                       ;         \
499                     subql     #1,%%d0                                           ;         \
500                     jne       1b"                                               :         \
501                                                                                 :         \
502                         "r" ((h) + (o)), "g" (val), "g" (c)           :         \
503                         "a0","d0","d1");                                                  \
504 } while (0);
505 
506 #define   bus_space_set_region_2(t, h, o, val, c) do {                          \
507           (void) t;                                                             \
508           __asm volatile ("                                                     \
509                     movl      %0,%%a0                                           ;         \
510                     movl      %1,%%d1                                           ;         \
511                     movl      %2,%%d0                                           ;         \
512           1:        movw      %%d1,%%a0@+                                       ;         \
513                     subql     #1,%%d0                                           ;         \
514                     jne       1b"                                               :         \
515                                                                                 :         \
516                         "r" ((h) + (o)), "g" (val), "g" (c)           :         \
517                         "a0","d0","d1");                                                  \
518 } while (0);
519 
520 #define   bus_space_set_region_4(t, h, o, val, c) do {                          \
521           (void) t;                                                             \
522           __asm volatile ("                                                     \
523                     movl      %0,%%a0                                           ;         \
524                     movl      %1,%%d1                                           ;         \
525                     movl      %2,%%d0                                           ;         \
526           1:        movl      d1,%%a0@+                               ;         \
527                     subql     #1,%%d0                                           ;         \
528                     jne       1b"                                               :         \
529                                                                                 :         \
530                         "r" ((h) + (o)), "g" (val), "g" (c)           :         \
531                         "a0","d0","d1");                                                  \
532 } while (0);
533 
534 /*
535  *        void bus_space_copy_N(bus_space_tag_t tag,
536  *            bus_space_handle_t bsh1, bus_size_t off1,
537  *            bus_space_handle_t bsh2, bus_size_t off2,
538  *            size_t count);
539  *
540  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
541  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
542  */
543 
544 #define   __COLDFIRE_copy_region_N(BYTES)                                                 \
545 static __inline void __CONCAT(bus_space_copy_region_,BYTES)           \
546           (bus_space_tag_t,                                                     \
547               bus_space_handle_t bsh1, bus_size_t off1,                         \
548               bus_space_handle_t bsh2, bus_size_t off2,                         \
549               bus_size_t count);                                                          \
550                                                                                           \
551 static __inline void                                                                      \
552 __CONCAT(bus_space_copy_region_,BYTES)(                                         \
553           bus_space_tag_t t,                                                    \
554           bus_space_handle_t h1,                                                          \
555           bus_size_t o1,                                                                  \
556           bus_space_handle_t h2,                                                          \
557           bus_size_t o2,                                                                  \
558           bus_size_t c)                                                                   \
559 {                                                                                         \
560           bus_size_t o;                                                                   \
561                                                                                           \
562           if ((h1 + o1) >= (h2 + o2)) {                                         \
563                     /* src after dest: copy forward */                          \
564                     for (o = 0; c != 0; c--, o += BYTES)                        \
565                               __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,   \
566                                   __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
567           } else {                                                              \
568                     /* dest after src: copy backwards */                        \
569                     for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)          \
570                               __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,   \
571                                   __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
572           }                                                                               \
573 }
574 __COLDFIRE_copy_region_N(1)
575 __COLDFIRE_copy_region_N(2)
576 __COLDFIRE_copy_region_N(4)
577 
578 #undef __COLDFIRE_copy_region_N
579 
580 /*
581  * Bus read/write barrier methods.
582  *
583  *        void bus_space_barrier(bus_space_tag_t tag,
584  *            bus_space_handle_t bsh, bus_size_t offset,
585  *            bus_size_t len, int flags);
586  *
587  * Note: Coldfire does not currently require barriers, but we must
588  * provide the flags to MI code.
589  */
590 #define   bus_space_barrier(t, h, o, l, f)        \
591           ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
592 #define   BUS_SPACE_BARRIER_READ        0x01                /* force read barrier */
593 #define   BUS_SPACE_BARRIER_WRITE       0x02                /* force write barrier */
594 
595 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
596 
597 
598 #ifdef _COLDFIRE_BUS_SPACE_PRIVATE
599 extern int _bus_space_map(void *, bus_addr_t, bus_size_t,
600     int, bus_space_handle_t *);
601 extern void _bus_space_unmap(void *, bus_space_handle_t, bus_size_t);
602 extern int _bus_space_peek_1(void *, bus_space_handle_t,
603     bus_size_t, uint8_t *);
604 extern int _bus_space_peek_2(void *, bus_space_handle_t,
605     bus_size_t, uint16_t *);
606 extern int _bus_space_peek_4(void *, bus_space_handle_t,
607     bus_size_t, uint32_t *);
608 extern int _bus_space_poke_1(void *, bus_space_handle_t, bus_size_t, uint8_t);
609 extern int _bus_space_poke_2(void *, bus_space_handle_t, bus_size_t, uint16_t);
610 extern int _bus_space_poke_4(void *, bus_space_handle_t, bus_size_t, uint32_t);
611 #endif /* _COLDFIRE_BUS_SPACE_PRIVATE */
612 
613 #endif /* _EVBCF_BUS_SPACE_H_ */
614