diff --git a/makefiles/stdio.inc.mk b/makefiles/stdio.inc.mk index 1073ad3745..2599138eaa 100644 --- a/makefiles/stdio.inc.mk +++ b/makefiles/stdio.inc.mk @@ -46,7 +46,7 @@ endif ifneq (,$(filter stdio_semihosting,$(USEMODULE))) USEMODULE += xtimer - FEATURES_REQUIRED += cpu_core_cortexm + FEATURES_REQUIRED_ANY += cpu_core_cortexm|arch_riscv endif # enable stdout buffering for modules that benefit from sending out buffers in larger chunks diff --git a/sys/stdio_semihosting/stdio_semihosting.c b/sys/stdio_semihosting/stdio_semihosting.c index bf5ca0c861..0897ba4be7 100644 --- a/sys/stdio_semihosting/stdio_semihosting.c +++ b/sys/stdio_semihosting/stdio_semihosting.c @@ -11,7 +11,10 @@ * @{ * * @file - * @brief STDIO over ARM Semihosting implementation + * @brief STDIO over ARM and RISC-V Semihosting implementation + * + * RISC-V semihosting closely mimics ARM semihosting. Only the break sequence is + * different, but all defined values are also used with RISC-V * * @author Koen Zandberg * @@ -35,17 +38,19 @@ #define STDIO_SEMIHOSTING_POLL_RATE (10 * US_PER_MS) /** - * @brief ARM Semihosting STDIN file descriptor + * @brief ARM Semihosting STDIN file descriptor. Also used with RISC-V */ #define STDIO_SEMIHOSTING_F_STDIN (1) /** - * @brief ARM Semihosting STDOUT file descriptor + * @brief ARM Semihosting STDOUT file descriptor. Also used with RISC-V */ #define STDIO_SEMIHOSTING_F_STDOUT (1) /** - * @name ARM Semihosting commands + * @name ARM Semihosting commands. + * + * RISC-V copied over these command names and values * * Extend when required * @{ @@ -54,6 +59,41 @@ #define STDIO_SEMIHOSTING_SYS_READ (0x06) /**< Read command */ /** @} */ +#if defined(CPU_FE310) +static bool _semihosting_connected(void) { + return true; +} + +static uint32_t _semihosting_raw(int cmd, uint32_t *args) +{ + uint32_t result = 0; + /* Moves cmd and args to r0 and r1. Then triggers a breakpoint. + * Finally moves the results stored in r0 to result + */ + __asm__( + ".option norvc \n" + "mv a0, %[cmd] \n" + "mv a1, %[args] \n" + /* Wrapping the ebreak instruction in two NOP SLLI and SRAI instructions + * act as indicator to the GDB session that this is a + * semihosting trap */ + "slli x0, x0, 0x1f \n" + "ebreak \n" + "srai x0, x0, 7 \n" + "mv %[result], a0 \n" + : /* Outputs */ + [result] "=r" (result) + : /* Inputs */ + [cmd] "r" (cmd), + [args] "r" (args) + : /* Clobbered registers */ + "a0", "a1", "memory" + ); + return result; +} + +#elif defined(MODULE_CORTEXM_COMMON) + static bool _semihosting_connected(void) { #ifdef CoreDebug_DHCSR_C_DEBUGEN_Msk /* Best effort attempt to detect if a debug session is active */ @@ -84,6 +124,7 @@ static uint32_t _semihosting_raw(int cmd, uint32_t *args) ); return result; } +#endif static size_t _semihosting_write(const uint8_t *buffer, size_t len) {