1 /* $NetBSD: bus.h,v 1.18 2012/05/07 18:16:38 tsutsui 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 #define HP300_BUS_SPACE_SGC 2 /* space is sgc space */ 68 69 /* 70 * Bus address and size types 71 */ 72 typedef u_long bus_addr_t; 73 typedef u_long bus_size_t; 74 75 /* 76 * Access methods for bus resources and address space. 77 */ 78 typedef struct bus_space_tag *bus_space_tag_t; 79 typedef u_long bus_space_handle_t; 80 81 /* 82 * Implementation specific structures. 83 * XXX Don't use outside of bus_space definitions! 84 * XXX maybe this should be encapsuled in a non-global .h file? 85 */ 86 87 struct bus_space_tag { 88 u_int bustype; 89 90 uint8_t (*bsr1)(bus_space_tag_t, bus_space_handle_t, 91 bus_size_t); 92 uint16_t (*bsr2)(bus_space_tag_t, bus_space_handle_t, 93 bus_size_t); 94 uint32_t (*bsr4)(bus_space_tag_t, bus_space_handle_t, 95 bus_size_t); 96 void (*bsrm1)(bus_space_tag_t, bus_space_handle_t, 97 bus_size_t, uint8_t *, bus_size_t); 98 void (*bsrm2)(bus_space_tag_t, bus_space_handle_t, 99 bus_size_t, uint16_t *, bus_size_t); 100 void (*bsrm4)(bus_space_tag_t, bus_space_handle_t, 101 bus_size_t, uint32_t *, bus_size_t); 102 void (*bsrr1)(bus_space_tag_t, bus_space_handle_t, 103 bus_size_t, uint8_t *, bus_size_t); 104 void (*bsrr2)(bus_space_tag_t, bus_space_handle_t, 105 bus_size_t, uint16_t *, bus_size_t); 106 void (*bsrr4)(bus_space_tag_t, bus_space_handle_t, 107 bus_size_t, uint32_t *, bus_size_t); 108 void (*bsw1)(bus_space_tag_t, bus_space_handle_t, 109 bus_size_t, uint8_t); 110 void (*bsw2)(bus_space_tag_t, bus_space_handle_t, 111 bus_size_t, uint16_t); 112 void (*bsw4)(bus_space_tag_t, bus_space_handle_t, 113 bus_size_t, uint32_t); 114 void (*bswm1)(bus_space_tag_t, bus_space_handle_t, 115 bus_size_t, const uint8_t *, bus_size_t); 116 void (*bswm2)(bus_space_tag_t, bus_space_handle_t, 117 bus_size_t, const uint16_t *, bus_size_t); 118 void (*bswm4)(bus_space_tag_t, bus_space_handle_t, 119 bus_size_t, const uint32_t *, bus_size_t); 120 void (*bswr1)(bus_space_tag_t, bus_space_handle_t , 121 bus_size_t, const uint8_t *, bus_size_t); 122 void (*bswr2)(bus_space_tag_t, bus_space_handle_t, 123 bus_size_t, const uint16_t *, bus_size_t); 124 void (*bswr4)(bus_space_tag_t, bus_space_handle_t, 125 bus_size_t, const uint32_t *, bus_size_t); 126 void (*bssm1)(bus_space_tag_t, bus_space_handle_t, 127 bus_size_t, uint8_t, bus_size_t); 128 void (*bssm2)(bus_space_tag_t, bus_space_handle_t, 129 bus_size_t, uint16_t, bus_size_t); 130 void (*bssm4)(bus_space_tag_t, bus_space_handle_t, 131 bus_size_t, uint32_t, bus_size_t); 132 void (*bssr1)(bus_space_tag_t, bus_space_handle_t, 133 bus_size_t, uint8_t, bus_size_t); 134 void (*bssr2)(bus_space_tag_t, bus_space_handle_t, 135 bus_size_t, uint16_t, bus_size_t); 136 void (*bssr4)(bus_space_tag_t, bus_space_handle_t, 137 bus_size_t, uint32_t, bus_size_t); 138 }; 139 140 /* 141 * int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 142 * bus_size_t size, int flags, bus_space_handle_t *bshp); 143 * 144 * Map a region of bus space. 145 */ 146 147 #define BUS_SPACE_MAP_CACHEABLE 0x01 148 #define BUS_SPACE_MAP_LINEAR 0x02 149 #define BUS_SPACE_MAP_PREFETCHABLE 0x04 150 151 int bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, 152 int, bus_space_handle_t *); 153 154 /* 155 * void bus_space_unmap(bus_space_tag_t t, 156 * bus_space_handle_t bsh, bus_size_t size); 157 * 158 * Unmap a region of bus space. 159 */ 160 161 void bus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t); 162 163 /* 164 * int bus_space_subregion(bus_space_tag_t t, 165 * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, 166 * bus_space_handle_t *nbshp); 167 * 168 * Get a new handle for a subregion of an already-mapped area of bus space. 169 */ 170 171 int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 172 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp); 173 174 /* 175 * int bus_space_alloc(bus_space_tag_t t, bus_addr_t, rstart, 176 * bus_addr_t rend, bus_size_t size, bus_size_t align, 177 * bus_size_t boundary, int flags, bus_addr_t *addrp, 178 * bus_space_handle_t *bshp); 179 * 180 * Allocate a region of bus space. 181 */ 182 183 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 184 bus_addr_t rend, bus_size_t size, bus_size_t align, 185 bus_size_t boundary, int cacheable, bus_addr_t *addrp, 186 bus_space_handle_t *bshp); 187 188 /* 189 * int bus_space_free(bus_space_tag_t t, 190 * bus_space_handle_t bsh, bus_size_t size); 191 * 192 * Free a region of bus space. 193 */ 194 195 void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, 196 bus_size_t size); 197 198 /* 199 * void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t); 200 * 201 * Get the kernel virtual address for the mapped bus space. 202 * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR. 203 * (XXX not enforced) 204 */ 205 #define bus_space_vaddr(t, h) (void *)(h) 206 207 /* 208 * int hp300_bus_space_probe(bus_space_tag_t t, 209 * bus_space_handle_t bsh, bus_size_t offset, int sz); 210 * 211 * Probe the bus at t/bsh/offset, using sz as the size of the load. 212 * 213 * This is a machine-dependent extension, and is not to be used by 214 * machine-independent code. 215 */ 216 217 int hp300_bus_space_probe(bus_space_tag_t t, 218 bus_space_handle_t bsh, bus_size_t offset, int sz); 219 220 /* 221 * u_intN_t bus_space_read_N(bus_space_tag_t tag, 222 * bus_space_handle_t bsh, bus_size_t offset); 223 * 224 * Read a 1, 2, 4, or 8 byte quantity from bus space 225 * described by tag/handle/offset. 226 */ 227 228 #define bus_space_read_1(t, h, o) \ 229 (((t)->bsr1 != NULL) ? ((t)->bsr1)(t, h, o) : \ 230 (*(volatile uint8_t *)((h) + (o)))) 231 232 #define bus_space_read_2(t, h, o) \ 233 (((t)->bsr2 != NULL) ? ((t)->bsr2)(t, h, o) : \ 234 (*(volatile uint16_t *)((h) + (o)))) 235 236 #define bus_space_read_4(t, h, o) \ 237 (((t)->bsr4 != NULL) ? ((t)->bsr4)(t, h, o) : \ 238 (*(volatile uint32_t *)((h) + (o)))) 239 240 #if 0 /* Cause a link error for bus_space_read_8 */ 241 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! 242 #endif 243 244 /* 245 * void bus_space_read_multi_N(bus_space_tag_t tag, 246 * bus_space_handle_t bsh, bus_size_t offset, 247 * u_intN_t *addr, size_t count); 248 * 249 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 250 * described by tag/handle/offset and copy into buffer provided. 251 */ 252 253 #define bus_space_read_multi_1(t, h, o, a, c) \ 254 do { \ 255 if ((t)->bsrm1 != NULL) \ 256 ((t)->bsrm1)(t, h, o, a, c); \ 257 else { \ 258 __asm volatile (" \ 259 movl %0,%%a0 ; \ 260 movl %1,%%a1 ; \ 261 movl %2,%%d0 ; \ 262 1: movb %%a0@,%%a1@+ ; \ 263 subql #1,%%d0 ; \ 264 jne 1b" : \ 265 : \ 266 "r" ((h) + (o)), "g" (a), "g" (c) : \ 267 "%a0","%a1","%d0"); \ 268 } \ 269 } while (/* CONSTCOND */ 0) 270 271 #define bus_space_read_multi_2(t, h, o, a, c) \ 272 do { \ 273 if ((t)->bsrm2 != NULL) \ 274 ((t)->bsrm2)(t, h, o, a, c); \ 275 else { \ 276 __asm volatile (" \ 277 movl %0,%%a0 ; \ 278 movl %1,%%a1 ; \ 279 movl %2,%%d0 ; \ 280 1: movw %%a0@,%%a1@+ ; \ 281 subql #1,%%d0 ; \ 282 jne 1b" : \ 283 : \ 284 "r" ((h) + (o)), "g" (a), "g" (c) : \ 285 "%a0","%a1","%d0"); \ 286 } \ 287 } while (/* CONSTCOND */ 0) 288 289 #define bus_space_read_multi_4(t, h, o, a, c) do { \ 290 if ((t)->bsrm4 != NULL) \ 291 ((t)->bsrm4)(t, h, o, a, c); \ 292 else { \ 293 __asm volatile (" \ 294 movl %0,%%a0 ; \ 295 movl %1,%%a1 ; \ 296 movl %2,%%d0 ; \ 297 1: movl %%a0@,%%a1@+ ; \ 298 subql #1,%%d0 ; \ 299 jne 1b" : \ 300 : \ 301 "r" ((h) + (o)), "g" (a), "g" (c) : \ 302 "%a0","%a1","%d0"); \ 303 } \ 304 } while (/* CONSTCOND */ 0) 305 306 #if 0 /* Cause a link error for bus_space_read_multi_8 */ 307 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! 308 #endif 309 310 /* 311 * void bus_space_read_region_N(bus_space_tag_t tag, 312 * bus_space_handle_t bsh, bus_size_t offset, 313 * u_intN_t *addr, size_t count); 314 * 315 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 316 * described by tag/handle and starting at `offset' and copy into 317 * buffer provided. 318 */ 319 320 #define bus_space_read_region_1(t, h, o, a, c) \ 321 do { \ 322 if ((t)->bsrr1 != NULL) \ 323 ((t)->bsrr1)(t, h, o, a, c); \ 324 else { \ 325 __asm volatile (" \ 326 movl %0,%%a0 ; \ 327 movl %1,%%a1 ; \ 328 movl %2,%%d0 ; \ 329 1: movb %%a0@+,%%a1@+ ; \ 330 subql #1,%%d0 ; \ 331 jne 1b" : \ 332 : \ 333 "r" ((h) + (o)), "g" (a), "g" (c) : \ 334 "%a0","%a1","%d0"); \ 335 } \ 336 } while (/* CONSTCOND */ 0) 337 338 #define bus_space_read_region_2(t, h, o, a, c) \ 339 do { \ 340 if ((t)->bsrr2 != NULL) \ 341 ((t)->bsrr2)(t, h, o, a, c); \ 342 else { \ 343 __asm volatile (" \ 344 movl %0,%%a0 ; \ 345 movl %1,%%a1 ; \ 346 movl %2,%%d0 ; \ 347 1: movw %%a0@+,%%a1@+ ; \ 348 subql #1,%%d0 ; \ 349 jne 1b" : \ 350 : \ 351 "r" ((h) + (o)), "g" (a), "g" (c) : \ 352 "%a0","%a1","%d0"); \ 353 } \ 354 } while (/* CONSTCOND */ 0) 355 356 #define bus_space_read_region_4(t, h, o, a, c) \ 357 do { \ 358 if ((t)->bsrr4 != NULL) \ 359 ((t)->bsrr4)(t, h, o, a, c); \ 360 else { \ 361 __asm volatile (" \ 362 movl %0,%%a0 ; \ 363 movl %1,%%a1 ; \ 364 movl %2,%%d0 ; \ 365 1: movl %%a0@+,%%a1@+ ; \ 366 subql #1,%%d0 ; \ 367 jne 1b" : \ 368 : \ 369 "r" ((h) + (o)), "g" (a), "g" (c) : \ 370 "%a0","%a1","%d0"); \ 371 } \ 372 } while (/* CONSTCOND */ 0) 373 374 #if 0 /* Cause a link error for bus_space_read_region_8 */ 375 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! 376 #endif 377 378 /* 379 * void bus_space_write_N(bus_space_tag_t tag, 380 * bus_space_handle_t bsh, bus_size_t offset, 381 * u_intN_t value); 382 * 383 * Write the 1, 2, 4, or 8 byte value `value' to bus space 384 * described by tag/handle/offset. 385 */ 386 387 #define bus_space_write_1(t, h, o, v) \ 388 do { \ 389 if ((t)->bsw1 != NULL) \ 390 ((t)->bsw1)(t, h, o, v); \ 391 else \ 392 ((void)(*(volatile uint8_t *)((h) + (o)) = (v))); \ 393 } while (/* CONSTCOND */ 0) 394 395 #define bus_space_write_2(t, h, o, v) \ 396 do { \ 397 if ((t)->bsw2 != NULL) \ 398 ((t)->bsw2)(t, h, o, v); \ 399 else \ 400 ((void)(*(volatile uint16_t *)((h) + (o)) = (v))); \ 401 } while (/* CONSTCOND */ 0) 402 403 #define bus_space_write_4(t, h, o, v) \ 404 do { \ 405 if ((t)->bsw4 != NULL) \ 406 ((t)->bsw4)(t, h, o, v); \ 407 else \ 408 ((void)(*(volatile uint32_t *)((h) + (o)) = (v))); \ 409 } while (/* CONSTCOND */ 0) 410 411 #if 0 /* Cause a link error for bus_space_write_8 */ 412 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!! 413 #endif 414 415 /* 416 * void bus_space_write_multi_N(bus_space_tag_t tag, 417 * bus_space_handle_t bsh, bus_size_t offset, 418 * const u_intN_t *addr, size_t count); 419 * 420 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 421 * provided to bus space described by tag/handle/offset. 422 */ 423 424 #define bus_space_write_multi_1(t, h, o, a, c) \ 425 do { \ 426 if ((t)->bswm1 != NULL) \ 427 ((t)->bswm1)(t, h, o, a, c); \ 428 else { \ 429 __asm volatile (" \ 430 movl %0,%%a0 ; \ 431 movl %1,%%a1 ; \ 432 movl %2,%%d0 ; \ 433 1: movb %%a1@+,%%a0@ ; \ 434 subql #1,%%d0 ; \ 435 jne 1b" : \ 436 : \ 437 "r" ((h) + (o)), "g" (a), "g" (c) : \ 438 "%a0","%a1","%d0"); \ 439 } \ 440 } while (/* CONSTCOND */ 0) 441 442 #define bus_space_write_multi_2(t, h, o, a, c) \ 443 do { \ 444 if ((t)->bswm2 != NULL) \ 445 ((t)->bswm2)(t, h, o, a, c); \ 446 else { \ 447 __asm volatile (" \ 448 movl %0,%%a0 ; \ 449 movl %1,%%a1 ; \ 450 movl %2,%%d0 ; \ 451 1: movw %%a1@+,%%a0@ ; \ 452 subql #1,%%d0 ; \ 453 jne 1b" : \ 454 : \ 455 "r" ((h) + (o)), "g" (a), "g" (c) : \ 456 "%a0","%a1","%d0"); \ 457 } \ 458 } while (/* CONSTCOND */ 0) 459 460 #define bus_space_write_multi_4(t, h, o, a, c) \ 461 do { \ 462 (void) t; \ 463 if ((t)->bswm4 != NULL) \ 464 ((t)->bswm4)(t, h, o, a, c); \ 465 else { \ 466 __asm volatile (" \ 467 movl %0,%%a0 ; \ 468 movl %1,%%a1 ; \ 469 movl %2,%%d0 ; \ 470 1: movl %%a1@+,%%a0@ ; \ 471 subql #1,%%d0 ; \ 472 jne 1b" : \ 473 : \ 474 "r" ((h) + (o)), "g" (a), "g" (c) : \ 475 "%a0","%a1","%d0"); \ 476 } \ 477 } while (/* CONSTCOND */ 0) 478 479 #if 0 /* Cause a link error for bus_space_write_8 */ 480 #define bus_space_write_multi_8(t, h, o, a, c) \ 481 !!! bus_space_write_multi_8 unimplimented !!! 482 #endif 483 484 /* 485 * void bus_space_write_region_N(bus_space_tag_t tag, 486 * bus_space_handle_t bsh, bus_size_t offset, 487 * const u_intN_t *addr, size_t count); 488 * 489 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 490 * to bus space described by tag/handle starting at `offset'. 491 */ 492 493 #define bus_space_write_region_1(t, h, o, a, c) \ 494 do { \ 495 if ((t)->bswr1 != NULL) \ 496 ((t)->bswr1)(t, h, o, a, c); \ 497 else { \ 498 __asm volatile (" \ 499 movl %0,%%a0 ; \ 500 movl %1,%%a1 ; \ 501 movl %2,%%d0 ; \ 502 1: movb %%a1@+,%%a0@+ ; \ 503 subql #1,%%d0 ; \ 504 jne 1b" : \ 505 : \ 506 "r" ((h) + (o)), "g" (a), "g" (c) : \ 507 "%a0","%a1","%d0"); \ 508 } \ 509 } while (/* CONSTCOND */ 0) 510 511 #define bus_space_write_region_2(t, h, o, a, c) \ 512 do { \ 513 if ((t)->bswr2) != NULL) \ 514 ((t)->bswr2)(t, h, o, a, c); \ 515 else { \ 516 __asm volatile (" \ 517 movl %0,%%a0 ; \ 518 movl %1,%%a1 ; \ 519 movl %2,%%d0 ; \ 520 1: movw %%a1@+,%%a0@+ ; \ 521 subql #1,%%d0 ; \ 522 jne 1b" : \ 523 : \ 524 "r" ((h) + (o)), "g" (a), "g" (c) : \ 525 "%a0","%a1","%d0"); \ 526 } \ 527 } while (/* CONSTCOND */ 0) 528 529 #define bus_space_write_region_4(t, h, o, a, c) \ 530 do { \ 531 if ((t)->bswr4) != NULL) \ 532 ((t)->bswr4)(t, h, o, a, c); \ 533 else { \ 534 __asm volatile (" \ 535 movl %0,%%a0 ; \ 536 movl %1,%%a1 ; \ 537 movl %2,%%d0 ; \ 538 1: movl %%a1@+,%%a0@+ ; \ 539 subql #1,%%d0 ; \ 540 jne 1b" : \ 541 : \ 542 "r" ((h) + (o)), "g" (a), "g" (c) : \ 543 "%a0","%a1","%d0"); \ 544 } \ 545 } while (/* CONSTCOND */ 0) 546 547 #if 0 /* Cause a link error for bus_space_write_region_8 */ 548 #define bus_space_write_region_8 \ 549 !!! bus_space_write_region_8 unimplemented !!! 550 #endif 551 552 /* 553 * void bus_space_set_multi_N(bus_space_tag_t tag, 554 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 555 * size_t count); 556 * 557 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 558 * by tag/handle/offset `count' times. 559 */ 560 561 #define bus_space_set_multi_1(t, h, o, val, c) \ 562 do { \ 563 if ((t)->bssm1 != NULL) \ 564 ((t)->bssm1)(t, h, o, val, c); \ 565 else { \ 566 __asm volatile (" \ 567 movl %0,%%a0 ; \ 568 movl %1,%%d1 ; \ 569 movl %2,%%d0 ; \ 570 1: movb %%d1,%%a0@ ; \ 571 subql #1,%%d0 ; \ 572 jne 1b" : \ 573 : \ 574 "r" ((h) + (o)), "g" (val), "g" (c) : \ 575 "%a0","%d0","%d1"); \ 576 } \ 577 } while (/* CONSTCOND */ 0) 578 579 #define bus_space_set_multi_2(t, h, o, val, c) \ 580 do { \ 581 if ((t)->bssm2 != NULL) \ 582 ((t)->bssm2)(t, h, o, val, c); \ 583 else { \ 584 __asm volatile (" \ 585 movl %0,%%a0 ; \ 586 movl %1,%%d1 ; \ 587 movl %2,%%d0 ; \ 588 1: movw %%d1,%%a0@ ; \ 589 subql #1,%%d0 ; \ 590 jne 1b" : \ 591 : \ 592 "r" ((h) + (o)), "g" (val), "g" (c) : \ 593 "%a0","%d0","%d1"); \ 594 } \ 595 } while (/* CONSTCOND */ 0) 596 597 #define bus_space_set_multi_4(t, h, o, val, c) \ 598 do { \ 599 if ((t)->bssm4 != NULL) \ 600 ((t)->bssm4)(t, h, o, val, c); \ 601 else { \ 602 __asm volatile (" \ 603 movl %0,%%a0 ; \ 604 movl %1,%%d1 ; \ 605 movl %2,%%d0 ; \ 606 1: movl %%d1,%%a0@ ; \ 607 subql #1,%%d0 ; \ 608 jne 1b" : \ 609 : \ 610 "r" ((h) + (o)), "g" (val), "g" (c) : \ 611 "%a0","%d0","%d1"); \ 612 } \ 613 } while (/* CONSTCOND */ 0) 614 615 #if 0 /* Cause a link error for bus_space_set_multi_8 */ 616 #define bus_space_set_multi_8 \ 617 !!! bus_space_set_multi_8 unimplemented !!! 618 #endif 619 620 /* 621 * void bus_space_set_region_N(bus_space_tag_t tag, 622 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 623 * size_t count); 624 * 625 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 626 * by tag/handle starting at `offset'. 627 */ 628 629 #define bus_space_set_region_1(t, h, o, val, c) \ 630 do { \ 631 if ((t)->bssr1 != NULL) \ 632 ((t)->bssr1)(t, h, o, val, c); \ 633 else { \ 634 __asm volatile (" \ 635 movl %0,%%a0 ; \ 636 movl %1,%%d1 ; \ 637 movl %2,%%d0 ; \ 638 1: movb %%d1,%%a0@+ ; \ 639 subql #1,%%d0 ; \ 640 jne 1b" : \ 641 : \ 642 "r" ((h) + (o)), "g" (val), "g" (c) : \ 643 "%a0","%d0","%d1"); \ 644 } \ 645 } while (/* CONSTCOND */ 0) 646 647 #define bus_space_set_region_2(t, h, o, val, c) \ 648 do { \ 649 if ((t)->bssr2 != NULL) \ 650 ((t)->bssr2)(t, h, o, val, c); \ 651 else { \ 652 __asm volatile (" \ 653 movl %0,%%a0 ; \ 654 movl %1,%%d1 ; \ 655 movl %2,%%d0 ; \ 656 1: movw %%d1,%%a0@+ ; \ 657 subql #1,%%d0 ; \ 658 jne 1b" : \ 659 : \ 660 "r" ((h) + (o)), "g" (val), "g" (c) : \ 661 "%a0","%d0","%d1"); \ 662 } \ 663 } while (/* CONSTCOND */ 0) 664 665 #define bus_space_set_region_4(t, h, o, val, c) \ 666 do { \ 667 (void) t; \ 668 if ((t)->bssr4 != NULL) \ 669 ((t)->bssr4)(t, h, o, val, c); \ 670 else { \ 671 __asm volatile (" \ 672 movl %0,%%a0 ; \ 673 movl %1,%%d1 ; \ 674 movl %2,%%d0 ; \ 675 1: movl %%d1,%%a0@+ ; \ 676 subql #1,%%d0 ; \ 677 jne 1b" : \ 678 : \ 679 "r" ((h) + (o)), "g" (val), "g" (c) : \ 680 "%a0","%d0","%d1"); \ 681 } \ 682 } while (/* CONSTCOND */ 0) 683 684 #if 0 /* Cause a link error for bus_space_set_region_8 */ 685 #define bus_space_set_region_8 \ 686 !!! bus_space_set_region_8 unimplemented !!! 687 #endif 688 689 /* 690 * void bus_space_copy_region_N(bus_space_tag_t tag, 691 * bus_space_handle_t bsh1, bus_size_t off1, 692 * bus_space_handle_t bsh2, bus_size_t off2, 693 * bus_size_t count); 694 * 695 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 696 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 697 */ 698 699 #define __HP300_copy_region_N(BYTES) \ 700 static __inline void \ 701 __CONCAT(bus_space_copy_region_,BYTES)(bus_space_tag_t t, \ 702 bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, \ 703 bus_size_t o2, bus_size_t c) \ 704 { \ 705 bus_size_t o; \ 706 \ 707 if ((h1 + o1) >= (h2 + o2)) { \ 708 /* src after dest: copy forward */ \ 709 for (o = 0; c != 0; c--, o += BYTES) \ 710 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 711 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 712 } else { \ 713 /* dest after src: copy backwards */ \ 714 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 715 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 716 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 717 } \ 718 } 719 __HP300_copy_region_N(1) 720 __HP300_copy_region_N(2) 721 __HP300_copy_region_N(4) 722 #if 0 /* Cause a link error for bus_space_copy_region_8 */ 723 #define bus_space_copy_region_8 \ 724 !!! bus_space_copy_region_8 unimplemented !!! 725 #endif 726 727 #undef __HP300_copy_region_N 728 729 /* 730 * Bus stream operations--defined in terms of non-stream counterparts 731 */ 732 #define __BUS_SPACE_HAS_STREAM_METHODS 1 733 #define bus_space_read_stream_1 bus_space_read_1 734 #define bus_space_read_stream_2 bus_space_read_2 735 #define bus_space_read_stream_4 bus_space_read_4 736 #define bus_space_read_stream_8 bus_space_read_8 737 #define bus_space_read_multi_stream_1 bus_space_read_multi_1 738 #define bus_space_read_multi_stream_2 bus_space_read_multi_2 739 #define bus_space_read_multi_stream_4 bus_space_read_multi_4 740 #define bus_space_read_multi_stream_8 bus_space_read_multi_8 741 #define bus_space_read_region_stream_1 bus_space_read_region_1 742 #define bus_space_read_region_stream_2 bus_space_read_region_2 743 #define bus_space_read_region_stream_4 bus_space_read_region_4 744 #define bus_space_read_region_stream_8 bus_space_read_region_8 745 #define bus_space_write_stream_1 bus_space_write_1 746 #define bus_space_write_stream_2 bus_space_write_2 747 #define bus_space_write_stream_4 bus_space_write_4 748 #define bus_space_write_stream_8 bus_space_write_8 749 #define bus_space_write_multi_stream_1 bus_space_write_multi_1 750 #define bus_space_write_multi_stream_2 bus_space_write_multi_2 751 #define bus_space_write_multi_stream_4 bus_space_write_multi_4 752 #define bus_space_write_multi_stream_8 bus_space_write_multi_8 753 #define bus_space_write_region_stream_1 bus_space_write_region_1 754 #define bus_space_write_region_stream_2 bus_space_write_region_2 755 #define bus_space_write_region_stream_4 bus_space_write_region_4 756 #define bus_space_write_region_stream_8 bus_space_write_region_8 757 758 /* 759 * Bus read/write barrier methods. 760 * 761 * void bus_space_barrier(bus_space_tag_t tag, 762 * bus_space_handle_t bsh, bus_size_t offset, 763 * bus_size_t len, int flags); 764 * 765 * Note: the 680x0 does not currently require barriers, but we must 766 * provide the flags to MI code. 767 */ 768 #define bus_space_barrier(t, h, o, l, f) \ 769 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 770 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 771 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 772 773 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 774 775 /* 776 * There is no bus_dma(9)'fied bus drivers on this port. 777 */ 778 #define __HAVE_NO_BUS_DMA 779 780 #endif /* _HP300_BUS_H_ */ 781