kvm: Extract virtio-blk driver to separate file

This patch extracts virtio-blk driver to a separate file.

Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
Pekka Enberg
2015-06-01 16:39:40 +01:00
committed by Will Deacon
parent ba8246776e
commit b30d05ad0a
6 changed files with 77 additions and 35 deletions
+1
View File
@@ -9,6 +9,7 @@ export E Q
PROGRAM = kvm
OBJS += blk-virtio.o
OBJS += cpuid.o
OBJS += early_printk.o
OBJS += interrupt.o
+42
View File
@@ -0,0 +1,42 @@
#include "kvm/blk-virtio.h"
#include "kvm/ioport.h"
#include "kvm/pci.h"
#define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4
#define PCI_DEVICE_ID_VIRTIO_BLK 0x1001
#define PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET 0x1af4
#define PCI_SUBSYSTEM_ID_VIRTIO_BLK 0x0002
static struct pci_device_header virtio_device = {
.vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
.device_id = PCI_DEVICE_ID_VIRTIO_BLK,
.header_type = PCI_HEADER_TYPE_NORMAL,
.revision_id = 0,
.class = 0x010000,
.subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
.subsys_id = PCI_SUBSYSTEM_ID_VIRTIO_BLK,
.bar[0] = IOPORT_VIRTIO | PCI_BASE_ADDRESS_SPACE_IO,
};
static bool virtio_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
{
return true;
}
static bool virtio_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
{
return true;
}
static struct ioport_operations virtio_io_ops = {
.io_in = virtio_in,
.io_out = virtio_out,
};
void blk_virtio__init(void)
{
pci__register(&virtio_device, 1);
ioport__register(IOPORT_VIRTIO, &virtio_io_ops);
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef KVM__BLK_VIRTIO_H
#define KVM__BLK_VIRTIO_H
void blk_virtio__init(void);
#endif /* KVM__BLK_VIRTIO_H */
+1
View File
@@ -50,5 +50,6 @@ struct pci_device_header {
};
void pci__init(void);
void pci__register(struct pci_device_header *dev, uint8_t dev_num);
#endif /* KVM__PCI_H */
+2
View File
@@ -1,6 +1,7 @@
#include "kvm/kvm.h"
#include "kvm/early_printk.h"
#include "kvm/blk-virtio.h"
#include "kvm/util.h"
#include "kvm/pci.h"
@@ -116,6 +117,7 @@ int main(int argc, char *argv[])
early_printk__init();
pci__init();
blk_virtio__init();
for (;;) {
kvm__run(kvm);
+25 -35
View File
@@ -2,9 +2,14 @@
#include "kvm/ioport.h"
#include "kvm/util.h"
#include <assert.h>
#include <stdint.h>
static struct pci_config_address pci_config_address;
#define PCI_MAX_DEVICES 256
static struct pci_device_header *pci_devices[PCI_MAX_DEVICES];
static struct pci_config_address pci_config_address;
static void *pci_config_address_ptr(uint16_t port)
{
@@ -45,36 +50,28 @@ static bool pci_config_data_out(struct kvm *self, uint16_t port, void *data, int
return true;
}
#define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4
#define PCI_DEVICE_ID_VIRTIO_BLK 0x1001
#define PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET 0x1af4
#define PCI_SUBSYSTEM_ID_VIRTIO_BLK 0x0002
static struct pci_device_header virtio_device = {
.vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
.device_id = PCI_DEVICE_ID_VIRTIO_BLK,
.header_type = PCI_HEADER_TYPE_NORMAL,
.revision_id = 0,
.class = 0x010000,
.subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
.subsys_id = PCI_SUBSYSTEM_ID_VIRTIO_BLK,
.bar[0] = IOPORT_VIRTIO | PCI_BASE_ADDRESS_SPACE_IO,
};
static bool pci_device_matches(uint8_t bus_number, uint8_t device_number, uint8_t function_number)
static bool pci_device_exists(uint8_t bus_number, uint8_t device_number, uint8_t function_number)
{
struct pci_device_header *dev;
if (pci_config_address.bus_number != bus_number)
return false;
if (pci_config_address.device_number != device_number)
if (pci_config_address.function_number != function_number)
return false;
return pci_config_address.function_number == function_number;
if (device_number >= PCI_MAX_DEVICES)
return false;
dev = pci_devices[device_number];
return dev != NULL;
}
static bool pci_config_data_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
{
unsigned long start;
uint8_t dev_num;
/*
* If someone accesses PCI configuration space offsets that are not
@@ -82,12 +79,15 @@ static bool pci_config_data_in(struct kvm *self, uint16_t port, void *data, int
*/
start = port - PCI_CONFIG_DATA;
if (pci_device_matches(0, 1, 0)) {
dev_num = pci_config_address.device_number;
if (pci_device_exists(0, dev_num, 0)) {
unsigned long offset;
offset = start + (pci_config_address.register_number << 2);
if (offset < sizeof(struct pci_device_header)) {
void *p = &virtio_device;
void *p = pci_devices[dev_num];
memcpy(data, p + offset, size);
} else
memset(data, 0x00, size);
@@ -102,25 +102,15 @@ static struct ioport_operations pci_config_data_ops = {
.io_out = pci_config_data_out,
};
static bool virtio_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
void pci__register(struct pci_device_header *dev, uint8_t dev_num)
{
return true;
}
assert(dev_num < PCI_MAX_DEVICES);
static bool virtio_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
{
return true;
pci_devices[dev_num] = dev;
}
static struct ioport_operations virtio_io_ops = {
.io_in = virtio_in,
.io_out = virtio_out,
};
void pci__init(void)
{
ioport__register(IOPORT_VIRTIO, &virtio_io_ops);
ioport__register(PCI_CONFIG_DATA + 0, &pci_config_data_ops);
ioport__register(PCI_CONFIG_DATA + 1, &pci_config_data_ops);
ioport__register(PCI_CONFIG_DATA + 2, &pci_config_data_ops);