1 /* $OpenBSD: bus.h,v 1.31 2017/05/08 00:27:45 dlg Exp $ */ 2 /* $NetBSD: bus.h,v 1.10 1996/12/02 22:19:32 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1996 Carnegie-Mellon University. 6 * All rights reserved. 7 * 8 * Author: Chris G. Demetriou 9 * 10 * Permission to use, copy, modify and distribute this software and 11 * its documentation is hereby granted, provided that both the copyright 12 * notice and this permission notice appear in all copies of the 13 * software, derivative works or modified versions, and any portions 14 * thereof, and that both notices appear in supporting documentation. 15 * 16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 19 * 20 * Carnegie Mellon requests users of this software to return to 21 * 22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 23 * School of Computer Science 24 * Carnegie Mellon University 25 * Pittsburgh PA 15213-3890 26 * 27 * any improvements or extensions that they make and grant Carnegie the 28 * rights to redistribute these changes. 29 */ 30 31 #ifndef _MACHINE_BUS_H_ 32 #define _MACHINE_BUS_H_ 33 34 /* 35 * Addresses (in bus space). 36 */ 37 typedef u_long bus_addr_t; 38 typedef u_long bus_size_t; 39 40 /* 41 * Access methods for bus space. 42 */ 43 typedef struct alpha_bus_space *bus_space_tag_t; 44 typedef u_long bus_space_handle_t; 45 46 struct alpha_bus_space { 47 /* cookie */ 48 void *abs_cookie; 49 50 /* mapping/unmapping */ 51 int (*abs_map)(void *, bus_addr_t, bus_size_t, 52 int, bus_space_handle_t *); 53 void (*abs_unmap)(void *, bus_space_handle_t, 54 bus_size_t); 55 int (*abs_subregion)(void *, bus_space_handle_t, 56 bus_size_t, bus_size_t, bus_space_handle_t *); 57 58 /* allocation/deallocation */ 59 int (*abs_alloc)(void *, bus_addr_t, bus_addr_t, 60 bus_size_t, bus_size_t, bus_size_t, int, 61 bus_addr_t *, bus_space_handle_t *); 62 void (*abs_free)(void *, bus_space_handle_t, 63 bus_size_t); 64 65 /* get kernel virtual address */ 66 void * (*abs_vaddr)(void *, bus_space_handle_t); 67 68 /* barrier */ 69 void (*abs_barrier)(void *, bus_space_handle_t, 70 bus_size_t, bus_size_t, int); 71 72 /* read (single) */ 73 u_int8_t (*abs_r_1)(void *, bus_space_handle_t, 74 bus_size_t); 75 u_int16_t (*abs_r_2)(void *, bus_space_handle_t, 76 bus_size_t); 77 u_int32_t (*abs_r_4)(void *, bus_space_handle_t, 78 bus_size_t); 79 u_int64_t (*abs_r_8)(void *, bus_space_handle_t, 80 bus_size_t); 81 82 /* read multiple */ 83 void (*abs_rm_1)(void *, bus_space_handle_t, 84 bus_size_t, u_int8_t *, bus_size_t); 85 void (*abs_rm_2)(void *, bus_space_handle_t, 86 bus_size_t, u_int16_t *, bus_size_t); 87 void (*abs_rm_4)(void *, bus_space_handle_t, 88 bus_size_t, u_int32_t *, bus_size_t); 89 void (*abs_rm_8)(void *, bus_space_handle_t, 90 bus_size_t, u_int64_t *, bus_size_t); 91 92 /* read region */ 93 void (*abs_rr_1)(void *, bus_space_handle_t, 94 bus_size_t, u_int8_t *, bus_size_t); 95 void (*abs_rr_2)(void *, bus_space_handle_t, 96 bus_size_t, u_int16_t *, bus_size_t); 97 void (*abs_rr_4)(void *, bus_space_handle_t, 98 bus_size_t, u_int32_t *, bus_size_t); 99 void (*abs_rr_8)(void *, bus_space_handle_t, 100 bus_size_t, u_int64_t *, bus_size_t); 101 102 /* write (single) */ 103 void (*abs_w_1)(void *, bus_space_handle_t, 104 bus_size_t, u_int8_t); 105 void (*abs_w_2)(void *, bus_space_handle_t, 106 bus_size_t, u_int16_t); 107 void (*abs_w_4)(void *, bus_space_handle_t, 108 bus_size_t, u_int32_t); 109 void (*abs_w_8)(void *, bus_space_handle_t, 110 bus_size_t, u_int64_t); 111 112 /* write multiple */ 113 void (*abs_wm_1)(void *, bus_space_handle_t, 114 bus_size_t, const u_int8_t *, bus_size_t); 115 void (*abs_wm_2)(void *, bus_space_handle_t, 116 bus_size_t, const u_int16_t *, bus_size_t); 117 void (*abs_wm_4)(void *, bus_space_handle_t, 118 bus_size_t, const u_int32_t *, bus_size_t); 119 void (*abs_wm_8)(void *, bus_space_handle_t, 120 bus_size_t, const u_int64_t *, bus_size_t); 121 122 /* write region */ 123 void (*abs_wr_1)(void *, bus_space_handle_t, 124 bus_size_t, const u_int8_t *, bus_size_t); 125 void (*abs_wr_2)(void *, bus_space_handle_t, 126 bus_size_t, const u_int16_t *, bus_size_t); 127 void (*abs_wr_4)(void *, bus_space_handle_t, 128 bus_size_t, const u_int32_t *, bus_size_t); 129 void (*abs_wr_8)(void *, bus_space_handle_t, 130 bus_size_t, const u_int64_t *, bus_size_t); 131 132 /* set multiple */ 133 void (*abs_sm_1)(void *, bus_space_handle_t, 134 bus_size_t, u_int8_t, bus_size_t); 135 void (*abs_sm_2)(void *, bus_space_handle_t, 136 bus_size_t, u_int16_t, bus_size_t); 137 void (*abs_sm_4)(void *, bus_space_handle_t, 138 bus_size_t, u_int32_t, bus_size_t); 139 void (*abs_sm_8)(void *, bus_space_handle_t, 140 bus_size_t, u_int64_t, bus_size_t); 141 142 /* set region */ 143 void (*abs_sr_1)(void *, bus_space_handle_t, 144 bus_size_t, u_int8_t, bus_size_t); 145 void (*abs_sr_2)(void *, bus_space_handle_t, 146 bus_size_t, u_int16_t, bus_size_t); 147 void (*abs_sr_4)(void *, bus_space_handle_t, 148 bus_size_t, u_int32_t, bus_size_t); 149 void (*abs_sr_8)(void *, bus_space_handle_t, 150 bus_size_t, u_int64_t, bus_size_t); 151 152 /* copy */ 153 void (*abs_c_1)(void *, bus_space_handle_t, bus_size_t, 154 bus_space_handle_t, bus_size_t, bus_size_t); 155 void (*abs_c_2)(void *, bus_space_handle_t, bus_size_t, 156 bus_space_handle_t, bus_size_t, bus_size_t); 157 void (*abs_c_4)(void *, bus_space_handle_t, bus_size_t, 158 bus_space_handle_t, bus_size_t, bus_size_t); 159 void (*abs_c_8)(void *, bus_space_handle_t, bus_size_t, 160 bus_space_handle_t, bus_size_t, bus_size_t); 161 162 /* OpenBSD extensions follows */ 163 164 /* read multiple raw */ 165 void (*abs_rrm_2)(void *, bus_space_handle_t, 166 bus_size_t, u_int8_t *, bus_size_t); 167 void (*abs_rrm_4)(void *, bus_space_handle_t, 168 bus_size_t, u_int8_t *, bus_size_t); 169 void (*abs_rrm_8)(void *, bus_space_handle_t, 170 bus_size_t, u_int8_t *, bus_size_t); 171 172 /* write multiple raw */ 173 void (*abs_wrm_2)(void *, bus_space_handle_t, 174 bus_size_t, const u_int8_t *, bus_size_t); 175 void (*abs_wrm_4)(void *, bus_space_handle_t, 176 bus_size_t, const u_int8_t *, bus_size_t); 177 void (*abs_wrm_8)(void *, bus_space_handle_t, 178 bus_size_t, const u_int8_t *, bus_size_t); 179 }; 180 181 182 /* 183 * Utility macros; INTERNAL USE ONLY. 184 */ 185 #define __abs_c(a,b) __CONCAT(a,b) 186 #define __abs_opname(op,size) __abs_c(__abs_c(__abs_c(abs_,op),_),size) 187 188 #define __abs_rs(sz, t, h, o) \ 189 (*(t)->__abs_opname(r,sz))((t)->abs_cookie, h, o) 190 #define __abs_ws(sz, t, h, o, v) \ 191 (*(t)->__abs_opname(w,sz))((t)->abs_cookie, h, o, v) 192 #define __abs_nonsingle(type, sz, t, h, o, a, c) \ 193 (*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, a, c) 194 #ifndef DEBUG 195 #define __abs_aligned_nonsingle(type, sz, t, h, o, a, c) \ 196 __abs_nonsingle(type, sz, (t), (h), (o), (a), (c)) 197 198 #else 199 #define __abs_aligned_nonsingle(type, sz, t, h, o, a, c) \ 200 do { \ 201 if (((unsigned long)a & (sz - 1)) != 0) \ 202 panic("bus non-single %d-byte unaligned (to %p) at %s:%d", \ 203 sz, a, __FILE__, __LINE__); \ 204 (*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, a, c); \ 205 } while (0) 206 #endif 207 #define __abs_set(type, sz, t, h, o, v, c) \ 208 (*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, v, c) 209 #define __abs_copy(sz, t, h1, o1, h2, o2, cnt) \ 210 (*(t)->__abs_opname(c,sz))((t)->abs_cookie, h1, o1, h2, o2, cnt) 211 212 /* 213 * Mapping and unmapping operations. 214 */ 215 #define bus_space_map(t, a, s, c, hp) \ 216 (*(t)->abs_map)((t)->abs_cookie, (a), (s), (c), (hp)) 217 #define alpha_bus_space_map_noacct bus_space_map 218 #define bus_space_unmap(t, h, s) \ 219 (*(t)->abs_unmap)((t)->abs_cookie, (h), (s)) 220 #define alpha_bus_space_unmap_noacct bus_space_unmap 221 #define bus_space_subregion(t, h, o, s, hp) \ 222 (*(t)->abs_subregion)((t)->abs_cookie, (h), (o), (s), (hp)) 223 224 #define BUS_SPACE_MAP_CACHEABLE 0x01 225 #define BUS_SPACE_MAP_LINEAR 0x02 226 #define BUS_SPACE_MAP_PREFETCHABLE 0x04 227 228 /* 229 * Allocation and deallocation operations. 230 */ 231 #define bus_space_alloc(t, rs, re, s, a, b, c, ap, hp) \ 232 (*(t)->abs_alloc)((t)->abs_cookie, (rs), (re), (s), (a), (b), \ 233 (c), (ap), (hp)) 234 #define bus_space_free(t, h, s) \ 235 (*(t)->abs_free)((t)->abs_cookie, (h), (s)) 236 237 /* 238 * Get kernel virtual address for ranges mapped BUS_SPACE_MAP_LINEAR. 239 */ 240 #define bus_space_vaddr(t, h) \ 241 (*(t)->abs_vaddr)((t)->abs_cookie, (h)) 242 243 /* 244 * Bus barrier operations. 245 */ 246 #define bus_space_barrier(t, h, o, l, f) \ 247 (*(t)->abs_barrier)((t)->abs_cookie, (h), (o), (l), (f)) 248 249 #define BUS_SPACE_BARRIER_READ 0x01 250 #define BUS_SPACE_BARRIER_WRITE 0x02 251 252 253 /* 254 * Bus read (single) operations. 255 */ 256 #define bus_space_read_1(t, h, o) __abs_rs(1,(t),(h),(o)) 257 #define bus_space_read_2(t, h, o) __abs_rs(2,(t),(h),(o)) 258 #define bus_space_read_4(t, h, o) __abs_rs(4,(t),(h),(o)) 259 #define bus_space_read_8(t, h, o) __abs_rs(8,(t),(h),(o)) 260 261 262 /* 263 * Bus read (single) operations. 264 */ 265 #define bus_space_read_raw_1(t, h, o) __abs_rs(1,(t),(h),(o)) 266 #define bus_space_read_raw_2(t, h, o) __abs_rs(2,(t),(h),(o)) 267 #define bus_space_read_raw_4(t, h, o) __abs_rs(4,(t),(h),(o)) 268 #define bus_space_read_raw_8(t, h, o) __abs_rs(8,(t),(h),(o)) 269 270 271 /* 272 * Bus read multiple operations. 273 */ 274 #define bus_space_read_multi_1(t, h, o, a, c) \ 275 __abs_nonsingle(rm,1,(t),(h),(o),(a),(c)) 276 #define bus_space_read_multi_2(t, h, o, a, c) \ 277 __abs_aligned_nonsingle(rm,2,(t),(h),(o),(a),(c)) 278 #define bus_space_read_multi_4(t, h, o, a, c) \ 279 __abs_aligned_nonsingle(rm,4,(t),(h),(o),(a),(c)) 280 #define bus_space_read_multi_8(t, h, o, a, c) \ 281 __abs_aligned_nonsingle(rm,8,(t),(h),(o),(a),(c)) 282 283 284 /* 285 * void bus_space_read_raw_multi_N(bus_space_tag_t tag, 286 * bus_space_handle_t bsh, bus_size_t offset, 287 * u_int8_t *addr, size_t count); 288 * 289 * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space 290 * described by tag/handle/offset and copy into buffer provided. The buffer 291 * must have proper alignment for the N byte wide entities. Furthermore 292 * possible byte-swapping should be done by these functions. 293 */ 294 295 #define bus_space_read_raw_multi_2(t, h, o, a, c) \ 296 __abs_nonsingle(rrm,2,(t),(h),(o),(a),(c)) 297 #define bus_space_read_raw_multi_4(t, h, o, a, c) \ 298 __abs_nonsingle(rrm,4,(t),(h),(o),(a),(c)) 299 #define bus_space_read_raw_multi_8(t, h, o, a, c) \ 300 __abs_nonsingle(rrm,8,(t),(h),(o),(a),(c)) 301 302 /* 303 * Bus read region operations. 304 */ 305 #define bus_space_read_region_1(t, h, o, a, c) \ 306 __abs_nonsingle(rr,1,(t),(h),(o),(a),(c)) 307 #define bus_space_read_region_2(t, h, o, a, c) \ 308 __abs_aligned_nonsingle(rr,2,(t),(h),(o),(a),(c)) 309 #define bus_space_read_region_4(t, h, o, a, c) \ 310 __abs_aligned_nonsingle(rr,4,(t),(h),(o),(a),(c)) 311 #define bus_space_read_region_8(t, h, o, a, c) \ 312 __abs_aligned_nonsingle(rr,8,(t),(h),(o),(a),(c)) 313 314 315 /* 316 * void bus_space_read_raw_region_N(bus_space_tag_t tag, 317 * bus_space_handle_t bsh, bus_size_t offset, 318 * u_int8_t *addr, size_t count); 319 * 320 * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space 321 * described by tag/handle and starting at `offset' from the 322 * buffer provided. The buffer must have proper alignment for the N byte 323 * wide entities. Furthermore possible byte-swapping should be done by 324 * these functions. 325 */ 326 327 #define bus_space_read_raw_region_2(t, h, o, a, c) \ 328 bus_space_read_region_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1) 329 #define bus_space_read_raw_region_4(t, h, o, a, c) \ 330 bus_space_read_region_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2) 331 332 /* 333 * Bus write (single) operations. 334 */ 335 #define bus_space_write_1(t, h, o, v) __abs_ws(1,(t),(h),(o),(v)) 336 #define bus_space_write_2(t, h, o, v) __abs_ws(2,(t),(h),(o),(v)) 337 #define bus_space_write_4(t, h, o, v) __abs_ws(4,(t),(h),(o),(v)) 338 #define bus_space_write_8(t, h, o, v) __abs_ws(8,(t),(h),(o),(v)) 339 340 341 /* 342 * Bus write raw (single) operations. 343 */ 344 #define bus_space_write_raw_1(t, h, o, v) __abs_ws(1,(t),(h),(o),(v)) 345 #define bus_space_write_raw_2(t, h, o, v) __abs_ws(2,(t),(h),(o),(v)) 346 #define bus_space_write_raw_4(t, h, o, v) __abs_ws(4,(t),(h),(o),(v)) 347 #define bus_space_write_raw_8(t, h, o, v) __abs_ws(8,(t),(h),(o),(v)) 348 349 350 /* 351 * Bus write multiple operations. 352 */ 353 #define bus_space_write_multi_1(t, h, o, a, c) \ 354 __abs_nonsingle(wm,1,(t),(h),(o),(a),(c)) 355 #define bus_space_write_multi_2(t, h, o, a, c) \ 356 __abs_aligned_nonsingle(wm,2,(t),(h),(o),(a),(c)) 357 #define bus_space_write_multi_4(t, h, o, a, c) \ 358 __abs_aligned_nonsingle(wm,4,(t),(h),(o),(a),(c)) 359 #define bus_space_write_multi_8(t, h, o, a, c) \ 360 __abs_aligned_nonsingle(wm,8,(t),(h),(o),(a),(c)) 361 362 /* 363 * void bus_space_write_raw_multi_N(bus_space_tag_t tag, 364 * bus_space_handle_t bsh, bus_size_t offset, 365 * u_int8_t *addr, size_t count); 366 * 367 * Write `count' bytes in 2, 4 or 8 byte wide quantities from the buffer 368 * provided to bus space described by tag/handle/offset. The buffer 369 * must have proper alignment for the N byte wide entities. Furthermore 370 * possible byte-swapping should be done by these functions. 371 */ 372 373 #define bus_space_write_raw_multi_2(t, h, o, a, c) \ 374 __abs_nonsingle(wrm,2,(t),(h),(o),(a),(c)) 375 #define bus_space_write_raw_multi_4(t, h, o, a, c) \ 376 __abs_nonsingle(wrm,4,(t),(h),(o),(a),(c)) 377 #define bus_space_write_raw_multi_8(t, h, o, a, c) \ 378 __abs_nonsingle(wrm,8,(t),(h),(o),(a),(c)) 379 380 /* 381 * Bus write region operations. 382 */ 383 #define bus_space_write_region_1(t, h, o, a, c) \ 384 __abs_nonsingle(wr,1,(t),(h),(o),(a),(c)) 385 #define bus_space_write_region_2(t, h, o, a, c) \ 386 __abs_aligned_nonsingle(wr,2,(t),(h),(o),(a),(c)) 387 #define bus_space_write_region_4(t, h, o, a, c) \ 388 __abs_aligned_nonsingle(wr,4,(t),(h),(o),(a),(c)) 389 #define bus_space_write_region_8(t, h, o, a, c) \ 390 __abs_aligned_nonsingle(wr,8,(t),(h),(o),(a),(c)) 391 392 393 /* 394 * void bus_space_write_raw_region_N(bus_space_tag_t tag, 395 * bus_space_handle_t bsh, bus_size_t offset, 396 * const u_int8_t *addr, size_t count); 397 * 398 * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space 399 * described by tag/handle and starting at `offset' from the 400 * buffer provided. The buffer must have proper alignment for the N byte 401 * wide entities. Furthermore possible byte-swapping should be done by 402 * these functions. 403 */ 404 405 #define bus_space_write_raw_region_2(t, h, o, a, c) \ 406 bus_space_write_region_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1) 407 #define bus_space_write_raw_region_4(t, h, o, a, c) \ 408 bus_space_write_region_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2) 409 410 /* 411 * Set multiple operations. 412 */ 413 #define bus_space_set_multi_1(t, h, o, v, c) \ 414 __abs_set(sm,1,(t),(h),(o),(v),(c)) 415 #define bus_space_set_multi_2(t, h, o, v, c) \ 416 __abs_set(sm,2,(t),(h),(o),(v),(c)) 417 #define bus_space_set_multi_4(t, h, o, v, c) \ 418 __abs_set(sm,4,(t),(h),(o),(v),(c)) 419 #define bus_space_set_multi_8(t, h, o, v, c) \ 420 __abs_set(sm,8,(t),(h),(o),(v),(c)) 421 422 423 /* 424 * Set region operations. 425 */ 426 #define bus_space_set_region_1(t, h, o, v, c) \ 427 __abs_set(sr,1,(t),(h),(o),(v),(c)) 428 #define bus_space_set_region_2(t, h, o, v, c) \ 429 __abs_set(sr,2,(t),(h),(o),(v),(c)) 430 #define bus_space_set_region_4(t, h, o, v, c) \ 431 __abs_set(sr,4,(t),(h),(o),(v),(c)) 432 #define bus_space_set_region_8(t, h, o, v, c) \ 433 __abs_set(sr,8,(t),(h),(o),(v),(c)) 434 435 436 /* 437 * Copy operations. 438 */ 439 #define bus_space_copy_1(t, h1, o1, h2, o2, c) \ 440 __abs_copy(1, t, h1, o1, h2, o2, c) 441 #define bus_space_copy_2(t, h1, o1, h2, o2, c) \ 442 __abs_copy(2, t, h1, o1, h2, o2, c) 443 #define bus_space_copy_4(t, h1, o1, h2, o2, c) \ 444 __abs_copy(4, t, h1, o1, h2, o2, c) 445 #define bus_space_copy_8(t, h1, o1, h2, o2, c) \ 446 __abs_copy(8, t, h1, o1, h2, o2, c) 447 448 /* 449 * Bus DMA methods. 450 */ 451 452 /* 453 * Flags used in various bus DMA methods. 454 */ 455 #define BUS_DMA_WAITOK 0x0000 /* safe to sleep (pseudo-flag) */ 456 #define BUS_DMA_NOWAIT 0x0001 /* not safe to sleep */ 457 #define BUS_DMA_ALLOCNOW 0x0002 /* perform resource allocation now */ 458 #define BUS_DMA_COHERENT 0x0004 /* hint: map memory DMA coherent */ 459 #define BUS_DMA_BUS1 0x0010 /* placeholders for bus functions... */ 460 #define BUS_DMA_BUS2 0x0020 461 #define BUS_DMA_BUS3 0x0040 462 #define BUS_DMA_24BIT 0x0080 /* isadma map */ 463 #define BUS_DMA_STREAMING 0x0100 /* hint: sequential, unidirectional */ 464 #define BUS_DMA_READ 0x0200 /* mapping is device -> memory only */ 465 #define BUS_DMA_WRITE 0x0400 /* mapping is memory -> device only */ 466 #define BUS_DMA_ZERO 0x1000 /* zero memory in dmamem_alloc */ 467 #define BUS_DMA_64BIT 0x2000 /* device handles 64bit dva */ 468 469 /* 470 * Private flags stored in the DMA map. 471 */ 472 #define DMAMAP_NO_COALESCE 0x40000000 /* don't coalesce adjacent 473 segments */ 474 475 /* Forwards needed by prototypes below. */ 476 struct mbuf; 477 struct uio; 478 struct alpha_sgmap; 479 480 /* 481 * Operations performed by bus_dmamap_sync(). 482 */ 483 #define BUS_DMASYNC_PREREAD 0x01 484 #define BUS_DMASYNC_POSTREAD 0x02 485 #define BUS_DMASYNC_PREWRITE 0x04 486 #define BUS_DMASYNC_POSTWRITE 0x08 487 488 /* 489 * alpha_bus_t 490 * 491 * Busses supported by NetBSD/alpha, used by internal 492 * utility functions. NOT TO BE USED BY MACHINE-INDEPENDENT 493 * CODE! 494 */ 495 typedef enum { 496 ALPHA_BUS_TURBOCHANNEL, 497 ALPHA_BUS_PCI, 498 ALPHA_BUS_EISA, 499 ALPHA_BUS_ISA, 500 ALPHA_BUS_TLSB, 501 } alpha_bus_t; 502 503 typedef struct alpha_bus_dma_tag *bus_dma_tag_t; 504 typedef struct alpha_bus_dmamap *bus_dmamap_t; 505 506 /* 507 * bus_dma_segment_t 508 * 509 * Describes a single contiguous DMA transaction. Values 510 * are suitable for programming into DMA registers. 511 */ 512 struct alpha_bus_dma_segment { 513 bus_addr_t ds_addr; /* DMA address */ 514 bus_size_t ds_len; /* length of transfer */ 515 }; 516 typedef struct alpha_bus_dma_segment bus_dma_segment_t; 517 518 /* 519 * bus_dma_tag_t 520 * 521 * A machine-dependent opaque type describing the implementation of 522 * DMA for a given bus. 523 */ 524 struct alpha_bus_dma_tag { 525 void *_cookie; /* cookie used in the guts */ 526 bus_addr_t _wbase; /* DMA window base */ 527 528 /* 529 * The following two members are used to chain DMA windows 530 * together. If, during the course of a map load, the 531 * resulting physical memory address is too large to 532 * be addressed by the window, the next window will be 533 * attempted. These would be chained together like so: 534 * 535 * direct -> sgmap -> NULL 536 * or 537 * sgmap -> NULL 538 * or 539 * direct -> NULL 540 * 541 * If the window size is 0, it will not be checked (e.g. 542 * TurboChannel DMA). 543 */ 544 bus_size_t _wsize; 545 struct alpha_bus_dma_tag *_next_window; 546 547 /* 548 * Some chipsets have a built-in boundary constraint, independent 549 * of what the device requests. This allows that boundary to 550 * be specified. If the device has a more restrictive constraint, 551 * the map will use that, otherwise this boundary will be used. 552 * This value is ignored if 0. 553 */ 554 bus_size_t _boundary; 555 556 /* 557 * A chipset may have more than one SGMAP window, so SGMAP 558 * windows also get a pointer to their SGMAP state. 559 */ 560 struct alpha_sgmap *_sgmap; 561 562 /* 563 * Internal-use only utility methods. NOT TO BE USED BY 564 * MACHINE-INDEPENDENT CODE! 565 */ 566 bus_dma_tag_t (*_get_tag)(bus_dma_tag_t, alpha_bus_t); 567 568 /* 569 * DMA mapping methods. 570 */ 571 int (*_dmamap_create)(bus_dma_tag_t, bus_size_t, int, 572 bus_size_t, bus_size_t, int, bus_dmamap_t *); 573 void (*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t); 574 int (*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *, 575 bus_size_t, struct proc *, int); 576 int (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t, 577 struct mbuf *, int); 578 int (*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t, 579 struct uio *, int); 580 int (*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t, 581 bus_dma_segment_t *, int, bus_size_t, int); 582 void (*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t); 583 void (*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t, 584 bus_addr_t, bus_size_t, int); 585 586 /* 587 * DMA memory utility functions. 588 */ 589 int (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t, 590 bus_size_t, bus_dma_segment_t *, int, int *, int); 591 void (*_dmamem_free)(bus_dma_tag_t, 592 bus_dma_segment_t *, int); 593 int (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *, 594 int, size_t, caddr_t *, int); 595 void (*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t); 596 paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *, 597 int, off_t, int, int); 598 }; 599 600 #define alphabus_dma_get_tag(t, b) \ 601 (*(t)->_get_tag)(t, b) 602 603 #define bus_dmamap_create(t, s, n, m, b, f, p) \ 604 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p)) 605 #define bus_dmamap_destroy(t, p) \ 606 (*(t)->_dmamap_destroy)((t), (p)) 607 #define bus_dmamap_load(t, m, b, s, p, f) \ 608 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f)) 609 #define bus_dmamap_load_mbuf(t, m, b, f) \ 610 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f)) 611 #define bus_dmamap_load_uio(t, m, u, f) \ 612 (*(t)->_dmamap_load_uio)((t), (m), (u), (f)) 613 #define bus_dmamap_load_raw(t, m, sg, n, s, f) \ 614 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f)) 615 #define bus_dmamap_unload(t, p) \ 616 (void)(t), \ 617 (*(p)->_dm_window->_dmamap_unload)((p)->_dm_window, (p)) 618 #define bus_dmamap_sync(t, p, a, s, op) \ 619 (void)(t), \ 620 (*(p)->_dm_window->_dmamap_sync)((p)->_dm_window, (p), (a), (s), (op)) 621 #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \ 622 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f)) 623 #define bus_dmamem_free(t, sg, n) \ 624 (*(t)->_dmamem_free)((t), (sg), (n)) 625 #define bus_dmamem_map(t, sg, n, s, k, f) \ 626 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f)) 627 #define bus_dmamem_unmap(t, k, s) \ 628 (*(t)->_dmamem_unmap)((t), (k), (s)) 629 #define bus_dmamem_mmap(t, sg, n, o, p, f) \ 630 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) 631 632 /* 633 * bus_dmamap_t 634 * 635 * Describes a DMA mapping. 636 */ 637 struct alpha_bus_dmamap { 638 /* 639 * PRIVATE MEMBERS: not for use by machine-independent code. 640 */ 641 bus_size_t _dm_size; /* largest DMA transfer mappable */ 642 int _dm_segcnt; /* number of segs this map can map */ 643 bus_size_t _dm_maxsegsz; /* largest possible segment */ 644 bus_size_t _dm_boundary; /* don't cross this */ 645 int _dm_flags; /* misc. flags */ 646 647 /* 648 * Private cookie to be used by the DMA back-end. 649 */ 650 void *_dm_cookie; 651 652 /* 653 * The DMA window that we ended up being mapped in. 654 */ 655 bus_dma_tag_t _dm_window; 656 657 /* 658 * PUBLIC MEMBERS: these are used by machine-independent code. 659 */ 660 bus_size_t dm_mapsize; /* size of the mapping */ 661 int dm_nsegs; /* # valid segments in mapping */ 662 bus_dma_segment_t dm_segs[1]; /* segments; variable length */ 663 }; 664 665 #ifdef _ALPHA_BUS_DMA_PRIVATE 666 int _bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t, 667 bus_size_t, int, bus_dmamap_t *); 668 void _bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t); 669 670 int _bus_dmamap_load_direct(bus_dma_tag_t, bus_dmamap_t, 671 void *, bus_size_t, struct proc *, int); 672 int _bus_dmamap_load_mbuf_direct(bus_dma_tag_t, 673 bus_dmamap_t, struct mbuf *, int); 674 int _bus_dmamap_load_uio_direct(bus_dma_tag_t, 675 bus_dmamap_t, struct uio *, int); 676 int _bus_dmamap_load_raw_direct(bus_dma_tag_t, 677 bus_dmamap_t, bus_dma_segment_t *, int, bus_size_t, int); 678 679 void _bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t); 680 void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t, 681 bus_size_t, int); 682 683 int _bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size, 684 bus_size_t alignment, bus_size_t boundary, 685 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags); 686 int _bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size, 687 bus_size_t alignment, bus_size_t boundary, 688 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, 689 paddr_t low, paddr_t high); 690 void _bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs, 691 int nsegs); 692 int _bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs, 693 int nsegs, size_t size, caddr_t *kvap, int flags); 694 void _bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva, 695 size_t size); 696 paddr_t _bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs, 697 int nsegs, off_t off, int prot, int flags); 698 #endif /* _ALPHA_BUS_DMA_PRIVATE */ 699 700 #endif /* _MACHINE_BUS_H_ */ 701