int kvm_pic_read_irq(struct kvm_pic *s) { int irq, irq2, intno; irq = pic_get_irq(&s->pics[0]); if (irq >= 0) { pic_intack(&s->pics[0], irq); if (irq == 2) { irq2 = pic_get_irq(&s->pics[1]); if (irq2 >= 0) pic_intack(&s->pics[1], irq2); else /* * spurious IRQ on slave controller */ irq2 = 7; intno = s->pics[1].irq_base + irq2; irq = irq2 + 8; } else intno = s->pics[0].irq_base + irq; } else { /* * spurious IRQ on host controller */ irq = 7; intno = s->pics[0].irq_base + irq; } pic_update_irq(s); return intno; }
/* raise irq to CPU if necessary. must be called every time the active irq may change */ static int pic_update_irq(PDEVPIC pThis) { PicState *pics = &pThis->aPics[0]; int irq2, irq; /* first look at slave pic */ irq2 = pic_get_irq(&pics[1]); Log(("pic_update_irq irq2=%d\n", irq2)); if (irq2 >= 0) { /* if irq request by slave pic, signal master PIC */ pic_set_irq1(&pics[0], 2, 1); } else { /* If not, clear the IR on the master PIC. */ pic_set_irq1(&pics[0], 2, 0); } /* look at requested irq */ irq = pic_get_irq(&pics[0]); if (irq >= 0) { /* If irq 2 is pending on the master pic, then there must be one pending on the slave pic too! Otherwise we'll get * spurious slave interrupts in picGetInterrupt. */ if (irq != 2 || irq2 != -1) { #if defined(DEBUG_PIC) int i; for(i = 0; i < 2; i++) { Log(("pic%d: imr=%x irr=%x padd=%d\n", i, pics[i].imr, pics[i].irr, pics[i].priority_add)); } Log(("pic: cpu_interrupt\n")); #endif pThis->CTX_SUFF(pPicHlp)->pfnSetInterruptFF(pThis->CTX_SUFF(pDevIns)); } else { STAM_COUNTER_INC(&pThis->StatClearedActiveIRQ2); Log(("pic_update_irq: irq 2 is active, but no interrupt is pending on the slave pic!!\n")); /* Clear it here, so lower priority interrupts can still be dispatched. */ /* if this was the only pending irq, then we must clear the interrupt ff flag */ pThis->CTX_SUFF(pPicHlp)->pfnClearInterruptFF(pThis->CTX_SUFF(pDevIns)); /** @note Is this correct? */ pics[0].irr &= ~(1 << 2); /* Call ourselves again just in case other interrupts are pending */ return pic_update_irq(pThis); } } else { Log(("pic_update_irq: no interrupt is pending!!\n")); /* we must clear the interrupt ff flag */ pThis->CTX_SUFF(pPicHlp)->pfnClearInterruptFF(pThis->CTX_SUFF(pDevIns)); } return VINF_SUCCESS; }
int pic_read_irq(PicState2 *s) { int irq, irq2, intno; irq = pic_get_irq(&s->pics[0]); if (irq >= 0) { pic_intack(&s->pics[0], irq); #ifndef TARGET_IA64 if (time_drift_fix && irq == 0) { extern int64_t timer_acks, timer_ints_to_push; timer_acks++; if (timer_ints_to_push > 0) { timer_ints_to_push--; /* simulate an edge irq0, like the one generated by i8254 */ pic_set_irq1(&s->pics[0], 0, 0); pic_set_irq1(&s->pics[0], 0, 1); } } #endif if (irq == 2) { irq2 = pic_get_irq(&s->pics[1]); if (irq2 >= 0) { pic_intack(&s->pics[1], irq2); } else { /* spurious IRQ on slave controller */ irq2 = 7; } intno = s->pics[1].irq_base + irq2; #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_LATENCY) irq = irq2 + 8; #endif } else { intno = s->pics[0].irq_base + irq; } } else { /* spurious IRQ on host controller */ irq = 7; intno = s->pics[0].irq_base + irq; } pic_update_irq(s); #ifdef DEBUG_IRQ_LATENCY printf("IRQ%d latency=%0.3fus\n", irq, (double)(qemu_get_clock(vm_clock) - irq_time[irq]) * 1000000.0 / get_ticks_per_sec()); #endif #if defined(DEBUG_PIC) printf("pic_interrupt: irq=%d\n", irq); #endif return intno; }
static void or1k_pic_handle_irq(struct pt_regs *regs) { int irq = -1; while ((irq = pic_get_irq(irq + 1)) != NO_IRQ) handle_domain_irq(root_domain, irq, regs); }
/* * raise irq to CPU if necessary. must be called every time the active * irq may change */ static void pic_update_irq(struct kvm_pic *s) { int irq2, irq; irq2 = pic_get_irq(&s->pics[1]); if (irq2 >= 0) { /* * if irq request by slave pic, signal master PIC */ pic_set_irq1(&s->pics[0], 2, 1); pic_set_irq1(&s->pics[0], 2, 0); } irq = pic_get_irq(&s->pics[0]); if (irq >= 0) s->irq_request(s->irq_request_opaque, 1); else s->irq_request(s->irq_request_opaque, 0); }
/** @note if an interrupt line state changes from unmasked to masked, then it must be deactivated when currently pending! */ static void pic_update_imr(PDEVPIC pThis, PPICSTATE pPic, uint8_t val) { int irq, intno; PPICSTATE pActivePIC; /* Query the current pending irq, if any. */ pActivePIC = &pThis->aPics[0]; intno = irq = pic_get_irq(pActivePIC); if (irq == 2) { pActivePIC = &pThis->aPics[1]; irq = pic_get_irq(pActivePIC); intno = irq + 8; } /* Update IMR */ Log(("pic_update_imr: pic%u %#x -> %#x\n", pPic->idxPic, pPic->imr, val)); pPic->imr = val; /* If an interrupt is pending and now masked, then clear the FF flag. */ if ( irq >= 0 && ((1 << irq) & ~pActivePIC->imr) == 0) { Log(("pic_update_imr: pic0: elcr=%x last_irr=%x irr=%x imr=%x isr=%x irq_base=%x\n", pThis->aPics[0].elcr, pThis->aPics[0].last_irr, pThis->aPics[0].irr, pThis->aPics[0].imr, pThis->aPics[0].isr, pThis->aPics[0].irq_base)); Log(("pic_update_imr: pic1: elcr=%x last_irr=%x irr=%x imr=%x isr=%x irq_base=%x\n", pThis->aPics[1].elcr, pThis->aPics[1].last_irr, pThis->aPics[1].irr, pThis->aPics[1].imr, pThis->aPics[1].isr, pThis->aPics[1].irq_base)); /* Clear pending IRQ 2 on master controller in case of slave interrupt. */ /** @todo Is this correct? */ if (intno > 7) { pThis->aPics[0].irr &= ~(1 << 2); STAM_COUNTER_INC(&pThis->StatClearedActiveSlaveIRQ); } else STAM_COUNTER_INC(&pThis->StatClearedActiveMasterIRQ); Log(("pic_update_imr: clear pending interrupt %d\n", intno)); pThis->CTX_SUFF(pPicHlp)->pfnClearInterruptFF(pThis->CTX_SUFF(pDevIns)); } }
int pic_read_irq(DeviceState *d) { PICCommonState *s = DO_UPCAST(PICCommonState, dev.qdev, d); int irq, irq2, intno; irq = pic_get_irq(s); if (irq >= 0) { if (irq == 2) { irq2 = pic_get_irq(slave_pic); if (irq2 >= 0) { pic_intack(slave_pic, irq2); } else { /* spurious IRQ on slave controller */ irq2 = 7; } intno = slave_pic->irq_base + irq2; } else { intno = s->irq_base + irq; } pic_intack(s, irq); } else { /* spurious IRQ on host controller */ irq = 7; intno = s->irq_base + irq; } #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_LATENCY) if (irq == 2) { irq = irq2 + 8; } #endif #ifdef DEBUG_IRQ_LATENCY printf("IRQ%d latency=%0.3fus\n", irq, (double)(qemu_get_clock_ns(vm_clock) - irq_time[irq]) * 1000000.0 / get_ticks_per_sec()); #endif DPRINTF("pic_interrupt: irq=%d\n", irq); return intno; }
int pic_read_irq(DeviceState *d) { PICCommonState *s = PIC_COMMON(d); int irq, irq2, intno; irq = pic_get_irq(s); if (irq >= 0) { if (irq == 2) { irq2 = pic_get_irq(slave_pic); if (irq2 >= 0) { pic_intack(slave_pic, irq2); } else { /* spurious IRQ on slave controller */ irq2 = 7; } intno = slave_pic->irq_base + irq2; } else { intno = s->irq_base + irq; } pic_intack(s, irq); } else { /* spurious IRQ on host controller */ irq = 7; intno = s->irq_base + irq; } #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_LATENCY) if (irq == 2) { irq = irq2 + 8; } #endif #ifdef DEBUG_IRQ_LATENCY printf("IRQ%d latency=%0.3fus\n", irq, (double)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - irq_time[irq]) * 1000000.0 / NANOSECONDS_PER_SECOND); #endif DPRINTF("pic_interrupt: irq=%d\n", irq); return intno; }
/* Update INT output. Must be called every time the output may have changed. */ static void pic_update_irq(PICCommonState *s) { int irq; irq = pic_get_irq(s); if (irq >= 0) { DPRINTF("pic%d: imr=%x irr=%x padd=%d\n", s->master ? 0 : 1, s->imr, s->irr, s->priority_add); qemu_irq_raise(s->int_out[0]); } else { qemu_irq_lower(s->int_out[0]); } }
void __irq_entry do_IRQ(struct pt_regs *regs) { int irq = -1; struct pt_regs *old_regs = set_irq_regs(regs); irq_enter(); while ((irq = pic_get_irq(irq + 1)) != NO_IRQ) generic_handle_irq(irq); irq_exit(); set_irq_regs(old_regs); }
int pic_read_irq(PicState2 *s) { int irq, irq2, intno; irq = pic_get_irq(&s->pics[0]); if (irq >= 0) { pic_intack(&s->pics[0], irq); if (irq == 2) { irq2 = pic_get_irq(&s->pics[1]); if (irq2 >= 0) { pic_intack(&s->pics[1], irq2); } else { /* spurious IRQ on slave controller */ irq2 = 7; } intno = s->pics[1].irq_base + irq2; #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_LATENCY) irq = irq2 + 8; #endif } else { intno = s->pics[0].irq_base + irq; } } else { /* spurious IRQ on host controller */ irq = 7; intno = s->pics[0].irq_base + irq; } pic_update_irq(s); #ifdef DEBUG_IRQ_LATENCY printf("IRQ%d latency=%0.3fus\n", irq, (double)(qemu_get_clock_ns(vm_clock) - irq_time[irq]) * 1000000.0 / get_ticks_per_sec()); #endif DPRINTF("pic_interrupt: irq=%d\n", irq); return intno; }
/* XXX: should not export it, but it is needed for an APIC kludge */ void pic_update_irq(PicState2 *s) { int irq2, irq; /* first look at slave pic */ irq2 = pic_get_irq(&s->pics[1]); if (irq2 >= 0) { /* if irq request by slave pic, signal master PIC */ pic_set_irq1(&s->pics[0], 2, 1); pic_set_irq1(&s->pics[0], 2, 0); } /* look at requested irq */ irq = pic_get_irq(&s->pics[0]); if (irq >= 0) { #if defined(DEBUG_PIC) { int i; for(i = 0; i < 2; i++) { printf("pic%d: imr=%x irr=%x padd=%d\n", i, s->pics[i].imr, s->pics[i].irr, s->pics[i].priority_add); } } printf("pic: cpu_interrupt\n"); #endif qemu_irq_raise(s->parent_irq); } /* all targets should do this rather than acking the IRQ in the cpu */ /* vova: at least on x86 targets this is required to avoid crashed when simulation speed is low (for example due to logging enabled */ //#if defined(TARGET_MIPS) || defined(TARGET_PPC) || defined(TARGET_ALPHA) else { qemu_irq_lower(s->parent_irq); } //#endif }
/* XXX: should not export it, but it is needed for an APIC kludge */ void pic_update_irq(PicState2 *s) { int irq2, irq; /* first look at slave pic */ irq2 = pic_get_irq(&s->pics[1]); if (irq2 >= 0) { /* if irq request by slave pic, signal master PIC */ pic_set_irq1(&s->pics[0], 2, 1); pic_set_irq1(&s->pics[0], 2, 0); } /* look at requested irq */ irq = pic_get_irq(&s->pics[0]); if (irq >= 0) { #if defined(DEBUG_PIC) { int i; for(i = 0; i < 2; i++) { printf("pic%d: imr=%x irr=%x padd=%d\n", i, s->pics[i].imr, s->pics[i].irr, s->pics[i].priority_add); } } printf("pic: cpu_interrupt\n"); #endif qemu_irq_raise(s->parent_irq); } /* all targets should do this rather than acking the IRQ in the cpu */ #if defined(TARGET_MIPS) || defined(TARGET_PPC) else { qemu_irq_lower(s->parent_irq); } #endif }