diff options
Diffstat (limited to 'common/console.c')
-rw-r--r-- | common/console.c | 216 |
1 files changed, 195 insertions, 21 deletions
diff --git a/common/console.c b/common/console.c index cfcaeb8..89aeab6 100644 --- a/common/console.c +++ b/common/console.c @@ -33,20 +33,20 @@ DECLARE_GLOBAL_DATA_PTR; int console_changed = 0; #endif -#ifdef CFG_CONSOLE_IS_IN_ENV +#ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV /* * if overwrite_console returns 1, the stdin, stderr and stdout * are switched to the serial port, else the settings in the * environment are used */ -#ifdef CFG_CONSOLE_OVERWRITE_ROUTINE +#ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE extern int overwrite_console (void); #define OVERWRITE_CONSOLE overwrite_console () #else #define OVERWRITE_CONSOLE 0 -#endif /* CFG_CONSOLE_OVERWRITE_ROUTINE */ +#endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */ -#endif /* CFG_CONSOLE_IS_IN_ENV */ +#endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */ static int console_setfile (int file, device_t * dev) { @@ -93,13 +93,83 @@ 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, ...) { va_list args; uint i; - char printbuffer[CFG_PBSIZE]; + char printbuffer[CONFIG_SYS_PBSIZE]; va_start (args, 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,20 +228,28 @@ 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, ...) { va_list args; uint i; - char printbuffer[CFG_PBSIZE]; + char printbuffer[CONFIG_SYS_PBSIZE]; va_start (args, fmt); @@ -162,6 +267,11 @@ void fprintf (int file, const char *fmt, ...) int getc (void) { +#ifdef CONFIG_DISABLE_CONSOLE + if (gd->flags & GD_FLG_DISABLE_CONSOLE) + return 0; +#endif + if (gd->flags & GD_FLG_DEVINIT) { /* Get from the standard input */ return fgetc (stdin); @@ -173,6 +283,11 @@ int getc (void) int tstc (void) { +#ifdef CONFIG_DISABLE_CONSOLE + if (gd->flags & GD_FLG_DISABLE_CONSOLE) + return 0; +#endif + if (gd->flags & GD_FLG_DEVINIT) { /* Test the standard input */ return ftstc (stdin); @@ -189,6 +304,11 @@ void putc (const char c) return; #endif +#ifdef CONFIG_DISABLE_CONSOLE + if (gd->flags & GD_FLG_DISABLE_CONSOLE) + return; +#endif + if (gd->flags & GD_FLG_DEVINIT) { /* Send to the standard output */ fputc (stdout, c); @@ -205,6 +325,11 @@ void puts (const char *s) return; #endif +#ifdef CONFIG_DISABLE_CONSOLE + if (gd->flags & GD_FLG_DISABLE_CONSOLE) + return; +#endif + if (gd->flags & GD_FLG_DEVINIT) { /* Send to the standard output */ fputs (stdout, s); @@ -218,7 +343,7 @@ void printf (const char *fmt, ...) { va_list args; uint i; - char printbuffer[CFG_PBSIZE]; + char printbuffer[CONFIG_SYS_PBSIZE]; va_start (args, fmt); @@ -235,7 +360,7 @@ void printf (const char *fmt, ...) void vprintf (const char *fmt, va_list args) { uint i; - char printbuffer[CFG_PBSIZE]; + char printbuffer[CONFIG_SYS_PBSIZE]; /* For this to work, printbuffer must be larger than * anything we ever want to print. @@ -294,7 +419,7 @@ inline void dbg(const char *fmt, ...) { va_list args; uint i; - char printbuffer[CFG_PBSIZE]; + char printbuffer[CONFIG_SYS_PBSIZE]; if (!once) { memset(screen, 0, sizeof(screen)); @@ -378,15 +503,18 @@ int console_init_f (void) return (0); } -#ifdef CFG_CONSOLE_IS_IN_ENV +#ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV /* Called after the relocation - use desired console functions */ int console_init_r (void) { char *stdinname, *stdoutname, *stderrname; device_t *inputdev = NULL, *outputdev = NULL, *errdev = NULL; -#ifdef CFG_CONSOLE_ENV_OVERWRITE +#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE int i; -#endif /* CFG_CONSOLE_ENV_OVERWRITE */ +#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; @@ -405,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) { @@ -418,47 +554,78 @@ 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 CFG_CONSOLE_INFO_QUIET +#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET /* Print information */ puts ("In: "); 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 /* CFG_CONSOLE_INFO_QUIET */ +#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ -#ifdef CFG_CONSOLE_ENV_OVERWRITE +#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE /* set the environment variables (will overwrite previous env settings) */ for (i = 0; i < 3; i++) { setenv (stdio_names[i], stdio_devices[i]->name); } -#endif /* CFG_CONSOLE_ENV_OVERWRITE */ +#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */ #if 0 /* If nothing usable installed, use only the initial console */ @@ -468,7 +635,7 @@ int console_init_r (void) return (0); } -#else /* CFG_CONSOLE_IS_IN_ENV */ +#else /* CONFIG_SYS_CONSOLE_IS_IN_ENV */ /* Called after the relocation - use desired console functions */ int console_init_r (void) @@ -504,16 +671,23 @@ 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 */ -#ifndef CFG_CONSOLE_INFO_QUIET +#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET /* Print information */ puts ("In: "); if (stdio_devices[stdin] == NULL) { @@ -535,7 +709,7 @@ int console_init_r (void) } else { printf ("%s\n", stdio_devices[stderr]->name); } -#endif /* CFG_CONSOLE_INFO_QUIET */ +#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ /* Setting environment variables */ for (i = 0; i < 3; i++) { @@ -551,4 +725,4 @@ int console_init_r (void) return (0); } -#endif /* CFG_CONSOLE_IS_IN_ENV */ +#endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */ |