// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2019 MediaTek Inc. */ #include #include #include #include #include #include "m4u_mva.h" #include "m4u_priv.h" #if defined(CONFIG_MACH_MT6758) int M4U_VPU_PORT_NAME = M4U_PORT_VPU; #else int M4U_VPU_PORT_NAME = M4U_PORT_VPU1; #endif void verify_ret(int ret, unsigned int start, unsigned int end) { switch (ret) { case -1: M4UMSG("test range [0x%x, 0x%x] config error\n", start, end); break; case 1: M4UMSG( "test range [0x%x, 0x%x] is in the vpu region\n", start, end); break; case 0: M4UMSG( "test range [0x%x, 0x%x] is out of vpu region\n", start, end); break; default: break; } } #define case_nr 5 void test_case_check_mva_region(void) { int ret = 0; int i = 0, j = 0; unsigned int test_mva_start[case_nr] = {0x40000000, VPU_RESET_VECTOR_FIX_MVA_END, 0x50080000, VPU_FIX_MVA_END, 0x500FFFFF}; unsigned int test_mva_end[case_nr] = { VPU_RESET_VECTOR_FIX_MVA_START, 0x5FFFFFFF, VPU_FIX_MVA_START, 0xFFFFFFFF, VPU_FIX_MVA_START}; unsigned int size, size_aligned; unsigned int nr; unsigned int startIdx; struct m4u_buf_info_t tmp; struct m4u_buf_info_t *pMvaInfo = &tmp; pMvaInfo->port = M4U_VPU_PORT_NAME;/*M4U_PORT_DISP_OVL0, M4U_PORT_VPU*/ M4UMSG( "%s========================>\n", __func__); /*test case that input range intersects to vpu. *should print config error. */ /*4 cases: * |--------------|------|---------|------------|----------| * 0x0 0x500 0x501 0x600 0x800 0xFFF *case 1: start | end *case 2: start| end *case 3: start | end *case 4: start | end */ M4UMSG( "<*test case that input range intersects to vpu: =>should print config error.*>\n"); for (i = 0; i < case_nr; i++) { size = test_mva_end[i] - test_mva_start[i] + 1; size_aligned = GET_RANGE_SIZE(START_ALIGNED(test_mva_start[i]), END_ALIGNED(test_mva_start[i], size)); nr = MVA_GRAPH_BLOCK_NR_ALIGNED(size_aligned); startIdx = MVAGRAPH_INDEX(test_mva_start[i]); ret = m4u_check_mva_region(startIdx, nr, pMvaInfo); verify_ret(ret, test_mva_start[i], test_mva_end[i]); } /*test case: input range is in the vpu region *case 1: in and port id is rgiht. should print belongs to vpu. *case 2: in and port id isn's rgiht. should print config error. */ M4UMSG( "<*test case: input range is in the vpu region: =>should print in vpu region & config error*>\n"); test_mva_start[0] = VPU_RESET_VECTOR_FIX_MVA_START; test_mva_end[0] = VPU_RESET_VECTOR_FIX_MVA_END; test_mva_start[1] = VPU_FIX_MVA_START; test_mva_end[1] = VPU_FIX_MVA_END; for (i = 0; i < 2; i++) { if (i == 0) pMvaInfo->port = M4U_VPU_PORT_NAME; else pMvaInfo->port = M4U_PORT_DISP_OVL0; for (j = 0; j < 2; j++) { size = test_mva_end[j] - test_mva_start[j] + 1; size_aligned = GET_RANGE_SIZE(START_ALIGNED(test_mva_start[j]), END_ALIGNED(test_mva_start[j], size)); nr = MVA_GRAPH_BLOCK_NR_ALIGNED(size_aligned); startIdx = MVAGRAPH_INDEX(test_mva_start[j]); ret = m4u_check_mva_region(startIdx, nr, pMvaInfo); verify_ret(ret, test_mva_start[j], test_mva_end[j]); } } /*test case: input range is out of vpu region.*/ M4UMSG( "<*test case: input range is out of vpu region: =>should print out of vpu region*>\n"); test_mva_start[0] = 0x100000; test_mva_end[0] = 0x4FFFFFFF; /*0x50080000 is out of vpu mva region, but in the vpu mvaGraph, *we think input range intersects to vpu region */ test_mva_start[1] = 0x50100000; test_mva_end[1] = 0x5FFFFFFF; test_mva_start[2] = 0x80000000; test_mva_end[2] = 0x8FFFFFFF; for (i = 0; i < 3; i++) { size = test_mva_end[i] - test_mva_start[i] + 1; size_aligned = GET_RANGE_SIZE(START_ALIGNED(test_mva_start[i]), END_ALIGNED(test_mva_start[i], size)); nr = MVA_GRAPH_BLOCK_NR_ALIGNED(size_aligned); startIdx = MVAGRAPH_INDEX(test_mva_start[i]); ret = m4u_check_mva_region(startIdx, nr, pMvaInfo); verify_ret(ret, test_mva_start[i], test_mva_end[i]); } } #define REGION_NR 15 #define IN_INDEX_START 5 #define IN_INDEX_END 6 #define INTERSECT_INDEX_START 0 #define INTERSECT_INDEX_END 4 #define OUT_INDEX_START 7 #define OUT_INDEX_END 9 #define SUB_INDEX_START 10 #define SUB_INDEX_END 14 /*0-3: intersect to vpu fix region. *4-5: in vpu fix region *6-8: out of vpu fix region */ unsigned int gtest_mva_start[REGION_NR] = {0x40000000, 0x5007FFFF, 0x50080000, VPU_FIX_MVA_END, 0x500FFFFF, 0x50000000, 0x60000000, 0x40000000, 0x50100000, 0x80000000, 0x60000000, 0x60f00000, 0x62100000, 0x70100000, 0x7c000000}; unsigned int gtest_mva_end[REGION_NR] = {0x50000000, 0x5FFFFFFF, 0x60000000, 0xFFFFFFFF, 0x60000000, 0x5007FFFF, VPU_FIX_MVA_END, 0x4FFFFFFF, 0x5FFFFFFF, 0x8FFFFFFF, 0x60e00000, 0x62000000, 0x62f00000, 0x7b000000, VPU_FIX_MVA_END}; typedef unsigned int (*mva_alloc_from_fix_region)( unsigned long, unsigned int, unsigned int, void *); static void verify_m4u_do_mva_alloc_fake(unsigned int port_id) { int i = 0; unsigned int size, size_aligned; unsigned int nr; unsigned int startIdx; struct m4u_buf_info_t tmp; struct m4u_buf_info_t *pMvaInfo = &tmp; unsigned int ret = 0; pMvaInfo->port = port_id;/*M4U_PORT_DISP_OVL0, M4U_PORT_VPU*/ for (; i < REGION_NR; i++) { size = gtest_mva_end[i] - gtest_mva_start[i] + 1; M4UMSG("test %dth region [0x%x, 0x%x].\n", i, gtest_mva_start[i], gtest_mva_end[i]); size_aligned = GET_RANGE_SIZE(START_ALIGNED(gtest_mva_start[i]), END_ALIGNED(gtest_mva_start[i], size)); nr = MVA_GRAPH_BLOCK_NR_ALIGNED(size_aligned); startIdx = MVAGRAPH_INDEX(gtest_mva_start[i]); ret = m4u_check_mva_region(startIdx, nr, pMvaInfo); if (ret) M4UMSG( "%dth buf port: %d m4u_do_mva_alloc region [0x%x, 0x%x] failed.\n", i, pMvaInfo->port, gtest_mva_start[i], gtest_mva_end[i]); else M4UMSG( "%dth buf port: %d m4u_do_mva_alloc region [0x%x, 0x%x] success.\n", i, pMvaInfo->port, gtest_mva_start[i], gtest_mva_end[i]); } } void test_case_m4u_do_mva_alloc(void) { M4UMSG( "%s========================>\n", __func__); /*since we are only care that if input mva *region is in or intersects vpu fix region. *if each of the 2 cases occur, m4u_do_mva_alloc will failed. *so, it's ok to only test if m4u_check_mva_region return 0. */ /*vpu port should not m4u_do_mva_alloc vpu fix region, *but it can m4u_do_mva_alloc non-vpu fix region. */ M4UMSG( "<*test case: if vpu want to alloc vpu fix region,"); M4UMSG( "it should not use m4u_do_mva_alloc: => 7th&9th buffer should print success*>\n"); verify_m4u_do_mva_alloc_fake(M4U_VPU_PORT_NAME); /*non-vpu port can m4u_do_mva_alloc non-vpu fix region. *the 7th & 9th buffer should print success. others should print failed */ M4UMSG( "<*test case: non-vpu port can m4u_do_mva_alloc non-vpu fix region:"); M4UMSG( "=>7th&9th buffer should print success*>\n"); verify_m4u_do_mva_alloc_fake(M4U_PORT_DISP_OVL0); } /*m4u_do_mva_alloc_fix should notice the following: *(1) vpu fix region is protected by m4u_check_mva_region. *(2) if vpu port alloc vpu fix region by this, it must make sure reserved bit * mustn't be destroyed. *(3)There is no protection to non-vpu fix region now. if other fix regions are *taken by some ports, only m4u user can check this. *(4)because formal parameter [mva] == fix mva region start, *va + size - 1 should be *not more than fix mva region end. */ static void verify_m4u_do_mva_alloc_fix(unsigned int test_region_start, unsigned int test_region_end, unsigned int port_id, mva_alloc_from_fix_region callback, struct m4u_buf_info_t *pinfo_array[]) { unsigned int va_offset = 0xff, actual_mva_start; int i = 0; unsigned int size, size_aligned; unsigned int nr; unsigned int startIdx; unsigned int ret = 0; for (i = test_region_start; i <= test_region_end; i++) { pinfo_array[i] = vmalloc(sizeof(struct m4u_buf_info_t)); /*M4U_PORT_DISP_OVL0, M4U_PORT_VPU*/ pinfo_array[i]->port = port_id; /*because formal parameter of *m4u_do_mva_alloc_fix [mva] == fix mva region start, *va + size - 1 should be not more than fix mva region end. */ actual_mva_start = gtest_mva_start[i] + va_offset; size = gtest_mva_end[i] - actual_mva_start + 1; M4UMSG("test region [0x%x, 0x%x].\n", actual_mva_start, gtest_mva_end[i]); ret = callback(va_offset, gtest_mva_start[i], size, pinfo_array[i]); if (!ret) { M4UMSG( "port: %d m4u_do_mva_alloc_fix region [0x%x, 0x%x] failed.\n", pinfo_array[i]->port, actual_mva_start, gtest_mva_end[i]); vfree(pinfo_array[i]); } else if (ret == actual_mva_start) M4UMSG( "port: %d m4u_do_mva_alloc_fix region [0x%x, 0x%x] success.\n", pinfo_array[i]->port, actual_mva_start, gtest_mva_end[i]); else { M4UMSG( "port: %d m4u_do_mva_alloc_fix region [0x%x, 0x%x].", pinfo_array[i]->port, actual_mva_start, gtest_mva_end[i]); M4UMSG( "returned 0x%x is not equal to expection one(0x%x).\n", ret, actual_mva_start); m4u_do_mva_free(actual_mva_start, size); vfree(pinfo_array[i]); } size_aligned = GET_RANGE_SIZE(START_ALIGNED(actual_mva_start), END_ALIGNED(actual_mva_start, size)); nr = MVA_GRAPH_BLOCK_NR_ALIGNED(size_aligned); startIdx = MVAGRAPH_INDEX(actual_mva_start); ret = check_reserved_region_integrity(startIdx, nr); if (ret) M4UMSG("check [0x%x - 0x%x] integrity pass\n", startIdx, GET_END_INDEX(startIdx, nr)); else M4UMSG("check [0x%x - 0x%x] integrity failed\n", startIdx, GET_END_INDEX(startIdx, nr)); } } unsigned int gtest_mva_start_normal[REGION_NR] = {0}; unsigned int gtest_mva_end_normal[REGION_NR] = {0}; static void verify_m4u_do_mva_alloc(unsigned int test_region_start, unsigned int test_region_end, unsigned int port_id, struct m4u_buf_info_t *pinfo_array[]) { unsigned int va_offset = 0xff, actual_mva_start; unsigned int size; unsigned int i; unsigned int ret = 0; for (i = test_region_start; i <= test_region_end; i++) { pinfo_array[i] = vmalloc( sizeof(struct m4u_buf_info_t)); /*M4U_PORT_DISP_OVL0, M4U_PORT_VPU*/ pinfo_array[i]->port = port_id; size = gtest_mva_end[i] - gtest_mva_start[i] + 1; actual_mva_start = gtest_mva_start[i] | va_offset; ret = m4u_do_mva_alloc(va_offset, size, (void *)pinfo_array[i]); if (!ret) { M4UMSG("port: %d m4u_do_mva_alloc 0x%x bytes failed.\n", pinfo_array[i]->port, size); vfree(pinfo_array[i]); } else { M4UMSG( "port: %d m4u_do_mva_alloc 0x%x bytes in [0x%x, 0x%x] success.\n", pinfo_array[i]->port, size, ret, (ret + size - 1)); gtest_mva_start_normal[i] = ret; gtest_mva_end_normal[i] = ret + size - 1; } } } /*verify_m4u_do_mva_free only free non-vpu region. *it doesn't need integrity-checking. */ static void verify_m4u_do_mva_free(unsigned int test_region_start, unsigned int test_region_end, struct m4u_buf_info_t *pinfo_array[]) { unsigned int size; unsigned int i; unsigned int ret = 0; for (i = test_region_start; i <= test_region_end; i++) { M4UMSG("free region [0x%x, 0x%x].\n", gtest_mva_start_normal[i], gtest_mva_end_normal[i]); size = gtest_mva_end_normal[i] - gtest_mva_start_normal[i] + 1; ret = m4u_do_mva_free(gtest_mva_start_normal[i], size); if (ret) M4UMSG("m4u_do_mva_free region [0x%x, 0x%x] failed.\n", gtest_mva_start_normal[i], gtest_mva_end_normal[i]); else M4UMSG("m4u_do_mva_free region [0x%x, 0x%x] success.\n", gtest_mva_start_normal[i], gtest_mva_end_normal[i]); vfree(pinfo_array[i]); } } /*free vpu region. need to check integrity*/ static void verify_m4u_do_mva_free_fix(unsigned int test_region_start, unsigned int test_region_end, struct m4u_buf_info_t *pinfo_array[]) { unsigned int va_offset = 0xff, actual_mva_start; unsigned int size, size_aligned, nr, startIdx; unsigned int i; unsigned int ret = 0; for (i = test_region_start; i <= test_region_end; i++) { actual_mva_start = gtest_mva_start[i] + va_offset; M4UMSG("free region [0x%x, 0x%x].\n", actual_mva_start, gtest_mva_end[i]); size = gtest_mva_end[i] - actual_mva_start + 1; ret = m4u_do_mva_free(actual_mva_start, size); if (ret) M4UMSG("m4u_do_mva_free region [0x%x, 0x%x] failed.\n", actual_mva_start, gtest_mva_end[i]); else M4UMSG("m4u_do_mva_free region [0x%x, 0x%x] success.\n", actual_mva_start, gtest_mva_end[i]); vfree(pinfo_array[i]); size_aligned = GET_RANGE_SIZE(START_ALIGNED(actual_mva_start), END_ALIGNED(actual_mva_start, size)); nr = MVA_GRAPH_BLOCK_NR_ALIGNED(size_aligned); startIdx = MVAGRAPH_INDEX(actual_mva_start); ret = check_reserved_region_integrity(startIdx, nr); if (ret) M4UMSG("check [0x%x - 0x%x] integrity pass\n", startIdx, GET_END_INDEX(startIdx, nr)); else M4UMSG("check [0x%x - 0x%x] integrity failed\n", startIdx, GET_END_INDEX(startIdx, nr)); } } /*allocate 5-9 success. free 5-9 success & check integrity pass*/ void test_case_m4u_do_mva_alloc_fix(void) { struct m4u_buf_info_t **p_info_array0 = vmalloc(sizeof(struct m4u_buf_info_t **) * (IN_INDEX_END - IN_INDEX_START + 1)); struct m4u_buf_info_t **p_info_array1 = vmalloc(sizeof(struct m4u_buf_info_t **) * (IN_INDEX_END - IN_INDEX_START + 1)); struct m4u_buf_info_t **p_info_array2 = vmalloc(sizeof(struct m4u_buf_info_t **) * (OUT_INDEX_END - OUT_INDEX_START + 1)); struct m4u_buf_info_t **p_info_array3 = vmalloc(sizeof(struct m4u_buf_info_t **) * (INTERSECT_INDEX_END - INTERSECT_INDEX_START + 1)); if (p_info_array0 == NULL || p_info_array1 == NULL || p_info_array2 == NULL || p_info_array3 == NULL) M4UMSG("p_info_array == NULL"); else { m4u_mvaGraph_dump(); M4UMSG( "%s========================>\n", __func__); M4UMSG( "<*test case: CANNOT m4u_do_mva_alloc_fix vpu fix region by non-vpu port:"); M4UMSG( "=> allocation print failed & integrity must pass*>\n"); verify_m4u_do_mva_alloc_fix( IN_INDEX_START, IN_INDEX_END, M4U_PORT_DISP_OVL0, m4u_do_mva_alloc_fix, p_info_array0); M4UMSG( "<*test case: it's ok to m4u_do_mva_alloc_fix vpu fix region by vpu port:"); M4UMSG( "=> allocation print success & integrity must pass*>\n"); verify_m4u_do_mva_alloc_fix( IN_INDEX_START, IN_INDEX_END, M4U_VPU_PORT_NAME, m4u_do_mva_alloc_fix, p_info_array1); M4UMSG( "<*test case: it's ok to m4u_do_mva_alloc_fix non-vpu fix region by vpu port:"); M4UMSG( "=> allocation print success & integrity is no requeired*>\n"); verify_m4u_do_mva_alloc_fix( OUT_INDEX_START, OUT_INDEX_END, M4U_VPU_PORT_NAME, m4u_do_mva_alloc_fix, p_info_array2); M4UMSG( "<*test case: CANNOT m4u_do_mva_alloc_fix the one intersecting vpu fix region:"); M4UMSG( "=> allocation print failed & integrity is no requeired*>\n"); verify_m4u_do_mva_alloc_fix( INTERSECT_INDEX_START, INTERSECT_INDEX_END, M4U_VPU_PORT_NAME, m4u_do_mva_alloc_fix, p_info_array3); M4UMSG("free all allocated mva.\n"); verify_m4u_do_mva_free_fix(IN_INDEX_START, IN_INDEX_END, p_info_array1); verify_m4u_do_mva_free_fix(OUT_INDEX_START, OUT_INDEX_END, p_info_array2); } vfree(p_info_array0); vfree(p_info_array1); vfree(p_info_array2); vfree(p_info_array3); m4u_mvaGraph_dump(); } void test_case_m4u_do_mva_alloc_start_from(void) { struct m4u_buf_info_t **p_info_array0 = vmalloc(sizeof(struct m4u_buf_info_t **) * (IN_INDEX_END - IN_INDEX_START + 1)); struct m4u_buf_info_t **p_info_array1 = vmalloc(sizeof(struct m4u_buf_info_t **) * (IN_INDEX_END - IN_INDEX_START + 1)); struct m4u_buf_info_t **p_info_array2 = vmalloc(sizeof(struct m4u_buf_info_t **) * (OUT_INDEX_END - OUT_INDEX_START + 1)); struct m4u_buf_info_t **p_info_array3 = vmalloc(sizeof(struct m4u_buf_info_t **) * (INTERSECT_INDEX_END - INTERSECT_INDEX_START + 1)); M4UMSG( "test_case_m4u_do_mva_alloc_fix========================>\n"); if (p_info_array0 == NULL || p_info_array1 == NULL || p_info_array2 == NULL || p_info_array3 == NULL) M4UMSG("p_info_array == NULL"); else { M4UMSG( "<*test case: CANNOT m4u_do_mva_alloc_fix vpu fix region by non-vpu port:"); M4UMSG( "=> allocation print failed & integrity must pass*>\n"); verify_m4u_do_mva_alloc_fix( IN_INDEX_START, IN_INDEX_END, M4U_PORT_DISP_OVL0, m4u_do_mva_alloc_start_from, p_info_array0); M4UMSG( "<*test case: it's ok to m4u_do_mva_alloc_fix vpu fix region by vpu port:"); M4UMSG( "=> allocation print success & integrity must pass*>\n"); verify_m4u_do_mva_alloc_fix( IN_INDEX_START, IN_INDEX_END, M4U_VPU_PORT_NAME, m4u_do_mva_alloc_start_from, p_info_array1); M4UMSG( "<*test case: it's ok to m4u_do_mva_alloc_fix non-vpu fix region by vpu port:"); M4UMSG( "=> allocation print success & integrity is no requeired*>\n"); verify_m4u_do_mva_alloc_fix( OUT_INDEX_START, OUT_INDEX_END, M4U_VPU_PORT_NAME, m4u_do_mva_alloc_start_from, p_info_array2); M4UMSG( "<*test case: CANNOT m4u_do_mva_alloc_fix the one intersecting vpu fix region:"); M4UMSG( "=> allocation print failed & integrity is no requeired*>\n"); verify_m4u_do_mva_alloc_fix( INTERSECT_INDEX_START, INTERSECT_INDEX_END, M4U_VPU_PORT_NAME, m4u_do_mva_alloc_start_from, p_info_array3); M4UMSG("free all allocated mva.\n"); verify_m4u_do_mva_free_fix(IN_INDEX_START, IN_INDEX_END, p_info_array1); verify_m4u_do_mva_free_fix(OUT_INDEX_START, OUT_INDEX_END, p_info_array1); } vfree(p_info_array0); vfree(p_info_array1); vfree(p_info_array2); vfree(p_info_array3); } /*(1)make sure m4u_do_mva_free non-vpu fix region or vpu fix region is passed. *(2)non-vpu port should not free vpu fix region. */ void test_case_m4u_do_mva_free(void) { struct m4u_buf_info_t **p_info_array0 = vmalloc(sizeof(struct m4u_buf_info_t **) * (OUT_INDEX_START - OUT_INDEX_START + 1)); struct m4u_buf_info_t **p_info_array1 = vmalloc(sizeof(struct m4u_buf_info_t **) * (IN_INDEX_END - IN_INDEX_START + 1)); struct m4u_buf_info_t **p_info_array2 = vmalloc(sizeof(struct m4u_buf_info_t **) * (OUT_INDEX_END - OUT_INDEX_START + 1)); struct m4u_buf_info_t **p_info_array3 = vmalloc(sizeof(struct m4u_buf_info_t **) * (SUB_INDEX_END - SUB_INDEX_START + 1)); if (p_info_array0 == NULL || p_info_array1 == NULL || p_info_array2 == NULL || p_info_array3 == NULL) M4UMSG("p_info_array == NULL"); else { M4UMSG( "%s========================>\n", __func__); m4u_mvaGraph_dump(); M4UMSG( "<*test case: non vpu port m4u_do_mva_alloc non-vpu region => print pass*>\n"); /*non vpu port m4u_do_mva_alloc non-vpu region*/ verify_m4u_do_mva_alloc(OUT_INDEX_START, OUT_INDEX_START, M4U_PORT_DISP_OVL0, p_info_array0); m4u_mvaGraph_dump(); /*free non-vpu fix region*/ M4UMSG( "<*test case: free non-vpu fix region allocated by m4u_do_mva_alloc => print pass*>\n"); verify_m4u_do_mva_free(OUT_INDEX_START, OUT_INDEX_START, p_info_array0); m4u_mvaGraph_dump(); /*use m4u_do_mva_alloc_start_from to alloc *sub range in vpu fix region. and then free. */ M4UMSG( "<*test case: non-vpu port verify_m4u_do_mva_alloc_fix non-vpu fix region => print pass*>\n"); verify_m4u_do_mva_alloc_fix(SUB_INDEX_START, SUB_INDEX_END, M4U_VPU_PORT_NAME, m4u_do_mva_alloc_start_from, p_info_array3); m4u_mvaGraph_dump(); /*free sub-vpu fix region*/ M4UMSG( "<*test case: free non-vpu fix region allocated by m4u_do_mva_alloc_fix => print pass*>\n"); verify_m4u_do_mva_free_fix(SUB_INDEX_START, SUB_INDEX_END, p_info_array3); m4u_mvaGraph_dump(); } vfree(p_info_array0); vfree(p_info_array1); vfree(p_info_array2); vfree(p_info_array3); } void test_dummy(void) { int i = 0; unsigned int size; unsigned int nr; struct m4u_buf_info_t tmp; struct m4u_buf_info_t *pMvaInfo = &tmp; unsigned int ret = 0; unsigned int startIdx; /*M4U_PORT_DISP_OVL0, M4U_PORT_VPU*/ pMvaInfo->port = M4U_VPU_PORT_NAME; size = gtest_mva_end[0] - gtest_mva_start[0] + 1; M4UMSG("test %dth region [0x%x, 0x%x].\n", i, gtest_mva_start[0], gtest_mva_end[0]); nr = MVA_GRAPH_BLOCK_NR_ALIGNED(size); startIdx = MVAGRAPH_INDEX(gtest_mva_start[0]); ret = m4u_check_mva_region(gtest_mva_start[0], nr, pMvaInfo); if (ret) M4UMSG( "%dth buf m4u_do_mva_alloc region [0x%x, 0x%x] failed.\n", 0, gtest_mva_start[0], gtest_mva_end[0]); else M4UMSG( "%dth buf m4u_do_mva_alloc region [0x%x, 0x%x] success.\n", 0, gtest_mva_start[0], gtest_mva_end[0]); } void test_m4u_do_mva_alloc_stage3(void) { int last_free_index_in_stage1, size0, size1, size2, nr; struct m4u_buf_info_t *pinfo; unsigned int result_mva0, result_mva1, result_mva2; M4UMSG("start to %s\n", __func__); pinfo = vmalloc(sizeof(struct m4u_buf_info_t)); if (pinfo == NULL) { M4UMSG("pinfo == NULL\n"); vfree(pinfo); return; } pinfo->port = 0; last_free_index_in_stage1 = get_last_free_graph_idx_in_stage1_region(); M4UMSG("cur_first_index = 0x%x\n", last_free_index_in_stage1); if (last_free_index_in_stage1 < MVAGRAPH_INDEX(VPU_RESET_VECTOR_FIX_MVA_START)) { nr = MVAGRAPH_INDEX(VPU_RESET_VECTOR_FIX_MVA_START) - 1 - last_free_index_in_stage1 + 1; size0 = MVA_GRAPH_NR_TO_SIZE(nr); /*stage 1*/ result_mva0 = m4u_do_mva_alloc(0, size0, pinfo); M4UMSG( "allocated all remained free blocks in stage 1, result_mva = 0x%x size = 0x%x\n", result_mva0, size0); nr = MVAGRAPH_INDEX(VPU_FIX_MVA_START) - 1 - MVAGRAPH_INDEX(VPU_RESET_VECTOR_FIX_MVA_END); size1 = MVA_GRAPH_NR_TO_SIZE(nr); /*stage 2*/ result_mva1 = m4u_do_mva_alloc(0, size1, pinfo); M4UMSG( "allocated all remained free blocks in stage 2, result_mva = 0x%x size = 0x%x\n", result_mva1, size1); /*stage 3*/ size2 = 0x5000000; result_mva2 = m4u_do_mva_alloc(0, size2, pinfo); if (result_mva2 <= VPU_FIX_MVA_END) M4UMSG( "result_mva = 0x%x is not in stage 3, case failed!\n", result_mva2); else M4UMSG( "result_mva = 0x%x is in stage 3, case succed!\n", result_mva2); m4u_mvaGraph_dump(); m4u_do_mva_free(result_mva0, size0); m4u_do_mva_free(result_mva1, size1); m4u_do_mva_free(result_mva2, size2); m4u_mvaGraph_dump(); } else M4UMSG( "after just boot, mva should not be allocated in stage 3!\n"); vfree(pinfo); } void test_m4u_do_mva_alloc_start_from_V2p4(void) { int last_free_index_in_stage1, size0, size1, size2, nr; struct m4u_buf_info_t *pinfo; unsigned int result_mva0, result_mva1, result_mva2; M4UMSG("start to test_m4u_do_mva_alloc_start_from_V2_4\n"); pinfo = vmalloc(sizeof(struct m4u_buf_info_t)); if (!pinfo) { M4UMSG("alloc info fail\n"); return; } pinfo->port = 0; last_free_index_in_stage1 = get_last_free_graph_idx_in_stage1_region(); if (last_free_index_in_stage1 < MVAGRAPH_INDEX(VPU_RESET_VECTOR_FIX_MVA_START)) { nr = MVAGRAPH_INDEX(VPU_RESET_VECTOR_FIX_MVA_START) - 1 - last_free_index_in_stage1; size0 = MVA_GRAPH_NR_TO_SIZE(nr); M4UMSG( "alloc mva in stage 1, port=%d index = 0x%x size = 0x%x\n", pinfo->port, last_free_index_in_stage1, size0); result_mva0 = m4u_do_mva_alloc(0, size0, pinfo); m4u_mvaGraph_dump(); M4UMSG("alloc mva in stage 1, result_mva0 = 0x%x\n", result_mva0); pinfo->port = M4U_VPU_PORT_NAME; size1 = 0x12000000; M4UMSG("alloc mva in stage 2, port=%d, size = 0x%x\n", pinfo->port, size1); result_mva1 = m4u_do_mva_alloc_start_from(0, 0x12000000, size1, pinfo); m4u_mvaGraph_dump(); M4UMSG("alloc mva in stage 2, result_mva1 = 0x%x\n", result_mva1); pinfo->port = 0; size2 = 0x20000000; M4UMSG("alloc mva in stage 3, size = 0x%x\n", size2); result_mva2 = m4u_do_mva_alloc_start_from(0, 0x10000000, size2, pinfo); m4u_mvaGraph_dump(); M4UMSG("alloc mva in stage 3, result_mva2 = 0x%x\n", result_mva2); pinfo->port = M4U_VPU_PORT_NAME; m4u_mvaGraph_dump(); m4u_do_mva_free(result_mva0, size0); m4u_do_mva_free(result_mva1, size1); m4u_do_mva_free(result_mva2, size2); m4u_mvaGraph_dump(); } else M4UMSG( "after just boot, mva should not be allocated out of stage 1!\n"); vfree(pinfo); } void test_m4u_do_mva_alloc_start_from_V2p4_case1(void) { int first_free_idx, size = 0x4000000; struct m4u_buf_info_t *pinfo; int i; unsigned int *ret_mva = kzalloc(sizeof(unsigned int) * 4096, GFP_KERNEL); M4UMSG( "start to %s\n", __func__); pinfo = vmalloc(sizeof(struct m4u_buf_info_t)); if (pinfo == NULL) { M4UMSG("pinfo == NULL\n"); vfree(pinfo); kfree(ret_mva); return; } pinfo->port = 0; first_free_idx = get_first_free_idx(); M4UMSG("get 1st free index = 0x%x\n", first_free_idx); /*alloc non-vpu region*/ for (i = 0; i < 4096; i++) { *(ret_mva + i) = m4u_do_mva_alloc_start_from(0, (first_free_idx << 20), size, pinfo); if (!*(ret_mva + i)) { M4UMSG( "non vpu region has been allocated over, the last valid %d.\n", i-1); break; } } m4u_mvaGraph_dump(); /*alloc vpu region*/ pinfo->port = M4U_VPU_PORT_NAME; for (; i < 4096; i++) { *(ret_mva + i) = m4u_do_mva_alloc_start_from(0, 0x60000000, size, pinfo); if (!*(ret_mva + i)) { M4UMSG( "vpu region has been allocated over, the last valid %d.\n", i-1); break; } } m4u_mvaGraph_dump(); /*free all*/ for (i = i - 1 ; i >= 0; i--) { if (*(ret_mva + i)) m4u_do_mva_free(*(ret_mva + i), size); } m4u_mvaGraph_dump(); vfree(pinfo); kfree(ret_mva); }