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
27 typedef struct {
28 int a;
29 int b;
30 } custom_callback_data;
31
legacy_ion_custom_callback(int ion_fd,int dma_buf_fd,void * legacy_ion_custom_data)32 int legacy_ion_custom_callback(int ion_fd, int dma_buf_fd,
33 void *legacy_ion_custom_data) {
34 int ret = 0;
35 custom_callback_data *data;
36 (void) dma_buf_fd;
37 if (!ion_is_legacy(ion_fd)) {
38 perror("error in legacy ion custom callback");
39 ret = errno;
40 } else {
41 printf("in custom legacy ion cpu sync callback\n");
42 if (legacy_ion_custom_data) {
43 data = (custom_callback_data *) legacy_ion_custom_data;
44 printf("custom data was supplied to ion cpu sync callback: a = %d, b = %d\n",
45 data->a, data->b);
46 }
47 }
48
49 return ret;
50 }
51
libdmabufheaptest(bool use_custom_callback,void * legacy_ion_custom_data)52 void libdmabufheaptest(bool use_custom_callback, void *legacy_ion_custom_data) {
53 const size_t len = 1024 * 1024;
54 int fd = -1, ret = 0;
55 size_t i = 0;
56 unsigned char* ptr = NULL;
57
58 BufferAllocator* bufferAllocator = CreateDmabufHeapBufferAllocator();
59 if (!bufferAllocator) {
60 printf("unable to get allocator\n");
61 return;
62 }
63
64 /*
65 * Legacy ion devices may have hardcoded heap IDs that do not
66 * match the ion UAPI header. Map heap name 'system' to a heap mask
67 * of all 1s so that these devices will allocate from the first
68 * available heap when asked to allocate from a heap of name 'system'.
69 */
70 ret = MapDmabufHeapNameToIonHeap(bufferAllocator, kDmabufSystemHeapName,
71 "" /* no mapping for non-legacy */,
72 0 /* no mapping for non-legacy ion */,
73 ~0 /* legacy ion heap mask */, 0 /* legacy ion heap flag */);
74 if (ret < 0) {
75 printf("MapDmabufHeapNameToIonHeap failed: %d\n", ret);
76 return;
77 }
78
79 /*
80 * Test the DmabufHeapAllocSystem() APIs.
81 */
82 fd = DmabufHeapAllocSystem(bufferAllocator, true /* cpu_access */, len, 0, 0);
83 if (fd < 0) {
84 printf("DmabufHeapAllocSystem() failed: %d cpu_access: true\n", fd);
85 return;
86 }
87 close(fd);
88
89 fd = DmabufHeapAllocSystem(bufferAllocator, false /* cpu_access */, len, 0, 0);
90 if (fd < 0) {
91 printf("DmabufHeapAllocSystem() failed: %d cpu_access: false\n", fd);
92 return;
93 }
94 close(fd);
95
96 fd = DmabufHeapAlloc(bufferAllocator, kDmabufSystemHeapName, len, 0, 0);
97 if (fd < 0) {
98 printf("Alloc failed: %d\n", fd);
99 return;
100 }
101
102 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
103 if (ptr == MAP_FAILED) {
104 perror("mmap failed\n");
105 return;
106 }
107
108 ret = DmabufHeapCpuSyncStart(bufferAllocator, fd, kSyncReadWrite,
109 use_custom_callback ? legacy_ion_custom_callback : NULL,
110 legacy_ion_custom_data);
111 if (ret) {
112 printf("DmabufHeapCpuSyncStart failed: %d\n", ret);
113 return;
114 }
115
116 for (i = 0; i < len; i++) {
117 ptr[i] = (unsigned char)i;
118 }
119 for (i = 0; i < len; i++) {
120 if (ptr[i] != (unsigned char)i) {
121 printf("%s failed wrote %zu read %d from mapped "
122 "memory\n",
123 __func__, i, ptr[i]);
124 return;
125 }
126 }
127
128 ret = DmabufHeapCpuSyncEnd(bufferAllocator, fd, kSyncReadWrite,
129 use_custom_callback ? legacy_ion_custom_callback : NULL,
130 legacy_ion_custom_data);
131 if (ret) {
132 printf("DmabufHeapCpuSyncEnd failed: %d\n", ret);
133 return;
134 }
135
136 munmap(ptr, len);
137 close(fd);
138
139 FreeDmabufHeapBufferAllocator(bufferAllocator);
140 printf("PASSED\n");
141 }
142
main(int argc,char * argv[])143 int main(int argc, char* argv[]) {
144 (void)argc;
145 (void)argv;
146
147 if (CheckIonSupport())
148 printf("ION support detected\n");
149 else
150 printf("No ION support detected\n");
151
152 custom_callback_data data = {.a = 1, .b = 2};
153 printf("*****running with custom legacy ion cpu sync callback, with custom data****\n");
154 libdmabufheaptest(true, &data);
155 printf("*****running with custom legacy ion cpu sync callback, without custom data****\n");
156 libdmabufheaptest(true, NULL);
157 printf("****running without custom legacy ion cpu sync callback, with custom data****\n");
158 libdmabufheaptest(false, &data);
159 printf("****running without custom legacy ion cpu sync callback, without custom data****\n");
160 libdmabufheaptest(false, NULL);
161 return 0;
162 }
163