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