1 /* $NetBSD: bus_space.h,v 1.7 2001/05/12 22:35:29 chs 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 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Copyright (C) 1997 Scott Reynolds. All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. The name of the author may not be used to endorse or promote products 52 * derived from this software without specific prior written permission 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 57 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 58 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 59 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 60 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 61 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 62 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 63 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 64 */ 65 66 #ifndef _NEXT68K_BUS_SPACE_H_ 67 #define _NEXT68K_BUS_SPACE_H_ 68 /* 69 * Addresses (in bus space). 70 */ 71 typedef u_long bus_addr_t; 72 typedef u_long bus_size_t; 73 74 /* 75 * Access methods for bus resources and address space. 76 */ 77 typedef volatile char * bus_space_tag_t; 78 typedef u_long bus_space_handle_t; 79 80 /* 81 * Value for the next68k bus space tag, not to be used directly by MI code. 82 */ 83 #define NEXT68K_INTIO_BUS_SPACE intiobase 84 85 /* 86 * Values for the next68k video bus space tags, not to be used directly 87 * by MI code. 88 */ 89 #define NEXT68K_MONO_VIDEO_BUS_SPACE monobase 90 #define NEXT68K_COLOR_VIDEO_BUS_SPACE colorbase 91 92 /* 93 * Mapping and unmapping operations. 94 */ 95 #define bus_space_map(t, a, s, f, hp) \ 96 ((((a)>=INTIOBASE)&&((a)+(s)<INTIOTOP)) ? \ 97 ((*(hp)=(bus_space_handle_t)((t)+((a)-INTIOBASE))),0) : \ 98 ((((a)>=MONOBASE)&&((a)+(s)<MONOTOP)) ? \ 99 ((*(hp)=(bus_space_handle_t)((t)+((a)-MONOBASE))),0) : \ 100 ((((a)>=COLORBASE)&&((a)+(s)<COLORTOP)) ? \ 101 ((*(hp)=(bus_space_handle_t)((t)+((a)-COLORBASE))),0) : (-1)))) 102 103 #define bus_space_unmap(t, h, s) 104 105 #define bus_space_subregion(t, h, o, s, hp) \ 106 (*(hp)=(h)+(o)) 107 108 #define BUS_SPACE_MAP_CACHEABLE 0x01 109 #define BUS_SPACE_MAP_LINEAR 0x02 110 111 /* 112 * Allocation and deallocation operations. 113 */ 114 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \ 115 (-1) 116 117 #define bus_space_free(t, h, s) 118 119 /* 120 * u_intN_t bus_space_read_N __P((bus_space_tag_t tag, 121 * bus_space_handle_t bsh, bus_size_t offset)); 122 * 123 * Read a 1, 2, 4, or 8 byte quantity from bus space 124 * described by tag/handle/offset. 125 */ 126 127 #define bus_space_read_1(t, h, o) \ 128 ((void) t, (*(volatile u_int8_t *)((h) + (o)))) 129 130 #define bus_space_read_2(t, h, o) \ 131 ((void) t, (*(volatile u_int16_t *)((h) + (o)))) 132 133 #define bus_space_read_4(t, h, o) \ 134 ((void) t, (*(volatile u_int32_t *)((h) + (o)))) 135 136 #if 0 /* Cause a link error for bus_space_read_8 */ 137 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! 138 #endif 139 140 /* 141 * void bus_space_read_multi_N __P((bus_space_tag_t tag, 142 * bus_space_handle_t bsh, bus_size_t offset, 143 * u_intN_t *addr, size_t count)); 144 * 145 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 146 * described by tag/handle/offset and copy into buffer provided. 147 */ 148 149 #define bus_space_read_multi_1(t, h, o, a, c) do { \ 150 (void) t; \ 151 __asm __volatile (" \ 152 movl %0,%%a0 ; \ 153 movl %1,%%a1 ; \ 154 movl %2,%%d0 ; \ 155 1: movb %%a0@,%%a1@+ ; \ 156 subql #1,%%d0 ; \ 157 jne 1b" : \ 158 : \ 159 "r" ((h) + (o)), "g" (a), "g" (c) : \ 160 "a0","a1","d0"); \ 161 } while (0); 162 163 #define bus_space_read_multi_2(t, h, o, a, c) do { \ 164 (void) t; \ 165 __asm __volatile (" \ 166 movl %0,%%a0 ; \ 167 movl %1,%%a1 ; \ 168 movl %2,%%d0 ; \ 169 1: movw %%a0@,%%a1@+ ; \ 170 subql #1,%%d0 ; \ 171 jne 1b" : \ 172 : \ 173 "r" ((h) + (o)), "g" (a), "g" (c) : \ 174 "a0","a1","d0"); \ 175 } while (0); 176 177 #define bus_space_read_multi_4(t, h, o, a, c) do { \ 178 (void) t; \ 179 __asm __volatile (" \ 180 movl %0,%%a0 ; \ 181 movl %1,%%a1 ; \ 182 movl %2,%%d0 ; \ 183 1: movl %%a0@,%%a1@+ ; \ 184 subql #1,%%d0 ; \ 185 jne 1b" : \ 186 : \ 187 "r" ((h) + (o)), "g" (a), "g" (c) : \ 188 "a0","a1","d0"); \ 189 } while (0); 190 191 #if 0 /* Cause a link error for bus_space_read_multi_8 */ 192 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! 193 #endif 194 195 /* 196 * void bus_space_read_region_N __P((bus_space_tag_t tag, 197 * bus_space_handle_t bsh, bus_size_t offset, 198 * u_intN_t *addr, size_t count)); 199 * 200 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 201 * described by tag/handle and starting at `offset' and copy into 202 * buffer provided. 203 */ 204 205 #define bus_space_read_region_1(t, h, o, a, c) do { \ 206 (void) t; \ 207 __asm __volatile (" \ 208 movl %0,%%a0 ; \ 209 movl %1,%%a1 ; \ 210 movl %2,%%d0 ; \ 211 1: movb %%a0@+,%%a1@+ ; \ 212 subql #1,%%d0 ; \ 213 jne 1b" : \ 214 : \ 215 "r" ((h) + (o)), "g" (a), "g" (c) : \ 216 "a0","a1","d0"); \ 217 } while (0); 218 219 #define bus_space_read_region_2(t, h, o, a, c) do { \ 220 (void) t; \ 221 __asm __volatile (" \ 222 movl %0,%%a0 ; \ 223 movl %1,%%a1 ; \ 224 movl %2,%%d0 ; \ 225 1: movw %%a0@+,%%a1@+ ; \ 226 subql #1,%%d0 ; \ 227 jne 1b" : \ 228 : \ 229 "r" ((h) + (o)), "g" (a), "g" (c) : \ 230 "a0","a1","d0"); \ 231 } while (0); 232 233 #define bus_space_read_region_4(t, h, o, a, c) do { \ 234 (void) t; \ 235 __asm __volatile (" \ 236 movl %0,%%a0 ; \ 237 movl %1,%%a1 ; \ 238 movl %2,%%d0 ; \ 239 1: movl %%a0@+,%%a1@+ ; \ 240 subql #1,%%d0 ; \ 241 jne 1b" : \ 242 : \ 243 "r" ((h) + (o)), "g" (a), "g" (c) : \ 244 "a0","a1","d0"); \ 245 } while (0); 246 247 #if 0 /* Cause a link error for bus_space_read_region_8 */ 248 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! 249 #endif 250 251 /* 252 * void bus_space_write_N __P((bus_space_tag_t tag, 253 * bus_space_handle_t bsh, bus_size_t offset, 254 * u_intN_t value)); 255 * 256 * Write the 1, 2, 4, or 8 byte value `value' to bus space 257 * described by tag/handle/offset. 258 */ 259 260 #define bus_space_write_1(t, h, o, v) \ 261 ((void) t, ((void)(*(volatile u_int8_t *)((h) + (o)) = (v)))) 262 263 #define bus_space_write_2(t, h, o, v) \ 264 ((void) t, ((void)(*(volatile u_int16_t *)((h) + (o)) = (v)))) 265 266 #define bus_space_write_4(t, h, o, v) \ 267 ((void) t, ((void)(*(volatile u_int32_t *)((h) + (o)) = (v)))) 268 269 #if 0 /* Cause a link error for bus_space_write_8 */ 270 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!! 271 #endif 272 273 /* 274 * void bus_space_write_multi_N __P((bus_space_tag_t tag, 275 * bus_space_handle_t bsh, bus_size_t offset, 276 * const u_intN_t *addr, size_t count)); 277 * 278 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 279 * provided to bus space described by tag/handle/offset. 280 */ 281 282 #define bus_space_write_multi_1(t, h, o, a, c) do { \ 283 (void) t; \ 284 __asm __volatile (" \ 285 movl %0,%%a0 ; \ 286 movl %1,%%a1 ; \ 287 movl %2,%%d0 ; \ 288 1: movb %%a1@+,%%a0@ ; \ 289 subql #1,%%d0 ; \ 290 jne 1b" : \ 291 : \ 292 "r" ((h) + (o)), "g" (a), "g" (c) : \ 293 "a0","a1","d0"); \ 294 } while (0); 295 296 #define bus_space_write_multi_2(t, h, o, a, c) do { \ 297 (void) t; \ 298 __asm __volatile (" \ 299 movl %0,%%a0 ; \ 300 movl %1,%%a1 ; \ 301 movl %2,%%d0 ; \ 302 1: movw %%a1@+,%%a0@ ; \ 303 subql #1,%%d0 ; \ 304 jne 1b" : \ 305 : \ 306 "r" ((h) + (o)), "g" (a), "g" (c) : \ 307 "a0","a1","d0"); \ 308 } while (0); 309 310 #define bus_space_write_multi_4(t, h, o, a, c) do { \ 311 (void) t; \ 312 __asm __volatile (" \ 313 movl %0,%%a0 ; \ 314 movl %1,%%a1 ; \ 315 movl %2,%%d0 ; \ 316 1: movl %%a1@+,%%a0@ ; \ 317 subql #1,%%d0 ; \ 318 jne 1b" : \ 319 : \ 320 "r" ((h) + (o)), "g" (a), "g" (c) : \ 321 "a0","a1","d0"); \ 322 } while (0); 323 324 #if 0 /* Cause a link error for bus_space_write_8 */ 325 #define bus_space_write_multi_8(t, h, o, a, c) \ 326 !!! bus_space_write_multi_8 unimplimented !!! 327 #endif 328 329 /* 330 * void bus_space_write_region_N __P((bus_space_tag_t tag, 331 * bus_space_handle_t bsh, bus_size_t offset, 332 * const u_intN_t *addr, size_t count)); 333 * 334 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 335 * to bus space described by tag/handle starting at `offset'. 336 */ 337 338 #define bus_space_write_region_1(t, h, o, a, c) do { \ 339 (void) t; \ 340 __asm __volatile (" \ 341 movl %0,%%a0 ; \ 342 movl %1,%%a1 ; \ 343 movl %2,%%d0 ; \ 344 1: movb %%a1@+,%%a0@+ ; \ 345 subql #1,%%d0 ; \ 346 jne 1b" : \ 347 : \ 348 "r" ((h) + (o)), "g" (a), "g" (c) : \ 349 "a0","a1","d0"); \ 350 } while (0); 351 352 #define bus_space_write_region_2(t, h, o, a, c) do { \ 353 (void) t; \ 354 __asm __volatile (" \ 355 movl %0,%%a0 ; \ 356 movl %1,%%a1 ; \ 357 movl %2,%%d0 ; \ 358 1: movw %%a1@+,%%a0@+ ; \ 359 subql #1,%%d0 ; \ 360 jne 1b" : \ 361 : \ 362 "r" ((h) + (o)), "g" (a), "g" (c) : \ 363 "a0","a1","d0"); \ 364 } while (0); 365 366 #define bus_space_write_region_4(t, h, o, a, c) do { \ 367 (void) t; \ 368 __asm __volatile (" \ 369 movl %0,%%a0 ; \ 370 movl %1,%%a1 ; \ 371 movl %2,%%d0 ; \ 372 1: movl %%a1@+,%%a0@+ ; \ 373 subql #1,%%d0 ; \ 374 jne 1b" : \ 375 : \ 376 "r" ((h) + (o)), "g" (a), "g" (c) : \ 377 "a0","a1","d0"); \ 378 } while (0); 379 380 #if 0 /* Cause a link error for bus_space_write_region_8 */ 381 #define bus_space_write_region_8 \ 382 !!! bus_space_write_region_8 unimplemented !!! 383 #endif 384 385 /* 386 * void bus_space_set_multi_N __P((bus_space_tag_t tag, 387 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 388 * size_t count)); 389 * 390 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 391 * by tag/handle/offset `count' times. 392 */ 393 394 #define bus_space_set_multi_1(t, h, o, val, c) do { \ 395 (void) t; \ 396 __asm __volatile (" \ 397 movl %0,%%a0 ; \ 398 movl %1,%%d1 ; \ 399 movl %2,%%d0 ; \ 400 1: movb %%d1,%%a0@ ; \ 401 subql #1,%%d0 ; \ 402 jne 1b" : \ 403 : \ 404 "r" ((h) + (o)), "g" (val), "g" (c) : \ 405 "a0","d0","d1"); \ 406 } while (0); 407 408 #define bus_space_set_multi_2(t, h, o, val, c) do { \ 409 (void) t; \ 410 __asm __volatile (" \ 411 movl %0,%%a0 ; \ 412 movl %1,%%d1 ; \ 413 movl %2,%%d0 ; \ 414 1: movw %%d1,%%a0@ ; \ 415 subql #1,%%d0 ; \ 416 jne 1b" : \ 417 : \ 418 "r" ((h) + (o)), "g" (val), "g" (c) : \ 419 "a0","d0","d1"); \ 420 } while (0); 421 422 #define bus_space_set_multi_4(t, h, o, val, c) do { \ 423 (void) t; \ 424 __asm __volatile (" \ 425 movl %0,%%a0 ; \ 426 movl %1,%%d1 ; \ 427 movl %2,%%d0 ; \ 428 1: movl %%d1,%%a0@ ; \ 429 subql #1,%%d0 ; \ 430 jne 1b" : \ 431 : \ 432 "r" ((h) + (o)), "g" (val), "g" (c) : \ 433 "a0","d0","d1"); \ 434 } while (0); 435 436 #if 0 /* Cause a link error for bus_space_set_multi_8 */ 437 #define bus_space_set_multi_8 \ 438 !!! bus_space_set_multi_8 unimplemented !!! 439 #endif 440 441 /* 442 * void bus_space_set_region_N __P((bus_space_tag_t tag, 443 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 444 * size_t count)); 445 * 446 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 447 * by tag/handle starting at `offset'. 448 */ 449 450 #define bus_space_set_region_1(t, h, o, val, c) do { \ 451 (void) t; \ 452 __asm __volatile (" \ 453 movl %0,%%a0 ; \ 454 movl %1,%%d1 ; \ 455 movl %2,%%d0 ; \ 456 1: movb %%d1,%%a0@+ ; \ 457 subql #1,%%d0 ; \ 458 jne 1b" : \ 459 : \ 460 "r" ((h) + (o)), "g" (val), "g" (c) : \ 461 "a0","d0","d1"); \ 462 } while (0); 463 464 #define bus_space_set_region_2(t, h, o, val, c) do { \ 465 (void) t; \ 466 __asm __volatile (" \ 467 movl %0,%%a0 ; \ 468 movl %1,%%d1 ; \ 469 movl %2,%%d0 ; \ 470 1: movw %%d1,%%a0@+ ; \ 471 subql #1,%%d0 ; \ 472 jne 1b" : \ 473 : \ 474 "r" ((h) + (o)), "g" (val), "g" (c) : \ 475 "a0","d0","d1"); \ 476 } while (0); 477 478 #define bus_space_set_region_4(t, h, o, val, c) do { \ 479 (void) t; \ 480 __asm __volatile (" \ 481 movl %0,%%a0 ; \ 482 movl %1,%%d1 ; \ 483 movl %2,%%d0 ; \ 484 1: movl %%d1,%%a0@+ ; \ 485 subql #1,%%d0 ; \ 486 jne 1b" : \ 487 : \ 488 "r" ((h) + (o)), "g" (val), "g" (c) : \ 489 "a0","d0","d1"); \ 490 } while (0); 491 492 #if 0 /* Cause a link error for bus_space_set_region_8 */ 493 #define bus_space_set_region_8 \ 494 !!! bus_space_set_region_8 unimplemented !!! 495 #endif 496 497 /* 498 * void bus_space_copy_N __P((bus_space_tag_t tag, 499 * bus_space_handle_t bsh1, bus_size_t off1, 500 * bus_space_handle_t bsh2, bus_size_t off2, 501 * size_t count)); 502 * 503 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 504 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 505 */ 506 507 #define __NEXT68K_copy_region_N(BYTES) \ 508 static __inline void __CONCAT(bus_space_copy_region_,BYTES) \ 509 __P((bus_space_tag_t, \ 510 bus_space_handle_t bsh1, bus_size_t off1, \ 511 bus_space_handle_t bsh2, bus_size_t off2, \ 512 bus_size_t count)); \ 513 \ 514 static __inline void \ 515 __CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c) \ 516 bus_space_tag_t t; \ 517 bus_space_handle_t h1, h2; \ 518 bus_size_t o1, o2, c; \ 519 { \ 520 bus_size_t o; \ 521 \ 522 if ((h1 + o1) >= (h2 + o2)) { \ 523 /* src after dest: copy forward */ \ 524 for (o = 0; c != 0; c--, o += BYTES) \ 525 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 526 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 527 } else { \ 528 /* dest after src: copy backwards */ \ 529 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 530 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 531 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 532 } \ 533 } 534 __NEXT68K_copy_region_N(1) 535 __NEXT68K_copy_region_N(2) 536 __NEXT68K_copy_region_N(4) 537 #if 0 /* Cause a link error for bus_space_copy_8 */ 538 #define bus_space_copy_8 \ 539 !!! bus_space_copy_8 unimplemented !!! 540 #endif 541 542 #undef __NEXT68K_copy_region_N 543 544 /* 545 * Bus read/write barrier methods. 546 * 547 * void bus_space_barrier __P((bus_space_tag_t tag, 548 * bus_space_handle_t bsh, bus_size_t offset, 549 * bus_size_t len, int flags)); 550 * 551 * Note: the 680x0 does not currently require barriers, but we must 552 * provide the flags to MI code. 553 */ 554 #define bus_space_barrier(t, h, o, l, f) \ 555 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 556 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 557 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 558 559 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 560 561 #endif /* _NEXT68K_BUS_SPACE_H_ */ 562