diff options
author | Alistair Francis <Alistair.Francis@wdc.com> | 2018-12-19 19:19:59 +0000 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2018-12-26 06:40:02 +1100 |
commit | 464e447a0c4fbda2c5adce9a1b0f96800648a36f (patch) | |
tree | c03ce2cd1dcd634bb656bbd37caea521bf28e8b0 | |
parent | 7a5549f2aea84bf8c71c6eaa438b4bb84e9ad967 (diff) |
tcg: Add RISC-V cpu signal handler
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <c445175310fa836b61fd862a55628907f0093194.1545246859.git.alistair.francis@wdc.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r-- | accel/tcg/user-exec.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index cd75829cf2..941295ea49 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -571,6 +571,81 @@ int cpu_signal_handler(int host_signum, void *pinfo, return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask); } +#elif defined(__riscv) + +int cpu_signal_handler(int host_signum, void *pinfo, + void *puc) +{ + siginfo_t *info = pinfo; + ucontext_t *uc = puc; + greg_t pc = uc->uc_mcontext.__gregs[REG_PC]; + uint32_t insn = *(uint32_t *)pc; + int is_write = 0; + + /* Detect store by reading the instruction at the program + counter. Note: we currently only generate 32-bit + instructions so we thus only detect 32-bit stores */ + switch (((insn >> 0) & 0b11)) { + case 3: + switch (((insn >> 2) & 0b11111)) { + case 8: + switch (((insn >> 12) & 0b111)) { + case 0: /* sb */ + case 1: /* sh */ + case 2: /* sw */ + case 3: /* sd */ + case 4: /* sq */ + is_write = 1; + break; + default: + break; + } + break; + case 9: + switch (((insn >> 12) & 0b111)) { + case 2: /* fsw */ + case 3: /* fsd */ + case 4: /* fsq */ + is_write = 1; + break; + default: + break; + } + break; + default: + break; + } + } + + /* Check for compressed instructions */ + switch (((insn >> 13) & 0b111)) { + case 7: + switch (insn & 0b11) { + case 0: /*c.sd */ + case 2: /* c.sdsp */ + is_write = 1; + break; + default: + break; + } + break; + case 6: + switch (insn & 0b11) { + case 0: /* c.sw */ + case 3: /* c.swsp */ + is_write = 1; + break; + default: + break; + } + break; + default: + break; + } + + return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask); +} + #else #error host CPU specific signal handler needed |