Compare commits

...

13 Commits
extm2 ... clia2

Author SHA1 Message Date
Simon Glass
a845243258 doc: Tidy up the console docs a little
Tweak the documentation to look better when viewed. Use 'write' instead
of 'put'.

Series-to: concept
Series-cc: heinrich
Series-version: 2
Cover-letter:
console: Refactor in preparation for the pager
This series tidies up a few small things the serial and console areas:

- Move detection of serial-console size to the serial module
- Provide a Kconfig to disable serial detection
- Fix some missing driver-model flags in stdio devices
- Move console docs into the main documentation

This series is marked v2 since some of the patches were sent in any
earlier series. With various tweaks that series grew too large to be
sent as a single series.
END

Signed-off-by: Simon Glass <sjg@chromium.org>
Series-links: 2:17
2025-08-25 10:27:02 -06:00
Simon Glass
c9f6855c71 doc: Move console docs to rST
Move the console readme into the main documentation, with as few changes
as possible.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 07:26:58 -06:00
Simon Glass
2c2f4923b3 doc: Remove obsolete text in README.console
The latter part of this file is very out-of-date, so drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 07:26:58 -06:00
Simon Glass
2423466c67 console: Refactor handling of the result in on_console()
This function has lots of return statements in a switch statement. Move
them out so we can (later) do something else in this function.

Series-changes: 2
- Add new patch to refactor handling of the result in on_console()

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 07:26:58 -06:00
Simon Glass
27bea75c2c console: Move environment handling lower in the file
Move the environment callbacks lower so that we can call functions
elsewhere in common/console.c

Series-changes: 2
- Add new patch to move environment handling lower in the file

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 07:26:58 -06:00
Simon Glass
36a202e795 console: Update conio command to show uclass
When an stdio device is provided by a driver model device, optionally
show the uclass.

Be careful to avoid increasing code size, since this is a common
command.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 07:26:58 -06:00
Simon Glass
58abd769d7 console: Update coninfo to use sdev instead of dev
The 'dev' variable is generally used for driver model, so change
do_coninfo() to use sdev, to avoid confusion.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 07:26:58 -06:00
Simon Glass
b94075124a cli: Avoid sending ANSI characters to a non-terminal
Detect if there is no terminal present (this only works on sandbox) and
skip sending ANSI characters when the CLI starts up. This avoids having
them in logs, for example.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 07:26:58 -06:00
Simon Glass
2e79615c2b post: Include config.h in the header
The post system requires use of CFG_xxx values which are only included
via the config.h header. Most files don't include this now.

The serial.h header includes post.h which causes a build error on any
platform which enables CONFIG_POST, such as pg_wcom_seli8

Add an explicit #include of config.h in the post.h header file.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 07:26:58 -06:00
Simon Glass
e3bd2654af sandbox: Provide a way to tell if the video is visible
Sandbox is often run with the display disabled, so even though it has a
video device, it is not being shown. Provide a way to detect this. For
all other platforms, we assume the display is shown, when there is a
video device.

Series-changes: 2
- Add new patch to provide a way to tell if the video is visible

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 07:26:58 -06:00
Simon Glass
e1d98424f0 sandbox: Add a function to detect terminal connection
Add a serial_is_tty() function that determines if the serial console
is connected to a terminal. For sandbox, this uses os_isatty() to
check stdin, except for cooked mode, where we don't want to assume
anything about the terminal.

For other platforms, it always returns true.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 07:26:58 -06:00
Simon Glass
9f7600b270 serial: Cache the terminal size
Add serial_priv structure to serial uclass to cache terminal dimensions.
When serial_query_size() successfully queries the terminal, store the
results in the uclass-private data for later retrieval.

This avoids repeated terminal queries and improves performance when
different subsystems need the terminal size.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 07:26:57 -06:00
Simon Glass
aa1cd00676 serial: Generalise the code to check the terminal size
The EFI loader has some code to check the size (rows and columns) of an
attached terminal. Move this over to the serial uclass so that it can be
used elsewhere.

Create a new CONFIG_SERIAL_TERM_PRESENT to control whether it should be
used. Enable that for the EFI loader to preserve existing behaviour.

Adjust the implementation so that it returns a useful error code on
failure. Put the ESC and cESC values in the serial.h header.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-25 06:56:46 -06:00
18 changed files with 477 additions and 299 deletions

View File

