1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2023-08-22 Shell test case for aspace_map with varea_expand
9 */
10 #include "common.h"
11 #include "lwp_user_mm.h"
12 #include <mm_aspace.h>
13
14 #include <rtthread.h>
15
16 static size_t flags = MMF_PREFETCH | MMF_MAP_FIXED;
17 static size_t attr = MMU_MAP_K_RWCB;
18 static rt_mem_obj_t mem_obj = &rt_mm_dummy_mapper;
19
20 static char *ex_vaddr = (void *)0x100000000;
21 static size_t ex_offset = 1024;
22 static size_t map_size = 0x3000;
23
24 static size_t former_vsz;
25 static size_t former_vcount;
26
27 static struct rt_lwp *lwp;
28
_count_vsz(rt_varea_t varea,void * arg)29 static int _count_vsz(rt_varea_t varea, void *arg)
30 {
31 rt_base_t *pvsz = arg;
32 *pvsz += 1;
33 return 0;
34 }
35
count_vcount(rt_aspace_t aspace)36 static rt_base_t count_vcount(rt_aspace_t aspace)
37 {
38 rt_base_t vcount = 0;
39 rt_aspace_traversal(aspace, _count_vsz, &vcount);
40 return vcount;
41 }
42
test_map_varea_expand(void)43 static void test_map_varea_expand(void)
44 {
45 char *next_va;
46 size_t next_offset;
47
48 /* create an existed mapping */
49 next_va = ex_vaddr;
50 former_vsz = rt_aspace_count_vsz(lwp->aspace);
51 former_vcount = count_vcount(lwp->aspace);
52 utest_int_equal(
53 RT_EOK,
54 rt_aspace_map(lwp->aspace, (void *)&ex_vaddr, map_size, attr, flags, mem_obj, ex_offset)
55 );
56 uassert_true(next_va == ex_vaddr);
57 utest_int_equal(former_vsz + map_size, rt_aspace_count_vsz(lwp->aspace));
58 utest_int_equal(former_vcount + 1, count_vcount(lwp->aspace));
59 former_vsz += map_size;
60 former_vcount += 1;
61
62 /* test the RIGHT side expansion of varea by rt_aspace_map */
63 next_va = ex_vaddr + map_size;
64 next_offset = ex_offset + (map_size >> MM_PAGE_SHIFT);
65 utest_int_equal(
66 RT_EOK,
67 rt_aspace_map(lwp->aspace, (void *)&next_va, map_size, attr, flags, mem_obj, next_offset)
68 );
69 uassert_true(next_va == (char *)ex_vaddr + map_size);
70 utest_int_equal(former_vsz + map_size, rt_aspace_count_vsz(lwp->aspace));
71 utest_int_equal(former_vcount, count_vcount(lwp->aspace));
72 former_vsz += map_size;
73
74 /* test the LEFT side expansion of varea by rt_aspace_map */
75 next_va = ex_vaddr - map_size;
76 next_offset = ex_offset - (map_size >> MM_PAGE_SHIFT);
77 utest_int_equal(
78 RT_EOK,
79 rt_aspace_map(lwp->aspace, (void *)&next_va, map_size, attr, flags, mem_obj, next_offset)
80 );
81 uassert_true(next_va == ex_vaddr - map_size);
82 utest_int_equal(former_vsz + map_size, rt_aspace_count_vsz(lwp->aspace));
83 utest_int_equal(former_vcount, count_vcount(lwp->aspace));
84 former_vsz += map_size;
85
86 /* test the expand varea routine from rt_aspace_map_static */
87 utest_int_equal(RT_EOK, rt_aspace_unmap_range(lwp->aspace, next_va, 3 * map_size));
88
89 /* test the expand varea routine from rt_aspace_map_phy */
90 /* test the expand varea routine from rt_aspace_map_phy_static */
91 /* these 2 from another file */
92 }
93
aspace_map_tc(void)94 static void aspace_map_tc(void)
95 {
96 CONSIST_HEAP(test_map_varea_expand());
97 }
98
utest_tc_init(void)99 static rt_err_t utest_tc_init(void)
100 {
101 lwp = lwp_create(0);
102 if (lwp)
103 lwp_user_space_init(lwp, 1);
104 else
105 return -RT_ENOMEM;
106 return RT_EOK;
107 }
108
utest_tc_cleanup(void)109 static rt_err_t utest_tc_cleanup(void)
110 {
111 lwp_ref_dec(lwp);
112 return RT_EOK;
113 }
114
testcase(void)115 static void testcase(void)
116 {
117 UTEST_UNIT_RUN(aspace_map_tc);
118 }
119 UTEST_TC_EXPORT(testcase, "testcases.mm.aspace_map.varea_expand", utest_tc_init, utest_tc_cleanup, 10);
120