+// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2000
* Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <console.h>
#include <debug_uart.h>
#include <dm.h>
+#include <env.h>
#include <stdarg.h>
#include <iomux.h>
#include <malloc.h>
#include <serial.h>
#include <stdio_dev.h>
#include <exports.h>
-#include <environment.h>
+#include <env_internal.h>
#include <watchdog.h>
+#include <linux/delay.h>
DECLARE_GLOBAL_DATA_PTR;
static int on_silent(const char *name, const char *value, enum env_op op,
int flags)
{
-#if !CONFIG_IS_ENABLED(CONFIG_SILENT_CONSOLE_UPDATE_ON_SET)
+#if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET)
if (flags & H_INTERACTIVE)
return 0;
#endif
-#if !CONFIG_IS_ENABLED(CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC)
+#if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC)
if ((flags & H_INTERACTIVE) == 0)
return 0;
#endif
{
int i, ret;
struct stdio_dev *dev;
+ int prev;
- disable_ctrlc(1);
+ prev = disable_ctrlc(1);
for (i = 0; i < cd_count[file]; i++) {
dev = console_devices[file][i];
if (dev->tstc != NULL) {
ret = dev->tstc(dev);
if (ret > 0) {
tstcdev = dev;
- disable_ctrlc(0);
+ disable_ctrlc(prev);
return ret;
}
}
}
- disable_ctrlc(0);
+ disable_ctrlc(prev);
return 0;
}
}
}
+#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
static inline void console_doenv(int file, struct stdio_dev *dev)
{
iomux_doenv(file, dev->name);
}
+#endif
#else
static inline int console_getc(int file)
{
stdio_devices[file]->puts(stdio_devices[file], s);
}
+#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
static inline void console_doenv(int file, struct stdio_dev *dev)
{
console_setfile(file, dev);
}
+#endif
#endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
/** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
int fgetc(int file)
{
if (file < MAX_FILES) {
-#if CONFIG_IS_ENABLED(CONSOLE_MUX)
/*
* Effectively poll for input wherever it may be available.
*/
for (;;) {
WATCHDOG_RESET();
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
/*
* Upper layer may have already called tstc() so
* check for that first.
if (tstcdev != NULL)
return console_getc(file);
console_tstc(file);
+#else
+ if (console_tstc(file))
+ return console_getc(file);
+#endif
#ifdef CONFIG_WATCHDOG
/*
* If the watchdog must be rate-limited then it should
udelay(1);
#endif
}
-#else
- return console_getc(file);
-#endif
}
return -1;
if (gd->console_in.start) {
int ch;
- ch = membuff_getbyte(&gd->console_in);
+ ch = membuff_getbyte((struct membuff *)&gd->console_in);
if (ch != -1)
return 1;
}
return 0;
#ifdef CONFIG_CONSOLE_RECORD
if (gd->console_in.start) {
- if (membuff_peekbyte(&gd->console_in) != -1)
+ if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1)
return 1;
}
#endif
unmap_sysmem(buffer);
}
+static void pre_console_puts(const char *s)
+{
+ while (*s)
+ pre_console_putc(*s++);
+}
+
static void print_pre_console_buffer(int flushpoint)
{
unsigned long in = 0, out = 0;
char buf_out[CONFIG_PRE_CON_BUF_SZ + 1];
char *buf_in;
+#ifdef CONFIG_SILENT_CONSOLE
+ if (gd->flags & GD_FLG_SILENT)
+ return;
+#endif
+
buf_in = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ)
in = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
}
#else
static inline void pre_console_putc(const char c) {}
+static inline void pre_console_puts(const char *s) {}
static inline void print_pre_console_buffer(int flushpoint) {}
#endif
void putc(const char c)
{
+#ifdef CONFIG_SANDBOX
+ /* sandbox can send characters to stdout before it has a console */
+ if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+ os_putc(c);
+ return;
+ }
+#endif
#ifdef CONFIG_DEBUG_UART
/* if we don't have a console yet, use the debug UART */
if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
return;
}
#endif
+ if (!gd)
+ return;
#ifdef CONFIG_CONSOLE_RECORD
- if (gd && (gd->flags & GD_FLG_RECORD) && gd->console_out.start)
- membuff_putbyte(&gd->console_out, c);
+ if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start)
+ membuff_putbyte((struct membuff *)&gd->console_out, c);
#endif
#ifdef CONFIG_SILENT_CONSOLE
- if (gd->flags & GD_FLG_SILENT)
+ if (gd->flags & GD_FLG_SILENT) {
+ if (!(gd->flags & GD_FLG_DEVINIT))
+ pre_console_putc(c);
return;
+ }
#endif
#ifdef CONFIG_DISABLE_CONSOLE
void puts(const char *s)
{
- while (*s)
- putc(*s++);
+#ifdef CONFIG_SANDBOX
+ /* sandbox can send characters to stdout before it has a console */
+ if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+ os_puts(s);
+ return;
+ }
+#endif
+#ifdef CONFIG_DEBUG_UART
+ if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+ while (*s) {
+ int ch = *s++;
+
+ printch(ch);
+ }
+ return;
+ }
+#endif
+ if (!gd)
+ return;
+#ifdef CONFIG_CONSOLE_RECORD
+ if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start)
+ membuff_put((struct membuff *)&gd->console_out, s, strlen(s));
+#endif
+#ifdef CONFIG_SILENT_CONSOLE
+ if (gd->flags & GD_FLG_SILENT) {
+ if (!(gd->flags & GD_FLG_DEVINIT))
+ pre_console_puts(s);
+ return;
+ }
+#endif
+
+#ifdef CONFIG_DISABLE_CONSOLE
+ if (gd->flags & GD_FLG_DISABLE_CONSOLE)
+ return;
+#endif
+
+ if (!gd->have_console)
+ return pre_console_puts(s);
+
+ if (gd->flags & GD_FLG_DEVINIT) {
+ /* Send to the standard output */
+ fputs(stdout, s);
+ } else {
+ /* Send directly to the handler */
+ pre_console_puts(s);
+ serial_puts(s);
+ }
}
#ifdef CONFIG_CONSOLE_RECORD
{
int ret;
- ret = membuff_new(&gd->console_out, CONFIG_CONSOLE_RECORD_OUT_SIZE);
+ ret = membuff_new((struct membuff *)&gd->console_out,
+ CONFIG_CONSOLE_RECORD_OUT_SIZE);
if (ret)
return ret;
- ret = membuff_new(&gd->console_in, CONFIG_CONSOLE_RECORD_IN_SIZE);
+ ret = membuff_new((struct membuff *)&gd->console_in,
+ CONFIG_CONSOLE_RECORD_IN_SIZE);
return ret;
}
void console_record_reset(void)
{
- membuff_purge(&gd->console_out);
- membuff_purge(&gd->console_in);
+ membuff_purge((struct membuff *)&gd->console_out);
+ membuff_purge((struct membuff *)&gd->console_in);
}
void console_record_reset_enable(void)
console_record_reset();
gd->flags |= GD_FLG_RECORD;
}
+
+int console_record_readline(char *str, int maxlen)
+{
+ return membuff_readline((struct membuff *)&gd->console_out, str,
+ maxlen, ' ');
+}
+
+int console_record_avail(void)
+{
+ return membuff_avail((struct membuff *)&gd->console_out);
+}
+
#endif
/* test if ctrl-c was pressed */
static int ctrlc_was_pressed = 0;
int ctrlc(void)
{
-#ifndef CONFIG_SANDBOX
if (!ctrlc_disabled && gd->have_console) {
if (tstc()) {
switch (getc()) {
}
}
}
-#endif
return 0;
}
dev = stdio_get_by_name(name);
#ifdef CONFIG_VIDCONSOLE_AS_LCD
- if (!dev && !strcmp(name, "lcd"))
+ if (!dev && !strcmp(name, CONFIG_VIDCONSOLE_AS_LCD))
dev = stdio_get_by_name("vidconsole");
#endif
return -1;
}
-static void console_update_silent(void)
+/* return true if the 'silent' flag is removed */
+static bool console_update_silent(void)
{
#ifdef CONFIG_SILENT_CONSOLE
- if (getenv("silent") != NULL)
+ if (env_get("silent")) {
gd->flags |= GD_FLG_SILENT;
- else
+ } else {
+ unsigned long flags = gd->flags;
+
gd->flags &= ~GD_FLG_SILENT;
+
+ return !!(flags & GD_FLG_SILENT);
+ }
#endif
+
+ return false;
}
int console_announce_r(void)
#if CONFIG_IS_ENABLED(CONSOLE_MUX)
int iomux_err = 0;
#endif
+ int flushpoint;
+
+ /* update silent for env loaded from flash (initr_env) */
+ if (console_update_silent())
+ flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
+ else
+ flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
/* set default handlers at first */
gd->jt->getc = serial_getc;
/* stdin stdout and stderr are in environment */
/* scan for it */
- stdinname = getenv("stdin");
- stdoutname = getenv("stdout");
- stderrname = getenv("stderr");
+ stdinname = env_get("stdin");
+ stdoutname = env_get("stdout");
+ stderrname = env_get("stderr");
if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */
inputdev = search_device(DEV_FLAGS_INPUT, stdinname);
stdio_print_current_devices();
#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
#ifdef CONFIG_VIDCONSOLE_AS_LCD
- if (strstr(stdoutname, "lcd"))
- printf("Warning: Please change 'lcd' to 'vidconsole' in stdout/stderr environment vars\n");
+ if (strstr(stdoutname, CONFIG_VIDCONSOLE_AS_LCD))
+ printf("Warning: Please change '%s' to 'vidconsole' in stdout/stderr environment vars\n",
+ CONFIG_VIDCONSOLE_AS_LCD);
#endif
#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
/* set the environment variables (will overwrite previous env settings) */
- for (i = 0; i < 3; i++) {
- setenv(stdio_names[i], stdio_devices[i]->name);
+ for (i = 0; i < MAX_FILES; i++) {
+ env_set(stdio_names[i], stdio_devices[i]->name);
}
#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
return 0;
#endif
- print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL);
+ print_pre_console_buffer(flushpoint);
return 0;
}
struct list_head *list = stdio_get_list();
struct list_head *pos;
struct stdio_dev *dev;
+ int flushpoint;
- console_update_silent();
+ /* update silent for env loaded from flash (initr_env) */
+ if (console_update_silent())
+ flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL;
+ else
+ flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL;
#ifdef CONFIG_SPLASH_SCREEN
/*
* console to serial console in this case or suppress it if
* "silent" mode was requested.
*/
- if (getenv("splashimage") != NULL) {
+ if (env_get("splashimage") != NULL) {
if (!(gd->flags & GD_FLG_SILENT))
outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
}
#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
/* Setting environment variables */
- for (i = 0; i < 3; i++) {
- setenv(stdio_names[i], stdio_devices[i]->name);
+ for (i = 0; i < MAX_FILES; i++) {
+ env_set(stdio_names[i], stdio_devices[i]->name);
}
gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
return 0;
#endif
- print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL);
+ print_pre_console_buffer(flushpoint);
return 0;
}