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