1 1.19 skrll /* $NetBSD: bus.h,v 1.19 2019/09/23 16:17:58 skrll Exp $ */ 2 1.1 fredette 3 1.1 fredette /*- 4 1.1 fredette * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. 5 1.1 fredette * All rights reserved. 6 1.1 fredette * 7 1.1 fredette * This code is derived from software contributed to The NetBSD Foundation 8 1.1 fredette * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 1.1 fredette * NASA Ames Research Center. 10 1.1 fredette * 11 1.1 fredette * Redistribution and use in source and binary forms, with or without 12 1.1 fredette * modification, are permitted provided that the following conditions 13 1.1 fredette * are met: 14 1.1 fredette * 1. Redistributions of source code must retain the above copyright 15 1.1 fredette * notice, this list of conditions and the following disclaimer. 16 1.1 fredette * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 fredette * notice, this list of conditions and the following disclaimer in the 18 1.1 fredette * documentation and/or other materials provided with the distribution. 19 1.1 fredette * 20 1.1 fredette * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.1 fredette * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 fredette * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 fredette * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.1 fredette * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.1 fredette * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.1 fredette * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.1 fredette * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 fredette * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 fredette * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 fredette * POSSIBILITY OF SUCH DAMAGE. 31 1.1 fredette */ 32 1.1 fredette 33 1.1 fredette /* 34 1.1 fredette * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 35 1.1 fredette * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 36 1.1 fredette * 37 1.1 fredette * Redistribution and use in source and binary forms, with or without 38 1.1 fredette * modification, are permitted provided that the following conditions 39 1.1 fredette * are met: 40 1.1 fredette * 1. Redistributions of source code must retain the above copyright 41 1.1 fredette * notice, this list of conditions and the following disclaimer. 42 1.1 fredette * 2. Redistributions in binary form must reproduce the above copyright 43 1.1 fredette * notice, this list of conditions and the following disclaimer in the 44 1.1 fredette * documentation and/or other materials provided with the distribution. 45 1.1 fredette * 3. All advertising materials mentioning features or use of this software 46 1.1 fredette * must display the following acknowledgement: 47 1.1 fredette * This product includes software developed by Christopher G. Demetriou 48 1.1 fredette * for the NetBSD Project. 49 1.1 fredette * 4. The name of the author may not be used to endorse or promote products 50 1.1 fredette * derived from this software without specific prior written permission 51 1.1 fredette * 52 1.1 fredette * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 53 1.1 fredette * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 54 1.1 fredette * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 55 1.1 fredette * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 56 1.1 fredette * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 57 1.1 fredette * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 58 1.1 fredette * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 59 1.1 fredette * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60 1.1 fredette * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 61 1.1 fredette * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 1.1 fredette */ 63 1.1 fredette 64 1.1 fredette #ifndef _SUN68K_BUS_H_ 65 1.1 fredette #define _SUN68K_BUS_H_ 66 1.1 fredette 67 1.1 fredette #define SUN68K_BUS_SPACE 0 68 1.1 fredette 69 1.1 fredette /* 70 1.1 fredette * Bus address and size types 71 1.1 fredette */ 72 1.1 fredette typedef u_long bus_space_handle_t; 73 1.1 fredette typedef u_long bus_type_t; 74 1.1 fredette typedef u_long bus_addr_t; 75 1.1 fredette typedef u_long bus_size_t; 76 1.6 cl 77 1.19 skrll #define PRIxBSH "lx" 78 1.19 skrll #define PRIxBUSADDR "lx" 79 1.19 skrll #define PRIxBUSSIZE "lx" 80 1.19 skrll #define PRIuBUSSIZE "lu" 81 1.19 skrll 82 1.7 chs #define BUS_ADDR_PADDR(x) ((x) & 0xffffffff) 83 1.1 fredette 84 1.1 fredette /* 85 1.1 fredette * Access methods for bus resources and address space. 86 1.1 fredette */ 87 1.1 fredette typedef struct sun68k_bus_space_tag *bus_space_tag_t; 88 1.1 fredette 89 1.1 fredette struct sun68k_bus_space_tag { 90 1.1 fredette void *cookie; 91 1.1 fredette bus_space_tag_t parent; 92 1.1 fredette 93 1.7 chs int (*sun68k_bus_map)( 94 1.1 fredette bus_space_tag_t, 95 1.1 fredette bus_type_t, 96 1.1 fredette bus_addr_t, 97 1.1 fredette bus_size_t, 98 1.1 fredette int, /*flags*/ 99 1.1 fredette vaddr_t, /*preferred vaddr*/ 100 1.7 chs bus_space_handle_t *); 101 1.7 chs 102 1.7 chs int (*sun68k_bus_unmap)( 103 1.1 fredette bus_space_tag_t, 104 1.1 fredette bus_space_handle_t, 105 1.7 chs bus_size_t); 106 1.7 chs 107 1.7 chs int (*sun68k_bus_subregion)( 108 1.1 fredette bus_space_tag_t, 109 1.1 fredette bus_space_handle_t, 110 1.1 fredette bus_size_t, /*offset*/ 111 1.1 fredette bus_size_t, /*size*/ 112 1.7 chs bus_space_handle_t *); 113 1.1 fredette 114 1.7 chs void (*sun68k_bus_barrier)( 115 1.1 fredette bus_space_tag_t, 116 1.1 fredette bus_space_handle_t, 117 1.1 fredette bus_size_t, /*offset*/ 118 1.1 fredette bus_size_t, /*size*/ 119 1.7 chs int); /*flags*/ 120 1.1 fredette 121 1.7 chs paddr_t (*sun68k_bus_mmap)( 122 1.1 fredette bus_space_tag_t, 123 1.1 fredette bus_type_t, /**/ 124 1.1 fredette bus_addr_t, /**/ 125 1.3 fredette off_t, /*offset*/ 126 1.3 fredette int, /*prot*/ 127 1.7 chs int); /*flags*/ 128 1.1 fredette 129 1.7 chs void *(*sun68k_intr_establish)( 130 1.1 fredette bus_space_tag_t, 131 1.1 fredette int, /*bus-specific intr*/ 132 1.1 fredette int, /*device class level, 133 1.1 fredette see machine/intr.h*/ 134 1.1 fredette int, /*flags*/ 135 1.7 chs int (*)(void *), /*handler*/ 136 1.7 chs void *); /*handler arg*/ 137 1.1 fredette 138 1.7 chs int (*sun68k_bus_peek)( 139 1.1 fredette bus_space_tag_t, 140 1.1 fredette bus_space_handle_t, 141 1.1 fredette bus_size_t, /*offset*/ 142 1.1 fredette size_t, /*probe size*/ 143 1.7 chs void *); /*result ptr*/ 144 1.1 fredette 145 1.7 chs int (*sun68k_bus_poke)( 146 1.1 fredette bus_space_tag_t, 147 1.1 fredette bus_space_handle_t, 148 1.1 fredette bus_size_t, /*offset*/ 149 1.1 fredette size_t, /*probe size*/ 150 1.7 chs uint32_t); /*value*/ 151 1.1 fredette }; 152 1.1 fredette 153 1.1 fredette #if 0 154 1.1 fredette /* 155 1.1 fredette * The following macro could be used to generate the bus_space*() functions 156 1.1 fredette * but it uses a gcc extension and is ANSI-only. 157 1.7 chs #define PROTO_bus_space_xxx (bus_space_tag_t t, ...) 158 1.1 fredette #define RETURNTYPE_bus_space_xxx void * 159 1.1 fredette #define BUSFUN(name, returntype, t, args...) \ 160 1.11 perry __inline RETURNTYPE_##name \ 161 1.1 fredette bus_##name PROTO_##name \ 162 1.1 fredette { \ 163 1.1 fredette while (t->sun68k_##name == NULL) \ 164 1.1 fredette t = t->parent; \ 165 1.1 fredette return (*(t)->sun68k_##name)(t, args); \ 166 1.1 fredette } 167 1.1 fredette */ 168 1.1 fredette #endif 169 1.1 fredette 170 1.1 fredette /* 171 1.1 fredette * Bus space function prototypes. 172 1.1 fredette */ 173 1.7 chs static int bus_space_map( 174 1.1 fredette bus_space_tag_t, 175 1.1 fredette bus_addr_t, 176 1.1 fredette bus_size_t, 177 1.1 fredette int, /*flags*/ 178 1.7 chs bus_space_handle_t *); 179 1.7 chs static int bus_space_map2( 180 1.1 fredette bus_space_tag_t, 181 1.1 fredette bus_type_t, 182 1.1 fredette bus_addr_t, 183 1.1 fredette bus_size_t, 184 1.1 fredette int, /*flags*/ 185 1.1 fredette vaddr_t, /*preferred vaddr*/ 186 1.7 chs bus_space_handle_t *); 187 1.7 chs static int bus_space_unmap( 188 1.1 fredette bus_space_tag_t, 189 1.1 fredette bus_space_handle_t, 190 1.7 chs bus_size_t); 191 1.7 chs static int bus_space_subregion( 192 1.1 fredette bus_space_tag_t, 193 1.1 fredette bus_space_handle_t, 194 1.1 fredette bus_size_t, 195 1.1 fredette bus_size_t, 196 1.7 chs bus_space_handle_t *); 197 1.7 chs static void bus_space_barrier( 198 1.1 fredette bus_space_tag_t, 199 1.1 fredette bus_space_handle_t, 200 1.1 fredette bus_size_t, 201 1.1 fredette bus_size_t, 202 1.7 chs int); 203 1.7 chs static paddr_t bus_space_mmap( 204 1.3 fredette bus_space_tag_t, 205 1.3 fredette bus_addr_t, /**/ 206 1.3 fredette off_t, /*offset*/ 207 1.3 fredette int, /*prot*/ 208 1.7 chs int); /*flags*/ 209 1.7 chs static paddr_t bus_space_mmap2( 210 1.1 fredette bus_space_tag_t, 211 1.3 fredette bus_type_t, 212 1.1 fredette bus_addr_t, /**/ 213 1.3 fredette off_t, /*offset*/ 214 1.3 fredette int, /*prot*/ 215 1.7 chs int); /*flags*/ 216 1.7 chs static void *bus_intr_establish( 217 1.1 fredette bus_space_tag_t, 218 1.1 fredette int, /*bus-specific intr*/ 219 1.1 fredette int, /*device class level, 220 1.1 fredette see machine/intr.h*/ 221 1.1 fredette int, /*flags*/ 222 1.7 chs int (*)(void *), /*handler*/ 223 1.7 chs void *); /*handler arg*/ 224 1.7 chs static int _bus_space_peek( 225 1.1 fredette bus_space_tag_t, 226 1.1 fredette bus_space_handle_t, 227 1.1 fredette bus_size_t, /*offset*/ 228 1.1 fredette size_t, /*probe size*/ 229 1.7 chs void *); /*result ptr*/ 230 1.7 chs static int _bus_space_poke( 231 1.1 fredette bus_space_tag_t, 232 1.1 fredette bus_space_handle_t, 233 1.1 fredette bus_size_t, /*offset*/ 234 1.1 fredette size_t, /*probe size*/ 235 1.7 chs uint32_t); /*value*/ 236 1.1 fredette 237 1.1 fredette /* This macro finds the first "upstream" implementation of method `f' */ 238 1.1 fredette #define _BS_CALL(t,f) \ 239 1.1 fredette while (t->f == NULL) \ 240 1.1 fredette t = t->parent; \ 241 1.1 fredette return (*(t)->f) 242 1.1 fredette 243 1.18 mrg static __inline int 244 1.7 chs bus_space_map(bus_space_tag_t t, bus_addr_t a, bus_size_t s, int f, 245 1.7 chs bus_space_handle_t *hp) 246 1.1 fredette { 247 1.1 fredette _BS_CALL(t, sun68k_bus_map)((t), 0, (a), (s), (f), 0, (hp)); 248 1.1 fredette } 249 1.1 fredette 250 1.18 mrg static __inline int 251 1.7 chs bus_space_map2(bus_space_tag_t t, bus_type_t bt, bus_addr_t a, bus_size_t s, 252 1.7 chs int f, vaddr_t v, bus_space_handle_t *hp) 253 1.1 fredette { 254 1.1 fredette _BS_CALL(t, sun68k_bus_map)(t, bt, a, s, f, v, hp); 255 1.1 fredette } 256 1.1 fredette 257 1.18 mrg static __inline int 258 1.7 chs bus_space_unmap(bus_space_tag_t t, bus_space_handle_t h, bus_size_t s) 259 1.1 fredette { 260 1.1 fredette _BS_CALL(t, sun68k_bus_unmap)(t, h, s); 261 1.1 fredette } 262 1.1 fredette 263 1.18 mrg static __inline int 264 1.7 chs bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 265 1.7 chs bus_size_t s, bus_space_handle_t *hp) 266 1.1 fredette { 267 1.1 fredette _BS_CALL(t, sun68k_bus_subregion)(t, h, o, s, hp); 268 1.1 fredette } 269 1.1 fredette 270 1.18 mrg static __inline paddr_t 271 1.7 chs bus_space_mmap(bus_space_tag_t t, bus_addr_t a, off_t o, int p, int f) 272 1.3 fredette { 273 1.3 fredette _BS_CALL(t, sun68k_bus_mmap)(t, 0, a, o, p, f); 274 1.3 fredette } 275 1.3 fredette 276 1.18 mrg static __inline paddr_t 277 1.7 chs bus_space_mmap2(bus_space_tag_t t, bus_type_t bt, bus_addr_t a, off_t o, int p, 278 1.7 chs int f) 279 1.1 fredette { 280 1.3 fredette _BS_CALL(t, sun68k_bus_mmap)(t, bt, a, o, p, f); 281 1.1 fredette } 282 1.1 fredette 283 1.18 mrg static __inline void * 284 1.7 chs bus_intr_establish(bus_space_tag_t t, int p, int l, int f, int (*h)(void *), 285 1.7 chs void *a) 286 1.1 fredette { 287 1.1 fredette _BS_CALL(t, sun68k_intr_establish)(t, p, l, f, h, a); 288 1.1 fredette } 289 1.1 fredette 290 1.18 mrg static __inline void 291 1.7 chs bus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 292 1.7 chs bus_size_t s, int f) 293 1.1 fredette { 294 1.1 fredette _BS_CALL(t, sun68k_bus_barrier)(t, h, o, s, f); 295 1.1 fredette } 296 1.1 fredette 297 1.18 mrg static __inline int 298 1.7 chs _bus_space_peek(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, size_t s, 299 1.7 chs void *vp) 300 1.1 fredette { 301 1.1 fredette _BS_CALL(t, sun68k_bus_peek)(t, h, o, s, vp); 302 1.1 fredette } 303 1.1 fredette 304 1.18 mrg static __inline int 305 1.7 chs _bus_space_poke(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, size_t s, 306 1.7 chs uint32_t v) 307 1.1 fredette { 308 1.1 fredette _BS_CALL(t, sun68k_bus_poke)(t, h, o, s, v); 309 1.1 fredette } 310 1.1 fredette 311 1.1 fredette #if 0 312 1.7 chs int bus_space_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t, bus_size_t, 313 1.7 chs bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *); 314 1.7 chs void bus_space_free(bus_space_tag_t, bus_space_handle_t, bus_size_t); 315 1.1 fredette #endif 316 1.1 fredette 317 1.13 tsutsui /* 318 1.13 tsutsui * void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t); 319 1.13 tsutsui * 320 1.13 tsutsui * Get the kernel virtual address for the mapped bus space. 321 1.13 tsutsui * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR. 322 1.13 tsutsui * (XXX not enforced) 323 1.13 tsutsui */ 324 1.13 tsutsui #define bus_space_vaddr(t, h) ((void)(t), (void *)(h)) 325 1.13 tsutsui 326 1.1 fredette /* flags for bus space map functions */ 327 1.1 fredette #define BUS_SPACE_MAP_CACHEABLE 0x0001 328 1.1 fredette #define BUS_SPACE_MAP_LINEAR 0x0002 329 1.1 fredette #define BUS_SPACE_MAP_PREFETCHABLE 0x0004 330 1.1 fredette #define BUS_SPACE_MAP_BUS1 0x0100 /* placeholders for bus functions... */ 331 1.1 fredette #define BUS_SPACE_MAP_BUS2 0x0200 332 1.1 fredette #define BUS_SPACE_MAP_BUS3 0x0400 333 1.1 fredette #define BUS_SPACE_MAP_BUS4 0x0800 334 1.1 fredette 335 1.1 fredette /* Internal flag: try to find and use a PROM maping for the device. */ 336 1.1 fredette #define _SUN68K_BUS_MAP_USE_PROM BUS_SPACE_MAP_BUS1 337 1.1 fredette 338 1.1 fredette /* flags for intr_establish() */ 339 1.1 fredette #define BUS_INTR_ESTABLISH_FASTTRAP 1 340 1.1 fredette #define BUS_INTR_ESTABLISH_SOFTINTR 2 341 1.1 fredette 342 1.1 fredette /* flags for bus_space_barrier() */ 343 1.1 fredette #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 344 1.1 fredette #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 345 1.1 fredette 346 1.1 fredette /* 347 1.1 fredette * int bus_space_peek_N(bus_space_tag_t tag, 348 1.1 fredette * bus_space_handle_t bsh, bus_size_t offset, u_intN_t *valuep); 349 1.1 fredette * 350 1.1 fredette * Cautiously read 1, 2, 4 or 8 byte quantity from bus space described 351 1.1 fredette * by tag/handle/offset. 352 1.1 fredette * If no hardware responds to the read access, the function returns a 353 1.1 fredette * non-zero value. Otherwise the value read is placed in `valuep'. 354 1.1 fredette */ 355 1.1 fredette 356 1.1 fredette #define bus_space_peek_1(t, h, o, vp) \ 357 1.7 chs _bus_space_peek(t, h, o, sizeof(uint8_t), (void *)vp) 358 1.1 fredette 359 1.1 fredette #define bus_space_peek_2(t, h, o, vp) \ 360 1.7 chs _bus_space_peek(t, h, o, sizeof(uint16_t), (void *)vp) 361 1.1 fredette 362 1.1 fredette #define bus_space_peek_4(t, h, o, vp) \ 363 1.7 chs _bus_space_peek(t, h, o, sizeof(uint32_t), (void *)vp) 364 1.1 fredette 365 1.1 fredette /* 366 1.1 fredette * int bus_space_poke_N(bus_space_tag_t tag, 367 1.7 chs * bus_space_handle_t bsh, bus_size_t offset, uintN_t value); 368 1.1 fredette * 369 1.1 fredette * Cautiously write 1, 2, 4 or 8 byte quantity to bus space described 370 1.1 fredette * by tag/handle/offset. 371 1.1 fredette * If no hardware responds to the write access, the function returns a 372 1.1 fredette * non-zero value. 373 1.1 fredette */ 374 1.1 fredette 375 1.1 fredette #define bus_space_poke_1(t, h, o, v) \ 376 1.7 chs _bus_space_poke(t, h, o, sizeof(uint8_t), v) 377 1.1 fredette 378 1.1 fredette #define bus_space_poke_2(t, h, o, v) \ 379 1.7 chs _bus_space_poke(t, h, o, sizeof(uint16_t), v) 380 1.1 fredette 381 1.1 fredette #define bus_space_poke_4(t, h, o, v) \ 382 1.7 chs _bus_space_poke(t, h, o, sizeof(uint32_t), v) 383 1.1 fredette 384 1.1 fredette /* 385 1.7 chs * uintN_t bus_space_read_N(bus_space_tag_t tag, 386 1.7 chs * bus_space_handle_t bsh, bus_size_t offset); 387 1.1 fredette * 388 1.1 fredette * Read a 1, 2, 4, or 8 byte quantity from bus space 389 1.1 fredette * described by tag/handle/offset. 390 1.1 fredette */ 391 1.1 fredette 392 1.1 fredette #define bus_space_read_1(t, h, o) \ 393 1.7 chs ((void)t, *(volatile uint8_t *)((h) + (o))) 394 1.1 fredette 395 1.1 fredette #define bus_space_read_2(t, h, o) \ 396 1.7 chs ((void)t, *(volatile uint16_t *)((h) + (o))) 397 1.1 fredette 398 1.1 fredette #define bus_space_read_4(t, h, o) \ 399 1.7 chs ((void)t, *(volatile uint32_t *)((h) + (o))) 400 1.1 fredette 401 1.1 fredette #define bus_space_read_8(t, h, o) \ 402 1.7 chs ((void)t, *(volatile uint64_t *)((h) + (o))) 403 1.1 fredette 404 1.1 fredette 405 1.1 fredette /* 406 1.7 chs * void bus_space_write_N(bus_space_tag_t tag, 407 1.1 fredette * bus_space_handle_t bsh, bus_size_t offset, 408 1.7 chs * uintN_t value); 409 1.1 fredette * 410 1.1 fredette * Write the 1, 2, 4, or 8 byte value `value' to bus space 411 1.1 fredette * described by tag/handle/offset. 412 1.1 fredette */ 413 1.1 fredette 414 1.1 fredette #define bus_space_write_1(t, h, o, v) do { \ 415 1.7 chs ((void)t, (void)(*(volatile uint8_t *)((h) + (o)) = (v))); \ 416 1.1 fredette } while (0) 417 1.1 fredette 418 1.1 fredette #define bus_space_write_2(t, h, o, v) do { \ 419 1.7 chs ((void)t, (void)(*(volatile uint16_t *)((h) + (o)) = (v))); \ 420 1.1 fredette } while (0) 421 1.1 fredette 422 1.1 fredette #define bus_space_write_4(t, h, o, v) do { \ 423 1.7 chs ((void)t, (void)(*(volatile uint32_t *)((h) + (o)) = (v))); \ 424 1.1 fredette } while (0) 425 1.1 fredette 426 1.1 fredette #define bus_space_write_8(t, h, o, v) do { \ 427 1.7 chs ((void)t, (void)(*(volatile uint64_t *)((h) + (o)) = (v))); \ 428 1.1 fredette } while (0) 429 1.1 fredette 430 1.1 fredette 431 1.1 fredette /* 432 1.7 chs * void bus_space_read_multi_N(bus_space_tag_t tag, 433 1.1 fredette * bus_space_handle_t bsh, bus_size_t offset, 434 1.7 chs * uintN_t *addr, bus_size_t count); 435 1.1 fredette * 436 1.1 fredette * Read `count' 1, 2, 4, or 8 byte quantities from bus space 437 1.1 fredette * described by tag/handle/offset and copy into buffer provided. 438 1.1 fredette */ 439 1.1 fredette 440 1.18 mrg static __inline void 441 1.7 chs bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 442 1.7 chs uint8_t *a, bus_size_t c) 443 1.1 fredette { 444 1.17 tsutsui volatile uint8_t *p; 445 1.17 tsutsui 446 1.17 tsutsui p = (volatile uint8_t *)(h + o); 447 1.1 fredette while (c-- > 0) 448 1.17 tsutsui *a++ = *p; 449 1.1 fredette } 450 1.1 fredette 451 1.18 mrg static __inline void 452 1.7 chs bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 453 1.7 chs uint16_t *a, bus_size_t c) 454 1.1 fredette { 455 1.17 tsutsui volatile uint16_t *p; 456 1.17 tsutsui 457 1.17 tsutsui p = (volatile uint16_t *)(h + o); 458 1.1 fredette while (c-- > 0) 459 1.17 tsutsui *a++ = *p; 460 1.1 fredette } 461 1.1 fredette 462 1.18 mrg static __inline void 463 1.7 chs bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 464 1.7 chs uint32_t *a, bus_size_t c) 465 1.1 fredette { 466 1.17 tsutsui volatile uint32_t *p; 467 1.17 tsutsui 468 1.17 tsutsui p = (volatile uint32_t *)(h + o); 469 1.1 fredette while (c-- > 0) 470 1.17 tsutsui *a++ = *p; 471 1.1 fredette } 472 1.1 fredette 473 1.18 mrg static __inline void 474 1.7 chs bus_space_read_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 475 1.7 chs uint64_t *a, bus_size_t c) 476 1.1 fredette { 477 1.17 tsutsui volatile uint64_t *p; 478 1.17 tsutsui 479 1.17 tsutsui p = (volatile uint64_t *)(h + o); 480 1.1 fredette while (c-- > 0) 481 1.17 tsutsui *a++ = *p; 482 1.1 fredette } 483 1.1 fredette 484 1.1 fredette 485 1.1 fredette /* 486 1.7 chs * void bus_space_write_multi_N(bus_space_tag_t tag, 487 1.1 fredette * bus_space_handle_t bsh, bus_size_t offset, 488 1.7 chs * const u_intN_t *addr, bus_size_t count); 489 1.1 fredette * 490 1.1 fredette * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 491 1.1 fredette * provided to bus space described by tag/handle/offset. 492 1.1 fredette */ 493 1.7 chs 494 1.18 mrg static __inline void 495 1.7 chs bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 496 1.7 chs const uint8_t *a, bus_size_t c) 497 1.1 fredette { 498 1.17 tsutsui volatile uint8_t *p; 499 1.17 tsutsui 500 1.17 tsutsui p = (volatile uint8_t *)(h + o); 501 1.1 fredette while (c-- > 0) 502 1.17 tsutsui *p = *a++; 503 1.1 fredette } 504 1.1 fredette 505 1.18 mrg static __inline void 506 1.7 chs bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 507 1.7 chs const uint16_t *a, bus_size_t c) 508 1.1 fredette { 509 1.17 tsutsui volatile uint16_t *p; 510 1.17 tsutsui 511 1.17 tsutsui p = (volatile uint16_t *)(h + o); 512 1.1 fredette while (c-- > 0) 513 1.17 tsutsui *p = *a++; 514 1.1 fredette } 515 1.1 fredette 516 1.18 mrg static __inline void 517 1.7 chs bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 518 1.7 chs const uint32_t *a, bus_size_t c) 519 1.1 fredette { 520 1.17 tsutsui volatile uint32_t *p; 521 1.17 tsutsui 522 1.17 tsutsui p = (volatile uint32_t *)(h + o); 523 1.1 fredette while (c-- > 0) 524 1.17 tsutsui *p = *a++; 525 1.1 fredette } 526 1.1 fredette 527 1.18 mrg static __inline void 528 1.7 chs bus_space_write_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 529 1.7 chs const uint64_t *a, bus_size_t c) 530 1.1 fredette { 531 1.17 tsutsui volatile uint64_t *p; 532 1.17 tsutsui 533 1.17 tsutsui p = (volatile uint64_t *)(h + o); 534 1.1 fredette while (c-- > 0) 535 1.17 tsutsui *p = *a++; 536 1.1 fredette } 537 1.1 fredette 538 1.1 fredette /* 539 1.7 chs * void bus_space_set_multi_N(bus_space_tag_t tag, 540 1.7 chs * bus_space_handle_t bsh, bus_size_t offset, uintN_t val, 541 1.7 chs * bus_size_t count); 542 1.1 fredette * 543 1.1 fredette * Write the 1, 2, 4, or 8 byte value `val' to bus space described 544 1.1 fredette * by tag/handle/offset `count' times. 545 1.1 fredette */ 546 1.1 fredette 547 1.18 mrg static __inline void 548 1.7 chs bus_space_set_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 549 1.7 chs const uint8_t v, bus_size_t c) 550 1.1 fredette { 551 1.17 tsutsui volatile uint8_t *p; 552 1.17 tsutsui 553 1.17 tsutsui p = (volatile uint8_t *)(h + o); 554 1.1 fredette while (c-- > 0) 555 1.17 tsutsui *p = v; 556 1.1 fredette } 557 1.1 fredette 558 1.18 mrg static __inline void 559 1.7 chs bus_space_set_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 560 1.7 chs const uint16_t v, bus_size_t c) 561 1.1 fredette { 562 1.17 tsutsui volatile uint16_t *p; 563 1.17 tsutsui 564 1.17 tsutsui p = (volatile uint16_t *)(h + o); 565 1.1 fredette while (c-- > 0) 566 1.17 tsutsui *p = v; 567 1.1 fredette } 568 1.1 fredette 569 1.18 mrg static __inline void 570 1.7 chs bus_space_set_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 571 1.7 chs const uint32_t v, bus_size_t c) 572 1.1 fredette { 573 1.17 tsutsui volatile uint32_t *p; 574 1.17 tsutsui 575 1.17 tsutsui p = (volatile uint32_t *)(h + o); 576 1.1 fredette while (c-- > 0) 577 1.17 tsutsui *p = v; 578 1.1 fredette } 579 1.1 fredette 580 1.18 mrg static __inline void 581 1.7 chs bus_space_set_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 582 1.7 chs const uint64_t v, bus_size_t c) 583 1.1 fredette { 584 1.17 tsutsui volatile uint64_t *p; 585 1.17 tsutsui 586 1.17 tsutsui p = (volatile uint64_t *)(h + o); 587 1.1 fredette while (c-- > 0) 588 1.17 tsutsui *p = v; 589 1.1 fredette } 590 1.1 fredette 591 1.1 fredette 592 1.1 fredette /* 593 1.7 chs * void bus_space_read_region_N(bus_space_tag_t tag, 594 1.1 fredette * bus_space_handle_t bsh, bus_size_t off, 595 1.7 chs * uintN_t *addr, bus_size_t count); 596 1.1 fredette * 597 1.1 fredette */ 598 1.7 chs 599 1.18 mrg static __inline void 600 1.7 chs bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 601 1.7 chs uint8_t *a, bus_size_t c) 602 1.1 fredette { 603 1.17 tsutsui volatile uint8_t *p; 604 1.17 tsutsui 605 1.17 tsutsui p = (volatile uint8_t *)(h + o); 606 1.17 tsutsui while (c-- > 0) 607 1.17 tsutsui *a++ = *p++; 608 1.1 fredette } 609 1.18 mrg static __inline void 610 1.7 chs bus_space_read_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 611 1.7 chs uint16_t *a, bus_size_t c) 612 1.1 fredette { 613 1.17 tsutsui volatile uint16_t *p; 614 1.17 tsutsui 615 1.17 tsutsui p = (volatile uint16_t *)(h + o); 616 1.17 tsutsui while (c-- > 0) 617 1.17 tsutsui *a++ = *p++; 618 1.1 fredette } 619 1.18 mrg static __inline void 620 1.7 chs bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 621 1.7 chs uint32_t *a, bus_size_t c) 622 1.1 fredette { 623 1.17 tsutsui volatile uint32_t *p; 624 1.17 tsutsui 625 1.17 tsutsui p = (volatile uint32_t *)(h + o); 626 1.17 tsutsui while (c-- > 0) 627 1.17 tsutsui *a++ = *p++; 628 1.1 fredette } 629 1.18 mrg static __inline void 630 1.7 chs bus_space_read_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 631 1.7 chs uint64_t *a, bus_size_t c) 632 1.1 fredette { 633 1.17 tsutsui volatile uint64_t *p; 634 1.17 tsutsui 635 1.17 tsutsui p = (volatile uint64_t *)(h + o); 636 1.17 tsutsui while (c-- > 0) 637 1.17 tsutsui *a++ = *p++; 638 1.1 fredette } 639 1.1 fredette 640 1.1 fredette /* 641 1.7 chs * void bus_space_write_region_N(bus_space_tag_t tag, 642 1.1 fredette * bus_space_handle_t bsh, bus_size_t off, 643 1.7 chs * uintN_t *addr, bus_size_t count); 644 1.1 fredette * 645 1.1 fredette */ 646 1.7 chs 647 1.18 mrg static __inline void 648 1.7 chs bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 649 1.7 chs const uint8_t *a, bus_size_t c) 650 1.1 fredette { 651 1.17 tsutsui volatile uint8_t *p; 652 1.17 tsutsui 653 1.17 tsutsui p = (volatile uint8_t *)(h + o); 654 1.17 tsutsui while (c-- > 0) 655 1.17 tsutsui *p++ = *a++; 656 1.1 fredette } 657 1.1 fredette 658 1.18 mrg static __inline void 659 1.7 chs bus_space_write_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 660 1.7 chs const uint16_t *a, bus_size_t c) 661 1.1 fredette { 662 1.17 tsutsui volatile uint16_t *p; 663 1.17 tsutsui 664 1.17 tsutsui p = (volatile uint16_t *)(h + o); 665 1.17 tsutsui while (c-- > 0) 666 1.17 tsutsui *p++ = *a++; 667 1.1 fredette } 668 1.1 fredette 669 1.18 mrg static __inline void 670 1.7 chs bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 671 1.7 chs const uint32_t *a, bus_size_t c) 672 1.1 fredette { 673 1.17 tsutsui volatile uint32_t *p; 674 1.17 tsutsui 675 1.17 tsutsui p = (volatile uint32_t *)(h + o); 676 1.17 tsutsui while (c-- > 0) 677 1.17 tsutsui *p++ = *a++; 678 1.1 fredette } 679 1.1 fredette 680 1.18 mrg static __inline void 681 1.7 chs bus_space_write_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 682 1.7 chs const uint64_t *a, bus_size_t c) 683 1.1 fredette { 684 1.17 tsutsui volatile uint64_t *p; 685 1.17 tsutsui 686 1.17 tsutsui p = (volatile uint64_t *)(h + o); 687 1.17 tsutsui while (c-- > 0) 688 1.17 tsutsui *p++ = *a++; 689 1.1 fredette } 690 1.1 fredette 691 1.1 fredette 692 1.1 fredette /* 693 1.7 chs * void bus_space_set_region_N(bus_space_tag_t tag, 694 1.1 fredette * bus_space_handle_t bsh, bus_size_t off, 695 1.7 chs * uintN_t *addr, bus_size_t count); 696 1.1 fredette * 697 1.1 fredette */ 698 1.7 chs 699 1.18 mrg static __inline void 700 1.7 chs bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 701 1.7 chs const uint8_t v, bus_size_t c) 702 1.1 fredette { 703 1.17 tsutsui volatile uint8_t *p; 704 1.17 tsutsui 705 1.17 tsutsui p = (volatile uint8_t *)(h + o); 706 1.17 tsutsui while (c-- > 0) 707 1.17 tsutsui *p++ = v; 708 1.1 fredette } 709 1.1 fredette 710 1.18 mrg static __inline void 711 1.7 chs bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 712 1.7 chs const uint16_t v, bus_size_t c) 713 1.1 fredette { 714 1.17 tsutsui volatile uint16_t *p; 715 1.17 tsutsui 716 1.17 tsutsui p = (volatile uint16_t *)(h + o); 717 1.17 tsutsui while (c-- > 0) 718 1.17 tsutsui *p++ = v; 719 1.1 fredette } 720 1.1 fredette 721 1.18 mrg static __inline void 722 1.7 chs bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 723 1.7 chs const uint32_t v, bus_size_t c) 724 1.1 fredette { 725 1.17 tsutsui volatile uint32_t *p; 726 1.17 tsutsui 727 1.17 tsutsui p = (volatile uint32_t *)(h + o); 728 1.17 tsutsui while (c-- > 0) 729 1.17 tsutsui *p++ = v; 730 1.1 fredette } 731 1.1 fredette 732 1.18 mrg static __inline void 733 1.7 chs bus_space_set_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 734 1.7 chs const uint64_t v, bus_size_t c) 735 1.1 fredette { 736 1.17 tsutsui volatile uint64_t *p; 737 1.17 tsutsui 738 1.17 tsutsui p = (volatile uint64_t *)(h + o); 739 1.17 tsutsui while (c-- > 0) 740 1.17 tsutsui *p++ = v; 741 1.1 fredette } 742 1.1 fredette 743 1.1 fredette 744 1.1 fredette /* 745 1.7 chs * void bus_space_copy_region_N(bus_space_tag_t tag, 746 1.1 fredette * bus_space_handle_t bsh1, bus_size_t off1, 747 1.1 fredette * bus_space_handle_t bsh2, bus_size_t off2, 748 1.7 chs * bus_size_t count); 749 1.1 fredette * 750 1.1 fredette * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 751 1.1 fredette * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 752 1.1 fredette */ 753 1.1 fredette 754 1.18 mrg static __inline void 755 1.7 chs bus_space_copy_region_1(bus_space_tag_t t, bus_space_handle_t h1, bus_size_t o1, 756 1.7 chs bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 757 1.1 fredette { 758 1.17 tsutsui volatile uint8_t *srcp, *dstp; 759 1.17 tsutsui bus_size_t offset; 760 1.17 tsutsui 761 1.17 tsutsui srcp = (volatile uint8_t *)(h1 + o1); 762 1.17 tsutsui dstp = (volatile uint8_t *)(h2 + o2); 763 1.17 tsutsui if (srcp >= dstp) { 764 1.17 tsutsui /* src after dest; copy forward */ 765 1.17 tsutsui for (offset = 0; c > 0; c--, offset++) 766 1.17 tsutsui dstp[offset] = srcp[offset]; 767 1.17 tsutsui } else { 768 1.17 tsutsui /* dst after src; copy backward */ 769 1.17 tsutsui for (offset = c; c > 0; c--, offset--) 770 1.17 tsutsui dstp[offset] = srcp[offset]; 771 1.17 tsutsui } 772 1.1 fredette } 773 1.1 fredette 774 1.18 mrg static __inline void 775 1.7 chs bus_space_copy_region_2(bus_space_tag_t t, bus_space_handle_t h1, bus_size_t o1, 776 1.7 chs bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 777 1.1 fredette { 778 1.17 tsutsui volatile uint16_t *srcp, *dstp; 779 1.17 tsutsui bus_size_t offset; 780 1.17 tsutsui 781 1.17 tsutsui srcp = (volatile uint16_t *)(h1 + o1); 782 1.17 tsutsui dstp = (volatile uint16_t *)(h2 + o2); 783 1.17 tsutsui if (srcp >= dstp) { 784 1.17 tsutsui /* src after dest; copy forward */ 785 1.17 tsutsui for (offset = 0; c > 0; c--, offset++) 786 1.17 tsutsui dstp[offset] = srcp[offset]; 787 1.17 tsutsui } else { 788 1.17 tsutsui /* dst after src; copy backward */ 789 1.17 tsutsui for (offset = c; c > 0; c--, offset--) 790 1.17 tsutsui dstp[offset] = srcp[offset]; 791 1.17 tsutsui } 792 1.1 fredette } 793 1.1 fredette 794 1.18 mrg static __inline void 795 1.7 chs bus_space_copy_region_4(bus_space_tag_t t, bus_space_handle_t h1, bus_size_t o1, 796 1.7 chs bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 797 1.1 fredette { 798 1.17 tsutsui volatile uint32_t *srcp, *dstp; 799 1.17 tsutsui bus_size_t offset; 800 1.17 tsutsui 801 1.17 tsutsui srcp = (volatile uint32_t *)(h1 + o1); 802 1.17 tsutsui dstp = (volatile uint32_t *)(h2 + o2); 803 1.17 tsutsui if (srcp >= dstp) { 804 1.17 tsutsui /* src after dest; copy forward */ 805 1.17 tsutsui for (offset = 0; c > 0; c--, offset++) 806 1.17 tsutsui dstp[offset] = srcp[offset]; 807 1.17 tsutsui } else { 808 1.17 tsutsui /* dst after src; copy backward */ 809 1.17 tsutsui for (offset = c; c > 0; c--, offset--) 810 1.17 tsutsui dstp[offset] = srcp[offset]; 811 1.17 tsutsui } 812 1.1 fredette } 813 1.1 fredette 814 1.18 mrg static __inline void 815 1.7 chs bus_space_copy_region_8(bus_space_tag_t t, bus_space_handle_t h1, bus_size_t o1, 816 1.7 chs bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 817 1.1 fredette { 818 1.17 tsutsui volatile uint64_t *srcp, *dstp; 819 1.17 tsutsui bus_size_t offset; 820 1.17 tsutsui 821 1.17 tsutsui srcp = (volatile uint64_t *)(h1 + o1); 822 1.17 tsutsui dstp = (volatile uint64_t *)(h2 + o2); 823 1.17 tsutsui if (srcp >= dstp) { 824 1.17 tsutsui /* src after dest; copy forward */ 825 1.17 tsutsui for (offset = 0; c > 0; c--, offset++) 826 1.17 tsutsui dstp[offset] = srcp[offset]; 827 1.17 tsutsui } else { 828 1.17 tsutsui /* dst after src; copy backward */ 829 1.17 tsutsui for (offset = c; c > 0; c--, offset--) 830 1.17 tsutsui dstp[offset] = srcp[offset]; 831 1.17 tsutsui } 832 1.1 fredette } 833 1.1 fredette 834 1.1 fredette /* 835 1.7 chs * void bus_space_copyin(bus_space_tag_t tag, 836 1.1 fredette * bus_space_handle_t bsh, bus_size_t off, 837 1.7 chs * void *addr, bus_size_t count); 838 1.1 fredette * 839 1.1 fredette * Copy `count' bytes from bus space starting at tag/bsh/off 840 1.1 fredette * to kernel memory at addr using the most optimized transfer 841 1.1 fredette * possible for the bus. 842 1.1 fredette */ 843 1.1 fredette 844 1.1 fredette #define bus_space_copyin(t, h, o, a, c) \ 845 1.7 chs ((void)t, w16copy((uint8_t *)((h) + (o)), (a), (c))) 846 1.1 fredette 847 1.1 fredette /* 848 1.7 chs * void bus_space_copyout(bus_space_tag_t tag, 849 1.1 fredette * bus_space_handle_t bsh, bus_size_t off, 850 1.7 chs * const void *addr, bus_size_t count); 851 1.1 fredette * 852 1.1 fredette * Copy `count' bytes to bus space starting at tag/bsh/off 853 1.1 fredette * from kernel memory at addr using the most optimized transfer 854 1.1 fredette * possible for the bus. 855 1.1 fredette */ 856 1.1 fredette 857 1.1 fredette #define bus_space_copyout(t, h, o, a, c) \ 858 1.7 chs ((void)t, w16copy((a), (uint8_t *)((h) + (o)), (c))) 859 1.1 fredette 860 1.1 fredette #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 861 1.1 fredette 862 1.13 tsutsui int find_prom_map(paddr_t, bus_type_t, int, vaddr_t *); 863 1.12 tsutsui 864 1.1 fredette /*--------------------------------*/ 865 1.1 fredette 866 1.1 fredette /* 867 1.1 fredette * Flags used in various bus DMA methods. 868 1.1 fredette */ 869 1.2 thorpej #define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */ 870 1.2 thorpej #define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */ 871 1.2 thorpej #define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */ 872 1.2 thorpej #define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */ 873 1.2 thorpej #define BUS_DMA_BUS1 0x010 /* placeholders for bus functions... */ 874 1.2 thorpej #define BUS_DMA_BUS2 0x020 875 1.2 thorpej #define BUS_DMA_BUS3 0x040 876 1.2 thorpej #define BUS_DMA_BUS4 0x080 877 1.2 thorpej #define BUS_DMA_READ 0x100 /* mapping is device -> memory only */ 878 1.2 thorpej #define BUS_DMA_WRITE 0x200 /* mapping is memory -> device only */ 879 1.4 kent #define BUS_DMA_NOCACHE 0x400 /* hint: map non-cached memory */ 880 1.1 fredette 881 1.1 fredette /* For devices that have a 24-bit address space */ 882 1.1 fredette #define BUS_DMA_24BIT BUS_DMA_BUS1 883 1.1 fredette 884 1.1 fredette /* Internal flag: current DVMA address is equal to the KVA buffer address */ 885 1.1 fredette #define _BUS_DMA_DIRECTMAP BUS_DMA_BUS2 886 1.1 fredette 887 1.1 fredette /* 888 1.1 fredette * Internal flag: current DVMA address has been double-mapped by hand 889 1.1 fredette * to the KVA buffer address (without the pmap's help). 890 1.1 fredette */ 891 1.1 fredette #define _BUS_DMA_NOPMAP BUS_DMA_BUS3 892 1.1 fredette 893 1.1 fredette /* Forwards needed by prototypes below. */ 894 1.1 fredette struct mbuf; 895 1.1 fredette struct uio; 896 1.1 fredette 897 1.1 fredette /* 898 1.1 fredette * Operations performed by bus_dmamap_sync(). 899 1.1 fredette */ 900 1.1 fredette #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ 901 1.1 fredette #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ 902 1.1 fredette #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ 903 1.1 fredette #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ 904 1.1 fredette 905 1.1 fredette typedef struct sun68k_bus_dma_tag *bus_dma_tag_t; 906 1.1 fredette typedef struct sun68k_bus_dmamap *bus_dmamap_t; 907 1.5 fvdl 908 1.7 chs #define BUS_DMA_TAG_VALID(t) ((t) != NULL) 909 1.1 fredette 910 1.1 fredette /* 911 1.1 fredette * bus_dma_segment_t 912 1.1 fredette * 913 1.1 fredette * Describes a single contiguous DMA transaction. Values 914 1.1 fredette * are suitable for programming into DMA registers. 915 1.1 fredette */ 916 1.1 fredette struct sun68k_bus_dma_segment { 917 1.1 fredette bus_addr_t ds_addr; /* DVMA address */ 918 1.1 fredette bus_size_t ds_len; /* length of transfer */ 919 1.1 fredette bus_size_t _ds_sgsize; /* size of allocated DVMA segment */ 920 1.1 fredette void *_ds_mlist; /* page list when dmamem_alloc'ed */ 921 1.1 fredette vaddr_t _ds_va; /* VA when dmamem_map'ed */ 922 1.1 fredette }; 923 1.1 fredette typedef struct sun68k_bus_dma_segment bus_dma_segment_t; 924 1.1 fredette 925 1.1 fredette 926 1.1 fredette /* 927 1.1 fredette * bus_dma_tag_t 928 1.1 fredette * 929 1.1 fredette * A machine-dependent opaque type describing the implementation of 930 1.1 fredette * DMA for a given bus. 931 1.1 fredette */ 932 1.1 fredette struct sun68k_bus_dma_tag { 933 1.1 fredette void *_cookie; /* cookie used in the guts */ 934 1.1 fredette 935 1.1 fredette /* 936 1.1 fredette * DMA mapping methods. 937 1.1 fredette */ 938 1.7 chs int (*_dmamap_create)(bus_dma_tag_t, bus_size_t, int, bus_size_t, 939 1.7 chs bus_size_t, int, bus_dmamap_t *); 940 1.7 chs void (*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t); 941 1.7 chs int (*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t, 942 1.7 chs struct proc *, int); 943 1.7 chs int (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t, struct mbuf *, 944 1.7 chs int); 945 1.7 chs int (*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t, struct uio *, 946 1.7 chs int); 947 1.7 chs int (*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t, 948 1.7 chs bus_dma_segment_t *, int, bus_size_t, int); 949 1.7 chs void (*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t); 950 1.7 chs void (*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t, bus_addr_t, 951 1.7 chs bus_size_t, int); 952 1.1 fredette 953 1.1 fredette /* 954 1.1 fredette * DMA memory utility functions. 955 1.1 fredette */ 956 1.7 chs int (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t, 957 1.7 chs bus_size_t, bus_dma_segment_t *, int, int *, int); 958 1.7 chs void (*_dmamem_free)(bus_dma_tag_t, bus_dma_segment_t *, int); 959 1.7 chs int (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *, int, size_t, 960 1.15 christos void **, int); 961 1.15 christos void (*_dmamem_unmap)(bus_dma_tag_t, void *, size_t); 962 1.7 chs paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *, int, off_t, 963 1.7 chs int, int); 964 1.1 fredette }; 965 1.1 fredette 966 1.1 fredette #define bus_dmamap_create(t, s, n, m, b, f, p) \ 967 1.1 fredette (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p)) 968 1.1 fredette #define bus_dmamap_destroy(t, p) \ 969 1.1 fredette (*(t)->_dmamap_destroy)((t), (p)) 970 1.1 fredette #define bus_dmamap_load(t, m, b, s, p, f) \ 971 1.1 fredette (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f)) 972 1.1 fredette #define bus_dmamap_load_mbuf(t, m, b, f) \ 973 1.1 fredette (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f)) 974 1.1 fredette #define bus_dmamap_load_uio(t, m, u, f) \ 975 1.1 fredette (*(t)->_dmamap_load_uio)((t), (m), (u), (f)) 976 1.1 fredette #define bus_dmamap_load_raw(t, m, sg, n, s, f) \ 977 1.1 fredette (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f)) 978 1.1 fredette #define bus_dmamap_unload(t, p) \ 979 1.1 fredette (*(t)->_dmamap_unload)((t), (p)) 980 1.1 fredette #define bus_dmamap_sync(t, p, o, l, ops) \ 981 1.1 fredette (void)((t)->_dmamap_sync ? \ 982 1.1 fredette (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0) 983 1.1 fredette 984 1.1 fredette #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \ 985 1.1 fredette (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f)) 986 1.1 fredette #define bus_dmamem_free(t, sg, n) \ 987 1.1 fredette (*(t)->_dmamem_free)((t), (sg), (n)) 988 1.1 fredette #define bus_dmamem_map(t, sg, n, s, k, f) \ 989 1.1 fredette (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f)) 990 1.1 fredette #define bus_dmamem_unmap(t, k, s) \ 991 1.1 fredette (*(t)->_dmamem_unmap)((t), (k), (s)) 992 1.1 fredette #define bus_dmamem_mmap(t, sg, n, o, p, f) \ 993 1.1 fredette (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) 994 1.1 fredette 995 1.14 mrg #define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP 996 1.14 mrg #define bus_dmatag_destroy(t) 997 1.14 mrg 998 1.1 fredette /* 999 1.1 fredette * bus_dmamap_t 1000 1.1 fredette * 1001 1.1 fredette * Describes a DMA mapping. 1002 1.1 fredette */ 1003 1.1 fredette struct sun68k_bus_dmamap { 1004 1.1 fredette /* 1005 1.1 fredette * PRIVATE MEMBERS: not for use by machine-independent code. 1006 1.1 fredette */ 1007 1.1 fredette bus_size_t _dm_size; /* largest DMA transfer mappable */ 1008 1.1 fredette int _dm_segcnt; /* number of segs this map can map */ 1009 1.8 matt bus_size_t _dm_maxmaxsegsz; /* fixed largest possible segment */ 1010 1.1 fredette bus_size_t _dm_boundary; /* don't cross this */ 1011 1.1 fredette int _dm_flags; /* misc. flags */ 1012 1.1 fredette 1013 1.1 fredette void *_dm_cookie; /* cookie for bus-specific functions */ 1014 1.1 fredette 1015 1.1 fredette u_long _dm_align; /* DVMA alignment; must be a 1016 1.1 fredette multiple of the page size */ 1017 1.1 fredette u_long _dm_ex_start; /* constraints on DVMA map */ 1018 1.1 fredette u_long _dm_ex_end; /* allocations; used by the VME bus 1019 1.1 fredette driver and by the IOMMU driver 1020 1.1 fredette when mapping 24-bit devices */ 1021 1.1 fredette 1022 1.1 fredette /* 1023 1.1 fredette * PUBLIC MEMBERS: these are used by machine-independent code. 1024 1.1 fredette */ 1025 1.8 matt bus_size_t dm_maxsegsz; /* largest possible segment */ 1026 1.1 fredette bus_size_t dm_mapsize; /* size of the mapping */ 1027 1.1 fredette int dm_nsegs; /* # valid segments in mapping */ 1028 1.1 fredette bus_dma_segment_t dm_segs[1]; /* segments; variable length */ 1029 1.1 fredette }; 1030 1.1 fredette 1031 1.1 fredette #ifdef _SUN68K_BUS_DMA_PRIVATE 1032 1.7 chs int _bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t, 1033 1.7 chs bus_size_t, int, bus_dmamap_t *); 1034 1.7 chs void _bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t); 1035 1.7 chs int _bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t, struct mbuf *, int); 1036 1.7 chs int _bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t, struct uio *, int); 1037 1.7 chs int _bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t, bus_dma_segment_t *, 1038 1.7 chs int, bus_size_t, int); 1039 1.7 chs int _bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t, 1040 1.7 chs struct proc *, int); 1041 1.7 chs void _bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t); 1042 1.7 chs void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t, bus_size_t, 1043 1.7 chs int); 1044 1.7 chs 1045 1.7 chs int _bus_dmamem_alloc(bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t, 1046 1.7 chs bus_dma_segment_t *, int, int *, int); 1047 1.7 chs void _bus_dmamem_free(bus_dma_tag_t, bus_dma_segment_t *, int); 1048 1.7 chs int _bus_dmamem_map(bus_dma_tag_t, bus_dma_segment_t *, int, size_t, 1049 1.15 christos void **, int); 1050 1.15 christos void _bus_dmamem_unmap(bus_dma_tag_t, void *, size_t); 1051 1.7 chs paddr_t _bus_dmamem_mmap(bus_dma_tag_t, bus_dma_segment_t *, int, off_t, int, 1052 1.7 chs int); 1053 1.7 chs 1054 1.7 chs int _bus_dmamem_alloc_range(bus_dma_tag_t, bus_size_t, bus_size_t, 1055 1.7 chs bus_size_t, bus_dma_segment_t *, int, int *, int, vaddr_t, vaddr_t); 1056 1.1 fredette 1057 1.1 fredette vaddr_t _bus_dma_valloc_skewed(size_t, u_long, u_long, u_long); 1058 1.1 fredette #endif /* _SUN68K_BUS_DMA_PRIVATE */ 1059 1.1 fredette 1060 1.1 fredette #endif /* _SUN68K_BUS_H_ */ 1061