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 static const struct {
34 std::string heap_name;
35 std::string ion_heap_name;
36 unsigned int ion_heap_flags;
37 unsigned int legacy_ion_heap_mask;
38 } heap_map_table[] = {
39 {"system", "ion_system_heap", ION_FLAG_CACHED, EXYNOS_ION_HEAP_SYSTEM_MASK},
40 {"system-uncached", "ion_system_heap", 0, EXYNOS_ION_HEAP_SYSTEM_MASK},
41 {"crypto", "crypto_heap", ION_FLAG_CACHED, EXYNOS_ION_HEAP_CRYPTO_MASK},
42 {"crypto-uncached", "crypto_heap", 0, EXYNOS_ION_HEAP_CRYPTO_MASK},
43 {"vstream-secure", "vstream_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_VIDEO_STREAM_MASK},
44 {"vframe-secure", "vframe_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_VIDEO_FRAME_MASK},
45 {"vscaler-secure", "vscaler_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_VIDEO_SCALER_MASK},
46 {"faceauth_tpu-secure", "fatpu_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_FA_TPU_MASK},
47 {"faimg-secure", "faimg_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_FA_IMG_MASK},
48 {"farawimg-secure", "farawimg_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_FA_RAWIMG_MASK},
49 {"faprev-secure", "faprev_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_FA_PREV_MASK},
50 {"famodel-secure", "famodel_heap", ION_FLAG_PROTECTED, EXYNOS_ION_HEAP_FA_MODEL_MASK},
51 };
52
exynos_ion_open(void)53 int exynos_ion_open(void) {
54 return 0;
55 }
56
exynos_ion_close(int)57 int exynos_ion_close(int /* fd */) {
58 return 0;
59 }
60
exynos_ion_get_allocator(void)61 BufferAllocator& exynos_ion_get_allocator(void) {
62 static BufferAllocator bufallocator;
63
64 return bufallocator;
65 }
66
exynos_ion_alloc(int,size_t len,unsigned int heap_mask,unsigned int flags)67 int exynos_ion_alloc(int /* ion_fd */, size_t len, unsigned int heap_mask, unsigned int flags) {
68 unsigned int heapflags = flags & (ION_FLAG_PROTECTED | ION_FLAG_CACHED);
69
70 auto& bufallocator = exynos_ion_get_allocator();
71
72 for (const auto& it : heap_map_table) {
73 if ((heap_mask == it.legacy_ion_heap_mask) && (heapflags == it.ion_heap_flags)) {
74 int ret = bufallocator.Alloc(it.heap_name, len, flags);
75 if (ret < 0)
76 ALOGE("Failed to alloc %s, %zu %x (%d)", it.heap_name.c_str(), len, flags, ret);
77
78 return ret;
79 }
80 }
81 ALOGE("%s: unable to find heaps of heap_mask %#x", __func__, heap_mask);
82 return -EINVAL;
83 }
84
exynos_ion_import_handle(int,int fd,int * handle)85 int exynos_ion_import_handle(int /* ion_fd */, int fd, int* handle) {
86 assert(handle != NULL);
87
88 *handle = fd;
89 return 0;
90 }
91
exynos_ion_free_handle(int,int)92 int exynos_ion_free_handle(int /* ion_fd */, int /* handle */) {
93 return 0;
94 }
95
exynos_ion_sync_fd(int __unused ion_fd,int fd)96 int exynos_ion_sync_fd(int __unused ion_fd, int fd) {
97 auto& bufallocator = exynos_ion_get_allocator();
98
99 return bufallocator.CpuSyncStart(fd, kSyncReadWrite);
100 }
101
exynos_ion_sync_start(int __unused ion_fd,int fd,int direction)102 int exynos_ion_sync_start(int __unused ion_fd, int fd, int direction) {
103 auto& bufallocator = exynos_ion_get_allocator();
104
105 return bufallocator.CpuSyncStart(fd, static_cast<SyncType>(direction));
106 }
107
exynos_ion_sync_end(int __unused ion_fd,int fd,int direction)108 int exynos_ion_sync_end(int __unused ion_fd, int fd, int direction) {
109 auto& bufallocator = exynos_ion_get_allocator();
110
111 return bufallocator.CpuSyncEnd(fd, static_cast<SyncType>(direction));
112 }
113