From ec151d0a4e6ae9d42c58e3710566ec3fb69ff935 Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Wed, 11 Dec 2013 11:40:17 -0800 Subject: [PATCH] implement a simple payload chooser for coreboot. This is always built into coreboot, and is enabled by a static variable in src/lib/hardwaremain.c. Payload choosing can be enabled at build time, or at runtime via jtag/gdb. The operation is simple. The chooser, if enabled, lists the payloads and puts up a prompt. Payloads: fallback/payload Pick one> The user then types in the name of a payload, e.g. Pick one>fallback/payload The line is ended by newline or carriage return. And the payload is booted. If you get it wrong, no backspace or correction. Just hit return and try again. I started with Bayou but feel the need is low and the complexity high for that solution; this is just much simpler. So, let's think about some UI here. Some options: - default to the first payload if the user hits return - time out after 5 seconds or so - Don't make people type the name; number the payloads as they are printed and let the user hit, say, 2, to get the second payload What would you like to see? BUG=None TEST=Works on Nyan BRANCH=None Change-Id: I4f93633636abf73e65e1b14c1b9e77ac2e25c453 Signed-off-by: Ronald G. Minnich Reviewed-on: https://chromium-review.googlesource.com/180343 Reviewed-by: Puneet Kumar Commit-Queue: Ronald Minnich Tested-by: Ronald Minnich --- src/lib/hardwaremain.c | 44 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c index 30d6cf5456..ca39bfcd0d 100644 --- a/src/lib/hardwaremain.c +++ b/src/lib/hardwaremain.c @@ -222,15 +222,53 @@ static boot_state_t bs_write_tables(void *arg) return BS_PAYLOAD_LOAD; } +/* This is something we don't want to use most of the time. + * It is for debug only. Hence, it is not a config variable. + * It is done this way so people can control it from + * build or at runtime via gdb/jtag. The amount of code it + * adds is insignificant. + */ +static int chooser = 0; + static boot_state_t bs_payload_load(void *arg) { - void *payload; + void *payload = NULL; void *entry; + const char *payload_name = CONFIG_CBFS_PREFIX "/payload"; timestamp_add_now(TS_LOAD_PAYLOAD); - payload = cbfs_load_payload(CBFS_DEFAULT_MEDIA, - CONFIG_CBFS_PREFIX "/payload"); + if (chooser) { + static char chosen[128]; + static struct cbfs_payload_info info[16]; + int i; + int npayloads; + + printk(BIOS_SPEW, "Payloads:\n"); + npayloads = cbfs_payload_headers(CBFS_DEFAULT_MEDIA, + info, ARRAY_SIZE(info)); + for(i = 0; i < npayloads; i++) + printk(BIOS_INFO, "%s\n", info[i].name); + while (! payload) { + printk(BIOS_SPEW, "Pick one>"); + for(i = 0; i < sizeof(chosen); i++) { + chosen[i] = console_rx_byte(); + console_tx_byte(chosen[i]); + if ((chosen[i] == '\n') || (chosen[i] == '\r')) { + chosen[i] = 0; + break; + } + } + printk(BIOS_SPEW, "Try to get :%s:\n", chosen); + payload_name = chosen; + payload = cbfs_load_payload(CBFS_DEFAULT_MEDIA, + payload_name); + } + } + + if (! payload) + payload = cbfs_load_payload(CBFS_DEFAULT_MEDIA, + payload_name); if (! payload) die("Could not find a payload\n");