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