diff --git a/src/arch/i386/core/video_subr.c b/src/arch/i386/core/video_subr.c index 6885ad9af..7dd99e712 100644 --- a/src/arch/i386/core/video_subr.c +++ b/src/arch/i386/core/video_subr.c @@ -11,6 +11,14 @@ #include #include #include "vga.h" +#include + +/* Set default console usage if applicable */ +#if ! ( defined ( CONSOLE_DIRECT_VGA ) && \ + CONSOLE_EXPLICIT ( CONSOLE_DIRECT_VGA ) ) +#undef CONSOLE_DIRECT_VGA +#define CONSOLE_DIRECT_VGA CONSOLE_USAGE_ALL +#endif struct console_driver vga_console __console_driver; @@ -97,6 +105,7 @@ static void vga_putc(int byte) struct console_driver vga_console __console_driver = { .putchar = vga_putc, .disabled = 1, + .usage = CONSOLE_DIRECT_VGA, }; struct init_fn video_init_fn __init_fn ( INIT_EARLY ) = { diff --git a/src/arch/i386/firmware/pcbios/bios_console.c b/src/arch/i386/firmware/pcbios/bios_console.c index e489971f1..8a8795d77 100644 --- a/src/arch/i386/firmware/pcbios/bios_console.c +++ b/src/arch/i386/firmware/pcbios/bios_console.c @@ -23,6 +23,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #define ATTR_BOLD 0x08 @@ -48,6 +49,12 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define ATTR_DEFAULT ATTR_FCOL_WHITE +/* Set default console usage if applicable */ +#if ! ( defined ( CONSOLE_PCBIOS ) && CONSOLE_EXPLICIT ( CONSOLE_PCBIOS ) ) +#undef CONSOLE_PCBIOS +#define CONSOLE_PCBIOS CONSOLE_USAGE_ALL +#endif + /** Current character attribute */ static unsigned int bios_attr = ATTR_DEFAULT; @@ -319,4 +326,5 @@ struct console_driver bios_console __console_driver = { .putchar = bios_putchar, .getchar = bios_getchar, .iskey = bios_iskey, + .usage = CONSOLE_PCBIOS, }; diff --git a/src/arch/i386/interface/vmware/vmconsole.c b/src/arch/i386/interface/vmware/vmconsole.c index 930c088d7..3096e5b53 100644 --- a/src/arch/i386/interface/vmware/vmconsole.c +++ b/src/arch/i386/interface/vmware/vmconsole.c @@ -29,10 +29,17 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include /** VMware logfile console buffer size */ #define VMCONSOLE_BUFSIZE 128 +/* Set default console usage if applicable */ +#if ! ( defined ( CONSOLE_VMWARE ) && CONSOLE_EXPLICIT ( CONSOLE_VMWARE ) ) +#undef CONSOLE_VMWARE +#define CONSOLE_VMWARE CONSOLE_USAGE_ALL +#endif + /** VMware logfile console GuestRPC channel */ static int vmconsole_channel; @@ -87,6 +94,7 @@ static void vmconsole_putchar ( int character ) { struct console_driver vmconsole __console_driver = { .putchar = vmconsole_putchar, .disabled = 1, + .usage = CONSOLE_VMWARE, }; /** diff --git a/src/core/console.c b/src/core/console.c index f27edf468..a26a3ef63 100644 --- a/src/core/console.c +++ b/src/core/console.c @@ -7,6 +7,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); +/** Current console usage */ +int console_usage = CONSOLE_USAGE_STDOUT; + /** * Write a single character to each console device. * @@ -26,7 +29,9 @@ void putchar ( int character ) { putchar ( '\r' ); for_each_table_entry ( console, CONSOLES ) { - if ( ( ! console->disabled ) && console->putchar ) + if ( ( ! console->disabled ) && + ( console_usage & console->usage ) && + console->putchar ) console->putchar ( character ); } } diff --git a/src/core/debug.c b/src/core/debug.c index 8fca8d90d..fc90c64a1 100644 --- a/src/core/debug.c +++ b/src/core/debug.c @@ -21,16 +21,38 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include -#include +#include + +/** + * Print debug message + * + * @v fmt Format string + * @v ... Arguments + */ +void dbg_printf ( const char *fmt, ... ) { + int saved_usage; + va_list args; + + /* Mark console as in use for debugging messages */ + saved_usage = console_set_usage ( CONSOLE_USAGE_DEBUG ); + + /* Print message */ + va_start ( args, fmt ); + vprintf ( fmt, args ); + va_end ( args ); + + /* Restore console usage */ + console_set_usage ( saved_usage ); +} /** * Pause until a key is pressed * */ void dbg_pause ( void ) { - printf ( "\nPress a key..." ); + dbg_printf ( "\nPress a key..." ); getchar(); - printf ( "\r \r" ); + dbg_printf ( "\r \r" ); } /** @@ -38,9 +60,9 @@ void dbg_pause ( void ) { * */ void dbg_more ( void ) { - printf ( "---more---" ); + dbg_printf ( "---more---" ); getchar(); - printf ( "\r \r" ); + dbg_printf ( "\r \r" ); } /** @@ -57,27 +79,27 @@ static void dbg_hex_dump_da_row ( unsigned long dispaddr, const void *data, unsigned int i; uint8_t byte; - printf ( "%08lx :", ( dispaddr + offset ) ); + dbg_printf ( "%08lx :", ( dispaddr + offset ) ); for ( i = offset ; i < ( offset + 16 ) ; i++ ) { if ( i >= len ) { - printf ( " " ); + dbg_printf ( " " ); continue; } - printf ( "%c%02x", - ( ( ( i % 16 ) == 8 ) ? '-' : ' ' ), bytes[i] ); + dbg_printf ( "%c%02x", + ( ( ( i % 16 ) == 8 ) ? '-' : ' ' ), bytes[i] ); } - printf ( " : " ); + dbg_printf ( " : " ); for ( i = offset ; i < ( offset + 16 ) ; i++ ) { if ( i >= len ) { - printf ( " " ); + dbg_printf ( " " ); continue; } byte = bytes[i]; if ( ( byte < 0x20 ) || ( byte >= 0x7f ) ) byte = '.'; - printf ( "%c", byte ); + dbg_printf ( "%c", byte ); } - printf ( "\n" ); + dbg_printf ( "\n" ); } /** @@ -157,8 +179,8 @@ static int dbg_autocolour ( unsigned long stream ) { * @v stream Message stream ID */ void dbg_autocolourise ( unsigned long stream ) { - printf ( "\033[%dm", - ( stream ? ( 31 + dbg_autocolour ( stream ) ) : 0 ) ); + dbg_printf ( "\033[%dm", + ( stream ? ( 31 + dbg_autocolour ( stream ) ) : 0 ) ); } /** @@ -166,5 +188,5 @@ void dbg_autocolourise ( unsigned long stream ) { * */ void dbg_decolourise ( void ) { - printf ( "\033[0m" ); + dbg_printf ( "\033[0m" ); } diff --git a/src/core/serial_console.c b/src/core/serial_console.c index b05a06b17..52bd53760 100644 --- a/src/core/serial_console.c +++ b/src/core/serial_console.c @@ -1,6 +1,7 @@ #include #include #include +#include /** @file * @@ -8,6 +9,12 @@ * */ +/* Set default console usage if applicable */ +#if ! ( defined ( CONSOLE_SERIAL ) && CONSOLE_EXPLICIT ( CONSOLE_SERIAL ) ) +#undef CONSOLE_SERIAL +#define CONSOLE_SERIAL CONSOLE_USAGE_ALL +#endif + struct console_driver serial_console __console_driver; static void serial_console_init ( void ) { @@ -21,6 +28,7 @@ struct console_driver serial_console __console_driver = { .getchar = serial_getc, .iskey = serial_ischar, .disabled = 1, + .usage = CONSOLE_SERIAL, }; /** diff --git a/src/include/compiler.h b/src/include/compiler.h index 9a751d3bb..ed9af237d 100644 --- a/src/include/compiler.h +++ b/src/include/compiler.h @@ -260,19 +260,9 @@ REQUEST_EXPANDED ( CONFIG_SYMBOL ); #ifndef ASSEMBLY -/** printf() for debugging - * - * This function exists so that the DBG() macros can expand to - * printf() calls without dragging the printf() prototype into scope. - * - * As far as the compiler is concerned, dbg_printf() and printf() are - * completely unrelated calls; it's only at the assembly stage that - * references to the dbg_printf symbol are collapsed into references - * to the printf symbol. - */ -extern int __attribute__ (( format ( printf, 1, 2 ) )) -dbg_printf ( const char *fmt, ... ) asm ( "printf" ); - +/** printf() for debugging */ +extern void __attribute__ (( format ( printf, 1, 2 ) )) +dbg_printf ( const char *fmt, ... ); extern void dbg_autocolourise ( unsigned long id ); extern void dbg_decolourise ( void ); extern void dbg_hex_dump_da ( unsigned long dispaddr, diff --git a/src/include/ipxe/console.h b/src/include/ipxe/console.h index 5188f9855..f70dd714a 100644 --- a/src/include/ipxe/console.h +++ b/src/include/ipxe/console.h @@ -75,6 +75,13 @@ struct console_driver { * */ int ( *iskey ) ( void ); + + /** Console usage bitmask + * + * This is the bitwise OR of zero or more @c CONSOLE_USAGE_XXX + * values. + */ + int usage; }; /** Console driver table */ @@ -99,7 +106,49 @@ struct console_driver { */ #define __console_driver __table_entry ( CONSOLES, 01 ) -/* Function prototypes */ +/** + * @defgroup consoleusage Console usages + * @{ + */ + +/** Standard output */ +#define CONSOLE_USAGE_STDOUT 0x0001 + +/** Debug messages */ +#define CONSOLE_USAGE_DEBUG 0x0002 + +/** All console usages */ +#define CONSOLE_USAGE_ALL ( CONSOLE_USAGE_STDOUT | CONSOLE_USAGE_DEBUG ) + +/** @} */ + +/** + * Test to see if console has an explicit usage + * + * @v console Console definition (e.g. CONSOLE_PCBIOS) + * @ret explicit Console has an explicit usage + * + * This relies upon the trick that the expression ( 2 * N + 1 ) will + * be valid even if N is defined to be empty, since it will then + * evaluate to give ( 2 * + 1 ) == ( 2 * +1 ) == 2. + */ +#define CONSOLE_EXPLICIT( console ) ( ( 2 * console + 1 ) != 2 ) + +extern int console_usage; + +/** + * Set console usage + * + * @v usage New console usage + * @ret old_usage Previous console usage + */ +static inline __attribute__ (( always_inline )) int +console_set_usage ( int usage ) { + int old_usage = console_usage; + + console_usage = usage; + return old_usage; +} extern int iskey ( void ); extern int getkey ( unsigned long timeout ); diff --git a/src/interface/efi/efi_console.c b/src/interface/efi/efi_console.c index 1303a4278..54b0c0804 100644 --- a/src/interface/efi/efi_console.c +++ b/src/interface/efi/efi_console.c @@ -23,6 +23,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #define ATTR_BOLD 0x08 @@ -48,6 +49,12 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define ATTR_DEFAULT ATTR_FCOL_WHITE +/* Set default console usage if applicable */ +#if ! ( defined ( CONSOLE_EFI ) && CONSOLE_EXPLICIT ( CONSOLE_EFI ) ) +#undef CONSOLE_EFI +#define CONSOLE_EFI CONSOLE_USAGE_ALL +#endif + /** Current character attribute */ static unsigned int efi_attr = ATTR_DEFAULT; @@ -273,4 +280,5 @@ struct console_driver efi_console __console_driver = { .putchar = efi_putchar, .getchar = efi_getchar, .iskey = efi_iskey, + .usage = CONSOLE_EFI, }; diff --git a/src/interface/linux/linux_console.c b/src/interface/linux/linux_console.c index aeb7c6618..c79e52631 100644 --- a/src/interface/linux/linux_console.c +++ b/src/interface/linux/linux_console.c @@ -33,6 +33,14 @@ FILE_LICENCE(GPL2_OR_LATER); #include #include +#include + +/* Set default console usage if applicable */ +#if ! ( defined ( CONSOLE_LINUX ) && CONSOLE_EXPLICIT ( CONSOLE_LINUX ) ) +#undef CONSOLE_LINUX +#define CONSOLE_LINUX CONSOLE_USAGE_ALL +#endif + static void linux_console_putchar(int c) { /* write to stdout */ @@ -79,6 +87,7 @@ struct console_driver linux_console __console_driver = { .putchar = linux_console_putchar, .getchar = linux_console_getchar, .iskey = linux_console_iskey, + .usage = CONSOLE_LINUX, }; static int linux_tcgetattr(int fd, struct termios *termios_p) diff --git a/src/net/udp/syslog.c b/src/net/udp/syslog.c index 5a8a865a5..8788e1c45 100644 --- a/src/net/udp/syslog.c +++ b/src/net/udp/syslog.c @@ -34,6 +34,13 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include + +/* Set default console usage if applicable */ +#if ! ( defined ( CONSOLE_SYSLOG ) && CONSOLE_EXPLICIT ( CONSOLE_SYSLOG ) ) +#undef CONSOLE_SYSLOG +#define CONSOLE_SYSLOG CONSOLE_USAGE_ALL +#endif /** The syslog server */ static struct sockaddr_tcpip logserver = { @@ -106,6 +113,7 @@ static void syslog_putchar ( int character ) { struct console_driver syslog_console __console_driver = { .putchar = syslog_putchar, .disabled = 1, + .usage = CONSOLE_SYSLOG, }; /******************************************************************************