1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <common.h>
25#include <stdarg.h>
26#include <malloc.h>
27#include <stdio_dev.h>
28#include <exports.h>
29
30DECLARE_GLOBAL_DATA_PTR;
31
32#ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
33
34
35
36
37
38#ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
39extern int overwrite_console(void);
40#define OVERWRITE_CONSOLE overwrite_console()
41#else
42#define OVERWRITE_CONSOLE 0
43#endif
44
45#endif
46
47static int console_setfile(int file, struct stdio_dev * dev)
48{
49 int error = 0;
50
51 if (dev == NULL)
52 return -1;
53
54 switch (file) {
55 case stdin:
56 case stdout:
57 case stderr:
58
59 if (dev->start) {
60 error = dev->start();
61
62 if (error < 0)
63 break;
64 }
65
66
67 stdio_devices[file] = dev;
68
69
70
71
72
73 switch (file) {
74 case stdin:
75 gd->jt[XF_getc] = dev->getc;
76 gd->jt[XF_tstc] = dev->tstc;
77 break;
78 case stdout:
79 gd->jt[XF_putc] = dev->putc;
80 gd->jt[XF_puts] = dev->puts;
81 gd->jt[XF_printf] = printf;
82 break;
83 }
84 break;
85
86 default:
87 error = -1;
88 }
89 return error;
90}
91
92#if defined(CONFIG_CONSOLE_MUX)
93
94
95static struct stdio_dev *tstcdev;
96struct stdio_dev **console_devices[MAX_FILES];
97int cd_count[MAX_FILES];
98
99
100
101
102
103
104
105static int console_getc(int file)
106{
107 unsigned char ret;
108
109
110 ret = tstcdev->getc();
111 tstcdev = NULL;
112 return ret;
113}
114
115static int console_tstc(int file)
116{
117 int i, ret;
118 struct stdio_dev *dev;
119
120 disable_ctrlc(1);
121 for (i = 0; i < cd_count[file]; i++) {
122 dev = console_devices[file][i];
123 if (dev->tstc != NULL) {
124 ret = dev->tstc();
125 if (ret > 0) {
126 tstcdev = dev;
127 disable_ctrlc(0);
128 return ret;
129 }
130 }
131 }
132 disable_ctrlc(0);
133
134 return 0;
135}
136
137static void console_putc(int file, const char c)
138{
139 int i;
140 struct stdio_dev *dev;
141
142 for (i = 0; i < cd_count[file]; i++) {
143 dev = console_devices[file][i];
144 if (dev->putc != NULL)
145 dev->putc(c);
146 }
147}
148
149static void console_puts(int file, const char *s)
150{
151 int i;
152 struct stdio_dev *dev;
153
154 for (i = 0; i < cd_count[file]; i++) {
155 dev = console_devices[file][i];
156 if (dev->puts != NULL)
157 dev->puts(s);
158 }
159}
160
161static inline void console_printdevs(int file)
162{
163 iomux_printdevs(file);
164}
165
166static inline void console_doenv(int file, struct stdio_dev *dev)
167{
168 iomux_doenv(file, dev->name);
169}
170#else
171static inline int console_getc(int file)
172{
173 return stdio_devices[file]->getc();
174}
175
176static inline int console_tstc(int file)
177{
178 return stdio_devices[file]->tstc();
179}
180
181static inline void console_putc(int file, const char c)
182{
183 stdio_devices[file]->putc(c);
184}
185
186static inline void console_puts(int file, const char *s)
187{
188 stdio_devices[file]->puts(s);
189}
190
191static inline void console_printdevs(int file)
192{
193 printf("%s\n", stdio_devices[file]->name);
194}
195
196static inline void console_doenv(int file, struct stdio_dev *dev)
197{
198 console_setfile(file, dev);
199}
200#endif
201
202
203
204int serial_printf(const char *fmt, ...)
205{
206 va_list args;
207 uint i;
208 char printbuffer[CONFIG_SYS_PBSIZE];
209
210 va_start(args, fmt);
211
212
213
214
215 i = vsprintf(printbuffer, fmt, args);
216 va_end(args);
217
218 serial_puts(printbuffer);
219 return i;
220}
221
222int fgetc(int file)
223{
224 if (file < MAX_FILES) {
225#if defined(CONFIG_CONSOLE_MUX)
226
227
228
229 for (;;) {
230
231
232
233
234 if (tstcdev != NULL)
235 return console_getc(file);
236 console_tstc(file);
237#ifdef CONFIG_WATCHDOG
238
239
240
241
242 udelay(1);
243#endif
244 }
245#else
246 return console_getc(file);
247#endif
248 }
249
250 return -1;
251}
252
253int ftstc(int file)
254{
255 if (file < MAX_FILES)
256 return console_tstc(file);
257
258 return -1;
259}
260
261void fputc(int file, const char c)
262{
263 if (file < MAX_FILES)
264 console_putc(file, c);
265}
266
267void fputs(int file, const char *s)
268{
269 if (file < MAX_FILES)
270 console_puts(file, s);
271}
272
273int fprintf(int file, const char *fmt, ...)
274{
275 va_list args;
276 uint i;
277 char printbuffer[CONFIG_SYS_PBSIZE];
278
279 va_start(args, fmt);
280
281
282
283
284 i = vsprintf(printbuffer, fmt, args);
285 va_end(args);
286
287
288 fputs(file, printbuffer);
289 return i;
290}
291
292
293
294int getc(void)
295{
296#ifdef CONFIG_DISABLE_CONSOLE
297 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
298 return 0;
299#endif
300
301 if (!gd->have_console)
302 return 0;
303
304 if (gd->flags & GD_FLG_DEVINIT) {
305
306 return fgetc(stdin);
307 }
308
309
310 return serial_getc();
311}
312
313int tstc(void)
314{
315#ifdef CONFIG_DISABLE_CONSOLE
316 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
317 return 0;
318#endif
319
320 if (!gd->have_console)
321 return 0;
322
323 if (gd->flags & GD_FLG_DEVINIT) {
324
325 return ftstc(stdin);
326 }
327
328
329 return serial_tstc();
330}
331
332#if defined(CONFIG_PRE_CONSOLE_BUFFER) || defined(CONFIG_PRE_CONSOLE_PUTC)
333#define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ)
334
335static void pre_console_putc(const char c)
336{
337#ifdef CONFIG_PRE_CONSOLE_BUFFER
338 char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
339
340 buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c;
341#endif
342#ifdef CONFIG_PRE_CONSOLE_PUTC
343 board_pre_console_putc(c);
344#endif
345}
346
347static void pre_console_puts(const char *s)
348{
349 while (*s)
350 pre_console_putc(*s++);
351}
352
353static void print_pre_console_buffer(void)
354{
355#ifdef CONFIG_PRE_CONSOLE_BUFFER
356 unsigned long i = 0;
357 char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
358
359 if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ)
360 i = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
361
362 while (i < gd->precon_buf_idx)
363 putc(buffer[CIRC_BUF_IDX(i++)]);
364#endif
365}
366
367#else
368static inline void pre_console_putc(const char c) {}
369static inline void pre_console_puts(const char *s) {}
370static inline void print_pre_console_buffer(void) {}
371#endif
372
373void putc(const char c)
374{
375#ifdef CONFIG_SILENT_CONSOLE
376 if (gd->flags & GD_FLG_SILENT)
377 return;
378#endif
379
380#ifdef CONFIG_DISABLE_CONSOLE
381 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
382 return;
383#endif
384
385 if (!gd->have_console)
386 return pre_console_putc(c);
387
388 if (gd->flags & GD_FLG_DEVINIT) {
389
390 fputc(stdout, c);
391 } else {
392
393 serial_putc(c);
394 }
395}
396
397void puts(const char *s)
398{
399#ifdef CONFIG_SILENT_CONSOLE
400 if (gd->flags & GD_FLG_SILENT)
401 return;
402#endif
403
404#ifdef CONFIG_DISABLE_CONSOLE
405 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
406 return;
407#endif
408
409 if (!gd->have_console)
410 return pre_console_puts(s);
411
412 if (gd->flags & GD_FLG_DEVINIT) {
413
414 fputs(stdout, s);
415 } else {
416
417 serial_puts(s);
418 }
419}
420
421int printf(const char *fmt, ...)
422{
423 va_list args;
424 uint i;
425 char printbuffer[CONFIG_SYS_PBSIZE];
426
427#ifndef CONFIG_PRE_CONSOLE_BUFFER
428 if (!gd->have_console)
429 return 0;
430#endif
431
432 va_start(args, fmt);
433
434
435
436
437 i = vsprintf(printbuffer, fmt, args);
438 va_end(args);
439
440
441 puts(printbuffer);
442 return i;
443}
444
445int vprintf(const char *fmt, va_list args)
446{
447 uint i;
448 char printbuffer[CONFIG_SYS_PBSIZE];
449
450#ifndef CONFIG_PRE_CONSOLE_BUFFER
451 if (!gd->have_console)
452 return 0;
453#endif
454
455
456
457
458 i = vsprintf(printbuffer, fmt, args);
459
460
461 puts(printbuffer);
462 return i;
463}
464
465
466static int ctrlc_disabled = 0;
467static int ctrlc_was_pressed = 0;
468int ctrlc(void)
469{
470 if (!ctrlc_disabled && gd->have_console) {
471 if (tstc()) {
472 switch (getc()) {
473 case 0x03:
474 ctrlc_was_pressed = 1;
475 return 1;
476 default:
477 break;
478 }
479 }
480 }
481 return 0;
482}
483
484
485
486
487int disable_ctrlc(int disable)
488{
489 int prev = ctrlc_disabled;
490
491 ctrlc_disabled = disable;
492 return prev;
493}
494
495int had_ctrlc (void)
496{
497 return ctrlc_was_pressed;
498}
499
500void clear_ctrlc(void)
501{
502 ctrlc_was_pressed = 0;
503}
504
505#ifdef CONFIG_MODEM_SUPPORT_DEBUG
506char screen[1024];
507char *cursor = screen;
508int once = 0;
509inline void dbg(const char *fmt, ...)
510{
511 va_list args;
512 uint i;
513 char printbuffer[CONFIG_SYS_PBSIZE];
514
515 if (!once) {
516 memset(screen, 0, sizeof(screen));
517 once++;
518 }
519
520 va_start(args, fmt);
521
522
523
524
525 i = vsprintf(printbuffer, fmt, args);
526 va_end(args);
527
528 if ((screen + sizeof(screen) - 1 - cursor)
529 < strlen(printbuffer) + 1) {
530 memset(screen, 0, sizeof(screen));
531 cursor = screen;
532 }
533 sprintf(cursor, printbuffer);
534 cursor += strlen(printbuffer);
535
536}
537#else
538inline void dbg(const char *fmt, ...)
539{
540}
541#endif
542
543
544
545struct stdio_dev *search_device(int flags, const char *name)
546{
547 struct stdio_dev *dev;
548
549 dev = stdio_get_by_name(name);
550
551 if (dev && (dev->flags & flags))
552 return dev;
553
554 return NULL;
555}
556
557int console_assign(int file, const char *devname)
558{
559 int flag;
560 struct stdio_dev *dev;
561
562
563 switch (file) {
564 case stdin:
565 flag = DEV_FLAGS_INPUT;
566 break;
567 case stdout:
568 case stderr:
569 flag = DEV_FLAGS_OUTPUT;
570 break;
571 default:
572 return -1;
573 }
574
575
576
577 dev = search_device(flag, devname);
578
579 if (dev)
580 return console_setfile(file, dev);
581
582 return -1;
583}
584
585
586int console_init_f(void)
587{
588 gd->have_console = 1;
589
590#ifdef CONFIG_SILENT_CONSOLE
591 if (getenv("silent") != NULL)
592 gd->flags |= GD_FLG_SILENT;
593#endif
594
595 print_pre_console_buffer();
596
597 return 0;
598}
599
600void stdio_print_current_devices(void)
601{
602#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
603
604 puts("In: ");
605 if (stdio_devices[stdin] == NULL) {
606 puts("No input devices available!\n");
607 } else {
608 printf ("%s\n", stdio_devices[stdin]->name);
609 }
610
611 puts("Out: ");
612 if (stdio_devices[stdout] == NULL) {
613 puts("No output devices available!\n");
614 } else {
615 printf ("%s\n", stdio_devices[stdout]->name);
616 }
617
618 puts("Err: ");
619 if (stdio_devices[stderr] == NULL) {
620 puts("No error devices available!\n");
621 } else {
622 printf ("%s\n", stdio_devices[stderr]->name);
623 }
624#endif
625}
626
627#ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
628
629int console_init_r(void)
630{
631 char *stdinname, *stdoutname, *stderrname;
632 struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
633#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
634 int i;
635#endif
636#ifdef CONFIG_CONSOLE_MUX
637 int iomux_err = 0;
638#endif
639
640
641 gd->jt[XF_getc] = serial_getc;
642 gd->jt[XF_tstc] = serial_tstc;
643 gd->jt[XF_putc] = serial_putc;
644 gd->jt[XF_puts] = serial_puts;
645 gd->jt[XF_printf] = serial_printf;
646
647
648
649 stdinname = getenv("stdin");
650 stdoutname = getenv("stdout");
651 stderrname = getenv("stderr");
652
653 if (OVERWRITE_CONSOLE == 0) {
654 inputdev = search_device(DEV_FLAGS_INPUT, stdinname);
655 outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname);
656 errdev = search_device(DEV_FLAGS_OUTPUT, stderrname);
657#ifdef CONFIG_CONSOLE_MUX
658 iomux_err = iomux_doenv(stdin, stdinname);
659 iomux_err += iomux_doenv(stdout, stdoutname);
660 iomux_err += iomux_doenv(stderr, stderrname);
661 if (!iomux_err)
662
663 goto done;
664#endif
665 }
666
667 if (inputdev == NULL) {
668 inputdev = search_device(DEV_FLAGS_INPUT, "serial");
669 }
670 if (outputdev == NULL) {
671 outputdev = search_device(DEV_FLAGS_OUTPUT, "serial");
672 }
673 if (errdev == NULL) {
674 errdev = search_device(DEV_FLAGS_OUTPUT, "serial");
675 }
676
677 if (outputdev != NULL) {
678
679 console_doenv(stdout, outputdev);
680 }
681 if (errdev != NULL) {
682
683 console_doenv(stderr, errdev);
684 }
685 if (inputdev != NULL) {
686
687 console_doenv(stdin, inputdev);
688 }
689
690#ifdef CONFIG_CONSOLE_MUX
691done:
692#endif
693
694 gd->flags |= GD_FLG_DEVINIT;
695
696 stdio_print_current_devices();
697
698#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
699
700 for (i = 0; i < 3; i++) {
701 setenv(stdio_names[i], stdio_devices[i]->name);
702 }
703#endif
704
705#if 0
706
707 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
708 return 0;
709#endif
710 return 0;
711}
712
713#else
714
715
716int console_init_r(void)
717{
718 struct stdio_dev *inputdev = NULL, *outputdev = NULL;
719 int i;
720 struct list_head *list = stdio_get_list();
721 struct list_head *pos;
722 struct stdio_dev *dev;
723
724#ifdef CONFIG_SPLASH_SCREEN
725
726
727
728
729
730
731 if (getenv("splashimage") != NULL) {
732 if (!(gd->flags & GD_FLG_SILENT))
733 outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
734 }
735#endif
736
737
738 list_for_each(pos, list) {
739 dev = list_entry(pos, struct stdio_dev, list);
740
741 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
742 inputdev = dev;
743 }
744 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
745 outputdev = dev;
746 }
747 if(inputdev && outputdev)
748 break;
749 }
750
751
752 if (outputdev != NULL) {
753 console_setfile(stdout, outputdev);
754 console_setfile(stderr, outputdev);
755#ifdef CONFIG_CONSOLE_MUX
756 console_devices[stdout][0] = outputdev;
757 console_devices[stderr][0] = outputdev;
758#endif
759 }
760
761
762 if (inputdev != NULL) {
763 console_setfile(stdin, inputdev);
764#ifdef CONFIG_CONSOLE_MUX
765 console_devices[stdin][0] = inputdev;
766#endif
767 }
768
769 gd->flags |= GD_FLG_DEVINIT;
770
771 stdio_print_current_devices();
772
773
774 for (i = 0; i < 3; i++) {
775 setenv(stdio_names[i], stdio_devices[i]->name);
776 }
777
778#if 0
779
780 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
781 return 0;
782#endif
783
784 return 0;
785}
786
787#endif
788