X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=common%2Fconsole.c;h=4695386a332ab867c12df32e938d4976ce7f0115;hb=c88eaea0a0a809884388c3a5727d960bac0b0ced;hp=8c650e05e1c352ff5406b576387cb25dd2f5dd35;hpb=006915fbb0e3c1c9927fe32c4e92cb011f8499e7;p=karo-tx-uboot.git diff --git a/common/console.c b/common/console.c index 8c650e05e1..4695386a33 100644 --- a/common/console.c +++ b/common/console.c @@ -2,33 +2,86 @@ * (C) Copyright 2000 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 (at your option) 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ #include #include +#include #include +#include +#include #include #include +#include DECLARE_GLOBAL_DATA_PTR; +static int on_console(const char *name, const char *value, enum env_op op, + int flags) +{ + int console = -1; + + /* Check for console redirection */ + if (strcmp(name, "stdin") == 0) + console = stdin; + else if (strcmp(name, "stdout") == 0) + console = stdout; + else if (strcmp(name, "stderr") == 0) + console = stderr; + + /* if not actually setting a console variable, we don't care */ + if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0) + return 0; + + switch (op) { + case env_op_create: + case env_op_overwrite: + +#ifdef CONFIG_CONSOLE_MUX + if (iomux_doenv(console, value)) + return 1; +#else + /* Try assigning specified device */ + if (console_assign(console, value) < 0) + return 1; +#endif /* CONFIG_CONSOLE_MUX */ + return 0; + + case env_op_delete: + if ((flags & H_FORCE) == 0) + printf("Can't delete \"%s\"\n", name); + return 1; + + default: + return 0; + } +} +U_BOOT_ENV_CALLBACK(console, on_console); + +#ifdef CONFIG_SILENT_CONSOLE +static int on_silent(const char *name, const char *value, enum env_op op, + int flags) +{ +#ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_SET + if (flags & H_INTERACTIVE) + return 0; +#endif +#ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC + if ((flags & H_INTERACTIVE) == 0) + return 0; +#endif + + if (value != NULL) + gd->flags |= GD_FLG_SILENT; + else + gd->flags &= ~GD_FLG_SILENT; + + return 0; +} +U_BOOT_ENV_CALLBACK(silent, on_silent); +#endif + #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV /* * if overwrite_console returns 1, the stdin, stderr and stdout @@ -57,7 +110,7 @@ static int console_setfile(int file, struct stdio_dev * dev) case stderr: /* Start new device */ if (dev->start) { - error = dev->start(); + error = dev->start(dev); /* If it's not started dont use it */ if (error < 0) break; @@ -107,7 +160,7 @@ static int console_getc(int file) unsigned char ret; /* This is never called with testcdev == NULL */ - ret = tstcdev->getc(); + ret = tstcdev->getc(tstcdev); tstcdev = NULL; return ret; } @@ -121,7 +174,7 @@ static int console_tstc(int file) for (i = 0; i < cd_count[file]; i++) { dev = console_devices[file][i]; if (dev->tstc != NULL) { - ret = dev->tstc(); + ret = dev->tstc(dev); if (ret > 0) { tstcdev = dev; disable_ctrlc(0); @@ -142,7 +195,7 @@ static void console_putc(int file, const char c) for (i = 0; i < cd_count[file]; i++) { dev = console_devices[file][i]; if (dev->putc != NULL) - dev->putc(c); + dev->putc(dev, c); } } @@ -154,7 +207,7 @@ static void console_puts(int file, const char *s) for (i = 0; i < cd_count[file]; i++) { dev = console_devices[file][i]; if (dev->puts != NULL) - dev->puts(s); + dev->puts(dev, s); } } @@ -170,22 +223,22 @@ static inline void console_doenv(int file, struct stdio_dev *dev) #else static inline int console_getc(int file) { - return stdio_devices[file]->getc(); + return stdio_devices[file]->getc(stdio_devices[file]); } static inline int console_tstc(int file) { - return stdio_devices[file]->tstc(); + return stdio_devices[file]->tstc(stdio_devices[file]); } static inline void console_putc(int file, const char c) { - stdio_devices[file]->putc(c); + stdio_devices[file]->putc(stdio_devices[file], c); } static inline void console_puts(int file, const char *s) { - stdio_devices[file]->puts(s); + stdio_devices[file]->puts(stdio_devices[file], s); } static inline void console_printdevs(int file) @@ -212,7 +265,7 @@ int serial_printf(const char *fmt, ...) /* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i = vsprintf(printbuffer, fmt, args); + i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); va_end(args); serial_puts(printbuffer); @@ -281,7 +334,7 @@ int fprintf(int file, const char *fmt, ...) /* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i = vsprintf(printbuffer, fmt, args); + i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); va_end(args); /* Send to desired file */ @@ -298,6 +351,9 @@ int getc(void) return 0; #endif + if (!gd->have_console) + return 0; + if (gd->flags & GD_FLG_DEVINIT) { /* Get from the standard input */ return fgetc(stdin); @@ -314,6 +370,9 @@ int tstc(void) return 0; #endif + if (!gd->have_console) + return 0; + if (gd->flags & GD_FLG_DEVINIT) { /* Test the standard input */ return ftstc(stdin); @@ -323,8 +382,47 @@ int tstc(void) return serial_tstc(); } +#ifdef CONFIG_PRE_CONSOLE_BUFFER +#define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ) + +static void pre_console_putc(const char c) +{ + char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR; + + buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c; +} + +static void pre_console_puts(const char *s) +{ + while (*s) + pre_console_putc(*s++); +} + +static void print_pre_console_buffer(void) +{ + unsigned long i = 0; + char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR; + + if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ) + i = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ; + + while (i < gd->precon_buf_idx) + putc(buffer[CIRC_BUF_IDX(i++)]); +} +#else +static inline void pre_console_putc(const char c) {} +static inline void pre_console_puts(const char *s) {} +static inline void print_pre_console_buffer(void) {} +#endif + void putc(const char c) { +#ifdef CONFIG_SANDBOX + if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) { + os_putc(c); + return; + } +#endif #ifdef CONFIG_SILENT_CONSOLE if (gd->flags & GD_FLG_SILENT) return; @@ -335,6 +433,9 @@ void putc(const char c) return; #endif + if (!gd->have_console) + return pre_console_putc(c); + if (gd->flags & GD_FLG_DEVINIT) { /* Send to the standard output */ fputc(stdout, c); @@ -346,6 +447,13 @@ void putc(const char c) void puts(const char *s) { +#ifdef CONFIG_SANDBOX + if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) { + os_puts(s); + return; + } +#endif + #ifdef CONFIG_SILENT_CONSOLE if (gd->flags & GD_FLG_SILENT) return; @@ -356,6 +464,9 @@ void puts(const char *s) return; #endif + if (!gd->have_console) + return pre_console_puts(s); + if (gd->flags & GD_FLG_DEVINIT) { /* Send to the standard output */ fputs(stdout, s); @@ -371,12 +482,17 @@ int printf(const char *fmt, ...) uint i; char printbuffer[CONFIG_SYS_PBSIZE]; +#if !defined(CONFIG_SANDBOX) && !defined(CONFIG_PRE_CONSOLE_BUFFER) + if (!gd->have_console) + return 0; +#endif + va_start(args, fmt); /* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i = vsprintf(printbuffer, fmt, args); + i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); va_end(args); /* Print the string */ @@ -389,10 +505,15 @@ int vprintf(const char *fmt, va_list args) uint i; char printbuffer[CONFIG_SYS_PBSIZE]; +#if defined(CONFIG_PRE_CONSOLE_BUFFER) && !defined(CONFIG_SANDBOX) + if (!gd->have_console) + return 0; +#endif + /* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i = vsprintf(printbuffer, fmt, args); + i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); /* Print the string */ puts(printbuffer); @@ -404,6 +525,7 @@ static int ctrlc_disabled = 0; /* see disable_ctrl() */ static int ctrlc_was_pressed = 0; int ctrlc(void) { +#ifndef CONFIG_SANDBOX if (!ctrlc_disabled && gd->have_console) { if (tstc()) { switch (getc()) { @@ -415,9 +537,37 @@ int ctrlc(void) } } } +#endif + + return 0; +} +/* Reads user's confirmation. + Returns 1 if user's input is "y", "Y", "yes" or "YES" +*/ +int confirm_yesno(void) +{ + int i; + char str_input[5]; + + /* Flush input */ + while (tstc()) + getc(); + i = 0; + while (i < sizeof(str_input)) { + str_input[i] = getc(); + putc(str_input[i]); + if (str_input[i] == '\r') + break; + i++; + } + putc('\n'); + if (strncmp(str_input, "y\r", 2) == 0 || + strncmp(str_input, "Y\r", 2) == 0 || + strncmp(str_input, "yes\r", 4) == 0 || + strncmp(str_input, "YES\r", 4) == 0) + return 1; return 0; } - /* pass 1 to disable ctrlc() checking, 0 to enable. * returns previous state */ @@ -459,7 +609,7 @@ inline void dbg(const char *fmt, ...) /* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i = vsprintf(printbuffer, fmt, args); + i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args); va_end(args); if ((screen + sizeof(screen) - 1 - cursor) @@ -472,7 +622,7 @@ inline void dbg(const char *fmt, ...) } #else -inline void dbg(const char *fmt, ...) +static inline void dbg(const char *fmt, ...) { } #endif @@ -529,12 +679,13 @@ int console_init_f(void) gd->flags |= GD_FLG_SILENT; #endif + print_pre_console_buffer(); + return 0; } void stdio_print_current_devices(void) { -#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET /* Print information */ puts("In: "); if (stdio_devices[stdin] == NULL) { @@ -556,7 +707,6 @@ void stdio_print_current_devices(void) } else { printf ("%s\n", stdio_devices[stderr]->name); } -#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ } #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV @@ -626,9 +776,9 @@ int console_init_r(void) done: #endif - gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ - +#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET stdio_print_current_devices(); +#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE /* set the environment variables (will overwrite previous env settings) */ @@ -637,6 +787,8 @@ done: } #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */ + gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ + #if 0 /* If nothing usable installed, use only the initial console */ if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) @@ -701,15 +853,17 @@ int console_init_r(void) #endif } - gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ - +#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET stdio_print_current_devices(); +#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ /* Setting environment variables */ for (i = 0; i < 3; i++) { setenv(stdio_names[i], stdio_devices[i]->name); } + gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ + #if 0 /* If nothing usable installed, use only the initial console */ if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))