Home | History | Annotate | Line # | Download | only in include
      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