2 Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
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.
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.
30 #include "coi_device.h"
32 #include "coi_version_asm.h"
34 #define CYCLE_FREQUENCY 1000000000
37 static uint32_t engine_index
;
38 static char *engine_dir
;
45 SYMBOL_VERSION (COIBufferAddRef
, 1) (void *ptr
)
47 COITRACE ("COIBufferAddRef");
49 /* Looks like we have nothing to do here. */
56 SYMBOL_VERSION (COIBufferReleaseRef
, 1) (void *ptr
)
58 COITRACE ("COIBufferReleaseRef");
60 /* Looks like we have nothing to do here. */
67 SYMBOL_VERSION (COIEngineGetIndex
, 1) (COI_ISA_TYPE
*type
,
70 COITRACE ("COIEngineGetIndex");
72 /* type is not used in liboffloadmic. */
73 *index
= engine_index
;
80 SYMBOL_VERSION (COIPipelineStartExecutingRunFunctions
, 1) ()
82 COITRACE ("COIPipelineStartExecutingRunFunctions");
84 /* Looks like we have nothing to do here. */
90 /* The start routine for the COI pipeline thread. */
93 pipeline_thread_routine (void *in_pipeline_num
)
95 uint32_t pipeline_num
= *(uint32_t *) in_pipeline_num
;
96 free (in_pipeline_num
);
99 char *pipe_host2tgt_path
, *pipe_tgt2host_path
;
100 MALLOCN (char *, pipe_host2tgt_path
,
101 strlen (engine_dir
) + sizeof (PIPE_HOST2TGT_NAME
"0000000000"));
102 MALLOCN (char *, pipe_tgt2host_path
,
103 strlen (engine_dir
) + sizeof (PIPE_TGT2HOST_NAME
"0000000000"));
104 sprintf (pipe_host2tgt_path
, "%s" PIPE_HOST2TGT_NAME
"%010d", engine_dir
,
106 sprintf (pipe_tgt2host_path
, "%s" PIPE_TGT2HOST_NAME
"%010d", engine_dir
,
108 int pipe_host2tgt
= open (pipe_host2tgt_path
, O_CLOEXEC
| O_RDONLY
);
109 if (pipe_host2tgt
< 0)
110 COIERRORN ("Cannot open host-to-target pipe.");
111 int pipe_tgt2host
= open (pipe_tgt2host_path
, O_CLOEXEC
| O_WRONLY
);
112 if (pipe_tgt2host
< 0)
113 COIERRORN ("Cannot open target-to-host pipe.");
115 free (pipe_host2tgt_path
);
116 free (pipe_tgt2host_path
);
120 /* Read and execute command. */
121 cmd_t cmd
= CMD_PIPELINE_DESTROY
;
122 int cmd_len
= read (pipe_host2tgt
, &cmd
, sizeof (cmd_t
));
123 if (cmd_len
!= sizeof (cmd_t
) && cmd_len
!= 0)
124 COIERRORN ("Cannot read from pipe.");
126 if (cmd
== CMD_PIPELINE_DESTROY
)
128 else if (cmd
== CMD_PIPELINE_RUN_FUNCTION
)
130 /* Receive data from host. */
131 void (*func
) (uint32_t, void **, uint64_t *, void *, uint16_t, void *,
133 uint32_t buffer_count
;
134 READN (pipe_host2tgt
, &func
, sizeof (void *));
135 READN (pipe_host2tgt
, &buffer_count
, sizeof (uint32_t));
137 uint64_t *buffers_len
;
138 MALLOCN (void **, buffers
, buffer_count
* sizeof (void *));
139 MALLOCN (uint64_t *, buffers_len
, buffer_count
* sizeof (uint64_t));
140 for (uint32_t i
= 0; i
< buffer_count
; i
++)
142 READN (pipe_host2tgt
, &buffers_len
[i
], sizeof (uint64_t));
143 READN (pipe_host2tgt
, &buffers
[i
], sizeof (void *));
145 uint16_t misc_data_len
;
146 READN (pipe_host2tgt
, &misc_data_len
, sizeof (uint16_t));
147 void *misc_data
= NULL
;
148 if (misc_data_len
> 0)
150 MALLOCN (void *, misc_data
, misc_data_len
);
151 READN (pipe_host2tgt
, misc_data
, misc_data_len
);
153 uint16_t return_data_len
;
154 READN (pipe_host2tgt
, &return_data_len
, sizeof (uint16_t));
156 if (return_data_len
> 0)
157 MALLOCN (void *, return_data
, return_data_len
);
160 func (buffer_count
, buffers
, buffers_len
, misc_data
,
161 misc_data_len
, return_data
, return_data_len
);
163 /* Send data to host if any or just send notification. */
164 WRITEN (pipe_tgt2host
, return_data_len
> 0 ? return_data
: &cmd
,
165 return_data_len
> 0 ? return_data_len
: sizeof (cmd_t
));
170 if (misc_data_len
> 0)
172 if (return_data_len
> 0)
176 COIERRORN ("Unrecognizable command from host.");
180 if (close (pipe_host2tgt
) < 0)
181 COIERRORN ("Cannot close host-to-target pipe.");
182 if (close (pipe_tgt2host
) < 0)
183 COIERRORN ("Cannot close target-to-host pipe.");
190 SYMBOL_VERSION (COIProcessWaitForShutdown
, 1) ()
192 COITRACE ("COIProcessWaitForShutdown");
194 engine_dir
= getenv (MIC_DIR_ENV
);
195 char *mic_index
= getenv (MIC_INDEX_ENV
);
196 assert (engine_dir
!= NULL
&& mic_index
!= NULL
);
198 /* Get engine index. */
199 engine_index
= atoi (mic_index
);
201 /* Open main pipes. */
202 char *pipe_host2tgt_path
, *pipe_tgt2host_path
;
203 MALLOC (char *, pipe_host2tgt_path
,
204 strlen (engine_dir
) + sizeof (PIPE_HOST2TGT_NAME
"mainpipe"));
205 MALLOC (char *, pipe_tgt2host_path
,
206 strlen (engine_dir
) + sizeof (PIPE_TGT2HOST_NAME
"mainpipe"));
207 sprintf (pipe_host2tgt_path
, "%s" PIPE_HOST2TGT_NAME
"mainpipe", engine_dir
);
208 sprintf (pipe_tgt2host_path
, "%s" PIPE_TGT2HOST_NAME
"mainpipe", engine_dir
);
209 int pipe_host2tgt
= open (pipe_host2tgt_path
, O_CLOEXEC
| O_RDONLY
);
210 if (pipe_host2tgt
< 0)
211 COIERROR ("Cannot open host-to-target main pipe.");
212 int pipe_tgt2host
= open (pipe_tgt2host_path
, O_CLOEXEC
| O_WRONLY
);
213 if (pipe_tgt2host
< 0)
214 COIERROR ("Cannot open target-to-host main pipe.");
217 free (pipe_host2tgt_path
);
218 free (pipe_tgt2host_path
);
223 /* Read and execute command. */
224 cmd_t cmd
= CMD_SHUTDOWN
;
225 int cmd_len
= read (pipe_host2tgt
, &cmd
, sizeof (cmd_t
));
226 if (cmd_len
!= sizeof (cmd_t
) && cmd_len
!= 0)
227 COIERROR ("Cannot read from main pipe.");
231 case CMD_BUFFER_COPY
:
236 /* Receive data from host. */
237 READ (pipe_host2tgt
, &dest
, sizeof (void *));
238 READ (pipe_host2tgt
, &source
, sizeof (void *));
239 READ (pipe_host2tgt
, &len
, sizeof (uint64_t));
242 memcpy (dest
, source
, len
);
244 /* Notify host about completion. */
245 WRITE (pipe_tgt2host
, &cmd
, sizeof (cmd_t
));
256 /* Receive data from host. */
257 READ (pipe_host2tgt
, &len
, sizeof (size_t));
258 MALLOC (char *, name
, len
);
259 READ (pipe_host2tgt
, name
, len
);
260 READ (pipe_host2tgt
, &buffer_len
, sizeof (uint64_t));
262 /* Open shared memory. */
263 int fd
= shm_open (name
, O_CLOEXEC
| O_RDWR
, S_IRUSR
| S_IWUSR
);
265 COIERROR ("Cannot open shared memory.");
267 /* Map shared memory. */
268 buffer
= mmap (NULL
, buffer_len
, PROT_READ
| PROT_WRITE
,
271 COIERROR ("Cannot map shared memory.");
273 /* Send data to host. */
274 WRITE (pipe_tgt2host
, &fd
, sizeof (int));
275 WRITE (pipe_tgt2host
, &buffer
, sizeof (void *));
282 case CMD_BUFFER_UNMAP
:
288 /* Receive data from host. */
289 READ (pipe_host2tgt
, &fd
, sizeof (int));
290 READ (pipe_host2tgt
, &buffer
, sizeof (void *));
291 READ (pipe_host2tgt
, &buffer_len
, sizeof (uint64_t));
294 if (munmap (buffer
, buffer_len
) < 0)
295 COIERROR ("Cannot unmap shared memory.");
297 /* Close shared memory. */
299 COIERROR ("Cannot close shared memory file.");
301 /* Notify host about completion. */
302 WRITE (pipe_tgt2host
, &cmd
, sizeof (cmd_t
));
306 case CMD_GET_FUNCTION_HANDLE
:
311 /* Receive data from host. */
312 READ (pipe_host2tgt
, &len
, sizeof (size_t));
313 MALLOC (char *, name
, len
);
314 READ (pipe_host2tgt
, name
, len
);
317 void *ptr
= dlsym (RTLD_DEFAULT
, name
);
319 COIERROR ("Cannot find symbol %s.", name
);
321 /* Send data to host. */
322 WRITE (pipe_tgt2host
, &ptr
, sizeof (void *));
329 case CMD_OPEN_LIBRARY
:
334 /* Receive data from host. */
335 READ (pipe_host2tgt
, &len
, sizeof (size_t));
336 MALLOC (char *, lib_path
, len
);
337 READ (pipe_host2tgt
, lib_path
, len
);
340 void *handle
= dlopen (lib_path
, RTLD_LAZY
| RTLD_GLOBAL
);
342 COIERROR ("Cannot load %s: %s", lib_path
, dlerror ());
344 /* Send data to host. */
345 WRITE (pipe_tgt2host
, &handle
, sizeof (void *));
352 case CMD_CLOSE_LIBRARY
:
354 /* Receive data from host. */
356 READ (pipe_host2tgt
, &handle
, sizeof (void *));
362 case CMD_PIPELINE_CREATE
:
364 /* Receive data from host. */
365 uint32_t *pipeline_num
;
366 MALLOC (uint32_t *, pipeline_num
, sizeof (uint32_t));
367 READ (pipe_host2tgt
, pipeline_num
, sizeof (*pipeline_num
));
369 /* Create a new thread for the pipeline. */
371 if (pthread_create (&thread
, NULL
, pipeline_thread_routine
,
373 COIERROR ("Cannot create new thread.");
377 if (close (pipe_host2tgt
) < 0)
378 COIERROR ("Cannot close host-to-target main pipe.");
379 if (close (pipe_tgt2host
) < 0)
380 COIERROR ("Cannot close target-to-host main pipe.");
383 COIERROR ("Unrecognizable command from host.");
393 SYMBOL_VERSION (COIPerfGetCycleFrequency
, 1) ()
395 COITRACE ("COIPerfGetCycleFrequency");
397 return (uint64_t) CYCLE_FREQUENCY
;