diff --git a/src/arch/i386/interface/vmware/vmconsole.c b/src/arch/i386/interface/vmware/vmconsole.c new file mode 100644 index 000000000..930c088d7 --- /dev/null +++ b/src/arch/i386/interface/vmware/vmconsole.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2012 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** @file + * + * VMware logfile console + * + */ + +#include +#include +#include +#include +#include + +/** VMware logfile console buffer size */ +#define VMCONSOLE_BUFSIZE 128 + +/** VMware logfile console GuestRPC channel */ +static int vmconsole_channel; + +/** VMware logfile console line buffer */ +static struct { + char prefix[4]; + char message[VMCONSOLE_BUFSIZE]; +} vmconsole_buffer = { + .prefix = "log ", +}; + +/** VMware logfile line console */ +static struct line_console vmconsole_line = { + .buffer = vmconsole_buffer.message, + .len = sizeof ( vmconsole_buffer.message ), +}; + +/** VMware logfile console recursion marker */ +static int vmconsole_entered; + +/** + * Print a character to VMware logfile console + * + * @v character Character to be printed + */ +static void vmconsole_putchar ( int character ) { + int rc; + + /* Ignore if we are already mid-logging */ + if ( vmconsole_entered ) + return; + + /* Fill line buffer */ + if ( line_putchar ( &vmconsole_line, character ) == 0 ) + return; + + /* Guard against re-entry */ + vmconsole_entered = 1; + + /* Send log message */ + if ( ( rc = guestrpc_command ( vmconsole_channel, + vmconsole_buffer.prefix, NULL, 0 ) ) <0){ + DBG ( "VMware console could not send log message: %s\n", + strerror ( rc ) ); + } + + /* Clear re-entry flag */ + vmconsole_entered = 0; +} + +/** VMware logfile console driver */ +struct console_driver vmconsole __console_driver = { + .putchar = vmconsole_putchar, + .disabled = 1, +}; + +/** + * Initialise VMware logfile console + * + */ +static void vmconsole_init ( void ) { + int rc; + + /* Attempt to open console */ + vmconsole_channel = guestrpc_open(); + if ( vmconsole_channel < 0 ) { + rc = vmconsole_channel; + DBG ( "VMware console could not be initialised: %s\n", + strerror ( rc ) ); + return; + } + + /* Mark console as available */ + vmconsole.disabled = 0; +} + +/** + * VMware logfile console initialisation function + */ +struct init_fn vmconsole_init_fn __init_fn ( INIT_CONSOLE ) = { + .initialise = vmconsole_init, +}; diff --git a/src/config/config.c b/src/config/config.c index 2c3555ead..bdf6b5cea 100644 --- a/src/config/config.c +++ b/src/config/config.c @@ -86,6 +86,9 @@ REQUIRE_OBJECT ( efi_console ); #ifdef CONSOLE_LINUX REQUIRE_OBJECT ( linux_console ); #endif +#ifdef CONSOLE_VMWARE +REQUIRE_OBJECT ( vmconsole ); +#endif /* * Drag in all requested network protocols diff --git a/src/config/console.h b/src/config/console.h index afc89569c..bf7ea0507 100644 --- a/src/config/console.h +++ b/src/config/console.h @@ -20,6 +20,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); //#define CONSOLE_BTEXT /* Who knows what this does? */ //#define CONSOLE_PC_KBD /* Direct access to PC keyboard */ //#define CONSOLE_SYSLOG /* Syslog console */ +//#define CONSOLE_VMWARE /* VMware logfile console */ #define KEYBOARD_MAP us