1 /* $NetBSD: bus_space.c,v 1.18 2002/04/09 01:53:47 briggs Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 1997 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 * Implementation of bus_space mapping for mac68k. 42 */ 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/extent.h> 47 #include <sys/map.h> 48 49 #include <machine/bus.h> 50 51 #include <uvm/uvm_extern.h> 52 53 int bus_mem_add_mapping __P((bus_addr_t bpa, bus_size_t size, int flags, 54 bus_space_handle_t *hp)); 55 56 extern struct extent *iomem_ex; 57 extern int iomem_malloc_safe; 58 label_t *nofault; 59 60 int 61 bus_mem_add_mapping(bus_addr_t bpa, bus_size_t size, int flags, 62 bus_space_handle_t *hp) 63 { 64 u_long pa, endpa; 65 vaddr_t va; 66 pt_entry_t *pte; 67 68 pa = m68k_trunc_page(bpa); 69 endpa = m68k_round_page((bpa + size) - 1); 70 71 #ifdef DIAGNOSTIC 72 if (endpa <= pa) 73 panic("bus_mem_add_mapping: overflow"); 74 #endif 75 76 va = uvm_km_valloc(kernel_map, endpa - pa); 77 if (va == 0) 78 return (ENOMEM); 79 80 hp->base = (u_long)(va + m68k_page_offset(bpa)); 81 hp->swapped = 0; 82 hp->stride = 1; 83 hp->bsr1 = mac68k_bsr1; 84 hp->bsr2 = mac68k_bsr2; 85 hp->bsr4 = mac68k_bsr4; 86 hp->bsrs1 = mac68k_bsr1; 87 hp->bsrs2 = mac68k_bsr2; 88 hp->bsrs4 = mac68k_bsr4; 89 hp->bsrm1 = mac68k_bsrm1; 90 hp->bsrm2 = mac68k_bsrm2; 91 hp->bsrm4 = mac68k_bsrm4; 92 hp->bsrms1 = mac68k_bsrm1; 93 hp->bsrms2 = mac68k_bsrm2; 94 hp->bsrms4 = mac68k_bsrm4; 95 hp->bsrr1 = mac68k_bsrr1; 96 hp->bsrr2 = mac68k_bsrr2; 97 hp->bsrr4 = mac68k_bsrr4; 98 hp->bsrrs1 = mac68k_bsrr1; 99 hp->bsrrs2 = mac68k_bsrr2; 100 hp->bsrrs4 = mac68k_bsrr4; 101 hp->bsw1 = mac68k_bsw1; 102 hp->bsw2 = mac68k_bsw2; 103 hp->bsw4 = mac68k_bsw4; 104 hp->bsws1 = mac68k_bsw1; 105 hp->bsws2 = mac68k_bsw2; 106 hp->bsws4 = mac68k_bsw4; 107 hp->bswm1 = mac68k_bswm1; 108 hp->bswm2 = mac68k_bswm2; 109 hp->bswm4 = mac68k_bswm4; 110 hp->bswms1 = mac68k_bswm1; 111 hp->bswms2 = mac68k_bswm2; 112 hp->bswms4 = mac68k_bswm4; 113 hp->bswr1 = mac68k_bswr1; 114 hp->bswr2 = mac68k_bswr2; 115 hp->bswr4 = mac68k_bswr4; 116 hp->bswrs1 = mac68k_bswr1; 117 hp->bswrs2 = mac68k_bswr2; 118 hp->bswrs4 = mac68k_bswr4; 119 hp->bssm1 = mac68k_bssm1; 120 hp->bssm2 = mac68k_bssm2; 121 hp->bssm4 = mac68k_bssm4; 122 hp->bssr1 = mac68k_bssr1; 123 hp->bssr2 = mac68k_bssr2; 124 hp->bssr4 = mac68k_bssr4; 125 126 for (; pa < endpa; pa += NBPG, va += NBPG) { 127 pmap_enter(pmap_kernel(), va, pa, 128 VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED); 129 pte = kvtopte(va); 130 if ((flags & BUS_SPACE_MAP_CACHEABLE)) 131 *pte &= ~PG_CI; 132 else 133 *pte |= PG_CI; 134 TBIS(va); 135 } 136 pmap_update(pmap_kernel()); 137 138 return 0; 139 } 140 141 int 142 bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags, 143 bus_space_handle_t *hp) 144 { 145 paddr_t pa, endpa; 146 int error; 147 148 /* 149 * Before we go any further, let's make sure that this 150 * region is available. 151 */ 152 error = extent_alloc_region(iomem_ex, bpa, size, 153 EX_NOWAIT | (iomem_malloc_safe ? EX_MALLOCOK : 0)); 154 if (error) 155 return (error); 156 157 pa = m68k_trunc_page(bpa + t); 158 endpa = m68k_round_page((bpa + t + size) - 1); 159 160 #ifdef DIAGNOSTIC 161 if (endpa <= pa) 162 panic("bus_space_map: overflow"); 163 #endif 164 165 error = bus_mem_add_mapping(bpa, size, flags, hp); 166 if (error) { 167 if (extent_free(iomem_ex, bpa, size, EX_NOWAIT | 168 (iomem_malloc_safe ? EX_MALLOCOK : 0))) { 169 printf("bus_space_map: pa 0x%lx, size 0x%lx\n", 170 bpa, size); 171 printf("bus_space_map: can't free region\n"); 172 } 173 } 174 175 return (error); 176 } 177 178 int 179 bus_space_alloc(bus_space_tag_t t, 180 bus_addr_t rstart, bus_addr_t rend, bus_size_t size, 181 bus_size_t alignment, bus_size_t boundary, int flags, 182 bus_addr_t *bpap, bus_space_handle_t *hp) 183 { 184 u_long bpa; 185 int error; 186 187 /* 188 * Sanity check the allocation against the extent's boundaries. 189 */ 190 if (rstart < iomem_ex->ex_start || rend > iomem_ex->ex_end) 191 panic("bus_space_alloc: bad region start/end"); 192 193 /* 194 * Do the requested allocation. 195 */ 196 error = extent_alloc_subregion(iomem_ex, rstart, rend, size, alignment, 197 boundary, 198 EX_FAST | EX_NOWAIT | (iomem_malloc_safe ? EX_MALLOCOK : 0), 199 &bpa); 200 201 if (error) 202 return (error); 203 204 /* 205 * For memory space, map the bus physical address to 206 * a kernel virtual address. 207 */ 208 error = bus_mem_add_mapping(bpa, size, flags, hp); 209 if (error) { 210 if (extent_free(iomem_ex, bpa, size, EX_NOWAIT | 211 (iomem_malloc_safe ? EX_MALLOCOK : 0))) { 212 printf("bus_space_alloc: pa 0x%lx, size 0x%lx\n", 213 bpa, size); 214 printf("bus_space_alloc: can't free region\n"); 215 } 216 } 217 218 *bpap = bpa; 219 220 return (error); 221 } 222 223 void 224 bus_space_unmap(bus_space_tag_t t, bus_space_handle_t h, bus_size_t size) 225 { 226 vaddr_t va, endva; 227 bus_addr_t bpa; 228 229 va = m68k_trunc_page(h.base); 230 endva = m68k_round_page((h.base + size) - 1); 231 232 #ifdef DIAGNOSTIC 233 if (endva <= va) 234 panic("bus_space_unmap: overflow"); 235 #endif 236 237 (void) pmap_extract(pmap_kernel(), va, &bpa); 238 bpa += m68k_page_offset(h.base); 239 240 /* 241 * Free the kernel virtual mapping. 242 */ 243 uvm_km_free(kernel_map, va, endva - va); 244 245 if (extent_free(iomem_ex, bpa, size, 246 EX_NOWAIT | (iomem_malloc_safe ? EX_MALLOCOK : 0))) { 247 printf("bus_space_unmap: pa 0x%lx, size 0x%lx\n", 248 bpa, size); 249 printf("bus_space_unmap: can't free region\n"); 250 } 251 } 252 253 void 254 bus_space_free(bus_space_tag_t t, bus_space_handle_t h, bus_size_t size) 255 { 256 /* bus_space_unmap() does all that we need to do. */ 257 bus_space_unmap(t, h, size); 258 } 259 260 int 261 bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset, 262 bus_size_t size, bus_space_handle_t *nhp) 263 { 264 265 *nhp = h; 266 nhp->base += offset; 267 return (0); 268 } 269 270 int 271 mac68k_bus_space_probe(bus_space_tag_t t, bus_space_handle_t h, 272 bus_size_t offset, int size) 273 { 274 int i; 275 label_t faultbuf; 276 277 nofault = &faultbuf; 278 if (setjmp(nofault)) { 279 nofault = (label_t *)0; 280 return (0); 281 } 282 283 switch (size) { 284 case 1: 285 i = bus_space_read_1(t, h, offset); 286 break; 287 case 2: 288 i = bus_space_read_2(t, h, offset); 289 break; 290 case 4: 291 i = bus_space_read_4(t, h, offset); 292 break; 293 case 8: 294 default: 295 panic("bus_space_probe: unsupported data size %d\n", size); 296 /* NOTREACHED */ 297 } 298 299 nofault = (label_t *)0; 300 return (1); 301 } 302 303 void 304 mac68k_bus_space_handle_swapped(bus_space_tag_t t, bus_space_handle_t *h) 305 { 306 h->swapped = 1; 307 if (h->stride == 1) { 308 h->bsr2 = mac68k_bsr2_swap; 309 h->bsr4 = mac68k_bsr4_swap; 310 h->bsrm2 = mac68k_bsrm2_swap; 311 h->bsrm4 = mac68k_bsrm4_swap; 312 h->bsrr2 = mac68k_bsrr2_swap; 313 h->bsrr4 = mac68k_bsrr4_swap; 314 h->bsw2 = mac68k_bsw2_swap; 315 h->bsw4 = mac68k_bsw4_swap; 316 h->bswm2 = mac68k_bswm2_swap; 317 h->bswm4 = mac68k_bswm4_swap; 318 h->bswr2 = mac68k_bswr2_swap; 319 h->bswr4 = mac68k_bswr4_swap; 320 h->bssm2 = mac68k_bssm2_swap; 321 h->bssm4 = mac68k_bssm4_swap; 322 h->bssr2 = mac68k_bssr2_swap; 323 h->bssr4 = mac68k_bssr4_swap; 324 } 325 } 326 327 void 328 mac68k_bus_space_handle_set_stride(bus_space_tag_t t, bus_space_handle_t *h, 329 int stride) 330 { 331 h->stride = stride; 332 h->bsr1 = mac68k_bsr1_gen; 333 h->bsr2 = mac68k_bsr2_gen; 334 h->bsr4 = mac68k_bsr4_gen; 335 h->bsrs2 = mac68k_bsrs2_gen; 336 h->bsrs4 = mac68k_bsrs4_gen; 337 h->bsrm1 = mac68k_bsrm1_gen; 338 h->bsrm2 = mac68k_bsrm2_gen; 339 h->bsrm4 = mac68k_bsrm4_gen; 340 h->bsrms2 = mac68k_bsrms2_gen; 341 h->bsrms4 = mac68k_bsrms4_gen; 342 h->bsrr1 = mac68k_bsrr1_gen; 343 h->bsrr2 = mac68k_bsrr2_gen; 344 h->bsrr4 = mac68k_bsrr4_gen; 345 h->bsrrs2 = mac68k_bsrrs2_gen; 346 h->bsrrs4 = mac68k_bsrrs4_gen; 347 h->bsw1 = mac68k_bsw1_gen; 348 h->bsw2 = mac68k_bsw2_gen; 349 h->bsw4 = mac68k_bsw4_gen; 350 h->bsws2 = mac68k_bsws2_gen; 351 h->bsws4 = mac68k_bsws4_gen; 352 h->bswm2 = mac68k_bswm2_gen; 353 h->bswm4 = mac68k_bswm4_gen; 354 h->bswms2 = mac68k_bswms2_gen; 355 h->bswms4 = mac68k_bswms4_gen; 356 h->bswr1 = mac68k_bswr1_gen; 357 h->bswr2 = mac68k_bswr2_gen; 358 h->bswr4 = mac68k_bswr4_gen; 359 h->bswrs2 = mac68k_bswrs2_gen; 360 h->bswrs4 = mac68k_bswrs4_gen; 361 h->bssm1 = mac68k_bssm1_gen; 362 h->bssm2 = mac68k_bssm2_gen; 363 h->bssm4 = mac68k_bssm4_gen; 364 h->bssr1 = mac68k_bssr1_gen; 365 h->bssr2 = mac68k_bssr2_gen; 366 h->bssr4 = mac68k_bssr4_gen; 367 } 368 369 u_int8_t 370 mac68k_bsr1(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset) 371 { 372 return (*(volatile u_int8_t *)(h->base + offset)); 373 } 374 375 u_int8_t 376 mac68k_bsr1_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset) 377 { 378 return (*(volatile u_int8_t *)(h->base + offset * h->stride)); 379 } 380 381 u_int16_t 382 mac68k_bsr2(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset) 383 { 384 return (*(volatile u_int16_t *)(h->base + offset)); 385 } 386 387 u_int16_t 388 mac68k_bsr2_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset) 389 { 390 u_int16_t v; 391 392 v = (*(volatile u_int16_t *)(h->base + offset)); 393 return bswap16(v); 394 } 395 396 u_int16_t 397 mac68k_bsrs2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset) 398 { 399 u_int16_t v; 400 401 v = (*(volatile u_int8_t *)(h->base + offset++ * h->stride)) << 8; 402 v |= (*(volatile u_int8_t *)(h->base + offset * h->stride)); 403 return v; 404 } 405 406 u_int16_t 407 mac68k_bsr2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset) 408 { 409 u_int16_t v; 410 411 v = mac68k_bsrs2_gen(t, h, offset); 412 if (h->swapped) { 413 bswap16(v); 414 } 415 return v; 416 } 417 418 u_int32_t 419 mac68k_bsr4(bus_space_tag_t tag, bus_space_handle_t *h, bus_size_t offset) 420 { 421 return (*(volatile u_int32_t *)(h->base + offset)); 422 } 423 424 u_int32_t 425 mac68k_bsr4_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset) 426 { 427 u_int32_t v; 428 429 v = (*(volatile u_int32_t *)(h->base + offset)); 430 return bswap32(v); 431 } 432 433 u_int32_t 434 mac68k_bsrs4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset) 435 { 436 u_int32_t v; 437 438 v = (*(volatile u_int8_t *)(h->base + offset++ * h->stride)); 439 v <<= 8; 440 v |= (*(volatile u_int8_t *)(h->base + offset++ * h->stride)); 441 v <<= 8; 442 v |= (*(volatile u_int8_t *)(h->base + offset++ * h->stride)); 443 v <<= 8; 444 v |= (*(volatile u_int8_t *)(h->base + offset++ * h->stride)); 445 return v; 446 } 447 448 u_int32_t 449 mac68k_bsr4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset) 450 { 451 u_int32_t v; 452 453 v = mac68k_bsrs4_gen(t, h, offset); 454 if (h->swapped) { 455 v = bswap32(v); 456 } 457 return v; 458 } 459 460 void 461 mac68k_bsrm1(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 462 u_int8_t *a, size_t c) 463 { 464 __asm __volatile (" 465 movl %0,%%a0 ; 466 movl %1,%%a1 ; 467 movl %2,%%d0 ; 468 1: movb %%a0@,%%a1@+ ; 469 subql #1,%%d0 ; 470 jne 1b" : 471 : 472 "r" (h->base + offset), "g" (a), "g" (c) : 473 "a0","a1","d0"); 474 } 475 476 void 477 mac68k_bsrm1_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 478 u_int8_t *a, size_t c) 479 { 480 while (c--) { 481 *a++ = bus_space_read_1(t, *h, offset); 482 } 483 } 484 485 void 486 mac68k_bsrm2(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 487 u_int16_t *a, size_t c) 488 { 489 __asm __volatile (" 490 movl %0,%%a0 ; 491 movl %1,%%a1 ; 492 movl %2,%%d0 ; 493 1: movw %%a0@,%%a1@+ ; 494 subql #1,%%d0 ; 495 jne 1b" : 496 : 497 "r" (h->base + offset), "g" (a), "g" (c) : 498 "a0","a1","d0"); 499 } 500 501 void 502 mac68k_bsrm2_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 503 u_int16_t *a, size_t c) 504 { 505 __asm __volatile (" 506 movl %0,%%a0 ; 507 movl %1,%%a1 ; 508 movl %2,%%d0 ; 509 1: movw %%a0@,%%d1 ; 510 rolw #8,%%d1 ; 511 movw %%d1,%%a1@+ ; 512 subql #1,%%d0 ; 513 jne 1b" : 514 : 515 "r" (h->base + offset), "g" (a), "g" (c) : 516 "a0","a1","d0","d1"); 517 } 518 519 void 520 mac68k_bsrm2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 521 u_int16_t *a, size_t c) 522 { 523 while (c--) { 524 *a++ = bus_space_read_2(t, *h, offset); 525 } 526 } 527 528 void 529 mac68k_bsrms2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 530 u_int16_t *a, size_t c) 531 { 532 while (c--) { 533 *a++ = bus_space_read_stream_2(t, *h, offset); 534 } 535 } 536 537 void 538 mac68k_bsrm4(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 539 u_int32_t *a, size_t c) 540 { 541 __asm __volatile (" 542 movl %0,%%a0 ; 543 movl %1,%%a1 ; 544 movl %2,%%d0 ; 545 1: movl %%a0@,%%a1@+ ; 546 subql #1,%%d0 ; 547 jne 1b" : 548 : 549 "r" (h->base + offset), "g" (a), "g" (c) : 550 "a0","a1","d0"); 551 } 552 553 void 554 mac68k_bsrm4_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 555 u_int32_t *a, size_t c) 556 { 557 __asm __volatile (" 558 movl %0,%%a0 ; 559 movl %1,%%a1 ; 560 movl %2,%%d0 ; 561 1: movl %%a0@,%%d1 ; 562 rolw #8,%%d1 ; 563 swap %%d1 ; 564 rolw #8,%%d1 ; 565 movl %%d1,%%a1@+ ; 566 subql #1,%%d0 ; 567 jne 1b" : 568 : 569 "r" (h->base + offset), "g" (a), "g" (c) : 570 "a0","a1","d0","d1"); 571 } 572 573 void 574 mac68k_bsrm4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 575 u_int32_t *a, size_t c) 576 { 577 while (c--) { 578 *a++ = bus_space_read_4(t, *h, offset); 579 } 580 } 581 582 void 583 mac68k_bsrms4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 584 u_int32_t *a, size_t c) 585 { 586 while (c--) { 587 *a++ = bus_space_read_stream_4(t, *h, offset); 588 } 589 } 590 591 void 592 mac68k_bsrr1(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 593 u_int8_t *a, size_t c) 594 { 595 __asm __volatile (" 596 movl %0,%%a0 ; 597 movl %1,%%a1 ; 598 movl %2,%%d0 ; 599 1: movb %%a0@+,%%a1@+ ; 600 subql #1,%%d0 ; 601 jne 1b" : 602 : 603 "r" (h->base + offset), "g" (a), "g" (c) : 604 "a0","a1","d0"); 605 } 606 607 void 608 mac68k_bsrr1_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 609 u_int8_t *a, size_t c) 610 { 611 while (c--) { 612 *a++ = bus_space_read_1(t, *h, offset); 613 offset++; 614 } 615 } 616 617 void 618 mac68k_bsrr2(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 619 u_int16_t *a, size_t c) 620 { 621 __asm __volatile (" 622 movl %0,%%a0 ; 623 movl %1,%%a1 ; 624 movl %2,%%d0 ; 625 1: movw %%a0@+,%%a1@+ ; 626 subql #1,%%d0 ; 627 jne 1b" : 628 : 629 "r" (h->base + offset), "g" (a), "g" (c) : 630 "a0","a1","d0"); 631 } 632 633 void 634 mac68k_bsrr2_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 635 u_int16_t *a, size_t c) 636 { 637 __asm __volatile (" 638 movl %0,%%a0 ; 639 movl %1,%%a1 ; 640 movl %2,%%d0 ; 641 1: movw %%a0@+,%%d1 ; 642 rolw #8,%%d1 ; 643 movw %%d1,%%a1@+ ; 644 subql #1,%%d0 ; 645 jne 1b" : 646 : 647 "r" (h->base + offset), "g" (a), "g" (c) : 648 "a0","a1","d0","d1"); 649 } 650 651 void 652 mac68k_bsrr2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 653 u_int16_t *a, size_t c) 654 { 655 while (c--) { 656 *a++ = bus_space_read_2(t, *h, offset); 657 offset += 2; 658 } 659 } 660 661 void 662 mac68k_bsrrs2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 663 u_int16_t *a, size_t c) 664 { 665 while (c--) { 666 *a++ = bus_space_read_stream_2(t, *h, offset); 667 offset += 2; 668 } 669 } 670 671 void 672 mac68k_bsrr4(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 673 u_int32_t *a, size_t c) 674 { 675 __asm __volatile (" 676 movl %0,%%a0 ; 677 movl %1,%%a1 ; 678 movl %2,%%d0 ; 679 1: movl %%a0@+,%%a1@+ ; 680 subql #1,%%d0 ; 681 jne 1b" : 682 : 683 "r" (h->base + offset), "g" (a), "g" (c) : 684 "a0","a1","d0"); 685 } 686 687 void 688 mac68k_bsrr4_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 689 u_int32_t *a, size_t c) 690 { 691 __asm __volatile (" 692 movl %0,%%a0 ; 693 movl %1,%%a1 ; 694 movl %2,%%d0 ; 695 1: movl %%a0@+,%%d1 ; 696 rolw #8,%%d1 ; 697 swap %%d1 ; 698 rolw #8,%%d1 ; 699 movl %%d1,%%a1@+ ; 700 subql #1,%%d0 ; 701 jne 1b" : 702 : 703 "r" (h->base + offset), "g" (a), "g" (c) : 704 "a0","a1","d0"); 705 } 706 707 void 708 mac68k_bsrr4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 709 u_int32_t *a, size_t c) 710 { 711 while (c--) { 712 *a++ = bus_space_read_4(t, *h, offset); 713 offset += 4; 714 } 715 } 716 717 void 718 mac68k_bsrrs4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 719 u_int32_t *a, size_t c) 720 { 721 while (c--) { 722 *a++ = bus_space_read_stream_4(t, *h, offset); 723 offset += 4; 724 } 725 } 726 727 void 728 mac68k_bsw1(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 729 u_int8_t v) 730 { 731 (*(volatile u_int8_t *)(h->base + offset)) = v; 732 } 733 734 void 735 mac68k_bsw1_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 736 u_int8_t v) 737 { 738 (*(volatile u_int8_t *)(h->base + offset * h->stride)) = v; 739 } 740 741 void 742 mac68k_bsw2(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 743 u_int16_t v) 744 { 745 (*(volatile u_int16_t *)(h->base + offset)) = v; 746 } 747 748 void 749 mac68k_bsw2_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 750 u_int16_t v) 751 { 752 v = bswap16(v); 753 (*(volatile u_int16_t *)(h->base + offset)) = v; 754 } 755 756 void 757 mac68k_bsws2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 758 u_int16_t v) 759 { 760 u_int8_t v1; 761 762 v1 = (v & 0xff00) >> 8; 763 (*(volatile u_int8_t *)(h->base + offset++ * h->stride)) = v1; 764 (*(volatile u_int8_t *)(h->base + offset * h->stride)) = v & 0xff; 765 } 766 767 void 768 mac68k_bsw2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 769 u_int16_t v) 770 { 771 if (h->swapped) { 772 v = bswap16(v); 773 } 774 mac68k_bsws2_gen(t, h, offset, v); 775 } 776 777 void 778 mac68k_bsw4(bus_space_tag_t tag, bus_space_handle_t *h, bus_size_t offset, 779 u_int32_t v) 780 { 781 (*(volatile u_int32_t *)(h->base + offset)) = v; 782 } 783 784 void 785 mac68k_bsw4_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 786 u_int32_t v) 787 { 788 v = bswap32(v); 789 (*(volatile u_int32_t *)(h->base + offset)) = v; 790 } 791 792 void 793 mac68k_bsws4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 794 u_int32_t v) 795 { 796 u_int8_t v1,v2,v3; 797 798 v1 = (v & 0xff000000) >> 24; 799 v2 = (v & 0x00ff0000) >> 16; 800 v3 = (v & 0x0000ff00) >> 8; 801 (*(volatile u_int8_t *)(h->base + offset++ * h->stride)) = v1; 802 (*(volatile u_int8_t *)(h->base + offset++ * h->stride)) = v2; 803 (*(volatile u_int8_t *)(h->base + offset++ * h->stride)) = v3; 804 (*(volatile u_int8_t *)(h->base + offset * h->stride)) = v & 0xff; 805 } 806 807 void 808 mac68k_bsw4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 809 u_int32_t v) 810 { 811 if (h->swapped) { 812 v = bswap32(v); 813 } 814 mac68k_bsws4_gen(t, h, offset, v); 815 } 816 817 void 818 mac68k_bswm1(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 819 const u_int8_t *a, size_t c) 820 { 821 __asm __volatile (" 822 movl %0,%%a0 ; 823 movl %1,%%a1 ; 824 movl %2,%%d0 ; 825 1: movb %%a1@+,%%a0@ ; 826 subql #1,%%d0 ; 827 jne 1b" : 828 : 829 "r" (h->base + offset), "g" (a), "g" (c) : 830 "a0","a1","d0"); 831 } 832 833 void 834 mac68k_bswm1_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 835 const u_int8_t *a, size_t c) 836 { 837 while (c--) { 838 bus_space_write_1(t, *h, offset, *a++); 839 } 840 } 841 842 void 843 mac68k_bswm2(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 844 const u_int16_t *a, size_t c) 845 { 846 __asm __volatile (" 847 movl %0,%%a0 ; 848 movl %1,%%a1 ; 849 movl %2,%%d0 ; 850 1: movw %%a1@+,%%a0@ ; 851 subql #1,%%d0 ; 852 jne 1b" : 853 : 854 "r" (h->base + offset), "g" (a), "g" (c) : 855 "a0","a1","d0"); 856 } 857 858 void 859 mac68k_bswm2_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 860 const u_int16_t *a, size_t c) 861 { 862 __asm __volatile (" 863 movl %0,%%a0 ; 864 movl %1,%%a1 ; 865 movl %2,%%d0 ; 866 1: movw %%a1@+,%%d1 ; 867 rolw #8,%%d1 ; 868 movw %%d1,%%a0@ ; 869 subql #1,%%d0 ; 870 jne 1b" : 871 : 872 "r" (h->base + offset), "g" (a), "g" (c) : 873 "a0","a1","d0","d1"); 874 } 875 876 void 877 mac68k_bswm2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 878 const u_int16_t *a, size_t c) 879 { 880 while (c--) { 881 bus_space_write_2(t, *h, offset, *a++); 882 } 883 } 884 885 void 886 mac68k_bswms2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 887 const u_int16_t *a, size_t c) 888 { 889 while (c--) { 890 bus_space_write_stream_2(t, *h, offset, *a++); 891 } 892 } 893 894 void 895 mac68k_bswm4(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 896 const u_int32_t *a, size_t c) 897 { 898 __asm __volatile (" 899 movl %0,%%a0 ; 900 movl %1,%%a1 ; 901 movl %2,%%d0 ; 902 1: movl %%a1@+,%%a0@ ; 903 subql #1,%%d0 ; 904 jne 1b" : 905 : 906 "r" (h->base + offset), "g" (a), "g" (c) : 907 "a0","a1","d0"); 908 } 909 910 void 911 mac68k_bswm4_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 912 const u_int32_t *a, size_t c) 913 { 914 __asm __volatile (" 915 movl %0,%%a0 ; 916 movl %1,%%a1 ; 917 movl %2,%%d0 ; 918 1: movl %%a1@+,%%d1 ; 919 rolw #8,%%d1 ; 920 swap %%d1 ; 921 rolw #8,%%d1 ; 922 movl %%d1,%%a0@ ; 923 subql #1,%%d0 ; 924 jne 1b" : 925 : 926 "r" (h->base + offset), "g" (a), "g" (c) : 927 "a0","a1","d0","d1"); 928 } 929 930 void 931 mac68k_bswm4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 932 const u_int32_t *a, size_t c) 933 { 934 while (c--) { 935 bus_space_write_4(t, *h, offset, *a++); 936 } 937 } 938 939 void 940 mac68k_bswms4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 941 const u_int32_t *a, size_t c) 942 { 943 while (c--) { 944 bus_space_write_stream_4(t, *h, offset, *a++); 945 } 946 } 947 948 void 949 mac68k_bswr1(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 950 const u_int8_t *a, size_t c) 951 { 952 __asm __volatile (" 953 movl %0,%%a0 ; 954 movl %1,%%a1 ; 955 movl %2,%%d0 ; 956 1: movb %%a1@+,%%a0@+ ; 957 subql #1,%%d0 ; 958 jne 1b" : 959 : 960 "r" (h->base + offset), "g" (a), "g" (c) : 961 "a0","a1","d0"); 962 } 963 964 void 965 mac68k_bswr1_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 966 const u_int8_t *a, size_t c) 967 { 968 while (c--) { 969 bus_space_write_1(t, *h, offset, *a++); 970 offset++; 971 } 972 } 973 974 void 975 mac68k_bswr2(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 976 const u_int16_t *a, size_t c) 977 { 978 __asm __volatile (" 979 movl %0,%%a0 ; 980 movl %1,%%a1 ; 981 movl %2,%%d0 ; 982 1: movw %%a1@+,%%a0@+ ; 983 subql #1,%%d0 ; 984 jne 1b" : 985 : 986 "r" (h->base + offset), "g" (a), "g" (c) : 987 "a0","a1","d0"); 988 } 989 990 void 991 mac68k_bswr2_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 992 const u_int16_t *a, size_t c) 993 { 994 __asm __volatile (" 995 movl %0,%%a0 ; 996 movl %1,%%a1 ; 997 movl %2,%%d0 ; 998 1: movw %%a1@+,%%d1 ; 999 rolw #8,%%d1 ; 1000 movw %%d1,%%a0@+ ; 1001 subql #1,%%d0 ; 1002 jne 1b" : 1003 : 1004 "r" (h->base + offset), "g" (a), "g" (c) : 1005 "a0","a1","d0","d1"); 1006 } 1007 1008 void 1009 mac68k_bswr2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1010 const u_int16_t *a, size_t c) 1011 { 1012 while (c--) { 1013 bus_space_write_2(t, *h, offset, *a++); 1014 offset += 2; 1015 } 1016 } 1017 1018 void 1019 mac68k_bswrs2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1020 const u_int16_t *a, size_t c) 1021 { 1022 while (c--) { 1023 bus_space_write_stream_2(t, *h, offset, *a++); 1024 offset += 2; 1025 } 1026 } 1027 1028 void 1029 mac68k_bswr4(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1030 const u_int32_t *a, size_t c) 1031 { 1032 __asm __volatile (" 1033 movl %0,%%a0 ; 1034 movl %1,%%a1 ; 1035 movl %2,%%d0 ; 1036 1: movl %%a1@+,%%a0@+ ; 1037 subql #1,%%d0 ; 1038 jne 1b" : 1039 : 1040 "r" (h->base + offset), "g" (a), "g" (c) : 1041 "a0","a1","d0"); 1042 } 1043 1044 void 1045 mac68k_bswr4_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1046 const u_int32_t *a, size_t c) 1047 { 1048 __asm __volatile (" 1049 movl %0,%%a0 ; 1050 movl %1,%%a1 ; 1051 movl %2,%%d0 ; 1052 1: movl %%a1@+,%%d1 ; 1053 rolw #8,%%d1 ; 1054 swap %%d1 ; 1055 rolw #8,%%d1 ; 1056 movl %%d1,%%a0@+ ; 1057 subql #1,%%d0 ; 1058 jne 1b" : 1059 : 1060 "r" (h->base + offset), "g" (a), "g" (c) : 1061 "a0","a1","d0","d1"); 1062 } 1063 1064 void 1065 mac68k_bswr4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1066 const u_int32_t *a, size_t c) 1067 { 1068 while (c--) { 1069 bus_space_write_4(t, *h, offset, *a++); 1070 offset += 4; 1071 } 1072 } 1073 1074 void 1075 mac68k_bswrs4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1076 const u_int32_t *a, size_t c) 1077 { 1078 while (c--) { 1079 bus_space_write_4(t, *h, offset, *a++); 1080 offset += 4; 1081 } 1082 } 1083 1084 void 1085 mac68k_bssm1(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1086 u_int8_t v, size_t c) 1087 { 1088 __asm __volatile (" 1089 movl %0,%%a0 ; 1090 movl %1,%%d1 ; 1091 movl %2,%%d0 ; 1092 1: movb %%d1,%%a0@ ; 1093 subql #1,%%d0 ; 1094 jne 1b" : 1095 : 1096 "r" (h->base + offset), "g" ((u_long)v), "g" (c) : 1097 "a0","d0","d1"); 1098 } 1099 1100 void 1101 mac68k_bssm1_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1102 u_int8_t v, size_t c) 1103 { 1104 while (c--) { 1105 bus_space_write_1(t, *h, offset, v); 1106 } 1107 } 1108 1109 void 1110 mac68k_bssm2(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1111 u_int16_t v, size_t c) 1112 { 1113 __asm __volatile (" 1114 movl %0,%%a0 ; 1115 movl %1,%%d1 ; 1116 movl %2,%%d0 ; 1117 1: movw %%d1,%%a0@ ; 1118 subql #1,%%d0 ; 1119 jne 1b" : 1120 : 1121 "r" (h->base + offset), "g" ((u_long)v), "g" (c) : 1122 "a0","d0","d1"); 1123 } 1124 1125 void 1126 mac68k_bssm2_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1127 u_int16_t v, size_t c) 1128 { 1129 __asm __volatile (" 1130 movl %0,%%a0 ; 1131 movl %1,%%d1 ; 1132 rolw #8,%%d1 ; 1133 movl %2,%%d0 ; 1134 1: movw %%d1,%%a0@ ; 1135 subql #1,%%d0 ; 1136 jne 1b" : 1137 : 1138 "r" (h->base + offset), "g" ((u_long)v), "g" (c) : 1139 "a0","d0","d1"); 1140 } 1141 1142 void 1143 mac68k_bssm2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1144 u_int16_t v, size_t c) 1145 { 1146 while (c--) { 1147 bus_space_write_2(t, *h, offset, v); 1148 } 1149 } 1150 1151 void 1152 mac68k_bssm4(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1153 u_int32_t v, size_t c) 1154 { 1155 __asm __volatile (" 1156 movl %0,%%a0 ; 1157 movl %1,%%d1 ; 1158 movl %2,%%d0 ; 1159 1: movl %%d1,%%a0@ ; 1160 subql #1,%%d0 ; 1161 jne 1b" : 1162 : 1163 "r" (h->base + offset), "g" ((u_long)v), "g" (c) : 1164 "a0","d0","d1"); 1165 } 1166 1167 void 1168 mac68k_bssm4_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1169 u_int32_t v, size_t c) 1170 { 1171 __asm __volatile (" 1172 movl %0,%%a0 ; 1173 movl %1,%%d1 ; 1174 rolw #8,%%d1 ; 1175 swap %%d1 ; 1176 rolw #8,%%d1 ; 1177 movl %2,%%d0 ; 1178 1: movl %%d1,%%a0@ ; 1179 subql #1,%%d0 ; 1180 jne 1b" : 1181 : 1182 "r" (h->base + offset), "g" ((u_long)v), "g" (c) : 1183 "a0","d0","d1"); 1184 } 1185 1186 void 1187 mac68k_bssm4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1188 u_int32_t v, size_t c) 1189 { 1190 while (c--) { 1191 bus_space_write_4(t, *h, offset, v); 1192 } 1193 } 1194 1195 void 1196 mac68k_bssr1(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1197 u_int8_t v, size_t c) 1198 { 1199 __asm __volatile (" 1200 movl %0,%%a0 ; 1201 movl %1,%%d1 ; 1202 movl %2,%%d0 ; 1203 1: movb %%d1,%%a0@+ ; 1204 subql #1,%%d0 ; 1205 jne 1b" : 1206 : 1207 "r" (h->base + offset), "g" ((u_long)v), "g" (c) : 1208 "a0","d0","d1"); 1209 } 1210 1211 void 1212 mac68k_bssr1_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1213 u_int8_t v, size_t c) 1214 { 1215 while (c--) { 1216 bus_space_write_1(t, *h, offset, v); 1217 offset++; 1218 } 1219 } 1220 1221 void 1222 mac68k_bssr2(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1223 u_int16_t v, size_t c) 1224 { 1225 __asm __volatile (" 1226 movl %0,%%a0 ; 1227 movl %1,%%d1 ; 1228 movl %2,%%d0 ; 1229 1: movw %%d1,%%a0@+ ; 1230 subql #1,%%d0 ; 1231 jne 1b" : 1232 : 1233 "r" (h->base + offset), "g" ((u_long)v), "g" (c) : 1234 "a0","d0","d1"); 1235 } 1236 1237 void 1238 mac68k_bssr2_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1239 u_int16_t v, size_t c) 1240 { 1241 __asm __volatile (" 1242 movl %0,%%a0 ; 1243 movl %1,%%d1 ; 1244 rolw #8,%%d1 ; 1245 movl %2,%%d0 ; 1246 1: movw %%d1,%%a0@+ ; 1247 subql #1,%%d0 ; 1248 jne 1b" : 1249 : 1250 "r" (h->base + offset), "g" ((u_long)v), "g" (c) : 1251 "a0","d0","d1"); 1252 } 1253 1254 void 1255 mac68k_bssr2_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1256 u_int16_t v, size_t c) 1257 { 1258 while (c--) { 1259 bus_space_write_2(t, *h, offset, v); 1260 offset += 2; 1261 } 1262 } 1263 1264 void 1265 mac68k_bssr4(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1266 u_int32_t v, size_t c) 1267 { 1268 __asm __volatile (" 1269 movl %0,%%a0 ; 1270 movl %1,%%d1 ; 1271 movl %2,%%d0 ; 1272 1: movl %%d1,%%a0@+ ; 1273 subql #1,%%d0 ; 1274 jne 1b" : 1275 : 1276 "r" (h->base + offset), "g" ((u_long)v), "g" (c) : 1277 "a0","d0","d1"); 1278 } 1279 1280 void 1281 mac68k_bssr4_swap(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1282 u_int32_t v, size_t c) 1283 { 1284 __asm __volatile (" 1285 movl %0,%%a0 ; 1286 movl %1,%%d1 ; 1287 rolw #8,%%d1 ; 1288 swap %%d1 ; 1289 rolw #8,%%d1 ; 1290 movl %2,%%d0 ; 1291 1: movl %%d1,%%a0@+ ; 1292 subql #1,%%d0 ; 1293 jne 1b" : 1294 : 1295 "r" (h->base + offset), "g" ((u_long)v), "g" (c) : 1296 "a0","d0","d1"); 1297 } 1298 1299 void 1300 mac68k_bssr4_gen(bus_space_tag_t t, bus_space_handle_t *h, bus_size_t offset, 1301 u_int32_t v, size_t c) 1302 { 1303 while (c--) { 1304 bus_space_write_4(t, *h, offset, v); 1305 offset += 4; 1306 } 1307 } 1308