/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _LDC_H #define _LDC_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include /* Types */ typedef uint64_t ldc_handle_t; /* Channel handle */ typedef uint64_t ldc_mem_handle_t; /* Channel memory handle */ typedef uint64_t ldc_dring_handle_t; /* Descriptor ring handle */ /* LDC transport mode */ typedef enum { LDC_MODE_RAW, /* Raw mode */ LDC_MODE_UNRELIABLE, /* Unreliable packet mode */ _LDC_MODE_RESERVED_, /* reserved */ LDC_MODE_RELIABLE /* Reliable packet mode */ } ldc_mode_t; /* LDC message payload sizes */ #define LDC_ELEM_SIZE 8 /* size in bytes */ #define LDC_PACKET_SIZE (LDC_ELEM_SIZE * 8) #define LDC_PAYLOAD_SIZE_RAW (LDC_PACKET_SIZE) #define LDC_PAYLOAD_SIZE_UNRELIABLE (LDC_PACKET_SIZE - LDC_ELEM_SIZE) #define LDC_PAYLOAD_SIZE_RELIABLE (LDC_PACKET_SIZE - (LDC_ELEM_SIZE * 2)) /* LDC Channel Status */ typedef enum { LDC_INIT = 1, /* Channel initialized */ LDC_OPEN, /* Channel open */ LDC_READY, /* Channel peer opened (hw-link-up) */ LDC_UP /* Channel UP - ready for data xfer */ } ldc_status_t; /* Callback return values */ #define LDC_SUCCESS 0 #define LDC_FAILURE 1 /* LDC callback mode */ typedef enum { LDC_CB_ENABLE, /* Enable callbacks */ LDC_CB_DISABLE /* Disable callbacks */ } ldc_cb_mode_t; /* Callback events */ #define LDC_EVT_DOWN 0x1 /* Channel DOWN, status = OPEN */ #define LDC_EVT_RESET 0x2 /* Channel RESET, status = READY */ #define LDC_EVT_UP 0x4 /* Channel UP, status = UP */ #define LDC_EVT_READ 0x8 /* Channel has data for read */ #define LDC_EVT_WRITE 0x10 /* Channel has space for write */ /* LDC device classes */ typedef enum { LDC_DEV_GENERIC = 1, /* generic device */ LDC_DEV_BLK, /* block device, eg. vdc */ LDC_DEV_BLK_SVC, /* block device service, eg. vds */ LDC_DEV_NT, /* network device, eg. vnet */ LDC_DEV_NT_SVC, /* network service eg. vsw */ LDC_DEV_SERIAL /* serial device eg. vldc, vcc */ } ldc_dev_t; /* Channel nexus registration */ typedef struct ldc_cnex { dev_info_t *dip; /* dip of channel nexus */ int (*reg_chan)(); /* interface for channel register */ int (*unreg_chan)(); /* interface for channel unregister */ int (*add_intr)(); /* interface for adding interrupts */ int (*rem_intr)(); /* interface for removing interrupts */ int (*clr_intr)(); /* interface for clearing interrupts */ } ldc_cnex_t; /* LDC attribute structure */ typedef struct ldc_attr { ldc_dev_t devclass; /* device class */ uint64_t instance; /* device class instance */ ldc_mode_t mode; /* channel mode */ uint64_t mtu; /* channel mtu */ } ldc_attr_t; /* LDC memory cookie */ typedef struct ldc_mem_cookie { uint64_t addr; /* cookie address */ uint64_t size; /* size @ offset */ } ldc_mem_cookie_t; /* * LDC Memory Map Type * Specifies how shared memory being created is shared with its * peer and/or how the peer has mapped in the exported memory. */ #define LDC_SHADOW_MAP 0x1 /* share mem via shadow copy only */ #define LDC_DIRECT_MAP 0x2 /* share mem direct access */ #define LDC_IO_MAP 0x4 /* share mem for IOMMU/DMA access */ /* * Default mapin size supported with legacy f/w. */ #define LDC_DIRECT_MAP_SIZE_DEFAULT (64 * 1024 * 1024) /* LDC Memory Access Permissions */ #define LDC_MEM_R 0x1 /* Memory region is read only */ #define LDC_MEM_W 0x2 /* Memory region is write only */ #define LDC_MEM_X 0x4 /* Memory region is execute only */ #define LDC_MEM_RW (LDC_MEM_R|LDC_MEM_W) #define LDC_MEM_RWX (LDC_MEM_R|LDC_MEM_W|LDC_MEM_X) /* LDC Memory Copy Direction */ #define LDC_COPY_IN 0x0 /* Copy data to VA from cookie mem */ #define LDC_COPY_OUT 0x1 /* Copy data from VA to cookie mem */ /* LDC memory/dring (handle) status */ typedef enum { LDC_UNBOUND, /* Memory handle is unbound */ LDC_BOUND, /* Memory handle is bound */ LDC_MAPPED /* Memory handle is mapped */ } ldc_mstatus_t; /* LDC [dring] memory info */ typedef struct ldc_mem_info { uint8_t mtype; /* map type */ uint8_t perm; /* RWX permissions */ caddr_t vaddr; /* base VA */ uintptr_t raddr; /* base RA */ ldc_mstatus_t status; /* dring/mem handle status */ } ldc_mem_info_t; /* LDC channel info */ typedef struct ldc_info { uint64_t direct_map_size_max; /* Max direct mapin space size */ } ldc_info_t; /* API functions */ int ldc_register(ldc_cnex_t *cinfo); int ldc_unregister(ldc_cnex_t *cinfo); int ldc_init(uint64_t id, ldc_attr_t *attr, ldc_handle_t *handle); int ldc_fini(ldc_handle_t handle); int ldc_open(ldc_handle_t handle); int ldc_close(ldc_handle_t handle); int ldc_up(ldc_handle_t handle); int ldc_down(ldc_handle_t handle); int ldc_reg_callback(ldc_handle_t handle, uint_t(*callback)(uint64_t event, caddr_t arg), caddr_t arg); int ldc_unreg_callback(ldc_handle_t handle); int ldc_set_cb_mode(ldc_handle_t handle, ldc_cb_mode_t imode); int ldc_chkq(ldc_handle_t handle, boolean_t *hasdata); int ldc_read(ldc_handle_t handle, caddr_t buf, size_t *size); int ldc_write(ldc_handle_t handle, caddr_t buf, size_t *size); int ldc_status(ldc_handle_t handle, ldc_status_t *status); int ldc_mem_alloc_handle(ldc_handle_t handle, ldc_mem_handle_t *mhandle); int ldc_mem_free_handle(ldc_mem_handle_t mhandle); int ldc_mem_bind_handle(ldc_mem_handle_t mhandle, caddr_t vaddr, size_t len, uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *cookie, uint32_t *ccount); int ldc_mem_unbind_handle(ldc_mem_handle_t mhandle); int ldc_mem_info(ldc_mem_handle_t mhandle, ldc_mem_info_t *minfo); int ldc_mem_nextcookie(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie); int ldc_mem_copy(ldc_handle_t handle, caddr_t vaddr, uint64_t off, size_t *len, ldc_mem_cookie_t *cookies, uint32_t ccount, uint8_t direction); int ldc_mem_rdwr_cookie(ldc_handle_t handle, caddr_t vaddr, size_t *size, caddr_t paddr, uint8_t direction); int ldc_mem_map(ldc_mem_handle_t mhandle, ldc_mem_cookie_t *cookie, uint32_t ccount, uint8_t mtype, uint8_t perm, caddr_t *vaddr, caddr_t *raddr); int ldc_mem_unmap(ldc_mem_handle_t mhandle); int ldc_mem_acquire(ldc_mem_handle_t mhandle, uint64_t offset, uint64_t size); int ldc_mem_release(ldc_mem_handle_t mhandle, uint64_t offset, uint64_t size); int ldc_mem_dring_create(uint32_t len, uint32_t dsize, ldc_dring_handle_t *dhandle); int ldc_mem_dring_destroy(ldc_dring_handle_t dhandle); int ldc_mem_dring_bind(ldc_handle_t handle, ldc_dring_handle_t dhandle, uint8_t mtype, uint8_t perm, ldc_mem_cookie_t *dcookie, uint32_t *ccount); int ldc_mem_dring_nextcookie(ldc_dring_handle_t mhandle, ldc_mem_cookie_t *cookie); int ldc_mem_dring_unbind(ldc_dring_handle_t dhandle); int ldc_mem_dring_info(ldc_dring_handle_t dhandle, ldc_mem_info_t *minfo); int ldc_mem_dring_map(ldc_handle_t handle, ldc_mem_cookie_t *cookie, uint32_t ccount, uint32_t len, uint32_t dsize, uint8_t mtype, ldc_dring_handle_t *dhandle); int ldc_mem_dring_unmap(ldc_dring_handle_t dhandle); int ldc_mem_dring_acquire(ldc_dring_handle_t dhandle, uint64_t start, uint64_t end); int ldc_mem_dring_release(ldc_dring_handle_t dhandle, uint64_t start, uint64_t end); int ldc_info(ldc_handle_t handle, ldc_info_t *info); /* * Shared Memory (Direct Map) Acquire and Release API * * LDC_ON_TRAP and LDC_NO_TRAP provide on_trap protection for clients accessing * imported LDC_DIRECT_MAP'd shared memory segments. Use of these macros is * analogous to the ldc_mem_acquire/release and ldc_mem_dring_acquire/release * interfaces for LDC_SHADOW_MAP'd segments. After LDC_ON_TRAP is called, * unless an error is returned, LDC_NO_TRAP must be called. * * LDC_ON_TRAP returns zero on success and EACCES if a data access exception * occurs after enabling protection, but before it is disabled. If EACCES is * returned, the caller must not call LDC_NO_TRAP. In order to handle the * EACCES error return, callers should take the same precautions that apply * when calling on_trap() when calling LDC_ON_TRAP. * * LDC_ON_TRAP is implemented as a macro so that on_trap protection can be * enabled without first executing a save instruction and obtaining a new * register window. Aside from LDC clients calling on_trap() directly, one * alternative approach is to implement the LDC_ON_TRAP function in assembly * language without a save instruction and to then call on_trap() as a tail * call. */ #define LDC_ON_TRAP(otd) \ (on_trap((otd), OT_DATA_ACCESS) != 0 ? \ (no_trap(), EACCES) : 0) #define LDC_NO_TRAP() \ (no_trap(), 0) #ifdef __cplusplus } #endif #endif /* _LDC_H */