1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2012, The Chromium Authors
4  */
5 
6 #include <common.h>
7 #include <command.h>
8 #include <efi_api.h>
9 #include <display_options.h>
10 #include <log.h>
11 #include <mapmem.h>
12 #include <version_string.h>
13 #include <vsprintf.h>
14 #include <test/suites.h>
15 #include <test/test.h>
16 #include <test/ut.h>
17 
18 #define BUF_SIZE	0x100
19 
20 #define FAKE_BUILD_TAG	"jenkins-u-boot-denx_uboot_dm-master-build-aarch64" \
21 			"and a lot more text to come"
22 
23 /* Declare a new print test */
24 #define PRINT_TEST(_name, _flags)	UNIT_TEST(_name, _flags, print_test)
25 
26 #if CONFIG_IS_ENABLED(LIB_UUID)
27 /* Test printing GUIDs */
print_guid(struct unit_test_state * uts)28 static int print_guid(struct unit_test_state *uts)
29 {
30 	unsigned char guid[16] = {
31 		1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
32 	};
33 	unsigned char guid_esp[16] = {
34 		0x28, 0x73, 0x2a, 0xc1, 0x1f, 0xf8, 0xd2, 0x11,
35 		0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B
36 	};
37 	char str[40];
38 	int ret;
39 
40 	sprintf(str, "%pUb", guid);
41 	ut_asserteq_str("01020304-0506-0708-090a-0b0c0d0e0f10", str);
42 	sprintf(str, "%pUB", guid);
43 	ut_asserteq_str("01020304-0506-0708-090A-0B0C0D0E0F10", str);
44 	sprintf(str, "%pUl", guid);
45 	ut_asserteq_str("04030201-0605-0807-090a-0b0c0d0e0f10", str);
46 	sprintf(str, "%pUs", guid);
47 	ut_asserteq_str("04030201-0605-0807-090a-0b0c0d0e0f10", str);
48 	sprintf(str, "%pUL", guid);
49 	ut_asserteq_str("04030201-0605-0807-090A-0B0C0D0E0F10", str);
50 	sprintf(str, "%pUs", guid_esp);
51 	if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID)) { /* brace needed */
52 		ut_asserteq_str("system", str);
53 	} else {
54 		ut_asserteq_str("c12a7328-f81f-11d2-ba4b-00a0c93ec93b", str);
55 	}
56 	ret = snprintf(str, 4, "%pUL", guid);
57 	ut_asserteq(0, str[3]);
58 	ut_asserteq(36, ret);
59 
60 	return 0;
61 }
62 PRINT_TEST(print_guid, 0);
63 #endif
64 
65 #if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD)
66 /* Test efi_loader specific printing */
print_efi_ut(struct unit_test_state * uts)67 static int print_efi_ut(struct unit_test_state *uts)
68 {
69 	char str[10];
70 	u8 buf[sizeof(struct efi_device_path_sd_mmc_path) +
71 	       sizeof(struct efi_device_path)];
72 	u8 *pos = buf;
73 	struct efi_device_path *dp_end;
74 	struct efi_device_path_sd_mmc_path *dp_sd =
75 			(struct efi_device_path_sd_mmc_path *)pos;
76 
77 	/* Create a device path for an SD card */
78 	dp_sd->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
79 	dp_sd->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_SD;
80 	dp_sd->dp.length = sizeof(struct efi_device_path_sd_mmc_path);
81 	dp_sd->slot_number = 3;
82 	pos += sizeof(struct efi_device_path_sd_mmc_path);
83 	/* Append end node */
84 	dp_end = (struct efi_device_path *)pos;
85 	dp_end->type = DEVICE_PATH_TYPE_END;
86 	dp_end->sub_type = DEVICE_PATH_SUB_TYPE_END;
87 	dp_end->length = sizeof(struct efi_device_path);
88 
89 	snprintf(str, sizeof(str), "_%pD_", buf);
90 	ut_assertok(strcmp("_/SD(3)_", str));
91 
92 	/* NULL device path */
93 	snprintf(str, sizeof(str), "_%pD_", NULL);
94 	ut_assertok(strcmp("_<NULL>_", str));
95 
96 	return 0;
97 }
98 PRINT_TEST(print_efi_ut, 0);
99 #endif
100 
print_printf(struct unit_test_state * uts)101 static int print_printf(struct unit_test_state *uts)
102 {
103 	char big_str[400];
104 	int big_str_len;
105 	char str[10], *s;
106 	int len;
107 
108 	snprintf(str, sizeof(str), "testing");
109 	ut_assertok(strcmp("testing", str));
110 
111 	snprintf(str, sizeof(str), "testing but too long");
112 	ut_assertok(strcmp("testing b", str));
113 
114 	snprintf(str, 1, "testing none");
115 	ut_assertok(strcmp("", str));
116 
117 	*str = 'x';
118 	snprintf(str, 0, "testing none");
119 	ut_asserteq('x', *str);
120 
121 	sprintf(big_str, "_%ls_", u"foo");
122 	ut_assertok(strcmp("_foo_", big_str));
123 
124 	/* Test the banner function */
125 	s = display_options_get_banner(true, str, sizeof(str));
126 	ut_asserteq_ptr(str, s);
127 	ut_assertok(strcmp("\n\nU-Boo\n\n", s));
128 
129 	/* Assert that we do not overwrite memory before the buffer */
130 	str[0] = '`';
131 	s = display_options_get_banner(true, str + 1, 1);
132 	ut_asserteq_ptr(str + 1, s);
133 	ut_assertok(strcmp("`", str));
134 
135 	str[0] = '~';
136 	s = display_options_get_banner(true, str + 1, 2);
137 	ut_asserteq_ptr(str + 1, s);
138 	ut_assertok(strcmp("~\n", str));
139 
140 	/* The last two characters are set to \n\n for all buffer sizes > 2 */
141 	s = display_options_get_banner(false, str, sizeof(str));
142 	ut_asserteq_ptr(str, s);
143 	ut_assertok(strcmp("U-Boot \n\n", s));
144 
145 	/* Give it enough space for some of the version */
146 	big_str_len = strlen(version_string) - 5;
147 	s = display_options_get_banner_priv(false, FAKE_BUILD_TAG, big_str,
148 					    big_str_len);
149 	ut_asserteq_ptr(big_str, s);
150 	ut_assertok(strncmp(version_string, s, big_str_len - 3));
151 	ut_assertok(strcmp("\n\n", s + big_str_len - 3));
152 
153 	/* Give it enough space for the version and some of the build tag */
154 	big_str_len = strlen(version_string) + 9 + 20;
155 	s = display_options_get_banner_priv(false, FAKE_BUILD_TAG, big_str,
156 					    big_str_len);
157 	ut_asserteq_ptr(big_str, s);
158 	len = strlen(version_string);
159 	ut_assertok(strncmp(version_string, s, len));
160 	ut_assertok(strncmp(", Build: ", s + len, 9));
161 	ut_assertok(strncmp(FAKE_BUILD_TAG, s + 9 + len, 12));
162 	ut_assertok(strcmp("\n\n", s + big_str_len - 3));
163 
164 	return 0;
165 }
166 PRINT_TEST(print_printf, 0);
167 
print_display_buffer(struct unit_test_state * uts)168 static int print_display_buffer(struct unit_test_state *uts)
169 {
170 	u8 *buf;
171 	int i;
172 
173 	buf = map_sysmem(0, BUF_SIZE);
174 	memset(buf, '\0', BUF_SIZE);
175 	for (i = 0; i < 0x11; i++)
176 		buf[i] = i * 0x11;
177 
178 	/* bytes */
179 	console_record_reset();
180 	print_buffer(0, buf, 1, 0x12, 0);
181 	ut_assert_nextline("00000000: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  ..\"3DUfw........");
182 	ut_assert_nextline("00000010: 10 00                                            ..");
183 	ut_assert_console_end();
184 
185 	/* line length */
186 	console_record_reset();
187 	print_buffer(0, buf, 1, 0x12, 8);
188 	ut_assert_nextline("00000000: 00 11 22 33 44 55 66 77  ..\"3DUfw");
189 	ut_assert_nextline("00000008: 88 99 aa bb cc dd ee ff  ........");
190 	ut_assert_nextline("00000010: 10 00                    ..");
191 	ut_assert_console_end();
192 
193 	/* long line */
194 	console_record_reset();
195 	buf[0x41] = 0x41;
196 	print_buffer(0, buf, 1, 0x42, 0x40);
197 	ut_assert_nextline("00000000: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ..\"3DUfw........................................................");
198 	ut_assert_nextline("00000040: 00 41                                                                                                                                                                                            .A");
199 	ut_assert_console_end();
200 
201 	/* address */
202 	console_record_reset();
203 	print_buffer(0x12345678, buf, 1, 0x12, 0);
204 	ut_assert_nextline("12345678: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  ..\"3DUfw........");
205 	ut_assert_nextline("12345688: 10 00                                            ..");
206 	ut_assert_console_end();
207 
208 	/* 16-bit */
209 	console_record_reset();
210 	print_buffer(0, buf, 2, 9, 0);
211 	ut_assert_nextline("00000000: 1100 3322 5544 7766 9988 bbaa ddcc ffee  ..\"3DUfw........");
212 	ut_assert_nextline("00000010: 0010                                     ..");
213 	ut_assert_console_end();
214 
215 	/* 32-bit */
216 	console_record_reset();
217 	print_buffer(0, buf, 4, 5, 0);
218 	ut_assert_nextline("00000000: 33221100 77665544 bbaa9988 ffeeddcc  ..\"3DUfw........");
219 	ut_assert_nextline("00000010: 00000010                             ....");
220 	ut_assert_console_end();
221 
222 	/* 64-bit */
223 	console_record_reset();
224 	print_buffer(0, buf, 8, 3, 0);
225 	ut_assert_nextline("00000000: 7766554433221100 ffeeddccbbaa9988  ..\"3DUfw........");
226 	ut_assert_nextline("00000010: 0000000000000010                   ........");
227 	ut_assert_console_end();
228 
229 	/* ASCII */
230 	console_record_reset();
231 	buf[1] = 31;
232 	buf[2] = 32;
233 	buf[3] = 33;
234 	for (i = 0; i < 4; i++)
235 		buf[4 + i] = 126 + i;
236 	buf[8] = 255;
237 	print_buffer(0, buf, 1, 10, 0);
238 	ut_assert_nextline("00000000: 00 1f 20 21 7e 7f 80 81 ff 99                    .. !~.....");
239 	ut_assert_console_end();
240 
241 	unmap_sysmem(buf);
242 
243 	return 0;
244 }
245 PRINT_TEST(print_display_buffer, UT_TESTF_CONSOLE_REC);
246 
print_hexdump_line(struct unit_test_state * uts)247 static int print_hexdump_line(struct unit_test_state *uts)
248 {
249 	char *linebuf;
250 	u8 *buf;
251 	int i;
252 
253 	buf = map_sysmem(0, BUF_SIZE);
254 	memset(buf, '\0', BUF_SIZE);
255 	for (i = 0; i < 0x11; i++)
256 		buf[i] = i * 0x11;
257 
258 	/* Check buffer size calculations */
259 	linebuf = map_sysmem(0x400, BUF_SIZE);
260 	memset(linebuf, '\xff', BUF_SIZE);
261 	ut_asserteq(-ENOSPC, hexdump_line(0, buf, 1, 0x10, 0, linebuf, 75));
262 	ut_asserteq(-1, linebuf[0]);
263 	ut_asserteq(0x10, hexdump_line(0, buf, 1, 0x10, 0, linebuf, 76));
264 	ut_asserteq(0, linebuf[75]);
265 	ut_asserteq(-1, linebuf[76]);
266 
267 	unmap_sysmem(buf);
268 
269 	return 0;
270 }
271 PRINT_TEST(print_hexdump_line, UT_TESTF_CONSOLE_REC);
272 
print_do_hex_dump(struct unit_test_state * uts)273 static int print_do_hex_dump(struct unit_test_state *uts)
274 {
275 	u8 *buf;
276 	int i;
277 
278 	buf = map_sysmem(0, BUF_SIZE);
279 	memset(buf, '\0', BUF_SIZE);
280 	for (i = 0; i < 0x11; i++)
281 		buf[i] = i * 0x11;
282 
283 	/* bytes */
284 	console_record_reset();
285 	print_hex_dump_bytes("", DUMP_PREFIX_ADDRESS, buf, 0x12);
286 	ut_assert_nextline("00000000: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  ..\"3DUfw........");
287 	ut_assert_nextline("00000010: 10 00                                            ..");
288 	ut_assert_console_end();
289 
290 	/* line length */
291 	console_record_reset();
292 	print_hex_dump("", DUMP_PREFIX_ADDRESS, 8, 1, buf, 0x12, true);
293 	ut_assert_nextline("00000000: 00 11 22 33 44 55 66 77  ..\"3DUfw");
294 	ut_assert_nextline("00000008: 88 99 aa bb cc dd ee ff  ........");
295 	ut_assert_nextline("00000010: 10 00                    ..");
296 	ut_assert_console_end();
297 	unmap_sysmem(buf);
298 
299 	/* long line */
300 	console_record_reset();
301 	buf[0x41] = 0x41;
302 	print_hex_dump("", DUMP_PREFIX_ADDRESS, 0x40, 1, buf, 0x42, true);
303 	ut_assert_nextline("00000000: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ..\"3DUfw........................................................");
304 	ut_assert_nextline("00000040: 00 41                                                                                                                                                                                            .A");
305 	ut_assert_console_end();
306 
307 	/* 16-bit */
308 	console_record_reset();
309 	print_hex_dump("", DUMP_PREFIX_ADDRESS, 0, 2, buf, 0x12, true);
310 	ut_assert_nextline("00000000: 1100 3322 5544 7766 9988 bbaa ddcc ffee  ..\"3DUfw........");
311 	ut_assert_nextline("00000010: 0010                                     ..");
312 	ut_assert_console_end();
313 	unmap_sysmem(buf);
314 
315 	/* 32-bit */
316 	console_record_reset();
317 	print_hex_dump("", DUMP_PREFIX_ADDRESS, 0, 4, buf, 0x14, true);
318 	ut_assert_nextline("00000000: 33221100 77665544 bbaa9988 ffeeddcc  ..\"3DUfw........");
319 	ut_assert_nextline("00000010: 00000010                             ....");
320 	ut_assert_console_end();
321 	unmap_sysmem(buf);
322 
323 	/* 64-bit */
324 	console_record_reset();
325 	print_hex_dump("", DUMP_PREFIX_ADDRESS, 16, 8, buf, 0x18, true);
326 	ut_assert_nextline("00000000: 7766554433221100 ffeeddccbbaa9988  ..\"3DUfw........");
327 	ut_assert_nextline("00000010: 0000000000000010                   ........");
328 	ut_assert_console_end();
329 	unmap_sysmem(buf);
330 
331 	/* ASCII */
332 	console_record_reset();
333 	buf[1] = 31;
334 	buf[2] = 32;
335 	buf[3] = 33;
336 	for (i = 0; i < 4; i++)
337 		buf[4 + i] = 126 + i;
338 	buf[8] = 255;
339 	print_hex_dump("", DUMP_PREFIX_ADDRESS, 0, 1, buf, 10, true);
340 	ut_assert_nextline("00000000: 00 1f 20 21 7e 7f 80 81 ff 99                    .. !~.....");
341 	ut_assert_console_end();
342 	unmap_sysmem(buf);
343 
344 	return 0;
345 }
346 PRINT_TEST(print_do_hex_dump, UT_TESTF_CONSOLE_REC);
347 
snprint(struct unit_test_state * uts)348 static int snprint(struct unit_test_state *uts)
349 {
350 	char buf[10] = "xxxxxxxxx";
351 	int ret;
352 
353 	ret = snprintf(buf, 5, "%d", 12345678);
354 	ut_asserteq_str("1234", buf);
355 	ut_asserteq(8, ret);
356 	ret = snprintf(buf, 5, "0x%x", 0x1234);
357 	ut_asserteq_str("0x12", buf);
358 	ut_asserteq(6, ret);
359 	ret = snprintf(buf, 5, "0x%08x", 0x1234);
360 	ut_asserteq_str("0x00", buf);
361 	ut_asserteq(10, ret);
362 	ret = snprintf(buf, 3, "%s", "abc");
363 	ut_asserteq_str("ab", buf);
364 	ut_asserteq(3, ret);
365 	ret = snprintf(buf, 4, "%s:%s", "abc", "def");
366 	ut_asserteq(0, buf[3]);
367 	ut_asserteq(7, ret);
368 	ret = snprintf(buf, 4, "%s:%d", "abc", 9999);
369 	ut_asserteq(8, ret);
370 	return 0;
371 }
372 PRINT_TEST(snprint, 0);
373 
do_ut_print(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])374 int do_ut_print(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
375 {
376 	struct unit_test *tests = UNIT_TEST_SUITE_START(print_test);
377 	const int n_ents = UNIT_TEST_SUITE_COUNT(print_test);
378 
379 	return cmd_ut_category("print", "print_", tests, n_ents, argc, argv);
380 }
381