From: Sagar Karandikar <sagark@eecs.berkeley.edu>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, rth@twiddle.net,
kbastian@mail.uni-paderborn.de,
Sagar Karandikar <sagark@eecs.berkeley.edu>
Subject: [Qemu-devel] [PATCH 15/18] target-riscv: Interrupt Handling
Date: Mon, 26 Sep 2016 03:56:45 -0700 [thread overview]
Message-ID: <eddecb72ff94ffe4dc9ba365253cebd04fbb50b0.1474886798.git.sagark@eecs.berkeley.edu> (raw)
In-Reply-To: <cover.1474886798.git.sagark@eecs.berkeley.edu>
In-Reply-To: <cover.1474886798.git.sagark@eecs.berkeley.edu>
Signed-off-by: Sagar Karandikar <sagark@eecs.berkeley.edu>
---
target-riscv/helper.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 154 insertions(+)
diff --git a/target-riscv/helper.c b/target-riscv/helper.c
index 2e02351..08c53fa 100644
--- a/target-riscv/helper.c
+++ b/target-riscv/helper.c
@@ -33,6 +33,16 @@
bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
+ if (interrupt_request & CPU_INTERRUPT_HARD) {
+ RISCVCPU *cpu = RISCV_CPU(cs);
+ CPURISCVState *env = &cpu->env;
+ int interruptno = cpu_riscv_hw_interrupts_pending(env);
+ if (interruptno + 1) {
+ cs->exception_index = 0x70000000U | interruptno;
+ riscv_cpu_do_interrupt(cs);
+ return true;
+ }
+ }
return false;
}
@@ -255,6 +265,40 @@ int riscv_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
return ret;
}
+#ifdef RISCV_DEBUG_INTERRUPT
+static const char * const riscv_excp_names[12] = {
+ "misaligned fetch",
+ "fault fetch",
+ "illegal instruction",
+ "Breakpoint",
+ "misaligned load",
+ "fault load",
+ "misaligned store",
+ "fault store",
+ "user_ecall",
+ "supervisor_ecall",
+ "hypervisor_ecall",
+ "machine_ecall",
+};
+
+static const char * const riscv_interrupt_names[14] = {
+ "",
+ "S Soft interrupt",
+ "H Soft interrupt",
+ "M Soft interrupt",
+ "",
+ "S Timer interrupt",
+ "H Timer interrupt",
+ "M Timer interrupt",
+ "",
+ "S Ext interrupt",
+ "H Ext interrupt",
+ "M Ext interrupt",
+ "COP interrupt",
+ "Host interrupt"
+};
+#endif /* RISCV_DEBUG_INTERRUPT */
+
/*
* Handle Traps
*
@@ -263,4 +307,114 @@ int riscv_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
*/
void riscv_cpu_do_interrupt(CPUState *cs)
{
+ RISCVCPU *cpu = RISCV_CPU(cs);
+ CPURISCVState *env = &cpu->env;
+
+ #ifdef RISCV_DEBUG_INTERRUPT
+ if (cs->exception_index & 0x70000000) {
+ fprintf(stderr, "core 0: exception trap_%s, epc 0x" TARGET_FMT_lx "\n"
+ , riscv_interrupt_names[cs->exception_index & 0x0fffffff],
+ env->PC);
+ } else {
+ fprintf(stderr, "core 0: exception trap_%s, epc 0x" TARGET_FMT_lx "\n"
+ , riscv_excp_names[cs->exception_index], env->PC);
+ }
+ #endif
+
+ if (cs->exception_index == RISCV_EXCP_BREAKPOINT) {
+ fprintf(stderr, "debug mode not implemented\n");
+ }
+
+ /* skip dcsr cause check */
+
+ target_ulong fixed_cause = 0;
+ if (cs->exception_index & (0x70000000)) {
+ /* hacky for now. the MSB (bit 63) indicates interrupt but cs->exception
+ index is only 32 bits wide */
+ fixed_cause = cs->exception_index & 0x0FFFFFFF;
+ fixed_cause |= (1L << 63);
+ } else {
+ /* fixup User ECALL -> correct priv ECALL */
+ if (cs->exception_index == RISCV_EXCP_U_ECALL) {
+ switch (env->priv) {
+ case PRV_U:
+ fixed_cause = RISCV_EXCP_U_ECALL;
+ break;
+ case PRV_S:
+ fixed_cause = RISCV_EXCP_S_ECALL;
+ break;
+ case PRV_H:
+ fixed_cause = RISCV_EXCP_H_ECALL;
+ break;
+ case PRV_M:
+ fixed_cause = RISCV_EXCP_M_ECALL;
+ break;
+ }
+ } else {
+ fixed_cause = cs->exception_index;
+ }
+ }
+
+ target_ulong backup_epc = env->PC;
+
+ target_ulong bit = fixed_cause;
+ target_ulong deleg = env->csr[CSR_MEDELEG];
+
+ int hasbadaddr =
+ (fixed_cause == RISCV_EXCP_INST_ADDR_MIS) ||
+ (fixed_cause == RISCV_EXCP_INST_ACCESS_FAULT) ||
+ (fixed_cause == RISCV_EXCP_LOAD_ADDR_MIS) ||
+ (fixed_cause == RISCV_EXCP_STORE_AMO_ADDR_MIS) ||
+ (fixed_cause == RISCV_EXCP_LOAD_ACCESS_FAULT) ||
+ (fixed_cause == RISCV_EXCP_STORE_AMO_ACCESS_FAULT);
+
+ if (bit & ((target_ulong)1 << (TARGET_LONG_BITS - 1))) {
+ deleg = env->csr[CSR_MIDELEG], bit &= ~(1L << (TARGET_LONG_BITS - 1));
+ }
+
+ if (env->priv <= PRV_S && bit < 64 && ((deleg >> bit) & 1)) {
+ /* handle the trap in S-mode */
+ /* No need to check STVEC for misaligned - lower 2 bits cannot be set */
+ env->PC = env->csr[CSR_STVEC];
+ env->csr[CSR_SCAUSE] = fixed_cause;
+ env->csr[CSR_SEPC] = backup_epc;
+
+ if (hasbadaddr) {
+ #ifdef RISCV_DEBUG_INTERRUPT
+ fprintf(stderr, "core 0: badaddr 0x" TARGET_FMT_lx "\n",
+ env->badaddr);
+ #endif
+ env->csr[CSR_SBADADDR] = env->badaddr;
+ }
+
+ target_ulong s = env->csr[CSR_MSTATUS];
+ s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_UIE << env->priv));
+ s = set_field(s, MSTATUS_SPP, env->priv);
+ s = set_field(s, MSTATUS_SIE, 0);
+ csr_write_helper(env, s, CSR_MSTATUS);
+ set_privilege(env, PRV_S);
+ } else {
+ /* No need to check MTVEC for misaligned - lower 2 bits cannot be set */
+ env->PC = env->csr[CSR_MTVEC];
+ env->csr[CSR_MEPC] = backup_epc;
+ env->csr[CSR_MCAUSE] = fixed_cause;
+
+ if (hasbadaddr) {
+ #ifdef RISCV_DEBUG_INTERRUPT
+ fprintf(stderr, "core 0: badaddr 0x" TARGET_FMT_lx "\n",
+ env->badaddr);
+ #endif
+ env->csr[CSR_MBADADDR] = env->badaddr;
+ }
+
+ target_ulong s = env->csr[CSR_MSTATUS];
+ s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_UIE << env->priv));
+ s = set_field(s, MSTATUS_MPP, env->priv);
+ s = set_field(s, MSTATUS_MIE, 0);
+ csr_write_helper(env, s, CSR_MSTATUS);
+ set_privilege(env, PRV_M);
+ }
+ /* TODO yield load reservation */
+
+ cs->exception_index = EXCP_NONE; /* mark handled to qemu */
}
--
2.9.3
next prev parent reply other threads:[~2016-09-26 11:31 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-26 10:56 [Qemu-devel] [PATCH 00/18] target-riscv: Add full-system emulation support for the RISC-V Instruction Set Architecture (RV64G, RV32G) Sagar Karandikar
2016-09-26 10:56 ` [Qemu-devel] [PATCH 01/18] target-riscv: Add RISC-V target stubs and Maintainer Sagar Karandikar
2016-09-26 19:06 ` Eric Blake
2016-09-26 10:56 ` [Qemu-devel] [PATCH 02/18] target-riscv: Add RISC-V Target stubs inside target-riscv/ Sagar Karandikar
2016-09-26 16:30 ` Richard Henderson
2016-09-26 21:50 ` Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 03/18] target-riscv: Add initialization for translation Sagar Karandikar
2016-09-26 16:34 ` Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 04/18] target-riscv: Add framework for instruction decode Sagar Karandikar
2016-09-26 16:49 ` Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 05/18] target-riscv: Add Arithmetic instructions Sagar Karandikar
2016-09-26 17:31 ` Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 06/18] target-riscv: Add JALR, Branch Instructions Sagar Karandikar
2016-09-26 18:28 ` Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 07/18] target-riscv: Add Loads/Stores, FP Loads/Stores Sagar Karandikar
2016-09-26 20:44 ` Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 08/18] target-riscv: Add Atomic Instructions Sagar Karandikar
2016-09-27 19:30 ` Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 09/18] target-riscv: Add FMADD, FMSUB, FNMADD, FNMSUB Instructions, Sagar Karandikar
2016-09-26 21:15 ` Richard Henderson
2016-09-27 19:20 ` Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 10/18] target-riscv: Add Single Precision Floating-Point Instructions Sagar Karandikar
2016-09-26 21:35 ` Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 11/18] target-riscv: Add Double " Sagar Karandikar
2016-09-26 21:37 ` Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 12/18] target-riscv: Add system instructions Sagar Karandikar
2016-09-26 12:21 ` Paolo Bonzini
2016-09-26 12:38 ` Bastian Koppelmann
2016-09-26 12:44 ` Paolo Bonzini
2016-09-27 18:12 ` Sagar Karandikar
2016-09-26 21:41 ` Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 13/18] target-riscv: Add CSR read/write helpers Sagar Karandikar
2016-09-26 10:56 ` [Qemu-devel] [PATCH 14/18] target-riscv: softmmu/address translation support Sagar Karandikar
2016-09-26 22:04 ` Richard Henderson
2016-09-26 10:56 ` Sagar Karandikar [this message]
2016-09-26 22:07 ` [Qemu-devel] [PATCH 15/18] target-riscv: Interrupt Handling Richard Henderson
2016-09-26 10:56 ` [Qemu-devel] [PATCH 16/18] target-riscv: Timer Support Sagar Karandikar
2016-09-26 10:56 ` [Qemu-devel] [PATCH 17/18] target-riscv: Add support for Host-Target Interface (HTIF) Devices Sagar Karandikar
2016-09-26 10:56 ` [Qemu-devel] [PATCH 18/18] target-riscv: Add generic test board, activate target Sagar Karandikar
2016-09-26 12:20 ` [Qemu-devel] [PATCH 00/18] target-riscv: Add full-system emulation support for the RISC-V Instruction Set Architecture (RV64G, RV32G) Paolo Bonzini
2016-09-26 16:17 ` Richard Henderson
2016-09-26 16:20 ` Andreas Färber
2016-09-26 16:24 ` Paolo Bonzini
2016-09-26 16:35 ` Andreas Färber
2016-09-26 16:37 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=eddecb72ff94ffe4dc9ba365253cebd04fbb50b0.1474886798.git.sagark@eecs.berkeley.edu \
--to=sagark@eecs.berkeley.edu \
--cc=kbastian@mail.uni-paderborn.de \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).