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