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