Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a845243258 | ||
|
|
c9f6855c71 | ||
|
|
2c2f4923b3 | ||
|
|
2423466c67 | ||
|
|
27bea75c2c | ||
|
|
36a202e795 | ||
|
|
58abd769d7 | ||
|
|
b94075124a | ||
|
|
2e79615c2b | ||
|
|
e3bd2654af | ||
|
|
e1d98424f0 | ||
|
|
9f7600b270 | ||
|
|
aa1cd00676 |
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
130
common/console.c
130
common/console.c
@@ -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)
|
||||
|
||||
@@ -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
62
doc/usage/console.rst
Normal 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()`.
|
||||
@@ -6,6 +6,7 @@ Use U-Boot
|
||||
|
||||
spl_boot
|
||||
blkmap
|
||||
console
|
||||
dfu
|
||||
environment
|
||||
fdt_overlays
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user