|
@@ -93,6 +93,76 @@ static int console_setfile (int file, device_t * dev)
|
|
return error;
|
|
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 *************************/
|
|
/** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
|
|
|
|
|
|
void serial_printf (const char *fmt, ...)
|
|
void serial_printf (const char *fmt, ...)
|
|
@@ -114,8 +184,31 @@ void serial_printf (const char *fmt, ...)
|
|
|
|
|
|
int fgetc (int file)
|
|
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 ();
|
|
return stdio_devices[file]->getc ();
|
|
|
|
+#endif
|
|
|
|
+ }
|
|
|
|
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -123,7 +216,11 @@ int fgetc (int file)
|
|
int ftstc (int file)
|
|
int ftstc (int file)
|
|
{
|
|
{
|
|
if (file < MAX_FILES)
|
|
if (file < MAX_FILES)
|
|
|
|
+#if defined(CONFIG_CONSOLE_MUX)
|
|
|
|
+ return iomux_tstc(file);
|
|
|
|
+#else
|
|
return stdio_devices[file]->tstc ();
|
|
return stdio_devices[file]->tstc ();
|
|
|
|
+#endif
|
|
|
|
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -131,13 +228,21 @@ int ftstc (int file)
|
|
void fputc (int file, const char c)
|
|
void fputc (int file, const char c)
|
|
{
|
|
{
|
|
if (file < MAX_FILES)
|
|
if (file < MAX_FILES)
|
|
|
|
+#if defined(CONFIG_CONSOLE_MUX)
|
|
|
|
+ iomux_putc(file, c);
|
|
|
|
+#else
|
|
stdio_devices[file]->putc (c);
|
|
stdio_devices[file]->putc (c);
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
void fputs (int file, const char *s)
|
|
void fputs (int file, const char *s)
|
|
{
|
|
{
|
|
if (file < MAX_FILES)
|
|
if (file < MAX_FILES)
|
|
|
|
+#if defined(CONFIG_CONSOLE_MUX)
|
|
|
|
+ iomux_puts(file, s);
|
|
|
|
+#else
|
|
stdio_devices[file]->puts (s);
|
|
stdio_devices[file]->puts (s);
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
void fprintf (int file, const char *fmt, ...)
|
|
void fprintf (int file, const char *fmt, ...)
|
|
@@ -407,6 +512,9 @@ int console_init_r (void)
|
|
#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
|
|
#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
|
|
int i;
|
|
int i;
|
|
#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
|
|
#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
|
|
|
|
+#ifdef CONFIG_CONSOLE_MUX
|
|
|
|
+ int iomux_err = 0;
|
|
|
|
+#endif
|
|
|
|
|
|
/* set default handlers at first */
|
|
/* set default handlers at first */
|
|
gd->jt[XF_getc] = serial_getc;
|
|
gd->jt[XF_getc] = serial_getc;
|
|
@@ -425,6 +533,14 @@ int console_init_r (void)
|
|
inputdev = search_device (DEV_FLAGS_INPUT, stdinname);
|
|
inputdev = search_device (DEV_FLAGS_INPUT, stdinname);
|
|
outputdev = search_device (DEV_FLAGS_OUTPUT, stdoutname);
|
|
outputdev = search_device (DEV_FLAGS_OUTPUT, stdoutname);
|
|
errdev = search_device (DEV_FLAGS_OUTPUT, stderrname);
|
|
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 the devices are overwritten or not found, use default device */
|
|
if (inputdev == NULL) {
|
|
if (inputdev == NULL) {
|
|
@@ -438,15 +554,34 @@ int console_init_r (void)
|
|
}
|
|
}
|
|
/* Initializes output console first */
|
|
/* Initializes output console first */
|
|
if (outputdev != NULL) {
|
|
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);
|
|
console_setfile (stdout, outputdev);
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
if (errdev != NULL) {
|
|
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);
|
|
console_setfile (stderr, errdev);
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
if (inputdev != NULL) {
|
|
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);
|
|
console_setfile (stdin, inputdev);
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_CONSOLE_MUX
|
|
|
|
+done:
|
|
|
|
+#endif
|
|
|
|
+
|
|
gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
|
|
gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
|
|
|
|
|
|
#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
|
|
#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
|
|
@@ -455,21 +590,33 @@ int console_init_r (void)
|
|
if (stdio_devices[stdin] == NULL) {
|
|
if (stdio_devices[stdin] == NULL) {
|
|
puts ("No input devices available!\n");
|
|
puts ("No input devices available!\n");
|
|
} else {
|
|
} else {
|
|
|
|
+#ifdef CONFIG_CONSOLE_MUX
|
|
|
|
+ iomux_printdevs(stdin);
|
|
|
|
+#else
|
|
printf ("%s\n", stdio_devices[stdin]->name);
|
|
printf ("%s\n", stdio_devices[stdin]->name);
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
puts ("Out: ");
|
|
puts ("Out: ");
|
|
if (stdio_devices[stdout] == NULL) {
|
|
if (stdio_devices[stdout] == NULL) {
|
|
puts ("No output devices available!\n");
|
|
puts ("No output devices available!\n");
|
|
} else {
|
|
} else {
|
|
|
|
+#ifdef CONFIG_CONSOLE_MUX
|
|
|
|
+ iomux_printdevs(stdout);
|
|
|
|
+#else
|
|
printf ("%s\n", stdio_devices[stdout]->name);
|
|
printf ("%s\n", stdio_devices[stdout]->name);
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
puts ("Err: ");
|
|
puts ("Err: ");
|
|
if (stdio_devices[stderr] == NULL) {
|
|
if (stdio_devices[stderr] == NULL) {
|
|
puts ("No error devices available!\n");
|
|
puts ("No error devices available!\n");
|
|
} else {
|
|
} else {
|
|
|
|
+#ifdef CONFIG_CONSOLE_MUX
|
|
|
|
+ iomux_printdevs(stderr);
|
|
|
|
+#else
|
|
printf ("%s\n", stdio_devices[stderr]->name);
|
|
printf ("%s\n", stdio_devices[stderr]->name);
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
|
|
#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
|
|
|
|
|
|
@@ -524,11 +671,18 @@ int console_init_r (void)
|
|
if (outputdev != NULL) {
|
|
if (outputdev != NULL) {
|
|
console_setfile (stdout, outputdev);
|
|
console_setfile (stdout, outputdev);
|
|
console_setfile (stderr, outputdev);
|
|
console_setfile (stderr, outputdev);
|
|
|
|
+#ifdef CONFIG_CONSOLE_MUX
|
|
|
|
+ console_devices[stdout][0] = outputdev;
|
|
|
|
+ console_devices[stderr][0] = outputdev;
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
/* Initializes input console */
|
|
/* Initializes input console */
|
|
if (inputdev != NULL) {
|
|
if (inputdev != NULL) {
|
|
console_setfile (stdin, inputdev);
|
|
console_setfile (stdin, inputdev);
|
|
|
|
+#ifdef CONFIG_CONSOLE_MUX
|
|
|
|
+ console_devices[stdin][0] = inputdev;
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
|
|
gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
|