qemu/virtio: virtio support for many interrupt vectors
Extend virtio to support many interrupt vectors, and rearrange code in preparation for multi-vector support (mostly move reset out to bindings, because we will have to reset the vectors in transport-specific code). Actual bindings in pci, and use in net, to follow. Load and save are not connected to bindings yet, so they are left stubbed out for now. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
54c96da798
commit
7055e687cd
|
@ -134,6 +134,9 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset,
|
||||||
vdev->features = value;
|
vdev->features = value;
|
||||||
break;
|
break;
|
||||||
case SYBORG_VIRTIO_QUEUE_BASE:
|
case SYBORG_VIRTIO_QUEUE_BASE:
|
||||||
|
if (value == 0)
|
||||||
|
virtio_reset(vdev);
|
||||||
|
else
|
||||||
virtio_queue_set_addr(vdev, vdev->queue_sel, value);
|
virtio_queue_set_addr(vdev, vdev->queue_sel, value);
|
||||||
break;
|
break;
|
||||||
case SYBORG_VIRTIO_QUEUE_SEL:
|
case SYBORG_VIRTIO_QUEUE_SEL:
|
||||||
|
@ -228,7 +231,7 @@ static CPUWriteMemoryFunc *syborg_virtio_writefn[] = {
|
||||||
syborg_virtio_writel
|
syborg_virtio_writel
|
||||||
};
|
};
|
||||||
|
|
||||||
static void syborg_virtio_update_irq(void *opaque)
|
static void syborg_virtio_update_irq(void *opaque, uint16_t vector)
|
||||||
{
|
{
|
||||||
SyborgVirtIOProxy *proxy = opaque;
|
SyborgVirtIOProxy *proxy = opaque;
|
||||||
int level;
|
int level;
|
||||||
|
@ -239,7 +242,7 @@ static void syborg_virtio_update_irq(void *opaque)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VirtIOBindings syborg_virtio_bindings = {
|
static VirtIOBindings syborg_virtio_bindings = {
|
||||||
.update_irq = syborg_virtio_update_irq
|
.notify = syborg_virtio_update_irq
|
||||||
};
|
};
|
||||||
|
|
||||||
static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
|
static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
|
||||||
|
@ -248,6 +251,8 @@ static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
|
||||||
|
|
||||||
proxy->vdev = vdev;
|
proxy->vdev = vdev;
|
||||||
|
|
||||||
|
/* Don't support multiple vectors */
|
||||||
|
proxy->vdev->nvectors = 0;
|
||||||
sysbus_init_irq(&proxy->busdev, &proxy->irq);
|
sysbus_init_irq(&proxy->busdev, &proxy->irq);
|
||||||
iomemtype = cpu_register_io_memory(syborg_virtio_readfn,
|
iomemtype = cpu_register_io_memory(syborg_virtio_readfn,
|
||||||
syborg_virtio_writefn, proxy);
|
syborg_virtio_writefn, proxy);
|
||||||
|
@ -255,6 +260,8 @@ static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
|
||||||
|
|
||||||
proxy->id = ((uint32_t)0x1af4 << 16) | vdev->device_id;
|
proxy->id = ((uint32_t)0x1af4 << 16) | vdev->device_id;
|
||||||
|
|
||||||
|
qemu_register_reset(virtio_reset, 0, vdev);
|
||||||
|
|
||||||
virtio_bind_device(vdev, &syborg_virtio_bindings, proxy);
|
virtio_bind_device(vdev, &syborg_virtio_bindings, proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,13 +78,19 @@ typedef struct {
|
||||||
|
|
||||||
/* virtio device */
|
/* virtio device */
|
||||||
|
|
||||||
static void virtio_pci_update_irq(void *opaque)
|
static void virtio_pci_notify(void *opaque, uint16_t vector)
|
||||||
{
|
{
|
||||||
VirtIOPCIProxy *proxy = opaque;
|
VirtIOPCIProxy *proxy = opaque;
|
||||||
|
|
||||||
qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
|
qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_pci_reset(void *opaque)
|
||||||
|
{
|
||||||
|
VirtIOPCIProxy *proxy = opaque;
|
||||||
|
virtio_reset(proxy->vdev);
|
||||||
|
}
|
||||||
|
|
||||||
static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
VirtIOPCIProxy *proxy = opaque;
|
VirtIOPCIProxy *proxy = opaque;
|
||||||
|
@ -108,6 +114,9 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
break;
|
break;
|
||||||
case VIRTIO_PCI_QUEUE_PFN:
|
case VIRTIO_PCI_QUEUE_PFN:
|
||||||
pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
|
pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
|
||||||
|
if (pa == 0)
|
||||||
|
virtio_pci_reset(proxy);
|
||||||
|
else
|
||||||
virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
|
virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
|
||||||
break;
|
break;
|
||||||
case VIRTIO_PCI_QUEUE_SEL:
|
case VIRTIO_PCI_QUEUE_SEL:
|
||||||
|
@ -120,7 +129,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
case VIRTIO_PCI_STATUS:
|
case VIRTIO_PCI_STATUS:
|
||||||
vdev->status = val & 0xFF;
|
vdev->status = val & 0xFF;
|
||||||
if (vdev->status == 0)
|
if (vdev->status == 0)
|
||||||
virtio_reset(vdev);
|
virtio_pci_reset(proxy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +169,7 @@ static uint32_t virtio_ioport_read(void *opaque, uint32_t addr)
|
||||||
/* reading from the ISR also clears it. */
|
/* reading from the ISR also clears it. */
|
||||||
ret = vdev->isr;
|
ret = vdev->isr;
|
||||||
vdev->isr = 0;
|
vdev->isr = 0;
|
||||||
virtio_update_irq(vdev);
|
qemu_set_irq(proxy->pci_dev.irq[0], 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -245,7 +254,7 @@ static void virtio_map(PCIDevice *pci_dev, int region_num,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const VirtIOBindings virtio_pci_bindings = {
|
static const VirtIOBindings virtio_pci_bindings = {
|
||||||
.update_irq = virtio_pci_update_irq
|
.notify = virtio_pci_notify
|
||||||
};
|
};
|
||||||
|
|
||||||
static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
|
static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
|
||||||
|
@ -257,6 +266,9 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
|
||||||
|
|
||||||
proxy->vdev = vdev;
|
proxy->vdev = vdev;
|
||||||
|
|
||||||
|
/* No support for multiple vectors yet. */
|
||||||
|
proxy->vdev->nvectors = 0;
|
||||||
|
|
||||||
config = proxy->pci_dev.config;
|
config = proxy->pci_dev.config;
|
||||||
pci_config_set_vendor_id(config, vendor);
|
pci_config_set_vendor_id(config, vendor);
|
||||||
pci_config_set_device_id(config, device);
|
pci_config_set_device_id(config, device);
|
||||||
|
@ -281,6 +293,8 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
|
||||||
pci_register_bar(&proxy->pci_dev, 0, size, PCI_ADDRESS_SPACE_IO,
|
pci_register_bar(&proxy->pci_dev, 0, size, PCI_ADDRESS_SPACE_IO,
|
||||||
virtio_map);
|
virtio_map);
|
||||||
|
|
||||||
|
qemu_register_reset(virtio_pci_reset, 0, proxy);
|
||||||
|
|
||||||
virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
|
virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
55
hw/virtio.c
55
hw/virtio.c
|
@ -68,6 +68,7 @@ struct VirtQueue
|
||||||
target_phys_addr_t pa;
|
target_phys_addr_t pa;
|
||||||
uint16_t last_avail_idx;
|
uint16_t last_avail_idx;
|
||||||
int inuse;
|
int inuse;
|
||||||
|
uint16_t vector;
|
||||||
void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
|
void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -421,12 +422,16 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtio device */
|
/* virtio device */
|
||||||
|
static void virtio_notify_vector(VirtIODevice *vdev, uint16_t vector)
|
||||||
|
{
|
||||||
|
if (vdev->binding->notify) {
|
||||||
|
vdev->binding->notify(vdev->binding_opaque, vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void virtio_update_irq(VirtIODevice *vdev)
|
void virtio_update_irq(VirtIODevice *vdev)
|
||||||
{
|
{
|
||||||
if (vdev->binding->update_irq) {
|
virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
|
||||||
vdev->binding->update_irq(vdev->binding_opaque);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_reset(void *opaque)
|
void virtio_reset(void *opaque)
|
||||||
|
@ -441,7 +446,8 @@ void virtio_reset(void *opaque)
|
||||||
vdev->queue_sel = 0;
|
vdev->queue_sel = 0;
|
||||||
vdev->status = 0;
|
vdev->status = 0;
|
||||||
vdev->isr = 0;
|
vdev->isr = 0;
|
||||||
virtio_update_irq(vdev);
|
vdev->config_vector = VIRTIO_NO_VECTOR;
|
||||||
|
virtio_notify_vector(vdev, vdev->config_vector);
|
||||||
|
|
||||||
for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
|
for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
|
||||||
vdev->vq[i].vring.desc = 0;
|
vdev->vq[i].vring.desc = 0;
|
||||||
|
@ -449,6 +455,7 @@ void virtio_reset(void *opaque)
|
||||||
vdev->vq[i].vring.used = 0;
|
vdev->vq[i].vring.used = 0;
|
||||||
vdev->vq[i].last_avail_idx = 0;
|
vdev->vq[i].last_avail_idx = 0;
|
||||||
vdev->vq[i].pa = 0;
|
vdev->vq[i].pa = 0;
|
||||||
|
vdev->vq[i].vector = VIRTIO_NO_VECTOR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,12 +539,8 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
|
||||||
|
|
||||||
void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr)
|
void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr)
|
||||||
{
|
{
|
||||||
if (addr == 0) {
|
|
||||||
virtio_reset(vdev);
|
|
||||||
} else {
|
|
||||||
vdev->vq[n].pa = addr;
|
vdev->vq[n].pa = addr;
|
||||||
virtqueue_init(&vdev->vq[n]);
|
virtqueue_init(&vdev->vq[n]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n)
|
target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n)
|
||||||
|
@ -557,6 +560,18 @@ void virtio_queue_notify(VirtIODevice *vdev, int n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t virtio_queue_vector(VirtIODevice *vdev, int n)
|
||||||
|
{
|
||||||
|
return n < VIRTIO_PCI_QUEUE_MAX ? vdev->vq[n].vector :
|
||||||
|
VIRTIO_NO_VECTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector)
|
||||||
|
{
|
||||||
|
if (n < VIRTIO_PCI_QUEUE_MAX)
|
||||||
|
vdev->vq[n].vector = vector;
|
||||||
|
}
|
||||||
|
|
||||||
VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
|
VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
|
||||||
void (*handle_output)(VirtIODevice *, VirtQueue *))
|
void (*handle_output)(VirtIODevice *, VirtQueue *))
|
||||||
{
|
{
|
||||||
|
@ -585,7 +600,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vdev->isr |= 0x01;
|
vdev->isr |= 0x01;
|
||||||
virtio_update_irq(vdev);
|
virtio_notify_vector(vdev, vq->vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_notify_config(VirtIODevice *vdev)
|
void virtio_notify_config(VirtIODevice *vdev)
|
||||||
|
@ -594,7 +609,7 @@ void virtio_notify_config(VirtIODevice *vdev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vdev->isr |= 0x03;
|
vdev->isr |= 0x03;
|
||||||
virtio_update_irq(vdev);
|
virtio_notify_vector(vdev, vdev->config_vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_save(VirtIODevice *vdev, QEMUFile *f)
|
void virtio_save(VirtIODevice *vdev, QEMUFile *f)
|
||||||
|
@ -603,6 +618,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
|
||||||
|
|
||||||
/* FIXME: load/save binding. */
|
/* FIXME: load/save binding. */
|
||||||
//pci_device_save(&vdev->pci_dev, f);
|
//pci_device_save(&vdev->pci_dev, f);
|
||||||
|
//msix_save(&vdev->pci_dev, f);
|
||||||
|
|
||||||
qemu_put_8s(f, &vdev->status);
|
qemu_put_8s(f, &vdev->status);
|
||||||
qemu_put_8s(f, &vdev->isr);
|
qemu_put_8s(f, &vdev->isr);
|
||||||
|
@ -611,6 +627,9 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
|
||||||
qemu_put_be32(f, vdev->config_len);
|
qemu_put_be32(f, vdev->config_len);
|
||||||
qemu_put_buffer(f, vdev->config, vdev->config_len);
|
qemu_put_buffer(f, vdev->config, vdev->config_len);
|
||||||
|
|
||||||
|
if (vdev->nvectors)
|
||||||
|
qemu_put_be16s(f, &vdev->config_vector);
|
||||||
|
|
||||||
for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
|
for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
|
||||||
if (vdev->vq[i].vring.num == 0)
|
if (vdev->vq[i].vring.num == 0)
|
||||||
break;
|
break;
|
||||||
|
@ -625,6 +644,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
|
||||||
qemu_put_be32(f, vdev->vq[i].vring.num);
|
qemu_put_be32(f, vdev->vq[i].vring.num);
|
||||||
qemu_put_be64(f, vdev->vq[i].pa);
|
qemu_put_be64(f, vdev->vq[i].pa);
|
||||||
qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
|
qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
|
||||||
|
if (vdev->nvectors)
|
||||||
|
qemu_put_be16s(f, &vdev->vq[i].vector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,6 +655,7 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
||||||
|
|
||||||
/* FIXME: load/save binding. */
|
/* FIXME: load/save binding. */
|
||||||
//pci_device_load(&vdev->pci_dev, f);
|
//pci_device_load(&vdev->pci_dev, f);
|
||||||
|
//r = msix_load(&vdev->pci_dev, f);
|
||||||
|
|
||||||
qemu_get_8s(f, &vdev->status);
|
qemu_get_8s(f, &vdev->status);
|
||||||
qemu_get_8s(f, &vdev->isr);
|
qemu_get_8s(f, &vdev->isr);
|
||||||
|
@ -642,6 +664,10 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
||||||
vdev->config_len = qemu_get_be32(f);
|
vdev->config_len = qemu_get_be32(f);
|
||||||
qemu_get_buffer(f, vdev->config, vdev->config_len);
|
qemu_get_buffer(f, vdev->config, vdev->config_len);
|
||||||
|
|
||||||
|
if (vdev->nvectors) {
|
||||||
|
qemu_get_be16s(f, &vdev->config_vector);
|
||||||
|
//msix_vector_use(&vdev->pci_dev, vdev->config_vector);
|
||||||
|
}
|
||||||
num = qemu_get_be32(f);
|
num = qemu_get_be32(f);
|
||||||
|
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
|
@ -652,9 +678,13 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
||||||
if (vdev->vq[i].pa) {
|
if (vdev->vq[i].pa) {
|
||||||
virtqueue_init(&vdev->vq[i]);
|
virtqueue_init(&vdev->vq[i]);
|
||||||
}
|
}
|
||||||
|
if (vdev->nvectors) {
|
||||||
|
qemu_get_be16s(f, &vdev->vq[i].vector);
|
||||||
|
//msix_vector_use(&vdev->pci_dev, vdev->config_vector);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtio_update_irq(vdev);
|
virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_cleanup(VirtIODevice *vdev)
|
void virtio_cleanup(VirtIODevice *vdev)
|
||||||
|
@ -675,6 +705,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
|
||||||
vdev->status = 0;
|
vdev->status = 0;
|
||||||
vdev->isr = 0;
|
vdev->isr = 0;
|
||||||
vdev->queue_sel = 0;
|
vdev->queue_sel = 0;
|
||||||
|
vdev->config_vector = VIRTIO_NO_VECTOR;
|
||||||
vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
|
vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
|
||||||
|
|
||||||
vdev->name = name;
|
vdev->name = name;
|
||||||
|
@ -684,8 +715,6 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
|
||||||
else
|
else
|
||||||
vdev->config = NULL;
|
vdev->config = NULL;
|
||||||
|
|
||||||
qemu_register_reset(virtio_reset, 0, vdev);
|
|
||||||
|
|
||||||
return vdev;
|
return vdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
hw/virtio.h
10
hw/virtio.h
|
@ -75,11 +75,13 @@ typedef struct VirtQueueElement
|
||||||
} VirtQueueElement;
|
} VirtQueueElement;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void (*update_irq)(void * opaque);
|
void (*notify)(void * opaque, uint16_t vector);
|
||||||
} VirtIOBindings;
|
} VirtIOBindings;
|
||||||
|
|
||||||
#define VIRTIO_PCI_QUEUE_MAX 16
|
#define VIRTIO_PCI_QUEUE_MAX 16
|
||||||
|
|
||||||
|
#define VIRTIO_NO_VECTOR 0xffff
|
||||||
|
|
||||||
struct VirtIODevice
|
struct VirtIODevice
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -89,6 +91,8 @@ struct VirtIODevice
|
||||||
uint32_t features;
|
uint32_t features;
|
||||||
size_t config_len;
|
size_t config_len;
|
||||||
void *config;
|
void *config;
|
||||||
|
uint16_t config_vector;
|
||||||
|
int nvectors;
|
||||||
uint32_t (*get_features)(VirtIODevice *vdev);
|
uint32_t (*get_features)(VirtIODevice *vdev);
|
||||||
uint32_t (*bad_features)(VirtIODevice *vdev);
|
uint32_t (*bad_features)(VirtIODevice *vdev);
|
||||||
void (*set_features)(VirtIODevice *vdev, uint32_t val);
|
void (*set_features)(VirtIODevice *vdev, uint32_t val);
|
||||||
|
@ -118,7 +122,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
|
||||||
|
|
||||||
void virtio_save(VirtIODevice *vdev, QEMUFile *f);
|
void virtio_save(VirtIODevice *vdev, QEMUFile *f);
|
||||||
|
|
||||||
void virtio_load(VirtIODevice *vdev, QEMUFile *f);
|
int virtio_load(VirtIODevice *vdev, QEMUFile *f);
|
||||||
|
|
||||||
void virtio_cleanup(VirtIODevice *vdev);
|
void virtio_cleanup(VirtIODevice *vdev);
|
||||||
|
|
||||||
|
@ -144,6 +148,8 @@ void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr);
|
||||||
target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n);
|
target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n);
|
||||||
int virtio_queue_get_num(VirtIODevice *vdev, int n);
|
int virtio_queue_get_num(VirtIODevice *vdev, int n);
|
||||||
void virtio_queue_notify(VirtIODevice *vdev, int n);
|
void virtio_queue_notify(VirtIODevice *vdev, int n);
|
||||||
|
uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
|
||||||
|
void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
|
||||||
void virtio_reset(void *opaque);
|
void virtio_reset(void *opaque);
|
||||||
void virtio_update_irq(VirtIODevice *vdev);
|
void virtio_update_irq(VirtIODevice *vdev);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue