openpic: move IACK to its own function
Besides making the code cleaner, we will need a separate way to access IACK in order to implement EPR (external proxy) interrupt delivery. Signed-off-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
		
							parent
							
								
									4417c73305
								
							
						
					
					
						commit
						a898a8fc96
					
				
							
								
								
									
										95
									
								
								hw/openpic.c
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								hw/openpic.c
									
									
									
									
									
								
							@ -975,14 +975,64 @@ static void openpic_cpu_write(void *opaque, hwaddr addr, uint64_t val,
 | 
			
		||||
    openpic_cpu_write_internal(opaque, addr, val, (addr & 0x1f000) >> 12);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu)
 | 
			
		||||
{
 | 
			
		||||
    IRQSource *src;
 | 
			
		||||
    int retval, irq;
 | 
			
		||||
 | 
			
		||||
    DPRINTF("Lower OpenPIC INT output\n");
 | 
			
		||||
    qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
 | 
			
		||||
 | 
			
		||||
    irq = IRQ_get_next(opp, &dst->raised);
 | 
			
		||||
    DPRINTF("IACK: irq=%d\n", irq);
 | 
			
		||||
 | 
			
		||||
    if (irq == -1) {
 | 
			
		||||
        /* No more interrupt pending */
 | 
			
		||||
        return opp->spve;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    src = &opp->src[irq];
 | 
			
		||||
    if (!(src->ivpr & IVPR_ACTIVITY_MASK) ||
 | 
			
		||||
            !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) {
 | 
			
		||||
        /* - Spurious level-sensitive IRQ
 | 
			
		||||
         * - Priorities has been changed
 | 
			
		||||
         *   and the pending IRQ isn't allowed anymore
 | 
			
		||||
         */
 | 
			
		||||
        src->ivpr &= ~IVPR_ACTIVITY_MASK;
 | 
			
		||||
        retval = opp->spve;
 | 
			
		||||
    } else {
 | 
			
		||||
        /* IRQ enter servicing state */
 | 
			
		||||
        IRQ_setbit(&dst->servicing, irq);
 | 
			
		||||
        retval = IVPR_VECTOR(opp, src->ivpr);
 | 
			
		||||
    }
 | 
			
		||||
    IRQ_resetbit(&dst->raised, irq);
 | 
			
		||||
    if (!src->level) {
 | 
			
		||||
        /* edge-sensitive IRQ */
 | 
			
		||||
        src->ivpr &= ~IVPR_ACTIVITY_MASK;
 | 
			
		||||
        src->pending = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((irq >= opp->irq_ipi0) &&  (irq < (opp->irq_ipi0 + MAX_IPI))) {
 | 
			
		||||
        src->idr &= ~(1 << cpu);
 | 
			
		||||
        if (src->idr && !src->level) {
 | 
			
		||||
            /* trigger on CPUs that didn't know about it yet */
 | 
			
		||||
            openpic_set_irq(opp, irq, 1);
 | 
			
		||||
            openpic_set_irq(opp, irq, 0);
 | 
			
		||||
            /* if all CPUs knew about it, set active bit again */
 | 
			
		||||
            src->ivpr |= IVPR_ACTIVITY_MASK;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
 | 
			
		||||
                                          int idx)
 | 
			
		||||
{
 | 
			
		||||
    OpenPICState *opp = opaque;
 | 
			
		||||
    IRQSource *src;
 | 
			
		||||
    IRQDest *dst;
 | 
			
		||||
    uint32_t retval;
 | 
			
		||||
    int n_IRQ;
 | 
			
		||||
 | 
			
		||||
    DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx "\n", __func__, idx, addr);
 | 
			
		||||
    retval = 0xFFFFFFFF;
 | 
			
		||||
@ -1004,46 +1054,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
 | 
			
		||||
        retval = idx;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0xA0: /* IACK */
 | 
			
		||||
        DPRINTF("Lower OpenPIC INT output\n");
 | 
			
		||||
        qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
 | 
			
		||||
        n_IRQ = IRQ_get_next(opp, &dst->raised);
 | 
			
		||||
        DPRINTF("IACK: irq=%d\n", n_IRQ);
 | 
			
		||||
        if (n_IRQ == -1) {
 | 
			
		||||
            /* No more interrupt pending */
 | 
			
		||||
            retval = opp->spve;
 | 
			
		||||
        } else {
 | 
			
		||||
            src = &opp->src[n_IRQ];
 | 
			
		||||
            if (!(src->ivpr & IVPR_ACTIVITY_MASK) ||
 | 
			
		||||
                !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) {
 | 
			
		||||
                /* - Spurious level-sensitive IRQ
 | 
			
		||||
                 * - Priorities has been changed
 | 
			
		||||
                 *   and the pending IRQ isn't allowed anymore
 | 
			
		||||
                 */
 | 
			
		||||
                src->ivpr &= ~IVPR_ACTIVITY_MASK;
 | 
			
		||||
                retval = opp->spve;
 | 
			
		||||
            } else {
 | 
			
		||||
                /* IRQ enter servicing state */
 | 
			
		||||
                IRQ_setbit(&dst->servicing, n_IRQ);
 | 
			
		||||
                retval = IVPR_VECTOR(opp, src->ivpr);
 | 
			
		||||
            }
 | 
			
		||||
            IRQ_resetbit(&dst->raised, n_IRQ);
 | 
			
		||||
            if (!src->level) {
 | 
			
		||||
                /* edge-sensitive IRQ */
 | 
			
		||||
                src->ivpr &= ~IVPR_ACTIVITY_MASK;
 | 
			
		||||
                src->pending = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ((n_IRQ >= opp->irq_ipi0) &&  (n_IRQ < (opp->irq_ipi0 + MAX_IPI))) {
 | 
			
		||||
                src->idr &= ~(1 << idx);
 | 
			
		||||
                if (src->idr && !src->level) {
 | 
			
		||||
                    /* trigger on CPUs that didn't know about it yet */
 | 
			
		||||
                    openpic_set_irq(opp, n_IRQ, 1);
 | 
			
		||||
                    openpic_set_irq(opp, n_IRQ, 0);
 | 
			
		||||
                    /* if all CPUs knew about it, set active bit again */
 | 
			
		||||
                    src->ivpr |= IVPR_ACTIVITY_MASK;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        retval = openpic_iack(opp, dst, idx);
 | 
			
		||||
        break;
 | 
			
		||||
    case 0xB0: /* EOI */
 | 
			
		||||
        retval = 0;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user