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