void cpu_check_irqs(CPUSPARCState *env) { CPUState *cs; uint32_t pil = env->pil_in | (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER)); /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */ if (env->ivec_status & 0x20) { return; } cs = CPU(sparc_env_get_cpu(env)); /* check if TM or SM in SOFTINT are set setting these also causes interrupt 14 */ if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) { pil |= 1 << 14; } /* The bit corresponding to psrpil is (1<< psrpil), the next bit is (2 << psrpil). */ if (pil < (2 << env->psrpil)){ if (cs->interrupt_request & CPU_INTERRUPT_HARD) { CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n", env->interrupt_index); env->interrupt_index = 0; cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } return; } if (cpu_interrupts_enabled(env)) { unsigned int i; for (i = 15; i > env->psrpil; i--) { if (pil & (1 << i)) { int old_interrupt = env->interrupt_index; int new_interrupt = TT_EXTINT | i; if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt && ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) { CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d " "current %x >= pending %x\n", env->tl, cpu_tsptr(env)->tt, new_interrupt); } else if (old_interrupt != new_interrupt) { env->interrupt_index = new_interrupt; CPUIRQ_DPRINTF("Set CPU IRQ %d old=%x new=%x\n", i, old_interrupt, new_interrupt); cpu_interrupt(cs, CPU_INTERRUPT_HARD); } break; } } } else if (cs->interrupt_request & CPU_INTERRUPT_HARD) { CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x " "current interrupt %x\n", pil, env->pil_in, env->softint, env->interrupt_index); env->interrupt_index = 0; cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } }
static void cpu_set_ivec_irq(void *opaque, int irq, int level) { SPARCCPU *cpu = opaque; CPUSPARCState *env = &cpu->env; CPUState *cs; if (level) { if (!(env->ivec_status & 0x20)) { CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq); cs = CPU(cpu); cs->halted = 0; env->interrupt_index = TT_IVEC; env->ivec_status |= 0x20; env->ivec_data[0] = (0x1f << 6) | irq; env->ivec_data[1] = 0; env->ivec_data[2] = 0; cpu_interrupt(cs, CPU_INTERRUPT_HARD); } } else { if (env->ivec_status & 0x20) { CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq); cs = CPU(cpu); env->ivec_status &= ~0x20; cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } }
void cpu_check_irqs(CPUState *env) { uint32_t pil = env->pil_in | (env->softint & ~SOFTINT_TIMER) | ((env->softint & SOFTINT_TIMER) << 14); if (pil && (env->interrupt_index == 0 || (env->interrupt_index & ~15) == TT_EXTINT)) { unsigned int i; for (i = 15; i > 0; i--) { if (pil & (1 << i)) { int old_interrupt = env->interrupt_index; env->interrupt_index = TT_EXTINT | i; if (old_interrupt != env->interrupt_index) { CPUIRQ_DPRINTF("Set CPU IRQ %d\n", i); cpu_interrupt(env, CPU_INTERRUPT_HARD); } break; } } } else if (!pil && (env->interrupt_index & ~15) == TT_EXTINT) { CPUIRQ_DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15); env->interrupt_index = 0; cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); } }
void cpu_check_irqs(CPUSPARCState *env) { CPUState *cs; if (env->pil_in && (env->interrupt_index == 0 || (env->interrupt_index & ~15) == TT_EXTINT)) { unsigned int i; for (i = 15; i > 0; i--) { if (env->pil_in & (1 << i)) { int old_interrupt = env->interrupt_index; env->interrupt_index = TT_EXTINT | i; if (old_interrupt != env->interrupt_index) { cs = CPU(sparc_env_get_cpu(env)); trace_sun4m_cpu_interrupt(i); cpu_interrupt(cs, CPU_INTERRUPT_HARD); } break; } } } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) { cs = CPU(sparc_env_get_cpu(env)); trace_sun4m_cpu_reset_interrupt(env->interrupt_index & 15); env->interrupt_index = 0; cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } }
static void leon3_set_pil_in(void *opaque, uint32_t pil_in) { CPUSPARCState *env = (CPUSPARCState *)opaque; assert(env != NULL); env->pil_in = pil_in; if (env->pil_in && (env->interrupt_index == 0 || (env->interrupt_index & ~15) == TT_EXTINT)) { unsigned int i; for (i = 15; i > 0; i--) { if (env->pil_in & (1 << i)) { int old_interrupt = env->interrupt_index; env->interrupt_index = TT_EXTINT | i; if (old_interrupt != env->interrupt_index) { trace_leon3_set_irq(i); cpu_interrupt(env, CPU_INTERRUPT_HARD); } break; } } } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) { trace_leon3_reset_irq(env->interrupt_index & 15); env->interrupt_index = 0; cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); } }
static void cpu_riscv_irq_request(void *opaque, int irq, int level) { /* These are not the same irq numbers visible to the emulated processor. */ RISCVCPU *cpu = opaque; CPURISCVState *env = &cpu->env; CPUState *cs = CPU(cpu); /* current irqs: 4: Host Interrupt. mfromhost should have a nonzero value 3: Machine Timer. MIP_MTIP should have already been set 2, 1, 0: Interrupts triggered by the CPU. At least one of MIP_STIP, MIP_SSIP, MIP_MSIP should already be set */ if (unlikely(!(irq < 5 && irq >= 0))) { printf("IRQNO: %d\n", irq); fprintf(stderr, "Unused IRQ was raised.\n"); exit(1); } if (level) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { if (!env->mip && !env->mfromhost) { /* no interrupts pending, no host interrupt for HTIF, reset */ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } }
void sparc64_cpu_set_ivec_irq(void *opaque, int irq, int level) { SPARCCPU *cpu = opaque; CPUSPARCState *env = &cpu->env; CPUState *cs; if (level) { if (!(env->ivec_status & 0x20)) { trace_sparc64_cpu_ivec_raise_irq(irq); cs = CPU(cpu); cs->halted = 0; env->interrupt_index = TT_IVEC; env->ivec_status |= 0x20; env->ivec_data[0] = (0x1f << 6) | irq; env->ivec_data[1] = 0; env->ivec_data[2] = 0; cpu_interrupt(cs, CPU_INTERRUPT_HARD); } } else { if (env->ivec_status & 0x20) { trace_sparc64_cpu_ivec_lower_irq(irq); cs = CPU(cpu); env->ivec_status &= ~0x20; cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } }
static void cpu_mips_irq_request(void *opaque, int irq, int level) { MIPSCPU *cpu = opaque; CPUMIPSState *env = &cpu->env; CPUState *cs = CPU(cpu); if (irq < 0 || irq > 7) return; if (level) { env->CP0_Cause |= 1 << (irq + CP0Ca_IP); if (kvm_enabled() && irq == 2) { kvm_mips_set_interrupt(cpu, irq, level); } } else { env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP)); if (kvm_enabled() && irq == 2) { kvm_mips_set_interrupt(cpu, irq, level); } } if (env->CP0_Cause & CP0Ca_IP_mask) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } }
static void cpu_irq_handler(void *opaque, int irq, int level) { CPULM32State *env = opaque; if (level) { cpu_interrupt(env, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); } }
void sh_intc_toggle_source(struct intc_source *source, int enable_adj, int assert_adj) { int enable_changed = 0; int pending_changed = 0; int old_pending; if ((source->enable_count == source->enable_max) && (enable_adj == -1)) enable_changed = -1; source->enable_count += enable_adj; if (source->enable_count == source->enable_max) enable_changed = 1; source->asserted += assert_adj; old_pending = source->pending; source->pending = source->asserted && (source->enable_count == source->enable_max); if (old_pending != source->pending) pending_changed = 1; if (pending_changed) { CPUState *cpu = CPU(sh_env_get_cpu(first_cpu)); if (source->pending) { source->parent->pending++; if (source->parent->pending == 1) { cpu_interrupt(cpu, CPU_INTERRUPT_HARD); } } else { source->parent->pending--; if (source->parent->pending == 0) { cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD); } } } if (enable_changed || assert_adj || pending_changed) { #ifdef DEBUG_INTC_SOURCES printf("sh_intc: (%d/%d/%d/%d) interrupt source 0x%x %s%s%s\n", source->parent->pending, source->asserted, source->enable_count, source->enable_max, source->vect, source->asserted ? "asserted " : assert_adj ? "deasserted" : "", enable_changed == 1 ? "enabled " : enable_changed == -1 ? "disabled " : "", source->pending ? "pending" : ""); #endif } }
/* Called when one of DRIR or DIM changes. */ static void cpu_irq_change(CPUState *env, uint64_t req) { /* If there are any non-masked interrupts, tell the cpu. */ if (env) { if (req) { cpu_interrupt(env, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); } } }
static void cpu_irq_handler(void *opaque, int irq, int level) { LM32CPU *cpu = opaque; CPUState *cs = CPU(cpu); if (level) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } }
static void puv3_intc_cpu_handler(void *opaque, int irq, int level) { CPUUniCore32State *env = opaque; assert(irq == 0); if (level) { cpu_interrupt(env, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); } }
/* Called when one of DRIR or DIM changes. */ static void cpu_irq_change(AlphaCPU *cpu, uint64_t req) { /* If there are any non-masked interrupts, tell the cpu. */ if (cpu != NULL) { CPUState *cs = CPU(cpu); if (req) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } }
static void puv3_intc_cpu_handler(void *opaque, int irq, int level) { UniCore32CPU *cpu = opaque; CPUState *cs = CPU(cpu); assert(irq == 0); if (level) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } }
static void microblaze_cpu_set_irq(void *opaque, int irq, int level) { MicroBlazeCPU *cpu = opaque; CPUState *cs = CPU(cpu); int type = irq ? CPU_INTERRUPT_NMI : CPU_INTERRUPT_HARD; if (level) { cpu_interrupt(cs, type); } else { cpu_reset_interrupt(cs, type); } }
static void arm_pic_cpu_handler(void *opaque, int irq, int level) { arm_pic_cpu_state *s = (arm_pic_cpu_state *)opaque; switch (irq) { case ARM_PIC_CPU_IRQ: if (level) cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); else cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); break; case ARM_PIC_CPU_FIQ: if (level) cpu_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ); else cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ); break; default: cpu_abort(s->cpu_env, "arm_pic_cpu_handler: Bad interrput line %d\n", irq); } }
/* Raise IRQ to CPU if necessary. It must be called every time the active IRQ may change */ void cpu_mips_update_irq(CPUState *env) { if ((env->CP0_Status & (1 << CP0St_IE)) && !(env->CP0_Status & (1 << CP0St_EXL)) && !(env->CP0_Status & (1 << CP0St_ERL)) && !(env->hflags & MIPS_HFLAG_DM)) { if ((env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && !(env->interrupt_request & CPU_INTERRUPT_HARD)) { cpu_interrupt(env, CPU_INTERRUPT_HARD); } } else cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); }
void cpu_check_irqs(CPUState *env) { uint32_t pil = env->pil_in | (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER)); /* check if TM or SM in SOFTINT are set setting these also causes interrupt 14 */ if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) { pil |= 1 << 14; } if (!pil) { if (env->interrupt_request & CPU_INTERRUPT_HARD) { CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n", env->interrupt_index); env->interrupt_index = 0; cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); } return; } if (cpu_interrupts_enabled(env)) { unsigned int i; for (i = 15; i > env->psrpil; i--) { if (pil & (1 << i)) { int old_interrupt = env->interrupt_index; int new_interrupt = TT_EXTINT | i; if (env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt) { CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d " "current %x >= pending %x\n", env->tl, cpu_tsptr(env)->tt, new_interrupt); } else if (old_interrupt != new_interrupt) { env->interrupt_index = new_interrupt; CPUIRQ_DPRINTF("Set CPU IRQ %d old=%x new=%x\n", i, old_interrupt, new_interrupt); cpu_interrupt(env, CPU_INTERRUPT_HARD); } break; } } } else { CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x " "current interrupt %x\n", pil, env->pil_in, env->softint, env->interrupt_index); } }
/* Input 0 is IRQ and input 1 is FIQ. */ static void arm_pic_cpu_handler(void *opaque, int irq, int level) { ARMCPU *cpu = opaque; CPUState *cs = CPU(cpu); switch (irq) { case ARM_PIC_CPU_IRQ: if (level) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } break; case ARM_PIC_CPU_FIQ: if (level) { cpu_interrupt(cs, CPU_INTERRUPT_FIQ); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_FIQ); } break; default: hw_error("arm_pic_cpu_handler: Bad interrupt line %d\n", irq); } }
static void pic_irq_request(void *opaque, int irq, int level) { CPUState *env = first_cpu; DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq); if (env->apic_state) { while (env) { if (apic_accept_pic_intr(env->apic_state)) { apic_deliver_pic_intr(env->apic_state, level); } env = env->next_cpu; } } else { if (level) cpu_interrupt(env, CPU_INTERRUPT_HARD); else cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); } }
void cpu_check_irqs(CPUState *env) { if (env->pil_in && (env->interrupt_index == 0 || (env->interrupt_index & ~15) == TT_EXTINT)) { unsigned int i; for (i = 15; i > 0; i--) { if (env->pil_in & (1 << i)) { int old_interrupt = env->interrupt_index; env->interrupt_index = TT_EXTINT | i; if (old_interrupt != env->interrupt_index) cpu_interrupt(env, CPU_INTERRUPT_HARD); break; } } } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) { env->interrupt_index = 0; cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); } }
void check_interrupts(CPUXtensaState *env) { int minlevel = xtensa_get_cintlevel(env); uint32_t int_set_enabled = env->sregs[INTSET] & env->sregs[INTENABLE]; int level; /* If the CPU is halted advance CCOUNT according to the vm_clock time * elapsed since the moment when it was advanced last time. */ if (env->halted) { int64_t now = qemu_get_clock_ns(vm_clock); xtensa_advance_ccount(env, muldiv64(now - env->halt_clock, env->config->clock_freq_khz, 1000000)); env->halt_clock = now; } for (level = env->config->nlevel; level > minlevel; --level) { if (env->config->level_mask[level] & int_set_enabled) { env->pending_irq_level = level; cpu_interrupt(env, CPU_INTERRUPT_HARD); qemu_log_mask(CPU_LOG_INT, "%s level = %d, cintlevel = %d, " "pc = %08x, a0 = %08x, ps = %08x, " "intset = %08x, intenable = %08x, " "ccount = %08x\n", __func__, level, xtensa_get_cintlevel(env), env->pc, env->regs[0], env->sregs[PS], env->sregs[INTSET], env->sregs[INTENABLE], env->sregs[CCOUNT]); return; } } env->pending_irq_level = 0; cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); }
static void cchip_write(void *opaque, hwaddr addr, uint64_t v32, unsigned size) { TyphoonState *s = opaque; CPUState *cpu_single_cpu = CPU(alpha_env_get_cpu(cpu_single_env)); uint64_t val, oldval, newval; if (addr & 4) { val = v32 << 32 | s->latch_tmp; addr ^= 4; } else { s->latch_tmp = v32; return; } switch (addr) { case 0x0000: /* CSC: Cchip System Configuration Register. */ /* All sorts of data here; nothing relevant RW. */ break; case 0x0040: /* MTR: Memory Timing Register. */ /* All sorts of stuff related to real DRAM. */ break; case 0x0080: /* MISC: Miscellaneous Register. */ newval = oldval = s->cchip.misc; newval &= ~(val & 0x10000ff0); /* W1C fields */ if (val & 0x100000) { newval &= ~0xff0000ull; /* ACL clears ABT and ABW */ } else { newval |= val & 0x00f00000; /* ABT field is W1S */ if ((newval & 0xf0000) == 0) { newval |= val & 0xf0000; /* ABW field is W1S iff zero */ } } newval |= (val & 0xf000) >> 4; /* IPREQ field sets IPINTR. */ newval &= ~0xf0000000000ull; /* WO and RW fields */ newval |= val & 0xf0000000000ull; s->cchip.misc = newval; /* Pass on changes to IPI and ITI state. */ if ((newval ^ oldval) & 0xff0) { int i; for (i = 0; i < 4; ++i) { AlphaCPU *cpu = s->cchip.cpu[i]; if (cpu != NULL) { CPUState *cs = CPU(cpu); /* IPI can be either cleared or set by the write. */ if (newval & (1 << (i + 8))) { cpu_interrupt(cs, CPU_INTERRUPT_SMP); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_SMP); } /* ITI can only be cleared by the write. */ if ((newval & (1 << (i + 4))) == 0) { cpu_reset_interrupt(cs, CPU_INTERRUPT_TIMER); } } } } break; case 0x00c0: /* MPD: Memory Presence Detect Register. */ break; case 0x0100: /* AAR0 */ case 0x0140: /* AAR1 */ case 0x0180: /* AAR2 */ case 0x01c0: /* AAR3 */ /* AAR: Array Address Register. */ /* All sorts of information about DRAM. */ break; case 0x0200: /* DIM0 */ /* DIM: Device Interrupt Mask Register, CPU0. */ s->cchip.dim[0] = val; cpu_irq_change(s->cchip.cpu[0], val & s->cchip.drir); break; case 0x0240: /* DIM1 */ /* DIM: Device Interrupt Mask Register, CPU1. */ s->cchip.dim[0] = val; cpu_irq_change(s->cchip.cpu[1], val & s->cchip.drir); break; case 0x0280: /* DIR0 (RO) */ case 0x02c0: /* DIR1 (RO) */ case 0x0300: /* DRIR (RO) */ break; case 0x0340: /* PRBEN: Probe Enable Register. */ break; case 0x0380: /* IIC0 */ s->cchip.iic[0] = val & 0xffffff; break; case 0x03c0: /* IIC1 */ s->cchip.iic[1] = val & 0xffffff; break; case 0x0400: /* MPR0 */ case 0x0440: /* MPR1 */ case 0x0480: /* MPR2 */ case 0x04c0: /* MPR3 */ /* MPR: Memory Programming Register. */ break; case 0x0580: /* TTR: TIGbus Timing Register. */ /* All sorts of stuff related to interrupt delivery timings. */ break; case 0x05c0: /* TDR: TIGbug Device Timing Register. */ break; case 0x0600: /* DIM2: Device Interrupt Mask Register, CPU2. */ s->cchip.dim[2] = val; cpu_irq_change(s->cchip.cpu[2], val & s->cchip.drir); break; case 0x0640: /* DIM3: Device Interrupt Mask Register, CPU3. */ s->cchip.dim[3] = val; cpu_irq_change(s->cchip.cpu[3], val & s->cchip.drir); break; case 0x0680: /* DIR2 (RO) */ case 0x06c0: /* DIR3 (RO) */ break; case 0x0700: /* IIC2 */ s->cchip.iic[2] = val & 0xffffff; break; case 0x0740: /* IIC3 */ s->cchip.iic[3] = val & 0xffffff; break; case 0x0780: /* PWR: Power Management Control. */ break; case 0x0c00: /* CMONCTLA */ case 0x0c40: /* CMONCTLB */ case 0x0c80: /* CMONCNT01 */ case 0x0cc0: /* CMONCNT23 */ break; default: cpu_unassigned_access(cpu_single_cpu, addr, true, false, 0, size); return; } }
void cpu_check_irqs(CPUSPARCState *env) { CPUState *cs; uint32_t pil = env->pil_in | (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER)); /* We should be holding the BQL before we mess with IRQs */ g_assert(qemu_mutex_iothread_locked()); /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */ if (env->ivec_status & 0x20) { return; } cs = CPU(sparc_env_get_cpu(env)); /* check if TM or SM in SOFTINT are set setting these also causes interrupt 14 */ if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) { pil |= 1 << 14; } /* The bit corresponding to psrpil is (1<< psrpil), the next bit is (2 << psrpil). */ if (pil < (2 << env->psrpil)) { if (cs->interrupt_request & CPU_INTERRUPT_HARD) { trace_sparc64_cpu_check_irqs_reset_irq(env->interrupt_index); env->interrupt_index = 0; cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } return; } if (cpu_interrupts_enabled(env)) { unsigned int i; for (i = 15; i > env->psrpil; i--) { if (pil & (1 << i)) { int old_interrupt = env->interrupt_index; int new_interrupt = TT_EXTINT | i; if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt && ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) { trace_sparc64_cpu_check_irqs_noset_irq(env->tl, cpu_tsptr(env)->tt, new_interrupt); } else if (old_interrupt != new_interrupt) { env->interrupt_index = new_interrupt; trace_sparc64_cpu_check_irqs_set_irq(i, old_interrupt, new_interrupt); cpu_interrupt(cs, CPU_INTERRUPT_HARD); } break; } } } else if (cs->interrupt_request & CPU_INTERRUPT_HARD) { trace_sparc64_cpu_check_irqs_disabled(pil, env->pil_in, env->softint, env->interrupt_index); env->interrupt_index = 0; cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } }