int msix_init(struct PCIDevice *dev, unsigned short nentries,

              MemoryRegion *table_bar, uint8_t table_bar_nr,

              unsigned table_offset, MemoryRegion *pba_bar,

              uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos)

{

    int cap;

    unsigned table_size, pba_size;

    uint8_t *config;



    /* Nothing to do if MSI is not supported by interrupt controller */

    if (!msi_nonbroken) {

        return -ENOTSUP;

    }



    if (nentries < 1 || nentries > PCI_MSIX_FLAGS_QSIZE + 1) {

        return -EINVAL;

    }



    table_size = nentries * PCI_MSIX_ENTRY_SIZE;

    pba_size = QEMU_ALIGN_UP(nentries, 64) / 8;



    /* Sanity test: table & pba don't overlap, fit within BARs, min aligned */

    if ((table_bar_nr == pba_bar_nr &&

         ranges_overlap(table_offset, table_size, pba_offset, pba_size)) ||

        table_offset + table_size > memory_region_size(table_bar) ||

        pba_offset + pba_size > memory_region_size(pba_bar) ||

        (table_offset | pba_offset) & PCI_MSIX_FLAGS_BIRMASK) {

        return -EINVAL;

    }



    cap = pci_add_capability(dev, PCI_CAP_ID_MSIX, cap_pos, MSIX_CAP_LENGTH);

    if (cap < 0) {

        return cap;

    }



    dev->msix_cap = cap;

    dev->cap_present |= QEMU_PCI_CAP_MSIX;

    config = dev->config + cap;



    pci_set_word(config + PCI_MSIX_FLAGS, nentries - 1);

    dev->msix_entries_nr = nentries;

    dev->msix_function_masked = true;



    pci_set_long(config + PCI_MSIX_TABLE, table_offset | table_bar_nr);

    pci_set_long(config + PCI_MSIX_PBA, pba_offset | pba_bar_nr);



    /* Make flags bit writable. */

    dev->wmask[cap + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |

                                             MSIX_MASKALL_MASK;



    dev->msix_table = g_malloc0(table_size);

    dev->msix_pba = g_malloc0(pba_size);

    dev->msix_entry_used = g_malloc0(nentries * sizeof *dev->msix_entry_used);



    msix_mask_all(dev, nentries);



    memory_region_init_io(&dev->msix_table_mmio, OBJECT(dev), &msix_table_mmio_ops, dev,

                          "msix-table", table_size);

    memory_region_add_subregion(table_bar, table_offset, &dev->msix_table_mmio);

    memory_region_init_io(&dev->msix_pba_mmio, OBJECT(dev), &msix_pba_mmio_ops, dev,

                          "msix-pba", pba_size);

    memory_region_add_subregion(pba_bar, pba_offset, &dev->msix_pba_mmio);



    return 0;

}

int msix_init(struct PCIDevice *dev, unsigned short nentries,

              MemoryRegion *table_bar, uint8_t table_bar_nr,

              unsigned table_offset, MemoryRegion *pba_bar,

              uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos)

{

    int cap;

    unsigned table_size, pba_size;

    uint8_t *config;



    

    if (!msi_nonbroken) {

        return -ENOTSUP;

    }



    if (nentries < 1 || nentries > PCI_MSIX_FLAGS_QSIZE + 1) {

        return -EINVAL;

    }



    table_size = nentries * PCI_MSIX_ENTRY_SIZE;

    pba_size = QEMU_ALIGN_UP(nentries, 64) / 8;



    

    if ((table_bar_nr == pba_bar_nr &&

         ranges_overlap(table_offset, table_size, pba_offset, pba_size)) ||

        table_offset + table_size > memory_region_size(table_bar) ||

        pba_offset + pba_size > memory_region_size(pba_bar) ||

        (table_offset | pba_offset) & PCI_MSIX_FLAGS_BIRMASK) {

        return -EINVAL;

    }



    cap = pci_add_capability(dev, PCI_CAP_ID_MSIX, cap_pos, MSIX_CAP_LENGTH);

    if (cap < 0) {

        return cap;

    }



    dev->msix_cap = cap;

    dev->cap_present |= QEMU_PCI_CAP_MSIX;

    config = dev->config + cap;



    pci_set_word(config + PCI_MSIX_FLAGS, nentries - 1);

    dev->msix_entries_nr = nentries;

    dev->msix_function_masked = true;



    pci_set_long(config + PCI_MSIX_TABLE, table_offset | table_bar_nr);

    pci_set_long(config + PCI_MSIX_PBA, pba_offset | pba_bar_nr);



    

    dev->wmask[cap + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |

                                             MSIX_MASKALL_MASK;



    dev->msix_table = g_malloc0(table_size);

    dev->msix_pba = g_malloc0(pba_size);

    dev->msix_entry_used = g_malloc0(nentries * sizeof *dev->msix_entry_used);



    msix_mask_all(dev, nentries);



    memory_region_init_io(&dev->msix_table_mmio, OBJECT(dev), &msix_table_mmio_ops, dev,

                          "msix-table", table_size);

    memory_region_add_subregion(table_bar, table_offset, &dev->msix_table_mmio);

    memory_region_init_io(&dev->msix_pba_mmio, OBJECT(dev), &msix_pba_mmio_ops, dev,

                          "msix-pba", pba_size);

    memory_region_add_subregion(pba_bar, pba_offset, &dev->msix_pba_mmio);



    return 0;

}

              uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos)     cap = pci_add_capability(dev, PCI_CAP_ID_MSIX, cap_pos, MSIX_CAP_LENGTH);
int FUNC_0(struct PCIDevice *VAR_0, unsigned short VAR_1,

              MemoryRegion *VAR_2, uint8_t VAR_3,

              unsigned VAR_4, MemoryRegion *VAR_5,

              uint8_t VAR_6, unsigned VAR_7, uint8_t VAR_8)

{

    int VAR_9;

    unsigned VAR_10, VAR_11;

    uint8_t *config;



    

    if (!msi_nonbroken) {

        return -ENOTSUP;

    }



    if (VAR_1 < 1 || VAR_1 > PCI_MSIX_FLAGS_QSIZE + 1) {

        return -EINVAL;

    }



    VAR_10 = VAR_1 * PCI_MSIX_ENTRY_SIZE;

    VAR_11 = QEMU_ALIGN_UP(VAR_1, 64) / 8;



    

    if ((VAR_3 == VAR_6 &&

         ranges_overlap(VAR_4, VAR_10, VAR_7, VAR_11)) ||

        VAR_4 + VAR_10 > memory_region_size(VAR_2) ||

        VAR_7 + VAR_11 > memory_region_size(VAR_5) ||

        (VAR_4 | VAR_7) & PCI_MSIX_FLAGS_BIRMASK) {

        return -EINVAL;

    }



    VAR_9 = pci_add_capability(VAR_0, PCI_CAP_ID_MSIX, VAR_8, MSIX_CAP_LENGTH);

    if (VAR_9 < 0) {

        return VAR_9;

    }



    VAR_0->msix_cap = VAR_9;

    VAR_0->cap_present |= QEMU_PCI_CAP_MSIX;

    config = VAR_0->config + VAR_9;



    pci_set_word(config + PCI_MSIX_FLAGS, VAR_1 - 1);

    VAR_0->msix_entries_nr = VAR_1;

    VAR_0->msix_function_masked = true;



    pci_set_long(config + PCI_MSIX_TABLE, VAR_4 | VAR_3);

    pci_set_long(config + PCI_MSIX_PBA, VAR_7 | VAR_6);



    

    VAR_0->wmask[VAR_9 + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |

                                             MSIX_MASKALL_MASK;



    VAR_0->msix_table = g_malloc0(VAR_10);

    VAR_0->msix_pba = g_malloc0(VAR_11);

    VAR_0->msix_entry_used = g_malloc0(VAR_1 * sizeof *VAR_0->msix_entry_used);



    msix_mask_all(VAR_0, VAR_1);



    memory_region_init_io(&VAR_0->msix_table_mmio, OBJECT(VAR_0), &msix_table_mmio_ops, VAR_0,

                          "msix-table", VAR_10);

    memory_region_add_subregion(VAR_2, VAR_4, &VAR_0->msix_table_mmio);

    memory_region_init_io(&VAR_0->msix_pba_mmio, OBJECT(VAR_0), &msix_pba_mmio_ops, VAR_0,

                          "msix-pba", VAR_11);

    memory_region_add_subregion(VAR_5, VAR_7, &VAR_0->msix_pba_mmio);



    return 0;

}

int FUNC_0(struct PCIDevice *VAR_0, unsigned short VAR_1,
MemoryRegion *VAR_2, uint8_t VAR_3,
unsigned VAR_4, MemoryRegion *VAR_5,
uint8_t VAR_6, unsigned VAR_7, uint8_t VAR_8)
{ int VAR_9; unsigned VAR_10, VAR_11; uint8_t *config; if (!msi_nonbroken) { return -ENOTSUP; } if (VAR_1 < 1 || VAR_1 > PCI_MSIX_FLAGS_QSIZE + 1) { return -EINVAL; } VAR_10 = VAR_1 * PCI_MSIX_ENTRY_SIZE; VAR_11 = QEMU_ALIGN_UP(VAR_1, 64) / 8; if ((VAR_3 == VAR_6 &&
ranges_overlap(VAR_4, VAR_10, VAR_7, VAR_11)) ||
VAR_4 + VAR_10 > memory_region_size(VAR_2) ||
VAR_7 + VAR_11 > memory_region_size(VAR_5) ||
(VAR_4 | VAR_7) & PCI_MSIX_FLAGS_BIRMASK) { return -EINVAL; } VAR_9 = pci_add_capability(VAR_0, PCI_CAP_ID_MSIX, VAR_8, MSIX_CAP_LENGTH); if (VAR_9 < 0) { return VAR_9; } VAR_0->msix_cap = VAR_9; VAR_0->cap_present |= QEMU_PCI_CAP_MSIX; config = VAR_0->config + VAR_9; pci_set_word(config + PCI_MSIX_FLAGS, VAR_1 - 1); VAR_0->msix_entries_nr = VAR_1; VAR_0->msix_function_masked = true; pci_set_long(config + PCI_MSIX_TABLE, VAR_4 | VAR_3); pci_set_long(config + PCI_MSIX_PBA, VAR_7 | VAR_6); VAR_0->wmask[VAR_9 + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |
MSIX_MASKALL_MASK; VAR_0->msix_table = g_malloc0(VAR_10); VAR_0->msix_pba = g_malloc0(VAR_11); VAR_0->msix_entry_used = g_malloc0(VAR_1 * sizeof *VAR_0->msix_entry_used); msix_mask_all(VAR_0, VAR_1); memory_region_init_io(&VAR_0->msix_table_mmio, OBJECT(VAR_0), &msix_table_mmio_ops, VAR_0,
"msix-table", VAR_10); memory_region_add_subregion(VAR_2, VAR_4, &VAR_0->msix_table_mmio); memory_region_init_io(&VAR_0->msix_pba_mmio, OBJECT(VAR_0), &msix_pba_mmio_ops, VAR_0,
"msix-pba", VAR_11); memory_region_add_subregion(VAR_5, VAR_7, &VAR_0->msix_pba_mmio); return 0; }