console: Introduce console_start() and console_stop()
[platform/kernel/u-boot.git] / common / console.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2000
4  * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
5  */
6
7 #include <common.h>
8 #include <console.h>
9 #include <debug_uart.h>
10 #include <dm.h>
11 #include <env.h>
12 #include <stdarg.h>
13 #include <iomux.h>
14 #include <malloc.h>
15 #include <mapmem.h>
16 #include <os.h>
17 #include <serial.h>
18 #include <stdio_dev.h>
19 #include <exports.h>
20 #include <env_internal.h>
21 #include <watchdog.h>
22 #include <linux/delay.h>
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 static int on_console(const char *name, const char *value, enum env_op op,
27         int flags)
28 {
29         int console = -1;
30
31         /* Check for console redirection */
32         if (strcmp(name, "stdin") == 0)
33                 console = stdin;
34         else if (strcmp(name, "stdout") == 0)
35                 console = stdout;
36         else if (strcmp(name, "stderr") == 0)
37                 console = stderr;
38
39         /* if not actually setting a console variable, we don't care */
40         if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0)
41                 return 0;
42
43         switch (op) {
44         case env_op_create:
45         case env_op_overwrite:
46
47                 if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
48                         if (iomux_doenv(console, value))
49                                 return 1;
50                 } else {
51                         /* Try assigning specified device */
52                         if (console_assign(console, value) < 0)
53                                 return 1;
54                 }
55
56                 return 0;
57
58         case env_op_delete:
59                 if ((flags & H_FORCE) == 0)
60                         printf("Can't delete \"%s\"\n", name);
61                 return 1;
62
63         default:
64                 return 0;
65         }
66 }
67 U_BOOT_ENV_CALLBACK(console, on_console);
68
69 #ifdef CONFIG_SILENT_CONSOLE
70 static int on_silent(const char *name, const char *value, enum env_op op,
71         int flags)
72 {
73         if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET))
74                 if (flags & H_INTERACTIVE)
75                         return 0;
76
77         if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC))
78                 if ((flags & H_INTERACTIVE) == 0)
79                         return 0;
80
81         if (value != NULL)
82                 gd->flags |= GD_FLG_SILENT;
83         else
84                 gd->flags &= ~GD_FLG_SILENT;
85
86         return 0;
87 }
88 U_BOOT_ENV_CALLBACK(silent, on_silent);
89 #endif
90
91 #ifdef CONFIG_CONSOLE_RECORD
92 /* helper function: access to gd->console_out and gd->console_in */
93 static void console_record_putc(const char c)
94 {
95         if (!(gd->flags & GD_FLG_RECORD))
96                 return;
97         if  (gd->console_out.start)
98                 membuff_putbyte((struct membuff *)&gd->console_out, c);
99 }
100
101 static void console_record_puts(const char *s)
102 {
103         if (!(gd->flags & GD_FLG_RECORD))
104                 return;
105         if  (gd->console_out.start)
106                 membuff_put((struct membuff *)&gd->console_out, s, strlen(s));
107 }
108
109 static int console_record_getc(void)
110 {
111         if (!(gd->flags & GD_FLG_RECORD))
112                 return -1;
113         if (!gd->console_in.start)
114                 return -1;
115
116         return membuff_getbyte((struct membuff *)&gd->console_in);
117 }
118
119 static int console_record_tstc(void)
120 {
121         if (!(gd->flags & GD_FLG_RECORD))
122                 return 0;
123         if (gd->console_in.start) {
124                 if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1)
125                         return 1;
126         }
127         return 0;
128 }
129 #else
130 static void console_record_putc(char c)
131 {
132 }
133
134 static void console_record_puts(const char *s)
135 {
136 }
137
138 static int console_record_getc(void)
139 {
140         return -1;
141 }
142
143 static int console_record_tstc(void)
144 {
145         return 0;
146 }
147 #endif
148
149 #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
150 /*
151  * if overwrite_console returns 1, the stdin, stderr and stdout
152  * are switched to the serial port, else the settings in the
153  * environment are used
154  */
155 #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
156 extern int overwrite_console(void);
157 #define OVERWRITE_CONSOLE overwrite_console()
158 #else
159 #define OVERWRITE_CONSOLE 0
160 #endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
161
162 #endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
163
164 static int console_setfile(int file, struct stdio_dev * dev)
165 {
166         int error = 0;
167
168         if (dev == NULL)
169                 return -1;
170
171         switch (file) {
172         case stdin:
173         case stdout:
174         case stderr:
175                 error = console_start(file, dev);
176                 if (error)
177                         break;
178
179                 /* Assign the new device (leaving the existing one started) */
180                 stdio_devices[file] = dev;
181
182                 /*
183                  * Update monitor functions
184                  * (to use the console stuff by other applications)
185                  */
186                 switch (file) {
187                 case stdin:
188                         gd->jt->getc = getchar;
189                         gd->jt->tstc = tstc;
190                         break;
191                 case stdout:
192                         gd->jt->putc  = putc;
193                         gd->jt->puts  = puts;
194                         gd->jt->printf = printf;
195                         break;
196                 }
197                 break;
198
199         default:                /* Invalid file ID */
200                 error = -1;
201         }
202         return error;
203 }
204
205 /**
206  * console_dev_is_serial() - Check if a stdio device is a serial device
207  *
208  * @sdev: Device to check
209  * @return true if this device is in the serial uclass (or for pre-driver-model,
210  * whether it is called "serial".
211  */
212 static bool console_dev_is_serial(struct stdio_dev *sdev)
213 {
214         bool is_serial;
215
216         if (IS_ENABLED(CONFIG_DM_SERIAL) && (sdev->flags & DEV_FLAGS_DM)) {
217                 struct udevice *dev = sdev->priv;
218
219                 is_serial = device_get_uclass_id(dev) == UCLASS_SERIAL;
220         } else {
221                 is_serial = !strcmp(sdev->name, "serial");
222         }
223
224         return is_serial;
225 }
226
227 #if CONFIG_IS_ENABLED(CONSOLE_MUX)
228 /** Console I/O multiplexing *******************************************/
229
230 /* tstcdev: save the last stdio device with pending characters, with tstc != 0 */
231 static struct stdio_dev *tstcdev;
232 struct stdio_dev **console_devices[MAX_FILES];
233 int cd_count[MAX_FILES];
234
235 static void __maybe_unused console_devices_set(int file, struct stdio_dev *dev)
236 {
237         console_devices[file][0] = dev;
238 }
239
240 /*
241  * This depends on tstc() always being called before getchar().
242  * This is guaranteed to be true because this routine is called
243  * only from fgetc() which assures it.
244  * No attempt is made to demultiplex multiple input sources.
245  */
246 static int console_getc(int file)
247 {
248         unsigned char ret;
249
250         /* This is never called with testcdev == NULL */
251         ret = tstcdev->getc(tstcdev);
252         tstcdev = NULL;
253         return ret;
254 }
255
256 /*  Upper layer may have already called tstc(): check the saved result */
257 static bool console_has_tstc(void)
258 {
259         return !!tstcdev;
260 }
261
262 static int console_tstc(int file)
263 {
264         int i, ret;
265         struct stdio_dev *dev;
266         int prev;
267
268         prev = disable_ctrlc(1);
269         for (i = 0; i < cd_count[file]; i++) {
270                 dev = console_devices[file][i];
271                 if (dev->tstc != NULL) {
272                         ret = dev->tstc(dev);
273                         if (ret > 0) {
274                                 tstcdev = dev;
275                                 disable_ctrlc(prev);
276                                 return ret;
277                         }
278                 }
279         }
280         disable_ctrlc(prev);
281
282         return 0;
283 }
284
285 static void console_putc(int file, const char c)
286 {
287         int i;
288         struct stdio_dev *dev;
289
290         for (i = 0; i < cd_count[file]; i++) {
291                 dev = console_devices[file][i];
292                 if (dev->putc != NULL)
293                         dev->putc(dev, c);
294         }
295 }
296
297 /**
298  * console_puts_select() - Output a string to all console devices
299  *
300  * @file: File number to output to (e,g, stdout, see stdio.h)
301  * @serial_only: true to output only to serial, false to output to everything
302  *      else
303  * @s: String to output
304  */
305 static void console_puts_select(int file, bool serial_only, const char *s)
306 {
307         int i;
308         struct stdio_dev *dev;
309
310         for (i = 0; i < cd_count[file]; i++) {
311                 bool is_serial;
312
313                 dev = console_devices[file][i];
314                 is_serial = console_dev_is_serial(dev);
315                 if (dev->puts && serial_only == is_serial)
316                         dev->puts(dev, s);
317         }
318 }
319
320 void console_puts_select_stderr(bool serial_only, const char *s)
321 {
322         console_puts_select(stderr, serial_only, s);
323 }
324
325 static void console_puts(int file, const char *s)
326 {
327         int i;
328         struct stdio_dev *dev;
329
330         for (i = 0; i < cd_count[file]; i++) {
331                 dev = console_devices[file][i];
332                 if (dev->puts != NULL)
333                         dev->puts(dev, s);
334         }
335 }
336
337 #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
338 static inline void console_doenv(int file, struct stdio_dev *dev)
339 {
340         iomux_doenv(file, dev->name);
341 }
342 #endif
343 #else
344
345 static void __maybe_unused console_devices_set(int file, struct stdio_dev *dev)
346 {
347 }
348
349 static inline int console_getc(int file)
350 {
351         return stdio_devices[file]->getc(stdio_devices[file]);
352 }
353
354 static bool console_has_tstc(void)
355 {
356         return false;
357 }
358
359 static inline int console_tstc(int file)
360 {
361         return stdio_devices[file]->tstc(stdio_devices[file]);
362 }
363
364 static inline void console_putc(int file, const char c)
365 {
366         stdio_devices[file]->putc(stdio_devices[file], c);
367 }
368
369 void console_puts_select(int file, bool serial_only, const char *s)
370 {
371         if (serial_only == console_dev_is_serial(stdio_devices[file]))
372                 stdio_devices[file]->puts(stdio_devices[file], s);
373 }
374
375 static inline void console_puts(int file, const char *s)
376 {
377         stdio_devices[file]->puts(stdio_devices[file], s);
378 }
379
380 #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
381 static inline void console_doenv(int file, struct stdio_dev *dev)
382 {
383         console_setfile(file, dev);
384 }
385 #endif
386 #endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
387
388 int console_start(int file, struct stdio_dev *sdev)
389 {
390         int error;
391
392         /* Start new device */
393         if (sdev->start) {
394                 error = sdev->start(sdev);
395                 /* If it's not started don't use it */
396                 if (error < 0)
397                         return error;
398         }
399         return 0;
400 }
401
402 void console_stop(int file, struct stdio_dev *sdev)
403 {
404         if (sdev->stop)
405                 sdev->stop(sdev);
406 }
407
408 /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
409
410 int serial_printf(const char *fmt, ...)
411 {
412         va_list args;
413         uint i;
414         char printbuffer[CONFIG_SYS_PBSIZE];
415
416         va_start(args, fmt);
417
418         /* For this to work, printbuffer must be larger than
419          * anything we ever want to print.
420          */
421         i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
422         va_end(args);
423
424         serial_puts(printbuffer);
425         return i;
426 }
427
428 int fgetc(int file)
429 {
430         if (file < MAX_FILES) {
431                 /*
432                  * Effectively poll for input wherever it may be available.
433                  */
434                 for (;;) {
435                         WATCHDOG_RESET();
436                         if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
437                                 /*
438                                  * Upper layer may have already called tstc() so
439                                  * check for that first.
440                                  */
441                                 if (console_has_tstc())
442                                         return console_getc(file);
443                                 console_tstc(file);
444                         } else {
445                                 if (console_tstc(file))
446                                         return console_getc(file);
447                         }
448
449                         /*
450                          * If the watchdog must be rate-limited then it should
451                          * already be handled in board-specific code.
452                          */
453                         if (IS_ENABLED(CONFIG_WATCHDOG))
454                                 udelay(1);
455                 }
456         }
457
458         return -1;
459 }
460
461 int ftstc(int file)
462 {
463         if (file < MAX_FILES)
464                 return console_tstc(file);
465
466         return -1;
467 }
468
469 void fputc(int file, const char c)
470 {
471         if (file < MAX_FILES)
472                 console_putc(file, c);
473 }
474
475 void fputs(int file, const char *s)
476 {
477         if (file < MAX_FILES)
478                 console_puts(file, s);
479 }
480
481 int fprintf(int file, const char *fmt, ...)
482 {
483         va_list args;
484         uint i;
485         char printbuffer[CONFIG_SYS_PBSIZE];
486
487         va_start(args, fmt);
488
489         /* For this to work, printbuffer must be larger than
490          * anything we ever want to print.
491          */
492         i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
493         va_end(args);
494
495         /* Send to desired file */
496         fputs(file, printbuffer);
497         return i;
498 }
499
500 /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
501
502 int getchar(void)
503 {
504         int ch;
505
506         if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
507                 return 0;
508
509         if (!gd->have_console)
510                 return 0;
511
512         ch = console_record_getc();
513         if (ch != -1)
514                 return ch;
515
516         if (gd->flags & GD_FLG_DEVINIT) {
517                 /* Get from the standard input */
518                 return fgetc(stdin);
519         }
520
521         /* Send directly to the handler */
522         return serial_getc();
523 }
524
525 int tstc(void)
526 {
527         if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
528                 return 0;
529
530         if (!gd->have_console)
531                 return 0;
532
533         if (console_record_tstc())
534                 return 1;
535
536         if (gd->flags & GD_FLG_DEVINIT) {
537                 /* Test the standard input */
538                 return ftstc(stdin);
539         }
540
541         /* Send directly to the handler */
542         return serial_tstc();
543 }
544
545 #define PRE_CONSOLE_FLUSHPOINT1_SERIAL                  0
546 #define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL   1
547
548 #if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
549 #define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ)
550
551 static void pre_console_putc(const char c)
552 {
553         char *buffer;
554
555         buffer = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
556
557         buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c;
558
559         unmap_sysmem(buffer);
560 }
561
562 static void pre_console_puts(const char *s)
563 {
564         while (*s)
565                 pre_console_putc(*s++);
566 }
567
568 static void print_pre_console_buffer(int flushpoint)
569 {
570         unsigned long in = 0, out = 0;
571         char buf_out[CONFIG_PRE_CON_BUF_SZ + 1];
572         char *buf_in;
573
574         if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT))
575                 return;
576
577         buf_in = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
578         if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ)
579                 in = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
580
581         while (in < gd->precon_buf_idx)
582                 buf_out[out++] = buf_in[CIRC_BUF_IDX(in++)];
583         unmap_sysmem(buf_in);
584
585         buf_out[out] = 0;
586
587         switch (flushpoint) {
588         case PRE_CONSOLE_FLUSHPOINT1_SERIAL:
589                 puts(buf_out);
590                 break;
591         case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL:
592                 console_puts_select(stdout, false, buf_out);
593                 break;
594         }
595 }
596 #else
597 static inline void pre_console_putc(const char c) {}
598 static inline void pre_console_puts(const char *s) {}
599 static inline void print_pre_console_buffer(int flushpoint) {}
600 #endif
601
602 void putc(const char c)
603 {
604         if (!gd)
605                 return;
606
607         console_record_putc(c);
608
609         /* sandbox can send characters to stdout before it has a console */
610         if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) {
611                 os_putc(c);
612                 return;
613         }
614
615         /* if we don't have a console yet, use the debug UART */
616         if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) {
617                 printch(c);
618                 return;
619         }
620
621         if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) {
622                 if (!(gd->flags & GD_FLG_DEVINIT))
623                         pre_console_putc(c);
624                 return;
625         }
626
627         if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
628                 return;
629
630         if (!gd->have_console)
631                 return pre_console_putc(c);
632
633         if (gd->flags & GD_FLG_DEVINIT) {
634                 /* Send to the standard output */
635                 fputc(stdout, c);
636         } else {
637                 /* Send directly to the handler */
638                 pre_console_putc(c);
639                 serial_putc(c);
640         }
641 }
642
643 void puts(const char *s)
644 {
645         if (!gd)
646                 return;
647
648         console_record_puts(s);
649
650         /* sandbox can send characters to stdout before it has a console */
651         if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) {
652                 os_puts(s);
653                 return;
654         }
655
656         if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) {
657                 while (*s) {
658                         int ch = *s++;
659
660                         printch(ch);
661                 }
662                 return;
663         }
664
665         if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) {
666                 if (!(gd->flags & GD_FLG_DEVINIT))
667                         pre_console_puts(s);
668                 return;
669         }
670
671         if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
672                 return;
673
674         if (!gd->have_console)
675                 return pre_console_puts(s);
676
677         if (gd->flags & GD_FLG_DEVINIT) {
678                 /* Send to the standard output */
679                 fputs(stdout, s);
680         } else {
681                 /* Send directly to the handler */
682                 pre_console_puts(s);
683                 serial_puts(s);
684         }
685 }
686
687 #ifdef CONFIG_CONSOLE_RECORD
688 int console_record_init(void)
689 {
690         int ret;
691
692         ret = membuff_new((struct membuff *)&gd->console_out,
693                           CONFIG_CONSOLE_RECORD_OUT_SIZE);
694         if (ret)
695                 return ret;
696         ret = membuff_new((struct membuff *)&gd->console_in,
697                           CONFIG_CONSOLE_RECORD_IN_SIZE);
698
699         return ret;
700 }
701
702 void console_record_reset(void)
703 {
704         membuff_purge((struct membuff *)&gd->console_out);
705         membuff_purge((struct membuff *)&gd->console_in);
706 }
707
708 int console_record_reset_enable(void)
709 {
710         console_record_reset();
711         gd->flags |= GD_FLG_RECORD;
712
713         return 0;
714 }
715
716 int console_record_readline(char *str, int maxlen)
717 {
718         return membuff_readline((struct membuff *)&gd->console_out, str,
719                                 maxlen, ' ');
720 }
721
722 int console_record_avail(void)
723 {
724         return membuff_avail((struct membuff *)&gd->console_out);
725 }
726
727 #endif
728
729 /* test if ctrl-c was pressed */
730 static int ctrlc_disabled = 0;  /* see disable_ctrl() */
731 static int ctrlc_was_pressed = 0;
732 int ctrlc(void)
733 {
734         if (!ctrlc_disabled && gd->have_console) {
735                 if (tstc()) {
736                         switch (getchar()) {
737                         case 0x03:              /* ^C - Control C */
738                                 ctrlc_was_pressed = 1;
739                                 return 1;
740                         default:
741                                 break;
742                         }
743                 }
744         }
745
746         return 0;
747 }
748 /* Reads user's confirmation.
749    Returns 1 if user's input is "y", "Y", "yes" or "YES"
750 */
751 int confirm_yesno(void)
752 {
753         int i;
754         char str_input[5];
755
756         /* Flush input */
757         while (tstc())
758                 getchar();
759         i = 0;
760         while (i < sizeof(str_input)) {
761                 str_input[i] = getchar();
762                 putc(str_input[i]);
763                 if (str_input[i] == '\r')
764                         break;
765                 i++;
766         }
767         putc('\n');
768         if (strncmp(str_input, "y\r", 2) == 0 ||
769             strncmp(str_input, "Y\r", 2) == 0 ||
770             strncmp(str_input, "yes\r", 4) == 0 ||
771             strncmp(str_input, "YES\r", 4) == 0)
772                 return 1;
773         return 0;
774 }
775 /* pass 1 to disable ctrlc() checking, 0 to enable.
776  * returns previous state
777  */
778 int disable_ctrlc(int disable)
779 {
780         int prev = ctrlc_disabled;      /* save previous state */
781
782         ctrlc_disabled = disable;
783         return prev;
784 }
785
786 int had_ctrlc (void)
787 {
788         return ctrlc_was_pressed;
789 }
790
791 void clear_ctrlc(void)
792 {
793         ctrlc_was_pressed = 0;
794 }
795
796 /** U-Boot INIT FUNCTIONS *************************************************/
797
798 struct stdio_dev *search_device(int flags, const char *name)
799 {
800         struct stdio_dev *dev;
801
802         dev = stdio_get_by_name(name);
803 #ifdef CONFIG_VIDCONSOLE_AS_LCD
804         if (!dev && !strcmp(name, CONFIG_VIDCONSOLE_AS_NAME))
805                 dev = stdio_get_by_name("vidconsole");
806 #endif
807
808         if (dev && (dev->flags & flags))
809                 return dev;
810
811         return NULL;
812 }
813
814 int console_assign(int file, const char *devname)
815 {
816         int flag;
817         struct stdio_dev *dev;
818
819         /* Check for valid file */
820         switch (file) {
821         case stdin:
822                 flag = DEV_FLAGS_INPUT;
823                 break;
824         case stdout:
825         case stderr:
826                 flag = DEV_FLAGS_OUTPUT;
827                 break;
828         default:
829                 return -1;
830         }
831
832         /* Check for valid device name */
833
834         dev = search_device(flag, devname);
835
836         if (dev)
837                 return console_setfile(file, dev);
838
839         return -1;
840 }
841
842 /* return true if the 'silent' flag is removed */
843 static bool console_update_silent(void)
844 {
845         unsigned long flags = gd->flags;
846
847         if (!IS_ENABLED(CONFIG_SILENT_CONSOLE))
848                 return false;
849
850         if (env_get("silent")) {
851                 gd->flags |= GD_FLG_SILENT;
852                 return false;
853         }
854
855         gd->flags &= ~GD_FLG_SILENT;
856
857         return !!(flags & GD_FLG_SILENT);
858 }
859
860 int console_announce_r(void)
861 {
862 #if !CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
863         char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
864
865         display_options_get_banner(false, buf, sizeof(buf));
866
867         console_puts_select(stdout, false, buf);
868 #endif
869
870         return 0;
871 }
872
873 /* Called before relocation - use serial functions */
874 int console_init_f(void)
875 {
876         gd->have_console = 1;
877
878         console_update_silent();
879
880         print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL);
881
882         return 0;
883 }
884
885 void stdio_print_current_devices(void)
886 {
887         /* Print information */
888         puts("In:    ");
889         if (stdio_devices[stdin] == NULL) {
890                 puts("No input devices available!\n");
891         } else {
892                 printf ("%s\n", stdio_devices[stdin]->name);
893         }
894
895         puts("Out:   ");
896         if (stdio_devices[stdout] == NULL) {
897                 puts("No output devices available!\n");
898         } else {
899                 printf ("%s\n", stdio_devices[stdout]->name);
900         }
901
902         puts("Err:   ");
903         if (stdio_devices[stderr] == NULL) {
904                 puts("No error devices available!\n");
905         } else {
906                 printf ("%s\n", stdio_devices[stderr]->name);
907         }
908 }
909
910 #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
911 /* Called after the relocation - use desired console functions */
912 int console_init_r(void)
913 {
914         char *stdinname, *stdoutname, *stderrname;
915         struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
916         int i;
917         int iomux_err = 0;
918         int flushpoint;
919
920         /* update silent for env loaded from flash (initr_env) */
921         if (console_update_silent())
922                 flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
923         else
924                 flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
925
926         /* set default handlers at first */
927         gd->jt->getc  = serial_getc;
928         gd->jt->tstc  = serial_tstc;
929         gd->jt->putc  = serial_putc;
930         gd->jt->puts  = serial_puts;
931         gd->jt->printf = serial_printf;
932
933         /* stdin stdout and stderr are in environment */
934         /* scan for it */
935         stdinname  = env_get("stdin");
936         stdoutname = env_get("stdout");
937         stderrname = env_get("stderr");
938
939         if (OVERWRITE_CONSOLE == 0) {   /* if not overwritten by config switch */
940                 inputdev  = search_device(DEV_FLAGS_INPUT,  stdinname);
941                 outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname);
942                 errdev    = search_device(DEV_FLAGS_OUTPUT, stderrname);
943                 if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
944                         iomux_err = iomux_doenv(stdin, stdinname);
945                         iomux_err += iomux_doenv(stdout, stdoutname);
946                         iomux_err += iomux_doenv(stderr, stderrname);
947                         if (!iomux_err)
948                                 /* Successful, so skip all the code below. */
949                                 goto done;
950                 }
951         }
952         /* if the devices are overwritten or not found, use default device */
953         if (inputdev == NULL) {
954                 inputdev  = search_device(DEV_FLAGS_INPUT,  "serial");
955         }
956         if (outputdev == NULL) {
957                 outputdev = search_device(DEV_FLAGS_OUTPUT, "serial");
958         }
959         if (errdev == NULL) {
960                 errdev    = search_device(DEV_FLAGS_OUTPUT, "serial");
961         }
962         /* Initializes output console first */
963         if (outputdev != NULL) {
964                 /* need to set a console if not done above. */
965                 console_doenv(stdout, outputdev);
966         }
967         if (errdev != NULL) {
968                 /* need to set a console if not done above. */
969                 console_doenv(stderr, errdev);
970         }
971         if (inputdev != NULL) {
972                 /* need to set a console if not done above. */
973                 console_doenv(stdin, inputdev);
974         }
975
976 done:
977
978         if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET))
979                 stdio_print_current_devices();
980
981 #ifdef CONFIG_VIDCONSOLE_AS_LCD
982         if (strstr(stdoutname, CONFIG_VIDCONSOLE_AS_NAME))
983                 printf("Warning: Please change '%s' to 'vidconsole' in stdout/stderr environment vars\n",
984                        CONFIG_VIDCONSOLE_AS_NAME);
985 #endif
986
987         if (IS_ENABLED(CONFIG_SYS_CONSOLE_ENV_OVERWRITE)) {
988                 /* set the environment variables (will overwrite previous env settings) */
989                 for (i = 0; i < MAX_FILES; i++)
990                         env_set(stdio_names[i], stdio_devices[i]->name);
991         }
992
993         gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
994
995 #if 0
996         /* If nothing usable installed, use only the initial console */
997         if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
998                 return 0;
999 #endif
1000         print_pre_console_buffer(flushpoint);
1001         return 0;
1002 }
1003
1004 #else /* !CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
1005
1006 /* Called after the relocation - use desired console functions */
1007 int console_init_r(void)
1008 {
1009         struct stdio_dev *inputdev = NULL, *outputdev = NULL;
1010         int i;
1011         struct list_head *list = stdio_get_list();
1012         struct list_head *pos;
1013         struct stdio_dev *dev;
1014         int flushpoint;
1015
1016         /* update silent for env loaded from flash (initr_env) */
1017         if (console_update_silent())
1018                 flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
1019         else
1020                 flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
1021
1022         /*
1023          * suppress all output if splash screen is enabled and we have
1024          * a bmp to display. We redirect the output from frame buffer
1025          * console to serial console in this case or suppress it if
1026          * "silent" mode was requested.
1027          */
1028         if (IS_ENABLED(CONFIG_SPLASH_SCREEN) && env_get("splashimage")) {
1029                 if (!(gd->flags & GD_FLG_SILENT))
1030                         outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
1031         }
1032
1033         /* Scan devices looking for input and output devices */
1034         list_for_each(pos, list) {
1035                 dev = list_entry(pos, struct stdio_dev, list);
1036
1037                 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
1038                         inputdev = dev;
1039                 }
1040                 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
1041                         outputdev = dev;
1042                 }
1043                 if(inputdev && outputdev)
1044                         break;
1045         }
1046
1047         /* Initializes output console first */
1048         if (outputdev != NULL) {
1049                 console_setfile(stdout, outputdev);
1050                 console_setfile(stderr, outputdev);
1051                 console_devices_set(stdout, outputdev);
1052                 console_devices_set(stderr, outputdev);
1053         }
1054
1055         /* Initializes input console */
1056         if (inputdev != NULL) {
1057                 console_setfile(stdin, inputdev);
1058                 console_devices_set(stdin, inputdev);
1059         }
1060
1061         if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET))
1062                 stdio_print_current_devices();
1063
1064         /* Setting environment variables */
1065         for (i = 0; i < MAX_FILES; i++) {
1066                 env_set(stdio_names[i], stdio_devices[i]->name);
1067         }
1068
1069         gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
1070
1071 #if 0
1072         /* If nothing usable installed, use only the initial console */
1073         if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
1074                 return 0;
1075 #endif
1076         print_pre_console_buffer(flushpoint);
1077         return 0;
1078 }
1079
1080 #endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */