xref: /rockchip-linux_mpp/osal/allocator/allocator_ext_dma.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3  * Copyright (c) 2018 Rockchip Electronics Co., Ltd.
4  */
5 
6 #include <stdio.h>
7 #include <sys/mman.h>
8 
9 #include "mpp_mem.h"
10 #include "mpp_debug.h"
11 #include "mpp_common.h"
12 
13 #include "allocator_ext_dma.h"
14 
15 typedef struct {
16     size_t              alignment;
17     MppAllocFlagType    flags;
18 } allocator_ctx;
19 
allocator_ext_dma_open(void ** ctx,size_t alignment,MppAllocFlagType flags)20 static MPP_RET allocator_ext_dma_open(void **ctx, size_t alignment, MppAllocFlagType flags)
21 {
22     MPP_RET ret = MPP_OK;
23     allocator_ctx *p = NULL;
24 
25     if (NULL == ctx) {
26         mpp_err_f("do not accept NULL input\n");
27         return MPP_ERR_NULL_PTR;
28     }
29 
30     p = mpp_malloc(allocator_ctx, 1);
31     if (NULL == p) {
32         mpp_err_f("failed to allocate context\n");
33         ret = MPP_ERR_MALLOC;
34     } else {
35         p->alignment = alignment;
36         p->flags = flags;
37     }
38 
39     *ctx = p;
40     return ret;
41 }
42 
allocator_ext_dma_alloc(void * ctx,MppBufferInfo * info)43 static MPP_RET allocator_ext_dma_alloc(void *ctx, MppBufferInfo *info)
44 {
45     if (!ctx || !info) {
46         mpp_err_f("found NULL context input\n");
47         return MPP_ERR_VALUE;
48     }
49 
50     return MPP_ERR_PERM;
51 }
52 
allocator_ext_dma_free(void * ctx,MppBufferInfo * info)53 static MPP_RET allocator_ext_dma_free(void *ctx, MppBufferInfo *info)
54 {
55     if (!ctx || !info) {
56         mpp_err_f("found NULL context input\n");
57         return MPP_ERR_VALUE;
58     }
59 
60     return MPP_ERR_PERM;
61 }
62 
allocator_ext_dma_import(void * ctx,MppBufferInfo * info)63 static MPP_RET allocator_ext_dma_import(void *ctx, MppBufferInfo *info)
64 {
65     allocator_ctx *p = (allocator_ctx *)ctx;
66     mpp_assert(p);
67     mpp_assert(info->size);
68 
69     if (info->ptr) {
70         mpp_err_f("The ext_dma is not used for userptr\n");
71         return MPP_ERR_VALUE;
72     }
73 
74     return ((info->fd < 0) ? MPP_ERR_VALUE : MPP_OK);
75 }
76 
allocator_ext_dma_mmap(void * ctx,MppBufferInfo * info)77 static MPP_RET allocator_ext_dma_mmap(void *ctx, MppBufferInfo *info)
78 {
79     void *ptr = NULL;
80     int flags = 0;
81     unsigned long offset = 0L;
82     mpp_assert(ctx);
83     mpp_assert(info->size);
84     mpp_assert(info->fd >= 0);
85 
86     if (info->ptr)
87         return MPP_OK;
88 
89     /*
90      * It is insecure to access the first memory page,
91      * usually system doesn't allow this behavior.
92      */
93     flags = PROT_READ;
94     if (fcntl(info->fd, F_GETFL) & O_RDWR)
95         flags |= PROT_WRITE;
96 
97     ptr = mmap(NULL, info->size, flags, MAP_SHARED, info->fd, offset);
98     if (ptr == MAP_FAILED)
99         return MPP_ERR_NULL_PTR;
100 
101     info->ptr = ptr;
102 
103     return MPP_OK;
104 }
105 
allocator_ext_dma_release(void * ctx,MppBufferInfo * info)106 static MPP_RET allocator_ext_dma_release(void *ctx, MppBufferInfo *info)
107 {
108     mpp_assert(ctx);
109     mpp_assert(info->size);
110 
111     if (info->ptr)
112         munmap(info->ptr, info->size);
113 
114     info->ptr   = NULL;
115     info->hnd   = NULL;
116     info->fd    = -1;
117     info->size  = 0;
118 
119     return MPP_OK;
120 }
121 
allocator_ext_dma_close(void * ctx)122 static MPP_RET allocator_ext_dma_close(void *ctx)
123 {
124     if (ctx) {
125         mpp_free(ctx);
126         return MPP_OK;
127     }
128 
129     mpp_err_f("found NULL context input\n");
130     return MPP_ERR_VALUE;
131 }
132 
os_allocator_ext_dma_flags(void * ctx)133 static MppAllocFlagType os_allocator_ext_dma_flags(void *ctx)
134 {
135     allocator_ctx *p = (allocator_ctx *)ctx;
136 
137     return p ? (MppAllocFlagType)p->flags : MPP_ALLOC_FLAG_NONE;
138 }
139 
140 os_allocator allocator_ext_dma = {
141     .type = MPP_BUFFER_TYPE_EXT_DMA,
142     .name = "ext_dma",
143     .open = allocator_ext_dma_open,
144     .close = allocator_ext_dma_close,
145     .alloc = allocator_ext_dma_alloc,
146     .free = allocator_ext_dma_free,
147     .import = allocator_ext_dma_import,
148     .release = allocator_ext_dma_release,
149     .mmap = allocator_ext_dma_mmap,
150     .flags = os_allocator_ext_dma_flags,
151 };
152