1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-01 08:42:12 +02:00

IOMUX: Add console multiplexing support.

Modifications to support console multiplexing.  This is controlled using
CONFIG_SYS_CONSOLE_MUX in the board configuration file.

This allows a user to specify multiple console devices in the environment
with a command like this: setenv stdin serial,nc.  As a result, the user can
enter text on both the serial and netconsole interfaces.

All devices - stdin, stdout and stderr - can be set in this manner.

1) common/iomux.c and include/iomux.h contain the environment setting
implementation.
2) doc/README.iomux contains a somewhat more detailed description.
3) The implementation in (1) is called from common/cmd_nvedit.c to
handle setenv and from common/console.c to handle initialization of
input/output devices at boot time.
4) common/console.c also contains the code needed to poll multiple console
devices for input and send output to all devices registered for output.
5) include/common.h includes iomux.h and common/Makefile generates iomux.o
when CONFIG_SYS_CONSOLE_MUX is set.

Signed-off-by: Gary Jennejohn <garyj@denx.de>
This commit is contained in:
Gary Jennejohn
2008-11-06 15:04:23 +01:00
committed by Wolfgang Denk
parent 774ce72026
commit 16a28ef219
7 changed files with 498 additions and 1 deletions

View File

@@ -93,6 +93,76 @@ static int console_setfile (int file, device_t * dev)
return error;
}
#if defined(CONFIG_CONSOLE_MUX)
/** Console I/O multiplexing *******************************************/
static device_t *tstcdev;
device_t **console_devices[MAX_FILES];
int cd_count[MAX_FILES];
/*
* This depends on tstc() always being called before getc().
* This is guaranteed to be true because this routine is called
* only from fgetc() which assures it.
* No attempt is made to demultiplex multiple input sources.
*/
static int iomux_getc(void)
{
unsigned char ret;
/* This is never called with testcdev == NULL */
ret = tstcdev->getc();
tstcdev = NULL;
return ret;
}
static int iomux_tstc(int file)
{
int i, ret;
device_t *dev;
disable_ctrlc(1);
for (i = 0; i < cd_count[file]; i++) {
dev = console_devices[file][i];
if (dev->tstc != NULL) {
ret = dev->tstc();
if (ret > 0) {
tstcdev = dev;
disable_ctrlc(0);
return ret;
}
}
}
disable_ctrlc(0);
return 0;
}
static void iomux_putc(int file, const char c)
{
int i;
device_t *dev;
for (i = 0; i < cd_count[file]; i++) {
dev = console_devices[file][i];
if (dev->putc != NULL)
dev->putc(c);
}
}
static void iomux_puts(int file, const char *s)
{
int i;
device_t *dev;
for (i = 0; i < cd_count[file]; i++) {
dev = console_devices[file][i];
if (dev->puts != NULL)
dev->puts(s);
}
}
#endif /* defined(CONFIG_CONSOLE_MUX) */
/** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
void serial_printf (const char *fmt, ...)
@@ -114,8 +184,31 @@ void serial_printf (const char *fmt, ...)
int fgetc (int file)
{
if (file < MAX_FILES)
if (file < MAX_FILES) {
#if defined(CONFIG_CONSOLE_MUX)
/*
* Effectively poll for input wherever it may be available.
*/
for (;;) {
/*
* Upper layer may have already called tstc() so
* check for that first.
*/
if (tstcdev != NULL)
return iomux_getc();
iomux_tstc(file);
#ifdef CONFIG_WATCHDOG
/*
* If the watchdog must be rate-limited then it should
* already be handled in board-specific code.
*/
udelay(1);
#endif
}
#else
return stdio_devices[file]->getc ();
#endif
}
return -1;
}
@@ -123,7 +216,11 @@ int fgetc (int file)
int ftstc (int file)
{
if (file < MAX_FILES)
#if defined(CONFIG_CONSOLE_MUX)
return iomux_tstc(file);
#else
return stdio_devices[file]->tstc ();
#endif
return -1;
}
@@ -131,13 +228,21 @@ int ftstc (int file)
void fputc (int file, const char c)
{
if (file < MAX_FILES)
#if defined(CONFIG_CONSOLE_MUX)
iomux_putc(file, c);
#else
stdio_devices[file]->putc (c);
#endif
}
void fputs (int file, const char *s)
{
if (file < MAX_FILES)
#if defined(CONFIG_CONSOLE_MUX)
iomux_puts(file, s);
#else
stdio_devices[file]->puts (s);
#endif
}
void fprintf (int file, const char *fmt, ...)
@@ -407,6 +512,9 @@ int console_init_r (void)
#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
int i;
#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
#ifdef CONFIG_CONSOLE_MUX
int iomux_err = 0;
#endif
/* set default handlers at first */
gd->jt[XF_getc] = serial_getc;
@@ -425,6 +533,14 @@ int console_init_r (void)
inputdev = search_device (DEV_FLAGS_INPUT, stdinname);
outputdev = search_device (DEV_FLAGS_OUTPUT, stdoutname);
errdev = search_device (DEV_FLAGS_OUTPUT, stderrname);
#ifdef CONFIG_CONSOLE_MUX
iomux_err = iomux_doenv(stdin, stdinname);
iomux_err += iomux_doenv(stdout, stdoutname);
iomux_err += iomux_doenv(stderr, stderrname);
if (!iomux_err)
/* Successful, so skip all the code below. */
goto done;
#endif
}
/* if the devices are overwritten or not found, use default device */
if (inputdev == NULL) {
@@ -438,15 +554,34 @@ int console_init_r (void)
}
/* Initializes output console first */
if (outputdev != NULL) {
#ifdef CONFIG_CONSOLE_MUX
/* need to set a console if not done above. */
iomux_doenv(stdout, outputdev->name);
#else
console_setfile (stdout, outputdev);
#endif
}
if (errdev != NULL) {
#ifdef CONFIG_CONSOLE_MUX
/* need to set a console if not done above. */
iomux_doenv(stderr, errdev->name);
#else
console_setfile (stderr, errdev);
#endif
}
if (inputdev != NULL) {
#ifdef CONFIG_CONSOLE_MUX
/* need to set a console if not done above. */
iomux_doenv(stdin, inputdev->name);
#else
console_setfile (stdin, inputdev);
#endif
}
#ifdef CONFIG_CONSOLE_MUX
done:
#endif
gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
@@ -455,21 +590,33 @@ int console_init_r (void)
if (stdio_devices[stdin] == NULL) {
puts ("No input devices available!\n");
} else {
#ifdef CONFIG_CONSOLE_MUX
iomux_printdevs(stdin);
#else
printf ("%s\n", stdio_devices[stdin]->name);
#endif
}
puts ("Out: ");
if (stdio_devices[stdout] == NULL) {
puts ("No output devices available!\n");
} else {
#ifdef CONFIG_CONSOLE_MUX
iomux_printdevs(stdout);
#else
printf ("%s\n", stdio_devices[stdout]->name);
#endif
}
puts ("Err: ");
if (stdio_devices[stderr] == NULL) {
puts ("No error devices available!\n");
} else {
#ifdef CONFIG_CONSOLE_MUX
iomux_printdevs(stderr);
#else
printf ("%s\n", stdio_devices[stderr]->name);
#endif
}
#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
@@ -524,11 +671,18 @@ int console_init_r (void)
if (outputdev != NULL) {
console_setfile (stdout, outputdev);
console_setfile (stderr, outputdev);
#ifdef CONFIG_CONSOLE_MUX
console_devices[stdout][0] = outputdev;
console_devices[stderr][0] = outputdev;
#endif
}
/* Initializes input console */
if (inputdev != NULL) {
console_setfile (stdin, inputdev);
#ifdef CONFIG_CONSOLE_MUX
console_devices[stdin][0] = inputdev;
#endif
}
gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */