]> git.ipfire.org Git - thirdparty/gcc.git/blame - liboffloadmic/runtime/emulator/coi_device.cpp
backport: Makefile.am (myo_inc_dir): Remove.
[thirdparty/gcc.git] / liboffloadmic / runtime / emulator / coi_device.cpp
CommitLineData
5f520819 1/*
df26a50d 2 Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved.
5f520819
KY
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#include "coi_device.h"
31
32#include "coi_version_asm.h"
33
34#define CYCLE_FREQUENCY 1000000000
35
36
37static uint32_t engine_index;
44799f87 38static char *engine_dir;
5f520819
KY
39
40
41extern "C"
42{
43
44COIRESULT
45SYMBOL_VERSION (COIBufferAddRef, 1) (void *ptr)
46{
47 COITRACE ("COIBufferAddRef");
48
49 /* Looks like we have nothing to do here. */
50
51 return COI_SUCCESS;
52}
53
54
55COIRESULT
56SYMBOL_VERSION (COIBufferReleaseRef, 1) (void *ptr)
57{
58 COITRACE ("COIBufferReleaseRef");
59
60 /* Looks like we have nothing to do here. */
61
62 return COI_SUCCESS;
63}
64
65
66COIRESULT
67SYMBOL_VERSION (COIEngineGetIndex, 1) (COI_ISA_TYPE *type,
68 uint32_t *index)
69{
70 COITRACE ("COIEngineGetIndex");
71
44799f87 72 /* type is not used in liboffloadmic. */
5f520819
KY
73 *index = engine_index;
74
75 return COI_SUCCESS;
76}
77
78
79COIRESULT
80SYMBOL_VERSION (COIPipelineStartExecutingRunFunctions, 1) ()
81{
82 COITRACE ("COIPipelineStartExecutingRunFunctions");
83
84 /* Looks like we have nothing to do here. */
85
86 return COI_SUCCESS;
87}
88
89
44799f87
IV
90/* The start routine for the COI pipeline thread. */
91
92static void *
93pipeline_thread_routine (void *in_pipeline_num)
94{
95 uint32_t pipeline_num = *(uint32_t *) in_pipeline_num;
96 free (in_pipeline_num);
97
98 /* Open pipes. */
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,
105 pipeline_num);
106 sprintf (pipe_tgt2host_path, "%s" PIPE_TGT2HOST_NAME "%010d", engine_dir,
107 pipeline_num);
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.");
114
115 free (pipe_host2tgt_path);
116 free (pipe_tgt2host_path);
117
118 while (1)
119 {
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.");
125
126 if (cmd == CMD_PIPELINE_DESTROY)
127 break;
128 else if (cmd == CMD_PIPELINE_RUN_FUNCTION)
129 {
130 /* Receive data from host. */
131 void (*func) (uint32_t, void **, uint64_t *, void *, uint16_t, void *,
132 uint16_t);
133 uint32_t buffer_count;
134 READN (pipe_host2tgt, &func, sizeof (void *));
135 READN (pipe_host2tgt, &buffer_count, sizeof (uint32_t));
136 void **buffers;
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++)
141 {
142 READN (pipe_host2tgt, &buffers_len[i], sizeof (uint64_t));
143 READN (pipe_host2tgt, &buffers[i], sizeof (void *));
144 }
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)
149 {
150 MALLOCN (void *, misc_data, misc_data_len);
151 READN (pipe_host2tgt, misc_data, misc_data_len);
152 }
153 uint16_t return_data_len;
154 READN (pipe_host2tgt, &return_data_len, sizeof (uint16_t));
155 void *return_data;
156 if (return_data_len > 0)
157 MALLOCN (void *, return_data, return_data_len);
158
159 /* Run function. */
160 func (buffer_count, buffers, buffers_len, misc_data,
161 misc_data_len, return_data, return_data_len);
162
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));
166
167 /* Clean up. */
168 free (buffers);
169 free (buffers_len);
170 if (misc_data_len > 0)
171 free (misc_data);
172 if (return_data_len > 0)
173 free (return_data);
174 }
175 else
176 COIERRORN ("Unrecognizable command from host.");
177 }
178
179 /* Close pipes. */
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.");
184
185 return NULL;
186}
187
188
5f520819
KY
189COIRESULT
190SYMBOL_VERSION (COIProcessWaitForShutdown, 1) ()
191{
192 COITRACE ("COIProcessWaitForShutdown");
193
44799f87 194 engine_dir = getenv (MIC_DIR_ENV);
5f520819 195 char *mic_index = getenv (MIC_INDEX_ENV);
44799f87 196 assert (engine_dir != NULL && mic_index != NULL);
5f520819
KY
197
198 /* Get engine index. */
199 engine_index = atoi (mic_index);
200
44799f87
IV
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.");
5f520819
KY
215
216 /* Clean up. */
44799f87
IV
217 free (pipe_host2tgt_path);
218 free (pipe_tgt2host_path);
5f520819
KY
219
220 /* Handler. */
221 while (1)
222 {
223 /* Read and execute command. */
44799f87
IV
224 cmd_t cmd = CMD_SHUTDOWN;
225 int cmd_len = read (pipe_host2tgt, &cmd, sizeof (cmd_t));
5f520819 226 if (cmd_len != sizeof (cmd_t) && cmd_len != 0)
44799f87 227 COIERROR ("Cannot read from main pipe.");
5f520819
KY
228
229 switch (cmd)
230 {
231 case CMD_BUFFER_COPY:
232 {
233 uint64_t len;
234 void *dest, *source;
235
236 /* Receive data from host. */
44799f87
IV
237 READ (pipe_host2tgt, &dest, sizeof (void *));
238 READ (pipe_host2tgt, &source, sizeof (void *));
239 READ (pipe_host2tgt, &len, sizeof (uint64_t));
5f520819
KY
240
241 /* Copy. */
242 memcpy (dest, source, len);
243
244 /* Notify host about completion. */
44799f87 245 WRITE (pipe_tgt2host, &cmd, sizeof (cmd_t));
5f520819
KY
246
247 break;
248 }
249 case CMD_BUFFER_MAP:
250 {
251 char *name;
5f520819
KY
252 size_t len;
253 uint64_t buffer_len;
254 void *buffer;
255
256 /* Receive data from host. */
44799f87 257 READ (pipe_host2tgt, &len, sizeof (size_t));
5f520819 258 MALLOC (char *, name, len);
44799f87
IV
259 READ (pipe_host2tgt, name, len);
260 READ (pipe_host2tgt, &buffer_len, sizeof (uint64_t));
5f520819
KY
261
262 /* Open shared memory. */
44799f87 263 int fd = shm_open (name, O_CLOEXEC | O_RDWR, S_IRUSR | S_IWUSR);
5f520819
KY
264 if (fd < 0)
265 COIERROR ("Cannot open shared memory.");
266
267 /* Map shared memory. */
268 buffer = mmap (NULL, buffer_len, PROT_READ | PROT_WRITE,
269 MAP_SHARED, fd, 0);
270 if (buffer == NULL)
271 COIERROR ("Cannot map shared memory.");
272
273 /* Send data to host. */
44799f87
IV
274 WRITE (pipe_tgt2host, &fd, sizeof (int));
275 WRITE (pipe_tgt2host, &buffer, sizeof (void *));
5f520819
KY
276
277 /* Clean up. */
278 free (name);
279
280 break;
281 }
282 case CMD_BUFFER_UNMAP:
283 {
284 int fd;
285 uint64_t buffer_len;
286 void *buffer;
287
288 /* Receive data from host. */
44799f87
IV
289 READ (pipe_host2tgt, &fd, sizeof (int));
290 READ (pipe_host2tgt, &buffer, sizeof (void *));
291 READ (pipe_host2tgt, &buffer_len, sizeof (uint64_t));
5f520819
KY
292
293 /* Unmap buffer. */
294 if (munmap (buffer, buffer_len) < 0)
295 COIERROR ("Cannot unmap shared memory.");
296
297 /* Close shared memory. */
298 if (close (fd) < 0)
299 COIERROR ("Cannot close shared memory file.");
300
301 /* Notify host about completion. */
44799f87 302 WRITE (pipe_tgt2host, &cmd, sizeof (cmd_t));
5f520819
KY
303
304 break;
305 }
306 case CMD_GET_FUNCTION_HANDLE:
307 {
308 char *name;
309 size_t len;
5f520819
KY
310
311 /* Receive data from host. */
44799f87 312 READ (pipe_host2tgt, &len, sizeof (size_t));
5f520819 313 MALLOC (char *, name, len);
44799f87 314 READ (pipe_host2tgt, name, len);
5f520819
KY
315
316 /* Find function. */
44799f87 317 void *ptr = dlsym (RTLD_DEFAULT, name);
5f520819
KY
318 if (ptr == NULL)
319 COIERROR ("Cannot find symbol %s.", name);
320
321 /* Send data to host. */
44799f87 322 WRITE (pipe_tgt2host, &ptr, sizeof (void *));
5f520819
KY
323
324 /* Clean up. */
325 free (name);
326
327 break;
328 }
329 case CMD_OPEN_LIBRARY:
330 {
331 char *lib_path;
332 size_t len;
333
334 /* Receive data from host. */
44799f87 335 READ (pipe_host2tgt, &len, sizeof (size_t));
5f520819 336 MALLOC (char *, lib_path, len);
44799f87 337 READ (pipe_host2tgt, lib_path, len);
5f520819
KY
338
339 /* Open library. */
44799f87 340 void *handle = dlopen (lib_path, RTLD_LAZY | RTLD_GLOBAL);
2eab9666 341 if (handle == NULL)
5f520819
KY
342 COIERROR ("Cannot load %s: %s", lib_path, dlerror ());
343
2eab9666 344 /* Send data to host. */
44799f87 345 WRITE (pipe_tgt2host, &handle, sizeof (void *));
2eab9666 346
5f520819
KY
347 /* Clean up. */
348 free (lib_path);
349
2eab9666
IV
350 break;
351 }
352 case CMD_CLOSE_LIBRARY:
353 {
354 /* Receive data from host. */
355 void *handle;
44799f87 356 READ (pipe_host2tgt, &handle, sizeof (void *));
2eab9666
IV
357
358 dlclose (handle);
359
5f520819
KY
360 break;
361 }
44799f87 362 case CMD_PIPELINE_CREATE:
5f520819 363 {
5f520819 364 /* Receive data from host. */
6fd2e66a
IV
365 uint32_t *pipeline_num;
366 MALLOC (uint32_t *, pipeline_num, sizeof (uint32_t));
44799f87
IV
367 READ (pipe_host2tgt, pipeline_num, sizeof (*pipeline_num));
368
369 /* Create a new thread for the pipeline. */
370 pthread_t thread;
371 if (pthread_create (&thread, NULL, pipeline_thread_routine,
372 pipeline_num))
373 COIERROR ("Cannot create new thread.");
5f520819
KY
374 break;
375 }
376 case CMD_SHUTDOWN:
44799f87
IV
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.");
5f520819
KY
381 return COI_SUCCESS;
382 default:
383 COIERROR ("Unrecognizable command from host.");
384 }
385 }
386
387 return COI_ERROR;
388}
389
390
391
392uint64_t
393SYMBOL_VERSION (COIPerfGetCycleFrequency, 1) ()
394{
395 COITRACE ("COIPerfGetCycleFrequency");
396
397 return (uint64_t) CYCLE_FREQUENCY;
398}
399
400} // extern "C"
401