mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-08-10 17:26:59 +02:00
drivers: serial: Add xtensa semihosting driver
Add xtensa semihosting driver. It can't use regular semihosting driver as Xtensa's has it's own semihosting ABI. Tested-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
This commit is contained in:
parent
bd64275f2d
commit
eb2daa0f4e
@ -501,6 +501,15 @@ config DEBUG_UART_MT7620
|
|||||||
driver will be available until the real driver model serial is
|
driver will be available until the real driver model serial is
|
||||||
running.
|
running.
|
||||||
|
|
||||||
|
config DEBUG_UART_XTENSA_SEMIHOSTING
|
||||||
|
bool "Xtensa semihosting"
|
||||||
|
depends on XTENSA_SEMIHOSTING_SERIAL
|
||||||
|
help
|
||||||
|
Select this to enable the debug UART using the Xtensa semihosting driver.
|
||||||
|
This provides basic serial output from the console without needing to
|
||||||
|
start up driver model. The driver will be available until the real
|
||||||
|
driver model serial is running.
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config DEBUG_UART_BASE
|
config DEBUG_UART_BASE
|
||||||
@ -936,7 +945,6 @@ config SH_SCIF_CLK_FREQ
|
|||||||
config SEMIHOSTING_SERIAL
|
config SEMIHOSTING_SERIAL
|
||||||
bool "Semihosting UART support"
|
bool "Semihosting UART support"
|
||||||
depends on SEMIHOSTING && !SERIAL_RX_BUFFER
|
depends on SEMIHOSTING && !SERIAL_RX_BUFFER
|
||||||
imply SERIAL_PUTS
|
|
||||||
help
|
help
|
||||||
Select this to enable a serial UART using semihosting. Special halt
|
Select this to enable a serial UART using semihosting. Special halt
|
||||||
instructions will be issued which an external debugger (such as a
|
instructions will be issued which an external debugger (such as a
|
||||||
@ -1115,6 +1123,14 @@ config XEN_SERIAL
|
|||||||
If built without DM support, then requires Xen
|
If built without DM support, then requires Xen
|
||||||
to be built with CONFIG_VERBOSE_DEBUG.
|
to be built with CONFIG_VERBOSE_DEBUG.
|
||||||
|
|
||||||
|
config XTENSA_SEMIHOSTING_SERIAL
|
||||||
|
bool "Xtensa Semihosting UART support"
|
||||||
|
depends on DM_SERIAL
|
||||||
|
depends on XTENSA_SEMIHOSTING
|
||||||
|
imply SERIAL_PUTS
|
||||||
|
help
|
||||||
|
Select this to enable a serial UART using Xtensa semihosting.
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "Console port"
|
prompt "Console port"
|
||||||
default 8xx_CONS_SMC1
|
default 8xx_CONS_SMC1
|
||||||
|
@ -60,6 +60,7 @@ obj-$(CONFIG_MT7620_SERIAL) += serial_mt7620.o
|
|||||||
obj-$(CONFIG_HTIF_CONSOLE) += serial_htif.o
|
obj-$(CONFIG_HTIF_CONSOLE) += serial_htif.o
|
||||||
obj-$(CONFIG_SIFIVE_SERIAL) += serial_sifive.o
|
obj-$(CONFIG_SIFIVE_SERIAL) += serial_sifive.o
|
||||||
obj-$(CONFIG_XEN_SERIAL) += serial_xen.o
|
obj-$(CONFIG_XEN_SERIAL) += serial_xen.o
|
||||||
|
obj-$(CONFIG_XTENSA_SEMIHOSTING_SERIAL) += serial_xtensa_semihosting.o
|
||||||
obj-$(CONFIG_S5P4418_PL011_SERIAL) += serial_s5p4418_pl011.o
|
obj-$(CONFIG_S5P4418_PL011_SERIAL) += serial_s5p4418_pl011.o
|
||||||
|
|
||||||
ifndef CONFIG_SPL_BUILD
|
ifndef CONFIG_SPL_BUILD
|
||||||
|
92
drivers/serial/serial_xtensa_semihosting.c
Normal file
92
drivers/serial/serial_xtensa_semihosting.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Jiaxun Yang <jiaxun.yang@flygoat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dm.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <serial.h>
|
||||||
|
|
||||||
|
#include <asm/platform/simcall.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct simc_serial_priv - Semihosting serial private data
|
||||||
|
* @counter: Counter used to fake pending every other call
|
||||||
|
*/
|
||||||
|
struct simc_serial_priv {
|
||||||
|
unsigned int counter;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int simc_serial_getc(struct udevice *dev)
|
||||||
|
{
|
||||||
|
char ch = 0;
|
||||||
|
|
||||||
|
simc_read(0, &ch, sizeof(ch));
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int simc_serial_putc(struct udevice *dev, const char ch)
|
||||||
|
{
|
||||||
|
char str[2] = {0};
|
||||||
|
|
||||||
|
str[0] = ch;
|
||||||
|
simc_write(1, str, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int simc_serial_pending(struct udevice *dev, bool input)
|
||||||
|
{
|
||||||
|
struct simc_serial_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
if (input) {
|
||||||
|
int res = simc_poll(0);
|
||||||
|
return res < 0 ? priv->counter++ & 1 : res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t smh_serial_puts(struct udevice *dev, const char *s, size_t len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = simc_write(1, s, len);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dm_serial_ops simc_serial_ops = {
|
||||||
|
.putc = simc_serial_putc,
|
||||||
|
.puts = smh_serial_puts,
|
||||||
|
.getc = simc_serial_getc,
|
||||||
|
.pending = simc_serial_pending,
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(simc_serial) = {
|
||||||
|
.name = "serial_xtensa_semihosting",
|
||||||
|
.id = UCLASS_SERIAL,
|
||||||
|
.priv_auto = sizeof(struct simc_serial_priv),
|
||||||
|
.ops = &simc_serial_ops,
|
||||||
|
.flags = DM_FLAG_PRE_RELOC,
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRVINFO(simc_serial) = {
|
||||||
|
.name = "serial_xtensa_semihosting",
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(DEBUG_UART_XTENSA_SEMIHOSTING)
|
||||||
|
#include <debug_uart.h>
|
||||||
|
|
||||||
|
static inline void _debug_uart_init(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _debug_uart_putc(int c)
|
||||||
|
{
|
||||||
|
simc_serial_putc(NULL, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_UART_FUNCS
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user