]> Git Repo - J-u-boot.git/blame - common/console.c
.gitlab-ci.yml: add Qemu tests for MIPS Malta board
[J-u-boot.git] / common / console.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
47d1a6e1
WD
2/*
3 * (C) Copyright 2000
4 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), [email protected]
47d1a6e1
WD
5 */
6
7#include <common.h>
24b852a7 8#include <console.h>
d6ea5307 9#include <debug_uart.h>
7b3c4c3a 10#include <dm.h>
9fb625ce 11#include <env.h>
47d1a6e1 12#include <stdarg.h>
482f4691 13#include <iomux.h>
47d1a6e1 14#include <malloc.h>
4e6bafa5 15#include <mapmem.h>
91b136c7 16#include <os.h>
849d5d9c 17#include <serial.h>
52cb4d4f 18#include <stdio_dev.h>
27b207fd 19#include <exports.h>
f3998fdc 20#include <env_internal.h>
64407467 21#include <watchdog.h>
c05ed00a 22#include <linux/delay.h>
47d1a6e1 23
d87080b7
WD
24DECLARE_GLOBAL_DATA_PTR;
25
849d5d9c
JH
26static int on_console(const char *name, const char *value, enum env_op op,
27 int flags)
28{
29 int console = -1;
30
31 /* Check for console redirection */
32 if (strcmp(name, "stdin") == 0)
33 console = stdin;
34 else if (strcmp(name, "stdout") == 0)
35 console = stdout;
36 else if (strcmp(name, "stderr") == 0)
37 console = stderr;
38
39 /* if not actually setting a console variable, we don't care */
40 if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0)
41 return 0;
42
43 switch (op) {
44 case env_op_create:
45 case env_op_overwrite:
46
b0265429 47#if CONFIG_IS_ENABLED(CONSOLE_MUX)
849d5d9c
JH
48 if (iomux_doenv(console, value))
49 return 1;
50#else
51 /* Try assigning specified device */
52 if (console_assign(console, value) < 0)
53 return 1;
b0265429 54#endif
849d5d9c
JH
55 return 0;
56
57 case env_op_delete:
58 if ((flags & H_FORCE) == 0)
59 printf("Can't delete \"%s\"\n", name);
60 return 1;
61
62 default:
63 return 0;
64 }
65}
66U_BOOT_ENV_CALLBACK(console, on_console);
67
e080d545
JH
68#ifdef CONFIG_SILENT_CONSOLE
69static int on_silent(const char *name, const char *value, enum env_op op,
70 int flags)
71{
5daf6e56 72#if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET)
e080d545
JH
73 if (flags & H_INTERACTIVE)
74 return 0;
75#endif
5daf6e56 76#if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC)
e080d545
JH
77 if ((flags & H_INTERACTIVE) == 0)
78 return 0;
79#endif
80
81 if (value != NULL)
82 gd->flags |= GD_FLG_SILENT;
83 else
84 gd->flags &= ~GD_FLG_SILENT;
85
86 return 0;
87}
88U_BOOT_ENV_CALLBACK(silent, on_silent);
89#endif
90
b0265429 91#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
47d1a6e1
WD
92/*
93 * if overwrite_console returns 1, the stdin, stderr and stdout
94 * are switched to the serial port, else the settings in the
95 * environment are used
96 */
6d0f6bcf 97#ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
ec6f1499
JCPV
98extern int overwrite_console(void);
99#define OVERWRITE_CONSOLE overwrite_console()
47d1a6e1 100#else
83e40ba7 101#define OVERWRITE_CONSOLE 0
6d0f6bcf 102#endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
47d1a6e1 103
b0265429 104#endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
47d1a6e1 105
52cb4d4f 106static int console_setfile(int file, struct stdio_dev * dev)
47d1a6e1
WD
107{
108 int error = 0;
109
110 if (dev == NULL)
111 return -1;
112
113 switch (file) {
114 case stdin:
115 case stdout:
116 case stderr:
117 /* Start new device */
118 if (dev->start) {
709ea543 119 error = dev->start(dev);
47d1a6e1
WD
120 /* If it's not started dont use it */
121 if (error < 0)
122 break;
123 }
124
125 /* Assign the new device (leaving the existing one started) */
126 stdio_devices[file] = dev;
127
128 /*
129 * Update monitor functions
130 * (to use the console stuff by other applications)
131 */
132 switch (file) {
133 case stdin:
49cad547
MD
134 gd->jt->getc = getc;
135 gd->jt->tstc = tstc;
47d1a6e1
WD
136 break;
137 case stdout:
49cad547
MD
138 gd->jt->putc = putc;
139 gd->jt->puts = puts;
140 gd->jt->printf = printf;
47d1a6e1
WD
141 break;
142 }
143 break;
144
145 default: /* Invalid file ID */
146 error = -1;
147 }
148 return error;
149}
150
42f9f915
SG
151/**
152 * console_dev_is_serial() - Check if a stdio device is a serial device
153 *
154 * @sdev: Device to check
7b3c4c3a
SG
155 * @return true if this device is in the serial uclass (or for pre-driver-model,
156 * whether it is called "serial".
42f9f915
SG
157 */
158static bool console_dev_is_serial(struct stdio_dev *sdev)
159{
160 bool is_serial;
161
7b3c4c3a
SG
162#ifdef CONFIG_DM_SERIAL
163 if (sdev->flags & DEV_FLAGS_DM) {
164 struct udevice *dev = sdev->priv;
165
166 is_serial = device_get_uclass_id(dev) == UCLASS_SERIAL;
167 } else
168#endif
42f9f915
SG
169 is_serial = !strcmp(sdev->name, "serial");
170
171 return is_serial;
172}
173
b0265429 174#if CONFIG_IS_ENABLED(CONSOLE_MUX)
16a28ef2
GJ
175/** Console I/O multiplexing *******************************************/
176
52cb4d4f
JCPV
177static struct stdio_dev *tstcdev;
178struct stdio_dev **console_devices[MAX_FILES];
16a28ef2
GJ
179int cd_count[MAX_FILES];
180
181/*
182 * This depends on tstc() always being called before getc().
183 * This is guaranteed to be true because this routine is called
184 * only from fgetc() which assures it.
185 * No attempt is made to demultiplex multiple input sources.
186 */
5f032010 187static int console_getc(int file)
16a28ef2
GJ
188{
189 unsigned char ret;
190
191 /* This is never called with testcdev == NULL */
709ea543 192 ret = tstcdev->getc(tstcdev);
16a28ef2
GJ
193 tstcdev = NULL;
194 return ret;
195}
196
5f032010 197static int console_tstc(int file)
16a28ef2
GJ
198{
199 int i, ret;
52cb4d4f 200 struct stdio_dev *dev;
b2f58d8e 201 int prev;
16a28ef2 202
b2f58d8e 203 prev = disable_ctrlc(1);
16a28ef2
GJ
204 for (i = 0; i < cd_count[file]; i++) {
205 dev = console_devices[file][i];
206 if (dev->tstc != NULL) {
709ea543 207 ret = dev->tstc(dev);
16a28ef2
GJ
208 if (ret > 0) {
209 tstcdev = dev;
b2f58d8e 210 disable_ctrlc(prev);
16a28ef2
GJ
211 return ret;
212 }
213 }
214 }
b2f58d8e 215 disable_ctrlc(prev);
16a28ef2
GJ
216
217 return 0;
218}
219
5f032010 220static void console_putc(int file, const char c)
16a28ef2
GJ
221{
222 int i;
52cb4d4f 223 struct stdio_dev *dev;
16a28ef2
GJ
224
225 for (i = 0; i < cd_count[file]; i++) {
226 dev = console_devices[file][i];
227 if (dev->putc != NULL)
709ea543 228 dev->putc(dev, c);
16a28ef2
GJ
229 }
230}
231
a8552c7c 232static void console_puts_noserial(int file, const char *s)
27669667
SS
233{
234 int i;
235 struct stdio_dev *dev;
236
237 for (i = 0; i < cd_count[file]; i++) {
238 dev = console_devices[file][i];
42f9f915 239 if (dev->puts != NULL && !console_dev_is_serial(dev))
a8552c7c 240 dev->puts(dev, s);
27669667
SS
241 }
242}
27669667 243
5f032010 244static void console_puts(int file, const char *s)
16a28ef2
GJ
245{
246 int i;
52cb4d4f 247 struct stdio_dev *dev;
16a28ef2
GJ
248
249 for (i = 0; i < cd_count[file]; i++) {
250 dev = console_devices[file][i];
251 if (dev->puts != NULL)
709ea543 252 dev->puts(dev, s);
16a28ef2
GJ
253 }
254}
5f032010 255
5e63c96a 256#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
52cb4d4f 257static inline void console_doenv(int file, struct stdio_dev *dev)
5f032010
JCPV
258{
259 iomux_doenv(file, dev->name);
260}
5e63c96a 261#endif
5f032010
JCPV
262#else
263static inline int console_getc(int file)
264{
709ea543 265 return stdio_devices[file]->getc(stdio_devices[file]);
5f032010
JCPV
266}
267
268static inline int console_tstc(int file)
269{
709ea543 270 return stdio_devices[file]->tstc(stdio_devices[file]);
5f032010
JCPV
271}
272
273static inline void console_putc(int file, const char c)
274{
709ea543 275 stdio_devices[file]->putc(stdio_devices[file], c);
5f032010
JCPV
276}
277
a8552c7c 278static inline void console_puts_noserial(int file, const char *s)
27669667 279{
42f9f915 280 if (!console_dev_is_serial(stdio_devices[file]))
a8552c7c 281 stdio_devices[file]->puts(stdio_devices[file], s);
27669667 282}
27669667 283
5f032010
JCPV
284static inline void console_puts(int file, const char *s)
285{
709ea543 286 stdio_devices[file]->puts(stdio_devices[file], s);
5f032010
JCPV
287}
288
5e63c96a 289#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
52cb4d4f 290static inline void console_doenv(int file, struct stdio_dev *dev)
5f032010
JCPV
291{
292 console_setfile(file, dev);
293}
5e63c96a 294#endif
b0265429 295#endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
16a28ef2 296
47d1a6e1
WD
297/** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
298
d9c27253 299int serial_printf(const char *fmt, ...)
47d1a6e1
WD
300{
301 va_list args;
302 uint i;
6d0f6bcf 303 char printbuffer[CONFIG_SYS_PBSIZE];
47d1a6e1 304
ec6f1499 305 va_start(args, fmt);
47d1a6e1
WD
306
307 /* For this to work, printbuffer must be larger than
308 * anything we ever want to print.
309 */
068af6f8 310 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
ec6f1499 311 va_end(args);
47d1a6e1 312
ec6f1499 313 serial_puts(printbuffer);
d9c27253 314 return i;
47d1a6e1
WD
315}
316
ec6f1499 317int fgetc(int file)
47d1a6e1 318{
16a28ef2 319 if (file < MAX_FILES) {
16a28ef2
GJ
320 /*
321 * Effectively poll for input wherever it may be available.
322 */
323 for (;;) {
64407467 324 WATCHDOG_RESET();
273a1252 325#if CONFIG_IS_ENABLED(CONSOLE_MUX)
16a28ef2
GJ
326 /*
327 * Upper layer may have already called tstc() so
328 * check for that first.
329 */
330 if (tstcdev != NULL)
5f032010
JCPV
331 return console_getc(file);
332 console_tstc(file);
273a1252
PD
333#else
334 if (console_tstc(file))
335 return console_getc(file);
336#endif
16a28ef2
GJ
337#ifdef CONFIG_WATCHDOG
338 /*
339 * If the watchdog must be rate-limited then it should
340 * already be handled in board-specific code.
341 */
342 udelay(1);
343#endif
344 }
16a28ef2 345 }
47d1a6e1
WD
346
347 return -1;
348}
349
ec6f1499 350int ftstc(int file)
47d1a6e1
WD
351{
352 if (file < MAX_FILES)
5f032010 353 return console_tstc(file);
47d1a6e1
WD
354
355 return -1;
356}
357
ec6f1499 358void fputc(int file, const char c)
47d1a6e1
WD
359{
360 if (file < MAX_FILES)
5f032010 361 console_putc(file, c);
47d1a6e1
WD
362}
363
ec6f1499 364void fputs(int file, const char *s)
47d1a6e1
WD
365{
366 if (file < MAX_FILES)
5f032010 367 console_puts(file, s);
47d1a6e1
WD
368}
369
d9c27253 370int fprintf(int file, const char *fmt, ...)
47d1a6e1
WD
371{
372 va_list args;
373 uint i;
6d0f6bcf 374 char printbuffer[CONFIG_SYS_PBSIZE];
47d1a6e1 375
ec6f1499 376 va_start(args, fmt);
47d1a6e1
WD
377
378 /* For this to work, printbuffer must be larger than
379 * anything we ever want to print.
380 */
068af6f8 381 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
ec6f1499 382 va_end(args);
47d1a6e1
WD
383
384 /* Send to desired file */
ec6f1499 385 fputs(file, printbuffer);
d9c27253 386 return i;
47d1a6e1
WD
387}
388
389/** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
390
ec6f1499 391int getc(void)
47d1a6e1 392{
f5c3ba79
MJ
393#ifdef CONFIG_DISABLE_CONSOLE
394 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
395 return 0;
396#endif
397
e3e454cd
GR
398 if (!gd->have_console)
399 return 0;
400
9854a874
SG
401#ifdef CONFIG_CONSOLE_RECORD
402 if (gd->console_in.start) {
403 int ch;
404
a3a9e046 405 ch = membuff_getbyte((struct membuff *)&gd->console_in);
9854a874
SG
406 if (ch != -1)
407 return 1;
408 }
409#endif
47d1a6e1
WD
410 if (gd->flags & GD_FLG_DEVINIT) {
411 /* Get from the standard input */
ec6f1499 412 return fgetc(stdin);
47d1a6e1
WD
413 }
414
415 /* Send directly to the handler */
ec6f1499 416 return serial_getc();
47d1a6e1
WD
417}
418
ec6f1499 419int tstc(void)
47d1a6e1 420{
f5c3ba79
MJ
421#ifdef CONFIG_DISABLE_CONSOLE
422 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
423 return 0;
424#endif
425
e3e454cd
GR
426 if (!gd->have_console)
427 return 0;
9854a874
SG
428#ifdef CONFIG_CONSOLE_RECORD
429 if (gd->console_in.start) {
a3a9e046 430 if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1)
9854a874
SG
431 return 1;
432 }
433#endif
47d1a6e1
WD
434 if (gd->flags & GD_FLG_DEVINIT) {
435 /* Test the standard input */
ec6f1499 436 return ftstc(stdin);
47d1a6e1
WD
437 }
438
439 /* Send directly to the handler */
ec6f1499 440 return serial_tstc();
47d1a6e1
WD
441}
442
27669667
SS
443#define PRE_CONSOLE_FLUSHPOINT1_SERIAL 0
444#define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL 1
445
8f925584 446#if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
9558b48a
GR
447#define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ)
448
449static void pre_console_putc(const char c)
450{
4e6bafa5
SG
451 char *buffer;
452
453 buffer = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
9558b48a
GR
454
455 buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c;
4e6bafa5
SG
456
457 unmap_sysmem(buffer);
9558b48a
GR
458}
459
be135cc5
SM
460static void pre_console_puts(const char *s)
461{
462 while (*s)
463 pre_console_putc(*s++);
464}
465
27669667 466static void print_pre_console_buffer(int flushpoint)
9558b48a 467{
a8552c7c 468 unsigned long in = 0, out = 0;
a8552c7c 469 char buf_out[CONFIG_PRE_CON_BUF_SZ + 1];
4e6bafa5 470 char *buf_in;
9558b48a 471
13551b91
PD
472#ifdef CONFIG_SILENT_CONSOLE
473 if (gd->flags & GD_FLG_SILENT)
474 return;
475#endif
476
4e6bafa5 477 buf_in = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
9558b48a 478 if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ)
a8552c7c 479 in = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
9558b48a 480
a8552c7c
HG
481 while (in < gd->precon_buf_idx)
482 buf_out[out++] = buf_in[CIRC_BUF_IDX(in++)];
4e6bafa5 483 unmap_sysmem(buf_in);
a8552c7c
HG
484
485 buf_out[out] = 0;
486
487 switch (flushpoint) {
488 case PRE_CONSOLE_FLUSHPOINT1_SERIAL:
489 puts(buf_out);
490 break;
491 case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL:
492 console_puts_noserial(stdout, buf_out);
493 break;
494 }
9558b48a
GR
495}
496#else
497static inline void pre_console_putc(const char c) {}
be135cc5 498static inline void pre_console_puts(const char *s) {}
27669667 499static inline void print_pre_console_buffer(int flushpoint) {}
9558b48a
GR
500#endif
501
ec6f1499 502void putc(const char c)
47d1a6e1 503{
64e9b4f3
SG
504#ifdef CONFIG_SANDBOX
505 /* sandbox can send characters to stdout before it has a console */
506 if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
507 os_putc(c);
508 return;
509 }
510#endif
d6ea5307
SG
511#ifdef CONFIG_DEBUG_UART
512 /* if we don't have a console yet, use the debug UART */
513 if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
514 printch(c);
515 return;
516 }
517#endif
af880e24
SG
518 if (!gd)
519 return;
9854a874 520#ifdef CONFIG_CONSOLE_RECORD
af880e24 521 if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start)
a3a9e046 522 membuff_putbyte((struct membuff *)&gd->console_out, c);
9854a874 523#endif
a6cccaea 524#ifdef CONFIG_SILENT_CONSOLE
13551b91
PD
525 if (gd->flags & GD_FLG_SILENT) {
526 if (!(gd->flags & GD_FLG_DEVINIT))
527 pre_console_putc(c);
f6e20fc6 528 return;
13551b91 529 }
a6cccaea
WD
530#endif
531
f5c3ba79
MJ
532#ifdef CONFIG_DISABLE_CONSOLE
533 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
534 return;
535#endif
536
e3e454cd 537 if (!gd->have_console)
9558b48a 538 return pre_console_putc(c);
e3e454cd 539
47d1a6e1
WD
540 if (gd->flags & GD_FLG_DEVINIT) {
541 /* Send to the standard output */
ec6f1499 542 fputc(stdout, c);
47d1a6e1
WD
543 } else {
544 /* Send directly to the handler */
27669667 545 pre_console_putc(c);
ec6f1499 546 serial_putc(c);
47d1a6e1
WD
547 }
548}
549
ec6f1499 550void puts(const char *s)
47d1a6e1 551{
36bcea62
SG
552#ifdef CONFIG_SANDBOX
553 /* sandbox can send characters to stdout before it has a console */
554 if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
555 os_puts(s);
556 return;
557 }
558#endif
be135cc5
SM
559#ifdef CONFIG_DEBUG_UART
560 if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
561 while (*s) {
562 int ch = *s++;
563
564 printch(ch);
565 }
566 return;
567 }
568#endif
af880e24
SG
569 if (!gd)
570 return;
be135cc5 571#ifdef CONFIG_CONSOLE_RECORD
af880e24 572 if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start)
a3a9e046 573 membuff_put((struct membuff *)&gd->console_out, s, strlen(s));
be135cc5
SM
574#endif
575#ifdef CONFIG_SILENT_CONSOLE
13551b91
PD
576 if (gd->flags & GD_FLG_SILENT) {
577 if (!(gd->flags & GD_FLG_DEVINIT))
578 pre_console_puts(s);
be135cc5 579 return;
13551b91 580 }
be135cc5
SM
581#endif
582
583#ifdef CONFIG_DISABLE_CONSOLE
584 if (gd->flags & GD_FLG_DISABLE_CONSOLE)
585 return;
586#endif
587
588 if (!gd->have_console)
589 return pre_console_puts(s);
590
591 if (gd->flags & GD_FLG_DEVINIT) {
592 /* Send to the standard output */
593 fputs(stdout, s);
594 } else {
595 /* Send directly to the handler */
596 pre_console_puts(s);
597 serial_puts(s);
598 }
47d1a6e1
WD
599}
600
9854a874
SG
601#ifdef CONFIG_CONSOLE_RECORD
602int console_record_init(void)
603{
604 int ret;
605
a3a9e046
HS
606 ret = membuff_new((struct membuff *)&gd->console_out,
607 CONFIG_CONSOLE_RECORD_OUT_SIZE);
9854a874
SG
608 if (ret)
609 return ret;
a3a9e046
HS
610 ret = membuff_new((struct membuff *)&gd->console_in,
611 CONFIG_CONSOLE_RECORD_IN_SIZE);
9854a874
SG
612
613 return ret;
614}
615
616void console_record_reset(void)
617{
a3a9e046
HS
618 membuff_purge((struct membuff *)&gd->console_out);
619 membuff_purge((struct membuff *)&gd->console_in);
9854a874
SG
620}
621
622void console_record_reset_enable(void)
623{
624 console_record_reset();
625 gd->flags |= GD_FLG_RECORD;
626}
b6123128
SG
627
628int console_record_readline(char *str, int maxlen)
629{
a3a9e046
HS
630 return membuff_readline((struct membuff *)&gd->console_out, str,
631 maxlen, ' ');
b6123128
SG
632}
633
634int console_record_avail(void)
635{
a3a9e046 636 return membuff_avail((struct membuff *)&gd->console_out);
b6123128
SG
637}
638
9854a874
SG
639#endif
640
47d1a6e1
WD
641/* test if ctrl-c was pressed */
642static int ctrlc_disabled = 0; /* see disable_ctrl() */
643static int ctrlc_was_pressed = 0;
ec6f1499 644int ctrlc(void)
47d1a6e1 645{
47d1a6e1 646 if (!ctrlc_disabled && gd->have_console) {
ec6f1499
JCPV
647 if (tstc()) {
648 switch (getc()) {
47d1a6e1
WD
649 case 0x03: /* ^C - Control C */
650 ctrlc_was_pressed = 1;
651 return 1;
652 default:
653 break;
654 }
655 }
656 }
8969ea3e 657
47d1a6e1
WD
658 return 0;
659}
a5dffa4b
PA
660/* Reads user's confirmation.
661 Returns 1 if user's input is "y", "Y", "yes" or "YES"
662*/
663int confirm_yesno(void)
664{
665 int i;
666 char str_input[5];
667
668 /* Flush input */
669 while (tstc())
670 getc();
671 i = 0;
672 while (i < sizeof(str_input)) {
673 str_input[i] = getc();
674 putc(str_input[i]);
675 if (str_input[i] == '\r')
676 break;
677 i++;
678 }
679 putc('\n');
680 if (strncmp(str_input, "y\r", 2) == 0 ||
681 strncmp(str_input, "Y\r", 2) == 0 ||
682 strncmp(str_input, "yes\r", 4) == 0 ||
683 strncmp(str_input, "YES\r", 4) == 0)
684 return 1;
685 return 0;
686}
47d1a6e1
WD
687/* pass 1 to disable ctrlc() checking, 0 to enable.
688 * returns previous state
689 */
ec6f1499 690int disable_ctrlc(int disable)
47d1a6e1
WD
691{
692 int prev = ctrlc_disabled; /* save previous state */
693
694 ctrlc_disabled = disable;
695 return prev;
696}
697
698int had_ctrlc (void)
699{
700 return ctrlc_was_pressed;
701}
702
ec6f1499 703void clear_ctrlc(void)
47d1a6e1
WD
704{
705 ctrlc_was_pressed = 0;
706}
707
47d1a6e1
WD
708/** U-Boot INIT FUNCTIONS *************************************************/
709
d7be3056 710struct stdio_dev *search_device(int flags, const char *name)
c1de7a6d 711{
52cb4d4f 712 struct stdio_dev *dev;
c1de7a6d 713
52cb4d4f 714 dev = stdio_get_by_name(name);
a2931b30
SG
715#ifdef CONFIG_VIDCONSOLE_AS_LCD
716 if (!dev && !strcmp(name, "lcd"))
717 dev = stdio_get_by_name("vidconsole");
718#endif
c1de7a6d 719
ec6f1499 720 if (dev && (dev->flags & flags))
c1de7a6d
JCPV
721 return dev;
722
723 return NULL;
724}
725
d7be3056 726int console_assign(int file, const char *devname)
47d1a6e1 727{
c1de7a6d 728 int flag;
52cb4d4f 729 struct stdio_dev *dev;
47d1a6e1
WD
730
731 /* Check for valid file */
732 switch (file) {
733 case stdin:
734 flag = DEV_FLAGS_INPUT;
735 break;
736 case stdout:
737 case stderr:
738 flag = DEV_FLAGS_OUTPUT;
739 break;
740 default:
741 return -1;
742 }
743
744 /* Check for valid device name */
745
c1de7a6d 746 dev = search_device(flag, devname);
47d1a6e1 747
ec6f1499
JCPV
748 if (dev)
749 return console_setfile(file, dev);
47d1a6e1
WD
750
751 return -1;
752}
753
13551b91
PD
754/* return true if the 'silent' flag is removed */
755static bool console_update_silent(void)
47d1a6e1 756{
f72da340 757#ifdef CONFIG_SILENT_CONSOLE
13551b91 758 if (env_get("silent")) {
f72da340 759 gd->flags |= GD_FLG_SILENT;
13551b91
PD
760 } else {
761 unsigned long flags = gd->flags;
762
43e0a3de 763 gd->flags &= ~GD_FLG_SILENT;
13551b91
PD
764
765 return !!(flags & GD_FLG_SILENT);
766 }
f72da340 767#endif
13551b91
PD
768
769 return false;
43e0a3de
CP
770}
771
b0895384
SG
772int console_announce_r(void)
773{
774#if !CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
775 char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
776
777 display_options_get_banner(false, buf, sizeof(buf));
778
779 console_puts_noserial(stdout, buf);
780#endif
781
782 return 0;
783}
784
43e0a3de
CP
785/* Called before relocation - use serial functions */
786int console_init_f(void)
787{
788 gd->have_console = 1;
789
790 console_update_silent();
f72da340 791
27669667 792 print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL);
9558b48a 793
ec6f1499 794 return 0;
47d1a6e1
WD
795}
796
7e3be7cf
JCPV
797void stdio_print_current_devices(void)
798{
7e3be7cf
JCPV
799 /* Print information */
800 puts("In: ");
801 if (stdio_devices[stdin] == NULL) {
802 puts("No input devices available!\n");
803 } else {
804 printf ("%s\n", stdio_devices[stdin]->name);
805 }
806
807 puts("Out: ");
808 if (stdio_devices[stdout] == NULL) {
809 puts("No output devices available!\n");
810 } else {
811 printf ("%s\n", stdio_devices[stdout]->name);
812 }
813
814 puts("Err: ");
815 if (stdio_devices[stderr] == NULL) {
816 puts("No error devices available!\n");
817 } else {
818 printf ("%s\n", stdio_devices[stderr]->name);
819 }
7e3be7cf
JCPV
820}
821
b0265429 822#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
47d1a6e1 823/* Called after the relocation - use desired console functions */
ec6f1499 824int console_init_r(void)
47d1a6e1
WD
825{
826 char *stdinname, *stdoutname, *stderrname;
52cb4d4f 827 struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
6d0f6bcf 828#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
6e592385 829 int i;
6d0f6bcf 830#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
b0265429 831#if CONFIG_IS_ENABLED(CONSOLE_MUX)
16a28ef2
GJ
832 int iomux_err = 0;
833#endif
13551b91 834 int flushpoint;
47d1a6e1 835
bf46be72 836 /* update silent for env loaded from flash (initr_env) */
13551b91
PD
837 if (console_update_silent())
838 flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
839 else
840 flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
bf46be72 841
47d1a6e1 842 /* set default handlers at first */
49cad547
MD
843 gd->jt->getc = serial_getc;
844 gd->jt->tstc = serial_tstc;
845 gd->jt->putc = serial_putc;
846 gd->jt->puts = serial_puts;
847 gd->jt->printf = serial_printf;
47d1a6e1
WD
848
849 /* stdin stdout and stderr are in environment */
850 /* scan for it */
00caae6d
SG
851 stdinname = env_get("stdin");
852 stdoutname = env_get("stdout");
853 stderrname = env_get("stderr");
47d1a6e1 854
53677ef1 855 if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */
ec6f1499
JCPV
856 inputdev = search_device(DEV_FLAGS_INPUT, stdinname);
857 outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname);
858 errdev = search_device(DEV_FLAGS_OUTPUT, stderrname);
b0265429 859#if CONFIG_IS_ENABLED(CONSOLE_MUX)
16a28ef2
GJ
860 iomux_err = iomux_doenv(stdin, stdinname);
861 iomux_err += iomux_doenv(stdout, stdoutname);
862 iomux_err += iomux_doenv(stderr, stderrname);
863 if (!iomux_err)
864 /* Successful, so skip all the code below. */
865 goto done;
866#endif
47d1a6e1
WD
867 }
868 /* if the devices are overwritten or not found, use default device */
869 if (inputdev == NULL) {
ec6f1499 870 inputdev = search_device(DEV_FLAGS_INPUT, "serial");
47d1a6e1
WD
871 }
872 if (outputdev == NULL) {
ec6f1499 873 outputdev = search_device(DEV_FLAGS_OUTPUT, "serial");
47d1a6e1
WD
874 }
875 if (errdev == NULL) {
ec6f1499 876 errdev = search_device(DEV_FLAGS_OUTPUT, "serial");
47d1a6e1
WD
877 }
878 /* Initializes output console first */
879 if (outputdev != NULL) {
16a28ef2 880 /* need to set a console if not done above. */
5f032010 881 console_doenv(stdout, outputdev);
47d1a6e1
WD
882 }
883 if (errdev != NULL) {
16a28ef2 884 /* need to set a console if not done above. */
5f032010 885 console_doenv(stderr, errdev);
47d1a6e1
WD
886 }
887 if (inputdev != NULL) {
16a28ef2 888 /* need to set a console if not done above. */
5f032010 889 console_doenv(stdin, inputdev);
47d1a6e1
WD
890 }
891
b0265429 892#if CONFIG_IS_ENABLED(CONSOLE_MUX)
16a28ef2
GJ
893done:
894#endif
895
78c112c9 896#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
7e3be7cf 897 stdio_print_current_devices();
78c112c9 898#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
a2931b30
SG
899#ifdef CONFIG_VIDCONSOLE_AS_LCD
900 if (strstr(stdoutname, "lcd"))
901 printf("Warning: Please change 'lcd' to 'vidconsole' in stdout/stderr environment vars\n");
902#endif
47d1a6e1 903
6d0f6bcf 904#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
47d1a6e1 905 /* set the environment variables (will overwrite previous env settings) */
27b4225b 906 for (i = 0; i < MAX_FILES; i++) {
382bee57 907 env_set(stdio_names[i], stdio_devices[i]->name);
47d1a6e1 908 }
6d0f6bcf 909#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
47d1a6e1 910
c4e0057f
JH
911 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
912
47d1a6e1
WD
913#if 0
914 /* If nothing usable installed, use only the initial console */
915 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
ec6f1499 916 return 0;
47d1a6e1 917#endif
13551b91 918 print_pre_console_buffer(flushpoint);
ec6f1499 919 return 0;
47d1a6e1
WD
920}
921
b0265429 922#else /* !CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
47d1a6e1
WD
923
924/* Called after the relocation - use desired console functions */
ec6f1499 925int console_init_r(void)
47d1a6e1 926{
52cb4d4f 927 struct stdio_dev *inputdev = NULL, *outputdev = NULL;
c1de7a6d 928 int i;
52cb4d4f 929 struct list_head *list = stdio_get_list();
c1de7a6d 930 struct list_head *pos;
52cb4d4f 931 struct stdio_dev *dev;
13551b91 932 int flushpoint;
47d1a6e1 933
bf46be72 934 /* update silent for env loaded from flash (initr_env) */
13551b91
PD
935 if (console_update_silent())
936 flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
937 else
938 flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
43e0a3de 939
d791b1dc 940#ifdef CONFIG_SPLASH_SCREEN
ec6f1499
JCPV
941 /*
942 * suppress all output if splash screen is enabled and we have
a7490816
AG
943 * a bmp to display. We redirect the output from frame buffer
944 * console to serial console in this case or suppress it if
945 * "silent" mode was requested.
ec6f1499 946 */
00caae6d 947 if (env_get("splashimage") != NULL) {
a7490816
AG
948 if (!(gd->flags & GD_FLG_SILENT))
949 outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
950 }
f72da340
WD
951#endif
952
47d1a6e1 953 /* Scan devices looking for input and output devices */
c1de7a6d 954 list_for_each(pos, list) {
52cb4d4f 955 dev = list_entry(pos, struct stdio_dev, list);
47d1a6e1
WD
956
957 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
958 inputdev = dev;
959 }
960 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
961 outputdev = dev;
962 }
c1de7a6d
JCPV
963 if(inputdev && outputdev)
964 break;
47d1a6e1
WD
965 }
966
967 /* Initializes output console first */
968 if (outputdev != NULL) {
ec6f1499
JCPV
969 console_setfile(stdout, outputdev);
970 console_setfile(stderr, outputdev);
b0265429 971#if CONFIG_IS_ENABLED(CONSOLE_MUX)
16a28ef2
GJ
972 console_devices[stdout][0] = outputdev;
973 console_devices[stderr][0] = outputdev;
974#endif
47d1a6e1
WD
975 }
976
977 /* Initializes input console */
978 if (inputdev != NULL) {
ec6f1499 979 console_setfile(stdin, inputdev);
b0265429 980#if CONFIG_IS_ENABLED(CONSOLE_MUX)
16a28ef2
GJ
981 console_devices[stdin][0] = inputdev;
982#endif
47d1a6e1
WD
983 }
984
78c112c9 985#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
7e3be7cf 986 stdio_print_current_devices();
78c112c9 987#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
47d1a6e1
WD
988
989 /* Setting environment variables */
27b4225b 990 for (i = 0; i < MAX_FILES; i++) {
382bee57 991 env_set(stdio_names[i], stdio_devices[i]->name);
47d1a6e1
WD
992 }
993
c4e0057f
JH
994 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
995
47d1a6e1
WD
996#if 0
997 /* If nothing usable installed, use only the initial console */
998 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
ec6f1499 999 return 0;
47d1a6e1 1000#endif
13551b91 1001 print_pre_console_buffer(flushpoint);
ec6f1499 1002 return 0;
47d1a6e1
WD
1003}
1004
b0265429 1005#endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */
This page took 0.616949 seconds and 4 git commands to generate.