qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 2/4] target/nios2: Exteral Interrupt Controller (EIC)


From: Richard Henderson
Subject: Re: [PATCH v2 2/4] target/nios2: Exteral Interrupt Controller (EIC)
Date: Thu, 24 Feb 2022 13:56:25 -1000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0

On 2/24/22 03:48, Amir Gonnen wrote:
+static void nios2_cpu_set_eic_irq(Nios2CPU *cpu, int level)
+{
+    CPUNios2State *env = &cpu->env;
+    CPUState *cs = CPU(cpu);
+
+    env->irq_pending = level;
+
+    if (env->irq_pending && nios2_take_eic_irq(cpu)) {
+        env->irq_pending = 0;
+        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+    } else if (!env->irq_pending) {
+        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+    }
+}

This looks wrong.  Of course, so does nios2_cpu_set_irq, from which you've 
cribbed this.

(1) The unset of irq_pending looks wrong, though come to think of it, it's existence also looks wrong. I think that it's completely redundant with cpu->interrupt_request, and that you should only use cpu_interrupt/cpu_reset_interrupt from this level.

Which also means that nios2_check_interrupts and callers all the way back up are also incorrect. All that should be required from wrctl status is the return to the main loop that you get from DISAS_UPDATE and tcg_gen_exit_tb.

Which also means that ipending is implemented incorrectly. The current manipulation of CR_IPENDING in nios2_cpu_set_irc should instead be manipulating an internal "external hw request", per Figure 3-2 in NII51003.

For our purposes, I think simply re-using env->regs[CR_IPENDING] as the external hw request word is the right thing to do. But we need to update RDCTL to compute the correct value from CR_IPENDING & CR_IENABLE, and update WRCTL to ignore writes.


(2) Checking nios2_take_eic_irq here, or CR_STATUS_PIE in nios2_cpu_set_irq is incorrect. If you check this here, then you'll miss the interrupt when the interrupt enable bit is reset. These checks belong in nios2_cpu_exec_interrupt.

+    if (cpu->rnmi) {
+        return !(env->regs[CR_STATUS] & CR_STATUS_NMI);
+    }

I think this should be a separate

    #define CPU_INTERRUPT_NMI  CPU_INTERRUPT_TGT_EXT_0


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]