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