xref: /aosp_15_r20/external/fastrpc/src/rpcmem_android.c (revision 418b791d679beb2078b579a3b6936cf330c41799)
1*418b791dSBob Badour /*
2*418b791dSBob Badour  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3*418b791dSBob Badour  *
4*418b791dSBob Badour  * Redistribution and use in source and binary forms, with or without
5*418b791dSBob Badour  * modification, are permitted provided that the following conditions are
6*418b791dSBob Badour  * met:
7*418b791dSBob Badour  *    * Redistributions of source code must retain the above copyright
8*418b791dSBob Badour  *      notice, this list of conditions and the following disclaimer.
9*418b791dSBob Badour  *    * Redistributions in binary form must reproduce the above
10*418b791dSBob Badour  *      copyright notice, this list of conditions and the following
11*418b791dSBob Badour  *      disclaimer in the documentation and/or other materials provided
12*418b791dSBob Badour  *      with the distribution.
13*418b791dSBob Badour  *    * Neither the name of The Linux Foundation nor the names of its
14*418b791dSBob Badour  *      contributors may be used to endorse or promote products derived
15*418b791dSBob Badour  *      from this software without specific prior written permission.
16*418b791dSBob Badour  *
17*418b791dSBob Badour  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18*418b791dSBob Badour  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19*418b791dSBob Badour  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20*418b791dSBob Badour  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21*418b791dSBob Badour  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*418b791dSBob Badour  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*418b791dSBob Badour  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24*418b791dSBob Badour  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25*418b791dSBob Badour  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26*418b791dSBob Badour  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27*418b791dSBob Badour  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*418b791dSBob Badour  */
29*418b791dSBob Badour 
30*418b791dSBob Badour #include "rpcmem.h"
31*418b791dSBob Badour #include "verify.h"
32*418b791dSBob Badour #include "fastrpc_internal.h"
33*418b791dSBob Badour #include "AEEQList.h"
34*418b791dSBob Badour #include "AEEstd.h"
35*418b791dSBob Badour #include "apps_std.h"
36*418b791dSBob Badour 
37*418b791dSBob Badour #include <stdlib.h>
38*418b791dSBob Badour #include <stdio.h>
39*418b791dSBob Badour #include <pthread.h>
40*418b791dSBob Badour #include <fcntl.h>
41*418b791dSBob Badour #include <string.h>
42*418b791dSBob Badour #include <unistd.h>
43*418b791dSBob Badour #include <sys/ioctl.h>
44*418b791dSBob Badour #include <sys/mman.h>
45*418b791dSBob Badour #include <errno.h>
46*418b791dSBob Badour 
47*418b791dSBob Badour #define PAGE_SIZE 4096
48*418b791dSBob Badour #define PAGE_MASK ~((uintptr_t)PAGE_SIZE - 1)
49*418b791dSBob Badour 
50*418b791dSBob Badour static QList rpclst;
51*418b791dSBob Badour static pthread_mutex_t rpcmt;
52*418b791dSBob Badour struct rpc_info
53*418b791dSBob Badour {
54*418b791dSBob Badour 	QNode qn;
55*418b791dSBob Badour 	void *buf;
56*418b791dSBob Badour 	void *aligned_buf;
57*418b791dSBob Badour 	int size;
58*418b791dSBob Badour 	int fd;
59*418b791dSBob Badour };
60*418b791dSBob Badour 
61*418b791dSBob Badour extern int open_device_node(int domain);
rpcmem_open_dev()62*418b791dSBob Badour static int rpcmem_open_dev()
63*418b791dSBob Badour {
64*418b791dSBob Badour 	return open_device_node(3);
65*418b791dSBob Badour }
66*418b791dSBob Badour 
rpcmem_init()67*418b791dSBob Badour void rpcmem_init()
68*418b791dSBob Badour {
69*418b791dSBob Badour 	int fd;
70*418b791dSBob Badour 	QList_Ctor(&rpclst);
71*418b791dSBob Badour 	pthread_mutex_init(&rpcmt, 0);
72*418b791dSBob Badour }
73*418b791dSBob Badour 
rpcmem_deinit()74*418b791dSBob Badour void rpcmem_deinit()
75*418b791dSBob Badour {
76*418b791dSBob Badour 	pthread_mutex_destroy(&rpcmt);
77*418b791dSBob Badour }
78*418b791dSBob Badour 
rpcmem_to_fd_internal(void * po)79*418b791dSBob Badour int rpcmem_to_fd_internal(void *po) {
80*418b791dSBob Badour 	struct rpc_info *rinfo, *rfree = 0;
81*418b791dSBob Badour 	QNode *pn, *pnn;
82*418b791dSBob Badour 
83*418b791dSBob Badour 	pthread_mutex_lock(&rpcmt);
84*418b791dSBob Badour 	QLIST_NEXTSAFE_FOR_ALL(&rpclst, pn, pnn)
85*418b791dSBob Badour 	{
86*418b791dSBob Badour 		rinfo = STD_RECOVER_REC(struct rpc_info, qn, pn);
87*418b791dSBob Badour 		if (rinfo->aligned_buf == po)
88*418b791dSBob Badour 		{
89*418b791dSBob Badour 			rfree = rinfo;
90*418b791dSBob Badour 			break;
91*418b791dSBob Badour 		}
92*418b791dSBob Badour 	}
93*418b791dSBob Badour 	pthread_mutex_unlock(&rpcmt);
94*418b791dSBob Badour 
95*418b791dSBob Badour 	if (rfree)
96*418b791dSBob Badour 		return rfree->fd;
97*418b791dSBob Badour 
98*418b791dSBob Badour 	return -1;
99*418b791dSBob Badour }
100*418b791dSBob Badour 
rpcmem_to_fd(void * po)101*418b791dSBob Badour int rpcmem_to_fd(void *po) {
102*418b791dSBob Badour 	return rpcmem_to_fd_internal(po);
103*418b791dSBob Badour }
104*418b791dSBob Badour 
105*418b791dSBob Badour 
rpcmem_alloc_internal(int heapid,uint32 flags,int size)106*418b791dSBob Badour void *rpcmem_alloc_internal(int heapid, uint32 flags, int size)
107*418b791dSBob Badour {
108*418b791dSBob Badour 	struct rpc_info *rinfo;
109*418b791dSBob Badour 	struct fastrpc_alloc_dma_buf buf;
110*418b791dSBob Badour 	int nErr = 0;
111*418b791dSBob Badour 	(void)heapid;
112*418b791dSBob Badour 	(void)flags;
113*418b791dSBob Badour 	int dev = rpcmem_open_dev();
114*418b791dSBob Badour 
115*418b791dSBob Badour 	VERIFY(0 != (rinfo = calloc(1, sizeof(*rinfo))));
116*418b791dSBob Badour 
117*418b791dSBob Badour 	buf.size = size + PAGE_SIZE;
118*418b791dSBob Badour 	buf.fd = -1;
119*418b791dSBob Badour 	buf.flags = 0;
120*418b791dSBob Badour 
121*418b791dSBob Badour 	VERIFY((0 == ioctl(dev, FASTRPC_IOCTL_ALLOC_DMA_BUFF, (unsigned long)&buf)) || errno == ENOTTY);
122*418b791dSBob Badour 	VERIFY(0 != (rinfo->buf = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, buf.fd, 0)));
123*418b791dSBob Badour 	rinfo->fd = buf.fd;
124*418b791dSBob Badour 	rinfo->aligned_buf = (void *)(((uintptr_t)rinfo->buf /*+ PAGE_SIZE*/) & PAGE_MASK);
125*418b791dSBob Badour 	rinfo->aligned_buf = rinfo->buf;
126*418b791dSBob Badour 	rinfo->size = size;
127*418b791dSBob Badour 	pthread_mutex_lock(&rpcmt);
128*418b791dSBob Badour 	QList_AppendNode(&rpclst, &rinfo->qn);
129*418b791dSBob Badour 	pthread_mutex_unlock(&rpcmt);
130*418b791dSBob Badour 
131*418b791dSBob Badour 	return rinfo->aligned_buf;
132*418b791dSBob Badour bail:
133*418b791dSBob Badour 	if (nErr)
134*418b791dSBob Badour 	{
135*418b791dSBob Badour 		if (rinfo)
136*418b791dSBob Badour 		{
137*418b791dSBob Badour 			if (rinfo->buf)
138*418b791dSBob Badour 			{
139*418b791dSBob Badour 				free(rinfo->buf);
140*418b791dSBob Badour 			}
141*418b791dSBob Badour 			free(rinfo);
142*418b791dSBob Badour 		}
143*418b791dSBob Badour 	}
144*418b791dSBob Badour 	return 0;
145*418b791dSBob Badour }
146*418b791dSBob Badour 
rpcmem_free_internal(void * po)147*418b791dSBob Badour void rpcmem_free_internal(void *po)
148*418b791dSBob Badour {
149*418b791dSBob Badour 	struct rpc_info *rinfo, *rfree = 0;
150*418b791dSBob Badour 	QNode *pn, *pnn;
151*418b791dSBob Badour 	int nErr = 0;
152*418b791dSBob Badour 
153*418b791dSBob Badour 	pthread_mutex_lock(&rpcmt);
154*418b791dSBob Badour 	QLIST_NEXTSAFE_FOR_ALL(&rpclst, pn, pnn)
155*418b791dSBob Badour 	{
156*418b791dSBob Badour 		rinfo = STD_RECOVER_REC(struct rpc_info, qn, pn);
157*418b791dSBob Badour 		if (rinfo->aligned_buf == po)
158*418b791dSBob Badour 		{
159*418b791dSBob Badour 			rfree = rinfo;
160*418b791dSBob Badour 			QNode_Dequeue(&rinfo->qn);
161*418b791dSBob Badour 			break;
162*418b791dSBob Badour 		}
163*418b791dSBob Badour 	}
164*418b791dSBob Badour 	pthread_mutex_unlock(&rpcmt);
165*418b791dSBob Badour 	if (rfree)
166*418b791dSBob Badour 	{
167*418b791dSBob Badour 		int dev = rpcmem_open_dev();
168*418b791dSBob Badour 
169*418b791dSBob Badour 		munmap(rfree->buf, rfree->size);
170*418b791dSBob Badour 		free(rfree);
171*418b791dSBob Badour 	}
172*418b791dSBob Badour bail:
173*418b791dSBob Badour 	return;
174*418b791dSBob Badour 
175*418b791dSBob Badour }
176*418b791dSBob Badour 
rpcmem_free(void * po)177*418b791dSBob Badour void rpcmem_free(void* po) {
178*418b791dSBob Badour     rpcmem_free_internal(po);
179*418b791dSBob Badour }
180*418b791dSBob Badour 
rpcmem_alloc(int heapid,uint32 flags,int size)181*418b791dSBob Badour void* rpcmem_alloc(int heapid, uint32 flags, int size) {
182*418b791dSBob Badour 	return rpcmem_alloc_internal(heapid, flags, size);
183*418b791dSBob Badour }
184