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:
committed by
Wolfgang Denk
parent
774ce72026
commit
16a28ef219
156
common/console.c
156
common/console.c
@@ -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 */
|
||||
|
Reference in New Issue
Block a user