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