1 /* 2 * (C) Copyright 2000 3 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <stdarg.h> 10 #include <malloc.h> 11 #include <os.h> 12 #include <serial.h> 13 #include <stdio_dev.h> 14 #include <exports.h> 15 #include <environment.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 static int on_console(const char *name, const char *value, enum env_op op, 20 int flags) 21 { 22 int console = -1; 23 24 /* Check for console redirection */ 25 if (strcmp(name, "stdin") == 0) 26 console = stdin; 27 else if (strcmp(name, "stdout") == 0) 28 console = stdout; 29 else if (strcmp(name, "stderr") == 0) 30 console = stderr; 31 32 /* if not actually setting a console variable, we don't care */ 33 if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0) 34 return 0; 35 36 switch (op) { 37 case env_op_create: 38 case env_op_overwrite: 39 40 #ifdef CONFIG_CONSOLE_MUX 41 if (iomux_doenv(console, value)) 42 return 1; 43 #else 44 /* Try assigning specified device */ 45 if (console_assign(console, value) < 0) 46 return 1; 47 #endif /* CONFIG_CONSOLE_MUX */ 48 return 0; 49 50 case env_op_delete: 51 if ((flags & H_FORCE) == 0) 52 printf("Can't delete \"%s\"\n", name); 53 return 1; 54 55 default: 56 return 0; 57 } 58 } 59 U_BOOT_ENV_CALLBACK(console, on_console); 60 61 #ifdef CONFIG_SILENT_CONSOLE 62 static int on_silent(const char *name, const char *value, enum env_op op, 63 int flags) 64 { 65 #ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_SET 66 if (flags & H_INTERACTIVE) 67 return 0; 68 #endif 69 #ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC 70 if ((flags & H_INTERACTIVE) == 0) 71 return 0; 72 #endif 73 74 if (value != NULL) 75 gd->flags |= GD_FLG_SILENT; 76 else 77 gd->flags &= ~GD_FLG_SILENT; 78 79 return 0; 80 } 81 U_BOOT_ENV_CALLBACK(silent, on_silent); 82 #endif 83 84 #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV 85 /* 86 * if overwrite_console returns 1, the stdin, stderr and stdout 87 * are switched to the serial port, else the settings in the 88 * environment are used 89 */ 90 #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE 91 extern int overwrite_console(void); 92 #define OVERWRITE_CONSOLE overwrite_console() 93 #else 94 #define OVERWRITE_CONSOLE 0 95 #endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */ 96 97 #endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */ 98 99 static int console_setfile(int file, struct stdio_dev * dev) 100 { 101 int error = 0; 102 103 if (dev == NULL) 104 return -1; 105 106 switch (file) { 107 case stdin: 108 case stdout: 109 case stderr: 110 /* Start new device */ 111 if (dev->start) { 112 error = dev->start(); 113 /* If it's not started dont use it */ 114 if (error < 0) 115 break; 116 } 117 118 /* Assign the new device (leaving the existing one started) */ 119 stdio_devices[file] = dev; 120 121 /* 122 * Update monitor functions 123 * (to use the console stuff by other applications) 124 */ 125 switch (file) { 126 case stdin: 127 gd->jt[XF_getc] = dev->getc; 128 gd->jt[XF_tstc] = dev->tstc; 129 break; 130 case stdout: 131 gd->jt[XF_putc] = dev->putc; 132 gd->jt[XF_puts] = dev->puts; 133 gd->jt[XF_printf] = printf; 134 break; 135 } 136 break; 137 138 default: /* Invalid file ID */ 139 error = -1; 140 } 141 return error; 142 } 143 144 #if defined(CONFIG_CONSOLE_MUX) 145 /** Console I/O multiplexing *******************************************/ 146 147 static struct stdio_dev *tstcdev; 148 struct stdio_dev **console_devices[MAX_FILES]; 149 int cd_count[MAX_FILES]; 150 151 /* 152 * This depends on tstc() always being called before getc(). 153 * This is guaranteed to be true because this routine is called 154 * only from fgetc() which assures it. 155 * No attempt is made to demultiplex multiple input sources. 156 */ 157 static int console_getc(int file) 158 { 159 unsigned char ret; 160 161 /* This is never called with testcdev == NULL */ 162 ret = tstcdev->getc(); 163 tstcdev = NULL; 164 return ret; 165 } 166 167 static int console_tstc(int file) 168 { 169 int i, ret; 170 struct stdio_dev *dev; 171 172 disable_ctrlc(1); 173 for (i = 0; i < cd_count[file]; i++) { 174 dev = console_devices[file][i]; 175 if (dev->tstc != NULL) { 176 ret = dev->tstc(); 177 if (ret > 0) { 178 tstcdev = dev; 179 disable_ctrlc(0); 180 return ret; 181 } 182 } 183 } 184 disable_ctrlc(0); 185 186 return 0; 187 } 188 189 static void console_putc(int file, const char c) 190 { 191 int i; 192 struct stdio_dev *dev; 193 194 for (i = 0; i < cd_count[file]; i++) { 195 dev = console_devices[file][i]; 196 if (dev->putc != NULL) 197 dev->putc(c); 198 } 199 } 200 201 static void console_puts(int file, const char *s) 202 { 203 int i; 204 struct stdio_dev *dev; 205 206 for (i = 0; i < cd_count[file]; i++) { 207 dev = console_devices[file][i]; 208 if (dev->puts != NULL) 209 dev->puts(s); 210 } 211 } 212 213 static inline void console_printdevs(int file) 214 { 215 iomux_printdevs(file); 216 } 217 218 static inline void console_doenv(int file, struct stdio_dev *dev) 219 { 220 iomux_doenv(file, dev->name); 221 } 222 #else 223 static inline int console_getc(int file) 224 { 225 return stdio_devices[file]->getc(); 226 } 227 228 static inline int console_tstc(int file) 229 { 230 return stdio_devices[file]->tstc(); 231 } 232 233 static inline void console_putc(int file, const char c) 234 { 235 stdio_devices[file]->putc(c); 236 } 237 238 static inline void console_puts(int file, const char *s) 239 { 240 stdio_devices[file]->puts(s); 241 } 242 243 static inline void console_printdevs(int file) 244 { 245 printf("%s\n", stdio_devices[file]->name); 246 } 247 248 static inline void console_doenv(int file, struct stdio_dev *dev) 249 { 250 console_setfile(file, dev); 251 } 252 #endif /* defined(CONFIG_CONSOLE_MUX) */ 253 254 /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/ 255 256 int serial_printf(const char *fmt, ...) 257 { 258 va_list args; 259 uint i; 260 char printbuffer[CONFIG_SYS_PBSIZE]; 261 262 va_start(args, fmt); 263 264 /* For this to work, printbuffer must be larger than 265 * anything we ever want to print. 266 */ 267 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); 268 va_end(args); 269 270 serial_puts(printbuffer); 271 return i; 272 } 273 274 int fgetc(int file) 275 { 276 if (file < MAX_FILES) { 277 #if defined(CONFIG_CONSOLE_MUX) 278 /* 279 * Effectively poll for input wherever it may be available. 280 */ 281 for (;;) { 282 /* 283 * Upper layer may have already called tstc() so 284 * check for that first. 285 */ 286 if (tstcdev != NULL) 287 return console_getc(file); 288 console_tstc(file); 289 #ifdef CONFIG_WATCHDOG 290 /* 291 * If the watchdog must be rate-limited then it should 292 * already be handled in board-specific code. 293 */ 294 udelay(1); 295 #endif 296 } 297 #else 298 return console_getc(file); 299 #endif 300 } 301 302 return -1; 303 } 304 305 int ftstc(int file) 306 { 307 if (file < MAX_FILES) 308 return console_tstc(file); 309 310 return -1; 311 } 312 313 void fputc(int file, const char c) 314 { 315 if (file < MAX_FILES) 316 console_putc(file, c); 317 } 318 319 void fputs(int file, const char *s) 320 { 321 if (file < MAX_FILES) 322 console_puts(file, s); 323 } 324 325 int fprintf(int file, const char *fmt, ...) 326 { 327 va_list args; 328 uint i; 329 char printbuffer[CONFIG_SYS_PBSIZE]; 330 331 va_start(args, fmt); 332 333 /* For this to work, printbuffer must be larger than 334 * anything we ever want to print. 335 */ 336 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); 337 va_end(args); 338 339 /* Send to desired file */ 340 fputs(file, printbuffer); 341 return i; 342 } 343 344 /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/ 345 346 int getc(void) 347 { 348 #ifdef CONFIG_DISABLE_CONSOLE 349 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 350 return 0; 351 #endif 352 353 if (!gd->have_console) 354 return 0; 355 356 if (gd->flags & GD_FLG_DEVINIT) { 357 /* Get from the standard input */ 358 return fgetc(stdin); 359 } 360 361 /* Send directly to the handler */ 362 return serial_getc(); 363 } 364 365 int tstc(void) 366 { 367 #ifdef CONFIG_DISABLE_CONSOLE 368 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 369 return 0; 370 #endif 371 372 if (!gd->have_console) 373 return 0; 374 375 if (gd->flags & GD_FLG_DEVINIT) { 376 /* Test the standard input */ 377 return ftstc(stdin); 378 } 379 380 /* Send directly to the handler */ 381 return serial_tstc(); 382 } 383 384 #ifdef CONFIG_PRE_CONSOLE_BUFFER 385 #define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ) 386 387 static void pre_console_putc(const char c) 388 { 389 char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR; 390 391 buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c; 392 } 393 394 static void pre_console_puts(const char *s) 395 { 396 while (*s) 397 pre_console_putc(*s++); 398 } 399 400 static void print_pre_console_buffer(void) 401 { 402 unsigned long i = 0; 403 char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR; 404 405 if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ) 406 i = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ; 407 408 while (i < gd->precon_buf_idx) 409 putc(buffer[CIRC_BUF_IDX(i++)]); 410 } 411 #else 412 static inline void pre_console_putc(const char c) {} 413 static inline void pre_console_puts(const char *s) {} 414 static inline void print_pre_console_buffer(void) {} 415 #endif 416 417 void putc(const char c) 418 { 419 #ifdef CONFIG_SANDBOX 420 if (!gd) { 421 os_putc(c); 422 return; 423 } 424 #endif 425 #ifdef CONFIG_SILENT_CONSOLE 426 if (gd->flags & GD_FLG_SILENT) 427 return; 428 #endif 429 430 #ifdef CONFIG_DISABLE_CONSOLE 431 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 432 return; 433 #endif 434 435 if (!gd->have_console) 436 return pre_console_putc(c); 437 438 if (gd->flags & GD_FLG_DEVINIT) { 439 /* Send to the standard output */ 440 fputc(stdout, c); 441 } else { 442 /* Send directly to the handler */ 443 serial_putc(c); 444 } 445 } 446 447 void puts(const char *s) 448 { 449 #ifdef CONFIG_SANDBOX 450 if (!gd) { 451 os_puts(s); 452 return; 453 } 454 #endif 455 456 #ifdef CONFIG_SILENT_CONSOLE 457 if (gd->flags & GD_FLG_SILENT) 458 return; 459 #endif 460 461 #ifdef CONFIG_DISABLE_CONSOLE 462 if (gd->flags & GD_FLG_DISABLE_CONSOLE) 463 return; 464 #endif 465 466 if (!gd->have_console) 467 return pre_console_puts(s); 468 469 if (gd->flags & GD_FLG_DEVINIT) { 470 /* Send to the standard output */ 471 fputs(stdout, s); 472 } else { 473 /* Send directly to the handler */ 474 serial_puts(s); 475 } 476 } 477 478 int printf(const char *fmt, ...) 479 { 480 va_list args; 481 uint i; 482 char printbuffer[CONFIG_SYS_PBSIZE]; 483 484 #if !defined(CONFIG_SANDBOX) && !defined(CONFIG_PRE_CONSOLE_BUFFER) 485 if (!gd->have_console) 486 return 0; 487 #endif 488 489 va_start(args, fmt); 490 491 /* For this to work, printbuffer must be larger than 492 * anything we ever want to print. 493 */ 494 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); 495 va_end(args); 496 497 /* Print the string */ 498 puts(printbuffer); 499 return i; 500 } 501 502 int vprintf(const char *fmt, va_list args) 503 { 504 uint i; 505 char printbuffer[CONFIG_SYS_PBSIZE]; 506 507 #ifndef CONFIG_PRE_CONSOLE_BUFFER 508 if (!gd->have_console) 509 return 0; 510 #endif 511 512 /* For this to work, printbuffer must be larger than 513 * anything we ever want to print. 514 */ 515 i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); 516 517 /* Print the string */ 518 puts(printbuffer); 519 return i; 520 } 521 522 /* test if ctrl-c was pressed */ 523 static int ctrlc_disabled = 0; /* see disable_ctrl() */ 524 static int ctrlc_was_pressed = 0; 525 int ctrlc(void) 526 { 527 if (!ctrlc_disabled && gd->have_console) { 528 if (tstc()) { 529 switch (getc()) { 530 case 0x03: /* ^C - Control C */ 531 ctrlc_was_pressed = 1; 532 return 1; 533 default: 534 break; 535 } 536 } 537 } 538 return 0; 539 } 540 541 /* pass 1 to disable ctrlc() checking, 0 to enable. 542 * returns previous state 543 */ 544 int disable_ctrlc(int disable) 545 { 546 int prev = ctrlc_disabled; /* save previous state */ 547 548 ctrlc_disabled = disable; 549 return prev; 550 } 551 552 int had_ctrlc (void) 553 { 554 return ctrlc_was_pressed; 555 } 556 557 void clear_ctrlc(void) 558 { 559 ctrlc_was_pressed = 0; 560 } 561 562 #ifdef CONFIG_MODEM_SUPPORT_DEBUG 563 char screen[1024]; 564 char *cursor = screen; 565 int once = 0; 566 inline void dbg(const char *fmt, ...) 567 { 568 va_list args; 569 uint i; 570 char printbuffer[CONFIG_SYS_PBSIZE]; 571 572 if (!once) { 573 memset(screen, 0, sizeof(screen)); 574 once++; 575 } 576 577 va_start(args, fmt); 578 579 /* For this to work, printbuffer must be larger than 580 * anything we ever want to print. 581 */ 582 i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args); 583 va_end(args); 584 585 if ((screen + sizeof(screen) - 1 - cursor) 586 < strlen(printbuffer) + 1) { 587 memset(screen, 0, sizeof(screen)); 588 cursor = screen; 589 } 590 sprintf(cursor, printbuffer); 591 cursor += strlen(printbuffer); 592 593 } 594 #else 595 inline void dbg(const char *fmt, ...) 596 { 597 } 598 #endif 599 600 /** U-Boot INIT FUNCTIONS *************************************************/ 601 602 struct stdio_dev *search_device(int flags, const char *name) 603 { 604 struct stdio_dev *dev; 605 606 dev = stdio_get_by_name(name); 607 608 if (dev && (dev->flags & flags)) 609 return dev; 610 611 return NULL; 612 } 613 614 int console_assign(int file, const char *devname) 615 { 616 int flag; 617 struct stdio_dev *dev; 618 619 /* Check for valid file */ 620 switch (file) { 621 case stdin: 622 flag = DEV_FLAGS_INPUT; 623 break; 624 case stdout: 625 case stderr: 626 flag = DEV_FLAGS_OUTPUT; 627 break; 628 default: 629 return -1; 630 } 631 632 /* Check for valid device name */ 633 634 dev = search_device(flag, devname); 635 636 if (dev) 637 return console_setfile(file, dev); 638 639 return -1; 640 } 641 642 /* Called before relocation - use serial functions */ 643 int console_init_f(void) 644 { 645 gd->have_console = 1; 646 647 #ifdef CONFIG_SILENT_CONSOLE 648 if (getenv("silent") != NULL) 649 gd->flags |= GD_FLG_SILENT; 650 #endif 651 652 print_pre_console_buffer(); 653 654 return 0; 655 } 656 657 void stdio_print_current_devices(void) 658 { 659 /* Print information */ 660 puts("In: "); 661 if (stdio_devices[stdin] == NULL) { 662 puts("No input devices available!\n"); 663 } else { 664 printf ("%s\n", stdio_devices[stdin]->name); 665 } 666 667 puts("Out: "); 668 if (stdio_devices[stdout] == NULL) { 669 puts("No output devices available!\n"); 670 } else { 671 printf ("%s\n", stdio_devices[stdout]->name); 672 } 673 674 puts("Err: "); 675 if (stdio_devices[stderr] == NULL) { 676 puts("No error devices available!\n"); 677 } else { 678 printf ("%s\n", stdio_devices[stderr]->name); 679 } 680 } 681 682 #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV 683 /* Called after the relocation - use desired console functions */ 684 int console_init_r(void) 685 { 686 char *stdinname, *stdoutname, *stderrname; 687 struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL; 688 #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE 689 int i; 690 #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */ 691 #ifdef CONFIG_CONSOLE_MUX 692 int iomux_err = 0; 693 #endif 694 695 /* set default handlers at first */ 696 gd->jt[XF_getc] = serial_getc; 697 gd->jt[XF_tstc] = serial_tstc; 698 gd->jt[XF_putc] = serial_putc; 699 gd->jt[XF_puts] = serial_puts; 700 gd->jt[XF_printf] = serial_printf; 701 702 /* stdin stdout and stderr are in environment */ 703 /* scan for it */ 704 stdinname = getenv("stdin"); 705 stdoutname = getenv("stdout"); 706 stderrname = getenv("stderr"); 707 708 if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */ 709 inputdev = search_device(DEV_FLAGS_INPUT, stdinname); 710 outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname); 711 errdev = search_device(DEV_FLAGS_OUTPUT, stderrname); 712 #ifdef CONFIG_CONSOLE_MUX 713 iomux_err = iomux_doenv(stdin, stdinname); 714 iomux_err += iomux_doenv(stdout, stdoutname); 715 iomux_err += iomux_doenv(stderr, stderrname); 716 if (!iomux_err) 717 /* Successful, so skip all the code below. */ 718 goto done; 719 #endif 720 } 721 /* if the devices are overwritten or not found, use default device */ 722 if (inputdev == NULL) { 723 inputdev = search_device(DEV_FLAGS_INPUT, "serial"); 724 } 725 if (outputdev == NULL) { 726 outputdev = search_device(DEV_FLAGS_OUTPUT, "serial"); 727 } 728 if (errdev == NULL) { 729 errdev = search_device(DEV_FLAGS_OUTPUT, "serial"); 730 } 731 /* Initializes output console first */ 732 if (outputdev != NULL) { 733 /* need to set a console if not done above. */ 734 console_doenv(stdout, outputdev); 735 } 736 if (errdev != NULL) { 737 /* need to set a console if not done above. */ 738 console_doenv(stderr, errdev); 739 } 740 if (inputdev != NULL) { 741 /* need to set a console if not done above. */ 742 console_doenv(stdin, inputdev); 743 } 744 745 #ifdef CONFIG_CONSOLE_MUX 746 done: 747 #endif 748 749 #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET 750 stdio_print_current_devices(); 751 #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ 752 753 #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE 754 /* set the environment variables (will overwrite previous env settings) */ 755 for (i = 0; i < 3; i++) { 756 setenv(stdio_names[i], stdio_devices[i]->name); 757 } 758 #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */ 759 760 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 761 762 #if 0 763 /* If nothing usable installed, use only the initial console */ 764 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) 765 return 0; 766 #endif 767 return 0; 768 } 769 770 #else /* CONFIG_SYS_CONSOLE_IS_IN_ENV */ 771 772 /* Called after the relocation - use desired console functions */ 773 int console_init_r(void) 774 { 775 struct stdio_dev *inputdev = NULL, *outputdev = NULL; 776 int i; 777 struct list_head *list = stdio_get_list(); 778 struct list_head *pos; 779 struct stdio_dev *dev; 780 781 #ifdef CONFIG_SPLASH_SCREEN 782 /* 783 * suppress all output if splash screen is enabled and we have 784 * a bmp to display. We redirect the output from frame buffer 785 * console to serial console in this case or suppress it if 786 * "silent" mode was requested. 787 */ 788 if (getenv("splashimage") != NULL) { 789 if (!(gd->flags & GD_FLG_SILENT)) 790 outputdev = search_device (DEV_FLAGS_OUTPUT, "serial"); 791 } 792 #endif 793 794 /* Scan devices looking for input and output devices */ 795 list_for_each(pos, list) { 796 dev = list_entry(pos, struct stdio_dev, list); 797 798 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) { 799 inputdev = dev; 800 } 801 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) { 802 outputdev = dev; 803 } 804 if(inputdev && outputdev) 805 break; 806 } 807 808 /* Initializes output console first */ 809 if (outputdev != NULL) { 810 console_setfile(stdout, outputdev); 811 console_setfile(stderr, outputdev); 812 #ifdef CONFIG_CONSOLE_MUX 813 console_devices[stdout][0] = outputdev; 814 console_devices[stderr][0] = outputdev; 815 #endif 816 } 817 818 /* Initializes input console */ 819 if (inputdev != NULL) { 820 console_setfile(stdin, inputdev); 821 #ifdef CONFIG_CONSOLE_MUX 822 console_devices[stdin][0] = inputdev; 823 #endif 824 } 825 826 #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET 827 stdio_print_current_devices(); 828 #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ 829 830 /* Setting environment variables */ 831 for (i = 0; i < 3; i++) { 832 setenv(stdio_names[i], stdio_devices[i]->name); 833 } 834 835 gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ 836 837 #if 0 838 /* If nothing usable installed, use only the initial console */ 839 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) 840 return 0; 841 #endif 842 843 return 0; 844 } 845 846 #endif /* CONFIG_SYS_CONSOLE_IS_IN_ENV */ 847