qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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

  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).