|  | /* | 
|  | Copyright (c) 2014-2016 Intel Corporation.  All Rights Reserved. | 
|  |  | 
|  | 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 | 
|  | HOLDER 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. | 
|  | */ | 
|  |  | 
|  |  | 
|  | // The COI host interface | 
|  |  | 
|  | #include "coi_client.h" | 
|  | #include "../offload_common.h" | 
|  |  | 
|  | namespace COI { | 
|  |  | 
|  | #define COI_VERSION1    "COI_1.0" | 
|  | #define COI_VERSION2    "COI_2.0" | 
|  |  | 
|  | bool            is_available; | 
|  | static void*    lib_handle; | 
|  |  | 
|  | // pointers to functions from COI library | 
|  | COIRESULT (*EngineGetCount)(COI_ISA_TYPE, uint32_t*); | 
|  | COIRESULT (*EngineGetHandle)(COI_ISA_TYPE, uint32_t, COIENGINE*); | 
|  |  | 
|  | COIRESULT (*ProcessCreateFromMemory)(COIENGINE, const char*, const void*, | 
|  | uint64_t, int, const char**, uint8_t, | 
|  | const char**, uint8_t, const char*, | 
|  | uint64_t, const char*, const char*, | 
|  | uint64_t, COIPROCESS*); | 
|  | COIRESULT (*ProcessCreateFromFile)(COIENGINE, const char*, | 
|  | int, const char**, uint8_t, | 
|  | const char**, uint8_t, const char*, | 
|  | uint64_t, const char*,COIPROCESS*); | 
|  | COIRESULT (*ProcessSetCacheSize)(COIPROCESS, uint64_t, uint32_t, | 
|  | uint64_t, uint32_t, uint32_t, | 
|  | const COIEVENT*, COIEVENT*); | 
|  | COIRESULT (*ProcessDestroy)(COIPROCESS, int32_t, uint8_t, int8_t*, uint32_t*); | 
|  | COIRESULT (*ProcessGetFunctionHandles)(COIPROCESS, uint32_t, const char**, | 
|  | COIFUNCTION*); | 
|  | COIRESULT (*ProcessLoadLibraryFromMemory)(COIPROCESS, const void*, uint64_t, | 
|  | const char*, const char*, | 
|  | const char*, uint64_t, uint32_t, | 
|  | COILIBRARY*); | 
|  | COIRESULT (*ProcessUnloadLibrary)(COIPROCESS, | 
|  | COILIBRARY); | 
|  | COIRESULT (*ProcessRegisterLibraries)(uint32_t, const void**, const uint64_t*, | 
|  | const char**, const uint64_t*); | 
|  |  | 
|  | COIRESULT (*PipelineCreate)(COIPROCESS, COI_CPU_MASK, uint32_t, COIPIPELINE*); | 
|  | COIRESULT (*PipelineDestroy)(COIPIPELINE); | 
|  | COIRESULT (*PipelineRunFunction)(COIPIPELINE, COIFUNCTION, uint32_t, | 
|  | const COIBUFFER*, const COI_ACCESS_FLAGS*, | 
|  | uint32_t, const COIEVENT*, const void*, | 
|  | uint16_t, void*, uint16_t, COIEVENT*); | 
|  |  | 
|  | COIRESULT (*BufferCreate)(uint64_t, COI_BUFFER_TYPE, uint32_t, const void*, | 
|  | uint32_t, const COIPROCESS*, COIBUFFER*); | 
|  | COIRESULT (*BufferCreateFromMemory)(uint64_t, COI_BUFFER_TYPE, uint32_t, | 
|  | void*, uint32_t, const COIPROCESS*, | 
|  | COIBUFFER*); | 
|  | COIRESULT (*BufferDestroy)(COIBUFFER); | 
|  | COIRESULT (*BufferMap)(COIBUFFER, uint64_t, uint64_t, COI_MAP_TYPE, uint32_t, | 
|  | const COIEVENT*, COIEVENT*, COIMAPINSTANCE*, void**); | 
|  | COIRESULT (*BufferUnmap)(COIMAPINSTANCE, uint32_t, const COIEVENT*, COIEVENT*); | 
|  | COIRESULT (*BufferWrite)(COIBUFFER, uint64_t, const void*, uint64_t, | 
|  | COI_COPY_TYPE, uint32_t, const COIEVENT*, COIEVENT*); | 
|  | COIRESULT (*BufferRead)(COIBUFFER, uint64_t, void*, uint64_t, COI_COPY_TYPE, | 
|  | uint32_t, const COIEVENT*, COIEVENT*); | 
|  | COIRESULT (*BufferReadMultiD)(COIBUFFER, uint64_t, | 
|  | void *, void *, COI_COPY_TYPE, | 
|  | uint32_t, const   COIEVENT*, COIEVENT*); | 
|  | COIRESULT (*BufferWriteMultiD)(COIBUFFER, const   COIPROCESS, | 
|  | uint64_t, void *, void *, | 
|  | COI_COPY_TYPE, uint32_t, const   COIEVENT*, COIEVENT*); | 
|  |  | 
|  | COIRESULT (*BufferCopy)(COIBUFFER, COIBUFFER, uint64_t, uint64_t, uint64_t, | 
|  | COI_COPY_TYPE, uint32_t, const COIEVENT*, COIEVENT*); | 
|  | COIRESULT (*BufferGetSinkAddress)(COIBUFFER, uint64_t*); | 
|  | COIRESULT (*BufferSetState)(COIBUFFER, COIPROCESS, COI_BUFFER_STATE, | 
|  | COI_BUFFER_MOVE_FLAG, uint32_t, | 
|  | const   COIEVENT*, COIEVENT*); | 
|  |  | 
|  | COIRESULT (*EventWait)(uint16_t, const COIEVENT*, int32_t, uint8_t, uint32_t*, | 
|  | uint32_t*); | 
|  |  | 
|  | uint64_t  (*PerfGetCycleFrequency)(void); | 
|  |  | 
|  | COIRESULT (*PipelineClearCPUMask) (COI_CPU_MASK); | 
|  |  | 
|  | COIRESULT (*PipelineSetCPUMask) (COIPROCESS, uint32_t, | 
|  | uint8_t, COI_CPU_MASK); | 
|  | COIRESULT (*EngineGetInfo)(COIENGINE, uint32_t, COI_ENGINE_INFO*); | 
|  |  | 
|  | COIRESULT (*EventRegisterCallback)( | 
|  | const COIEVENT, | 
|  | void (*)(COIEVENT, const COIRESULT, const void*), | 
|  | const void*, | 
|  | const uint64_t); | 
|  |  | 
|  | COIRESULT (*ProcessConfigureDMA)(const uint64_t, const int); | 
|  |  | 
|  | bool init(void) | 
|  | { | 
|  | #ifndef TARGET_WINNT | 
|  | const char *lib_name = "libcoi_host.so.0"; | 
|  | #else // TARGET_WINNT | 
|  | const char *lib_name = "coi_host.dll"; | 
|  | #endif // TARGET_WINNT | 
|  |  | 
|  | OFFLOAD_DEBUG_TRACE(2, "Loading COI library %s ...\n", lib_name); | 
|  | lib_handle = DL_open(lib_name); | 
|  | if (lib_handle == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to load the library\n"); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | EngineGetCount = | 
|  | (COIRESULT (*)(COI_ISA_TYPE, uint32_t*)) | 
|  | DL_sym(lib_handle, "COIEngineGetCount", COI_VERSION1); | 
|  | if (EngineGetCount == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIEngineGetCount"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | EngineGetHandle = | 
|  | (COIRESULT (*)(COI_ISA_TYPE, uint32_t, COIENGINE*)) | 
|  | DL_sym(lib_handle, "COIEngineGetHandle", COI_VERSION1); | 
|  | if (EngineGetHandle == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIEngineGetHandle"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | ProcessCreateFromMemory = | 
|  | (COIRESULT (*)(COIENGINE, const char*, const void*, uint64_t, int, | 
|  | const char**, uint8_t, const char**, uint8_t, | 
|  | const char*, uint64_t, const char*, const char*, | 
|  | uint64_t, COIPROCESS*)) | 
|  | DL_sym(lib_handle, "COIProcessCreateFromMemory", COI_VERSION1); | 
|  | if (ProcessCreateFromMemory == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIProcessCreateFromMemory"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | ProcessSetCacheSize = | 
|  | (COIRESULT (*)(COIPROCESS, uint64_t, uint32_t, | 
|  | uint64_t, uint32_t, uint32_t, | 
|  | const COIEVENT*, COIEVENT*)) | 
|  | DL_sym(lib_handle, "COIProcessSetCacheSize", COI_VERSION1); | 
|  | if (ProcessSetCacheSize == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIProcessSetCacheSize"); | 
|  | #if 0  // for now disable as ProcessSetCacheSize is not available on < MPSS 3.4 | 
|  | fini(); | 
|  | return false; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | ProcessCreateFromFile = | 
|  | (COIRESULT (*)(COIENGINE, const char*, int, const char**, uint8_t, | 
|  | const char**, uint8_t, const char*, uint64_t, | 
|  | const char*, COIPROCESS*)) | 
|  | DL_sym(lib_handle, "COIProcessCreateFromFile", COI_VERSION1); | 
|  | if (ProcessCreateFromFile == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIProcessCreateFromFile"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | ProcessDestroy = | 
|  | (COIRESULT (*)(COIPROCESS, int32_t, uint8_t, int8_t*, | 
|  | uint32_t*)) | 
|  | DL_sym(lib_handle, "COIProcessDestroy", COI_VERSION1); | 
|  | if (ProcessDestroy == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIProcessDestroy"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | ProcessGetFunctionHandles = | 
|  | (COIRESULT (*)(COIPROCESS, uint32_t, const char**, COIFUNCTION*)) | 
|  | DL_sym(lib_handle, "COIProcessGetFunctionHandles", COI_VERSION1); | 
|  | if (ProcessGetFunctionHandles == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIProcessGetFunctionHandles"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | ProcessLoadLibraryFromMemory = | 
|  | (COIRESULT (*)(COIPROCESS, const void*, uint64_t, const char*, | 
|  | const char*, const char*, uint64_t, uint32_t, | 
|  | COILIBRARY*)) | 
|  | DL_sym(lib_handle, "COIProcessLoadLibraryFromMemory", COI_VERSION2); | 
|  | if (ProcessLoadLibraryFromMemory == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIProcessLoadLibraryFromMemory"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | ProcessUnloadLibrary = | 
|  | (COIRESULT (*)(COIPROCESS, | 
|  | COILIBRARY)) | 
|  | DL_sym(lib_handle, "COIProcessUnloadLibrary", COI_VERSION1); | 
|  | if (ProcessUnloadLibrary == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIProcessUnloadLibrary"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | ProcessRegisterLibraries = | 
|  | (COIRESULT (*)(uint32_t, const void**, const uint64_t*, const char**, | 
|  | const uint64_t*)) | 
|  | DL_sym(lib_handle, "COIProcessRegisterLibraries", COI_VERSION1); | 
|  | if (ProcessRegisterLibraries == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIProcessRegisterLibraries"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | PipelineCreate = | 
|  | (COIRESULT (*)(COIPROCESS, COI_CPU_MASK, uint32_t, COIPIPELINE*)) | 
|  | DL_sym(lib_handle, "COIPipelineCreate", COI_VERSION1); | 
|  | if (PipelineCreate == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIPipelineCreate"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | PipelineDestroy = | 
|  | (COIRESULT (*)(COIPIPELINE)) | 
|  | DL_sym(lib_handle, "COIPipelineDestroy", COI_VERSION1); | 
|  | if (PipelineDestroy == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIPipelineDestroy"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | PipelineRunFunction = | 
|  | (COIRESULT (*)(COIPIPELINE, COIFUNCTION, uint32_t, const COIBUFFER*, | 
|  | const COI_ACCESS_FLAGS*, uint32_t, const COIEVENT*, | 
|  | const void*, uint16_t, void*, uint16_t, COIEVENT*)) | 
|  | DL_sym(lib_handle, "COIPipelineRunFunction", COI_VERSION1); | 
|  | if (PipelineRunFunction == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIPipelineRunFunction"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | BufferCreate = | 
|  | (COIRESULT (*)(uint64_t, COI_BUFFER_TYPE, uint32_t, const void*, | 
|  | uint32_t, const COIPROCESS*, COIBUFFER*)) | 
|  | DL_sym(lib_handle, "COIBufferCreate", COI_VERSION1); | 
|  | if (BufferCreate == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIBufferCreate"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | BufferCreateFromMemory = | 
|  | (COIRESULT (*)(uint64_t, COI_BUFFER_TYPE, uint32_t, void*, | 
|  | uint32_t, const COIPROCESS*, COIBUFFER*)) | 
|  | DL_sym(lib_handle, "COIBufferCreateFromMemory", COI_VERSION1); | 
|  | if (BufferCreateFromMemory == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIBufferCreateFromMemory"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | BufferDestroy = | 
|  | (COIRESULT (*)(COIBUFFER)) | 
|  | DL_sym(lib_handle, "COIBufferDestroy", COI_VERSION1); | 
|  | if (BufferDestroy == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIBufferDestroy"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | BufferMap = | 
|  | (COIRESULT (*)(COIBUFFER, uint64_t, uint64_t, COI_MAP_TYPE, uint32_t, | 
|  | const COIEVENT*, COIEVENT*, COIMAPINSTANCE*, | 
|  | void**)) | 
|  | DL_sym(lib_handle, "COIBufferMap", COI_VERSION1); | 
|  | if (BufferMap == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIBufferMap"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | BufferUnmap = | 
|  | (COIRESULT (*)(COIMAPINSTANCE, uint32_t, const COIEVENT*, | 
|  | COIEVENT*)) | 
|  | DL_sym(lib_handle, "COIBufferUnmap", COI_VERSION1); | 
|  | if (BufferUnmap == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIBufferUnmap"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | BufferWrite = | 
|  | (COIRESULT (*)(COIBUFFER, uint64_t, const void*, uint64_t, | 
|  | COI_COPY_TYPE, uint32_t, const COIEVENT*, | 
|  | COIEVENT*)) | 
|  | DL_sym(lib_handle, "COIBufferWrite", COI_VERSION1); | 
|  | if (BufferWrite == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIBufferWrite"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | BufferRead = | 
|  | (COIRESULT (*)(COIBUFFER, uint64_t, void*, uint64_t, | 
|  | COI_COPY_TYPE, uint32_t, | 
|  | const COIEVENT*, COIEVENT*)) | 
|  | DL_sym(lib_handle, "COIBufferRead", COI_VERSION1); | 
|  | if (BufferRead == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIBufferRead"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | BufferReadMultiD = | 
|  | (COIRESULT (*)(COIBUFFER, uint64_t, | 
|  | void *, void *, COI_COPY_TYPE, | 
|  | uint32_t, const   COIEVENT*, COIEVENT*)) | 
|  | DL_sym(lib_handle, "COIBufferReadMultiD", COI_VERSION1); | 
|  | // We  accept that coi library has no COIBufferReadMultiD routine. | 
|  | // So there is no check for zero value | 
|  |  | 
|  | BufferWriteMultiD = | 
|  | (COIRESULT (*)(COIBUFFER, const   COIPROCESS, | 
|  | uint64_t, void *, void *, | 
|  | COI_COPY_TYPE, uint32_t, const   COIEVENT*, COIEVENT*)) | 
|  | DL_sym(lib_handle, "COIBufferWriteMultiD", COI_VERSION1); | 
|  | // We  accept that coi library has no COIBufferWriteMultiD routine. | 
|  | // So there is no check for zero value | 
|  |  | 
|  | BufferCopy = | 
|  | (COIRESULT (*)(COIBUFFER, COIBUFFER, uint64_t, uint64_t, uint64_t, | 
|  | COI_COPY_TYPE, uint32_t, const COIEVENT*, | 
|  | COIEVENT*)) | 
|  | DL_sym(lib_handle, "COIBufferCopy", COI_VERSION1); | 
|  | if (BufferCopy == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIBufferCopy"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | BufferGetSinkAddress = | 
|  | (COIRESULT (*)(COIBUFFER, uint64_t*)) | 
|  | DL_sym(lib_handle, "COIBufferGetSinkAddress", COI_VERSION1); | 
|  | if (BufferGetSinkAddress == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIBufferGetSinkAddress"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | BufferSetState = | 
|  | (COIRESULT(*)(COIBUFFER, COIPROCESS, COI_BUFFER_STATE, | 
|  | COI_BUFFER_MOVE_FLAG, uint32_t, const COIEVENT*, | 
|  | COIEVENT*)) | 
|  | DL_sym(lib_handle, "COIBufferSetState", COI_VERSION1); | 
|  | if (BufferSetState == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIBufferSetState"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | EventWait = | 
|  | (COIRESULT (*)(uint16_t, const COIEVENT*, int32_t, uint8_t, | 
|  | uint32_t*, uint32_t*)) | 
|  | DL_sym(lib_handle, "COIEventWait", COI_VERSION1); | 
|  | if (EventWait == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIEventWait"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | PerfGetCycleFrequency = | 
|  | (uint64_t (*)(void)) | 
|  | DL_sym(lib_handle, "COIPerfGetCycleFrequency", COI_VERSION1); | 
|  | if (PerfGetCycleFrequency == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIPerfGetCycleFrequency"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | PipelineClearCPUMask = | 
|  | (COIRESULT (*)(COI_CPU_MASK)) | 
|  | DL_sym(lib_handle, "COIPipelineClearCPUMask", COI_VERSION1); | 
|  | if (PipelineClearCPUMask == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIPipelineClearCPUMask"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | PipelineSetCPUMask = | 
|  | (COIRESULT (*)(COIPROCESS, uint32_t,uint8_t, COI_CPU_MASK)) | 
|  | DL_sym(lib_handle, "COIPipelineSetCPUMask", COI_VERSION1); | 
|  | if (PipelineSetCPUMask == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIPipelineSetCPUMask"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | EngineGetInfo = | 
|  | (COIRESULT (*)(COIENGINE, uint32_t, COI_ENGINE_INFO*)) | 
|  | DL_sym(lib_handle, "COIEngineGetInfo", COI_VERSION1); | 
|  | if (EngineGetInfo == 0) { | 
|  | OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n", | 
|  | "COIEngineGetInfo"); | 
|  | fini(); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | EventRegisterCallback = | 
|  | (COIRESULT (*)(COIEVENT, | 
|  | void (*)(COIEVENT, const COIRESULT, const void*), | 
|  | const void*, | 
|  | const uint64_t)) | 
|  | DL_sym(lib_handle, "COIEventRegisterCallback", COI_VERSION1); | 
|  |  | 
|  | ProcessConfigureDMA = | 
|  | (COIRESULT (*)(const uint64_t, const int)) | 
|  | DL_sym(lib_handle, "COIProcessConfigureDMA", COI_VERSION1); | 
|  |  | 
|  | is_available = true; | 
|  |  | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void fini(void) | 
|  | { | 
|  | is_available = false; | 
|  |  | 
|  | if (lib_handle != 0) { | 
|  | #ifndef TARGET_WINNT | 
|  | DL_close(lib_handle); | 
|  | #endif // TARGET_WINNT | 
|  | lib_handle = 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | } // namespace COI |