From 6188bfb86c5520a1e85f7a1b4f0e445851aaf30d Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Sun, 9 Jul 2017 08:30:08 +0100 Subject: [PATCH] pcimin --- kernel_module/pci_min.c | 96 +++++++++++++++++++++++++++++++++++++++++ qemu | 2 +- 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 kernel_module/pci_min.c diff --git a/kernel_module/pci_min.c b/kernel_module/pci_min.c new file mode 100644 index 0000000..54481a7 --- /dev/null +++ b/kernel_module/pci_min.c @@ -0,0 +1,96 @@ +/* +Only tested in x86. + +PCI driver for our minimal pci_min.c QEMU fork device. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BAR 0 +#define CDEV_NAME "lkmc_hw_pci_min" +#define EDU_DEVICE_ID 0x11e9 +#define QEMU_VENDOR_ID 0x1234 + +MODULE_LICENSE("GPL"); + +static struct pci_device_id id_table[] = { + { PCI_DEVICE(QEMU_VENDOR_ID, EDU_DEVICE_ID), }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, id_table); +static int major; +static struct pci_dev *pdev; +static void __iomem *mmio; +static struct file_operations fops = { + .owner = THIS_MODULE, +}; + +static irqreturn_t irq_handler(int irq, void *dev) +{ + pr_info("irq_handler irq = %d dev = %d\n", irq, *(int *)dev); + iowrite32(0, mmio + 4); + return IRQ_HANDLED; +} + +static int probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + pr_info("probe\n"); + major = register_chrdev(0, CDEV_NAME, &fops); + pdev = dev; + if (pci_enable_device(dev) < 0) { + dev_err(&(pdev->dev), "pci_enable_device\n"); + goto error; + } + if (pci_request_region(dev, BAR, "myregion0")) { + dev_err(&(pdev->dev), "pci_request_region\n"); + goto error; + } + mmio = pci_iomap(pdev, BAR, pci_resource_len(pdev, BAR)); + pr_info("dev->irq = %u\n", dev->irq); + if (request_irq(dev->irq, irq_handler, IRQF_SHARED, "pci_irq_handler0", &major) < 0) { + dev_err(&(dev->dev), "request_irq\n"); + goto error; + } + iowrite32(0x12345678, mmio); + return 0; +error: + return 1; +} + +static void remove(struct pci_dev *dev) +{ + pr_info("remove\n"); + free_irq(dev->irq, &major); + pci_release_region(dev, BAR); + unregister_chrdev(major, CDEV_NAME); +} + +static struct pci_driver pci_driver = { + .name = CDEV_NAME, + .id_table = id_table, + .probe = probe, + .remove = remove, +}; + +static int myinit(void) +{ + if (pci_register_driver(&pci_driver) < 0) { + return 1; + } + return 0; +} + +static void myexit(void) +{ + pci_unregister_driver(&pci_driver); +} + +module_init(myinit); +module_exit(myexit); diff --git a/qemu b/qemu index 144ea94..577f463 160000 --- a/qemu +++ b/qemu @@ -1 +1 @@ -Subproject commit 144ea94d710c666babd06ed733007377e132ed4a +Subproject commit 577f4633f156c263aae9855c2f06328831e05ccd