1 /*
2  *   Copyright 2020 Google, Inc
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 
17 #include <BufferAllocator/BufferAllocatorWrapper.h>
18 #include <errno.h>
19 #include <ion/ion.h>
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sys/mman.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 
legacy_ion_custom_callback(int ion_fd)27 int legacy_ion_custom_callback(int ion_fd) {
28     int ret = 0;
29     if (!ion_is_legacy(ion_fd)) {
30         perror("error in legacy ion custom callback");
31         ret = errno;
32     } else {
33         printf("in custom legacy ion cpu sync callback\n");
34     }
35 
36     return ret;
37 }
38 
libdmabufheaptest(bool use_custom_callback)39 void libdmabufheaptest(bool use_custom_callback) {
40     const size_t len = 1024 * 1024;
41     int fd = -1, ret = 0;
42     size_t i = 0;
43     unsigned char* ptr = NULL;
44 
45     BufferAllocator* bufferAllocator = CreateDmabufHeapBufferAllocator();
46     if (!bufferAllocator) {
47         printf("unable to get allocator\n");
48         return;
49     }
50 
51     /*
52      * Legacy ion devices may have hardcoded heap IDs that do not
53      * match the ion UAPI header. Map heap name 'system' to a heap mask
54      * of all 1s so that these devices will allocate from the first
55      * available heap when asked to allocate from a heap of name 'system'.
56      */
57     ret = MapDmabufHeapNameToIonHeap(bufferAllocator, kDmabufSystemHeapName,
58                                      "" /* no mapping for non-legacy */,
59                                      0 /* no mapping for non-legacy ion */,
60                                      ~0 /* legacy ion heap mask */, 0 /* legacy ion heap flag */);
61     if (ret < 0) {
62         printf("MapDmabufHeapNameToIonHeap failed: %d\n", ret);
63         return;
64     }
65 
66     fd = DmabufHeapAlloc(bufferAllocator, kDmabufSystemHeapName, len, 0);
67     if (fd < 0) {
68         printf("Alloc failed: %d\n", fd);
69         return;
70     }
71 
72     ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
73     if (ptr == MAP_FAILED) {
74         perror("mmap failed\n");
75         return;
76     }
77 
78     ret = DmabufHeapCpuSyncStart(bufferAllocator, fd, kSyncReadWrite,
79                                  use_custom_callback ? legacy_ion_custom_callback : NULL);
80     if (ret) {
81         printf("DmabufHeapCpuSyncStart failed: %d\n", ret);
82         return;
83     }
84 
85     for (i = 0; i < len; i++) {
86         ptr[i] = (unsigned char)i;
87     }
88     for (i = 0; i < len; i++) {
89         if (ptr[i] != (unsigned char)i) {
90             printf("%s failed wrote %zu read %d from mapped "
91                    "memory\n",
92                    __func__, i, ptr[i]);
93             return;
94         }
95     }
96 
97     ret = DmabufHeapCpuSyncEnd(bufferAllocator, fd,
98                                use_custom_callback ? legacy_ion_custom_callback : NULL);
99     if (ret) {
100         printf("DmabufHeapCpuSyncEnd failed: %d\n", ret);
101         return;
102     }
103 
104     munmap(ptr, len);
105     close(fd);
106 
107     FreeDmabufHeapBufferAllocator(bufferAllocator);
108     printf("PASSED\n");
109 }
110 
main(int argc,char * argv[])111 int main(int argc, char* argv[]) {
112     (void)argc;
113     (void)argv;
114     printf("*****running with custom legacy ion cpu sync callback****\n");
115     libdmabufheaptest(true);
116     printf("****running without custom legacy ion cpu sync callback****\n");
117     libdmabufheaptest(false);
118     return 0;
119 }
120