// Copyright(c) 2018-2020, Intel Corporation // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of Intel Corporation nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. #ifdef HAVE_CONFIG_H #include #endif // HAVE_CONFIG_H #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif // _GNU_SOURCE #include #include #include #include "pluginmgr.h" #include "opae_int.h" #include "props.h" opae_wrapped_token * opae_allocate_wrapped_token(fpga_token token, const opae_api_adapter_table *adapter) { opae_wrapped_token *wtok = (opae_wrapped_token *)malloc(sizeof(opae_wrapped_token)); if (wtok) { wtok->magic = OPAE_WRAPPED_TOKEN_MAGIC; wtok->opae_token = token; wtok->adapter_table = (opae_api_adapter_table *)adapter; } return wtok; } opae_wrapped_handle * opae_allocate_wrapped_handle(opae_wrapped_token *wt, fpga_handle opae_handle, opae_api_adapter_table *adapter) { opae_wrapped_handle *whan = (opae_wrapped_handle *)malloc(sizeof(opae_wrapped_handle)); if (whan) { whan->magic = OPAE_WRAPPED_HANDLE_MAGIC; whan->wrapped_token = wt; whan->opae_handle = opae_handle; whan->adapter_table = adapter; } return whan; } opae_wrapped_event_handle * opae_allocate_wrapped_event_handle(fpga_event_handle opae_event_handle, opae_api_adapter_table *adapter) { pthread_mutexattr_t mattr; opae_wrapped_event_handle *wevent = (opae_wrapped_event_handle *)malloc( sizeof(opae_wrapped_event_handle)); if (wevent) { if (pthread_mutexattr_init(&mattr)) { OPAE_ERR("pthread_mutexattr_init() failed"); goto out_free; } if (pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE)) { OPAE_ERR("pthread_mutexattr_settype() failed"); goto out_destroy; } if (pthread_mutex_init(&wevent->lock, &mattr)) { OPAE_ERR("pthread_mutex_init() failed"); goto out_destroy; } pthread_mutexattr_destroy(&mattr); wevent->magic = OPAE_WRAPPED_EVENT_HANDLE_MAGIC; wevent->flags = 0; wevent->opae_event_handle = opae_event_handle; wevent->adapter_table = adapter; } return wevent; out_destroy: pthread_mutexattr_destroy(&mattr); out_free: free(wevent); return NULL; } opae_wrapped_object * opae_allocate_wrapped_object(fpga_object opae_object, opae_api_adapter_table *adapter) { opae_wrapped_object *wobj = (opae_wrapped_object *)malloc(sizeof(opae_wrapped_object)); if (wobj) { wobj->magic = OPAE_WRAPPED_OBJECT_MAGIC; wobj->opae_object = opae_object; wobj->adapter_table = adapter; } return wobj; } fpga_result __OPAE_API__ fpgaInitialize(const char *config_file) { return opae_plugin_mgr_initialize(config_file) ? FPGA_EXCEPTION : FPGA_OK; } fpga_result __OPAE_API__ fpgaFinalize(void) { return opae_plugin_mgr_finalize_all() ? FPGA_EXCEPTION : FPGA_OK; } fpga_result __OPAE_API__ fpgaOpen(fpga_token token, fpga_handle *handle, int flags) { fpga_result res; fpga_result cres = FPGA_OK; opae_wrapped_token *wrapped_token; fpga_handle opae_handle = NULL; opae_wrapped_handle *wrapped_handle; wrapped_token = opae_validate_wrapped_token(token); ASSERT_NOT_NULL(wrapped_token); ASSERT_NOT_NULL(handle); ASSERT_NOT_NULL_RESULT(wrapped_token->adapter_table->fpgaOpen, FPGA_NOT_SUPPORTED); ASSERT_NOT_NULL_RESULT(wrapped_token->adapter_table->fpgaClose, FPGA_NOT_SUPPORTED); res = wrapped_token->adapter_table->fpgaOpen(wrapped_token->opae_token, &opae_handle, flags); ASSERT_RESULT(res); wrapped_handle = opae_allocate_wrapped_handle( wrapped_token, opae_handle, wrapped_token->adapter_table); if (!wrapped_handle) { OPAE_ERR("malloc failed"); res = FPGA_NO_MEMORY; cres = wrapped_token->adapter_table->fpgaClose(opae_handle); } *handle = wrapped_handle; return res != FPGA_OK ? res : cres; } fpga_result __OPAE_API__ fpgaClose(fpga_handle handle) { fpga_result res; opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaClose, FPGA_NOT_SUPPORTED); res = wrapped_handle->adapter_table->fpgaClose( wrapped_handle->opae_handle); opae_destroy_wrapped_handle(wrapped_handle); return res; } fpga_result __OPAE_API__ fpgaReset(fpga_handle handle) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaReset, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaReset( wrapped_handle->opae_handle); } fpga_result __OPAE_API__ fpgaGetPropertiesFromHandle(fpga_handle handle, fpga_properties *prop) { fpga_result res; opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); struct _fpga_properties *p; int err; ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(prop); ASSERT_NOT_NULL_RESULT( wrapped_handle->adapter_table->fpgaGetPropertiesFromHandle, FPGA_NOT_SUPPORTED); res = wrapped_handle->adapter_table->fpgaGetPropertiesFromHandle( wrapped_handle->opae_handle, prop); ASSERT_RESULT(res); // If the output properties has a parent token set, // then it will be a raw token. We need to wrap it. p = opae_validate_and_lock_properties(*prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_PARENT)) { opae_wrapped_token *wrapped_parent = opae_allocate_wrapped_token( p->parent, wrapped_handle->adapter_table); if (wrapped_parent) { p->parent = wrapped_parent; p->flags |= OPAE_PROPERTIES_FLAG_PARENT_ALLOC; } else { OPAE_ERR("malloc failed"); res = FPGA_NO_MEMORY; } } opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaGetProperties(fpga_token token, fpga_properties *prop) { fpga_result res = FPGA_OK; opae_wrapped_token *wrapped_token = opae_validate_wrapped_token(token); ASSERT_NOT_NULL(prop); if (!token) { fpga_properties pr; pr = opae_properties_create(); if (!pr) { OPAE_ERR("malloc failed"); return FPGA_NO_MEMORY; } *prop = pr; } else { struct _fpga_properties *p; int err; ASSERT_NOT_NULL(wrapped_token); ASSERT_NOT_NULL_RESULT( wrapped_token->adapter_table->fpgaGetProperties, FPGA_NOT_SUPPORTED); res = wrapped_token->adapter_table->fpgaGetProperties( wrapped_token->opae_token, prop); ASSERT_RESULT(res); // If the output properties has a parent token set, // then it will be a raw token. We need to wrap it. p = opae_validate_and_lock_properties(*prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_PARENT)) { opae_wrapped_token *wrapped_parent = opae_allocate_wrapped_token( p->parent, wrapped_token->adapter_table); if (wrapped_parent) { p->parent = wrapped_parent; p->flags |= OPAE_PROPERTIES_FLAG_PARENT_ALLOC; } else { OPAE_ERR("malloc failed"); res = FPGA_NO_MEMORY; } } opae_mutex_unlock(err, &p->lock); } return res; } fpga_result __OPAE_API__ fpgaUpdateProperties(fpga_token token, fpga_properties prop) { fpga_result res; struct _fpga_properties *p; int err; opae_wrapped_token *wrapped_token = opae_validate_wrapped_token(token); opae_wrapped_token *wrapped_parent = NULL; ASSERT_NOT_NULL(wrapped_token); ASSERT_NOT_NULL_RESULT( wrapped_token->adapter_table->fpgaUpdateProperties, FPGA_NOT_SUPPORTED); // If the input properties already has a parent token // set, then it will be wrapped. If we allocated the wrapper, // Save the wrapper, and reuse it below. p = opae_validate_and_lock_properties(prop); ASSERT_NOT_NULL(p); if (FIELD_VALID(p, FPGA_PROPERTY_PARENT) && (p->flags & OPAE_PROPERTIES_FLAG_PARENT_ALLOC)) { wrapped_parent = opae_validate_wrapped_token(p->parent); if (wrapped_parent) p->parent = wrapped_parent->opae_token; } res = wrapped_token->adapter_table->fpgaUpdateProperties( wrapped_token->opae_token, prop); if (res != FPGA_OK) { opae_mutex_unlock(err, &p->lock); return res; } // If the output properties has a parent token set, // then it will be a raw token. We need to wrap it. if (FIELD_VALID(p, FPGA_PROPERTY_PARENT)) { if (!wrapped_parent) { // We need to allocate a wrapper. wrapped_parent = opae_allocate_wrapped_token( p->parent, wrapped_token->adapter_table); if (wrapped_parent) { p->parent = wrapped_parent; p->flags |= OPAE_PROPERTIES_FLAG_PARENT_ALLOC; } else { OPAE_ERR("malloc failed"); res = FPGA_NO_MEMORY; } } else { // We are re-using the wrapper from above. wrapped_parent->opae_token = p->parent; wrapped_parent->adapter_table = wrapped_token->adapter_table; p->parent = wrapped_parent; p->flags |= OPAE_PROPERTIES_FLAG_PARENT_ALLOC; } } else if (wrapped_parent) opae_destroy_wrapped_token(wrapped_parent); opae_mutex_unlock(err, &p->lock); return res; } fpga_result __OPAE_API__ fpgaWriteMMIO64(fpga_handle handle, uint32_t mmio_num, uint64_t offset, uint64_t value) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaWriteMMIO64, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaWriteMMIO64( wrapped_handle->opae_handle, mmio_num, offset, value); } fpga_result __OPAE_API__ fpgaReadMMIO64(fpga_handle handle, uint32_t mmio_num, uint64_t offset, uint64_t *value) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaReadMMIO64, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaReadMMIO64( wrapped_handle->opae_handle, mmio_num, offset, value); } fpga_result __OPAE_API__ fpgaWriteMMIO32(fpga_handle handle, uint32_t mmio_num, uint64_t offset, uint32_t value) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaWriteMMIO32, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaWriteMMIO32( wrapped_handle->opae_handle, mmio_num, offset, value); } fpga_result __OPAE_API__ fpgaReadMMIO32(fpga_handle handle, uint32_t mmio_num, uint64_t offset, uint32_t *value) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaReadMMIO32, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaReadMMIO32( wrapped_handle->opae_handle, mmio_num, offset, value); } fpga_result __OPAE_API__ fpgaWriteMMIO512(fpga_handle handle, uint32_t mmio_num, uint64_t offset, void *value) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaWriteMMIO512, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaWriteMMIO512( wrapped_handle->opae_handle, mmio_num, offset, value); } fpga_result __OPAE_API__ fpgaMapMMIO(fpga_handle handle, uint32_t mmio_num, uint64_t **mmio_ptr) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaMapMMIO, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaMapMMIO( wrapped_handle->opae_handle, mmio_num, mmio_ptr); } fpga_result __OPAE_API__ fpgaUnmapMMIO(fpga_handle handle, uint32_t mmio_num) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaUnmapMMIO, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaUnmapMMIO( wrapped_handle->opae_handle, mmio_num); } typedef struct _opae_enumeration_context { // const fpga_properties *filters; uint32_t num_filters; fpga_token *wrapped_tokens; uint32_t max_wrapped_tokens; uint32_t *num_matches; // fpga_token *adapter_tokens; uint32_t num_wrapped_tokens; uint32_t errors; } opae_enumeration_context; static int opae_enumerate(const opae_api_adapter_table *adapter, void *context) { opae_enumeration_context *ctx = (opae_enumeration_context *)context; fpga_result res; uint32_t num_matches = 0; uint32_t i; uint32_t space_remaining; // TODO: accept/reject this adapter, based on device support if (adapter->supports_device) { } // TODO: accept/reject this adapter, based on host support if (adapter->supports_host) { } space_remaining = ctx->max_wrapped_tokens - ctx->num_wrapped_tokens; if (ctx->wrapped_tokens && !space_remaining) return OPAE_ENUM_STOP; if (!adapter->fpgaEnumerate) { OPAE_MSG("NULL fpgaEnumerate in adapter \"%s\"", adapter->plugin.path); return OPAE_ENUM_CONTINUE; } res = adapter->fpgaEnumerate(ctx->filters, ctx->num_filters, ctx->adapter_tokens, space_remaining, &num_matches); if (res != FPGA_OK) { OPAE_ERR("fpgaEnumerate() failed for \"%s\"", adapter->plugin.path); ++ctx->errors; return OPAE_ENUM_CONTINUE; } *ctx->num_matches += num_matches; if (!ctx->adapter_tokens) { // requesting token count, only. return OPAE_ENUM_CONTINUE; } if (space_remaining > num_matches) space_remaining = num_matches; for (i = 0; i < space_remaining; ++i) { opae_wrapped_token *wt = opae_allocate_wrapped_token( ctx->adapter_tokens[i], adapter); if (!wt) { ++ctx->errors; return OPAE_ENUM_STOP; } if (ctx->wrapped_tokens) { ctx->wrapped_tokens[ctx->num_wrapped_tokens++] = wt; } else { opae_destroy_wrapped_token(wt); } } return ctx->num_wrapped_tokens == ctx->max_wrapped_tokens ? OPAE_ENUM_STOP : OPAE_ENUM_CONTINUE; } fpga_result __OPAE_API__ fpgaEnumerate(const fpga_properties *filters, uint32_t num_filters, fpga_token *tokens, uint32_t max_tokens, uint32_t *num_matches) { fpga_result res = FPGA_EXCEPTION; fpga_token *adapter_tokens = NULL; opae_enumeration_context enum_context; typedef struct _parent_token_fixup { struct _parent_token_fixup *next; fpga_properties prop; opae_wrapped_token *wrapped_token; } parent_token_fixup; parent_token_fixup *ptf_list = NULL; uint32_t i; ASSERT_NOT_NULL(num_matches); if ((max_tokens > 0) && !tokens) { OPAE_ERR("max_tokens > 0 with NULL tokens"); return FPGA_INVALID_PARAM; } if ((num_filters > 0) && !filters) { OPAE_ERR("num_filters > 0 with NULL filters"); return FPGA_INVALID_PARAM; } if ((num_filters == 0) && (filters != NULL)) { OPAE_ERR("num_filters == 0 with non-NULL filters"); return FPGA_INVALID_PARAM; } *num_matches = 0; enum_context.filters = filters; enum_context.num_filters = num_filters; enum_context.wrapped_tokens = tokens; enum_context.max_wrapped_tokens = max_tokens; enum_context.num_matches = num_matches; if (tokens) { adapter_tokens = (fpga_token *)calloc(max_tokens, sizeof(fpga_token)); if (!adapter_tokens) { OPAE_ERR("out of memory"); return FPGA_NO_MEMORY; } } enum_context.adapter_tokens = adapter_tokens; enum_context.num_wrapped_tokens = 0; enum_context.errors = 0; // If any of the input filters has a parent token set, // then it will be wrapped. We need to unwrap it here, // then re-wrap below. for (i = 0; i < num_filters; ++i) { int err; struct _fpga_properties *p = opae_validate_and_lock_properties(filters[i]); if (!p) { OPAE_ERR("Invalid input filter"); res = FPGA_INVALID_PARAM; goto out_free_tokens; } if (FIELD_VALID(p, FPGA_PROPERTY_PARENT)) { parent_token_fixup *fixup; opae_wrapped_token *wrapped_parent = opae_validate_wrapped_token(p->parent); if (!wrapped_parent) { OPAE_ERR("Invalid wrapped parent in filter"); res = FPGA_INVALID_PARAM; opae_mutex_unlock(err, &p->lock); goto out_free_tokens; } fixup = (parent_token_fixup *)malloc( sizeof(parent_token_fixup)); if (!fixup) { OPAE_ERR("malloc failed"); res = FPGA_NO_MEMORY; opae_mutex_unlock(err, &p->lock); goto out_free_tokens; } fixup->next = NULL; fixup->prop = filters[i]; fixup->wrapped_token = wrapped_parent; if (!ptf_list) ptf_list = fixup; else { fixup->next = ptf_list; ptf_list = fixup; } // Set the unwrapped parent token. p->parent = wrapped_parent->opae_token; } opae_mutex_unlock(err, &p->lock); } // perform the enumeration. opae_plugin_mgr_for_each_adapter(opae_enumerate, &enum_context); res = (enum_context.errors > 0) ? FPGA_EXCEPTION : FPGA_OK; out_free_tokens: if (adapter_tokens) free(adapter_tokens); // Re-establish any wrapped parent tokens. while (ptf_list) { int err; parent_token_fixup *trash = ptf_list; struct _fpga_properties *p = opae_validate_and_lock_properties(trash->prop); ptf_list = ptf_list->next; if (p) { p->parent = trash->wrapped_token; opae_mutex_unlock(err, &p->lock); } free(trash); } return res; } fpga_result __OPAE_API__ fpgaCloneToken(fpga_token src, fpga_token *dst) { fpga_result res; fpga_result dres = FPGA_OK; fpga_token cloned_token = NULL; opae_wrapped_token *wrapped_dst_token; opae_wrapped_token *wrapped_src_token = opae_validate_wrapped_token(src); ASSERT_NOT_NULL(wrapped_src_token); ASSERT_NOT_NULL(dst); ASSERT_NOT_NULL_RESULT(wrapped_src_token->adapter_table->fpgaCloneToken, FPGA_NOT_SUPPORTED); ASSERT_NOT_NULL_RESULT( wrapped_src_token->adapter_table->fpgaDestroyToken, FPGA_NOT_SUPPORTED); res = wrapped_src_token->adapter_table->fpgaCloneToken( wrapped_src_token->opae_token, &cloned_token); ASSERT_RESULT(res); wrapped_dst_token = opae_allocate_wrapped_token( cloned_token, wrapped_src_token->adapter_table); if (!wrapped_dst_token) { OPAE_ERR("malloc failed"); res = FPGA_NO_MEMORY; dres = wrapped_src_token->adapter_table->fpgaDestroyToken( &cloned_token); } *dst = wrapped_dst_token; return res != FPGA_OK ? res : dres; } fpga_result __OPAE_API__ fpgaDestroyToken(fpga_token *token) { fpga_result res; opae_wrapped_token *wrapped_token; ASSERT_NOT_NULL(token); wrapped_token = opae_validate_wrapped_token(*token); ASSERT_NOT_NULL(wrapped_token); ASSERT_NOT_NULL_RESULT(wrapped_token->adapter_table->fpgaDestroyToken, FPGA_NOT_SUPPORTED); res = wrapped_token->adapter_table->fpgaDestroyToken( &wrapped_token->opae_token); opae_destroy_wrapped_token(wrapped_token); return res; } fpga_result __OPAE_API__ fpgaGetNumUmsg(fpga_handle handle, uint64_t *value) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(value); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaGetNumUmsg, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaGetNumUmsg( wrapped_handle->opae_handle, value); } fpga_result __OPAE_API__ fpgaSetUmsgAttributes(fpga_handle handle, uint64_t value) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT( wrapped_handle->adapter_table->fpgaSetUmsgAttributes, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaSetUmsgAttributes( wrapped_handle->opae_handle, value); } fpga_result __OPAE_API__ fpgaTriggerUmsg(fpga_handle handle, uint64_t value) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaTriggerUmsg, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaTriggerUmsg( wrapped_handle->opae_handle, value); } fpga_result __OPAE_API__ fpgaGetUmsgPtr(fpga_handle handle, uint64_t **umsg_ptr) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(umsg_ptr); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaGetUmsgPtr, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaGetUmsgPtr( wrapped_handle->opae_handle, umsg_ptr); } fpga_result __OPAE_API__ fpgaPrepareBuffer(fpga_handle handle, uint64_t len, void **buf_addr, uint64_t *wsid, int flags) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); // A special case: allow each plugin to respond FPGA_OK // when !buf_addr and !len as an indication that // FPGA_BUF_PREALLOCATED is supported by the plugin. if (!(flags & FPGA_BUF_PREALLOCATED) || (len > 0)) { // Assert only if not the special case described above. ASSERT_NOT_NULL(buf_addr); } ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(wsid); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaPrepareBuffer, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaPrepareBuffer( wrapped_handle->opae_handle, len, buf_addr, wsid, flags); } fpga_result __OPAE_API__ fpgaReleaseBuffer(fpga_handle handle, uint64_t wsid) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaReleaseBuffer, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaReleaseBuffer( wrapped_handle->opae_handle, wsid); } fpga_result __OPAE_API__ fpgaGetIOAddress(fpga_handle handle, uint64_t wsid, uint64_t *ioaddr) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(ioaddr); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaGetIOAddress, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaGetIOAddress( wrapped_handle->opae_handle, wsid, ioaddr); } fpga_result __OPAE_API__ fpgaGetOPAECVersion(fpga_version *version) { ASSERT_NOT_NULL(version); version->major = OPAE_VERSION_MAJOR; version->minor = OPAE_VERSION_MINOR; version->patch = OPAE_VERSION_REVISION; return FPGA_OK; } fpga_result __OPAE_API__ fpgaGetOPAECVersionString(char *version_str, size_t len) { ASSERT_NOT_NULL(version_str); if (len <= sizeof(OPAE_VERSION)) return FPGA_INVALID_PARAM; snprintf(version_str, len, "%s", OPAE_VERSION); return FPGA_OK; } fpga_result __OPAE_API__ fpgaGetOPAECBuildString(char *build_str, size_t len) { ASSERT_NOT_NULL(build_str); if (!len) return FPGA_INVALID_PARAM; snprintf(build_str, len, "%s%s", OPAE_GIT_COMMIT_HASH, OPAE_GIT_SRC_TREE_DIRTY ? "*" : ""); build_str[len - 1] = '\0'; return FPGA_OK; } fpga_result __OPAE_API__ fpgaReadError(fpga_token token, uint32_t error_num, uint64_t *value) { opae_wrapped_token *wrapped_token = opae_validate_wrapped_token(token); ASSERT_NOT_NULL(wrapped_token); ASSERT_NOT_NULL(value); ASSERT_NOT_NULL_RESULT(wrapped_token->adapter_table->fpgaReadError, FPGA_NOT_SUPPORTED); return wrapped_token->adapter_table->fpgaReadError( wrapped_token->opae_token, error_num, value); } fpga_result __OPAE_API__ fpgaClearError(fpga_token token, uint32_t error_num) { opae_wrapped_token *wrapped_token = opae_validate_wrapped_token(token); ASSERT_NOT_NULL(wrapped_token); ASSERT_NOT_NULL_RESULT(wrapped_token->adapter_table->fpgaClearError, FPGA_NOT_SUPPORTED); return wrapped_token->adapter_table->fpgaClearError( wrapped_token->opae_token, error_num); } fpga_result __OPAE_API__ fpgaClearAllErrors(fpga_token token) { opae_wrapped_token *wrapped_token = opae_validate_wrapped_token(token); ASSERT_NOT_NULL(wrapped_token); ASSERT_NOT_NULL_RESULT(wrapped_token->adapter_table->fpgaClearAllErrors, FPGA_NOT_SUPPORTED); return wrapped_token->adapter_table->fpgaClearAllErrors( wrapped_token->opae_token); } fpga_result __OPAE_API__ fpgaGetErrorInfo(fpga_token token, uint32_t error_num, struct fpga_error_info *error_info) { opae_wrapped_token *wrapped_token = opae_validate_wrapped_token(token); ASSERT_NOT_NULL(wrapped_token); ASSERT_NOT_NULL(error_info); ASSERT_NOT_NULL_RESULT(wrapped_token->adapter_table->fpgaGetErrorInfo, FPGA_NOT_SUPPORTED); return wrapped_token->adapter_table->fpgaGetErrorInfo( wrapped_token->opae_token, error_num, error_info); } const char * __OPAE_API__ fpgaErrStr(fpga_result e) { switch (e) { case FPGA_OK: return "success"; case FPGA_INVALID_PARAM: return "invalid parameter"; case FPGA_BUSY: return "resource busy"; case FPGA_EXCEPTION: return "exception"; case FPGA_NOT_FOUND: return "not found"; case FPGA_NO_MEMORY: return "no memory"; case FPGA_NOT_SUPPORTED: return "not supported"; case FPGA_NO_DRIVER: return "no driver available"; case FPGA_NO_DAEMON: return "no fpga daemon running"; case FPGA_NO_ACCESS: return "insufficient privileges"; case FPGA_RECONF_ERROR: return "reconfiguration error"; default: return "unknown error"; } } fpga_result __OPAE_API__ fpgaCreateEventHandle(fpga_event_handle *event_handle) { opae_wrapped_event_handle *wrapped_event_handle; ASSERT_NOT_NULL(event_handle); // We don't have an adapter table yet, so just create an empty object. wrapped_event_handle = opae_allocate_wrapped_event_handle(NULL, NULL); ASSERT_NOT_NULL_RESULT(wrapped_event_handle, FPGA_NO_MEMORY); *event_handle = wrapped_event_handle; return FPGA_OK; } fpga_result __OPAE_API__ fpgaDestroyEventHandle(fpga_event_handle *event_handle) { fpga_result res = FPGA_OK; opae_wrapped_event_handle *wrapped_event_handle; int ires; ASSERT_NOT_NULL(event_handle); wrapped_event_handle = opae_validate_wrapped_event_handle(*event_handle); ASSERT_NOT_NULL(wrapped_event_handle); opae_mutex_lock(ires, &wrapped_event_handle->lock); if (wrapped_event_handle->flags & OPAE_WRAPPED_EVENT_HANDLE_CREATED) { if (!wrapped_event_handle->adapter_table ->fpgaDestroyEventHandle) { OPAE_ERR("NULL fpgaDestroyEventHandle() in adapter."); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_NOT_SUPPORTED; } if (!wrapped_event_handle->opae_event_handle) { OPAE_ERR("NULL fpga_event_handle in wrapper."); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_INVALID_PARAM; } res = wrapped_event_handle->adapter_table ->fpgaDestroyEventHandle( &wrapped_event_handle->opae_event_handle); } opae_mutex_unlock(ires, &wrapped_event_handle->lock); opae_destroy_wrapped_event_handle(wrapped_event_handle); return res; } fpga_result __OPAE_API__ fpgaGetOSObjectFromEventHandle( const fpga_event_handle eh, int *fd) { fpga_result res; opae_wrapped_event_handle *wrapped_event_handle = opae_validate_wrapped_event_handle(eh); int ires; ASSERT_NOT_NULL(fd); ASSERT_NOT_NULL(wrapped_event_handle); opae_mutex_lock(ires, &wrapped_event_handle->lock); if (!(wrapped_event_handle->flags & OPAE_WRAPPED_EVENT_HANDLE_CREATED)) { OPAE_ERR( "Attempting to query OS event object before event handle is registered."); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_INVALID_PARAM; } if (!wrapped_event_handle->opae_event_handle) { OPAE_ERR("NULL fpga_event_handle in wrapper."); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_INVALID_PARAM; } if (!wrapped_event_handle->adapter_table ->fpgaGetOSObjectFromEventHandle) { OPAE_ERR("NULL fpgaGetOSObjectFromEventHandle in adapter."); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_NOT_SUPPORTED; } res = wrapped_event_handle->adapter_table ->fpgaGetOSObjectFromEventHandle( wrapped_event_handle->opae_event_handle, fd); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return res; } fpga_result __OPAE_API__ fpgaRegisterEvent(fpga_handle handle, fpga_event_type event_type, fpga_event_handle event_handle, uint32_t flags) { fpga_result res = FPGA_OK; opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); opae_wrapped_event_handle *wrapped_event_handle = opae_validate_wrapped_event_handle(event_handle); int ires; ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(wrapped_event_handle); opae_mutex_lock(ires, &wrapped_event_handle->lock); if (!(wrapped_event_handle->flags & OPAE_WRAPPED_EVENT_HANDLE_CREATED)) { // Now that we have an adapter table, store the adapter in // the wrapped_event_handle, and create the event handle. if (!wrapped_handle->adapter_table->fpgaCreateEventHandle) { OPAE_ERR("NULL fpgaCreateEventHandle() in adapter."); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_NOT_SUPPORTED; } res = wrapped_handle->adapter_table->fpgaCreateEventHandle( &wrapped_event_handle->opae_event_handle); if (res != FPGA_OK) { opae_mutex_unlock(ires, &wrapped_event_handle->lock); return res; } // The event_handle is now created. wrapped_event_handle->adapter_table = wrapped_handle->adapter_table; wrapped_event_handle->flags |= OPAE_WRAPPED_EVENT_HANDLE_CREATED; } if (!wrapped_event_handle->opae_event_handle) { OPAE_ERR("NULL fpga_event_handle"); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_INVALID_PARAM; } if (!wrapped_event_handle->adapter_table) { OPAE_ERR("NULL adapter table in wrapped event handle."); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_INVALID_PARAM; } if (!wrapped_event_handle->adapter_table->fpgaRegisterEvent) { OPAE_ERR("NULL fpgaRegisterEvent() in adapter."); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_NOT_SUPPORTED; } res = wrapped_event_handle->adapter_table->fpgaRegisterEvent( wrapped_handle->opae_handle, event_type, wrapped_event_handle->opae_event_handle, flags); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return res; } fpga_result __OPAE_API__ fpgaUnregisterEvent(fpga_handle handle, fpga_event_type event_type, fpga_event_handle event_handle) { fpga_result res; opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); opae_wrapped_event_handle *wrapped_event_handle = opae_validate_wrapped_event_handle(event_handle); int ires; ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(wrapped_event_handle); opae_mutex_lock(ires, &wrapped_event_handle->lock); if (!(wrapped_event_handle->flags & OPAE_WRAPPED_EVENT_HANDLE_CREATED)) { OPAE_ERR( "Attempting to unregister event object before registering it."); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_INVALID_PARAM; } if (!wrapped_event_handle->opae_event_handle) { OPAE_ERR("NULL fpga_event_handle in wrapper."); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_INVALID_PARAM; } if (!wrapped_event_handle->adapter_table->fpgaUnregisterEvent) { OPAE_ERR("NULL fpgaUnregisterEvent() in adapter."); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return FPGA_NOT_SUPPORTED; } res = wrapped_event_handle->adapter_table->fpgaUnregisterEvent( wrapped_handle->opae_handle, event_type, wrapped_event_handle->opae_event_handle); opae_mutex_unlock(ires, &wrapped_event_handle->lock); return res; } fpga_result __OPAE_API__ fpgaAssignPortToInterface(fpga_handle fpga, uint32_t interface_num, uint32_t slot_num, int flags) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(fpga); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT( wrapped_handle->adapter_table->fpgaAssignPortToInterface, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaAssignPortToInterface( wrapped_handle->opae_handle, interface_num, slot_num, flags); } fpga_result __OPAE_API__ fpgaAssignToInterface(fpga_handle fpga, fpga_token accelerator, uint32_t host_interface, int flags) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(fpga); opae_wrapped_token *wrapped_token = opae_validate_wrapped_token(accelerator); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(wrapped_token); ASSERT_NOT_NULL_RESULT( wrapped_handle->adapter_table->fpgaAssignToInterface, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaAssignToInterface( wrapped_handle->opae_handle, wrapped_token->opae_token, host_interface, flags); } fpga_result __OPAE_API__ fpgaReleaseFromInterface(fpga_handle fpga, fpga_token accelerator) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(fpga); opae_wrapped_token *wrapped_token = opae_validate_wrapped_token(accelerator); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(wrapped_token); ASSERT_NOT_NULL_RESULT( wrapped_handle->adapter_table->fpgaReleaseFromInterface, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaReleaseFromInterface( wrapped_handle->opae_handle, wrapped_token->opae_token); } fpga_result __OPAE_API__ fpgaReconfigureSlot(fpga_handle fpga, uint32_t slot, const uint8_t *bitstream, size_t bitstream_len, int flags) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(fpga); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(bitstream); ASSERT_NOT_NULL_RESULT( wrapped_handle->adapter_table->fpgaReconfigureSlot, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaReconfigureSlot( wrapped_handle->opae_handle, slot, bitstream, bitstream_len, flags); } fpga_result __OPAE_API__ fpgaTokenGetObject(fpga_token token, const char *name, fpga_object *object, int flags) { fpga_result res; fpga_result dres = FPGA_OK; fpga_object obj = NULL; opae_wrapped_object *wrapped_object; opae_wrapped_token *wrapped_token = opae_validate_wrapped_token(token); ASSERT_NOT_NULL(wrapped_token); ASSERT_NOT_NULL(name); ASSERT_NOT_NULL(object); ASSERT_NOT_NULL_RESULT(wrapped_token->adapter_table->fpgaTokenGetObject, FPGA_NOT_SUPPORTED); ASSERT_NOT_NULL_RESULT(wrapped_token->adapter_table->fpgaDestroyObject, FPGA_NOT_SUPPORTED); res = wrapped_token->adapter_table->fpgaTokenGetObject( wrapped_token->opae_token, name, &obj, flags); ASSERT_RESULT(res); wrapped_object = opae_allocate_wrapped_object(obj, wrapped_token->adapter_table); if (!wrapped_object) { OPAE_ERR("malloc failed"); res = FPGA_NO_MEMORY; dres = wrapped_token->adapter_table->fpgaDestroyObject(&obj); } *object = wrapped_object; return res != FPGA_OK ? res : dres; } fpga_result __OPAE_API__ fpgaHandleGetObject(fpga_handle handle, const char *name, fpga_object *object, int flags) { fpga_result res; fpga_result dres = FPGA_OK; fpga_object obj = NULL; opae_wrapped_object *wrapped_object; opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(name); ASSERT_NOT_NULL(object); ASSERT_NOT_NULL_RESULT( wrapped_handle->adapter_table->fpgaHandleGetObject, FPGA_NOT_SUPPORTED); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaDestroyObject, FPGA_NOT_SUPPORTED); res = wrapped_handle->adapter_table->fpgaHandleGetObject( wrapped_handle->opae_handle, name, &obj, flags); ASSERT_RESULT(res); wrapped_object = opae_allocate_wrapped_object( obj, wrapped_handle->adapter_table); if (!wrapped_object) { OPAE_ERR("malloc failed"); res = FPGA_NO_MEMORY; dres = wrapped_handle->adapter_table->fpgaDestroyObject(&obj); } *object = wrapped_object; return res != FPGA_OK ? res : dres; } fpga_result __OPAE_API__ fpgaObjectGetObjectAt(fpga_object parent, size_t index, fpga_object *object) { fpga_result res; fpga_result dres = FPGA_OK; fpga_object obj = NULL; opae_wrapped_object *wrapped_child_object; opae_wrapped_object *wrapped_object = opae_validate_wrapped_object(parent); ASSERT_NOT_NULL(wrapped_object); ASSERT_NOT_NULL(object); ASSERT_NOT_NULL_RESULT( wrapped_object->adapter_table->fpgaObjectGetObjectAt, FPGA_NOT_SUPPORTED); ASSERT_NOT_NULL_RESULT(wrapped_object->adapter_table->fpgaDestroyObject, FPGA_NOT_SUPPORTED); res = wrapped_object->adapter_table->fpgaObjectGetObjectAt( wrapped_object->opae_object, index, &obj); ASSERT_RESULT(res); wrapped_child_object = opae_allocate_wrapped_object( obj, wrapped_object->adapter_table); if (!wrapped_child_object) { OPAE_ERR("malloc failed"); res = FPGA_NO_MEMORY; dres = wrapped_object->adapter_table->fpgaDestroyObject(&obj); } *object = wrapped_child_object; return res != FPGA_OK ? res : dres; } fpga_result __OPAE_API__ fpgaObjectGetObject(fpga_object parent, const char *name, fpga_object *object, int flags) { fpga_result res; fpga_result dres = FPGA_OK; fpga_object obj = NULL; opae_wrapped_object *wrapped_child_object; opae_wrapped_object *wrapped_object = opae_validate_wrapped_object(parent); ASSERT_NOT_NULL(wrapped_object); ASSERT_NOT_NULL(name); ASSERT_NOT_NULL(object); ASSERT_NOT_NULL_RESULT( wrapped_object->adapter_table->fpgaObjectGetObject, FPGA_NOT_SUPPORTED); ASSERT_NOT_NULL_RESULT(wrapped_object->adapter_table->fpgaDestroyObject, FPGA_NOT_SUPPORTED); res = wrapped_object->adapter_table->fpgaObjectGetObject( wrapped_object->opae_object, name, &obj, flags); ASSERT_RESULT(res); wrapped_child_object = opae_allocate_wrapped_object( obj, wrapped_object->adapter_table); if (!wrapped_child_object) { OPAE_ERR("malloc failed"); res = FPGA_NO_MEMORY; dres = wrapped_object->adapter_table->fpgaDestroyObject(&obj); } *object = wrapped_child_object; return res != FPGA_OK ? res : dres; } fpga_result __OPAE_API__ fpgaDestroyObject(fpga_object *obj) { fpga_result res; opae_wrapped_object *wrapped_object; ASSERT_NOT_NULL(obj); wrapped_object = opae_validate_wrapped_object(*obj); ASSERT_NOT_NULL(wrapped_object); ASSERT_NOT_NULL_RESULT(wrapped_object->adapter_table->fpgaDestroyObject, FPGA_NOT_SUPPORTED); res = wrapped_object->adapter_table->fpgaDestroyObject( &wrapped_object->opae_object); opae_destroy_wrapped_object(wrapped_object); return res; } fpga_result __OPAE_API__ fpgaObjectRead(fpga_object obj, uint8_t *buffer, size_t offset, size_t len, int flags) { opae_wrapped_object *wrapped_object = opae_validate_wrapped_object(obj); ASSERT_NOT_NULL(wrapped_object); ASSERT_NOT_NULL(buffer); ASSERT_NOT_NULL_RESULT(wrapped_object->adapter_table->fpgaObjectRead, FPGA_NOT_SUPPORTED); return wrapped_object->adapter_table->fpgaObjectRead( wrapped_object->opae_object, buffer, offset, len, flags); } fpga_result __OPAE_API__ fpgaObjectGetSize(fpga_object obj, uint64_t *value, int flags) { opae_wrapped_object *wrapped_object = opae_validate_wrapped_object(obj); ASSERT_NOT_NULL(wrapped_object); ASSERT_NOT_NULL(value); ASSERT_NOT_NULL_RESULT(wrapped_object->adapter_table->fpgaObjectGetSize, FPGA_NOT_SUPPORTED); return wrapped_object->adapter_table->fpgaObjectGetSize( wrapped_object->opae_object, value, flags); } fpga_result __OPAE_API__ fpgaObjectGetType(fpga_object obj, enum fpga_sysobject_type *type) { opae_wrapped_object *wrapped_object = opae_validate_wrapped_object(obj); ASSERT_NOT_NULL(wrapped_object); ASSERT_NOT_NULL(type); ASSERT_NOT_NULL_RESULT(wrapped_object->adapter_table->fpgaObjectGetType, FPGA_NOT_SUPPORTED); return wrapped_object->adapter_table->fpgaObjectGetType( wrapped_object->opae_object, type); } fpga_result __OPAE_API__ fpgaObjectRead64(fpga_object obj, uint64_t *value, int flags) { opae_wrapped_object *wrapped_object = opae_validate_wrapped_object(obj); ASSERT_NOT_NULL(wrapped_object); ASSERT_NOT_NULL(value); ASSERT_NOT_NULL_RESULT(wrapped_object->adapter_table->fpgaObjectRead64, FPGA_NOT_SUPPORTED); return wrapped_object->adapter_table->fpgaObjectRead64( wrapped_object->opae_object, value, flags); } fpga_result __OPAE_API__ fpgaObjectWrite64(fpga_object obj, uint64_t value, int flags) { opae_wrapped_object *wrapped_object = opae_validate_wrapped_object(obj); ASSERT_NOT_NULL(wrapped_object); ASSERT_NOT_NULL_RESULT(wrapped_object->adapter_table->fpgaObjectWrite64, FPGA_NOT_SUPPORTED); return wrapped_object->adapter_table->fpgaObjectWrite64( wrapped_object->opae_object, value, flags); } fpga_result __OPAE_API__ fpgaSetUserClock(fpga_handle handle, uint64_t high_clk, uint64_t low_clk, int flags) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaSetUserClock, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaSetUserClock( wrapped_handle->opae_handle, high_clk, low_clk, flags); } fpga_result __OPAE_API__ fpgaGetUserClock(fpga_handle handle, uint64_t *high_clk, uint64_t *low_clk, int flags) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(low_clk); ASSERT_NOT_NULL(high_clk); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaGetUserClock, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaGetUserClock( wrapped_handle->opae_handle, high_clk, low_clk, flags); } fpga_result __OPAE_API__ fpgaGetNumMetrics(fpga_handle handle, uint64_t *num_metrics) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(num_metrics); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaGetNumMetrics, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaGetNumMetrics( wrapped_handle->opae_handle, num_metrics); } fpga_result __OPAE_API__ fpgaGetMetricsInfo(fpga_handle handle, fpga_metric_info *metric_info, uint64_t *num_metrics) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(metric_info); ASSERT_NOT_NULL(num_metrics); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaGetMetricsInfo, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaGetMetricsInfo( wrapped_handle->opae_handle, metric_info, num_metrics); } fpga_result __OPAE_API__ fpgaGetMetricsByIndex(fpga_handle handle, uint64_t *metric_num, uint64_t num_metric_indexes, fpga_metric *metrics) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(num_metric_indexes); ASSERT_NOT_NULL(metrics); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaGetMetricsByIndex, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaGetMetricsByIndex( wrapped_handle->opae_handle, metric_num, num_metric_indexes, metrics); } fpga_result __OPAE_API__ fpgaGetMetricsByName(fpga_handle handle, char **metrics_names, uint64_t num_metric_names, fpga_metric *metrics) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(metrics_names); ASSERT_NOT_NULL(metrics); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaGetMetricsByName, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaGetMetricsByName( wrapped_handle->opae_handle, metrics_names, num_metric_names, metrics); } fpga_result __OPAE_API__ fpgaGetMetricsThresholdInfo(fpga_handle handle, metric_threshold *metric_thresholds, uint32_t *num_thresholds) { opae_wrapped_handle *wrapped_handle = opae_validate_wrapped_handle(handle); ASSERT_NOT_NULL(wrapped_handle); ASSERT_NOT_NULL(num_thresholds); ASSERT_NOT_NULL_RESULT(wrapped_handle->adapter_table->fpgaGetMetricsThresholdInfo, FPGA_NOT_SUPPORTED); return wrapped_handle->adapter_table->fpgaGetMetricsThresholdInfo( wrapped_handle->opae_handle, metric_thresholds, num_thresholds); }