@@ -142,6 +142,11 @@ int os_close(int fd)
return -1;
}
int os_isatty(int fd)
{
return isatty(fd);
}
int os_unlink(const char *pathname)
{
return unlink(pathname);

View File

@@ -613,6 +613,10 @@ int sandbox_main(int argc, char *argv[])
if (os_parse_args(state, argc, argv))
return 1;
/* Detect if serial console is connected to a terminal */
state->serial_is_tty = os_isatty(1) &&
state->term_raw != STATE_TERM_COOKED;
if (state->ram_buf_fname) {
ret = os_read_ram_buf(state->ram_buf_fname);
if (ret) {

View File

@@ -476,6 +476,20 @@ bool sandbox_sf_bootdev_enabled(void)
return !state->disable_sf_bootdevs;
}
bool sandbox_serial_is_tty(void)
{
struct sandbox_state *state = state_get_current();
return state->serial_is_tty;
}
bool sandbox_video_is_visible(void)
{
struct sandbox_state *state = state_get_current();
return state->show_lcd;
}
int state_init(void)
{
state = &main_state;

View File

@@ -157,6 +157,7 @@ struct sandbox_state {
bool ignore_missing_state_on_read; /* No error if state missing */
bool show_lcd; /* Show LCD on start-up */
bool double_lcd; /* Double display size for high-DPI */
bool serial_is_tty; /* Serial console is connected to a tty */
enum sysreset_t last_sysreset; /* Last system reset type */
bool sysreset_allowed[SYSRESET_COUNT]; /* Allowed system reset types */
enum state_terminal_raw term_raw; /* Terminal raw/cooked */
@@ -377,6 +378,20 @@ int state_get_rel_filename(const char *rel_path, char *buf, int size);
*/
int state_load_other_fdt(const char **bufp, int *sizep);
/**
* sandbox_serial_is_tty() - check if serial console is connected to a tty
*
* Return: true if serial console is connected to a terminal, false if not
*/
bool sandbox_serial_is_tty(void);
/*
* sandbox_video_is_visible() - check if video display is showing
*
* Return: true if display is active, false if just using the serial console
*/
bool sandbox_video_is_visible(void);
/**
* Initialize the test system state
*/

View File

@@ -175,6 +175,14 @@ config CMD_CONSOLE
help
Print console devices and information.
config CMD_CONSOLE_EXTRA
bool "Show uclass for driver model devices"
default y if SANDBOX
help
Expands the coninfo command to show the uclass for all stdio devices
which are provided by a driver model device. This increase code size
by about 200 bytes.
config CMD_CPU
bool "cpu"
depends on CPU

View File

@@ -8,40 +8,61 @@
* Boot support
*/
#include <command.h>
#include <dm.h>
#include <iomux.h>
#include <stdio_dev.h>
extern void _do_coninfo (void);
/* shenangans to avoid code-size increase */
#ifdef CONFIG_CMD_CONSOLE_EXTRA
#define USE_NL ""
#else
#define USE_NL "\n"
#endif
static int do_coninfo(struct cmd_tbl *cmd, int flag, int argc,
char *const argv[])
{
int l;
struct list_head *list = stdio_get_list();
struct list_head *pos;
struct stdio_dev *dev;
struct stdio_dev *sdev;
/* Scan for valid output and input devices */
puts("List of available devices\n");
puts("List of available devices\n\n");
if (IS_ENABLED(CONFIG_CMD_CONSOLE_EXTRA))
puts("Device File Uclass\n");
list_for_each(pos, list) {
dev = list_entry(pos, struct stdio_dev, list);
sdev = list_entry(pos, struct stdio_dev, list);
printf("|-- %s (%s%s)\n",
dev->name,
(dev->flags & DEV_FLAGS_INPUT) ? "I" : "",
(dev->flags & DEV_FLAGS_OUTPUT) ? "O" : "");
printf("|-- %s (%s%s)" USE_NL,
sdev->name,
(sdev->flags & DEV_FLAGS_INPUT) ? "I" : "",
(sdev->flags & DEV_FLAGS_OUTPUT) ? "O" : "");
if (IS_ENABLED(CONFIG_CMD_CONSOLE_EXTRA) &&
IS_ENABLED(CONFIG_DM_STDIO) &&
(sdev->flags & DEV_FLAGS_DM)) {
struct udevice *dev = sdev->priv;
int len = 0;
len += (sdev->flags & DEV_FLAGS_INPUT) != 0;
len += (sdev->flags & DEV_FLAGS_OUTPUT) != 0;
printf("%*s%s", 20 - len - (int)strlen(sdev->name), "",
dev_get_uclass_name(dev));
}
if (IS_ENABLED(CONFIG_CMD_CONSOLE_EXTRA))
puts("\n");
for (l = 0; l < MAX_FILES; l++) {
if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
if (iomux_match_device(console_devices[l],
cd_count[l], dev) >= 0)
cd_count[l], sdev) >= 0)
printf("| |-- %s\n", stdio_names[l]);
} else {
if (stdio_devices[l] == dev)
if (stdio_devices[l] == sdev)
printf("| |-- %s\n", stdio_names[l]);
}
}
}
return 0;

View File

@@ -20,6 +20,7 @@
#include <fdtdec.h>
#include <hang.h>
#include <malloc.h>
#include <serial.h>
#include <asm/global_data.h>
#include <dm/ofnode.h>
#include <linux/errno.h>
@@ -337,6 +338,6 @@ void cli_init(void)
hush_init_var();
#endif
if (CONFIG_IS_ENABLED(VIDEO_ANSI))
if (CONFIG_IS_ENABLED(VIDEO_ANSI) && serial_is_tty())
printf(ANSI_CURSOR_SHOW "\n");
}

View File

@@ -29,71 +29,6 @@ DECLARE_GLOBAL_DATA_PTR;
#define CSI "\x1b["
static int on_console(const char *name, const char *value, enum env_op op,
int flags)
{
int console = -1;
/* Check for console redirection */
if (strcmp(name, "stdin") == 0)
console = stdin;
else if (strcmp(name, "stdout") == 0)
console = stdout;
else if (strcmp(name, "stderr") == 0)
console = stderr;
/* if not actually setting a console variable, we don't care */
if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0)
return 0;
switch (op) {
case env_op_create:
case env_op_overwrite:
if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
if (iomux_doenv(console, value))
return 1;
} else {
/* Try assigning specified device */
if (console_assign(console, value) < 0)
return 1;
}
return 0;
case env_op_delete:
if ((flags & H_FORCE) == 0)
printf("Can't delete \"%s\"\n", name);
return 1;
default:
return 0;
}
}
U_BOOT_ENV_CALLBACK(console, on_console);
#ifdef CONFIG_SILENT_CONSOLE
static int on_silent(const char *name, const char *value, enum env_op op,
int flags)
{
if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET))
if (flags & H_INTERACTIVE)
return 0;
if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC))
if ((flags & H_INTERACTIVE) == 0)
return 0;
if (value != NULL)
gd->flags |= GD_FLG_SILENT;
else
gd->flags &= ~GD_FLG_SILENT;
return 0;
}
U_BOOT_ENV_CALLBACK(silent, on_silent);
#endif
#ifdef CONFIG_CONSOLE_RECORD
/* helper function: access to gd->console_out and gd->console_in */
static void console_record_putc(const char c)
@@ -1101,6 +1036,71 @@ static void stdio_print_current_devices(void)
printf("%s\n", stderrname);
}
static int on_console(const char *name, const char *value, enum env_op op,
int flags)
{
int console = -1;
int result = 0;
/* Check for console redirection */
if (strcmp(name, "stdin") == 0)
console = stdin;
else if (strcmp(name, "stdout") == 0)
console = stdout;
else if (strcmp(name, "stderr") == 0)
console = stderr;
/* if not actually setting a console variable, we don't care */
if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0)
return 0;
switch (op) {
case env_op_create:
case env_op_overwrite:
if (CONFIG_IS_ENABLED(CONSOLE_MUX)) {
if (iomux_doenv(console, value))
result = 1;
} else {
/* Try assigning specified device */
if (console_assign(console, value) < 0)
result = 1;
}
break;
case env_op_delete:
if ((flags & H_FORCE) == 0)
printf("Can't delete \"%s\"\n", name);
result = 1;
break;
default:
break;
}
return result;
}
U_BOOT_ENV_CALLBACK(console, on_console);
#ifdef CONFIG_SILENT_CONSOLE
static int on_silent(const char *name, const char *value, enum env_op op,
int flags)
{
if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET))
if (flags & H_INTERACTIVE)
return 0;
if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC))
if ((flags & H_INTERACTIVE) == 0)
return 0;
if (value)
gd->flags |= GD_FLG_SILENT;
else
gd->flags &= ~GD_FLG_SILENT;
return 0;
}
U_BOOT_ENV_CALLBACK(silent, on_silent);
#endif
#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
/* Called after the relocation - use desired console functions */
int console_init_r(void)

