1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2000
4 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
5 */
6
7 #define LOG_CATEGORY LOGC_CONSOLE
8
9 #include <console.h>
10 #include <debug_uart.h>
11 #include <display_options.h>
12 #include <dm.h>
13 #include <env.h>
14 #include <stdarg.h>
15 #include <iomux.h>
16 #include <malloc.h>
17 #include <mapmem.h>
18 #include <os.h>
19 #include <serial.h>
20 #include <stdio_dev.h>
21 #include <exports.h>
22 #include <env_internal.h>
23 #include <video_console.h>
24 #include <watchdog.h>
25 #include <asm/global_data.h>
26 #include <linux/delay.h>
27
28 DECLARE_GLOBAL_DATA_PTR;
29
30 #define CSI "\x1b["
31
on_console(const char * name,const char * value,enum env_op op,int flags)32 static int on_console(const char *name, const char *value, enum env_op op,
33 int flags)
34 {
35 int console = -1;
36
37 /* Check for console redirection */
38 if (strcmp(name, "stdin") == 0)
39 console = stdin;
40 else if (strcmp(name, "stdout") == 0)
41 console = stdout;
42 else if (strcmp(name, "stderr") == 0)
43 console = stderr;
44
45 /* if not actually setting a console variable, we don't care */
46 if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0)
47 return 0;
48
49 switch (op) {
50 case env_op_create:
51 case env_op_overwrite:
52
53 if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
54 if (iomux_doenv(console, value))
55 return 1;
56 } else {
57 /* Try assigning specified device */
58 if (console_assign(console, value) < 0)
59 return 1;
60 }
61
62 return 0;
63
64 case env_op_delete:
65 if ((flags & H_FORCE) == 0)
66 printf("Can't delete \"%s\"\n", name);
67 return 1;
68
69 default:
70 return 0;
71 }
72 }
73 U_BOOT_ENV_CALLBACK(console, on_console);
74
75 #ifdef CONFIG_SILENT_CONSOLE
on_silent(const char * name,const char * value,enum env_op op,int flags)76 static int on_silent(const char *name, const char *value, enum env_op op,
77 int flags)
78 {
79 if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET))
80 if (flags & H_INTERACTIVE)
81 return 0;
82
83 if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC))
84 if ((flags & H_INTERACTIVE) == 0)
85 return 0;
86
87 if (value != NULL)
88 gd->flags |= GD_FLG_SILENT;
89 else
90 gd->flags &= ~GD_FLG_SILENT;
91
92 return 0;
93 }
94 U_BOOT_ENV_CALLBACK(silent, on_silent);
95 #endif
96
97 #ifdef CONFIG_CONSOLE_RECORD
98 /* helper function: access to gd->console_out and gd->console_in */
console_record_putc(const char c)99 static void console_record_putc(const char c)
100 {
101 if (!(gd->flags & GD_FLG_RECORD))
102 return;
103 if (gd->console_out.start &&
104 !membuf_putbyte((struct membuf *)&gd->console_out, c))
105 gd->flags |= GD_FLG_RECORD_OVF;
106 }
107
console_record_puts(const char * s)108 static void console_record_puts(const char *s)
109 {
110 if (!(gd->flags & GD_FLG_RECORD))
111 return;
112 if (gd->console_out.start) {
113 int len = strlen(s);
114
115 if (membuf_put((struct membuf *)&gd->console_out, s, len) !=
116 len)
117 gd->flags |= GD_FLG_RECORD_OVF;
118 }
119 }
120
console_record_getc(void)121 static int console_record_getc(void)
122 {
123 if (!(gd->flags & GD_FLG_RECORD))
124 return -1;
125 if (!gd->console_in.start)
126 return -1;
127
128 return membuf_getbyte((struct membuf *)&gd->console_in);
129 }
130
console_record_tstc(void)131 static int console_record_tstc(void)
132 {
133 if (!(gd->flags & GD_FLG_RECORD))
134 return 0;
135 if (gd->console_in.start) {
136 if (membuf_peekbyte((struct membuf *)&gd->console_in) != -1)
137 return 1;
138 }
139 return 0;
140 }
141 #else
console_record_putc(char c)142 static void console_record_putc(char c)
143 {
144 }
145
console_record_puts(const char * s)146 static void console_record_puts(const char *s)
147 {
148 }
149
console_record_getc(void)150 static int console_record_getc(void)
151 {
152 return -1;
153 }
154
console_record_tstc(void)155 static int console_record_tstc(void)
156 {
157 return 0;
158 }
159 #endif
160
161 #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
162 /*
163 * if overwrite_console returns 1, the stdin, stderr and stdout
164 * are switched to the serial port, else the settings in the
165 * environment are used
166 */
167 #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
168 extern int overwrite_console(void);
169 #define OVERWRITE_CONSOLE overwrite_console()
170 #else
171 #define OVERWRITE_CONSOLE 0
172 #endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
173
174 #endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
175
console_setfile(int file,struct stdio_dev * dev)176 static int console_setfile(int file, struct stdio_dev * dev)
177 {
178 int error = 0;
179
180 if (dev == NULL)
181 return -1;
182
183 switch (file) {
184 case stdin:
185 case stdout:
186 case stderr:
187 error = console_start(file, dev);
188 if (error)
189 break;
190
191 /* Assign the new device (leaving the existing one started) */
192 stdio_devices[file] = dev;
193
194 #ifndef CONFIG_XPL_BUILD
195 /*
196 * Update monitor functions
197 * (to use the console stuff by other applications)
198 */
199 switch (file) {
200 case stdin:
201 gd->jt->getc = getchar;
202 gd->jt->tstc = tstc;
203 break;
204 case stdout:
205 gd->jt->putc = putc;
206 gd->jt->puts = puts;
207 STDIO_DEV_ASSIGN_FLUSH(gd->jt, flush);
208 gd->jt->printf = printf;
209 break;
210 }
211 #endif
212 break;
213 default: /* Invalid file ID */
214 error = -1;
215 }
216 return error;
217 }
218
219 /**
220 * console_dev_is_serial() - Check if a stdio device is a serial device
221 *
222 * @sdev: Device to check
223 * Return: true if this device is in the serial uclass (or for pre-driver-model,
224 * whether it is called "serial".
225 */
console_dev_is_serial(struct stdio_dev * sdev)226 static bool console_dev_is_serial(struct stdio_dev *sdev)
227 {
228 bool is_serial;
229
230 if (IS_ENABLED(CONFIG_DM_SERIAL) && (sdev->flags & DEV_FLAGS_DM)) {
231 struct udevice *dev = sdev->priv;
232
233 is_serial = device_get_uclass_id(dev) == UCLASS_SERIAL;
234 } else {
235 is_serial = !strcmp(sdev->name, "serial");
236 }
237
238 return is_serial;
239 }
240
241 #if CONFIG_IS_ENABLED(CONSOLE_MUX)
242 /** Console I/O multiplexing *******************************************/
243
244 /* tstcdev: save the last stdio device with pending characters, with tstc != 0 */
245 static struct stdio_dev *tstcdev;
246 struct stdio_dev **console_devices[MAX_FILES];
247 int cd_count[MAX_FILES];
248
console_devices_set(int file,struct stdio_dev * dev)249 static void console_devices_set(int file, struct stdio_dev *dev)
250 {
251 console_devices[file][0] = dev;
252 cd_count[file] = 1;
253 }
254
255 /**
256 * console_needs_start_stop() - check if we need to start or stop the STDIO device
257 * @file: STDIO file
258 * @sdev: STDIO device in question
259 *
260 * This function checks if we need to start or stop the stdio device used for
261 * a console. For IOMUX case it simply enforces one time start and one time
262 * stop of the device independently of how many STDIO files are using it. In
263 * other words, we start console once before first STDIO device wants it and
264 * stop after the last is gone.
265 */
console_needs_start_stop(int file,struct stdio_dev * sdev)266 static bool console_needs_start_stop(int file, struct stdio_dev *sdev)
267 {
268 int i;
269
270 for (i = 0; i < ARRAY_SIZE(cd_count); i++) {
271 if (i == file)
272 continue;
273
274 if (iomux_match_device(console_devices[i], cd_count[i], sdev) >= 0)
275 return false;
276 }
277 return true;
278 }
279
280 /*
281 * This depends on tstc() always being called before getchar().
282 * This is guaranteed to be true because this routine is called
283 * only from fgetc() which assures it.
284 * No attempt is made to demultiplex multiple input sources.
285 */
console_getc(int file)286 static int console_getc(int file)
287 {
288 unsigned char ret;
289
290 /* This is never called with testcdev == NULL */
291 ret = tstcdev->getc(tstcdev);
292 tstcdev = NULL;
293 return ret;
294 }
295
296 /* Upper layer may have already called tstc(): check the saved result */
console_has_tstc(void)297 static bool console_has_tstc(void)
298 {
299 return !!tstcdev;
300 }
301
console_tstc(int file)302 static int console_tstc(int file)
303 {
304 int i, ret;
305 struct stdio_dev *dev;
306 int prev;
307
308 prev = disable_ctrlc(1);
309 for_each_console_dev(i, file, dev) {
310 if (dev->tstc != NULL) {
311 ret = dev->tstc(dev);
312 if (ret > 0) {
313 tstcdev = dev;
314 disable_ctrlc(prev);
315 return ret;
316 }
317 }
318 }
319 disable_ctrlc(prev);
320
321 return 0;
322 }
323
console_putc(int file,const char c)324 static void console_putc(int file, const char c)
325 {
326 int i;
327 struct stdio_dev *dev;
328
329 for_each_console_dev(i, file, dev) {
330 if (dev->putc != NULL)
331 dev->putc(dev, c);
332 }
333 }
334
335 /**
336 * console_puts_select() - Output a string to all console devices
337 *
338 * @file: File number to output to (e,g, stdout, see stdio.h)
339 * @serial_only: true to output only to serial, false to output to everything
340 * else
341 * @s: String to output
342 */
console_puts_select(int file,bool serial_only,const char * s)343 static void console_puts_select(int file, bool serial_only, const char *s)
344 {
345 int i;
346 struct stdio_dev *dev;
347
348 for_each_console_dev(i, file, dev) {
349 bool is_serial = console_dev_is_serial(dev);
350
351 if (dev->puts && serial_only == is_serial)
352 dev->puts(dev, s);
353 }
354 }
355
console_puts_select_stderr(bool serial_only,const char * s)356 void console_puts_select_stderr(bool serial_only, const char *s)
357 {
358 if (gd->flags & GD_FLG_DEVINIT)
359 console_puts_select(stderr, serial_only, s);
360 }
361
console_printf_select_stderr(bool serial_only,const char * fmt,...)362 int console_printf_select_stderr(bool serial_only, const char *fmt, ...)
363 {
364 char buf[CONFIG_SYS_PBSIZE];
365 va_list args;
366 int ret;
367
368 va_start(args, fmt);
369
370 /* For this to work, buf must be larger than anything we ever want to
371 * print.
372 */
373 ret = vscnprintf(buf, sizeof(buf), fmt, args);
374 va_end(args);
375 console_puts_select_stderr(serial_only, buf);
376
377 return ret;
378 }
379
console_puts(int file,const char * s)380 static void console_puts(int file, const char *s)
381 {
382 int i;
383 struct stdio_dev *dev;
384
385 for_each_console_dev(i, file, dev) {
386 if (dev->puts != NULL)
387 dev->puts(dev, s);
388 }
389 }
390
391 #ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
console_flush(int file)392 static void console_flush(int file)
393 {
394 int i;
395 struct stdio_dev *dev;
396
397 for_each_console_dev(i, file, dev) {
398 if (dev->flush != NULL)
399 dev->flush(dev);
400 }
401 }
402 #endif
403
404 #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
console_doenv(int file,struct stdio_dev * dev)405 static inline void console_doenv(int file, struct stdio_dev *dev)
406 {
407 iomux_doenv(file, dev->name);
408 }
409 #endif
410 #else
411
console_devices_set(int file,struct stdio_dev * dev)412 static void console_devices_set(int file, struct stdio_dev *dev)
413 {
414 }
415
console_needs_start_stop(int file,struct stdio_dev * sdev)416 static inline bool console_needs_start_stop(int file, struct stdio_dev *sdev)
417 {
418 return true;
419 }
420
console_getc(int file)421 static inline int console_getc(int file)
422 {
423 return stdio_devices[file]->getc(stdio_devices[file]);
424 }
425
console_has_tstc(void)426 static bool console_has_tstc(void)
427 {
428 return false;
429 }
430
console_tstc(int file)431 static inline int console_tstc(int file)
432 {
433 return stdio_devices[file]->tstc(stdio_devices[file]);
434 }
435
console_putc(int file,const char c)436 static inline void console_putc(int file, const char c)
437 {
438 stdio_devices[file]->putc(stdio_devices[file], c);
439 }
440
console_puts_select(int file,bool serial_only,const char * s)441 void console_puts_select(int file, bool serial_only, const char *s)
442 {
443 if ((gd->flags & GD_FLG_DEVINIT) &&
444 serial_only == console_dev_is_serial(stdio_devices[file]))
445 stdio_devices[file]->puts(stdio_devices[file], s);
446 }
447
console_puts(int file,const char * s)448 static inline void console_puts(int file, const char *s)
449 {
450 stdio_devices[file]->puts(stdio_devices[file], s);
451 }
452
453 #ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
console_flush(int file)454 static inline void console_flush(int file)
455 {
456 if (stdio_devices[file]->flush)
457 stdio_devices[file]->flush(stdio_devices[file]);
458 }
459 #endif
460
461 #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
console_doenv(int file,struct stdio_dev * dev)462 static inline void console_doenv(int file, struct stdio_dev *dev)
463 {
464 console_setfile(file, dev);
465 }
466 #endif
467 #endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
468
console_setfile_and_devices(int file,struct stdio_dev * dev)469 static void __maybe_unused console_setfile_and_devices(int file, struct stdio_dev *dev)
470 {
471 console_setfile(file, dev);
472 console_devices_set(file, dev);
473 }
474
console_start(int file,struct stdio_dev * sdev)475 int console_start(int file, struct stdio_dev *sdev)
476 {
477 int error;
478
479 if (!console_needs_start_stop(file, sdev))
480 return 0;
481
482 /* Start new device */
483 if (sdev->start) {
484 error = sdev->start(sdev);
485 /* If it's not started don't use it */
486 if (error < 0)
487 return error;
488 }
489 return 0;
490 }
491
console_stop(int file,struct stdio_dev * sdev)492 void console_stop(int file, struct stdio_dev *sdev)
493 {
494 if (!console_needs_start_stop(file, sdev))
495 return;
496
497 if (sdev->stop)
498 sdev->stop(sdev);
499 }
500
501 /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
502
serial_printf(const char * fmt,...)503 int serial_printf(const char *fmt, ...)
504 {
505 va_list args;
506 uint i;
507 char printbuffer[CONFIG_SYS_PBSIZE];
508
509 va_start(args, fmt);
510
511 /* For this to work, printbuffer must be larger than
512 * anything we ever want to print.
513 */
514 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
515 va_end(args);
516
517 serial_puts(printbuffer);
518 return i;
519 }
520
fgetc(int file)521 int fgetc(int file)
522 {
523 if ((unsigned int)file < MAX_FILES) {
524 /*
525 * Effectively poll for input wherever it may be available.
526 */
527 for (;;) {
528 schedule();
529 if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
530 /*
531 * Upper layer may have already called tstc() so
532 * check for that first.
533 */
534 if (console_has_tstc())
535 return console_getc(file);
536 console_tstc(file);
537 } else {
538 if (console_tstc(file))
539 return console_getc(file);
540 }
541
542 /*
543 * If the watchdog must be rate-limited then it should
544 * already be handled in board-specific code.
545 */
546 if (IS_ENABLED(CONFIG_WATCHDOG))
547 udelay(1);
548 }
549 }
550
551 return -1;
552 }
553
ftstc(int file)554 int ftstc(int file)
555 {
556 if ((unsigned int)file < MAX_FILES)
557 return console_tstc(file);
558
559 return -1;
560 }
561
fputc(int file,const char c)562 void fputc(int file, const char c)
563 {
564 if ((unsigned int)file < MAX_FILES)
565 console_putc(file, c);
566 }
567
fputs(int file,const char * s)568 void fputs(int file, const char *s)
569 {
570 if ((unsigned int)file < MAX_FILES)
571 console_puts(file, s);
572 }
573
574 #ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
fflush(int file)575 void fflush(int file)
576 {
577 if ((unsigned int)file < MAX_FILES)
578 console_flush(file);
579 }
580 #endif
581
fprintf(int file,const char * fmt,...)582 int fprintf(int file, const char *fmt, ...)
583 {
584 va_list args;
585 uint i;
586 char printbuffer[CONFIG_SYS_PBSIZE];
587
588 va_start(args, fmt);
589
590 /* For this to work, printbuffer must be larger than
591 * anything we ever want to print.
592 */
593 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
594 va_end(args);
595
596 /* Send to desired file */
597 fputs(file, printbuffer);
598 return i;
599 }
600
601 /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
602
getchar(void)603 int getchar(void)
604 {
605 int ch;
606
607 if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
608 return 0;
609
610 if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
611 return 0;
612
613 ch = console_record_getc();
614 if (ch != -1)
615 return ch;
616
617 if (gd->flags & GD_FLG_DEVINIT) {
618 /* Get from the standard input */
619 return fgetc(stdin);
620 }
621
622 /* Send directly to the handler */
623 return serial_getc();
624 }
625
tstc(void)626 int tstc(void)
627 {
628 if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
629 return 0;
630
631 if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
632 return 0;
633
634 if (console_record_tstc())
635 return 1;
636
637 if (gd->flags & GD_FLG_DEVINIT) {
638 /* Test the standard input */
639 return ftstc(stdin);
640 }
641
642 /* Send directly to the handler */
643 return serial_tstc();
644 }
645
646 #define PRE_CONSOLE_FLUSHPOINT1_SERIAL 0
647 #define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL 1
648
649 #if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
650 #define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_VAL(PRE_CON_BUF_SZ))
651
pre_console_putc(const char c)652 static void pre_console_putc(const char c)
653 {
654 char *buffer;
655
656 if (gd->precon_buf_idx < 0)
657 return;
658
659 buffer = map_sysmem(CONFIG_VAL(PRE_CON_BUF_ADDR), CONFIG_VAL(PRE_CON_BUF_SZ));
660
661 buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c;
662
663 unmap_sysmem(buffer);
664 }
665
pre_console_puts(const char * s)666 static void pre_console_puts(const char *s)
667 {
668 if (gd->precon_buf_idx < 0)
669 return;
670
671 while (*s)
672 pre_console_putc(*s++);
673 }
674
print_pre_console_buffer(int flushpoint)675 static void print_pre_console_buffer(int flushpoint)
676 {
677 long in = 0, out = 0;
678 char buf_out[CONFIG_VAL(PRE_CON_BUF_SZ) + 1];
679 char *buf_in;
680
681 if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT))
682 return;
683
684 buf_in = map_sysmem(CONFIG_VAL(PRE_CON_BUF_ADDR), CONFIG_VAL(PRE_CON_BUF_SZ));
685 if (gd->precon_buf_idx > CONFIG_VAL(PRE_CON_BUF_SZ))
686 in = gd->precon_buf_idx - CONFIG_VAL(PRE_CON_BUF_SZ);
687
688 while (in < gd->precon_buf_idx)
689 buf_out[out++] = buf_in[CIRC_BUF_IDX(in++)];
690 unmap_sysmem(buf_in);
691
692 buf_out[out] = 0;
693
694 gd->precon_buf_idx = -1;
695 switch (flushpoint) {
696 case PRE_CONSOLE_FLUSHPOINT1_SERIAL:
697 puts(buf_out);
698 break;
699 case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL:
700 console_puts_select(stdout, false, buf_out);
701 break;
702 }
703 gd->precon_buf_idx = in;
704 }
705 #else
pre_console_putc(const char c)706 static inline void pre_console_putc(const char c) {}
pre_console_puts(const char * s)707 static inline void pre_console_puts(const char *s) {}
print_pre_console_buffer(int flushpoint)708 static inline void print_pre_console_buffer(int flushpoint) {}
709 #endif
710
putc(const char c)711 void putc(const char c)
712 {
713 if (!gd)
714 return;
715
716 console_record_putc(c);
717
718 /* sandbox can send characters to stdout before it has a console */
719 if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) {
720 os_putc(c);
721 return;
722 }
723
724 /* if we don't have a console yet, use the debug UART */
725 if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) {
726 printch(c);
727 return;
728 }
729
730 if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) {
731 if (!(gd->flags & GD_FLG_DEVINIT))
732 pre_console_putc(c);
733 return;
734 }
735
736 if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
737 return;
738
739 if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
740 return pre_console_putc(c);
741
742 if (gd->flags & GD_FLG_DEVINIT) {
743 /* Send to the standard output */
744 fputc(stdout, c);
745 } else {
746 /* Send directly to the handler */
747 pre_console_putc(c);
748 serial_putc(c);
749 }
750 }
751
puts(const char * s)752 void puts(const char *s)
753 {
754 if (!gd)
755 return;
756
757 console_record_puts(s);
758
759 /* sandbox can send characters to stdout before it has a console */
760 if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) {
761 os_puts(s);
762 return;
763 }
764
765 if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) {
766 printascii(s);
767 return;
768 }
769
770 if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) {
771 if (!(gd->flags & GD_FLG_DEVINIT))
772 pre_console_puts(s);
773 return;
774 }
775
776 if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
777 return;
778
779 if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
780 return pre_console_puts(s);
781
782 if (gd->flags & GD_FLG_DEVINIT) {
783 /* Send to the standard output */
784 fputs(stdout, s);
785 } else {
786 /* Send directly to the handler */
787 pre_console_puts(s);
788 serial_puts(s);
789 }
790 }
791
792 #ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
flush(void)793 void flush(void)
794 {
795 if (!gd)
796 return;
797
798 /* sandbox can send characters to stdout before it has a console */
799 if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) {
800 os_flush();
801 return;
802 }
803
804 if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY))
805 return;
806
807 if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT))
808 return;
809
810 if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
811 return;
812
813 if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
814 return;
815
816 if (gd->flags & GD_FLG_DEVINIT) {
817 /* Send to the standard output */
818 fflush(stdout);
819 } else {
820 /* Send directly to the handler */
821 serial_flush();
822 }
823 }
824 #endif
825
826 #ifdef CONFIG_CONSOLE_RECORD
console_record_init(void)827 int console_record_init(void)
828 {
829 int ret;
830
831 ret = membuf_new((struct membuf *)&gd->console_out,
832 gd->flags & GD_FLG_RELOC ?
833 CONFIG_CONSOLE_RECORD_OUT_SIZE :
834 CONFIG_CONSOLE_RECORD_OUT_SIZE_F);
835 if (ret)
836 return ret;
837 ret = membuf_new((struct membuf *)&gd->console_in,
838 CONFIG_CONSOLE_RECORD_IN_SIZE);
839
840 /* Start recording from the beginning */
841 gd->flags |= GD_FLG_RECORD;
842
843 return ret;
844 }
845
console_record_reset(void)846 void console_record_reset(void)
847 {
848 membuf_purge((struct membuf *)&gd->console_out);
849 membuf_purge((struct membuf *)&gd->console_in);
850 gd->flags &= ~GD_FLG_RECORD_OVF;
851 }
852
console_record_reset_enable(void)853 int console_record_reset_enable(void)
854 {
855 console_record_reset();
856 gd->flags |= GD_FLG_RECORD;
857
858 return 0;
859 }
860
console_record_readline(char * str,int maxlen)861 int console_record_readline(char *str, int maxlen)
862 {
863 if (gd->flags & GD_FLG_RECORD_OVF)
864 return -ENOSPC;
865 if (console_record_isempty())
866 return -ENOENT;
867
868 return membuf_readline((struct membuf *)&gd->console_out, str,
869 maxlen, '\0', false);
870 }
871
console_record_avail(void)872 int console_record_avail(void)
873 {
874 return membuf_avail((struct membuf *)&gd->console_out);
875 }
876
console_record_isempty(void)877 bool console_record_isempty(void)
878 {
879 return membuf_isempty((struct membuf *)&gd->console_out);
880 }
881
console_in_puts(const char * str)882 int console_in_puts(const char *str)
883 {
884 return membuf_put((struct membuf *)&gd->console_in, str, strlen(str));
885 }
886
887 #endif
888
889 /* test if ctrl-c was pressed */
890 static int ctrlc_disabled = 0; /* see disable_ctrl() */
891 static int ctrlc_was_pressed = 0;
ctrlc(void)892 int ctrlc(void)
893 {
894 if (!ctrlc_disabled && (gd->flags & GD_FLG_HAVE_CONSOLE)) {
895 if (tstc()) {
896 switch (getchar()) {
897 case 0x03: /* ^C - Control C */
898 ctrlc_was_pressed = 1;
899 return 1;
900 default:
901 break;
902 }
903 }
904 }
905
906 return 0;
907 }
908 /* Reads user's confirmation.
909 Returns 1 if user's input is "y", "Y", "yes" or "YES"
910 */
confirm_yesno(void)911 int confirm_yesno(void)
912 {
913 int i;
914 char str_input[5];
915
916 /* Flush input */
917 while (tstc())
918 getchar();
919 i = 0;
920 while (i < sizeof(str_input)) {
921 str_input[i] = getchar();
922 putc(str_input[i]);
923 if (str_input[i] == '\r')
924 break;
925 i++;
926 }
927 putc('\n');
928 if (strncmp(str_input, "y\r", 2) == 0 ||
929 strncmp(str_input, "Y\r", 2) == 0 ||
930 strncmp(str_input, "yes\r", 4) == 0 ||
931 strncmp(str_input, "YES\r", 4) == 0)
932 return 1;
933 return 0;
934 }
935 /* pass 1 to disable ctrlc() checking, 0 to enable.
936 * returns previous state
937 */
disable_ctrlc(int disable)938 int disable_ctrlc(int disable)
939 {
940 int prev = ctrlc_disabled; /* save previous state */
941
942 ctrlc_disabled = disable;
943 return prev;
944 }
945
had_ctrlc(void)946 int had_ctrlc (void)
947 {
948 return ctrlc_was_pressed;
949 }
950
clear_ctrlc(void)951 void clear_ctrlc(void)
952 {
953 ctrlc_was_pressed = 0;
954 }
955
956 /** U-Boot INIT FUNCTIONS *************************************************/
957
console_search_dev(int flags,const char * name)958 struct stdio_dev *console_search_dev(int flags, const char *name)
959 {
960 struct stdio_dev *dev;
961
962 dev = stdio_get_by_name(name);
963 if (dev && (dev->flags & flags))
964 return dev;
965
966 return NULL;
967 }
968
console_assign(int file,const char * devname)969 int console_assign(int file, const char *devname)
970 {
971 int flag;
972 struct stdio_dev *dev;
973
974 /* Check for valid file */
975 flag = stdio_file_to_flags(file);
976 if (flag < 0)
977 return flag;
978
979 /* Check for valid device name */
980
981 dev = console_search_dev(flag, devname);
982
983 if (dev)
984 return console_setfile(file, dev);
985
986 return -1;
987 }
988
989 /* return true if the 'silent' flag is removed */
console_update_silent(void)990 static bool console_update_silent(void)
991 {
992 unsigned long flags = gd->flags;
993
994 if (!IS_ENABLED(CONFIG_SILENT_CONSOLE))
995 return false;
996
997 if (IS_ENABLED(CONFIG_SILENT_CONSOLE_UNTIL_ENV) && !(gd->flags & GD_FLG_ENV_READY)) {
998 gd->flags |= GD_FLG_SILENT;
999 return false;
1000 }
1001
1002 if (env_get("silent")) {
1003 gd->flags |= GD_FLG_SILENT;
1004 return false;
1005 }
1006
1007 gd->flags &= ~GD_FLG_SILENT;
1008
1009 return !!(flags & GD_FLG_SILENT);
1010 }
1011
console_announce_r(void)1012 int console_announce_r(void)
1013 {
1014 #if !CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
1015 char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
1016
1017 display_options_get_banner(false, buf, sizeof(buf));
1018
1019 console_puts_select(stdout, false, buf);
1020 #endif
1021
1022 return 0;
1023 }
1024
1025 /* Called before relocation - use serial functions */
console_init_f(void)1026 int console_init_f(void)
1027 {
1028 gd->flags |= GD_FLG_HAVE_CONSOLE;
1029
1030 console_update_silent();
1031
1032 print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL);
1033
1034 return 0;
1035 }
1036
console_clear(void)1037 int console_clear(void)
1038 {
1039 /*
1040 * Send clear screen and home
1041 *
1042 * FIXME(Heinrich Schuchardt <xypron.glpk@gmx.de>): This should go
1043 * through an API and only be written to serial terminals, not video
1044 * displays
1045 */
1046 printf(CSI "2J" CSI "1;1H");
1047 if (IS_ENABLED(CONFIG_VIDEO_ANSI))
1048 return 0;
1049
1050 if (IS_ENABLED(CONFIG_VIDEO)) {
1051 struct udevice *dev;
1052 int ret;
1053
1054 ret = uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev);
1055 if (ret)
1056 return ret;
1057 ret = vidconsole_clear_and_reset(dev);
1058 if (ret)
1059 return ret;
1060 }
1061
1062 return 0;
1063 }
1064
get_stdio(const u8 std)1065 static char *get_stdio(const u8 std)
1066 {
1067 return stdio_devices[std] ? stdio_devices[std]->name : "No devices available!";
1068 }
1069
stdio_print_current_devices(void)1070 static void stdio_print_current_devices(void)
1071 {
1072 char *stdinname = NULL;
1073 char *stdoutname = NULL;
1074 char *stderrname = NULL;
1075
1076 if (CONFIG_IS_ENABLED(CONSOLE_MUX) &&
1077 CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)) {
1078 /* stdin stdout and stderr are in environment */
1079 stdinname = env_get("stdin");
1080 stdoutname = env_get("stdout");
1081 stderrname = env_get("stderr");
1082 }
1083
1084 stdinname = stdinname ? : get_stdio(stdin);
1085 stdoutname = stdoutname ? : get_stdio(stdout);
1086 stderrname = stderrname ? : get_stdio(stderr);
1087
1088 /* Print information */
1089 puts("In: ");
1090 printf("%s\n", stdinname);
1091
1092 puts("Out: ");
1093 printf("%s\n", stdoutname);
1094
1095 puts("Err: ");
1096 printf("%s\n", stderrname);
1097 }
1098
1099 #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
1100 /* Called after the relocation - use desired console functions */
console_init_r(void)1101 int console_init_r(void)
1102 {
1103 char *stdinname, *stdoutname, *stderrname;
1104 struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
1105 int i;
1106 int iomux_err = 0;
1107 int flushpoint;
1108
1109 /* update silent for env loaded from flash (initr_env) */
1110 if (console_update_silent())
1111 flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
1112 else
1113 flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
1114
1115 /* set default handlers at first */
1116 gd->jt->getc = serial_getc;
1117 gd->jt->tstc = serial_tstc;
1118 gd->jt->putc = serial_putc;
1119 gd->jt->puts = serial_puts;
1120 gd->jt->printf = serial_printf;
1121
1122 /* stdin stdout and stderr are in environment */
1123 /* scan for it */
1124 stdinname = env_get("stdin");
1125 stdoutname = env_get("stdout");
1126 stderrname = env_get("stderr");
1127
1128 if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */
1129 inputdev = console_search_dev(DEV_FLAGS_INPUT, stdinname);
1130 outputdev = console_search_dev(DEV_FLAGS_OUTPUT, stdoutname);
1131 errdev = console_search_dev(DEV_FLAGS_OUTPUT, stderrname);
1132 if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
1133 iomux_err = iomux_doenv(stdin, stdinname);
1134 iomux_err += iomux_doenv(stdout, stdoutname);
1135 iomux_err += iomux_doenv(stderr, stderrname);
1136 if (!iomux_err)
1137 /* Successful, so skip all the code below. */
1138 goto done;
1139 }
1140 }
1141 /* if the devices are overwritten or not found, use default device */
1142 if (inputdev == NULL) {
1143 inputdev = console_search_dev(DEV_FLAGS_INPUT, "serial");
1144 }
1145 if (outputdev == NULL) {
1146 outputdev = console_search_dev(DEV_FLAGS_OUTPUT, "serial");
1147 }
1148 if (errdev == NULL) {
1149 errdev = console_search_dev(DEV_FLAGS_OUTPUT, "serial");
1150 }
1151 /* Initializes output console first */
1152 if (outputdev != NULL) {
1153 /* need to set a console if not done above. */
1154 console_doenv(stdout, outputdev);
1155 }
1156 if (errdev != NULL) {
1157 /* need to set a console if not done above. */
1158 console_doenv(stderr, errdev);
1159 }
1160 if (inputdev != NULL) {
1161 /* need to set a console if not done above. */
1162 console_doenv(stdin, inputdev);
1163 }
1164
1165 done:
1166
1167 if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET))
1168 stdio_print_current_devices();
1169
1170 if (IS_ENABLED(CONFIG_SYS_CONSOLE_ENV_OVERWRITE)) {
1171 /* set the environment variables (will overwrite previous env settings) */
1172 for (i = 0; i < MAX_FILES; i++)
1173 env_set(stdio_names[i], stdio_devices[i]->name);
1174 }
1175
1176 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
1177
1178 print_pre_console_buffer(flushpoint);
1179 return 0;
1180 }
1181
1182 #else /* !CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
1183
1184 /* Called after the relocation - use desired console functions */
console_init_r(void)1185 int console_init_r(void)
1186 {
1187 struct stdio_dev *inputdev = NULL, *outputdev = NULL;
1188 int i;
1189 struct list_head *list = stdio_get_list();
1190 struct list_head *pos;
1191 struct stdio_dev *dev;
1192 int flushpoint;
1193
1194 /* update silent for env loaded from flash (initr_env) */
1195 if (console_update_silent())
1196 flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
1197 else
1198 flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
1199
1200 /*
1201 * suppress all output if splash screen is enabled and we have
1202 * a bmp to display. We redirect the output from frame buffer
1203 * console to serial console in this case or suppress it if
1204 * "silent" mode was requested.
1205 */
1206 if (IS_ENABLED(CONFIG_SPLASH_SCREEN) && env_get("splashimage")) {
1207 if (!(gd->flags & GD_FLG_SILENT))
1208 outputdev = console_search_dev (DEV_FLAGS_OUTPUT, "serial");
1209 }
1210
1211 /* Scan devices looking for input and output devices */
1212 list_for_each(pos, list) {
1213 dev = list_entry(pos, struct stdio_dev, list);
1214
1215 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
1216 inputdev = dev;
1217 }
1218 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
1219 outputdev = dev;
1220 }
1221 if(inputdev && outputdev)
1222 break;
1223 }
1224
1225 /* Initializes output console first */
1226 if (outputdev != NULL) {
1227 console_setfile_and_devices(stdout, outputdev);
1228 console_setfile_and_devices(stderr, outputdev);
1229 }
1230
1231 /* Initializes input console */
1232 if (inputdev != NULL)
1233 console_setfile_and_devices(stdin, inputdev);
1234
1235 if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET))
1236 stdio_print_current_devices();
1237
1238 /* Setting environment variables */
1239 for (i = 0; i < MAX_FILES; i++) {
1240 env_set(stdio_names[i], stdio_devices[i]->name);
1241 }
1242
1243 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
1244
1245 print_pre_console_buffer(flushpoint);
1246 return 0;
1247 }
1248
1249 #endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
1250
console_remove_by_name(const char * name)1251 int console_remove_by_name(const char *name)
1252 {
1253 int err = 0;
1254
1255 #if CONFIG_IS_ENABLED(CONSOLE_MUX)
1256 int fnum;
1257
1258 log_debug("removing console device %s\n", name);
1259 for (fnum = 0; fnum < MAX_FILES; fnum++) {
1260 struct stdio_dev **src, **dest;
1261 int i;
1262
1263 log_debug("file %d: %d devices: ", fnum, cd_count[fnum]);
1264 src = console_devices[fnum];
1265 dest = src;
1266 for (i = 0; i < cd_count[fnum]; i++, src++) {
1267 struct stdio_dev *sdev = *src;
1268 int ret = 0;
1269
1270 if (!strcmp(sdev->name, name))
1271 ret = stdio_deregister_dev(sdev, true);
1272 else
1273 *dest++ = *src;
1274 if (ret && !err)
1275 err = ret;
1276 }
1277 cd_count[fnum] = dest - console_devices[fnum];
1278 log_debug("now %d\n", cd_count[fnum]);
1279 }
1280 #endif /* CONSOLE_MUX */
1281
1282 return err;
1283 }
1284