1 /*
2 * ion.cpp
3 *
4 * Copyright 2021 Samsung Electronics Co., Ltd.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <BufferAllocator/BufferAllocator.h>
20 #include <assert.h>
21 #include <errno.h>
22 #include <hardware/exynos/ion.h>
23 #include <ion/ion.h>
24 #include <linux/dma-buf.h>
25 #include <linux/dma-heap.h>
26 #include <log/log.h>
27 #include <stdatomic.h>
28 #include <string.h>
29 #include <sys/stat.h>
30
31 #include <mutex>
32
33 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
34
35 static const struct {
36 std::string heap_name;
37 std::string ion_heap_name;
38 unsigned int ion_heap_flags;
39 unsigned int legacy_ion_heap_mask;
40 } heap_map_table[] = {
41 {"system", "ion_system_heap", ION_FLAG_CACHED, EXYNOS_ION_HEAP_SYSTEM_MASK},
42 {"system-uncached", "ion_system_heap", 0, EXYNOS_ION_HEAP_SYSTEM_MASK},
43 {"crypto", "crypto_heap", ION_FLAG_CACHED, EXYNOS_ION_HEAP_CRYPTO_MASK},
44 {"crypto-uncached", "crypto_heap", 0, EXYNOS_ION_HEAP_CRYPTO_MASK},
45 {"vstream-secure", "vstream_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_VIDEO_STREAM_MASK},
46 {"vframe-secure", "vframe_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_VIDEO_FRAME_MASK},
47 {"vscaler-secure", "vscaler_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_VIDEO_SCALER_MASK},
48 {"faceauth_tpu-secure", "fatpu_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_FA_TPU_MASK},
49 {"faimg-secure", "faimg_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_FA_IMG_MASK},
50 {"farawimg-secure", "farawimg_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_FA_RAWIMG_MASK},
51 {"faprev-secure", "faprev_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_FA_PREV_MASK},
52 {"famodel-secure", "famodel_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_FA_MODEL_MASK},
53 };
54
exynos_ion_get_heap_name(unsigned int legacy_heap_id)55 const char *exynos_ion_get_heap_name(unsigned int legacy_heap_id) {
56 if (legacy_heap_id >= ARRAY_SIZE(heap_map_table))
57 return NULL;
58
59 return heap_map_table[legacy_heap_id].ion_heap_name.c_str();
60 }
61
exynos_ion_open(void)62 int exynos_ion_open(void) {
63 return 0;
64 }
65
exynos_ion_close(int)66 int exynos_ion_close(int /* fd */) {
67 return 0;
68 }
69
exynos_ion_get_allocator(void)70 BufferAllocator& exynos_ion_get_allocator(void) {
71 static BufferAllocator bufallocator;
72
73 return bufallocator;
74 }
75
exynos_ion_alloc(int,size_t len,unsigned int heap_mask,unsigned int flags)76 int exynos_ion_alloc(int /* ion_fd */, size_t len, unsigned int heap_mask, unsigned int flags) {
77 unsigned int heapflags = flags & (ION_FLAG_PROTECTED | ION_FLAG_CACHED);
78
79 auto& bufallocator = exynos_ion_get_allocator();
80
81 for (const auto& it : heap_map_table) {
82 if ((heap_mask == it.legacy_ion_heap_mask) && (heapflags == it.ion_heap_flags)) {
83 int ret = bufallocator.Alloc(it.heap_name, len, flags);
84 if (ret < 0)
85 ALOGE("Failed to alloc %s, %zu %x (%d)", it.heap_name.c_str(), len, flags, ret);
86
87 return ret;
88 }
89 }
90 ALOGE("%s: unable to find heaps of heap_mask %#x", __func__, heap_mask);
91 return -EINVAL;
92 }
93
exynos_ion_import_handle(int,int fd,int * handle)94 int exynos_ion_import_handle(int /* ion_fd */, int fd, int* handle) {
95 assert(handle != NULL);
96
97 *handle = fd;
98 return 0;
99 }
100
exynos_ion_free_handle(int,int)101 int exynos_ion_free_handle(int /* ion_fd */, int /* handle */) {
102 return 0;
103 }
104
exynos_ion_sync_fd(int __unused ion_fd,int fd)105 int exynos_ion_sync_fd(int __unused ion_fd, int fd) {
106 auto& bufallocator = exynos_ion_get_allocator();
107
108 return bufallocator.CpuSyncStart(fd, kSyncReadWrite);
109 }
110
exynos_ion_sync_start(int __unused ion_fd,int fd,int direction)111 int exynos_ion_sync_start(int __unused ion_fd, int fd, int direction) {
112 auto& bufallocator = exynos_ion_get_allocator();
113
114 return bufallocator.CpuSyncStart(fd, static_cast<SyncType>(direction));
115 }
116
exynos_ion_sync_end(int __unused ion_fd,int fd,int direction)117 int exynos_ion_sync_end(int __unused ion_fd, int fd, int direction) {
118 auto& bufallocator = exynos_ion_get_allocator();
119
120 return bufallocator.CpuSyncEnd(fd, static_cast<SyncType>(direction));
121 }
122