On 02/16/2016 12:10 AM, Bastian Koppelmann wrote:
+
+void tricore_cpu_do_interrupt(CPUState *cs)
+{
+    TriCoreCPU *cpu = TRICORE_CPU(cs);
+    CPUTriCoreState *env = &cpu->env;
+
+    if (cs->exception_index <= TRAPC_NMI) {
+        /* The trap vector table is accessed to fetch the first instruction of
+           the trap handler. */
+        env->PC = env->BTV | (cs->exception_index << 5);
+    } else if (cs->exception_index == TRAPC_IRQ) {
+        /* The interrupt vector table is accessed to fetch the first 
instruction
+           of the interrupt handler. */
+        env->PC = env->BIV | ((env->ICR & MASK_ICR_PIPN) >> 10);
+    }
+}

You've still got a path whereby you modify PC without saving the old one.

I don't think you want to add the do_interrupt hook at all until you're ready to do real async interrupts.

+    /* PCXI.PCPN = ICR.CCPN */
+    env->PCXI = (env->PCXI & 0xffffff) +
+                ((env->ICR & MASK_ICR_CCPN) << 24);
+    cs->exception_index = class;
+    cpu_loop_exit(cs);
+}
+

There's no reason you can't modify PC here at the end of raise_exception_sync_internal. If you omit the set of exception_index here, you'll simply exit the cpu loop and immediately re-enter it at the new PC, without having to go through the do_interrupt hook.


r~

Reply via email to