Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
/* 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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
/*
 * 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);
}
Exemplo n.º 6
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));
    }
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
/* 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]);
    }
}
Exemplo n.º 10
0
Arquivo: irq.c Projeto: 08opt/linux
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);
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
Arquivo: i8259.c Projeto: xqx12/s2e1.1
/* 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
}
Exemplo n.º 13
0
/* 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
}