183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
247d1a6e1Swdenk /*
347d1a6e1Swdenk * (C) Copyright 2000
447d1a6e1Swdenk * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
547d1a6e1Swdenk */
647d1a6e1Swdenk
747d1a6e1Swdenk #include <common.h>
824b852a7SSimon Glass #include <console.h>
9d6ea5307SSimon Glass #include <debug_uart.h>
107b3c4c3aSSimon Glass #include <dm.h>
1147d1a6e1Swdenk #include <stdarg.h>
12482f4691SJeroen Hofstee #include <iomux.h>
1347d1a6e1Swdenk #include <malloc.h>
144e6bafa5SSimon Glass #include <mapmem.h>
1591b136c7SSimon Glass #include <os.h>
16849d5d9cSJoe Hershberger #include <serial.h>
1752cb4d4fSJean-Christophe PLAGNIOL-VILLARD #include <stdio_dev.h>
1827b207fdSwdenk #include <exports.h>
19849d5d9cSJoe Hershberger #include <environment.h>
2064407467SAndreas J. Reichel #include <watchdog.h>
2147d1a6e1Swdenk
22d87080b7SWolfgang Denk DECLARE_GLOBAL_DATA_PTR;
23d87080b7SWolfgang Denk
on_console(const char * name,const char * value,enum env_op op,int flags)24849d5d9cSJoe Hershberger static int on_console(const char *name, const char *value, enum env_op op,
25849d5d9cSJoe Hershberger int flags)
26849d5d9cSJoe Hershberger {
27849d5d9cSJoe Hershberger int console = -1;
28849d5d9cSJoe Hershberger
29849d5d9cSJoe Hershberger /* Check for console redirection */
30849d5d9cSJoe Hershberger if (strcmp(name, "stdin") == 0)
31849d5d9cSJoe Hershberger console = stdin;
32849d5d9cSJoe Hershberger else if (strcmp(name, "stdout") == 0)
33849d5d9cSJoe Hershberger console = stdout;
34849d5d9cSJoe Hershberger else if (strcmp(name, "stderr") == 0)
35849d5d9cSJoe Hershberger console = stderr;
36849d5d9cSJoe Hershberger
37849d5d9cSJoe Hershberger /* if not actually setting a console variable, we don't care */
38849d5d9cSJoe Hershberger if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0)
39849d5d9cSJoe Hershberger return 0;
40849d5d9cSJoe Hershberger
41849d5d9cSJoe Hershberger switch (op) {
42849d5d9cSJoe Hershberger case env_op_create:
43849d5d9cSJoe Hershberger case env_op_overwrite:
44849d5d9cSJoe Hershberger
45b0265429SSimon Glass #if CONFIG_IS_ENABLED(CONSOLE_MUX)
46849d5d9cSJoe Hershberger if (iomux_doenv(console, value))
47849d5d9cSJoe Hershberger return 1;
48849d5d9cSJoe Hershberger #else
49849d5d9cSJoe Hershberger /* Try assigning specified device */
50849d5d9cSJoe Hershberger if (console_assign(console, value) < 0)
51849d5d9cSJoe Hershberger return 1;
52b0265429SSimon Glass #endif
53849d5d9cSJoe Hershberger return 0;
54849d5d9cSJoe Hershberger
55849d5d9cSJoe Hershberger case env_op_delete:
56849d5d9cSJoe Hershberger if ((flags & H_FORCE) == 0)
57849d5d9cSJoe Hershberger printf("Can't delete \"%s\"\n", name);
58849d5d9cSJoe Hershberger return 1;
59849d5d9cSJoe Hershberger
60849d5d9cSJoe Hershberger default:
61849d5d9cSJoe Hershberger return 0;
62849d5d9cSJoe Hershberger }
63849d5d9cSJoe Hershberger }
64849d5d9cSJoe Hershberger U_BOOT_ENV_CALLBACK(console, on_console);
65849d5d9cSJoe Hershberger
66e080d545SJoe Hershberger #ifdef CONFIG_SILENT_CONSOLE
on_silent(const char * name,const char * value,enum env_op op,int flags)67e080d545SJoe Hershberger static int on_silent(const char *name, const char *value, enum env_op op,
68e080d545SJoe Hershberger int flags)
69e080d545SJoe Hershberger {
705daf6e56SWilson Lee #if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET)
71e080d545SJoe Hershberger if (flags & H_INTERACTIVE)
72e080d545SJoe Hershberger return 0;
73e080d545SJoe Hershberger #endif
745daf6e56SWilson Lee #if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC)
75e080d545SJoe Hershberger if ((flags & H_INTERACTIVE) == 0)
76e080d545SJoe Hershberger return 0;
77e080d545SJoe Hershberger #endif
78e080d545SJoe Hershberger
79e080d545SJoe Hershberger if (value != NULL)
80e080d545SJoe Hershberger gd->flags |= GD_FLG_SILENT;
81e080d545SJoe Hershberger else
82e080d545SJoe Hershberger gd->flags &= ~GD_FLG_SILENT;
83e080d545SJoe Hershberger
84e080d545SJoe Hershberger return 0;
85e080d545SJoe Hershberger }
86e080d545SJoe Hershberger U_BOOT_ENV_CALLBACK(silent, on_silent);
87e080d545SJoe Hershberger #endif
88e080d545SJoe Hershberger
89b0265429SSimon Glass #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
9047d1a6e1Swdenk /*
9147d1a6e1Swdenk * if overwrite_console returns 1, the stdin, stderr and stdout
9247d1a6e1Swdenk * are switched to the serial port, else the settings in the
9347d1a6e1Swdenk * environment are used
9447d1a6e1Swdenk */
956d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
9647d1a6e1Swdenk extern int overwrite_console(void);
9783e40ba7Swdenk #define OVERWRITE_CONSOLE overwrite_console()
9847d1a6e1Swdenk #else
9983e40ba7Swdenk #define OVERWRITE_CONSOLE 0
1006d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
10147d1a6e1Swdenk
102b0265429SSimon Glass #endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
10347d1a6e1Swdenk
console_setfile(int file,struct stdio_dev * dev)10452cb4d4fSJean-Christophe PLAGNIOL-VILLARD static int console_setfile(int file, struct stdio_dev * dev)
10547d1a6e1Swdenk {
10647d1a6e1Swdenk int error = 0;
10747d1a6e1Swdenk
10847d1a6e1Swdenk if (dev == NULL)
10947d1a6e1Swdenk return -1;
11047d1a6e1Swdenk
11147d1a6e1Swdenk switch (file) {
11247d1a6e1Swdenk case stdin:
11347d1a6e1Swdenk case stdout:
11447d1a6e1Swdenk case stderr:
11547d1a6e1Swdenk /* Start new device */
11647d1a6e1Swdenk if (dev->start) {
117709ea543SSimon Glass error = dev->start(dev);
11847d1a6e1Swdenk /* If it's not started dont use it */
11947d1a6e1Swdenk if (error < 0)
12047d1a6e1Swdenk break;
12147d1a6e1Swdenk }
12247d1a6e1Swdenk
12347d1a6e1Swdenk /* Assign the new device (leaving the existing one started) */
12447d1a6e1Swdenk stdio_devices[file] = dev;
12547d1a6e1Swdenk
12647d1a6e1Swdenk /*
12747d1a6e1Swdenk * Update monitor functions
12847d1a6e1Swdenk * (to use the console stuff by other applications)
12947d1a6e1Swdenk */
13047d1a6e1Swdenk switch (file) {
13147d1a6e1Swdenk case stdin:
13249cad547SMartin Dorwig gd->jt->getc = getc;
13349cad547SMartin Dorwig gd->jt->tstc = tstc;
13447d1a6e1Swdenk break;
13547d1a6e1Swdenk case stdout:
13649cad547SMartin Dorwig gd->jt->putc = putc;
13749cad547SMartin Dorwig gd->jt->puts = puts;
13849cad547SMartin Dorwig gd->jt->printf = printf;
13947d1a6e1Swdenk break;
14047d1a6e1Swdenk }
14147d1a6e1Swdenk break;
14247d1a6e1Swdenk
14347d1a6e1Swdenk default: /* Invalid file ID */
14447d1a6e1Swdenk error = -1;
14547d1a6e1Swdenk }
14647d1a6e1Swdenk return error;
14747d1a6e1Swdenk }
14847d1a6e1Swdenk
14942f9f915SSimon Glass /**
15042f9f915SSimon Glass * console_dev_is_serial() - Check if a stdio device is a serial device
15142f9f915SSimon Glass *
15242f9f915SSimon Glass * @sdev: Device to check
1537b3c4c3aSSimon Glass * @return true if this device is in the serial uclass (or for pre-driver-model,
1547b3c4c3aSSimon Glass * whether it is called "serial".
15542f9f915SSimon Glass */
console_dev_is_serial(struct stdio_dev * sdev)15642f9f915SSimon Glass static bool console_dev_is_serial(struct stdio_dev *sdev)
15742f9f915SSimon Glass {
15842f9f915SSimon Glass bool is_serial;
15942f9f915SSimon Glass
1607b3c4c3aSSimon Glass #ifdef CONFIG_DM_SERIAL
1617b3c4c3aSSimon Glass if (sdev->flags & DEV_FLAGS_DM) {
1627b3c4c3aSSimon Glass struct udevice *dev = sdev->priv;
1637b3c4c3aSSimon Glass
1647b3c4c3aSSimon Glass is_serial = device_get_uclass_id(dev) == UCLASS_SERIAL;
1657b3c4c3aSSimon Glass } else
1667b3c4c3aSSimon Glass #endif
16742f9f915SSimon Glass is_serial = !strcmp(sdev->name, "serial");
16842f9f915SSimon Glass
16942f9f915SSimon Glass return is_serial;
17042f9f915SSimon Glass }
17142f9f915SSimon Glass
172b0265429SSimon Glass #if CONFIG_IS_ENABLED(CONSOLE_MUX)
17316a28ef2SGary Jennejohn /** Console I/O multiplexing *******************************************/
17416a28ef2SGary Jennejohn
17552cb4d4fSJean-Christophe PLAGNIOL-VILLARD static struct stdio_dev *tstcdev;
17652cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev **console_devices[MAX_FILES];
17716a28ef2SGary Jennejohn int cd_count[MAX_FILES];
17816a28ef2SGary Jennejohn
17916a28ef2SGary Jennejohn /*
18016a28ef2SGary Jennejohn * This depends on tstc() always being called before getc().
18116a28ef2SGary Jennejohn * This is guaranteed to be true because this routine is called
18216a28ef2SGary Jennejohn * only from fgetc() which assures it.
18316a28ef2SGary Jennejohn * No attempt is made to demultiplex multiple input sources.
18416a28ef2SGary Jennejohn */
console_getc(int file)1855f032010SJean-Christophe PLAGNIOL-VILLARD static int console_getc(int file)
18616a28ef2SGary Jennejohn {
18716a28ef2SGary Jennejohn unsigned char ret;
18816a28ef2SGary Jennejohn
18916a28ef2SGary Jennejohn /* This is never called with testcdev == NULL */
190709ea543SSimon Glass ret = tstcdev->getc(tstcdev);
19116a28ef2SGary Jennejohn tstcdev = NULL;
19216a28ef2SGary Jennejohn return ret;
19316a28ef2SGary Jennejohn }
19416a28ef2SGary Jennejohn
console_tstc(int file)1955f032010SJean-Christophe PLAGNIOL-VILLARD static int console_tstc(int file)
19616a28ef2SGary Jennejohn {
19716a28ef2SGary Jennejohn int i, ret;
19852cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *dev;
199b2f58d8eSJoe Hershberger int prev;
20016a28ef2SGary Jennejohn
201b2f58d8eSJoe Hershberger prev = disable_ctrlc(1);
20216a28ef2SGary Jennejohn for (i = 0; i < cd_count[file]; i++) {
20316a28ef2SGary Jennejohn dev = console_devices[file][i];
20416a28ef2SGary Jennejohn if (dev->tstc != NULL) {
205709ea543SSimon Glass ret = dev->tstc(dev);
20616a28ef2SGary Jennejohn if (ret > 0) {
20716a28ef2SGary Jennejohn tstcdev = dev;
208b2f58d8eSJoe Hershberger disable_ctrlc(prev);
20916a28ef2SGary Jennejohn return ret;
21016a28ef2SGary Jennejohn }
21116a28ef2SGary Jennejohn }
21216a28ef2SGary Jennejohn }
213b2f58d8eSJoe Hershberger disable_ctrlc(prev);
21416a28ef2SGary Jennejohn
21516a28ef2SGary Jennejohn return 0;
21616a28ef2SGary Jennejohn }
21716a28ef2SGary Jennejohn
console_putc(int file,const char c)2185f032010SJean-Christophe PLAGNIOL-VILLARD static void console_putc(int file, const char c)
21916a28ef2SGary Jennejohn {
22016a28ef2SGary Jennejohn int i;
22152cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *dev;
22216a28ef2SGary Jennejohn
22316a28ef2SGary Jennejohn for (i = 0; i < cd_count[file]; i++) {
22416a28ef2SGary Jennejohn dev = console_devices[file][i];
22516a28ef2SGary Jennejohn if (dev->putc != NULL)
226709ea543SSimon Glass dev->putc(dev, c);
22716a28ef2SGary Jennejohn }
22816a28ef2SGary Jennejohn }
22916a28ef2SGary Jennejohn
console_puts_noserial(int file,const char * s)230a8552c7cSHans de Goede static void console_puts_noserial(int file, const char *s)
23127669667SSiarhei Siamashka {
23227669667SSiarhei Siamashka int i;
23327669667SSiarhei Siamashka struct stdio_dev *dev;
23427669667SSiarhei Siamashka
23527669667SSiarhei Siamashka for (i = 0; i < cd_count[file]; i++) {
23627669667SSiarhei Siamashka dev = console_devices[file][i];
23742f9f915SSimon Glass if (dev->puts != NULL && !console_dev_is_serial(dev))
238a8552c7cSHans de Goede dev->puts(dev, s);
23927669667SSiarhei Siamashka }
24027669667SSiarhei Siamashka }
24127669667SSiarhei Siamashka
console_puts(int file,const char * s)2425f032010SJean-Christophe PLAGNIOL-VILLARD static void console_puts(int file, const char *s)
24316a28ef2SGary Jennejohn {
24416a28ef2SGary Jennejohn int i;
24552cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *dev;
24616a28ef2SGary Jennejohn
24716a28ef2SGary Jennejohn for (i = 0; i < cd_count[file]; i++) {
24816a28ef2SGary Jennejohn dev = console_devices[file][i];
24916a28ef2SGary Jennejohn if (dev->puts != NULL)
250709ea543SSimon Glass dev->puts(dev, s);
25116a28ef2SGary Jennejohn }
25216a28ef2SGary Jennejohn }
2535f032010SJean-Christophe PLAGNIOL-VILLARD
console_doenv(int file,struct stdio_dev * dev)25452cb4d4fSJean-Christophe PLAGNIOL-VILLARD static inline void console_doenv(int file, struct stdio_dev *dev)
2555f032010SJean-Christophe PLAGNIOL-VILLARD {
2565f032010SJean-Christophe PLAGNIOL-VILLARD iomux_doenv(file, dev->name);
2575f032010SJean-Christophe PLAGNIOL-VILLARD }
2585f032010SJean-Christophe PLAGNIOL-VILLARD #else
console_getc(int file)2595f032010SJean-Christophe PLAGNIOL-VILLARD static inline int console_getc(int file)
2605f032010SJean-Christophe PLAGNIOL-VILLARD {
261709ea543SSimon Glass return stdio_devices[file]->getc(stdio_devices[file]);
2625f032010SJean-Christophe PLAGNIOL-VILLARD }
2635f032010SJean-Christophe PLAGNIOL-VILLARD
console_tstc(int file)2645f032010SJean-Christophe PLAGNIOL-VILLARD static inline int console_tstc(int file)
2655f032010SJean-Christophe PLAGNIOL-VILLARD {
266709ea543SSimon Glass return stdio_devices[file]->tstc(stdio_devices[file]);
2675f032010SJean-Christophe PLAGNIOL-VILLARD }
2685f032010SJean-Christophe PLAGNIOL-VILLARD
console_putc(int file,const char c)2695f032010SJean-Christophe PLAGNIOL-VILLARD static inline void console_putc(int file, const char c)
2705f032010SJean-Christophe PLAGNIOL-VILLARD {
271709ea543SSimon Glass stdio_devices[file]->putc(stdio_devices[file], c);
2725f032010SJean-Christophe PLAGNIOL-VILLARD }
2735f032010SJean-Christophe PLAGNIOL-VILLARD
console_puts_noserial(int file,const char * s)274a8552c7cSHans de Goede static inline void console_puts_noserial(int file, const char *s)
27527669667SSiarhei Siamashka {
27642f9f915SSimon Glass if (!console_dev_is_serial(stdio_devices[file]))
277a8552c7cSHans de Goede stdio_devices[file]->puts(stdio_devices[file], s);
27827669667SSiarhei Siamashka }
27927669667SSiarhei Siamashka
console_puts(int file,const char * s)2805f032010SJean-Christophe PLAGNIOL-VILLARD static inline void console_puts(int file, const char *s)
2815f032010SJean-Christophe PLAGNIOL-VILLARD {
282709ea543SSimon Glass stdio_devices[file]->puts(stdio_devices[file], s);
2835f032010SJean-Christophe PLAGNIOL-VILLARD }
2845f032010SJean-Christophe PLAGNIOL-VILLARD
console_doenv(int file,struct stdio_dev * dev)28552cb4d4fSJean-Christophe PLAGNIOL-VILLARD static inline void console_doenv(int file, struct stdio_dev *dev)
2865f032010SJean-Christophe PLAGNIOL-VILLARD {
2875f032010SJean-Christophe PLAGNIOL-VILLARD console_setfile(file, dev);
2885f032010SJean-Christophe PLAGNIOL-VILLARD }
289b0265429SSimon Glass #endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
29016a28ef2SGary Jennejohn
29147d1a6e1Swdenk /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
29247d1a6e1Swdenk
serial_printf(const char * fmt,...)293d9c27253SWolfgang Denk int serial_printf(const char *fmt, ...)
29447d1a6e1Swdenk {
29547d1a6e1Swdenk va_list args;
29647d1a6e1Swdenk uint i;
2976d0f6bcfSJean-Christophe PLAGNIOL-VILLARD char printbuffer[CONFIG_SYS_PBSIZE];
29847d1a6e1Swdenk
29947d1a6e1Swdenk va_start(args, fmt);
30047d1a6e1Swdenk
30147d1a6e1Swdenk /* For this to work, printbuffer must be larger than
30247d1a6e1Swdenk * anything we ever want to print.
30347d1a6e1Swdenk */
304068af6f8SSonny Rao i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
30547d1a6e1Swdenk va_end(args);
30647d1a6e1Swdenk
30747d1a6e1Swdenk serial_puts(printbuffer);
308d9c27253SWolfgang Denk return i;
30947d1a6e1Swdenk }
31047d1a6e1Swdenk
fgetc(int file)31147d1a6e1Swdenk int fgetc(int file)
31247d1a6e1Swdenk {
31316a28ef2SGary Jennejohn if (file < MAX_FILES) {
31416a28ef2SGary Jennejohn /*
31516a28ef2SGary Jennejohn * Effectively poll for input wherever it may be available.
31616a28ef2SGary Jennejohn */
31716a28ef2SGary Jennejohn for (;;) {
31864407467SAndreas J. Reichel WATCHDOG_RESET();
319273a1252SPatrick Delaunay #if CONFIG_IS_ENABLED(CONSOLE_MUX)
32016a28ef2SGary Jennejohn /*
32116a28ef2SGary Jennejohn * Upper layer may have already called tstc() so
32216a28ef2SGary Jennejohn * check for that first.
32316a28ef2SGary Jennejohn */
32416a28ef2SGary Jennejohn if (tstcdev != NULL)
3255f032010SJean-Christophe PLAGNIOL-VILLARD return console_getc(file);
3265f032010SJean-Christophe PLAGNIOL-VILLARD console_tstc(file);
327273a1252SPatrick Delaunay #else
328273a1252SPatrick Delaunay if (console_tstc(file))
329273a1252SPatrick Delaunay return console_getc(file);
330273a1252SPatrick Delaunay #endif
33116a28ef2SGary Jennejohn #ifdef CONFIG_WATCHDOG
33216a28ef2SGary Jennejohn /*
33316a28ef2SGary Jennejohn * If the watchdog must be rate-limited then it should
33416a28ef2SGary Jennejohn * already be handled in board-specific code.
33516a28ef2SGary Jennejohn */
33616a28ef2SGary Jennejohn udelay(1);
33716a28ef2SGary Jennejohn #endif
33816a28ef2SGary Jennejohn }
33916a28ef2SGary Jennejohn }
34047d1a6e1Swdenk
34147d1a6e1Swdenk return -1;
34247d1a6e1Swdenk }
34347d1a6e1Swdenk
ftstc(int file)34447d1a6e1Swdenk int ftstc(int file)
34547d1a6e1Swdenk {
34647d1a6e1Swdenk if (file < MAX_FILES)
3475f032010SJean-Christophe PLAGNIOL-VILLARD return console_tstc(file);
34847d1a6e1Swdenk
34947d1a6e1Swdenk return -1;
35047d1a6e1Swdenk }
35147d1a6e1Swdenk
fputc(int file,const char c)35247d1a6e1Swdenk void fputc(int file, const char c)
35347d1a6e1Swdenk {
35447d1a6e1Swdenk if (file < MAX_FILES)
3555f032010SJean-Christophe PLAGNIOL-VILLARD console_putc(file, c);
35647d1a6e1Swdenk }
35747d1a6e1Swdenk
fputs(int file,const char * s)35847d1a6e1Swdenk void fputs(int file, const char *s)
35947d1a6e1Swdenk {
36047d1a6e1Swdenk if (file < MAX_FILES)
3615f032010SJean-Christophe PLAGNIOL-VILLARD console_puts(file, s);
36247d1a6e1Swdenk }
36347d1a6e1Swdenk
fprintf(int file,const char * fmt,...)364d9c27253SWolfgang Denk int fprintf(int file, const char *fmt, ...)
36547d1a6e1Swdenk {
36647d1a6e1Swdenk va_list args;
36747d1a6e1Swdenk uint i;
3686d0f6bcfSJean-Christophe PLAGNIOL-VILLARD char printbuffer[CONFIG_SYS_PBSIZE];
36947d1a6e1Swdenk
37047d1a6e1Swdenk va_start(args, fmt);
37147d1a6e1Swdenk
37247d1a6e1Swdenk /* For this to work, printbuffer must be larger than
37347d1a6e1Swdenk * anything we ever want to print.
37447d1a6e1Swdenk */
375068af6f8SSonny Rao i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
37647d1a6e1Swdenk va_end(args);
37747d1a6e1Swdenk
37847d1a6e1Swdenk /* Send to desired file */
37947d1a6e1Swdenk fputs(file, printbuffer);
380d9c27253SWolfgang Denk return i;
38147d1a6e1Swdenk }
38247d1a6e1Swdenk
38347d1a6e1Swdenk /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
38447d1a6e1Swdenk
getc(void)38547d1a6e1Swdenk int getc(void)
38647d1a6e1Swdenk {
387f5c3ba79SMark Jackson #ifdef CONFIG_DISABLE_CONSOLE
388f5c3ba79SMark Jackson if (gd->flags & GD_FLG_DISABLE_CONSOLE)
389f5c3ba79SMark Jackson return 0;
390f5c3ba79SMark Jackson #endif
391f5c3ba79SMark Jackson
392e3e454cdSGraeme Russ if (!gd->have_console)
393e3e454cdSGraeme Russ return 0;
394e3e454cdSGraeme Russ
3959854a874SSimon Glass #ifdef CONFIG_CONSOLE_RECORD
3969854a874SSimon Glass if (gd->console_in.start) {
3979854a874SSimon Glass int ch;
3989854a874SSimon Glass
3999854a874SSimon Glass ch = membuff_getbyte(&gd->console_in);
4009854a874SSimon Glass if (ch != -1)
4019854a874SSimon Glass return 1;
4029854a874SSimon Glass }
4039854a874SSimon Glass #endif
40447d1a6e1Swdenk if (gd->flags & GD_FLG_DEVINIT) {
40547d1a6e1Swdenk /* Get from the standard input */
40647d1a6e1Swdenk return fgetc(stdin);
40747d1a6e1Swdenk }
40847d1a6e1Swdenk
40947d1a6e1Swdenk /* Send directly to the handler */
41047d1a6e1Swdenk return serial_getc();
41147d1a6e1Swdenk }
41247d1a6e1Swdenk
tstc(void)41347d1a6e1Swdenk int tstc(void)
41447d1a6e1Swdenk {
415f5c3ba79SMark Jackson #ifdef CONFIG_DISABLE_CONSOLE
416f5c3ba79SMark Jackson if (gd->flags & GD_FLG_DISABLE_CONSOLE)
417f5c3ba79SMark Jackson return 0;
418f5c3ba79SMark Jackson #endif
419f5c3ba79SMark Jackson
420e3e454cdSGraeme Russ if (!gd->have_console)
421e3e454cdSGraeme Russ return 0;
4229854a874SSimon Glass #ifdef CONFIG_CONSOLE_RECORD
4239854a874SSimon Glass if (gd->console_in.start) {
4249854a874SSimon Glass if (membuff_peekbyte(&gd->console_in) != -1)
4259854a874SSimon Glass return 1;
4269854a874SSimon Glass }
4279854a874SSimon Glass #endif
42847d1a6e1Swdenk if (gd->flags & GD_FLG_DEVINIT) {
42947d1a6e1Swdenk /* Test the standard input */
43047d1a6e1Swdenk return ftstc(stdin);
43147d1a6e1Swdenk }
43247d1a6e1Swdenk
43347d1a6e1Swdenk /* Send directly to the handler */
43447d1a6e1Swdenk return serial_tstc();
43547d1a6e1Swdenk }
43647d1a6e1Swdenk
43727669667SSiarhei Siamashka #define PRE_CONSOLE_FLUSHPOINT1_SERIAL 0
43827669667SSiarhei Siamashka #define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL 1
43927669667SSiarhei Siamashka
4408f925584SSimon Glass #if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
4419558b48aSGraeme Russ #define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ)
4429558b48aSGraeme Russ
pre_console_putc(const char c)4439558b48aSGraeme Russ static void pre_console_putc(const char c)
4449558b48aSGraeme Russ {
4454e6bafa5SSimon Glass char *buffer;
4464e6bafa5SSimon Glass
4474e6bafa5SSimon Glass buffer = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
4489558b48aSGraeme Russ
4499558b48aSGraeme Russ buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c;
4504e6bafa5SSimon Glass
4514e6bafa5SSimon Glass unmap_sysmem(buffer);
4529558b48aSGraeme Russ }
4539558b48aSGraeme Russ
pre_console_puts(const char * s)454be135cc5SSoeren Moch static void pre_console_puts(const char *s)
455be135cc5SSoeren Moch {
456be135cc5SSoeren Moch while (*s)
457be135cc5SSoeren Moch pre_console_putc(*s++);
458be135cc5SSoeren Moch }
459be135cc5SSoeren Moch
print_pre_console_buffer(int flushpoint)46027669667SSiarhei Siamashka static void print_pre_console_buffer(int flushpoint)
4619558b48aSGraeme Russ {
462a8552c7cSHans de Goede unsigned long in = 0, out = 0;
463a8552c7cSHans de Goede char buf_out[CONFIG_PRE_CON_BUF_SZ + 1];
4644e6bafa5SSimon Glass char *buf_in;
4659558b48aSGraeme Russ
4664e6bafa5SSimon Glass buf_in = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
4679558b48aSGraeme Russ if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ)
468a8552c7cSHans de Goede in = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
4699558b48aSGraeme Russ
470a8552c7cSHans de Goede while (in < gd->precon_buf_idx)
471a8552c7cSHans de Goede buf_out[out++] = buf_in[CIRC_BUF_IDX(in++)];
4724e6bafa5SSimon Glass unmap_sysmem(buf_in);
473a8552c7cSHans de Goede
474a8552c7cSHans de Goede buf_out[out] = 0;
475a8552c7cSHans de Goede
47627669667SSiarhei Siamashka switch (flushpoint) {
47727669667SSiarhei Siamashka case PRE_CONSOLE_FLUSHPOINT1_SERIAL:
478a8552c7cSHans de Goede puts(buf_out);
47927669667SSiarhei Siamashka break;
48027669667SSiarhei Siamashka case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL:
481a8552c7cSHans de Goede console_puts_noserial(stdout, buf_out);
48227669667SSiarhei Siamashka break;
48327669667SSiarhei Siamashka }
4849558b48aSGraeme Russ }
4859558b48aSGraeme Russ #else
pre_console_putc(const char c)4869558b48aSGraeme Russ static inline void pre_console_putc(const char c) {}
pre_console_puts(const char * s)487be135cc5SSoeren Moch static inline void pre_console_puts(const char *s) {}
print_pre_console_buffer(int flushpoint)48827669667SSiarhei Siamashka static inline void print_pre_console_buffer(int flushpoint) {}
4899558b48aSGraeme Russ #endif
4909558b48aSGraeme Russ
putc(const char c)49147d1a6e1Swdenk void putc(const char c)
49247d1a6e1Swdenk {
49364e9b4f3SSimon Glass #ifdef CONFIG_SANDBOX
49464e9b4f3SSimon Glass /* sandbox can send characters to stdout before it has a console */
49564e9b4f3SSimon Glass if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
49664e9b4f3SSimon Glass os_putc(c);
49764e9b4f3SSimon Glass return;
49864e9b4f3SSimon Glass }
49964e9b4f3SSimon Glass #endif
500d6ea5307SSimon Glass #ifdef CONFIG_DEBUG_UART
501d6ea5307SSimon Glass /* if we don't have a console yet, use the debug UART */
502d6ea5307SSimon Glass if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
503d6ea5307SSimon Glass printch(c);
504d6ea5307SSimon Glass return;
505d6ea5307SSimon Glass }
506d6ea5307SSimon Glass #endif
507af880e24SSimon Glass if (!gd)
508af880e24SSimon Glass return;
5099854a874SSimon Glass #ifdef CONFIG_CONSOLE_RECORD
510af880e24SSimon Glass if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start)
5119854a874SSimon Glass membuff_putbyte(&gd->console_out, c);
5129854a874SSimon Glass #endif
513a6cccaeaSwdenk #ifdef CONFIG_SILENT_CONSOLE
514a6cccaeaSwdenk if (gd->flags & GD_FLG_SILENT)
515f6e20fc6Swdenk return;
516a6cccaeaSwdenk #endif
517a6cccaeaSwdenk
518f5c3ba79SMark Jackson #ifdef CONFIG_DISABLE_CONSOLE
519f5c3ba79SMark Jackson if (gd->flags & GD_FLG_DISABLE_CONSOLE)
520f5c3ba79SMark Jackson return;
521f5c3ba79SMark Jackson #endif
522f5c3ba79SMark Jackson
523e3e454cdSGraeme Russ if (!gd->have_console)
5249558b48aSGraeme Russ return pre_console_putc(c);
525e3e454cdSGraeme Russ
52647d1a6e1Swdenk if (gd->flags & GD_FLG_DEVINIT) {
52747d1a6e1Swdenk /* Send to the standard output */
52847d1a6e1Swdenk fputc(stdout, c);
52947d1a6e1Swdenk } else {
53047d1a6e1Swdenk /* Send directly to the handler */
53127669667SSiarhei Siamashka pre_console_putc(c);
53247d1a6e1Swdenk serial_putc(c);
53347d1a6e1Swdenk }
53447d1a6e1Swdenk }
53547d1a6e1Swdenk
puts(const char * s)53647d1a6e1Swdenk void puts(const char *s)
53747d1a6e1Swdenk {
538*36bcea62SSimon Glass #ifdef CONFIG_SANDBOX
539*36bcea62SSimon Glass /* sandbox can send characters to stdout before it has a console */
540*36bcea62SSimon Glass if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
541*36bcea62SSimon Glass os_puts(s);
542*36bcea62SSimon Glass return;
543*36bcea62SSimon Glass }
544*36bcea62SSimon Glass #endif
545be135cc5SSoeren Moch #ifdef CONFIG_DEBUG_UART
546be135cc5SSoeren Moch if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
547be135cc5SSoeren Moch while (*s) {
548be135cc5SSoeren Moch int ch = *s++;
549be135cc5SSoeren Moch
550be135cc5SSoeren Moch printch(ch);
551be135cc5SSoeren Moch }
552be135cc5SSoeren Moch return;
553be135cc5SSoeren Moch }
554be135cc5SSoeren Moch #endif
555af880e24SSimon Glass if (!gd)
556af880e24SSimon Glass return;
557be135cc5SSoeren Moch #ifdef CONFIG_CONSOLE_RECORD
558af880e24SSimon Glass if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start)
559be135cc5SSoeren Moch membuff_put(&gd->console_out, s, strlen(s));
560be135cc5SSoeren Moch #endif
561be135cc5SSoeren Moch #ifdef CONFIG_SILENT_CONSOLE
562be135cc5SSoeren Moch if (gd->flags & GD_FLG_SILENT)
563be135cc5SSoeren Moch return;
564be135cc5SSoeren Moch #endif
565be135cc5SSoeren Moch
566be135cc5SSoeren Moch #ifdef CONFIG_DISABLE_CONSOLE
567be135cc5SSoeren Moch if (gd->flags & GD_FLG_DISABLE_CONSOLE)
568be135cc5SSoeren Moch return;
569be135cc5SSoeren Moch #endif
570be135cc5SSoeren Moch
571be135cc5SSoeren Moch if (!gd->have_console)
572be135cc5SSoeren Moch return pre_console_puts(s);
573be135cc5SSoeren Moch
574be135cc5SSoeren Moch if (gd->flags & GD_FLG_DEVINIT) {
575be135cc5SSoeren Moch /* Send to the standard output */
576be135cc5SSoeren Moch fputs(stdout, s);
577be135cc5SSoeren Moch } else {
578be135cc5SSoeren Moch /* Send directly to the handler */
579be135cc5SSoeren Moch pre_console_puts(s);
580be135cc5SSoeren Moch serial_puts(s);
581be135cc5SSoeren Moch }
58247d1a6e1Swdenk }
58347d1a6e1Swdenk
5849854a874SSimon Glass #ifdef CONFIG_CONSOLE_RECORD
console_record_init(void)5859854a874SSimon Glass int console_record_init(void)
5869854a874SSimon Glass {
5879854a874SSimon Glass int ret;
5889854a874SSimon Glass
5899854a874SSimon Glass ret = membuff_new(&gd->console_out, CONFIG_CONSOLE_RECORD_OUT_SIZE);
5909854a874SSimon Glass if (ret)
5919854a874SSimon Glass return ret;
5929854a874SSimon Glass ret = membuff_new(&gd->console_in, CONFIG_CONSOLE_RECORD_IN_SIZE);
5939854a874SSimon Glass
5949854a874SSimon Glass return ret;
5959854a874SSimon Glass }
5969854a874SSimon Glass
console_record_reset(void)5979854a874SSimon Glass void console_record_reset(void)
5989854a874SSimon Glass {
5999854a874SSimon Glass membuff_purge(&gd->console_out);
6009854a874SSimon Glass membuff_purge(&gd->console_in);
6019854a874SSimon Glass }
6029854a874SSimon Glass
console_record_reset_enable(void)6039854a874SSimon Glass void console_record_reset_enable(void)
6049854a874SSimon Glass {
6059854a874SSimon Glass console_record_reset();
6069854a874SSimon Glass gd->flags |= GD_FLG_RECORD;
6079854a874SSimon Glass }
6089854a874SSimon Glass #endif
6099854a874SSimon Glass
61047d1a6e1Swdenk /* test if ctrl-c was pressed */
61147d1a6e1Swdenk static int ctrlc_disabled = 0; /* see disable_ctrl() */
61247d1a6e1Swdenk static int ctrlc_was_pressed = 0;
ctrlc(void)61347d1a6e1Swdenk int ctrlc(void)
61447d1a6e1Swdenk {
61547d1a6e1Swdenk if (!ctrlc_disabled && gd->have_console) {
61647d1a6e1Swdenk if (tstc()) {
61747d1a6e1Swdenk switch (getc()) {
61847d1a6e1Swdenk case 0x03: /* ^C - Control C */
61947d1a6e1Swdenk ctrlc_was_pressed = 1;
62047d1a6e1Swdenk return 1;
62147d1a6e1Swdenk default:
62247d1a6e1Swdenk break;
62347d1a6e1Swdenk }
62447d1a6e1Swdenk }
62547d1a6e1Swdenk }
6268969ea3eSSimon Glass
62747d1a6e1Swdenk return 0;
62847d1a6e1Swdenk }
629a5dffa4bSPierre Aubert /* Reads user's confirmation.
630a5dffa4bSPierre Aubert Returns 1 if user's input is "y", "Y", "yes" or "YES"
631a5dffa4bSPierre Aubert */
confirm_yesno(void)632a5dffa4bSPierre Aubert int confirm_yesno(void)
633a5dffa4bSPierre Aubert {
634a5dffa4bSPierre Aubert int i;
635a5dffa4bSPierre Aubert char str_input[5];
63647d1a6e1Swdenk
637a5dffa4bSPierre Aubert /* Flush input */
638a5dffa4bSPierre Aubert while (tstc())
639a5dffa4bSPierre Aubert getc();
640a5dffa4bSPierre Aubert i = 0;
641a5dffa4bSPierre Aubert while (i < sizeof(str_input)) {
642a5dffa4bSPierre Aubert str_input[i] = getc();
643a5dffa4bSPierre Aubert putc(str_input[i]);
644a5dffa4bSPierre Aubert if (str_input[i] == '\r')
645a5dffa4bSPierre Aubert break;
646a5dffa4bSPierre Aubert i++;
647a5dffa4bSPierre Aubert }
648a5dffa4bSPierre Aubert putc('\n');
649a5dffa4bSPierre Aubert if (strncmp(str_input, "y\r", 2) == 0 ||
650a5dffa4bSPierre Aubert strncmp(str_input, "Y\r", 2) == 0 ||
651a5dffa4bSPierre Aubert strncmp(str_input, "yes\r", 4) == 0 ||
652a5dffa4bSPierre Aubert strncmp(str_input, "YES\r", 4) == 0)
653a5dffa4bSPierre Aubert return 1;
654a5dffa4bSPierre Aubert return 0;
655a5dffa4bSPierre Aubert }
65647d1a6e1Swdenk /* pass 1 to disable ctrlc() checking, 0 to enable.
65747d1a6e1Swdenk * returns previous state
65847d1a6e1Swdenk */
disable_ctrlc(int disable)65947d1a6e1Swdenk int disable_ctrlc(int disable)
66047d1a6e1Swdenk {
66147d1a6e1Swdenk int prev = ctrlc_disabled; /* save previous state */
66247d1a6e1Swdenk
66347d1a6e1Swdenk ctrlc_disabled = disable;
66447d1a6e1Swdenk return prev;
66547d1a6e1Swdenk }
66647d1a6e1Swdenk
had_ctrlc(void)66747d1a6e1Swdenk int had_ctrlc (void)
66847d1a6e1Swdenk {
66947d1a6e1Swdenk return ctrlc_was_pressed;
67047d1a6e1Swdenk }
67147d1a6e1Swdenk
clear_ctrlc(void)67247d1a6e1Swdenk void clear_ctrlc(void)
67347d1a6e1Swdenk {
67447d1a6e1Swdenk ctrlc_was_pressed = 0;
67547d1a6e1Swdenk }
67647d1a6e1Swdenk
67747d1a6e1Swdenk /** U-Boot INIT FUNCTIONS *************************************************/
67847d1a6e1Swdenk
search_device(int flags,const char * name)679d7be3056SMike Frysinger struct stdio_dev *search_device(int flags, const char *name)
680c1de7a6dSJean-Christophe PLAGNIOL-VILLARD {
68152cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *dev;
682c1de7a6dSJean-Christophe PLAGNIOL-VILLARD
68352cb4d4fSJean-Christophe PLAGNIOL-VILLARD dev = stdio_get_by_name(name);
684a2931b30SSimon Glass #ifdef CONFIG_VIDCONSOLE_AS_LCD
685a2931b30SSimon Glass if (!dev && !strcmp(name, "lcd"))
686a2931b30SSimon Glass dev = stdio_get_by_name("vidconsole");
687a2931b30SSimon Glass #endif
688c1de7a6dSJean-Christophe PLAGNIOL-VILLARD
689c1de7a6dSJean-Christophe PLAGNIOL-VILLARD if (dev && (dev->flags & flags))
690c1de7a6dSJean-Christophe PLAGNIOL-VILLARD return dev;
691c1de7a6dSJean-Christophe PLAGNIOL-VILLARD
692c1de7a6dSJean-Christophe PLAGNIOL-VILLARD return NULL;
693c1de7a6dSJean-Christophe PLAGNIOL-VILLARD }
694c1de7a6dSJean-Christophe PLAGNIOL-VILLARD
console_assign(int file,const char * devname)695d7be3056SMike Frysinger int console_assign(int file, const char *devname)
69647d1a6e1Swdenk {
697c1de7a6dSJean-Christophe PLAGNIOL-VILLARD int flag;
69852cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *dev;
69947d1a6e1Swdenk
70047d1a6e1Swdenk /* Check for valid file */
70147d1a6e1Swdenk switch (file) {
70247d1a6e1Swdenk case stdin:
70347d1a6e1Swdenk flag = DEV_FLAGS_INPUT;
70447d1a6e1Swdenk break;
70547d1a6e1Swdenk case stdout:
70647d1a6e1Swdenk case stderr:
70747d1a6e1Swdenk flag = DEV_FLAGS_OUTPUT;
70847d1a6e1Swdenk break;
70947d1a6e1Swdenk default:
71047d1a6e1Swdenk return -1;
71147d1a6e1Swdenk }
71247d1a6e1Swdenk
71347d1a6e1Swdenk /* Check for valid device name */
71447d1a6e1Swdenk
715c1de7a6dSJean-Christophe PLAGNIOL-VILLARD dev = search_device(flag, devname);
71647d1a6e1Swdenk
717c1de7a6dSJean-Christophe PLAGNIOL-VILLARD if (dev)
71847d1a6e1Swdenk return console_setfile(file, dev);
71947d1a6e1Swdenk
72047d1a6e1Swdenk return -1;
72147d1a6e1Swdenk }
72247d1a6e1Swdenk
console_update_silent(void)72343e0a3deSChris Packham static void console_update_silent(void)
72443e0a3deSChris Packham {
72543e0a3deSChris Packham #ifdef CONFIG_SILENT_CONSOLE
72600caae6dSSimon Glass if (env_get("silent") != NULL)
72743e0a3deSChris Packham gd->flags |= GD_FLG_SILENT;
72843e0a3deSChris Packham else
72943e0a3deSChris Packham gd->flags &= ~GD_FLG_SILENT;
73043e0a3deSChris Packham #endif
73143e0a3deSChris Packham }
73243e0a3deSChris Packham
console_announce_r(void)733b0895384SSimon Glass int console_announce_r(void)
734b0895384SSimon Glass {
735b0895384SSimon Glass #if !CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
736b0895384SSimon Glass char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
737b0895384SSimon Glass
738b0895384SSimon Glass display_options_get_banner(false, buf, sizeof(buf));
739b0895384SSimon Glass
740b0895384SSimon Glass console_puts_noserial(stdout, buf);
741b0895384SSimon Glass #endif
742b0895384SSimon Glass
743b0895384SSimon Glass return 0;
744b0895384SSimon Glass }
745b0895384SSimon Glass
74647d1a6e1Swdenk /* Called before relocation - use serial functions */
console_init_f(void)74747d1a6e1Swdenk int console_init_f(void)
74847d1a6e1Swdenk {
74947d1a6e1Swdenk gd->have_console = 1;
750f72da340Swdenk
75143e0a3deSChris Packham console_update_silent();
752f72da340Swdenk
75327669667SSiarhei Siamashka print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL);
7549558b48aSGraeme Russ
755ec6f1499SJean-Christophe PLAGNIOL-VILLARD return 0;
75647d1a6e1Swdenk }
75747d1a6e1Swdenk
stdio_print_current_devices(void)7587e3be7cfSJean-Christophe PLAGNIOL-VILLARD void stdio_print_current_devices(void)
7597e3be7cfSJean-Christophe PLAGNIOL-VILLARD {
7607e3be7cfSJean-Christophe PLAGNIOL-VILLARD /* Print information */
7617e3be7cfSJean-Christophe PLAGNIOL-VILLARD puts("In: ");
7627e3be7cfSJean-Christophe PLAGNIOL-VILLARD if (stdio_devices[stdin] == NULL) {
7637e3be7cfSJean-Christophe PLAGNIOL-VILLARD puts("No input devices available!\n");
7647e3be7cfSJean-Christophe PLAGNIOL-VILLARD } else {
7657e3be7cfSJean-Christophe PLAGNIOL-VILLARD printf ("%s\n", stdio_devices[stdin]->name);
7667e3be7cfSJean-Christophe PLAGNIOL-VILLARD }
7677e3be7cfSJean-Christophe PLAGNIOL-VILLARD
7687e3be7cfSJean-Christophe PLAGNIOL-VILLARD puts("Out: ");
7697e3be7cfSJean-Christophe PLAGNIOL-VILLARD if (stdio_devices[stdout] == NULL) {
7707e3be7cfSJean-Christophe PLAGNIOL-VILLARD puts("No output devices available!\n");
7717e3be7cfSJean-Christophe PLAGNIOL-VILLARD } else {
7727e3be7cfSJean-Christophe PLAGNIOL-VILLARD printf ("%s\n", stdio_devices[stdout]->name);
7737e3be7cfSJean-Christophe PLAGNIOL-VILLARD }
7747e3be7cfSJean-Christophe PLAGNIOL-VILLARD
7757e3be7cfSJean-Christophe PLAGNIOL-VILLARD puts("Err: ");
7767e3be7cfSJean-Christophe PLAGNIOL-VILLARD if (stdio_devices[stderr] == NULL) {
7777e3be7cfSJean-Christophe PLAGNIOL-VILLARD puts("No error devices available!\n");
7787e3be7cfSJean-Christophe PLAGNIOL-VILLARD } else {
7797e3be7cfSJean-Christophe PLAGNIOL-VILLARD printf ("%s\n", stdio_devices[stderr]->name);
7807e3be7cfSJean-Christophe PLAGNIOL-VILLARD }
7817e3be7cfSJean-Christophe PLAGNIOL-VILLARD }
7827e3be7cfSJean-Christophe PLAGNIOL-VILLARD
783b0265429SSimon Glass #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
78447d1a6e1Swdenk /* Called after the relocation - use desired console functions */
console_init_r(void)78547d1a6e1Swdenk int console_init_r(void)
78647d1a6e1Swdenk {
78747d1a6e1Swdenk char *stdinname, *stdoutname, *stderrname;
78852cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
7896d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
7906e592385Swdenk int i;
7916d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
792b0265429SSimon Glass #if CONFIG_IS_ENABLED(CONSOLE_MUX)
79316a28ef2SGary Jennejohn int iomux_err = 0;
79416a28ef2SGary Jennejohn #endif
79547d1a6e1Swdenk
79647d1a6e1Swdenk /* set default handlers at first */
79749cad547SMartin Dorwig gd->jt->getc = serial_getc;
79849cad547SMartin Dorwig gd->jt->tstc = serial_tstc;
79949cad547SMartin Dorwig gd->jt->putc = serial_putc;
80049cad547SMartin Dorwig gd->jt->puts = serial_puts;
80149cad547SMartin Dorwig gd->jt->printf = serial_printf;
80247d1a6e1Swdenk
80347d1a6e1Swdenk /* stdin stdout and stderr are in environment */
80447d1a6e1Swdenk /* scan for it */
80500caae6dSSimon Glass stdinname = env_get("stdin");
80600caae6dSSimon Glass stdoutname = env_get("stdout");
80700caae6dSSimon Glass stderrname = env_get("stderr");
80847d1a6e1Swdenk
80983e40ba7Swdenk if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */
81047d1a6e1Swdenk inputdev = search_device(DEV_FLAGS_INPUT, stdinname);
81147d1a6e1Swdenk outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname);
81247d1a6e1Swdenk errdev = search_device(DEV_FLAGS_OUTPUT, stderrname);
813b0265429SSimon Glass #if CONFIG_IS_ENABLED(CONSOLE_MUX)
81416a28ef2SGary Jennejohn iomux_err = iomux_doenv(stdin, stdinname);
81516a28ef2SGary Jennejohn iomux_err += iomux_doenv(stdout, stdoutname);
81616a28ef2SGary Jennejohn iomux_err += iomux_doenv(stderr, stderrname);
81716a28ef2SGary Jennejohn if (!iomux_err)
81816a28ef2SGary Jennejohn /* Successful, so skip all the code below. */
81916a28ef2SGary Jennejohn goto done;
82016a28ef2SGary Jennejohn #endif
82147d1a6e1Swdenk }
82247d1a6e1Swdenk /* if the devices are overwritten or not found, use default device */
82347d1a6e1Swdenk if (inputdev == NULL) {
82447d1a6e1Swdenk inputdev = search_device(DEV_FLAGS_INPUT, "serial");
82547d1a6e1Swdenk }
82647d1a6e1Swdenk if (outputdev == NULL) {
82747d1a6e1Swdenk outputdev = search_device(DEV_FLAGS_OUTPUT, "serial");
82847d1a6e1Swdenk }
82947d1a6e1Swdenk if (errdev == NULL) {
83047d1a6e1Swdenk errdev = search_device(DEV_FLAGS_OUTPUT, "serial");
83147d1a6e1Swdenk }
83247d1a6e1Swdenk /* Initializes output console first */
83347d1a6e1Swdenk if (outputdev != NULL) {
83416a28ef2SGary Jennejohn /* need to set a console if not done above. */
8355f032010SJean-Christophe PLAGNIOL-VILLARD console_doenv(stdout, outputdev);
83647d1a6e1Swdenk }
83747d1a6e1Swdenk if (errdev != NULL) {
83816a28ef2SGary Jennejohn /* need to set a console if not done above. */
8395f032010SJean-Christophe PLAGNIOL-VILLARD console_doenv(stderr, errdev);
84047d1a6e1Swdenk }
84147d1a6e1Swdenk if (inputdev != NULL) {
84216a28ef2SGary Jennejohn /* need to set a console if not done above. */
8435f032010SJean-Christophe PLAGNIOL-VILLARD console_doenv(stdin, inputdev);
84447d1a6e1Swdenk }
84547d1a6e1Swdenk
846b0265429SSimon Glass #if CONFIG_IS_ENABLED(CONSOLE_MUX)
84716a28ef2SGary Jennejohn done:
84816a28ef2SGary Jennejohn #endif
84916a28ef2SGary Jennejohn
85078c112c9SSimon Glass #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
8517e3be7cfSJean-Christophe PLAGNIOL-VILLARD stdio_print_current_devices();
85278c112c9SSimon Glass #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
853a2931b30SSimon Glass #ifdef CONFIG_VIDCONSOLE_AS_LCD
854a2931b30SSimon Glass if (strstr(stdoutname, "lcd"))
855a2931b30SSimon Glass printf("Warning: Please change 'lcd' to 'vidconsole' in stdout/stderr environment vars\n");
856a2931b30SSimon Glass #endif
85747d1a6e1Swdenk
8586d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
85947d1a6e1Swdenk /* set the environment variables (will overwrite previous env settings) */
86027b4225bSTom Rini for (i = 0; i < MAX_FILES; i++) {
861382bee57SSimon Glass env_set(stdio_names[i], stdio_devices[i]->name);
86247d1a6e1Swdenk }
8636d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
86447d1a6e1Swdenk
865c4e0057fSJoe Hershberger gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
866c4e0057fSJoe Hershberger
86747d1a6e1Swdenk #if 0
86847d1a6e1Swdenk /* If nothing usable installed, use only the initial console */
86947d1a6e1Swdenk if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
870ec6f1499SJean-Christophe PLAGNIOL-VILLARD return 0;
87147d1a6e1Swdenk #endif
87227669667SSiarhei Siamashka print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL);
873ec6f1499SJean-Christophe PLAGNIOL-VILLARD return 0;
87447d1a6e1Swdenk }
87547d1a6e1Swdenk
876b0265429SSimon Glass #else /* !CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
87747d1a6e1Swdenk
87847d1a6e1Swdenk /* Called after the relocation - use desired console functions */
console_init_r(void)87947d1a6e1Swdenk int console_init_r(void)
88047d1a6e1Swdenk {
88152cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *inputdev = NULL, *outputdev = NULL;
882c1de7a6dSJean-Christophe PLAGNIOL-VILLARD int i;
88352cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct list_head *list = stdio_get_list();
884c1de7a6dSJean-Christophe PLAGNIOL-VILLARD struct list_head *pos;
88552cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *dev;
88647d1a6e1Swdenk
88743e0a3deSChris Packham console_update_silent();
88843e0a3deSChris Packham
889d791b1dcSwdenk #ifdef CONFIG_SPLASH_SCREEN
890ec6f1499SJean-Christophe PLAGNIOL-VILLARD /*
891ec6f1499SJean-Christophe PLAGNIOL-VILLARD * suppress all output if splash screen is enabled and we have
892a7490816SAnatolij Gustschin * a bmp to display. We redirect the output from frame buffer
893a7490816SAnatolij Gustschin * console to serial console in this case or suppress it if
894a7490816SAnatolij Gustschin * "silent" mode was requested.
895ec6f1499SJean-Christophe PLAGNIOL-VILLARD */
89600caae6dSSimon Glass if (env_get("splashimage") != NULL) {
897a7490816SAnatolij Gustschin if (!(gd->flags & GD_FLG_SILENT))
898a7490816SAnatolij Gustschin outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
899a7490816SAnatolij Gustschin }
900f72da340Swdenk #endif
901f72da340Swdenk
90247d1a6e1Swdenk /* Scan devices looking for input and output devices */
903c1de7a6dSJean-Christophe PLAGNIOL-VILLARD list_for_each(pos, list) {
90452cb4d4fSJean-Christophe PLAGNIOL-VILLARD dev = list_entry(pos, struct stdio_dev, list);
90547d1a6e1Swdenk
90647d1a6e1Swdenk if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
90747d1a6e1Swdenk inputdev = dev;
90847d1a6e1Swdenk }
90947d1a6e1Swdenk if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
91047d1a6e1Swdenk outputdev = dev;
91147d1a6e1Swdenk }
912c1de7a6dSJean-Christophe PLAGNIOL-VILLARD if(inputdev && outputdev)
913c1de7a6dSJean-Christophe PLAGNIOL-VILLARD break;
91447d1a6e1Swdenk }
91547d1a6e1Swdenk
91647d1a6e1Swdenk /* Initializes output console first */
91747d1a6e1Swdenk if (outputdev != NULL) {
91847d1a6e1Swdenk console_setfile(stdout, outputdev);
91947d1a6e1Swdenk console_setfile(stderr, outputdev);
920b0265429SSimon Glass #if CONFIG_IS_ENABLED(CONSOLE_MUX)
92116a28ef2SGary Jennejohn console_devices[stdout][0] = outputdev;
92216a28ef2SGary Jennejohn console_devices[stderr][0] = outputdev;
92316a28ef2SGary Jennejohn #endif
92447d1a6e1Swdenk }
92547d1a6e1Swdenk
92647d1a6e1Swdenk /* Initializes input console */
92747d1a6e1Swdenk if (inputdev != NULL) {
92847d1a6e1Swdenk console_setfile(stdin, inputdev);
929b0265429SSimon Glass #if CONFIG_IS_ENABLED(CONSOLE_MUX)
93016a28ef2SGary Jennejohn console_devices[stdin][0] = inputdev;
93116a28ef2SGary Jennejohn #endif
93247d1a6e1Swdenk }
93347d1a6e1Swdenk
93478c112c9SSimon Glass #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
9357e3be7cfSJean-Christophe PLAGNIOL-VILLARD stdio_print_current_devices();
93678c112c9SSimon Glass #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
93747d1a6e1Swdenk
93847d1a6e1Swdenk /* Setting environment variables */
93927b4225bSTom Rini for (i = 0; i < MAX_FILES; i++) {
940382bee57SSimon Glass env_set(stdio_names[i], stdio_devices[i]->name);
94147d1a6e1Swdenk }
94247d1a6e1Swdenk
943c4e0057fSJoe Hershberger gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
944c4e0057fSJoe Hershberger
94547d1a6e1Swdenk #if 0
94647d1a6e1Swdenk /* If nothing usable installed, use only the initial console */
94747d1a6e1Swdenk if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
948ec6f1499SJean-Christophe PLAGNIOL-VILLARD return 0;
94947d1a6e1Swdenk #endif
95027669667SSiarhei Siamashka print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL);
951ec6f1499SJean-Christophe PLAGNIOL-VILLARD return 0;
95247d1a6e1Swdenk }
95347d1a6e1Swdenk
954b0265429SSimon Glass #endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
955