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 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #ifndef _LDC_H
     28 #define	_LDC_H
     29 
     30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     31 
     32 #ifdef __cplusplus
     33 extern "C" {
     34 #endif
     35 
     36 #include <sys/types.h>
     37 #include <sys/ddi.h>
     38 #include <sys/sunddi.h>
     39 #include <sys/ioctl.h>
     40 #include <sys/processor.h>
     41 #include <sys/ontrap.h>
     42 
     43 /* Types */
     44 typedef uint64_t ldc_handle_t;		/* Channel handle */
     45 typedef uint64_t ldc_mem_handle_t;	/* Channel memory handle */
     46 typedef uint64_t ldc_dring_handle_t;	/* Descriptor ring handle */
     47 
     48 /* LDC transport mode */
     49 typedef enum {
     50 	LDC_MODE_RAW,			/* Raw mode */
     51 	LDC_MODE_UNRELIABLE,		/* Unreliable packet mode */
     52 	_LDC_MODE_RESERVED_,		/* reserved */
     53 	LDC_MODE_RELIABLE		/* Reliable packet mode */
     54 } ldc_mode_t;
     55 
     56 /* LDC message payload sizes */
     57 #define	LDC_ELEM_SIZE			8		/* size in bytes */
     58 #define	LDC_PACKET_SIZE			(LDC_ELEM_SIZE * 8)
     59 #define	LDC_PAYLOAD_SIZE_RAW		(LDC_PACKET_SIZE)
     60 #define	LDC_PAYLOAD_SIZE_UNRELIABLE	(LDC_PACKET_SIZE - LDC_ELEM_SIZE)
     61 #define	LDC_PAYLOAD_SIZE_RELIABLE	(LDC_PACKET_SIZE - (LDC_ELEM_SIZE * 2))
     62 
     63 /* LDC Channel Status */
     64 typedef enum {
     65 	LDC_INIT = 1,			/* Channel initialized */
     66 	LDC_OPEN,			/* Channel open */
     67 	LDC_READY,			/* Channel peer opened (hw-link-up) */
     68 	LDC_UP				/* Channel UP - ready for data xfer */
     69 } ldc_status_t;
     70 
     71 /* Callback return values */
     72 #define	LDC_SUCCESS	0
     73 #define	LDC_FAILURE	1
     74 
     75 /* LDC callback mode */
     76 typedef enum {
     77 	LDC_CB_ENABLE,			/* Enable callbacks */
     78 	LDC_CB_DISABLE			/* Disable callbacks */
     79 } ldc_cb_mode_t;
     80 
     81 /* Callback events */
     82 #define	LDC_EVT_DOWN		0x1	/* Channel DOWN, status = OPEN */
     83 #define	LDC_EVT_RESET		0x2	/* Channel RESET, status = READY */
     84 #define	LDC_EVT_UP		0x4	/* Channel UP, status = UP */
     85 #define	LDC_EVT_READ		0x8	/* Channel has data for read */
     86 #define	LDC_EVT_WRITE		0x10	/* Channel has space for write */
     87 
     88 /* LDC device classes */
     89 typedef enum {
     90 	LDC_DEV_GENERIC = 1,		/* generic device */
     91 	LDC_DEV_BLK,			/* block device, eg. vdc */
     92 	LDC_DEV_BLK_SVC,		/* block device service, eg. vds */
     93 	LDC_DEV_NT,			/* network device, eg. vnet */
     94 	LDC_DEV_NT_SVC,			/* network service eg. vsw */
     95 	LDC_DEV_SERIAL			/* serial device eg. vldc, vcc */
     96 } ldc_dev_t;
     97 
     98 /* Channel nexus registration */
     99 typedef struct ldc_cnex {
    100 	dev_info_t	*dip;		/* dip of channel nexus */
    101 	int		(*reg_chan)();	/* interface for channel register */
    102 	int		(*unreg_chan)(); /* interface for channel unregister */
    103 	int		(*add_intr)();	/* interface for adding interrupts */
    104 	int		(*rem_intr)();	/* interface for removing interrupts */
    105 	int		(*clr_intr)();	/* interface for clearing interrupts */
    106 } ldc_cnex_t;
    107 
    108 /* LDC attribute structure */
    109 typedef struct ldc_attr {
    110 	ldc_dev_t	devclass;	/* device class */
    111 	uint64_t	instance;	/* device class instance */
    112 	ldc_mode_t	mode;		/* channel mode */
    113 	uint64_t	mtu;		/* channel mtu */
    114 } ldc_attr_t;
    115 
    116 /* LDC memory cookie */
    117 typedef struct ldc_mem_cookie {
    118 	uint64_t	addr;		/* cookie address */
    119 	uint64_t	size;		/* size @ offset */
    120 } ldc_mem_cookie_t;
    121 
    122 /*
    123  * LDC Memory Map Type
    124  * Specifies how shared memory being created is shared with its
    125  * peer and/or how the peer has mapped in the exported memory.
    126  */
    127 #define	LDC_SHADOW_MAP		0x1	/* share mem via shadow copy only */
    128 #define	LDC_DIRECT_MAP		0x2	/* share mem direct access */
    129 #define	LDC_IO_MAP		0x4	/* share mem for IOMMU/DMA access */
    130 
    131 /* LDC Memory Access Permissions  */
    132 #define	LDC_MEM_R		0x1	/* Memory region is read only */
    133 #define	LDC_MEM_W		0x2	/* Memory region is write only */
    134 #define	LDC_MEM_X		0x4	/* Memory region is execute only */
    135 #define	LDC_MEM_RW		(LDC_MEM_R|LDC_MEM_W)
    136 #define	LDC_MEM_RWX		(LDC_MEM_R|LDC_MEM_W|LDC_MEM_X)
    137 
    138 /* LDC Memory Copy Direction */
    139 #define	LDC_COPY_IN		0x0	/* Copy data to VA from cookie mem */
    140 #define	LDC_COPY_OUT		0x1	/* Copy data from VA to cookie mem */
    141 
    142 /* LDC memory/dring (handle) status */
    143 typedef enum {
    144 	LDC_UNBOUND,			/* Memory handle is unbound */
    145 	LDC_BOUND,			/* Memory handle is bound */
    146 	LDC_MAPPED			/* Memory handle is mapped */
    147 } ldc_mstatus_t;
    148 
    149 /* LDC [dring] memory info */
    150 typedef struct ldc_mem_info {
    151 	uint8_t		mtype;		/* map type */
    152 	uint8_t		perm;		/* RWX permissions */
    153 	caddr_t		vaddr;		/* base VA */
    154 	uintptr_t	raddr;		/* base RA */
    155 	ldc_mstatus_t	status;		/* dring/mem handle status */
    156 } ldc_mem_info_t;
    157 
    158 /* API functions */
    159 int ldc_register(ldc_cnex_t *cinfo);
    160 int ldc_unregister(ldc_cnex_t *cinfo);
    161 
    162 int ldc_init(uint64_t id, ldc_attr_t *attr, ldc_handle_t *handle);
    163 int ldc_fini(ldc_handle_t handle);
    164 int ldc_open(ldc_handle_t handle);
    165 int ldc_close(ldc_handle_t handle);
    166 int ldc_up(ldc_handle_t handle);
    167 int ldc_down(ldc_handle_t handle);
    168 int ldc_reg_callback(ldc_handle_t handle,
    169     uint_t(*callback)(uint64_t event, caddr_t arg), caddr_t arg);
    170 int ldc_unreg_callback(ldc_handle_t handle);
    171 int ldc_set_cb_mode(ldc_handle_t handle, ldc_cb_mode_t imode);
    172 int ldc_chkq(ldc_handle_t handle, boolean_t *hasdata);
    173 int ldc_read(ldc_handle_t handle, caddr_t buf, size_t *size);
    174 int ldc_write(ldc_handle_t handle, caddr_t buf, size_t *size);
    175 int ldc_status(ldc_handle_t handle, ldc_status_t *status);
    176 
    177 int ldc_mem_alloc_handle(ldc_handle_t handle, ldc_mem_handle_t *mhandle);
    178 int ldc_mem_free_handle(ldc_mem_handle_t mhandle);
    179 int ldc_mem_bind_handle(ldc_mem_handle_t mhandle, caddr_t vaddr, size_t len,
    180     uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *cookie, uint32_t *ccount);
    181 int ldc_mem_unbind_handle(ldc_mem_handle_t mhandle);
    182 int ldc_mem_info(ldc_mem_handle_t mhandle, ldc_mem_info_t *minfo);
    183 int ldc_mem_nextcookie(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie);
    184 int ldc_mem_copy(ldc_handle_t handle, caddr_t vaddr, uint64_t off, size_t *len,
    185     ldc_mem_cookie_t *cookies, uint32_t ccount, uint8_t direction);
    186 int ldc_mem_rdwr_cookie(ldc_handle_t handle, caddr_t vaddr, size_t *size,
    187     caddr_t paddr, uint8_t  direction);
    188 int ldc_mem_map(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie,
    189     uint32_t ccount, uint8_t mtype, uint8_t perm, caddr_t *vaddr,
    190     caddr_t *raddr);
    191 int ldc_mem_unmap(ldc_mem_handle_t mhandle);
    192 int ldc_mem_acquire(ldc_mem_handle_t mhandle, uint64_t offset, uint64_t size);
    193 int ldc_mem_release(ldc_mem_handle_t mhandle, uint64_t offset, uint64_t size);
    194 
    195 int ldc_mem_dring_create(uint32_t len, uint32_t dsize,
    196     ldc_dring_handle_t *dhandle);
    197 int ldc_mem_dring_destroy(ldc_dring_handle_t dhandle);
    198 int ldc_mem_dring_bind(ldc_handle_t handle, ldc_dring_handle_t dhandle,
    199     uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *dcookie, uint32_t *ccount);
    200 int ldc_mem_dring_nextcookie(ldc_dring_handle_t mhandle,
    201     ldc_mem_cookie_t *cookie);
    202 int ldc_mem_dring_unbind(ldc_dring_handle_t dhandle);
    203 int ldc_mem_dring_info(ldc_dring_handle_t dhandle, ldc_mem_info_t *minfo);
    204 int ldc_mem_dring_map(ldc_handle_t handle, ldc_mem_cookie_t *cookie,
    205     uint32_t ccount, uint32_t len, uint32_t dsize, uint8_t mtype,
    206     ldc_dring_handle_t *dhandle);
    207 int ldc_mem_dring_unmap(ldc_dring_handle_t dhandle);
    208 int ldc_mem_dring_acquire(ldc_dring_handle_t dhandle, uint64_t start,
    209     uint64_t end);
    210 int ldc_mem_dring_release(ldc_dring_handle_t dhandle, uint64_t start,
    211     uint64_t end);
    212 
    213 /*
    214  * Shared Memory (Direct Map) Acquire and Release API
    215  *
    216  * LDC_MEM_BARRIER_OPEN and LDC_MEM_BARRIER_CLOSE provide on_trap
    217  * protection for clients accessing imported LDC_DIRECT_MAP'd shared
    218  * memory segments. Use of these macros is analogous to the
    219  * ldc_mem_acquire/release and ldc_mem_dring_acquire/release interfaces
    220  * for LDC_SHADOW_MAP'd segments. After LDC_MEM_BARRIER_OPEN is called,
    221  * unless an error is returned, LDC_MEM_BARRIER_CLOSE must be called.
    222  *
    223  * LDC_MEM_BARRIER_OPEN returns zero on success and EACCES if a data
    224  * access exception occurs after the OPEN call, but before the CLOSE
    225  * call. If EACCES is returned, the caller must not call
    226  * LDC_MEM_BARRIER_CLOSE. In order to handle the EACCES error return,
    227  * callers should take the same precautions that apply when calling
    228  * on_trap() when calling LDC_MEM_BARRIER_OPEN.
    229  *
    230  * LDC_MEM_BARRIER_OPEN is implemented as a macro so that on_trap
    231  * protection can be enabled without first executing a save instruction
    232  * and obtaining a new register window. Aside from LDC clients calling
    233  * on_trap() directly, one alternative approach is to implement the
    234  * OPEN function in assembly language without a save instruction and to
    235  * then call on_trap() as a tail call.
    236  */
    237 #define	LDC_MEM_BARRIER_OPEN(otd)					\
    238 	(on_trap((otd), OT_DATA_ACCESS) != 0 ?				\
    239 	(no_trap(), EACCES) : 0)
    240 
    241 #define	LDC_MEM_BARRIER_CLOSE()						\
    242 	(no_trap(), 0)
    243 
    244 #ifdef __cplusplus
    245 }
    246 #endif
    247 
    248 #endif /* _LDC_H */
    249