Beispiel #1
0
static void ivshmem_setup_msi(IVShmemState * s) {

    int i;

    /* allocate the MSI-X vectors */

    if (!msix_init(&s->dev, s->vectors, 1, 0)) {
        pci_register_bar(&s->dev, 1,
                         msix_bar_size(&s->dev),
                         PCI_BASE_ADDRESS_SPACE_MEMORY,
                         msix_mmio_map);
        IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors);
    } else {
        IVSHMEM_DPRINTF("msix initialization failed\n");
        exit(1);
    }

    /* 'activate' the vectors */
    for (i = 0; i < s->vectors; i++) {
        msix_vector_use(&s->dev, i);
    }

    /* allocate Qemu char devices for receiving interrupts */
    s->eventfd_table = qemu_mallocz(s->vectors * sizeof(EventfdEntry));
}
Beispiel #2
0
int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,
                            uint8_t bar_nr)
{
    int ret;
    char *name;
    uint32_t bar_size = 4096;
    uint32_t bar_pba_offset = bar_size / 2;
    uint32_t bar_pba_size = (nentries / 8 + 1) * 8;

    /*
     * Migration compatibility dictates that this remains a 4k
     * BAR with the vector table in the lower half and PBA in
     * the upper half for nentries which is lower or equal to 128.
     * No need to care about using more than 65 entries for legacy
     * machine types who has at most 64 queues.
     */
    if (nentries * PCI_MSIX_ENTRY_SIZE > bar_pba_offset) {
        bar_pba_offset = nentries * PCI_MSIX_ENTRY_SIZE;
    }

    if (bar_pba_offset + bar_pba_size > 4096) {
        bar_size = bar_pba_offset + bar_pba_size;
    }

    if (bar_size & (bar_size - 1)) {
        bar_size = 1 << qemu_fls(bar_size);
    }

    name = g_strdup_printf("%s-msix", dev->name);
    memory_region_init(&dev->msix_exclusive_bar, OBJECT(dev), name, bar_size);
    g_free(name);

    ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr,
                    0, &dev->msix_exclusive_bar,
                    bar_nr, bar_pba_offset,
                    0);
    if (ret) {
        return ret;
    }

    pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY,
                     &dev->msix_exclusive_bar);

    return 0;
}
Beispiel #3
0
static void
e1000e_init_msix(E1000EState *s)
{
    PCIDevice *d = PCI_DEVICE(s);
    int res = msix_init(PCI_DEVICE(s), E1000E_MSIX_VEC_NUM,
                        &s->msix,
                        E1000E_MSIX_IDX, E1000E_MSIX_TABLE,
                        &s->msix,
                        E1000E_MSIX_IDX, E1000E_MSIX_PBA,
                        0xA0, NULL);

    if (res < 0) {
        trace_e1000e_msix_init_fail(res);
    } else {
        if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) {
            msix_uninit(d, &s->msix, &s->msix);
        }
    }
}
Beispiel #4
0
int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,
                            uint8_t bar_nr)
{
    int ret;
    char *name;

    /*
     * Migration compatibility dictates that this remains a 4k
     * BAR with the vector table in the lower half and PBA in
     * the upper half.  Do not use these elsewhere!
     */
#define MSIX_EXCLUSIVE_BAR_SIZE 4096
#define MSIX_EXCLUSIVE_BAR_TABLE_OFFSET 0
#define MSIX_EXCLUSIVE_BAR_PBA_OFFSET (MSIX_EXCLUSIVE_BAR_SIZE / 2)
#define MSIX_EXCLUSIVE_CAP_OFFSET 0

    if (nentries * PCI_MSIX_ENTRY_SIZE > MSIX_EXCLUSIVE_BAR_PBA_OFFSET) {
        return -EINVAL;
    }

    name = g_strdup_printf("%s-msix", dev->name);
    memory_region_init(&dev->msix_exclusive_bar, OBJECT(dev), name, MSIX_EXCLUSIVE_BAR_SIZE);
    g_free(name);

    ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr,
                    MSIX_EXCLUSIVE_BAR_TABLE_OFFSET, &dev->msix_exclusive_bar,
                    bar_nr, MSIX_EXCLUSIVE_BAR_PBA_OFFSET,
                    MSIX_EXCLUSIVE_CAP_OFFSET);
    if (ret) {
        memory_region_destroy(&dev->msix_exclusive_bar);
        return ret;
    }

    pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY,
                     &dev->msix_exclusive_bar);

    return 0;
}
Beispiel #5
0
static void ivshmem_setup_msi(IVShmemState * s) {

    int i;

    /* allocate the MSI-X vectors */

    memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
    if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
        pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
                         &s->msix_bar);
        IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors);
    } else {
        IVSHMEM_DPRINTF("msix initialization failed\n");
        exit(1);
    }

    /* 'activate' the vectors */
    for (i = 0; i < s->vectors; i++) {
        msix_vector_use(&s->dev, i);
    }

    /* allocate QEMU char devices for receiving interrupts */
    s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry));
}