View File

@@ -1,100 +0,0 @@
SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2000
* Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
*/
U-Boot console handling
========================
HOW THE CONSOLE WORKS?
----------------------
At system startup U-Boot initializes a serial console. When U-Boot
relocates itself to RAM, all console drivers are initialized (they
will register all detected console devices to the system for further
use).
If not defined in the environment, the first input device is assigned
to the 'stdin' file, the first output one to 'stdout' and 'stderr'.
You can use the command "coninfo" to see all registered console
devices and their flags. You can assign a standard file (stdin,
stdout or stderr) to any device you see in that list simply by
assigning its name to the corresponding environment variable. For
example:
setenv stdin serial <- To use the serial input
setenv stdout video <- To use the video console
Do a simple "saveenv" to save the console settings in the environment
and get them working on the next startup, too.
HOW CAN I USE STANDARD FILE INTO THE SOURCES?
---------------------------------------------
You can use the following functions to access the console:
* STDOUT:
putc (to put a char to stdout)
puts (to put a string to stdout)
printf (to format and put a string to stdout)
* STDIN:
tstc (to test for the presence of a char in stdin)
getc (to get a char from stdin)
* STDERR:
eputc (to put a char to stderr)
eputs (to put a string to stderr)
eprintf (to format and put a string to stderr)
* FILE (can be 'stdin', 'stdout', 'stderr'):
fputc (like putc but redirected to a file)
fputs (like puts but redirected to a file)
fprintf (like printf but redirected to a file)
ftstc (like tstc but redirected to a file)
fgetc (like getc but redirected to a file)
Remember that all FILE-related functions CANNOT be used before
U-Boot relocation (done in 'board_init_r' in arch/*/lib/board.c).
HOW CAN I USE STANDARD FILE INTO APPLICATIONS?
----------------------------------------------
Use the 'bd_mon_fnc' field of the bd_info structure passed to the
application to do everything you want with the console.
But REMEMBER that that will work only if you have not overwritten any
U-Boot code while loading (or uncompressing) the image of your
application.
For example, you won't get the console stuff running in the Linux
kernel because the kernel overwrites U-Boot before running. Only
some parameters like the framebuffer descriptors are passed to the
kernel in the high memory area to let the applications (the kernel)
use the framebuffers initialized by U-Boot.
SUPPORTED DRIVERS
-----------------
Working drivers:
serial (architecture dependent serial stuff)
video (mpc8xx video controller)
Work in progress:
wl_kbd (Wireless 4PPM keyboard)
Waiting for volounteers:
lcd (mpc8xx lcd controller; to )
TESTED CONFIGURATIONS
---------------------
The driver has been tested with the following configurations (see
CREDITS for other contact informations):
- MPC823FADS with AD7176 on a PAL TV (YCbYCr) - arsenio@tin.it

62
doc/usage/console.rst Normal file
View File

@@ -0,0 +1,62 @@
.. SPDX-License-Identifier: GPL-2.0+
.. sectionauthor:: Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
.. (C) Copyright 2000
=======================
U-Boot console handling
=======================
Introduction
------------
At system-startup U-Boot initializes a serial console. When U-Boot
relocates itself to RAM, all console drivers are initialized (they
will register all detected console devices to the system for further
use).
If not defined in the environment, the first input device is assigned
to the 'stdin' file, the first output one to 'stdout' and 'stderr'.
You can use the command `coninfo` to see all registered console
devices and their flags. You can assign a standard file (stdin,
stdout or stderr) to any device you see in that list simply by
assigning its name to the corresponding environment variable. For
example::
# Use the serial input
setenv stdin serial
# Use the video console
setenv stdout vidconsole
Do a simple `saveenv` to save the console settings in the environment
and get them working on the next startup, too.
How to output text to the console
---------------------------------
You can use the following functions to access the console:
stdout
- putc() - write a char to stdout
- puts() - write a string to stdout
- printf() - format and write a string to stdout
stdin
- tstc() - test for the presence of a char in stdin
- getchar() - get a char from stdin
stderr
- eputc() - write a char to stderr
- eputs() - write a string to stderr
- eprintf() - format and write a string to stderr
file ('stdin', 'stdout' or 'stderr')
- fputc() - write a char to a file
- fputs() - write a string to a file
- fprintf() - format and write a string to a file
- ftstc() - test for the presence of a char in file
- fgetc() - get a char from a file
Remember that FILE-related functions CANNOT be used before U-Boot relocation,
which is done in `board_init_r()`.

View File

@@ -6,6 +6,7 @@ Use U-Boot
spl_boot
blkmap
console
dfu
environment
fdt_overlays

View File

@@ -202,6 +202,21 @@ config VPL_DM_SERIAL
implements serial_putc() etc. The uclass interface is
defined in include/serial.h.
config SERIAL_TERM_PRESENT
bool "Assume there is a serial terminal present on the serial line"
depends on DM_SERIAL
default y if EFI_LOADER
help
In some cases boards are connected to a serial terminal and it is
useful to emit ANSI codes or other characters to determine the
properties of the terminal.
Enable this if you wish to have these features.
Note that enabling this for a board which is sending its output to
a log will result in junk in the log. It also introduces a delay of
up to 100ms on startup.
config DEBUG_UART
bool "Enable an early debug UART for debugging"
help

View File

@@ -13,6 +13,7 @@
#include <os.h>
#include <serial.h>
#include <stdio_dev.h>
#include <time.h>
#include <watchdog.h>
#include <asm/global_data.h>
#include <dm/lists.h>
@@ -23,6 +24,8 @@
DECLARE_GLOBAL_DATA_PTR;
#define ESC "\x1b"
/*
* Table with supported baudrates (defined in config_xyz.h)
*/
@@ -557,6 +560,158 @@ static int on_baudrate(const char *name, const char *value, enum env_op op,
}
U_BOOT_ENV_CALLBACK(baudrate, on_baudrate);
/**
* term_get_char() - read a character from the console
*
* Wait for up to 100 ms to read a character from the console.
*
* @c: pointer to the buffer to receive the character
* Return: 0 on success, -ETIMEDOUT if timed out
*/
static int term_get_char(s32 *c)
{
u64 timeout;
/* Wait up to 100 ms for a character */
timeout = timer_get_us() + 100000;
while (!tstc())
if (timer_get_us() > timeout)
return -ETIMEDOUT;
*c = getchar();
return 0;
}
/**
* term_read_reply() - receive and parse a reply from the terminal
*
* @n: array of return values
* @num: number of return values expected
* @end_char: character indicating end of terminal message
* Return: non-zero indicates error
*/
static int term_read_reply(int *n, int num, char end_char)
{
int ret, i = 0;
s32 c;
ret = term_get_char(&c);
if (ret)
return ret;
if (c != cESC)
return -EPROTO;
ret = term_get_char(&c);
if (ret)
return ret;
if (c != '[')
return -EPROTO;
n[0] = 0;
while (1) {
int ret;
ret = term_get_char(&c);
if (ret)
return ret;
if (c == ';') {
i++;
if (i >= num)
return -EPROTO;
n[i] = 0;
continue;
} else if (c == end_char) {
break;
} else if (c > '9' || c < '0') {
return -EPROTO;
}
/* Read one more decimal position */
n[i] *= 10;
n[i] += c - '0';
}
if (i != num - 1)
return -EPROTO;
return 0;
}
int serial_query_size(int *rowsp, int *colsp)
{
int ret = 0;
int n[2];
if (!CONFIG_IS_ENABLED(SERIAL_TERM_PRESENT))
return -ENOENT;
/* Empty input buffer */
while (tstc())
getchar();
/*
* Not all terminals understand CSI [18t for querying the console size.
* We should adhere to escape sequences documented in the console_codes
* man page and the ECMA-48 standard.
*
* So here we follow a different approach. We position the cursor to the
* bottom right and query its position. Before leaving the function we
* restore the original cursor position.
*/
puts(ESC "7" /* Save cursor position */
ESC "[r" /* Set scrolling region to full window */
ESC "[999;999H" /* Move to bottom right corner */
ESC "[6n"); /* Query cursor position */
/* Read {rows,cols} */
ret = term_read_reply(n, 2, 'R');
if (!ret) {
struct serial_priv *priv;
struct uclass *uc;
*colsp = n[1];
*rowsp = n[0];
/* Store in serial uclass private data if available */
if (!uclass_get(UCLASS_SERIAL, &uc)) {
priv = uclass_get_priv(uc);
priv->rows = n[0];
priv->cols = n[1];
}
}
printf(ESC "8"); /* Restore cursor position */
return ret;
}
int serial_get_size(struct udevice *dev, int *rowsp, int *colsp)
{
struct serial_priv *priv;
struct uclass *uc;
int ret;
ret = uclass_get(UCLASS_SERIAL, &uc);
if (ret)
return ret;
priv = uclass_get_priv(uc);
/* Check if we have cached values */
if (priv->rows && priv->cols) {
*rowsp = priv->rows;
*colsp = priv->cols;
return 0;
}
/* No cached values, query the terminal */
ret = serial_query_size(rowsp, colsp);
return ret;
}
#if CONFIG_IS_ENABLED(SERIAL_PRESENT)
static int serial_post_probe(struct udevice *dev)
{
@@ -612,5 +767,6 @@ UCLASS_DRIVER(serial) = {
.post_probe = serial_post_probe,
.pre_remove = serial_pre_remove,
.per_device_auto = sizeof(struct serial_dev_priv),
.priv_auto = sizeof(struct serial_priv),
};
#endif

View File

@@ -90,6 +90,14 @@ int os_open(const char *pathname, int flags);
*/
int os_close(int fd);
/**
* os_isatty() - check if file descriptor refers to a terminal
*
* @fd: File descriptor to check
* Return: 1 if fd is a terminal, 0 if not, -1 on error
*/
int os_isatty(int fd);
/**
* os_unlink() - access to the OS unlink() system call
*

View File

@@ -15,6 +15,8 @@
#if defined(CONFIG_POST)
#include <config.h>
#ifndef CFG_POST_EXTERNAL_WORD_FUNCS
#ifdef CFG_SYS_POST_WORD_ADDR
#define _POST_WORD_ADDR CFG_SYS_POST_WORD_ADDR

View File

@@ -2,6 +2,13 @@
#define __SERIAL_H__
#include <post.h>
#ifdef CONFIG_SANDBOX
#include <asm/state.h>
#endif
/* Escape value */
#define cESC '\x1b'
#define ESC "\x1b"
struct serial_device {
/* enough bytes to match alignment of following func pointer */
@@ -287,6 +294,17 @@ struct dm_serial_ops {
int (*getinfo)(struct udevice *dev, struct serial_device_info *info);
};
/**
* struct serial_priv - private data for serial uclass
*
* @rows: Number of terminal rows (0 if unknown)
* @cols: Number of terminal columns (0 if unknown)
*/
struct serial_priv {
int rows;
int cols;
};
/**
* struct serial_dev_priv - information about a device used by the uclass
*
@@ -382,4 +400,49 @@ static inline void serial_flush(void) {}
int serial_getc(void);
int serial_tstc(void);
/**
* serial_query_size() - query serial console size
*
* When using a serial console or the net console we can only devise the
* terminal size by querying the terminal using ECMA-48 control sequences.
*
* @rowsp: returns number of rows
* @colsp: returns number of columns
* Returns: 0 on success, -NOENT if no terminal is present, -ETIMEDOUT if we
* checked for a terminal but didn't get a response in time, -EPROTO if the
* terminal did not respond as expected
*/
int serial_query_size(int *rowsp, int *colsp);
/**
* serial_get_size() - get serial console size
*
* Get the terminal size, using cached values if available, or failing that,
* query the terminal
*
* @dev: serial device to query (may be NULL)
* @rowsp: returns number of rows
* @colsp: returns number of columns
* Returns: 0 on success, -ve on error
*/
int serial_get_size(struct udevice *dev, int *rowsp, int *colsp);
/*
* serial_is_tty() - check if the serial console is connected to a terminal
*
* This does not indicate that there is actually a terminal, only that if there
* is one, we can assume it is present and connected
*
* Return: true if any serial console is likely connected to a terminal, false if not
*/
static inline bool serial_is_tty(void)
{
#ifdef CONFIG_SANDBOX
return sandbox_serial_is_tty();
#else
/* assume that it is! */
return true;
#endif
}
#endif

View File

@@ -8,6 +8,9 @@
#define _VIDEO_H_
#include <stdio_dev.h>
#ifdef CONFIG_SANDBOX
#include <asm/state.h>
#endif
struct udevice;
@@ -460,4 +463,22 @@ int video_reserve_from_bloblist(struct video_handoff *ho);
*/
ulong video_get_fb(void);
/**
* video_is_visible() - check if the video display is being used
*
* This does not indicate that there is actually a display, only that if there
* is one, we can assume it is present
*
* Return: true if any display is likely visible, false if not
*/
static inline bool video_is_visible(void)
{
#ifdef CONFIG_SANDBOX
return sandbox_video_is_visible();
#else
/* assume that it is! */
return true;
#endif
}
#endif

View File

@@ -16,6 +16,7 @@
#include <efi_loader.h>
#include <env.h>
#include <log.h>
#include <serial.h>
#include <stdio_dev.h>
#include <video_console.h>
#include <linux/delay.h>
@@ -59,9 +60,6 @@ const efi_guid_t efi_guid_text_input_protocol =
const efi_guid_t efi_guid_text_output_protocol =
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
#define cESC '\x1b'
#define ESC "\x1b"
/*
* efi_con_mode - mode information of the Simple Text Output Protocol
*
@@ -77,76 +75,6 @@ static struct simple_text_output_mode efi_con_mode = {
.cursor_visible = 1,
};
/**
* term_get_char() - read a character from the console
*
* Wait for up to 100 ms to read a character from the console.
*
* @c: pointer to the buffer to receive the character
* Return: 0 on success, 1 otherwise
*/
static int term_get_char(s32 *c)
{
u64 timeout;
/* Wait up to 100 ms for a character */
timeout = timer_get_us() + 100000;
while (!tstc())
if (timer_get_us() > timeout)
return 1;
*c = getchar();
return 0;
}
/**
* term_read_reply() - receive and parse a reply from the terminal
*
* @n: array of return values
* @num: number of return values expected
* @end_char: character indicating end of terminal message
* Return: non-zero indicates error
*/
static int term_read_reply(int *n, int num, char end_char)
{
s32 c;
int i = 0;
if (term_get_char(&c) || c != cESC)
return -1;
if (term_get_char(&c) || c != '[')
return -1;
n[0] = 0;
while (1) {
if (!term_get_char(&c)) {
if (c == ';') {
i++;
if (i >= num)
return -1;
n[i] = 0;
continue;
} else if (c == end_char) {
break;
} else if (c > '9' || c < '0') {
return -1;
}
/* Read one more decimal position */
n[i] *= 10;
n[i] += c - '0';
} else {
return -1;
}
}
if (i != num - 1)
return -1;
return 0;
}
/**
* efi_cout_output_string() - write Unicode string to console
*
@@ -272,52 +200,6 @@ static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
return (mode->rows == rows) && (mode->columns == cols);
}
/**
* query_console_serial() - query serial console size
*
* When using a serial console or the net console we can only devise the
* terminal size by querying the terminal using ECMA-48 control sequences.
*
* @rows: pointer to return number of rows
* @cols: pointer to return number of columns
* Returns: 0 on success
*/
static int query_console_serial(int *rows, int *cols)
{
int ret = 0;
int n[2];
/* Empty input buffer */
while (tstc())
getchar();
/*
* Not all terminals understand CSI [18t for querying the console size.
* We should adhere to escape sequences documented in the console_codes
* man page and the ECMA-48 standard.
*
* So here we follow a different approach. We position the cursor to the
* bottom right and query its position. Before leaving the function we
* restore the original cursor position.
*/
printf(ESC "7" /* Save cursor position */
ESC "[r" /* Set scrolling region to full window */
ESC "[999;999H" /* Move to bottom right corner */
ESC "[6n"); /* Query cursor position */
/* Read {rows,cols} */
if (term_read_reply(n, 2, 'R')) {
ret = 1;
goto out;
}
*cols = n[1];
*rows = n[0];
out:
printf(ESC "8"); /* Restore cursor position */
return ret;
}
/**
* query_vidconsole() - query video console size
*
@@ -363,8 +245,8 @@ void efi_setup_console_size(void)
if (IS_ENABLED(CONFIG_VIDEO))
ret = query_vidconsole(&rows, &cols);
if (ret)
ret = query_console_serial(&rows, &cols);
if (ret && IS_ENABLED(CONFIG_DM_SERIAL))
ret = serial_query_size(&rows, &cols);
if (ret)
return;