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