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