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 /* 23*7bd3a2e2SSriharsha Basavapatna * Copyright 2010 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 #ifdef __cplusplus 311ae08745Sheppo extern "C" { 321ae08745Sheppo #endif 331ae08745Sheppo 341ae08745Sheppo #include <sys/types.h> 351ae08745Sheppo #include <sys/ddi.h> 361ae08745Sheppo #include <sys/sunddi.h> 371ae08745Sheppo #include <sys/ioctl.h> 381ae08745Sheppo #include <sys/processor.h> 39bbfa0259Sha137994 #include <sys/ontrap.h> 401ae08745Sheppo 411ae08745Sheppo /* Types */ 421ae08745Sheppo typedef uint64_t ldc_handle_t; /* Channel handle */ 431ae08745Sheppo typedef uint64_t ldc_mem_handle_t; /* Channel memory handle */ 441ae08745Sheppo typedef uint64_t ldc_dring_handle_t; /* Descriptor ring handle */ 451ae08745Sheppo 461ae08745Sheppo /* LDC transport mode */ 471ae08745Sheppo typedef enum { 481ae08745Sheppo LDC_MODE_RAW, /* Raw mode */ 491ae08745Sheppo LDC_MODE_UNRELIABLE, /* Unreliable packet mode */ 5020ae46ebSha137994 _LDC_MODE_RESERVED_, /* reserved */ 5120ae46ebSha137994 LDC_MODE_RELIABLE /* Reliable packet mode */ 521ae08745Sheppo } ldc_mode_t; 531ae08745Sheppo 541ae08745Sheppo /* LDC message payload sizes */ 551ae08745Sheppo #define LDC_ELEM_SIZE 8 /* size in bytes */ 561ae08745Sheppo #define LDC_PACKET_SIZE (LDC_ELEM_SIZE * 8) 571ae08745Sheppo #define LDC_PAYLOAD_SIZE_RAW (LDC_PACKET_SIZE) 581ae08745Sheppo #define LDC_PAYLOAD_SIZE_UNRELIABLE (LDC_PACKET_SIZE - LDC_ELEM_SIZE) 591ae08745Sheppo #define LDC_PAYLOAD_SIZE_RELIABLE (LDC_PACKET_SIZE - (LDC_ELEM_SIZE * 2)) 601ae08745Sheppo 611ae08745Sheppo /* LDC Channel Status */ 621ae08745Sheppo typedef enum { 631ae08745Sheppo LDC_INIT = 1, /* Channel initialized */ 641ae08745Sheppo LDC_OPEN, /* Channel open */ 651ae08745Sheppo LDC_READY, /* Channel peer opened (hw-link-up) */ 661ae08745Sheppo LDC_UP /* Channel UP - ready for data xfer */ 671ae08745Sheppo } ldc_status_t; 681ae08745Sheppo 691ae08745Sheppo /* Callback return values */ 701ae08745Sheppo #define LDC_SUCCESS 0 711ae08745Sheppo #define LDC_FAILURE 1 721ae08745Sheppo 731ae08745Sheppo /* LDC callback mode */ 741ae08745Sheppo typedef enum { 751ae08745Sheppo LDC_CB_ENABLE, /* Enable callbacks */ 761ae08745Sheppo LDC_CB_DISABLE /* Disable callbacks */ 771ae08745Sheppo } ldc_cb_mode_t; 781ae08745Sheppo 791ae08745Sheppo /* Callback events */ 801ae08745Sheppo #define LDC_EVT_DOWN 0x1 /* Channel DOWN, status = OPEN */ 811ae08745Sheppo #define LDC_EVT_RESET 0x2 /* Channel RESET, status = READY */ 821ae08745Sheppo #define LDC_EVT_UP 0x4 /* Channel UP, status = UP */ 831ae08745Sheppo #define LDC_EVT_READ 0x8 /* Channel has data for read */ 841ae08745Sheppo #define LDC_EVT_WRITE 0x10 /* Channel has space for write */ 851ae08745Sheppo 861ae08745Sheppo /* LDC device classes */ 871ae08745Sheppo typedef enum { 881ae08745Sheppo LDC_DEV_GENERIC = 1, /* generic device */ 891ae08745Sheppo LDC_DEV_BLK, /* block device, eg. vdc */ 901ae08745Sheppo LDC_DEV_BLK_SVC, /* block device service, eg. vds */ 911ae08745Sheppo LDC_DEV_NT, /* network device, eg. vnet */ 921ae08745Sheppo LDC_DEV_NT_SVC, /* network service eg. vsw */ 931ae08745Sheppo LDC_DEV_SERIAL /* serial device eg. vldc, vcc */ 941ae08745Sheppo } ldc_dev_t; 951ae08745Sheppo 961ae08745Sheppo /* Channel nexus registration */ 971ae08745Sheppo typedef struct ldc_cnex { 981ae08745Sheppo dev_info_t *dip; /* dip of channel nexus */ 991ae08745Sheppo int (*reg_chan)(); /* interface for channel register */ 1001ae08745Sheppo int (*unreg_chan)(); /* interface for channel unregister */ 1011ae08745Sheppo int (*add_intr)(); /* interface for adding interrupts */ 1021ae08745Sheppo int (*rem_intr)(); /* interface for removing interrupts */ 1031ae08745Sheppo int (*clr_intr)(); /* interface for clearing interrupts */ 1041ae08745Sheppo } ldc_cnex_t; 1051ae08745Sheppo 1061ae08745Sheppo /* LDC attribute structure */ 1071ae08745Sheppo typedef struct ldc_attr { 1081ae08745Sheppo ldc_dev_t devclass; /* device class */ 1091ae08745Sheppo uint64_t instance; /* device class instance */ 1101ae08745Sheppo ldc_mode_t mode; /* channel mode */ 111e1ebb9ecSlm66018 uint64_t mtu; /* channel mtu */ 1121ae08745Sheppo } ldc_attr_t; 1131ae08745Sheppo 1141ae08745Sheppo /* LDC memory cookie */ 1151ae08745Sheppo typedef struct ldc_mem_cookie { 1161ae08745Sheppo uint64_t addr; /* cookie address */ 1171ae08745Sheppo uint64_t size; /* size @ offset */ 1181ae08745Sheppo } ldc_mem_cookie_t; 1191ae08745Sheppo 1201ae08745Sheppo /* 1211ae08745Sheppo * LDC Memory Map Type 1221ae08745Sheppo * Specifies how shared memory being created is shared with its 1231ae08745Sheppo * peer and/or how the peer has mapped in the exported memory. 1241ae08745Sheppo */ 1251ae08745Sheppo #define LDC_SHADOW_MAP 0x1 /* share mem via shadow copy only */ 1261ae08745Sheppo #define LDC_DIRECT_MAP 0x2 /* share mem direct access */ 1271ae08745Sheppo #define LDC_IO_MAP 0x4 /* share mem for IOMMU/DMA access */ 1281ae08745Sheppo 1291ae08745Sheppo /* LDC Memory Access Permissions */ 1301ae08745Sheppo #define LDC_MEM_R 0x1 /* Memory region is read only */ 1311ae08745Sheppo #define LDC_MEM_W 0x2 /* Memory region is write only */ 1321ae08745Sheppo #define LDC_MEM_X 0x4 /* Memory region is execute only */ 1331ae08745Sheppo #define LDC_MEM_RW (LDC_MEM_R|LDC_MEM_W) 1341ae08745Sheppo #define LDC_MEM_RWX (LDC_MEM_R|LDC_MEM_W|LDC_MEM_X) 1351ae08745Sheppo 1361ae08745Sheppo /* LDC Memory Copy Direction */ 1371ae08745Sheppo #define LDC_COPY_IN 0x0 /* Copy data to VA from cookie mem */ 1381ae08745Sheppo #define LDC_COPY_OUT 0x1 /* Copy data from VA to cookie mem */ 1391ae08745Sheppo 1401ae08745Sheppo /* LDC memory/dring (handle) status */ 1411ae08745Sheppo typedef enum { 1421ae08745Sheppo LDC_UNBOUND, /* Memory handle is unbound */ 1431ae08745Sheppo LDC_BOUND, /* Memory handle is bound */ 1441ae08745Sheppo LDC_MAPPED /* Memory handle is mapped */ 1451ae08745Sheppo } ldc_mstatus_t; 1461ae08745Sheppo 1471ae08745Sheppo /* LDC [dring] memory info */ 1481ae08745Sheppo typedef struct ldc_mem_info { 1491ae08745Sheppo uint8_t mtype; /* map type */ 1501ae08745Sheppo uint8_t perm; /* RWX permissions */ 1511ae08745Sheppo caddr_t vaddr; /* base VA */ 1521ae08745Sheppo uintptr_t raddr; /* base RA */ 1531ae08745Sheppo ldc_mstatus_t status; /* dring/mem handle status */ 1541ae08745Sheppo } ldc_mem_info_t; 1551ae08745Sheppo 1561ae08745Sheppo /* API functions */ 1571ae08745Sheppo int ldc_register(ldc_cnex_t *cinfo); 1581ae08745Sheppo int ldc_unregister(ldc_cnex_t *cinfo); 1591ae08745Sheppo 1601ae08745Sheppo int ldc_init(uint64_t id, ldc_attr_t *attr, ldc_handle_t *handle); 1611ae08745Sheppo int ldc_fini(ldc_handle_t handle); 1621ae08745Sheppo int ldc_open(ldc_handle_t handle); 1631ae08745Sheppo int ldc_close(ldc_handle_t handle); 1641ae08745Sheppo int ldc_up(ldc_handle_t handle); 165e1ebb9ecSlm66018 int ldc_down(ldc_handle_t handle); 1661ae08745Sheppo int ldc_reg_callback(ldc_handle_t handle, 1671ae08745Sheppo uint_t(*callback)(uint64_t event, caddr_t arg), caddr_t arg); 1681ae08745Sheppo int ldc_unreg_callback(ldc_handle_t handle); 1691ae08745Sheppo int ldc_set_cb_mode(ldc_handle_t handle, ldc_cb_mode_t imode); 170e1ebb9ecSlm66018 int ldc_chkq(ldc_handle_t handle, boolean_t *hasdata); 1711ae08745Sheppo int ldc_read(ldc_handle_t handle, caddr_t buf, size_t *size); 1721ae08745Sheppo int ldc_write(ldc_handle_t handle, caddr_t buf, size_t *size); 1731ae08745Sheppo int ldc_status(ldc_handle_t handle, ldc_status_t *status); 1741ae08745Sheppo 1751ae08745Sheppo int ldc_mem_alloc_handle(ldc_handle_t handle, ldc_mem_handle_t *mhandle); 1761ae08745Sheppo int ldc_mem_free_handle(ldc_mem_handle_t mhandle); 1771ae08745Sheppo int ldc_mem_bind_handle(ldc_mem_handle_t mhandle, caddr_t vaddr, size_t len, 1781ae08745Sheppo uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *cookie, uint32_t *ccount); 1791ae08745Sheppo int ldc_mem_unbind_handle(ldc_mem_handle_t mhandle); 1801ae08745Sheppo int ldc_mem_info(ldc_mem_handle_t mhandle, ldc_mem_info_t *minfo); 1811ae08745Sheppo int ldc_mem_nextcookie(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie); 1821ae08745Sheppo int ldc_mem_copy(ldc_handle_t handle, caddr_t vaddr, uint64_t off, size_t *len, 1831ae08745Sheppo ldc_mem_cookie_t *cookies, uint32_t ccount, uint8_t direction); 1843af08d82Slm66018 int ldc_mem_rdwr_cookie(ldc_handle_t handle, caddr_t vaddr, size_t *size, 1851ae08745Sheppo caddr_t paddr, uint8_t direction); 1861ae08745Sheppo int ldc_mem_map(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie, 1874bac2208Snarayan uint32_t ccount, uint8_t mtype, uint8_t perm, caddr_t *vaddr, 1884bac2208Snarayan caddr_t *raddr); 1894bac2208Snarayan int ldc_mem_unmap(ldc_mem_handle_t mhandle); 1901ae08745Sheppo int ldc_mem_acquire(ldc_mem_handle_t mhandle, uint64_t offset, uint64_t size); 1911ae08745Sheppo int ldc_mem_release(ldc_mem_handle_t mhandle, uint64_t offset, uint64_t size); 1921ae08745Sheppo 1931ae08745Sheppo int ldc_mem_dring_create(uint32_t len, uint32_t dsize, 1941ae08745Sheppo ldc_dring_handle_t *dhandle); 1951ae08745Sheppo int ldc_mem_dring_destroy(ldc_dring_handle_t dhandle); 1961ae08745Sheppo int ldc_mem_dring_bind(ldc_handle_t handle, ldc_dring_handle_t dhandle, 1971ae08745Sheppo uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *dcookie, uint32_t *ccount); 1981ae08745Sheppo int ldc_mem_dring_nextcookie(ldc_dring_handle_t mhandle, 1991ae08745Sheppo ldc_mem_cookie_t *cookie); 2001ae08745Sheppo int ldc_mem_dring_unbind(ldc_dring_handle_t dhandle); 2011ae08745Sheppo int ldc_mem_dring_info(ldc_dring_handle_t dhandle, ldc_mem_info_t *minfo); 2021ae08745Sheppo int ldc_mem_dring_map(ldc_handle_t handle, ldc_mem_cookie_t *cookie, 2031ae08745Sheppo uint32_t ccount, uint32_t len, uint32_t dsize, uint8_t mtype, 2041ae08745Sheppo ldc_dring_handle_t *dhandle); 2051ae08745Sheppo int ldc_mem_dring_unmap(ldc_dring_handle_t dhandle); 2061ae08745Sheppo int ldc_mem_dring_acquire(ldc_dring_handle_t dhandle, uint64_t start, 2071ae08745Sheppo uint64_t end); 2081ae08745Sheppo int ldc_mem_dring_release(ldc_dring_handle_t dhandle, uint64_t start, 2091ae08745Sheppo uint64_t end); 2101ae08745Sheppo 211bbfa0259Sha137994 /* 212bbfa0259Sha137994 * Shared Memory (Direct Map) Acquire and Release API 213bbfa0259Sha137994 * 214*7bd3a2e2SSriharsha Basavapatna * LDC_ON_TRAP and LDC_NO_TRAP provide on_trap protection for clients accessing 215*7bd3a2e2SSriharsha Basavapatna * imported LDC_DIRECT_MAP'd shared memory segments. Use of these macros is 216*7bd3a2e2SSriharsha Basavapatna * analogous to the ldc_mem_acquire/release and ldc_mem_dring_acquire/release 217*7bd3a2e2SSriharsha Basavapatna * interfaces for LDC_SHADOW_MAP'd segments. After LDC_ON_TRAP is called, 218*7bd3a2e2SSriharsha Basavapatna * unless an error is returned, LDC_NO_TRAP must be called. 219bbfa0259Sha137994 * 220*7bd3a2e2SSriharsha Basavapatna * LDC_ON_TRAP returns zero on success and EACCES if a data access exception 221*7bd3a2e2SSriharsha Basavapatna * occurs after enabling protection, but before it is disabled. If EACCES is 222*7bd3a2e2SSriharsha Basavapatna * returned, the caller must not call LDC_NO_TRAP. In order to handle the 223*7bd3a2e2SSriharsha Basavapatna * EACCES error return, callers should take the same precautions that apply 224*7bd3a2e2SSriharsha Basavapatna * when calling on_trap() when calling LDC_ON_TRAP. 225bbfa0259Sha137994 * 226*7bd3a2e2SSriharsha Basavapatna * LDC_ON_TRAP is implemented as a macro so that on_trap protection can be 227*7bd3a2e2SSriharsha Basavapatna * enabled without first executing a save instruction and obtaining a new 228*7bd3a2e2SSriharsha Basavapatna * register window. Aside from LDC clients calling on_trap() directly, one 229*7bd3a2e2SSriharsha Basavapatna * alternative approach is to implement the LDC_ON_TRAP function in assembly 230*7bd3a2e2SSriharsha Basavapatna * language without a save instruction and to then call on_trap() as a tail 231*7bd3a2e2SSriharsha Basavapatna * call. 232bbfa0259Sha137994 */ 233*7bd3a2e2SSriharsha Basavapatna #define LDC_ON_TRAP(otd) \ 234bbfa0259Sha137994 (on_trap((otd), OT_DATA_ACCESS) != 0 ? \ 235bbfa0259Sha137994 (no_trap(), EACCES) : 0) 236bbfa0259Sha137994 237*7bd3a2e2SSriharsha Basavapatna #define LDC_NO_TRAP() \ 238bbfa0259Sha137994 (no_trap(), 0) 239bbfa0259Sha137994 2401ae08745Sheppo #ifdef __cplusplus 2411ae08745Sheppo } 2421ae08745Sheppo #endif 2431ae08745Sheppo 2441ae08745Sheppo #endif /* _LDC_H */ 245