• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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