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