diff mbox series

[v2,04/22] target/loongarch: Add interrupt handling support

Message ID 1626861198-6133-5-git-send-email-gaosong@loongson.cn
State New
Headers show
Series Add LoongArch linux-user emulation support | expand

Commit Message

Song Gao July 21, 2021, 9:53 a.m. UTC
This patch introduces functions loongarch_cpu_do_interrupt()
and loongarch_cpu_exec_interrupt()

Signed-off-by: Song Gao <gaosong@loongson.cn>
---
 target/loongarch/cpu.c | 23 +++++++++++++++++++++++
 target/loongarch/cpu.h | 25 +++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

Comments

Richard Henderson July 22, 2021, 10:47 p.m. UTC | #1
On 7/20/21 11:53 PM, Song Gao wrote:
> +bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
> +{
> +    if (interrupt_request & CPU_INTERRUPT_HARD) {
> +        LoongArchCPU *cpu = LOONGARCH_CPU(cs);
> +        CPULoongArchState *env = &cpu->env;
> +
> +        if (cpu_loongarch_hw_interrupts_enabled(env) &&
> +            cpu_loongarch_hw_interrupts_pending(env)) {
> +            cs->exception_index = EXCP_INTE;
> +            env->error_code = 0;
> +            loongarch_cpu_do_interrupt(cs);
> +            return true;
> +        }
> +    }
> +    return false;
> +}

Not sure what you're doing here, with user-only.  None of these conditions apply.


r~
Song Gao July 26, 2021, 9:23 a.m. UTC | #2
Hi, Richard.

On 07/23/2021 06:47 AM, Richard Henderson wrote:
> On 7/20/21 11:53 PM, Song Gao wrote:
>> +bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>> +{
>> +    if (interrupt_request & CPU_INTERRUPT_HARD) {
>> +        LoongArchCPU *cpu = LOONGARCH_CPU(cs);
>> +        CPULoongArchState *env = &cpu->env;
>> +
>> +        if (cpu_loongarch_hw_interrupts_enabled(env) &&
>> +            cpu_loongarch_hw_interrupts_pending(env)) {
>> +            cs->exception_index = EXCP_INTE;
>> +            env->error_code = 0;
>> +            loongarch_cpu_do_interrupt(cs);
>> +            return true;
>> +        }
>> +    }
>> +    return false;
>> +}
> 
> Not sure what you're doing here, with user-only.  None of these conditions apply.
> 

OK, I'll remove it.

Thanks
Song Gao.
diff mbox series

Patch

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 4db2d0f..8eaa778 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -79,6 +79,28 @@  static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
     env->active_tc.PC = value & ~(target_ulong)1;
 }
 
+bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+    if (interrupt_request & CPU_INTERRUPT_HARD) {
+        LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+        CPULoongArchState *env = &cpu->env;
+
+        if (cpu_loongarch_hw_interrupts_enabled(env) &&
+            cpu_loongarch_hw_interrupts_pending(env)) {
+            cs->exception_index = EXCP_INTE;
+            env->error_code = 0;
+            loongarch_cpu_do_interrupt(cs);
+            return true;
+        }
+    }
+    return false;
+}
+
+void loongarch_cpu_do_interrupt(CPUState *cs)
+{
+    cs->exception_index = EXCP_NONE;
+}
+
 #ifdef CONFIG_TCG
 static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
                                               const TranslationBlock *tb)
@@ -246,6 +268,7 @@  static Property loongarch_cpu_properties[] = {
 static struct TCGCPUOps loongarch_tcg_ops = {
     .initialize = loongarch_tcg_init,
     .synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
+    .cpu_exec_interrupt = loongarch_cpu_exec_interrupt,
 };
 #endif /* CONFIG_TCG */
 
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index ab1aeb6..1db8bb5 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -231,6 +231,31 @@  int cpu_loongarch_signal_handler(int host_signum, void *pinfo, void *puc);
 
 #include "exec/memattrs.h"
 
+void loongarch_cpu_do_interrupt(CPUState *cpu);
+bool loongarch_cpu_exec_interrupt(CPUState *cpu, int int_req);
+
+static inline bool cpu_loongarch_hw_interrupts_enabled(CPULoongArchState *env)
+{
+    bool ret = 0;
+
+    ret = env->CSR_CRMD & (1 << CSR_CRMD_IE_SHIFT);
+
+    return ret;
+}
+
+static inline bool cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env)
+{
+    int32_t pending;
+    int32_t status;
+    bool r;
+
+    pending = env->CSR_ESTAT & CSR_ESTAT_IPMASK;
+    status  = env->CSR_ECFG & CSR_ECFG_IPMASK;
+
+    r = (pending & status) != 0;
+    return r;
+}
+
 void loongarch_tcg_init(void);
 
 void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags);