1 /* $NetBSD: simple_busfuncs.c,v 1.11 2012/02/12 16:34:06 matt Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Ignatios Souvatzis. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: simple_busfuncs.c,v 1.11 2012/02/12 16:34:06 matt Exp $"); 34 35 /* 36 * Do NOT use this standalone. 37 * Instead define the stride (linear, not logarithmic!) in the enclosing 38 * file (AMIGA_SIMPLE_BUS_STRIDE), then include this one. 39 * If you want to use it only to provide the functions without creating the 40 * method array, also define AMIGA_SIMPLE_BUS_NO_ARRAY 41 */ 42 43 #ifndef AMIGA_SIMPLE_BUS_STRIDE 44 Error AMIGA_SIMPLE_BUS_STRIDE not defined in __FILE__, line __LINE__ . 45 #endif 46 47 #include <sys/bus.h> 48 #include <sys/null.h> 49 50 #define MKN2(x,y) __CONCAT(x, y) 51 #define MKN1(x,y) MKN2(x, y) 52 #define oabs(n) MKN1(n, AMIGA_SIMPLE_BUS_STRIDE) 53 54 /* function declarations */ 55 56 int oabs(bsm_)(bus_space_tag_t, bus_addr_t, bus_size_t, int, 57 bus_space_handle_t *); 58 59 int oabs(bsms_)(bus_space_handle_t, bus_size_t, bus_size_t, 60 bus_space_handle_t *); 61 62 void oabs(bsu_)(bus_space_handle_t, bus_size_t); 63 64 bsr (oabs(bsr1_), u_int8_t); 65 bsw (oabs(bsw1_), u_int8_t); 66 bsrm(oabs(bsrm1_), u_int8_t); 67 bswm(oabs(bswm1_), u_int8_t); 68 bsrm(oabs(bsrr1_), u_int8_t); 69 bswm(oabs(bswr1_), u_int8_t); 70 bssr(oabs(bssr1_), u_int8_t); 71 bscr(oabs(bscr1_), u_int8_t); 72 73 /* function definitions */ 74 /* ARGSUSED */ 75 int 76 oabs(bsm_)( 77 bus_space_tag_t tag, 78 bus_addr_t address, 79 bus_size_t size, 80 int flags, 81 bus_space_handle_t *handlep) 82 { 83 *handlep = tag->base + address * AMIGA_SIMPLE_BUS_STRIDE; 84 return 0; 85 } 86 87 /* ARGSUSED */ 88 int 89 oabs(bsms_)( 90 bus_space_handle_t handle, 91 bus_size_t offset, 92 bus_size_t size, 93 bus_space_handle_t *nhandlep) 94 { 95 *nhandlep = handle + offset * AMIGA_SIMPLE_BUS_STRIDE; 96 return 0; 97 } 98 99 /* ARGSUSED */ 100 void 101 oabs(bsu_)( 102 bus_space_handle_t handle, 103 bus_size_t size) 104 { 105 return; 106 } 107 108 u_int8_t 109 oabs(bsr1_)( 110 bus_space_handle_t handle, 111 bus_size_t offset) 112 { 113 u_int8_t *p; 114 u_int8_t x; 115 116 p = (u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 117 x = *p; 118 amiga_bus_reorder_protect(); 119 return x; 120 } 121 122 void 123 oabs(bsw1_)( 124 bus_space_handle_t handle, 125 bus_size_t offset, 126 unsigned value) 127 { 128 u_int8_t *p; 129 130 p = (u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 131 *p = (u_int8_t)value; 132 amiga_bus_reorder_protect(); 133 } 134 135 void 136 oabs(bsrm1_)( 137 bus_space_handle_t handle, 138 bus_size_t offset, 139 u_int8_t *pointer, 140 bus_size_t count) 141 { 142 volatile u_int8_t *p; 143 144 p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 145 146 while (count > 0) { 147 *pointer++ = *p; 148 amiga_bus_reorder_protect(); 149 --count; 150 } 151 } 152 153 void 154 oabs(bswm1_)( 155 bus_space_handle_t handle, 156 bus_size_t offset, 157 const u_int8_t *pointer, 158 bus_size_t count) 159 { 160 volatile u_int8_t *p; 161 162 p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 163 164 while (count > 0) { 165 *p = *pointer++; 166 amiga_bus_reorder_protect(); 167 --count; 168 } 169 } 170 171 void 172 oabs(bsrr1_)( 173 bus_space_handle_t handle, 174 bus_size_t offset, 175 u_int8_t *pointer, 176 bus_size_t count) 177 { 178 volatile u_int8_t *p; 179 180 p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 181 182 while (count > 0) { 183 *pointer++ = *p; 184 amiga_bus_reorder_protect(); 185 p += AMIGA_SIMPLE_BUS_STRIDE; 186 --count; 187 } 188 } 189 190 void 191 oabs(bswr1_)( 192 bus_space_handle_t handle, 193 bus_size_t offset, 194 const u_int8_t *pointer, 195 bus_size_t count) 196 { 197 volatile u_int8_t *p; 198 199 p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 200 201 while (count > 0) { 202 *p = *pointer++; 203 amiga_bus_reorder_protect(); 204 p += AMIGA_SIMPLE_BUS_STRIDE; 205 --count; 206 } 207 } 208 209 void 210 oabs(bssr1_)( 211 bus_space_handle_t handle, 212 bus_size_t offset, 213 unsigned value, 214 bus_size_t count) 215 { 216 volatile u_int8_t *p; 217 218 p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 219 220 while (count > 0) { 221 *p = value; 222 amiga_bus_reorder_protect(); 223 p += AMIGA_SIMPLE_BUS_STRIDE; 224 --count; 225 } 226 } 227 228 void 229 oabs(bscr1_)( 230 bus_space_handle_t handlefrom, 231 bus_size_t from, 232 bus_space_handle_t handleto, 233 bus_size_t to, 234 bus_size_t count) 235 { 236 volatile u_int8_t *p, *q; 237 238 p = (volatile u_int8_t *)(handlefrom + from * AMIGA_SIMPLE_BUS_STRIDE); 239 q = (volatile u_int8_t *)(handleto + to * AMIGA_SIMPLE_BUS_STRIDE); 240 241 while (count > 0) { 242 *q = *p; 243 amiga_bus_reorder_protect(); 244 p += AMIGA_SIMPLE_BUS_STRIDE; 245 q += AMIGA_SIMPLE_BUS_STRIDE; 246 --count; 247 } 248 } 249 250 251 #ifdef AMIGA_SIMPLE_BUS_WORD_METHODS 252 253 /* word methods */ 254 255 bsr (oabs(bsr2_), u_int16_t); 256 bsw (oabs(bsw2_), u_int16_t); 257 bsrm(oabs(bsrm2_), u_int16_t); 258 bswm(oabs(bswm2_), u_int16_t); 259 bsrm(oabs(bsrr2_), u_int16_t); 260 bswm(oabs(bswr2_), u_int16_t); 261 bssr(oabs(bssr2_), u_int16_t); 262 bscr(oabs(bscr2_), u_int16_t); 263 264 u_int16_t 265 oabs(bsr2_)( 266 bus_space_handle_t handle, 267 bus_size_t offset) 268 { 269 u_int16_t *p; 270 u_int16_t x; 271 272 p = (u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 273 x = *p; 274 amiga_bus_reorder_protect(); 275 return x; 276 } 277 278 void 279 oabs(bsw2_)( 280 bus_space_handle_t handle, 281 bus_size_t offset, 282 unsigned value) 283 { 284 u_int16_t *p; 285 286 p = (u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 287 *p = (u_int16_t)value; 288 amiga_bus_reorder_protect(); 289 } 290 291 void 292 oabs(bsrm2_)( 293 bus_space_handle_t handle, 294 bus_size_t offset, 295 u_int16_t *pointer, 296 bus_size_t count) 297 { 298 volatile u_int16_t *p; 299 300 p = (volatile u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 301 302 while (count > 0) { 303 *pointer++ = *p; 304 amiga_bus_reorder_protect(); 305 --count; 306 } 307 } 308 309 void 310 oabs(bswm2_)( 311 bus_space_handle_t handle, 312 bus_size_t offset, 313 const u_int16_t *pointer, 314 bus_size_t count) 315 { 316 volatile u_int16_t *p; 317 318 p = (volatile u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 319 320 while (count > 0) { 321 *p = *pointer++; 322 amiga_bus_reorder_protect(); 323 --count; 324 } 325 } 326 327 void 328 oabs(bsrr2_)( 329 bus_space_handle_t handle, 330 bus_size_t offset, 331 u_int16_t *pointer, 332 bus_size_t count) 333 { 334 volatile u_int8_t *p; 335 336 p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 337 338 while (count > 0) { 339 *pointer++ = *(volatile u_int16_t *)p; 340 amiga_bus_reorder_protect(); 341 p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t); 342 --count; 343 } 344 } 345 346 void 347 oabs(bswr2_)( 348 bus_space_handle_t handle, 349 bus_size_t offset, 350 const u_int16_t *pointer, 351 bus_size_t count) 352 { 353 volatile u_int8_t *p; 354 355 p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 356 357 while (count > 0) { 358 *(volatile u_int16_t *)p = *pointer++; 359 amiga_bus_reorder_protect(); 360 p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t); 361 --count; 362 } 363 } 364 365 void 366 oabs(bssr2_)( 367 bus_space_handle_t handle, 368 bus_size_t offset, 369 unsigned value, 370 bus_size_t count) 371 { 372 volatile u_int8_t *p; 373 374 p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 375 376 while (count > 0) { 377 *(volatile u_int16_t *)p = (unsigned)value; 378 amiga_bus_reorder_protect(); 379 p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t); 380 --count; 381 } 382 } 383 384 void 385 oabs(bscr2_)( 386 bus_space_handle_t handlefrom, 387 bus_size_t from, 388 bus_space_handle_t handleto, 389 bus_size_t to, 390 bus_size_t count) 391 { 392 volatile u_int8_t *p, *q; 393 394 p = (volatile u_int8_t *)(handlefrom + from * AMIGA_SIMPLE_BUS_STRIDE); 395 q = (volatile u_int8_t *)(handleto + to * AMIGA_SIMPLE_BUS_STRIDE); 396 397 while (count > 0) { 398 *(volatile u_int16_t *)q = *(volatile u_int16_t *)p; 399 amiga_bus_reorder_protect(); 400 p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t); 401 q += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t); 402 --count; 403 } 404 } 405 #endif /* AMIGA_SIMPLE_BUS_WORD_METHODS */ 406 407 #ifdef AMIGA_SIMPLE_BUS_LONGWORD_METHODS 408 409 /* longword methods */ 410 411 bsr (oabs(bsr4_), u_int32_t); 412 bsw (oabs(bsw4_), u_int32_t); 413 bsrm(oabs(bsrm4_), u_int32_t); 414 bswm(oabs(bswm4_), u_int32_t); 415 bsrm(oabs(bsrr4_), u_int32_t); 416 bswm(oabs(bswr4_), u_int32_t); 417 bssr(oabs(bssr4_), u_int32_t); 418 bscr(oabs(bscr4_), u_int32_t); 419 420 u_int32_t 421 oabs(bsr4_)( 422 bus_space_handle_t handle, 423 bus_size_t offset) 424 { 425 u_int32_t *p; 426 u_int32_t x; 427 428 p = (u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 429 x = *p; 430 amiga_bus_reorder_protect(); 431 return x; 432 } 433 434 void 435 oabs(bsw4_)( 436 bus_space_handle_t handle, 437 bus_size_t offset, 438 unsigned value) 439 { 440 u_int32_t *p; 441 442 p = (u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 443 *p = (u_int32_t)value; 444 amiga_bus_reorder_protect(); 445 } 446 447 448 void 449 oabs(bsrm4_)( 450 bus_space_handle_t handle, 451 bus_size_t offset, 452 u_int32_t *pointer, 453 bus_size_t count) 454 { 455 volatile u_int32_t *p; 456 457 p = (volatile u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 458 459 while (count > 0) { 460 *pointer++ = *p; 461 amiga_bus_reorder_protect(); 462 --count; 463 } 464 } 465 466 void 467 oabs(bswm4_)( 468 bus_space_handle_t handle, 469 bus_size_t offset, 470 const u_int32_t *pointer, 471 bus_size_t count) 472 { 473 volatile u_int32_t *p; 474 475 p = (volatile u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 476 477 while (count > 0) { 478 *p = *pointer++; 479 amiga_bus_reorder_protect(); 480 --count; 481 } 482 } 483 484 void 485 oabs(bsrr4_)( 486 bus_space_handle_t handle, 487 bus_size_t offset, 488 u_int32_t *pointer, 489 bus_size_t count) 490 { 491 volatile u_int8_t *p; 492 493 p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 494 495 while (count > 0) { 496 *pointer++ = *(volatile u_int32_t *)p; 497 amiga_bus_reorder_protect(); 498 p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t); 499 --count; 500 } 501 } 502 503 void 504 oabs(bswr4_)( 505 bus_space_handle_t handle, 506 bus_size_t offset, 507 const u_int32_t *pointer, 508 bus_size_t count) 509 { 510 volatile u_int8_t *p; 511 512 p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 513 514 while (count > 0) { 515 *(volatile u_int32_t *)p = *pointer++; 516 amiga_bus_reorder_protect(); 517 p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t); 518 --count; 519 } 520 } 521 522 void 523 oabs(bssr4_)( 524 bus_space_handle_t handle, 525 bus_size_t offset, 526 unsigned value, 527 bus_size_t count) 528 { 529 volatile u_int8_t *p; 530 531 p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE); 532 533 while (count > 0) { 534 *(volatile u_int32_t *)p = (unsigned)value; 535 amiga_bus_reorder_protect(); 536 p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t); 537 --count; 538 } 539 } 540 541 void 542 oabs(bscr4_)( 543 bus_space_handle_t handlefrom, 544 bus_size_t from, 545 bus_space_handle_t handleto, 546 bus_size_t to, 547 bus_size_t count) 548 { 549 volatile u_int8_t *p, *q; 550 551 p = (volatile u_int8_t *)(handlefrom + from * AMIGA_SIMPLE_BUS_STRIDE); 552 q = (volatile u_int8_t *)(handleto + to * AMIGA_SIMPLE_BUS_STRIDE); 553 554 while (count > 0) { 555 *(volatile u_int32_t *)q = *(volatile u_int32_t *)p; 556 amiga_bus_reorder_protect(); 557 p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t); 558 q += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t); 559 --count; 560 } 561 } 562 #endif /* AMIGA_SIMPLE_BUS_LONGWORD_METHODS */ 563 564 #ifndef AMIGA_SIMPLE_BUS_NO_ARRAY 565 /* method array */ 566 567 const struct amiga_bus_space_methods oabs(amiga_bus_stride_) = { 568 569 .bsm = oabs(bsm_), 570 .bsms = oabs(bsms_), 571 .bsu = oabs(bsu_), 572 .bsa = NULL, 573 .bsf = NULL, 574 575 .bsr1 = oabs(bsr1_), 576 .bsw1 = oabs(bsw1_), 577 .bsrm1 = oabs(bsrm1_), 578 .bswm1 = oabs(bswm1_), 579 .bsrr1 = oabs(bsrr1_), 580 .bswr1 = oabs(bswr1_), 581 .bssr1 = oabs(bssr1_), 582 .bscr1 = oabs(bscr1_), 583 584 #ifdef AMIGA_SIMPLE_BUS_WORD_METHODS 585 .bsr2 = oabs(bsr2_), 586 .bsw2 = oabs(bsw2_), 587 .bsrs2 = oabs(bsr2_), 588 .bsws2 = oabs(bsw2_), 589 .bsrm2 = oabs(bsrm2_), 590 .bswm2 = oabs(bswm2_), 591 .bsrms2 = oabs(bsrm2_), 592 .bswms2 = oabs(bswm2_), 593 .bsrr2 = oabs(bsrr2_), 594 .bswr2 = oabs(bswr2_), 595 .bsrrs2 = oabs(bsrr2_), 596 .bswrs2 = oabs(bswr2_), 597 .bssr2 = oabs(bssr2_), 598 .bscr2 = oabs(bscr2_), 599 #endif /* AMIGA_SIMPLE_BUS_WORD_METHODS */ 600 601 #ifdef AMIGA_SIMPLE_BUS_LONGWORD_METHODS 602 .bsr4 = oabs(bsr4_), 603 .bsw4 = oabs(bsw4_), 604 .bsrs4 = oabs(bsr4_), 605 .bsws4 = oabs(bsw4_), 606 .bsrm4 = oabs(bsrm4_), 607 .bswm4 = oabs(bswm4_), 608 .bsrms4 = oabs(bsrm4_), 609 .bswms4 = oabs(bswm4_), 610 .bsrr4 = oabs(bsrr4_), 611 .bswr4 = oabs(bswr4_), 612 .bsrrs4 = oabs(bsrr4_), 613 .bswrs4 = oabs(bswr4_), 614 .bssr4 = oabs(bssr4_), 615 .bscr4 = oabs(bscr4_) 616 #endif /* AMIGA_SIMPLE_BUS_LONGWORD_METHODS */ 617 }; 618 #endif 619