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