예제 #1
0
void virqmap_vgicd_changed_istatus_callback_handler( vmid_t vmid, uint32_t istatus, uint8_t word_offset )
{
    uint32_t cstatus;                          // changed bits only
    uint32_t minirq;
    int bit;

    minirq = word_offset * 32;                 /* irq range: 0~31 + word_offset * size_of_istatus_in_bits */
    cstatus = old_vgicd_status[vmid][word_offset] ^ istatus;   // find changed bits

    while(cstatus) {
        uint32_t virq;
        uint32_t pirq;
        bit = firstbit32(cstatus);

        virq = minirq + bit;
        pirq = virqmap_pirq(vmid, virq);

        if ( pirq != PIRQ_INVALID ) {
            /* changed bit */
            if ( istatus & (1 << bit) ) {
                printh("[%s : %d] enabled irq num is %d\n", __FUNCTION__, __LINE__, bit + minirq);
                gic_test_configure_irq(pirq, GIC_INT_POLARITY_LEVEL, gic_cpumask_current(), GIC_INT_PRIORITY_DEFAULT );
            } else {
                printh("[%s : %d] disabled irq num is %d\n",__FUNCTION__, __LINE__, bit + minirq);
                gic_disable_irq(pirq);
            }
        } else {
            printh( "WARNING: Ignoring virq %d for guest %d has no mapped pirq\n", virq, vmid );
        }
        cstatus &= ~(1<< bit);
    }
    old_vgicd_status[vmid][word_offset] = istatus;
}
예제 #2
0
hvmm_status_t gic_configure_irq(uint32_t irq,
                enum gic_int_polarity polarity,  uint8_t cpumask,
                uint8_t priority)
{
    hvmm_status_t result = HVMM_STATUS_UNKNOWN_ERROR;
    HVMM_TRACE_ENTER();
    if (irq < _gic.lines) {
        uint32_t icfg;
        volatile uint8_t *reg8;
        /* disable forwarding */
        result = gic_disable_irq(irq);
        if (result == HVMM_STATUS_SUCCESS) {
            /* polarity: level or edge */
            icfg = _gic.ba_gicd[GICD_ICFGR + irq / 16];
            if (polarity == GIC_INT_POLARITY_LEVEL)
                icfg &= ~(2u << (2 * (irq % 16)));
            else
                icfg |= (2u << (2 * (irq % 16)));

            _gic.ba_gicd[GICD_ICFGR + irq / 16] = icfg;
            /* routing */
            reg8 = (uint8_t *) &(_gic.ba_gicd[GICD_ITARGETSR]);
            reg8[irq] = cpumask;
            /* priority */
            reg8 = (uint8_t *) &(_gic.ba_gicd[GICD_IPRIORITYR]);
            reg8[irq] = priority;
            /* enable forwarding */
            result = gic_enable_irq(irq);
        }
    } else {
        uart_print("invalid irq:");
        uart_print_hex32(irq);
        uart_print("\n\r");
        result = HVMM_STATUS_UNSUPPORTED_FEATURE;
    }
    HVMM_TRACE_EXIT();
    return result;
}