From 550a9e7902ce2a6103d97d70a22bad64e4fab7fd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 28 Jul 2020 19:41:14 -0600 Subject: [PATCH] cmd: Update the memory-search command Add various fixes and improvements to this command that were missed in the original version. Unfortunately I forgot to send v2. - Fix Kconfig name - Use a separate variable for the remaining search length - Correct a minor bug - Move into a separate test suite - Add -q flag to the 'quiet' test to test operation when console is enabled - Enable the feature for sandbox Signed-off-by: Simon Glass --- cmd/Kconfig | 2 +- cmd/mem.c | 30 ++++++----- configs/sandbox_defconfig | 1 + include/test/suites.h | 1 + test/cmd/Makefile | 3 +- test/cmd/mem.c | 20 +++++++ test/cmd/mem_search.c | 108 ++++++++++++++++++++++++++++---------- test/cmd_ut.c | 2 + 8 files changed, 124 insertions(+), 43 deletions(-) create mode 100644 test/cmd/mem.c diff --git a/cmd/Kconfig b/cmd/Kconfig index e11176451b..6ac274e620 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -724,7 +724,7 @@ config CMD_MEMORY base - print or set address offset loop - initialize loop on address range -config MEM_SEARCH +config CMD_MEM_SEARCH bool "ms - Memory search" help Memory-search command diff --git a/cmd/mem.c b/cmd/mem.c index 575893c18d..190e2b94a7 100644 --- a/cmd/mem.c +++ b/cmd/mem.c @@ -53,7 +53,8 @@ static ulong dp_last_length = 0x40; static ulong mm_last_addr, mm_last_size; static ulong base_address = 0; -#ifdef CONFIG_MEM_SEARCH +#ifdef CONFIG_CMD_MEM_SEARCH +static ulong dp_last_ms_length; static u8 search_buf[64]; static uint search_len; #endif @@ -367,7 +368,7 @@ static int do_mem_cp(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } -#ifdef CONFIG_MEM_SEARCH +#ifdef CONFIG_CMD_MEM_SEARCH static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -377,6 +378,7 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc, ulong last_pos; /* Offset of last match in 'size' units*/ ulong last_addr; /* Address of last displayed line */ int limit = 10; + int used_len; int count; int size; int i; @@ -384,12 +386,12 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc, /* We use the last specified parameters, unless new ones are entered */ addr = dp_last_addr; size = dp_last_size; - length = dp_last_length; + length = dp_last_ms_length; if (argc < 3) return CMD_RET_USAGE; - if ((!flag & CMD_FLAG_REPEAT)) { + if (!(flag & CMD_FLAG_REPEAT)) { /* * Check for a size specification. * Defaults to long if no or incorrect specification. @@ -398,7 +400,8 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc, if (size < 0 && size != -2 /* string */) return 1; - argc--; argv++; + argc--; + argv++; while (argc && *argv[0] == '-') { int ch = argv[0][1]; @@ -408,7 +411,8 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc, limit = simple_strtoul(argv[0] + 2, NULL, 16); else return CMD_RET_USAGE; - argc--; argv++; + argc--; + argv++; } /* Address is specified since argc > 1 */ @@ -421,7 +425,7 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc, /* Read the bytes to search for */ end = search_buf + sizeof(search_buf); for (i = 2, ptr = search_buf; i < argc && ptr < end; i++) { - if (SUPPORT_64BIT_DATA && size == 8) { + if (MEM_SUPPORT_64BIT_DATA && size == 8) { u64 val = simple_strtoull(argv[i], NULL, 16); *(u64 *)ptr = val; @@ -460,7 +464,8 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc, last_pos = 0; last_addr = 0; count = 0; - for (offset = 0; offset <= bytes - search_len && count < limit; + for (offset = 0; + offset < bytes && offset <= bytes - search_len && count < limit; offset += size) { void *ptr = buf + offset; @@ -495,9 +500,10 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc, unmap_sysmem(buf); - dp_last_addr = addr + offset / size; + used_len = offset / size; + dp_last_addr = addr + used_len; dp_last_size = size; - dp_last_length = length - offset / size; + dp_last_ms_length = length < used_len ? 0 : length - used_len; return count ? 0 : CMD_RET_FAILURE; } @@ -1337,13 +1343,13 @@ U_BOOT_CMD( "[.b, .w, .l" HELP_Q "] addr1 addr2 count" ); -#ifdef CONFIG_MEM_SEARCH +#ifdef CONFIG_CMD_MEM_SEARCH /**************************************************/ U_BOOT_CMD( ms, 255, 1, do_mem_search, "memory search", "[.b, .w, .l" HELP_Q ", .s] [-q | -] address #-of-objects ..." - " -q = quiet, -l = match limit" : + " -q = quiet, -l = match limit" ); #endif diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index f4f97f34ff..65cfc85e51 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -42,6 +42,7 @@ CONFIG_CMD_NVEDIT_SELECT=y CONFIG_LOOPW=y CONFIG_CMD_MD5SUM=y CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MEM_SEARCH=y CONFIG_CMD_MX_CYCLIC=y CONFIG_CMD_MEMTEST=y CONFIG_SYS_MEMTEST_START=0x00100000 diff --git a/include/test/suites.h b/include/test/suites.h index f120b3a82a..ab7b3bd9ca 100644 --- a/include/test/suites.h +++ b/include/test/suites.h @@ -34,6 +34,7 @@ int do_ut_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_env(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]); +int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); diff --git a/test/cmd/Makefile b/test/cmd/Makefile index 85d38f09e8..859dcda239 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -2,4 +2,5 @@ # # Copyright (c) 2013 Google, Inc -obj-$(CONFIG_MEM_SEARCH) += mem_search.o +obj-y += mem.o +obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o diff --git a/test/cmd/mem.c b/test/cmd/mem.c new file mode 100644 index 0000000000..fa6770e8c0 --- /dev/null +++ b/test/cmd/mem.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Executes tests for memory-related commands + * + * Copyright 2020 Google LLC + */ + +#include +#include +#include +#include + +int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + struct unit_test *tests = ll_entry_start(struct unit_test, mem_test); + const int n_ents = ll_entry_count(struct unit_test, mem_test); + + return cmd_ut_category("cmd_mem", "cmd_mem_", tests, n_ents, argc, + argv); +} diff --git a/test/cmd/mem_search.c b/test/cmd/mem_search.c index d57bfad398..94942793a4 100644 --- a/test/cmd/mem_search.c +++ b/test/cmd/mem_search.c @@ -14,8 +14,11 @@ #define BUF_SIZE 0x100 +/* Declare a new mem test */ +#define MEM_TEST(_name, _flags) UNIT_TEST(_name, _flags, mem_test) + /* Test 'ms' command with bytes */ -static int dm_test_ms_b(struct unit_test_state *uts) +static int mem_test_ms_b(struct unit_test_state *uts) { u8 *buf; @@ -25,7 +28,7 @@ static int dm_test_ms_b(struct unit_test_state *uts) buf[0x31] = 0x12; buf[0xff] = 0x12; buf[0x100] = 0x12; - console_record_reset(); + ut_assertok(console_record_reset_enable()); run_command("ms.b 1 ff 12", 0); ut_assert_nextline("00000030: 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................"); ut_assert_nextline("--"); @@ -41,10 +44,10 @@ static int dm_test_ms_b(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ms_b, 0); +MEM_TEST(mem_test_ms_b, UT_TESTF_CONSOLE_REC); /* Test 'ms' command with 16-bit values */ -static int dm_test_ms_w(struct unit_test_state *uts) +static int mem_test_ms_w(struct unit_test_state *uts) { u16 *buf; @@ -52,7 +55,7 @@ static int dm_test_ms_w(struct unit_test_state *uts) memset(buf, '\0', BUF_SIZE); buf[0x34 / 2] = 0x1234; buf[BUF_SIZE / 2] = 0x1234; - console_record_reset(); + ut_assertok(console_record_reset_enable()); run_command("ms.w 0 80 1234", 0); ut_assert_nextline("00000030: 0000 0000 1234 0000 0000 0000 0000 0000 ....4..........."); ut_assert_nextline("1 match"); @@ -66,10 +69,10 @@ static int dm_test_ms_w(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ms_w, 0); +MEM_TEST(mem_test_ms_w, UT_TESTF_CONSOLE_REC); /* Test 'ms' command with 32-bit values */ -static int dm_test_ms_l(struct unit_test_state *uts) +static int mem_test_ms_l(struct unit_test_state *uts) { u32 *buf; @@ -77,7 +80,7 @@ static int dm_test_ms_l(struct unit_test_state *uts) memset(buf, '\0', BUF_SIZE); buf[0x38 / 4] = 0x12345678; buf[BUF_SIZE / 4] = 0x12345678; - console_record_reset(); + ut_assertok(console_record_reset_enable()); run_command("ms 0 40 12345678", 0); ut_assert_nextline("00000030: 00000000 00000000 12345678 00000000 ........xV4....."); ut_assert_nextline("1 match"); @@ -87,7 +90,7 @@ static int dm_test_ms_l(struct unit_test_state *uts) ut_asserteq(0x38, env_get_hex("memaddr", 0)); ut_asserteq(0x38 / 4, env_get_hex("mempos", 0)); - console_record_reset(); + ut_assertok(console_record_reset_enable()); run_command("ms 0 80 12345679", 0); ut_assert_nextline("0 matches"); ut_assert_console_end(); @@ -100,10 +103,10 @@ static int dm_test_ms_l(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ms_l, 0); +MEM_TEST(mem_test_ms_l, UT_TESTF_CONSOLE_REC); /* Test 'ms' command with continuation */ -static int dm_test_ms_cont(struct unit_test_state *uts) +static int mem_test_ms_cont(struct unit_test_state *uts) { char *const args[] = {"ms.b", "0", "100", "34"}; int repeatable; @@ -114,7 +117,7 @@ static int dm_test_ms_cont(struct unit_test_state *uts) memset(buf, '\0', BUF_SIZE); for (i = 5; i < 0x33; i += 3) buf[i] = 0x34; - console_record_reset(); + ut_assertok(console_record_reset_enable()); run_command("ms.b 0 100 34", 0); ut_assert_nextlinen("00000000: 00 00 00 00 00 34 00 00 34 00 00 34 00 00 34 00"); ut_assert_nextline("--"); @@ -132,7 +135,7 @@ static int dm_test_ms_cont(struct unit_test_state *uts) * run_command() ignoes the repeatable flag when using hush, so call * cmd_process() directly */ - console_record_reset(); + ut_assertok(console_record_reset_enable()); cmd_process(CMD_FLAG_REPEAT, 4, args, &repeatable, NULL); ut_assert_nextlinen("00000020: 34 00 00 34 00 00 34 00 00 34 00 00 34 00 00 34"); ut_assert_nextline("--"); @@ -150,10 +153,54 @@ static int dm_test_ms_cont(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ms_cont, 0); +MEM_TEST(mem_test_ms_cont, UT_TESTF_CONSOLE_REC); + +/* Test that an 'ms' command with continuation stops at the end of the range */ +static int mem_test_ms_cont_end(struct unit_test_state *uts) +{ + char *const args[] = {"ms.b", "1", "ff", "12"}; + int repeatable; + u8 *buf; + + buf = map_sysmem(0, BUF_SIZE); + memset(buf, '\0', BUF_SIZE); + buf[0x0] = 0x12; + buf[0x31] = 0x12; + buf[0xff] = 0x12; + buf[0x100] = 0x12; + ut_assertok(console_record_reset_enable()); + run_command("ms.b 1 ff 12", 0); + ut_assert_nextlinen("00000030"); + ut_assert_nextlinen("--"); + ut_assert_nextlinen("000000f0"); + ut_assert_nextlinen("2 matches"); + ut_assert_console_end(); + + /* + * run_command() ignoes the repeatable flag when using hush, so call + * cmd_process() directly. + * + * This should produce no matches. + */ + ut_assertok(console_record_reset_enable()); + cmd_process(CMD_FLAG_REPEAT, 4, args, &repeatable, NULL); + ut_assert_nextlinen("0 matches"); + ut_assert_console_end(); + + /* One more time */ + ut_assertok(console_record_reset_enable()); + cmd_process(CMD_FLAG_REPEAT, 4, args, &repeatable, NULL); + ut_assert_nextlinen("0 matches"); + ut_assert_console_end(); + + unmap_sysmem(buf); + + return 0; +} +MEM_TEST(mem_test_ms_cont_end, UT_TESTF_CONSOLE_REC); /* Test 'ms' command with multiple values */ -static int dm_test_ms_mult(struct unit_test_state *uts) +static int mem_test_ms_mult(struct unit_test_state *uts) { static const char str[] = "hello"; char *buf; @@ -163,7 +210,7 @@ static int dm_test_ms_mult(struct unit_test_state *uts) strcpy(buf + 0x1e, str); strcpy(buf + 0x63, str); strcpy(buf + BUF_SIZE - strlen(str) + 1, str); - console_record_reset(); + ut_assertok(console_record_reset_enable()); run_command("ms.b 0 100 68 65 6c 6c 6f", 0); ut_assert_nextline("00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68 65 ..............he"); ut_assert_nextline("00000020: 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 llo............."); @@ -179,10 +226,10 @@ static int dm_test_ms_mult(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ms_mult, 0); +MEM_TEST(mem_test_ms_mult, UT_TESTF_CONSOLE_REC); /* Test 'ms' command with string */ -static int dm_test_ms_s(struct unit_test_state *uts) +static int mem_test_ms_s(struct unit_test_state *uts) { static const char str[] = "hello"; static const char str2[] = "hellothere"; @@ -193,7 +240,7 @@ static int dm_test_ms_s(struct unit_test_state *uts) strcpy(buf + 0x1e, str); strcpy(buf + 0x63, str); strcpy(buf + 0xa1, str2); - console_record_reset(); + ut_assertok(console_record_reset_enable()); run_command("ms.s 0 100 hello", 0); ut_assert_nextline("00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68 65 ..............he"); ut_assert_nextline("00000020: 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 llo............."); @@ -208,7 +255,7 @@ static int dm_test_ms_s(struct unit_test_state *uts) ut_asserteq(0xa1, env_get_hex("memaddr", 0)); ut_asserteq(0xa1, env_get_hex("mempos", 0)); - console_record_reset(); + ut_assertok(console_record_reset_enable()); run_command("ms.s 0 100 hello there", 0); ut_assert_nextline("000000a0: 00 68 65 6c 6c 6f 74 68 65 72 65 00 00 00 00 00 .hellothere....."); ut_assert_nextline("1 match"); @@ -222,10 +269,10 @@ static int dm_test_ms_s(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ms_s, 0); +MEM_TEST(mem_test_ms_s, UT_TESTF_CONSOLE_REC); /* Test 'ms' command with limit */ -static int dm_test_ms_limit(struct unit_test_state *uts) +static int mem_test_ms_limit(struct unit_test_state *uts) { u8 *buf; @@ -235,7 +282,7 @@ static int dm_test_ms_limit(struct unit_test_state *uts) buf[0x31] = 0x12; buf[0x62] = 0x12; buf[0x76] = 0x12; - console_record_reset(); + ut_assertok(console_record_reset_enable()); run_command("ms.b -l2 1 ff 12", 0); ut_assert_nextline("00000030: 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................"); ut_assert_nextline("--"); @@ -251,10 +298,10 @@ static int dm_test_ms_limit(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ms_limit, 0); +MEM_TEST(mem_test_ms_limit, UT_TESTF_CONSOLE_REC); /* Test 'ms' command in quiet mode */ -static int dm_test_ms_quiet(struct unit_test_state *uts) +static int mem_test_ms_quiet(struct unit_test_state *uts) { u8 *buf; @@ -264,12 +311,15 @@ static int dm_test_ms_quiet(struct unit_test_state *uts) buf[0x31] = 0x12; buf[0x62] = 0x12; buf[0x76] = 0x12; - console_record_reset(); - run_command("ms.b -l2 1 ff 12", 0); + ut_assertok(console_record_reset_enable()); + run_command("ms.b -q -l2 1 ff 12", 0); ut_assert_console_end(); unmap_sysmem(buf); + ut_asserteq(2, env_get_hex("memmatches", 0)); + ut_asserteq(0x62, env_get_hex("memaddr", 0)); + ut_asserteq(0x61, env_get_hex("mempos", 0)); + return 0; } -DM_TEST(dm_test_ms_quiet, 0); - +MEM_TEST(mem_test_ms_quiet, UT_TESTF_CONSOLE_REC); diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 1963f3792c..8f0bc688a2 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -74,6 +74,7 @@ static struct cmd_tbl cmd_ut_sub[] = { #ifdef CONFIG_UT_LOG U_BOOT_CMD_MKENT(log, CONFIG_SYS_MAXARGS, 1, do_ut_log, "", ""), #endif + U_BOOT_CMD_MKENT(mem, CONFIG_SYS_MAXARGS, 1, do_ut_mem, "", ""), #ifdef CONFIG_UT_TIME U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""), #endif @@ -145,6 +146,7 @@ static char ut_help_text[] = #ifdef CONFIG_UT_LOG "ut log [test-name] - test logging functions\n" #endif + "ut mem [test-name] - test memory-related commands\n" #ifdef CONFIG_UT_OPTEE "ut optee [test-name]\n" #endif -- 2.39.5