]> git.ipfire.org Git - people/ms/u-boot.git/blame - common/console.c
Merge branch 'master' of git://git.denx.de/u-boot-fdt
[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>
482f4691 10#include <iomux.h>
47d1a6e1 11#include <malloc.h>
91b136c7 12#include <os.h>
849d5d9c 13#include <serial.h>
52cb4d4f 14#include <stdio_dev.h>
27b207fd 15#include <exports.h>
849d5d9c 16#include <environment.h>
47d1a6e1 17
d87080b7
WD
18DECLARE_GLOBAL_DATA_PTR;
19
849d5d9c
JH
20static 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}
60U_BOOT_ENV_CALLBACK(console, on_console);
61
e080d545
JH
62#ifdef CONFIG_SILENT_CONSOLE
63static 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}
82U_BOOT_ENV_CALLBACK(silent, on_silent);
83#endif
84
6d0f6bcf 85#ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
47d1a6e1
WD
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 */
6d0f6bcf 91#ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
ec6f1499
JCPV
92extern int overwrite_console(void);
93#define OVERWRITE_CONSOLE overwrite_console()
47d1a6e1 94#else
83e40ba7 95#define OVERWRITE_CONSOLE 0
6d0f6bcf 96#endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
47d1a6e1 97
6d0f6bcf 98#endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
47d1a6e1 99
52cb4d4f 100static int console_setfile(int file, struct stdio_dev * dev)
47d1a6e1
WD
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) {
709ea543 113 error = dev->start(dev);
47d1a6e1
WD
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:
49cad547
MD
128 gd->jt->getc = getc;
129 gd->jt->tstc = tstc;
47d1a6e1
WD
130 break;
131 case stdout:
49cad547
MD
132 gd->jt->putc = putc;
133 gd->jt->puts = puts;
134 gd->jt->printf = printf;
47d1a6e1
WD
135 break;
136 }
137 break;
138
139 default: /* Invalid file ID */
140 error = -1;
141 }
142 return error;
143}
144
16a28ef2
GJ
145#if defined(CONFIG_CONSOLE_MUX)
146/** Console I/O multiplexing *******************************************/
147
52cb4d4f
JCPV
148static struct stdio_dev *tstcdev;
149struct stdio_dev **console_devices[MAX_FILES];
16a28ef2
GJ
150int 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 */
5f032010 158static int console_getc(int file)
16a28ef2
GJ
159{
160 unsigned char ret;
161
162 /* This is never called with testcdev == NULL */
709ea543 163 ret = tstcdev->getc(tstcdev);
16a28ef2
GJ
164 tstcdev = NULL;
165 return ret;
166}
167
5f032010 168static int console_tstc(int file)
16a28ef2
GJ
169{
170 int i, ret;
52cb4d4f 171 struct stdio_dev *dev;
16a28ef2
GJ
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) {
709ea543 177 ret = dev->tstc(dev);
16a28ef2
GJ
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
5f032010 190static void console_putc(int file, const char c)
16a28ef2
GJ
191{
192 int i;
52cb4d4f 193 struct stdio_dev *dev;
16a28ef2
GJ
194
195 for (i = 0; i < cd_count[file]; i++) {
196 dev = console_devices[file][i];
197 if (dev->putc != NULL)
709ea543 198 dev->putc(dev, c);
16a28ef2
GJ
199 }
200}
201
27669667
SS
202#ifdef CONFIG_PRE_CONSOLE_BUFFER
203static void console_putc_noserial(int file, const char c)
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->putc != NULL && strcmp(dev->name, "serial") != 0)
211 dev->putc(dev, c);
212 }
213}
214#endif
215
5f032010 216static void console_puts(int file, const char *s)
16a28ef2
GJ
217{
218 int i;
52cb4d4f 219 struct stdio_dev *dev;
16a28ef2
GJ
220
221 for (i = 0; i < cd_count[file]; i++) {
222 dev = console_devices[file][i];
223 if (dev->puts != NULL)
709ea543 224 dev->puts(dev, s);
16a28ef2
GJ
225 }
226}
5f032010
JCPV
227
228static inline void console_printdevs(int file)
229{
230 iomux_printdevs(file);
231}
232
52cb4d4f 233static inline void console_doenv(int file, struct stdio_dev *dev)
5f032010
JCPV
234{
235 iomux_doenv(file, dev->name);
236}
237#else
238static inline int console_getc(int file)
239{
709ea543 240 return stdio_devices[file]->getc(stdio_devices[file]);
5f032010
JCPV
241}
242
243static inline int console_tstc(int file)
244{
709ea543 245 return stdio_devices[file]->tstc(stdio_devices[file]);
5f032010
JCPV
246}
247
248static inline void console_putc(int file, const char c)
249{
709ea543 250 stdio_devices[file]->putc(stdio_devices[file], c);
5f032010
JCPV
251}
252
27669667
SS
253#ifdef CONFIG_PRE_CONSOLE_BUFFER
254static inline void console_putc_noserial(int file, const char c)
255{
256 if (strcmp(stdio_devices[file]->name, "serial") != 0)
257 stdio_devices[file]->putc(stdio_devices[file], c);
258}
259#endif
260
5f032010
JCPV
261static inline void console_puts(int file, const char *s)
262{
709ea543 263 stdio_devices[file]->puts(stdio_devices[file], s);
5f032010
JCPV
264}
265
266static inline void console_printdevs(int file)
267{
268 printf("%s\n", stdio_devices[file]->name);
269}
270
52cb4d4f 271static inline void console_doenv(int file, struct stdio_dev *dev)
5f032010
JCPV
272{
273 console_setfile(file, dev);
274}
16a28ef2
GJ
275#endif /* defined(CONFIG_CONSOLE_MUX) */
276
47d1a6e1
WD
277/** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
278
d9c27253 279int serial_printf(const char *fmt, ...)
47d1a6e1
WD
280{
281 va_list args;
282 uint i;
6d0f6bcf 283 char printbuffer[CONFIG_SYS_PBSIZE];
47d1a6e1 284
ec6f1499 285 va_start(args, fmt);
47d1a6e1
WD
286
287 /* For this to work, printbuffer must be larger than
288 * anything we ever want to print.
289 */
068af6f8 290 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
ec6f1499 291 va_end(args);
47d1a6e1 292
ec6f1499 293 serial_puts(printbuffer);
d9c27253 294 return i;
47d1a6e1
WD
295}
296
ec6f1499 297int fgetc(int file)
47d1a6e1 298{
16a28ef2
GJ
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)
5f032010
JCPV
310 return console_getc(file);
311 console_tstc(file);
16a28ef2
GJ
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
5f032010 321 return console_getc(file);
16a28ef2
GJ
322#endif
323 }
47d1a6e1
WD
324
325 return -1;
326}
327
ec6f1499 328int ftstc(int file)
47d1a6e1
WD
329{
330 if (file < MAX_FILES)
5f032010 331 return console_tstc(file);
47d1a6e1
WD
332
333 return -1;
334}
335
ec6f1499 336void fputc(int file, const char c)
47d1a6e1
WD
337{
338 if (file < MAX_FILES)
5f032010 339 console_putc(file, c);
47d1a6e1
WD
340}
341
ec6f1499 342void fputs(int file, const char *s)
47d1a6e1
WD
343{
344 if (file < MAX_FILES)
5f032010 345 console_puts(file, s);
47d1a6e1
WD
346}
347
d9c27253 348int fprintf(int file, const char *fmt, ...)
47d1a6e1
WD
349{
350 va_list args;
351 uint i;
6d0f6bcf 352 char printbuffer[CONFIG_SYS_PBSIZE];
47d1a6e1 353
ec6f1499 354 va_start(args, fmt);
47d1a6e1
WD
355
356 /* For this to work, printbuffer must be larger than
357 * anything we ever want to print.
358 */
068af6f8 359 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
ec6f1499 360 va_end(args);
47d1a6e1
WD
361
362 /* Send to desired file */
ec6f1499 363 fputs(file, printbuffer);
d9c27253 364 return i;
47d1a6e1
WD
365}
366
367/** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
368
ec6f1499 369int getc(void)
47d1a6e1 370{
f5c3ba79
MJ
371#ifdef CONFIG_DISABLE_CONSOLE
372 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
373 return 0;
374#endif
375
e3e454cd
GR
376 if (!gd->have_console)
377 return 0;
378
47d1a6e1
WD
379 if (gd->flags & GD_FLG_DEVINIT) {
380 /* Get from the standard input */
ec6f1499 381 return fgetc(stdin);
47d1a6e1
WD
382 }
383
384 /* Send directly to the handler */
ec6f1499 385 return serial_getc();
47d1a6e1
WD
386}
387
ec6f1499 388int tstc(void)
47d1a6e1 389{
f5c3ba79
MJ
390#ifdef CONFIG_DISABLE_CONSOLE
391 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
392 return 0;
393#endif
394
e3e454cd
GR
395 if (!gd->have_console)
396 return 0;
397
47d1a6e1
WD
398 if (gd->flags & GD_FLG_DEVINIT) {
399 /* Test the standard input */
ec6f1499 400 return ftstc(stdin);
47d1a6e1
WD
401 }
402
403 /* Send directly to the handler */
ec6f1499 404 return serial_tstc();
47d1a6e1
WD
405}
406
27669667
SS
407#define PRE_CONSOLE_FLUSHPOINT1_SERIAL 0
408#define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL 1
409
3fa4977a 410#ifdef CONFIG_PRE_CONSOLE_BUFFER
9558b48a
GR
411#define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ)
412
413static 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
420static void pre_console_puts(const char *s)
421{
422 while (*s)
423 pre_console_putc(*s++);
424}
425
27669667 426static void print_pre_console_buffer(int flushpoint)
9558b48a
GR
427{
428 unsigned long i = 0;
429 char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
430
431 if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ)
432 i = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
433
434 while (i < gd->precon_buf_idx)
27669667
SS
435 switch (flushpoint) {
436 case PRE_CONSOLE_FLUSHPOINT1_SERIAL:
437 putc(buffer[CIRC_BUF_IDX(i++)]);
438 break;
439 case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL:
440 console_putc_noserial(stdout,
441 buffer[CIRC_BUF_IDX(i++)]);
442 break;
443 }
9558b48a
GR
444}
445#else
446static inline void pre_console_putc(const char c) {}
447static inline void pre_console_puts(const char *s) {}
27669667 448static inline void print_pre_console_buffer(int flushpoint) {}
9558b48a
GR
449#endif
450
ec6f1499 451void putc(const char c)
47d1a6e1 452{
91b136c7 453#ifdef CONFIG_SANDBOX
093f79ab 454 if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
91b136c7
SG
455 os_putc(c);
456 return;
457 }
458#endif
a6cccaea
WD
459#ifdef CONFIG_SILENT_CONSOLE
460 if (gd->flags & GD_FLG_SILENT)
f6e20fc6 461 return;
a6cccaea
WD
462#endif
463
f5c3ba79
MJ
464#ifdef CONFIG_DISABLE_CONSOLE
465 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
466 return;
467#endif
468
e3e454cd 469 if (!gd->have_console)
9558b48a 470 return pre_console_putc(c);
e3e454cd 471
47d1a6e1
WD
472 if (gd->flags & GD_FLG_DEVINIT) {
473 /* Send to the standard output */
ec6f1499 474 fputc(stdout, c);
47d1a6e1
WD
475 } else {
476 /* Send directly to the handler */
27669667 477 pre_console_putc(c);
ec6f1499 478 serial_putc(c);
47d1a6e1
WD
479 }
480}
481
ec6f1499 482void puts(const char *s)
47d1a6e1 483{
91b136c7 484#ifdef CONFIG_SANDBOX
093f79ab 485 if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
91b136c7
SG
486 os_puts(s);
487 return;
488 }
489#endif
490
a6cccaea
WD
491#ifdef CONFIG_SILENT_CONSOLE
492 if (gd->flags & GD_FLG_SILENT)
493 return;
494#endif
495
f5c3ba79
MJ
496#ifdef CONFIG_DISABLE_CONSOLE
497 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
498 return;
499#endif
500
e3e454cd 501 if (!gd->have_console)
9558b48a 502 return pre_console_puts(s);
e3e454cd 503
47d1a6e1
WD
504 if (gd->flags & GD_FLG_DEVINIT) {
505 /* Send to the standard output */
ec6f1499 506 fputs(stdout, s);
47d1a6e1
WD
507 } else {
508 /* Send directly to the handler */
27669667 509 pre_console_puts(s);
ec6f1499 510 serial_puts(s);
47d1a6e1
WD
511 }
512}
513
d9c27253 514int printf(const char *fmt, ...)
47d1a6e1
WD
515{
516 va_list args;
517 uint i;
6d0f6bcf 518 char printbuffer[CONFIG_SYS_PBSIZE];
47d1a6e1 519
91b136c7 520#if !defined(CONFIG_SANDBOX) && !defined(CONFIG_PRE_CONSOLE_BUFFER)
e3e454cd
GR
521 if (!gd->have_console)
522 return 0;
9558b48a 523#endif
e3e454cd 524
ec6f1499 525 va_start(args, fmt);
47d1a6e1
WD
526
527 /* For this to work, printbuffer must be larger than
528 * anything we ever want to print.
529 */
068af6f8 530 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
ec6f1499 531 va_end(args);
47d1a6e1
WD
532
533 /* Print the string */
ec6f1499 534 puts(printbuffer);
d9c27253 535 return i;
47d1a6e1
WD
536}
537
d9c27253 538int vprintf(const char *fmt, va_list args)
6dd652fa
WD
539{
540 uint i;
6d0f6bcf 541 char printbuffer[CONFIG_SYS_PBSIZE];
6dd652fa 542
7793ac96 543#if defined(CONFIG_PRE_CONSOLE_BUFFER) && !defined(CONFIG_SANDBOX)
e3e454cd
GR
544 if (!gd->have_console)
545 return 0;
9558b48a 546#endif
e3e454cd 547
6dd652fa
WD
548 /* For this to work, printbuffer must be larger than
549 * anything we ever want to print.
550 */
068af6f8 551 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
6dd652fa
WD
552
553 /* Print the string */
ec6f1499 554 puts(printbuffer);
d9c27253 555 return i;
6dd652fa
WD
556}
557
47d1a6e1
WD
558/* test if ctrl-c was pressed */
559static int ctrlc_disabled = 0; /* see disable_ctrl() */
560static int ctrlc_was_pressed = 0;
ec6f1499 561int ctrlc(void)
47d1a6e1 562{
8969ea3e 563#ifndef CONFIG_SANDBOX
47d1a6e1 564 if (!ctrlc_disabled && gd->have_console) {
ec6f1499
JCPV
565 if (tstc()) {
566 switch (getc()) {
47d1a6e1
WD
567 case 0x03: /* ^C - Control C */
568 ctrlc_was_pressed = 1;
569 return 1;
570 default:
571 break;
572 }
573 }
574 }
8969ea3e
SG
575#endif
576
47d1a6e1
WD
577 return 0;
578}
a5dffa4b
PA
579/* Reads user's confirmation.
580 Returns 1 if user's input is "y", "Y", "yes" or "YES"
581*/
582int confirm_yesno(void)
583{
584 int i;
585 char str_input[5];
586
587 /* Flush input */
588 while (tstc())
589 getc();
590 i = 0;
591 while (i < sizeof(str_input)) {
592 str_input[i] = getc();
593 putc(str_input[i]);
594 if (str_input[i] == '\r')
595 break;
596 i++;
597 }
598 putc('\n');
599 if (strncmp(str_input, "y\r", 2) == 0 ||
600 strncmp(str_input, "Y\r", 2) == 0 ||
601 strncmp(str_input, "yes\r", 4) == 0 ||
602 strncmp(str_input, "YES\r", 4) == 0)
603 return 1;
604 return 0;
605}
47d1a6e1
WD
606/* pass 1 to disable ctrlc() checking, 0 to enable.
607 * returns previous state
608 */
ec6f1499 609int disable_ctrlc(int disable)
47d1a6e1
WD
610{
611 int prev = ctrlc_disabled; /* save previous state */
612
613 ctrlc_disabled = disable;
614 return prev;
615}
616
617int had_ctrlc (void)
618{
619 return ctrlc_was_pressed;
620}
621
ec6f1499 622void clear_ctrlc(void)
47d1a6e1
WD
623{
624 ctrlc_was_pressed = 0;
625}
626
627#ifdef CONFIG_MODEM_SUPPORT_DEBUG
628char screen[1024];
629char *cursor = screen;
630int once = 0;
631inline void dbg(const char *fmt, ...)
632{
633 va_list args;
634 uint i;
6d0f6bcf 635 char printbuffer[CONFIG_SYS_PBSIZE];
47d1a6e1
WD
636
637 if (!once) {
638 memset(screen, 0, sizeof(screen));
639 once++;
640 }
641
642 va_start(args, fmt);
643
644 /* For this to work, printbuffer must be larger than
645 * anything we ever want to print.
646 */
068af6f8 647 i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args);
47d1a6e1
WD
648 va_end(args);
649
ec6f1499
JCPV
650 if ((screen + sizeof(screen) - 1 - cursor)
651 < strlen(printbuffer) + 1) {
47d1a6e1
WD
652 memset(screen, 0, sizeof(screen));
653 cursor = screen;
654 }
655 sprintf(cursor, printbuffer);
656 cursor += strlen(printbuffer);
657
658}
659#else
482f4691 660static inline void dbg(const char *fmt, ...)
47d1a6e1
WD
661{
662}
663#endif
664
665/** U-Boot INIT FUNCTIONS *************************************************/
666
d7be3056 667struct stdio_dev *search_device(int flags, const char *name)
c1de7a6d 668{
52cb4d4f 669 struct stdio_dev *dev;
c1de7a6d 670
52cb4d4f 671 dev = stdio_get_by_name(name);
c1de7a6d 672
ec6f1499 673 if (dev && (dev->flags & flags))
c1de7a6d
JCPV
674 return dev;
675
676 return NULL;
677}
678
d7be3056 679int console_assign(int file, const char *devname)
47d1a6e1 680{
c1de7a6d 681 int flag;
52cb4d4f 682 struct stdio_dev *dev;
47d1a6e1
WD
683
684 /* Check for valid file */
685 switch (file) {
686 case stdin:
687 flag = DEV_FLAGS_INPUT;
688 break;
689 case stdout:
690 case stderr:
691 flag = DEV_FLAGS_OUTPUT;
692 break;
693 default:
694 return -1;
695 }
696
697 /* Check for valid device name */
698
c1de7a6d 699 dev = search_device(flag, devname);
47d1a6e1 700
ec6f1499
JCPV
701 if (dev)
702 return console_setfile(file, dev);
47d1a6e1
WD
703
704 return -1;
705}
706
707/* Called before relocation - use serial functions */
ec6f1499 708int console_init_f(void)
47d1a6e1 709{
47d1a6e1 710 gd->have_console = 1;
f72da340
WD
711
712#ifdef CONFIG_SILENT_CONSOLE
713 if (getenv("silent") != NULL)
714 gd->flags |= GD_FLG_SILENT;
715#endif
716
27669667 717 print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL);
9558b48a 718
ec6f1499 719 return 0;
47d1a6e1
WD
720}
721
7e3be7cf
JCPV
722void stdio_print_current_devices(void)
723{
7e3be7cf
JCPV
724 /* Print information */
725 puts("In: ");
726 if (stdio_devices[stdin] == NULL) {
727 puts("No input devices available!\n");
728 } else {
729 printf ("%s\n", stdio_devices[stdin]->name);
730 }
731
732 puts("Out: ");
733 if (stdio_devices[stdout] == NULL) {
734 puts("No output devices available!\n");
735 } else {
736 printf ("%s\n", stdio_devices[stdout]->name);
737 }
738
739 puts("Err: ");
740 if (stdio_devices[stderr] == NULL) {
741 puts("No error devices available!\n");
742 } else {
743 printf ("%s\n", stdio_devices[stderr]->name);
744 }
7e3be7cf
JCPV
745}
746
6d0f6bcf 747#ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
47d1a6e1 748/* Called after the relocation - use desired console functions */
ec6f1499 749int console_init_r(void)
47d1a6e1
WD
750{
751 char *stdinname, *stdoutname, *stderrname;
52cb4d4f 752 struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
6d0f6bcf 753#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
6e592385 754 int i;
6d0f6bcf 755#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
16a28ef2
GJ
756#ifdef CONFIG_CONSOLE_MUX
757 int iomux_err = 0;
758#endif
47d1a6e1
WD
759
760 /* set default handlers at first */
49cad547
MD
761 gd->jt->getc = serial_getc;
762 gd->jt->tstc = serial_tstc;
763 gd->jt->putc = serial_putc;
764 gd->jt->puts = serial_puts;
765 gd->jt->printf = serial_printf;
47d1a6e1
WD
766
767 /* stdin stdout and stderr are in environment */
768 /* scan for it */
ec6f1499
JCPV
769 stdinname = getenv("stdin");
770 stdoutname = getenv("stdout");
771 stderrname = getenv("stderr");
47d1a6e1 772
53677ef1 773 if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */
ec6f1499
JCPV
774 inputdev = search_device(DEV_FLAGS_INPUT, stdinname);
775 outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname);
776 errdev = search_device(DEV_FLAGS_OUTPUT, stderrname);
16a28ef2
GJ
777#ifdef CONFIG_CONSOLE_MUX
778 iomux_err = iomux_doenv(stdin, stdinname);
779 iomux_err += iomux_doenv(stdout, stdoutname);
780 iomux_err += iomux_doenv(stderr, stderrname);
781 if (!iomux_err)
782 /* Successful, so skip all the code below. */
783 goto done;
784#endif
47d1a6e1
WD
785 }
786 /* if the devices are overwritten or not found, use default device */
787 if (inputdev == NULL) {
ec6f1499 788 inputdev = search_device(DEV_FLAGS_INPUT, "serial");
47d1a6e1
WD
789 }
790 if (outputdev == NULL) {
ec6f1499 791 outputdev = search_device(DEV_FLAGS_OUTPUT, "serial");
47d1a6e1
WD
792 }
793 if (errdev == NULL) {
ec6f1499 794 errdev = search_device(DEV_FLAGS_OUTPUT, "serial");
47d1a6e1
WD
795 }
796 /* Initializes output console first */
797 if (outputdev != NULL) {
16a28ef2 798 /* need to set a console if not done above. */
5f032010 799 console_doenv(stdout, outputdev);
47d1a6e1
WD
800 }
801 if (errdev != NULL) {
16a28ef2 802 /* need to set a console if not done above. */
5f032010 803 console_doenv(stderr, errdev);
47d1a6e1
WD
804 }
805 if (inputdev != NULL) {
16a28ef2 806 /* need to set a console if not done above. */
5f032010 807 console_doenv(stdin, inputdev);
47d1a6e1
WD
808 }
809
16a28ef2
GJ
810#ifdef CONFIG_CONSOLE_MUX
811done:
812#endif
813
78c112c9 814#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
7e3be7cf 815 stdio_print_current_devices();
78c112c9 816#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
47d1a6e1 817
6d0f6bcf 818#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
47d1a6e1
WD
819 /* set the environment variables (will overwrite previous env settings) */
820 for (i = 0; i < 3; i++) {
ec6f1499 821 setenv(stdio_names[i], stdio_devices[i]->name);
47d1a6e1 822 }
6d0f6bcf 823#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
47d1a6e1 824
c4e0057f
JH
825 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
826
47d1a6e1
WD
827#if 0
828 /* If nothing usable installed, use only the initial console */
829 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
ec6f1499 830 return 0;
47d1a6e1 831#endif
27669667 832 print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL);
ec6f1499 833 return 0;
47d1a6e1
WD
834}
835
6d0f6bcf 836#else /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
47d1a6e1
WD
837
838/* Called after the relocation - use desired console functions */
ec6f1499 839int console_init_r(void)
47d1a6e1 840{
52cb4d4f 841 struct stdio_dev *inputdev = NULL, *outputdev = NULL;
c1de7a6d 842 int i;
52cb4d4f 843 struct list_head *list = stdio_get_list();
c1de7a6d 844 struct list_head *pos;
52cb4d4f 845 struct stdio_dev *dev;
47d1a6e1 846
d791b1dc 847#ifdef CONFIG_SPLASH_SCREEN
ec6f1499
JCPV
848 /*
849 * suppress all output if splash screen is enabled and we have
a7490816
AG
850 * a bmp to display. We redirect the output from frame buffer
851 * console to serial console in this case or suppress it if
852 * "silent" mode was requested.
ec6f1499 853 */
a7490816
AG
854 if (getenv("splashimage") != NULL) {
855 if (!(gd->flags & GD_FLG_SILENT))
856 outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
857 }
f72da340
WD
858#endif
859
47d1a6e1 860 /* Scan devices looking for input and output devices */
c1de7a6d 861 list_for_each(pos, list) {
52cb4d4f 862 dev = list_entry(pos, struct stdio_dev, list);
47d1a6e1
WD
863
864 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
865 inputdev = dev;
866 }
867 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
868 outputdev = dev;
869 }
c1de7a6d
JCPV
870 if(inputdev && outputdev)
871 break;
47d1a6e1
WD
872 }
873
874 /* Initializes output console first */
875 if (outputdev != NULL) {
ec6f1499
JCPV
876 console_setfile(stdout, outputdev);
877 console_setfile(stderr, outputdev);
16a28ef2
GJ
878#ifdef CONFIG_CONSOLE_MUX
879 console_devices[stdout][0] = outputdev;
880 console_devices[stderr][0] = outputdev;
881#endif
47d1a6e1
WD
882 }
883
884 /* Initializes input console */
885 if (inputdev != NULL) {
ec6f1499 886 console_setfile(stdin, inputdev);
16a28ef2
GJ
887#ifdef CONFIG_CONSOLE_MUX
888 console_devices[stdin][0] = inputdev;
889#endif
47d1a6e1
WD
890 }
891
78c112c9 892#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
7e3be7cf 893 stdio_print_current_devices();
78c112c9 894#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
47d1a6e1
WD
895
896 /* Setting environment variables */
897 for (i = 0; i < 3; i++) {
ec6f1499 898 setenv(stdio_names[i], stdio_devices[i]->name);
47d1a6e1
WD
899 }
900
c4e0057f
JH
901 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
902
47d1a6e1
WD
903#if 0
904 /* If nothing usable installed, use only the initial console */
905 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
ec6f1499 906 return 0;
47d1a6e1 907#endif
27669667 908 print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL);
ec6f1499 909 return 0;
47d1a6e1
WD
910}
911
6d0f6bcf 912#endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */