In some cases, it is quite useful to have (for example) EFI on screen but u-boot on serial port.
Signed-off-by: Rob Clark <robdcl...@gmail.com> --- Applies on top of my previous efi_loader patchset. lib/efi_loader/efi_console.c | 104 +++++++++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 24 deletions(-) diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 139f7ea55b..e2b1b88ecf 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -47,6 +47,38 @@ static struct cout_mode efi_cout_modes[] = { const efi_guid_t efi_guid_console_control = CONSOLE_CONTROL_GUID; +static struct stdio_dev *efiin, *efiout; + +static int efi_tstc(void) +{ + return efiin->tstc(efiin); +} + +static int efi_getc(void) +{ + return efiin->getc(efiin); +} + +static int efi_printf(const char *fmt, ...) +{ + va_list args; + uint i; + char printbuffer[CONFIG_SYS_PBSIZE]; + + va_start(args, fmt); + + /* + * For this to work, printbuffer must be larger than + * anything we ever want to print. + */ + i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args); + va_end(args); + + /* Print the string */ + efiout->puts(efiout, printbuffer); + return i; +} + #define cESC '\x1b' #define ESC "\x1b" @@ -111,16 +143,16 @@ static int term_read_reply(int *n, int maxnum, char end_char) char c; int i = 0; - c = getc(); + c = efi_getc(); if (c != cESC) return -1; - c = getc(); + c = efi_getc(); if (c != '[') return -1; n[0] = 0; while (1) { - c = getc(); + c = efi_getc(); if (c == ';') { i++; if (i >= maxnum) @@ -164,7 +196,7 @@ static efi_status_t EFIAPI efi_cout_output_string( *utf16_to_utf8((u8 *)buf, string, n16) = '\0'; - fputs(stdout, buf); + efiout->puts(efiout, buf); for (p = buf; *p; p++) { switch (*p) { @@ -217,14 +249,14 @@ static int query_console_serial(int *rows, int *cols) u64 timeout; /* Empty input buffer */ - while (tstc()) - getc(); + while (efi_tstc()) + efi_getc(); - printf(ESC"[18t"); + efi_printf(ESC"[18t"); /* Check if we have a terminal that understands */ timeout = timer_get_us() + 1000000; - while (!tstc()) + while (!efi_tstc()) if (timer_get_us() > timeout) return -1; @@ -348,9 +380,9 @@ static efi_status_t EFIAPI efi_cout_set_attribute( EFI_ENTRY("%p, %lx", this, attribute); if (attribute) - printf(ESC"[%u;%um", color[fg].fg, color[bg].bg); + efi_printf(ESC"[%u;%um", color[fg].fg, color[bg].bg); else - printf(ESC"[37;40m"); + efi_printf(ESC"[37;40m"); /* Just ignore attributes (colors) for now */ return EFI_EXIT(EFI_UNSUPPORTED); @@ -361,7 +393,7 @@ static efi_status_t EFIAPI efi_cout_clear_screen( { EFI_ENTRY("%p", this); - printf(ESC"[2J"); + efi_printf(ESC"[2J"); return EFI_EXIT(EFI_SUCCESS); } @@ -372,7 +404,7 @@ static efi_status_t EFIAPI efi_cout_set_cursor_position( { EFI_ENTRY("%p, %ld, %ld", this, column, row); - printf(ESC"[%d;%df", (int)row, (int)column); + efi_printf(ESC"[%d;%df", (int)row, (int)column); efi_con_mode.cursor_column = column; efi_con_mode.cursor_row = row; @@ -385,7 +417,7 @@ static efi_status_t EFIAPI efi_cout_enable_cursor( { EFI_ENTRY("%p, %d", this, enable); - printf(ESC"[?25%c", enable ? 'h' : 'l'); + efi_printf(ESC"[?25%c", enable ? 'h' : 'l'); return EFI_EXIT(EFI_SUCCESS); } @@ -427,27 +459,27 @@ static efi_status_t read_key_stroke(struct efi_key_data *key_data) /* We don't do interrupts, so check for timers cooperatively */ efi_timer_check(); - if (!tstc()) { + if (!efi_tstc()) { /* No key pressed */ return EFI_NOT_READY; } - ch = getc(); + ch = efi_getc(); if (ch == cESC) { /* Escape Sequence */ - ch = getc(); + ch = efi_getc(); switch (ch) { case cESC: /* ESC */ pressed_key.scan_code = 23; break; case 'O': /* F1 - F4 */ - pressed_key.scan_code = getc() - 'P' + 11; + pressed_key.scan_code = efi_getc() - 'P' + 11; break; case 'a'...'z': ch = ch - 'a'; break; case '[': - ch = getc(); + ch = efi_getc(); switch (ch) { case 'A'...'D': /* up, down right, left */ pressed_key.scan_code = ch - 'A' + 1; @@ -459,16 +491,16 @@ static efi_status_t read_key_stroke(struct efi_key_data *key_data) pressed_key.scan_code = 5; break; case '1': /* F5 - F8 */ - pressed_key.scan_code = getc() - '0' + 11; - getc(); + pressed_key.scan_code = efi_getc() - '0' + 11; + efi_getc(); break; case '2': /* F9 - F12 */ - pressed_key.scan_code = getc() - '0' + 19; - getc(); + pressed_key.scan_code = efi_getc() - '0' + 19; + efi_getc(); break; case '3': /* DEL */ pressed_key.scan_code = 8; - getc(); + efi_getc(); break; } break; @@ -521,7 +553,7 @@ static void EFIAPI efi_console_timer_notify(struct efi_event *event, void *context) { EFI_ENTRY("%p, %p", event, context); - if (tstc()) + if (efi_tstc()) efi_signal_event(efi_con_in.wait_for_key); EFI_EXIT(EFI_SUCCESS); } @@ -604,6 +636,27 @@ struct efi_object efi_console_input_obj = { .handle = &efi_console_input_obj, }; +static struct stdio_dev *get_stdio_dev(const char *envname, int default_dev) +{ + const char *name; + struct stdio_dev *dev = NULL; + + name = env_get(envname); + if (name) { + dev = stdio_get_by_name(name); + if (dev && dev->start) { + int ret = dev->start(dev); + if (ret < 0) + dev = NULL; + } + } + + if (!dev) + dev = stdio_devices[default_dev]; + + return dev; +} + /* This gets called from do_bootefi_exec(). */ int efi_console_register(void) { @@ -614,6 +667,9 @@ int efi_console_register(void) list_add_tail(&efi_console_output_obj.link, &efi_obj_list); list_add_tail(&efi_console_input_obj.link, &efi_obj_list); + efiout = get_stdio_dev("efiout", stdout); + efiin = get_stdio_dev("efiin", stdin); + r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK, efi_key_notify, NULL, &efi_con_in.wait_for_key); if (r != EFI_SUCCESS) { -- 2.13.5 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot