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/internal.h | 24 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index b368e79..c3ecc4b 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -80,6 +80,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) @@ -356,6 +378,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/internal.h b/target/loongarch/internal.h index e2394af..09e667c 100644 --- a/target/loongarch/internal.h +++ b/target/loongarch/internal.h @@ -29,10 +29,34 @@ struct loongarch_def_t { extern const struct loongarch_def_t loongarch_defs[]; extern const int loongarch_defs_number; +void loongarch_cpu_do_interrupt(CPUState *cpu); +bool loongarch_cpu_exec_interrupt(CPUState *cpu, int int_req); void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags); #define cpu_signal_handler cpu_loongarch_signal_handler +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 QEMU_NORETURN do_raise_exception_err(CPULoongArchState *env, -- 1.8.3.1