bus.h revision 200051
1/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl 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 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40/*- 41 * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 42 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. All advertising materials mentioning features or use of this software 53 * must display the following acknowledgement: 54 * This product includes software developed by Christopher G. Demetriou 55 * for the NetBSD Project. 56 * 4. The name of the author may not be used to endorse or promote products 57 * derived from this software without specific prior written permission 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 60 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 61 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 62 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 63 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 64 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 65 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 66 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 67 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 68 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 69 */ 70/* $FreeBSD: head/sys/ia64/include/bus.h 200051 2009-12-03 04:06:48Z marcel $ */ 71 72#ifndef _MACHINE_BUS_H_ 73#define _MACHINE_BUS_H_ 74 75#include <machine/_bus.h> 76#include <machine/cpufunc.h> 77 78/* 79 * Values for the ia64 bus space tag, not to be used directly by MI code. 80 */ 81#define IA64_BUS_SPACE_IO 0 /* space is i/o space */ 82#define IA64_BUS_SPACE_MEM 1 /* space is mem space */ 83 84#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF 85#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF 86#define BUS_SPACE_MAXSIZE 0xFFFFFFFFFFFFFFFF 87#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF 88#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF 89#define BUS_SPACE_MAXADDR 0xFFFFFFFF 90 91#define BUS_SPACE_UNRESTRICTED (~0) 92 93/* 94 * Map a region of device bus space into CPU virtual address space. 95 */ 96 97static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 98 bus_size_t size, int flags, 99 bus_space_handle_t *bshp); 100 101static __inline int 102bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr, 103 bus_size_t size __unused, int flags __unused, 104 bus_space_handle_t *bshp) 105{ 106 107 *bshp = addr; 108 return (0); 109} 110 111/* 112 * Unmap a region of device bus space. 113 */ 114static __inline void 115bus_space_unmap(bus_space_tag_t bst __unused, bus_space_handle_t bsh __unused, 116 bus_size_t size __unused) 117{ 118} 119 120 121/* 122 * Get a new handle for a subregion of an already-mapped area of bus space. 123 */ 124static __inline int 125bus_space_subregion(bus_space_tag_t bst, bus_space_handle_t bsh, 126 bus_size_t ofs, bus_size_t size, bus_space_handle_t *nbshp) 127{ 128 *nbshp = bsh + ofs; 129 return (0); 130} 131 132 133/* 134 * Allocate a region of memory that is accessible to devices in bus space. 135 */ 136int 137bus_space_alloc(bus_space_tag_t bst, bus_addr_t rstart, bus_addr_t rend, 138 bus_size_t size, bus_size_t align, bus_size_t boundary, int flags, 139 bus_addr_t *addrp, bus_space_handle_t *bshp); 140 141 142/* 143 * Free a region of bus space accessible memory. 144 */ 145void 146bus_space_free(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t size); 147 148 149/* 150 * Bus read/write barrier method. 151 */ 152#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 153#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 154 155static __inline void 156bus_space_barrier(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, 157 bus_size_t size, int flags) 158{ 159 ia64_mf_a(); 160 ia64_mf(); 161} 162 163 164/* 165 * Read 1 unit of data from bus space described by the tag, handle and ofs 166 * tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The 167 * data is returned. 168 */ 169static __inline uint8_t 170bus_space_read_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) 171{ 172 uint8_t *bsp; 173 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 174 __MEMIO_ADDR(bsh + ofs); 175 return (ia64_ld1(bsp)); 176} 177 178static __inline uint16_t 179bus_space_read_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) 180{ 181 uint16_t *bsp; 182 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 183 __MEMIO_ADDR(bsh + ofs); 184 return (ia64_ld2(bsp)); 185} 186 187static __inline uint32_t 188bus_space_read_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) 189{ 190 uint32_t *bsp; 191 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 192 __MEMIO_ADDR(bsh + ofs); 193 return (ia64_ld4(bsp)); 194} 195 196static __inline uint64_t 197bus_space_read_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) 198{ 199 uint64_t *bsp; 200 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 201 __MEMIO_ADDR(bsh + ofs); 202 return (ia64_ld8(bsp)); 203} 204 205 206/* 207 * Write 1 unit of data to bus space described by the tag, handle and ofs 208 * tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The 209 * data is passed by value. 210 */ 211static __inline void 212bus_space_write_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, 213 uint8_t val) 214{ 215 uint8_t *bsp; 216 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 217 __MEMIO_ADDR(bsh + ofs); 218 ia64_st1(bsp, val); 219} 220 221static __inline void 222bus_space_write_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, 223 uint16_t val) 224{ 225 uint16_t *bsp; 226 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 227 __MEMIO_ADDR(bsh + ofs); 228 ia64_st2(bsp, val); 229} 230 231static __inline void 232bus_space_write_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, 233 uint32_t val) 234{ 235 uint32_t *bsp; 236 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 237 __MEMIO_ADDR(bsh + ofs); 238 ia64_st4(bsp, val); 239} 240 241static __inline void 242bus_space_write_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, 243 uint64_t val) 244{ 245 uint64_t *bsp; 246 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 247 __MEMIO_ADDR(bsh + ofs); 248 ia64_st8(bsp, val); 249} 250 251 252/* 253 * Read count units of data from bus space described by the tag, handle and 254 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The 255 * data is returned in the buffer passed by reference. 256 */ 257static __inline void 258bus_space_read_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh, 259 bus_size_t ofs, uint8_t *bufp, size_t count) 260{ 261 uint8_t *bsp; 262 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 263 __MEMIO_ADDR(bsh + ofs); 264 while (count-- > 0) 265 *bufp++ = ia64_ld1(bsp); 266} 267 268static __inline void 269bus_space_read_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh, 270 bus_size_t ofs, uint16_t *bufp, size_t count) 271{ 272 uint16_t *bsp; 273 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 274 __MEMIO_ADDR(bsh + ofs); 275 while (count-- > 0) 276 *bufp++ = ia64_ld2(bsp); 277} 278 279static __inline void 280bus_space_read_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh, 281 bus_size_t ofs, uint32_t *bufp, size_t count) 282{ 283 uint32_t *bsp; 284 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 285 __MEMIO_ADDR(bsh + ofs); 286 while (count-- > 0) 287 *bufp++ = ia64_ld4(bsp); 288} 289 290static __inline void 291bus_space_read_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh, 292 bus_size_t ofs, uint64_t *bufp, size_t count) 293{ 294 uint64_t *bsp; 295 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 296 __MEMIO_ADDR(bsh + ofs); 297 while (count-- > 0) 298 *bufp++ = ia64_ld8(bsp); 299} 300 301 302/* 303 * Write count units of data to bus space described by the tag, handle and 304 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The 305 * data is read from the buffer passed by reference. 306 */ 307static __inline void 308bus_space_write_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh, 309 bus_size_t ofs, const uint8_t *bufp, size_t count) 310{ 311 uint8_t *bsp; 312 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 313 __MEMIO_ADDR(bsh + ofs); 314 while (count-- > 0) 315 ia64_st1(bsp, *bufp++); 316} 317 318static __inline void 319bus_space_write_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh, 320 bus_size_t ofs, const uint16_t *bufp, size_t count) 321{ 322 uint16_t *bsp; 323 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 324 __MEMIO_ADDR(bsh + ofs); 325 while (count-- > 0) 326 ia64_st2(bsp, *bufp++); 327} 328 329static __inline void 330bus_space_write_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh, 331 bus_size_t ofs, const uint32_t *bufp, size_t count) 332{ 333 uint32_t *bsp; 334 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 335 __MEMIO_ADDR(bsh + ofs); 336 while (count-- > 0) 337 ia64_st4(bsp, *bufp++); 338} 339 340static __inline void 341bus_space_write_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh, 342 bus_size_t ofs, const uint64_t *bufp, size_t count) 343{ 344 uint64_t *bsp; 345 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 346 __MEMIO_ADDR(bsh + ofs); 347 while (count-- > 0) 348 ia64_st8(bsp, *bufp++); 349} 350 351 352/* 353 * Read count units of data from bus space described by the tag, handle and 354 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The 355 * data is written to the buffer passed by reference and read from successive 356 * bus space addresses. Access is unordered. 357 */ 358static __inline void 359bus_space_read_region_1(bus_space_tag_t bst, bus_space_handle_t bsh, 360 bus_size_t ofs, uint8_t *bufp, size_t count) 361{ 362 uint8_t *bsp; 363 while (count-- > 0) { 364 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 365 __MEMIO_ADDR(bsh + ofs); 366 *bufp++ = ia64_ld1(bsp); 367 ofs += 1; 368 } 369} 370 371static __inline void 372bus_space_read_region_2(bus_space_tag_t bst, bus_space_handle_t bsh, 373 bus_size_t ofs, uint16_t *bufp, size_t count) 374{ 375 uint16_t *bsp; 376 while (count-- > 0) { 377 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 378 __MEMIO_ADDR(bsh + ofs); 379 *bufp++ = ia64_ld2(bsp); 380 ofs += 2; 381 } 382} 383 384static __inline void 385bus_space_read_region_4(bus_space_tag_t bst, bus_space_handle_t bsh, 386 bus_size_t ofs, uint32_t *bufp, size_t count) 387{ 388 uint32_t *bsp; 389 while (count-- > 0) { 390 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 391 __MEMIO_ADDR(bsh + ofs); 392 *bufp++ = ia64_ld4(bsp); 393 ofs += 4; 394 } 395} 396 397static __inline void 398bus_space_read_region_8(bus_space_tag_t bst, bus_space_handle_t bsh, 399 bus_size_t ofs, uint64_t *bufp, size_t count) 400{ 401 uint64_t *bsp; 402 while (count-- > 0) { 403 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 404 __MEMIO_ADDR(bsh + ofs); 405 *bufp++ = ia64_ld8(bsp); 406 ofs += 8; 407 } 408} 409 410 411/* 412 * Write count units of data from bus space described by the tag, handle and 413 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The 414 * data is read from the buffer passed by reference and written to successive 415 * bus space addresses. Access is unordered. 416 */ 417static __inline void 418bus_space_write_region_1(bus_space_tag_t bst, bus_space_handle_t bsh, 419 bus_size_t ofs, const uint8_t *bufp, size_t count) 420{ 421 uint8_t *bsp; 422 while (count-- > 0) { 423 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 424 __MEMIO_ADDR(bsh + ofs); 425 ia64_st1(bsp, *bufp++); 426 ofs += 1; 427 } 428} 429 430static __inline void 431bus_space_write_region_2(bus_space_tag_t bst, bus_space_handle_t bsh, 432 bus_size_t ofs, const uint16_t *bufp, size_t count) 433{ 434 uint16_t *bsp; 435 while (count-- > 0) { 436 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 437 __MEMIO_ADDR(bsh + ofs); 438 ia64_st2(bsp, *bufp++); 439 ofs += 2; 440 } 441} 442 443static __inline void 444bus_space_write_region_4(bus_space_tag_t bst, bus_space_handle_t bsh, 445 bus_size_t ofs, const uint32_t *bufp, size_t count) 446{ 447 uint32_t *bsp; 448 while (count-- > 0) { 449 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 450 __MEMIO_ADDR(bsh + ofs); 451 ia64_st4(bsp, *bufp++); 452 ofs += 4; 453 } 454} 455 456static __inline void 457bus_space_write_region_8(bus_space_tag_t bst, bus_space_handle_t bsh, 458 bus_size_t ofs, const uint64_t *bufp, size_t count) 459{ 460 uint64_t *bsp; 461 while (count-- > 0) { 462 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 463 __MEMIO_ADDR(bsh + ofs); 464 ia64_st8(bsp, *bufp++); 465 ofs += 8; 466 } 467} 468 469 470/* 471 * Write count units of data from bus space described by the tag, handle and 472 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The 473 * data is passed by value. Writes are unordered. 474 */ 475static __inline void 476bus_space_set_multi_1(bus_space_tag_t bst, bus_space_handle_t bsh, 477 bus_size_t ofs, uint8_t val, size_t count) 478{ 479 uint8_t *bsp; 480 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 481 __MEMIO_ADDR(bsh + ofs); 482 while (count-- > 0) 483 ia64_st1(bsp, val); 484} 485 486static __inline void 487bus_space_set_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh, 488 bus_size_t ofs, uint16_t val, size_t count) 489{ 490 uint16_t *bsp; 491 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 492 __MEMIO_ADDR(bsh + ofs); 493 while (count-- > 0) 494 ia64_st2(bsp, val); 495} 496 497static __inline void 498bus_space_set_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh, 499 bus_size_t ofs, uint32_t val, size_t count) 500{ 501 uint32_t *bsp; 502 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 503 __MEMIO_ADDR(bsh + ofs); 504 while (count-- > 0) 505 ia64_st4(bsp, val); 506} 507 508static __inline void 509bus_space_set_multi_8(bus_space_tag_t bst, bus_space_handle_t bsh, 510 bus_size_t ofs, uint64_t val, size_t count) 511{ 512 uint64_t *bsp; 513 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 514 __MEMIO_ADDR(bsh + ofs); 515 while (count-- > 0) 516 ia64_st8(bsp, val); 517} 518 519 520/* 521 * Write count units of data from bus space described by the tag, handle and 522 * ofs tuple. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. The 523 * data is passed by value and written to successive bus space addresses. 524 * Writes are unordered. 525 */ 526static __inline void 527bus_space_set_region_1(bus_space_tag_t bst, bus_space_handle_t bsh, 528 bus_size_t ofs, uint8_t val, size_t count) 529{ 530 uint8_t *bsp; 531 while (count-- > 0) { 532 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 533 __MEMIO_ADDR(bsh + ofs); 534 ia64_st1(bsp, val); 535 ofs += 1; 536 } 537} 538 539static __inline void 540bus_space_set_region_2(bus_space_tag_t bst, bus_space_handle_t bsh, 541 bus_size_t ofs, uint16_t val, size_t count) 542{ 543 uint16_t *bsp; 544 while (count-- > 0) { 545 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 546 __MEMIO_ADDR(bsh + ofs); 547 ia64_st2(bsp, val); 548 ofs += 2; 549 } 550} 551 552static __inline void 553bus_space_set_region_4(bus_space_tag_t bst, bus_space_handle_t bsh, 554 bus_size_t ofs, uint32_t val, size_t count) 555{ 556 uint32_t *bsp; 557 while (count-- > 0) { 558 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 559 __MEMIO_ADDR(bsh + ofs); 560 ia64_st4(bsp, val); 561 ofs += 4; 562 } 563} 564 565static __inline void 566bus_space_set_region_8(bus_space_tag_t bst, bus_space_handle_t bsh, 567 bus_size_t ofs, uint64_t val, size_t count) 568{ 569 uint64_t *bsp; 570 while (count-- > 0) { 571 bsp = (bst == IA64_BUS_SPACE_IO) ? __PIO_ADDR(bsh + ofs) : 572 __MEMIO_ADDR(bsh + ofs); 573 ia64_st8(bsp, val); 574 ofs += 8; 575 } 576} 577 578 579/* 580 * Copy count units of data from bus space described by the tag and the first 581 * handle and ofs pair to bus space described by the tag and the second handle 582 * and ofs pair. A unit of data can be 1 byte, 2 bytes, 4 bytes or 8 bytes. 583 * The data is read from successive bus space addresses and also written to 584 * successive bus space addresses. Both reads and writes are unordered. 585 */ 586static __inline void 587bus_space_copy_region_1(bus_space_tag_t bst, bus_space_handle_t bsh1, 588 bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count) 589{ 590 bus_addr_t dst, src; 591 uint8_t *dstp, *srcp; 592 src = bsh1 + ofs1; 593 dst = bsh2 + ofs2; 594 if (dst > src) { 595 src += count - 1; 596 dst += count - 1; 597 while (count-- > 0) { 598 if (bst == IA64_BUS_SPACE_IO) { 599 srcp = __PIO_ADDR(src); 600 dstp = __PIO_ADDR(dst); 601 } else { 602 srcp = __MEMIO_ADDR(src); 603 dstp = __MEMIO_ADDR(dst); 604 } 605 ia64_st1(dstp, ia64_ld1(srcp)); 606 src -= 1; 607 dst -= 1; 608 } 609 } else { 610 while (count-- > 0) { 611 if (bst == IA64_BUS_SPACE_IO) { 612 srcp = __PIO_ADDR(src); 613 dstp = __PIO_ADDR(dst); 614 } else { 615 srcp = __MEMIO_ADDR(src); 616 dstp = __MEMIO_ADDR(dst); 617 } 618 ia64_st1(dstp, ia64_ld1(srcp)); 619 src += 1; 620 dst += 1; 621 } 622 } 623} 624 625static __inline void 626bus_space_copy_region_2(bus_space_tag_t bst, bus_space_handle_t bsh1, 627 bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count) 628{ 629 bus_addr_t dst, src; 630 uint16_t *dstp, *srcp; 631 src = bsh1 + ofs1; 632 dst = bsh2 + ofs2; 633 if (dst > src) { 634 src += (count - 1) << 1; 635 dst += (count - 1) << 1; 636 while (count-- > 0) { 637 if (bst == IA64_BUS_SPACE_IO) { 638 srcp = __PIO_ADDR(src); 639 dstp = __PIO_ADDR(dst); 640 } else { 641 srcp = __MEMIO_ADDR(src); 642 dstp = __MEMIO_ADDR(dst); 643 } 644 ia64_st2(dstp, ia64_ld2(srcp)); 645 src -= 2; 646 dst -= 2; 647 } 648 } else { 649 while (count-- > 0) { 650 if (bst == IA64_BUS_SPACE_IO) { 651 srcp = __PIO_ADDR(src); 652 dstp = __PIO_ADDR(dst); 653 } else { 654 srcp = __MEMIO_ADDR(src); 655 dstp = __MEMIO_ADDR(dst); 656 } 657 ia64_st2(dstp, ia64_ld2(srcp)); 658 src += 2; 659 dst += 2; 660 } 661 } 662} 663 664static __inline void 665bus_space_copy_region_4(bus_space_tag_t bst, bus_space_handle_t bsh1, 666 bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count) 667{ 668 bus_addr_t dst, src; 669 uint32_t *dstp, *srcp; 670 src = bsh1 + ofs1; 671 dst = bsh2 + ofs2; 672 if (dst > src) { 673 src += (count - 1) << 2; 674 dst += (count - 1) << 2; 675 while (count-- > 0) { 676 if (bst == IA64_BUS_SPACE_IO) { 677 srcp = __PIO_ADDR(src); 678 dstp = __PIO_ADDR(dst); 679 } else { 680 srcp = __MEMIO_ADDR(src); 681 dstp = __MEMIO_ADDR(dst); 682 } 683 ia64_st4(dstp, ia64_ld4(srcp)); 684 src -= 4; 685 dst -= 4; 686 } 687 } else { 688 while (count-- > 0) { 689 if (bst == IA64_BUS_SPACE_IO) { 690 srcp = __PIO_ADDR(src); 691 dstp = __PIO_ADDR(dst); 692 } else { 693 srcp = __MEMIO_ADDR(src); 694 dstp = __MEMIO_ADDR(dst); 695 } 696 ia64_st4(dstp, ia64_ld4(srcp)); 697 src += 4; 698 dst += 4; 699 } 700 } 701} 702 703static __inline void 704bus_space_copy_region_8(bus_space_tag_t bst, bus_space_handle_t bsh1, 705 bus_size_t ofs1, bus_space_handle_t bsh2, bus_size_t ofs2, size_t count) 706{ 707 bus_addr_t dst, src; 708 uint64_t *dstp, *srcp; 709 src = bsh1 + ofs1; 710 dst = bsh2 + ofs2; 711 if (dst > src) { 712 src += (count - 1) << 3; 713 dst += (count - 1) << 3; 714 while (count-- > 0) { 715 if (bst == IA64_BUS_SPACE_IO) { 716 srcp = __PIO_ADDR(src); 717 dstp = __PIO_ADDR(dst); 718 } else { 719 srcp = __MEMIO_ADDR(src); 720 dstp = __MEMIO_ADDR(dst); 721 } 722 ia64_st8(dstp, ia64_ld8(srcp)); 723 src -= 8; 724 dst -= 8; 725 } 726 } else { 727 while (count-- > 0) { 728 if (bst == IA64_BUS_SPACE_IO) { 729 srcp = __PIO_ADDR(src); 730 dstp = __PIO_ADDR(dst); 731 } else { 732 srcp = __MEMIO_ADDR(src); 733 dstp = __MEMIO_ADDR(dst); 734 } 735 ia64_st8(dstp, ia64_ld8(srcp)); 736 src += 8; 737 dst += 8; 738 } 739 } 740} 741 742 743/* 744 * Stream accesses are the same as normal accesses on ia64; there are no 745 * supported bus systems with an endianess different from the host one. 746 */ 747#define bus_space_read_stream_1(t, h, o) \ 748 bus_space_read_1(t, h, o) 749#define bus_space_read_stream_2(t, h, o) \ 750 bus_space_read_2(t, h, o) 751#define bus_space_read_stream_4(t, h, o) \ 752 bus_space_read_4(t, h, o) 753#define bus_space_read_stream_8(t, h, o) \ 754 bus_space_read_8(t, h, o) 755 756#define bus_space_read_multi_stream_1(t, h, o, a, c) \ 757 bus_space_read_multi_1(t, h, o, a, c) 758#define bus_space_read_multi_stream_2(t, h, o, a, c) \ 759 bus_space_read_multi_2(t, h, o, a, c) 760#define bus_space_read_multi_stream_4(t, h, o, a, c) \ 761 bus_space_read_multi_4(t, h, o, a, c) 762#define bus_space_read_multi_stream_8(t, h, o, a, c) \ 763 bus_space_read_multi_8(t, h, o, a, c) 764 765#define bus_space_write_stream_1(t, h, o, v) \ 766 bus_space_write_1(t, h, o, v) 767#define bus_space_write_stream_2(t, h, o, v) \ 768 bus_space_write_2(t, h, o, v) 769#define bus_space_write_stream_4(t, h, o, v) \ 770 bus_space_write_4(t, h, o, v) 771#define bus_space_write_stream_8(t, h, o, v) \ 772 bus_space_write_8(t, h, o, v) 773 774#define bus_space_write_multi_stream_1(t, h, o, a, c) \ 775 bus_space_write_multi_1(t, h, o, a, c) 776#define bus_space_write_multi_stream_2(t, h, o, a, c) \ 777 bus_space_write_multi_2(t, h, o, a, c) 778#define bus_space_write_multi_stream_4(t, h, o, a, c) \ 779 bus_space_write_multi_4(t, h, o, a, c) 780#define bus_space_write_multi_stream_8(t, h, o, a, c) \ 781 bus_space_write_multi_8(t, h, o, a, c) 782 783#define bus_space_set_multi_stream_1(t, h, o, v, c) \ 784 bus_space_set_multi_1(t, h, o, v, c) 785#define bus_space_set_multi_stream_2(t, h, o, v, c) \ 786 bus_space_set_multi_2(t, h, o, v, c) 787#define bus_space_set_multi_stream_4(t, h, o, v, c) \ 788 bus_space_set_multi_4(t, h, o, v, c) 789#define bus_space_set_multi_stream_8(t, h, o, v, c) \ 790 bus_space_set_multi_8(t, h, o, v, c) 791 792#define bus_space_read_region_stream_1(t, h, o, a, c) \ 793 bus_space_read_region_1(t, h, o, a, c) 794#define bus_space_read_region_stream_2(t, h, o, a, c) \ 795 bus_space_read_region_2(t, h, o, a, c) 796#define bus_space_read_region_stream_4(t, h, o, a, c) \ 797 bus_space_read_region_4(t, h, o, a, c) 798#define bus_space_read_region_stream_8(t, h, o, a, c) \ 799 bus_space_read_region_8(t, h, o, a, c) 800 801#define bus_space_write_region_stream_1(t, h, o, a, c) \ 802 bus_space_write_region_1(t, h, o, a, c) 803#define bus_space_write_region_stream_2(t, h, o, a, c) \ 804 bus_space_write_region_2(t, h, o, a, c) 805#define bus_space_write_region_stream_4(t, h, o, a, c) \ 806 bus_space_write_region_4(t, h, o, a, c) 807#define bus_space_write_region_stream_8(t, h, o, a, c) \ 808 bus_space_write_region_8(t, h, o, a, c) 809 810#define bus_space_set_region_stream_1(t, h, o, v, c) \ 811 bus_space_set_region_1(t, h, o, v, c) 812#define bus_space_set_region_stream_2(t, h, o, v, c) \ 813 bus_space_set_region_2(t, h, o, v, c) 814#define bus_space_set_region_stream_4(t, h, o, v, c) \ 815 bus_space_set_region_4(t, h, o, v, c) 816#define bus_space_set_region_stream_8(t, h, o, v, c) \ 817 bus_space_set_region_8(t, h, o, v, c) 818 819#define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \ 820 bus_space_copy_region_1(t, h1, o1, h2, o2, c) 821#define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \ 822 bus_space_copy_region_2(t, h1, o1, h2, o2, c) 823#define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \ 824 bus_space_copy_region_4(t, h1, o1, h2, o2, c) 825#define bus_space_copy_region_stream_8(t, h1, o1, h2, o2, c) \ 826 bus_space_copy_region_8(t, h1, o1, h2, o2, c) 827 828#include <machine/bus_dma.h> 829 830#endif /* _MACHINE_BUS_H_ */ 831