1*f56b290dSderaadt /* $OpenBSD: bus.h,v 1.33 2022/01/04 20:41:42 deraadt Exp $ */ 23a630e3fSniklas /* $NetBSD: bus.h,v 1.10 1996/12/02 22:19:32 cgd Exp $ */ 3417eba8cSderaadt 4417eba8cSderaadt /* 5417eba8cSderaadt * Copyright (c) 1996 Carnegie-Mellon University. 6417eba8cSderaadt * All rights reserved. 7417eba8cSderaadt * 8417eba8cSderaadt * Author: Chris G. Demetriou 9417eba8cSderaadt * 10417eba8cSderaadt * Permission to use, copy, modify and distribute this software and 11417eba8cSderaadt * its documentation is hereby granted, provided that both the copyright 12417eba8cSderaadt * notice and this permission notice appear in all copies of the 13417eba8cSderaadt * software, derivative works or modified versions, and any portions 14417eba8cSderaadt * thereof, and that both notices appear in supporting documentation. 15417eba8cSderaadt * 16417eba8cSderaadt * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 17417eba8cSderaadt * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 18417eba8cSderaadt * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 19417eba8cSderaadt * 20417eba8cSderaadt * Carnegie Mellon requests users of this software to return to 21417eba8cSderaadt * 22417eba8cSderaadt * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 23417eba8cSderaadt * School of Computer Science 24417eba8cSderaadt * Carnegie Mellon University 25417eba8cSderaadt * Pittsburgh PA 15213-3890 26417eba8cSderaadt * 27417eba8cSderaadt * any improvements or extensions that they make and grant Carnegie the 28417eba8cSderaadt * rights to redistribute these changes. 29417eba8cSderaadt */ 30417eba8cSderaadt 312fa72412Spirofti #ifndef _MACHINE_BUS_H_ 322fa72412Spirofti #define _MACHINE_BUS_H_ 33417eba8cSderaadt 34*f56b290dSderaadt #ifdef _KERNEL 35*f56b290dSderaadt 36417eba8cSderaadt /* 37ecbe32ebSniklas * Addresses (in bus space). 38417eba8cSderaadt */ 39ecbe32ebSniklas typedef u_long bus_addr_t; 40ecbe32ebSniklas typedef u_long bus_size_t; 41417eba8cSderaadt 42417eba8cSderaadt /* 43ecbe32ebSniklas * Access methods for bus space. 44417eba8cSderaadt */ 45ecbe32ebSniklas typedef struct alpha_bus_space *bus_space_tag_t; 46ecbe32ebSniklas typedef u_long bus_space_handle_t; 47417eba8cSderaadt 48ecbe32ebSniklas struct alpha_bus_space { 49ecbe32ebSniklas /* cookie */ 50ecbe32ebSniklas void *abs_cookie; 51417eba8cSderaadt 52ecbe32ebSniklas /* mapping/unmapping */ 53aed035abSart int (*abs_map)(void *, bus_addr_t, bus_size_t, 54aed035abSart int, bus_space_handle_t *); 55aed035abSart void (*abs_unmap)(void *, bus_space_handle_t, 56aed035abSart bus_size_t); 57aed035abSart int (*abs_subregion)(void *, bus_space_handle_t, 58aed035abSart bus_size_t, bus_size_t, bus_space_handle_t *); 59417eba8cSderaadt 60ecbe32ebSniklas /* allocation/deallocation */ 61aed035abSart int (*abs_alloc)(void *, bus_addr_t, bus_addr_t, 62ecbe32ebSniklas bus_size_t, bus_size_t, bus_size_t, int, 63aed035abSart bus_addr_t *, bus_space_handle_t *); 64aed035abSart void (*abs_free)(void *, bus_space_handle_t, 65aed035abSart bus_size_t); 66417eba8cSderaadt 67f8ac741cSmiod /* get kernel virtual address */ 68f8ac741cSmiod void * (*abs_vaddr)(void *, bus_space_handle_t); 69f8ac741cSmiod 703a630e3fSniklas /* barrier */ 71aed035abSart void (*abs_barrier)(void *, bus_space_handle_t, 72aed035abSart bus_size_t, bus_size_t, int); 733a630e3fSniklas 74ecbe32ebSniklas /* read (single) */ 75aed035abSart u_int8_t (*abs_r_1)(void *, bus_space_handle_t, 76aed035abSart bus_size_t); 77aed035abSart u_int16_t (*abs_r_2)(void *, bus_space_handle_t, 78aed035abSart bus_size_t); 79aed035abSart u_int32_t (*abs_r_4)(void *, bus_space_handle_t, 80aed035abSart bus_size_t); 81aed035abSart u_int64_t (*abs_r_8)(void *, bus_space_handle_t, 82aed035abSart bus_size_t); 83417eba8cSderaadt 843a630e3fSniklas /* read multiple */ 85aed035abSart void (*abs_rm_1)(void *, bus_space_handle_t, 86aed035abSart bus_size_t, u_int8_t *, bus_size_t); 87aed035abSart void (*abs_rm_2)(void *, bus_space_handle_t, 88aed035abSart bus_size_t, u_int16_t *, bus_size_t); 89aed035abSart void (*abs_rm_4)(void *, bus_space_handle_t, 90aed035abSart bus_size_t, u_int32_t *, bus_size_t); 91aed035abSart void (*abs_rm_8)(void *, bus_space_handle_t, 92aed035abSart bus_size_t, u_int64_t *, bus_size_t); 93417eba8cSderaadt 94ecbe32ebSniklas /* read region */ 95aed035abSart void (*abs_rr_1)(void *, bus_space_handle_t, 96aed035abSart bus_size_t, u_int8_t *, bus_size_t); 97aed035abSart void (*abs_rr_2)(void *, bus_space_handle_t, 98aed035abSart bus_size_t, u_int16_t *, bus_size_t); 99aed035abSart void (*abs_rr_4)(void *, bus_space_handle_t, 100aed035abSart bus_size_t, u_int32_t *, bus_size_t); 101aed035abSart void (*abs_rr_8)(void *, bus_space_handle_t, 102aed035abSart bus_size_t, u_int64_t *, bus_size_t); 103417eba8cSderaadt 104ecbe32ebSniklas /* write (single) */ 105aed035abSart void (*abs_w_1)(void *, bus_space_handle_t, 106aed035abSart bus_size_t, u_int8_t); 107aed035abSart void (*abs_w_2)(void *, bus_space_handle_t, 108aed035abSart bus_size_t, u_int16_t); 109aed035abSart void (*abs_w_4)(void *, bus_space_handle_t, 110aed035abSart bus_size_t, u_int32_t); 111aed035abSart void (*abs_w_8)(void *, bus_space_handle_t, 112aed035abSart bus_size_t, u_int64_t); 113417eba8cSderaadt 1143a630e3fSniklas /* write multiple */ 115aed035abSart void (*abs_wm_1)(void *, bus_space_handle_t, 116aed035abSart bus_size_t, const u_int8_t *, bus_size_t); 117aed035abSart void (*abs_wm_2)(void *, bus_space_handle_t, 118aed035abSart bus_size_t, const u_int16_t *, bus_size_t); 119aed035abSart void (*abs_wm_4)(void *, bus_space_handle_t, 120aed035abSart bus_size_t, const u_int32_t *, bus_size_t); 121aed035abSart void (*abs_wm_8)(void *, bus_space_handle_t, 122aed035abSart bus_size_t, const u_int64_t *, bus_size_t); 123417eba8cSderaadt 124ecbe32ebSniklas /* write region */ 125aed035abSart void (*abs_wr_1)(void *, bus_space_handle_t, 126aed035abSart bus_size_t, const u_int8_t *, bus_size_t); 127aed035abSart void (*abs_wr_2)(void *, bus_space_handle_t, 128aed035abSart bus_size_t, const u_int16_t *, bus_size_t); 129aed035abSart void (*abs_wr_4)(void *, bus_space_handle_t, 130aed035abSart bus_size_t, const u_int32_t *, bus_size_t); 131aed035abSart void (*abs_wr_8)(void *, bus_space_handle_t, 132aed035abSart bus_size_t, const u_int64_t *, bus_size_t); 133417eba8cSderaadt 1343a630e3fSniklas /* set multiple */ 135aed035abSart void (*abs_sm_1)(void *, bus_space_handle_t, 136aed035abSart bus_size_t, u_int8_t, bus_size_t); 137aed035abSart void (*abs_sm_2)(void *, bus_space_handle_t, 138aed035abSart bus_size_t, u_int16_t, bus_size_t); 139aed035abSart void (*abs_sm_4)(void *, bus_space_handle_t, 140aed035abSart bus_size_t, u_int32_t, bus_size_t); 141aed035abSart void (*abs_sm_8)(void *, bus_space_handle_t, 142aed035abSart bus_size_t, u_int64_t, bus_size_t); 143417eba8cSderaadt 144ecbe32ebSniklas /* set region */ 145aed035abSart void (*abs_sr_1)(void *, bus_space_handle_t, 146aed035abSart bus_size_t, u_int8_t, bus_size_t); 147aed035abSart void (*abs_sr_2)(void *, bus_space_handle_t, 148aed035abSart bus_size_t, u_int16_t, bus_size_t); 149aed035abSart void (*abs_sr_4)(void *, bus_space_handle_t, 150aed035abSart bus_size_t, u_int32_t, bus_size_t); 151aed035abSart void (*abs_sr_8)(void *, bus_space_handle_t, 152aed035abSart bus_size_t, u_int64_t, bus_size_t); 153417eba8cSderaadt 154ecbe32ebSniklas /* copy */ 155aed035abSart void (*abs_c_1)(void *, bus_space_handle_t, bus_size_t, 156aed035abSart bus_space_handle_t, bus_size_t, bus_size_t); 157aed035abSart void (*abs_c_2)(void *, bus_space_handle_t, bus_size_t, 158aed035abSart bus_space_handle_t, bus_size_t, bus_size_t); 159aed035abSart void (*abs_c_4)(void *, bus_space_handle_t, bus_size_t, 160aed035abSart bus_space_handle_t, bus_size_t, bus_size_t); 161aed035abSart void (*abs_c_8)(void *, bus_space_handle_t, bus_size_t, 162aed035abSart bus_space_handle_t, bus_size_t, bus_size_t); 1636b7448ebSniklas 1646b7448ebSniklas /* OpenBSD extensions follows */ 1656b7448ebSniklas 1666b7448ebSniklas /* read multiple raw */ 167aed035abSart void (*abs_rrm_2)(void *, bus_space_handle_t, 168aed035abSart bus_size_t, u_int8_t *, bus_size_t); 169aed035abSart void (*abs_rrm_4)(void *, bus_space_handle_t, 170aed035abSart bus_size_t, u_int8_t *, bus_size_t); 171aed035abSart void (*abs_rrm_8)(void *, bus_space_handle_t, 172aed035abSart bus_size_t, u_int8_t *, bus_size_t); 1736b7448ebSniklas 1746b7448ebSniklas /* write multiple raw */ 175aed035abSart void (*abs_wrm_2)(void *, bus_space_handle_t, 176aed035abSart bus_size_t, const u_int8_t *, bus_size_t); 177aed035abSart void (*abs_wrm_4)(void *, bus_space_handle_t, 178aed035abSart bus_size_t, const u_int8_t *, bus_size_t); 179aed035abSart void (*abs_wrm_8)(void *, bus_space_handle_t, 180aed035abSart bus_size_t, const u_int8_t *, bus_size_t); 181417eba8cSderaadt }; 182417eba8cSderaadt 183417eba8cSderaadt 184ecbe32ebSniklas /* 185ecbe32ebSniklas * Utility macros; INTERNAL USE ONLY. 186ecbe32ebSniklas */ 187ecbe32ebSniklas #define __abs_c(a,b) __CONCAT(a,b) 188ecbe32ebSniklas #define __abs_opname(op,size) __abs_c(__abs_c(__abs_c(abs_,op),_),size) 189417eba8cSderaadt 190ecbe32ebSniklas #define __abs_rs(sz, t, h, o) \ 191ecbe32ebSniklas (*(t)->__abs_opname(r,sz))((t)->abs_cookie, h, o) 192ecbe32ebSniklas #define __abs_ws(sz, t, h, o, v) \ 193ecbe32ebSniklas (*(t)->__abs_opname(w,sz))((t)->abs_cookie, h, o, v) 194ecbe32ebSniklas #define __abs_nonsingle(type, sz, t, h, o, a, c) \ 195ecbe32ebSniklas (*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, a, c) 1966b7448ebSniklas #ifndef DEBUG 1976b7448ebSniklas #define __abs_aligned_nonsingle(type, sz, t, h, o, a, c) \ 198def0378bSderaadt __abs_nonsingle(type, sz, (t), (h), (o), (a), (c)) 1996b7448ebSniklas 2003a630e3fSniklas #else 201c1c7f10dSmillert #define __abs_aligned_nonsingle(type, sz, t, h, o, a, c) \ 2023a630e3fSniklas do { \ 2033a630e3fSniklas if (((unsigned long)a & (sz - 1)) != 0) \ 2043a630e3fSniklas panic("bus non-single %d-byte unaligned (to %p) at %s:%d", \ 2053a630e3fSniklas sz, a, __FILE__, __LINE__); \ 2063a630e3fSniklas (*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, a, c); \ 2073a630e3fSniklas } while (0) 2083a630e3fSniklas #endif 2093a630e3fSniklas #define __abs_set(type, sz, t, h, o, v, c) \ 2103a630e3fSniklas (*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, v, c) 2113a630e3fSniklas #define __abs_copy(sz, t, h1, o1, h2, o2, cnt) \ 2123a630e3fSniklas (*(t)->__abs_opname(c,sz))((t)->abs_cookie, h1, o1, h2, o2, cnt) 213417eba8cSderaadt 214ecbe32ebSniklas /* 215ecbe32ebSniklas * Mapping and unmapping operations. 216ecbe32ebSniklas */ 217ecbe32ebSniklas #define bus_space_map(t, a, s, c, hp) \ 218ecbe32ebSniklas (*(t)->abs_map)((t)->abs_cookie, (a), (s), (c), (hp)) 219d1688987Snate #define alpha_bus_space_map_noacct bus_space_map 220ecbe32ebSniklas #define bus_space_unmap(t, h, s) \ 221ecbe32ebSniklas (*(t)->abs_unmap)((t)->abs_cookie, (h), (s)) 222d1688987Snate #define alpha_bus_space_unmap_noacct bus_space_unmap 223ecbe32ebSniklas #define bus_space_subregion(t, h, o, s, hp) \ 224ecbe32ebSniklas (*(t)->abs_subregion)((t)->abs_cookie, (h), (o), (s), (hp)) 225417eba8cSderaadt 2262fce6f75Smiod #define BUS_SPACE_MAP_CACHEABLE 0x01 2272fce6f75Smiod #define BUS_SPACE_MAP_LINEAR 0x02 2282fce6f75Smiod #define BUS_SPACE_MAP_PREFETCHABLE 0x04 229417eba8cSderaadt 230ecbe32ebSniklas /* 231ecbe32ebSniklas * Allocation and deallocation operations. 232ecbe32ebSniklas */ 233ecbe32ebSniklas #define bus_space_alloc(t, rs, re, s, a, b, c, ap, hp) \ 234ecbe32ebSniklas (*(t)->abs_alloc)((t)->abs_cookie, (rs), (re), (s), (a), (b), \ 235ecbe32ebSniklas (c), (ap), (hp)) 236ecbe32ebSniklas #define bus_space_free(t, h, s) \ 237ecbe32ebSniklas (*(t)->abs_free)((t)->abs_cookie, (h), (s)) 238417eba8cSderaadt 239f8ac741cSmiod /* 240f8ac741cSmiod * Get kernel virtual address for ranges mapped BUS_SPACE_MAP_LINEAR. 241f8ac741cSmiod */ 242f8ac741cSmiod #define bus_space_vaddr(t, h) \ 243f8ac741cSmiod (*(t)->abs_vaddr)((t)->abs_cookie, (h)) 244417eba8cSderaadt 245ecbe32ebSniklas /* 2463a630e3fSniklas * Bus barrier operations. 2473a630e3fSniklas */ 2483a630e3fSniklas #define bus_space_barrier(t, h, o, l, f) \ 2493a630e3fSniklas (*(t)->abs_barrier)((t)->abs_cookie, (h), (o), (l), (f)) 2503a630e3fSniklas 2517107682fSmiod #define BUS_SPACE_BARRIER_READ 0x01 2527107682fSmiod #define BUS_SPACE_BARRIER_WRITE 0x02 2533a630e3fSniklas 2543a630e3fSniklas 2553a630e3fSniklas /* 256ecbe32ebSniklas * Bus read (single) operations. 257ecbe32ebSniklas */ 258ecbe32ebSniklas #define bus_space_read_1(t, h, o) __abs_rs(1,(t),(h),(o)) 259ecbe32ebSniklas #define bus_space_read_2(t, h, o) __abs_rs(2,(t),(h),(o)) 260ecbe32ebSniklas #define bus_space_read_4(t, h, o) __abs_rs(4,(t),(h),(o)) 261ecbe32ebSniklas #define bus_space_read_8(t, h, o) __abs_rs(8,(t),(h),(o)) 262417eba8cSderaadt 263417eba8cSderaadt 264ecbe32ebSniklas /* 265a847dbdaSdlg * Bus read (single) operations. 266a847dbdaSdlg */ 267a847dbdaSdlg #define bus_space_read_raw_1(t, h, o) __abs_rs(1,(t),(h),(o)) 268a847dbdaSdlg #define bus_space_read_raw_2(t, h, o) __abs_rs(2,(t),(h),(o)) 269a847dbdaSdlg #define bus_space_read_raw_4(t, h, o) __abs_rs(4,(t),(h),(o)) 270a847dbdaSdlg #define bus_space_read_raw_8(t, h, o) __abs_rs(8,(t),(h),(o)) 271a847dbdaSdlg 272a847dbdaSdlg 273a847dbdaSdlg /* 274ecbe32ebSniklas * Bus read multiple operations. 275ecbe32ebSniklas */ 276ecbe32ebSniklas #define bus_space_read_multi_1(t, h, o, a, c) \ 277ecbe32ebSniklas __abs_nonsingle(rm,1,(t),(h),(o),(a),(c)) 278ecbe32ebSniklas #define bus_space_read_multi_2(t, h, o, a, c) \ 2796b7448ebSniklas __abs_aligned_nonsingle(rm,2,(t),(h),(o),(a),(c)) 280ecbe32ebSniklas #define bus_space_read_multi_4(t, h, o, a, c) \ 2816b7448ebSniklas __abs_aligned_nonsingle(rm,4,(t),(h),(o),(a),(c)) 282ecbe32ebSniklas #define bus_space_read_multi_8(t, h, o, a, c) \ 2836b7448ebSniklas __abs_aligned_nonsingle(rm,8,(t),(h),(o),(a),(c)) 284417eba8cSderaadt 285417eba8cSderaadt 286ecbe32ebSniklas /* 287aed035abSart * void bus_space_read_raw_multi_N(bus_space_tag_t tag, 288d1de8145Sniklas * bus_space_handle_t bsh, bus_size_t offset, 289aed035abSart * u_int8_t *addr, size_t count); 290d1de8145Sniklas * 291d1de8145Sniklas * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space 292d1de8145Sniklas * described by tag/handle/offset and copy into buffer provided. The buffer 293d1de8145Sniklas * must have proper alignment for the N byte wide entities. Furthermore 294d1de8145Sniklas * possible byte-swapping should be done by these functions. 295d1de8145Sniklas */ 296d1de8145Sniklas 297d1de8145Sniklas #define bus_space_read_raw_multi_2(t, h, o, a, c) \ 2986b7448ebSniklas __abs_nonsingle(rrm,2,(t),(h),(o),(a),(c)) 299d1de8145Sniklas #define bus_space_read_raw_multi_4(t, h, o, a, c) \ 3006b7448ebSniklas __abs_nonsingle(rrm,4,(t),(h),(o),(a),(c)) 301d1de8145Sniklas #define bus_space_read_raw_multi_8(t, h, o, a, c) \ 3026b7448ebSniklas __abs_nonsingle(rrm,8,(t),(h),(o),(a),(c)) 303d1de8145Sniklas 304d1de8145Sniklas /* 305ecbe32ebSniklas * Bus read region operations. 306ecbe32ebSniklas */ 307ecbe32ebSniklas #define bus_space_read_region_1(t, h, o, a, c) \ 308ecbe32ebSniklas __abs_nonsingle(rr,1,(t),(h),(o),(a),(c)) 309ecbe32ebSniklas #define bus_space_read_region_2(t, h, o, a, c) \ 3106b7448ebSniklas __abs_aligned_nonsingle(rr,2,(t),(h),(o),(a),(c)) 311ecbe32ebSniklas #define bus_space_read_region_4(t, h, o, a, c) \ 3126b7448ebSniklas __abs_aligned_nonsingle(rr,4,(t),(h),(o),(a),(c)) 313ecbe32ebSniklas #define bus_space_read_region_8(t, h, o, a, c) \ 3146b7448ebSniklas __abs_aligned_nonsingle(rr,8,(t),(h),(o),(a),(c)) 315ecbe32ebSniklas 316ecbe32ebSniklas 317ecbe32ebSniklas /* 318b4c0adb6Smiod * void bus_space_read_raw_region_N(bus_space_tag_t tag, 319b4c0adb6Smiod * bus_space_handle_t bsh, bus_size_t offset, 320b4c0adb6Smiod * u_int8_t *addr, size_t count); 321b4c0adb6Smiod * 322b4c0adb6Smiod * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space 323b4c0adb6Smiod * described by tag/handle and starting at `offset' from the 324b4c0adb6Smiod * buffer provided. The buffer must have proper alignment for the N byte 325b4c0adb6Smiod * wide entities. Furthermore possible byte-swapping should be done by 326b4c0adb6Smiod * these functions. 327b4c0adb6Smiod */ 328b4c0adb6Smiod 329b4c0adb6Smiod #define bus_space_read_raw_region_2(t, h, o, a, c) \ 330b4c0adb6Smiod bus_space_read_region_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1) 331b4c0adb6Smiod #define bus_space_read_raw_region_4(t, h, o, a, c) \ 332b4c0adb6Smiod bus_space_read_region_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2) 333b4c0adb6Smiod 334b4c0adb6Smiod /* 335ecbe32ebSniklas * Bus write (single) operations. 336ecbe32ebSniklas */ 337ecbe32ebSniklas #define bus_space_write_1(t, h, o, v) __abs_ws(1,(t),(h),(o),(v)) 338ecbe32ebSniklas #define bus_space_write_2(t, h, o, v) __abs_ws(2,(t),(h),(o),(v)) 339ecbe32ebSniklas #define bus_space_write_4(t, h, o, v) __abs_ws(4,(t),(h),(o),(v)) 340ecbe32ebSniklas #define bus_space_write_8(t, h, o, v) __abs_ws(8,(t),(h),(o),(v)) 341ecbe32ebSniklas 342ecbe32ebSniklas 343ecbe32ebSniklas /* 344a847dbdaSdlg * Bus write raw (single) operations. 345a847dbdaSdlg */ 346a847dbdaSdlg #define bus_space_write_raw_1(t, h, o, v) __abs_ws(1,(t),(h),(o),(v)) 347a847dbdaSdlg #define bus_space_write_raw_2(t, h, o, v) __abs_ws(2,(t),(h),(o),(v)) 348a847dbdaSdlg #define bus_space_write_raw_4(t, h, o, v) __abs_ws(4,(t),(h),(o),(v)) 349a847dbdaSdlg #define bus_space_write_raw_8(t, h, o, v) __abs_ws(8,(t),(h),(o),(v)) 350a847dbdaSdlg 351a847dbdaSdlg 352a847dbdaSdlg /* 353ecbe32ebSniklas * Bus write multiple operations. 354ecbe32ebSniklas */ 355ecbe32ebSniklas #define bus_space_write_multi_1(t, h, o, a, c) \ 356ecbe32ebSniklas __abs_nonsingle(wm,1,(t),(h),(o),(a),(c)) 357ecbe32ebSniklas #define bus_space_write_multi_2(t, h, o, a, c) \ 3586b7448ebSniklas __abs_aligned_nonsingle(wm,2,(t),(h),(o),(a),(c)) 359ecbe32ebSniklas #define bus_space_write_multi_4(t, h, o, a, c) \ 3606b7448ebSniklas __abs_aligned_nonsingle(wm,4,(t),(h),(o),(a),(c)) 361ecbe32ebSniklas #define bus_space_write_multi_8(t, h, o, a, c) \ 3626b7448ebSniklas __abs_aligned_nonsingle(wm,8,(t),(h),(o),(a),(c)) 363ecbe32ebSniklas 364d1de8145Sniklas /* 365aed035abSart * void bus_space_write_raw_multi_N(bus_space_tag_t tag, 366d1de8145Sniklas * bus_space_handle_t bsh, bus_size_t offset, 367aed035abSart * u_int8_t *addr, size_t count); 368d1de8145Sniklas * 369d1de8145Sniklas * Write `count' bytes in 2, 4 or 8 byte wide quantities from the buffer 370d1de8145Sniklas * provided to bus space described by tag/handle/offset. The buffer 371d1de8145Sniklas * must have proper alignment for the N byte wide entities. Furthermore 372d1de8145Sniklas * possible byte-swapping should be done by these functions. 373d1de8145Sniklas */ 374d1de8145Sniklas 375d1de8145Sniklas #define bus_space_write_raw_multi_2(t, h, o, a, c) \ 3766b7448ebSniklas __abs_nonsingle(wrm,2,(t),(h),(o),(a),(c)) 377d1de8145Sniklas #define bus_space_write_raw_multi_4(t, h, o, a, c) \ 3786b7448ebSniklas __abs_nonsingle(wrm,4,(t),(h),(o),(a),(c)) 379d1de8145Sniklas #define bus_space_write_raw_multi_8(t, h, o, a, c) \ 3806b7448ebSniklas __abs_nonsingle(wrm,8,(t),(h),(o),(a),(c)) 381ecbe32ebSniklas 382ecbe32ebSniklas /* 383ecbe32ebSniklas * Bus write region operations. 384ecbe32ebSniklas */ 385ecbe32ebSniklas #define bus_space_write_region_1(t, h, o, a, c) \ 386ecbe32ebSniklas __abs_nonsingle(wr,1,(t),(h),(o),(a),(c)) 387ecbe32ebSniklas #define bus_space_write_region_2(t, h, o, a, c) \ 3886b7448ebSniklas __abs_aligned_nonsingle(wr,2,(t),(h),(o),(a),(c)) 389ecbe32ebSniklas #define bus_space_write_region_4(t, h, o, a, c) \ 3906b7448ebSniklas __abs_aligned_nonsingle(wr,4,(t),(h),(o),(a),(c)) 391ecbe32ebSniklas #define bus_space_write_region_8(t, h, o, a, c) \ 3926b7448ebSniklas __abs_aligned_nonsingle(wr,8,(t),(h),(o),(a),(c)) 393ecbe32ebSniklas 394ecbe32ebSniklas 395ecbe32ebSniklas /* 396c4071fd1Smillert * void bus_space_write_raw_region_N(bus_space_tag_t tag, 39708aba307Sart * bus_space_handle_t bsh, bus_size_t offset, 398c4071fd1Smillert * const u_int8_t *addr, size_t count); 39908aba307Sart * 40008aba307Sart * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space 40108aba307Sart * described by tag/handle and starting at `offset' from the 40208aba307Sart * buffer provided. The buffer must have proper alignment for the N byte 40308aba307Sart * wide entities. Furthermore possible byte-swapping should be done by 40408aba307Sart * these functions. 40508aba307Sart */ 40608aba307Sart 40708aba307Sart #define bus_space_write_raw_region_2(t, h, o, a, c) \ 40808aba307Sart bus_space_write_region_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1) 40908aba307Sart #define bus_space_write_raw_region_4(t, h, o, a, c) \ 41008aba307Sart bus_space_write_region_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2) 41108aba307Sart 41208aba307Sart /* 413ecbe32ebSniklas * Set multiple operations. 414ecbe32ebSniklas */ 4153a630e3fSniklas #define bus_space_set_multi_1(t, h, o, v, c) \ 4163a630e3fSniklas __abs_set(sm,1,(t),(h),(o),(v),(c)) 4173a630e3fSniklas #define bus_space_set_multi_2(t, h, o, v, c) \ 4183a630e3fSniklas __abs_set(sm,2,(t),(h),(o),(v),(c)) 4193a630e3fSniklas #define bus_space_set_multi_4(t, h, o, v, c) \ 4203a630e3fSniklas __abs_set(sm,4,(t),(h),(o),(v),(c)) 4213a630e3fSniklas #define bus_space_set_multi_8(t, h, o, v, c) \ 4223a630e3fSniklas __abs_set(sm,8,(t),(h),(o),(v),(c)) 423ecbe32ebSniklas 424ecbe32ebSniklas 425ecbe32ebSniklas /* 426ecbe32ebSniklas * Set region operations. 427ecbe32ebSniklas */ 4283a630e3fSniklas #define bus_space_set_region_1(t, h, o, v, c) \ 4293a630e3fSniklas __abs_set(sr,1,(t),(h),(o),(v),(c)) 4303a630e3fSniklas #define bus_space_set_region_2(t, h, o, v, c) \ 4313a630e3fSniklas __abs_set(sr,2,(t),(h),(o),(v),(c)) 4323a630e3fSniklas #define bus_space_set_region_4(t, h, o, v, c) \ 4333a630e3fSniklas __abs_set(sr,4,(t),(h),(o),(v),(c)) 4343a630e3fSniklas #define bus_space_set_region_8(t, h, o, v, c) \ 4353a630e3fSniklas __abs_set(sr,8,(t),(h),(o),(v),(c)) 436ecbe32ebSniklas 437ecbe32ebSniklas 438ecbe32ebSniklas /* 439ecbe32ebSniklas * Copy operations. 440ecbe32ebSniklas */ 4413a630e3fSniklas #define bus_space_copy_1(t, h1, o1, h2, o2, c) \ 4423a630e3fSniklas __abs_copy(1, t, h1, o1, h2, o2, c) 4433a630e3fSniklas #define bus_space_copy_2(t, h1, o1, h2, o2, c) \ 4443a630e3fSniklas __abs_copy(2, t, h1, o1, h2, o2, c) 4453a630e3fSniklas #define bus_space_copy_4(t, h1, o1, h2, o2, c) \ 4463a630e3fSniklas __abs_copy(4, t, h1, o1, h2, o2, c) 4473a630e3fSniklas #define bus_space_copy_8(t, h1, o1, h2, o2, c) \ 4483a630e3fSniklas __abs_copy(8, t, h1, o1, h2, o2, c) 449417eba8cSderaadt 450aed035abSart /* 451aed035abSart * Bus DMA methods. 452aed035abSart */ 453aed035abSart 454aed035abSart /* 455aed035abSart * Flags used in various bus DMA methods. 456aed035abSart */ 457471ccd18Soga #define BUS_DMA_WAITOK 0x0000 /* safe to sleep (pseudo-flag) */ 458471ccd18Soga #define BUS_DMA_NOWAIT 0x0001 /* not safe to sleep */ 459471ccd18Soga #define BUS_DMA_ALLOCNOW 0x0002 /* perform resource allocation now */ 460471ccd18Soga #define BUS_DMA_COHERENT 0x0004 /* hint: map memory DMA coherent */ 461471ccd18Soga #define BUS_DMA_BUS1 0x0010 /* placeholders for bus functions... */ 462471ccd18Soga #define BUS_DMA_BUS2 0x0020 463471ccd18Soga #define BUS_DMA_BUS3 0x0040 464471ccd18Soga #define BUS_DMA_24BIT 0x0080 /* isadma map */ 465471ccd18Soga #define BUS_DMA_STREAMING 0x0100 /* hint: sequential, unidirectional */ 466471ccd18Soga #define BUS_DMA_READ 0x0200 /* mapping is device -> memory only */ 467471ccd18Soga #define BUS_DMA_WRITE 0x0400 /* mapping is memory -> device only */ 468471ccd18Soga #define BUS_DMA_ZERO 0x1000 /* zero memory in dmamem_alloc */ 469b0002153Sdlg #define BUS_DMA_64BIT 0x2000 /* device handles 64bit dva */ 470aed035abSart 471aed035abSart /* 472aed035abSart * Private flags stored in the DMA map. 473aed035abSart */ 474aed035abSart #define DMAMAP_NO_COALESCE 0x40000000 /* don't coalesce adjacent 475aed035abSart segments */ 476aed035abSart 477aed035abSart /* Forwards needed by prototypes below. */ 478aed035abSart struct mbuf; 479aed035abSart struct uio; 480aed035abSart struct alpha_sgmap; 481aed035abSart 482aed035abSart /* 483aed035abSart * Operations performed by bus_dmamap_sync(). 484aed035abSart */ 4850065d83cSart #define BUS_DMASYNC_PREREAD 0x01 4860065d83cSart #define BUS_DMASYNC_POSTREAD 0x02 4870065d83cSart #define BUS_DMASYNC_PREWRITE 0x04 4880065d83cSart #define BUS_DMASYNC_POSTWRITE 0x08 489aed035abSart 490aed035abSart /* 491aed035abSart * alpha_bus_t 492aed035abSart * 493aed035abSart * Busses supported by NetBSD/alpha, used by internal 494aed035abSart * utility functions. NOT TO BE USED BY MACHINE-INDEPENDENT 495aed035abSart * CODE! 496aed035abSart */ 497aed035abSart typedef enum { 498aed035abSart ALPHA_BUS_TURBOCHANNEL, 499aed035abSart ALPHA_BUS_PCI, 500aed035abSart ALPHA_BUS_EISA, 501aed035abSart ALPHA_BUS_ISA, 502aed035abSart ALPHA_BUS_TLSB, 503aed035abSart } alpha_bus_t; 504aed035abSart 505aed035abSart typedef struct alpha_bus_dma_tag *bus_dma_tag_t; 506aed035abSart typedef struct alpha_bus_dmamap *bus_dmamap_t; 507aed035abSart 508aed035abSart /* 509aed035abSart * bus_dma_segment_t 510aed035abSart * 511aed035abSart * Describes a single contiguous DMA transaction. Values 512aed035abSart * are suitable for programming into DMA registers. 513aed035abSart */ 514aed035abSart struct alpha_bus_dma_segment { 515aed035abSart bus_addr_t ds_addr; /* DMA address */ 516aed035abSart bus_size_t ds_len; /* length of transfer */ 517aed035abSart }; 518aed035abSart typedef struct alpha_bus_dma_segment bus_dma_segment_t; 519aed035abSart 520aed035abSart /* 521aed035abSart * bus_dma_tag_t 522aed035abSart * 523aed035abSart * A machine-dependent opaque type describing the implementation of 524aed035abSart * DMA for a given bus. 525aed035abSart */ 526aed035abSart struct alpha_bus_dma_tag { 527aed035abSart void *_cookie; /* cookie used in the guts */ 528aed035abSart bus_addr_t _wbase; /* DMA window base */ 529aed035abSart 530aed035abSart /* 531aed035abSart * The following two members are used to chain DMA windows 532aed035abSart * together. If, during the course of a map load, the 533aed035abSart * resulting physical memory address is too large to 534aed035abSart * be addressed by the window, the next window will be 535aed035abSart * attempted. These would be chained together like so: 536aed035abSart * 537aed035abSart * direct -> sgmap -> NULL 538aed035abSart * or 539aed035abSart * sgmap -> NULL 540aed035abSart * or 541aed035abSart * direct -> NULL 542aed035abSart * 543aed035abSart * If the window size is 0, it will not be checked (e.g. 544aed035abSart * TurboChannel DMA). 545aed035abSart */ 546aed035abSart bus_size_t _wsize; 547aed035abSart struct alpha_bus_dma_tag *_next_window; 548aed035abSart 549aed035abSart /* 550aed035abSart * Some chipsets have a built-in boundary constraint, independent 551aed035abSart * of what the device requests. This allows that boundary to 552a347b448Sjmc * be specified. If the device has a more restrictive constraint, 553aed035abSart * the map will use that, otherwise this boundary will be used. 554aed035abSart * This value is ignored if 0. 555aed035abSart */ 556aed035abSart bus_size_t _boundary; 557aed035abSart 558aed035abSart /* 559aed035abSart * A chipset may have more than one SGMAP window, so SGMAP 560aed035abSart * windows also get a pointer to their SGMAP state. 561aed035abSart */ 562aed035abSart struct alpha_sgmap *_sgmap; 563aed035abSart 564aed035abSart /* 565aed035abSart * Internal-use only utility methods. NOT TO BE USED BY 566aed035abSart * MACHINE-INDEPENDENT CODE! 567aed035abSart */ 568aed035abSart bus_dma_tag_t (*_get_tag)(bus_dma_tag_t, alpha_bus_t); 569aed035abSart 570aed035abSart /* 571aed035abSart * DMA mapping methods. 572aed035abSart */ 573aed035abSart int (*_dmamap_create)(bus_dma_tag_t, bus_size_t, int, 574aed035abSart bus_size_t, bus_size_t, int, bus_dmamap_t *); 575aed035abSart void (*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t); 576aed035abSart int (*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *, 577aed035abSart bus_size_t, struct proc *, int); 578aed035abSart int (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t, 579aed035abSart struct mbuf *, int); 580aed035abSart int (*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t, 581aed035abSart struct uio *, int); 582aed035abSart int (*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t, 583aed035abSart bus_dma_segment_t *, int, bus_size_t, int); 584aed035abSart void (*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t); 585aed035abSart void (*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t, 5860065d83cSart bus_addr_t, bus_size_t, int); 587aed035abSart 588aed035abSart /* 589aed035abSart * DMA memory utility functions. 590aed035abSart */ 591aed035abSart int (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t, 592aed035abSart bus_size_t, bus_dma_segment_t *, int, int *, int); 593aed035abSart void (*_dmamem_free)(bus_dma_tag_t, 594aed035abSart bus_dma_segment_t *, int); 595aed035abSart int (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *, 596aed035abSart int, size_t, caddr_t *, int); 597aed035abSart void (*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t); 598aed035abSart paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *, 599aed035abSart int, off_t, int, int); 600aed035abSart }; 601aed035abSart 602aed035abSart #define alphabus_dma_get_tag(t, b) \ 603aed035abSart (*(t)->_get_tag)(t, b) 604aed035abSart 605aed035abSart #define bus_dmamap_create(t, s, n, m, b, f, p) \ 606aed035abSart (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p)) 607aed035abSart #define bus_dmamap_destroy(t, p) \ 608aed035abSart (*(t)->_dmamap_destroy)((t), (p)) 609aed035abSart #define bus_dmamap_load(t, m, b, s, p, f) \ 610aed035abSart (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f)) 611aed035abSart #define bus_dmamap_load_mbuf(t, m, b, f) \ 612aed035abSart (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f)) 613aed035abSart #define bus_dmamap_load_uio(t, m, u, f) \ 614aed035abSart (*(t)->_dmamap_load_uio)((t), (m), (u), (f)) 615aed035abSart #define bus_dmamap_load_raw(t, m, sg, n, s, f) \ 616aed035abSart (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f)) 617aed035abSart #define bus_dmamap_unload(t, p) \ 61853312540Sbrad (void)(t), \ 61953312540Sbrad (*(p)->_dm_window->_dmamap_unload)((p)->_dm_window, (p)) 6200065d83cSart #define bus_dmamap_sync(t, p, a, s, op) \ 62153312540Sbrad (void)(t), \ 62253312540Sbrad (*(p)->_dm_window->_dmamap_sync)((p)->_dm_window, (p), (a), (s), (op)) 623aed035abSart #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \ 624aed035abSart (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f)) 625aed035abSart #define bus_dmamem_free(t, sg, n) \ 626aed035abSart (*(t)->_dmamem_free)((t), (sg), (n)) 627aed035abSart #define bus_dmamem_map(t, sg, n, s, k, f) \ 628aed035abSart (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f)) 629aed035abSart #define bus_dmamem_unmap(t, k, s) \ 630aed035abSart (*(t)->_dmamem_unmap)((t), (k), (s)) 631aed035abSart #define bus_dmamem_mmap(t, sg, n, o, p, f) \ 632aed035abSart (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) 633aed035abSart 634aed035abSart /* 635aed035abSart * bus_dmamap_t 636aed035abSart * 637aed035abSart * Describes a DMA mapping. 638aed035abSart */ 639aed035abSart struct alpha_bus_dmamap { 640aed035abSart /* 641da6a775aSjason * PRIVATE MEMBERS: not for use by machine-independent code. 642aed035abSart */ 643aed035abSart bus_size_t _dm_size; /* largest DMA transfer mappable */ 644aed035abSart int _dm_segcnt; /* number of segs this map can map */ 645aed035abSart bus_size_t _dm_maxsegsz; /* largest possible segment */ 646aed035abSart bus_size_t _dm_boundary; /* don't cross this */ 647aed035abSart int _dm_flags; /* misc. flags */ 648aed035abSart 649aed035abSart /* 650aed035abSart * Private cookie to be used by the DMA back-end. 651aed035abSart */ 652aed035abSart void *_dm_cookie; 6535be19075Smpi size_t _dm_cookiesize; /* size allocated for _dm_cookie */ 654aed035abSart 655aed035abSart /* 65653312540Sbrad * The DMA window that we ended up being mapped in. 65753312540Sbrad */ 65853312540Sbrad bus_dma_tag_t _dm_window; 65953312540Sbrad 66053312540Sbrad /* 661aed035abSart * PUBLIC MEMBERS: these are used by machine-independent code. 662aed035abSart */ 663aed035abSart bus_size_t dm_mapsize; /* size of the mapping */ 664aed035abSart int dm_nsegs; /* # valid segments in mapping */ 665aed035abSart bus_dma_segment_t dm_segs[1]; /* segments; variable length */ 666aed035abSart }; 667aed035abSart 668aed035abSart #ifdef _ALPHA_BUS_DMA_PRIVATE 669aed035abSart int _bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t, 670aed035abSart bus_size_t, int, bus_dmamap_t *); 671aed035abSart void _bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t); 672aed035abSart 673aed035abSart int _bus_dmamap_load_direct(bus_dma_tag_t, bus_dmamap_t, 674aed035abSart void *, bus_size_t, struct proc *, int); 675aed035abSart int _bus_dmamap_load_mbuf_direct(bus_dma_tag_t, 676aed035abSart bus_dmamap_t, struct mbuf *, int); 677aed035abSart int _bus_dmamap_load_uio_direct(bus_dma_tag_t, 678aed035abSart bus_dmamap_t, struct uio *, int); 679aed035abSart int _bus_dmamap_load_raw_direct(bus_dma_tag_t, 680aed035abSart bus_dmamap_t, bus_dma_segment_t *, int, bus_size_t, int); 681aed035abSart 682aed035abSart void _bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t); 6830065d83cSart void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t, 6840065d83cSart bus_size_t, int); 685aed035abSart 686aed035abSart int _bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size, 687aed035abSart bus_size_t alignment, bus_size_t boundary, 688aed035abSart bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags); 689aed035abSart int _bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size, 690aed035abSart bus_size_t alignment, bus_size_t boundary, 691aed035abSart bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, 692aed035abSart paddr_t low, paddr_t high); 693aed035abSart void _bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs, 694aed035abSart int nsegs); 695aed035abSart int _bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs, 696aed035abSart int nsegs, size_t size, caddr_t *kvap, int flags); 697aed035abSart void _bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva, 698aed035abSart size_t size); 699aed035abSart paddr_t _bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs, 700aed035abSart int nsegs, off_t off, int prot, int flags); 701aed035abSart #endif /* _ALPHA_BUS_DMA_PRIVATE */ 702c44e1821Sniklas 703*f56b290dSderaadt #endif /* _KERNEL */ 704*f56b290dSderaadt 7052fa72412Spirofti #endif /* _MACHINE_BUS_H_ */ 706