xref: /illumos-gate/usr/src/uts/common/sys/ddidevmap.h (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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