1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_DDIDEVMAP_H 27 #define _SYS_DDIDEVMAP_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #ifdef _KERNEL 36 37 #include <sys/mman.h> 38 39 struct devmap_info { 40 size_t length; /* and this length */ 41 size_t page_size; /* pte page size selected by framework */ 42 size_t offset; /* optimal page size based on this offset */ 43 ushort_t valid_flag; /* flag to indicate the validity of data */ 44 uchar_t byte_order; /* the endian characteristics of the mapping */ 45 46 /* 47 * describes order in which the CPU will reference data. 48 */ 49 uchar_t data_order; 50 }; 51 52 typedef void * ddi_umem_cookie_t; 53 54 /* 55 * umem callback function vector for drivers 56 * 57 * NOTE: IMPORTANT! When umem_lockmemory is called with a valid 58 * umem_callback_ops and DDI_UMEMLOCK_LONGTERM set, the 'cleanup' 59 * callback function may be called AFTER a call to ddi_umem_lock. 60 * It is the users responsibility to make sure that ddi_umem_lock is 61 * called ONLY once for each ddi_umem_lock/umem_lockmemory cookie. 62 */ 63 #define UMEM_CALLBACK_VERSION 1 64 struct umem_callback_ops { 65 int cbo_umem_callback_version; /* version number */ 66 void (*cbo_umem_lock_cleanup)(ddi_umem_cookie_t *); 67 }; 68 69 struct ddi_umem_cookie { 70 size_t size; /* size of allocation */ 71 caddr_t cvaddr; /* cookie virtual address. */ 72 /* KMEM - kvaddr returned from ddi_umem_alloc() */ 73 /* For LOCKEDUMEM - user address of backing store */ 74 /* For TRASH_UMEM - unused */ 75 kmutex_t lock; 76 uint_t type; /* see below for umem_cookie types */ 77 /* 78 * Following 4 members are used for UMEM_LOCKED cookie type 79 */ 80 page_t **pparray; /* shadow list from as_pagelock */ 81 void *procp; /* user process owning backing store */ 82 struct as *asp; /* as ptr for use by ddi_umem_unlock */ 83 enum seg_rw s_flags; /* flags used during pagelock/fault */ 84 /* 85 * locked indicates underlying memory locked for KMEM_PAGEABLE 86 * locked is a count of for how many pages this has been locked 87 */ 88 uint_t locked; 89 struct umem_callback_ops callbacks; 90 /* 91 * cook_refcnt used in UMEM_LOCKED type 92 */ 93 ulong_t cook_refcnt; /* cookie reference count */ 94 struct ddi_umem_cookie *unl_forw; /* list ptr for unlock cookies */ 95 void *reserved; /* unused */ 96 }; 97 98 typedef struct as *ddi_as_handle_t; 99 100 101 /* 102 * type of umem_cookie: 103 * pageable memory allocated from segkp segment driver 104 * non-pageable memory allocated from kmem_getpages() 105 * locked umem allocated from ddi_umem_lock 106 * trash umem maps all user virtual addresses to a common trash page 107 */ 108 #define KMEM_PAGEABLE 0x100 /* un-locked kernel memory */ 109 #define KMEM_NON_PAGEABLE 0x200 /* locked kernel memeory */ 110 #define UMEM_LOCKED 0x400 /* locked user process memeory */ 111 #define UMEM_TRASH 0x800 /* trash page mapping */ 112 113 typedef struct __devmap_pmem_cookie *devmap_pmem_cookie_t; 114 115 typedef void *devmap_cookie_t; 116 117 struct devmap_callback_ctl { 118 int devmap_rev; /* devmap_callback_ctl version number */ 119 int (*devmap_map)(devmap_cookie_t dhp, dev_t dev, uint_t flags, 120 offset_t off, size_t len, void **pvtp); 121 int (*devmap_access)(devmap_cookie_t dhp, void *pvtp, offset_t off, 122 size_t len, uint_t type, uint_t rw); 123 int (*devmap_dup)(devmap_cookie_t dhp, void *pvtp, 124 devmap_cookie_t new_dhp, void **new_pvtp); 125 void (*devmap_unmap)(devmap_cookie_t dhp, void *pvtp, offset_t off, 126 size_t len, devmap_cookie_t new_dhp1, 127 void **new_pvtp1, devmap_cookie_t new_dhp2, 128 void **new_pvtp2); 129 }; 130 131 struct devmap_softlock { 132 ulong_t id; /* handle grouping id */ 133 dev_t dev; /* Device to which we are mapping */ 134 struct devmap_softlock *next; 135 kmutex_t lock; 136 kcondvar_t cv; 137 int refcnt; /* Number of threads with mappings */ 138 ssize_t softlocked; 139 }; 140 141 struct devmap_ctx { 142 ulong_t id; /* handle grouping id */ 143 dev_info_t *dip; /* Device info struct for tracing context */ 144 struct devmap_ctx *next; 145 kmutex_t lock; 146 kcondvar_t cv; 147 int refcnt; /* Number of threads with mappings */ 148 uint_t oncpu; /* this context is running on a cpu */ 149 timeout_id_t timeout; /* Timeout ID */ 150 }; 151 152 /* 153 * Fault information passed to the driver fault handling routine. 154 * The DEVMAP_LOCK and DEVMAP_UNLOCK are used by software 155 * to lock and unlock pages for physical I/O. 156 */ 157 enum devmap_fault_type { 158 DEVMAP_ACCESS, /* invalid page */ 159 DEVMAP_PROT, /* protection fault */ 160 DEVMAP_LOCK, /* software requested locking */ 161 DEVMAP_UNLOCK /* software requested unlocking */ 162 }; 163 164 /* 165 * seg_rw gives the access type for a fault operation 166 */ 167 enum devmap_rw { 168 DEVMAP_OTHER, /* unknown or not touched */ 169 DEVMAP_READ, /* read access attempted */ 170 DEVMAP_WRITE, /* write access attempted */ 171 DEVMAP_EXEC, /* execution access attempted */ 172 DEVMAP_CREATE /* create if page doesn't exist */ 173 }; 174 175 typedef struct devmap_handle { 176 177 /* 178 * physical offset at the beginning of mapping. 179 */ 180 offset_t dh_roff; 181 182 /* 183 * user offset at the beginning of mapping. 184 */ 185 offset_t dh_uoff; 186 size_t dh_len; /* length of mapping */ 187 dev_t dh_dev; /* dev_t for this mapping */ 188 caddr_t dh_cvaddr; /* cookie virtual address */ 189 caddr_t dh_uvaddr; /* user address within dh_seg */ 190 191 /* 192 * Lock protects fields that can change during remap 193 * dh_roff, dh_cookie, dh_flags, dh_mmulevel, dh_maxprot, 194 * dh_pfn, dh_hat_attr 195 */ 196 kmutex_t dh_lock; 197 198 /* 199 * to sync. faults for remap and unlocked kvaddr. 200 */ 201 struct seg *dh_seg; /* segment created for this mapping */ 202 void *dh_pvtp; /* device mapping private data */ 203 struct devmap_handle *dh_next; 204 struct devmap_softlock *dh_softlock; 205 struct devmap_ctx *dh_ctx; 206 ddi_umem_cookie_t dh_cookie; /* kmem cookie */ 207 devmap_pmem_cookie_t dh_pcookie; /* pmem cookie */ 208 209 /* 210 * protection flag possible for attempted mapping. 211 */ 212 uint_t dh_prot; 213 214 /* 215 * Current maximum protection flag for attempted mapping. 216 * This controls how dh_prot can be changed in segdev_setprot 217 * See dh_orig_maxprot below also 218 */ 219 uint_t dh_maxprot; 220 221 /* 222 * mmu level corresponds to the Max page size can be use for 223 * the mapping. 224 */ 225 uint_t dh_mmulevel; 226 uint_t dh_flags; /* see defines below */ 227 pfn_t dh_pfn; /* pfn corresponds to dh_reg_off */ 228 uint_t dh_hat_attr; 229 clock_t dh_timeout_length; 230 struct devmap_callback_ctl dh_callbackops; 231 232 /* 233 * orig_maxprot is what the original mmap set maxprot to. 234 * This is never modified once it is setup during mmap(2) 235 * This is different from the current dh_maxprot which can 236 * be changed in devmap_*_setup/remap 237 */ 238 uint_t dh_orig_maxprot; 239 } devmap_handle_t; 240 241 #endif /* _KERNEL */ 242 243 /* 244 * define for devmap_rev 245 */ 246 #define DEVMAP_OPS_REV 1 247 248 /* 249 * defines for devmap_*_setup flag, called by drivers 250 */ 251 #define DEVMAP_DEFAULTS 0x00 252 #define DEVMAP_MAPPING_INVALID 0x01 /* mapping is invalid */ 253 #define DEVMAP_ALLOW_REMAP 0x02 /* allow remap */ 254 #define DEVMAP_USE_PAGESIZE 0x04 /* use pagesize for mmu load */ 255 256 /* flags used by drivers */ 257 #define DEVMAP_SETUP_FLAGS \ 258 (DEVMAP_MAPPING_INVALID | DEVMAP_ALLOW_REMAP | DEVMAP_USE_PAGESIZE) 259 260 /* 261 * defines for dh_flags, these are used internally in devmap 262 */ 263 #define DEVMAP_SETUP_DONE 0x100 /* mapping setup is done */ 264 #define DEVMAP_LOCK_INITED 0x200 /* locks are initailized */ 265 #define DEVMAP_LOCKED 0x800 /* dhp is locked. */ 266 #define DEVMAP_FLAG_LARGE 0x1000 /* cal. optimal pgsize */ 267 268 /* 269 * Flags to pass to ddi_umem_alloc and ddi_umem_iosetup 270 */ 271 #define DDI_UMEM_SLEEP 0x0 272 #define DDI_UMEM_NOSLEEP 0x01 273 #define DDI_UMEM_PAGEABLE 0x02 274 #define DDI_UMEM_TRASH 0x04 275 276 /* 277 * Flags to pass to ddi_umem_lock to indicate expected access pattern 278 * DDI_UMEMLOCK_READ implies the memory being locked will be read 279 * (e.g., data read from memory is written out to the disk or network) 280 * DDI_UMEMLOCK_WRITE implies the memory being locked will be written 281 * (e.g., data from the disk or network is written to memory) 282 * Both flags may be set in the call to ddi_umem_lock, 283 * Note that this corresponds to the VM subsystem definition of read/write 284 * and also correspond to the prots set in devmap 285 * When doing I/O, B_READ/B_WRITE are used which have exactly the opposite 286 * meaning. Be careful when using it both for I/O and devmap 287 * 288 * 289 */ 290 #define DDI_UMEMLOCK_READ 0x01 291 #define DDI_UMEMLOCK_WRITE 0x02 292 293 #ifdef __cplusplus 294 } 295 #endif 296 297 #endif /* _SYS_DDIDEVMAP_H */ 298