1 /* $NetBSD: bus_space.h,v 1.7 2000/11/29 09:18:32 scw 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 /* 67 * Lifted from the Next68k port. 68 * Modified for mvme68k by Steve Woodford. 69 * 70 * TODO: Support for VMEbus... 71 * (Do any existing VME card drivers use bus_space_* ?) 72 */ 73 74 #ifndef _MVME68K_BUS_SPACE_H_ 75 #define _MVME68K_BUS_SPACE_H_ 76 77 /* 78 * Addresses (in bus space). 79 */ 80 typedef u_long bus_addr_t; 81 typedef u_long bus_size_t; 82 83 /* 84 * Access methods for bus resources and address space. 85 */ 86 struct mvme68k_bus_space_tag; 87 typedef struct mvme68k_bus_space_tag *bus_space_tag_t; 88 typedef u_long bus_space_handle_t; 89 90 struct mvme68k_bus_space_tag { 91 void *bs_cookie; 92 int (*bs_map)(void *, bus_addr_t, bus_size_t, 93 int, bus_space_handle_t *); 94 void (*bs_unmap)(void *, bus_space_handle_t, bus_size_t); 95 int (*bs_peek_1)(void *, bus_space_handle_t, 96 bus_size_t, u_int8_t *); 97 int (*bs_peek_2)(void *, bus_space_handle_t, 98 bus_size_t, u_int16_t *); 99 int (*bs_peek_4)(void *, bus_space_handle_t, 100 bus_size_t, u_int32_t *); 101 #if 0 102 int (*bs_peek_8)(void *, bus_space_handle_t, 103 bus_size_t, u_int64_t *); 104 #endif 105 int (*bs_poke_1)(void *, bus_space_handle_t, 106 bus_size_t, u_int8_t); 107 int (*bs_poke_2)(void *, bus_space_handle_t, 108 bus_size_t, u_int16_t); 109 int (*bs_poke_4)(void *, bus_space_handle_t, 110 bus_size_t, u_int32_t); 111 #if 0 112 int (*bs_poke_8)(void *, bus_space_handle_t, 113 bus_size_t, u_int64_t); 114 #endif 115 }; 116 117 /* 118 * int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 119 * bus_size_t size, int flags, 120 * bus_space_handle_t *bshp); 121 * 122 * Map a region of bus space. 123 */ 124 #define bus_space_map(tag, offset, size, flags, handlep) \ 125 (*((tag)->bs_map))((tag)->bs_cookie, (offset), (size), (flags), (handlep)) 126 127 /* 128 * Possible values for the 'flags' parameter of bus_space_map() 129 */ 130 #define BUS_SPACE_MAP_CACHEABLE 0x01 131 #define BUS_SPACE_MAP_LINEAR 0x02 132 #define BUS_SPACE_MAP_PREFETCHABLE 0x04 133 134 /* 135 * void bus_space_unmap(bus_space_tag_t t, 136 * bus_space_handle_t bsh, bus_size_t size); 137 * 138 * Unmap a region of bus space. 139 */ 140 #define bus_space_unmap(tag, handle, size) \ 141 (*((tag)->bs_unmap))((tag)->bs_cookie, (handle), (size)) 142 143 /* 144 * int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h 145 * bus_addr_t offset, bus_size_t size, bus_space_handle_t *newh); 146 * 147 * Allocate a sub-region of an existing map 148 */ 149 #define bus_space_subregion(t, h, o, s, hp) \ 150 ((*(hp)=(h)+(o)), 0) 151 152 /* 153 * Allocation and deallocation operations. 154 */ 155 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \ 156 (-1) 157 158 #define bus_space_free(t, h, s) 159 160 /* 161 * int bus_space_peek_N(bus_space_tag_t tag, 162 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t *valuep); 163 * 164 * Cautiously read 1, 2, 4 or 8 byte quantity from bus space described 165 * by tag/handle/offset. 166 * If no hardware responds to the read access, the function returns a 167 * non-zero value. Otherwise the value read is placed in `valuep'. 168 */ 169 #define bus_space_peek_1(t, h, o, vp) \ 170 (*((t)->bs_peek_1))((t)->bs_cookie, (h), (o), (vp)) 171 172 #define bus_space_peek_2(t, h, o, vp) \ 173 (*((t)->bs_peek_2))((t)->bs_cookie, (h), (o), (vp)) 174 175 #define bus_space_peek_4(t, h, o, vp) \ 176 (*((t)->bs_peek_4))((t)->bs_cookie, (h), (o), (vp)) 177 178 #if 0 /* Cause a link error for bus_space_peek_8 */ 179 #define bus_space_peek_8(t, h, o, vp) \ 180 (*((t)->bs_peek_8))((t)->bs_cookie, (h), (o), (vp)) 181 #endif 182 183 /* 184 * int bus_space_poke_N(bus_space_tag_t tag, 185 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t value); 186 * 187 * Cautiously write 1, 2, 4 or 8 byte quantity to bus space described 188 * by tag/handle/offset. 189 * If no hardware responds to the write access, the function returns a 190 * non-zero value. 191 */ 192 #define bus_space_poke_1(t, h, o, v) \ 193 (*((t)->bs_poke_1))((t)->bs_cookie, (h), (o), (v)) 194 195 #define bus_space_poke_2(t, h, o, v) \ 196 (*((t)->bs_poke_2))((t)->bs_cookie, (h), (o), (v)) 197 198 #define bus_space_poke_4(t, h, o, v) \ 199 (*((t)->bs_poke_4))((t)->bs_cookie, (h), (o), (v)) 200 201 #if 0 /* Cause a link error for bus_space_poke_8 */ 202 #define bus_space_poke_8(t, h, o, v) \ 203 (*((t)->bs_poke_8))((t)->bs_cookie, (h), (o), (v)) 204 #endif 205 206 /* 207 * u_intN_t bus_space_read_N(bus_space_tag_t tag, 208 * bus_space_handle_t bsh, bus_size_t offset); 209 * 210 * Read a 1, 2, 4, or 8 byte quantity from bus space 211 * described by tag/handle/offset. 212 */ 213 static __inline u_int8_t 214 bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) 215 { 216 u_int8_t rv; 217 218 __asm __volatile("movb %1,%0" : "=dm" (rv) : 219 "g" (*((u_int8_t *)(h + o)))); 220 221 return (rv); 222 } 223 224 static __inline u_int16_t 225 bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) 226 { 227 u_int16_t rv; 228 229 __asm __volatile("movw %1,%0" : "=dm" (rv) : 230 "g" (*((u_int16_t *)(h + o)))); 231 232 return (rv); 233 } 234 235 static __inline u_int32_t 236 bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) 237 { 238 u_int32_t rv; 239 240 __asm __volatile("movl %1,%0" : "=rm" (rv) : 241 "g" (*((u_int32_t *)(h + o)))); 242 243 return (rv); 244 } 245 246 /* 247 * void bus_space_read_multi_N(bus_space_tag_t tag, 248 * bus_space_handle_t bsh, bus_size_t offset, 249 * u_intN_t *addr, size_t count); 250 * 251 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 252 * described by tag/handle/offset and copy into buffer provided. 253 */ 254 255 #define bus_space_read_multi_1(t, h, o, a, c) do { \ 256 (void) t; \ 257 __asm __volatile (" \ 258 movl %0,%%a0 ; \ 259 movl %1,%%a1 ; \ 260 movl %2,%%d0 ; \ 261 1: movb %%a0@,%%a1@+ ; \ 262 subql #1,%%d0 ; \ 263 jne 1b" : \ 264 : \ 265 "r" ((h) + (o)), "g" (a), "g" (c) : \ 266 "a0","a1","d0"); \ 267 } while (0); 268 269 #define bus_space_read_multi_2(t, h, o, a, c) do { \ 270 (void) t; \ 271 __asm __volatile (" \ 272 movl %0,%%a0 ; \ 273 movl %1,%%a1 ; \ 274 movl %2,%%d0 ; \ 275 1: movw %%a0@,%%a1@+ ; \ 276 subql #1,%%d0 ; \ 277 jne 1b" : \ 278 : \ 279 "r" ((h) + (o)), "g" (a), "g" (c) : \ 280 "a0","a1","d0"); \ 281 } while (0); 282 283 #define bus_space_read_multi_4(t, h, o, a, c) do { \ 284 (void) t; \ 285 __asm __volatile (" \ 286 movl %0,%%a0 ; \ 287 movl %1,%%a1 ; \ 288 movl %2,%%d0 ; \ 289 1: movl %%a0@,%%a1@+ ; \ 290 subql #1,%%d0 ; \ 291 jne 1b" : \ 292 : \ 293 "r" ((h) + (o)), "g" (a), "g" (c) : \ 294 "a0","a1","d0"); \ 295 } while (0); 296 297 #if 0 /* Cause a link error for bus_space_read_multi_8 */ 298 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! 299 #endif 300 301 /* 302 * void bus_space_read_region_N(bus_space_tag_t tag, 303 * bus_space_handle_t bsh, bus_size_t offset, 304 * u_intN_t *addr, size_t count); 305 * 306 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 307 * described by tag/handle and starting at `offset' and copy into 308 * buffer provided. 309 */ 310 311 #define bus_space_read_region_1(t, h, o, a, c) do { \ 312 (void) t; \ 313 __asm __volatile (" \ 314 movl %0,%%a0 ; \ 315 movl %1,%%a1 ; \ 316 movl %2,%%d0 ; \ 317 1: movb %%a0@+,%%a1@+ ; \ 318 subql #1,%%d0 ; \ 319 jne 1b" : \ 320 : \ 321 "r" ((h) + (o)), "g" (a), "g" (c) : \ 322 "a0","a1","d0"); \ 323 } while (0); 324 325 #define bus_space_read_region_2(t, h, o, a, c) do { \ 326 (void) t; \ 327 __asm __volatile (" \ 328 movl %0,%%a0 ; \ 329 movl %1,%%a1 ; \ 330 movl %2,%%d0 ; \ 331 1: movw %%a0@+,%%a1@+ ; \ 332 subql #1,%%d0 ; \ 333 jne 1b" : \ 334 : \ 335 "r" ((h) + (o)), "g" (a), "g" (c) : \ 336 "a0","a1","d0"); \ 337 } while (0); 338 339 #define bus_space_read_region_4(t, h, o, a, c) do { \ 340 (void) t; \ 341 __asm __volatile (" \ 342 movl %0,%%a0 ; \ 343 movl %1,%%a1 ; \ 344 movl %2,%%d0 ; \ 345 1: movl %%a0@+,%%a1@+ ; \ 346 subql #1,%%d0 ; \ 347 jne 1b" : \ 348 : \ 349 "r" ((h) + (o)), "g" (a), "g" (c) : \ 350 "a0","a1","d0"); \ 351 } while (0); 352 353 #if 0 /* Cause a link error for bus_space_read_region_8 */ 354 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! 355 #endif 356 357 /* 358 * void bus_space_write_N(bus_space_tag_t tag, 359 * bus_space_handle_t bsh, bus_size_t offset, 360 * u_intN_t value); 361 * 362 * Write the 1, 2, 4, or 8 byte value `value' to bus space 363 * described by tag/handle/offset. 364 */ 365 static __inline void 366 bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, 367 bus_size_t o, u_int8_t v) 368 { 369 __asm __volatile("movb %0,%1" :: 370 "dim" (v), "g" (*((u_int8_t *)(h + o)))); 371 } 372 373 static __inline void 374 bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, 375 bus_size_t o, u_int16_t v) 376 { 377 __asm __volatile("movw %0,%1" :: 378 "dim" (v), "g" (*((u_int16_t *)(h + o)))); 379 } 380 381 static __inline void 382 bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, 383 bus_size_t o, u_int32_t v) 384 { 385 __asm __volatile("movl %0,%1" :: 386 "g" (v), "g" (*((u_int32_t *)(h + o)))); 387 } 388 389 /* 390 * void bus_space_write_multi_N(bus_space_tag_t tag, 391 * bus_space_handle_t bsh, bus_size_t offset, 392 * const u_intN_t *addr, size_t count); 393 * 394 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 395 * provided to bus space described by tag/handle/offset. 396 */ 397 398 #define bus_space_write_multi_1(t, h, o, a, c) do { \ 399 (void) t; \ 400 __asm __volatile (" \ 401 movl %0,%%a0 ; \ 402 movl %1,%%a1 ; \ 403 movl %2,%%d0 ; \ 404 1: movb %%a1@+,%%a0@ ; \ 405 subql #1,%%d0 ; \ 406 jne 1b" : \ 407 : \ 408 "r" ((h) + (o)), "g" (a), "g" (c) : \ 409 "a0","a1","d0"); \ 410 } while (0); 411 412 #define bus_space_write_multi_2(t, h, o, a, c) do { \ 413 (void) t; \ 414 __asm __volatile (" \ 415 movl %0,%%a0 ; \ 416 movl %1,%%a1 ; \ 417 movl %2,%%d0 ; \ 418 1: movw %%a1@+,%%a0@ ; \ 419 subql #1,%%d0 ; \ 420 jne 1b" : \ 421 : \ 422 "r" ((h) + (o)), "g" (a), "g" (c) : \ 423 "a0","a1","d0"); \ 424 } while (0); 425 426 #define bus_space_write_multi_4(t, h, o, a, c) do { \ 427 (void) t; \ 428 __asm __volatile (" \ 429 movl %0,%%a0 ; \ 430 movl %1,%%a1 ; \ 431 movl %2,%%d0 ; \ 432 1: movl a1@+,%%a0@ ; \ 433 subql #1,%%d0 ; \ 434 jne 1b" : \ 435 : \ 436 "r" ((h) + (o)), "g" (a), "g" (c) : \ 437 "a0","a1","d0"); \ 438 } while (0); 439 440 #if 0 /* Cause a link error for bus_space_write_8 */ 441 #define bus_space_write_multi_8(t, h, o, a, c) \ 442 !!! bus_space_write_multi_8 unimplimented !!! 443 #endif 444 445 /* 446 * void bus_space_write_region_N(bus_space_tag_t tag, 447 * bus_space_handle_t bsh, bus_size_t offset, 448 * const u_intN_t *addr, size_t count); 449 * 450 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 451 * to bus space described by tag/handle starting at `offset'. 452 */ 453 454 #define bus_space_write_region_1(t, h, o, a, c) do { \ 455 (void) t; \ 456 __asm __volatile (" \ 457 movl %0,%%a0 ; \ 458 movl %1,%%a1 ; \ 459 movl %2,%%d0 ; \ 460 1: movb %%a1@+,%%a0@+ ; \ 461 subql #1,%%d0 ; \ 462 jne 1b" : \ 463 : \ 464 "r" ((h) + (o)), "g" (a), "g" (c) : \ 465 "a0","a1","d0"); \ 466 } while (0); 467 468 #define bus_space_write_region_2(t, h, o, a, c) do { \ 469 (void) t; \ 470 __asm __volatile (" \ 471 movl %0,%%a0 ; \ 472 movl %1,%%a1 ; \ 473 movl %2,%%d0 ; \ 474 1: movw %%a1@+,%%a0@+ ; \ 475 subql #1,%%d0 ; \ 476 jne 1b" : \ 477 : \ 478 "r" ((h) + (o)), "g" (a), "g" (c) : \ 479 "a0","a1","d0"); \ 480 } while (0); 481 482 #define bus_space_write_region_4(t, h, o, a, c) do { \ 483 (void) t; \ 484 __asm __volatile (" \ 485 movl %0,%%a0 ; \ 486 movl %1,%%a1 ; \ 487 movl %2,%%d0 ; \ 488 1: movl %%a1@+,%%a0@+ ; \ 489 subql #1,%%d0 ; \ 490 jne 1b" : \ 491 : \ 492 "r" ((h) + (o)), "g" (a), "g" (c) : \ 493 "a0","a1","d0"); \ 494 } while (0); 495 496 #if 0 /* Cause a link error for bus_space_write_region_8 */ 497 #define bus_space_write_region_8 \ 498 !!! bus_space_write_region_8 unimplemented !!! 499 #endif 500 501 /* 502 * void bus_space_set_multi_N(bus_space_tag_t tag, 503 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 504 * size_t count); 505 * 506 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 507 * by tag/handle/offset `count' times. 508 */ 509 510 #define bus_space_set_multi_1(t, h, o, val, c) do { \ 511 (void) t; \ 512 __asm __volatile (" \ 513 movl %0,%%a0 ; \ 514 movl %1,%%d1 ; \ 515 movl %2,%%d0 ; \ 516 1: movb %%d1,%%a0@ ; \ 517 subql #1,%%d0 ; \ 518 jne 1b" : \ 519 : \ 520 "r" ((h) + (o)), "g" (val), "g" (c) : \ 521 "a0","d0","d1"); \ 522 } while (0); 523 524 #define bus_space_set_multi_2(t, h, o, val, c) do { \ 525 (void) t; \ 526 __asm __volatile (" \ 527 movl %0,%%a0 ; \ 528 movl %1,%%d1 ; \ 529 movl %2,%%d0 ; \ 530 1: movw %%d1,%%a0@ ; \ 531 subql #1,%%d0 ; \ 532 jne 1b" : \ 533 : \ 534 "r" ((h) + (o)), "g" (val), "g" (c) : \ 535 "a0","d0","d1"); \ 536 } while (0); 537 538 #define bus_space_set_multi_4(t, h, o, val, c) do { \ 539 (void) t; \ 540 __asm __volatile (" \ 541 movl %0,%%a0 ; \ 542 movl %1,%%d1 ; \ 543 movl %2,%%d0 ; \ 544 1: movl %%d1,%%a0@ ; \ 545 subql #1,%%d0 ; \ 546 jne 1b" : \ 547 : \ 548 "r" ((h) + (o)), "g" (val), "g" (c) : \ 549 "a0","d0","d1"); \ 550 } while (0); 551 552 #if 0 /* Cause a link error for bus_space_set_multi_8 */ 553 #define bus_space_set_multi_8 \ 554 !!! bus_space_set_multi_8 unimplemented !!! 555 #endif 556 557 /* 558 * void bus_space_set_region_N(bus_space_tag_t tag, 559 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 560 * size_t count); 561 * 562 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 563 * by tag/handle starting at `offset'. 564 */ 565 566 #define bus_space_set_region_1(t, h, o, val, c) do { \ 567 (void) t; \ 568 __asm __volatile (" \ 569 movl %0,%%a0 ; \ 570 movl %1,%%d1 ; \ 571 movl %2,%%d0 ; \ 572 1: movb %%d1,%%a0@+ ; \ 573 subql #1,%%d0 ; \ 574 jne 1b" : \ 575 : \ 576 "r" ((h) + (o)), "g" (val), "g" (c) : \ 577 "a0","d0","d1"); \ 578 } while (0); 579 580 #define bus_space_set_region_2(t, h, o, val, c) do { \ 581 (void) t; \ 582 __asm __volatile (" \ 583 movl %0,%%a0 ; \ 584 movl %1,%%d1 ; \ 585 movl %2,%%d0 ; \ 586 1: movw %%d1,%%a0@+ ; \ 587 subql #1,%%d0 ; \ 588 jne 1b" : \ 589 : \ 590 "r" ((h) + (o)), "g" (val), "g" (c) : \ 591 "a0","d0","d1"); \ 592 } while (0); 593 594 #define bus_space_set_region_4(t, h, o, val, c) do { \ 595 (void) t; \ 596 __asm __volatile (" \ 597 movl %0,%%a0 ; \ 598 movl %1,%%d1 ; \ 599 movl %2,%%d0 ; \ 600 1: movl d1,%%a0@+ ; \ 601 subql #1,%%d0 ; \ 602 jne 1b" : \ 603 : \ 604 "r" ((h) + (o)), "g" (val), "g" (c) : \ 605 "a0","d0","d1"); \ 606 } while (0); 607 608 #if 0 /* Cause a link error for bus_space_set_region_8 */ 609 #define bus_space_set_region_8 \ 610 !!! bus_space_set_region_8 unimplemented !!! 611 #endif 612 613 /* 614 * void bus_space_copy_N(bus_space_tag_t tag, 615 * bus_space_handle_t bsh1, bus_size_t off1, 616 * bus_space_handle_t bsh2, bus_size_t off2, 617 * size_t count); 618 * 619 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 620 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 621 */ 622 623 #define __MVME68K_copy_region_N(BYTES) \ 624 static __inline void __CONCAT(bus_space_copy_region_,BYTES) \ 625 __P((bus_space_tag_t, \ 626 bus_space_handle_t bsh1, bus_size_t off1, \ 627 bus_space_handle_t bsh2, bus_size_t off2, \ 628 bus_size_t count)); \ 629 \ 630 static __inline void \ 631 __CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c) \ 632 bus_space_tag_t t; \ 633 bus_space_handle_t h1, h2; \ 634 bus_size_t o1, o2, c; \ 635 { \ 636 bus_size_t o; \ 637 \ 638 if ((h1 + o1) >= (h2 + o2)) { \ 639 /* src after dest: copy forward */ \ 640 for (o = 0; c != 0; c--, o += BYTES) \ 641 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 642 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 643 } else { \ 644 /* dest after src: copy backwards */ \ 645 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 646 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 647 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 648 } \ 649 } 650 __MVME68K_copy_region_N(1) 651 __MVME68K_copy_region_N(2) 652 __MVME68K_copy_region_N(4) 653 #if 0 /* Cause a link error for bus_space_copy_8 */ 654 #define bus_space_copy_8 \ 655 !!! bus_space_copy_8 unimplemented !!! 656 #endif 657 658 #undef __MVME68K_copy_region_N 659 660 /* 661 * Bus read/write barrier methods. 662 * 663 * void bus_space_barrier(bus_space_tag_t tag, 664 * bus_space_handle_t bsh, bus_size_t offset, 665 * bus_size_t len, int flags); 666 * 667 * Note: the 680x0 does not currently require barriers, but we must 668 * provide the flags to MI code. 669 */ 670 #define bus_space_barrier(t, h, o, l, f) \ 671 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 672 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 673 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 674 675 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 676 677 678 #ifdef _MVME68K_BUS_SPACE_PRIVATE 679 extern int _bus_space_map(void *, bus_addr_t, bus_size_t, 680 int, bus_space_handle_t *); 681 extern void _bus_space_unmap(void *, bus_space_handle_t, bus_size_t); 682 extern int _bus_space_peek_1(void *, bus_space_handle_t, 683 bus_size_t, u_int8_t *); 684 extern int _bus_space_peek_2(void *, bus_space_handle_t, 685 bus_size_t, u_int16_t *); 686 extern int _bus_space_peek_4(void *, bus_space_handle_t, 687 bus_size_t, u_int32_t *); 688 extern int _bus_space_poke_1(void *, bus_space_handle_t, bus_size_t, u_int8_t); 689 extern int _bus_space_poke_2(void *, bus_space_handle_t, bus_size_t, u_int16_t); 690 extern int _bus_space_poke_4(void *, bus_space_handle_t, bus_size_t, u_int32_t); 691 #endif /* _MVME68K_BUS_SPACE_PRIVATE */ 692 693 #endif /* _MVME68K_BUS_SPACE_H_ */ 694