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 */
21static 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}
47MEM_TEST(mem_test_ms_b, UT_TESTF_CONSOLE_REC);
48
49/* Test 'ms' command with 16-bit values */
50static 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}
72MEM_TEST(mem_test_ms_w, UT_TESTF_CONSOLE_REC);
73
74/* Test 'ms' command with 32-bit values */
75static 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}
106MEM_TEST(mem_test_ms_l, UT_TESTF_CONSOLE_REC);
107
108/* Test 'ms' command with continuation */
109static 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}
156MEM_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 */
159static 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}
200MEM_TEST(mem_test_ms_cont_end, UT_TESTF_CONSOLE_REC);
201
202/* Test 'ms' command with multiple values */
203static 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}
229MEM_TEST(mem_test_ms_mult, UT_TESTF_CONSOLE_REC);
230
231/* Test 'ms' command with string */
232static 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}
272MEM_TEST(mem_test_ms_s, UT_TESTF_CONSOLE_REC);
273
274/* Test 'ms' command with limit */
275static 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}
301MEM_TEST(mem_test_ms_limit, UT_TESTF_CONSOLE_REC);
302
303/* Test 'ms' command in quiet mode */
304static 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}
325MEM_TEST(mem_test_ms_quiet, UT_TESTF_CONSOLE_REC);
326