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