1 /*
2 /*
3 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
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
11 * copyright notice, this list of conditions and the following
12 * disclaimer in the documentation and/or other materials provided
13 * with the distribution.
14 * * Neither the name of The Linux Foundation nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <sys/ioctl.h>
36 #include <sys/time.h>
37 #include <errno.h>
38 #include <pthread.h>
39
40 #define FARF_ERROR 1
41 //#define FARF_HIGH 1
42 #include "HAP_farf.h"
43 #include "verify.h"
44 #include "remote_priv.h"
45 #include "shared.h"
46 #include "fastrpc_internal.h"
47 #include "fastrpc_apps_user.h"
48 #include "adsp_current_process.h"
49 #include "adsp_current_process1.h"
50 #include "adspmsgd_adsp1.h"
51 #include "remotectl.h"
52 #include "rpcmem.h"
53 #include "AEEstd.h"
54 #include "AEEStdErr.h"
55 #include "AEEQList.h"
56 #include "apps_std.h"
57 #include "platform_libs.h"
58 #include "fastrpc_perf.h"
59
60 #include <stdlib.h>
61 #include <stdio.h>
62 #include <string.h>
63 #include <unistd.h>
64 #include <sys/ioctl.h>
65 #include <errno.h>
66
67 #ifndef _WIN32
68 #include <pthread.h>
69 #include <sys/inotify.h>
70 #include <sys/eventfd.h>
71 #include <poll.h>
72 #include <sys/mman.h>
73 #endif // __WIN32
74
75 #ifndef INT_MAX
76 #define INT_MAX (int)(-1)
77 #endif
78
79 #define ADSPRPC_DEVICE "/dev/fastrpc-adsp"
80 #define SDSPRPC_DEVICE "/dev/fastrpc-sdsp"
81 #define MDSPRPC_DEVICE "/dev/fastrpc-mdsp"
82 #define CDSPRPC_DEVICE "/dev/fastrpc-cdsp"
83
84 /* Secure and default device nodes */
85 #define SECURE_DEVICE "/dev/fastrpc-adsp-secure"
86 #define DEFAULT_DEVICE "/dev/fastrpc-adsp"
87
88 #define INVALID_DOMAIN_ID -1
89 #define INVALID_HANDLE (remote_handle64)(-1)
90 #define INVALID_KEY (pthread_key_t)(-1)
91
92 #define MAX_DMA_HANDLES 256
93
94 #define FASTRPC_TRACE_INVOKE_START "fastrpc_trace_invoke_start"
95 #define FASTRPC_TRACE_INVOKE_END "fastrpc_trace_invoke_end"
96 #define FASTRPC_TRACE_LOG(k, handle, sc) if(fastrpc_trace == 1 && !IS_STATIC_HANDLE(handle)) { \
97 FARF(ALWAYS, "%s: sc 0x%x", (k), (sc)); } \
98
99 #define FASTRPC_MODE_DEBUG (0x1)
100 #define FASTRPC_MODE_PTRACE (0x2)
101 #define FASTRPC_MODE_CRC (0x4)
102 #define FASTRPC_MODE_ADAPTIVE_QOS (0x10)
103
104 #define FASTRPC_DISABLE_QOS 0
105 #define FASTRPC_PM_QOS 1
106 #define FASTRPC_ADAPTIVE_QOS 2
107
108 /* FastRPC mode for Unsigned module */
109 #define FASTRPC_MODE_UNSIGNED_MODULE (0x8)
110
111 #define M_CRCLIST (64)
112 #define IS_DEBUG_MODE_ENABLED(var) (var & FASTRPC_MODE_DEBUG)
113 #define IS_CRC_CHECK_ENABLED(var) (var & FASTRPC_MODE_CRC)
114 #define POLY32 0x04C11DB7 // G(x) = x^32+x^26+x^23+x^22+x^16+x^12
115 // +x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
116
117 #define FASTRPC_LATENCY_START (1)
118 #define FASTRPC_LATENCY_STOP (0)
119 #define FASTRPC_LATENCY_EXIT (2)
120 #define FASTRPC_LATENCY_VOTE_ON (1)
121 #define FASTRPC_LATENCY_VOTE_OFF (0)
122 #define FASTRPC_LATENCY_WAIT_TIME (1)
123
124 #ifdef ANDROID_P
125 #define FASTRPC_PROP_PROCESS "vendor.fastrpc.process.attrs"
126 #define FASTRPC_PROP_TRACE "vendor.fastrpc.debug.trace"
127 #define FASTRPC_PROP_TESTSIG "vendor.fastrpc.debug.testsig"
128 #else
129 #define FASTRPC_PROP_PROCESS "fastrpc.process.attrs"
130 #define FASTRPC_PROP_TRACE "fastrpc.debug.trace"
131 #define FASTRPC_PROP_TESTSIG "fastrpc.debug.testsig"
132 #endif
133
134 #define DEFAULT_UTHREAD_PRIORITY 0xC0
135 #define DEFAULT_UTHREAD_STACK_SIZE 16*1024
136
137 /* Shell prefix for signed and unsigned */
138 const char* const SIGNED_SHELL = "fastrpc_shell_";
139 const char* const UNSIGNED_SHELL = "fastrpc_shell_unsigned_";
140
141 struct fastrpc_latency {
142 int adaptive_qos;
143 int state;
144 int exit;
145 int invoke;
146 int vote;
147 int dev;
148 int wait_time;
149 int latency;
150 pthread_t thread;
151 pthread_mutex_t mut;
152 pthread_mutex_t wmut;
153 pthread_cond_t cond;
154 };
155
156 struct fastrpc_thread_params {
157 uint32_t prio;
158 uint32_t stack_size;
159 int reqID;
160 pthread_t thread;
161 };
162
163 struct mem_to_fd {
164 QNode qn;
165 void* buf;
166 int size;
167 int fd;
168 int nova;
169 int attr;
170 int refcount;
171 };
172
173 struct mem_to_fd_list {
174 QList ql;
175 pthread_mutex_t mut;
176 };
177
178 struct dma_handle_info {
179 int fd;
180 int len;
181 int used;
182 uint32_t attr;
183 };
184
185 struct handle_info {
186 QNode qn;
187 struct handle_list *hlist;
188 remote_handle64 local;
189 remote_handle64 remote;
190 };
191
192 struct handle_list {
193 QList ql;
194 pthread_mutex_t mut;
195 pthread_mutex_t init;
196 int dsppd;
197 char *dsppdname;
198 int domainsupport;
199 int nondomainsupport;
200 int kmem_support;
201 int dev;
202 int initialized;
203 int setmode;
204 uint32_t mode;
205 uint32_t info;
206 void* pdmem;
207 remote_handle64 cphandle;
208 remote_handle64 msghandle;
209 int procattrs;
210 struct fastrpc_latency qos;
211 struct fastrpc_thread_params th_params;
212 int unsigned_module;
213 };
214
215 static struct mem_to_fd_list fdlist;
216 static struct handle_list *hlist = 0;
217 static struct dma_handle_info dhandles[MAX_DMA_HANDLES];
218 static int dma_handle_count = 0;
219 static pthread_key_t tlsKey = INVALID_KEY;
220
221 static int fastrpc_trace = 0;
222
223 extern int listener_android_domain_init(int domain);
224 extern void listener_android_domain_deinit(int domain);
225 extern int initFileWatcher(int domain);
226 extern void deinitFileWatcher(int domain);
227 static int open_dev(int domain);
228 static void domain_deinit(int domain);
229 static int __attribute__((constructor)) fastrpc_init_once(void);
230 remote_handle64 get_adsp_current_process1_handle(int domain);
231 remote_handle64 get_adspmsgd_adsp1_handle(int domain);
232 static int remote_unmap_fd(void *buf, int size, int fd, int attr);
233
234 static uint32_t crc_table[256];
235
GenCrc32Tab(uint32_t GenPoly,uint32_t * crctab)236 static void GenCrc32Tab(uint32_t GenPoly, uint32_t *crctab)
237 {
238 uint32_t crc;
239 int i, j;
240
241 for (i = 0; i < 256; i++) {
242 crc = i<<24;
243 for (j = 0; j <8; j++) {
244 crc = (crc << 1) ^ (crc & 0x80000000 ? GenPoly : 0);
245 }
246 crctab[i] = crc;
247 }
248 }
249
crc32_lut(unsigned char * data,int nbyte,uint32_t * crctab)250 static uint32_t crc32_lut(unsigned char *data, int nbyte, uint32_t *crctab)
251 {
252 uint32_t crc = 0;
253 if (!data || !crctab)
254 return 0;
255
256 while(nbyte--) {
257 crc = (crc<<8) ^ crctab[(crc>>24) ^ *data++];
258 }
259 return crc;
260 }
261
fastrpc_latency_refinc(struct fastrpc_latency * qp)262 int fastrpc_latency_refinc(struct fastrpc_latency *qp) {
263 int nErr = 0;
264
265 if (qp == NULL || qp->state == FASTRPC_LATENCY_STOP)
266 goto bail;
267 qp->invoke++;
268 if (qp->vote == FASTRPC_LATENCY_VOTE_OFF) {
269 pthread_mutex_lock(&qp->wmut);
270 pthread_cond_signal(&qp->cond);
271 pthread_mutex_unlock(&qp->wmut);
272 }
273 bail:
274 return 0;
275 }
276
fastrpc_latency_thread_handler(void * arg)277 static void* fastrpc_latency_thread_handler(void* arg) {
278 FARF(ALWAYS, "Unsupported: rpc latency thread exited");
279 return NULL;
280 }
281
fastrpc_latency_init(int dev,struct fastrpc_latency * qos)282 int fastrpc_latency_init(int dev, struct fastrpc_latency *qos) {
283 int i, nErr = 0;
284
285 VERIFY(qos && dev != -1);
286
287 qos->dev = dev;
288 qos->state = FASTRPC_LATENCY_STOP;
289 qos->thread = 0;
290 qos->wait_time = FASTRPC_LATENCY_WAIT_TIME;
291 pthread_mutex_init(&qos->mut, 0);
292 pthread_mutex_init(&qos->wmut, 0);
293 pthread_cond_init(&qos->cond, NULL);
294 bail:
295 return nErr;
296 }
297
fastrpc_latency_deinit(struct fastrpc_latency * qos)298 int fastrpc_latency_deinit(struct fastrpc_latency *qos) {
299 int nErr = 0;
300
301 VERIFY(qos);
302 if (qos->state == FASTRPC_LATENCY_START) {
303 pthread_mutex_lock(&qos->wmut);
304 qos->exit = FASTRPC_LATENCY_EXIT;
305 pthread_cond_signal(&qos->cond);
306 pthread_mutex_unlock(&qos->wmut);
307 if(qos->thread) {
308 pthread_join(qos->thread, 0);
309 qos->thread = 0;
310 FARF(ALWAYS, "latency thread joined");
311 }
312 qos->state = FASTRPC_LATENCY_STOP;
313 pthread_mutex_destroy(&qos->mut);
314 pthread_mutex_destroy(&qos->wmut);
315 }
316 bail:
317 return 0;
318 }
319
320 /* Thread function that will be invoked to update remote user PD parameters */
fastrpc_set_remote_uthread_params(void * arg)321 static void *fastrpc_set_remote_uthread_params(void *arg)
322 {
323 int nErr = AEE_SUCCESS, paramsLen = 2;
324 struct fastrpc_thread_params *th_params = (struct fastrpc_thread_params*)arg;
325
326 VERIFY(th_params != NULL);
327 VERIFY(AEE_SUCCESS == (nErr = remotectl_set_param(th_params->reqID, (uint32_t*)th_params, paramsLen)));
328 bail:
329 if (nErr != AEE_SUCCESS)
330 FARF(ERROR, "Error 0x%x: setting remote user thread parameters failed !", nErr);
331 return NULL;
332 }
333
remote_register_fd_attr(int fd,int size,int attr)334 void *remote_register_fd_attr(int fd, int size, int attr) {
335 int nErr = AEE_SUCCESS;
336 void *po = NULL;
337 void *buf = (void*)-1;
338 struct mem_to_fd* tofd = 0;
339
340 VERIFY(!fastrpc_init_once());
341 VERIFYC(NULL != (tofd = calloc(1, sizeof(*tofd))), AEE_ENOMEMORY);
342 QNode_CtorZ(&tofd->qn);
343 VERIFYC((void*)-1 != (buf = mmap(0, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0)), AEE_EMMAP);
344 tofd->buf = buf;
345 tofd->size = size;
346 tofd->fd = fd;
347 tofd->nova = 1;
348 tofd->attr = attr;
349
350 pthread_mutex_lock(&fdlist.mut);
351 QList_AppendNode(&fdlist.ql, &tofd->qn);
352 pthread_mutex_unlock(&fdlist.mut);
353
354 tofd = 0;
355 po = buf;
356 buf = (void*)-1;
357 bail:
358 if(buf != (void*)-1)
359 munmap(buf, size);
360 if(tofd)
361 {
362 free(tofd);
363 tofd = NULL;
364 }
365 if(nErr != AEE_SUCCESS) {
366 FARF(ERROR,"Error %x: remote register fd fails for fd %x, size %x\n", nErr, fd, size);
367 }
368 return po;
369 }
370
remote_register_fd(int fd,int size)371 void *remote_register_fd(int fd, int size) {
372 return remote_register_fd_attr(fd, size, 0);
373 }
374
remote_register_buf_common(void * buf,int size,int fd,int attr)375 static void remote_register_buf_common(void* buf, int size, int fd, int attr) {
376 int nErr = 0;
377 VERIFY(!fastrpc_init_once());
378 if(fd != -1) {
379 struct mem_to_fd* tofd;
380 int fdfound = 0;
381 QNode* pn, *pnn;
382
383 pthread_mutex_lock(&fdlist.mut);
384 QLIST_NEXTSAFE_FOR_ALL(&fdlist.ql, pn, pnn) {
385 tofd = STD_RECOVER_REC(struct mem_to_fd, qn, pn);
386 if(tofd->buf == buf && tofd->size == size && tofd->fd == fd) {
387 fdfound = 1;
388 if(attr)
389 tofd->attr = attr;
390 tofd->refcount++;
391 break;
392 }
393 }
394 pthread_mutex_unlock(&fdlist.mut);
395 if(!fdfound) {
396 VERIFYC(NULL != (tofd = calloc(1, sizeof(*tofd))), AEE_ENOMEMORY);
397 QNode_CtorZ(&tofd->qn);
398 tofd->buf = buf;
399 tofd->size = size;
400 tofd->fd = fd;
401 if (attr)
402 tofd->attr = attr;
403 tofd->refcount++;
404 pthread_mutex_lock(&fdlist.mut);
405 QList_AppendNode(&fdlist.ql, &tofd->qn);
406 pthread_mutex_unlock(&fdlist.mut);
407 }
408 } else {
409 QNode* pn, *pnn;
410 pthread_mutex_lock(&fdlist.mut);
411 QLIST_NEXTSAFE_FOR_ALL(&fdlist.ql, pn, pnn) {
412 struct mem_to_fd* tofd = STD_RECOVER_REC(struct mem_to_fd, qn, pn);
413 if(tofd->buf == buf && tofd->size == size) {
414 tofd->refcount--;
415 if(tofd->refcount <= 0) {
416 QNode_DequeueZ(&tofd->qn);
417 if (tofd->attr & FASTRPC_ATTR_KEEP_MAP) {
418 remote_unmap_fd(tofd->buf, tofd->size, tofd->fd, tofd->attr);
419 }
420 if(tofd->nova) {
421 munmap(tofd->buf, tofd->size);
422 }
423 free(tofd);
424 tofd = NULL;
425 }
426 break;
427 }
428 }
429 pthread_mutex_unlock(&fdlist.mut);
430 }
431 bail:
432 if(nErr != AEE_SUCCESS) {
433 FARF(ERROR, "Error %x: remote_register_buf failed buf %p, size %d, fd %x", nErr, buf, size, fd);
434 }
435 return;
436 }
437
remote_register_buf(void * buf,int size,int fd)438 void remote_register_buf(void* buf, int size, int fd) {
439 return remote_register_buf_common(buf, size, fd, 0);
440 }
441
remote_register_buf_attr(void * buf,int size,int fd,int attr)442 void remote_register_buf_attr(void* buf, int size, int fd, int attr) {
443 return remote_register_buf_common(buf, size, fd, attr);
444 }
445
remote_register_dma_handle_attr(int fd,uint32_t len,uint32_t attr)446 int remote_register_dma_handle_attr(int fd, uint32_t len, uint32_t attr) {
447 int nErr = AEE_SUCCESS, i;
448 int fd_found = 0;
449
450 if (attr && attr != FASTRPC_ATTR_NOMAP) {
451 FARF(ERROR, "Error: %s failed, unsupported attribute 0x%x", __func__, attr);
452 return AEE_EBADPARM;
453 }
454 VERIFY(!fastrpc_init_once());
455
456 pthread_mutex_lock(&fdlist.mut);
457 for(i = 0; i < dma_handle_count; i++) {
458 if(dhandles[i].used && dhandles[i].fd == fd) {
459 /* If fd already present in handle list, then just update attribute only if its zero */
460 if(!dhandles[i].attr) {
461 dhandles[i].attr = attr;
462 }
463 fd_found = 1;
464 break;
465 }
466 }
467 pthread_mutex_unlock(&fdlist.mut);
468
469 if (fd_found) {
470 return AEE_SUCCESS;
471 }
472
473 pthread_mutex_lock(&fdlist.mut);
474 for(i = 0; i < dma_handle_count; i++) {
475 if(!dhandles[i].used) {
476 dhandles[i].fd = fd;
477 dhandles[i].len = len;
478 dhandles[i].used = 1;
479 dhandles[i].attr = attr;
480 break;
481 }
482 }
483 if(i == dma_handle_count) {
484 if(dma_handle_count >= MAX_DMA_HANDLES) {
485 FARF(ERROR, "Error: %s: DMA handle list is already full (count %d)", __func__, dma_handle_count);
486 nErr = AEE_EOUTOFHANDLES;
487 } else {
488 dhandles[dma_handle_count].fd = fd;
489 dhandles[dma_handle_count].len = len;
490 dhandles[dma_handle_count].used = 1;
491 dhandles[dma_handle_count].attr = attr;
492 dma_handle_count++;
493 }
494 }
495 pthread_mutex_unlock(&fdlist.mut);
496
497 bail:
498 if(nErr) {
499 FARF(ERROR, "Error 0x%x: %s failed for fd 0x%x, len %d, attr 0x%x", nErr, __func__, fd, len, attr);
500 }
501 return nErr;
502 }
503
remote_register_dma_handle(int fd,uint32_t len)504 int remote_register_dma_handle(int fd, uint32_t len) {
505 return remote_register_dma_handle_attr(fd, len, 0);
506 }
507
unregister_dma_handle(int fd,uint32_t * len,uint32_t * attr)508 static void unregister_dma_handle(int fd, uint32_t *len, uint32_t *attr) {
509 int i, last_used = 0;
510
511 *len = 0;
512 *attr = 0;
513
514 pthread_mutex_lock(&fdlist.mut);
515 for(i = 0; i < dma_handle_count; i++) {
516 if(dhandles[i].used) {
517 if(dhandles[i].fd == fd) {
518 dhandles[i].used = 0;
519 *len = dhandles[i].len;
520 *attr = dhandles[i].attr;
521 if(i == (dma_handle_count - 1)) {
522 dma_handle_count = last_used + 1;
523 }
524 break;
525 } else {
526 last_used = i;
527 }
528 }
529 }
530 pthread_mutex_unlock(&fdlist.mut);
531 }
532
fdlist_fd_from_buf(void * buf,int bufLen,int * nova,void ** base,int * attr,int * ofd)533 static int fdlist_fd_from_buf(void* buf, int bufLen, int* nova, void** base, int* attr, int* ofd) {
534 QNode* pn;
535 int fd = -1;
536 pthread_mutex_lock(&fdlist.mut);
537 QLIST_FOR_ALL(&fdlist.ql, pn) {
538 if(fd != -1) {
539 break;
540 } else {
541 struct mem_to_fd* tofd = STD_RECOVER_REC(struct mem_to_fd, qn, pn);
542 if(STD_BETWEEN(buf, tofd->buf, (unsigned long)tofd->buf + tofd->size)) {
543 if(STD_BETWEEN((unsigned long)buf + bufLen -1, tofd->buf, (unsigned long)tofd->buf + tofd->size)) {
544 fd = tofd->fd;
545 *nova = tofd->nova;
546 *base = tofd->buf;
547 *attr = tofd->attr;
548 } else {
549 pthread_mutex_unlock(&fdlist.mut);
550 FARF(ERROR,"Error %x: Mismatch in buffer address(%p) or size(%x) to the registered FD(%x), address(%p) and size(%x)\n", AEE_EBADPARM, buf, bufLen, tofd->fd, tofd->buf, tofd->size);
551 return AEE_EBADPARM;
552 }
553 }
554 }
555 }
556 *ofd = fd;
557 pthread_mutex_unlock(&fdlist.mut);
558 return 0;
559 }
560
verify_local_handle(remote_handle64 local)561 static int verify_local_handle(remote_handle64 local) {
562 struct handle_info* hinfo = (struct handle_info*)(uintptr_t)local;
563 int nErr = AEE_SUCCESS;
564
565 VERIFYC(hinfo, AEE_EMEMPTR);
566 VERIFYC((hinfo->hlist >= &hlist[0]) && (hinfo->hlist < &hlist[NUM_DOMAINS_EXTEND]), AEE_EMEMPTR);
567 VERIFYC(QNode_IsQueuedZ(&hinfo->qn), AEE_ENOSUCHHANDLE);
568 bail:
569 if (nErr != AEE_SUCCESS) {
570 FARF(HIGH, "Error %x: verify local handle failed. handle %p\n", nErr, &local);
571 }
572 return nErr;
573 }
574
get_domain_from_handle(remote_handle64 local,int * domain)575 static int get_domain_from_handle(remote_handle64 local, int *domain) {
576 struct handle_info *hinfo = (struct handle_info*)(uintptr_t)local;
577 int dom, nErr = AEE_SUCCESS;
578
579 VERIFY(AEE_SUCCESS == (nErr = verify_local_handle(local)));
580 dom = (int)(hinfo->hlist - &hlist[0]);
581 VERIFYC((dom >= 0) && (dom < NUM_DOMAINS_EXTEND), AEE_EINVALIDDOMAIN);
582 *domain = dom;
583 bail:
584 if (nErr != AEE_SUCCESS) {
585 FARF(HIGH, "Error %x: get domain from handle failed. handle %p\n", nErr, &local);
586 }
587 return nErr;
588 }
589
get_domain_from_name(const char * uri)590 static int get_domain_from_name(const char *uri) {
591 int domain = DEFAULT_DOMAIN_ID;
592
593 if(uri) {
594 if(std_strstr(uri, ADSP_DOMAIN)) {
595 domain = ADSP_DOMAIN_ID;
596 } else if(std_strstr(uri, MDSP_DOMAIN)) {
597 domain = MDSP_DOMAIN_ID;
598 } else if(std_strstr(uri, SDSP_DOMAIN)) {
599 domain = SDSP_DOMAIN_ID;
600 } else if(std_strstr(uri, CDSP_DOMAIN)) {
601 domain = CDSP_DOMAIN_ID;
602 } else {
603 domain = INVALID_DOMAIN_ID;
604 FARF(ERROR, "invalid domain uri: %s\n", uri);
605 }
606 if (std_strstr(uri, FASTRPC_SESSION_URI)) {
607 domain = domain | FASTRPC_SESSION_ID1;
608 }
609 }
610 VERIFY_IPRINTF("get_domain_from_name: %d\n", domain);
611 return domain;
612 }
613
alloc_handle(int domain,remote_handle64 remote,struct handle_info ** info)614 static int alloc_handle(int domain, remote_handle64 remote, struct handle_info **info) {
615 struct handle_info* hinfo;
616 int nErr = AEE_SUCCESS;
617
618 VERIFYC(NULL != (hinfo = malloc(sizeof(*hinfo))), AEE_ENOMEMORY);
619 hinfo->local = (remote_handle64)(uintptr_t)hinfo;
620 hinfo->remote = remote;
621 hinfo->hlist = &hlist[domain];
622 QNode_CtorZ(&hinfo->qn);
623 pthread_mutex_lock(&hlist[domain].mut);
624 QList_PrependNode(&hlist[domain].ql, &hinfo->qn);
625 pthread_mutex_unlock(&hlist[domain].mut);
626 *info = hinfo;
627
628 bail:
629 if (nErr != AEE_SUCCESS) {
630 FARF(ERROR, "Error %x: alloc handle failed. domain %d\n", nErr, domain);
631 }
632 return nErr;
633 }
634
635 #define IS_CONST_HANDLE(h) (((h) < 0xff) ? 1 : 0)
is_last_handle(int domain)636 static int is_last_handle(int domain) {
637 QNode* pn;
638 int nErr = AEE_SUCCESS, empty = 0;
639
640 pthread_mutex_lock(&hlist[domain].mut);
641 if(!(hlist[domain].domainsupport && !hlist[domain].nondomainsupport)){
642 VERIFY_IPRINTF("Error %x: hlist[domain].domainsupport && !hlist[domain].nondomainsupport\n",AEE_EBADDOMAIN);
643 goto bail;
644 }
645 empty = 1;
646 if (!QList_IsEmpty(&hlist[domain].ql)) {
647 empty = 1;
648 QLIST_FOR_ALL(&hlist[domain].ql, pn) {
649 struct handle_info* hi = STD_RECOVER_REC(struct handle_info, qn, pn);
650 empty = empty & IS_CONST_HANDLE(hi->remote);
651 if(!empty)
652 break;
653 }
654 }
655 bail:
656 pthread_mutex_unlock(&hlist[domain].mut);
657 if (nErr != AEE_SUCCESS) {
658 VERIFY_IPRINTF("Error %x: is_last_handle %d failed\n", nErr, domain);
659 }
660 return empty;
661 }
662
free_handle(remote_handle64 local)663 static int free_handle(remote_handle64 local) {
664 struct handle_info* hinfo = (struct handle_info*)(uintptr_t)local;
665 int nErr = AEE_SUCCESS;
666
667 VERIFY(AEE_SUCCESS == (nErr = verify_local_handle(local)));
668 pthread_mutex_lock(&hinfo->hlist->mut);
669 QNode_DequeueZ(&hinfo->qn);
670 pthread_mutex_unlock(&hinfo->hlist->mut);
671 free(hinfo);
672 hinfo = NULL;
673 bail:
674 if (nErr != AEE_SUCCESS) {
675 FARF(ERROR, "Error %x: free handle failed %p\n", nErr, &local);
676 }
677 return nErr;
678 }
679
get_handle_remote(remote_handle64 local,remote_handle64 * remote)680 static int get_handle_remote(remote_handle64 local, remote_handle64 *remote) {
681 struct handle_info* hinfo = (struct handle_info*)(uintptr_t)local;
682 int nErr = AEE_SUCCESS;
683
684 VERIFY(AEE_SUCCESS == (nErr = verify_local_handle(local)));
685 *remote = hinfo->remote;
686 bail:
687 if (nErr != AEE_SUCCESS) {
688 FARF(ERROR, "Error %x: get handle remote failed %p\n", nErr, &local);
689 }
690 return nErr;
691 }
692
set_thread_context(int domain)693 void set_thread_context(int domain) {
694 if(tlsKey != INVALID_KEY) {
695 pthread_setspecific(tlsKey, (void*)&hlist[domain]);
696 }
697 }
698
get_domain_id()699 int get_domain_id() {
700 int domain;
701 struct handle_list* list;
702 list = (struct handle_list*)pthread_getspecific(tlsKey);
703 if(list && hlist){
704 domain = (int)(list - &hlist[0]);
705 }else{
706 domain = DEFAULT_DOMAIN_ID;
707 }
708 return domain;
709 }
710
is_smmu_enabled(void)711 int is_smmu_enabled(void) {
712 struct handle_list* list;
713 int domain, nErr = 0;
714
715 list = (struct handle_list*)pthread_getspecific(tlsKey);
716 if (list) {
717 domain = (int)(list - &hlist[0]);
718 VERIFY((domain >= 0) && (domain < NUM_DOMAINS_EXTEND));
719 return hlist[domain].info & FASTRPC_INFO_SMMU;
720 }
721 bail:
722 return 0;
723 }
724
fdlist_fd_to_buf(void * buf)725 static int fdlist_fd_to_buf(void *buf)
726 {
727 QNode *pn;
728 int fd = -1;
729 pthread_mutex_lock(&fdlist.mut);
730 QLIST_FOR_ALL(&fdlist.ql, pn)
731 {
732 if (fd != -1)
733 {
734 break;
735 }
736 else
737 {
738 struct mem_to_fd *tofd = STD_RECOVER_REC(struct mem_to_fd, qn, pn);
739 if (STD_BETWEEN(buf, tofd->buf, (unsigned long)tofd->buf + tofd->size))
740 {
741 fd = tofd->fd;
742 }
743 }
744 }
745 pthread_mutex_unlock(&fdlist.mut);
746 return fd;
747 }
748
remote_handle_invoke_domain(int domain,remote_handle handle,uint32_t sc,remote_arg * pra)749 int remote_handle_invoke_domain(int domain, remote_handle handle, uint32_t sc, remote_arg* pra) {
750 struct fastrpc_invoke invoke;
751 struct fastrpc_invoke_args *args;
752 int bufs, i, req, nErr = 0;
753 int dev;
754 VERIFY(dev != -1);
755 invoke.handle = handle;
756 invoke.sc = sc;
757 struct handle_list* list;
758
759 VERIFYC(-1 != (dev = open_dev(domain)), AEE_EINVALIDDEVICE);
760 list = &hlist[domain];
761 if(0 == pthread_getspecific(tlsKey)) {
762 pthread_setspecific(tlsKey, (void*)list);
763 }
764 bufs = REMOTE_SCALARS_LENGTH(sc);
765
766 args = malloc(bufs * sizeof(*args));
767 if (!args)
768 return -ENOMEM;
769
770 invoke.args = (__u64)(uintptr_t)args;
771
772 for (i = 0; i < bufs; i++)
773 {
774 args[i].reserved = 0;
775 args[i].length = pra[i].buf.nLen;
776 args[i].ptr = (__u64)(uintptr_t)pra[i].buf.pv;
777
778
779 if (pra[i].buf.nLen)
780 {
781 FARF(HIGH,"debug:sc:%x,handle:%x,len:%llx\n",sc,pra[i].buf.nLen);
782 args[i].fd = fdlist_fd_to_buf(pra[i].buf.pv);
783 }
784 else
785 {
786 args[i].fd = -1;
787 }
788 }
789 req = FASTRPC_IOCTL_INVOKE;
790
791 if (0 == pthread_getspecific(tlsKey))
792 {
793 pthread_setspecific(tlsKey, (void *)1);
794 }
795 FARF(HIGH,"debug:sc:%x,handle:%x\n",sc,handle);
796 nErr = ioctl(dev, req, (unsigned long)&invoke);
797 free(args);
798 bail:
799 return nErr;
800 }
801
remote_handle_invoke(remote_handle handle,uint32_t sc,remote_arg * pra)802 int remote_handle_invoke(remote_handle handle, uint32_t sc, remote_arg* pra) {
803 struct handle_list* list;
804 int domain = DEFAULT_DOMAIN_ID, nErr = AEE_SUCCESS;
805
806 VERIFYC(handle != (remote_handle)-1, AEE_EBADHANDLE);
807 list = (struct handle_list*)pthread_getspecific(tlsKey);
808
809 if(list) {
810 domain = (int)(list - &hlist[0]);
811 VERIFYC((domain >= 0) && (domain < NUM_DOMAINS_EXTEND), AEE_EINVALIDDOMAIN);
812 } else {
813 domain = DEFAULT_DOMAIN_ID;
814 }
815 VERIFY(AEE_SUCCESS == (nErr = remote_handle_invoke_domain(domain, handle, sc, pra)));
816 bail:
817 if (nErr != AEE_SUCCESS) {
818 FARF(HIGH, "Error %x: remote handle invoke failed. domain %d, handle %x, sc %x, pra %p\n", nErr, domain, handle, sc, pra);
819 }
820 return nErr;
821 }
822
remote_handle64_invoke(remote_handle64 local,uint32_t sc,remote_arg * pra)823 int remote_handle64_invoke(remote_handle64 local, uint32_t sc, remote_arg* pra) {
824 remote_handle64 remote;
825 int nErr = AEE_SUCCESS, domain = DEFAULT_DOMAIN_ID;
826
827 VERIFYC(local != (remote_handle64)-1, AEE_EBADHANDLE);
828 VERIFY(AEE_SUCCESS == (nErr = get_domain_from_handle(local, &domain)));
829 VERIFY(AEE_SUCCESS == (nErr = get_handle_remote(local, &remote)));
830 VERIFY(AEE_SUCCESS == (nErr = remote_handle_invoke_domain(domain, remote, sc, pra)));
831 bail:
832 if (nErr != AEE_SUCCESS) {
833 FARF(HIGH, "Error %x: remote handle64 invoke failed. domain %d, handle %p, sc %x, pra %p\n", nErr, domain, &local, sc, pra);
834 }
835 return nErr;
836 }
837
838 int listener_android_geteventfd(int domain, int *fd);
remote_handle_open_domain(int domain,const char * name,remote_handle * ph)839 int remote_handle_open_domain(int domain, const char* name, remote_handle *ph)
840 {
841 char dlerrstr[255];
842 int dlerr = 0, nErr = AEE_SUCCESS;
843 if (!std_strncmp(name, ITRANSPORT_PREFIX "geteventfd", std_strlen(ITRANSPORT_PREFIX "geteventfd"))) {
844 FARF(HIGH, "getting event fd \n");
845 return listener_android_geteventfd(domain, (int *)ph);
846 }
847 if (!std_strncmp(name, ITRANSPORT_PREFIX "attachguestos", std_strlen(ITRANSPORT_PREFIX "attachguestos"))) {
848 FARF(HIGH, "setting attach mode to guestos : %d\n", domain);
849 VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
850 hlist[domain].dsppd = GUEST_OS;
851 return AEE_SUCCESS;
852 }
853 if (!std_strncmp(name, ITRANSPORT_PREFIX "createstaticpd", std_strlen(ITRANSPORT_PREFIX "createstaticpd"))) {
854 FARF(HIGH, "creating static pd on domain: %d\n", domain);
855 VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
856 const char *pdName = name + std_strlen(ITRANSPORT_PREFIX "createstaticpd:");
857 hlist[domain].dsppdname = (char *)malloc((std_strlen(pdName) + 1)*(sizeof(char)));
858 VERIFYC(NULL != hlist[domain].dsppdname, AEE_ENOMEMORY);
859 std_strlcpy(hlist[domain].dsppdname, pdName, std_strlen(pdName) + 1);
860 if (!std_strncmp(pdName, "audiopd", std_strlen("audiopd"))) {
861 hlist[domain].dsppd = STATIC_USER_PD;
862 } else if (!std_strncmp(pdName, "sensorspd", std_strlen("sensorspd"))) {
863 hlist[domain].dsppd = ATTACH_SENSORS_PD;
864 } else if (!std_strncmp(pdName, "rootpd", std_strlen("rootpd"))) {
865 hlist[domain].dsppd = GUEST_OS_SHARED;
866 }
867 return AEE_SUCCESS;
868 }
869 if (std_strbegins(name, ITRANSPORT_PREFIX "attachuserpd")) {
870 FARF(HIGH, "setting attach mode to userpd : %d\n", domain);
871 VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
872 hlist[domain].dsppd = USER_PD;
873 return AEE_SUCCESS;
874 }
875 VERIFYC(-1 != open_dev(domain), AEE_EINVALIDDEVICE);
876 FARF(HIGH, "Name of the shared object to open %s\n", name);
877 VERIFY(AEE_SUCCESS == (nErr = remotectl_open(name, (int*)ph, dlerrstr, sizeof(dlerrstr), &dlerr)));
878 VERIFY(AEE_SUCCESS == (nErr = dlerr));
879
880 bail:
881 if(dlerr != 0) {
882 FARF(ERROR, "Error %x: remote handle open domain failed. domain %d, name %s, dlerror %s\n", nErr, domain, name, dlerrstr);
883 }
884 if (nErr != 0)
885 if (hlist[domain].dsppdname != NULL)
886 {
887 free(hlist[domain].dsppdname);
888 hlist[domain].dsppdname = NULL;
889 }
890 return nErr;
891 }
892
remote_handle_open(const char * name,remote_handle * ph)893 int remote_handle_open(const char* name, remote_handle *ph) {
894 int nErr = 0, domain;
895 domain = DEFAULT_DOMAIN_ID;
896 VERIFY(!remote_handle_open_domain(domain, name, ph));
897 hlist[domain].nondomainsupport = 1;
898 bail:
899 return nErr;
900 }
901
remote_handle64_open(const char * name,remote_handle64 * ph)902 int remote_handle64_open(const char* name, remote_handle64 *ph)
903 {
904 struct handle_info* hinfo = 0;
905 remote_handle h = 0;
906 int domain, nErr = 0;
907
908 domain = get_domain_from_name(name);
909 VERIFYC(domain >= 0, AEE_EINVALIDDOMAIN);
910 VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
911 VERIFY(AEE_SUCCESS == (nErr = remote_handle_open_domain(domain, name, &h)));
912 hlist[domain].domainsupport = 1;
913 VERIFY(AEE_SUCCESS == (nErr = alloc_handle(domain, h, &hinfo)));
914 *ph = hinfo->local;
915 bail:
916 if(nErr) {
917 if(h)
918 remote_handle_close(h);
919 FARF(HIGH, "Error %x: remote handle64 open failed. name %s\n", nErr, name);
920 }
921 return nErr;
922 }
923
remote_handle_close(remote_handle h)924 int remote_handle_close(remote_handle h)
925 {
926 char dlerrstr[255];
927 int dlerr = 0, nErr = AEE_SUCCESS;
928
929 VERIFY(AEE_SUCCESS == (nErr = remotectl_close(h, dlerrstr, sizeof(dlerrstr), &dlerr)));
930 VERIFY(AEE_SUCCESS == (nErr = dlerr));
931 bail:
932 if (nErr != AEE_SUCCESS) {
933 FARF(HIGH, "Error %x: remote handle close failed. error %s\n", nErr, dlerrstr);
934 }
935 return nErr;
936 }
937
remote_handle64_close(remote_handle64 handle)938 int remote_handle64_close(remote_handle64 handle) {
939 remote_handle64 remote;
940 int domain, nErr = AEE_SUCCESS;
941
942 VERIFY(AEE_SUCCESS == (nErr = get_domain_from_handle(handle, &domain)));
943 VERIFY(AEE_SUCCESS == (nErr = get_handle_remote(handle, &remote)));
944 set_thread_context(domain);
945 VERIFY(AEE_SUCCESS == (nErr = remote_handle_close((remote_handle)remote)));
946 bail:
947 free_handle(handle);
948 if (is_last_handle(domain)) {
949 domain_deinit(domain);
950 }
951 if (nErr != AEE_SUCCESS) {
952 FARF(HIGH, "Error %x: remote handle64 close failed.\n", nErr);
953 }
954 return nErr;
955 }
956
manage_pm_qos(int domain,remote_handle64 h,uint32_t enable,uint32_t latency)957 int manage_pm_qos(int domain, remote_handle64 h, uint32_t enable, uint32_t latency) {
958 int nErr = AEE_SUCCESS;
959 struct fastrpc_latency *qos;
960 int state = 0;
961
962 if (h == -1) {
963 /* Handle will be -1 in non-domains invocation. Create session if necessary */
964 if (!hlist || (hlist && hlist[domain].dev == -1))
965 VERIFYC(-1 != open_dev(domain), AEE_EINVALIDDEVICE);
966 } else {
967 /* If the multi-domain handle is valid, then verify that session is created already */
968 VERIFY(hlist[domain].dev != -1);
969 }
970 qos = &hlist[domain].qos;
971 VERIFY(qos);
972 if (qos->exit == FASTRPC_LATENCY_EXIT)
973 goto bail;
974 pthread_mutex_lock(&qos->mut);
975 state = qos->state;
976 qos->latency = latency;
977 pthread_mutex_unlock(&qos->mut);
978
979 if (!enable && state == FASTRPC_LATENCY_START) {
980 qos->exit = FASTRPC_LATENCY_EXIT;
981 pthread_mutex_lock(&qos->wmut);
982 pthread_cond_signal(&qos->cond);
983 pthread_mutex_unlock(&qos->wmut);
984 }
985
986 if (enable && state == FASTRPC_LATENCY_STOP) {
987 qos->state = FASTRPC_LATENCY_START;
988 VERIFY(AEE_SUCCESS == (nErr = pthread_create(&qos->thread, 0, fastrpc_latency_thread_handler, (void*)qos)));
989 }
990 bail:
991 return nErr;
992 }
993
manage_adaptive_qos(int domain,uint32_t enable)994 int manage_adaptive_qos(int domain, uint32_t enable) {
995 int nErr = AEE_SUCCESS;
996
997 VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
998
999 /* If adaptive QoS is already enabled/disabled, then just return */
1000 if ((enable && hlist[domain].qos.adaptive_qos) || (!enable && !hlist[domain].qos.adaptive_qos))
1001 return nErr;
1002
1003 if (hlist[domain].dev != -1) {
1004 /* If session is already open on DSP, then make rpc call directly to user PD */
1005 nErr = remotectl_set_param(FASTRPC_ADAPTIVE_QOS, &enable, 1);
1006 if (nErr) {
1007 FARF(ERROR, "Error: %s: remotectl_set_param failed to reset adaptive QoS on DSP to %d on domain %d",
1008 __func__, enable, domain);
1009 goto bail;
1010 } else {
1011 hlist[domain].qos.adaptive_qos = ((enable == FASTRPC_ADAPTIVE_QOS)? 1:0);
1012 }
1013 } else {
1014 /* If session is not created already, then just process attribute */
1015 hlist[domain].qos.adaptive_qos = ((enable == FASTRPC_ADAPTIVE_QOS)? 1:0);
1016 }
1017
1018 if (enable)
1019 FARF(ALWAYS, "%s: Successfully enabled adaptive QoS on domain %d", __func__, domain);
1020 else
1021 FARF(ALWAYS, "%s: Disabled adaptive QoS on domain %d", __func__, domain);
1022 bail:
1023 return nErr;
1024 }
1025
remote_handle_control_domain(int domain,remote_handle64 h,uint32_t req,void * data,uint32_t len)1026 int remote_handle_control_domain(int domain, remote_handle64 h, uint32_t req, void* data, uint32_t len) {
1027 int nErr = AEE_SUCCESS;
1028
1029 switch (req) {
1030 case DSPRPC_CONTROL_LATENCY:
1031 {
1032 struct remote_rpc_control_latency *lp = (struct remote_rpc_control_latency*)data;
1033 VERIFYC(lp, AEE_EBADPARM);
1034 VERIFYC(len == sizeof(struct remote_rpc_control_latency), AEE_EBADPARM);
1035
1036 switch(lp->enable) {
1037 /* Only one of PM QoS or adaptive QoS can be enabled */
1038 case FASTRPC_DISABLE_QOS:
1039 {
1040 VERIFY(AEE_SUCCESS == (nErr = manage_adaptive_qos(domain, FASTRPC_DISABLE_QOS)));
1041 VERIFY(AEE_SUCCESS == (nErr = manage_pm_qos(domain, h, FASTRPC_DISABLE_QOS, lp->latency)));
1042 break;
1043 }
1044 case FASTRPC_PM_QOS:
1045 {
1046 VERIFY(AEE_SUCCESS == (nErr = manage_adaptive_qos(domain, FASTRPC_DISABLE_QOS)));
1047 VERIFY(AEE_SUCCESS == (nErr = manage_pm_qos(domain, h, FASTRPC_PM_QOS, lp->latency)));
1048 break;
1049 }
1050 case FASTRPC_ADAPTIVE_QOS:
1051 {
1052 /* Disable PM QoS if enabled and then enable adaptive QoS */
1053 VERIFY(AEE_SUCCESS == (nErr = manage_pm_qos(domain, h, FASTRPC_DISABLE_QOS, lp->latency)));
1054 VERIFY(AEE_SUCCESS == (nErr = manage_adaptive_qos(domain, FASTRPC_ADAPTIVE_QOS)));
1055 break;
1056 }
1057 default:
1058 nErr = AEE_EBADPARM;
1059 FARF(ERROR, "Error: %s: Bad enable parameter %d passed for QoS control", __func__, lp->enable);
1060 break;
1061 }
1062 break;
1063 }
1064 default:
1065 nErr = AEE_EUNSUPPORTEDAPI;
1066 FARF(ERROR, "Error: %s: remote handle control called with unsupported request ID %d", __func__, req);
1067 break;
1068 }
1069 bail:
1070 if (nErr != AEE_SUCCESS)
1071 FARF(ERROR, "Error 0x%x: %s failed for request ID %d on domain %d", nErr, __func__, req, domain);
1072 return nErr;
1073 }
1074
remote_handle_control(uint32_t req,void * data,uint32_t len)1075 int remote_handle_control(uint32_t req, void* data, uint32_t len) {
1076 struct handle_list* list;
1077 int domain = DEFAULT_DOMAIN_ID, nErr = AEE_SUCCESS;
1078
1079 VERIFY(AEE_SUCCESS == (nErr = remote_handle_control_domain(domain, -1, req, data, len)));
1080 bail:
1081 if (nErr != AEE_SUCCESS)
1082 FARF(ERROR, "Error 0x%x: %s failed for request ID %d", nErr, __func__, req);
1083 return nErr;
1084 }
1085
remote_handle64_control(remote_handle64 handle,uint32_t req,void * data,uint32_t len)1086 int remote_handle64_control(remote_handle64 handle, uint32_t req, void* data, uint32_t len) {
1087 int nErr = AEE_SUCCESS, domain = 0;
1088
1089 VERIFY(AEE_SUCCESS == (nErr = get_domain_from_handle(handle, &domain)));
1090 VERIFY(AEE_SUCCESS == (nErr = remote_handle_control_domain(domain, handle, req, data, len)));
1091
1092 bail:
1093 if (nErr != AEE_SUCCESS)
1094 FARF(ERROR, "Error 0x%x: %s failed for request ID %d", nErr, __func__, req);
1095 return nErr;
1096 }
1097
store_domain_thread_params(int domain,struct remote_rpc_thread_params * params,uint32_t req)1098 static int store_domain_thread_params(int domain, struct remote_rpc_thread_params *params, uint32_t req)
1099 {
1100 int nErr = AEE_SUCCESS;
1101
1102 if (hlist[domain].dev != -1) {
1103 nErr = AEE_ENOTALLOWED;
1104 FARF(ERROR, "%s: Session already open on domain %d ! Set parameters before making any RPC calls",
1105 __func__, domain);
1106 goto bail;
1107 }
1108 if (params->prio != -1) {
1109 /* Valid QuRT thread priorities are 1 to 255 */
1110 unsigned int min_prio = 1, max_prio = 255;
1111
1112 if ((params->prio < min_prio) || (params->prio > max_prio)) {
1113 nErr = AEE_EBADPARM;
1114 FARF(ERROR, "%s: Priority %d is invalid! Should be between %d and %d",
1115 __func__, params->prio, min_prio, max_prio);
1116 goto bail;
1117 } else
1118 hlist[domain].th_params.prio = (uint32_t) params->prio;
1119 }
1120 if (params->stack_size != -1) {
1121 /* Stack size passed by user should be between 16 KB and 8 MB */
1122 unsigned int min_stack_size = 16*1024, max_stack_size = 8*1024*1024;
1123
1124 if ((params->stack_size < min_stack_size) || (params->stack_size > max_stack_size)) {
1125 nErr = AEE_EBADPARM;
1126 FARF(ERROR, "%s: Stack size %d is invalid! Should be between %d and %d",
1127 __func__, params->stack_size, min_stack_size, max_stack_size);
1128 goto bail;
1129 } else
1130 hlist[domain].th_params.stack_size = (uint32_t) params->stack_size;
1131 }
1132 hlist[domain].th_params.reqID = req;
1133 bail:
1134 if (nErr != AEE_SUCCESS)
1135 FARF(ERROR, "Error 0x%x: %s failed for domain %d", nErr, __func__, domain);
1136 return nErr;
1137 }
1138
1139 /* Set remote session parameters like thread stack size, running on unsigned PD etc */
remote_session_control(uint32_t req,void * data,uint32_t datalen)1140 int remote_session_control(uint32_t req, void *data, uint32_t datalen)
1141 {
1142 int nErr = AEE_SUCCESS;
1143
1144 VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
1145
1146 switch (req) {
1147 case FASTRPC_THREAD_PARAMS:
1148 {
1149 struct remote_rpc_thread_params *params = (struct remote_rpc_thread_params*)data;
1150 if (!params) {
1151 nErr = AEE_EBADPARM;
1152 FARF(ERROR, "%s: Thread params struct passed is %p", __func__, params);
1153 goto bail;
1154 }
1155 VERIFYC(datalen == sizeof(struct remote_rpc_thread_params), AEE_EINVALIDFORMAT);
1156 if (params->domain != -1) {
1157 if ((params->domain < 0) || (params->domain >= NUM_DOMAINS_EXTEND)) {
1158 nErr = AEE_EINVALIDDOMAIN;
1159 FARF(ERROR, "%s: Invalid domain ID %d passed", __func__, params->domain);
1160 goto bail;
1161 }
1162 VERIFY(AEE_SUCCESS == (nErr = store_domain_thread_params(params->domain, params, req)));
1163 } else {
1164 /* If domain is -1, then set parameters for all domains */
1165 for (int i = 0; i < NUM_DOMAINS_EXTEND; i++) {
1166 VERIFY(AEE_SUCCESS == (nErr = store_domain_thread_params(i, params, req)));
1167 }
1168 }
1169 break;
1170 }
1171 case DSPRPC_CONTROL_UNSIGNED_MODULE:
1172 {
1173 // Handle the unsigned module offload request
1174 struct remote_rpc_control_unsigned_module *um = (struct remote_rpc_control_unsigned_module*)data;
1175 VERIFYC(datalen == sizeof(struct remote_rpc_control_unsigned_module), AEE_EINVALIDFORMAT);
1176 VERIFY(um != NULL);
1177 FARF (HIGH, "%s Unsigned module offload enable %d for domain %d", __func__, um->enable, um->domain);
1178 if (um->domain != -1) {
1179 VERIFYC((um->domain >= 0) && (um->domain < NUM_DOMAINS_EXTEND), AEE_EINVALIDDOMAIN);
1180 hlist[um->domain].unsigned_module = um->enable? 1 :0 ;
1181 } else {
1182 for (int ii = 0; ii < NUM_DOMAINS_EXTEND; ii++) {
1183 hlist[ii].unsigned_module = um->enable? 1: 0;
1184 }
1185 }
1186 }
1187 break;
1188 default:
1189 nErr = AEE_EUNSUPPORTEDAPI;
1190 FARF(ERROR, "%s: Unsupported request ID %d", __func__, req);
1191 break;
1192 }
1193 bail:
1194 if (nErr != AEE_SUCCESS) {
1195 FARF(ERROR, "Error 0x%x: %s failed for request ID %d", nErr, __func__, req);
1196 }
1197 return nErr;
1198 }
1199
remote_mmap64(int fd,uint32_t flags,uint64_t vaddrin,int64_t size,uint64_t * vaddrout)1200 int remote_mmap64(int fd, uint32_t flags, uint64_t vaddrin, int64_t size, uint64_t* vaddrout) {
1201 struct handle_list* list;
1202 struct fastrpc_ioctl_mmap mmap;
1203 int dev, domain, nErr = AEE_SUCCESS;
1204
1205 list = (struct handle_list*)pthread_getspecific(tlsKey);
1206 VERIFYC(NULL != list, AEE_EMEMPTR);
1207 domain = (int)(list - &hlist[0]);
1208 VERIFYC((domain >= 0) && (domain < NUM_DOMAINS_EXTEND), AEE_EINVALIDDOMAIN);
1209 VERIFYC(-1 != (dev = open_dev(domain)), AEE_EINVALIDDEVICE);
1210 mmap.fd = fd;
1211 mmap.flags = flags;
1212 mmap.vaddrin = vaddrin;
1213 mmap.size = size;
1214 FARF(HIGH, "Entering %s : fd %d, vaddrin %llx, size %llx ioctl %x\n", __func__, fd, vaddrin, size, FASTRPC_IOCTL_MMAP);
1215 VERIFY(AEE_SUCCESS == (nErr = ioctl(dev, FASTRPC_IOCTL_MMAP, (unsigned long)&mmap)));
1216 *vaddrout = mmap.vaddrout;
1217 bail:
1218 if (nErr != AEE_SUCCESS) {
1219 FARF(ERROR, "Error %x: remote mmap64 failed. fd %x, flags %x, vaddrin %llx, size %zx\n", nErr, fd, flags, vaddrin, size);
1220 }
1221 return nErr;
1222 }
1223
remote_mmap(int fd,uint32_t flags,uint32_t vaddrin,int size,uint32_t * vaddrout)1224 int remote_mmap(int fd, uint32_t flags, uint32_t vaddrin, int size, uint32_t* vaddrout) {
1225 return remote_mmap64(fd, flags, (uintptr_t)vaddrin, (int64_t)size, (uint64_t*)vaddrout);
1226 }
1227
remote_munmap64(uint64_t vaddrout,int64_t size)1228 int remote_munmap64(uint64_t vaddrout, int64_t size) {
1229 struct handle_list* list;
1230 struct fastrpc_ioctl_munmap munmap;
1231 int dev, domain, nErr = AEE_SUCCESS;
1232
1233 list = (struct handle_list*)pthread_getspecific(tlsKey);
1234 VERIFYC(NULL != list, AEE_EMEMPTR);
1235 domain = (int)(list - &hlist[0]);
1236 VERIFYC((domain >= 0) && (domain < NUM_DOMAINS_EXTEND), AEE_EINVALIDDOMAIN);
1237 VERIFYC(-1 != (dev = open_dev(domain)), AEE_EINVALIDDEVICE);
1238 VERIFY(list->dev > 0);
1239 munmap.vaddrout = vaddrout;
1240 munmap.size = size;
1241 FARF(HIGH, "Entering %s : vaddrin %llx, size %llx\n", __func__, vaddrout, size);
1242 VERIFY(AEE_SUCCESS == (nErr = ioctl(dev, FASTRPC_IOCTL_MUNMAP, (unsigned long)&munmap)));
1243 bail:
1244 if (nErr != AEE_SUCCESS) {
1245 FARF(ERROR, "Error %x: remote munmap64 failed. vaddrout %p, size %zx\n", nErr, vaddrout, size);
1246 }
1247 return nErr;
1248 }
1249
remote_munmap(uint32_t vaddrout,int size)1250 int remote_munmap(uint32_t vaddrout, int size) {
1251 return remote_munmap64((uintptr_t)vaddrout, (int64_t)size);
1252 }
1253
remote_unmap_fd(void * buf,int size,int fd,int attr)1254 static int remote_unmap_fd(void *buf, int size, int fd, int attr) {
1255 int nErr = 0;
1256 int i;
1257 struct fastrpc_ioctl_munmap map;
1258
1259 VERIFY(hlist);
1260 map.vaddrout = (uintptr_t) buf;
1261 map.size = size;
1262 for (i = 0; i < NUM_DOMAINS; i++) {
1263 pthread_mutex_lock(&hlist[i].mut);
1264 if (hlist[i].dev != -1) {
1265 nErr = ioctl(hlist[i].dev, FASTRPC_IOCTL_MUNMAP, (unsigned long)&map);
1266 if (nErr)
1267 FARF(LOW, "unmap_fd: device found %d for domain %d returned %d", hlist[i].dev, i, nErr);
1268 }
1269 pthread_mutex_unlock(&hlist[i].mut);
1270 }
1271 bail:
1272 return nErr;
1273 }
1274
1275
remote_set_mode(uint32_t mode)1276 int remote_set_mode(uint32_t mode) {
1277 int i;
1278 for(i = 0; i < NUM_DOMAINS_EXTEND; i++) {
1279 hlist[i].mode = mode;
1280 hlist[i].setmode = 1;
1281 }
1282 return AEE_SUCCESS;
1283 }
1284
1285 #ifdef __ANDROID__
1286 #include <android/log.h>
1287 extern const char* __progname;
HAP_debug(const char * msg,int level,const char * filename,int line)1288 void HAP_debug(const char *msg, int level, const char *filename, int line) {
1289 __android_log_print(level, __progname, "%s:%d: %s", filename, line, msg);
1290 }
1291 #else
1292 extern const char* __progname;
HAP_debug(const char * msg,int level,const char * filename,int line)1293 void HAP_debug(const char *msg, int level, const char *filename, int line) {
1294 printf("hello %s - %s:%d: %s", __progname, filename, line, msg);
1295 }
1296 #endif
1297
1298 PL_DEP(fastrpc_apps_user);
1299 PL_DEP(gpls);
1300 PL_DEP(apps_mem);
1301 PL_DEP(apps_std);
1302 PL_DEP(rpcmem);
1303 PL_DEP(listener_android);
1304
attach_guestos(int domain)1305 static int attach_guestos(int domain) {
1306 int attach;
1307
1308 switch(domain & DOMAIN_ID_MASK) {
1309 case MDSP_DOMAIN_ID:
1310 case ADSP_DOMAIN_ID:
1311 attach = USER_PD;
1312 break;
1313 case CDSP_DOMAIN_ID:
1314 attach = USER_PD;
1315 break;
1316 default:
1317 attach = GUEST_OS;
1318 break;
1319 }
1320 return attach;
1321 }
1322
domain_deinit(int domain)1323 static void domain_deinit(int domain) {
1324 QNode *pn;
1325 remote_handle64 handle;
1326
1327 if(!hlist) {
1328 return;
1329 }
1330
1331 pthread_mutex_lock(&hlist[domain].mut);
1332 FARF(HIGH, "domain_deinit for domain %d: dev %d \n", domain, hlist[domain].dev);
1333 if(hlist[domain].dev != -1) {
1334 handle = get_adsp_current_process1_handle(domain);
1335 if(handle != INVALID_HANDLE) {
1336 adsp_current_process1_exit(handle);
1337 } else {
1338 adsp_current_process_exit();
1339 }
1340
1341 listener_android_domain_deinit(domain);
1342 deinitFileWatcher(domain);
1343 fastrpc_perf_deinit();
1344 fastrpc_latency_deinit(&hlist[domain].qos);
1345 while((pn = QList_Pop(&hlist[domain].ql))) {
1346 struct handle_info* hi = STD_RECOVER_REC(struct handle_info, qn, pn);
1347 free(hi);
1348 hi = NULL;
1349 }
1350 hlist[domain].cphandle = 0;
1351 hlist[domain].msghandle = 0;
1352 hlist[domain].domainsupport = 0;
1353 hlist[domain].nondomainsupport = 0;
1354 hlist[domain].initialized = 0;
1355 hlist[domain].dsppd = attach_guestos(domain);
1356 if (hlist[domain].dsppdname != NULL)
1357 {
1358 free(hlist[domain].dsppdname);
1359 hlist[domain].dsppdname = NULL;
1360 }
1361
1362 FARF(HIGH, "exit: closing %d, rpc errors are expected.\n", domain);
1363
1364 if (close(hlist[domain].dev))
1365 FARF(ERROR, "exit: failed to close file descriptor for domain %d\n", domain);
1366
1367 hlist[domain].dev = -1;
1368 }
1369 if(hlist[domain].pdmem) {
1370 rpcmem_free_internal(hlist[domain].pdmem);
1371 hlist[domain].pdmem = NULL;
1372 }
1373 pthread_mutex_unlock(&hlist[domain].mut);
1374 }
1375
1376 #define ALIGN_B(p, a) (((p) + ((a) - 1)) & ~((a) - 1))
1377
get_domain_name(int domain_id)1378 static const char* get_domain_name(int domain_id) {
1379 const char* name;
1380 int domain = domain_id & DOMAIN_ID_MASK;
1381
1382 switch (domain) {
1383 case ADSP_DOMAIN_ID:
1384 name = ADSPRPC_DEVICE;
1385 break;
1386 case SDSP_DOMAIN_ID:
1387 name = SDSPRPC_DEVICE;
1388 break;
1389 case MDSP_DOMAIN_ID:
1390 name = MDSPRPC_DEVICE;
1391 break;
1392 case CDSP_DOMAIN_ID:
1393 name = CDSPRPC_DEVICE;
1394 break;
1395 default:
1396 name = DEFAULT_DEVICE;
1397 break;
1398 }
1399 return name;
1400 }
1401
1402 /* Returns the name of the domain based on the following
1403 ADSP/SLPI/MDSP - Return Secure node
1404 CDSP - Return default node
1405 */
get_secure_domain_name(int domain_id)1406 static const char* get_secure_domain_name(int domain_id) {
1407 const char* name;
1408 int domain = domain_id & DOMAIN_ID_MASK;
1409
1410 switch (domain) {
1411 case ADSP_DOMAIN_ID:
1412 case SDSP_DOMAIN_ID:
1413 case MDSP_DOMAIN_ID:
1414 name = SECURE_DEVICE;
1415 break;
1416 case CDSP_DOMAIN_ID:
1417 // Intentional fallthrough
1418 default:
1419 name = DEFAULT_DEVICE;
1420 break;
1421 }
1422 return name;
1423 }
1424
1425 /* Opens device node based on the domain
1426 This function takes care of the backward compatibility to open
1427 approriate device for following configurations of the device nodes
1428 1. 4 different device nodes
1429 2. 1 device node (adsprpc-smd)
1430 3. 2 device nodes (adsprpc-smd, adsprpc-smd-secure)
1431 Algorithm
1432 For ADSP, SDSP, MDSP domains:
1433 Open secure device node fist
1434 if no secure device, open actual device node
1435 if still no device, open default node
1436 if failed to open the secure node due to permission,
1437 open default node
1438 For CDSP domain:
1439 Open actual device node ("cdsprpc-smd")
1440 if no device, open secure / default device node
1441 */
open_device_node_internal(int domain_id)1442 static int open_device_node_internal (int domain_id) {
1443 int dev = -1;
1444 int domain = domain_id & DOMAIN_ID_MASK;
1445
1446 switch (domain) {
1447 case ADSP_DOMAIN_ID:
1448 case SDSP_DOMAIN_ID:
1449 case MDSP_DOMAIN_ID:
1450 dev = open(get_secure_domain_name(domain), O_NONBLOCK);
1451 if((dev < 0) && (errno == ENOENT)) {
1452 FARF(HIGH, "Device node %s open failed for domain %d (errno %s),\n"
1453 "falling back to node %s \n",
1454 get_secure_domain_name(domain), domain, strerror(errno),
1455 get_domain_name(domain));
1456 dev = open(get_domain_name(domain), O_NONBLOCK);
1457 if((dev < 0) && (errno == ENOENT)) {
1458 FARF(HIGH, "Device node %s open failed for domain %d (errno %s),"
1459 "falling back to node %s \n",
1460 get_domain_name(domain), domain, strerror(errno),
1461 DEFAULT_DEVICE);
1462 dev = open(DEFAULT_DEVICE, O_NONBLOCK);
1463 }
1464 } else if ((dev < 0) && (errno == EACCES)) {
1465 // Open the default device node if unable to open the
1466 // secure device node due to permissions
1467 FARF(HIGH, "Device node %s open failed for domain %d (errno %s),"
1468 "falling back to node %s \n",
1469 get_secure_domain_name(domain), domain, strerror(errno),
1470 DEFAULT_DEVICE);
1471 dev = open(DEFAULT_DEVICE, O_NONBLOCK);
1472 }
1473 break;
1474 case CDSP_DOMAIN_ID:
1475 dev = open(get_domain_name(domain), O_NONBLOCK);
1476 if((dev < 0) && (errno == ENOENT)) {
1477 FARF(HIGH, "Device node %s open failed for domain %d (errno %s),"
1478 "falling back to node %s \n",
1479 get_domain_name(domain), domain, strerror(errno),
1480 get_secure_domain_name(domain));
1481 dev = open(get_secure_domain_name(domain), O_NONBLOCK);
1482 }
1483 break;
1484 default:
1485 break;
1486 }
1487
1488 if (dev < 0)
1489 FARF(ERROR, "Error: Device node open failed for domain %d (errno %s)",
1490 domain, strerror(errno));
1491
1492 return dev;
1493 }
1494
1495
get_process_attrs(int domain)1496 static int get_process_attrs(int domain) {
1497 int nErr = 0;
1498 uint64 len = 0;
1499 int attrs = 0;
1500
1501 attrs = FASTRPC_PROPERTY_GET_INT32(FASTRPC_PROP_PROCESS, 0);
1502 if (!attrs) {
1503 const char *env = getenv("ADSP_PROCESS_ATTRS");
1504 attrs = env == 0 ? 0 : (int)atoi(env);
1505 }
1506 fastrpc_trace = FASTRPC_PROPERTY_GET_INT32(FASTRPC_PROP_TRACE, 0);
1507 attrs |= hlist[domain].qos.adaptive_qos ? FASTRPC_MODE_ADAPTIVE_QOS : 0;
1508 attrs |= hlist[domain].unsigned_module ? FASTRPC_MODE_UNSIGNED_MODULE : 0;
1509 return attrs;
1510 }
1511
get_process_testsig(apps_std_FILE * fp,uint64 * ptrlen)1512 static void get_process_testsig(apps_std_FILE *fp, uint64 *ptrlen) {
1513 int nErr = 0;
1514 uint64 len = 0;
1515 char testsig[PROPERTY_VALUE_MAX];
1516
1517 if (fp == NULL || ptrlen == NULL)
1518 return;
1519
1520 if (FASTRPC_PROPERTY_GET_STR(FASTRPC_PROP_TESTSIG, testsig, NULL)) {
1521 FARF(HIGH, "testsig file loading is %s", testsig);
1522 nErr = apps_std_fopen_with_env("ADSP_LIBRARY_PATH", ";", testsig, "r", fp);
1523 if (nErr == AEE_SUCCESS && *fp != -1)
1524 nErr = apps_std_flen(*fp, &len);
1525 }
1526 bail:
1527 if (nErr)
1528 len = 0;
1529 *ptrlen = len;
1530 return;
1531 }
1532
is_kernel_alloc_supported(int dev,int domain)1533 int is_kernel_alloc_supported(int dev, int domain) {
1534 return 1;
1535 }
1536
open_shell(int domain_id,apps_std_FILE * fh,int unsigned_shell)1537 static int open_shell(int domain_id, apps_std_FILE *fh, int unsigned_shell) {
1538 char *absName = NULL;
1539 char *shell_absName = NULL;
1540 char *domain_str = NULL;
1541 uint16 shell_absNameLen = 0, absNameLen = 0;;
1542 int nErr = AEE_SUCCESS;
1543 int domain = domain_id & DOMAIN_ID_MASK;
1544 const char* shell_name = SIGNED_SHELL;
1545
1546 if (1 == unsigned_shell) {
1547 shell_name = UNSIGNED_SHELL;
1548 }
1549
1550 if (domain == MDSP_DOMAIN_ID) {
1551 return nErr;
1552 }
1553 VERIFYC(NULL != (domain_str = (char*)malloc(sizeof(domain))), AEE_ENOMEMORY);
1554 snprintf(domain_str, sizeof(domain), "%d",domain);
1555
1556
1557 shell_absNameLen = std_strlen(shell_name) + std_strlen(domain_str) + 1;
1558
1559 VERIFYC(NULL != (shell_absName = (char*)malloc(sizeof(char) * shell_absNameLen)), AEE_ENOMEMORY);
1560 std_strlcpy(shell_absName, shell_name, shell_absNameLen);
1561
1562 std_strlcat(shell_absName, domain_str, shell_absNameLen);
1563
1564 absNameLen = std_strlen("/usr/lib/") + shell_absNameLen + 1;
1565 VERIFYC(NULL != (absName = (char*)malloc(sizeof(char) * absNameLen)), AEE_ENOMEMORY);
1566 std_strlcpy(absName, "/usr/lib/",absNameLen);
1567 std_strlcat(absName, shell_absName, absNameLen);
1568
1569 nErr = apps_std_fopen(absName, "r", fh);
1570 if (nErr) {
1571 absNameLen = std_strlen("/vendor/dsp/") + shell_absNameLen + 1;
1572 VERIFYC(NULL != (absName = (char*)realloc(absName, sizeof(char) * absNameLen)), AEE_ENOMEMORY);
1573 std_strlcpy(absName, "/vendor/dsp/",absNameLen);
1574 std_strlcat(absName, shell_absName, absNameLen);
1575
1576 nErr = apps_std_fopen(absName, "r", fh);
1577 if (nErr) {
1578 FARF(HIGH, "Searching for %s%d ...", shell_name, domain);
1579 nErr = apps_std_fopen_with_env("ADSP_LIBRARY_PATH", ";", shell_absName, "r", fh);
1580 }
1581 }
1582 FARF(HIGH, "fopen for shell returned %d", nErr);
1583 bail:
1584 if(domain_str){
1585 free(domain_str);
1586 domain_str = NULL;
1587 }
1588 if(shell_absName){
1589 free(shell_absName);
1590 shell_absName = NULL;
1591 }
1592 if(absName){
1593 free(absName);
1594 absName = NULL;
1595 }
1596 if (nErr != AEE_SUCCESS) {
1597 if (domain == SDSP_DOMAIN_ID && fh != NULL) {
1598 nErr = AEE_SUCCESS;
1599 *fh = -1;
1600 } else {
1601 FARF(ERROR, "open_shell failed with err %d domain %d\n", nErr, domain);
1602 }
1603 }
1604 return nErr;
1605 }
1606
open_device_node(int domain)1607 int open_device_node(int domain) {
1608 int nErr=0;
1609
1610 VERIFY(!fastrpc_init_once());
1611
1612 pthread_mutex_lock(&hlist[domain].mut);
1613 if(hlist[domain].dev == -1) {
1614 hlist[domain].dev = open_device_node_internal(domain);
1615 /* the domain was opened but not apps initialized */
1616 hlist[domain].initialized = 0;
1617 }
1618 pthread_mutex_unlock(&hlist[domain].mut);
1619 bail:
1620 return hlist[domain].dev;
1621 }
1622
apps_dev_init(int domain)1623 static int apps_dev_init(int domain) {
1624 int nErr = AEE_SUCCESS;
1625 struct fastrpc_init_create uproc = {0};
1626 apps_std_FILE fh = -1;
1627 int battach;
1628 uint32_t info = domain & DOMAIN_ID_MASK;
1629
1630 FARF(HIGH, "starting %s for domain %d", __func__, domain);
1631 pthread_mutex_lock(&hlist[domain].mut);
1632 pthread_setspecific(tlsKey, (void*)&hlist[domain]);
1633 battach = hlist[domain].dsppd;
1634 if(!hlist[domain].initialized) {
1635 if (hlist[domain].dev == -1)
1636 hlist[domain].dev = open_device_node_internal(domain);
1637
1638 VERIFYC(hlist[domain].dev >= 0, AEE_EFOPEN);
1639 FARF(HIGH, "%s: device %d opened with info 0x%x (attach %d)", __func__, hlist[domain].dev, hlist[domain].info, battach);
1640 hlist[domain].initialized = 1;
1641 //keep the memory we used to allocate
1642 if (battach == GUEST_OS || battach == GUEST_OS_SHARED) {
1643 FARF(HIGH, "%s: attaching to guest OS for domain %d", __func__, domain);
1644 VERIFY(!ioctl(hlist[domain].dev, FASTRPC_IOCTL_INIT_ATTACH) || errno == ENOTTY);
1645 } else if (battach == USER_PD) {
1646 uint64 len = 0;
1647 uint64 filelen = 0;
1648 int readlen = 0, eof;
1649 int procattr = 0;
1650 apps_std_FILE fsig = -1;
1651 uint64 siglen = 0;
1652
1653 VERIFY(0 == open_shell(domain, &fh, hlist[domain].unsigned_module));
1654
1655 hlist[domain].procattrs = get_process_attrs(domain);
1656 if (IS_DEBUG_MODE_ENABLED(hlist[domain].procattrs))
1657 get_process_testsig(&fsig, &siglen);
1658
1659 if (fh != -1) {
1660 VERIFY(AEE_SUCCESS == (nErr = apps_std_flen(fh, &len)));
1661 filelen = len + siglen;
1662 VERIFYC(filelen < INT_MAX, AEE_EBADSIZE);
1663 pthread_mutex_unlock(&hlist[domain].mut);
1664 FARF(HIGH,"debug:file len:%llx",filelen);
1665 FARF(HIGH,"debug:file len to rpc malloc:%x",filelen);
1666 uproc.file = (__u64)rpcmem_alloc_internal(0, RPCMEM_HEAP_DEFAULT, (int)(filelen));
1667 pthread_mutex_lock(&hlist[domain].mut);
1668 VERIFYC(uproc.file, AEE_ENORPCMEMORY);
1669 VERIFY(AEE_SUCCESS == (nErr = apps_std_fread(fh, (void *)uproc.file, len, &readlen, &eof)));
1670 VERIFYC((int)len == readlen, AEE_EFREAD);
1671 uproc.filefd = rpcmem_to_fd_internal((void *)uproc.file);
1672 uproc.filelen = (int)len;
1673 VERIFYC(uproc.filefd != -1, AEE_EINVALIDFD);
1674 } else {
1675 FARF(ERROR, "Unable to open shell file\n");
1676 }
1677 uproc.attrs = hlist[domain].procattrs;
1678 if(siglen && fsig != -1) {
1679 VERIFY(AEE_SUCCESS == (nErr = apps_std_fread(fsig, (byte*)(uproc.file + len), siglen, &readlen, &eof)));
1680 VERIFYC(siglen == (uint64)readlen, AEE_EFREAD);
1681 uproc.siglen = siglen;
1682 uproc.filelen = len + siglen;
1683 }
1684 nErr = ioctl(hlist[domain].dev, FASTRPC_IOCTL_INIT_CREATE, (unsigned long)&uproc);
1685 if (nErr == AEE_SUCCESS) {
1686 FARF(HIGH, "Successfully created user PD on domain %d (attrs 0x%x)", domain, hlist[domain].procattrs);
1687 }
1688 } else {
1689 FARF(ERROR, "Error: %s called for unknown mode %d", __func__, battach);
1690 }
1691 }
1692 bail:
1693 pthread_mutex_unlock(&hlist[domain].mut);
1694 if(uproc.file) {
1695 rpcmem_free_internal((void*)uproc.file);
1696 }
1697 if(fh != -1) {
1698 apps_std_fclose(fh);
1699 }
1700 if(nErr != AEE_SUCCESS) {
1701 domain_deinit(domain);
1702 FARF(ERROR, "Error 0x%x: %s failed for domain %d, errno %s\n", nErr, __func__, domain, strerror(errno));
1703 }
1704 FARF(HIGH, "Done with %s, err: 0x%x, dev: %d", __func__, nErr, hlist[domain].dev);
1705 return nErr;
1706 }
1707
1708 __attribute__((destructor))
close_dev(void)1709 static void close_dev(void) {
1710 int i;
1711 for(i = 0; i < NUM_DOMAINS_EXTEND; i++) {
1712 domain_deinit(i);
1713 }
1714 pl_deinit();
1715 PL_DEINIT(fastrpc_apps_user);
1716 }
1717
get_adsp_current_process1_handle(int domain)1718 remote_handle64 get_adsp_current_process1_handle(int domain) {
1719 struct handle_info* hinfo;
1720 int nErr = AEE_SUCCESS;
1721
1722 VERIFYC(hlist[domain].domainsupport, AEE_EBADDOMAIN);
1723 if(hlist[domain].cphandle) {
1724 return hlist[domain].cphandle;
1725 }
1726 VERIFY(AEE_SUCCESS == (nErr = alloc_handle(domain, _const_adsp_current_process1_handle, &hinfo)));
1727 hlist[domain].cphandle = hinfo->local;
1728 return hlist[domain].cphandle;
1729 bail:
1730 if (nErr != AEE_SUCCESS) {
1731 if (hlist[domain].domainsupport)
1732 FARF(ERROR, "Error %x: adsp current process handle failed. domain %d\n", nErr, domain);
1733 else if (!hlist[domain].nondomainsupport)
1734 FARF(ERROR, "Error %x: adsp current process handle failed. domain %d\n", nErr, domain);
1735 }
1736 return INVALID_HANDLE;
1737 }
1738
get_adspmsgd_adsp1_handle(int domain)1739 remote_handle64 get_adspmsgd_adsp1_handle(int domain) {
1740 struct handle_info* hinfo;
1741 int nErr = AEE_SUCCESS;
1742
1743 VERIFYC(hlist[domain].domainsupport, AEE_EBADDOMAIN);
1744 if(hlist[domain].msghandle) {
1745 return hlist[domain].msghandle;
1746 }
1747 VERIFY(AEE_SUCCESS == (nErr = alloc_handle(domain, _const_adspmsgd_adsp1_handle, &hinfo)));
1748 hlist[domain].msghandle = hinfo->local;
1749 return hlist[domain].msghandle;
1750 bail:
1751 if (nErr != AEE_SUCCESS) {
1752 FARF(ERROR,"Error %x: get adsp msgd handle failed. domain %d\n", nErr, domain);
1753 }
1754 return INVALID_HANDLE;
1755 }
1756
open_dev(int domain)1757 static int open_dev(int domain) {
1758 static pthread_once_t pl = PTHREAD_ONCE_INIT;
1759 int init = 0, nErr = AEE_SUCCESS;
1760
1761 if(hlist && hlist[domain].dev != -1 && hlist[domain].initialized) {
1762 if(0 == pthread_getspecific(tlsKey)) {
1763 pthread_setspecific(tlsKey, (void*)&hlist[domain]);
1764 }
1765 goto bail;
1766 }
1767 VERIFY(AEE_SUCCESS == (nErr = fastrpc_init_once()));
1768 VERIFY(AEE_SUCCESS == (nErr = pthread_once(&pl, (void*)pl_init)));
1769 init = 1;
1770 pthread_mutex_lock(&hlist[domain].init);
1771 if(hlist && hlist[domain].dev != -1 && hlist[domain].initialized) {
1772 goto bail;
1773 }
1774 VERIFY(AEE_SUCCESS == (nErr = apps_dev_init(domain)));
1775 VERIFY(AEE_SUCCESS == (nErr = listener_android_domain_init(domain)));
1776 initFileWatcher(domain); // Ignore errors
1777 if(hlist){
1778 fastrpc_perf_init(hlist[domain].dev);
1779 VERIFY(AEE_SUCCESS == (nErr = fastrpc_latency_init(hlist[domain].dev, &hlist[domain].qos)));
1780 }
1781 if (hlist[domain].th_params.prio != DEFAULT_UTHREAD_PRIORITY || hlist[domain].th_params.stack_size != DEFAULT_UTHREAD_STACK_SIZE) {
1782 struct fastrpc_thread_params *uthread_params = &hlist[domain].th_params;
1783
1784 VERIFY(AEE_SUCCESS == (nErr = pthread_create(&uthread_params->thread, NULL, fastrpc_set_remote_uthread_params, (void*)uthread_params)));
1785 VERIFY(AEE_SUCCESS == (nErr = pthread_join(uthread_params->thread, NULL)));
1786 FARF(ALWAYS, "%s: Successfully set remote user thread priority to %d and stack size to %d",
1787 __func__, uthread_params->prio, uthread_params->stack_size);
1788 }
1789
1790 bail:
1791 if(init) {
1792 pthread_mutex_unlock(&hlist[domain].init);
1793 }
1794 if(nErr != AEE_SUCCESS) {
1795 domain_deinit(domain);
1796 if(hlist)
1797 FARF(ERROR, "Error %x: open dev %d for domain %d failed\n", nErr, hlist[domain].dev, domain);
1798 return -1;
1799 }
1800 if(hlist){
1801 FARF(HIGH, "done open dev %d err %d", hlist[domain].dev, nErr);
1802 return hlist[domain].dev;
1803 } else {
1804 return -1;
1805 }
1806 }
1807
fastrpc_apps_user_deinit(void)1808 static void fastrpc_apps_user_deinit(void) {
1809 QNode *pn;
1810 int i;
1811 if(tlsKey != INVALID_KEY) {
1812 pthread_key_delete(tlsKey);
1813 tlsKey = INVALID_KEY;
1814 }
1815 PL_DEINIT(apps_mem);
1816 PL_DEINIT(apps_std);
1817 PL_DEINIT(rpcmem);
1818 if(hlist) {
1819 for (i = 0; i < NUM_DOMAINS_EXTEND; i++) {
1820 while((pn = QList_Pop(&hlist[i].ql))) {
1821 struct handle_info* h = STD_RECOVER_REC(struct handle_info, qn, pn);
1822 free(h);
1823 h = NULL;
1824 }
1825 pthread_mutex_destroy(&hlist[i].mut);
1826 pthread_mutex_destroy(&hlist[i].init);
1827 }
1828 free(hlist);
1829 hlist = NULL;
1830 }
1831 pthread_mutex_destroy(&fdlist.mut);
1832 return;
1833 }
1834
exit_thread(void * value)1835 static void exit_thread(void *value)
1836 {
1837 remote_handle64 handle;
1838 struct handle_list* list = (struct handle_list*)value;
1839 int domain;
1840
1841 if(!hlist) {
1842 return;
1843 }
1844 domain = (int)(list - &hlist[0]);
1845 if(hlist[domain].dev != -1) {
1846 FARF(HIGH, "exiting thread domain: %d", domain);
1847 if((domain < NUM_DOMAINS_EXTEND) &&
1848 (handle = get_adsp_current_process1_handle(domain)) != INVALID_HANDLE) {
1849 (void)adsp_current_process1_thread_exit(handle);
1850 } else if (domain == DEFAULT_DOMAIN_ID) {
1851 (void)adsp_current_process_thread_exit();
1852 }
1853 }
1854 }
1855
fastrpc_apps_user_init()1856 static int fastrpc_apps_user_init() {
1857 int nErr = AEE_SUCCESS, i;
1858
1859 pthread_mutexattr_t attr;
1860 pthread_mutexattr_init(&attr);
1861 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
1862 pthread_mutex_init(&fdlist.mut, 0);
1863 QList_Ctor(&fdlist.ql);
1864 std_memset(dhandles, 0, sizeof(dhandles));
1865 VERIFYC(NULL != (hlist = calloc(NUM_DOMAINS_EXTEND, sizeof(*hlist))), AEE_ENOMEMORY);
1866 for (i = 0; i < NUM_DOMAINS_EXTEND; i++) {
1867 hlist[i].dev = -1;
1868 hlist[i].domainsupport = 0;
1869 hlist[i].nondomainsupport = 0;
1870 hlist[i].kmem_support = 0;
1871 hlist[i].th_params.prio = DEFAULT_UTHREAD_PRIORITY;
1872 hlist[i].th_params.stack_size = DEFAULT_UTHREAD_STACK_SIZE;
1873 hlist[i].th_params.reqID = 0;
1874 hlist[i].dsppd = attach_guestos(i);
1875 hlist[i].dsppdname = NULL;
1876 pthread_mutex_init(&hlist[i].mut, &attr);
1877 pthread_mutex_init(&hlist[i].init, 0);
1878 QList_Ctor(&hlist[i].ql);
1879 }
1880 pthread_mutexattr_destroy(&attr);
1881 VERIFY(AEE_SUCCESS == (nErr = pthread_key_create(&tlsKey, exit_thread)));
1882 VERIFY(AEE_SUCCESS == (nErr = PL_INIT(rpcmem)));
1883 VERIFY(AEE_SUCCESS == (nErr = PL_INIT(apps_mem)));
1884 VERIFY(AEE_SUCCESS == (nErr = PL_INIT(apps_std)));
1885 GenCrc32Tab(POLY32, crc_table);
1886 bail:
1887 if(nErr) {
1888 FARF(ERROR, "Error %x: fastrpc_apps_user_init failed\n", nErr);
1889 fastrpc_apps_user_deinit();
1890 }
1891 return nErr;
1892 }
1893
1894 PL_DEFINE(fastrpc_apps_user, fastrpc_apps_user_init, fastrpc_apps_user_deinit);
1895
frpc_init(void)1896 static void frpc_init(void) {
1897 PL_INIT(fastrpc_apps_user);
1898 }
1899
fastrpc_init_once(void)1900 static int fastrpc_init_once(void) {
1901 static pthread_once_t frpc = PTHREAD_ONCE_INIT;
1902 int nErr = AEE_SUCCESS;
1903 VERIFY(AEE_SUCCESS == (nErr = pthread_once(&frpc, (void*)frpc_init)));
1904 bail:
1905 if(nErr != AEE_SUCCESS) {
1906 FARF(ERROR, "Error %x: fastrpc init once failed\n", nErr);
1907 }
1908 return nErr == AEE_SUCCESS ? _pl_fastrpc_apps_user()->nErr : nErr;
1909 }
1910
rpcmem_init_me(void)1911 static int rpcmem_init_me(void) {
1912 rpcmem_init();
1913 return AEE_SUCCESS;
1914 }
1915 PL_DEFINE(rpcmem, rpcmem_init_me, rpcmem_deinit);
1916