1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <lk/macros.h>
18 #include <sys/auxv.h>
19 #include <sys/mman.h>
20 #include <trusty/sys/mman.h>
21 #include <trusty_unittest.h>
22 #include <uapi/err.h>
23
24 #define TEST1_ID 1
25 #define TEST1_PHY_BASE_ADDR 0x70000000U
26 #define TEST1_REG_SIZE 0x1000U
27
28 #define TEST2_ID 2
29 #define TEST2_PHY_BASE_ADDR 0x70010000U
30 #define TEST2_REG_SIZE 0x100U
31
32 #define TEST3_ID 3
33 #define TEST3_PHY_BASE_ADDR 0x70020000U
34 #define TEST3_REG_SIZE 0x4U
35
36 #define PAGE_SIZE getauxval(AT_PAGESZ)
37
38 typedef struct manifest_test {
39 } manifest_test_t;
40
TEST_F_SETUP(manifest_test)41 TEST_F_SETUP(manifest_test) {}
42
TEST_F_TEARDOWN(manifest_test)43 TEST_F_TEARDOWN(manifest_test) {
44 test_abort:;
45 }
46
compare_memory_map(uint8_t * va_base,uint64_t phy_addr,uint32_t size)47 bool compare_memory_map(uint8_t* va_base, uint64_t phy_addr, uint32_t size) {
48 const uint32_t flags = DMA_FLAG_FROM_DEVICE | DMA_FLAG_ALLOW_PARTIAL;
49 int ret;
50 struct dma_pmem pmem;
51
52 ASSERT_NE(va_base, MAP_FAILED);
53
54 ret = prepare_dma((void*)va_base, size, flags, &pmem);
55 ASSERT_EQ(ret, 1);
56 ret = finish_dma((void*)va_base, size, flags);
57 ASSERT_EQ(ret, NO_ERROR);
58 ASSERT_NE(0, phy_addr);
59 ASSERT_EQ(phy_addr, pmem.paddr);
60 ASSERT_EQ(size, pmem.size);
61
62 return true;
63
64 test_abort:
65 return false;
66 }
67
TEST_F(manifest_test,mem_map_test_1)68 TEST_F(manifest_test, mem_map_test_1) {
69 uint8_t* va_base = MAP_FAILED;
70 bool ret;
71
72 va_base = mmap(NULL, TEST1_REG_SIZE, PROT_READ | PROT_WRITE,
73 MMAP_FLAG_IO_HANDLE, TEST1_ID, 0);
74
75 ret = compare_memory_map(va_base, TEST1_PHY_BASE_ADDR, TEST1_REG_SIZE);
76
77 ASSERT_EQ(ret, true)
78
79 test_abort:
80 if (va_base != MAP_FAILED) {
81 EXPECT_EQ(NO_ERROR,
82 munmap(va_base, ROUND_UP(TEST1_REG_SIZE, PAGE_SIZE)));
83 }
84 }
85
TEST_F(manifest_test,mem_map_test_2)86 TEST_F(manifest_test, mem_map_test_2) {
87 uint8_t* va_base = MAP_FAILED;
88 bool ret;
89
90 va_base = mmap(NULL, TEST2_REG_SIZE, PROT_READ | PROT_WRITE,
91 MMAP_FLAG_IO_HANDLE, TEST2_ID, 0);
92
93 ret = compare_memory_map(va_base, TEST2_PHY_BASE_ADDR, TEST2_REG_SIZE);
94
95 ASSERT_EQ(ret, true)
96
97 test_abort:
98 if (va_base != MAP_FAILED) {
99 EXPECT_EQ(NO_ERROR,
100 munmap(va_base, ROUND_UP(TEST2_REG_SIZE, PAGE_SIZE)));
101 }
102 }
103
TEST_F(manifest_test,mem_map_test_3)104 TEST_F(manifest_test, mem_map_test_3) {
105 uint8_t* va_base = MAP_FAILED;
106 bool ret;
107
108 va_base = mmap(NULL, TEST3_REG_SIZE, PROT_READ | PROT_WRITE,
109 MMAP_FLAG_IO_HANDLE, TEST3_ID, 0);
110
111 ret = compare_memory_map(va_base, TEST3_PHY_BASE_ADDR, TEST3_REG_SIZE);
112
113 ASSERT_EQ(ret, true)
114
115 test_abort:
116 if (va_base != MAP_FAILED) {
117 EXPECT_EQ(NO_ERROR,
118 munmap(va_base, ROUND_UP(TEST3_REG_SIZE, PAGE_SIZE)));
119 }
120 }
121
TEST_F(manifest_test,mem_map_test_small_size)122 TEST_F(manifest_test, mem_map_test_small_size) {
123 uint8_t* va_base = MAP_FAILED;
124 bool ret;
125 uint32_t size = 0x400;
126
127 va_base = mmap(NULL, size, PROT_READ | PROT_WRITE, MMAP_FLAG_IO_HANDLE,
128 TEST1_ID, 0);
129
130 ret = compare_memory_map(va_base, TEST1_PHY_BASE_ADDR, size);
131
132 ASSERT_EQ(ret, true)
133
134 test_abort:
135 if (va_base != MAP_FAILED) {
136 EXPECT_EQ(NO_ERROR, munmap(va_base, ROUND_UP(size, PAGE_SIZE)));
137 }
138 }
139
TEST_F(manifest_test,mem_map_test_large_size)140 TEST_F(manifest_test, mem_map_test_large_size) {
141 uint8_t* va_base = MAP_FAILED;
142 uint32_t size = 0x2000;
143
144 va_base = mmap(NULL, size, PROT_READ | PROT_WRITE, MMAP_FLAG_IO_HANDLE,
145 TEST2_ID, 0);
146 ASSERT_EQ(va_base, MAP_FAILED);
147
148 test_abort:
149 if (va_base != MAP_FAILED) {
150 EXPECT_EQ(NO_ERROR, munmap(va_base, ROUND_UP(size, PAGE_SIZE)));
151 }
152 }
153
TEST_F(manifest_test,mem_map_test_unknown_id)154 TEST_F(manifest_test, mem_map_test_unknown_id) {
155 uint8_t* va_base = MAP_FAILED;
156 uint32_t id = 100;
157
158 va_base = mmap(NULL, TEST1_REG_SIZE, PROT_READ | PROT_WRITE,
159 MMAP_FLAG_IO_HANDLE, id, 0);
160 ASSERT_EQ(va_base, MAP_FAILED);
161
162 test_abort:
163 if (va_base != MAP_FAILED) {
164 EXPECT_EQ(NO_ERROR,
165 munmap(va_base, ROUND_UP(TEST1_REG_SIZE, PAGE_SIZE)));
166 }
167 }
168
169 PORT_TEST(manifest_test, "com.android.manifesttest");
170