|
|
|
@ -16,6 +16,7 @@ |
|
|
|
#include "libqos/malloc.h" |
|
|
|
#include "libqos/malloc-pc.h" |
|
|
|
#include "standard-headers/linux/virtio_ring.h" |
|
|
|
#include "standard-headers/linux/virtio_pci.h" |
|
|
|
|
|
|
|
#include "hw/pci/pci.h" |
|
|
|
#include "hw/pci/pci_regs.h" |
|
|
|
@ -103,31 +104,31 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t addr) |
|
|
|
static uint32_t qvirtio_pci_get_features(QVirtioDevice *d) |
|
|
|
{ |
|
|
|
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d; |
|
|
|
return qpci_io_readl(dev->pdev, dev->addr + QVIRTIO_PCI_DEVICE_FEATURES); |
|
|
|
return qpci_io_readl(dev->pdev, dev->addr + VIRTIO_PCI_HOST_FEATURES); |
|
|
|
} |
|
|
|
|
|
|
|
static void qvirtio_pci_set_features(QVirtioDevice *d, uint32_t features) |
|
|
|
{ |
|
|
|
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d; |
|
|
|
qpci_io_writel(dev->pdev, dev->addr + QVIRTIO_PCI_GUEST_FEATURES, features); |
|
|
|
qpci_io_writel(dev->pdev, dev->addr + VIRTIO_PCI_GUEST_FEATURES, features); |
|
|
|
} |
|
|
|
|
|
|
|
static uint32_t qvirtio_pci_get_guest_features(QVirtioDevice *d) |
|
|
|
{ |
|
|
|
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d; |
|
|
|
return qpci_io_readl(dev->pdev, dev->addr + QVIRTIO_PCI_GUEST_FEATURES); |
|
|
|
return qpci_io_readl(dev->pdev, dev->addr + VIRTIO_PCI_GUEST_FEATURES); |
|
|
|
} |
|
|
|
|
|
|
|
static uint8_t qvirtio_pci_get_status(QVirtioDevice *d) |
|
|
|
{ |
|
|
|
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d; |
|
|
|
return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_PCI_DEVICE_STATUS); |
|
|
|
return qpci_io_readb(dev->pdev, dev->addr + VIRTIO_PCI_STATUS); |
|
|
|
} |
|
|
|
|
|
|
|
static void qvirtio_pci_set_status(QVirtioDevice *d, uint8_t status) |
|
|
|
{ |
|
|
|
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d; |
|
|
|
qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_PCI_DEVICE_STATUS, status); |
|
|
|
qpci_io_writeb(dev->pdev, dev->addr + VIRTIO_PCI_STATUS, status); |
|
|
|
} |
|
|
|
|
|
|
|
static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq) |
|
|
|
@ -151,7 +152,7 @@ static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq) |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_PCI_ISR_STATUS) & 1; |
|
|
|
return qpci_io_readb(dev->pdev, dev->addr + VIRTIO_PCI_ISR) & 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -175,26 +176,26 @@ static bool qvirtio_pci_get_config_isr_status(QVirtioDevice *d) |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_PCI_ISR_STATUS) & 2; |
|
|
|
return qpci_io_readb(dev->pdev, dev->addr + VIRTIO_PCI_ISR) & 2; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void qvirtio_pci_queue_select(QVirtioDevice *d, uint16_t index) |
|
|
|
{ |
|
|
|
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d; |
|
|
|
qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_SELECT, index); |
|
|
|
qpci_io_writeb(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_SEL, index); |
|
|
|
} |
|
|
|
|
|
|
|
static uint16_t qvirtio_pci_get_queue_size(QVirtioDevice *d) |
|
|
|
{ |
|
|
|
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d; |
|
|
|
return qpci_io_readw(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_SIZE); |
|
|
|
return qpci_io_readw(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_NUM); |
|
|
|
} |
|
|
|
|
|
|
|
static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn) |
|
|
|
{ |
|
|
|
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d; |
|
|
|
qpci_io_writel(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_ADDRESS, pfn); |
|
|
|
qpci_io_writel(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_PFN, pfn); |
|
|
|
} |
|
|
|
|
|
|
|
static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d, |
|
|
|
@ -212,7 +213,7 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d, |
|
|
|
vqpci->vq.size = qvirtio_pci_get_queue_size(d); |
|
|
|
vqpci->vq.free_head = 0; |
|
|
|
vqpci->vq.num_free = vqpci->vq.size; |
|
|
|
vqpci->vq.align = QVIRTIO_PCI_ALIGN; |
|
|
|
vqpci->vq.align = VIRTIO_PCI_VRING_ALIGN; |
|
|
|
vqpci->vq.indirect = (feat & (1u << VIRTIO_RING_F_INDIRECT_DESC)) != 0; |
|
|
|
vqpci->vq.event = (feat & (1u << VIRTIO_RING_F_EVENT_IDX)) != 0; |
|
|
|
|
|
|
|
@ -226,9 +227,10 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d, |
|
|
|
/* Check power of 2 */ |
|
|
|
g_assert_cmpint(vqpci->vq.size & (vqpci->vq.size - 1), ==, 0); |
|
|
|
|
|
|
|
addr = guest_alloc(alloc, qvring_size(vqpci->vq.size, QVIRTIO_PCI_ALIGN)); |
|
|
|
addr = guest_alloc(alloc, qvring_size(vqpci->vq.size, |
|
|
|
VIRTIO_PCI_VRING_ALIGN)); |
|
|
|
qvring_init(alloc, &vqpci->vq, addr); |
|
|
|
qvirtio_pci_set_queue_address(d, vqpci->vq.desc / QVIRTIO_PCI_ALIGN); |
|
|
|
qvirtio_pci_set_queue_address(d, vqpci->vq.desc / VIRTIO_PCI_VRING_ALIGN); |
|
|
|
|
|
|
|
return &vqpci->vq; |
|
|
|
} |
|
|
|
@ -236,7 +238,7 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d, |
|
|
|
static void qvirtio_pci_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq) |
|
|
|
{ |
|
|
|
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d; |
|
|
|
qpci_io_writew(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_NOTIFY, vq->index); |
|
|
|
qpci_io_writew(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_NOTIFY, vq->index); |
|
|
|
} |
|
|
|
|
|
|
|
const QVirtioBus qvirtio_pci = { |
|
|
|
@ -316,9 +318,9 @@ void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci, |
|
|
|
control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT); |
|
|
|
|
|
|
|
qvirtio_pci_queue_select(&d->vdev, vqpci->vq.index); |
|
|
|
qpci_io_writew(d->pdev, d->addr + QVIRTIO_PCI_MSIX_QUEUE_VECTOR, entry); |
|
|
|
vector = qpci_io_readw(d->pdev, d->addr + QVIRTIO_PCI_MSIX_QUEUE_VECTOR); |
|
|
|
g_assert_cmphex(vector, !=, QVIRTIO_MSI_NO_VECTOR); |
|
|
|
qpci_io_writew(d->pdev, d->addr + VIRTIO_MSI_QUEUE_VECTOR, entry); |
|
|
|
vector = qpci_io_readw(d->pdev, d->addr + VIRTIO_MSI_QUEUE_VECTOR); |
|
|
|
g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR); |
|
|
|
} |
|
|
|
|
|
|
|
void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d, |
|
|
|
@ -348,7 +350,7 @@ void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d, |
|
|
|
qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL, |
|
|
|
control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT); |
|
|
|
|
|
|
|
qpci_io_writew(d->pdev, d->addr + QVIRTIO_PCI_MSIX_CONF_VECTOR, entry); |
|
|
|
vector = qpci_io_readw(d->pdev, d->addr + QVIRTIO_PCI_MSIX_CONF_VECTOR); |
|
|
|
g_assert_cmphex(vector, !=, QVIRTIO_MSI_NO_VECTOR); |
|
|
|
qpci_io_writew(d->pdev, d->addr + VIRTIO_MSI_CONFIG_VECTOR, entry); |
|
|
|
vector = qpci_io_readw(d->pdev, d->addr + VIRTIO_MSI_CONFIG_VECTOR); |
|
|
|
g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR); |
|
|
|
} |
|
|
|
|