aboutsummaryrefslogtreecommitdiffstats
path: root/roms/ipxe/src/arch/i386/interface/vmware/vmconsole.c
blob: c6b9fff123032215f22d44ebd1d770d87b1e2f69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

FILE_LICENCE ( GPL2_OR_LATER );

/** @file
 *
 * VMware logfile console
 *
 */

#include <string.h>
#include <ipxe/console.h>
#include <ipxe/lineconsole.h>
#include <ipxe/init.h>
#include <ipxe/guestrpc.h>
#include <config/console.h>

/** 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 & ~CONSOLE_USAGE_TUI )
#endif

/** 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 console ANSI escape sequence handlers */
static struct ansiesc_handler vmconsole_handlers[] = {
	{ 0, NULL }
};

/** VMware logfile line console */
static struct line_console vmconsole_line = {
	.buffer = vmconsole_buffer.message,
	.len = sizeof ( vmconsole_buffer.message ),
	.ctx = {
		.handlers = vmconsole_handlers,
	},
};

/** 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 = CONSOLE_DISABLED,
	.usage = CONSOLE_VMWARE,
};

/**
 * 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,
};