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