1 /*
2 Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30
31 // The COI host interface
32
33 #include "coi_client.h"
34 #include "../offload_common.h"
35
36 namespace COI {
37
38 #define COI_VERSION1 "COI_1.0"
39 #define COI_VERSION2 "COI_2.0"
40
41 bool is_available;
42 static void* lib_handle;
43
44 // pointers to functions from COI library
45 COIRESULT (*EngineGetCount)(COI_ISA_TYPE, uint32_t*);
46 COIRESULT (*EngineGetHandle)(COI_ISA_TYPE, uint32_t, COIENGINE*);
47
48 COIRESULT (*ProcessCreateFromMemory)(COIENGINE, const char*, const void*,
49 uint64_t, int, const char**, uint8_t,
50 const char**, uint8_t, const char*,
51 uint64_t, const char*, const char*,
52 uint64_t, COIPROCESS*);
53 COIRESULT (*ProcessCreateFromFile)(COIENGINE, const char*,
54 int, const char**, uint8_t,
55 const char**, uint8_t, const char*,
56 uint64_t, const char*,COIPROCESS*);
57 COIRESULT (*ProcessSetCacheSize)(COIPROCESS, uint64_t, uint32_t,
58 uint64_t, uint32_t, uint32_t,
59 const COIEVENT*, COIEVENT*);
60 COIRESULT (*ProcessDestroy)(COIPROCESS, int32_t, uint8_t, int8_t*, uint32_t*);
61 COIRESULT (*ProcessGetFunctionHandles)(COIPROCESS, uint32_t, const char**,
62 COIFUNCTION*);
63 COIRESULT (*ProcessLoadLibraryFromMemory)(COIPROCESS, const void*, uint64_t,
64 const char*, const char*,
65 const char*, uint64_t, uint32_t,
66 COILIBRARY*);
67 COIRESULT (*ProcessUnloadLibrary)(COIPROCESS,
68 COILIBRARY);
69 COIRESULT (*ProcessRegisterLibraries)(uint32_t, const void**, const uint64_t*,
70 const char**, const uint64_t*);
71
72 COIRESULT (*PipelineCreate)(COIPROCESS, COI_CPU_MASK, uint32_t, COIPIPELINE*);
73 COIRESULT (*PipelineDestroy)(COIPIPELINE);
74 COIRESULT (*PipelineRunFunction)(COIPIPELINE, COIFUNCTION, uint32_t,
75 const COIBUFFER*, const COI_ACCESS_FLAGS*,
76 uint32_t, const COIEVENT*, const void*,
77 uint16_t, void*, uint16_t, COIEVENT*);
78
79 COIRESULT (*BufferCreate)(uint64_t, COI_BUFFER_TYPE, uint32_t, const void*,
80 uint32_t, const COIPROCESS*, COIBUFFER*);
81 COIRESULT (*BufferCreateFromMemory)(uint64_t, COI_BUFFER_TYPE, uint32_t,
82 void*, uint32_t, const COIPROCESS*,
83 COIBUFFER*);
84 COIRESULT (*BufferDestroy)(COIBUFFER);
85 COIRESULT (*BufferMap)(COIBUFFER, uint64_t, uint64_t, COI_MAP_TYPE, uint32_t,
86 const COIEVENT*, COIEVENT*, COIMAPINSTANCE*, void**);
87 COIRESULT (*BufferUnmap)(COIMAPINSTANCE, uint32_t, const COIEVENT*, COIEVENT*);
88 COIRESULT (*BufferWrite)(COIBUFFER, uint64_t, const void*, uint64_t,
89 COI_COPY_TYPE, uint32_t, const COIEVENT*, COIEVENT*);
90 COIRESULT (*BufferRead)(COIBUFFER, uint64_t, void*, uint64_t, COI_COPY_TYPE,
91 uint32_t, const COIEVENT*, COIEVENT*);
92 COIRESULT (*BufferReadMultiD)(COIBUFFER, uint64_t,
93 void *, void *, COI_COPY_TYPE,
94 uint32_t, const COIEVENT*, COIEVENT*);
95 COIRESULT (*BufferWriteMultiD)(COIBUFFER, const COIPROCESS,
96 uint64_t, void *, void *,
97 COI_COPY_TYPE, uint32_t, const COIEVENT*, COIEVENT*);
98
99 COIRESULT (*BufferCopy)(COIBUFFER, COIBUFFER, uint64_t, uint64_t, uint64_t,
100 COI_COPY_TYPE, uint32_t, const COIEVENT*, COIEVENT*);
101 COIRESULT (*BufferGetSinkAddress)(COIBUFFER, uint64_t*);
102 COIRESULT (*BufferSetState)(COIBUFFER, COIPROCESS, COI_BUFFER_STATE,
103 COI_BUFFER_MOVE_FLAG, uint32_t,
104 const COIEVENT*, COIEVENT*);
105
106 COIRESULT (*EventWait)(uint16_t, const COIEVENT*, int32_t, uint8_t, uint32_t*,
107 uint32_t*);
108
109 uint64_t (*PerfGetCycleFrequency)(void);
110
111 COIRESULT (*PipelineClearCPUMask) (COI_CPU_MASK);
112
113 COIRESULT (*PipelineSetCPUMask) (COIPROCESS, uint32_t,
114 uint8_t, COI_CPU_MASK);
115 COIRESULT (*EngineGetInfo)(COIENGINE, uint32_t, COI_ENGINE_INFO*);
116
117 COIRESULT (*EventRegisterCallback)(
118 const COIEVENT,
119 void (*)(COIEVENT, const COIRESULT, const void*),
120 const void*,
121 const uint64_t);
122
123 COIRESULT (*ProcessConfigureDMA)(const uint64_t, const int);
124
init(void)125 bool init(void)
126 {
127 #ifndef TARGET_WINNT
128 const char *lib_name = "libcoi_host.so.0";
129 #else // TARGET_WINNT
130 const char *lib_name = "coi_host.dll";
131 #endif // TARGET_WINNT
132
133 OFFLOAD_DEBUG_TRACE(2, "Loading COI library %s ...\n", lib_name);
134 lib_handle = DL_open(lib_name);
135 if (lib_handle == 0) {
136 OFFLOAD_DEBUG_TRACE(2, "Failed to load the library\n");
137 return false;
138 }
139
140 EngineGetCount =
141 (COIRESULT (*)(COI_ISA_TYPE, uint32_t*))
142 DL_sym(lib_handle, "COIEngineGetCount", COI_VERSION1);
143 if (EngineGetCount == 0) {
144 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
145 "COIEngineGetCount");
146 fini();
147 return false;
148 }
149
150 EngineGetHandle =
151 (COIRESULT (*)(COI_ISA_TYPE, uint32_t, COIENGINE*))
152 DL_sym(lib_handle, "COIEngineGetHandle", COI_VERSION1);
153 if (EngineGetHandle == 0) {
154 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
155 "COIEngineGetHandle");
156 fini();
157 return false;
158 }
159
160 ProcessCreateFromMemory =
161 (COIRESULT (*)(COIENGINE, const char*, const void*, uint64_t, int,
162 const char**, uint8_t, const char**, uint8_t,
163 const char*, uint64_t, const char*, const char*,
164 uint64_t, COIPROCESS*))
165 DL_sym(lib_handle, "COIProcessCreateFromMemory", COI_VERSION1);
166 if (ProcessCreateFromMemory == 0) {
167 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
168 "COIProcessCreateFromMemory");
169 fini();
170 return false;
171 }
172
173 ProcessSetCacheSize =
174 (COIRESULT (*)(COIPROCESS, uint64_t, uint32_t,
175 uint64_t, uint32_t, uint32_t,
176 const COIEVENT*, COIEVENT*))
177 DL_sym(lib_handle, "COIProcessSetCacheSize", COI_VERSION1);
178 if (ProcessSetCacheSize == 0) {
179 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
180 "COIProcessSetCacheSize");
181 #if 0 // for now disable as ProcessSetCacheSize is not available on < MPSS 3.4
182 fini();
183 return false;
184 #endif
185 }
186
187 ProcessCreateFromFile =
188 (COIRESULT (*)(COIENGINE, const char*, int, const char**, uint8_t,
189 const char**, uint8_t, const char*, uint64_t,
190 const char*, COIPROCESS*))
191 DL_sym(lib_handle, "COIProcessCreateFromFile", COI_VERSION1);
192 if (ProcessCreateFromFile == 0) {
193 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
194 "COIProcessCreateFromFile");
195 fini();
196 return false;
197 }
198
199 ProcessDestroy =
200 (COIRESULT (*)(COIPROCESS, int32_t, uint8_t, int8_t*,
201 uint32_t*))
202 DL_sym(lib_handle, "COIProcessDestroy", COI_VERSION1);
203 if (ProcessDestroy == 0) {
204 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
205 "COIProcessDestroy");
206 fini();
207 return false;
208 }
209
210 ProcessGetFunctionHandles =
211 (COIRESULT (*)(COIPROCESS, uint32_t, const char**, COIFUNCTION*))
212 DL_sym(lib_handle, "COIProcessGetFunctionHandles", COI_VERSION1);
213 if (ProcessGetFunctionHandles == 0) {
214 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
215 "COIProcessGetFunctionHandles");
216 fini();
217 return false;
218 }
219
220 ProcessLoadLibraryFromMemory =
221 (COIRESULT (*)(COIPROCESS, const void*, uint64_t, const char*,
222 const char*, const char*, uint64_t, uint32_t,
223 COILIBRARY*))
224 DL_sym(lib_handle, "COIProcessLoadLibraryFromMemory", COI_VERSION2);
225 if (ProcessLoadLibraryFromMemory == 0) {
226 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
227 "COIProcessLoadLibraryFromMemory");
228 fini();
229 return false;
230 }
231
232 ProcessUnloadLibrary =
233 (COIRESULT (*)(COIPROCESS,
234 COILIBRARY))
235 DL_sym(lib_handle, "COIProcessUnloadLibrary", COI_VERSION1);
236 if (ProcessUnloadLibrary == 0) {
237 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
238 "COIProcessUnloadLibrary");
239 fini();
240 return false;
241 }
242
243 ProcessRegisterLibraries =
244 (COIRESULT (*)(uint32_t, const void**, const uint64_t*, const char**,
245 const uint64_t*))
246 DL_sym(lib_handle, "COIProcessRegisterLibraries", COI_VERSION1);
247 if (ProcessRegisterLibraries == 0) {
248 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
249 "COIProcessRegisterLibraries");
250 fini();
251 return false;
252 }
253
254 PipelineCreate =
255 (COIRESULT (*)(COIPROCESS, COI_CPU_MASK, uint32_t, COIPIPELINE*))
256 DL_sym(lib_handle, "COIPipelineCreate", COI_VERSION1);
257 if (PipelineCreate == 0) {
258 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
259 "COIPipelineCreate");
260 fini();
261 return false;
262 }
263
264 PipelineDestroy =
265 (COIRESULT (*)(COIPIPELINE))
266 DL_sym(lib_handle, "COIPipelineDestroy", COI_VERSION1);
267 if (PipelineDestroy == 0) {
268 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
269 "COIPipelineDestroy");
270 fini();
271 return false;
272 }
273
274 PipelineRunFunction =
275 (COIRESULT (*)(COIPIPELINE, COIFUNCTION, uint32_t, const COIBUFFER*,
276 const COI_ACCESS_FLAGS*, uint32_t, const COIEVENT*,
277 const void*, uint16_t, void*, uint16_t, COIEVENT*))
278 DL_sym(lib_handle, "COIPipelineRunFunction", COI_VERSION1);
279 if (PipelineRunFunction == 0) {
280 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
281 "COIPipelineRunFunction");
282 fini();
283 return false;
284 }
285
286 BufferCreate =
287 (COIRESULT (*)(uint64_t, COI_BUFFER_TYPE, uint32_t, const void*,
288 uint32_t, const COIPROCESS*, COIBUFFER*))
289 DL_sym(lib_handle, "COIBufferCreate", COI_VERSION1);
290 if (BufferCreate == 0) {
291 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
292 "COIBufferCreate");
293 fini();
294 return false;
295 }
296
297 BufferCreateFromMemory =
298 (COIRESULT (*)(uint64_t, COI_BUFFER_TYPE, uint32_t, void*,
299 uint32_t, const COIPROCESS*, COIBUFFER*))
300 DL_sym(lib_handle, "COIBufferCreateFromMemory", COI_VERSION1);
301 if (BufferCreateFromMemory == 0) {
302 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
303 "COIBufferCreateFromMemory");
304 fini();
305 return false;
306 }
307
308 BufferDestroy =
309 (COIRESULT (*)(COIBUFFER))
310 DL_sym(lib_handle, "COIBufferDestroy", COI_VERSION1);
311 if (BufferDestroy == 0) {
312 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
313 "COIBufferDestroy");
314 fini();
315 return false;
316 }
317
318 BufferMap =
319 (COIRESULT (*)(COIBUFFER, uint64_t, uint64_t, COI_MAP_TYPE, uint32_t,
320 const COIEVENT*, COIEVENT*, COIMAPINSTANCE*,
321 void**))
322 DL_sym(lib_handle, "COIBufferMap", COI_VERSION1);
323 if (BufferMap == 0) {
324 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
325 "COIBufferMap");
326 fini();
327 return false;
328 }
329
330 BufferUnmap =
331 (COIRESULT (*)(COIMAPINSTANCE, uint32_t, const COIEVENT*,
332 COIEVENT*))
333 DL_sym(lib_handle, "COIBufferUnmap", COI_VERSION1);
334 if (BufferUnmap == 0) {
335 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
336 "COIBufferUnmap");
337 fini();
338 return false;
339 }
340
341 BufferWrite =
342 (COIRESULT (*)(COIBUFFER, uint64_t, const void*, uint64_t,
343 COI_COPY_TYPE, uint32_t, const COIEVENT*,
344 COIEVENT*))
345 DL_sym(lib_handle, "COIBufferWrite", COI_VERSION1);
346 if (BufferWrite == 0) {
347 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
348 "COIBufferWrite");
349 fini();
350 return false;
351 }
352
353 BufferRead =
354 (COIRESULT (*)(COIBUFFER, uint64_t, void*, uint64_t,
355 COI_COPY_TYPE, uint32_t,
356 const COIEVENT*, COIEVENT*))
357 DL_sym(lib_handle, "COIBufferRead", COI_VERSION1);
358 if (BufferRead == 0) {
359 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
360 "COIBufferRead");
361 fini();
362 return false;
363 }
364
365 BufferReadMultiD =
366 (COIRESULT (*)(COIBUFFER, uint64_t,
367 void *, void *, COI_COPY_TYPE,
368 uint32_t, const COIEVENT*, COIEVENT*))
369 DL_sym(lib_handle, "COIBufferReadMultiD", COI_VERSION1);
370 // We accept that coi library has no COIBufferReadMultiD routine.
371 // So there is no check for zero value
372
373 BufferWriteMultiD =
374 (COIRESULT (*)(COIBUFFER, const COIPROCESS,
375 uint64_t, void *, void *,
376 COI_COPY_TYPE, uint32_t, const COIEVENT*, COIEVENT*))
377 DL_sym(lib_handle, "COIBufferWriteMultiD", COI_VERSION1);
378 // We accept that coi library has no COIBufferWriteMultiD routine.
379 // So there is no check for zero value
380
381 BufferCopy =
382 (COIRESULT (*)(COIBUFFER, COIBUFFER, uint64_t, uint64_t, uint64_t,
383 COI_COPY_TYPE, uint32_t, const COIEVENT*,
384 COIEVENT*))
385 DL_sym(lib_handle, "COIBufferCopy", COI_VERSION1);
386 if (BufferCopy == 0) {
387 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
388 "COIBufferCopy");
389 fini();
390 return false;
391 }
392
393 BufferGetSinkAddress =
394 (COIRESULT (*)(COIBUFFER, uint64_t*))
395 DL_sym(lib_handle, "COIBufferGetSinkAddress", COI_VERSION1);
396 if (BufferGetSinkAddress == 0) {
397 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
398 "COIBufferGetSinkAddress");
399 fini();
400 return false;
401 }
402
403 BufferSetState =
404 (COIRESULT(*)(COIBUFFER, COIPROCESS, COI_BUFFER_STATE,
405 COI_BUFFER_MOVE_FLAG, uint32_t, const COIEVENT*,
406 COIEVENT*))
407 DL_sym(lib_handle, "COIBufferSetState", COI_VERSION1);
408 if (BufferSetState == 0) {
409 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
410 "COIBufferSetState");
411 fini();
412 return false;
413 }
414
415 EventWait =
416 (COIRESULT (*)(uint16_t, const COIEVENT*, int32_t, uint8_t,
417 uint32_t*, uint32_t*))
418 DL_sym(lib_handle, "COIEventWait", COI_VERSION1);
419 if (EventWait == 0) {
420 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
421 "COIEventWait");
422 fini();
423 return false;
424 }
425
426 PerfGetCycleFrequency =
427 (uint64_t (*)(void))
428 DL_sym(lib_handle, "COIPerfGetCycleFrequency", COI_VERSION1);
429 if (PerfGetCycleFrequency == 0) {
430 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
431 "COIPerfGetCycleFrequency");
432 fini();
433 return false;
434 }
435
436 PipelineClearCPUMask =
437 (COIRESULT (*)(COI_CPU_MASK))
438 DL_sym(lib_handle, "COIPipelineClearCPUMask", COI_VERSION1);
439 if (PipelineClearCPUMask == 0) {
440 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
441 "COIPipelineClearCPUMask");
442 fini();
443 return false;
444 }
445
446 PipelineSetCPUMask =
447 (COIRESULT (*)(COIPROCESS, uint32_t,uint8_t, COI_CPU_MASK))
448 DL_sym(lib_handle, "COIPipelineSetCPUMask", COI_VERSION1);
449 if (PipelineSetCPUMask == 0) {
450 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
451 "COIPipelineSetCPUMask");
452 fini();
453 return false;
454 }
455
456 EngineGetInfo =
457 (COIRESULT (*)(COIENGINE, uint32_t, COI_ENGINE_INFO*))
458 DL_sym(lib_handle, "COIEngineGetInfo", COI_VERSION1);
459 if (EngineGetInfo == 0) {
460 OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
461 "COIEngineGetInfo");
462 fini();
463 return false;
464 }
465
466 EventRegisterCallback =
467 (COIRESULT (*)(COIEVENT,
468 void (*)(COIEVENT, const COIRESULT, const void*),
469 const void*,
470 const uint64_t))
471 DL_sym(lib_handle, "COIEventRegisterCallback", COI_VERSION1);
472
473 ProcessConfigureDMA =
474 (COIRESULT (*)(const uint64_t, const int))
475 DL_sym(lib_handle, "COIProcessConfigureDMA", COI_VERSION1);
476
477 is_available = true;
478
479 return true;
480 }
481
fini(void)482 void fini(void)
483 {
484 is_available = false;
485
486 if (lib_handle != 0) {
487 #ifndef TARGET_WINNT
488 DL_close(lib_handle);
489 #endif // TARGET_WINNT
490 lib_handle = 0;
491 }
492 }
493
494 } // namespace COI
495