1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

stdio_semihosting: Extend with RISC-V support

RISC-V support semihosting in very similar way as the cortex-m
microcontrollers. The code calls a breakpoint instruction and the
attached debugger reads/writes registers and memory for stdio.

The RISC-V architecture doesn't support a call number with the EBREAK
instruction, to allow the debugger to detect a semihosting break point,
the EBREAK instruction is wrapped in a SLLI and SRAI instruction. These
use x0 as output register, making them NOP instructions.

One caveat when using this is that the RISC-V core traps the EBREAK
instruction with trap code 3 when no debugger is attached. Restarting
the application with the debugger attached avoids this.
This commit is contained in:
Koen Zandberg 2020-09-09 11:32:30 +02:00
parent b3ffb690b1
commit 0a6c9c4ec0
No known key found for this signature in database
GPG Key ID: 0895A893E6D2985B
2 changed files with 46 additions and 5 deletions

View File

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

View File

@ -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 <koen@bergzand.net>
*
@ -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)
{