* [PATCH v4 0/3] Add riscv semihosting support in u-boot
@ 2022-09-19 11:49 Kautuk Consul
2022-09-19 11:49 ` [PATCH v4 1/3] lib: Add common semihosting library Kautuk Consul
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Kautuk Consul @ 2022-09-19 11:49 UTC (permalink / raw)
To: Rayagonda Kokatanur, Sean Anderson, Rick Chen, Leo, Simon Glass,
Heinrich Schuchardt, Ilias Apalodimas, Alexandru Gagniuc,
Philippe Reynes, Rasmus Villemoes, Stefan Roese, Loic Poulain,
Bin Meng
Cc: u-boot, Kautuk Consul
Semihosting is a mechanism that enables code running on
a target to communicate and use the Input/Output
facilities on a host computer that is running a debugger.
This patchset adds support for semihosting in u-boot
for RISCV64 targets.
CHANGES since v2 and v3:
- v2: Move the arch/arm/Kconfig common *SEMIHOSTING* config
options from arch/arm/Kconfig to lib/Kconfig.
- v2: Improve the *SEMIHOSTING_FALLBACK config options in
lib/Kconfig to depend on RISCV or ARM64.
- v2: Remove the arch/riscv/include/asm/semhosting.h file.
- v2: Improve the arch/riscv/lib/semihosting.c by removing the
jump statement and moving the .align 4 to before the 2
.option directives.
- v3: Additionally check for the RISCV config option in the "depends"
of the SPL_SEMIHOSTING_FALLBACK config option in lib/Kconfig.
Compilation and test commands for SPL and S-mode configurations
=================================================================
U-Boot S-mode on QEMU virt
----------------------------
// Compilation of S-mode u-boot
ARCH=riscv
CROSS_COMPILE=riscv64-unknown-linux-gnu-
make qemu-riscv64_smode_defconfig
make
// Run riscv 64-bit u-boot with opensbi on qemu
qemu-system-riscv64 -M virt -m 256M -display none -serial stdio -bios\
opensbi/build/platform/generic/firmware/fw_jump.bin -kernel\
u-boot/u-boot.bin
U-Boot SPL on QEMU virt
------------------------
// Compilation of u-boot-spl
ARCH=riscv
CROSS_COMPILE=riscv64-unknown-linux-gnu-
make qemu-riscv64_spl_defconfig
make OPENSBI=opensbi/build/platform/generic/firmware/fw_dynamic.bin
// Run 64-bit u-boot-spl in qemu
qemu-system-riscv64 -M virt -m 256M -display none -serial stdio -bios\
u-boot/spl/u-boot-spl.bin -device\
loader,file=u-boot/u-boot.itb,addr=0x80200000
Kautuk Consul (3):
lib: Add common semihosting library
arch/riscv: add semihosting support for RISC-V
board: qemu-riscv: enable semihosting
arch/arm/Kconfig | 46 -------
arch/arm/lib/semihosting.c | 181 +-------------------------
arch/riscv/include/asm/spl.h | 1 +
arch/riscv/lib/Makefile | 2 +
arch/riscv/lib/interrupts.c | 11 ++
arch/riscv/lib/semihosting.c | 24 ++++
configs/qemu-riscv32_defconfig | 4 +
configs/qemu-riscv32_smode_defconfig | 4 +
configs/qemu-riscv32_spl_defconfig | 7 +
configs/qemu-riscv64_defconfig | 4 +
configs/qemu-riscv64_smode_defconfig | 4 +
configs/qemu-riscv64_spl_defconfig | 7 +
include/semihosting.h | 11 ++
lib/Kconfig | 46 +++++++
lib/Makefile | 2 +
lib/semihosting.c | 186 +++++++++++++++++++++++++++
16 files changed, 314 insertions(+), 226 deletions(-)
create mode 100644 arch/riscv/lib/semihosting.c
create mode 100644 lib/semihosting.c
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v4 1/3] lib: Add common semihosting library 2022-09-19 11:49 [PATCH v4 0/3] Add riscv semihosting support in u-boot Kautuk Consul @ 2022-09-19 11:49 ` Kautuk Consul 2022-09-22 9:02 ` Leo Liang 2022-09-22 17:00 ` Sean Anderson 2022-09-19 11:49 ` [PATCH v4 2/3] arch/riscv: add semihosting support for RISC-V Kautuk Consul 2022-09-19 11:49 ` [PATCH v4 3/3] board: qemu-riscv: enable semihosting Kautuk Consul 2 siblings, 2 replies; 11+ messages in thread From: Kautuk Consul @ 2022-09-19 11:49 UTC (permalink / raw) To: Rayagonda Kokatanur, Sean Anderson, Rick Chen, Leo, Simon Glass, Heinrich Schuchardt, Ilias Apalodimas, Alexandru Gagniuc, Philippe Reynes, Rasmus Villemoes, Stefan Roese, Loic Poulain, Bin Meng Cc: u-boot, Kautuk Consul We factor out the arch-independent parts of the ARM semihosting implementation as a common library so that it can be shared with RISC-V. Signed-off-by: Kautuk Consul <kconsul@ventanamicro.com> --- arch/arm/Kconfig | 46 --------- arch/arm/lib/semihosting.c | 181 +----------------------------------- include/semihosting.h | 11 +++ lib/Kconfig | 46 +++++++++ lib/Makefile | 2 + lib/semihosting.c | 186 +++++++++++++++++++++++++++++++++++++ 6 files changed, 246 insertions(+), 226 deletions(-) create mode 100644 lib/semihosting.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 82cd456f51..ee6a9fadd9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -413,52 +413,6 @@ config ARM_SMCCC This should be enabled if U-Boot needs to communicate with system firmware (for example, PSCI) according to SMCCC. -config SEMIHOSTING - bool "Support ARM semihosting" - help - Semihosting is a method for a target to communicate with a host - debugger. It uses special instructions which the debugger will trap - on and interpret. This allows U-Boot to read/write files, print to - the console, and execute arbitrary commands on the host system. - - Enabling this option will add support for reading and writing files - on the host system. If you don't have a debugger attached then trying - to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. - -config SEMIHOSTING_FALLBACK - bool "Recover gracefully when semihosting fails" - depends on SEMIHOSTING && ARM64 - default y - help - Normally, if U-Boot makes a semihosting call and no debugger is - attached, then it will panic due to a synchronous abort - exception. This config adds an exception handler which will allow - U-Boot to recover. Say 'y' if unsure. - -config SPL_SEMIHOSTING - bool "Support ARM semihosting in SPL" - depends on SPL - help - Semihosting is a method for a target to communicate with a host - debugger. It uses special instructions which the debugger will trap - on and interpret. This allows U-Boot to read/write files, print to - the console, and execute arbitrary commands on the host system. - - Enabling this option will add support for reading and writing files - on the host system. If you don't have a debugger attached then trying - to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. - -config SPL_SEMIHOSTING_FALLBACK - bool "Recover gracefully when semihosting fails in SPL" - depends on SPL_SEMIHOSTING && ARM64 - select ARMV8_SPL_EXCEPTION_VECTORS - default y - help - Normally, if U-Boot makes a semihosting call and no debugger is - attached, then it will panic due to a synchronous abort - exception. This config adds an exception handler which will allow - U-Boot to recover. Say 'y' if unsure. - config SYS_THUMB_BUILD bool "Build U-Boot using the Thumb instruction set" depends on !ARM64 diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c index 01d652a6b8..11e7b85ee6 100644 --- a/arch/arm/lib/semihosting.c +++ b/arch/arm/lib/semihosting.c @@ -10,25 +10,11 @@ * available in silicon now, fastmodel usage makes less sense for them. */ #include <common.h> -#include <log.h> -#include <semihosting.h> - -#define SYSOPEN 0x01 -#define SYSCLOSE 0x02 -#define SYSWRITEC 0x03 -#define SYSWRITE0 0x04 -#define SYSWRITE 0x05 -#define SYSREAD 0x06 -#define SYSREADC 0x07 -#define SYSISERROR 0x08 -#define SYSSEEK 0x0A -#define SYSFLEN 0x0C -#define SYSERRNO 0x13 /* * Call the handler */ -static noinline long smh_trap(unsigned int sysnum, void *addr) +long smh_trap(unsigned int sysnum, void *addr) { register long result asm("r0"); #if defined(CONFIG_ARM64) @@ -41,168 +27,3 @@ static noinline long smh_trap(unsigned int sysnum, void *addr) #endif return result; } - -#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) -static bool _semihosting_enabled = true; -static bool try_semihosting = true; - -bool semihosting_enabled(void) -{ - if (try_semihosting) { - smh_trap(SYSERRNO, NULL); - try_semihosting = false; - } - - return _semihosting_enabled; -} - -void disable_semihosting(void) -{ - _semihosting_enabled = false; -} -#endif - -/** - * smh_errno() - Read the host's errno - * - * This gets the value of the host's errno and negates it. The host's errno may - * or may not be set, so only call this function if a previous semihosting call - * has failed. - * - * Return: a negative error value - */ -static int smh_errno(void) -{ - long ret = smh_trap(SYSERRNO, NULL); - - if (ret > 0 && ret < INT_MAX) - return -ret; - return -EIO; -} - -long smh_open(const char *fname, enum smh_open_mode mode) -{ - long fd; - struct smh_open_s { - const char *fname; - unsigned long mode; - size_t len; - } open; - - debug("%s: file \'%s\', mode \'%u\'\n", __func__, fname, mode); - - open.fname = fname; - open.len = strlen(fname); - open.mode = mode; - - /* Open the file on the host */ - fd = smh_trap(SYSOPEN, &open); - if (fd == -1) - return smh_errno(); - return fd; -} - -/** - * struct smg_rdwr_s - Arguments for read and write - * @fd: A file descriptor returned from smh_open() - * @memp: Pointer to a buffer of memory of at least @len bytes - * @len: The number of bytes to read or write - */ -struct smh_rdwr_s { - long fd; - void *memp; - size_t len; -}; - -long smh_read(long fd, void *memp, size_t len) -{ - long ret; - struct smh_rdwr_s read; - - debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); - - read.fd = fd; - read.memp = memp; - read.len = len; - - ret = smh_trap(SYSREAD, &read); - if (ret < 0) - return smh_errno(); - return len - ret; -} - -long smh_write(long fd, const void *memp, size_t len, ulong *written) -{ - long ret; - struct smh_rdwr_s write; - - debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); - - write.fd = fd; - write.memp = (void *)memp; - write.len = len; - - ret = smh_trap(SYSWRITE, &write); - *written = len - ret; - if (ret) - return smh_errno(); - return 0; -} - -long smh_close(long fd) -{ - long ret; - - debug("%s: fd %ld\n", __func__, fd); - - ret = smh_trap(SYSCLOSE, &fd); - if (ret == -1) - return smh_errno(); - return 0; -} - -long smh_flen(long fd) -{ - long ret; - - debug("%s: fd %ld\n", __func__, fd); - - ret = smh_trap(SYSFLEN, &fd); - if (ret == -1) - return smh_errno(); - return ret; -} - -long smh_seek(long fd, long pos) -{ - long ret; - struct smh_seek_s { - long fd; - long pos; - } seek; - - debug("%s: fd %ld pos %ld\n", __func__, fd, pos); - - seek.fd = fd; - seek.pos = pos; - - ret = smh_trap(SYSSEEK, &seek); - if (ret) - return smh_errno(); - return 0; -} - -int smh_getc(void) -{ - return smh_trap(SYSREADC, NULL); -} - -void smh_putc(char ch) -{ - smh_trap(SYSWRITEC, &ch); -} - -void smh_puts(const char *s) -{ - smh_trap(SYSWRITE0, (char *)s); -} diff --git a/include/semihosting.h b/include/semihosting.h index f1f73464e4..4e844cbad8 100644 --- a/include/semihosting.h +++ b/include/semihosting.h @@ -17,6 +17,17 @@ #define SMH_T32_SVC 0xDFAB #define SMH_T32_HLT 0xBABC +/** + * smh_trap() - ARCH-specific semihosting call. + * + * Semihosting library/driver can use this function to do the + * actual semihosting calls. + * + * Return: Error code defined by semihosting spec. + */ + +long smh_trap(unsigned int sysnum, void *addr); + #if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) /** * semihosting_enabled() - Determine whether semihosting is supported diff --git a/lib/Kconfig b/lib/Kconfig index 6121c80dc8..97920e7552 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -71,6 +71,52 @@ config HAVE_PRIVATE_LIBGCC config LIB_UUID bool +config SEMIHOSTING + bool "Support semihosting" + help + Semihosting is a method for a target to communicate with a host + debugger. It uses special instructions which the debugger will trap + on and interpret. This allows U-Boot to read/write files, print to + the console, and execute arbitrary commands on the host system. + + Enabling this option will add support for reading and writing files + on the host system. If you don't have a debugger attached then trying + to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. + +config SEMIHOSTING_FALLBACK + bool "Recover gracefully when semihosting fails" + depends on SEMIHOSTING && ARM64 + default y + help + Normally, if U-Boot makes a semihosting call and no debugger is + attached, then it will panic due to a synchronous abort + exception. This config adds an exception handler which will allow + U-Boot to recover. Say 'y' if unsure. + +config SPL_SEMIHOSTING + bool "Support semihosting in SPL" + depends on SPL + help + Semihosting is a method for a target to communicate with a host + debugger. It uses special instructions which the debugger will trap + on and interpret. This allows U-Boot to read/write files, print to + the console, and execute arbitrary commands on the host system. + + Enabling this option will add support for reading and writing files + on the host system. If you don't have a debugger attached then trying + to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. + +config SPL_SEMIHOSTING_FALLBACK + bool "Recover gracefully when semihosting fails in SPL" + depends on SPL_SEMIHOSTING && ARM64 + select ARMV8_SPL_EXCEPTION_VECTORS + default y + help + Normally, if U-Boot makes a semihosting call and no debugger is + attached, then it will panic due to a synchronous abort + exception. This config adds an exception handler which will allow + U-Boot to recover. Say 'y' if unsure. + config PRINTF bool default y diff --git a/lib/Makefile b/lib/Makefile index e3deb15287..134c4319cd 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -145,6 +145,8 @@ obj-y += date.o obj-y += rtc-lib.o obj-$(CONFIG_LIB_ELF) += elf.o +obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o + # # Build a fast OID lookup registry from include/linux/oid_registry.h # diff --git a/lib/semihosting.c b/lib/semihosting.c new file mode 100644 index 0000000000..831774e356 --- /dev/null +++ b/lib/semihosting.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com> + * Copyright 2014 Broadcom Corporation + */ + +#include <common.h> +#include <log.h> +#include <semihosting.h> + +#define SYSOPEN 0x01 +#define SYSCLOSE 0x02 +#define SYSWRITEC 0x03 +#define SYSWRITE0 0x04 +#define SYSWRITE 0x05 +#define SYSREAD 0x06 +#define SYSREADC 0x07 +#define SYSISERROR 0x08 +#define SYSSEEK 0x0A +#define SYSFLEN 0x0C +#define SYSERRNO 0x13 + +#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) +static bool _semihosting_enabled = true; +static bool try_semihosting = true; + +bool semihosting_enabled(void) +{ + if (try_semihosting) { + smh_trap(SYSERRNO, NULL); + try_semihosting = false; + } + + return _semihosting_enabled; +} + +void disable_semihosting(void) +{ + _semihosting_enabled = false; +} +#endif + +/** + * smh_errno() - Read the host's errno + * + * This gets the value of the host's errno and negates it. The host's errno may + * or may not be set, so only call this function if a previous semihosting call + * has failed. + * + * Return: a negative error value + */ +static int smh_errno(void) +{ + long ret = smh_trap(SYSERRNO, NULL); + + if (ret > 0 && ret < INT_MAX) + return -ret; + return -EIO; +} + +long smh_open(const char *fname, enum smh_open_mode mode) +{ + long fd; + struct smh_open_s { + const char *fname; + unsigned long mode; + size_t len; + } open; + + debug("%s: file \'%s\', mode \'%u\'\n", __func__, fname, mode); + + open.fname = fname; + open.len = strlen(fname); + open.mode = mode; + + /* Open the file on the host */ + fd = smh_trap(SYSOPEN, &open); + if (fd == -1) + return smh_errno(); + return fd; +} + +/** + * struct smg_rdwr_s - Arguments for read and write + * @fd: A file descriptor returned from smh_open() + * @memp: Pointer to a buffer of memory of at least @len bytes + * @len: The number of bytes to read or write + */ +struct smh_rdwr_s { + long fd; + void *memp; + size_t len; +}; + +long smh_read(long fd, void *memp, size_t len) +{ + long ret; + struct smh_rdwr_s read; + + debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); + + read.fd = fd; + read.memp = memp; + read.len = len; + + ret = smh_trap(SYSREAD, &read); + if (ret < 0) + return smh_errno(); + return len - ret; +} + +long smh_write(long fd, const void *memp, size_t len, ulong *written) +{ + long ret; + struct smh_rdwr_s write; + + debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); + + write.fd = fd; + write.memp = (void *)memp; + write.len = len; + + ret = smh_trap(SYSWRITE, &write); + *written = len - ret; + if (ret) + return smh_errno(); + return 0; +} + +long smh_close(long fd) +{ + long ret; + + debug("%s: fd %ld\n", __func__, fd); + + ret = smh_trap(SYSCLOSE, &fd); + if (ret == -1) + return smh_errno(); + return 0; +} + +long smh_flen(long fd) +{ + long ret; + + debug("%s: fd %ld\n", __func__, fd); + + ret = smh_trap(SYSFLEN, &fd); + if (ret == -1) + return smh_errno(); + return ret; +} + +long smh_seek(long fd, long pos) +{ + long ret; + struct smh_seek_s { + long fd; + long pos; + } seek; + + debug("%s: fd %ld pos %ld\n", __func__, fd, pos); + + seek.fd = fd; + seek.pos = pos; + + ret = smh_trap(SYSSEEK, &seek); + if (ret) + return smh_errno(); + return 0; +} + +int smh_getc(void) +{ + return smh_trap(SYSREADC, NULL); +} + +void smh_putc(char ch) +{ + smh_trap(SYSWRITEC, &ch); +} + +void smh_puts(const char *s) +{ + smh_trap(SYSWRITE0, (char *)s); +} -- 2.34.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 1/3] lib: Add common semihosting library 2022-09-19 11:49 ` [PATCH v4 1/3] lib: Add common semihosting library Kautuk Consul @ 2022-09-22 9:02 ` Leo Liang 2022-09-22 17:00 ` Sean Anderson 1 sibling, 0 replies; 11+ messages in thread From: Leo Liang @ 2022-09-22 9:02 UTC (permalink / raw) To: Kautuk Consul Cc: Rayagonda Kokatanur, Sean Anderson, Rick Chen, Simon Glass, Heinrich Schuchardt, Ilias Apalodimas, Alexandru Gagniuc, Philippe Reynes, Rasmus Villemoes, Stefan Roese, Loic Poulain, Bin Meng, u-boot On Mon, Sep 19, 2022 at 05:19:06PM +0530, Kautuk Consul wrote: > We factor out the arch-independent parts of the ARM semihosting > implementation as a common library so that it can be shared > with RISC-V. > > Signed-off-by: Kautuk Consul <kconsul@ventanamicro.com> > --- > arch/arm/Kconfig | 46 --------- > arch/arm/lib/semihosting.c | 181 +----------------------------------- > include/semihosting.h | 11 +++ > lib/Kconfig | 46 +++++++++ > lib/Makefile | 2 + > lib/semihosting.c | 186 +++++++++++++++++++++++++++++++++++++ > 6 files changed, 246 insertions(+), 226 deletions(-) > create mode 100644 lib/semihosting.c Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com> ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 1/3] lib: Add common semihosting library 2022-09-19 11:49 ` [PATCH v4 1/3] lib: Add common semihosting library Kautuk Consul 2022-09-22 9:02 ` Leo Liang @ 2022-09-22 17:00 ` Sean Anderson 2022-09-23 4:39 ` Kautuk Consul 1 sibling, 1 reply; 11+ messages in thread From: Sean Anderson @ 2022-09-22 17:00 UTC (permalink / raw) To: Kautuk Consul, Rayagonda Kokatanur, Rick Chen, Leo, Simon Glass, Heinrich Schuchardt, Ilias Apalodimas, Alexandru Gagniuc, Philippe Reynes, Rasmus Villemoes, Stefan Roese, Loic Poulain, Bin Meng Cc: u-boot On 9/19/22 7:49 AM, Kautuk Consul wrote: > We factor out the arch-independent parts of the ARM semihosting > implementation as a common library so that it can be shared > with RISC-V. > > Signed-off-by: Kautuk Consul <kconsul@ventanamicro.com> > --- > arch/arm/Kconfig | 46 --------- > arch/arm/lib/semihosting.c | 181 +----------------------------------- > include/semihosting.h | 11 +++ > lib/Kconfig | 46 +++++++++ > lib/Makefile | 2 + > lib/semihosting.c | 186 +++++++++++++++++++++++++++++++++++++ > 6 files changed, 246 insertions(+), 226 deletions(-) > create mode 100644 lib/semihosting.c > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 82cd456f51..ee6a9fadd9 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -413,52 +413,6 @@ config ARM_SMCCC > This should be enabled if U-Boot needs to communicate with system > firmware (for example, PSCI) according to SMCCC. > > -config SEMIHOSTING > - bool "Support ARM semihosting" > - help > - Semihosting is a method for a target to communicate with a host > - debugger. It uses special instructions which the debugger will trap > - on and interpret. This allows U-Boot to read/write files, print to > - the console, and execute arbitrary commands on the host system. > - > - Enabling this option will add support for reading and writing files > - on the host system. If you don't have a debugger attached then trying > - to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. > - > -config SEMIHOSTING_FALLBACK > - bool "Recover gracefully when semihosting fails" > - depends on SEMIHOSTING && ARM64 > - default y > - help > - Normally, if U-Boot makes a semihosting call and no debugger is > - attached, then it will panic due to a synchronous abort > - exception. This config adds an exception handler which will allow > - U-Boot to recover. Say 'y' if unsure. > - > -config SPL_SEMIHOSTING > - bool "Support ARM semihosting in SPL" > - depends on SPL > - help > - Semihosting is a method for a target to communicate with a host > - debugger. It uses special instructions which the debugger will trap > - on and interpret. This allows U-Boot to read/write files, print to > - the console, and execute arbitrary commands on the host system. > - > - Enabling this option will add support for reading and writing files > - on the host system. If you don't have a debugger attached then trying > - to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. > - > -config SPL_SEMIHOSTING_FALLBACK > - bool "Recover gracefully when semihosting fails in SPL" > - depends on SPL_SEMIHOSTING && ARM64 > - select ARMV8_SPL_EXCEPTION_VECTORS > - default y > - help > - Normally, if U-Boot makes a semihosting call and no debugger is > - attached, then it will panic due to a synchronous abort > - exception. This config adds an exception handler which will allow > - U-Boot to recover. Say 'y' if unsure. > - > config SYS_THUMB_BUILD > bool "Build U-Boot using the Thumb instruction set" > depends on !ARM64 > diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c > index 01d652a6b8..11e7b85ee6 100644 > --- a/arch/arm/lib/semihosting.c > +++ b/arch/arm/lib/semihosting.c > @@ -10,25 +10,11 @@ > * available in silicon now, fastmodel usage makes less sense for them. > */ > #include <common.h> > -#include <log.h> > -#include <semihosting.h> > - > -#define SYSOPEN 0x01 > -#define SYSCLOSE 0x02 > -#define SYSWRITEC 0x03 > -#define SYSWRITE0 0x04 > -#define SYSWRITE 0x05 > -#define SYSREAD 0x06 > -#define SYSREADC 0x07 > -#define SYSISERROR 0x08 > -#define SYSSEEK 0x0A > -#define SYSFLEN 0x0C > -#define SYSERRNO 0x13 > > /* > * Call the handler > */ > -static noinline long smh_trap(unsigned int sysnum, void *addr) > +long smh_trap(unsigned int sysnum, void *addr) > { > register long result asm("r0"); > #if defined(CONFIG_ARM64) > @@ -41,168 +27,3 @@ static noinline long smh_trap(unsigned int sysnum, void *addr) > #endif > return result; > } > - > -#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) > -static bool _semihosting_enabled = true; > -static bool try_semihosting = true; > - > -bool semihosting_enabled(void) > -{ > - if (try_semihosting) { > - smh_trap(SYSERRNO, NULL); > - try_semihosting = false; > - } > - > - return _semihosting_enabled; > -} > - > -void disable_semihosting(void) > -{ > - _semihosting_enabled = false; > -} > -#endif > - > -/** > - * smh_errno() - Read the host's errno > - * > - * This gets the value of the host's errno and negates it. The host's errno may > - * or may not be set, so only call this function if a previous semihosting call > - * has failed. > - * > - * Return: a negative error value > - */ > -static int smh_errno(void) > -{ > - long ret = smh_trap(SYSERRNO, NULL); > - > - if (ret > 0 && ret < INT_MAX) > - return -ret; > - return -EIO; > -} > - > -long smh_open(const char *fname, enum smh_open_mode mode) > -{ > - long fd; > - struct smh_open_s { > - const char *fname; > - unsigned long mode; > - size_t len; > - } open; > - > - debug("%s: file \'%s\', mode \'%u\'\n", __func__, fname, mode); > - > - open.fname = fname; > - open.len = strlen(fname); > - open.mode = mode; > - > - /* Open the file on the host */ > - fd = smh_trap(SYSOPEN, &open); > - if (fd == -1) > - return smh_errno(); > - return fd; > -} > - > -/** > - * struct smg_rdwr_s - Arguments for read and write > - * @fd: A file descriptor returned from smh_open() > - * @memp: Pointer to a buffer of memory of at least @len bytes > - * @len: The number of bytes to read or write > - */ > -struct smh_rdwr_s { > - long fd; > - void *memp; > - size_t len; > -}; > - > -long smh_read(long fd, void *memp, size_t len) > -{ > - long ret; > - struct smh_rdwr_s read; > - > - debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > - > - read.fd = fd; > - read.memp = memp; > - read.len = len; > - > - ret = smh_trap(SYSREAD, &read); > - if (ret < 0) > - return smh_errno(); > - return len - ret; > -} > - > -long smh_write(long fd, const void *memp, size_t len, ulong *written) > -{ > - long ret; > - struct smh_rdwr_s write; > - > - debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > - > - write.fd = fd; > - write.memp = (void *)memp; > - write.len = len; > - > - ret = smh_trap(SYSWRITE, &write); > - *written = len - ret; > - if (ret) > - return smh_errno(); > - return 0; > -} > - > -long smh_close(long fd) > -{ > - long ret; > - > - debug("%s: fd %ld\n", __func__, fd); > - > - ret = smh_trap(SYSCLOSE, &fd); > - if (ret == -1) > - return smh_errno(); > - return 0; > -} > - > -long smh_flen(long fd) > -{ > - long ret; > - > - debug("%s: fd %ld\n", __func__, fd); > - > - ret = smh_trap(SYSFLEN, &fd); > - if (ret == -1) > - return smh_errno(); > - return ret; > -} > - > -long smh_seek(long fd, long pos) > -{ > - long ret; > - struct smh_seek_s { > - long fd; > - long pos; > - } seek; > - > - debug("%s: fd %ld pos %ld\n", __func__, fd, pos); > - > - seek.fd = fd; > - seek.pos = pos; > - > - ret = smh_trap(SYSSEEK, &seek); > - if (ret) > - return smh_errno(); > - return 0; > -} > - > -int smh_getc(void) > -{ > - return smh_trap(SYSREADC, NULL); > -} > - > -void smh_putc(char ch) > -{ > - smh_trap(SYSWRITEC, &ch); > -} > - > -void smh_puts(const char *s) > -{ > - smh_trap(SYSWRITE0, (char *)s); > -} > diff --git a/include/semihosting.h b/include/semihosting.h > index f1f73464e4..4e844cbad8 100644 > --- a/include/semihosting.h > +++ b/include/semihosting.h > @@ -17,6 +17,17 @@ > #define SMH_T32_SVC 0xDFAB > #define SMH_T32_HLT 0xBABC > > +/** > + * smh_trap() - ARCH-specific semihosting call. > + * > + * Semihosting library/driver can use this function to do the > + * actual semihosting calls. > + * > + * Return: Error code defined by semihosting spec. > + */ > + > +long smh_trap(unsigned int sysnum, void *addr); > + > #if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) > /** > * semihosting_enabled() - Determine whether semihosting is supported > diff --git a/lib/Kconfig b/lib/Kconfig > index 6121c80dc8..97920e7552 100644 > --- a/lib/Kconfig > +++ b/lib/Kconfig > @@ -71,6 +71,52 @@ config HAVE_PRIVATE_LIBGCC > config LIB_UUID > bool > > +config SEMIHOSTING > + bool "Support semihosting" Should probably depend on ARM (and in the next patch RISCV). > + help > + Semihosting is a method for a target to communicate with a host > + debugger. It uses special instructions which the debugger will trap > + on and interpret. This allows U-Boot to read/write files, print to > + the console, and execute arbitrary commands on the host system. > + > + Enabling this option will add support for reading and writing files > + on the host system. If you don't have a debugger attached then trying > + to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. > + > +config SEMIHOSTING_FALLBACK > + bool "Recover gracefully when semihosting fails" > + depends on SEMIHOSTING && ARM64 > + default y > + help > + Normally, if U-Boot makes a semihosting call and no debugger is > + attached, then it will panic due to a synchronous abort > + exception. This config adds an exception handler which will allow > + U-Boot to recover. Say 'y' if unsure. > + > +config SPL_SEMIHOSTING > + bool "Support semihosting in SPL" > + depends on SPL ditto > + help > + Semihosting is a method for a target to communicate with a host > + debugger. It uses special instructions which the debugger will trap > + on and interpret. This allows U-Boot to read/write files, print to > + the console, and execute arbitrary commands on the host system. > + > + Enabling this option will add support for reading and writing files > + on the host system. If you don't have a debugger attached then trying > + to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. > + > +config SPL_SEMIHOSTING_FALLBACK > + bool "Recover gracefully when semihosting fails in SPL" > + depends on SPL_SEMIHOSTING && ARM64 > + select ARMV8_SPL_EXCEPTION_VECTORS > + default y > + help > + Normally, if U-Boot makes a semihosting call and no debugger is > + attached, then it will panic due to a synchronous abort > + exception. This config adds an exception handler which will allow > + U-Boot to recover. Say 'y' if unsure. > + > config PRINTF > bool > default y > diff --git a/lib/Makefile b/lib/Makefile > index e3deb15287..134c4319cd 100644 > --- a/lib/Makefile > +++ b/lib/Makefile > @@ -145,6 +145,8 @@ obj-y += date.o > obj-y += rtc-lib.o > obj-$(CONFIG_LIB_ELF) += elf.o > > +obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o > + > # > # Build a fast OID lookup registry from include/linux/oid_registry.h > # > diff --git a/lib/semihosting.c b/lib/semihosting.c > new file mode 100644 > index 0000000000..831774e356 > --- /dev/null > +++ b/lib/semihosting.c > @@ -0,0 +1,186 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com> > + * Copyright 2014 Broadcom Corporation > + */ > + > +#include <common.h> > +#include <log.h> > +#include <semihosting.h> > + > +#define SYSOPEN 0x01 > +#define SYSCLOSE 0x02 > +#define SYSWRITEC 0x03 > +#define SYSWRITE0 0x04 > +#define SYSWRITE 0x05 > +#define SYSREAD 0x06 > +#define SYSREADC 0x07 > +#define SYSISERROR 0x08 > +#define SYSSEEK 0x0A > +#define SYSFLEN 0x0C > +#define SYSERRNO 0x13 > + > +#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) > +static bool _semihosting_enabled = true; > +static bool try_semihosting = true; > + > +bool semihosting_enabled(void) > +{ > + if (try_semihosting) { > + smh_trap(SYSERRNO, NULL); > + try_semihosting = false; > + } > + > + return _semihosting_enabled; > +} > + > +void disable_semihosting(void) > +{ > + _semihosting_enabled = false; > +} > +#endif > + > +/** > + * smh_errno() - Read the host's errno > + * > + * This gets the value of the host's errno and negates it. The host's errno may > + * or may not be set, so only call this function if a previous semihosting call > + * has failed. > + * > + * Return: a negative error value > + */ > +static int smh_errno(void) > +{ > + long ret = smh_trap(SYSERRNO, NULL); > + > + if (ret > 0 && ret < INT_MAX) > + return -ret; > + return -EIO; > +} > + > +long smh_open(const char *fname, enum smh_open_mode mode) > +{ > + long fd; > + struct smh_open_s { > + const char *fname; > + unsigned long mode; > + size_t len; > + } open; > + > + debug("%s: file \'%s\', mode \'%u\'\n", __func__, fname, mode); > + > + open.fname = fname; > + open.len = strlen(fname); > + open.mode = mode; > + > + /* Open the file on the host */ > + fd = smh_trap(SYSOPEN, &open); > + if (fd == -1) > + return smh_errno(); > + return fd; > +} > + > +/** > + * struct smg_rdwr_s - Arguments for read and write > + * @fd: A file descriptor returned from smh_open() > + * @memp: Pointer to a buffer of memory of at least @len bytes > + * @len: The number of bytes to read or write > + */ > +struct smh_rdwr_s { > + long fd; > + void *memp; > + size_t len; > +}; > + > +long smh_read(long fd, void *memp, size_t len) > +{ > + long ret; > + struct smh_rdwr_s read; > + > + debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > + > + read.fd = fd; > + read.memp = memp; > + read.len = len; > + > + ret = smh_trap(SYSREAD, &read); > + if (ret < 0) > + return smh_errno(); > + return len - ret; > +} > + > +long smh_write(long fd, const void *memp, size_t len, ulong *written) > +{ > + long ret; > + struct smh_rdwr_s write; > + > + debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > + > + write.fd = fd; > + write.memp = (void *)memp; > + write.len = len; > + > + ret = smh_trap(SYSWRITE, &write); > + *written = len - ret; > + if (ret) > + return smh_errno(); > + return 0; > +} > + > +long smh_close(long fd) > +{ > + long ret; > + > + debug("%s: fd %ld\n", __func__, fd); > + > + ret = smh_trap(SYSCLOSE, &fd); > + if (ret == -1) > + return smh_errno(); > + return 0; > +} > + > +long smh_flen(long fd) > +{ > + long ret; > + > + debug("%s: fd %ld\n", __func__, fd); > + > + ret = smh_trap(SYSFLEN, &fd); > + if (ret == -1) > + return smh_errno(); > + return ret; > +} > + > +long smh_seek(long fd, long pos) > +{ > + long ret; > + struct smh_seek_s { > + long fd; > + long pos; > + } seek; > + > + debug("%s: fd %ld pos %ld\n", __func__, fd, pos); > + > + seek.fd = fd; > + seek.pos = pos; > + > + ret = smh_trap(SYSSEEK, &seek); > + if (ret) > + return smh_errno(); > + return 0; > +} > + > +int smh_getc(void) > +{ > + return smh_trap(SYSREADC, NULL); > +} > + > +void smh_putc(char ch) > +{ > + smh_trap(SYSWRITEC, &ch); > +} > + > +void smh_puts(const char *s) > +{ > + smh_trap(SYSWRITE0, (char *)s); > +} > Other than that, Reviewed-by: Sean Anderson <sean.anderson@seco.com> ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 1/3] lib: Add common semihosting library 2022-09-22 17:00 ` Sean Anderson @ 2022-09-23 4:39 ` Kautuk Consul 0 siblings, 0 replies; 11+ messages in thread From: Kautuk Consul @ 2022-09-23 4:39 UTC (permalink / raw) To: Sean Anderson Cc: Rayagonda Kokatanur, Rick Chen, Leo, Simon Glass, Heinrich Schuchardt, Ilias Apalodimas, Alexandru Gagniuc, Philippe Reynes, Rasmus Villemoes, Stefan Roese, Loic Poulain, Bin Meng, u-boot Hi Sean, On Thu, Sep 22, 2022 at 10:30 PM Sean Anderson <sean.anderson@seco.com> wrote: > > > > On 9/19/22 7:49 AM, Kautuk Consul wrote: > > We factor out the arch-independent parts of the ARM semihosting > > implementation as a common library so that it can be shared > > with RISC-V. > > > > Signed-off-by: Kautuk Consul <kconsul@ventanamicro.com> > > --- > > arch/arm/Kconfig | 46 --------- > > arch/arm/lib/semihosting.c | 181 +----------------------------------- > > include/semihosting.h | 11 +++ > > lib/Kconfig | 46 +++++++++ > > lib/Makefile | 2 + > > lib/semihosting.c | 186 +++++++++++++++++++++++++++++++++++++ > > 6 files changed, 246 insertions(+), 226 deletions(-) > > create mode 100644 lib/semihosting.c > > > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > > index 82cd456f51..ee6a9fadd9 100644 > > --- a/arch/arm/Kconfig > > +++ b/arch/arm/Kconfig > > @@ -413,52 +413,6 @@ config ARM_SMCCC > > This should be enabled if U-Boot needs to communicate with system > > firmware (for example, PSCI) according to SMCCC. > > > > -config SEMIHOSTING > > - bool "Support ARM semihosting" > > - help > > - Semihosting is a method for a target to communicate with a host > > - debugger. It uses special instructions which the debugger will trap > > - on and interpret. This allows U-Boot to read/write files, print to > > - the console, and execute arbitrary commands on the host system. > > - > > - Enabling this option will add support for reading and writing files > > - on the host system. If you don't have a debugger attached then trying > > - to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. > > - > > -config SEMIHOSTING_FALLBACK > > - bool "Recover gracefully when semihosting fails" > > - depends on SEMIHOSTING && ARM64 > > - default y > > - help > > - Normally, if U-Boot makes a semihosting call and no debugger is > > - attached, then it will panic due to a synchronous abort > > - exception. This config adds an exception handler which will allow > > - U-Boot to recover. Say 'y' if unsure. > > - > > -config SPL_SEMIHOSTING > > - bool "Support ARM semihosting in SPL" > > - depends on SPL > > - help > > - Semihosting is a method for a target to communicate with a host > > - debugger. It uses special instructions which the debugger will trap > > - on and interpret. This allows U-Boot to read/write files, print to > > - the console, and execute arbitrary commands on the host system. > > - > > - Enabling this option will add support for reading and writing files > > - on the host system. If you don't have a debugger attached then trying > > - to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. > > - > > -config SPL_SEMIHOSTING_FALLBACK > > - bool "Recover gracefully when semihosting fails in SPL" > > - depends on SPL_SEMIHOSTING && ARM64 > > - select ARMV8_SPL_EXCEPTION_VECTORS > > - default y > > - help > > - Normally, if U-Boot makes a semihosting call and no debugger is > > - attached, then it will panic due to a synchronous abort > > - exception. This config adds an exception handler which will allow > > - U-Boot to recover. Say 'y' if unsure. > > - > > config SYS_THUMB_BUILD > > bool "Build U-Boot using the Thumb instruction set" > > depends on !ARM64 > > diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c > > index 01d652a6b8..11e7b85ee6 100644 > > --- a/arch/arm/lib/semihosting.c > > +++ b/arch/arm/lib/semihosting.c > > @@ -10,25 +10,11 @@ > > * available in silicon now, fastmodel usage makes less sense for them. > > */ > > #include <common.h> > > -#include <log.h> > > -#include <semihosting.h> > > - > > -#define SYSOPEN 0x01 > > -#define SYSCLOSE 0x02 > > -#define SYSWRITEC 0x03 > > -#define SYSWRITE0 0x04 > > -#define SYSWRITE 0x05 > > -#define SYSREAD 0x06 > > -#define SYSREADC 0x07 > > -#define SYSISERROR 0x08 > > -#define SYSSEEK 0x0A > > -#define SYSFLEN 0x0C > > -#define SYSERRNO 0x13 > > > > /* > > * Call the handler > > */ > > -static noinline long smh_trap(unsigned int sysnum, void *addr) > > +long smh_trap(unsigned int sysnum, void *addr) > > { > > register long result asm("r0"); > > #if defined(CONFIG_ARM64) > > @@ -41,168 +27,3 @@ static noinline long smh_trap(unsigned int sysnum, void *addr) > > #endif > > return result; > > } > > - > > -#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) > > -static bool _semihosting_enabled = true; > > -static bool try_semihosting = true; > > - > > -bool semihosting_enabled(void) > > -{ > > - if (try_semihosting) { > > - smh_trap(SYSERRNO, NULL); > > - try_semihosting = false; > > - } > > - > > - return _semihosting_enabled; > > -} > > - > > -void disable_semihosting(void) > > -{ > > - _semihosting_enabled = false; > > -} > > -#endif > > - > > -/** > > - * smh_errno() - Read the host's errno > > - * > > - * This gets the value of the host's errno and negates it. The host's errno may > > - * or may not be set, so only call this function if a previous semihosting call > > - * has failed. > > - * > > - * Return: a negative error value > > - */ > > -static int smh_errno(void) > > -{ > > - long ret = smh_trap(SYSERRNO, NULL); > > - > > - if (ret > 0 && ret < INT_MAX) > > - return -ret; > > - return -EIO; > > -} > > - > > -long smh_open(const char *fname, enum smh_open_mode mode) > > -{ > > - long fd; > > - struct smh_open_s { > > - const char *fname; > > - unsigned long mode; > > - size_t len; > > - } open; > > - > > - debug("%s: file \'%s\', mode \'%u\'\n", __func__, fname, mode); > > - > > - open.fname = fname; > > - open.len = strlen(fname); > > - open.mode = mode; > > - > > - /* Open the file on the host */ > > - fd = smh_trap(SYSOPEN, &open); > > - if (fd == -1) > > - return smh_errno(); > > - return fd; > > -} > > - > > -/** > > - * struct smg_rdwr_s - Arguments for read and write > > - * @fd: A file descriptor returned from smh_open() > > - * @memp: Pointer to a buffer of memory of at least @len bytes > > - * @len: The number of bytes to read or write > > - */ > > -struct smh_rdwr_s { > > - long fd; > > - void *memp; > > - size_t len; > > -}; > > - > > -long smh_read(long fd, void *memp, size_t len) > > -{ > > - long ret; > > - struct smh_rdwr_s read; > > - > > - debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > > - > > - read.fd = fd; > > - read.memp = memp; > > - read.len = len; > > - > > - ret = smh_trap(SYSREAD, &read); > > - if (ret < 0) > > - return smh_errno(); > > - return len - ret; > > -} > > - > > -long smh_write(long fd, const void *memp, size_t len, ulong *written) > > -{ > > - long ret; > > - struct smh_rdwr_s write; > > - > > - debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > > - > > - write.fd = fd; > > - write.memp = (void *)memp; > > - write.len = len; > > - > > - ret = smh_trap(SYSWRITE, &write); > > - *written = len - ret; > > - if (ret) > > - return smh_errno(); > > - return 0; > > -} > > - > > -long smh_close(long fd) > > -{ > > - long ret; > > - > > - debug("%s: fd %ld\n", __func__, fd); > > - > > - ret = smh_trap(SYSCLOSE, &fd); > > - if (ret == -1) > > - return smh_errno(); > > - return 0; > > -} > > - > > -long smh_flen(long fd) > > -{ > > - long ret; > > - > > - debug("%s: fd %ld\n", __func__, fd); > > - > > - ret = smh_trap(SYSFLEN, &fd); > > - if (ret == -1) > > - return smh_errno(); > > - return ret; > > -} > > - > > -long smh_seek(long fd, long pos) > > -{ > > - long ret; > > - struct smh_seek_s { > > - long fd; > > - long pos; > > - } seek; > > - > > - debug("%s: fd %ld pos %ld\n", __func__, fd, pos); > > - > > - seek.fd = fd; > > - seek.pos = pos; > > - > > - ret = smh_trap(SYSSEEK, &seek); > > - if (ret) > > - return smh_errno(); > > - return 0; > > -} > > - > > -int smh_getc(void) > > -{ > > - return smh_trap(SYSREADC, NULL); > > -} > > - > > -void smh_putc(char ch) > > -{ > > - smh_trap(SYSWRITEC, &ch); > > -} > > - > > -void smh_puts(const char *s) > > -{ > > - smh_trap(SYSWRITE0, (char *)s); > > -} > > diff --git a/include/semihosting.h b/include/semihosting.h > > index f1f73464e4..4e844cbad8 100644 > > --- a/include/semihosting.h > > +++ b/include/semihosting.h > > @@ -17,6 +17,17 @@ > > #define SMH_T32_SVC 0xDFAB > > #define SMH_T32_HLT 0xBABC > > > > +/** > > + * smh_trap() - ARCH-specific semihosting call. > > + * > > + * Semihosting library/driver can use this function to do the > > + * actual semihosting calls. > > + * > > + * Return: Error code defined by semihosting spec. > > + */ > > + > > +long smh_trap(unsigned int sysnum, void *addr); > > + > > #if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) > > /** > > * semihosting_enabled() - Determine whether semihosting is supported > > diff --git a/lib/Kconfig b/lib/Kconfig > > index 6121c80dc8..97920e7552 100644 > > --- a/lib/Kconfig > > +++ b/lib/Kconfig > > @@ -71,6 +71,52 @@ config HAVE_PRIVATE_LIBGCC > > config LIB_UUID > > bool > > > > +config SEMIHOSTING > > + bool "Support semihosting" > > Should probably depend on ARM (and in the next patch RISCV). I did think of this. The fallback part appears to be arch-dependent. But can we make the main SEMIHOSTING options as arch-independent as that was the way they were before ? > > > + help > > + Semihosting is a method for a target to communicate with a host > > + debugger. It uses special instructions which the debugger will trap > > + on and interpret. This allows U-Boot to read/write files, print to > > + the console, and execute arbitrary commands on the host system. > > + > > + Enabling this option will add support for reading and writing files > > + on the host system. If you don't have a debugger attached then trying > > + to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. > > + > > +config SEMIHOSTING_FALLBACK > > + bool "Recover gracefully when semihosting fails" > > + depends on SEMIHOSTING && ARM64 > > + default y > > + help > > + Normally, if U-Boot makes a semihosting call and no debugger is > > + attached, then it will panic due to a synchronous abort > > + exception. This config adds an exception handler which will allow > > + U-Boot to recover. Say 'y' if unsure. > > + > > +config SPL_SEMIHOSTING > > + bool "Support semihosting in SPL" > > + depends on SPL > > ditto > > > + help > > + Semihosting is a method for a target to communicate with a host > > + debugger. It uses special instructions which the debugger will trap > > + on and interpret. This allows U-Boot to read/write files, print to > > + the console, and execute arbitrary commands on the host system. > > + > > + Enabling this option will add support for reading and writing files > > + on the host system. If you don't have a debugger attached then trying > > + to do this will likely cause U-Boot to hang. Say 'n' if you are unsure. > > + > > +config SPL_SEMIHOSTING_FALLBACK > > + bool "Recover gracefully when semihosting fails in SPL" > > + depends on SPL_SEMIHOSTING && ARM64 > > + select ARMV8_SPL_EXCEPTION_VECTORS > > + default y > > + help > > + Normally, if U-Boot makes a semihosting call and no debugger is > > + attached, then it will panic due to a synchronous abort > > + exception. This config adds an exception handler which will allow > > + U-Boot to recover. Say 'y' if unsure. > > + > > config PRINTF > > bool > > default y > > diff --git a/lib/Makefile b/lib/Makefile > > index e3deb15287..134c4319cd 100644 > > --- a/lib/Makefile > > +++ b/lib/Makefile > > @@ -145,6 +145,8 @@ obj-y += date.o > > obj-y += rtc-lib.o > > obj-$(CONFIG_LIB_ELF) += elf.o > > > > +obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o > > + > > # > > # Build a fast OID lookup registry from include/linux/oid_registry.h > > # > > diff --git a/lib/semihosting.c b/lib/semihosting.c > > new file mode 100644 > > index 0000000000..831774e356 > > --- /dev/null > > +++ b/lib/semihosting.c > > @@ -0,0 +1,186 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +/* > > + * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com> > > + * Copyright 2014 Broadcom Corporation > > + */ > > + > > +#include <common.h> > > +#include <log.h> > > +#include <semihosting.h> > > + > > +#define SYSOPEN 0x01 > > +#define SYSCLOSE 0x02 > > +#define SYSWRITEC 0x03 > > +#define SYSWRITE0 0x04 > > +#define SYSWRITE 0x05 > > +#define SYSREAD 0x06 > > +#define SYSREADC 0x07 > > +#define SYSISERROR 0x08 > > +#define SYSSEEK 0x0A > > +#define SYSFLEN 0x0C > > +#define SYSERRNO 0x13 > > + > > +#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) > > +static bool _semihosting_enabled = true; > > +static bool try_semihosting = true; > > + > > +bool semihosting_enabled(void) > > +{ > > + if (try_semihosting) { > > + smh_trap(SYSERRNO, NULL); > > + try_semihosting = false; > > + } > > + > > + return _semihosting_enabled; > > +} > > + > > +void disable_semihosting(void) > > +{ > > + _semihosting_enabled = false; > > +} > > +#endif > > + > > +/** > > + * smh_errno() - Read the host's errno > > + * > > + * This gets the value of the host's errno and negates it. The host's errno may > > + * or may not be set, so only call this function if a previous semihosting call > > + * has failed. > > + * > > + * Return: a negative error value > > + */ > > +static int smh_errno(void) > > +{ > > + long ret = smh_trap(SYSERRNO, NULL); > > + > > + if (ret > 0 && ret < INT_MAX) > > + return -ret; > > + return -EIO; > > +} > > + > > +long smh_open(const char *fname, enum smh_open_mode mode) > > +{ > > + long fd; > > + struct smh_open_s { > > + const char *fname; > > + unsigned long mode; > > + size_t len; > > + } open; > > + > > + debug("%s: file \'%s\', mode \'%u\'\n", __func__, fname, mode); > > + > > + open.fname = fname; > > + open.len = strlen(fname); > > + open.mode = mode; > > + > > + /* Open the file on the host */ > > + fd = smh_trap(SYSOPEN, &open); > > + if (fd == -1) > > + return smh_errno(); > > + return fd; > > +} > > + > > +/** > > + * struct smg_rdwr_s - Arguments for read and write > > + * @fd: A file descriptor returned from smh_open() > > + * @memp: Pointer to a buffer of memory of at least @len bytes > > + * @len: The number of bytes to read or write > > + */ > > +struct smh_rdwr_s { > > + long fd; > > + void *memp; > > + size_t len; > > +}; > > + > > +long smh_read(long fd, void *memp, size_t len) > > +{ > > + long ret; > > + struct smh_rdwr_s read; > > + > > + debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > > + > > + read.fd = fd; > > + read.memp = memp; > > + read.len = len; > > + > > + ret = smh_trap(SYSREAD, &read); > > + if (ret < 0) > > + return smh_errno(); > > + return len - ret; > > +} > > + > > +long smh_write(long fd, const void *memp, size_t len, ulong *written) > > +{ > > + long ret; > > + struct smh_rdwr_s write; > > + > > + debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > > + > > + write.fd = fd; > > + write.memp = (void *)memp; > > + write.len = len; > > + > > + ret = smh_trap(SYSWRITE, &write); > > + *written = len - ret; > > + if (ret) > > + return smh_errno(); > > + return 0; > > +} > > + > > +long smh_close(long fd) > > +{ > > + long ret; > > + > > + debug("%s: fd %ld\n", __func__, fd); > > + > > + ret = smh_trap(SYSCLOSE, &fd); > > + if (ret == -1) > > + return smh_errno(); > > + return 0; > > +} > > + > > +long smh_flen(long fd) > > +{ > > + long ret; > > + > > + debug("%s: fd %ld\n", __func__, fd); > > + > > + ret = smh_trap(SYSFLEN, &fd); > > + if (ret == -1) > > + return smh_errno(); > > + return ret; > > +} > > + > > +long smh_seek(long fd, long pos) > > +{ > > + long ret; > > + struct smh_seek_s { > > + long fd; > > + long pos; > > + } seek; > > + > > + debug("%s: fd %ld pos %ld\n", __func__, fd, pos); > > + > > + seek.fd = fd; > > + seek.pos = pos; > > + > > + ret = smh_trap(SYSSEEK, &seek); > > + if (ret) > > + return smh_errno(); > > + return 0; > > +} > > + > > +int smh_getc(void) > > +{ > > + return smh_trap(SYSREADC, NULL); > > +} > > + > > +void smh_putc(char ch) > > +{ > > + smh_trap(SYSWRITEC, &ch); > > +} > > + > > +void smh_puts(const char *s) > > +{ > > + smh_trap(SYSWRITE0, (char *)s); > > +} > > > > Other than that, > > Reviewed-by: Sean Anderson <sean.anderson@seco.com> ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 2/3] arch/riscv: add semihosting support for RISC-V 2022-09-19 11:49 [PATCH v4 0/3] Add riscv semihosting support in u-boot Kautuk Consul 2022-09-19 11:49 ` [PATCH v4 1/3] lib: Add common semihosting library Kautuk Consul @ 2022-09-19 11:49 ` Kautuk Consul 2022-09-22 9:03 ` Leo Liang 2022-09-22 17:05 ` Sean Anderson 2022-09-19 11:49 ` [PATCH v4 3/3] board: qemu-riscv: enable semihosting Kautuk Consul 2 siblings, 2 replies; 11+ messages in thread From: Kautuk Consul @ 2022-09-19 11:49 UTC (permalink / raw) To: Rayagonda Kokatanur, Sean Anderson, Rick Chen, Leo, Simon Glass, Heinrich Schuchardt, Ilias Apalodimas, Alexandru Gagniuc, Philippe Reynes, Rasmus Villemoes, Stefan Roese, Loic Poulain, Bin Meng Cc: u-boot, Kautuk Consul, Anup Patel We add RISC-V semihosting based serial console for JTAG based early debugging. The RISC-V semihosting specification is available at: https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc Signed-off-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Kautuk Consul <kconsul@ventanamicro.com> --- arch/riscv/include/asm/spl.h | 1 + arch/riscv/lib/Makefile | 2 ++ arch/riscv/lib/interrupts.c | 11 +++++++++++ arch/riscv/lib/semihosting.c | 24 ++++++++++++++++++++++++ lib/Kconfig | 6 +++--- 5 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 arch/riscv/lib/semihosting.c diff --git a/arch/riscv/include/asm/spl.h b/arch/riscv/include/asm/spl.h index e8a94fcb1f..2898a770ee 100644 --- a/arch/riscv/include/asm/spl.h +++ b/arch/riscv/include/asm/spl.h @@ -25,6 +25,7 @@ enum { BOOT_DEVICE_DFU, BOOT_DEVICE_XIP, BOOT_DEVICE_BOOTROM, + BOOT_DEVICE_SMH, BOOT_DEVICE_NONE }; diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index 06020fcc2a..64e29804c1 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -42,3 +42,5 @@ extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC) obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMSET) += memset.o obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMMOVE) += memmove.o obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMCPY) += memcpy.o + +obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c index 100be2e966..bd7cd772b8 100644 --- a/arch/riscv/lib/interrupts.c +++ b/arch/riscv/lib/interrupts.c @@ -17,6 +17,7 @@ #include <asm/ptrace.h> #include <asm/system.h> #include <asm/encoding.h> +#include <semihosting.h> DECLARE_GLOBAL_DATA_PTR; @@ -149,6 +150,16 @@ ulong handle_trap(ulong cause, ulong epc, ulong tval, struct pt_regs *regs) /* An UEFI application may have changed gd. Restore U-Boot's gd. */ efi_restore_gd(); + if (cause == CAUSE_BREAKPOINT && + CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK)) { + /* For semihosting fallback we simply skip the ebreak + * instruction. + */ + disable_semihosting(); + epc += 4; + return epc; + } + is_irq = (cause & MCAUSE_INT); irq = (cause & ~MCAUSE_INT); diff --git a/arch/riscv/lib/semihosting.c b/arch/riscv/lib/semihosting.c new file mode 100644 index 0000000000..d6593b02a6 --- /dev/null +++ b/arch/riscv/lib/semihosting.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Ventana Micro Systems Inc. + */ + +#include <common.h> + +long smh_trap(int sysnum, void *addr) +{ + register int ret asm ("a0") = sysnum; + register void *param0 asm ("a1") = addr; + + asm volatile (".align 4\n" + ".option push\n" + ".option norvc\n" + + "slli zero, zero, 0x1f\n" + "ebreak\n" + "srai zero, zero, 7\n" + ".option pop\n" + : "+r" (ret) : "r" (param0) : "memory"); + + return ret; +} diff --git a/lib/Kconfig b/lib/Kconfig index 97920e7552..eed3a231d9 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -85,7 +85,7 @@ config SEMIHOSTING config SEMIHOSTING_FALLBACK bool "Recover gracefully when semihosting fails" - depends on SEMIHOSTING && ARM64 + depends on SEMIHOSTING && (ARM64 || RISCV) default y help Normally, if U-Boot makes a semihosting call and no debugger is @@ -108,8 +108,8 @@ config SPL_SEMIHOSTING config SPL_SEMIHOSTING_FALLBACK bool "Recover gracefully when semihosting fails in SPL" - depends on SPL_SEMIHOSTING && ARM64 - select ARMV8_SPL_EXCEPTION_VECTORS + depends on SPL_SEMIHOSTING && (ARM64 || RISCV) + select ARMV8_SPL_EXCEPTION_VECTORS if ARM64 default y help Normally, if U-Boot makes a semihosting call and no debugger is -- 2.34.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 2/3] arch/riscv: add semihosting support for RISC-V 2022-09-19 11:49 ` [PATCH v4 2/3] arch/riscv: add semihosting support for RISC-V Kautuk Consul @ 2022-09-22 9:03 ` Leo Liang 2022-09-22 17:05 ` Sean Anderson 1 sibling, 0 replies; 11+ messages in thread From: Leo Liang @ 2022-09-22 9:03 UTC (permalink / raw) To: Kautuk Consul Cc: Rayagonda Kokatanur, Sean Anderson, Rick Chen, Simon Glass, Heinrich Schuchardt, Ilias Apalodimas, Alexandru Gagniuc, Philippe Reynes, Rasmus Villemoes, Stefan Roese, Loic Poulain, Bin Meng, u-boot, Anup Patel On Mon, Sep 19, 2022 at 05:19:07PM +0530, Kautuk Consul wrote: > We add RISC-V semihosting based serial console for JTAG based early > debugging. > > The RISC-V semihosting specification is available at: > https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc > > Signed-off-by: Anup Patel <apatel@ventanamicro.com> > Signed-off-by: Kautuk Consul <kconsul@ventanamicro.com> > --- > arch/riscv/include/asm/spl.h | 1 + > arch/riscv/lib/Makefile | 2 ++ > arch/riscv/lib/interrupts.c | 11 +++++++++++ > arch/riscv/lib/semihosting.c | 24 ++++++++++++++++++++++++ > lib/Kconfig | 6 +++--- > 5 files changed, 41 insertions(+), 3 deletions(-) > create mode 100644 arch/riscv/lib/semihosting.c Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com> ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 2/3] arch/riscv: add semihosting support for RISC-V 2022-09-19 11:49 ` [PATCH v4 2/3] arch/riscv: add semihosting support for RISC-V Kautuk Consul 2022-09-22 9:03 ` Leo Liang @ 2022-09-22 17:05 ` Sean Anderson 2022-09-23 4:57 ` Kautuk Consul 1 sibling, 1 reply; 11+ messages in thread From: Sean Anderson @ 2022-09-22 17:05 UTC (permalink / raw) To: Kautuk Consul, Rayagonda Kokatanur, Rick Chen, Leo, Simon Glass, Heinrich Schuchardt, Ilias Apalodimas, Alexandru Gagniuc, Philippe Reynes, Rasmus Villemoes, Stefan Roese, Loic Poulain, Bin Meng Cc: u-boot, Anup Patel On 9/19/22 7:49 AM, Kautuk Consul wrote: > We add RISC-V semihosting based serial console for JTAG based early > debugging. > > The RISC-V semihosting specification is available at: > https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc > > Signed-off-by: Anup Patel <apatel@ventanamicro.com> > Signed-off-by: Kautuk Consul <kconsul@ventanamicro.com> > --- > arch/riscv/include/asm/spl.h | 1 + > arch/riscv/lib/Makefile | 2 ++ > arch/riscv/lib/interrupts.c | 11 +++++++++++ > arch/riscv/lib/semihosting.c | 24 ++++++++++++++++++++++++ > lib/Kconfig | 6 +++--- > 5 files changed, 41 insertions(+), 3 deletions(-) > create mode 100644 arch/riscv/lib/semihosting.c > > diff --git a/arch/riscv/include/asm/spl.h b/arch/riscv/include/asm/spl.h > index e8a94fcb1f..2898a770ee 100644 > --- a/arch/riscv/include/asm/spl.h > +++ b/arch/riscv/include/asm/spl.h > @@ -25,6 +25,7 @@ enum { > BOOT_DEVICE_DFU, > BOOT_DEVICE_XIP, > BOOT_DEVICE_BOOTROM, > + BOOT_DEVICE_SMH, > BOOT_DEVICE_NONE > }; > > diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile > index 06020fcc2a..64e29804c1 100644 > --- a/arch/riscv/lib/Makefile > +++ b/arch/riscv/lib/Makefile > @@ -42,3 +42,5 @@ extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC) > obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMSET) += memset.o > obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMMOVE) += memmove.o > obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMCPY) += memcpy.o > + > +obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o > diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c > index 100be2e966..bd7cd772b8 100644 > --- a/arch/riscv/lib/interrupts.c > +++ b/arch/riscv/lib/interrupts.c > @@ -17,6 +17,7 @@ > #include <asm/ptrace.h> > #include <asm/system.h> > #include <asm/encoding.h> > +#include <semihosting.h> > > DECLARE_GLOBAL_DATA_PTR; > > @@ -149,6 +150,16 @@ ulong handle_trap(ulong cause, ulong epc, ulong tval, struct pt_regs *regs) > /* An UEFI application may have changed gd. Restore U-Boot's gd. */ > efi_restore_gd(); > > + if (cause == CAUSE_BREAKPOINT && > + CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK)) { Hm, shouldn't we check to see if this is actually a semihosting breakpoint? This involves reading the prior and posterior instructions, which might be a bit too much. Alternatively, we could only take this trap if semihosting_enabled(), which would limit any suppression of spurious breakpoints to one instruction. > + /* For semihosting fallback we simply skip the ebreak > + * instruction. > + */ > + disable_semihosting(); > + epc += 4; > + return epc; > + } > + > is_irq = (cause & MCAUSE_INT); > irq = (cause & ~MCAUSE_INT); > > diff --git a/arch/riscv/lib/semihosting.c b/arch/riscv/lib/semihosting.c > new file mode 100644 > index 0000000000..d6593b02a6 > --- /dev/null > +++ b/arch/riscv/lib/semihosting.c > @@ -0,0 +1,24 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2022 Ventana Micro Systems Inc. > + */ > + > +#include <common.h> > + > +long smh_trap(int sysnum, void *addr) > +{ > + register int ret asm ("a0") = sysnum; > + register void *param0 asm ("a1") = addr; > + > + asm volatile (".align 4\n" > + ".option push\n" > + ".option norvc\n" > + > + "slli zero, zero, 0x1f\n" > + "ebreak\n" > + "srai zero, zero, 7\n" > + ".option pop\n" > + : "+r" (ret) : "r" (param0) : "memory"); > + > + return ret; > +} > diff --git a/lib/Kconfig b/lib/Kconfig > index 97920e7552..eed3a231d9 100644 > --- a/lib/Kconfig > +++ b/lib/Kconfig > @@ -85,7 +85,7 @@ config SEMIHOSTING > > config SEMIHOSTING_FALLBACK > bool "Recover gracefully when semihosting fails" > - depends on SEMIHOSTING && ARM64 > + depends on SEMIHOSTING && (ARM64 || RISCV) > default y > help > Normally, if U-Boot makes a semihosting call and no debugger is > @@ -108,8 +108,8 @@ config SPL_SEMIHOSTING > > config SPL_SEMIHOSTING_FALLBACK > bool "Recover gracefully when semihosting fails in SPL" > - depends on SPL_SEMIHOSTING && ARM64 > - select ARMV8_SPL_EXCEPTION_VECTORS > + depends on SPL_SEMIHOSTING && (ARM64 || RISCV) > + select ARMV8_SPL_EXCEPTION_VECTORS if ARM64 > default y > help > Normally, if U-Boot makes a semihosting call and no debugger is > The rest looks fine. --Sean ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 2/3] arch/riscv: add semihosting support for RISC-V 2022-09-22 17:05 ` Sean Anderson @ 2022-09-23 4:57 ` Kautuk Consul 0 siblings, 0 replies; 11+ messages in thread From: Kautuk Consul @ 2022-09-23 4:57 UTC (permalink / raw) To: Sean Anderson Cc: Rayagonda Kokatanur, Rick Chen, Leo, Simon Glass, Heinrich Schuchardt, Ilias Apalodimas, Alexandru Gagniuc, Philippe Reynes, Rasmus Villemoes, Stefan Roese, Loic Poulain, Bin Meng, u-boot, Anup Patel Hi Sean, On Thu, Sep 22, 2022 at 10:35 PM Sean Anderson <sean.anderson@seco.com> wrote: > > > > On 9/19/22 7:49 AM, Kautuk Consul wrote: > > We add RISC-V semihosting based serial console for JTAG based early > > debugging. > > > > The RISC-V semihosting specification is available at: > > https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc > > > > Signed-off-by: Anup Patel <apatel@ventanamicro.com> > > Signed-off-by: Kautuk Consul <kconsul@ventanamicro.com> > > --- > > arch/riscv/include/asm/spl.h | 1 + > > arch/riscv/lib/Makefile | 2 ++ > > arch/riscv/lib/interrupts.c | 11 +++++++++++ > > arch/riscv/lib/semihosting.c | 24 ++++++++++++++++++++++++ > > lib/Kconfig | 6 +++--- > > 5 files changed, 41 insertions(+), 3 deletions(-) > > create mode 100644 arch/riscv/lib/semihosting.c > > > > diff --git a/arch/riscv/include/asm/spl.h b/arch/riscv/include/asm/spl.h > > index e8a94fcb1f..2898a770ee 100644 > > --- a/arch/riscv/include/asm/spl.h > > +++ b/arch/riscv/include/asm/spl.h > > @@ -25,6 +25,7 @@ enum { > > BOOT_DEVICE_DFU, > > BOOT_DEVICE_XIP, > > BOOT_DEVICE_BOOTROM, > > + BOOT_DEVICE_SMH, > > BOOT_DEVICE_NONE > > }; > > > > diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile > > index 06020fcc2a..64e29804c1 100644 > > --- a/arch/riscv/lib/Makefile > > +++ b/arch/riscv/lib/Makefile > > @@ -42,3 +42,5 @@ extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC) > > obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMSET) += memset.o > > obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMMOVE) += memmove.o > > obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMCPY) += memcpy.o > > + > > +obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o > > diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c > > index 100be2e966..bd7cd772b8 100644 > > --- a/arch/riscv/lib/interrupts.c > > +++ b/arch/riscv/lib/interrupts.c > > @@ -17,6 +17,7 @@ > > #include <asm/ptrace.h> > > #include <asm/system.h> > > #include <asm/encoding.h> > > +#include <semihosting.h> > > > > DECLARE_GLOBAL_DATA_PTR; > > > > @@ -149,6 +150,16 @@ ulong handle_trap(ulong cause, ulong epc, ulong tval, struct pt_regs *regs) > > /* An UEFI application may have changed gd. Restore U-Boot's gd. */ > > efi_restore_gd(); > > > > + if (cause == CAUSE_BREAKPOINT && > > + CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK)) { > > Hm, shouldn't we check to see if this is actually a semihosting > breakpoint? This involves reading the prior and posterior > instructions, which might be a bit too much. Alternatively, we > could only take this trap if semihosting_enabled(), which would > limit any suppression of spurious breakpoints to one instruction. > Agreed. Will read the prior and posterior instructions in v5 and send this out. Thanks. > > + /* For semihosting fallback we simply skip the ebreak > > + * instruction. > > + */ > > + disable_semihosting(); > > + epc += 4; > > + return epc; > > + } > > + > > is_irq = (cause & MCAUSE_INT); > > irq = (cause & ~MCAUSE_INT); > > > > diff --git a/arch/riscv/lib/semihosting.c b/arch/riscv/lib/semihosting.c > > new file mode 100644 > > index 0000000000..d6593b02a6 > > --- /dev/null > > +++ b/arch/riscv/lib/semihosting.c > > @@ -0,0 +1,24 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +/* > > + * Copyright (C) 2022 Ventana Micro Systems Inc. > > + */ > > + > > +#include <common.h> > > + > > +long smh_trap(int sysnum, void *addr) > > +{ > > + register int ret asm ("a0") = sysnum; > > + register void *param0 asm ("a1") = addr; > > + > > + asm volatile (".align 4\n" > > + ".option push\n" > > + ".option norvc\n" > > + > > + "slli zero, zero, 0x1f\n" > > + "ebreak\n" > > + "srai zero, zero, 7\n" > > + ".option pop\n" > > + : "+r" (ret) : "r" (param0) : "memory"); > > + > > + return ret; > > +} > > diff --git a/lib/Kconfig b/lib/Kconfig > > index 97920e7552..eed3a231d9 100644 > > --- a/lib/Kconfig > > +++ b/lib/Kconfig > > @@ -85,7 +85,7 @@ config SEMIHOSTING > > > > config SEMIHOSTING_FALLBACK > > bool "Recover gracefully when semihosting fails" > > - depends on SEMIHOSTING && ARM64 > > + depends on SEMIHOSTING && (ARM64 || RISCV) > > default y > > help > > Normally, if U-Boot makes a semihosting call and no debugger is > > @@ -108,8 +108,8 @@ config SPL_SEMIHOSTING > > > > config SPL_SEMIHOSTING_FALLBACK > > bool "Recover gracefully when semihosting fails in SPL" > > - depends on SPL_SEMIHOSTING && ARM64 > > - select ARMV8_SPL_EXCEPTION_VECTORS > > + depends on SPL_SEMIHOSTING && (ARM64 || RISCV) > > + select ARMV8_SPL_EXCEPTION_VECTORS if ARM64 > > default y > > help > > Normally, if U-Boot makes a semihosting call and no debugger is > > > > The rest looks fine. > > --Sean ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 3/3] board: qemu-riscv: enable semihosting 2022-09-19 11:49 [PATCH v4 0/3] Add riscv semihosting support in u-boot Kautuk Consul 2022-09-19 11:49 ` [PATCH v4 1/3] lib: Add common semihosting library Kautuk Consul 2022-09-19 11:49 ` [PATCH v4 2/3] arch/riscv: add semihosting support for RISC-V Kautuk Consul @ 2022-09-19 11:49 ` Kautuk Consul 2022-09-22 9:03 ` Leo Liang 2 siblings, 1 reply; 11+ messages in thread From: Kautuk Consul @ 2022-09-19 11:49 UTC (permalink / raw) To: Rayagonda Kokatanur, Sean Anderson, Rick Chen, Leo, Simon Glass, Heinrich Schuchardt, Ilias Apalodimas, Alexandru Gagniuc, Philippe Reynes, Rasmus Villemoes, Stefan Roese, Loic Poulain, Bin Meng Cc: u-boot, Kautuk Consul To enable semihosting we also need to enable the following configs in defconfigs: CONFIG_SEMIHOSTING CONFIG_SPL_SEMIHOSTING CONFIG_SEMIHOSTING_SERIAL CONFIG_SERIAL_PROBE_ALL CONFIG_SPL_FS_EXT4 CONFIG_SPL_FS_FAT Signed-off-by: Kautuk Consul <kconsul@ventanamicro.com> --- configs/qemu-riscv32_defconfig | 4 ++++ configs/qemu-riscv32_smode_defconfig | 4 ++++ configs/qemu-riscv32_spl_defconfig | 7 +++++++ configs/qemu-riscv64_defconfig | 4 ++++ configs/qemu-riscv64_smode_defconfig | 4 ++++ configs/qemu-riscv64_spl_defconfig | 7 +++++++ 6 files changed, 30 insertions(+) diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-riscv32_defconfig index 9634d7f77f..4961652548 100644 --- a/configs/qemu-riscv32_defconfig +++ b/configs/qemu-riscv32_defconfig @@ -1,4 +1,5 @@ CONFIG_RISCV=y +CONFIG_SEMIHOSTING=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 @@ -20,3 +21,6 @@ CONFIG_CMD_NVEDIT_EFI=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM_MTD=y CONFIG_SYS_MAX_FLASH_BANKS=2 +# CONFIG_SERIAL_PUTS is not set +CONFIG_SERIAL_PROBE_ALL=y +CONFIG_SEMIHOSTING_SERIAL=y diff --git a/configs/qemu-riscv32_smode_defconfig b/configs/qemu-riscv32_smode_defconfig index 1c5a0617aa..91e4ffebc2 100644 --- a/configs/qemu-riscv32_smode_defconfig +++ b/configs/qemu-riscv32_smode_defconfig @@ -1,4 +1,5 @@ CONFIG_RISCV=y +CONFIG_SEMIHOSTING=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 @@ -21,4 +22,7 @@ CONFIG_CMD_NVEDIT_EFI=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM_MTD=y CONFIG_SYS_MAX_FLASH_BANKS=2 +# CONFIG_SERIAL_PUTS is not set +CONFIG_SERIAL_PROBE_ALL=y +CONFIG_SEMIHOSTING_SERIAL=y CONFIG_SYSRESET_SBI=y diff --git a/configs/qemu-riscv32_spl_defconfig b/configs/qemu-riscv32_spl_defconfig index 2421c9a371..5fd28fc58c 100644 --- a/configs/qemu-riscv32_spl_defconfig +++ b/configs/qemu-riscv32_spl_defconfig @@ -1,9 +1,12 @@ CONFIG_RISCV=y +CONFIG_SEMIHOSTING=y +CONFIG_SPL_SEMIHOSTING=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 CONFIG_DEFAULT_DEVICE_TREE="qemu-virt32" CONFIG_SPL=y +CONFIG_SPL_FS_FAT=y CONFIG_SYS_LOAD_ADDR=0x80200000 CONFIG_TARGET_QEMU_VIRT=y CONFIG_RISCV_SMODE=y @@ -18,6 +21,7 @@ CONFIG_DISPLAY_BOARDINFO=y CONFIG_SPL_MAX_SIZE=0x100000 CONFIG_SPL_BSS_START_ADDR=0x84000000 CONFIG_SYS_SPL_MALLOC=y +CONFIG_SPL_FS_EXT4=y CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 CONFIG_SYS_BOOTM_LEN=0x4000000 @@ -25,5 +29,8 @@ CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM_MTD=y CONFIG_SYS_MAX_FLASH_BANKS=2 +# CONFIG_SERIAL_PUTS is not set +CONFIG_SERIAL_PROBE_ALL=y +CONFIG_SEMIHOSTING_SERIAL=y CONFIG_SYSRESET_SBI=y # CONFIG_BINMAN_FDT is not set diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-riscv64_defconfig index d5eae95c80..87478f4481 100644 --- a/configs/qemu-riscv64_defconfig +++ b/configs/qemu-riscv64_defconfig @@ -1,4 +1,5 @@ CONFIG_RISCV=y +CONFIG_SEMIHOSTING=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 @@ -21,3 +22,6 @@ CONFIG_CMD_NVEDIT_EFI=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM_MTD=y CONFIG_SYS_MAX_FLASH_BANKS=2 +# CONFIG_SERIAL_PUTS is not set +CONFIG_SERIAL_PROBE_ALL=y +CONFIG_SEMIHOSTING_SERIAL=y diff --git a/configs/qemu-riscv64_smode_defconfig b/configs/qemu-riscv64_smode_defconfig index 2861d07f97..5e9d6af3be 100644 --- a/configs/qemu-riscv64_smode_defconfig +++ b/configs/qemu-riscv64_smode_defconfig @@ -1,4 +1,5 @@ CONFIG_RISCV=y +CONFIG_SEMIHOSTING=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 @@ -24,4 +25,7 @@ CONFIG_CMD_NVEDIT_EFI=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM_MTD=y CONFIG_SYS_MAX_FLASH_BANKS=2 +# CONFIG_SERIAL_PUTS is not set +CONFIG_SERIAL_PROBE_ALL=y +CONFIG_SEMIHOSTING_SERIAL=y CONFIG_SYSRESET_SBI=y diff --git a/configs/qemu-riscv64_spl_defconfig b/configs/qemu-riscv64_spl_defconfig index 1ecfa27ce2..e5d817b783 100644 --- a/configs/qemu-riscv64_spl_defconfig +++ b/configs/qemu-riscv64_spl_defconfig @@ -1,9 +1,12 @@ CONFIG_RISCV=y +CONFIG_SEMIHOSTING=y +CONFIG_SPL_SEMIHOSTING=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 CONFIG_DEFAULT_DEVICE_TREE="qemu-virt64" CONFIG_SPL=y +CONFIG_SPL_FS_FAT=y CONFIG_SYS_LOAD_ADDR=0x80200000 CONFIG_TARGET_QEMU_VIRT=y CONFIG_ARCH_RV64I=y @@ -18,6 +21,7 @@ CONFIG_DISPLAY_BOARDINFO=y CONFIG_SPL_MAX_SIZE=0x100000 CONFIG_SPL_BSS_START_ADDR=0x84000000 CONFIG_SYS_SPL_MALLOC=y +CONFIG_SPL_FS_EXT4=y CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 CONFIG_SYS_BOOTM_LEN=0x4000000 @@ -25,5 +29,8 @@ CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM_MTD=y CONFIG_SYS_MAX_FLASH_BANKS=2 +# CONFIG_SERIAL_PUTS is not set +CONFIG_SERIAL_PROBE_ALL=y +CONFIG_SEMIHOSTING_SERIAL=y CONFIG_SYSRESET_SBI=y # CONFIG_BINMAN_FDT is not set -- 2.34.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 3/3] board: qemu-riscv: enable semihosting 2022-09-19 11:49 ` [PATCH v4 3/3] board: qemu-riscv: enable semihosting Kautuk Consul @ 2022-09-22 9:03 ` Leo Liang 0 siblings, 0 replies; 11+ messages in thread From: Leo Liang @ 2022-09-22 9:03 UTC (permalink / raw) To: Kautuk Consul Cc: Rayagonda Kokatanur, Sean Anderson, Rick Chen, Simon Glass, Heinrich Schuchardt, Ilias Apalodimas, Alexandru Gagniuc, Philippe Reynes, Rasmus Villemoes, Stefan Roese, Loic Poulain, Bin Meng, u-boot On Mon, Sep 19, 2022 at 05:19:08PM +0530, Kautuk Consul wrote: > To enable semihosting we also need to enable the following > configs in defconfigs: > CONFIG_SEMIHOSTING > CONFIG_SPL_SEMIHOSTING > CONFIG_SEMIHOSTING_SERIAL > CONFIG_SERIAL_PROBE_ALL > CONFIG_SPL_FS_EXT4 > CONFIG_SPL_FS_FAT > > Signed-off-by: Kautuk Consul <kconsul@ventanamicro.com> > --- > configs/qemu-riscv32_defconfig | 4 ++++ > configs/qemu-riscv32_smode_defconfig | 4 ++++ > configs/qemu-riscv32_spl_defconfig | 7 +++++++ > configs/qemu-riscv64_defconfig | 4 ++++ > configs/qemu-riscv64_smode_defconfig | 4 ++++ > configs/qemu-riscv64_spl_defconfig | 7 +++++++ > 6 files changed, 30 insertions(+) Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com> ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2022-09-23 4:57 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-09-19 11:49 [PATCH v4 0/3] Add riscv semihosting support in u-boot Kautuk Consul 2022-09-19 11:49 ` [PATCH v4 1/3] lib: Add common semihosting library Kautuk Consul 2022-09-22 9:02 ` Leo Liang 2022-09-22 17:00 ` Sean Anderson 2022-09-23 4:39 ` Kautuk Consul 2022-09-19 11:49 ` [PATCH v4 2/3] arch/riscv: add semihosting support for RISC-V Kautuk Consul 2022-09-22 9:03 ` Leo Liang 2022-09-22 17:05 ` Sean Anderson 2022-09-23 4:57 ` Kautuk Consul 2022-09-19 11:49 ` [PATCH v4 3/3] board: qemu-riscv: enable semihosting Kautuk Consul 2022-09-22 9:03 ` Leo Liang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox