Home | History | Annotate | Download | only in sys
      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