1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #define _GNU_SOURCE
17
18 #include <pthread.h>
19 #include <stdio.h>
20 #include <stdio.h>
21 #include <sys/stat.h>
22 #include <sys/wait.h>
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <sys/ioctl.h>
26 #include <sys/time.h>
27 #include <sys/mman.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <fcntl.h>
31 #include <errno.h>
32 #include <linux/ion.h>
33
34 #define ION_HEAP(bit) (1 << (bit))
35
36 enum ion_heap_ids {
37 INVALID_HEAP_ID = -1,
38 ION_CP_MM_HEAP_ID = 8,
39 ION_SECURE_HEAP_ID = 9,
40 ION_SECURE_DISPLAY_HEAP_ID = 10,
41 ION_CP_MFC_HEAP_ID = 12,
42 ION_CP_WB_HEAP_ID = 16, /* 8660 only */
43 ION_CAMERA_HEAP_ID = 20, /* 8660 only */
44 ION_SYSTEM_CONTIG_HEAP_ID = 21,
45 ION_ADSP_HEAP_ID = 22,
46 ION_PIL1_HEAP_ID = 23, /* Currently used for other PIL images */
47 ION_SF_HEAP_ID = 24,
48 ION_SYSTEM_HEAP_ID = 25,
49 ION_PIL2_HEAP_ID = 26, /* Currently used for modem firmware images */
50 ION_QSECOM_HEAP_ID = 27,
51 ION_AUDIO_HEAP_ID = 28,
52 ION_MM_FIRMWARE_HEAP_ID = 29,
53 ION_HEAP_ID_RESERVED = 31 /** Bit reserved for ION_FLAG_SECURE flag */
54 };
55
56 static unsigned int ion_type[] = {
57 ION_HEAP(ION_CP_MM_HEAP_ID),
58 ION_HEAP(ION_CP_MFC_HEAP_ID),
59 ION_HEAP(ION_SYSTEM_CONTIG_HEAP_ID),
60 ION_HEAP(ION_ADSP_HEAP_ID ),
61 ION_HEAP(ION_SF_HEAP_ID),
62 ION_HEAP(ION_SYSTEM_HEAP_ID),
63 ION_HEAP(ION_QSECOM_HEAP_ID),
64 ION_HEAP(ION_AUDIO_HEAP_ID),
65 };
66
67 #define NEW_ION
ion_alloc(int fd,int len,int * hdl,unsigned int ion_type)68 int ion_alloc(int fd, int len, int *hdl, unsigned int ion_type)
69 {
70 int ret;
71 struct ion_allocation_data req = {
72 .len = len,
73 #ifdef NEW_ION
74 .heap_id_mask = ion_type,
75 //.flags = ION_SECURE | ION_FORCE_CONTIGUOUS,
76 .flags = (1 << 0),
77 .flags = 0x0,
78 #else
79 .flags = ION_SECURE | ION_FORCE_CONTIGUOUS | ION_HEAP(ION_CP_MM_HEAP_ID),
80 #endif
81 .align = len,
82 };
83
84 ret = ioctl(fd, ION_IOC_ALLOC, &req);
85 if (ret) {
86 return ret;
87 }
88
89 *hdl = req.handle;
90
91 return 0;
92 }
93
ion_free(int fd,int hdl)94 int ion_free(int fd, int hdl)
95 {
96 int ret;
97 struct ion_handle_data req = {
98 .handle = hdl,
99 };
100
101 ret = ioctl(fd, ION_IOC_FREE, &req);
102 if (ret) {
103 return ret;
104 }
105
106 return 0;
107 }
108
ion_map(int fd,int hdl)109 int ion_map(int fd, int hdl)
110 {
111 int ret;
112 struct ion_fd_data req = {
113 .handle = hdl,
114 };
115
116 ret = ioctl(fd, ION_IOC_MAP, &req);
117 if (ret) {
118 return ret;
119 }
120
121 return req.fd;
122 }
123
124 int ion_fd;
125 int ion_handle;
126 int status[2];
127 int cmd = 0;
128
threadForIonFree01()129 void *threadForIonFree01()
130 {
131 status[0] = 1;
132
133 while (cmd == 0) {
134 usleep(10);
135 }
136 if (cmd == -1)
137 goto failed;
138
139 usleep(50);
140 ion_free(ion_fd, ion_handle);
141
142 failed:
143 status[0] = 2;
144 return NULL;
145 }
146
147
threadForIonFree02()148 void *threadForIonFree02()
149 {
150 status[1] = 1;
151
152 while (cmd == 0) {
153 usleep(10);
154 }
155 if(cmd == -1)
156 goto failed;
157
158 usleep(50);
159 ion_free(ion_fd, ion_handle);
160
161 failed:
162 status[1] = 2;
163 return NULL;
164 }
165
main()166 int main()
167 {
168 int ret, i, count;
169 pthread_t tid_free[2];
170
171 count = 0;
172 retry:
173 status[0] = 0;
174 status[1] = 0;
175 cmd = 0;
176 ion_fd = open("/dev/ion", O_RDONLY| O_SYNC, 0);
177 if (ion_fd < 0) {
178 return -1;
179 }
180
181 for (i=0; i < sizeof(ion_type)/sizeof(ion_type[0]); i++) {
182 ret = ion_alloc(ion_fd, 0x1000, &ion_handle, ion_type[i]);
183 if (ret == 0) {
184 break;
185 }
186 }
187
188 if (i == sizeof(ion_type)/sizeof(ion_type[0])) {
189 goto failed;
190 }
191
192 ret = pthread_create(&tid_free[0], NULL, threadForIonFree01, NULL);
193 if (ret != 0) {
194 goto failed;
195 }
196
197 ret = pthread_create(&tid_free[1], NULL, threadForIonFree02, NULL);
198 if (ret != 0) {
199 cmd = -1;
200 goto failed;
201 }
202
203 while (status[0] != 1 || status[1] != 1) {
204 usleep(50);
205 }
206
207 cmd = 1;
208 ret = ion_map(ion_fd, ion_handle);
209
210 while (status[0] != 2 || status[1] != 2) {
211 usleep(50);
212 }
213
214 failed:
215 ion_free(ion_fd,ion_handle);
216 close(ion_fd);
217 goto retry;
218
219 return 0;
220 }
221
222