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