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:
parent
b3ffb690b1
commit
0a6c9c4ec0
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user