qemu-devel
[Top][All Lists]
Advanced

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

Re: [PATCH v3 3/5] target/nios2: Exteral Interrupt Controller (EIC)


From: Richard Henderson
Subject: Re: [PATCH v3 3/5] target/nios2: Exteral Interrupt Controller (EIC)
Date: Fri, 4 Mar 2022 12:25:20 -1000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0

On 3/3/22 05:39, Amir Gonnen wrote:
@@ -55,6 +55,7 @@ static void nios2_cpu_reset(DeviceState *dev)

      memset(env->regs, 0, sizeof(uint32_t) * NUM_CORE_REGS);
      memset(env->shadow_regs, 0, sizeof(uint32_t) * NUM_REG_SETS * 
NUM_GP_REGS);
+    env->regs[CR_STATUS] |= CR_STATUS_RSIE;

status is supposed to be reset to zero other than RSIE.

@@ -131,13 +144,26 @@ static bool nios2_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
      Nios2CPU *cpu = NIOS2_CPU(cs);
      CPUNios2State *env = &cpu->env;

-    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
-        (env->regs[CR_STATUS] & CR_STATUS_PIE) &&
-        (env->regs[CR_IPENDING] & env->regs[CR_IENABLE])) {
-        cs->exception_index = EXCP_IRQ;
-        nios2_cpu_do_interrupt(cs);
-        return true;
+    if (cpu->intc_present) {
+        if ((interrupt_request & CPU_INTERRUPT_HARD) &&
+            (env->regs[CR_STATUS] & CR_STATUS_PIE) &&
+            (env->regs[CR_IPENDING] & env->regs[CR_IENABLE])) {
+            cs->exception_index = EXCP_IRQ;
+            nios2_cpu_do_interrupt(cs);
+            return true;
+        }
+    } else {
+        /*
+         * IPENDING does not exist with external interrupt controller
+         * but we still use it to signal an external interrupt
+         */
+        if (env->regs[CR_IPENDING] && nios2_take_eic_irq(cpu)) {

Why CR_IPENDING? The ipending register isn't supposed to exist with the EIC. Did you in fact mean interrupt_request & CPU_INTERRUPT_HARD, as set by nios2_cpu_set_irq?


-    /*
-     * These interrupt lines model the IIC (internal interrupt
-     * controller). QEMU does not currently support the EIC
-     * (external interrupt controller) -- if we did it would be
-     * a separate device in hw/intc with a custom interface to
-     * the CPU, and boards using it would not wire up these IRQ lines.
-     */

You should note that this is still used for EIC, though only IRQ[0].

There's a fair amount of checking cpu->intc_present, then doing two completely different things. I'm thinking that it might be best to split these into two separate functions, and then set up the pointers properly.

You could in fact replace intc_present with two separate cpu classes (which is where many of those pointers are registered). That would be early enough for the cpu_init hook to *not* register 32 interrupt lines for the EIC, as per above.


r~



reply via email to

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