diff --git a/src/arch/i386/image/bootsector.c b/src/arch/i386/image/bootsector.c index cb164fda..9a089e6b 100644 --- a/src/arch/i386/image/bootsector.c +++ b/src/arch/i386/image/bootsector.c @@ -30,6 +30,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include /** Vector for storing original INT 18 handler * @@ -60,6 +61,9 @@ int call_bootsector ( unsigned int segment, unsigned int offset, unsigned int drive ) { int discard_b, discard_D, discard_d; + /* Reset console, since boot sector will probably use it */ + console_reset(); + DBG ( "Booting from boot sector at %04x:%04x\n", segment, offset ); /* Hook INTs 18 and 19 to capture failure paths */ diff --git a/src/arch/i386/image/pxe_image.c b/src/arch/i386/image/pxe_image.c index 4a7d874b..dc28f608 100644 --- a/src/arch/i386/image/pxe_image.c +++ b/src/arch/i386/image/pxe_image.c @@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include FEATURE ( FEATURE_IMAGE, "PXE", DHCP_EB_FEATURE_PXE, 1 ); @@ -74,6 +75,9 @@ static int pxe_exec ( struct image *image ) { /* Set PXE command line */ pxe_cmdline = image->cmdline; + /* Reset console since PXE NBP will probably use it */ + console_reset(); + /* Start PXE NBP */ rc = pxe_start_nbp(); diff --git a/src/core/console.c b/src/core/console.c index 73baf7f6..5f3c28d8 100644 --- a/src/core/console.c +++ b/src/core/console.c @@ -121,3 +121,35 @@ int getchar ( void ) { int iskey ( void ) { return has_input() ? 1 : 0; } + +/** + * Configure console + * + * @v config Console configuration + * @ret rc Return status code + * + * The configuration is passed to all configurable consoles, including + * those which are currently disabled. Consoles may choose to enable + * or disable themselves depending upon the configuration. + * + * If configuration fails, then all consoles will be reset. + */ +int console_configure ( struct console_configuration *config ) { + struct console_driver *console; + int rc; + + /* Try to configure each console */ + for_each_table_entry ( console, CONSOLES ) { + if ( ( console->configure ) && + ( ( rc = console->configure ( config ) ) != 0 ) ) + goto err; + } + + return 0; + + err: + /* Reset all consoles, avoiding a potential infinite loop */ + if ( config ) + console_reset(); + return rc; +} diff --git a/src/core/init.c b/src/core/init.c index 56274419..7ea0730f 100644 --- a/src/core/init.c +++ b/src/core/init.c @@ -20,6 +20,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include +#include #include /** @file @@ -95,5 +96,8 @@ void shutdown ( int flags ) { startup_fn->shutdown ( flags ); } + /* Reset console */ + console_reset(); + started = 0; } diff --git a/src/include/ipxe/console.h b/src/include/ipxe/console.h index 2fcc4150..9c2620bc 100644 --- a/src/include/ipxe/console.h +++ b/src/include/ipxe/console.h @@ -77,6 +77,13 @@ struct console_driver { * will not block. */ int ( * iskey ) ( void ); + /** + * Configure console + * + * @v config Console configuration, or NULL to reset + * @ret rc Return status code + */ + int ( * configure ) ( struct console_configuration *config ); /** * Console usage bitmask * @@ -170,5 +177,15 @@ console_set_usage ( int usage ) { extern int iskey ( void ); extern int getkey ( unsigned long timeout ); +extern int console_configure ( struct console_configuration *config ); + +/** + * Reset console + * + */ +static inline __attribute__ (( always_inline )) void console_reset ( void ) { + + console_configure ( NULL ); +} #endif /* _IPXE_CONSOLE_H */