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