xref: /openbsd/sys/arch/luna88k/include/bus.h (revision 8932bfb7)
1 /*	$OpenBSD: bus.h,v 1.8 2011/03/23 16:54:35 pirofti Exp $	*/
2 /*	$NetBSD: bus.h,v 1.9 1998/01/13 18:32:15 scottr Exp $	*/
3 
4 /*-
5  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10  * NASA Ames Research Center.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * Copyright (C) 1997 Scott Reynolds.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. The name of the author may not be used to endorse or promote products
46  *    derived from this software without specific prior written permission
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
49  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
50  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
51  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
52  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
54  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
55  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
56  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
57  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58  */
59 
60 #ifndef _MACHINE_BUS_H_
61 #define _MACHINE_BUS_H_
62 
63 /*
64  * Bus address and size types
65  */
66 typedef u_long bus_addr_t;
67 typedef u_long bus_size_t;
68 
69 /*
70  * Access methods for bus resources and address space.
71  */
72 typedef u_long bus_space_handle_t;
73 typedef struct luna88k_bus_space_tag *bus_space_tag_t;
74 
75 struct luna88k_bus_space_tag {
76 	/* 'stride' for each bytes reading/writing */
77 	uint8_t	bs_stride_1;
78 	uint8_t	bs_stride_2;
79 	uint8_t bs_stride_4;
80 	uint8_t	bs_stride_8;
81 };
82 
83 /*
84  *	int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
85  *	    bus_size_t size, int flags, bus_space_handle_t *bshp);
86  *
87  * Map a region of bus space.
88  */
89 
90 #define	BUS_SPACE_MAP_CACHEABLE		0x01
91 #define	BUS_SPACE_MAP_LINEAR		0x02
92 
93 int	bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t,
94 	    int, bus_space_handle_t *);
95 
96 /*
97  *	void bus_space_unmap(bus_space_tag_t t,
98  *	    bus_space_handle_t bsh, bus_size_t size);
99  *
100  * Unmap a region of bus space.
101  */
102 
103 void	bus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
104 
105 /*
106  *	int bus_space_subregion(bus_space_tag_t t,
107  *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
108  *	    bus_space_handle_t *nbshp);
109  *
110  * Get a new handle for a subregion of an already-mapped area of bus space.
111  */
112 
113 int	bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
114 	    bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
115 
116 /*
117  *	int bus_space_alloc(bus_space_tag_t t, bus_addr_t, rstart,
118  *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
119  *	    bus_size_t boundary, int flags, bus_addr_t *addrp,
120  *	    bus_space_handle_t *bshp);
121  *
122  * Allocate a region of bus space.
123  */
124 
125 int	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
126 	    bus_addr_t rend, bus_size_t size, bus_size_t align,
127 	    bus_size_t boundary, int flags, bus_addr_t *addrp,
128 	    bus_space_handle_t *bshp);
129 
130 /*
131  *	int bus_space_free(bus_space_tag_t t,
132  *	    bus_space_handle_t bsh, bus_size_t size);
133  *
134  * Free a region of bus space.
135  */
136 
137 void	bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
138 	    bus_size_t size);
139 
140 /*
141  *	u_intN_t bus_space_read_N(bus_space_tag_t tag,
142  *	    bus_space_handle_t bsh, bus_size_t offset);
143  *
144  * Read a 1, 2, 4, or 8 byte quantity from bus space
145  * described by tag/handle/offset.
146  */
147 
148 #define	bus_space_read_1(t, h, o)					\
149     (*(volatile u_int8_t *)((h) + (t->bs_stride_1) * (o)))
150 
151 #define	bus_space_read_2(t, h, o)					\
152     (*(volatile u_int16_t *)((h) + (t->bs_stride_2) * (o)))
153 
154 #define	bus_space_read_4(t, h, o)					\
155     (*(volatile u_int32_t *)((h) + (t->bs_stride_4) * (o)))
156 
157 #if 0	/* Cause a link error for bus_space_read_8 */
158 #define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
159 #endif
160 
161 /*
162  *	void bus_space_read_multi_N(bus_space_tag_t tag,
163  *	    bus_space_handle_t bsh, bus_size_t offset,
164  *	    u_intN_t *addr, size_t count);
165  *
166  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
167  * described by tag/handle/offset and copy into buffer provided.
168  */
169 
170 static __inline__ void
171 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t handle,
172     bus_addr_t offset, u_int8_t *dest, size_t count)
173 {
174 	while ((int)--count >= 0)
175 		*dest++ = bus_space_read_1(tag, handle, offset);
176 }
177 
178 static __inline__ void
179 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
180     bus_addr_t offset, u_int16_t *dest, size_t count)
181 {
182 	while ((int)--count >= 0)
183 		*dest++ = bus_space_read_2(tag, handle, offset);
184 }
185 
186 static __inline__ void
187 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
188     bus_addr_t offset, u_int32_t *dest, size_t count)
189 {
190 	while ((int)--count >= 0)
191 		*dest++ = bus_space_read_4(tag, handle, offset);
192 }
193 
194 #if 0	/* Cause a link error for bus_space_read_multi_8 */
195 #define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
196 #endif
197 
198 /*
199  *	void bus_space_read_region_N(bus_space_tag_t tag,
200  *	    bus_space_handle_t bsh, bus_size_t offset,
201  *	    u_intN_t *addr, size_t count);
202  *
203  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
204  * described by tag/handle and starting at `offset' and copy into
205  * buffer provided.
206  */
207 
208 static __inline__ void
209 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t handle,
210     bus_addr_t offset, u_int8_t *dest, size_t count)
211 {
212 	while ((int)--count >= 0)
213 		*dest++ = bus_space_read_1(tag, handle, offset++);
214 }
215 
216 static __inline__ void
217 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
218     bus_addr_t offset, u_int16_t *dest, size_t count)
219 {
220 	while ((int)--count >= 0) {
221 		*dest++ = bus_space_read_2(tag, handle, offset);
222 		offset += 2;
223 	}
224 }
225 
226 static __inline__ void
227 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
228     bus_addr_t offset, u_int32_t *dest, size_t count)
229 {
230 	while ((int)--count >= 0) {
231 		*dest++ = bus_space_read_4(tag, handle, offset);
232 		offset += 4;
233 	}
234 }
235 
236 #if 0	/* Cause a link error for bus_space_read_region_8 */
237 #define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
238 #endif
239 
240 /*
241  *	void bus_space_write_N(bus_space_tag_t tag,
242  *	    bus_space_handle_t bsh, bus_size_t offset,
243  *	    u_intN_t value);
244  *
245  * Write the 1, 2, 4, or 8 byte value `value' to bus space
246  * described by tag/handle/offset.
247  */
248 
249 #define	bus_space_write_1(t, h, o, v)					\
250     ((void)(*(volatile u_int8_t *)((h) + (t->bs_stride_1) * (o)) = (v)))
251 
252 #define	bus_space_write_2(t, h, o, v)					\
253     ((void)(*(volatile u_int16_t *)((h) + (t->bs_stride_2) * (o)) = (v)))
254 
255 #define	bus_space_write_4(t, h, o, v)					\
256     ((void)(*(volatile u_int32_t *)((h) + (t->bs_stride_4) * (o)) = (v)))
257 
258 #if 0	/* Cause a link error for bus_space_write_8 */
259 #define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
260 #endif
261 
262 /*
263  *	void bus_space_write_multi_N(bus_space_tag_t tag,
264  *	    bus_space_handle_t bsh, bus_size_t offset,
265  *	    const u_intN_t *addr, size_t count);
266  *
267  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
268  * provided to bus space described by tag/handle/offset.
269  */
270 
271 static __inline__ void
272 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t handle,
273     bus_addr_t offset, u_int8_t *dest, size_t count)
274 {
275 	while ((int)--count >= 0)
276 		bus_space_write_1(tag, handle, offset, *dest++);
277 }
278 
279 static __inline__ void
280 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
281     bus_addr_t offset, u_int16_t *dest, size_t count)
282 {
283 	while ((int)--count >= 0)
284 		bus_space_write_2(tag, handle, offset, *dest++);
285 }
286 
287 static __inline__ void
288 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
289     bus_addr_t offset, u_int32_t *dest, size_t count)
290 {
291 	while ((int)--count >= 0)
292 		bus_space_write_4(tag, handle, offset, *dest++);
293 }
294 
295 #if 0	/* Cause a link error for bus_space_write_8 */
296 #define	bus_space_write_multi_8(t, h, o, a, c)				\
297 			!!! bus_space_write_multi_8 unimplemented !!!
298 #endif
299 
300 /*
301  *	void bus_space_write_region_N(bus_space_tag_t tag,
302  *	    bus_space_handle_t bsh, bus_size_t offset,
303  *	    const u_intN_t *addr, size_t count);
304  *
305  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
306  * to bus space described by tag/handle starting at `offset'.
307  */
308 
309 static __inline__ void
310 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t handle,
311     bus_addr_t offset, u_int8_t *dest, size_t count)
312 {
313 	while ((int)--count >= 0)
314 		bus_space_write_1(tag, handle, offset++, *dest++);
315 }
316 
317 static __inline__ void
318 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
319     bus_addr_t offset, u_int16_t *dest, size_t count)
320 {
321 	while ((int)--count >= 0) {
322 		bus_space_write_2(tag, handle, offset, *dest++);
323 		offset += 2;
324 	}
325 }
326 
327 static __inline__ void
328 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
329     bus_addr_t offset, u_int32_t *dest, size_t count)
330 {
331 	while ((int)--count >= 0) {
332 		bus_space_write_4(tag, handle, offset, *dest++);
333 		offset += 4;
334 	}
335 }
336 
337 #if 0	/* Cause a link error for bus_space_write_region_8 */
338 #define	bus_space_write_region_8					\
339 			!!! bus_space_write_region_8 unimplemented !!!
340 #endif
341 
342 /*
343  *	void bus_space_set_multi_N(bus_space_tag_t tag,
344  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
345  *	    size_t count);
346  *
347  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
348  * by tag/handle/offset `count' times.
349  */
350 
351 static __inline__ void
352 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t handle,
353     bus_addr_t offset, u_int8_t value, size_t count)
354 {
355 	while ((int)--count >= 0)
356 		bus_space_write_1(tag, handle, offset, value);
357 }
358 
359 static __inline__ void
360 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
361     bus_addr_t offset, u_int16_t value, size_t count)
362 {
363 	while ((int)--count >= 0)
364 		bus_space_write_2(tag, handle, offset, value);
365 }
366 
367 static __inline__ void
368 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
369     bus_addr_t offset, u_int32_t value, size_t count)
370 {
371 	while ((int)--count >= 0)
372 		bus_space_write_4(tag, handle, offset, value);
373 }
374 
375 #if 0	/* Cause a link error for bus_space_set_multi_8 */
376 #define	bus_space_set_multi_8						\
377 			!!! bus_space_set_multi_8 unimplemented !!!
378 #endif
379 
380 /*
381  *	void bus_space_set_region_N(bus_space_tag_t tag,
382  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
383  *	    size_t count);
384  *
385  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
386  * by tag/handle starting at `offset'.
387  */
388 
389 static __inline__ void
390 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t handle,
391     bus_addr_t offset, u_int8_t value, size_t count)
392 {
393 	while ((int)--count >= 0)
394 		bus_space_write_1(tag, handle, offset++, value);
395 }
396 
397 static __inline__ void
398 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
399     bus_addr_t offset, u_int16_t value, size_t count)
400 {
401 	while ((int)--count >= 0) {
402 		bus_space_write_2(tag, handle, offset, value);
403 		offset += 2;
404 	}
405 }
406 
407 static __inline__ void
408 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
409     bus_addr_t offset, u_int32_t value, size_t count)
410 {
411 	while ((int)--count >= 0) {
412 		bus_space_write_4(tag, handle, offset, value);
413 		offset += 4;
414 	}
415 }
416 
417 #if 0	/* Cause a link error for bus_space_set_region_8 */
418 #define	bus_space_set_region_8						\
419 			!!! bus_space_set_region_8 unimplemented !!!
420 #endif
421 
422 /*
423  *	void bus_space_copy_N(bus_space_tag_t tag,
424  *	    bus_space_handle_t bsh1, bus_size_t off1,
425  *	    bus_space_handle_t bsh2, bus_size_t off2,
426  *	    size_t count);
427  *
428  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
429  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
430  */
431 
432 #define	__LUNA88K_copy_N(BYTES)					\
433 static __inline void __CONCAT(bus_space_copy_,BYTES)		\
434 	    (bus_space_tag_t,						\
435 	    bus_space_handle_t bsh1, bus_size_t off1,			\
436 	    bus_space_handle_t bsh2, bus_size_t off2,			\
437 	    bus_size_t count);						\
438 									\
439 static __inline void							\
440 __CONCAT(bus_space_copy_,BYTES)(t, h1, o1, h2, o2, c)		\
441 	bus_space_tag_t t;						\
442 	bus_space_handle_t h1, h2;					\
443 	bus_size_t o1, o2, c;						\
444 {									\
445 	bus_size_t o;							\
446 									\
447 	if ((h1 + o1) >= (h2 + o2)) {					\
448 		/* src after dest: copy forward */			\
449 		for (o = 0; c != 0; c--, o += BYTES)			\
450 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
451 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
452 	} else {							\
453 		/* dest after src: copy backwards */			\
454 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
455 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
456 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
457 	}								\
458 }
459 __LUNA88K_copy_N(1)
460 __LUNA88K_copy_N(2)
461 __LUNA88K_copy_N(4)
462 #if 0	/* Cause a link error for bus_space_copy_8 */
463 #define	bus_space_copy_8						\
464 			!!! bus_space_copy_8 unimplemented !!!
465 #endif
466 
467 #undef __LUNA88K_copy_N
468 
469 /*
470  * Bus read/write barrier methods.
471  *
472  *	void bus_space_barrier(bus_space_tag_t tag,
473  *	    bus_space_handle_t bsh, bus_size_t offset,
474  *	    bus_size_t len, int flags);
475  *
476  */
477 #define	bus_space_barrier(t, h, o, l, f)	\
478 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
479 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
480 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
481 
482 #endif /* _MACHINE_BUS_H_ */
483