xref: /netbsd-src/sys/arch/hp300/include/bus.h (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
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