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