This patch introduces functions loongarch_cpu_do_interrupt() and loongarch_cpu_exec_interrupt()
Signed-off-by: Song Gao <gaos...@loongson.cn> --- target/loongarch/cpu.c | 23 +++++++++++++++++++++++ target/loongarch/cpu.h | 25 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+) 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); -- 1.8.3.1