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~