"Das U-Boot" Source Tree
at master 1276 lines 28 kB view raw
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 28DECLARE_GLOBAL_DATA_PTR; 29 30#define CSI "\x1b[" 31 32static 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} 73U_BOOT_ENV_CALLBACK(console, on_console); 74 75#ifdef CONFIG_SILENT_CONSOLE 76static 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} 94U_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 */ 99static void console_record_putc(const char c) 100{ 101 if (!(gd->flags & GD_FLG_RECORD)) 102 return; 103 if (gd->console_out.start && 104 !membuff_putbyte((struct membuff *)&gd->console_out, c)) 105 gd->flags |= GD_FLG_RECORD_OVF; 106} 107 108static 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 (membuff_put((struct membuff *)&gd->console_out, s, len) != 116 len) 117 gd->flags |= GD_FLG_RECORD_OVF; 118 } 119} 120 121static 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 membuff_getbyte((struct membuff *)&gd->console_in); 129} 130 131static int console_record_tstc(void) 132{ 133 if (!(gd->flags & GD_FLG_RECORD)) 134 return 0; 135 if (gd->console_in.start) { 136 if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1) 137 return 1; 138 } 139 return 0; 140} 141#else 142static void console_record_putc(char c) 143{ 144} 145 146static void console_record_puts(const char *s) 147{ 148} 149 150static int console_record_getc(void) 151{ 152 return -1; 153} 154 155static 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 168extern 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 176static 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 break; 212#endif 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 */ 226static 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 */ 245static struct stdio_dev *tstcdev; 246struct stdio_dev **console_devices[MAX_FILES]; 247int cd_count[MAX_FILES]; 248 249static 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 */ 266static 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 */ 286static 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 */ 297static bool console_has_tstc(void) 298{ 299 return !!tstcdev; 300} 301 302static 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 324static 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 */ 343static 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 356void 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 362static void console_puts(int file, const char *s) 363{ 364 int i; 365 struct stdio_dev *dev; 366 367 for_each_console_dev(i, file, dev) { 368 if (dev->puts != NULL) 369 dev->puts(dev, s); 370 } 371} 372 373#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT 374static void console_flush(int file) 375{ 376 int i; 377 struct stdio_dev *dev; 378 379 for_each_console_dev(i, file, dev) { 380 if (dev->flush != NULL) 381 dev->flush(dev); 382 } 383} 384#endif 385 386#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) 387static inline void console_doenv(int file, struct stdio_dev *dev) 388{ 389 iomux_doenv(file, dev->name); 390} 391#endif 392#else 393 394static void console_devices_set(int file, struct stdio_dev *dev) 395{ 396} 397 398static inline bool console_needs_start_stop(int file, struct stdio_dev *sdev) 399{ 400 return true; 401} 402 403static inline int console_getc(int file) 404{ 405 return stdio_devices[file]->getc(stdio_devices[file]); 406} 407 408static bool console_has_tstc(void) 409{ 410 return false; 411} 412 413static inline int console_tstc(int file) 414{ 415 return stdio_devices[file]->tstc(stdio_devices[file]); 416} 417 418static inline void console_putc(int file, const char c) 419{ 420 stdio_devices[file]->putc(stdio_devices[file], c); 421} 422 423void console_puts_select(int file, bool serial_only, const char *s) 424{ 425 if ((gd->flags & GD_FLG_DEVINIT) && 426 serial_only == console_dev_is_serial(stdio_devices[file])) 427 stdio_devices[file]->puts(stdio_devices[file], s); 428} 429 430static inline void console_puts(int file, const char *s) 431{ 432 stdio_devices[file]->puts(stdio_devices[file], s); 433} 434 435#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT 436static inline void console_flush(int file) 437{ 438 if (stdio_devices[file]->flush) 439 stdio_devices[file]->flush(stdio_devices[file]); 440} 441#endif 442 443#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) 444static inline void console_doenv(int file, struct stdio_dev *dev) 445{ 446 console_setfile(file, dev); 447} 448#endif 449#endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */ 450 451static void __maybe_unused console_setfile_and_devices(int file, struct stdio_dev *dev) 452{ 453 console_setfile(file, dev); 454 console_devices_set(file, dev); 455} 456 457int console_start(int file, struct stdio_dev *sdev) 458{ 459 int error; 460 461 if (!console_needs_start_stop(file, sdev)) 462 return 0; 463 464 /* Start new device */ 465 if (sdev->start) { 466 error = sdev->start(sdev); 467 /* If it's not started don't use it */ 468 if (error < 0) 469 return error; 470 } 471 return 0; 472} 473 474void console_stop(int file, struct stdio_dev *sdev) 475{ 476 if (!console_needs_start_stop(file, sdev)) 477 return; 478 479 if (sdev->stop) 480 sdev->stop(sdev); 481} 482 483/** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/ 484 485int serial_printf(const char *fmt, ...) 486{ 487 va_list args; 488 uint i; 489 char printbuffer[CONFIG_SYS_PBSIZE]; 490 491 va_start(args, fmt); 492 493 /* For this to work, printbuffer must be larger than 494 * anything we ever want to print. 495 */ 496 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); 497 va_end(args); 498 499 serial_puts(printbuffer); 500 return i; 501} 502 503int fgetc(int file) 504{ 505 if ((unsigned int)file < MAX_FILES) { 506 /* 507 * Effectively poll for input wherever it may be available. 508 */ 509 for (;;) { 510 schedule(); 511 if (CONFIG_IS_ENABLED(CONSOLE_MUX)) { 512 /* 513 * Upper layer may have already called tstc() so 514 * check for that first. 515 */ 516 if (console_has_tstc()) 517 return console_getc(file); 518 console_tstc(file); 519 } else { 520 if (console_tstc(file)) 521 return console_getc(file); 522 } 523 524 /* 525 * If the watchdog must be rate-limited then it should 526 * already be handled in board-specific code. 527 */ 528 if (IS_ENABLED(CONFIG_WATCHDOG)) 529 udelay(1); 530 } 531 } 532 533 return -1; 534} 535 536int ftstc(int file) 537{ 538 if ((unsigned int)file < MAX_FILES) 539 return console_tstc(file); 540 541 return -1; 542} 543 544void fputc(int file, const char c) 545{ 546 if ((unsigned int)file < MAX_FILES) 547 console_putc(file, c); 548} 549 550void fputs(int file, const char *s) 551{ 552 if ((unsigned int)file < MAX_FILES) 553 console_puts(file, s); 554} 555 556#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT 557void fflush(int file) 558{ 559 if ((unsigned int)file < MAX_FILES) 560 console_flush(file); 561} 562#endif 563 564int fprintf(int file, const char *fmt, ...) 565{ 566 va_list args; 567 uint i; 568 char printbuffer[CONFIG_SYS_PBSIZE]; 569 570 va_start(args, fmt); 571 572 /* For this to work, printbuffer must be larger than 573 * anything we ever want to print. 574 */ 575 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); 576 va_end(args); 577 578 /* Send to desired file */ 579 fputs(file, printbuffer); 580 return i; 581} 582 583/** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/ 584 585int getchar(void) 586{ 587 int ch; 588 589 if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) 590 return 0; 591 592 if (!(gd->flags & GD_FLG_HAVE_CONSOLE)) 593 return 0; 594 595 ch = console_record_getc(); 596 if (ch != -1) 597 return ch; 598 599 if (gd->flags & GD_FLG_DEVINIT) { 600 /* Get from the standard input */ 601 return fgetc(stdin); 602 } 603 604 /* Send directly to the handler */ 605 return serial_getc(); 606} 607 608int tstc(void) 609{ 610 if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) 611 return 0; 612 613 if (!(gd->flags & GD_FLG_HAVE_CONSOLE)) 614 return 0; 615 616 if (console_record_tstc()) 617 return 1; 618 619 if (gd->flags & GD_FLG_DEVINIT) { 620 /* Test the standard input */ 621 return ftstc(stdin); 622 } 623 624 /* Send directly to the handler */ 625 return serial_tstc(); 626} 627 628#define PRE_CONSOLE_FLUSHPOINT1_SERIAL 0 629#define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL 1 630 631#if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER) 632#define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_VAL(PRE_CON_BUF_SZ)) 633 634static void pre_console_putc(const char c) 635{ 636 char *buffer; 637 638 if (gd->precon_buf_idx < 0) 639 return; 640 641 buffer = map_sysmem(CONFIG_VAL(PRE_CON_BUF_ADDR), CONFIG_VAL(PRE_CON_BUF_SZ)); 642 643 buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c; 644 645 unmap_sysmem(buffer); 646} 647 648static void pre_console_puts(const char *s) 649{ 650 if (gd->precon_buf_idx < 0) 651 return; 652 653 while (*s) 654 pre_console_putc(*s++); 655} 656 657static void print_pre_console_buffer(int flushpoint) 658{ 659 long in = 0, out = 0; 660 char buf_out[CONFIG_VAL(PRE_CON_BUF_SZ) + 1]; 661 char *buf_in; 662 663 if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) 664 return; 665 666 buf_in = map_sysmem(CONFIG_VAL(PRE_CON_BUF_ADDR), CONFIG_VAL(PRE_CON_BUF_SZ)); 667 if (gd->precon_buf_idx > CONFIG_VAL(PRE_CON_BUF_SZ)) 668 in = gd->precon_buf_idx - CONFIG_VAL(PRE_CON_BUF_SZ); 669 670 while (in < gd->precon_buf_idx) 671 buf_out[out++] = buf_in[CIRC_BUF_IDX(in++)]; 672 unmap_sysmem(buf_in); 673 674 buf_out[out] = 0; 675 676 gd->precon_buf_idx = -1; 677 switch (flushpoint) { 678 case PRE_CONSOLE_FLUSHPOINT1_SERIAL: 679 puts(buf_out); 680 break; 681 case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL: 682 console_puts_select(stdout, false, buf_out); 683 break; 684 } 685 gd->precon_buf_idx = in; 686} 687#else 688static inline void pre_console_putc(const char c) {} 689static inline void pre_console_puts(const char *s) {} 690static inline void print_pre_console_buffer(int flushpoint) {} 691#endif 692 693void putc(const char c) 694{ 695 if (!gd) 696 return; 697 698 console_record_putc(c); 699 700 /* sandbox can send characters to stdout before it has a console */ 701 if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) { 702 os_putc(c); 703 return; 704 } 705 706 /* if we don't have a console yet, use the debug UART */ 707 if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) { 708 printch(c); 709 return; 710 } 711 712 if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) { 713 if (!(gd->flags & GD_FLG_DEVINIT)) 714 pre_console_putc(c); 715 return; 716 } 717 718 if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) 719 return; 720 721 if (!(gd->flags & GD_FLG_HAVE_CONSOLE)) 722 return pre_console_putc(c); 723 724 if (gd->flags & GD_FLG_DEVINIT) { 725 /* Send to the standard output */ 726 fputc(stdout, c); 727 } else { 728 /* Send directly to the handler */ 729 pre_console_putc(c); 730 serial_putc(c); 731 } 732} 733 734void puts(const char *s) 735{ 736 if (!gd) 737 return; 738 739 console_record_puts(s); 740 741 /* sandbox can send characters to stdout before it has a console */ 742 if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) { 743 os_puts(s); 744 return; 745 } 746 747 if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) { 748 printascii(s); 749 return; 750 } 751 752 if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) { 753 if (!(gd->flags & GD_FLG_DEVINIT)) 754 pre_console_puts(s); 755 return; 756 } 757 758 if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) 759 return; 760 761 if (!(gd->flags & GD_FLG_HAVE_CONSOLE)) 762 return pre_console_puts(s); 763 764 if (gd->flags & GD_FLG_DEVINIT) { 765 /* Send to the standard output */ 766 fputs(stdout, s); 767 } else { 768 /* Send directly to the handler */ 769 pre_console_puts(s); 770 serial_puts(s); 771 } 772} 773 774#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT 775void flush(void) 776{ 777 if (!gd) 778 return; 779 780 /* sandbox can send characters to stdout before it has a console */ 781 if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) { 782 os_flush(); 783 return; 784 } 785 786 if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) 787 return; 788 789 if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) 790 return; 791 792 if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) 793 return; 794 795 if (!(gd->flags & GD_FLG_HAVE_CONSOLE)) 796 return; 797 798 if (gd->flags & GD_FLG_DEVINIT) { 799 /* Send to the standard output */ 800 fflush(stdout); 801 } else { 802 /* Send directly to the handler */ 803 serial_flush(); 804 } 805} 806#endif 807 808#ifdef CONFIG_CONSOLE_RECORD 809int console_record_init(void) 810{ 811 int ret; 812 813 ret = membuff_new((struct membuff *)&gd->console_out, 814 gd->flags & GD_FLG_RELOC ? 815 CONFIG_CONSOLE_RECORD_OUT_SIZE : 816 CONFIG_CONSOLE_RECORD_OUT_SIZE_F); 817 if (ret) 818 return ret; 819 ret = membuff_new((struct membuff *)&gd->console_in, 820 CONFIG_CONSOLE_RECORD_IN_SIZE); 821 822 /* Start recording from the beginning */ 823 gd->flags |= GD_FLG_RECORD; 824 825 return ret; 826} 827 828void console_record_reset(void) 829{ 830 membuff_purge((struct membuff *)&gd->console_out); 831 membuff_purge((struct membuff *)&gd->console_in); 832 gd->flags &= ~GD_FLG_RECORD_OVF; 833} 834 835int console_record_reset_enable(void) 836{ 837 console_record_reset(); 838 gd->flags |= GD_FLG_RECORD; 839 840 return 0; 841} 842 843int console_record_readline(char *str, int maxlen) 844{ 845 if (gd->flags & GD_FLG_RECORD_OVF) 846 return -ENOSPC; 847 if (console_record_isempty()) 848 return -ENOENT; 849 850 return membuff_readline((struct membuff *)&gd->console_out, str, 851 maxlen, '\0', false); 852} 853 854int console_record_avail(void) 855{ 856 return membuff_avail((struct membuff *)&gd->console_out); 857} 858 859bool console_record_isempty(void) 860{ 861 return membuff_isempty((struct membuff *)&gd->console_out); 862} 863 864int console_in_puts(const char *str) 865{ 866 return membuff_put((struct membuff *)&gd->console_in, str, strlen(str)); 867} 868 869#endif 870 871/* test if ctrl-c was pressed */ 872static int ctrlc_disabled = 0; /* see disable_ctrl() */ 873static int ctrlc_was_pressed = 0; 874int ctrlc(void) 875{ 876 if (!ctrlc_disabled && (gd->flags & GD_FLG_HAVE_CONSOLE)) { 877 if (tstc()) { 878 switch (getchar()) { 879 case 0x03: /* ^C - Control C */ 880 ctrlc_was_pressed = 1; 881 return 1; 882 default: 883 break; 884 } 885 } 886 } 887 888 return 0; 889} 890/* Reads user's confirmation. 891 Returns 1 if user's input is "y", "Y", "yes" or "YES" 892*/ 893int confirm_yesno(void) 894{ 895 int i; 896 char str_input[5]; 897 898 /* Flush input */ 899 while (tstc()) 900 getchar(); 901 i = 0; 902 while (i < sizeof(str_input)) { 903 str_input[i] = getchar(); 904 putc(str_input[i]); 905 if (str_input[i] == '\r') 906 break; 907 i++; 908 } 909 putc('\n'); 910 if (strncmp(str_input, "y\r", 2) == 0 || 911 strncmp(str_input, "Y\r", 2) == 0 || 912 strncmp(str_input, "yes\r", 4) == 0 || 913 strncmp(str_input, "YES\r", 4) == 0) 914 return 1; 915 return 0; 916} 917/* pass 1 to disable ctrlc() checking, 0 to enable. 918 * returns previous state 919 */ 920int disable_ctrlc(int disable) 921{ 922 int prev = ctrlc_disabled; /* save previous state */ 923 924 ctrlc_disabled = disable; 925 return prev; 926} 927 928int had_ctrlc (void) 929{ 930 return ctrlc_was_pressed; 931} 932 933void clear_ctrlc(void) 934{ 935 ctrlc_was_pressed = 0; 936} 937 938/** U-Boot INIT FUNCTIONS *************************************************/ 939 940struct stdio_dev *console_search_dev(int flags, const char *name) 941{ 942 struct stdio_dev *dev; 943 944 dev = stdio_get_by_name(name); 945#ifdef CONFIG_VIDCONSOLE_AS_LCD 946 if (!dev && !strcmp(name, CONFIG_VIDCONSOLE_AS_NAME)) 947 dev = stdio_get_by_name("vidconsole"); 948#endif 949 950 if (dev && (dev->flags & flags)) 951 return dev; 952 953 return NULL; 954} 955 956int console_assign(int file, const char *devname) 957{ 958 int flag; 959 struct stdio_dev *dev; 960 961 /* Check for valid file */ 962 flag = stdio_file_to_flags(file); 963 if (flag < 0) 964 return flag; 965 966 /* Check for valid device name */ 967 968 dev = console_search_dev(flag, devname); 969 970 if (dev) 971 return console_setfile(file, dev); 972 973 return -1; 974} 975 976/* return true if the 'silent' flag is removed */ 977static bool console_update_silent(void) 978{ 979 unsigned long flags = gd->flags; 980 981 if (!IS_ENABLED(CONFIG_SILENT_CONSOLE)) 982 return false; 983 984 if (IS_ENABLED(CONFIG_SILENT_CONSOLE_UNTIL_ENV) && !(gd->flags & GD_FLG_ENV_READY)) { 985 gd->flags |= GD_FLG_SILENT; 986 return false; 987 } 988 989 if (env_get("silent")) { 990 gd->flags |= GD_FLG_SILENT; 991 return false; 992 } 993 994 gd->flags &= ~GD_FLG_SILENT; 995 996 return !!(flags & GD_FLG_SILENT); 997} 998 999int console_announce_r(void) 1000{ 1001#if !CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER) 1002 char buf[DISPLAY_OPTIONS_BANNER_LENGTH]; 1003 1004 display_options_get_banner(false, buf, sizeof(buf)); 1005 1006 console_puts_select(stdout, false, buf); 1007#endif 1008 1009 return 0; 1010} 1011 1012/* Called before relocation - use serial functions */ 1013int console_init_f(void) 1014{ 1015 gd->flags |= GD_FLG_HAVE_CONSOLE; 1016 1017 console_update_silent(); 1018 1019 print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL); 1020 1021 return 0; 1022} 1023 1024int console_clear(void) 1025{ 1026 /* 1027 * Send clear screen and home 1028 * 1029 * FIXME(Heinrich Schuchardt <xypron.glpk@gmx.de>): This should go 1030 * through an API and only be written to serial terminals, not video 1031 * displays 1032 */ 1033 printf(CSI "2J" CSI "1;1H"); 1034 if (IS_ENABLED(CONFIG_VIDEO_ANSI)) 1035 return 0; 1036 1037 if (IS_ENABLED(CONFIG_VIDEO)) { 1038 struct udevice *dev; 1039 int ret; 1040 1041 ret = uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev); 1042 if (ret) 1043 return ret; 1044 ret = vidconsole_clear_and_reset(dev); 1045 if (ret) 1046 return ret; 1047 } 1048 1049 return 0; 1050} 1051 1052static char *get_stdio(const u8 std) 1053{ 1054 return stdio_devices[std] ? stdio_devices[std]->name : "No devices available!"; 1055} 1056 1057static void stdio_print_current_devices(void) 1058{ 1059 char *stdinname = NULL; 1060 char *stdoutname = NULL; 1061 char *stderrname = NULL; 1062 1063 if (CONFIG_IS_ENABLED(CONSOLE_MUX) && 1064 CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)) { 1065 /* stdin stdout and stderr are in environment */ 1066 stdinname = env_get("stdin"); 1067 stdoutname = env_get("stdout"); 1068 stderrname = env_get("stderr"); 1069 } 1070 1071 stdinname = stdinname ? : get_stdio(stdin); 1072 stdoutname = stdoutname ? : get_stdio(stdout); 1073 stderrname = stderrname ? : get_stdio(stderr); 1074 1075 /* Print information */ 1076 puts("In: "); 1077 printf("%s\n", stdinname); 1078 1079 puts("Out: "); 1080 printf("%s\n", stdoutname); 1081 1082 puts("Err: "); 1083 printf("%s\n", stderrname); 1084} 1085 1086#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) 1087/* Called after the relocation - use desired console functions */ 1088int console_init_r(void) 1089{ 1090 char *stdinname, *stdoutname, *stderrname; 1091 struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL; 1092 int i; 1093 int iomux_err = 0; 1094 int flushpoint; 1095 1096 /* update silent for env loaded from flash (initr_env) */ 1097 if (console_update_silent()) 1098 flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL; 1099 else 1100 flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL; 1101 1102 /* set default handlers at first */ 1103 gd->jt->getc = serial_getc; 1104 gd->jt->tstc = serial_tstc; 1105 gd->jt->putc = serial_putc; 1106 gd->jt->puts = serial_puts; 1107 gd->jt->printf = serial_printf; 1108 1109 /* stdin stdout and stderr are in environment */ 1110 /* scan for it */ 1111 stdinname = env_get("stdin"); 1112 stdoutname = env_get("stdout"); 1113 stderrname = env_get("stderr"); 1114 1115 if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */ 1116 inputdev = console_search_dev(DEV_FLAGS_INPUT, stdinname); 1117 outputdev = console_search_dev(DEV_FLAGS_OUTPUT, stdoutname); 1118 errdev = console_search_dev(DEV_FLAGS_OUTPUT, stderrname); 1119 if (CONFIG_IS_ENABLED(CONSOLE_MUX)) { 1120 iomux_err = iomux_doenv(stdin, stdinname); 1121 iomux_err += iomux_doenv(stdout, stdoutname); 1122 iomux_err += iomux_doenv(stderr, stderrname); 1123 if (!iomux_err) 1124 /* Successful, so skip all the code below. */ 1125 goto done; 1126 } 1127 } 1128 /* if the devices are overwritten or not found, use default device */ 1129 if (inputdev == NULL) { 1130 inputdev = console_search_dev(DEV_FLAGS_INPUT, "serial"); 1131 } 1132 if (outputdev == NULL) { 1133 outputdev = console_search_dev(DEV_FLAGS_OUTPUT, "serial"); 1134 } 1135 if (errdev == NULL) { 1136 errdev = console_search_dev(DEV_FLAGS_OUTPUT, "serial"); 1137 } 1138 /* Initializes output console first */ 1139 if (outputdev != NULL) { 1140 /* need to set a console if not done above. */ 1141 console_doenv(stdout, outputdev); 1142 } 1143 if (errdev != NULL) { 1144 /* need to set a console if not done above. */ 1145 console_doenv(stderr, errdev); 1146 } 1147 if (inputdev != NULL) { 1148 /* need to set a console if not done above. */ 1149 console_doenv(stdin, inputdev); 1150 } 1151 1152done: 1153 1154 if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET)) 1155 stdio_print_current_devices(); 1156 1157#ifdef CONFIG_VIDCONSOLE_AS_LCD 1158 if (strstr(stdoutname, CONFIG_VIDCONSOLE_AS_NAME)) 1159 printf("Warning: Please change '%s' to 'vidconsole' in stdout/stderr environment vars\n", 1160 CONFIG_VIDCONSOLE_AS_NAME); 1161#endif 1162 1163 if (IS_ENABLED(CONFIG_SYS_CONSOLE_ENV_OVERWRITE)) { 1164 /* set the environment variables (will overwrite previous env settings) */ 1165 for (i = 0; i < MAX_FILES; i++) 1166 env_set(stdio_names[i], stdio_devices[i]->name); 1167 } 1168 1169 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 1170 1171 print_pre_console_buffer(flushpoint); 1172 return 0; 1173} 1174 1175#else /* !CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */ 1176 1177/* Called after the relocation - use desired console functions */ 1178int console_init_r(void) 1179{ 1180 struct stdio_dev *inputdev = NULL, *outputdev = NULL; 1181 int i; 1182 struct list_head *list = stdio_get_list(); 1183 struct list_head *pos; 1184 struct stdio_dev *dev; 1185 int flushpoint; 1186 1187 /* update silent for env loaded from flash (initr_env) */ 1188 if (console_update_silent()) 1189 flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL; 1190 else 1191 flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL; 1192 1193 /* 1194 * suppress all output if splash screen is enabled and we have 1195 * a bmp to display. We redirect the output from frame buffer 1196 * console to serial console in this case or suppress it if 1197 * "silent" mode was requested. 1198 */ 1199 if (IS_ENABLED(CONFIG_SPLASH_SCREEN) && env_get("splashimage")) { 1200 if (!(gd->flags & GD_FLG_SILENT)) 1201 outputdev = console_search_dev (DEV_FLAGS_OUTPUT, "serial"); 1202 } 1203 1204 /* Scan devices looking for input and output devices */ 1205 list_for_each(pos, list) { 1206 dev = list_entry(pos, struct stdio_dev, list); 1207 1208 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) { 1209 inputdev = dev; 1210 } 1211 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) { 1212 outputdev = dev; 1213 } 1214 if(inputdev && outputdev) 1215 break; 1216 } 1217 1218 /* Initializes output console first */ 1219 if (outputdev != NULL) { 1220 console_setfile_and_devices(stdout, outputdev); 1221 console_setfile_and_devices(stderr, outputdev); 1222 } 1223 1224 /* Initializes input console */ 1225 if (inputdev != NULL) 1226 console_setfile_and_devices(stdin, inputdev); 1227 1228 if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET)) 1229 stdio_print_current_devices(); 1230 1231 /* Setting environment variables */ 1232 for (i = 0; i < MAX_FILES; i++) { 1233 env_set(stdio_names[i], stdio_devices[i]->name); 1234 } 1235 1236 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 1237 1238 print_pre_console_buffer(flushpoint); 1239 return 0; 1240} 1241 1242#endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */ 1243 1244int console_remove_by_name(const char *name) 1245{ 1246 int err = 0; 1247 1248#if CONFIG_IS_ENABLED(CONSOLE_MUX) 1249 int fnum; 1250 1251 log_debug("removing console device %s\n", name); 1252 for (fnum = 0; fnum < MAX_FILES; fnum++) { 1253 struct stdio_dev **src, **dest; 1254 int i; 1255 1256 log_debug("file %d: %d devices: ", fnum, cd_count[fnum]); 1257 src = console_devices[fnum]; 1258 dest = src; 1259 for (i = 0; i < cd_count[fnum]; i++, src++) { 1260 struct stdio_dev *sdev = *src; 1261 int ret = 0; 1262 1263 if (!strcmp(sdev->name, name)) 1264 ret = stdio_deregister_dev(sdev, true); 1265 else 1266 *dest++ = *src; 1267 if (ret && !err) 1268 err = ret; 1269 } 1270 cd_count[fnum] = dest - console_devices[fnum]; 1271 log_debug("now %d\n", cd_count[fnum]); 1272 } 1273#endif /* CONSOLE_MUX */ 1274 1275 return err; 1276}