|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH RFC 12/23] plat/virtio_mmio: Implement platform probe for virtio_mmio
This implements the probe interface for virtio_mmio device upon platform
bus.
Signed-off-by: Jia He <justin.he@xxxxxxx>
---
plat/drivers/virtio/virtio_mmio.c | 98 ++++++++++++++++++++++++++-----
1 file changed, 84 insertions(+), 14 deletions(-)
diff --git a/plat/drivers/virtio/virtio_mmio.c
b/plat/drivers/virtio/virtio_mmio.c
index 3b9a940c..a15d148b 100644
--- a/plat/drivers/virtio/virtio_mmio.c
+++ b/plat/drivers/virtio/virtio_mmio.c
@@ -42,6 +42,9 @@
#include <uk/plat/irq.h>
#include <uk/bus.h>
#include <uk/bitops.h>
+#include <libfdt.h>
+#include <ofw/fdt.h>
+#include <kvm/config.h>
#include <platform_bus.h>
#include <virtio/virtio_config.h>
@@ -406,6 +409,48 @@ static const struct virtio_config_ops
virtio_mmio_config_ops = {
.vq_setup = vm_setup_vq,
};
+static int virtio_mmio_probe(struct pf_device *pfdev)
+{
+ const fdt32_t *prop;
+ int type, hwirq, prop_len;
+ int fdt_vm = pfdev->fdt_offset;
+ __u64 reg_base;
+ __u64 reg_size;
+
+ if (fdt_vm == -FDT_ERR_NOTFOUND) {
+ uk_pr_info("device not found in fdt\n");
+ goto error_exit;
+ } else {
+ prop = fdt_getprop(_libkvmplat_cfg.dtb, fdt_vm, "interrupts",
&prop_len);
+ if (!prop) {
+ uk_pr_err("irq of device not found in fdt\n");
+ goto error_exit;
+ }
+
+ type = fdt32_to_cpu(prop[0]);
+ hwirq = fdt32_to_cpu(prop[1]);
+
+ prop = fdt_getprop(_libkvmplat_cfg.dtb, fdt_vm, "reg",
&prop_len);
+ if (!prop) {
+ uk_pr_err("reg of device not found in fdt\n");
+ goto error_exit;
+ }
+
+ /* only care about base addr, ignore the size */
+ fdt_get_address(_libkvmplat_cfg.dtb, fdt_vm, 0,
+ ®_base, ®_size);
+ }
+
+ pfdev->base = reg_base;
+ pfdev->irq = gic_irq_translate(type, hwirq);
+ uk_pr_info("virtio mmio probe base(0x%llx) irq(%d)\n",
+ pfdev->base, pfdev->irq);
+ return 0;
+
+error_exit:
+ return -EFAULT;
+}
+
static int virtio_mmio_add_dev(struct pf_device *pfdev)
{
struct virtio_mmio_device *vm_dev;
@@ -418,7 +463,8 @@ static int virtio_mmio_add_dev(struct pf_device *pfdev)
vm_dev = uk_malloc(a, sizeof(*vm_dev));
if (!vm_dev) {
uk_pr_err("Failed to allocate virtio-pci device\n");
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto free_vmdev;
}
/* Fetch Pf Device information */
@@ -427,20 +473,24 @@ static int virtio_mmio_add_dev(struct pf_device *pfdev)
vm_dev->vdev.cops = &virtio_mmio_config_ops;
vm_dev->name = "virtio_mmio";
- if (vm_dev->base == NULL)
- return -EFAULT;
+ if (vm_dev->base == NULL) {
+ rc = -EFAULT;
+ goto free_vmdev;
+ }
magic = virtio_cread32(vm_dev->base, VIRTIO_MMIO_MAGIC_VALUE);
if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) {
uk_pr_err("Wrong magic value 0x%x!\n", magic);
- return -ENODEV;
+ rc = -ENODEV;
+ goto free_vmdev;
}
/* Check device version */
vm_dev->version = virtio_cread32(vm_dev->base, VIRTIO_MMIO_VERSION);
if (vm_dev->version < 1 || vm_dev->version > 2) {
uk_pr_err("Version %ld not supported!\n", vm_dev->version);
- return -ENXIO;
+ rc = -ENXIO;
+ goto free_vmdev;
}
vm_dev->vdev.id.virtio_device_id = virtio_cread32(vm_dev->base,
VIRTIO_MMIO_DEVICE_ID);
@@ -451,7 +501,8 @@ static int virtio_mmio_add_dev(struct pf_device *pfdev)
*/
uk_pr_err("virtio_device_id is 0\n");
- return -ENODEV;
+ rc = -ENODEV;
+ goto free_vmdev;
}
vm_dev->id.vendor = virtio_cread32(vm_dev->base, VIRTIO_MMIO_VENDOR_ID);
@@ -460,17 +511,15 @@ static int virtio_mmio_add_dev(struct pf_device *pfdev)
rc = virtio_bus_register_device(&vm_dev->vdev);
if (rc != 0) {
uk_pr_err("Failed to register the virtio device: %d\n", rc);
- goto free_pf_dev;
+ goto free_vmdev;
}
- uk_pr_info("finish add a virtio mmio dev\n");
-
- return rc;
-
-free_pf_dev:
- uk_free(a, vm_dev);
+ uk_pr_info("finish probing a virtio mmio dev\n");
return 0;
+
+free_vmdev:
+ return rc;
}
static int virtio_mmio_drv_init(struct uk_alloc *drv_allocator)
@@ -484,6 +533,19 @@ static int virtio_mmio_drv_init(struct uk_alloc
*drv_allocator)
return 0;
}
+static const struct device_match_table virtio_mmio_match_table[];
+
+static struct pf_device_id* virtio_mmio_id_match_compatible(const char
*compatible)
+{
+ int i;
+
+ for (int i = 0; virtio_mmio_match_table[i].compatible != NULL; i++)
+ if (strcmp(virtio_mmio_match_table[i].compatible, compatible)
== 0)
+ return virtio_mmio_match_table[i].id;
+
+ return NULL;
+}
+
static const struct pf_device_id virtio_mmio_ids = {
.device_id = VIRTIO_MMIO_ID
};
@@ -491,7 +553,15 @@ static const struct pf_device_id virtio_mmio_ids = {
static struct pf_driver virtio_mmio_drv = {
.device_ids = &virtio_mmio_ids,
.init = virtio_mmio_drv_init,
- .add_dev = virtio_mmio_add_dev
+ .probe = virtio_mmio_probe,
+ .add_dev = virtio_mmio_add_dev,
+ .match = virtio_mmio_id_match_compatible
+};
+
+static const struct device_match_table virtio_mmio_match_table[] = {
+ { .compatible = "virtio,mmio",
+ .id = &virtio_mmio_ids },
+ {NULL}
};
PF_REGISTER_DRIVER(&virtio_mmio_drv);
--
2.17.1
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |