Example #1
0
/**
 * \brief globally enables the interrupts for the given device
 *
 * \param dev   IOAT DMA device
 * \param type  the interrupt type to enable
 */
errval_t ioat_dma_device_irq_setup(struct ioat_dma_device *dev,
                                   dma_irq_t type)
{
    ioat_dma_intrctrl_t intcrtl = 0;
    intcrtl = ioat_dma_intrctrl_intp_en_insert(intcrtl, 1);

    dev->common.irq_type = type;
    switch (type) {
        case DMA_IRQ_MSIX:
            IOATDEV_DEBUG("Initializing MSI-X interrupts \n", dev->common.id);
            assert(!"NYI");
            break;
        case DMA_IRQ_MSI:
            IOATDEV_DEBUG("Initializing MSI interrupts \n", dev->common.id);
            assert(!"NYI");
            break;
        case DMA_IRQ_INTX:
            IOATDEV_DEBUG("Initializing INTx interrupts \n", dev->common.id);
            assert(!"NYI");
            break;
        default:
            /* disabled */
            intcrtl = 0;
            IOATDEV_DEBUG("Disabling interrupts \n", dev->common.id);
            break;
    }

    ioat_dma_intrctrl_wr(&dev->device, intcrtl);

    return SYS_ERR_OK;
}
/**
 * \brief globally enables the interrupts for the given device
 *
 * \param dev   IOAT DMA device
 * \param type  the interrupt type to enable
 */
errval_t ioat_dma_device_irq_setup(struct ioat_dma_device *dev,
                                   dma_irq_t type)
{
    errval_t err;

    ioat_dma_intrctrl_t intcrtl = 0;
    intcrtl = ioat_dma_intrctrl_intp_en_insert(intcrtl, 1);

    dev->common.irq_type = type;
    switch (type) {
        case DMA_IRQ_MSIX:
            /* The number of MSI-X vectors should equal the number of channels */
            IOATDEV_DEBUG("MSI-X interrupt setup for device (%u, %u, %u)\n",
                          dev->common.id, dev->pci_addr.bus, dev->pci_addr.device,
                          dev->pci_addr.function);

            err = pci_msix_enable_addr(&dev->pci_addr, &dev->irq_msix_count);
            if (err_is_fail(err)) {
                return err;
            }

            assert(dev->irq_msix_count > 0);

            IOATDEV_DEBUG("MSI-X enabled #vecs=%d\n", dev->common.id,
                          dev->irq_msix_count);

            err = pci_setup_inthandler(ioat_dma_device_irq_handler, dev,
                                       &dev->irq_msix_vector);
            assert(err_is_ok(err));

            uint8_t dest = get_local_apic_id();

            IOATDEV_DEBUG("MSI-X routing to apic=%u\n", dev->common.id,
                          dest);

            err = pci_msix_vector_init_addr(&dev->pci_addr, 0, dest,
                                            dev->irq_msix_vector);
            assert(err_is_ok(err));

            /* enable the interrupts */
            intcrtl = ioat_dma_intrctrl_msix_vec_insert(intcrtl, 1);
            intcrtl = ioat_dma_intrctrl_intp_en_insert(intcrtl, 1);
            break;
        case DMA_IRQ_MSI:
            IOATDEV_DEBUG("Initializing MSI interrupts \n", dev->common.id);
            assert(!"NYI");
            break;
        case DMA_IRQ_INTX:
            IOATDEV_DEBUG("Initializing INTx interrupts \n", dev->common.id);
            assert(!"NYI");
            break;
        default:
            /* disabled */
            intcrtl = 0;
            IOATDEV_DEBUG("Disabling interrupts \n", dev->common.id);
            break;
    }

    ioat_dma_intrctrl_wr(&dev->device, intcrtl);


#if IOAT_DEBUG_INTR_ENABLED
    /*
     * check if interrupts are working.
     */
    msix_intr_happened = 0;

    struct ioat_dma_channel *chan;
    chan = (struct ioat_dma_channel *)dev->common.channels.c[0];

    ioat_dma_request_nop_chan(chan);
    err = ioat_dma_channel_issue_pending(chan);
    if (err_is_fail(err)) {
        return err;
    }

    while(msix_intr_happened == 0) {
        uint64_t status = ioat_dma_channel_get_status(chan);
        err = event_dispatch_non_block(get_default_waitset());

        if (!ioat_dma_channel_is_active(status) && !ioat_dma_channel_is_idle(status)) {
            USER_PANIC("DMA request turned channel into erroneous state.")
        }

        switch(err_no(err)) {
            case LIB_ERR_NO_EVENT:
                thread_yield();
                break;
            case SYS_ERR_OK:
                continue;
            default:
                USER_PANIC_ERR(err, "dispatching event");
        }
    }
#endif

    return SYS_ERR_OK;
}