blob: 9397328609d0e65593d698ec3ea40b1ac0363690 [file] [log] [blame]
Simon Glassb255efc2022-04-24 23:31:24 -06001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Test for bootdev functions. All start with 'bootdev'
4 *
5 * Copyright 2021 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
7 */
8
Simon Glassb255efc2022-04-24 23:31:24 -06009#include <bootdev.h>
10#include <bootflow.h>
Simon Glassc8d37212022-07-30 15:52:34 -060011#include <bootmeth.h>
Simon Glassb255efc2022-04-24 23:31:24 -060012#include <bootstd.h>
Simon Glassd2bc33ed2023-01-06 08:52:41 -060013#include <cli.h>
Simon Glassb255efc2022-04-24 23:31:24 -060014#include <dm.h>
Simon Glass3b1e60b2024-11-07 14:31:43 -070015#include <efi.h>
Simon Glass4f378de2024-11-07 14:31:50 -070016#include <efi_loader.h>
Simon Glassd92bcc42023-01-06 08:52:42 -060017#include <expo.h>
Simon Glass90b643d2022-07-30 15:52:36 -060018#ifdef CONFIG_SANDBOX
Simon Glass161e1e32022-07-30 15:52:22 -060019#include <asm/test.h>
Simon Glass90b643d2022-07-30 15:52:36 -060020#endif
Simon Glassd2bc33ed2023-01-06 08:52:41 -060021#include <dm/device-internal.h>
Simon Glassb255efc2022-04-24 23:31:24 -060022#include <dm/lists.h>
23#include <test/suites.h>
24#include <test/ut.h>
25#include "bootstd_common.h"
Simon Glassd92bcc42023-01-06 08:52:42 -060026#include "../../boot/bootflow_internal.h"
27#include "../../boot/scene_internal.h"
Simon Glassb255efc2022-04-24 23:31:24 -060028
Simon Glassd2bc33ed2023-01-06 08:52:41 -060029DECLARE_GLOBAL_DATA_PTR;
30
Mattijs Korpershoekd77f8152024-07-10 10:40:06 +020031extern U_BOOT_DRIVER(bootmeth_android);
Simon Glassfff928c2023-08-24 13:55:41 -060032extern U_BOOT_DRIVER(bootmeth_cros);
Simon Glass2f27e472023-08-19 16:49:35 -060033extern U_BOOT_DRIVER(bootmeth_2script);
Simon Glassd2bc33ed2023-01-06 08:52:41 -060034
Simon Glass4f378de2024-11-07 14:31:50 -070035/* Use this as the vendor for EFI to tell the app to exit boot services */
36static u16 __efi_runtime_data test_vendor[] = u"U-Boot testing";
37
Simon Glass49ad1d82022-07-30 15:52:16 -060038static int inject_response(struct unit_test_state *uts)
39{
40 /*
41 * The image being booted presents a menu of options:
42 *
43 * Fedora-Workstation-armhfp-31-1.9 Boot Options.
44 * 1: Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
45 * Enter choice:
46 *
47 * Provide input for this, to avoid waiting two seconds for a timeout.
48 */
49 ut_asserteq(2, console_in_puts("1\n"));
50
51 return 0;
52}
53
Simon Glassb255efc2022-04-24 23:31:24 -060054/* Check 'bootflow scan/list' commands */
55static int bootflow_cmd(struct unit_test_state *uts)
56{
Simon Glassb255efc2022-04-24 23:31:24 -060057 ut_assertok(run_command("bootdev select 1", 0));
58 ut_assert_console_end();
Simon Glasse4cf1062023-01-17 10:48:13 -070059 ut_assertok(run_command("bootflow scan -lH", 0));
Simon Glassb255efc2022-04-24 23:31:24 -060060 ut_assert_nextline("Scanning for bootflows in bootdev 'mmc1.bootdev'");
61 ut_assert_nextline("Seq Method State Uclass Part Name Filename");
62 ut_assert_nextlinen("---");
Simon Glass484e4072023-01-17 10:48:14 -070063 ut_assert_nextline("Scanning bootdev 'mmc2.bootdev':");
64 ut_assert_nextline("Scanning bootdev 'mmc1.bootdev':");
Simon Glassb71d7f72023-05-10 16:34:46 -060065 ut_assert_nextline(" 0 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf");
Simon Glass484e4072023-01-17 10:48:14 -070066 ut_assert_nextline("No more bootdevs");
Simon Glassb255efc2022-04-24 23:31:24 -060067 ut_assert_nextlinen("---");
68 ut_assert_nextline("(1 bootflow, 1 valid)");
69 ut_assert_console_end();
70
71 ut_assertok(run_command("bootflow list", 0));
72 ut_assert_nextline("Showing bootflows for bootdev 'mmc1.bootdev'");
73 ut_assert_nextline("Seq Method State Uclass Part Name Filename");
74 ut_assert_nextlinen("---");
Simon Glassb71d7f72023-05-10 16:34:46 -060075 ut_assert_nextline(" 0 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf");
Simon Glassb255efc2022-04-24 23:31:24 -060076 ut_assert_nextlinen("---");
77 ut_assert_nextline("(1 bootflow, 1 valid)");
78 ut_assert_console_end();
79
80 return 0;
81}
Simon Glassf0425022024-08-22 07:57:54 -060082BOOTSTD_TEST(bootflow_cmd, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glassb255efc2022-04-24 23:31:24 -060083
Simon Glass484e4072023-01-17 10:48:14 -070084/* Check 'bootflow scan' with a label / seq */
Simon Glassb255efc2022-04-24 23:31:24 -060085static int bootflow_cmd_label(struct unit_test_state *uts)
86{
Simon Glass484e4072023-01-17 10:48:14 -070087 test_set_eth_enable(false);
88
Simon Glasse4cf1062023-01-17 10:48:13 -070089 ut_assertok(run_command("bootflow scan -lH mmc1", 0));
Simon Glass484e4072023-01-17 10:48:14 -070090 ut_assert_nextline("Scanning for bootflows with label 'mmc1'");
Simon Glassb255efc2022-04-24 23:31:24 -060091 ut_assert_skip_to_line("(1 bootflow, 1 valid)");
92 ut_assert_console_end();
93
Simon Glass484e4072023-01-17 10:48:14 -070094 ut_assertok(run_command("bootflow scan -lH 0", 0));
95 ut_assert_nextline("Scanning for bootflows with label '0'");
Simon Glassb255efc2022-04-24 23:31:24 -060096 ut_assert_skip_to_line("(0 bootflows, 0 valid)");
97 ut_assert_console_end();
98
Simon Glass484e4072023-01-17 10:48:14 -070099 /*
100 * with ethernet enabled we have 8 devices ahead of the mmc ones:
101 *
102 * ut_assertok(run_command("bootdev list", 0));
103 * Seq Probed Status Uclass Name
104 * --- ------ ------ -------- ------------------
105 * 0 [ + ] OK ethernet eth@10002000.bootdev
106 * 1 [ ] OK ethernet eth@10003000.bootdev
107 * 2 [ ] OK ethernet sbe5.bootdev
108 * 3 [ ] OK ethernet eth@10004000.bootdev
109 * 4 [ ] OK ethernet phy-test-eth.bootdev
110 * 5 [ ] OK ethernet dsa-test-eth.bootdev
111 * 6 [ ] OK ethernet dsa-test@0.bootdev
112 * 7 [ ] OK ethernet dsa-test@1.bootdev
113 * 8 [ ] OK mmc mmc2.bootdev
114 * 9 [ + ] OK mmc mmc1.bootdev
115 * a [ ] OK mmc mmc0.bootdev
Jerome Forissier253d5982024-10-16 11:56:26 +0200116 *
117 * However with CONFIG_DSA_SANDBOX=n we have two fewer (dsa-test@0 and
118 * dsa-test@1).
Simon Glass484e4072023-01-17 10:48:14 -0700119 */
Jerome Forissier253d5982024-10-16 11:56:26 +0200120 if (CONFIG_IS_ENABLED(DSA_SANDBOX)) {
121 ut_assertok(run_command("bootflow scan -lH 9", 0));
122 ut_assert_nextline("Scanning for bootflows with label '9'");
123 } else {
124 ut_assertok(run_command("bootflow scan -lH 7", 0));
125 ut_assert_nextline("Scanning for bootflows with label '7'");
126 }
Simon Glass484e4072023-01-17 10:48:14 -0700127 ut_assert_skip_to_line("(1 bootflow, 1 valid)");
128
Simon Glasse4cf1062023-01-17 10:48:13 -0700129 ut_assertok(run_command("bootflow scan -lH 0", 0));
Simon Glass484e4072023-01-17 10:48:14 -0700130 ut_assert_nextline("Scanning for bootflows with label '0'");
Simon Glassb255efc2022-04-24 23:31:24 -0600131 ut_assert_skip_to_line("(0 bootflows, 0 valid)");
132 ut_assert_console_end();
133
134 return 0;
135}
Simon Glassf0425022024-08-22 07:57:54 -0600136BOOTSTD_TEST(bootflow_cmd_label, UTF_DM | UTF_SCAN_FDT | UTF_ETH_BOOTDEV |
137 UTF_CONSOLE);
Simon Glassb255efc2022-04-24 23:31:24 -0600138
139/* Check 'bootflow scan/list' commands using all bootdevs */
140static int bootflow_cmd_glob(struct unit_test_state *uts)
141{
142 ut_assertok(bootstd_test_drop_bootdev_order(uts));
143
Simon Glasse4cf1062023-01-17 10:48:13 -0700144 ut_assertok(run_command("bootflow scan -lGH", 0));
Simon Glassb255efc2022-04-24 23:31:24 -0600145 ut_assert_nextline("Scanning for bootflows in all bootdevs");
146 ut_assert_nextline("Seq Method State Uclass Part Name Filename");
147 ut_assert_nextlinen("---");
148 ut_assert_nextline("Scanning bootdev 'mmc2.bootdev':");
149 ut_assert_nextline("Scanning bootdev 'mmc1.bootdev':");
Simon Glassb71d7f72023-05-10 16:34:46 -0600150 ut_assert_nextline(" 0 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf");
Simon Glassb255efc2022-04-24 23:31:24 -0600151 ut_assert_nextline("Scanning bootdev 'mmc0.bootdev':");
152 ut_assert_nextline("No more bootdevs");
153 ut_assert_nextlinen("---");
154 ut_assert_nextline("(1 bootflow, 1 valid)");
155 ut_assert_console_end();
156
157 ut_assertok(run_command("bootflow list", 0));
158 ut_assert_nextline("Showing all bootflows");
159 ut_assert_nextline("Seq Method State Uclass Part Name Filename");
160 ut_assert_nextlinen("---");
Simon Glassb71d7f72023-05-10 16:34:46 -0600161 ut_assert_nextline(" 0 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf");
Simon Glassb255efc2022-04-24 23:31:24 -0600162 ut_assert_nextlinen("---");
163 ut_assert_nextline("(1 bootflow, 1 valid)");
164 ut_assert_console_end();
165
166 return 0;
167}
Simon Glassf0425022024-08-22 07:57:54 -0600168BOOTSTD_TEST(bootflow_cmd_glob, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glassb255efc2022-04-24 23:31:24 -0600169
170/* Check 'bootflow scan -e' */
171static int bootflow_cmd_scan_e(struct unit_test_state *uts)
172{
173 ut_assertok(bootstd_test_drop_bootdev_order(uts));
174
Simon Glasse4cf1062023-01-17 10:48:13 -0700175 ut_assertok(run_command("bootflow scan -aleGH", 0));
Simon Glassb255efc2022-04-24 23:31:24 -0600176 ut_assert_nextline("Scanning for bootflows in all bootdevs");
177 ut_assert_nextline("Seq Method State Uclass Part Name Filename");
178 ut_assert_nextlinen("---");
179 ut_assert_nextline("Scanning bootdev 'mmc2.bootdev':");
Simon Glassd465ad52023-08-24 13:55:39 -0600180 ut_assert_nextline(" 0 extlinux media mmc 0 mmc2.bootdev.whole ");
Simon Glass9482fdf2023-05-10 16:34:26 -0600181 ut_assert_nextline(" ** No partition found, err=-93: Protocol not supported");
Simon Glassd465ad52023-08-24 13:55:39 -0600182 ut_assert_nextline(" 1 efi media mmc 0 mmc2.bootdev.whole ");
Simon Glass9482fdf2023-05-10 16:34:26 -0600183 ut_assert_nextline(" ** No partition found, err=-93: Protocol not supported");
Simon Glassb255efc2022-04-24 23:31:24 -0600184
185 ut_assert_nextline("Scanning bootdev 'mmc1.bootdev':");
Simon Glassd465ad52023-08-24 13:55:39 -0600186 ut_assert_nextline(" 2 extlinux media mmc 0 mmc1.bootdev.whole ");
Simon Glass9482fdf2023-05-10 16:34:26 -0600187 ut_assert_nextline(" ** No partition found, err=-2: No such file or directory");
Simon Glassd465ad52023-08-24 13:55:39 -0600188 ut_assert_nextline(" 3 efi media mmc 0 mmc1.bootdev.whole ");
Simon Glass9482fdf2023-05-10 16:34:26 -0600189 ut_assert_nextline(" ** No partition found, err=-2: No such file or directory");
Simon Glassb71d7f72023-05-10 16:34:46 -0600190 ut_assert_nextline(" 4 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf");
Simon Glass3b1e60b2024-11-07 14:31:43 -0700191 ut_assert_nextline(
192 " 5 efi fs mmc 1 mmc1.bootdev.part_1 /EFI/BOOT/%s",
193 efi_get_basename());
Simon Glassb255efc2022-04-24 23:31:24 -0600194
195 ut_assert_skip_to_line("Scanning bootdev 'mmc0.bootdev':");
Simon Glassd465ad52023-08-24 13:55:39 -0600196 ut_assert_skip_to_line(
197 " 3f efi media mmc 0 mmc0.bootdev.whole ");
Simon Glass9482fdf2023-05-10 16:34:26 -0600198 ut_assert_nextline(" ** No partition found, err=-93: Protocol not supported");
Simon Glassb255efc2022-04-24 23:31:24 -0600199 ut_assert_nextline("No more bootdevs");
200 ut_assert_nextlinen("---");
201 ut_assert_nextline("(64 bootflows, 1 valid)");
202 ut_assert_console_end();
203
204 ut_assertok(run_command("bootflow list", 0));
205 ut_assert_nextline("Showing all bootflows");
206 ut_assert_nextline("Seq Method State Uclass Part Name Filename");
207 ut_assert_nextlinen("---");
Simon Glassd465ad52023-08-24 13:55:39 -0600208 ut_assert_nextline(" 0 extlinux media mmc 0 mmc2.bootdev.whole ");
209 ut_assert_nextline(" 1 efi media mmc 0 mmc2.bootdev.whole ");
210 ut_assert_skip_to_line(
211 " 4 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf");
212 ut_assert_skip_to_line(" 3f efi media mmc 0 mmc0.bootdev.whole ");
Simon Glassb255efc2022-04-24 23:31:24 -0600213 ut_assert_nextlinen("---");
214 ut_assert_nextline("(64 bootflows, 1 valid)");
215 ut_assert_console_end();
216
217 return 0;
218}
Simon Glassf0425022024-08-22 07:57:54 -0600219BOOTSTD_TEST(bootflow_cmd_scan_e, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glassb255efc2022-04-24 23:31:24 -0600220
221/* Check 'bootflow info' */
222static int bootflow_cmd_info(struct unit_test_state *uts)
223{
Simon Glassb255efc2022-04-24 23:31:24 -0600224 ut_assertok(run_command("bootdev select 1", 0));
225 ut_assert_console_end();
226 ut_assertok(run_command("bootflow scan", 0));
227 ut_assert_console_end();
228 ut_assertok(run_command("bootflow select 0", 0));
229 ut_assert_console_end();
230 ut_assertok(run_command("bootflow info", 0));
231 ut_assert_nextline("Name: mmc1.bootdev.part_1");
232 ut_assert_nextline("Device: mmc1.bootdev");
233 ut_assert_nextline("Block dev: mmc1.blk");
Simon Glassb71d7f72023-05-10 16:34:46 -0600234 ut_assert_nextline("Method: extlinux");
Simon Glassb255efc2022-04-24 23:31:24 -0600235 ut_assert_nextline("State: ready");
236 ut_assert_nextline("Partition: 1");
237 ut_assert_nextline("Subdir: (none)");
238 ut_assert_nextline("Filename: /extlinux/extlinux.conf");
239 ut_assert_nextlinen("Buffer: ");
240 ut_assert_nextline("Size: 253 (595 bytes)");
Simon Glass72b7b192023-01-06 08:52:33 -0600241 ut_assert_nextline("OS: Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)");
Simon Glass33927522023-07-12 09:04:34 -0600242 ut_assert_nextline("Cmdline: (none)");
Simon Glass612b9cc2023-01-06 08:52:34 -0600243 ut_assert_nextline("Logo: (none)");
Simon Glass7b8c6342023-01-17 10:47:56 -0700244 ut_assert_nextline("FDT: <NULL>");
Simon Glassb255efc2022-04-24 23:31:24 -0600245 ut_assert_nextline("Error: 0");
246 ut_assert_console_end();
247
248 ut_assertok(run_command("bootflow info -d", 0));
249 ut_assert_nextline("Name: mmc1.bootdev.part_1");
250 ut_assert_skip_to_line("Error: 0");
251 ut_assert_nextline("Contents:");
252 ut_assert_nextline("%s", "");
253 ut_assert_nextline("# extlinux.conf generated by appliance-creator");
254 ut_assert_skip_to_line(" initrd /initramfs-5.3.7-301.fc31.armv7hl.img");
255 ut_assert_console_end();
256
257 return 0;
258}
Simon Glassf0425022024-08-22 07:57:54 -0600259BOOTSTD_TEST(bootflow_cmd_info, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glassb255efc2022-04-24 23:31:24 -0600260
261/* Check 'bootflow scan -b' to boot the first available bootdev */
262static int bootflow_scan_boot(struct unit_test_state *uts)
263{
Simon Glass49ad1d82022-07-30 15:52:16 -0600264 ut_assertok(inject_response(uts));
Simon Glassb255efc2022-04-24 23:31:24 -0600265 ut_assertok(run_command("bootflow scan -b", 0));
266 ut_assert_nextline(
Simon Glassb71d7f72023-05-10 16:34:46 -0600267 "** Booting bootflow 'mmc1.bootdev.part_1' with extlinux");
Simon Glassb255efc2022-04-24 23:31:24 -0600268 ut_assert_nextline("Ignoring unknown command: ui");
269
270 /*
271 * We expect it to get through to boot although sandbox always returns
272 * -EFAULT as it cannot actually boot the kernel
273 */
274 ut_assert_skip_to_line("sandbox: continuing, as we cannot run Linux");
275 ut_assert_nextline("Boot failed (err=-14)");
276 ut_assert_console_end();
277
278 return 0;
279}
Simon Glassf0425022024-08-22 07:57:54 -0600280BOOTSTD_TEST(bootflow_scan_boot, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glassb255efc2022-04-24 23:31:24 -0600281
282/* Check iterating through available bootflows */
283static int bootflow_iter(struct unit_test_state *uts)
284{
285 struct bootflow_iter iter;
286 struct bootflow bflow;
287
288 bootstd_clear_glob();
289
290 /* The first device is mmc2.bootdev which has no media */
291 ut_asserteq(-EPROTONOSUPPORT,
Simon Glass5d3d44f2023-01-17 10:48:16 -0700292 bootflow_scan_first(NULL, NULL, &iter,
Simon Glass99e68182023-02-22 12:17:03 -0700293 BOOTFLOWIF_ALL | BOOTFLOWIF_SKIP_GLOBAL, &bflow));
Simon Glassb255efc2022-04-24 23:31:24 -0600294 ut_asserteq(2, iter.num_methods);
295 ut_asserteq(0, iter.cur_method);
296 ut_asserteq(0, iter.part);
297 ut_asserteq(0, iter.max_part);
Simon Glassb71d7f72023-05-10 16:34:46 -0600298 ut_asserteq_str("extlinux", iter.method->name);
Simon Glassb255efc2022-04-24 23:31:24 -0600299 ut_asserteq(0, bflow.err);
300
301 /*
Simon Glassc8d37212022-07-30 15:52:34 -0600302 * This shows MEDIA even though there is none, since in
Simon Glassb255efc2022-04-24 23:31:24 -0600303 * bootdev_find_in_blk() we call part_get_info() which returns
304 * -EPROTONOSUPPORT. Ideally it would return -EEOPNOTSUPP and we would
305 * know.
306 */
307 ut_asserteq(BOOTFLOWST_MEDIA, bflow.state);
308
309 ut_asserteq(-EPROTONOSUPPORT, bootflow_scan_next(&iter, &bflow));
310 ut_asserteq(2, iter.num_methods);
311 ut_asserteq(1, iter.cur_method);
312 ut_asserteq(0, iter.part);
313 ut_asserteq(0, iter.max_part);
314 ut_asserteq_str("efi", iter.method->name);
315 ut_asserteq(0, bflow.err);
316 ut_asserteq(BOOTFLOWST_MEDIA, bflow.state);
317 bootflow_free(&bflow);
318
319 /* The next device is mmc1.bootdev - at first we use the whole device */
320 ut_asserteq(-ENOENT, bootflow_scan_next(&iter, &bflow));
321 ut_asserteq(2, iter.num_methods);
322 ut_asserteq(0, iter.cur_method);
323 ut_asserteq(0, iter.part);
324 ut_asserteq(0x1e, iter.max_part);
Simon Glassb71d7f72023-05-10 16:34:46 -0600325 ut_asserteq_str("extlinux", iter.method->name);
Simon Glassb255efc2022-04-24 23:31:24 -0600326 ut_asserteq(0, bflow.err);
327 ut_asserteq(BOOTFLOWST_MEDIA, bflow.state);
328 bootflow_free(&bflow);
329
330 ut_asserteq(-ENOENT, bootflow_scan_next(&iter, &bflow));
331 ut_asserteq(2, iter.num_methods);
332 ut_asserteq(1, iter.cur_method);
333 ut_asserteq(0, iter.part);
334 ut_asserteq(0x1e, iter.max_part);
335 ut_asserteq_str("efi", iter.method->name);
336 ut_asserteq(0, bflow.err);
337 ut_asserteq(BOOTFLOWST_MEDIA, bflow.state);
338 bootflow_free(&bflow);
339
340 /* Then more to partition 1 where we find something */
341 ut_assertok(bootflow_scan_next(&iter, &bflow));
342 ut_asserteq(2, iter.num_methods);
343 ut_asserteq(0, iter.cur_method);
344 ut_asserteq(1, iter.part);
345 ut_asserteq(0x1e, iter.max_part);
Simon Glassb71d7f72023-05-10 16:34:46 -0600346 ut_asserteq_str("extlinux", iter.method->name);
Simon Glassb255efc2022-04-24 23:31:24 -0600347 ut_asserteq(0, bflow.err);
348 ut_asserteq(BOOTFLOWST_READY, bflow.state);
349 bootflow_free(&bflow);
350
351 ut_asserteq(-ENOENT, bootflow_scan_next(&iter, &bflow));
352 ut_asserteq(2, iter.num_methods);
353 ut_asserteq(1, iter.cur_method);
354 ut_asserteq(1, iter.part);
355 ut_asserteq(0x1e, iter.max_part);
356 ut_asserteq_str("efi", iter.method->name);
357 ut_asserteq(0, bflow.err);
358 ut_asserteq(BOOTFLOWST_FS, bflow.state);
359 bootflow_free(&bflow);
360
Simon Glassf5e2df02023-01-17 10:47:41 -0700361 /* Then more to partition 2 which exists but is not bootable */
Simon Glass64cbc5c2023-01-17 10:47:42 -0700362 ut_asserteq(-EINVAL, bootflow_scan_next(&iter, &bflow));
Simon Glassb255efc2022-04-24 23:31:24 -0600363 ut_asserteq(2, iter.num_methods);
364 ut_asserteq(0, iter.cur_method);
365 ut_asserteq(2, iter.part);
366 ut_asserteq(0x1e, iter.max_part);
Simon Glassb71d7f72023-05-10 16:34:46 -0600367 ut_asserteq_str("extlinux", iter.method->name);
Simon Glassb255efc2022-04-24 23:31:24 -0600368 ut_asserteq(0, bflow.err);
Simon Glass64cbc5c2023-01-17 10:47:42 -0700369 ut_asserteq(BOOTFLOWST_MEDIA, bflow.state);
Simon Glassb255efc2022-04-24 23:31:24 -0600370 bootflow_free(&bflow);
371
372 bootflow_iter_uninit(&iter);
373
374 ut_assert_console_end();
375
376 return 0;
377}
Simon Glass129ba732024-10-19 09:21:58 -0600378BOOTSTD_TEST(bootflow_iter, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glassb255efc2022-04-24 23:31:24 -0600379
Simon Glass90b643d2022-07-30 15:52:36 -0600380#if defined(CONFIG_SANDBOX) && defined(CONFIG_BOOTMETH_GLOBAL)
Simon Glassb255efc2022-04-24 23:31:24 -0600381/* Check using the system bootdev */
382static int bootflow_system(struct unit_test_state *uts)
383{
Simon Glassb9ff6482023-01-17 10:47:23 -0700384 struct udevice *bootstd, *dev;
Simon Glassb255efc2022-04-24 23:31:24 -0600385
AKASHI Takahiroe3e542d2024-01-17 13:39:42 +0900386 if (!IS_ENABLED(CONFIG_EFI_BOOTMGR))
Simon Glassc7599442022-10-20 18:22:49 -0600387 return -EAGAIN;
Simon Glassb9ff6482023-01-17 10:47:23 -0700388 ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
Heinrich Schuchardtdc1f0062024-04-03 20:34:15 +0200389 ut_assertok(device_bind(bootstd, DM_DRIVER_GET(bootmeth_3efi_mgr),
Simon Glassb9ff6482023-01-17 10:47:23 -0700390 "efi_mgr", 0, ofnode_null(), &dev));
391 ut_assertok(device_probe(dev));
Simon Glass161e1e32022-07-30 15:52:22 -0600392 sandbox_set_fake_efi_mgr_dev(dev, true);
Simon Glassb255efc2022-04-24 23:31:24 -0600393
Simon Glassb255efc2022-04-24 23:31:24 -0600394 /* We should get a single 'bootmgr' method right at the end */
395 bootstd_clear_glob();
Simon Glasse4cf1062023-01-17 10:48:13 -0700396 ut_assertok(run_command("bootflow scan -lH", 0));
Simon Glasscc15e142022-07-30 15:52:27 -0600397 ut_assert_skip_to_line(
Simon Glassd465ad52023-08-24 13:55:39 -0600398 " 0 efi_mgr ready (none) 0 <NULL> ");
Simon Glasscc15e142022-07-30 15:52:27 -0600399 ut_assert_skip_to_line("No more bootdevs");
Simon Glassb9ff6482023-01-17 10:47:23 -0700400 ut_assert_skip_to_line("(2 bootflows, 2 valid)");
Simon Glassb255efc2022-04-24 23:31:24 -0600401 ut_assert_console_end();
402
403 return 0;
404}
Simon Glassf0425022024-08-22 07:57:54 -0600405BOOTSTD_TEST(bootflow_system, UTF_DM | UTF_SCAN_PDATA | UTF_SCAN_FDT |
406 UTF_CONSOLE);
Simon Glass90b643d2022-07-30 15:52:36 -0600407#endif
Simon Glassb255efc2022-04-24 23:31:24 -0600408
409/* Check disabling a bootmethod if it requests it */
410static int bootflow_iter_disable(struct unit_test_state *uts)
411{
412 struct udevice *bootstd, *dev;
413 struct bootflow_iter iter;
414 struct bootflow bflow;
415 int i;
416
417 /* Add the EFI bootmgr driver */
418 ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
419 ut_assertok(device_bind_driver(bootstd, "bootmeth_sandbox", "sandbox",
420 &dev));
421
Simon Glassb255efc2022-04-24 23:31:24 -0600422 ut_assertok(bootstd_test_drop_bootdev_order(uts));
423
424 bootstd_clear_glob();
Simon Glass49ad1d82022-07-30 15:52:16 -0600425 ut_assertok(inject_response(uts));
Simon Glasse4cf1062023-01-17 10:48:13 -0700426 ut_assertok(run_command("bootflow scan -lbH", 0));
Simon Glassb255efc2022-04-24 23:31:24 -0600427
428 /* Try to boot the bootmgr flow, which will fail */
429 console_record_reset_enable();
Simon Glass5d3d44f2023-01-17 10:48:16 -0700430 ut_assertok(bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
Simon Glassb255efc2022-04-24 23:31:24 -0600431 ut_asserteq(3, iter.num_methods);
432 ut_asserteq_str("sandbox", iter.method->name);
Simon Glass49ad1d82022-07-30 15:52:16 -0600433 ut_assertok(inject_response(uts));
Simon Glassb255efc2022-04-24 23:31:24 -0600434 ut_asserteq(-ENOTSUPP, bootflow_run_boot(&iter, &bflow));
435
436 ut_assert_skip_to_line("Boot method 'sandbox' failed and will not be retried");
437 ut_assert_console_end();
438
439 /* Check that the sandbox bootmeth has been removed */
440 ut_asserteq(2, iter.num_methods);
441 for (i = 0; i < iter.num_methods; i++)
442 ut_assert(strcmp("sandbox", iter.method_order[i]->name));
443
444 return 0;
445}
Simon Glassf0425022024-08-22 07:57:54 -0600446BOOTSTD_TEST(bootflow_iter_disable, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glassb255efc2022-04-24 23:31:24 -0600447
Simon Glassc8d37212022-07-30 15:52:34 -0600448/* Check 'bootflow scan' with a bootmeth ordering including a global bootmeth */
449static int bootflow_scan_glob_bootmeth(struct unit_test_state *uts)
450{
Simon Glass90b643d2022-07-30 15:52:36 -0600451 if (!IS_ENABLED(CONFIG_BOOTMETH_GLOBAL))
Simon Glassc7599442022-10-20 18:22:49 -0600452 return -EAGAIN;
Simon Glass90b643d2022-07-30 15:52:36 -0600453
Simon Glassc8d37212022-07-30 15:52:34 -0600454 ut_assertok(bootstd_test_drop_bootdev_order(uts));
455
456 /*
457 * Make sure that the -G flag makes the scan fail, since this is not
458 * supported when an ordering is provided
459 */
Simon Glassc8d37212022-07-30 15:52:34 -0600460 ut_assertok(bootmeth_set_order("efi firmware0"));
Simon Glasse4cf1062023-01-17 10:48:13 -0700461 ut_assertok(run_command("bootflow scan -lGH", 0));
Simon Glassc8d37212022-07-30 15:52:34 -0600462 ut_assert_nextline("Scanning for bootflows in all bootdevs");
463 ut_assert_nextline(
464 "Seq Method State Uclass Part Name Filename");
465 ut_assert_nextlinen("---");
466 ut_assert_nextlinen("---");
467 ut_assert_nextline("(0 bootflows, 0 valid)");
468 ut_assert_console_end();
469
Simon Glasse4cf1062023-01-17 10:48:13 -0700470 ut_assertok(run_command("bootflow scan -lH", 0));
Simon Glassc8d37212022-07-30 15:52:34 -0600471 ut_assert_nextline("Scanning for bootflows in all bootdevs");
472 ut_assert_nextline(
473 "Seq Method State Uclass Part Name Filename");
474 ut_assert_nextlinen("---");
475 ut_assert_nextline("Scanning global bootmeth 'firmware0':");
476 ut_assert_nextline("Scanning bootdev 'mmc2.bootdev':");
477 ut_assert_nextline("Scanning bootdev 'mmc1.bootdev':");
478 ut_assert_nextline("Scanning bootdev 'mmc0.bootdev':");
479 ut_assert_nextline("No more bootdevs");
480 ut_assert_nextlinen("---");
481 ut_assert_nextline("(0 bootflows, 0 valid)");
482 ut_assert_console_end();
483
484 return 0;
485}
Simon Glassf0425022024-08-22 07:57:54 -0600486BOOTSTD_TEST(bootflow_scan_glob_bootmeth, UTF_DM | UTF_SCAN_FDT |
487 UTF_CONSOLE);
Simon Glassc8d37212022-07-30 15:52:34 -0600488
Simon Glassb255efc2022-04-24 23:31:24 -0600489/* Check 'bootflow boot' to boot a selected bootflow */
490static int bootflow_cmd_boot(struct unit_test_state *uts)
491{
Simon Glassb255efc2022-04-24 23:31:24 -0600492 ut_assertok(run_command("bootdev select 1", 0));
493 ut_assert_console_end();
494 ut_assertok(run_command("bootflow scan", 0));
495 ut_assert_console_end();
496 ut_assertok(run_command("bootflow select 0", 0));
497 ut_assert_console_end();
Simon Glass49ad1d82022-07-30 15:52:16 -0600498
499 ut_assertok(inject_response(uts));
Simon Glassb255efc2022-04-24 23:31:24 -0600500 ut_asserteq(1, run_command("bootflow boot", 0));
501 ut_assert_nextline(
Simon Glassb71d7f72023-05-10 16:34:46 -0600502 "** Booting bootflow 'mmc1.bootdev.part_1' with extlinux");
Simon Glassb255efc2022-04-24 23:31:24 -0600503 ut_assert_nextline("Ignoring unknown command: ui");
504
505 /*
506 * We expect it to get through to boot although sandbox always returns
507 * -EFAULT as it cannot actually boot the kernel
508 */
509 ut_assert_skip_to_line("sandbox: continuing, as we cannot run Linux");
510 ut_assert_nextline("Boot failed (err=-14)");
511 ut_assert_console_end();
512
513 return 0;
514}
Simon Glassf0425022024-08-22 07:57:54 -0600515BOOTSTD_TEST(bootflow_cmd_boot, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600516
Simon Glassd92bcc42023-01-06 08:52:42 -0600517/**
Simon Glassbb76a5c2023-08-24 13:55:40 -0600518 * prep_mmc_bootdev() - Set up an mmc bootdev so we can access other distros
Simon Glassd92bcc42023-01-06 08:52:42 -0600519 *
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600520 * After calling this function, set std->bootdev_order to *@old_orderp to
521 * restore normal operation of bootstd (i.e. with the original bootdev order)
522 *
Simon Glassd92bcc42023-01-06 08:52:42 -0600523 * @uts: Unit test state
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600524 * @mmc_dev: MMC device to use, e.g. "mmc4". Note that this must remain valid
525 * in the caller until
Mattijs Korpershoekd77f8152024-07-10 10:40:06 +0200526 * @bind_cros: true to bind the ChromiumOS and Android bootmeths
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600527 * @old_orderp: Returns the original bootdev order, which must be restored
Simon Glassd92bcc42023-01-06 08:52:42 -0600528 * Returns 0 on success, -ve on failure
529 */
Simon Glassfff928c2023-08-24 13:55:41 -0600530static int prep_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev,
Mattijs Korpershoekd77f8152024-07-10 10:40:06 +0200531 bool bind_cros_android, const char ***old_orderp)
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600532{
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600533 static const char *order[] = {"mmc2", "mmc1", NULL, NULL};
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600534 struct udevice *dev, *bootstd;
535 struct bootstd_priv *std;
536 const char **old_order;
Simon Glassbb76a5c2023-08-24 13:55:40 -0600537 ofnode root, node;
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600538
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600539 order[2] = mmc_dev;
540
Simon Glass64c63252024-11-07 14:31:49 -0700541 /* Enable the requested mmc node since we need a second bootflow */
Simon Glassbb76a5c2023-08-24 13:55:40 -0600542 root = oftree_root(oftree_default());
543 node = ofnode_find_subnode(root, mmc_dev);
544 ut_assert(ofnode_valid(node));
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600545 ut_assertok(lists_bind_fdt(gd->dm_root, node, &dev, NULL, false));
546
547 /* Enable the script bootmeth too */
548 ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
Simon Glass2f27e472023-08-19 16:49:35 -0600549 ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_2script),
Simon Glassa59d6d32024-10-19 09:21:50 -0600550 "script", 0, ofnode_null(), &dev));
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600551
Simon Glassfff928c2023-08-24 13:55:41 -0600552 /* Enable the cros bootmeth if needed */
Mattijs Korpershoekd77f8152024-07-10 10:40:06 +0200553 if (IS_ENABLED(CONFIG_BOOTMETH_CROS) && bind_cros_android) {
Simon Glassfff928c2023-08-24 13:55:41 -0600554 ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
555 ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_cros),
556 "cros", 0, ofnode_null(), &dev));
557 }
558
Mattijs Korpershoekd77f8152024-07-10 10:40:06 +0200559 /* Enable the android bootmeths if needed */
560 if (IS_ENABLED(CONFIG_BOOTMETH_ANDROID) && bind_cros_android) {
561 ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
562 ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_android),
563 "android", 0, ofnode_null(), &dev));
564 }
565
Simon Glassbb76a5c2023-08-24 13:55:40 -0600566 /* Change the order to include the device */
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600567 std = dev_get_priv(bootstd);
568 old_order = std->bootdev_order;
569 std->bootdev_order = order;
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600570 *old_orderp = old_order;
571
572 return 0;
573}
574
575/**
576 * scan_mmc_bootdev() - Set up an mmc bootdev so we can access other distros
577 *
578 * @uts: Unit test state
579 * @mmc_dev: MMC device to use, e.g. "mmc4"
580 * @bind_cros: true to bind the ChromiumOS bootmeth
581 * Returns 0 on success, -ve on failure
582 */
583static int scan_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev,
584 bool bind_cros)
585{
586 struct bootstd_priv *std;
587 struct udevice *bootstd;
588 const char **old_order;
589
590 ut_assertok(prep_mmc_bootdev(uts, mmc_dev, bind_cros, &old_order));
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600591
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600592 ut_assertok(run_command("bootflow scan", 0));
593 ut_assert_console_end();
594
595 /* Restore the order used by the device tree */
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600596 ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
597 std = dev_get_priv(bootstd);
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600598 std->bootdev_order = old_order;
599
Simon Glassd92bcc42023-01-06 08:52:42 -0600600 return 0;
601}
602
Simon Glassbb76a5c2023-08-24 13:55:40 -0600603/**
Mattijs Korpershoekd77f8152024-07-10 10:40:06 +0200604 * scan_mmc_android_bootdev() - Set up an mmc bootdev so we can access other
605 * distros. Android bootflow might print "ANDROID:*" while scanning
606 *
607 * @uts: Unit test state
608 * @mmc_dev: MMC device to use, e.g. "mmc4"
609 * Returns 0 on success, -ve on failure
610 */
611static int scan_mmc_android_bootdev(struct unit_test_state *uts, const char *mmc_dev)
612{
613 struct bootstd_priv *std;
614 struct udevice *bootstd;
615 const char **old_order;
616
617 ut_assertok(prep_mmc_bootdev(uts, mmc_dev, true, &old_order));
618
Mattijs Korpershoekd77f8152024-07-10 10:40:06 +0200619 ut_assertok(run_command("bootflow scan", 0));
620 /* Android bootflow might print one or two 'ANDROID:*' logs */
621 ut_check_skipline(uts);
622 ut_check_skipline(uts);
623 ut_assert_console_end();
624
625 /* Restore the order used by the device tree */
626 ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
627 std = dev_get_priv(bootstd);
628 std->bootdev_order = old_order;
629
630 return 0;
631}
632
633/**
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600634 * scan_mmc4_bootdev() - Set up the mmc4 bootdev so we can access a fake Armbian
Simon Glassbb76a5c2023-08-24 13:55:40 -0600635 *
636 * @uts: Unit test state
637 * Returns 0 on success, -ve on failure
638 */
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600639static int scan_mmc4_bootdev(struct unit_test_state *uts)
Simon Glassbb76a5c2023-08-24 13:55:40 -0600640{
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600641 ut_assertok(scan_mmc_bootdev(uts, "mmc4", false));
Simon Glassbb76a5c2023-08-24 13:55:40 -0600642
643 return 0;
644}
645
Simon Glassd92bcc42023-01-06 08:52:42 -0600646/* Check 'bootflow menu' to select a bootflow */
647static int bootflow_cmd_menu(struct unit_test_state *uts)
648{
Simon Glass6d5083b2023-10-01 19:14:38 -0600649 struct bootstd_priv *std;
Simon Glassd92bcc42023-01-06 08:52:42 -0600650 char prev[3];
651
Simon Glass6d5083b2023-10-01 19:14:38 -0600652 /* get access to the current bootflow */
653 ut_assertok(bootstd_get_priv(&std));
654
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600655 ut_assertok(scan_mmc4_bootdev(uts));
Simon Glassd92bcc42023-01-06 08:52:42 -0600656
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600657 /* Add keypresses to move to and select the second one in the list */
658 prev[0] = CTL_CH('n');
659 prev[1] = '\r';
660 prev[2] = '\0';
661 ut_asserteq(2, console_in_puts(prev));
662
663 ut_assertok(run_command("bootflow menu", 0));
664 ut_assert_nextline("Selected: Armbian");
Simon Glass6d5083b2023-10-01 19:14:38 -0600665 ut_assertnonnull(std->cur_bootflow);
666 ut_assert_console_end();
667
668 /* Check not selecting anything */
669 prev[0] = '\e';
670 prev[1] = '\0';
671 ut_asserteq(1, console_in_puts(prev));
672
673 ut_asserteq(1, run_command("bootflow menu", 0));
674 ut_assertnull(std->cur_bootflow);
675 ut_assert_nextline("Nothing chosen");
Simon Glassd2bc33ed2023-01-06 08:52:41 -0600676 ut_assert_console_end();
677
678 return 0;
679}
Simon Glassf0425022024-08-22 07:57:54 -0600680BOOTSTD_TEST(bootflow_cmd_menu, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glassd92bcc42023-01-06 08:52:42 -0600681
Simon Glass9bf27862023-10-01 19:15:25 -0600682/* Check 'bootflow scan -m' to select a bootflow using a menu */
683static int bootflow_scan_menu(struct unit_test_state *uts)
684{
685 struct bootstd_priv *std;
686 const char **old_order, **new_order;
687 char prev[3];
688
689 /* get access to the current bootflow */
690 ut_assertok(bootstd_get_priv(&std));
691
692 ut_assertok(prep_mmc_bootdev(uts, "mmc4", false, &old_order));
693
694 /* Add keypresses to move to and select the second one in the list */
695 prev[0] = CTL_CH('n');
696 prev[1] = '\r';
697 prev[2] = '\0';
698 ut_asserteq(2, console_in_puts(prev));
699
700 ut_assertok(run_command("bootflow scan -lm", 0));
701 new_order = std->bootdev_order;
702 std->bootdev_order = old_order;
703
704 ut_assert_skip_to_line("No more bootdevs");
705 ut_assert_nextlinen("--");
706 ut_assert_nextline("(2 bootflows, 2 valid)");
707
708 ut_assert_nextline("Selected: Armbian");
709 ut_assertnonnull(std->cur_bootflow);
710 ut_assert_console_end();
711
712 /* Check not selecting anything */
713 prev[0] = '\e';
714 prev[1] = '\0';
715 ut_asserteq(1, console_in_puts(prev));
716
717 std->bootdev_order = new_order; /* Blue Monday */
718 ut_assertok(run_command("bootflow scan -lm", 0));
719 std->bootdev_order = old_order;
720
721 ut_assertnull(std->cur_bootflow);
722 ut_assert_skip_to_line("(2 bootflows, 2 valid)");
723 ut_assert_nextline("Nothing chosen");
724 ut_assert_console_end();
725
726 return 0;
727}
Simon Glass11fcfa32024-08-22 07:57:50 -0600728BOOTSTD_TEST(bootflow_scan_menu, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glass9bf27862023-10-01 19:15:25 -0600729
730/* Check 'bootflow scan -mb' to select and boot a bootflow using a menu */
731static int bootflow_scan_menu_boot(struct unit_test_state *uts)
732{
733 struct bootstd_priv *std;
734 const char **old_order;
735 char prev[3];
736
737 /* get access to the current bootflow */
738 ut_assertok(bootstd_get_priv(&std));
739
740 ut_assertok(prep_mmc_bootdev(uts, "mmc4", false, &old_order));
741
742 /* Add keypresses to move to and select the second one in the list */
743 prev[0] = CTL_CH('n');
744 prev[1] = '\r';
745 prev[2] = '\0';
746 ut_asserteq(2, console_in_puts(prev));
747
748 ut_assertok(run_command("bootflow scan -lmb", 0));
749 std->bootdev_order = old_order;
750
751 ut_assert_skip_to_line("(2 bootflows, 2 valid)");
752
753 ut_assert_nextline("Selected: Armbian");
Francis Laniel5b64c452023-12-22 22:02:35 +0100754
755 if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
756 /*
757 * With old hush, despite booti failing to boot, i.e. returning
758 * CMD_RET_FAILURE, run_command() returns 0 which leads bootflow_boot(), as
759 * we are using bootmeth_script here, to return -EFAULT.
760 */
761 ut_assert_skip_to_line("Boot failed (err=-14)");
762 } else if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
763 /*
764 * While with modern one, run_command() propagates CMD_RET_FAILURE returned
765 * by booti, so we get 1 here.
766 */
767 ut_assert_skip_to_line("Boot failed (err=1)");
768 }
Simon Glass9bf27862023-10-01 19:15:25 -0600769 ut_assertnonnull(std->cur_bootflow);
770 ut_assert_console_end();
771
772 return 0;
773}
Simon Glass11fcfa32024-08-22 07:57:50 -0600774BOOTSTD_TEST(bootflow_scan_menu_boot, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glass9bf27862023-10-01 19:15:25 -0600775
Simon Glassba3d5372023-01-17 10:48:15 -0700776/* Check searching for a single bootdev using the hunters */
777static int bootflow_cmd_hunt_single(struct unit_test_state *uts)
778{
779 struct bootstd_priv *std;
780
781 /* get access to the used hunters */
782 ut_assertok(bootstd_get_priv(&std));
783
784 ut_assertok(bootstd_test_drop_bootdev_order(uts));
785
Simon Glassba3d5372023-01-17 10:48:15 -0700786 ut_assertok(run_command("bootflow scan -l mmc1", 0));
787 ut_assert_nextline("Scanning for bootflows with label 'mmc1'");
788 ut_assert_skip_to_line("(1 bootflow, 1 valid)");
789 ut_assert_console_end();
790
791 /* check that the hunter was used */
792 ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
793
794 return 0;
795}
Simon Glassf0425022024-08-22 07:57:54 -0600796BOOTSTD_TEST(bootflow_cmd_hunt_single, UTF_DM | UTF_SCAN_FDT |
797 UTF_CONSOLE);
Simon Glassba3d5372023-01-17 10:48:15 -0700798
799/* Check searching for a uclass label using the hunters */
800static int bootflow_cmd_hunt_label(struct unit_test_state *uts)
801{
802 struct bootstd_priv *std;
803
804 /* get access to the used hunters */
805 ut_assertok(bootstd_get_priv(&std));
806
807 test_set_skip_delays(true);
808 test_set_eth_enable(false);
809 ut_assertok(bootstd_test_drop_bootdev_order(uts));
810
Simon Glassba3d5372023-01-17 10:48:15 -0700811 ut_assertok(run_command("bootflow scan -l mmc", 0));
812
813 /* check that the hunter was used */
814 ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
815
816 /* check that we got the mmc1 bootflow */
817 ut_assert_nextline("Scanning for bootflows with label 'mmc'");
818 ut_assert_nextlinen("Seq");
819 ut_assert_nextlinen("---");
820 ut_assert_nextline("Hunting with: simple_bus");
821 ut_assert_nextline("Found 2 extension board(s).");
822 ut_assert_nextline("Hunting with: mmc");
823 ut_assert_nextline("Scanning bootdev 'mmc2.bootdev':");
824 ut_assert_nextline("Scanning bootdev 'mmc1.bootdev':");
825 ut_assert_nextline(
Simon Glassb71d7f72023-05-10 16:34:46 -0600826 " 0 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf");
Simon Glassba3d5372023-01-17 10:48:15 -0700827 ut_assert_nextline("Scanning bootdev 'mmc0.bootdev':");
828 ut_assert_skip_to_line("(1 bootflow, 1 valid)");
829 ut_assert_console_end();
830
831 return 0;
832}
Simon Glassf0425022024-08-22 07:57:54 -0600833BOOTSTD_TEST(bootflow_cmd_hunt_label, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glassba3d5372023-01-17 10:48:15 -0700834
Simon Glassd92bcc42023-01-06 08:52:42 -0600835/**
836 * check_font() - Check that the font size for an item matches expectations
837 *
838 * @uts: Unit test state
839 * @scn: Scene containing the text object
840 * @id: ID of the text object
841 * Returns 0 on success, -ve on failure
842 */
843static int check_font(struct unit_test_state *uts, struct scene *scn, uint id,
844 int font_size)
845{
846 struct scene_obj_txt *txt;
847
848 txt = scene_obj_find(scn, id, SCENEOBJT_TEXT);
849 ut_assertnonnull(txt);
850
851 ut_asserteq(font_size, txt->font_size);
852
853 return 0;
854}
855
856/* Check themes work with a bootflow menu */
857static int bootflow_menu_theme(struct unit_test_state *uts)
858{
859 const int font_size = 30;
860 struct scene *scn;
861 struct expo *exp;
862 ofnode node;
863 int i;
864
Marek Vasutabb772a2024-10-20 17:43:12 +0200865 if (!CONFIG_IS_ENABLED(BOOTSTD_MENU))
866 return -EAGAIN;
867
Simon Glass3ff8a9a2023-10-01 19:14:37 -0600868 ut_assertok(scan_mmc4_bootdev(uts));
Simon Glassd92bcc42023-01-06 08:52:42 -0600869
870 ut_assertok(bootflow_menu_new(&exp));
871 node = ofnode_path("/bootstd/theme");
872 ut_assert(ofnode_valid(node));
873 ut_assertok(bootflow_menu_apply_theme(exp, node));
874
875 scn = expo_lookup_scene_id(exp, MAIN);
876 ut_assertnonnull(scn);
877
878 /*
879 * Check that the txt objects have the correct font size from the
880 * device tree node: bootstd/theme
881 *
882 * Check both menu items, since there are two bootflows
883 */
884 ut_assertok(check_font(uts, scn, OBJ_PROMPT, font_size));
885 ut_assertok(check_font(uts, scn, OBJ_POINTER, font_size));
886 for (i = 0; i < 2; i++) {
887 ut_assertok(check_font(uts, scn, ITEM_DESC + i, font_size));
888 ut_assertok(check_font(uts, scn, ITEM_KEY + i, font_size));
889 ut_assertok(check_font(uts, scn, ITEM_LABEL + i, font_size));
890 }
891
892 expo_destroy(exp);
893
894 return 0;
895}
Simon Glassf0425022024-08-22 07:57:54 -0600896BOOTSTD_TEST(bootflow_menu_theme, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
Simon Glassa08adca2023-07-12 09:04:38 -0600897
898/**
899 * check_arg() - Check both the normal case and the buffer-overflow case
900 *
901 * @uts: Unit-test state
902 * @expect_ret: Expected return value (i.e. buffer length)
903 * @expect_str: String expected to be returned
904 * @buf: Buffer to use
905 * @from: Original cmdline to update
906 * @arg: Argument to update (e.g. "console")
907 * @val: Value to set (e.g. "ttyS2") or NULL to delete the argument if present,
908 * "" to set it to an empty value (e.g. "console=") and BOOTFLOWCL_EMPTY to add
909 * it without any value ("initrd")
910 */
911static int check_arg(struct unit_test_state *uts, int expect_ret,
912 const char *expect_str, char *buf, const char *from,
913 const char *arg, const char *val)
914{
915 /* check for writing outside the reported bounds */
916 buf[expect_ret] = '[';
917 ut_asserteq(expect_ret,
918 cmdline_set_arg(buf, expect_ret, from, arg, val, NULL));
919 ut_asserteq_str(expect_str, buf);
920 ut_asserteq('[', buf[expect_ret]);
921
922 /* do the test again but with one less byte in the buffer */
923 ut_asserteq(-E2BIG, cmdline_set_arg(buf, expect_ret - 1, from, arg,
924 val, NULL));
925
926 return 0;
927}
928
929/* Test of bootflow_cmdline_set_arg() */
930static int test_bootflow_cmdline_set(struct unit_test_state *uts)
931{
932 char buf[50];
933 const int size = sizeof(buf);
934
935 /*
936 * note that buffer-overflow tests are immediately each test case, just
937 * top keep the code together
938 */
939
940 /* add an arg that doesn't already exist, starting from empty */
941 ut_asserteq(-ENOENT, cmdline_set_arg(buf, size, NULL, "me", NULL,
942 NULL));
943
944 ut_assertok(check_arg(uts, 3, "me", buf, NULL, "me", BOOTFLOWCL_EMPTY));
945 ut_assertok(check_arg(uts, 4, "me=", buf, NULL, "me", ""));
946 ut_assertok(check_arg(uts, 8, "me=fred", buf, NULL, "me", "fred"));
947
948 /* add an arg that doesn't already exist, starting from non-empty */
949 ut_assertok(check_arg(uts, 11, "arg=123 me", buf, "arg=123", "me",
950 BOOTFLOWCL_EMPTY));
951 ut_assertok(check_arg(uts, 12, "arg=123 me=", buf, "arg=123", "me",
952 ""));
953 ut_assertok(check_arg(uts, 16, "arg=123 me=fred", buf, "arg=123", "me",
954 "fred"));
955
956 /* update an arg at the start */
957 ut_assertok(check_arg(uts, 1, "", buf, "arg=123", "arg", NULL));
958 ut_assertok(check_arg(uts, 4, "arg", buf, "arg=123", "arg",
959 BOOTFLOWCL_EMPTY));
960 ut_assertok(check_arg(uts, 5, "arg=", buf, "arg=123", "arg", ""));
961 ut_assertok(check_arg(uts, 6, "arg=1", buf, "arg=123", "arg", "1"));
962 ut_assertok(check_arg(uts, 9, "arg=1234", buf, "arg=123", "arg",
963 "1234"));
964
965 /* update an arg at the end */
966 ut_assertok(check_arg(uts, 5, "mary", buf, "mary arg=123", "arg",
967 NULL));
968 ut_assertok(check_arg(uts, 9, "mary arg", buf, "mary arg=123", "arg",
969 BOOTFLOWCL_EMPTY));
970 ut_assertok(check_arg(uts, 10, "mary arg=", buf, "mary arg=123", "arg",
971 ""));
972 ut_assertok(check_arg(uts, 11, "mary arg=1", buf, "mary arg=123", "arg",
973 "1"));
974 ut_assertok(check_arg(uts, 14, "mary arg=1234", buf, "mary arg=123",
975 "arg", "1234"));
976
977 /* update an arg in the middle */
978 ut_assertok(check_arg(uts, 16, "mary=abc john=2", buf,
979 "mary=abc arg=123 john=2", "arg", NULL));
980 ut_assertok(check_arg(uts, 20, "mary=abc arg john=2", buf,
981 "mary=abc arg=123 john=2", "arg",
982 BOOTFLOWCL_EMPTY));
983 ut_assertok(check_arg(uts, 21, "mary=abc arg= john=2", buf,
984 "mary=abc arg=123 john=2", "arg", ""));
985 ut_assertok(check_arg(uts, 22, "mary=abc arg=1 john=2", buf,
986 "mary=abc arg=123 john=2", "arg", "1"));
987 ut_assertok(check_arg(uts, 25, "mary=abc arg=1234 john=2", buf,
988 "mary=abc arg=123 john=2", "arg", "1234"));
989
990 /* handle existing args with quotes */
991 ut_assertok(check_arg(uts, 16, "mary=\"abc\" john", buf,
992 "mary=\"abc\" arg=123 john", "arg", NULL));
993
994 /* handle existing args with quoted spaces */
995 ut_assertok(check_arg(uts, 20, "mary=\"abc def\" john", buf,
996 "mary=\"abc def\" arg=123 john", "arg", NULL));
997
998 ut_assertok(check_arg(uts, 34, "mary=\"abc def\" arg=123 john def=4",
999 buf, "mary=\"abc def\" arg=123 john", "def",
1000 "4"));
1001
1002 /* quote at the start */
1003 ut_asserteq(-EBADF, cmdline_set_arg(buf, size,
1004 "mary=\"abc def\" arg=\"123 456\"",
1005 "arg", "\"4 5 6", NULL));
1006
1007 /* quote at the end */
1008 ut_asserteq(-EBADF, cmdline_set_arg(buf, size,
1009 "mary=\"abc def\" arg=\"123 456\"",
1010 "arg", "4 5 6\"", NULL));
1011
1012 /* quote in the middle */
1013 ut_asserteq(-EBADF, cmdline_set_arg(buf, size,
1014 "mary=\"abc def\" arg=\"123 456\"",
1015 "arg", "\"4 \"5 6\"", NULL));
1016
1017 /* handle updating a quoted arg */
1018 ut_assertok(check_arg(uts, 27, "mary=\"abc def\" arg=\"4 5 6\"", buf,
1019 "mary=\"abc def\" arg=\"123 456\"", "arg",
1020 "4 5 6"));
1021
1022 /* changing a quoted arg to a non-quoted arg */
1023 ut_assertok(check_arg(uts, 23, "mary=\"abc def\" arg=789", buf,
1024 "mary=\"abc def\" arg=\"123 456\"", "arg",
1025 "789"));
1026
1027 /* changing a non-quoted arg to a quoted arg */
1028 ut_assertok(check_arg(uts, 29, "mary=\"abc def\" arg=\"456 789\"", buf,
1029 "mary=\"abc def\" arg=123", "arg", "456 789"));
1030
1031 /* handling of spaces */
1032 ut_assertok(check_arg(uts, 8, "arg=123", buf, " ", "arg", "123"));
1033 ut_assertok(check_arg(uts, 8, "arg=123", buf, " ", "arg", "123"));
1034 ut_assertok(check_arg(uts, 13, "john arg=123", buf, " john ", "arg",
1035 "123"));
1036 ut_assertok(check_arg(uts, 13, "john arg=123", buf, " john arg=123 ",
1037 "arg", "123"));
1038 ut_assertok(check_arg(uts, 18, "john arg=123 mary", buf,
1039 " john arg=123 mary ", "arg", "123"));
1040
1041 /* unchanged arg */
1042 ut_assertok(check_arg(uts, 3, "me", buf, "me", "me", BOOTFLOWCL_EMPTY));
1043
1044 /* arg which starts with the same name */
1045 ut_assertok(check_arg(uts, 28, "mary=abc johnathon=2 john=3", buf,
1046 "mary=abc johnathon=2 john=1", "john", "3"));
1047
1048 return 0;
1049}
1050BOOTSTD_TEST(test_bootflow_cmdline_set, 0);
Simon Glass55a2da32023-07-12 09:04:39 -06001051
1052/* Test of bootflow_cmdline_set_arg() */
1053static int bootflow_set_arg(struct unit_test_state *uts)
1054{
1055 struct bootflow s_bflow, *bflow = &s_bflow;
1056 ulong mem_start;
1057
1058 ut_assertok(env_set("bootargs", NULL));
1059
1060 mem_start = ut_check_delta(0);
1061
1062 /* Do a simple sanity check. Rely on bootflow_cmdline() for the rest */
1063 bflow->cmdline = NULL;
1064 ut_assertok(bootflow_cmdline_set_arg(bflow, "fred", "123", false));
1065 ut_asserteq_str(bflow->cmdline, "fred=123");
1066
1067 ut_assertok(bootflow_cmdline_set_arg(bflow, "mary", "and here", false));
1068 ut_asserteq_str(bflow->cmdline, "fred=123 mary=\"and here\"");
1069
1070 ut_assertok(bootflow_cmdline_set_arg(bflow, "mary", NULL, false));
1071 ut_asserteq_str(bflow->cmdline, "fred=123");
1072 ut_assertok(bootflow_cmdline_set_arg(bflow, "fred", NULL, false));
1073 ut_asserteq_ptr(bflow->cmdline, NULL);
1074
1075 ut_asserteq(0, ut_check_delta(mem_start));
1076
1077 ut_assertok(bootflow_cmdline_set_arg(bflow, "mary", "here", true));
1078 ut_asserteq_str("mary=here", env_get("bootargs"));
1079 ut_assertok(env_set("bootargs", NULL));
1080
1081 return 0;
1082}
1083BOOTSTD_TEST(bootflow_set_arg, 0);
1084
1085/* Test of bootflow_cmdline_get_arg() */
1086static int bootflow_cmdline_get(struct unit_test_state *uts)
1087{
1088 int pos;
1089
1090 /* empty string */
1091 ut_asserteq(-ENOENT, cmdline_get_arg("", "fred", &pos));
1092
1093 /* arg with empty value */
1094 ut_asserteq(0, cmdline_get_arg("fred= mary", "fred", &pos));
1095 ut_asserteq(5, pos);
1096
1097 /* arg with a value */
1098 ut_asserteq(2, cmdline_get_arg("fred=23", "fred", &pos));
1099 ut_asserteq(5, pos);
1100
1101 /* arg with a value */
1102 ut_asserteq(3, cmdline_get_arg("mary=1 fred=234", "fred", &pos));
1103 ut_asserteq(12, pos);
1104
1105 /* arg with a value, after quoted arg */
1106 ut_asserteq(3, cmdline_get_arg("mary=\"1 2\" fred=234", "fred", &pos));
1107 ut_asserteq(16, pos);
1108
1109 /* arg in the middle */
1110 ut_asserteq(0, cmdline_get_arg("mary=\"1 2\" fred john=23", "fred",
1111 &pos));
1112 ut_asserteq(15, pos);
1113
1114 /* quoted arg */
1115 ut_asserteq(3, cmdline_get_arg("mary=\"1 2\" fred=\"3 4\" john=23",
1116 "fred", &pos));
1117 ut_asserteq(17, pos);
1118
1119 /* args starting with the same prefix */
1120 ut_asserteq(1, cmdline_get_arg("mary=abc johnathon=3 john=1", "john",
1121 &pos));
1122 ut_asserteq(26, pos);
1123
1124 return 0;
1125}
1126BOOTSTD_TEST(bootflow_cmdline_get, 0);
1127
1128static int bootflow_cmdline(struct unit_test_state *uts)
1129{
1130 ut_assertok(run_command("bootflow scan mmc", 0));
1131 ut_assertok(run_command("bootflow sel 0", 0));
Simon Glass55a2da32023-07-12 09:04:39 -06001132
1133 ut_asserteq(1, run_command("bootflow cmdline get fred", 0));
1134 ut_assert_nextline("Argument not found");
1135 ut_assert_console_end();
1136
1137 ut_asserteq(0, run_command("bootflow cmdline set fred 123", 0));
1138 ut_asserteq(0, run_command("bootflow cmdline get fred", 0));
1139 ut_assert_nextline("123");
1140
1141 ut_asserteq(0, run_command("bootflow cmdline set mary abc", 0));
1142 ut_asserteq(0, run_command("bootflow cmdline get mary", 0));
1143 ut_assert_nextline("abc");
1144
1145 ut_asserteq(0, run_command("bootflow cmdline delete fred", 0));
1146 ut_asserteq(1, run_command("bootflow cmdline get fred", 0));
1147 ut_assert_nextline("Argument not found");
1148
1149 ut_asserteq(0, run_command("bootflow cmdline clear mary", 0));
1150 ut_asserteq(0, run_command("bootflow cmdline get mary", 0));
1151 ut_assert_nextline_empty();
1152
Simon Glass7a164f82023-11-29 10:31:19 -07001153 ut_asserteq(0, run_command("bootflow cmdline set mary abc", 0));
1154 ut_asserteq(0, run_command("bootflow cmdline set mary", 0));
Simon Glass55a2da32023-07-12 09:04:39 -06001155 ut_assert_console_end();
1156
1157 return 0;
1158}
Simon Glassf0425022024-08-22 07:57:54 -06001159BOOTSTD_TEST(bootflow_cmdline, UTF_CONSOLE);
Simon Glassfff928c2023-08-24 13:55:41 -06001160
Simon Glassa61057f2023-10-25 07:17:36 +13001161/* test a few special changes to a long command line */
1162static int bootflow_cmdline_special(struct unit_test_state *uts)
1163{
1164 char buf[500];
1165 int pos;
1166
1167 /*
1168 * check handling of an argument which has an embedded '=', as well as
1169 * handling of a argument which partially matches ("ro" and "root")
1170 */
1171 ut_asserteq(32, cmdline_set_arg(
1172 buf, sizeof(buf),
1173 "loglevel=7 root=PARTUUID=d68352e3 rootwait ro noinitrd",
1174 "root", NULL, &pos));
1175 ut_asserteq_str("loglevel=7 rootwait ro noinitrd", buf);
1176
1177 return 0;
1178}
1179BOOTSTD_TEST(bootflow_cmdline_special, 0);
1180
Simon Glassfff928c2023-08-24 13:55:41 -06001181/* Test ChromiumOS bootmeth */
1182static int bootflow_cros(struct unit_test_state *uts)
1183{
Simon Glass3ff8a9a2023-10-01 19:14:37 -06001184 ut_assertok(scan_mmc_bootdev(uts, "mmc5", true));
Simon Glassfff928c2023-08-24 13:55:41 -06001185 ut_assertok(run_command("bootflow list", 0));
1186
1187 ut_assert_nextlinen("Showing all");
1188 ut_assert_nextlinen("Seq");
1189 ut_assert_nextlinen("---");
1190 ut_assert_nextlinen(" 0 extlinux");
Simon Glassd7d3a972023-08-24 13:55:45 -06001191 ut_assert_nextlinen(" 1 cros ready mmc 2 mmc5.bootdev.part_2 ");
1192 ut_assert_nextlinen(" 2 cros ready mmc 4 mmc5.bootdev.part_4 ");
Simon Glassfff928c2023-08-24 13:55:41 -06001193 ut_assert_nextlinen("---");
Simon Glassd7d3a972023-08-24 13:55:45 -06001194 ut_assert_skip_to_line("(3 bootflows, 3 valid)");
Simon Glassfff928c2023-08-24 13:55:41 -06001195
1196 ut_assert_console_end();
1197
1198 return 0;
1199}
Simon Glassf0425022024-08-22 07:57:54 -06001200BOOTSTD_TEST(bootflow_cros, UTF_CONSOLE);
Mattijs Korpershoekd77f8152024-07-10 10:40:06 +02001201
1202/* Test Android bootmeth */
1203static int bootflow_android(struct unit_test_state *uts)
1204{
1205 if (!IS_ENABLED(CONFIG_BOOTMETH_ANDROID))
1206 return -EAGAIN;
1207
1208 ut_assertok(scan_mmc_android_bootdev(uts, "mmc7"));
1209 ut_assertok(run_command("bootflow list", 0));
1210
1211 ut_assert_nextlinen("Showing all");
1212 ut_assert_nextlinen("Seq");
1213 ut_assert_nextlinen("---");
1214 ut_assert_nextlinen(" 0 extlinux");
1215 ut_assert_nextlinen(" 1 android ready mmc 0 mmc7.bootdev.whole ");
1216 ut_assert_nextlinen("---");
1217 ut_assert_skip_to_line("(2 bootflows, 2 valid)");
1218
1219 ut_assert_console_end();
1220
1221 return 0;
1222}
Simon Glassf0425022024-08-22 07:57:54 -06001223BOOTSTD_TEST(bootflow_android, UTF_CONSOLE);
Simon Glass4f378de2024-11-07 14:31:50 -07001224
1225/* Test EFI bootmeth */
1226static int bootflow_efi(struct unit_test_state *uts)
1227{
1228 static const char *order[] = {"mmc1", "usb", NULL};
1229 struct bootstd_priv *std;
1230 struct udevice *bootstd;
1231 const char **old_order;
1232
1233 ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
1234 std = dev_get_priv(bootstd);
1235 old_order = std->bootdev_order;
1236 std->bootdev_order = order;
1237
1238 /* disable ethernet since the hunter will run dhcp */
1239 test_set_eth_enable(false);
1240
1241 /* make USB scan without delays */
1242 test_set_skip_delays(true);
1243
1244 bootstd_reset_usb();
1245
1246 ut_assertok(run_command("bootflow scan", 0));
1247 ut_assert_skip_to_line(
1248 "Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found");
1249
1250 ut_assertok(run_command("bootflow list", 0));
1251
1252 ut_assert_nextlinen("Showing all");
1253 ut_assert_nextlinen("Seq");
1254 ut_assert_nextlinen("---");
1255 ut_assert_nextlinen(" 0 extlinux");
1256 ut_assert_nextlinen(
1257 " 1 efi ready usb_mass_ 1 usb_mass_storage.lun0.boo /EFI/BOOT/BOOTSBOX.EFI");
1258 ut_assert_nextlinen("---");
1259 ut_assert_skip_to_line("(2 bootflows, 2 valid)");
1260 ut_assert_console_end();
1261
1262 ut_assertok(run_command("bootflow select 1", 0));
1263 ut_assert_console_end();
1264
1265 systab.fw_vendor = test_vendor;
1266
1267 ut_asserteq(1, run_command("bootflow boot", 0));
1268 ut_assert_nextline(
1269 "** Booting bootflow 'usb_mass_storage.lun0.bootdev.part_1' with efi");
1270 if (IS_ENABLED(CONFIG_LOGF_FUNC))
1271 ut_assert_skip_to_line(" efi_run_image() Booting /\\EFI\\BOOT\\BOOTSBOX.EFI");
1272 else
1273 ut_assert_skip_to_line("Booting /\\EFI\\BOOT\\BOOTSBOX.EFI");
1274
1275 /* TODO: Why the \r ? */
1276 ut_assert_nextline("U-Boot test app for EFI_LOADER\r");
1277 ut_assert_nextline("Exiting test app");
1278 ut_assert_nextline("Boot failed (err=-14)");
1279
1280 ut_assert_console_end();
1281
1282 ut_assertok(bootstd_test_drop_bootdev_order(uts));
1283
1284 return 0;
1285}
1286BOOTSTD_TEST(bootflow_efi, UTF_CONSOLE);