Hi, On 10 October 2017 at 10:12, Alexander Graf <[email protected]> wrote: > > > On 10.10.17 02:27, Rob Clark wrote: >> On Mon, Sep 11, 2017 at 10:04 AM, Rob Clark <[email protected]> wrote: >>> 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 <[email protected]> >>> --- >>> 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]; >> >> btw, the one thing remaining holding up re-sending the efi_loader >> patches to get Shell.efi working is this one.. it isn't so much a >> problem with this patch, as much as that on the qemu-x86 target, >> printf() != fprintf(stdout), which breaks 'bootefi hello'.. I'm not >> quite sure yet what to do about that. > > Let's ask Bin and Simon :). There's a lot of magic in the putc() code to > account for cases where device initialization didn't happen yet. Maybe > the serial driver just wasn't probed properly yet?
That magic should be ignored for EFI - once console_init_r() is called we are in a 'normal' state. It's funny that (in that state) you see that inconsistency. I cannot think of a reason for it, but more study might perhaps provide an explanation. Regards, Simon _______________________________________________ U-Boot mailing list [email protected] https://lists.denx.de/listinfo/u-boot

