1*4882a593Smuzhiyun /* Copyright 2020 Rockchip Electronics Co. LTD
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * Licensed under the Apache License, Version 2.0 (the "License");
4*4882a593Smuzhiyun * you may not use this file except in compliance with the License.
5*4882a593Smuzhiyun * You may obtain a copy of the License at
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * http://www.apache.org/licenses/LICENSE-2.0
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * Unless required by applicable law or agreed to in writing, software
10*4882a593Smuzhiyun * distributed under the License is distributed on an "AS IS" BASIS,
11*4882a593Smuzhiyun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*4882a593Smuzhiyun * See the License for the specific language governing permissions and
13*4882a593Smuzhiyun * limitations under the License.
14*4882a593Smuzhiyun */
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #undef DBG_MOD_ID
17*4882a593Smuzhiyun #define DBG_MOD_ID RK_ID_MB
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include <stdio.h>
20*4882a593Smuzhiyun #include <unistd.h>
21*4882a593Smuzhiyun #include <cstring>
22*4882a593Smuzhiyun #include <vector>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #include "rk_debug.h"
25*4882a593Smuzhiyun #include "rk_mpi_mb.h"
26*4882a593Smuzhiyun #include "rk_mpi_sys.h"
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #include "test_comm_argparse.h"
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define MB_POOL_COUNT 10
31*4882a593Smuzhiyun #define MB_POOL_MB_COUNT 10
32*4882a593Smuzhiyun #define MB_POOL_MB_SIZE 1280 * 720 * 2
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun typedef struct _rkTestMbCtx {
35*4882a593Smuzhiyun RK_S32 s32MbCount;
36*4882a593Smuzhiyun RK_S32 s32MbSize;
37*4882a593Smuzhiyun RK_S32 s32PoolCount;
38*4882a593Smuzhiyun RK_S32 s32LoopCount;
39*4882a593Smuzhiyun RK_BOOL bExternal;
40*4882a593Smuzhiyun RK_BOOL bPreAlloc;
41*4882a593Smuzhiyun RK_S32 s32RemapMode;
42*4882a593Smuzhiyun RK_S32 s32AllocType;
43*4882a593Smuzhiyun } TEST_MB_CTX_S;
44*4882a593Smuzhiyun
unit_test_mpi_mb(const TEST_MB_CTX_S * pstCtx)45*4882a593Smuzhiyun RK_S32 unit_test_mpi_mb(const TEST_MB_CTX_S *pstCtx) {
46*4882a593Smuzhiyun MB_POOL_CONFIG_S pstMbPoolCfg;
47*4882a593Smuzhiyun std::vector<MB_BLK> vector;
48*4882a593Smuzhiyun std::vector<MB_BLK>::iterator iter;
49*4882a593Smuzhiyun RK_S32 s32Ret = RK_SUCCESS;
50*4882a593Smuzhiyun RK_S32 loopCount = pstCtx->s32LoopCount;
51*4882a593Smuzhiyun RK_S32 s32UniqueId = -1;
52*4882a593Smuzhiyun RK_S32 s32DupFd = -1;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun memset(&pstMbPoolCfg, 0, sizeof(MB_POOL_CONFIG_S));
55*4882a593Smuzhiyun pstMbPoolCfg.u64MBSize = pstCtx->s32MbSize;
56*4882a593Smuzhiyun pstMbPoolCfg.u32MBCnt = pstCtx->s32MbCount;
57*4882a593Smuzhiyun pstMbPoolCfg.bPreAlloc = pstCtx->bPreAlloc;
58*4882a593Smuzhiyun pstMbPoolCfg.enRemapMode = (MB_REMAP_MODE_E)pstCtx->s32RemapMode;
59*4882a593Smuzhiyun pstMbPoolCfg.enAllocType = (MB_ALLOC_TYPE_E)pstCtx->s32AllocType;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun do {
62*4882a593Smuzhiyun for (RK_S32 i = 0; i < pstCtx->s32PoolCount; i++) {
63*4882a593Smuzhiyun MB_POOL pool = RK_MPI_MB_CreatePool(&pstMbPoolCfg);
64*4882a593Smuzhiyun if (pool == MB_INVALID_POOLID) {
65*4882a593Smuzhiyun s32Ret = RK_ERR_MB_2MPOOLS;
66*4882a593Smuzhiyun goto __FAILED;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun RK_LOGI("pool id %d", pool);
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun for (RK_S32 i = 0; i < pstCtx->s32PoolCount; i++) {
72*4882a593Smuzhiyun vector.clear();
73*4882a593Smuzhiyun for (RK_S32 j = 0; j < pstCtx->s32MbCount; j++) {
74*4882a593Smuzhiyun MB_BLK mb = RK_MPI_MB_GetMB(i, pstMbPoolCfg.u64MBSize, RK_FALSE);
75*4882a593Smuzhiyun if (mb == MB_INVALID_HANDLE) {
76*4882a593Smuzhiyun s32Ret = RK_ERR_MB_NOBUF;
77*4882a593Smuzhiyun goto __FAILED;
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun RK_U64 phyAddr = RK_MPI_MB_Handle2PhysAddr(mb);
80*4882a593Smuzhiyun if (pstMbPoolCfg.enDmaType == MB_DMA_TYPE_CMA
81*4882a593Smuzhiyun && pstMbPoolCfg.enAllocType == MB_ALLOC_TYPE_DMA
82*4882a593Smuzhiyun && phyAddr == 0) {
83*4882a593Smuzhiyun s32Ret = RK_ERR_MB_BUSY;
84*4882a593Smuzhiyun RK_MPI_MB_ReleaseMB(mb);
85*4882a593Smuzhiyun goto __FAILED;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun MB_POOL poolId = RK_MPI_MB_Handle2PoolId(mb);
88*4882a593Smuzhiyun if (poolId != i) {
89*4882a593Smuzhiyun s32Ret = RK_ERR_MB_BUSY;
90*4882a593Smuzhiyun RK_MPI_MB_ReleaseMB(mb);
91*4882a593Smuzhiyun goto __FAILED;
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun RK_S32 refsCount = RK_MPI_MB_InquireUserCnt(mb);
94*4882a593Smuzhiyun if (refsCount != 1) {
95*4882a593Smuzhiyun s32Ret = RK_ERR_MB_BUSY;
96*4882a593Smuzhiyun RK_MPI_MB_ReleaseMB(mb);
97*4882a593Smuzhiyun goto __FAILED;
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun RK_VOID *virAddr = RK_MPI_MB_Handle2VirAddr(mb);
100*4882a593Smuzhiyun if (virAddr == RK_NULL) {
101*4882a593Smuzhiyun s32Ret = RK_ERR_MB_BUSY;
102*4882a593Smuzhiyun RK_MPI_MB_ReleaseMB(mb);
103*4882a593Smuzhiyun goto __FAILED;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun RK_S32 fd = RK_MPI_MB_Handle2Fd(mb);
106*4882a593Smuzhiyun if (pstMbPoolCfg.enAllocType == MB_ALLOC_TYPE_DMA
107*4882a593Smuzhiyun && fd < 0) {
108*4882a593Smuzhiyun s32Ret = RK_ERR_MB_BUSY;
109*4882a593Smuzhiyun RK_MPI_MB_ReleaseMB(mb);
110*4882a593Smuzhiyun goto __FAILED;
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun if (pstMbPoolCfg.enAllocType == MB_ALLOC_TYPE_DMA) {
113*4882a593Smuzhiyun if (RK_MPI_MB_VirAddr2Handle(virAddr) != mb) {
114*4882a593Smuzhiyun s32Ret = RK_ERR_MB_BUSY;
115*4882a593Smuzhiyun RK_MPI_MB_ReleaseMB(mb);
116*4882a593Smuzhiyun goto __FAILED;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun s32UniqueId = RK_MPI_MB_Handle2UniqueId(mb);
119*4882a593Smuzhiyun if (s32UniqueId < 0) {
120*4882a593Smuzhiyun s32Ret = RK_ERR_MB_BUSY;
121*4882a593Smuzhiyun RK_MPI_MB_ReleaseMB(mb);
122*4882a593Smuzhiyun goto __FAILED;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun s32DupFd = RK_MPI_MB_UniqueId2Fd(s32UniqueId);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun RK_LOGI("get poolId(%d) from mb(%p) refsCount(%d) phyAddr(%p) virAddr(%p) "
128*4882a593Smuzhiyun "fd(%d) uniqueId(%d) dupFd(%d)",
129*4882a593Smuzhiyun poolId, mb, refsCount, phyAddr, virAddr, fd, s32UniqueId, s32DupFd);
130*4882a593Smuzhiyun if (s32DupFd >= 0) {
131*4882a593Smuzhiyun close(s32DupFd);
132*4882a593Smuzhiyun s32DupFd = -1;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun vector.emplace_back(mb);
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun iter = vector.begin();
137*4882a593Smuzhiyun for (; iter != vector.end(); ++iter) {
138*4882a593Smuzhiyun s32Ret = RK_MPI_MB_ReleaseMB(*iter);
139*4882a593Smuzhiyun if (s32Ret != RK_SUCCESS) {
140*4882a593Smuzhiyun goto __FAILED;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun for (RK_S32 i = 0; i < pstCtx->s32PoolCount; i++) {
146*4882a593Smuzhiyun s32Ret = RK_MPI_MB_DestroyPool(i);
147*4882a593Smuzhiyun if (s32Ret != RK_SUCCESS) {
148*4882a593Smuzhiyun goto __FAILED;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun loopCount--;
152*4882a593Smuzhiyun RK_LOGI("looping times %d", pstCtx->s32LoopCount - loopCount);
153*4882a593Smuzhiyun } while (loopCount > 0);
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun return RK_SUCCESS;
156*4882a593Smuzhiyun __FAILED:
157*4882a593Smuzhiyun iter = vector.begin();
158*4882a593Smuzhiyun for (; iter != vector.end(); ++iter) {
159*4882a593Smuzhiyun RK_MPI_MB_ReleaseMB(*iter);
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun for (RK_S32 i = 0; i < pstCtx->s32PoolCount; i++) {
162*4882a593Smuzhiyun RK_MPI_MB_DestroyPool(i);
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun return s32Ret;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun static const char *const usages[] = {
168*4882a593Smuzhiyun "./rk_mpi_mb_test [-c MB_COUNT] [-s MB_SIZE]...",
169*4882a593Smuzhiyun NULL,
170*4882a593Smuzhiyun };
171*4882a593Smuzhiyun
main(RK_S32 argc,const char ** argv)172*4882a593Smuzhiyun RK_S32 main(RK_S32 argc, const char **argv) {
173*4882a593Smuzhiyun RK_S32 s32Ret = RK_SUCCESS;
174*4882a593Smuzhiyun TEST_MB_CTX_S stMbCtx;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun memset(&stMbCtx, 0, sizeof(TEST_MB_CTX_S));
177*4882a593Smuzhiyun stMbCtx.s32MbCount = 1;
178*4882a593Smuzhiyun stMbCtx.s32MbSize = 4 * 1024 * 1024;
179*4882a593Smuzhiyun stMbCtx.s32LoopCount = 1;
180*4882a593Smuzhiyun stMbCtx.s32PoolCount = 1;
181*4882a593Smuzhiyun stMbCtx.bPreAlloc = RK_FALSE;
182*4882a593Smuzhiyun stMbCtx.s32RemapMode = MB_REMAP_MODE_CACHED;
183*4882a593Smuzhiyun stMbCtx.s32AllocType = MB_ALLOC_TYPE_DMA;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun struct argparse_option options[] = {
186*4882a593Smuzhiyun OPT_HELP(),
187*4882a593Smuzhiyun OPT_GROUP("basic options:"),
188*4882a593Smuzhiyun OPT_INTEGER('n', "loop", &(stMbCtx.s32LoopCount), "the count of looping. default(1).", NULL, 0, 0),
189*4882a593Smuzhiyun OPT_INTEGER('c', "mb_count", &(stMbCtx.s32MbCount), "the count of mb. default(1).", NULL, 0, 0),
190*4882a593Smuzhiyun OPT_INTEGER('s', "mb_size", &(stMbCtx.s32MbSize), "mb size. default(4MB).", NULL, 0, 0),
191*4882a593Smuzhiyun OPT_INTEGER('p', "pool_count", &(stMbCtx.s32PoolCount), "the count of pool. default(1).", NULL, 0, 0),
192*4882a593Smuzhiyun OPT_INTEGER('a', "pre_alloc", &(stMbCtx.bPreAlloc), "pre alloc or not. default(0). 0: no 1: yes.", NULL, 0, 0),
193*4882a593Smuzhiyun OPT_INTEGER('r', "remap_mode", &(stMbCtx.s32RemapMode),
194*4882a593Smuzhiyun "remapping mode. default(2). 0: none, 256: no cache, 512: cached", NULL, 0, 0),
195*4882a593Smuzhiyun OPT_INTEGER('t', "alloc_type", &(stMbCtx.s32AllocType),
196*4882a593Smuzhiyun "alloc type. default(0). 0: DMA, 1: malloc", NULL, 0, 0),
197*4882a593Smuzhiyun OPT_END(),
198*4882a593Smuzhiyun };
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun struct argparse argparse;
201*4882a593Smuzhiyun argparse_init(&argparse, options, usages, 0);
202*4882a593Smuzhiyun argparse_describe(&argparse, "\nselect a test case to run.",
203*4882a593Smuzhiyun "\nuse --help for details.");
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun argc = argparse_parse(&argparse, argc, argv);
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun s32Ret = unit_test_mpi_mb(&stMbCtx);
208*4882a593Smuzhiyun if (s32Ret != RK_SUCCESS) {
209*4882a593Smuzhiyun goto __FAILED;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun RK_LOGI("test running ok.");
213*4882a593Smuzhiyun return RK_SUCCESS;
214*4882a593Smuzhiyun __FAILED:
215*4882a593Smuzhiyun RK_LOGE("test running failed!");
216*4882a593Smuzhiyun return RK_ERR_MB_BUSY;
217*4882a593Smuzhiyun }
218