1 /*        $NetBSD: bus.h,v 1.24 2023/01/27 19:48:00 tsutsui 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 #ifndef _HP300_BUS_H_
60 #define _HP300_BUS_H_
61 
62 /*
63  * Values for the hp300 bus space tag, not to be used directly by MI code.
64  */
65 #define   HP300_BUS_SPACE_INTIO         0         /* space is intio space */
66 #define   HP300_BUS_SPACE_DIO 1         /* space is dio space */
67 #define   HP300_BUS_SPACE_SGC 2         /* space is sgc space */
68 
69 /*
70  * Bus address and size types
71  */
72 typedef u_long bus_addr_t;
73 typedef u_long bus_size_t;
74 
75 #define PRIxBUSADDR "lx"
76 #define PRIxBUSSIZE "lx"
77 #define PRIuBUSSIZE "lu"
78 
79 /*
80  * Access methods for bus resources and address space.
81  */
82 typedef struct bus_space_tag *bus_space_tag_t;
83 typedef u_long bus_space_handle_t;
84 
85 #define PRIxBSH               "lx"
86 
87 /*
88  * Implementation specific structures.
89  * XXX Don't use outside of bus_space definitions!
90  * XXX maybe this should be encapsuled in a non-global .h file?
91  */
92 
93 struct bus_space_tag {
94           u_int               bustype;
95 
96           uint8_t             (*bsr1)(bus_space_tag_t, bus_space_handle_t,
97                                   bus_size_t);
98           uint16_t  (*bsr2)(bus_space_tag_t, bus_space_handle_t,
99                                   bus_size_t);
100           uint32_t  (*bsr4)(bus_space_tag_t, bus_space_handle_t,
101                                   bus_size_t);
102           void                (*bsrm1)(bus_space_tag_t, bus_space_handle_t,
103                                   bus_size_t, uint8_t *, bus_size_t);
104           void                (*bsrm2)(bus_space_tag_t, bus_space_handle_t,
105                                   bus_size_t, uint16_t *, bus_size_t);
106           void                (*bsrm4)(bus_space_tag_t, bus_space_handle_t,
107                                   bus_size_t, uint32_t *, bus_size_t);
108           void                (*bsrr1)(bus_space_tag_t, bus_space_handle_t,
109                                   bus_size_t, uint8_t *, bus_size_t);
110           void                (*bsrr2)(bus_space_tag_t, bus_space_handle_t,
111                                   bus_size_t, uint16_t *, bus_size_t);
112           void                (*bsrr4)(bus_space_tag_t, bus_space_handle_t,
113                                   bus_size_t, uint32_t *, bus_size_t);
114           void                (*bsw1)(bus_space_tag_t, bus_space_handle_t,
115                                   bus_size_t, uint8_t);
116           void                (*bsw2)(bus_space_tag_t, bus_space_handle_t,
117                                   bus_size_t, uint16_t);
118           void                (*bsw4)(bus_space_tag_t, bus_space_handle_t,
119                                   bus_size_t, uint32_t);
120           void                (*bswm1)(bus_space_tag_t, bus_space_handle_t,
121                                   bus_size_t, const uint8_t *, bus_size_t);
122           void                (*bswm2)(bus_space_tag_t, bus_space_handle_t,
123                                   bus_size_t, const uint16_t *, bus_size_t);
124           void                (*bswm4)(bus_space_tag_t, bus_space_handle_t,
125                                   bus_size_t, const uint32_t *, bus_size_t);
126           void                (*bswr1)(bus_space_tag_t, bus_space_handle_t ,
127                                   bus_size_t, const uint8_t *, bus_size_t);
128           void                (*bswr2)(bus_space_tag_t, bus_space_handle_t,
129                                   bus_size_t, const uint16_t *, bus_size_t);
130           void                (*bswr4)(bus_space_tag_t, bus_space_handle_t,
131                                   bus_size_t, const uint32_t *, bus_size_t);
132           void                (*bssm1)(bus_space_tag_t, bus_space_handle_t,
133                                   bus_size_t, uint8_t, bus_size_t);
134           void                (*bssm2)(bus_space_tag_t, bus_space_handle_t,
135                                   bus_size_t, uint16_t, bus_size_t);
136           void                (*bssm4)(bus_space_tag_t, bus_space_handle_t,
137                                   bus_size_t, uint32_t, bus_size_t);
138           void                (*bssr1)(bus_space_tag_t, bus_space_handle_t,
139                                   bus_size_t, uint8_t, bus_size_t);
140           void                (*bssr2)(bus_space_tag_t, bus_space_handle_t,
141                                   bus_size_t, uint16_t, bus_size_t);
142           void                (*bssr4)(bus_space_tag_t, bus_space_handle_t,
143                                   bus_size_t, uint32_t, bus_size_t);
144 };
145 
146 /*
147  *        int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
148  *            bus_size_t size, int flags, bus_space_handle_t *bshp);
149  *
150  * Map a region of bus space.
151  */
152 
153 #define   BUS_SPACE_MAP_CACHEABLE                 0x01
154 #define   BUS_SPACE_MAP_LINEAR                    0x02
155 #define   BUS_SPACE_MAP_PREFETCHABLE    0x04
156 
157 int       bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t,
158               int, bus_space_handle_t *);
159 
160 /*
161  *        void bus_space_unmap(bus_space_tag_t t,
162  *            bus_space_handle_t bsh, bus_size_t size);
163  *
164  * Unmap a region of bus space.
165  */
166 
167 void      bus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
168 
169 /*
170  *        paddr_t bus_space_mmap(bus_space_tag_t t,
171  *            bus_addr_t addr, off_t off, int prot, int flags);
172  *
173  * Provide a cookie for pmap_phys_address/pmap_mmap_flags for bus_space address at
174  * addr + offset and flags.
175  */
176 static __inline paddr_t
bus_space_mmap(bus_space_tag_t t,bus_addr_t addr,off_t off,int prot,int flags)177 bus_space_mmap(bus_space_tag_t t, bus_addr_t addr, off_t off, int prot, int flags)
178 {
179           /* Always fail for now */
180           return -1;
181 }
182 
183 /*
184  *        int bus_space_subregion(bus_space_tag_t t,
185  *            bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
186  *            bus_space_handle_t *nbshp);
187  *
188  * Get a new handle for a subregion of an already-mapped area of bus space.
189  */
190 
191 int       bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
192               bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
193 
194 /*
195  *        int bus_space_alloc(bus_space_tag_t t, bus_addr_t, rstart,
196  *            bus_addr_t rend, bus_size_t size, bus_size_t align,
197  *            bus_size_t boundary, int flags, bus_addr_t *addrp,
198  *            bus_space_handle_t *bshp);
199  *
200  * Allocate a region of bus space.
201  */
202 
203 int       bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
204               bus_addr_t rend, bus_size_t size, bus_size_t align,
205               bus_size_t boundary, int cacheable, bus_addr_t *addrp,
206               bus_space_handle_t *bshp);
207 
208 /*
209  *        int bus_space_free(bus_space_tag_t t,
210  *            bus_space_handle_t bsh, bus_size_t size);
211  *
212  * Free a region of bus space.
213  */
214 
215 void      bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
216               bus_size_t size);
217 
218 /*
219  *        void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t);
220  *
221  * Get the kernel virtual address for the mapped bus space.
222  * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR.
223  *  (XXX not enforced)
224  */
225 #define bus_space_vaddr(t, h) (void *)(h)
226 
227 /*
228  *        int hp300_bus_space_probe(bus_space_tag_t t,
229  *            bus_space_handle_t bsh, bus_size_t offset, int sz);
230  *
231  * Probe the bus at t/bsh/offset, using sz as the size of the load.
232  *
233  * This is a machine-dependent extension, and is not to be used by
234  * machine-independent code.
235  */
236 
237 int       hp300_bus_space_probe(bus_space_tag_t t,
238               bus_space_handle_t bsh, bus_size_t offset, int sz);
239 
240 /*
241  *        u_intN_t bus_space_read_N(bus_space_tag_t tag,
242  *            bus_space_handle_t bsh, bus_size_t offset);
243  *
244  * Read a 1, 2, 4, or 8 byte quantity from bus space
245  * described by tag/handle/offset.
246  */
247 
248 #define   bus_space_read_1(t, h, o)                                             \
249     (((t)->bsr1 != NULL) ? ((t)->bsr1)(t, h, o) :                     \
250     (*(volatile uint8_t *)((h) + (o))))
251 
252 #define   bus_space_read_2(t, h, o)                                             \
253     (((t)->bsr2 != NULL) ? ((t)->bsr2)(t, h, o) :                     \
254     (*(volatile uint16_t *)((h) + (o))))
255 
256 #define   bus_space_read_4(t, h, o)                                             \
257     (((t)->bsr4 != NULL) ? ((t)->bsr4)(t, h, o) :                     \
258     (*(volatile uint32_t *)((h) + (o))))
259 
260 /*
261  *        void bus_space_read_multi_N(bus_space_tag_t tag,
262  *            bus_space_handle_t bsh, bus_size_t offset,
263  *            u_intN_t *addr, size_t count);
264  *
265  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
266  * described by tag/handle/offset and copy into buffer provided.
267  */
268 
269 #define   bus_space_read_multi_1(t, h, o, a, c)                                 \
270 do {                                                                                      \
271           if ((t)->bsrm1 != NULL)                                                         \
272                     ((t)->bsrm1)(t, h, o, a, c);                                \
273           else {                                                                          \
274                     __asm volatile ("                                           \
275                               movl      %0,%%a0                                 ;         \
276                               movl      %1,%%a1                                 ;         \
277                               movl      %2,%%d0                                 ;         \
278                     1:        movb      %%a0@,%%a1@+                            ;         \
279                               subql     #1,%%d0                                 ;         \
280                               jne       1b"                                     :         \
281                                                                                 :         \
282                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
283                                   "a0","a1","d0","memory");                     \
284           }                                                                               \
285 } while (/* CONSTCOND */ 0)
286 
287 #define   bus_space_read_multi_2(t, h, o, a, c)                                 \
288 do {                                                                                      \
289           if ((t)->bsrm2 != NULL)                                                         \
290                     ((t)->bsrm2)(t, h, o, a, c);                                \
291           else {                                                                          \
292                     __asm volatile ("                                           \
293                               movl      %0,%%a0                                 ;         \
294                               movl      %1,%%a1                                 ;         \
295                               movl      %2,%%d0                                 ;         \
296                     1:        movw      %%a0@,%%a1@+                            ;         \
297                               subql     #1,%%d0                                 ;         \
298                               jne       1b"                                     :         \
299                                                                                 :         \
300                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
301                                   "a0","a1","d0","memory");                     \
302           }                                                                               \
303 } while (/* CONSTCOND */ 0)
304 
305 #define   bus_space_read_multi_4(t, h, o, a, c) do {                            \
306           if ((t)->bsrm4 != NULL)                                                         \
307                     ((t)->bsrm4)(t, h, o, a, c);                                \
308           else {                                                                          \
309                     __asm volatile ("                                           \
310                               movl      %0,%%a0                                 ;         \
311                               movl      %1,%%a1                                 ;         \
312                               movl      %2,%%d0                                 ;         \
313                     1:        movl      %%a0@,%%a1@+                            ;         \
314                               subql     #1,%%d0                                 ;         \
315                               jne       1b"                                     :         \
316                                                                                 :         \
317                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
318                                   "a0","a1","d0","memory");                     \
319           }                                                                               \
320 } while (/* CONSTCOND */ 0)
321 
322 /*
323  *        void bus_space_read_region_N(bus_space_tag_t tag,
324  *            bus_space_handle_t bsh, bus_size_t offset,
325  *            u_intN_t *addr, size_t count);
326  *
327  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
328  * described by tag/handle and starting at `offset' and copy into
329  * buffer provided.
330  */
331 
332 #define   bus_space_read_region_1(t, h, o, a, c)                                \
333 do {                                                                                      \
334           if ((t)->bsrr1 != NULL)                                                         \
335                     ((t)->bsrr1)(t, h, o, a, c);                                \
336           else {                                                                          \
337                     __asm volatile ("                                           \
338                               movl      %0,%%a0                                 ;         \
339                               movl      %1,%%a1                                 ;         \
340                               movl      %2,%%d0                                 ;         \
341                     1:        movb      %%a0@+,%%a1@+                           ;         \
342                               subql     #1,%%d0                                 ;         \
343                               jne       1b"                                     :         \
344                                                                                 :         \
345                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
346                                   "a0","a1","d0","memory");                     \
347           }                                                                               \
348 } while (/* CONSTCOND */ 0)
349 
350 #define   bus_space_read_region_2(t, h, o, a, c)                                \
351 do {                                                                                      \
352           if ((t)->bsrr2 != NULL)                                                         \
353                     ((t)->bsrr2)(t, h, o, a, c);                                \
354           else {                                                                          \
355                     __asm volatile ("                                           \
356                               movl      %0,%%a0                                 ;         \
357                               movl      %1,%%a1                                 ;         \
358                               movl      %2,%%d0                                 ;         \
359                     1:        movw      %%a0@+,%%a1@+                           ;         \
360                               subql     #1,%%d0                                 ;         \
361                               jne       1b"                                     :         \
362                                                                                 :         \
363                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
364                                   "a0","a1","d0","memory");                     \
365           }                                                                               \
366 } while (/* CONSTCOND */ 0)
367 
368 #define   bus_space_read_region_4(t, h, o, a, c)                                \
369 do {                                                                                      \
370           if ((t)->bsrr4 != NULL)                                                         \
371                     ((t)->bsrr4)(t, h, o, a, c);                                \
372           else {                                                                          \
373                     __asm volatile ("                                           \
374                               movl      %0,%%a0                                 ;         \
375                               movl      %1,%%a1                                 ;         \
376                               movl      %2,%%d0                                 ;         \
377                     1:        movl      %%a0@+,%%a1@+                           ;         \
378                               subql     #1,%%d0                                 ;         \
379                               jne       1b"                                     :         \
380                                                                                 :         \
381                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
382                                   "a0","a1","d0","memory");                     \
383           }                                                                               \
384 } while (/* CONSTCOND */ 0)
385 
386 /*
387  *        void bus_space_write_N(bus_space_tag_t tag,
388  *            bus_space_handle_t bsh, bus_size_t offset,
389  *            u_intN_t value);
390  *
391  * Write the 1, 2, 4, or 8 byte value `value' to bus space
392  * described by tag/handle/offset.
393  */
394 
395 #define   bus_space_write_1(t, h, o, v)                                         \
396 do {                                                                                      \
397           if ((t)->bsw1 != NULL)                                                          \
398                     ((t)->bsw1)(t, h, o, v);                                    \
399           else                                                                            \
400                     ((void)(*(volatile uint8_t *)((h) + (o)) = (v))); \
401 } while (/* CONSTCOND */ 0)
402 
403 #define   bus_space_write_2(t, h, o, v)                                         \
404 do {                                                                                      \
405           if ((t)->bsw2 != NULL)                                                          \
406                     ((t)->bsw2)(t, h, o, v);                                    \
407           else                                                                            \
408                     ((void)(*(volatile uint16_t *)((h) + (o)) = (v)));          \
409 } while (/* CONSTCOND */ 0)
410 
411 #define   bus_space_write_4(t, h, o, v)                                         \
412 do {                                                                                      \
413           if ((t)->bsw4 != NULL)                                                          \
414                     ((t)->bsw4)(t, h, o, v);                                    \
415           else                                                                            \
416                     ((void)(*(volatile uint32_t *)((h) + (o)) = (v)));          \
417 } while (/* CONSTCOND */ 0)
418 
419 /*
420  *        void bus_space_write_multi_N(bus_space_tag_t tag,
421  *            bus_space_handle_t bsh, bus_size_t offset,
422  *            const u_intN_t *addr, size_t count);
423  *
424  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
425  * provided to bus space described by tag/handle/offset.
426  */
427 
428 #define   bus_space_write_multi_1(t, h, o, a, c)                                \
429 do {                                                                                      \
430           if ((t)->bswm1 != NULL)                                                         \
431                     ((t)->bswm1)(t, h, o, a, c);                                \
432           else {                                                                          \
433                     __asm volatile ("                                           \
434                               movl      %0,%%a0                                 ;         \
435                               movl      %1,%%a1                                 ;         \
436                               movl      %2,%%d0                                 ;         \
437                     1:        movb      %%a1@+,%%a0@                            ;         \
438                               subql     #1,%%d0                                 ;         \
439                               jne       1b"                                     :         \
440                                                                                 :         \
441                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
442                                   "a0","a1","d0");                                        \
443           }                                                                               \
444 } while (/* CONSTCOND */ 0)
445 
446 #define   bus_space_write_multi_2(t, h, o, a, c)                                \
447 do {                                                                                      \
448           if ((t)->bswm2 != NULL)                                                         \
449                     ((t)->bswm2)(t, h, o, a, c);                                \
450           else {                                                                          \
451                     __asm volatile ("                                           \
452                               movl      %0,%%a0                                 ;         \
453                               movl      %1,%%a1                                 ;         \
454                               movl      %2,%%d0                                 ;         \
455                     1:        movw      %%a1@+,%%a0@                            ;         \
456                               subql     #1,%%d0                                 ;         \
457                               jne       1b"                                     :         \
458                                                                                 :         \
459                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
460                                   "a0","a1","d0");                                        \
461           }                                                                               \
462 } while (/* CONSTCOND */ 0)
463 
464 #define   bus_space_write_multi_4(t, h, o, a, c)                                \
465 do {                                                                                      \
466           (void) t;                                                             \
467           if ((t)->bswm4 != NULL)                                               \
468                     ((t)->bswm4)(t, h, o, a, c);                                \
469           else {                                                                          \
470                     __asm volatile ("                                           \
471                               movl      %0,%%a0                                 ;         \
472                               movl      %1,%%a1                                 ;         \
473                               movl      %2,%%d0                                 ;         \
474                     1:        movl      %%a1@+,%%a0@                            ;         \
475                               subql     #1,%%d0                                 ;         \
476                               jne       1b"                                     :         \
477                                                                                 :         \
478                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
479                                   "a0","a1","d0");                                        \
480           }                                                                               \
481 } while (/* CONSTCOND */ 0)
482 
483 /*
484  *        void bus_space_write_region_N(bus_space_tag_t tag,
485  *            bus_space_handle_t bsh, bus_size_t offset,
486  *            const u_intN_t *addr, size_t count);
487  *
488  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
489  * to bus space described by tag/handle starting at `offset'.
490  */
491 
492 #define   bus_space_write_region_1(t, h, o, a, c)                               \
493 do {                                                                                      \
494           if ((t)->bswr1 != NULL)                                               \
495                     ((t)->bswr1)(t, h, o, a, c);                                \
496           else {                                                                          \
497                     __asm volatile ("                                           \
498                               movl      %0,%%a0                                 ;         \
499                               movl      %1,%%a1                                 ;         \
500                               movl      %2,%%d0                                 ;         \
501                     1:        movb      %%a1@+,%%a0@+                           ;         \
502                               subql     #1,%%d0                                 ;         \
503                               jne       1b"                                     :         \
504                                                                                 :         \
505                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
506                                   "a0","a1","d0");                                        \
507           }                                                                               \
508 } while (/* CONSTCOND */ 0)
509 
510 #define   bus_space_write_region_2(t, h, o, a, c)                               \
511 do {                                                                                      \
512           if ((t)->bswr2) != NULL)                                              \
513                     ((t)->bswr2)(t, h, o, a, c);                                \
514           else {                                                                          \
515                     __asm volatile ("                                           \
516                               movl      %0,%%a0                                 ;         \
517                               movl      %1,%%a1                                 ;         \
518                               movl      %2,%%d0                                 ;         \
519                     1:        movw      %%a1@+,%%a0@+                           ;         \
520                               subql     #1,%%d0                                 ;         \
521                               jne       1b"                                     :         \
522                                                                                 :         \
523                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
524                                   "a0","a1","d0");                                        \
525           }                                                                               \
526 } while (/* CONSTCOND */ 0)
527 
528 #define   bus_space_write_region_4(t, h, o, a, c)                               \
529 do {                                                                                      \
530           if ((t)->bswr4) != NULL)                                              \
531                     ((t)->bswr4)(t, h, o, a, c);                                \
532           else {                                                                          \
533                     __asm volatile ("                                           \
534                               movl      %0,%%a0                                 ;         \
535                               movl      %1,%%a1                                 ;         \
536                               movl      %2,%%d0                                 ;         \
537                     1:        movl      %%a1@+,%%a0@+                           ;         \
538                               subql     #1,%%d0                                 ;         \
539                               jne       1b"                                     :         \
540                                                                                 :         \
541                                   "r" ((h) + (o)), "g" (a), "g" (c)   :         \
542                                   "a0","a1","d0");                                        \
543           }                                                                               \
544 } while (/* CONSTCOND */ 0)
545 
546 /*
547  *        void bus_space_set_multi_N(bus_space_tag_t tag,
548  *            bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
549  *            size_t count);
550  *
551  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
552  * by tag/handle/offset `count' times.
553  */
554 
555 #define   bus_space_set_multi_1(t, h, o, val, c)                                \
556 do {                                                                                      \
557           if ((t)->bssm1 != NULL)                                                         \
558                     ((t)->bssm1)(t, h, o, val, c);                                        \
559           else {                                                                          \
560                     __asm volatile ("                                           \
561                               movl      %0,%%a0                                 ;         \
562                               movl      %1,%%d1                                 ;         \
563                               movl      %2,%%d0                                 ;         \
564                     1:        movb      %%d1,%%a0@                              ;         \
565                               subql     #1,%%d0                                 ;         \
566                               jne       1b"                                     :         \
567                                                                                 :         \
568                                   "r" ((h) + (o)), "g" (val), "g" (c) :         \
569                                   "a0","d0","d1");                                        \
570           }                                                                               \
571 } while (/* CONSTCOND */ 0)
572 
573 #define   bus_space_set_multi_2(t, h, o, val, c)                                \
574 do {                                                                                      \
575           if ((t)->bssm2 != NULL)                                                         \
576                     ((t)->bssm2)(t, h, o, val, c);                                        \
577           else {                                                                          \
578                     __asm volatile ("                                           \
579                               movl      %0,%%a0                                 ;         \
580                               movl      %1,%%d1                                 ;         \
581                               movl      %2,%%d0                                 ;         \
582                     1:        movw      %%d1,%%a0@                              ;         \
583                               subql     #1,%%d0                                 ;         \
584                               jne       1b"                                     :         \
585                                                                                 :         \
586                                   "r" ((h) + (o)), "g" (val), "g" (c) :         \
587                                   "a0","d0","d1");                                        \
588           }                                                                               \
589 } while (/* CONSTCOND */ 0)
590 
591 #define   bus_space_set_multi_4(t, h, o, val, c)                                \
592 do {                                                                                      \
593           if ((t)->bssm4 != NULL)                                                         \
594                     ((t)->bssm4)(t, h, o, val, c);                                        \
595           else {                                                                          \
596                     __asm volatile ("                                           \
597                               movl      %0,%%a0                                 ;         \
598                               movl      %1,%%d1                                 ;         \
599                               movl      %2,%%d0                                 ;         \
600                     1:        movl      %%d1,%%a0@                              ;         \
601                               subql     #1,%%d0                                 ;         \
602                               jne       1b"                                     :         \
603                                                                                 :         \
604                                   "r" ((h) + (o)), "g" (val), "g" (c) :         \
605                                   "a0","d0","d1");                                        \
606           }                                                                               \
607 } while (/* CONSTCOND */ 0)
608 
609 /*
610  *        void bus_space_set_region_N(bus_space_tag_t tag,
611  *            bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
612  *            size_t count);
613  *
614  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
615  * by tag/handle starting at `offset'.
616  */
617 
618 #define   bus_space_set_region_1(t, h, o, val, c)                               \
619 do {                                                                                      \
620           if ((t)->bssr1 != NULL)                                                         \
621                     ((t)->bssr1)(t, h, o, val, c);                                        \
622           else {                                                                          \
623                     __asm volatile ("                                           \
624                               movl      %0,%%a0                                 ;         \
625                               movl      %1,%%d1                                 ;         \
626                               movl      %2,%%d0                                 ;         \
627                     1:        movb      %%d1,%%a0@+                             ;         \
628                               subql     #1,%%d0                                 ;         \
629                               jne       1b"                                     :         \
630                                                                                 :         \
631                                   "r" ((h) + (o)), "g" (val), "g" (c) :         \
632                                   "a0","d0","d1");                                        \
633           }                                                                               \
634 } while (/* CONSTCOND */ 0)
635 
636 #define   bus_space_set_region_2(t, h, o, val, c)                               \
637 do {                                                                                      \
638           if ((t)->bssr2 != NULL)                                                         \
639                     ((t)->bssr2)(t, h, o, val, c);                                        \
640           else {                                                                          \
641                     __asm volatile ("                                           \
642                               movl      %0,%%a0                                 ;         \
643                               movl      %1,%%d1                                 ;         \
644                               movl      %2,%%d0                                 ;         \
645                     1:        movw      %%d1,%%a0@+                             ;         \
646                               subql     #1,%%d0                                 ;         \
647                               jne       1b"                                     :         \
648                                                                                 :         \
649                                   "r" ((h) + (o)), "g" (val), "g" (c) :         \
650                                   "a0","d0","d1");                                        \
651           }                                                                               \
652 } while (/* CONSTCOND */ 0)
653 
654 #define   bus_space_set_region_4(t, h, o, val, c)                               \
655 do {                                                                                      \
656           (void) t;                                                             \
657           if ((t)->bssr4 != NULL)                                                         \
658                     ((t)->bssr4)(t, h, o, val, c);                                        \
659           else {                                                                          \
660                     __asm volatile ("                                           \
661                               movl      %0,%%a0                                 ;         \
662                               movl      %1,%%d1                                 ;         \
663                               movl      %2,%%d0                                 ;         \
664                     1:        movl      %%d1,%%a0@+                             ;         \
665                               subql     #1,%%d0                                 ;         \
666                               jne       1b"                                     :         \
667                                                                                 :         \
668                                   "r" ((h) + (o)), "g" (val), "g" (c) :         \
669                                   "a0","d0","d1");                                        \
670           }                                                                               \
671 } while (/* CONSTCOND */ 0)
672 
673 /*
674  *        void bus_space_copy_region_N(bus_space_tag_t tag,
675  *            bus_space_handle_t bsh1, bus_size_t off1,
676  *            bus_space_handle_t bsh2, bus_size_t off2,
677  *            bus_size_t count);
678  *
679  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
680  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
681  */
682 
683 #define   __HP300_copy_region_N(BYTES)                                          \
684 static __inline void                                                            \
685 __CONCAT(bus_space_copy_region_,BYTES)(bus_space_tag_t t,             \
686     bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2,      \
687     bus_size_t o2, bus_size_t c)                                                \
688 {                                                                                         \
689           bus_size_t o;                                                                   \
690                                                                                           \
691           if ((h1 + o1) >= (h2 + o2)) {                                         \
692                     /* src after dest: copy forward */                          \
693                     for (o = 0; c != 0; c--, o += BYTES)                        \
694                               __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,   \
695                                   __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
696           } else {                                                              \
697                     /* dest after src: copy backwards */                        \
698                     for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)          \
699                               __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,   \
700                                   __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
701           }                                                                               \
702 }
703 __HP300_copy_region_N(1)
704 __HP300_copy_region_N(2)
705 __HP300_copy_region_N(4)
706 
707 #undef __HP300_copy_region_N
708 
709 /*
710  * Bus stream operations--defined in terms of non-stream counterparts
711  */
712 #define   __BUS_SPACE_HAS_STREAM_METHODS 1
713 #define   bus_space_read_stream_1 bus_space_read_1
714 #define   bus_space_read_stream_2 bus_space_read_2
715 #define   bus_space_read_stream_4 bus_space_read_4
716 #define   bus_space_read_stream_8 bus_space_read_8
717 #define   bus_space_read_multi_stream_1 bus_space_read_multi_1
718 #define   bus_space_read_multi_stream_2 bus_space_read_multi_2
719 #define   bus_space_read_multi_stream_4 bus_space_read_multi_4
720 #define   bus_space_read_multi_stream_8 bus_space_read_multi_8
721 #define   bus_space_read_region_stream_1 bus_space_read_region_1
722 #define   bus_space_read_region_stream_2 bus_space_read_region_2
723 #define   bus_space_read_region_stream_4 bus_space_read_region_4
724 #define   bus_space_read_region_stream_8 bus_space_read_region_8
725 #define   bus_space_write_stream_1 bus_space_write_1
726 #define   bus_space_write_stream_2 bus_space_write_2
727 #define   bus_space_write_stream_4 bus_space_write_4
728 #define   bus_space_write_stream_8 bus_space_write_8
729 #define   bus_space_write_multi_stream_1 bus_space_write_multi_1
730 #define   bus_space_write_multi_stream_2 bus_space_write_multi_2
731 #define   bus_space_write_multi_stream_4 bus_space_write_multi_4
732 #define   bus_space_write_multi_stream_8 bus_space_write_multi_8
733 #define   bus_space_write_region_stream_1 bus_space_write_region_1
734 #define   bus_space_write_region_stream_2 bus_space_write_region_2
735 #define   bus_space_write_region_stream_4 bus_space_write_region_4
736 #define   bus_space_write_region_stream_8         bus_space_write_region_8
737 
738 /*
739  * Bus read/write barrier methods.
740  *
741  *        void bus_space_barrier(bus_space_tag_t tag,
742  *            bus_space_handle_t bsh, bus_size_t offset,
743  *            bus_size_t len, int flags);
744  *
745  * Note: the 680x0 does not currently require barriers, but we must
746  * provide the flags to MI code.
747  */
748 #define   bus_space_barrier(t, h, o, l, f)        \
749           ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
750 #define   BUS_SPACE_BARRIER_READ        0x01                /* force read barrier */
751 #define   BUS_SPACE_BARRIER_WRITE       0x02                /* force write barrier */
752 
753 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
754 
755 /*
756  * There is no bus_dma(9)'fied bus drivers on this port.
757  */
758 #define __HAVE_NO_BUS_DMA
759 
760 #endif /* _HP300_BUS_H_ */
761