xref: /netbsd/sys/arch/next68k/include/bus_space.h (revision ca81c76a)
1 /*	$NetBSD: bus_space.h,v 1.23 2023/02/11 02:31:34 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 _NEXT68K_BUS_SPACE_H_
60 #define	_NEXT68K_BUS_SPACE_H_
61 /*
62  * Addresses (in bus space).
63  */
64 typedef u_long bus_addr_t;
65 typedef u_long bus_size_t;
66 
67 #define PRIxBUSADDR	"lx"
68 #define PRIxBUSSIZE	"lx"
69 #define PRIuBUSSIZE	"lu"
70 
71 /*
72  * Access methods for bus resources and address space.
73  */
74 typedef volatile char *  bus_space_tag_t;
75 typedef u_long	bus_space_handle_t;
76 
77 #define PRIxBSH		"lx"
78 
79 /*
80  * Value for the next68k bus space tag, not to be used directly by MI code.
81  */
82 #define NEXT68K_INTIO_BUS_SPACE		((bus_space_tag_t)intiobase)
83 
84 /*
85  * Mapping and unmapping operations.
86  */
87 
88 int bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
89     bus_space_handle_t *);
90 
91 #define	bus_space_unmap(t, h, s)
92 
93 #define	bus_space_subregion(t, h, o, s, hp)				\
94      (*(hp)=(h)+(o))
95 
96 #define	BUS_SPACE_MAP_CACHEABLE		0x01
97 #define	BUS_SPACE_MAP_LINEAR		0x02
98 
99 /*
100  * Allocation and deallocation operations.
101  */
102 #define	bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)  		\
103      (-1)
104 
105 #define	bus_space_free(t, h, s)
106 
107 /*
108  *	paddr_t bus_space_mmap(bus_space_tag_t t, bus_addr_t base,
109  *	    off_t offset, int prot, int flags);
110  *
111  * Mmap an area of bus space.
112  */
113 
114 paddr_t bus_space_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);
115 
116 /*
117  *	uintN_t bus_space_read_N(bus_space_tag_t tag,
118  *	    bus_space_handle_t bsh, bus_size_t offset);
119  *
120  * Read a 1, 2, 4, or 8 byte quantity from bus space
121  * described by tag/handle/offset.
122  */
123 
124 #define	bus_space_read_1(t, h, o)					\
125     ((void) t, (*(volatile uint8_t *)((h) + (o))))
126 
127 #define	bus_space_read_2(t, h, o)					\
128     ((void) t, (*(volatile uint16_t *)((h) + (o))))
129 
130 #define	bus_space_read_4(t, h, o)					\
131     ((void) t, (*(volatile uint32_t *)((h) + (o))))
132 
133 /*
134  *	void bus_space_read_multi_N(bus_space_tag_t tag,
135  *	    bus_space_handle_t bsh, bus_size_t offset,
136  *	    uintN_t *addr, size_t count);
137  *
138  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
139  * described by tag/handle/offset and copy into buffer provided.
140  */
141 
142 #define	bus_space_read_multi_1(t, h, o, a, c) do {			\
143 	(void) t;							\
144 	__asm volatile ("						\
145 		movl	%0,%%a0					;	\
146 		movl	%1,%%a1					;	\
147 		movl	%2,%%d0					;	\
148 	1:	movb	%%a0@,%%a1@+				;	\
149 		subql	#1,%%d0					;	\
150 		jne	1b"					:	\
151 								:	\
152 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
153 		    "a0","a1","d0","memory");				\
154 } while (0);
155 
156 #define	bus_space_read_multi_2(t, h, o, a, c) do {			\
157 	(void) t;							\
158 	__asm volatile ("						\
159 		movl	%0,%%a0					;	\
160 		movl	%1,%%a1					;	\
161 		movl	%2,%%d0					;	\
162 	1:	movw	%%a0@,%%a1@+				;	\
163 		subql	#1,%%d0					;	\
164 		jne	1b"					:	\
165 								:	\
166 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
167 		    "a0","a1","d0","memory");				\
168 } while (0);
169 
170 #define	bus_space_read_multi_4(t, h, o, a, c) do {			\
171 	(void) t;							\
172 	__asm volatile ("						\
173 		movl	%0,%%a0					;	\
174 		movl	%1,%%a1					;	\
175 		movl	%2,%%d0					;	\
176 	1:	movl	%%a0@,%%a1@+				;	\
177 		subql	#1,%%d0					;	\
178 		jne	1b"					:	\
179 								:	\
180 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
181 		    "a0","a1","d0","memory");				\
182 } while (0);
183 
184 /*
185  *	void bus_space_read_region_N(bus_space_tag_t tag,
186  *	    bus_space_handle_t bsh, bus_size_t offset,
187  *	    uintN_t *addr, size_t count);
188  *
189  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
190  * described by tag/handle and starting at `offset' and copy into
191  * buffer provided.
192  */
193 
194 #define	bus_space_read_region_1(t, h, o, a, c) do {			\
195 	(void) t;							\
196 	__asm volatile ("						\
197 		movl	%0,%%a0					;	\
198 		movl	%1,%%a1					;	\
199 		movl	%2,%%d0					;	\
200 	1:	movb	%%a0@+,%%a1@+				;	\
201 		subql	#1,%%d0					;	\
202 		jne	1b"					:	\
203 								:	\
204 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
205 		    "a0","a1","d0","memory");				\
206 } while (0);
207 
208 #define	bus_space_read_region_2(t, h, o, a, c) do {			\
209 	(void) t;							\
210 	__asm volatile ("						\
211 		movl	%0,%%a0					;	\
212 		movl	%1,%%a1					;	\
213 		movl	%2,%%d0					;	\
214 	1:	movw	%%a0@+,%%a1@+				;	\
215 		subql	#1,%%d0					;	\
216 		jne	1b"					:	\
217 								:	\
218 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
219 		    "a0","a1","d0","memory");					\
220 } while (0);
221 
222 #define	bus_space_read_region_4(t, h, o, a, c) do {			\
223 	(void) t;							\
224 	__asm volatile ("						\
225 		movl	%0,%%a0					;	\
226 		movl	%1,%%a1					;	\
227 		movl	%2,%%d0					;	\
228 	1:	movl	%%a0@+,%%a1@+				;	\
229 		subql	#1,%%d0					;	\
230 		jne	1b"					:	\
231 								:	\
232 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
233 		    "a0","a1","d0","memory");					\
234 } while (0);
235 
236 /*
237  *	void bus_space_write_N(bus_space_tag_t tag,
238  *	    bus_space_handle_t bsh, bus_size_t offset,
239  *	    uintN_t value);
240  *
241  * Write the 1, 2, 4, or 8 byte value `value' to bus space
242  * described by tag/handle/offset.
243  */
244 
245 #define	bus_space_write_1(t, h, o, v)					\
246     ((void) t, ((void)(*(volatile uint8_t *)((h) + (o)) = (v))))
247 
248 #define	bus_space_write_2(t, h, o, v)					\
249     ((void) t, ((void)(*(volatile uint16_t *)((h) + (o)) = (v))))
250 
251 #define	bus_space_write_4(t, h, o, v)					\
252     ((void) t, ((void)(*(volatile uint32_t *)((h) + (o)) = (v))))
253 
254 /*
255  *	void bus_space_write_multi_N(bus_space_tag_t tag,
256  *	    bus_space_handle_t bsh, bus_size_t offset,
257  *	    const uintN_t *addr, size_t count);
258  *
259  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
260  * provided to bus space described by tag/handle/offset.
261  */
262 
263 #define	bus_space_write_multi_1(t, h, o, a, c) do {			\
264 	(void) t;							\
265 	__asm volatile ("						\
266 		movl	%0,%%a0					;	\
267 		movl	%1,%%a1					;	\
268 		movl	%2,%%d0					;	\
269 	1:	movb	%%a1@+,%%a0@				;	\
270 		subql	#1,%%d0					;	\
271 		jne	1b"					:	\
272 								:	\
273 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
274 		    "a0","a1","d0");					\
275 } while (0);
276 
277 #define	bus_space_write_multi_2(t, h, o, a, c) do {			\
278 	(void) t;							\
279 	__asm volatile ("						\
280 		movl	%0,%%a0					;	\
281 		movl	%1,%%a1					;	\
282 		movl	%2,%%d0					;	\
283 	1:	movw	%%a1@+,%%a0@				;	\
284 		subql	#1,%%d0					;	\
285 		jne	1b"					:	\
286 								:	\
287 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
288 		    "a0","a1","d0");					\
289 } while (0);
290 
291 #define	bus_space_write_multi_4(t, h, o, a, c) do {			\
292 	(void) t;							\
293 	__asm volatile ("						\
294 		movl	%0,%%a0					;	\
295 		movl	%1,%%a1					;	\
296 		movl	%2,%%d0					;	\
297 	1:	movl	%%a1@+,%%a0@				;	\
298 		subql	#1,%%d0					;	\
299 		jne	1b"					:	\
300 								:	\
301 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
302 		    "a0","a1","d0");					\
303 } while (0);
304 
305 /*
306  *	void bus_space_write_region_N(bus_space_tag_t tag,
307  *	    bus_space_handle_t bsh, bus_size_t offset,
308  *	    const uintN_t *addr, size_t count);
309  *
310  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
311  * to bus space described by tag/handle starting at `offset'.
312  */
313 
314 #define	bus_space_write_region_1(t, h, o, a, c) do {			\
315 	(void) t;							\
316 	__asm volatile ("						\
317 		movl	%0,%%a0					;	\
318 		movl	%1,%%a1					;	\
319 		movl	%2,%%d0					;	\
320 	1:	movb	%%a1@+,%%a0@+				;	\
321 		subql	#1,%%d0					;	\
322 		jne	1b"					:	\
323 								:	\
324 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
325 		    "a0","a1","d0");					\
326 } while (0);
327 
328 #define	bus_space_write_region_2(t, h, o, a, c) do {			\
329 	(void) t;							\
330 	__asm volatile ("						\
331 		movl	%0,%%a0					;	\
332 		movl	%1,%%a1					;	\
333 		movl	%2,%%d0					;	\
334 	1:	movw	%%a1@+,%%a0@+				;	\
335 		subql	#1,%%d0					;	\
336 		jne	1b"					:	\
337 								:	\
338 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
339 		    "a0","a1","d0");					\
340 } while (0);
341 
342 #define	bus_space_write_region_4(t, h, o, a, c) do {			\
343 	(void) t;							\
344 	__asm volatile ("						\
345 		movl	%0,%%a0					;	\
346 		movl	%1,%%a1					;	\
347 		movl	%2,%%d0					;	\
348 	1:	movl	%%a1@+,%%a0@+				;	\
349 		subql	#1,%%d0					;	\
350 		jne	1b"					:	\
351 								:	\
352 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
353 		    "a0","a1","d0");					\
354 } while (0);
355 
356 /*
357  *	void bus_space_set_multi_N(bus_space_tag_t tag,
358  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
359  *	    size_t count);
360  *
361  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
362  * by tag/handle/offset `count' times.
363  */
364 
365 #define	bus_space_set_multi_1(t, h, o, val, c) do {			\
366 	(void) t;							\
367 	__asm volatile ("						\
368 		movl	%0,%%a0					;	\
369 		movl	%1,%%d1					;	\
370 		movl	%2,%%d0					;	\
371 	1:	movb	%%d1,%%a0@				;	\
372 		subql	#1,%%d0					;	\
373 		jne	1b"					:	\
374 								:	\
375 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
376 		    "a0","d0","d1");					\
377 } while (0);
378 
379 #define	bus_space_set_multi_2(t, h, o, val, c) do {			\
380 	(void) t;							\
381 	__asm volatile ("						\
382 		movl	%0,%%a0					;	\
383 		movl	%1,%%d1					;	\
384 		movl	%2,%%d0					;	\
385 	1:	movw	%%d1,%%a0@				;	\
386 		subql	#1,%%d0					;	\
387 		jne	1b"					:	\
388 								:	\
389 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
390 		    "a0","d0","d1");					\
391 } while (0);
392 
393 #define	bus_space_set_multi_4(t, h, o, val, c) do {			\
394 	(void) t;							\
395 	__asm volatile ("						\
396 		movl	%0,%%a0					;	\
397 		movl	%1,%%d1					;	\
398 		movl	%2,%%d0					;	\
399 	1:	movl	%%d1,%%a0@				;	\
400 		subql	#1,%%d0					;	\
401 		jne	1b"					:	\
402 								:	\
403 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
404 		    "a0","d0","d1");					\
405 } while (0);
406 
407 /*
408  *	void bus_space_set_region_N(bus_space_tag_t tag,
409  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
410  *	    size_t count);
411  *
412  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
413  * by tag/handle starting at `offset'.
414  */
415 
416 #define	bus_space_set_region_1(t, h, o, val, c) do {			\
417 	(void) t;							\
418 	__asm volatile ("						\
419 		movl	%0,%%a0					;	\
420 		movl	%1,%%d1					;	\
421 		movl	%2,%%d0					;	\
422 	1:	movb	%%d1,%%a0@+				;	\
423 		subql	#1,%%d0					;	\
424 		jne	1b"					:	\
425 								:	\
426 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
427 		    "a0","d0","d1");					\
428 } while (0);
429 
430 #define	bus_space_set_region_2(t, h, o, val, c) do {			\
431 	(void) t;							\
432 	__asm volatile ("						\
433 		movl	%0,%%a0					;	\
434 		movl	%1,%%d1					;	\
435 		movl	%2,%%d0					;	\
436 	1:	movw	%%d1,%%a0@+				;	\
437 		subql	#1,%%d0					;	\
438 		jne	1b"					:	\
439 								:	\
440 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
441 		    "a0","d0","d1");					\
442 } while (0);
443 
444 #define	bus_space_set_region_4(t, h, o, val, c) do {			\
445 	(void) t;							\
446 	__asm volatile ("						\
447 		movl	%0,%%a0					;	\
448 		movl	%1,%%d1					;	\
449 		movl	%2,%%d0					;	\
450 	1:	movl	%%d1,%%a0@+				;	\
451 		subql	#1,%%d0					;	\
452 		jne	1b"					:	\
453 								:	\
454 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
455 		    "a0","d0","d1");					\
456 } while (0);
457 
458 /*
459  *	void bus_space_copy_N(bus_space_tag_t tag,
460  *	    bus_space_handle_t bsh1, bus_size_t off1,
461  *	    bus_space_handle_t bsh2, bus_size_t off2,
462  *	    size_t count);
463  *
464  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
465  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
466  */
467 
468 #define	__NEXT68K_copy_region_N(BYTES)					\
469 static __inline void __CONCAT(bus_space_copy_region_,BYTES)		\
470 	(bus_space_tag_t,						\
471 	 bus_space_handle_t, bus_size_t,				\
472 	 bus_space_handle_t, bus_size_t,				\
473 	 bus_size_t);							\
474 									\
475 static __inline void							\
476 __CONCAT(bus_space_copy_region_,BYTES)(					\
477 	bus_space_tag_t t,						\
478 	bus_space_handle_t h1,						\
479 	bus_size_t o1,							\
480 	bus_space_handle_t h2,						\
481 	bus_size_t o2,							\
482 	bus_size_t c)							\
483 {									\
484 	bus_size_t o;							\
485 									\
486 	if ((h1 + o1) >= (h2 + o2)) {					\
487 		/* src after dest: copy forward */			\
488 		for (o = 0; c != 0; c--, o += BYTES)			\
489 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
490 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
491 	} else {							\
492 		/* dest after src: copy backwards */			\
493 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
494 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
495 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
496 	}								\
497 }
498 __NEXT68K_copy_region_N(1)
499 __NEXT68K_copy_region_N(2)
500 __NEXT68K_copy_region_N(4)
501 
502 #undef __NEXT68K_copy_region_N
503 
504 /*
505  * Bus read/write barrier methods.
506  *
507  *	void bus_space_barrier(bus_space_tag_t tag,
508  *	    bus_space_handle_t bsh, bus_size_t offset,
509  *	    bus_size_t len, int flags);
510  *
511  * Note: the 680x0 does not currently require barriers, but we must
512  * provide the flags to MI code.
513  */
514 #define	bus_space_barrier(t, h, o, l, f)	\
515 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
516 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
517 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
518 
519 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
520 
521 #endif /* _NEXT68K_BUS_SPACE_H_ */
522