• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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