1 /* $NetBSD: bus.h,v 1.15 2008/04/28 20:23:19 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 1997, 1998 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 * Copyright (C) 1997 Scott Reynolds. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. The name of the author may not be used to endorse or promote products 45 * derived from this software without specific prior written permission 46 * 47 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 51 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 52 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 53 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 54 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 55 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 56 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 57 */ 58 59 #ifndef _HP300_BUS_H_ 60 #define _HP300_BUS_H_ 61 62 /* 63 * Values for the hp300 bus space tag, not to be used directly by MI code. 64 */ 65 #define HP300_BUS_SPACE_INTIO 0 /* space is intio space */ 66 #define HP300_BUS_SPACE_DIO 1 /* space is dio space */ 67 68 /* 69 * Bus address and size types 70 */ 71 typedef u_long bus_addr_t; 72 typedef u_long bus_size_t; 73 74 /* 75 * Access methods for bus resources and address space. 76 */ 77 typedef struct bus_space_tag *bus_space_tag_t; 78 typedef u_long bus_space_handle_t; 79 80 /* 81 * Implementation specific structures. 82 * XXX Don't use outside of bus_space definitions! 83 * XXX maybe this should be encapsuled in a non-global .h file? 84 */ 85 86 struct bus_space_tag { 87 u_int bustype; 88 89 uint8_t (*bsr1)(bus_space_tag_t, bus_space_handle_t, 90 bus_size_t); 91 uint16_t (*bsr2)(bus_space_tag_t, bus_space_handle_t, 92 bus_size_t); 93 uint32_t (*bsr4)(bus_space_tag_t, bus_space_handle_t, 94 bus_size_t); 95 void (*bsrm1)(bus_space_tag_t, bus_space_handle_t, 96 bus_size_t, uint8_t *, bus_size_t); 97 void (*bsrm2)(bus_space_tag_t, bus_space_handle_t, 98 bus_size_t, uint16_t *, bus_size_t); 99 void (*bsrm4)(bus_space_tag_t, bus_space_handle_t, 100 bus_size_t, uint32_t *, bus_size_t); 101 void (*bsrr1)(bus_space_tag_t, bus_space_handle_t, 102 bus_size_t, uint8_t *, bus_size_t); 103 void (*bsrr2)(bus_space_tag_t, bus_space_handle_t, 104 bus_size_t, uint16_t *, bus_size_t); 105 void (*bsrr4)(bus_space_tag_t, bus_space_handle_t, 106 bus_size_t, uint32_t *, bus_size_t); 107 void (*bsw1)(bus_space_tag_t, bus_space_handle_t, 108 bus_size_t, uint8_t); 109 void (*bsw2)(bus_space_tag_t, bus_space_handle_t, 110 bus_size_t, uint16_t); 111 void (*bsw4)(bus_space_tag_t, bus_space_handle_t, 112 bus_size_t, uint32_t); 113 void (*bswm1)(bus_space_tag_t, bus_space_handle_t, 114 bus_size_t, const uint8_t *, bus_size_t); 115 void (*bswm2)(bus_space_tag_t, bus_space_handle_t, 116 bus_size_t, const uint16_t *, bus_size_t); 117 void (*bswm4)(bus_space_tag_t, bus_space_handle_t, 118 bus_size_t, const uint32_t *, bus_size_t); 119 void (*bswr1)(bus_space_tag_t, bus_space_handle_t , 120 bus_size_t, const uint8_t *, bus_size_t); 121 void (*bswr2)(bus_space_tag_t, bus_space_handle_t, 122 bus_size_t, const uint16_t *, bus_size_t); 123 void (*bswr4)(bus_space_tag_t, bus_space_handle_t, 124 bus_size_t, const uint32_t *, bus_size_t); 125 void (*bssm1)(bus_space_tag_t, bus_space_handle_t, 126 bus_size_t, uint8_t, bus_size_t); 127 void (*bssm2)(bus_space_tag_t, bus_space_handle_t, 128 bus_size_t, uint16_t, bus_size_t); 129 void (*bssm4)(bus_space_tag_t, bus_space_handle_t, 130 bus_size_t, uint32_t, bus_size_t); 131 void (*bssr1)(bus_space_tag_t, bus_space_handle_t, 132 bus_size_t, uint8_t, bus_size_t); 133 void (*bssr2)(bus_space_tag_t, bus_space_handle_t, 134 bus_size_t, uint16_t, bus_size_t); 135 void (*bssr4)(bus_space_tag_t, bus_space_handle_t, 136 bus_size_t, uint32_t, bus_size_t); 137 }; 138 139 /* 140 * int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 141 * bus_size_t size, int flags, bus_space_handle_t *bshp); 142 * 143 * Map a region of bus space. 144 */ 145 146 #define BUS_SPACE_MAP_CACHEABLE 0x01 147 #define BUS_SPACE_MAP_LINEAR 0x02 148 #define BUS_SPACE_MAP_PREFETCHABLE 0x04 149 150 int bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, 151 int, bus_space_handle_t *); 152 153 /* 154 * void bus_space_unmap(bus_space_tag_t t, 155 * bus_space_handle_t bsh, bus_size_t size); 156 * 157 * Unmap a region of bus space. 158 */ 159 160 void bus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t); 161 162 /* 163 * int bus_space_subregion(bus_space_tag_t t, 164 * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, 165 * bus_space_handle_t *nbshp); 166 * 167 * Get a new handle for a subregion of an already-mapped area of bus space. 168 */ 169 170 int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 171 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp); 172 173 /* 174 * int bus_space_alloc(bus_space_tag_t t, bus_addr_t, rstart, 175 * bus_addr_t rend, bus_size_t size, bus_size_t align, 176 * bus_size_t boundary, int flags, bus_addr_t *addrp, 177 * bus_space_handle_t *bshp); 178 * 179 * Allocate a region of bus space. 180 */ 181 182 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 183 bus_addr_t rend, bus_size_t size, bus_size_t align, 184 bus_size_t boundary, int cacheable, bus_addr_t *addrp, 185 bus_space_handle_t *bshp); 186 187 /* 188 * int bus_space_free(bus_space_tag_t t, 189 * bus_space_handle_t bsh, bus_size_t size); 190 * 191 * Free a region of bus space. 192 */ 193 194 void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, 195 bus_size_t size); 196 197 /* 198 * void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t); 199 * 200 * Get the kernel virtual address for the mapped bus space. 201 * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR. 202 * (XXX not enforced) 203 */ 204 #define bus_space_vaddr(t, h) (void *)(h) 205 206 /* 207 * int hp300_bus_space_probe(bus_space_tag_t t, 208 * bus_space_handle_t bsh, bus_size_t offset, int sz); 209 * 210 * Probe the bus at t/bsh/offset, using sz as the size of the load. 211 * 212 * This is a machine-dependent extension, and is not to be used by 213 * machine-independent code. 214 */ 215 216 int hp300_bus_space_probe(bus_space_tag_t t, 217 bus_space_handle_t bsh, bus_size_t offset, int sz); 218 219 /* 220 * u_intN_t bus_space_read_N(bus_space_tag_t tag, 221 * bus_space_handle_t bsh, bus_size_t offset); 222 * 223 * Read a 1, 2, 4, or 8 byte quantity from bus space 224 * described by tag/handle/offset. 225 */ 226 227 #define bus_space_read_1(t, h, o) \ 228 (((t)->bsr1 != NULL) ? ((t)->bsr1)(t, h, o) : \ 229 (*(volatile uint8_t *)((h) + (o)))) 230 231 #define bus_space_read_2(t, h, o) \ 232 (((t)->bsr2 != NULL) ? ((t)->bsr2)(t, h, o) : \ 233 (*(volatile uint16_t *)((h) + (o)))) 234 235 #define bus_space_read_4(t, h, o) \ 236 (((t)->bsr4 != NULL) ? ((t)->bsr4)(t, h, o) : \ 237 (*(volatile uint32_t *)((h) + (o)))) 238 239 #if 0 /* Cause a link error for bus_space_read_8 */ 240 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! 241 #endif 242 243 /* 244 * void bus_space_read_multi_N(bus_space_tag_t tag, 245 * bus_space_handle_t bsh, bus_size_t offset, 246 * u_intN_t *addr, size_t count); 247 * 248 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 249 * described by tag/handle/offset and copy into buffer provided. 250 */ 251 252 #define bus_space_read_multi_1(t, h, o, a, c) \ 253 do { \ 254 if ((t)->bsrm1 != NULL) \ 255 ((t)->bsrm1)(t, h, o, a, c); \ 256 else { \ 257 __asm volatile (" \ 258 movl %0,%%a0 ; \ 259 movl %1,%%a1 ; \ 260 movl %2,%%d0 ; \ 261 1: movb %%a0@,%%a1@+ ; \ 262 subql #1,%%d0 ; \ 263 jne 1b" : \ 264 : \ 265 "r" ((h) + (o)), "g" (a), "g" (c) : \ 266 "%a0","%a1","%d0"); \ 267 } \ 268 } while (/* CONSTCOND */ 0) 269 270 #define bus_space_read_multi_2(t, h, o, a, c) \ 271 do { \ 272 if ((t)->bsrm2 != NULL) \ 273 ((t)->bsrm2)(t, h, o, a, c); \ 274 else { \ 275 __asm volatile (" \ 276 movl %0,%%a0 ; \ 277 movl %1,%%a1 ; \ 278 movl %2,%%d0 ; \ 279 1: movw %%a0@,%%a1@+ ; \ 280 subql #1,%%d0 ; \ 281 jne 1b" : \ 282 : \ 283 "r" ((h) + (o)), "g" (a), "g" (c) : \ 284 "%a0","%a1","%d0"); \ 285 } \ 286 } while (/* CONSTCOND */ 0) 287 288 #define bus_space_read_multi_4(t, h, o, a, c) do { \ 289 if ((t)->bsrm4 != NULL) \ 290 ((t)->bsrm4)(t, h, o, a, c); \ 291 else { \ 292 __asm volatile (" \ 293 movl %0,%%a0 ; \ 294 movl %1,%%a1 ; \ 295 movl %2,%%d0 ; \ 296 1: movl %%a0@,%%a1@+ ; \ 297 subql #1,%%d0 ; \ 298 jne 1b" : \ 299 : \ 300 "r" ((h) + (o)), "g" (a), "g" (c) : \ 301 "%a0","%a1","%d0"); \ 302 } \ 303 } while (/* CONSTCOND */ 0) 304 305 #if 0 /* Cause a link error for bus_space_read_multi_8 */ 306 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! 307 #endif 308 309 /* 310 * void bus_space_read_region_N(bus_space_tag_t tag, 311 * bus_space_handle_t bsh, bus_size_t offset, 312 * u_intN_t *addr, size_t count); 313 * 314 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 315 * described by tag/handle and starting at `offset' and copy into 316 * buffer provided. 317 */ 318 319 #define bus_space_read_region_1(t, h, o, a, c) \ 320 do { \ 321 if ((t)->bsrr1 != NULL) \ 322 ((t)->bsrr1)(t, h, o, a, c); \ 323 else { \ 324 __asm volatile (" \ 325 movl %0,%%a0 ; \ 326 movl %1,%%a1 ; \ 327 movl %2,%%d0 ; \ 328 1: movb %%a0@+,%%a1@+ ; \ 329 subql #1,%%d0 ; \ 330 jne 1b" : \ 331 : \ 332 "r" ((h) + (o)), "g" (a), "g" (c) : \ 333 "%a0","%a1","%d0"); \ 334 } \ 335 } while (/* CONSTCOND */ 0) 336 337 #define bus_space_read_region_2(t, h, o, a, c) \ 338 do { \ 339 if ((t)->bsrr2 != NULL) \ 340 ((t)->bsrr2)(t, h, o, a, c); \ 341 else { \ 342 __asm volatile (" \ 343 movl %0,%%a0 ; \ 344 movl %1,%%a1 ; \ 345 movl %2,%%d0 ; \ 346 1: movw %%a0@+,%%a1@+ ; \ 347 subql #1,%%d0 ; \ 348 jne 1b" : \ 349 : \ 350 "r" ((h) + (o)), "g" (a), "g" (c) : \ 351 "%a0","%a1","%d0"); \ 352 } \ 353 } while (/* CONSTCOND */ 0) 354 355 #define bus_space_read_region_4(t, h, o, a, c) \ 356 do { \ 357 if ((t)->bsrr4 != NULL) \ 358 ((t)->bsrr4)(t, h, o, a, c); \ 359 else { \ 360 __asm volatile (" \ 361 movl %0,%%a0 ; \ 362 movl %1,%%a1 ; \ 363 movl %2,%%d0 ; \ 364 1: movl %%a0@+,%%a1@+ ; \ 365 subql #1,%%d0 ; \ 366 jne 1b" : \ 367 : \ 368 "r" ((h) + (o)), "g" (a), "g" (c) : \ 369 "%a0","%a1","%d0"); \ 370 } \ 371 } while (/* CONSTCOND */ 0) 372 373 #if 0 /* Cause a link error for bus_space_read_region_8 */ 374 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! 375 #endif 376 377 /* 378 * void bus_space_write_N(bus_space_tag_t tag, 379 * bus_space_handle_t bsh, bus_size_t offset, 380 * u_intN_t value); 381 * 382 * Write the 1, 2, 4, or 8 byte value `value' to bus space 383 * described by tag/handle/offset. 384 */ 385 386 #define bus_space_write_1(t, h, o, v) \ 387 do { \ 388 if ((t)->bsw1 != NULL) \ 389 ((t)->bsw1)(t, h, o, v); \ 390 else \ 391 ((void)(*(volatile uint8_t *)((h) + (o)) = (v))); \ 392 } while (/* CONSTCOND */ 0) 393 394 #define bus_space_write_2(t, h, o, v) \ 395 do { \ 396 if ((t)->bsw2 != NULL) \ 397 ((t)->bsw2)(t, h, o, v); \ 398 else \ 399 ((void)(*(volatile uint16_t *)((h) + (o)) = (v))); \ 400 } while (/* CONSTCOND */ 0) 401 402 #define bus_space_write_4(t, h, o, v) \ 403 do { \ 404 if ((t)->bsw4 != NULL) \ 405 ((t)->bsw4)(t, h, o, v); \ 406 else \ 407 ((void)(*(volatile uint32_t *)((h) + (o)) = (v))); \ 408 } while (/* CONSTCOND */ 0) 409 410 #if 0 /* Cause a link error for bus_space_write_8 */ 411 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!! 412 #endif 413 414 /* 415 * void bus_space_write_multi_N(bus_space_tag_t tag, 416 * bus_space_handle_t bsh, bus_size_t offset, 417 * const u_intN_t *addr, size_t count); 418 * 419 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 420 * provided to bus space described by tag/handle/offset. 421 */ 422 423 #define bus_space_write_multi_1(t, h, o, a, c) \ 424 do { \ 425 if ((t)->bswm1 != NULL) \ 426 ((t)->bswm1)(t, h, o, a, c); \ 427 else { \ 428 __asm volatile (" \ 429 movl %0,%%a0 ; \ 430 movl %1,%%a1 ; \ 431 movl %2,%%d0 ; \ 432 1: movb %%a1@+,%%a0@ ; \ 433 subql #1,%%d0 ; \ 434 jne 1b" : \ 435 : \ 436 "r" ((h) + (o)), "g" (a), "g" (c) : \ 437 "%a0","%a1","%d0"); \ 438 } \ 439 } while (/* CONSTCOND */ 0) 440 441 #define bus_space_write_multi_2(t, h, o, a, c) \ 442 do { \ 443 if ((t)->bswm2 != NULL) \ 444 ((t)->bswm2)(t, h, o, a, c); \ 445 else { \ 446 __asm volatile (" \ 447 movl %0,%%a0 ; \ 448 movl %1,%%a1 ; \ 449 movl %2,%%d0 ; \ 450 1: movw %%a1@+,%%a0@ ; \ 451 subql #1,%%d0 ; \ 452 jne 1b" : \ 453 : \ 454 "r" ((h) + (o)), "g" (a), "g" (c) : \ 455 "%a0","%a1","%d0"); \ 456 } \ 457 } while (/* CONSTCOND */ 0) 458 459 #define bus_space_write_multi_4(t, h, o, a, c) \ 460 do { \ 461 (void) t; \ 462 if ((t)->bswm4 != NULL) \ 463 ((t)->bswm4)(t, h, o, a, c); \ 464 else { \ 465 __asm volatile (" \ 466 movl %0,%%a0 ; \ 467 movl %1,%%a1 ; \ 468 movl %2,%%d0 ; \ 469 1: movl %%a1@+,%%a0@ ; \ 470 subql #1,%%d0 ; \ 471 jne 1b" : \ 472 : \ 473 "r" ((h) + (o)), "g" (a), "g" (c) : \ 474 "%a0","%a1","%d0"); \ 475 } \ 476 } while (/* CONSTCOND */ 0) 477 478 #if 0 /* Cause a link error for bus_space_write_8 */ 479 #define bus_space_write_multi_8(t, h, o, a, c) \ 480 !!! bus_space_write_multi_8 unimplimented !!! 481 #endif 482 483 /* 484 * void bus_space_write_region_N(bus_space_tag_t tag, 485 * bus_space_handle_t bsh, bus_size_t offset, 486 * const u_intN_t *addr, size_t count); 487 * 488 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 489 * to bus space described by tag/handle starting at `offset'. 490 */ 491 492 #define bus_space_write_region_1(t, h, o, a, c) \ 493 do { \ 494 if ((t)->bswr1 != NULL) \ 495 ((t)->bswr1)(t, h, o, a, c); \ 496 else { \ 497 __asm volatile (" \ 498 movl %0,%%a0 ; \ 499 movl %1,%%a1 ; \ 500 movl %2,%%d0 ; \ 501 1: movb %%a1@+,%%a0@+ ; \ 502 subql #1,%%d0 ; \ 503 jne 1b" : \ 504 : \ 505 "r" ((h) + (o)), "g" (a), "g" (c) : \ 506 "%a0","%a1","%d0"); \ 507 } \ 508 } while (/* CONSTCOND */ 0) 509 510 #define bus_space_write_region_2(t, h, o, a, c) \ 511 do { \ 512 if ((t)->bswr2) != NULL) \ 513 ((t)->bswr2)(t, h, o, a, c); \ 514 else { \ 515 __asm volatile (" \ 516 movl %0,%%a0 ; \ 517 movl %1,%%a1 ; \ 518 movl %2,%%d0 ; \ 519 1: movw %%a1@+,%%a0@+ ; \ 520 subql #1,%%d0 ; \ 521 jne 1b" : \ 522 : \ 523 "r" ((h) + (o)), "g" (a), "g" (c) : \ 524 "%a0","%a1","%d0"); \ 525 } \ 526 } while (/* CONSTCOND */ 0) 527 528 #define bus_space_write_region_4(t, h, o, a, c) \ 529 do { \ 530 if ((t)->bswr4) != NULL) \ 531 ((t)->bswr4)(t, h, o, a, c); \ 532 else { \ 533 __asm volatile (" \ 534 movl %0,%%a0 ; \ 535 movl %1,%%a1 ; \ 536 movl %2,%%d0 ; \ 537 1: movl %%a1@+,%%a0@+ ; \ 538 subql #1,%%d0 ; \ 539 jne 1b" : \ 540 : \ 541 "r" ((h) + (o)), "g" (a), "g" (c) : \ 542 "%a0","%a1","%d0"); \ 543 } \ 544 } while (/* CONSTCOND */ 0) 545 546 #if 0 /* Cause a link error for bus_space_write_region_8 */ 547 #define bus_space_write_region_8 \ 548 !!! bus_space_write_region_8 unimplemented !!! 549 #endif 550 551 /* 552 * void bus_space_set_multi_N(bus_space_tag_t tag, 553 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 554 * size_t count); 555 * 556 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 557 * by tag/handle/offset `count' times. 558 */ 559 560 #define bus_space_set_multi_1(t, h, o, val, c) \ 561 do { \ 562 if ((t)->bssm1 != NULL) \ 563 ((t)->bssm1)(t, h, o, val, c); \ 564 else { \ 565 __asm volatile (" \ 566 movl %0,%%a0 ; \ 567 movl %1,%%d1 ; \ 568 movl %2,%%d0 ; \ 569 1: movb %%d1,%%a0@ ; \ 570 subql #1,%%d0 ; \ 571 jne 1b" : \ 572 : \ 573 "r" ((h) + (o)), "g" (val), "g" (c) : \ 574 "%a0","%d0","%d1"); \ 575 } \ 576 } while (/* CONSTCOND */ 0) 577 578 #define bus_space_set_multi_2(t, h, o, val, c) \ 579 do { \ 580 if ((t)->bssm2 != NULL) \ 581 ((t)->bssm2)(t, h, o, val, c); \ 582 else { \ 583 __asm volatile (" \ 584 movl %0,%%a0 ; \ 585 movl %1,%%d1 ; \ 586 movl %2,%%d0 ; \ 587 1: movw %%d1,%%a0@ ; \ 588 subql #1,%%d0 ; \ 589 jne 1b" : \ 590 : \ 591 "r" ((h) + (o)), "g" (val), "g" (c) : \ 592 "%a0","%d0","%d1"); \ 593 } \ 594 } while (/* CONSTCOND */ 0) 595 596 #define bus_space_set_multi_4(t, h, o, val, c) \ 597 do { \ 598 if ((t)->bssm4 != NULL) \ 599 ((t)->bssm4)(t, h, o, val, c); \ 600 else { \ 601 __asm volatile (" \ 602 movl %0,%%a0 ; \ 603 movl %1,%%d1 ; \ 604 movl %2,%%d0 ; \ 605 1: movl %%d1,%%a0@ ; \ 606 subql #1,%%d0 ; \ 607 jne 1b" : \ 608 : \ 609 "r" ((h) + (o)), "g" (val), "g" (c) : \ 610 "%a0","%d0","%d1"); \ 611 } \ 612 } while (/* CONSTCOND */ 0) 613 614 #if 0 /* Cause a link error for bus_space_set_multi_8 */ 615 #define bus_space_set_multi_8 \ 616 !!! bus_space_set_multi_8 unimplemented !!! 617 #endif 618 619 /* 620 * void bus_space_set_region_N(bus_space_tag_t tag, 621 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 622 * size_t count); 623 * 624 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 625 * by tag/handle starting at `offset'. 626 */ 627 628 #define bus_space_set_region_1(t, h, o, val, c) \ 629 do { \ 630 if ((t)->bssr1 != NULL) \ 631 ((t)->bssr1)(t, h, o, val, c); \ 632 else { \ 633 __asm volatile (" \ 634 movl %0,%%a0 ; \ 635 movl %1,%%d1 ; \ 636 movl %2,%%d0 ; \ 637 1: movb %%d1,%%a0@+ ; \ 638 subql #1,%%d0 ; \ 639 jne 1b" : \ 640 : \ 641 "r" ((h) + (o)), "g" (val), "g" (c) : \ 642 "%a0","%d0","%d1"); \ 643 } \ 644 } while (/* CONSTCOND */ 0) 645 646 #define bus_space_set_region_2(t, h, o, val, c) \ 647 do { \ 648 if ((t)->bssr2 != NULL) \ 649 ((t)->bssr2)(t, h, o, val, c); \ 650 else { \ 651 __asm volatile (" \ 652 movl %0,%%a0 ; \ 653 movl %1,%%d1 ; \ 654 movl %2,%%d0 ; \ 655 1: movw %%d1,%%a0@+ ; \ 656 subql #1,%%d0 ; \ 657 jne 1b" : \ 658 : \ 659 "r" ((h) + (o)), "g" (val), "g" (c) : \ 660 "%a0","%d0","%d1"); \ 661 } \ 662 } while (/* CONSTCOND */ 0) 663 664 #define bus_space_set_region_4(t, h, o, val, c) \ 665 do { \ 666 (void) t; \ 667 if ((t)->bssr4 != NULL) \ 668 ((t)->bssr4)(t, h, o, val, c); \ 669 else { \ 670 __asm volatile (" \ 671 movl %0,%%a0 ; \ 672 movl %1,%%d1 ; \ 673 movl %2,%%d0 ; \ 674 1: movl %%d1,%%a0@+ ; \ 675 subql #1,%%d0 ; \ 676 jne 1b" : \ 677 : \ 678 "r" ((h) + (o)), "g" (val), "g" (c) : \ 679 "%a0","%d0","%d1"); \ 680 } \ 681 } while (/* CONSTCOND */ 0) 682 683 #if 0 /* Cause a link error for bus_space_set_region_8 */ 684 #define bus_space_set_region_8 \ 685 !!! bus_space_set_region_8 unimplemented !!! 686 #endif 687 688 /* 689 * void bus_space_copy_region_N(bus_space_tag_t tag, 690 * bus_space_handle_t bsh1, bus_size_t off1, 691 * bus_space_handle_t bsh2, bus_size_t off2, 692 * bus_size_t count); 693 * 694 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 695 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 696 */ 697 698 #define __HP300_copy_region_N(BYTES) \ 699 static __inline void \ 700 __CONCAT(bus_space_copy_region_,BYTES)(bus_space_tag_t t, \ 701 bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, \ 702 bus_size_t o2, bus_size_t c) \ 703 { \ 704 bus_size_t o; \ 705 \ 706 if ((h1 + o1) >= (h2 + o2)) { \ 707 /* src after dest: copy forward */ \ 708 for (o = 0; c != 0; c--, o += BYTES) \ 709 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 710 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 711 } else { \ 712 /* dest after src: copy backwards */ \ 713 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 714 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 715 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 716 } \ 717 } 718 __HP300_copy_region_N(1) 719 __HP300_copy_region_N(2) 720 __HP300_copy_region_N(4) 721 #if 0 /* Cause a link error for bus_space_copy_region_8 */ 722 #define bus_space_copy_region_8 \ 723 !!! bus_space_copy_region_8 unimplemented !!! 724 #endif 725 726 #undef __HP300_copy_region_N 727 728 /* 729 * Bus read/write barrier methods. 730 * 731 * void bus_space_barrier(bus_space_tag_t tag, 732 * bus_space_handle_t bsh, bus_size_t offset, 733 * bus_size_t len, int flags); 734 * 735 * Note: the 680x0 does not currently require barriers, but we must 736 * provide the flags to MI code. 737 */ 738 #define bus_space_barrier(t, h, o, l, f) \ 739 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 740 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 741 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 742 743 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 744 745 #endif /* _HP300_BUS_H_ */ 746