mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-09-04 20:51:28 +00:00
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:
committed by
Will Deacon
parent
ba8246776e
commit
b30d05ad0a
@@ -9,6 +9,7 @@ export E Q
|
||||
|
||||
PROGRAM = kvm
|
||||
|
||||
OBJS += blk-virtio.o
|
||||
OBJS += cpuid.o
|
||||
OBJS += early_printk.o
|
||||
OBJS += interrupt.o
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef KVM__BLK_VIRTIO_H
|
||||
#define KVM__BLK_VIRTIO_H
|
||||
|
||||
void blk_virtio__init(void);
|
||||
|
||||
#endif /* KVM__BLK_VIRTIO_H */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user