bus.h revision 1.1
1/* $NetBSD: bus.h,v 1.1 2000/02/29 15:21:27 nonaka Exp $ */ 2/* $OpenBSD: bus.h,v 1.1 1997/10/13 10:53:42 pefo Exp $ */ 3 4/*- 5 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the NetBSD 23 * Foundation, Inc. and its contributors. 24 * 4. Neither the name of The NetBSD Foundation nor the names of its 25 * contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41/* 42 * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 43 * Copyright (c) 1996 Jason R. Thorpe. All rights reserved. 44 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. All advertising materials mentioning features or use of this software 55 * must display the following acknowledgement: 56 * This product includes software developed by Christopher G. Demetriou 57 * for the NetBSD Project. 58 * 4. The name of the author may not be used to endorse or promote products 59 * derived from this software without specific prior written permission 60 * 61 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 62 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 63 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 64 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 65 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 66 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 67 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 68 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 69 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 70 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 71 */ 72 73/* 74 * Copyright (c) 1997 Per Fogelstrom. All rights reserved. 75 * Copyright (c) 1996 Niklas Hallqvist. All rights reserved. 76 * 77 * Redistribution and use in source and binary forms, with or without 78 * modification, are permitted provided that the following conditions 79 * are met: 80 * 1. Redistributions of source code must retain the above copyright 81 * notice, this list of conditions and the following disclaimer. 82 * 2. Redistributions in binary form must reproduce the above copyright 83 * notice, this list of conditions and the following disclaimer in the 84 * documentation and/or other materials provided with the distribution. 85 * 3. All advertising materials mentioning features or use of this software 86 * must display the following acknowledgement: 87 * This product includes software developed by Christopher G. Demetriou 88 * for the NetBSD Project. 89 * 4. The name of the author may not be used to endorse or promote products 90 * derived from this software without specific prior written permission 91 * 92 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 93 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 94 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 95 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 96 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 98 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 99 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 100 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 101 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 102 */ 103 104#ifndef _PREP_BUS_H_ 105#define _PREP_BUS_H_ 106 107#include <machine/pio.h> 108 109/* 110 * Values for the Be bus space tag, not to be used directly by MI code. 111 */ 112#define PREP_BUS_SPACE_IO 0x80000000 /* i/o space */ 113#define PREP_BUS_SPACE_MEM 0xC0000000 /* mem space */ 114 115/* 116 * Address conversion as seen from a PCI master. 117 */ 118#define MPC105_DIRECT_MAPPED_SPACE 0x80000000 119#define PHYS_TO_PCI_MEM(x) ((x) | MPC105_DIRECT_MAPPED_SPACE) 120#define PCI_MEM_TO_PHYS(x) ((x) & ~MPC105_DIRECT_MAPPED_SPACE) 121 122/* 123 * Bus access types. 124 */ 125typedef u_int32_t bus_addr_t; 126typedef u_int32_t bus_size_t; 127typedef u_int32_t bus_space_handle_t; 128typedef u_int32_t bus_space_tag_t; 129 130#define BUS_SPACE_MAP_CACHEABLE 0x01 131#define BUS_SPACE_MAP_LINEAR 0x02 132#define BUS_SPACE_MAP_PREFETCHABLE 0x04 133 134#ifdef __STDC__ 135#define CAT(a,b) a##b 136#define CAT3(a,b,c) a##b##c 137#else 138#define CAT(a,b) a/**/b 139#define CAT3(a,b,c) a/**/b/**/c 140#endif 141 142/* 143 * Access methods for bus resources 144 */ 145 146#define __BUS_SPACE_HAS_STREAM_METHODS 147 148/* 149 * int bus_space_map __P((bus_space_tag_t t, bus_addr_t addr, 150 * bus_size_t size, int flags, bus_space_handle_t *bshp)); 151 * 152 * Map a region of bus space. 153 */ 154 155#define bus_space_map(t, addr, size, flags, bshp) \ 156 ((*(bshp) = (t) + (addr)), 0) 157 158/* 159 * int bus_space_unmap __P((bus_space_tag_t t, 160 * bus_space_handle_t bsh, bus_size_t size)); 161 * 162 * Unmap a region of bus space. 163 */ 164 165#define bus_space_unmap(t, bsh, size) 166 167/* 168 * int bus_space_subregion __P((bus_space_tag_t t, 169 * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, 170 * bus_space_handle_t *nbshp)); 171 * 172 * Get a new handle for a subregion of an already-mapped area of bus space. 173 */ 174 175#define bus_space_subregion(t, bsh, offset, size, bshp) \ 176 ((*(bshp) = (bsh) + (offset)), 0) 177 178/* 179 * int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart, 180 * bus_addr_t rend, bus_size_t size, bus_size_t align, 181 * bus_size_t boundary, int flags, bus_addr_t *addrp, 182 * bus_space_handle_t *bshp)); 183 * 184 * Allocate a region of bus space. 185 */ 186 187#define bus_space_alloc !!! bus_space_alloc not implemented !!! 188 189/* 190 * int bus_space_free __P((bus_space_tag_t t, 191 * bus_space_handle_t bsh, bus_size_t size)); 192 * 193 * Free a region of bus space. 194 */ 195 196#define bus_space_free !!! bus_space_free not implemented !!! 197 198/* 199 * u_intN_t bus_space_read_N __P((bus_space_tag_t tag, 200 * bus_space_handle_t bsh, bus_size_t offset)); 201 * 202 * Read a 1, 2, 4, or 8 byte quantity from bus space 203 * described by tag/handle/offset. 204 */ 205 206#define bus_space_read(n,m) \ 207static __inline CAT3(u_int,m,_t) \ 208CAT(bus_space_read_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ 209 bus_size_t offset) \ 210{ \ 211 return CAT3(in,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset))); \ 212} 213 214bus_space_read(1,8) 215bus_space_read(2,16) 216bus_space_read(4,32) 217#define bus_space_read_8 !!! bus_space_read_8 unimplemented !!! 218 219/* 220 * u_intN_t bus_space_read_stream_N __P((bus_space_tag_t tag, 221 * bus_space_handle_t bsh, bus_size_t offset)); 222 * 223 * Read a 2, 4, or 8 byte stream quantity from bus space 224 * described by tag/handle/offset. 225 */ 226 227#define bus_space_read_stream(n,m) \ 228static __inline CAT3(u_int,m,_t) \ 229CAT(bus_space_read_stream_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ 230 bus_size_t offset) \ 231{ \ 232 return CAT(in,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset))); \ 233} 234 235bus_space_read_stream(2,16) 236bus_space_read_stream(4,32) 237#define bus_space_read_stream_8 !!! bus_space_read_stream_8 unimplemented !!! 238 239/* 240 * void bus_space_read_multi_N __P((bus_space_tag_t tag, 241 * bus_space_handle_t bsh, bus_size_t offset, 242 * u_intN_t *addr, size_t count)); 243 * 244 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 245 * described by tag/handle/offset and copy into buffer provided. 246 */ 247 248#define bus_space_read_multi(n,m) \ 249static __inline void \ 250CAT(bus_space_read_multi_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ 251 bus_size_t offset, CAT3(u_int,m,_t) *addr, size_t count) \ 252{ \ 253 CAT3(ins,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), \ 254 (CAT3(u_int,m,_t) *)addr, (size_t)count); \ 255} 256 257bus_space_read_multi(1,8) 258bus_space_read_multi(2,16) 259bus_space_read_multi(4,32) 260#define bus_space_read_multi_8 !!! bus_space_read_multi_8 not implemented !!! 261 262/* 263 * void bus_space_read_multi_stream_N __P((bus_space_tag_t tag, 264 * bus_space_handle_t bsh, bus_size_t offset, 265 * u_intN_t *addr, size_t count)); 266 * 267 * Read `count' 2, 4, or 8 byte stream quantities from bus space 268 * described by tag/handle/offset and copy into buffer provided. 269 */ 270 271#define bus_space_read_multi_stream(n,m) \ 272static __inline void \ 273CAT(bus_space_read_multi_stream_,n)(bus_space_tag_t tag, \ 274 bus_space_handle_t bsh, \ 275 bus_size_t offset, CAT3(u_int,m,_t) *addr, size_t count) \ 276{ \ 277 CAT(ins,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), \ 278 (CAT3(u_int,m,_t) *)addr, (size_t)count); \ 279} 280 281bus_space_read_multi_stream(2,16) 282bus_space_read_multi_stream(4,32) 283#define bus_space_read_multi_stream_8 \ 284 !!! bus_space_read_multi_stream_8 not implemented !!! 285 286/* 287 * void bus_space_write_N __P((bus_space_tag_t tag, 288 * bus_space_handle_t bsh, bus_size_t offset, 289 * u_intN_t value)); 290 * 291 * Write the 1, 2, 4, or 8 byte value `value' to bus space 292 * described by tag/handle/offset. 293 */ 294 295#define bus_space_write(n,m) \ 296static __inline void \ 297CAT(bus_space_write_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ 298 bus_size_t offset, CAT3(u_int,m,_t) x) \ 299{ \ 300 CAT3(out,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), x); \ 301} 302 303bus_space_write(1,8) 304bus_space_write(2,16) 305bus_space_write(4,32) 306#define bus_space_write_8 !!! bus_space_write_8 unimplemented !!! 307 308/* 309 * void bus_space_write_stream_N __P((bus_space_tag_t tag, 310 * bus_space_handle_t bsh, bus_size_t offset, 311 * u_intN_t value)); 312 * 313 * Write the 2, 4, or 8 byte stream value `value' to bus space 314 * described by tag/handle/offset. 315 */ 316 317#define bus_space_write_stream(n,m) \ 318static __inline void \ 319CAT(bus_space_write_stream_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ 320 bus_size_t offset, CAT3(u_int,m,_t) x) \ 321{ \ 322 CAT(out,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), x); \ 323} 324 325bus_space_write_stream(2,16) 326bus_space_write_stream(4,32) 327#define bus_space_write_stream_8 !!! bus_space_write_stream_8 unimplemented !!! 328 329/* 330 * void bus_space_write_multi_N __P((bus_space_tag_t tag, 331 * bus_space_handle_t bsh, bus_size_t offset, 332 * const u_intN_t *addr, size_t count)); 333 * 334 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 335 * provided to bus space described by tag/handle/offset. 336 */ 337 338#define bus_space_write_multi(n,m) \ 339static __inline void \ 340CAT(bus_space_write_multi_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ 341 bus_size_t offset, const CAT3(u_int,m,_t) *addr, size_t count) \ 342{ \ 343 CAT3(outs,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), \ 344 (CAT3(u_int,m,_t) *)addr, (size_t)count); \ 345} 346 347bus_space_write_multi(1,8) 348bus_space_write_multi(2,16) 349bus_space_write_multi(4,32) 350#define bus_space_write_multi_8 !!! bus_space_write_multi_8 not implemented !!! 351 352/* 353 * void bus_space_write_multi_stream_N __P((bus_space_tag_t tag, 354 * bus_space_handle_t bsh, bus_size_t offset, 355 * const u_intN_t *addr, size_t count)); 356 * 357 * Write `count' 2, 4, or 8 byte stream quantities from the buffer 358 * provided to bus space described by tag/handle/offset. 359 */ 360 361#define bus_space_write_multi_stream(n,m) \ 362static __inline void \ 363CAT(bus_space_write_multi_stream_,n)(bus_space_tag_t tag, \ 364 bus_space_handle_t bsh, \ 365 bus_size_t offset, const CAT3(u_int,m,_t) *addr, size_t count) \ 366{ \ 367 CAT(outs,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), \ 368 (CAT3(u_int,m,_t) *)addr, (size_t)count); \ 369} 370 371bus_space_write_multi_stream(2,16) 372bus_space_write_multi_stream(4,32) 373#define bus_space_write_multi_stream_8 \ 374 !!! bus_space_write_multi_stream_8 not implemented !!! 375 376/* 377 * void bus_space_read_region_N __P((bus_space_tag_t tag, 378 * bus_space_handle_t bsh, bus_size_t offset, 379 * u_intN_t *addr, size_t count)); 380 * 381 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 382 * described by tag/handle and starting at `offset' and copy into 383 * buffer provided. 384 */ 385static __inline void bus_space_read_region_1 __P((bus_space_tag_t, 386 bus_space_handle_t, bus_size_t, u_int8_t *, size_t)); 387static __inline void bus_space_read_region_2 __P((bus_space_tag_t, 388 bus_space_handle_t, bus_size_t, u_int16_t *, size_t)); 389static __inline void bus_space_read_region_4 __P((bus_space_tag_t, 390 bus_space_handle_t, bus_size_t, u_int32_t *, size_t)); 391 392static __inline void 393bus_space_read_region_1(tag, bsh, offset, addr, count) 394 bus_space_tag_t tag; 395 bus_space_handle_t bsh; 396 bus_size_t offset; 397 u_int8_t *addr; 398 size_t count; 399{ 400 volatile u_int8_t *s; 401 402 s = (volatile u_int8_t *)(bsh + offset); 403 while (count--) 404 *addr++ = *s++; 405 __asm__ volatile("eieio; sync"); 406} 407 408static __inline void 409bus_space_read_region_2(tag, bsh, offset, addr, count) 410 bus_space_tag_t tag; 411 bus_space_handle_t bsh; 412 bus_size_t offset; 413 u_int16_t *addr; 414 size_t count; 415{ 416 volatile u_int16_t *s; 417 418 s = (volatile u_int16_t *)(bsh + offset); 419 while (count--) 420 __asm__ volatile("lhbrx %0, 0, %1" : 421 "=r"(*addr++) : "r"(s++)); 422 __asm__ volatile("eieio; sync"); 423} 424 425static __inline void 426bus_space_read_region_4(tag, bsh, offset, addr, count) 427 bus_space_tag_t tag; 428 bus_space_handle_t bsh; 429 bus_size_t offset; 430 u_int32_t *addr; 431 size_t count; 432{ 433 volatile u_int32_t *s; 434 435 s = (volatile u_int32_t *)(bsh + offset); 436 while (count--) 437 __asm__ volatile("lwbrx %0, 0, %1" : 438 "=r"(*addr++) : "r"(s++)); 439 __asm__ volatile("eieio; sync"); 440} 441 442#define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! 443 444/* 445 * void bus_space_read_region_stream_N __P((bus_space_tag_t tag, 446 * bus_space_handle_t bsh, bus_size_t offset, 447 * u_intN_t *addr, size_t count)); 448 * 449 * Read `count' 2, 4, or 8 byte stream quantities from bus space 450 * described by tag/handle and starting at `offset' and copy into 451 * buffer provided. 452 */ 453static __inline void bus_space_read_region_stream_2 __P((bus_space_tag_t, 454 bus_space_handle_t, bus_size_t, u_int16_t *, size_t)); 455static __inline void bus_space_read_region_stream_4 __P((bus_space_tag_t, 456 bus_space_handle_t, bus_size_t, u_int32_t *, size_t)); 457 458static __inline void 459bus_space_read_region_stream_2(tag, bsh, offset, addr, count) 460 bus_space_tag_t tag; 461 bus_space_handle_t bsh; 462 bus_size_t offset; 463 u_int16_t *addr; 464 size_t count; 465{ 466 volatile u_int16_t *s; 467 468 s = (volatile u_int16_t *)(bsh + offset); 469 while (count--) 470 *addr++ = *s++; 471 __asm__ volatile("eieio; sync"); 472} 473 474static __inline void 475bus_space_read_region_stream_4(tag, bsh, offset, addr, count) 476 bus_space_tag_t tag; 477 bus_space_handle_t bsh; 478 bus_size_t offset; 479 u_int32_t *addr; 480 size_t count; 481{ 482 volatile u_int32_t *s; 483 484 s = (volatile u_int32_t *)(bsh + offset); 485 while (count--) 486 *addr++ = *s++; 487 __asm__ volatile("eieio; sync"); 488} 489 490#define bus_space_read_region_stream_8 \ 491 !!! bus_space_read_region_stream_8 unimplemented !!! 492 493/* 494 * void bus_space_write_region_N __P((bus_space_tag_t tag, 495 * bus_space_handle_t bsh, bus_size_t offset, 496 * const u_intN_t *addr, size_t count)); 497 * 498 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 499 * to bus space described by tag/handle starting at `offset'. 500 */ 501static __inline void bus_space_write_region_1 __P((bus_space_tag_t, 502 bus_space_handle_t, bus_size_t, const u_int8_t *, size_t)); 503static __inline void bus_space_write_region_2 __P((bus_space_tag_t, 504 bus_space_handle_t, bus_size_t, const u_int16_t *, size_t)); 505static __inline void bus_space_write_region_4 __P((bus_space_tag_t, 506 bus_space_handle_t, bus_size_t, const u_int32_t *, size_t)); 507 508static __inline void 509bus_space_write_region_1(tag, bsh, offset, addr, count) 510 bus_space_tag_t tag; 511 bus_space_handle_t bsh; 512 bus_size_t offset; 513 const u_int8_t *addr; 514 size_t count; 515{ 516 volatile u_int8_t *d; 517 518 d = (volatile u_int8_t *)(bsh + offset); 519 while (count--) 520 *d++ = *addr++; 521 __asm__ volatile("eieio; sync"); 522} 523 524static __inline void 525bus_space_write_region_2(tag, bsh, offset, addr, count) 526 bus_space_tag_t tag; 527 bus_space_handle_t bsh; 528 bus_size_t offset; 529 const u_int16_t *addr; 530 size_t count; 531{ 532 volatile u_int16_t *d; 533 534 d = (volatile u_int16_t *)(bsh + offset); 535 while (count--) 536 __asm__ volatile("sthbrx %0, 0, %1" :: 537 "r"(*addr++), "r"(d++)); 538 __asm__ volatile("eieio; sync"); 539} 540 541static __inline void 542bus_space_write_region_4(tag, bsh, offset, addr, count) 543 bus_space_tag_t tag; 544 bus_space_handle_t bsh; 545 bus_size_t offset; 546 const u_int32_t *addr; 547 size_t count; 548{ 549 volatile u_int32_t *d; 550 551 d = (volatile u_int32_t *)(bsh + offset); 552 while (count--) 553 __asm__ volatile("stwbrx %0, 0, %1" :: 554 "r"(*addr++), "r"(d++)); 555 __asm__ volatile("eieio; sync"); 556} 557 558#define bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!! 559 560/* 561 * void bus_space_write_region_stream_N __P((bus_space_tag_t tag, 562 * bus_space_handle_t bsh, bus_size_t offset, 563 * const u_intN_t *addr, size_t count)); 564 * 565 * Write `count' 2, 4, or 8 byte stream quantities from the buffer provided 566 * to bus space described by tag/handle starting at `offset'. 567 */ 568static __inline void bus_space_write_region_stream_2 __P((bus_space_tag_t, 569 bus_space_handle_t, bus_size_t, const u_int16_t *, size_t)); 570static __inline void bus_space_write_region_stream_4 __P((bus_space_tag_t, 571 bus_space_handle_t, bus_size_t, const u_int32_t *, size_t)); 572 573static __inline void 574bus_space_write_region_stream_2(tag, bsh, offset, addr, count) 575 bus_space_tag_t tag; 576 bus_space_handle_t bsh; 577 bus_size_t offset; 578 const u_int16_t *addr; 579 size_t count; 580{ 581 volatile u_int16_t *d; 582 583 d = (volatile u_int16_t *)(bsh + offset); 584 while (count--) 585 *d++ = *addr++; 586 __asm__ volatile("eieio; sync"); 587} 588 589static __inline void 590bus_space_write_region_stream_4(tag, bsh, offset, addr, count) 591 bus_space_tag_t tag; 592 bus_space_handle_t bsh; 593 bus_size_t offset; 594 const u_int32_t *addr; 595 size_t count; 596{ 597 volatile u_int32_t *d; 598 599 d = (volatile u_int32_t *)(bsh + offset); 600 while (count--) 601 *d++ = *addr++; 602 __asm__ volatile("eieio; sync"); 603} 604 605#define bus_space_write_region_stream_8 \ 606 !!! bus_space_write_region_stream_8 unimplemented !!! 607 608/* 609 * void bus_space_set_multi_N __P((bus_space_tag_t tag, 610 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 611 * size_t count)); 612 * 613 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 614 * by tag/handle/offset `count' times. 615 */ 616static __inline void bus_space_set_multi_1 __P((bus_space_tag_t, 617 bus_space_handle_t, bus_size_t, u_int8_t, size_t)); 618static __inline void bus_space_set_multi_2 __P((bus_space_tag_t, 619 bus_space_handle_t, bus_size_t, u_int16_t, size_t)); 620static __inline void bus_space_set_multi_4 __P((bus_space_tag_t, 621 bus_space_handle_t, bus_size_t, u_int32_t, size_t)); 622 623static __inline void 624bus_space_set_multi_1(tag, bsh, offset, val, count) 625 bus_space_tag_t tag; 626 bus_space_handle_t bsh; 627 bus_size_t offset; 628 u_int8_t val; 629 size_t count; 630{ 631 volatile u_int8_t *d; 632 633 d = (volatile u_int8_t *)(bsh + offset); 634 while (count--) 635 *d = val; 636 __asm__ volatile("eieio; sync"); 637} 638 639static __inline void 640bus_space_set_multi_2(tag, bsh, offset, val, count) 641 bus_space_tag_t tag; 642 bus_space_handle_t bsh; 643 bus_size_t offset; 644 u_int16_t val; 645 size_t count; 646{ 647 volatile u_int16_t *d; 648 649 d = (volatile u_int16_t *)(bsh + offset); 650 while (count--) 651 __asm__ volatile("sthbrx %0, 0, %1" :: 652 "r"(val), "r"(d)); 653 __asm__ volatile("eieio; sync"); 654} 655 656static __inline void 657bus_space_set_multi_4(tag, bsh, offset, val, count) 658 bus_space_tag_t tag; 659 bus_space_handle_t bsh; 660 bus_size_t offset; 661 u_int32_t val; 662 size_t count; 663{ 664 volatile u_int32_t *d; 665 666 d = (volatile u_int32_t *)(bsh + offset); 667 while (count--) 668 __asm__ volatile("stwbrx %0, 0, %1" :: 669 "r"(val), "r"(d)); 670 __asm__ volatile("eieio; sync"); 671} 672 673#define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!! 674 675/* 676 * void bus_space_set_multi_stream_N __P((bus_space_tag_t tag, 677 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 678 * size_t count)); 679 * 680 * Write the 2, 4, or 8 byte stream value `val' to bus space described 681 * by tag/handle/offset `count' times. 682 */ 683static __inline void bus_space_set_multi_stream_2 __P((bus_space_tag_t, 684 bus_space_handle_t, bus_size_t, u_int16_t, size_t)); 685static __inline void bus_space_set_multi_stream_4 __P((bus_space_tag_t, 686 bus_space_handle_t, bus_size_t, u_int32_t, size_t)); 687 688static __inline void 689bus_space_set_multi_stream_2(tag, bsh, offset, val, count) 690 bus_space_tag_t tag; 691 bus_space_handle_t bsh; 692 bus_size_t offset; 693 u_int16_t val; 694 size_t count; 695{ 696 volatile u_int16_t *d; 697 698 d = (volatile u_int16_t *)(bsh + offset); 699 while (count--) 700 *d = val; 701 __asm__ volatile("eieio; sync"); 702} 703 704static __inline void 705bus_space_set_multi_stream_4(tag, bsh, offset, val, count) 706 bus_space_tag_t tag; 707 bus_space_handle_t bsh; 708 bus_size_t offset; 709 u_int32_t val; 710 size_t count; 711{ 712 volatile u_int32_t *d; 713 714 d = (volatile u_int32_t *)(bsh + offset); 715 while (count--) 716 *d = val; 717 __asm__ volatile("eieio; sync"); 718} 719 720#define bus_space_set_multi_stream_8 \ 721 !!! bus_space_set_multi_stream_8 unimplemented !!! 722 723/* 724 * void bus_space_set_region_N __P((bus_space_tag_t tag, 725 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 726 * size_t count)); 727 * 728 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 729 * by tag/handle starting at `offset'. 730 */ 731static __inline void bus_space_set_region_1 __P((bus_space_tag_t, 732 bus_space_handle_t, bus_size_t, u_int8_t, size_t)); 733static __inline void bus_space_set_region_2 __P((bus_space_tag_t, 734 bus_space_handle_t, bus_size_t, u_int16_t, size_t)); 735static __inline void bus_space_set_region_4 __P((bus_space_tag_t, 736 bus_space_handle_t, bus_size_t, u_int32_t, size_t)); 737 738static __inline void 739bus_space_set_region_1(tag, bsh, offset, val, count) 740 bus_space_tag_t tag; 741 bus_space_handle_t bsh; 742 bus_size_t offset; 743 u_int8_t val; 744 size_t count; 745{ 746 volatile u_int8_t *d; 747 748 d = (volatile u_int8_t *)(bsh + offset); 749 while (count--) 750 *d++ = val; 751 __asm__ volatile("eieio; sync"); 752} 753 754static __inline void 755bus_space_set_region_2(tag, bsh, offset, val, count) 756 bus_space_tag_t tag; 757 bus_space_handle_t bsh; 758 bus_size_t offset; 759 u_int16_t val; 760 size_t count; 761{ 762 volatile u_int16_t *d; 763 764 d = (volatile u_int16_t *)(bsh + offset); 765 while (count--) 766 __asm__ volatile("sthbrx %0, 0, %1" :: 767 "r"(val), "r"(d++)); 768 __asm__ volatile("eieio; sync"); 769} 770 771static __inline void 772bus_space_set_region_4(tag, bsh, offset, val, count) 773 bus_space_tag_t tag; 774 bus_space_handle_t bsh; 775 bus_size_t offset; 776 u_int32_t val; 777 size_t count; 778{ 779 volatile u_int32_t *d; 780 781 d = (volatile u_int32_t *)(bsh + offset); 782 while (count--) 783 __asm__ volatile("stwbrx %0, 0, %1" :: 784 "r"(val), "r"(d++)); 785 __asm__ volatile("eieio; sync"); 786} 787 788#define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!! 789 790/* 791 * void bus_space_set_region_stream_N __P((bus_space_tag_t tag, 792 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 793 * size_t count)); 794 * 795 * Write `count' 2, 4, or 8 byte stream value `val' to bus space described 796 * by tag/handle starting at `offset'. 797 */ 798static __inline void bus_space_set_region_stream_2 __P((bus_space_tag_t, 799 bus_space_handle_t, bus_size_t, u_int16_t, size_t)); 800static __inline void bus_space_set_region_stream_4 __P((bus_space_tag_t, 801 bus_space_handle_t, bus_size_t, u_int32_t, size_t)); 802 803 804static __inline void 805bus_space_set_region_stream_2(tag, bsh, offset, val, count) 806 bus_space_tag_t tag; 807 bus_space_handle_t bsh; 808 bus_size_t offset; 809 u_int16_t val; 810 size_t count; 811{ 812 volatile u_int16_t *d; 813 814 d = (volatile u_int16_t *)(bsh + offset); 815 while (count--) 816 *d++ = val; 817 __asm__ volatile("eieio; sync"); 818} 819 820static __inline void 821bus_space_set_region_stream_4(tag, bsh, offset, val, count) 822 bus_space_tag_t tag; 823 bus_space_handle_t bsh; 824 bus_size_t offset; 825 u_int32_t val; 826 size_t count; 827{ 828 volatile u_int32_t *d; 829 830 d = (volatile u_int32_t *)(bsh + offset); 831 while (count--) 832 *d++ = val; 833 __asm__ volatile("eieio; sync"); 834} 835 836#define bus_space_set_region_stream_8 \ 837 !!! bus_space_set_region_stream_8 unimplemented !!! 838 839/* 840 * void bus_space_copy_region_N __P((bus_space_tag_t tag, 841 * bus_space_handle_t bsh1, bus_size_t off1, 842 * bus_space_handle_t bsh2, bus_size_t off2, 843 * size_t count)); 844 * 845 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 846 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 847 */ 848 849static __inline void bus_space_copy_region_1 __P((bus_space_tag_t, 850 bus_space_handle_t, bus_size_t, bus_space_handle_t, 851 bus_size_t, size_t)); 852static __inline void bus_space_copy_region_2 __P((bus_space_tag_t, 853 bus_space_handle_t, bus_size_t, bus_space_handle_t, 854 bus_size_t, size_t)); 855static __inline void bus_space_copy_region_4 __P((bus_space_tag_t, 856 bus_space_handle_t, bus_size_t, bus_space_handle_t, 857 bus_size_t, size_t)); 858 859static __inline void 860bus_space_copy_region_1(t, h1, o1, h2, o2, c) 861 bus_space_tag_t t; 862 bus_space_handle_t h1; 863 bus_size_t o1; 864 bus_space_handle_t h2; 865 bus_size_t o2; 866 size_t c; 867{ 868 bus_addr_t addr1 = h1 + o1; 869 bus_addr_t addr2 = h2 + o2; 870 871 if (addr1 >= addr2) { 872 /* src after dest: copy forward */ 873 for (; c != 0; c--, addr1++, addr2++) 874 *(volatile u_int8_t *)(addr2) = 875 *(volatile u_int8_t *)(addr1); 876 } else { 877 /* dest after src: copy backwards */ 878 for (addr1 += (c - 1), addr2 += (c - 1); 879 c != 0; c--, addr1--, addr2--) 880 *(volatile u_int8_t *)(addr2) = 881 *(volatile u_int8_t *)(addr1); 882 } 883} 884 885static __inline void 886bus_space_copy_region_2(t, h1, o1, h2, o2, c) 887 bus_space_tag_t t; 888 bus_space_handle_t h1; 889 bus_size_t o1; 890 bus_space_handle_t h2; 891 bus_size_t o2; 892 size_t c; 893{ 894 bus_addr_t addr1 = h1 + o1; 895 bus_addr_t addr2 = h2 + o2; 896 897 if (addr1 >= addr2) { 898 /* src after dest: copy forward */ 899 for (; c != 0; c--, addr1 += 2, addr2 += 2) 900 *(volatile u_int16_t *)(addr2) = 901 *(volatile u_int16_t *)(addr1); 902 } else { 903 /* dest after src: copy backwards */ 904 for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1); 905 c != 0; c--, addr1 -= 2, addr2 -= 2) 906 *(volatile u_int16_t *)(addr2) = 907 *(volatile u_int16_t *)(addr1); 908 } 909} 910 911static __inline void 912bus_space_copy_region_4(t, h1, o1, h2, o2, c) 913 bus_space_tag_t t; 914 bus_space_handle_t h1; 915 bus_size_t o1; 916 bus_space_handle_t h2; 917 bus_size_t o2; 918 size_t c; 919{ 920 bus_addr_t addr1 = h1 + o1; 921 bus_addr_t addr2 = h2 + o2; 922 923 if (addr1 >= addr2) { 924 /* src after dest: copy forward */ 925 for (; c != 0; c--, addr1 += 4, addr2 += 4) 926 *(volatile u_int32_t *)(addr2) = 927 *(volatile u_int32_t *)(addr1); 928 } else { 929 /* dest after src: copy backwards */ 930 for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1); 931 c != 0; c--, addr1 -= 4, addr2 -= 4) 932 *(volatile u_int32_t *)(addr2) = 933 *(volatile u_int32_t *)(addr1); 934 } 935} 936 937#define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!! 938 939/* 940 * Bus read/write barrier methods. 941 * 942 * void bus_space_barrier __P((bus_space_tag_t tag, 943 * bus_space_handle_t bsh, bus_size_t offset, 944 * bus_size_t len, int flags)); 945 * 946 */ 947#define bus_space_barrier(t, h, o, l, f) \ 948 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 949#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 950#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 951 952#define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 953 954/* 955 * Bus DMA methods. 956 */ 957 958/* 959 * Flags used in various bus DMA methods. 960 */ 961#define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */ 962#define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */ 963#define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */ 964#define BUS_DMA_COHERENT 0x04 /* hint: map memory DMA coherent */ 965#define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */ 966#define BUS_DMA_BUS2 0x20 967#define BUS_DMA_BUS3 0x40 968#define BUS_DMA_BUS4 0x80 969 970/* Forwards needed by prototypes below. */ 971struct mbuf; 972struct uio; 973 974/* 975 * Operations performed by bus_dmamap_sync(). 976 */ 977#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ 978#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ 979#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ 980#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ 981 982typedef struct prep_bus_dma_tag *bus_dma_tag_t; 983typedef struct prep_bus_dmamap *bus_dmamap_t; 984 985/* 986 * bus_dma_segment_t 987 * 988 * Describes a single contiguous DMA transaction. Values 989 * are suitable for programming into DMA registers. 990 */ 991struct prep_bus_dma_segment { 992 bus_addr_t ds_addr; /* DMA address */ 993 bus_size_t ds_len; /* length of transfer */ 994}; 995typedef struct prep_bus_dma_segment bus_dma_segment_t; 996 997/* 998 * bus_dma_tag_t 999 * 1000 * A machine-dependent opaque type describing the implementation of 1001 * DMA for a given bus. 1002 */ 1003 1004struct prep_bus_dma_tag { 1005 /* 1006 * The `bounce threshold' is checked while we are loading 1007 * the DMA map. If the physical address of the segment 1008 * exceeds the threshold, an error will be returned. The 1009 * caller can then take whatever action is necessary to 1010 * bounce the transfer. If this value is 0, it will be 1011 * ignored. 1012 */ 1013 bus_addr_t _bounce_thresh; 1014 1015 /* 1016 * DMA mapping methods. 1017 */ 1018 int (*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int, 1019 bus_size_t, bus_size_t, int, bus_dmamap_t *)); 1020 void (*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t)); 1021 int (*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *, 1022 bus_size_t, struct proc *, int)); 1023 int (*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t, 1024 struct mbuf *, int)); 1025 int (*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t, 1026 struct uio *, int)); 1027 int (*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t, 1028 bus_dma_segment_t *, int, bus_size_t, int)); 1029 void (*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t)); 1030 void (*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t, 1031 bus_addr_t, bus_size_t, int)); 1032 1033 /* 1034 * DMA memory utility functions. 1035 */ 1036 int (*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t, 1037 bus_size_t, bus_dma_segment_t *, int, int *, int)); 1038 void (*_dmamem_free) __P((bus_dma_tag_t, 1039 bus_dma_segment_t *, int)); 1040 int (*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *, 1041 int, size_t, caddr_t *, int)); 1042 void (*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t)); 1043 int (*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *, 1044 int, int, int, int)); 1045}; 1046 1047#define bus_dmamap_create(t, s, n, m, b, f, p) \ 1048 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p)) 1049#define bus_dmamap_destroy(t, p) \ 1050 (*(t)->_dmamap_destroy)((t), (p)) 1051#define bus_dmamap_load(t, m, b, s, p, f) \ 1052 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f)) 1053#define bus_dmamap_load_mbuf(t, m, b, f) \ 1054 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f)) 1055#define bus_dmamap_load_uio(t, m, u, f) \ 1056 (*(t)->_dmamap_load_uio)((t), (m), (u), (f)) 1057#define bus_dmamap_load_raw(t, m, sg, n, s, f) \ 1058 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f)) 1059#define bus_dmamap_unload(t, p) \ 1060 (*(t)->_dmamap_unload)((t), (p)) 1061#define bus_dmamap_sync(t, p, o, l, ops) \ 1062 (void)((t)->_dmamap_sync ? \ 1063 (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0) 1064 1065#define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \ 1066 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f)) 1067#define bus_dmamem_free(t, sg, n) \ 1068 (*(t)->_dmamem_free)((t), (sg), (n)) 1069#define bus_dmamem_map(t, sg, n, s, k, f) \ 1070 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f)) 1071#define bus_dmamem_unmap(t, k, s) \ 1072 (*(t)->_dmamem_unmap)((t), (k), (s)) 1073#define bus_dmamem_mmap(t, sg, n, o, p, f) \ 1074 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) 1075 1076/* 1077 * bus_dmamap_t 1078 * 1079 * Describes a DMA mapping. 1080 */ 1081struct prep_bus_dmamap { 1082 /* 1083 * PRIVATE MEMBERS: not for use my machine-independent code. 1084 */ 1085 bus_size_t _dm_size; /* largest DMA transfer mappable */ 1086 int _dm_segcnt; /* number of segs this map can map */ 1087 bus_size_t _dm_maxsegsz; /* largest possible segment */ 1088 bus_size_t _dm_boundary; /* don't cross this */ 1089 bus_addr_t _dm_bounce_thresh; /* bounce threshold; see tag */ 1090 int _dm_flags; /* misc. flags */ 1091 1092 void *_dm_cookie; /* cookie for bus-specific functions */ 1093 1094 /* 1095 * PUBLIC MEMBERS: these are used by machine-independent code. 1096 */ 1097 bus_size_t dm_mapsize; /* size of the mapping */ 1098 int dm_nsegs; /* # valid segments in mapping */ 1099 bus_dma_segment_t dm_segs[1]; /* segments; variable length */ 1100}; 1101 1102#ifdef _PREP_BUS_DMA_PRIVATE 1103int _bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t, 1104 bus_size_t, int, bus_dmamap_t *)); 1105void _bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t)); 1106int _bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *, 1107 bus_size_t, struct proc *, int)); 1108int _bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t, 1109 struct mbuf *, int)); 1110int _bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t, 1111 struct uio *, int)); 1112int _bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t, 1113 bus_dma_segment_t *, int, bus_size_t, int)); 1114void _bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t)); 1115void _bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t, 1116 bus_size_t, int)); 1117 1118int _bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size, 1119 bus_size_t alignment, bus_size_t boundary, 1120 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags)); 1121void _bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, 1122 int nsegs)); 1123int _bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, 1124 int nsegs, size_t size, caddr_t *kvap, int flags)); 1125void _bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva, 1126 size_t size)); 1127int _bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, 1128 int nsegs, int off, int prot, int flags)); 1129 1130int _bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size, 1131 bus_size_t alignment, bus_size_t boundary, 1132 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, 1133 paddr_t low, paddr_t high)); 1134#endif /* _PREP_BUS_DMA_PRIVATE */ 1135#endif /* _PREP_BUS_H_ */ 1136