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)))
|
ifneq (,$(filter stdio_semihosting,$(USEMODULE)))
|
||||||
USEMODULE += xtimer
|
USEMODULE += xtimer
|
||||||
FEATURES_REQUIRED += cpu_core_cortexm
|
FEATURES_REQUIRED_ANY += cpu_core_cortexm|arch_riscv
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# enable stdout buffering for modules that benefit from sending out buffers in larger chunks
|
# enable stdout buffering for modules that benefit from sending out buffers in larger chunks
|
||||||
|
@ -11,7 +11,10 @@
|
|||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @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>
|
* @author Koen Zandberg <koen@bergzand.net>
|
||||||
*
|
*
|
||||||
@ -35,17 +38,19 @@
|
|||||||
#define STDIO_SEMIHOSTING_POLL_RATE (10 * US_PER_MS)
|
#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)
|
#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)
|
#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
|
* Extend when required
|
||||||
* @{
|
* @{
|
||||||
@ -54,6 +59,41 @@
|
|||||||
#define STDIO_SEMIHOSTING_SYS_READ (0x06) /**< Read command */
|
#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) {
|
static bool _semihosting_connected(void) {
|
||||||
#ifdef CoreDebug_DHCSR_C_DEBUGEN_Msk
|
#ifdef CoreDebug_DHCSR_C_DEBUGEN_Msk
|
||||||
/* Best effort attempt to detect if a debug session is active */
|
/* 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;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static size_t _semihosting_write(const uint8_t *buffer, size_t len)
|
static size_t _semihosting_write(const uint8_t *buffer, size_t len)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user