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 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 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 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 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 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 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