change source file mode to 0644 instead of 0755
[profile/mobile/platform/kernel/u-boot-tm1.git] / common / console.c
1 /*
2  * (C) Copyright 2000
3  * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <stdarg.h>
26 #include <malloc.h>
27 #include <stdio_dev.h>
28 #include <exports.h>
29
30 DECLARE_GLOBAL_DATA_PTR;
31
32 #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
33 /*
34  * if overwrite_console returns 1, the stdin, stderr and stdout
35  * are switched to the serial port, else the settings in the
36  * environment are used
37  */
38 #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
39 extern int overwrite_console(void);
40 #define OVERWRITE_CONSOLE overwrite_console()
41 #else
42 #define OVERWRITE_CONSOLE 0
43 #endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
44
45 #endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
46
47 static 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                 /* Start new device */
59                 if (dev->start) {
60                         error = dev->start();
61                         /* If it's not started dont use it */
62                         if (error < 0)
63                                 break;
64                 }
65
66                 /* Assign the new device (leaving the existing one started) */
67                 stdio_devices[file] = dev;
68
69                 /*
70                  * Update monitor functions
71                  * (to use the console stuff by other applications)
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:                /* Invalid file ID */
87                 error = -1;
88         }
89         return error;
90 }
91
92 #if defined(CONFIG_CONSOLE_MUX)
93 /** Console I/O multiplexing *******************************************/
94
95 static struct stdio_dev *tstcdev;
96 struct stdio_dev **console_devices[MAX_FILES];
97 int cd_count[MAX_FILES];
98
99 /*
100  * This depends on tstc() always being called before getc().
101  * This is guaranteed to be true because this routine is called
102  * only from fgetc() which assures it.
103  * No attempt is made to demultiplex multiple input sources.
104  */
105 static int console_getc(int file)
106 {
107         unsigned char ret;
108
109         /* This is never called with testcdev == NULL */
110         ret = tstcdev->getc();
111         tstcdev = NULL;
112         return ret;
113 }
114
115 static 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
137 static 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
149 static 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
161 static inline void console_printdevs(int file)
162 {
163         iomux_printdevs(file);
164 }
165
166 static inline void console_doenv(int file, struct stdio_dev *dev)
167 {
168         iomux_doenv(file, dev->name);
169 }
170 #else
171 static inline int console_getc(int file)
172 {
173         return stdio_devices[file]->getc();
174 }
175
176 static inline int console_tstc(int file)
177 {
178         return stdio_devices[file]->tstc();
179 }
180
181 static inline void console_putc(int file, const char c)
182 {
183         stdio_devices[file]->putc(c);
184 }
185
186 static inline void console_puts(int file, const char *s)
187 {
188         stdio_devices[file]->puts(s);
189 }
190
191 static inline void console_printdevs(int file)
192 {
193         printf("%s\n", stdio_devices[file]->name);
194 }
195
196 static inline void console_doenv(int file, struct stdio_dev *dev)
197 {
198         console_setfile(file, dev);
199 }
200 #endif /* defined(CONFIG_CONSOLE_MUX) */
201
202 #ifdef CONFIG_RAM_CONSOLE
203 static uint used_size = 0;
204
205 void ram_puts(const char* s)
206 {
207         uint *p = NULL;
208         uint  wlen = strlen(s);
209
210         p = (unsigned char*)CONFIG_RAM_CONSOLE_START +  used_size;
211
212         if (used_size >= CONFIG_RAM_CONSOLE_SIZE) {
213                 serial_puts("ram console: space overflow!\n");
214                 return;
215         }
216         else if ((used_size + wlen) > CONFIG_RAM_CONSOLE_SIZE) {
217                 serial_puts("ram console: no enough ram space !\n");
218
219                 /* fill available space */
220                 wlen = CONFIG_RAM_CONSOLE_SIZE - used_size;
221                 memcpy((void*)p, (void*)s, wlen);
222
223                 used_size = CONFIG_RAM_CONSOLE_SIZE;
224                 return;
225         }
226
227         memcpy((void*)p, (void*)s, wlen);
228
229         used_size += wlen;
230 }
231
232 #endif
233
234 /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
235
236 int serial_printf(const char *fmt, ...)
237 {
238         va_list args;
239         uint i;
240         char printbuffer[CONFIG_SYS_PBSIZE];
241
242         va_start(args, fmt);
243
244         /* For this to work, printbuffer must be larger than
245          * anything we ever want to print.
246          */
247         i = vsprintf(printbuffer, fmt, args);
248         va_end(args);
249
250         serial_puts(printbuffer);
251         return i;
252 }
253
254 int fgetc(int file)
255 {
256         if (file < MAX_FILES) {
257 #if defined(CONFIG_CONSOLE_MUX)
258                 /*
259                  * Effectively poll for input wherever it may be available.
260                  */
261                 for (;;) {
262                         /*
263                          * Upper layer may have already called tstc() so
264                          * check for that first.
265                          */
266                         if (tstcdev != NULL)
267                                 return console_getc(file);
268                         console_tstc(file);
269 #ifdef CONFIG_WATCHDOG
270                         /*
271                          * If the watchdog must be rate-limited then it should
272                          * already be handled in board-specific code.
273                          */
274                          udelay(1);
275 #endif
276                 }
277 #else
278                 return console_getc(file);
279 #endif
280         }
281
282         return -1;
283 }
284
285 int ftstc(int file)
286 {
287         if (file < MAX_FILES)
288                 return console_tstc(file);
289
290         return -1;
291 }
292
293 void fputc(int file, const char c)
294 {
295         if (file < MAX_FILES)
296                 console_putc(file, c);
297 }
298
299 void fputs(int file, const char *s)
300 {
301         if (file < MAX_FILES)
302                 console_puts(file, s);
303 }
304
305 int fprintf(int file, const char *fmt, ...)
306 {
307         va_list args;
308         uint i;
309         char printbuffer[CONFIG_SYS_PBSIZE];
310
311         va_start(args, fmt);
312
313         /* For this to work, printbuffer must be larger than
314          * anything we ever want to print.
315          */
316         i = vsprintf(printbuffer, fmt, args);
317         va_end(args);
318
319         /* Send to desired file */
320         fputs(file, printbuffer);
321         return i;
322 }
323
324 /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
325
326 int getc(void)
327 {
328 #ifdef CONFIG_DISABLE_CONSOLE
329         if (gd->flags & GD_FLG_DISABLE_CONSOLE)
330                 return 0;
331 #endif
332
333         if (gd->flags & GD_FLG_DEVINIT) {
334                 /* Get from the standard input */
335                 return fgetc(stdin);
336         }
337
338         /* Send directly to the handler */
339         return serial_getc();
340 }
341
342 int tstc(void)
343 {
344 #ifdef CONFIG_DISABLE_CONSOLE
345         if (gd->flags & GD_FLG_DISABLE_CONSOLE)
346                 return 0;
347 #endif
348
349         if (gd->flags & GD_FLG_DEVINIT) {
350                 /* Test the standard input */
351                 return ftstc(stdin);
352         }
353
354         /* Send directly to the handler */
355         return serial_tstc();
356 }
357
358 void putc(const char c)
359 {
360 #ifdef CONFIG_SILENT_CONSOLE
361         if (gd->flags & GD_FLG_SILENT)
362                 return;
363 #endif
364
365 #ifdef CONFIG_DISABLE_CONSOLE
366         if (gd->flags & GD_FLG_DISABLE_CONSOLE)
367                 return;
368 #endif
369
370         if (gd->flags & GD_FLG_DEVINIT) {
371                 /* Send to the standard output */
372                 fputc(stdout, c);
373         } else {
374                 /* Send directly to the handler */
375                 serial_putc(c);
376         }
377 }
378
379 void puts(const char *s)
380 {
381 #ifdef CONFIG_SILENT_CONSOLE
382         if (gd->flags & GD_FLG_SILENT)
383                 return;
384 #endif
385
386 #ifdef CONFIG_DISABLE_CONSOLE
387         if (gd->flags & GD_FLG_DISABLE_CONSOLE)
388                 return;
389 #endif
390
391         if (gd->flags & GD_FLG_DEVINIT) {
392                 /* Send to the standard output */
393                 fputs(stdout, s);
394         } else {
395                 /* Send directly to the handler */
396                 serial_puts(s);
397         }
398
399 #ifdef CONFIG_RAM_CONSOLE
400         ram_puts(s);
401 #endif
402 }
403
404 int printf(const char *fmt, ...)
405 {
406         va_list args;
407         uint i;
408         char printbuffer[CONFIG_SYS_PBSIZE];
409
410         va_start(args, fmt);
411
412         /* For this to work, printbuffer must be larger than
413          * anything we ever want to print.
414          */
415         i = vsprintf(printbuffer, fmt, args);
416         va_end(args);
417
418         /* Print the string */
419         puts(printbuffer);
420         return i;
421 }
422
423 int vprintf(const char *fmt, va_list args)
424 {
425         uint i;
426         char printbuffer[CONFIG_SYS_PBSIZE];
427
428         /* For this to work, printbuffer must be larger than
429          * anything we ever want to print.
430          */
431         i = vsprintf(printbuffer, fmt, args);
432
433         /* Print the string */
434         puts(printbuffer);
435         return i;
436 }
437
438 /* test if ctrl-c was pressed */
439 static int ctrlc_disabled = 0;  /* see disable_ctrl() */
440 static int ctrlc_was_pressed = 0;
441 int ctrlc(void)
442 {
443         if (!ctrlc_disabled && gd->have_console) {
444                 if (tstc()) {
445                         switch (getc()) {
446                         case 0x03:              /* ^C - Control C */
447                                 ctrlc_was_pressed = 1;
448                                 return 1;
449                         default:
450                                 break;
451                         }
452                 }
453         }
454         return 0;
455 }
456
457 /* pass 1 to disable ctrlc() checking, 0 to enable.
458  * returns previous state
459  */
460 int disable_ctrlc(int disable)
461 {
462         int prev = ctrlc_disabled;      /* save previous state */
463
464         ctrlc_disabled = disable;
465         return prev;
466 }
467
468 int had_ctrlc (void)
469 {
470         return ctrlc_was_pressed;
471 }
472
473 void clear_ctrlc(void)
474 {
475         ctrlc_was_pressed = 0;
476 }
477
478 #ifdef CONFIG_MODEM_SUPPORT_DEBUG
479 char    screen[1024];
480 char *cursor = screen;
481 int once = 0;
482 inline void dbg(const char *fmt, ...)
483 {
484         va_list args;
485         uint    i;
486         char    printbuffer[CONFIG_SYS_PBSIZE];
487
488         if (!once) {
489                 memset(screen, 0, sizeof(screen));
490                 once++;
491         }
492
493         va_start(args, fmt);
494
495         /* For this to work, printbuffer must be larger than
496          * anything we ever want to print.
497          */
498         i = vsprintf(printbuffer, fmt, args);
499         va_end(args);
500
501         if ((screen + sizeof(screen) - 1 - cursor)
502             < strlen(printbuffer) + 1) {
503                 memset(screen, 0, sizeof(screen));
504                 cursor = screen;
505         }
506         sprintf(cursor, printbuffer);
507         cursor += strlen(printbuffer);
508
509 }
510 #else
511 inline void dbg(const char *fmt, ...)
512 {
513 }
514 #endif
515
516 /** U-Boot INIT FUNCTIONS *************************************************/
517
518 struct stdio_dev *search_device(int flags, char *name)
519 {
520         struct stdio_dev *dev;
521
522         dev = stdio_get_by_name(name);
523
524         if (dev && (dev->flags & flags))
525                 return dev;
526
527         return NULL;
528 }
529
530 int console_assign(int file, char *devname)
531 {
532         int flag;
533         struct stdio_dev *dev;
534
535         /* Check for valid file */
536         switch (file) {
537         case stdin:
538                 flag = DEV_FLAGS_INPUT;
539                 break;
540         case stdout:
541         case stderr:
542                 flag = DEV_FLAGS_OUTPUT;
543                 break;
544         default:
545                 return -1;
546         }
547
548         /* Check for valid device name */
549
550         dev = search_device(flag, devname);
551
552         if (dev)
553                 return console_setfile(file, dev);
554
555         return -1;
556 }
557
558 /* Called before relocation - use serial functions */
559 int console_init_f(void)
560 {
561         gd->have_console = 1;
562
563 #ifdef CONFIG_SILENT_CONSOLE
564         if (getenv("silent") != NULL)
565                 gd->flags |= GD_FLG_SILENT;
566 #endif
567
568         return 0;
569 }
570
571 void stdio_print_current_devices(void)
572 {
573 #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
574         /* Print information */
575         puts("In:    ");
576         if (stdio_devices[stdin] == NULL) {
577                 puts("No input devices available!\n");
578         } else {
579                 printf ("%s\n", stdio_devices[stdin]->name);
580         }
581
582         puts("Out:   ");
583         if (stdio_devices[stdout] == NULL) {
584                 puts("No output devices available!\n");
585         } else {
586                 printf ("%s\n", stdio_devices[stdout]->name);
587         }
588
589         puts("Err:   ");
590         if (stdio_devices[stderr] == NULL) {
591                 puts("No error devices available!\n");
592         } else {
593                 printf ("%s\n", stdio_devices[stderr]->name);
594         }
595 #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
596 }
597
598 #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
599 /* Called after the relocation - use desired console functions */
600 int console_init_r(void)
601 {
602         char *stdinname, *stdoutname, *stderrname;
603         struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
604 #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
605         int i;
606 #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
607 #ifdef CONFIG_CONSOLE_MUX
608         int iomux_err = 0;
609 #endif
610
611         /* set default handlers at first */
612         gd->jt[XF_getc] = serial_getc;
613         gd->jt[XF_tstc] = serial_tstc;
614         gd->jt[XF_putc] = serial_putc;
615         gd->jt[XF_puts] = serial_puts;
616         gd->jt[XF_printf] = serial_printf;
617
618         /* stdin stdout and stderr are in environment */
619         /* scan for it */
620         stdinname  = getenv("stdin");
621         stdoutname = getenv("stdout");
622         stderrname = getenv("stderr");
623
624         if (OVERWRITE_CONSOLE == 0) {   /* if not overwritten by config switch */
625                 inputdev  = search_device(DEV_FLAGS_INPUT,  stdinname);
626                 outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname);
627                 errdev    = search_device(DEV_FLAGS_OUTPUT, stderrname);
628 #ifdef CONFIG_CONSOLE_MUX
629                 iomux_err = iomux_doenv(stdin, stdinname);
630                 iomux_err += iomux_doenv(stdout, stdoutname);
631                 iomux_err += iomux_doenv(stderr, stderrname);
632                 if (!iomux_err)
633                         /* Successful, so skip all the code below. */
634                         goto done;
635 #endif
636         }
637         /* if the devices are overwritten or not found, use default device */
638         if (inputdev == NULL) {
639                 inputdev  = search_device(DEV_FLAGS_INPUT,  "serial");
640         }
641         if (outputdev == NULL) {
642                 outputdev = search_device(DEV_FLAGS_OUTPUT, "serial");
643         }
644         if (errdev == NULL) {
645                 errdev    = search_device(DEV_FLAGS_OUTPUT, "serial");
646         }
647         /* Initializes output console first */
648         if (outputdev != NULL) {
649                 /* need to set a console if not done above. */
650                 console_doenv(stdout, outputdev);
651         }
652         if (errdev != NULL) {
653                 /* need to set a console if not done above. */
654                 console_doenv(stderr, errdev);
655         }
656         if (inputdev != NULL) {
657                 /* need to set a console if not done above. */
658                 console_doenv(stdin, inputdev);
659         }
660
661 #ifdef CONFIG_CONSOLE_MUX
662 done:
663 #endif
664
665         gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
666
667         stdio_print_current_devices();
668
669 #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
670         /* set the environment variables (will overwrite previous env settings) */
671         for (i = 0; i < 3; i++) {
672                 setenv(stdio_names[i], stdio_devices[i]->name);
673         }
674 #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
675
676 #if 0
677         /* If nothing usable installed, use only the initial console */
678         if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
679                 return 0;
680 #endif
681         return 0;
682 }
683
684 #else /* CONFIG_SYS_CONSOLE_IS_IN_ENV */
685
686 /* Called after the relocation - use desired console functions */
687 int console_init_r(void)
688 {
689         struct stdio_dev *inputdev = NULL, *outputdev = NULL;
690         int i;
691         struct list_head *list = stdio_get_list();
692         struct list_head *pos;
693         struct stdio_dev *dev;
694
695 #ifdef CONFIG_SPLASH_SCREEN
696         /*
697          * suppress all output if splash screen is enabled and we have
698          * a bmp to display. We redirect the output from frame buffer
699          * console to serial console in this case or suppress it if
700          * "silent" mode was requested.
701          */
702         if (getenv("splashimage") != NULL) {
703                 if (!(gd->flags & GD_FLG_SILENT))
704                         outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
705         }
706 #endif
707
708         /* Scan devices looking for input and output devices */
709         list_for_each(pos, list) {
710                 dev = list_entry(pos, struct stdio_dev, list);
711
712                 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
713                         inputdev = dev;
714                 }
715                 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
716                         outputdev = dev;
717                 }
718                 if(inputdev && outputdev)
719                         break;
720         }
721
722         /* Initializes output console first */
723         if (outputdev != NULL) {
724                 console_setfile(stdout, outputdev);
725                 console_setfile(stderr, outputdev);
726 #ifdef CONFIG_CONSOLE_MUX
727                 console_devices[stdout][0] = outputdev;
728                 console_devices[stderr][0] = outputdev;
729 #endif
730         }
731
732         /* Initializes input console */
733         if (inputdev != NULL) {
734                 console_setfile(stdin, inputdev);
735 #ifdef CONFIG_CONSOLE_MUX
736                 console_devices[stdin][0] = inputdev;
737 #endif
738         }
739
740 #if !(defined(CONFIG_SC8830) || defined(CONFIG_SC9630) )
741
742         gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
743 #endif
744
745         stdio_print_current_devices();
746
747         /* Setting environment variables */
748         for (i = 0; i < 3; i++) {
749                 setenv(stdio_names[i], stdio_devices[i]->name);
750         }
751
752 #if 0
753         /* If nothing usable installed, use only the initial console */
754         if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
755                 return 0;
756 #endif
757
758         return 0;
759 }
760
761 #endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */