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