mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
riscv: Add semihosting support
Adapt the arm semihosting support code for RISCV. This implementation is based on the standard for RISC-V semihosting version 0.2 as documented in https://github.com/riscv/riscv-semihosting-spec/releases/tag/0.2 Signed-off-by: Keith Packard <keithp@keithp.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20210107170717.2098982-6-keithp@keithp.com> Message-Id: <20210108224256.2321-17-alex.bennee@linaro.org>
This commit is contained in:
parent
095f8c0293
commit
a10b9d93ec
13 changed files with 162 additions and 12 deletions
|
@ -29,7 +29,42 @@ static bool trans_ecall(DisasContext *ctx, arg_ecall *a)
|
|||
|
||||
static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
|
||||
{
|
||||
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
|
||||
target_ulong ebreak_addr = ctx->base.pc_next;
|
||||
target_ulong pre_addr = ebreak_addr - 4;
|
||||
target_ulong post_addr = ebreak_addr + 4;
|
||||
uint32_t pre = 0;
|
||||
uint32_t ebreak = 0;
|
||||
uint32_t post = 0;
|
||||
|
||||
/*
|
||||
* The RISC-V semihosting spec specifies the following
|
||||
* three-instruction sequence to flag a semihosting call:
|
||||
*
|
||||
* slli zero, zero, 0x1f 0x01f01013
|
||||
* ebreak 0x00100073
|
||||
* srai zero, zero, 0x7 0x40705013
|
||||
*
|
||||
* The two shift operations on the zero register are no-ops, used
|
||||
* here to signify a semihosting exception, rather than a breakpoint.
|
||||
*
|
||||
* Uncompressed instructions are required so that the sequence is easy
|
||||
* to validate.
|
||||
*
|
||||
* The three instructions are required to lie in the same page so
|
||||
* that no exception will be raised when fetching them.
|
||||
*/
|
||||
|
||||
if ((pre_addr & TARGET_PAGE_MASK) == (post_addr & TARGET_PAGE_MASK)) {
|
||||
pre = opcode_at(&ctx->base, pre_addr);
|
||||
ebreak = opcode_at(&ctx->base, ebreak_addr);
|
||||
post = opcode_at(&ctx->base, post_addr);
|
||||
}
|
||||
|
||||
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
|
||||
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
|
||||
} else {
|
||||
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
|
||||
}
|
||||
exit_tb(ctx); /* no chaining */
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue