xref: /titanic_53/usr/src/uts/sun4v/sys/ldc.h (revision bbfa0259e68b6b625e9e085053d41d620f185eee)
11ae08745Sheppo /*
21ae08745Sheppo  * CDDL HEADER START
31ae08745Sheppo  *
41ae08745Sheppo  * The contents of this file are subject to the terms of the
51ae08745Sheppo  * Common Development and Distribution License (the "License").
61ae08745Sheppo  * You may not use this file except in compliance with the License.
71ae08745Sheppo  *
81ae08745Sheppo  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91ae08745Sheppo  * or http://www.opensolaris.org/os/licensing.
101ae08745Sheppo  * See the License for the specific language governing permissions
111ae08745Sheppo  * and limitations under the License.
121ae08745Sheppo  *
131ae08745Sheppo  * When distributing Covered Code, include this CDDL HEADER in each
141ae08745Sheppo  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151ae08745Sheppo  * If applicable, add the following below this CDDL HEADER, with the
161ae08745Sheppo  * fields enclosed by brackets "[]" replaced with your own identifying
171ae08745Sheppo  * information: Portions Copyright [yyyy] [name of copyright owner]
181ae08745Sheppo  *
191ae08745Sheppo  * CDDL HEADER END
201ae08745Sheppo  */
211ae08745Sheppo 
221ae08745Sheppo /*
2320ae46ebSha137994  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
241ae08745Sheppo  * Use is subject to license terms.
251ae08745Sheppo  */
261ae08745Sheppo 
271ae08745Sheppo #ifndef _LDC_H
281ae08745Sheppo #define	_LDC_H
291ae08745Sheppo 
301ae08745Sheppo #pragma ident	"%Z%%M%	%I%	%E% SMI"
311ae08745Sheppo 
321ae08745Sheppo #ifdef __cplusplus
331ae08745Sheppo extern "C" {
341ae08745Sheppo #endif
351ae08745Sheppo 
361ae08745Sheppo #include <sys/types.h>
371ae08745Sheppo #include <sys/ddi.h>
381ae08745Sheppo #include <sys/sunddi.h>
391ae08745Sheppo #include <sys/ioctl.h>
401ae08745Sheppo #include <sys/processor.h>
41*bbfa0259Sha137994 #include <sys/ontrap.h>
421ae08745Sheppo 
431ae08745Sheppo /* Types */
441ae08745Sheppo typedef uint64_t ldc_handle_t;		/* Channel handle */
451ae08745Sheppo typedef uint64_t ldc_mem_handle_t;	/* Channel memory handle */
461ae08745Sheppo typedef uint64_t ldc_dring_handle_t;	/* Descriptor ring handle */
471ae08745Sheppo 
481ae08745Sheppo /* LDC transport mode */
491ae08745Sheppo typedef enum {
501ae08745Sheppo 	LDC_MODE_RAW,			/* Raw mode */
511ae08745Sheppo 	LDC_MODE_UNRELIABLE,		/* Unreliable packet mode */
5220ae46ebSha137994 	_LDC_MODE_RESERVED_,		/* reserved */
5320ae46ebSha137994 	LDC_MODE_RELIABLE		/* Reliable packet mode */
541ae08745Sheppo } ldc_mode_t;
551ae08745Sheppo 
561ae08745Sheppo /* LDC message payload sizes */
571ae08745Sheppo #define	LDC_ELEM_SIZE			8		/* size in bytes */
581ae08745Sheppo #define	LDC_PACKET_SIZE			(LDC_ELEM_SIZE * 8)
591ae08745Sheppo #define	LDC_PAYLOAD_SIZE_RAW		(LDC_PACKET_SIZE)
601ae08745Sheppo #define	LDC_PAYLOAD_SIZE_UNRELIABLE	(LDC_PACKET_SIZE - LDC_ELEM_SIZE)
611ae08745Sheppo #define	LDC_PAYLOAD_SIZE_RELIABLE	(LDC_PACKET_SIZE - (LDC_ELEM_SIZE * 2))
621ae08745Sheppo 
631ae08745Sheppo /* LDC Channel Status */
641ae08745Sheppo typedef enum {
651ae08745Sheppo 	LDC_INIT = 1,			/* Channel initialized */
661ae08745Sheppo 	LDC_OPEN,			/* Channel open */
671ae08745Sheppo 	LDC_READY,			/* Channel peer opened (hw-link-up) */
681ae08745Sheppo 	LDC_UP				/* Channel UP - ready for data xfer */
691ae08745Sheppo } ldc_status_t;
701ae08745Sheppo 
711ae08745Sheppo /* Callback return values */
721ae08745Sheppo #define	LDC_SUCCESS	0
731ae08745Sheppo #define	LDC_FAILURE	1
741ae08745Sheppo 
751ae08745Sheppo /* LDC callback mode */
761ae08745Sheppo typedef enum {
771ae08745Sheppo 	LDC_CB_ENABLE,			/* Enable callbacks */
781ae08745Sheppo 	LDC_CB_DISABLE			/* Disable callbacks */
791ae08745Sheppo } ldc_cb_mode_t;
801ae08745Sheppo 
811ae08745Sheppo /* Callback events */
821ae08745Sheppo #define	LDC_EVT_DOWN		0x1	/* Channel DOWN, status = OPEN */
831ae08745Sheppo #define	LDC_EVT_RESET		0x2	/* Channel RESET, status = READY */
841ae08745Sheppo #define	LDC_EVT_UP		0x4	/* Channel UP, status = UP */
851ae08745Sheppo #define	LDC_EVT_READ		0x8	/* Channel has data for read */
861ae08745Sheppo #define	LDC_EVT_WRITE		0x10	/* Channel has space for write */
871ae08745Sheppo 
881ae08745Sheppo /* LDC device classes */
891ae08745Sheppo typedef enum {
901ae08745Sheppo 	LDC_DEV_GENERIC = 1,		/* generic device */
911ae08745Sheppo 	LDC_DEV_BLK,			/* block device, eg. vdc */
921ae08745Sheppo 	LDC_DEV_BLK_SVC,		/* block device service, eg. vds */
931ae08745Sheppo 	LDC_DEV_NT,			/* network device, eg. vnet */
941ae08745Sheppo 	LDC_DEV_NT_SVC,			/* network service eg. vsw */
951ae08745Sheppo 	LDC_DEV_SERIAL			/* serial device eg. vldc, vcc */
961ae08745Sheppo } ldc_dev_t;
971ae08745Sheppo 
981ae08745Sheppo /* Channel nexus registration */
991ae08745Sheppo typedef struct ldc_cnex {
1001ae08745Sheppo 	dev_info_t	*dip;		/* dip of channel nexus */
1011ae08745Sheppo 	int		(*reg_chan)();	/* interface for channel register */
1021ae08745Sheppo 	int		(*unreg_chan)(); /* interface for channel unregister */
1031ae08745Sheppo 	int		(*add_intr)();	/* interface for adding interrupts */
1041ae08745Sheppo 	int		(*rem_intr)();	/* interface for removing interrupts */
1051ae08745Sheppo 	int		(*clr_intr)();	/* interface for clearing interrupts */
1061ae08745Sheppo } ldc_cnex_t;
1071ae08745Sheppo 
1081ae08745Sheppo /* LDC attribute structure */
1091ae08745Sheppo typedef struct ldc_attr {
1101ae08745Sheppo 	ldc_dev_t	devclass;	/* device class */
1111ae08745Sheppo 	uint64_t	instance;	/* device class instance */
1121ae08745Sheppo 	ldc_mode_t	mode;		/* channel mode */
113e1ebb9ecSlm66018 	uint64_t	mtu;		/* channel mtu */
1141ae08745Sheppo } ldc_attr_t;
1151ae08745Sheppo 
1161ae08745Sheppo /* LDC memory cookie */
1171ae08745Sheppo typedef struct ldc_mem_cookie {
1181ae08745Sheppo 	uint64_t	addr;		/* cookie address */
1191ae08745Sheppo 	uint64_t	size;		/* size @ offset */
1201ae08745Sheppo } ldc_mem_cookie_t;
1211ae08745Sheppo 
1221ae08745Sheppo /*
1231ae08745Sheppo  * LDC Memory Map Type
1241ae08745Sheppo  * Specifies how shared memory being created is shared with its
1251ae08745Sheppo  * peer and/or how the peer has mapped in the exported memory.
1261ae08745Sheppo  */
1271ae08745Sheppo #define	LDC_SHADOW_MAP		0x1	/* share mem via shadow copy only */
1281ae08745Sheppo #define	LDC_DIRECT_MAP		0x2	/* share mem direct access */
1291ae08745Sheppo #define	LDC_IO_MAP		0x4	/* share mem for IOMMU/DMA access */
1301ae08745Sheppo 
1311ae08745Sheppo /* LDC Memory Access Permissions  */
1321ae08745Sheppo #define	LDC_MEM_R		0x1	/* Memory region is read only */
1331ae08745Sheppo #define	LDC_MEM_W		0x2	/* Memory region is write only */
1341ae08745Sheppo #define	LDC_MEM_X		0x4	/* Memory region is execute only */
1351ae08745Sheppo #define	LDC_MEM_RW		(LDC_MEM_R|LDC_MEM_W)
1361ae08745Sheppo #define	LDC_MEM_RWX		(LDC_MEM_R|LDC_MEM_W|LDC_MEM_X)
1371ae08745Sheppo 
1381ae08745Sheppo /* LDC Memory Copy Direction */
1391ae08745Sheppo #define	LDC_COPY_IN		0x0	/* Copy data to VA from cookie mem */
1401ae08745Sheppo #define	LDC_COPY_OUT		0x1	/* Copy data from VA to cookie mem */
1411ae08745Sheppo 
1421ae08745Sheppo /* LDC memory/dring (handle) status */
1431ae08745Sheppo typedef enum {
1441ae08745Sheppo 	LDC_UNBOUND,			/* Memory handle is unbound */
1451ae08745Sheppo 	LDC_BOUND,			/* Memory handle is bound */
1461ae08745Sheppo 	LDC_MAPPED			/* Memory handle is mapped */
1471ae08745Sheppo } ldc_mstatus_t;
1481ae08745Sheppo 
1491ae08745Sheppo /* LDC [dring] memory info */
1501ae08745Sheppo typedef struct ldc_mem_info {
1511ae08745Sheppo 	uint8_t		mtype;		/* map type */
1521ae08745Sheppo 	uint8_t		perm;		/* RWX permissions */
1531ae08745Sheppo 	caddr_t		vaddr;		/* base VA */
1541ae08745Sheppo 	uintptr_t	raddr;		/* base RA */
1551ae08745Sheppo 	ldc_mstatus_t	status;		/* dring/mem handle status */
1561ae08745Sheppo } ldc_mem_info_t;
1571ae08745Sheppo 
1581ae08745Sheppo /* API functions */
1591ae08745Sheppo int ldc_register(ldc_cnex_t *cinfo);
1601ae08745Sheppo int ldc_unregister(ldc_cnex_t *cinfo);
1611ae08745Sheppo 
1621ae08745Sheppo int ldc_init(uint64_t id, ldc_attr_t *attr, ldc_handle_t *handle);
1631ae08745Sheppo int ldc_fini(ldc_handle_t handle);
1641ae08745Sheppo int ldc_open(ldc_handle_t handle);
1651ae08745Sheppo int ldc_close(ldc_handle_t handle);
1661ae08745Sheppo int ldc_up(ldc_handle_t handle);
167e1ebb9ecSlm66018 int ldc_down(ldc_handle_t handle);
1681ae08745Sheppo int ldc_reg_callback(ldc_handle_t handle,
1691ae08745Sheppo     uint_t(*callback)(uint64_t event, caddr_t arg), caddr_t arg);
1701ae08745Sheppo int ldc_unreg_callback(ldc_handle_t handle);
1711ae08745Sheppo int ldc_set_cb_mode(ldc_handle_t handle, ldc_cb_mode_t imode);
172e1ebb9ecSlm66018 int ldc_chkq(ldc_handle_t handle, boolean_t *hasdata);
1731ae08745Sheppo int ldc_read(ldc_handle_t handle, caddr_t buf, size_t *size);
1741ae08745Sheppo int ldc_write(ldc_handle_t handle, caddr_t buf, size_t *size);
1751ae08745Sheppo int ldc_status(ldc_handle_t handle, ldc_status_t *status);
1761ae08745Sheppo 
1771ae08745Sheppo int ldc_mem_alloc_handle(ldc_handle_t handle, ldc_mem_handle_t *mhandle);
1781ae08745Sheppo int ldc_mem_free_handle(ldc_mem_handle_t mhandle);
1791ae08745Sheppo int ldc_mem_bind_handle(ldc_mem_handle_t mhandle, caddr_t vaddr, size_t len,
1801ae08745Sheppo     uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *cookie, uint32_t *ccount);
1811ae08745Sheppo int ldc_mem_unbind_handle(ldc_mem_handle_t mhandle);
1821ae08745Sheppo int ldc_mem_info(ldc_mem_handle_t mhandle, ldc_mem_info_t *minfo);
1831ae08745Sheppo int ldc_mem_nextcookie(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie);
1841ae08745Sheppo int ldc_mem_copy(ldc_handle_t handle, caddr_t vaddr, uint64_t off, size_t *len,
1851ae08745Sheppo     ldc_mem_cookie_t *cookies, uint32_t ccount, uint8_t direction);
1863af08d82Slm66018 int ldc_mem_rdwr_cookie(ldc_handle_t handle, caddr_t vaddr, size_t *size,
1871ae08745Sheppo     caddr_t paddr, uint8_t  direction);
1881ae08745Sheppo int ldc_mem_map(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie,
1894bac2208Snarayan     uint32_t ccount, uint8_t mtype, uint8_t perm, caddr_t *vaddr,
1904bac2208Snarayan     caddr_t *raddr);
1914bac2208Snarayan int ldc_mem_unmap(ldc_mem_handle_t mhandle);
1921ae08745Sheppo int ldc_mem_acquire(ldc_mem_handle_t mhandle, uint64_t offset, uint64_t size);
1931ae08745Sheppo int ldc_mem_release(ldc_mem_handle_t mhandle, uint64_t offset, uint64_t size);
1941ae08745Sheppo 
1951ae08745Sheppo int ldc_mem_dring_create(uint32_t len, uint32_t dsize,
1961ae08745Sheppo     ldc_dring_handle_t *dhandle);
1971ae08745Sheppo int ldc_mem_dring_destroy(ldc_dring_handle_t dhandle);
1981ae08745Sheppo int ldc_mem_dring_bind(ldc_handle_t handle, ldc_dring_handle_t dhandle,
1991ae08745Sheppo     uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *dcookie, uint32_t *ccount);
2001ae08745Sheppo int ldc_mem_dring_nextcookie(ldc_dring_handle_t mhandle,
2011ae08745Sheppo     ldc_mem_cookie_t *cookie);
2021ae08745Sheppo int ldc_mem_dring_unbind(ldc_dring_handle_t dhandle);
2031ae08745Sheppo int ldc_mem_dring_info(ldc_dring_handle_t dhandle, ldc_mem_info_t *minfo);
2041ae08745Sheppo int ldc_mem_dring_map(ldc_handle_t handle, ldc_mem_cookie_t *cookie,
2051ae08745Sheppo     uint32_t ccount, uint32_t len, uint32_t dsize, uint8_t mtype,
2061ae08745Sheppo     ldc_dring_handle_t *dhandle);
2071ae08745Sheppo int ldc_mem_dring_unmap(ldc_dring_handle_t dhandle);
2081ae08745Sheppo int ldc_mem_dring_acquire(ldc_dring_handle_t dhandle, uint64_t start,
2091ae08745Sheppo     uint64_t end);
2101ae08745Sheppo int ldc_mem_dring_release(ldc_dring_handle_t dhandle, uint64_t start,
2111ae08745Sheppo     uint64_t end);
2121ae08745Sheppo 
213*bbfa0259Sha137994 /*
214*bbfa0259Sha137994  * Shared Memory (Direct Map) Acquire and Release API
215*bbfa0259Sha137994  *
216*bbfa0259Sha137994  * LDC_MEM_BARRIER_OPEN and LDC_MEM_BARRIER_CLOSE provide on_trap
217*bbfa0259Sha137994  * protection for clients accessing imported LDC_DIRECT_MAP'd shared
218*bbfa0259Sha137994  * memory segments. Use of these macros is analogous to the
219*bbfa0259Sha137994  * ldc_mem_acquire/release and ldc_mem_dring_acquire/release interfaces
220*bbfa0259Sha137994  * for LDC_SHADOW_MAP'd segments. After LDC_MEM_BARRIER_OPEN is called,
221*bbfa0259Sha137994  * unless an error is returned, LDC_MEM_BARRIER_CLOSE must be called.
222*bbfa0259Sha137994  *
223*bbfa0259Sha137994  * LDC_MEM_BARRIER_OPEN returns zero on success and EACCES if a data
224*bbfa0259Sha137994  * access exception occurs after the OPEN call, but before the CLOSE
225*bbfa0259Sha137994  * call. If EACCES is returned, the caller must not call
226*bbfa0259Sha137994  * LDC_MEM_BARRIER_CLOSE. In order to handle the EACCES error return,
227*bbfa0259Sha137994  * callers should take the same precautions that apply when calling
228*bbfa0259Sha137994  * on_trap() when calling LDC_MEM_BARRIER_OPEN.
229*bbfa0259Sha137994  *
230*bbfa0259Sha137994  * LDC_MEM_BARRIER_OPEN is implemented as a macro so that on_trap
231*bbfa0259Sha137994  * protection can be enabled without first executing a save instruction
232*bbfa0259Sha137994  * and obtaining a new register window. Aside from LDC clients calling
233*bbfa0259Sha137994  * on_trap() directly, one alternative approach is to implement the
234*bbfa0259Sha137994  * OPEN function in assembly language without a save instruction and to
235*bbfa0259Sha137994  * then call on_trap() as a tail call.
236*bbfa0259Sha137994  */
237*bbfa0259Sha137994 #define	LDC_MEM_BARRIER_OPEN(otd)					\
238*bbfa0259Sha137994 	(on_trap((otd), OT_DATA_ACCESS) != 0 ?				\
239*bbfa0259Sha137994 	(no_trap(), EACCES) : 0)
240*bbfa0259Sha137994 
241*bbfa0259Sha137994 #define	LDC_MEM_BARRIER_CLOSE()						\
242*bbfa0259Sha137994 	(no_trap(), 0)
243*bbfa0259Sha137994 
2441ae08745Sheppo #ifdef __cplusplus
2451ae08745Sheppo }
2461ae08745Sheppo #endif
2471ae08745Sheppo 
2481ae08745Sheppo #endif /* _LDC_H */
249