1 /* $NetBSD: bus.h,v 1.13 2020/03/08 02:42:00 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef _SYS_BUS_H_ 30 #define _SYS_BUS_H_ 31 32 #include <sys/types.h> 33 34 #ifdef __HAVE_NEW_STYLE_BUS_H 35 36 #include <machine/bus_defs.h> 37 38 struct bus_space_reservation { 39 bus_addr_t _bsr_start; 40 bus_size_t _bsr_size; 41 }; 42 43 typedef struct bus_space_reservation bus_space_reservation_t; 44 45 static __inline bus_size_t 46 bus_space_reservation_size(bus_space_reservation_t *bsr) 47 { 48 return bsr->_bsr_size; 49 } 50 51 static __inline bus_space_reservation_t * 52 bus_space_reservation_init(bus_space_reservation_t *bsr, 53 bus_addr_t addr, bus_size_t size) 54 { 55 bsr->_bsr_start = addr; 56 bsr->_bsr_size = size; 57 return bsr; 58 } 59 60 static __inline bus_addr_t 61 bus_space_reservation_addr(bus_space_reservation_t *bsr) 62 { 63 return bsr->_bsr_start; 64 } 65 66 enum bus_space_override_idx { 67 BUS_SPACE_OVERRIDE_MAP = __BIT(0) 68 , BUS_SPACE_OVERRIDE_UNMAP = __BIT(1) 69 , BUS_SPACE_OVERRIDE_ALLOC = __BIT(2) 70 , BUS_SPACE_OVERRIDE_FREE = __BIT(3) 71 , BUS_SPACE_OVERRIDE_RESERVE = __BIT(4) 72 , BUS_SPACE_OVERRIDE_RELEASE = __BIT(5) 73 , BUS_SPACE_OVERRIDE_RESERVATION_MAP = __BIT(6) 74 , BUS_SPACE_OVERRIDE_RESERVATION_UNMAP = __BIT(7) 75 , BUS_SPACE_OVERRIDE_RESERVE_SUBREGION = __BIT(8) 76 #if 0 77 , BUS_SPACE_OVERRIDE_EXTEND = __BIT(9) 78 , BUS_SPACE_OVERRIDE_TRIM = __BIT(10) 79 #endif 80 }; 81 82 enum bus_dma_override_idx { 83 BUS_DMAMAP_OVERRIDE_CREATE = __BIT(0) 84 , BUS_DMAMAP_OVERRIDE_DESTROY = __BIT(1) 85 , BUS_DMAMAP_OVERRIDE_LOAD = __BIT(2) 86 , BUS_DMAMAP_OVERRIDE_LOAD_MBUF = __BIT(3) 87 , BUS_DMAMAP_OVERRIDE_LOAD_UIO = __BIT(4) 88 , BUS_DMAMAP_OVERRIDE_LOAD_RAW = __BIT(5) 89 , BUS_DMAMAP_OVERRIDE_UNLOAD = __BIT(6) 90 , BUS_DMAMAP_OVERRIDE_SYNC = __BIT(7) 91 , BUS_DMAMEM_OVERRIDE_ALLOC = __BIT(8) 92 , BUS_DMAMEM_OVERRIDE_FREE = __BIT(9) 93 , BUS_DMAMEM_OVERRIDE_MAP = __BIT(10) 94 , BUS_DMAMEM_OVERRIDE_UNMAP = __BIT(11) 95 , BUS_DMAMEM_OVERRIDE_MMAP = __BIT(12) 96 , BUS_DMATAG_OVERRIDE_SUBREGION = __BIT(13) 97 , BUS_DMATAG_OVERRIDE_DESTROY = __BIT(14) 98 }; 99 100 /* Only add new members at the end of this struct! */ 101 struct bus_space_overrides { 102 int (*ov_space_map)(void *, bus_space_tag_t, bus_addr_t, bus_size_t, 103 int, bus_space_handle_t *); 104 105 void (*ov_space_unmap)(void *, bus_space_tag_t, bus_space_handle_t, 106 bus_size_t); 107 108 int (*ov_space_alloc)(void *, bus_space_tag_t, bus_addr_t, bus_addr_t, 109 bus_size_t, bus_size_t, bus_size_t, int, bus_addr_t *, 110 bus_space_handle_t *); 111 112 void (*ov_space_free)(void *, bus_space_tag_t, bus_space_handle_t, 113 bus_size_t); 114 115 int (*ov_space_reserve)(void *, bus_space_tag_t, bus_addr_t, bus_size_t, 116 int, bus_space_reservation_t *); 117 118 void (*ov_space_release)(void *, bus_space_tag_t, 119 bus_space_reservation_t *); 120 121 int (*ov_space_reservation_map)(void *, bus_space_tag_t, 122 bus_space_reservation_t *, int, bus_space_handle_t *); 123 124 void (*ov_space_reservation_unmap)(void *, bus_space_tag_t, 125 bus_space_handle_t, bus_size_t); 126 127 int (*ov_space_reserve_subregion)(void *, bus_space_tag_t, 128 bus_addr_t, bus_addr_t, bus_size_t, bus_size_t, bus_size_t, 129 int, bus_space_reservation_t *); 130 131 #if 0 132 int (*ov_space_extend)(void *, bus_space_tag_t, 133 bus_space_reservation_t *, bus_size_t, bus_size_t); 134 135 void (*ov_space_trim)(void *, bus_space_tag_t, 136 bus_space_reservation_t *, bus_size_t, bus_size_t); 137 #endif 138 }; 139 140 struct mbuf; 141 struct uio; 142 143 /* Only add new members at the end of this struct! */ 144 struct bus_dma_overrides { 145 int (*ov_dmamap_create)(void *, bus_dma_tag_t, bus_size_t, int, 146 bus_size_t, bus_size_t, int, bus_dmamap_t *); 147 void (*ov_dmamap_destroy)(void *, bus_dma_tag_t, bus_dmamap_t); 148 int (*ov_dmamap_load)(void *, bus_dma_tag_t, bus_dmamap_t, void *, 149 bus_size_t, struct proc *, int); 150 int (*ov_dmamap_load_mbuf)(void *, bus_dma_tag_t, bus_dmamap_t, 151 struct mbuf *, int); 152 int (*ov_dmamap_load_uio)(void *, bus_dma_tag_t, bus_dmamap_t, 153 struct uio *, int); 154 int (*ov_dmamap_load_raw)(void *, bus_dma_tag_t, bus_dmamap_t, 155 bus_dma_segment_t *, int, bus_size_t, int); 156 void (*ov_dmamap_unload)(void *, bus_dma_tag_t, bus_dmamap_t); 157 void (*ov_dmamap_sync)(void *, bus_dma_tag_t, bus_dmamap_t, bus_addr_t, 158 bus_size_t, int); 159 int (*ov_dmamem_alloc)(void *, bus_dma_tag_t, bus_size_t, bus_size_t, 160 bus_size_t, bus_dma_segment_t *, int, int *, int); 161 void (*ov_dmamem_free)(void *, bus_dma_tag_t, bus_dma_segment_t *, int); 162 int (*ov_dmamem_map)(void *, bus_dma_tag_t, bus_dma_segment_t *, int, 163 size_t, void **, int); 164 void (*ov_dmamem_unmap)(void *, bus_dma_tag_t, void *, size_t); 165 paddr_t (*ov_dmamem_mmap)(void *, bus_dma_tag_t, bus_dma_segment_t *, 166 int, off_t, int, int); 167 int (*ov_dmatag_subregion)(void *, bus_dma_tag_t, bus_addr_t, 168 bus_addr_t, bus_dma_tag_t *, int); 169 void (*ov_dmatag_destroy)(void *, bus_dma_tag_t); 170 }; 171 172 int bus_space_tag_create(bus_space_tag_t, uint64_t, uint64_t, 173 const struct bus_space_overrides *, void *, 174 bus_space_tag_t *); 175 void bus_space_tag_destroy(bus_space_tag_t); 176 177 int bus_dma_tag_create(bus_dma_tag_t, uint64_t, 178 const struct bus_dma_overrides *, void *, bus_dma_tag_t *); 179 void bus_dma_tag_destroy(bus_dma_tag_t); 180 181 /* Reserve a region of bus space. Reserved bus space cannot be allocated 182 * with bus_space_alloc(). Reserved space has not been bus_space_map()'d. 183 */ 184 int bus_space_reserve(bus_space_tag_t, bus_addr_t, bus_size_t, int, 185 bus_space_reservation_t *); 186 187 int 188 bus_space_reserve_subregion(bus_space_tag_t, 189 bus_addr_t, bus_addr_t, bus_size_t, bus_size_t, bus_size_t, 190 int, bus_space_reservation_t *); 191 192 /* Cancel a reservation. */ 193 void bus_space_release(bus_space_tag_t, bus_space_reservation_t *); 194 195 int bus_space_reservation_map(bus_space_tag_t, bus_space_reservation_t *, 196 int, bus_space_handle_t *); 197 198 void bus_space_reservation_unmap(bus_space_tag_t, bus_space_handle_t, 199 bus_size_t); 200 201 #if 0 202 /* Extend a reservation to the left and/or to the right. The extension 203 * has not been bus_space_map()'d. 204 */ 205 int bus_space_extend(bus_space_tag_t, bus_space_reservation_t *, bus_size_t, 206 bus_size_t); 207 208 /* Trim bus space from a reservation on the left and/or on the right. */ 209 void bus_space_trim(bus_space_tag_t, bus_space_reservation_t *, bus_size_t, 210 bus_size_t); 211 #endif 212 213 #include <sys/bus_proto.h> 214 215 #include <machine/bus_funcs.h> 216 217 #else /* !__HAVE_NEW_STYLE_BUS_H */ 218 219 #include <machine/bus.h> 220 221 bool bus_space_is_equal(bus_space_tag_t, bus_space_tag_t); 222 bool bus_space_handle_is_equal(bus_space_tag_t, bus_space_handle_t, 223 bus_space_handle_t); 224 225 #endif /* __HAVE_NEW_STYLE_BUS_H */ 226 227 #ifdef __HAVE_NO_BUS_DMA 228 /* 229 * XXX 230 * Dummy bus_dma(9) stuff for ports which don't bother to have 231 * unnecessary bus_dma(9) implementation to appease MI driver modules etc. 232 */ 233 typedef void *bus_dma_tag_t; 234 235 typedef struct bus_dma_segment { 236 bus_addr_t ds_addr; 237 bus_size_t ds_len; 238 } bus_dma_segment_t; 239 240 typedef struct bus_dmamap { 241 bus_size_t dm_maxsegsz; 242 bus_size_t dm_mapsize; 243 int dm_nsegs; 244 bus_dma_segment_t *dm_segs; 245 } *bus_dmamap_t; 246 #endif /* __HAVE_NO_BUS_DMA */ 247 248 /* 249 * Convenience macros to correctly extract the upper and lower 250 * 32 bits of a bus_addr_t (which may be a 32-bit or 64-bit 251 * value). 252 */ 253 #define BUS_ADDR_HI32(a) ((uint32_t) __SHIFTOUT(a, __BITS(32,63))) 254 #define BUS_ADDR_LO32(a) ((uint32_t) __SHIFTOUT(a, __BITS(0,31))) 255 256 #endif /* _SYS_BUS_H_ */ 257