1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Tests for memory commands
4  *
5  * Copyright 2020 Google LLC
6  * Written by Simon Glass <sjg@chromium.org>
7  */
8 
9 #include <common.h>
10 #include <console.h>
11 #include <mapmem.h>
12 #include <dm/test.h>
13 #include <test/ut.h>
14 
15 #define BUF_SIZE	0x100
16 
17 /* Declare a new mem test */
18 #define MEM_TEST(_name, _flags)	UNIT_TEST(_name, _flags, mem_test)
19 
20 /* Test 'ms' command with bytes */
mem_test_ms_b(struct unit_test_state * uts)21 static int mem_test_ms_b(struct unit_test_state *uts)
22 {
23 	u8 *buf;
24 
25 	buf = map_sysmem(0, BUF_SIZE + 1);
26 	memset(buf, '\0', BUF_SIZE);
27 	buf[0x0] = 0x12;
28 	buf[0x31] = 0x12;
29 	buf[0xff] = 0x12;
30 	buf[0x100] = 0x12;
31 	ut_assertok(console_record_reset_enable());
32 	run_command("ms.b 1 ff 12", 0);
33 	ut_assert_nextline("00000030: 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................");
34 	ut_assert_nextline("--");
35 	ut_assert_nextline("000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12    ................");
36 	ut_assert_nextline("2 matches");
37 	ut_assert_console_end();
38 
39 	ut_asserteq(2, env_get_hex("memmatches", 0));
40 	ut_asserteq(0xff, env_get_hex("memaddr", 0));
41 	ut_asserteq(0xfe, env_get_hex("mempos", 0));
42 
43 	unmap_sysmem(buf);
44 
45 	return 0;
46 }
47 MEM_TEST(mem_test_ms_b, UT_TESTF_CONSOLE_REC);
48 
49 /* Test 'ms' command with 16-bit values */
mem_test_ms_w(struct unit_test_state * uts)50 static int mem_test_ms_w(struct unit_test_state *uts)
51 {
52 	u16 *buf;
53 
54 	buf = map_sysmem(0, BUF_SIZE + 2);
55 	memset(buf, '\0', BUF_SIZE);
56 	buf[0x34 / 2] = 0x1234;
57 	buf[BUF_SIZE / 2] = 0x1234;
58 	ut_assertok(console_record_reset_enable());
59 	run_command("ms.w 0 80 1234", 0);
60 	ut_assert_nextline("00000030: 0000 0000 1234 0000 0000 0000 0000 0000    ....4...........");
61 	ut_assert_nextline("1 match");
62 	ut_assert_console_end();
63 
64 	ut_asserteq(1, env_get_hex("memmatches", 0));
65 	ut_asserteq(0x34, env_get_hex("memaddr", 0));
66 	ut_asserteq(0x34 / 2, env_get_hex("mempos", 0));
67 
68 	unmap_sysmem(buf);
69 
70 	return 0;
71 }
72 MEM_TEST(mem_test_ms_w, UT_TESTF_CONSOLE_REC);
73 
74 /* Test 'ms' command with 32-bit values */
mem_test_ms_l(struct unit_test_state * uts)75 static int mem_test_ms_l(struct unit_test_state *uts)
76 {
77 	u32 *buf;
78 
79 	buf = map_sysmem(0, BUF_SIZE + 4);
80 	memset(buf, '\0', BUF_SIZE);
81 	buf[0x38 / 4] = 0x12345678;
82 	buf[BUF_SIZE / 4] = 0x12345678;
83 	ut_assertok(console_record_reset_enable());
84 	run_command("ms 0 40 12345678", 0);
85 	ut_assert_nextline("00000030: 00000000 00000000 12345678 00000000    ........xV4.....");
86 	ut_assert_nextline("1 match");
87 	ut_assert_console_end();
88 
89 	ut_asserteq(1, env_get_hex("memmatches", 0));
90 	ut_asserteq(0x38, env_get_hex("memaddr", 0));
91 	ut_asserteq(0x38 / 4, env_get_hex("mempos", 0));
92 
93 	ut_assertok(console_record_reset_enable());
94 	run_command("ms 0 80 12345679", 0);
95 	ut_assert_nextline("0 matches");
96 	ut_assert_console_end();
97 
98 	ut_asserteq(0, env_get_hex("memmatches", 0));
99 	ut_asserteq(0, env_get_hex("memaddr", 0));
100 	ut_asserteq(0 / 4, env_get_hex("mempos", 0));
101 
102 	unmap_sysmem(buf);
103 
104 	return 0;
105 }
106 MEM_TEST(mem_test_ms_l, UT_TESTF_CONSOLE_REC);
107 
108 /* Test 'ms' command with continuation */
mem_test_ms_cont(struct unit_test_state * uts)109 static int mem_test_ms_cont(struct unit_test_state *uts)
110 {
111 	char *const args[] = {"ms.b", "0", "100", "34"};
112 	int repeatable;
113 	u8 *buf;
114 	int i;
115 
116 	buf = map_sysmem(0, BUF_SIZE);
117 	memset(buf, '\0', BUF_SIZE);
118 	for (i = 5; i < 0x33; i += 3)
119 		buf[i] = 0x34;
120 	ut_assertok(console_record_reset_enable());
121 	run_command("ms.b 0 100 34", 0);
122 	ut_assert_nextlinen("00000000: 00 00 00 00 00 34 00 00 34 00 00 34 00 00 34 00");
123 	ut_assert_nextline("--");
124 	ut_assert_nextlinen("00000010: 00 34 00 00 34 00 00 34 00 00 34 00 00 34 00 00");
125 	ut_assert_nextline("--");
126 	ut_assert_nextlinen("00000020: 34 00 00 34 00 00 34 00 00 34 00 00 34 00 00 34");
127 	ut_assert_nextlinen("10 matches (repeat command to check for more)");
128 	ut_assert_console_end();
129 
130 	ut_asserteq(10, env_get_hex("memmatches", 0));
131 	ut_asserteq(0x20, env_get_hex("memaddr", 0));
132 	ut_asserteq(0x20, env_get_hex("mempos", 0));
133 
134 	/*
135 	 * run_command() ignoes the repeatable flag when using hush, so call
136 	 * cmd_process() directly
137 	 */
138 	ut_assertok(console_record_reset_enable());
139 	cmd_process(CMD_FLAG_REPEAT, 4, args, &repeatable, NULL);
140 	ut_assert_nextlinen("00000020: 34 00 00 34 00 00 34 00 00 34 00 00 34 00 00 34");
141 	ut_assert_nextline("--");
142 	ut_assert_nextlinen("00000030: 00 00 34 00 00 00 00 00");
143 	ut_assert_nextlinen("6 matches");
144 	ut_assert_console_end();
145 
146 	ut_asserteq(6, env_get_hex("memmatches", 0));
147 	ut_asserteq(0x32, env_get_hex("memaddr", 0));
148 
149 	/* 0x32 less 0x21, where the second search started */
150 	ut_asserteq(0x11, env_get_hex("mempos", 0));
151 
152 	unmap_sysmem(buf);
153 
154 	return 0;
155 }
156 MEM_TEST(mem_test_ms_cont, UT_TESTF_CONSOLE_REC);
157 
158 /* Test that an 'ms' command with continuation stops at the end of the range */
mem_test_ms_cont_end(struct unit_test_state * uts)159 static int mem_test_ms_cont_end(struct unit_test_state *uts)
160 {
161 	char *const args[] = {"ms.b", "1", "ff", "12"};
162 	int repeatable;
163 	u8 *buf;
164 
165 	buf = map_sysmem(0, BUF_SIZE);
166 	memset(buf, '\0', BUF_SIZE);
167 	buf[0x0] = 0x12;
168 	buf[0x31] = 0x12;
169 	buf[0xff] = 0x12;
170 	buf[0x100] = 0x12;
171 	ut_assertok(console_record_reset_enable());
172 	run_command("ms.b 1 ff 12", 0);
173 	ut_assert_nextlinen("00000030");
174 	ut_assert_nextlinen("--");
175 	ut_assert_nextlinen("000000f0");
176 	ut_assert_nextlinen("2 matches");
177 	ut_assert_console_end();
178 
179 	/*
180 	 * run_command() ignoes the repeatable flag when using hush, so call
181 	 * cmd_process() directly.
182 	 *
183 	 * This should produce no matches.
184 	 */
185 	ut_assertok(console_record_reset_enable());
186 	cmd_process(CMD_FLAG_REPEAT, 4, args, &repeatable, NULL);
187 	ut_assert_nextlinen("0 matches");
188 	ut_assert_console_end();
189 
190 	/* One more time */
191 	ut_assertok(console_record_reset_enable());
192 	cmd_process(CMD_FLAG_REPEAT, 4, args, &repeatable, NULL);
193 	ut_assert_nextlinen("0 matches");
194 	ut_assert_console_end();
195 
196 	unmap_sysmem(buf);
197 
198 	return 0;
199 }
200 MEM_TEST(mem_test_ms_cont_end, UT_TESTF_CONSOLE_REC);
201 
202 /* Test 'ms' command with multiple values */
mem_test_ms_mult(struct unit_test_state * uts)203 static int mem_test_ms_mult(struct unit_test_state *uts)
204 {
205 	static const char str[] = "hello";
206 	char *buf;
207 
208 	buf = map_sysmem(0, BUF_SIZE + 5);
209 	memset(buf, '\0', BUF_SIZE);
210 	strcpy(buf + 0x1e, str);
211 	strcpy(buf + 0x63, str);
212 	strcpy(buf + BUF_SIZE - strlen(str) + 1, str);
213 	ut_assertok(console_record_reset_enable());
214 	run_command("ms.b 0 100 68 65 6c 6c 6f", 0);
215 	ut_assert_nextline("00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68 65    ..............he");
216 	ut_assert_nextline("00000020: 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 00 00    llo.............");
217 	ut_assert_nextline("--");
218 	ut_assert_nextline("00000060: 00 00 00 68 65 6c 6c 6f 00 00 00 00 00 00 00 00    ...hello........");
219 	ut_assert_nextline("2 matches");
220 	ut_assert_console_end();
221 	unmap_sysmem(buf);
222 
223 	ut_asserteq(2, env_get_hex("memmatches", 0));
224 	ut_asserteq(0x63, env_get_hex("memaddr", 0));
225 	ut_asserteq(0x63, env_get_hex("mempos", 0));
226 
227 	return 0;
228 }
229 MEM_TEST(mem_test_ms_mult, UT_TESTF_CONSOLE_REC);
230 
231 /* Test 'ms' command with string */
mem_test_ms_s(struct unit_test_state * uts)232 static int mem_test_ms_s(struct unit_test_state *uts)
233 {
234 	static const char str[] = "hello";
235 	static const char str2[] = "hellothere";
236 	char *buf;
237 
238 	buf = map_sysmem(0, BUF_SIZE);
239 	memset(buf, '\0', BUF_SIZE);
240 	strcpy(buf + 0x1e, str);
241 	strcpy(buf + 0x63, str);
242 	strcpy(buf + 0xa1, str2);
243 	ut_assertok(console_record_reset_enable());
244 	run_command("ms.s 0 100 hello", 0);
245 	ut_assert_nextline("00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68 65    ..............he");
246 	ut_assert_nextline("00000020: 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 00 00    llo.............");
247 	ut_assert_nextline("--");
248 	ut_assert_nextline("00000060: 00 00 00 68 65 6c 6c 6f 00 00 00 00 00 00 00 00    ...hello........");
249 	ut_assert_nextline("--");
250 	ut_assert_nextline("000000a0: 00 68 65 6c 6c 6f 74 68 65 72 65 00 00 00 00 00    .hellothere.....");
251 	ut_assert_nextline("3 matches");
252 	ut_assert_console_end();
253 
254 	ut_asserteq(3, env_get_hex("memmatches", 0));
255 	ut_asserteq(0xa1, env_get_hex("memaddr", 0));
256 	ut_asserteq(0xa1, env_get_hex("mempos", 0));
257 
258 	ut_assertok(console_record_reset_enable());
259 	run_command("ms.s 0 100 hello there", 0);
260 	ut_assert_nextline("000000a0: 00 68 65 6c 6c 6f 74 68 65 72 65 00 00 00 00 00    .hellothere.....");
261 	ut_assert_nextline("1 match");
262 	ut_assert_console_end();
263 
264 	ut_asserteq(1, env_get_hex("memmatches", 0));
265 	ut_asserteq(0xa1, env_get_hex("memaddr", 0));
266 	ut_asserteq(0xa1, env_get_hex("mempos", 0));
267 
268 	unmap_sysmem(buf);
269 
270 	return 0;
271 }
272 MEM_TEST(mem_test_ms_s, UT_TESTF_CONSOLE_REC);
273 
274 /* Test 'ms' command with limit */
mem_test_ms_limit(struct unit_test_state * uts)275 static int mem_test_ms_limit(struct unit_test_state *uts)
276 {
277 	u8 *buf;
278 
279 	buf = map_sysmem(0, BUF_SIZE + 1);
280 	memset(buf, '\0', BUF_SIZE);
281 	buf[0x0] = 0x12;
282 	buf[0x31] = 0x12;
283 	buf[0x62] = 0x12;
284 	buf[0x76] = 0x12;
285 	ut_assertok(console_record_reset_enable());
286 	run_command("ms.b -l2 1 ff 12", 0);
287 	ut_assert_nextline("00000030: 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................");
288 	ut_assert_nextline("--");
289 	ut_assert_nextlinen("00000060: 00 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00");
290 	ut_assert_nextline("2 matches (repeat command to check for more)");
291 	ut_assert_console_end();
292 
293 	ut_asserteq(2, env_get_hex("memmatches", 0));
294 	ut_asserteq(0x62, env_get_hex("memaddr", 0));
295 	ut_asserteq(0x61, env_get_hex("mempos", 0));
296 
297 	unmap_sysmem(buf);
298 
299 	return 0;
300 }
301 MEM_TEST(mem_test_ms_limit, UT_TESTF_CONSOLE_REC);
302 
303 /* Test 'ms' command in quiet mode */
mem_test_ms_quiet(struct unit_test_state * uts)304 static int mem_test_ms_quiet(struct unit_test_state *uts)
305 {
306 	u8 *buf;
307 
308 	buf = map_sysmem(0, BUF_SIZE + 1);
309 	memset(buf, '\0', BUF_SIZE);
310 	buf[0x0] = 0x12;
311 	buf[0x31] = 0x12;
312 	buf[0x62] = 0x12;
313 	buf[0x76] = 0x12;
314 	ut_assertok(console_record_reset_enable());
315 	run_command("ms.b -q -l2 1 ff 12", 0);
316 	ut_assert_console_end();
317 	unmap_sysmem(buf);
318 
319 	ut_asserteq(2, env_get_hex("memmatches", 0));
320 	ut_asserteq(0x62, env_get_hex("memaddr", 0));
321 	ut_asserteq(0x61, env_get_hex("mempos", 0));
322 
323 	return 0;
324 }
325 MEM_TEST(mem_test_ms_quiet, UT_TESTF_CONSOLE_REC);
326