[PATCH v4 0/3] Add riscv semihosting support in u-boot

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

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); +}

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

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

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

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-...
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

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-...
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

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-...
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

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-...
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

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

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
participants (3)
-
Kautuk Consul
-
Leo Liang
-
Sean Anderson