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