1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Tests for bootm routines 4 * 5 * Copyright 2020 Google LLC 6 */ 7 8#include <common.h> 9#include <bootm.h> 10#include <asm/global_data.h> 11#include <test/suites.h> 12#include <test/test.h> 13#include <test/ut.h> 14 15DECLARE_GLOBAL_DATA_PTR; 16 17#define BOOTM_TEST(_name, _flags) UNIT_TEST(_name, _flags, bootm_test) 18 19enum { 20 BUF_SIZE = 1024, 21}; 22 23#define CONSOLE_STR "console=/dev/ttyS0" 24 25/* Test cmdline processing where nothing happens */ 26static int bootm_test_nop(struct unit_test_state *uts) 27{ 28 char buf[BUF_SIZE]; 29 30 *buf = '\0'; 31 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true)); 32 ut_asserteq_str("", buf); 33 34 strcpy(buf, "test"); 35 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true)); 36 ut_asserteq_str("test", buf); 37 38 return 0; 39} 40BOOTM_TEST(bootm_test_nop, 0); 41 42/* Test cmdline processing when out of space */ 43static int bootm_test_nospace(struct unit_test_state *uts) 44{ 45 char buf[BUF_SIZE]; 46 47 /* Zero buffer size */ 48 *buf = '\0'; 49 ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 0, true)); 50 51 /* Buffer string not terminated */ 52 memset(buf, 'a', BUF_SIZE); 53 ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, true)); 54 55 /* Not enough space to copy string */ 56 memset(buf, '\0', BUF_SIZE); 57 memset(buf, 'a', BUF_SIZE / 2); 58 ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, BUF_SIZE, true)); 59 60 /* Just enough space */ 61 memset(buf, '\0', BUF_SIZE); 62 memset(buf, 'a', BUF_SIZE / 2 - 1); 63 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, true)); 64 65 return 0; 66} 67BOOTM_TEST(bootm_test_nospace, 0); 68 69/* Test silent processing */ 70static int bootm_test_silent(struct unit_test_state *uts) 71{ 72 char buf[BUF_SIZE]; 73 74 /* 'silent_linux' not set should do nothing */ 75 env_set("silent_linux", NULL); 76 strcpy(buf, CONSOLE_STR); 77 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT)); 78 ut_asserteq_str(CONSOLE_STR, buf); 79 80 ut_assertok(env_set("silent_linux", "no")); 81 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT)); 82 ut_asserteq_str(CONSOLE_STR, buf); 83 84 ut_assertok(env_set("silent_linux", "yes")); 85 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT)); 86 ut_asserteq_str("console=ttynull", buf); 87 88 /* Empty buffer should still add the string */ 89 *buf = '\0'; 90 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT)); 91 ut_asserteq_str("console=ttynull", buf); 92 93 /* Check nothing happens when do_silent is false */ 94 *buf = '\0'; 95 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, 0)); 96 ut_asserteq_str("", buf); 97 98 /* Not enough space */ 99 *buf = '\0'; 100 ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 15, BOOTM_CL_SILENT)); 101 102 /* Just enough space */ 103 *buf = '\0'; 104 ut_assertok(bootm_process_cmdline(buf, 16, BOOTM_CL_SILENT)); 105 106 /* add at end */ 107 strcpy(buf, "something"); 108 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT)); 109 ut_asserteq_str("something console=ttynull", buf); 110 111 /* change at start */ 112 strcpy(buf, CONSOLE_STR " something"); 113 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SILENT)); 114 ut_asserteq_str("console=ttynull something", buf); 115 116 return 0; 117} 118BOOTM_TEST(bootm_test_silent, 0); 119 120/* Test substitution processing */ 121static int bootm_test_subst(struct unit_test_state *uts) 122{ 123 char buf[BUF_SIZE]; 124 125 /* try with an unset variable */ 126 ut_assertok(env_set("var", NULL)); 127 strcpy(buf, "some${var}thing"); 128 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST)); 129 ut_asserteq_str("something", buf); 130 131 /* Replace with shorter string */ 132 ut_assertok(env_set("var", "bb")); 133 strcpy(buf, "some${var}thing"); 134 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST)); 135 ut_asserteq_str("somebbthing", buf); 136 137 /* Replace with same-length string */ 138 ut_assertok(env_set("var", "abc")); 139 strcpy(buf, "some${var}thing"); 140 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST)); 141 ut_asserteq_str("someabcthing", buf); 142 143 /* Replace with longer string */ 144 ut_assertok(env_set("var", "abcde")); 145 strcpy(buf, "some${var}thing"); 146 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST)); 147 ut_asserteq_str("someabcdething", buf); 148 149 /* Check it is case sensitive */ 150 ut_assertok(env_set("VAR", NULL)); 151 strcpy(buf, "some${VAR}thing"); 152 ut_assertok(bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST)); 153 ut_asserteq_str("something", buf); 154 155 /* Check too long - need 12 bytes for each string */ 156 strcpy(buf, "some${var}thing"); 157 ut_asserteq(-ENOSPC, 158 bootm_process_cmdline(buf, 12 * 2 - 1, BOOTM_CL_SUBST)); 159 160 /* Check just enough space */ 161 strcpy(buf, "some${var}thing"); 162 ut_assertok(bootm_process_cmdline(buf, 16 * 2, BOOTM_CL_SUBST)); 163 ut_asserteq_str("someabcdething", buf); 164 165 /* 166 * Check the substition string being too long. This results in a string 167 * of 12 (13 bytes). We need enough space for that plus the original 168 * "a${var}c" string of 9 bytes. So 12 + 9 = 21 bytes. 169 */ 170 ut_assertok(env_set("var", "1234567890")); 171 strcpy(buf, "a${var}c"); 172 ut_asserteq(-ENOSPC, bootm_process_cmdline(buf, 21, BOOTM_CL_SUBST)); 173 174 strcpy(buf, "a${var}c"); 175 ut_asserteq(0, bootm_process_cmdline(buf, 22, BOOTM_CL_SUBST)); 176 177 /* Check multiple substitutions */ 178 ut_assertok(env_set("var", "abc")); 179 strcpy(buf, "some${var}thing${bvar}else"); 180 ut_asserteq(0, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST)); 181 ut_asserteq_str("someabcthingelse", buf); 182 183 /* Check multiple substitutions */ 184 ut_assertok(env_set("bvar", "123")); 185 strcpy(buf, "some${var}thing${bvar}else"); 186 ut_asserteq(0, bootm_process_cmdline(buf, BUF_SIZE, BOOTM_CL_SUBST)); 187 ut_asserteq_str("someabcthing123else", buf); 188 189 return 0; 190} 191BOOTM_TEST(bootm_test_subst, 0); 192 193/* Test silent processing in the bootargs variable */ 194static int bootm_test_silent_var(struct unit_test_state *uts) 195{ 196 env_set("bootargs", NULL); 197 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SUBST)); 198 ut_assertnull(env_get("bootargs")); 199 200 ut_assertok(env_set("bootargs", "some${var}thing")); 201 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SUBST)); 202 ut_asserteq_str("something", env_get("bootargs")); 203 204 return 0; 205} 206BOOTM_TEST(bootm_test_silent_var, 0); 207 208/* Test substitution processing in the bootargs variable */ 209static int bootm_test_subst_var(struct unit_test_state *uts) 210{ 211 ut_assertok(env_set("silent_linux", "yes")); 212 ut_assertok(env_set("bootargs", NULL)); 213 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT)); 214 ut_asserteq_str("console=ttynull", env_get("bootargs")); 215 216 ut_assertok(env_set("var", "abc")); 217 ut_assertok(env_set("bootargs", "some${var}thing")); 218 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT)); 219 ut_asserteq_str("some${var}thing console=ttynull", env_get("bootargs")); 220 221 return 0; 222} 223BOOTM_TEST(bootm_test_subst_var, 0); 224 225/* Test substitution and silent console processing in the bootargs variable */ 226static int bootm_test_subst_both(struct unit_test_state *uts) 227{ 228 ut_assertok(env_set("silent_linux", "yes")); 229 env_set("bootargs", NULL); 230 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_ALL)); 231 ut_asserteq_str("console=ttynull", env_get("bootargs")); 232 233 ut_assertok(env_set("bootargs", "some${var}thing " CONSOLE_STR)); 234 ut_assertok(env_set("var", "1234567890")); 235 ut_assertok(bootm_process_cmdline_env(BOOTM_CL_ALL)); 236 ut_asserteq_str("some1234567890thing console=ttynull", env_get("bootargs")); 237 238 return 0; 239} 240BOOTM_TEST(bootm_test_subst_both, 0); 241 242int do_ut_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 243{ 244 struct unit_test *tests = UNIT_TEST_SUITE_START(bootm_test); 245 const int n_ents = UNIT_TEST_SUITE_COUNT(bootm_test); 246 247 return cmd_ut_category("bootm", "bootm_test_", tests, n_ents, 248 argc, argv); 249} 250