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