efi_loader: Decouple EFI input/output from stdin/stdout
PATCH 1/1 efi_loader: Decouple EFI input/output from stdin/stdout
In some cases, it is quite useful to have (for example) EFI on screen but u-boot on serial port.
---
Applies on top of my previous efi_loader patchset.
lib/efi_loader/efi_console.c | 104 +++++++++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 24 deletions(-)
lib/efi_loader/efi_console.c +80 -24
@@ -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 ) {
Signature · 1 line
2.13.5
PATCH 1/1 efi_loader: Decouple EFI input/output from stdin/stdout
Quoted 215 lines · Rob Clark
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 previousefi_loaderpatchset.lib/efi_loader/efi_console.c | 104 +++++++++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 24 deletions(-)lib/efi_loader/efi_console.c +63
-24@@ -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) {
lib/efi_loader/efi_console.c struct efi_object efi_console_input_obj = { · line 655
Quoted 10 lines
lib/efi_loader/efi_console.c +10
-0+ 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.
somehow stdio_devices[stdio] is vidconsole but printf() goes to serial, which the test is expecting. We could perhaps explicitly set 'stdout' env var somewhere. Although I suspect we should probably also fix puts() to be the same thing as fputs(stdout) and fix the various boards where that accidentally working before :-/
suggestions welcome.. I could drop this patch for now, since not strictly required, but I think we should somehow fix the root problem.
BR,
-R
Quoted 20 lines
lib/efi_loader/efi_console.c +7
-1+ +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
PATCH 1/1 efi_loader: Decouple EFI input/output from stdin/stdout
Quoted 224 lines · Rob Clark
Quoted 223 lines · Rob Clark
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 previousefi_loaderpatchset.lib/efi_loader/efi_console.c | 104 +++++++++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 24 deletions(-)lib/efi_loader/efi_console.c +71
-24@@ -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 ; + } + } +
Quoted 8 lines
lib/efi_loader/efi_console.c struct efi_object efi_console_input_obj = { · line 655
Quoted 2 lines
lib/efi_loader/efi_console.c +2
-0+if (!dev) + dev = stdio_devices[default_dev];btw, the one thing remaining holding up re-sending the
efi_loaderpatches 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?
Alex
Quoted 33 lines
somehow stdio_devices[stdio] is vidconsole but
printf()goes to serial, which the test is expecting. We could perhaps explicitly set 'stdout' env var somewhere. Although I suspect we should probably also fixputs()to be the same thing as fputs(stdout) and fix the various boards where that accidentally working before :-/suggestions welcome.. I could drop this patch for now, since not strictly required, but I think we should somehow fix the root problem.
BR,
-RQuoted 20 lines
lib/efi_loader/efi_console.c +7
-1+ +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
PATCH 1/1 efi_loader: Decouple EFI input/output from stdin/stdout
Hi,
Quoted 236 lines · Alexander Graf
Quoted 224 lines · Rob Clark
Quoted 223 lines · Rob Clark
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 previousefi_loaderpatchset.lib/efi_loader/efi_console.c | 104 +++++++++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 24 deletions(-)lib/efi_loader/efi_console.c +71
-24@@ -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 ; + } + } +Quoted 8 lines
lib/efi_loader/efi_console.c struct efi_object efi_console_input_obj = { · line 655
Quoted 2 lines
lib/efi_loader/efi_console.c +2
-0+if (!dev) + dev = stdio_devices[default_dev];btw, the one thing remaining holding up re-sending the
efi_loaderpatches 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.
Quoted 3 lines
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