From 8d087ecc92ca2a8eb85ec0601ad9b8a3a1ad2d4c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 13 Feb 2020 13:16:05 -0800 Subject: [PATCH 1/2] Consolidate example driver code --- example/ADM_PCIE_9V3/fpga_axi_x8/driver | 1 + example/ExaNIC_X10/fpga_axi/driver | 1 + example/ExaNIC_X10/fpga_axi/driver/Makefile | 11 - .../fpga_axi/driver/example_driver.c | 371 ------------------ .../fpga_axi/driver/example_driver.h | 50 --- example/ExaNIC_X25/fpga_axi/driver | 1 + example/ExaNIC_X25/fpga_axi/driver/Makefile | 11 - .../fpga_axi/driver/example_driver.c | 371 ------------------ .../fpga_axi/driver/example_driver.h | 50 --- example/VCU108/fpga_axi/driver | 1 + example/VCU108/fpga_axi/driver/Makefile | 11 - .../VCU108/fpga_axi/driver/example_driver.c | 371 ------------------ .../VCU108/fpga_axi/driver/example_driver.h | 50 --- example/VCU118/fpga_axi_x8/driver | 1 + example/VCU118/fpga_axi_x8/driver/Makefile | 11 - .../fpga_axi_x8/driver/example_driver.c | 371 ------------------ .../fpga_axi_x8/driver/example_driver.h | 50 --- example/VCU1525/fpga_axi/driver | 1 + example/VCU1525/fpga_axi/driver/Makefile | 11 - .../VCU1525/fpga_axi/driver/example_driver.c | 371 ------------------ .../VCU1525/fpga_axi/driver/example_driver.h | 50 --- .../fpga_axi_x8 => common}/driver/Makefile | 0 .../driver/example_driver.c | 0 .../driver/example_driver.h | 0 24 files changed, 6 insertions(+), 2160 deletions(-) create mode 120000 example/ADM_PCIE_9V3/fpga_axi_x8/driver create mode 120000 example/ExaNIC_X10/fpga_axi/driver delete mode 100644 example/ExaNIC_X10/fpga_axi/driver/Makefile delete mode 100644 example/ExaNIC_X10/fpga_axi/driver/example_driver.c delete mode 100644 example/ExaNIC_X10/fpga_axi/driver/example_driver.h create mode 120000 example/ExaNIC_X25/fpga_axi/driver delete mode 100644 example/ExaNIC_X25/fpga_axi/driver/Makefile delete mode 100644 example/ExaNIC_X25/fpga_axi/driver/example_driver.c delete mode 100644 example/ExaNIC_X25/fpga_axi/driver/example_driver.h create mode 120000 example/VCU108/fpga_axi/driver delete mode 100644 example/VCU108/fpga_axi/driver/Makefile delete mode 100644 example/VCU108/fpga_axi/driver/example_driver.c delete mode 100644 example/VCU108/fpga_axi/driver/example_driver.h create mode 120000 example/VCU118/fpga_axi_x8/driver delete mode 100644 example/VCU118/fpga_axi_x8/driver/Makefile delete mode 100644 example/VCU118/fpga_axi_x8/driver/example_driver.c delete mode 100644 example/VCU118/fpga_axi_x8/driver/example_driver.h create mode 120000 example/VCU1525/fpga_axi/driver delete mode 100644 example/VCU1525/fpga_axi/driver/Makefile delete mode 100644 example/VCU1525/fpga_axi/driver/example_driver.c delete mode 100644 example/VCU1525/fpga_axi/driver/example_driver.h rename example/{ADM_PCIE_9V3/fpga_axi_x8 => common}/driver/Makefile (100%) rename example/{ADM_PCIE_9V3/fpga_axi_x8 => common}/driver/example_driver.c (100%) rename example/{ADM_PCIE_9V3/fpga_axi_x8 => common}/driver/example_driver.h (100%) diff --git a/example/ADM_PCIE_9V3/fpga_axi_x8/driver b/example/ADM_PCIE_9V3/fpga_axi_x8/driver new file mode 120000 index 000000000..f5aacbaaf --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_axi_x8/driver @@ -0,0 +1 @@ +../../common/driver/ \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga_axi/driver b/example/ExaNIC_X10/fpga_axi/driver new file mode 120000 index 000000000..f5aacbaaf --- /dev/null +++ b/example/ExaNIC_X10/fpga_axi/driver @@ -0,0 +1 @@ +../../common/driver/ \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga_axi/driver/Makefile b/example/ExaNIC_X10/fpga_axi/driver/Makefile deleted file mode 100644 index 46f7ba228..000000000 --- a/example/ExaNIC_X10/fpga_axi/driver/Makefile +++ /dev/null @@ -1,11 +0,0 @@ - -# object files to build -obj-m += example.o -example-objs += example_driver.o - -all: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules - -clean: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean - diff --git a/example/ExaNIC_X10/fpga_axi/driver/example_driver.c b/example/ExaNIC_X10/fpga_axi/driver/example_driver.c deleted file mode 100644 index 67d654b32..000000000 --- a/example/ExaNIC_X10/fpga_axi/driver/example_driver.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -#include "example_driver.h" -#include -#include -#include -#include - -MODULE_DESCRIPTION("verilog-pcie example driver"); -MODULE_AUTHOR("Alex Forencich"); -MODULE_LICENSE("Dual MIT/GPL"); -MODULE_VERSION(DRIVER_VERSION); -MODULE_SUPPORTED_DEVICE(DRIVER_NAME); - -static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void edev_remove(struct pci_dev *pdev); -static void edev_shutdown(struct pci_dev *pdev); - -static int enumerate_bars(struct example_dev *edev, struct pci_dev *pdev); -static int map_bars(struct example_dev *edev, struct pci_dev *pdev); -static void free_bars(struct example_dev *edev, struct pci_dev *pdev); - -static const struct pci_device_id pci_ids[] = { - { PCI_DEVICE(0x1234, 0x0001) }, - { 0 /* end */ } -}; - -MODULE_DEVICE_TABLE(pci, pci_ids); - -static irqreturn_t edev_intr(int irq, void *data) -{ - struct example_dev *edev = data; - struct device *dev = &edev->pdev->dev; - - edev->irqcount++; - - dev_info(dev, "Interrupt"); - - return IRQ_HANDLED; -} - -static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int ret = 0; - struct example_dev *edev; - struct device *dev = &pdev->dev; - - int k; - - dev_info(dev, "edev probe"); - dev_info(dev, " vendor: 0x%04x", pdev->vendor); - dev_info(dev, " device: 0x%04x", pdev->device); - dev_info(dev, " class: 0x%06x", pdev->class); - dev_info(dev, " pci id: %02x:%02x.%02x", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); - - if (!(edev = devm_kzalloc(dev, sizeof(struct example_dev), GFP_KERNEL))) { - return -ENOMEM; - } - - edev->pdev = pdev; - pci_set_drvdata(pdev, edev); - - // Allocate DMA buffer - edev->dma_region_len = 16*1024; - edev->dma_region = dma_alloc_coherent(dev, edev->dma_region_len, &edev->dma_region_addr, GFP_KERNEL | __GFP_ZERO); - if (!edev->dma_region) - { - dev_err(dev, "Failed to allocate DMA buffer"); - ret = -ENOMEM; - goto fail_dma_alloc; - } - - dev_info(dev, "Allocated DMA region virt %p, phys %p", edev->dma_region, (void *)edev->dma_region_addr); - - // Disable ASPM - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM); - - // Enable device - ret = pci_enable_device_mem(pdev); - if (ret) - { - dev_err(dev, "Failed to enable PCI device"); - //ret = -ENODEV; - goto fail_enable_device; - } - - // Enable bus mastering for DMA - pci_set_master(pdev); - - // Reserve regions - ret = pci_request_regions(pdev, DRIVER_NAME); - if (ret) - { - dev_err(dev, "Failed to reserve regions"); - //ret = -EBUSY; - goto fail_regions; - } - - // Enumerate BARs - enumerate_bars(edev, pdev); - - // Map BARs - ret = map_bars(edev, pdev); - if (ret) - { - dev_err(dev, "Failed to map BARs"); - goto fail_map_bars; - } - - // Allocate MSI IRQs - ret = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI); - if (ret < 0) - { - dev_err(dev, "Failed to allocate IRQs"); - goto fail_map_bars; - } - - // Set up interrupt - ret = pci_request_irq(pdev, 0, edev_intr, 0, edev, "edev"); - if (ret < 0) - { - dev_err(dev, "Failed to request IRQ"); - goto fail_irq; - } - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // Read/write test - dev_info(dev, "write to BAR1"); - iowrite32(0x11223344, edev->bar[1]); - - dev_info(dev, "read from BAR1"); - dev_info(dev, "%08x", ioread32(edev->bar[1])); - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // PCIe DMA test - dev_info(dev, "write test data"); - for (k = 0; k < 256; k++) - { - ((char *)edev->dma_region)[k] = k; - } - - dev_info(dev, "read test data"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, edev->dma_region, 256, true); - - dev_info(dev, "check DMA enable"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000000)); - - dev_info(dev, "enable DMA"); - iowrite32(0x1, edev->bar[0]+0x000000); - - dev_info(dev, "check DMA enable"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000000)); - - dev_info(dev, "start copy to card"); - iowrite32((edev->dma_region_addr+0x0000)&0xffffffff, edev->bar[0]+0x000100); - iowrite32(((edev->dma_region_addr+0x0000) >> 32)&0xffffffff, edev->bar[0]+0x000104); - iowrite32(0x100, edev->bar[0]+0x000108); - iowrite32(0, edev->bar[0]+0x00010C); - iowrite32(0x100, edev->bar[0]+0x000110); - iowrite32(0xAA, edev->bar[0]+0x000114); - - msleep(1); - - dev_info(dev, "Read status"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000118)); - - dev_info(dev, "start copy to host"); - iowrite32((edev->dma_region_addr+0x0200)&0xffffffff, edev->bar[0]+0x000200); - iowrite32(((edev->dma_region_addr+0x0200) >> 32)&0xffffffff, edev->bar[0]+0x000204); - iowrite32(0x100, edev->bar[0]+0x000208); - iowrite32(0, edev->bar[0]+0x00020C); - iowrite32(0x100, edev->bar[0]+0x000210); - iowrite32(0x55, edev->bar[0]+0x000214); - - msleep(1); - - dev_info(dev, "Read status"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000218)); - - dev_info(dev, "read test data"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, edev->dma_region+0x0200, 256, true); - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // probe complete - return 0; - - // error handling -fail_irq: - pci_free_irq_vectors(pdev); -fail_map_bars: - free_bars(edev, pdev); - pci_release_regions(pdev); -fail_regions: - pci_clear_master(pdev); - pci_disable_device(pdev); -fail_enable_device: - dma_free_coherent(dev, edev->dma_region_len, edev->dma_region, edev->dma_region_addr); -fail_dma_alloc: - return ret; -} - -static void edev_remove(struct pci_dev *pdev) -{ - struct example_dev *edev; - struct device *dev = &pdev->dev; - - dev_info(dev, "edev remove"); - - if (!(edev = pci_get_drvdata(pdev))) { - return; - } - - pci_free_irq(pdev, 0, edev); - pci_free_irq_vectors(pdev); - free_bars(edev, pdev); - pci_release_regions(pdev); - pci_clear_master(pdev); - pci_disable_device(pdev); - dma_free_coherent(dev, edev->dma_region_len, edev->dma_region, edev->dma_region_addr); -} - -static void edev_shutdown(struct pci_dev *pdev) -{ - struct example_dev *edev = pci_get_drvdata(pdev); - struct device *dev = &pdev->dev; - - dev_info(dev, "edev shutdown"); - - if (!edev) { - return; - } - - // ensure DMA is disabled on shutdown - pci_clear_master(pdev); -} - -static int enumerate_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - resource_size_t bar_start = pci_resource_start(pdev, i); - if (bar_start) - { - resource_size_t bar_end = pci_resource_end(pdev, i); - unsigned long bar_flags = pci_resource_flags(pdev, i); - dev_info(dev, "BAR[%d] 0x%08llx-0x%08llx flags 0x%08lx", - i, bar_start, bar_end, bar_flags); - } - } - - return 0; -} - -static int map_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - resource_size_t bar_start = pci_resource_start(pdev, i); - resource_size_t bar_end = pci_resource_end(pdev, i); - resource_size_t bar_len = bar_end - bar_start + 1; - edev->bar_len[i] = bar_len; - - if (!bar_start || !bar_end) - { - edev->bar_len[i] = 0; - continue; - } - - if (bar_len < 1) - { - dev_warn(dev, "BAR[%d] is less than 1 byte", i); - continue; - } - - edev->bar[i] = pci_ioremap_bar(pdev, i); - - if (!edev->bar[i]) - { - dev_err(dev, "Could not map BAR[%d]", i); - return -1; - } - - dev_info(dev, "BAR[%d] mapped at 0x%p with length %llu", i, edev->bar[i], bar_len); - } - - return 0; -} - -static void free_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - if (edev->bar[i]) - { - pci_iounmap(pdev, edev->bar[i]); - edev->bar[i] = NULL; - dev_info(dev, "Unmapped BAR[%d]", i); - } - } -} - -static struct pci_driver pci_driver = { - .name = DRIVER_NAME, - .id_table = pci_ids, - .probe = edev_probe, - .remove = edev_remove, - .shutdown = edev_shutdown -}; - -static int __init edev_init(void) -{ - return pci_register_driver(&pci_driver); -} - -static void __exit edev_exit(void) -{ - pci_unregister_driver(&pci_driver); -} - -module_init(edev_init); -module_exit(edev_exit); - diff --git a/example/ExaNIC_X10/fpga_axi/driver/example_driver.h b/example/ExaNIC_X10/fpga_axi/driver/example_driver.h deleted file mode 100644 index 9054bbcaa..000000000 --- a/example/ExaNIC_X10/fpga_axi/driver/example_driver.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -#ifndef EXAMPLE_DRIVER_H -#define EXAMPLE_DRIVER_H - -#include - -#define DRIVER_NAME "edev" -#define DRIVER_VERSION "0.1" - -#define DEV_BAR_CNT 2 - -struct example_dev { - struct pci_dev *pdev; - - // BAR pointers - void * __iomem bar[DEV_BAR_CNT]; - resource_size_t bar_len[DEV_BAR_CNT]; - - // DMA buffer - size_t dma_region_len; - void *dma_region; - dma_addr_t dma_region_addr; - - int irqcount; -}; - -#endif /* EXAMPLE_DRIVER_H */ diff --git a/example/ExaNIC_X25/fpga_axi/driver b/example/ExaNIC_X25/fpga_axi/driver new file mode 120000 index 000000000..f5aacbaaf --- /dev/null +++ b/example/ExaNIC_X25/fpga_axi/driver @@ -0,0 +1 @@ +../../common/driver/ \ No newline at end of file diff --git a/example/ExaNIC_X25/fpga_axi/driver/Makefile b/example/ExaNIC_X25/fpga_axi/driver/Makefile deleted file mode 100644 index 46f7ba228..000000000 --- a/example/ExaNIC_X25/fpga_axi/driver/Makefile +++ /dev/null @@ -1,11 +0,0 @@ - -# object files to build -obj-m += example.o -example-objs += example_driver.o - -all: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules - -clean: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean - diff --git a/example/ExaNIC_X25/fpga_axi/driver/example_driver.c b/example/ExaNIC_X25/fpga_axi/driver/example_driver.c deleted file mode 100644 index 67d654b32..000000000 --- a/example/ExaNIC_X25/fpga_axi/driver/example_driver.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -#include "example_driver.h" -#include -#include -#include -#include - -MODULE_DESCRIPTION("verilog-pcie example driver"); -MODULE_AUTHOR("Alex Forencich"); -MODULE_LICENSE("Dual MIT/GPL"); -MODULE_VERSION(DRIVER_VERSION); -MODULE_SUPPORTED_DEVICE(DRIVER_NAME); - -static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void edev_remove(struct pci_dev *pdev); -static void edev_shutdown(struct pci_dev *pdev); - -static int enumerate_bars(struct example_dev *edev, struct pci_dev *pdev); -static int map_bars(struct example_dev *edev, struct pci_dev *pdev); -static void free_bars(struct example_dev *edev, struct pci_dev *pdev); - -static const struct pci_device_id pci_ids[] = { - { PCI_DEVICE(0x1234, 0x0001) }, - { 0 /* end */ } -}; - -MODULE_DEVICE_TABLE(pci, pci_ids); - -static irqreturn_t edev_intr(int irq, void *data) -{ - struct example_dev *edev = data; - struct device *dev = &edev->pdev->dev; - - edev->irqcount++; - - dev_info(dev, "Interrupt"); - - return IRQ_HANDLED; -} - -static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int ret = 0; - struct example_dev *edev; - struct device *dev = &pdev->dev; - - int k; - - dev_info(dev, "edev probe"); - dev_info(dev, " vendor: 0x%04x", pdev->vendor); - dev_info(dev, " device: 0x%04x", pdev->device); - dev_info(dev, " class: 0x%06x", pdev->class); - dev_info(dev, " pci id: %02x:%02x.%02x", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); - - if (!(edev = devm_kzalloc(dev, sizeof(struct example_dev), GFP_KERNEL))) { - return -ENOMEM; - } - - edev->pdev = pdev; - pci_set_drvdata(pdev, edev); - - // Allocate DMA buffer - edev->dma_region_len = 16*1024; - edev->dma_region = dma_alloc_coherent(dev, edev->dma_region_len, &edev->dma_region_addr, GFP_KERNEL | __GFP_ZERO); - if (!edev->dma_region) - { - dev_err(dev, "Failed to allocate DMA buffer"); - ret = -ENOMEM; - goto fail_dma_alloc; - } - - dev_info(dev, "Allocated DMA region virt %p, phys %p", edev->dma_region, (void *)edev->dma_region_addr); - - // Disable ASPM - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM); - - // Enable device - ret = pci_enable_device_mem(pdev); - if (ret) - { - dev_err(dev, "Failed to enable PCI device"); - //ret = -ENODEV; - goto fail_enable_device; - } - - // Enable bus mastering for DMA - pci_set_master(pdev); - - // Reserve regions - ret = pci_request_regions(pdev, DRIVER_NAME); - if (ret) - { - dev_err(dev, "Failed to reserve regions"); - //ret = -EBUSY; - goto fail_regions; - } - - // Enumerate BARs - enumerate_bars(edev, pdev); - - // Map BARs - ret = map_bars(edev, pdev); - if (ret) - { - dev_err(dev, "Failed to map BARs"); - goto fail_map_bars; - } - - // Allocate MSI IRQs - ret = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI); - if (ret < 0) - { - dev_err(dev, "Failed to allocate IRQs"); - goto fail_map_bars; - } - - // Set up interrupt - ret = pci_request_irq(pdev, 0, edev_intr, 0, edev, "edev"); - if (ret < 0) - { - dev_err(dev, "Failed to request IRQ"); - goto fail_irq; - } - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // Read/write test - dev_info(dev, "write to BAR1"); - iowrite32(0x11223344, edev->bar[1]); - - dev_info(dev, "read from BAR1"); - dev_info(dev, "%08x", ioread32(edev->bar[1])); - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // PCIe DMA test - dev_info(dev, "write test data"); - for (k = 0; k < 256; k++) - { - ((char *)edev->dma_region)[k] = k; - } - - dev_info(dev, "read test data"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, edev->dma_region, 256, true); - - dev_info(dev, "check DMA enable"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000000)); - - dev_info(dev, "enable DMA"); - iowrite32(0x1, edev->bar[0]+0x000000); - - dev_info(dev, "check DMA enable"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000000)); - - dev_info(dev, "start copy to card"); - iowrite32((edev->dma_region_addr+0x0000)&0xffffffff, edev->bar[0]+0x000100); - iowrite32(((edev->dma_region_addr+0x0000) >> 32)&0xffffffff, edev->bar[0]+0x000104); - iowrite32(0x100, edev->bar[0]+0x000108); - iowrite32(0, edev->bar[0]+0x00010C); - iowrite32(0x100, edev->bar[0]+0x000110); - iowrite32(0xAA, edev->bar[0]+0x000114); - - msleep(1); - - dev_info(dev, "Read status"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000118)); - - dev_info(dev, "start copy to host"); - iowrite32((edev->dma_region_addr+0x0200)&0xffffffff, edev->bar[0]+0x000200); - iowrite32(((edev->dma_region_addr+0x0200) >> 32)&0xffffffff, edev->bar[0]+0x000204); - iowrite32(0x100, edev->bar[0]+0x000208); - iowrite32(0, edev->bar[0]+0x00020C); - iowrite32(0x100, edev->bar[0]+0x000210); - iowrite32(0x55, edev->bar[0]+0x000214); - - msleep(1); - - dev_info(dev, "Read status"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000218)); - - dev_info(dev, "read test data"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, edev->dma_region+0x0200, 256, true); - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // probe complete - return 0; - - // error handling -fail_irq: - pci_free_irq_vectors(pdev); -fail_map_bars: - free_bars(edev, pdev); - pci_release_regions(pdev); -fail_regions: - pci_clear_master(pdev); - pci_disable_device(pdev); -fail_enable_device: - dma_free_coherent(dev, edev->dma_region_len, edev->dma_region, edev->dma_region_addr); -fail_dma_alloc: - return ret; -} - -static void edev_remove(struct pci_dev *pdev) -{ - struct example_dev *edev; - struct device *dev = &pdev->dev; - - dev_info(dev, "edev remove"); - - if (!(edev = pci_get_drvdata(pdev))) { - return; - } - - pci_free_irq(pdev, 0, edev); - pci_free_irq_vectors(pdev); - free_bars(edev, pdev); - pci_release_regions(pdev); - pci_clear_master(pdev); - pci_disable_device(pdev); - dma_free_coherent(dev, edev->dma_region_len, edev->dma_region, edev->dma_region_addr); -} - -static void edev_shutdown(struct pci_dev *pdev) -{ - struct example_dev *edev = pci_get_drvdata(pdev); - struct device *dev = &pdev->dev; - - dev_info(dev, "edev shutdown"); - - if (!edev) { - return; - } - - // ensure DMA is disabled on shutdown - pci_clear_master(pdev); -} - -static int enumerate_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - resource_size_t bar_start = pci_resource_start(pdev, i); - if (bar_start) - { - resource_size_t bar_end = pci_resource_end(pdev, i); - unsigned long bar_flags = pci_resource_flags(pdev, i); - dev_info(dev, "BAR[%d] 0x%08llx-0x%08llx flags 0x%08lx", - i, bar_start, bar_end, bar_flags); - } - } - - return 0; -} - -static int map_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - resource_size_t bar_start = pci_resource_start(pdev, i); - resource_size_t bar_end = pci_resource_end(pdev, i); - resource_size_t bar_len = bar_end - bar_start + 1; - edev->bar_len[i] = bar_len; - - if (!bar_start || !bar_end) - { - edev->bar_len[i] = 0; - continue; - } - - if (bar_len < 1) - { - dev_warn(dev, "BAR[%d] is less than 1 byte", i); - continue; - } - - edev->bar[i] = pci_ioremap_bar(pdev, i); - - if (!edev->bar[i]) - { - dev_err(dev, "Could not map BAR[%d]", i); - return -1; - } - - dev_info(dev, "BAR[%d] mapped at 0x%p with length %llu", i, edev->bar[i], bar_len); - } - - return 0; -} - -static void free_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - if (edev->bar[i]) - { - pci_iounmap(pdev, edev->bar[i]); - edev->bar[i] = NULL; - dev_info(dev, "Unmapped BAR[%d]", i); - } - } -} - -static struct pci_driver pci_driver = { - .name = DRIVER_NAME, - .id_table = pci_ids, - .probe = edev_probe, - .remove = edev_remove, - .shutdown = edev_shutdown -}; - -static int __init edev_init(void) -{ - return pci_register_driver(&pci_driver); -} - -static void __exit edev_exit(void) -{ - pci_unregister_driver(&pci_driver); -} - -module_init(edev_init); -module_exit(edev_exit); - diff --git a/example/ExaNIC_X25/fpga_axi/driver/example_driver.h b/example/ExaNIC_X25/fpga_axi/driver/example_driver.h deleted file mode 100644 index 9054bbcaa..000000000 --- a/example/ExaNIC_X25/fpga_axi/driver/example_driver.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -#ifndef EXAMPLE_DRIVER_H -#define EXAMPLE_DRIVER_H - -#include - -#define DRIVER_NAME "edev" -#define DRIVER_VERSION "0.1" - -#define DEV_BAR_CNT 2 - -struct example_dev { - struct pci_dev *pdev; - - // BAR pointers - void * __iomem bar[DEV_BAR_CNT]; - resource_size_t bar_len[DEV_BAR_CNT]; - - // DMA buffer - size_t dma_region_len; - void *dma_region; - dma_addr_t dma_region_addr; - - int irqcount; -}; - -#endif /* EXAMPLE_DRIVER_H */ diff --git a/example/VCU108/fpga_axi/driver b/example/VCU108/fpga_axi/driver new file mode 120000 index 000000000..f5aacbaaf --- /dev/null +++ b/example/VCU108/fpga_axi/driver @@ -0,0 +1 @@ +../../common/driver/ \ No newline at end of file diff --git a/example/VCU108/fpga_axi/driver/Makefile b/example/VCU108/fpga_axi/driver/Makefile deleted file mode 100644 index 46f7ba228..000000000 --- a/example/VCU108/fpga_axi/driver/Makefile +++ /dev/null @@ -1,11 +0,0 @@ - -# object files to build -obj-m += example.o -example-objs += example_driver.o - -all: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules - -clean: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean - diff --git a/example/VCU108/fpga_axi/driver/example_driver.c b/example/VCU108/fpga_axi/driver/example_driver.c deleted file mode 100644 index 67d654b32..000000000 --- a/example/VCU108/fpga_axi/driver/example_driver.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -#include "example_driver.h" -#include -#include -#include -#include - -MODULE_DESCRIPTION("verilog-pcie example driver"); -MODULE_AUTHOR("Alex Forencich"); -MODULE_LICENSE("Dual MIT/GPL"); -MODULE_VERSION(DRIVER_VERSION); -MODULE_SUPPORTED_DEVICE(DRIVER_NAME); - -static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void edev_remove(struct pci_dev *pdev); -static void edev_shutdown(struct pci_dev *pdev); - -static int enumerate_bars(struct example_dev *edev, struct pci_dev *pdev); -static int map_bars(struct example_dev *edev, struct pci_dev *pdev); -static void free_bars(struct example_dev *edev, struct pci_dev *pdev); - -static const struct pci_device_id pci_ids[] = { - { PCI_DEVICE(0x1234, 0x0001) }, - { 0 /* end */ } -}; - -MODULE_DEVICE_TABLE(pci, pci_ids); - -static irqreturn_t edev_intr(int irq, void *data) -{ - struct example_dev *edev = data; - struct device *dev = &edev->pdev->dev; - - edev->irqcount++; - - dev_info(dev, "Interrupt"); - - return IRQ_HANDLED; -} - -static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int ret = 0; - struct example_dev *edev; - struct device *dev = &pdev->dev; - - int k; - - dev_info(dev, "edev probe"); - dev_info(dev, " vendor: 0x%04x", pdev->vendor); - dev_info(dev, " device: 0x%04x", pdev->device); - dev_info(dev, " class: 0x%06x", pdev->class); - dev_info(dev, " pci id: %02x:%02x.%02x", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); - - if (!(edev = devm_kzalloc(dev, sizeof(struct example_dev), GFP_KERNEL))) { - return -ENOMEM; - } - - edev->pdev = pdev; - pci_set_drvdata(pdev, edev); - - // Allocate DMA buffer - edev->dma_region_len = 16*1024; - edev->dma_region = dma_alloc_coherent(dev, edev->dma_region_len, &edev->dma_region_addr, GFP_KERNEL | __GFP_ZERO); - if (!edev->dma_region) - { - dev_err(dev, "Failed to allocate DMA buffer"); - ret = -ENOMEM; - goto fail_dma_alloc; - } - - dev_info(dev, "Allocated DMA region virt %p, phys %p", edev->dma_region, (void *)edev->dma_region_addr); - - // Disable ASPM - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM); - - // Enable device - ret = pci_enable_device_mem(pdev); - if (ret) - { - dev_err(dev, "Failed to enable PCI device"); - //ret = -ENODEV; - goto fail_enable_device; - } - - // Enable bus mastering for DMA - pci_set_master(pdev); - - // Reserve regions - ret = pci_request_regions(pdev, DRIVER_NAME); - if (ret) - { - dev_err(dev, "Failed to reserve regions"); - //ret = -EBUSY; - goto fail_regions; - } - - // Enumerate BARs - enumerate_bars(edev, pdev); - - // Map BARs - ret = map_bars(edev, pdev); - if (ret) - { - dev_err(dev, "Failed to map BARs"); - goto fail_map_bars; - } - - // Allocate MSI IRQs - ret = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI); - if (ret < 0) - { - dev_err(dev, "Failed to allocate IRQs"); - goto fail_map_bars; - } - - // Set up interrupt - ret = pci_request_irq(pdev, 0, edev_intr, 0, edev, "edev"); - if (ret < 0) - { - dev_err(dev, "Failed to request IRQ"); - goto fail_irq; - } - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // Read/write test - dev_info(dev, "write to BAR1"); - iowrite32(0x11223344, edev->bar[1]); - - dev_info(dev, "read from BAR1"); - dev_info(dev, "%08x", ioread32(edev->bar[1])); - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // PCIe DMA test - dev_info(dev, "write test data"); - for (k = 0; k < 256; k++) - { - ((char *)edev->dma_region)[k] = k; - } - - dev_info(dev, "read test data"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, edev->dma_region, 256, true); - - dev_info(dev, "check DMA enable"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000000)); - - dev_info(dev, "enable DMA"); - iowrite32(0x1, edev->bar[0]+0x000000); - - dev_info(dev, "check DMA enable"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000000)); - - dev_info(dev, "start copy to card"); - iowrite32((edev->dma_region_addr+0x0000)&0xffffffff, edev->bar[0]+0x000100); - iowrite32(((edev->dma_region_addr+0x0000) >> 32)&0xffffffff, edev->bar[0]+0x000104); - iowrite32(0x100, edev->bar[0]+0x000108); - iowrite32(0, edev->bar[0]+0x00010C); - iowrite32(0x100, edev->bar[0]+0x000110); - iowrite32(0xAA, edev->bar[0]+0x000114); - - msleep(1); - - dev_info(dev, "Read status"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000118)); - - dev_info(dev, "start copy to host"); - iowrite32((edev->dma_region_addr+0x0200)&0xffffffff, edev->bar[0]+0x000200); - iowrite32(((edev->dma_region_addr+0x0200) >> 32)&0xffffffff, edev->bar[0]+0x000204); - iowrite32(0x100, edev->bar[0]+0x000208); - iowrite32(0, edev->bar[0]+0x00020C); - iowrite32(0x100, edev->bar[0]+0x000210); - iowrite32(0x55, edev->bar[0]+0x000214); - - msleep(1); - - dev_info(dev, "Read status"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000218)); - - dev_info(dev, "read test data"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, edev->dma_region+0x0200, 256, true); - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // probe complete - return 0; - - // error handling -fail_irq: - pci_free_irq_vectors(pdev); -fail_map_bars: - free_bars(edev, pdev); - pci_release_regions(pdev); -fail_regions: - pci_clear_master(pdev); - pci_disable_device(pdev); -fail_enable_device: - dma_free_coherent(dev, edev->dma_region_len, edev->dma_region, edev->dma_region_addr); -fail_dma_alloc: - return ret; -} - -static void edev_remove(struct pci_dev *pdev) -{ - struct example_dev *edev; - struct device *dev = &pdev->dev; - - dev_info(dev, "edev remove"); - - if (!(edev = pci_get_drvdata(pdev))) { - return; - } - - pci_free_irq(pdev, 0, edev); - pci_free_irq_vectors(pdev); - free_bars(edev, pdev); - pci_release_regions(pdev); - pci_clear_master(pdev); - pci_disable_device(pdev); - dma_free_coherent(dev, edev->dma_region_len, edev->dma_region, edev->dma_region_addr); -} - -static void edev_shutdown(struct pci_dev *pdev) -{ - struct example_dev *edev = pci_get_drvdata(pdev); - struct device *dev = &pdev->dev; - - dev_info(dev, "edev shutdown"); - - if (!edev) { - return; - } - - // ensure DMA is disabled on shutdown - pci_clear_master(pdev); -} - -static int enumerate_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - resource_size_t bar_start = pci_resource_start(pdev, i); - if (bar_start) - { - resource_size_t bar_end = pci_resource_end(pdev, i); - unsigned long bar_flags = pci_resource_flags(pdev, i); - dev_info(dev, "BAR[%d] 0x%08llx-0x%08llx flags 0x%08lx", - i, bar_start, bar_end, bar_flags); - } - } - - return 0; -} - -static int map_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - resource_size_t bar_start = pci_resource_start(pdev, i); - resource_size_t bar_end = pci_resource_end(pdev, i); - resource_size_t bar_len = bar_end - bar_start + 1; - edev->bar_len[i] = bar_len; - - if (!bar_start || !bar_end) - { - edev->bar_len[i] = 0; - continue; - } - - if (bar_len < 1) - { - dev_warn(dev, "BAR[%d] is less than 1 byte", i); - continue; - } - - edev->bar[i] = pci_ioremap_bar(pdev, i); - - if (!edev->bar[i]) - { - dev_err(dev, "Could not map BAR[%d]", i); - return -1; - } - - dev_info(dev, "BAR[%d] mapped at 0x%p with length %llu", i, edev->bar[i], bar_len); - } - - return 0; -} - -static void free_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - if (edev->bar[i]) - { - pci_iounmap(pdev, edev->bar[i]); - edev->bar[i] = NULL; - dev_info(dev, "Unmapped BAR[%d]", i); - } - } -} - -static struct pci_driver pci_driver = { - .name = DRIVER_NAME, - .id_table = pci_ids, - .probe = edev_probe, - .remove = edev_remove, - .shutdown = edev_shutdown -}; - -static int __init edev_init(void) -{ - return pci_register_driver(&pci_driver); -} - -static void __exit edev_exit(void) -{ - pci_unregister_driver(&pci_driver); -} - -module_init(edev_init); -module_exit(edev_exit); - diff --git a/example/VCU108/fpga_axi/driver/example_driver.h b/example/VCU108/fpga_axi/driver/example_driver.h deleted file mode 100644 index 9054bbcaa..000000000 --- a/example/VCU108/fpga_axi/driver/example_driver.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -#ifndef EXAMPLE_DRIVER_H -#define EXAMPLE_DRIVER_H - -#include - -#define DRIVER_NAME "edev" -#define DRIVER_VERSION "0.1" - -#define DEV_BAR_CNT 2 - -struct example_dev { - struct pci_dev *pdev; - - // BAR pointers - void * __iomem bar[DEV_BAR_CNT]; - resource_size_t bar_len[DEV_BAR_CNT]; - - // DMA buffer - size_t dma_region_len; - void *dma_region; - dma_addr_t dma_region_addr; - - int irqcount; -}; - -#endif /* EXAMPLE_DRIVER_H */ diff --git a/example/VCU118/fpga_axi_x8/driver b/example/VCU118/fpga_axi_x8/driver new file mode 120000 index 000000000..f5aacbaaf --- /dev/null +++ b/example/VCU118/fpga_axi_x8/driver @@ -0,0 +1 @@ +../../common/driver/ \ No newline at end of file diff --git a/example/VCU118/fpga_axi_x8/driver/Makefile b/example/VCU118/fpga_axi_x8/driver/Makefile deleted file mode 100644 index 46f7ba228..000000000 --- a/example/VCU118/fpga_axi_x8/driver/Makefile +++ /dev/null @@ -1,11 +0,0 @@ - -# object files to build -obj-m += example.o -example-objs += example_driver.o - -all: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules - -clean: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean - diff --git a/example/VCU118/fpga_axi_x8/driver/example_driver.c b/example/VCU118/fpga_axi_x8/driver/example_driver.c deleted file mode 100644 index 67d654b32..000000000 --- a/example/VCU118/fpga_axi_x8/driver/example_driver.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -#include "example_driver.h" -#include -#include -#include -#include - -MODULE_DESCRIPTION("verilog-pcie example driver"); -MODULE_AUTHOR("Alex Forencich"); -MODULE_LICENSE("Dual MIT/GPL"); -MODULE_VERSION(DRIVER_VERSION); -MODULE_SUPPORTED_DEVICE(DRIVER_NAME); - -static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void edev_remove(struct pci_dev *pdev); -static void edev_shutdown(struct pci_dev *pdev); - -static int enumerate_bars(struct example_dev *edev, struct pci_dev *pdev); -static int map_bars(struct example_dev *edev, struct pci_dev *pdev); -static void free_bars(struct example_dev *edev, struct pci_dev *pdev); - -static const struct pci_device_id pci_ids[] = { - { PCI_DEVICE(0x1234, 0x0001) }, - { 0 /* end */ } -}; - -MODULE_DEVICE_TABLE(pci, pci_ids); - -static irqreturn_t edev_intr(int irq, void *data) -{ - struct example_dev *edev = data; - struct device *dev = &edev->pdev->dev; - - edev->irqcount++; - - dev_info(dev, "Interrupt"); - - return IRQ_HANDLED; -} - -static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int ret = 0; - struct example_dev *edev; - struct device *dev = &pdev->dev; - - int k; - - dev_info(dev, "edev probe"); - dev_info(dev, " vendor: 0x%04x", pdev->vendor); - dev_info(dev, " device: 0x%04x", pdev->device); - dev_info(dev, " class: 0x%06x", pdev->class); - dev_info(dev, " pci id: %02x:%02x.%02x", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); - - if (!(edev = devm_kzalloc(dev, sizeof(struct example_dev), GFP_KERNEL))) { - return -ENOMEM; - } - - edev->pdev = pdev; - pci_set_drvdata(pdev, edev); - - // Allocate DMA buffer - edev->dma_region_len = 16*1024; - edev->dma_region = dma_alloc_coherent(dev, edev->dma_region_len, &edev->dma_region_addr, GFP_KERNEL | __GFP_ZERO); - if (!edev->dma_region) - { - dev_err(dev, "Failed to allocate DMA buffer"); - ret = -ENOMEM; - goto fail_dma_alloc; - } - - dev_info(dev, "Allocated DMA region virt %p, phys %p", edev->dma_region, (void *)edev->dma_region_addr); - - // Disable ASPM - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM); - - // Enable device - ret = pci_enable_device_mem(pdev); - if (ret) - { - dev_err(dev, "Failed to enable PCI device"); - //ret = -ENODEV; - goto fail_enable_device; - } - - // Enable bus mastering for DMA - pci_set_master(pdev); - - // Reserve regions - ret = pci_request_regions(pdev, DRIVER_NAME); - if (ret) - { - dev_err(dev, "Failed to reserve regions"); - //ret = -EBUSY; - goto fail_regions; - } - - // Enumerate BARs - enumerate_bars(edev, pdev); - - // Map BARs - ret = map_bars(edev, pdev); - if (ret) - { - dev_err(dev, "Failed to map BARs"); - goto fail_map_bars; - } - - // Allocate MSI IRQs - ret = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI); - if (ret < 0) - { - dev_err(dev, "Failed to allocate IRQs"); - goto fail_map_bars; - } - - // Set up interrupt - ret = pci_request_irq(pdev, 0, edev_intr, 0, edev, "edev"); - if (ret < 0) - { - dev_err(dev, "Failed to request IRQ"); - goto fail_irq; - } - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // Read/write test - dev_info(dev, "write to BAR1"); - iowrite32(0x11223344, edev->bar[1]); - - dev_info(dev, "read from BAR1"); - dev_info(dev, "%08x", ioread32(edev->bar[1])); - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // PCIe DMA test - dev_info(dev, "write test data"); - for (k = 0; k < 256; k++) - { - ((char *)edev->dma_region)[k] = k; - } - - dev_info(dev, "read test data"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, edev->dma_region, 256, true); - - dev_info(dev, "check DMA enable"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000000)); - - dev_info(dev, "enable DMA"); - iowrite32(0x1, edev->bar[0]+0x000000); - - dev_info(dev, "check DMA enable"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000000)); - - dev_info(dev, "start copy to card"); - iowrite32((edev->dma_region_addr+0x0000)&0xffffffff, edev->bar[0]+0x000100); - iowrite32(((edev->dma_region_addr+0x0000) >> 32)&0xffffffff, edev->bar[0]+0x000104); - iowrite32(0x100, edev->bar[0]+0x000108); - iowrite32(0, edev->bar[0]+0x00010C); - iowrite32(0x100, edev->bar[0]+0x000110); - iowrite32(0xAA, edev->bar[0]+0x000114); - - msleep(1); - - dev_info(dev, "Read status"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000118)); - - dev_info(dev, "start copy to host"); - iowrite32((edev->dma_region_addr+0x0200)&0xffffffff, edev->bar[0]+0x000200); - iowrite32(((edev->dma_region_addr+0x0200) >> 32)&0xffffffff, edev->bar[0]+0x000204); - iowrite32(0x100, edev->bar[0]+0x000208); - iowrite32(0, edev->bar[0]+0x00020C); - iowrite32(0x100, edev->bar[0]+0x000210); - iowrite32(0x55, edev->bar[0]+0x000214); - - msleep(1); - - dev_info(dev, "Read status"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000218)); - - dev_info(dev, "read test data"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, edev->dma_region+0x0200, 256, true); - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // probe complete - return 0; - - // error handling -fail_irq: - pci_free_irq_vectors(pdev); -fail_map_bars: - free_bars(edev, pdev); - pci_release_regions(pdev); -fail_regions: - pci_clear_master(pdev); - pci_disable_device(pdev); -fail_enable_device: - dma_free_coherent(dev, edev->dma_region_len, edev->dma_region, edev->dma_region_addr); -fail_dma_alloc: - return ret; -} - -static void edev_remove(struct pci_dev *pdev) -{ - struct example_dev *edev; - struct device *dev = &pdev->dev; - - dev_info(dev, "edev remove"); - - if (!(edev = pci_get_drvdata(pdev))) { - return; - } - - pci_free_irq(pdev, 0, edev); - pci_free_irq_vectors(pdev); - free_bars(edev, pdev); - pci_release_regions(pdev); - pci_clear_master(pdev); - pci_disable_device(pdev); - dma_free_coherent(dev, edev->dma_region_len, edev->dma_region, edev->dma_region_addr); -} - -static void edev_shutdown(struct pci_dev *pdev) -{ - struct example_dev *edev = pci_get_drvdata(pdev); - struct device *dev = &pdev->dev; - - dev_info(dev, "edev shutdown"); - - if (!edev) { - return; - } - - // ensure DMA is disabled on shutdown - pci_clear_master(pdev); -} - -static int enumerate_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - resource_size_t bar_start = pci_resource_start(pdev, i); - if (bar_start) - { - resource_size_t bar_end = pci_resource_end(pdev, i); - unsigned long bar_flags = pci_resource_flags(pdev, i); - dev_info(dev, "BAR[%d] 0x%08llx-0x%08llx flags 0x%08lx", - i, bar_start, bar_end, bar_flags); - } - } - - return 0; -} - -static int map_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - resource_size_t bar_start = pci_resource_start(pdev, i); - resource_size_t bar_end = pci_resource_end(pdev, i); - resource_size_t bar_len = bar_end - bar_start + 1; - edev->bar_len[i] = bar_len; - - if (!bar_start || !bar_end) - { - edev->bar_len[i] = 0; - continue; - } - - if (bar_len < 1) - { - dev_warn(dev, "BAR[%d] is less than 1 byte", i); - continue; - } - - edev->bar[i] = pci_ioremap_bar(pdev, i); - - if (!edev->bar[i]) - { - dev_err(dev, "Could not map BAR[%d]", i); - return -1; - } - - dev_info(dev, "BAR[%d] mapped at 0x%p with length %llu", i, edev->bar[i], bar_len); - } - - return 0; -} - -static void free_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - if (edev->bar[i]) - { - pci_iounmap(pdev, edev->bar[i]); - edev->bar[i] = NULL; - dev_info(dev, "Unmapped BAR[%d]", i); - } - } -} - -static struct pci_driver pci_driver = { - .name = DRIVER_NAME, - .id_table = pci_ids, - .probe = edev_probe, - .remove = edev_remove, - .shutdown = edev_shutdown -}; - -static int __init edev_init(void) -{ - return pci_register_driver(&pci_driver); -} - -static void __exit edev_exit(void) -{ - pci_unregister_driver(&pci_driver); -} - -module_init(edev_init); -module_exit(edev_exit); - diff --git a/example/VCU118/fpga_axi_x8/driver/example_driver.h b/example/VCU118/fpga_axi_x8/driver/example_driver.h deleted file mode 100644 index 9054bbcaa..000000000 --- a/example/VCU118/fpga_axi_x8/driver/example_driver.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -#ifndef EXAMPLE_DRIVER_H -#define EXAMPLE_DRIVER_H - -#include - -#define DRIVER_NAME "edev" -#define DRIVER_VERSION "0.1" - -#define DEV_BAR_CNT 2 - -struct example_dev { - struct pci_dev *pdev; - - // BAR pointers - void * __iomem bar[DEV_BAR_CNT]; - resource_size_t bar_len[DEV_BAR_CNT]; - - // DMA buffer - size_t dma_region_len; - void *dma_region; - dma_addr_t dma_region_addr; - - int irqcount; -}; - -#endif /* EXAMPLE_DRIVER_H */ diff --git a/example/VCU1525/fpga_axi/driver b/example/VCU1525/fpga_axi/driver new file mode 120000 index 000000000..f5aacbaaf --- /dev/null +++ b/example/VCU1525/fpga_axi/driver @@ -0,0 +1 @@ +../../common/driver/ \ No newline at end of file diff --git a/example/VCU1525/fpga_axi/driver/Makefile b/example/VCU1525/fpga_axi/driver/Makefile deleted file mode 100644 index 46f7ba228..000000000 --- a/example/VCU1525/fpga_axi/driver/Makefile +++ /dev/null @@ -1,11 +0,0 @@ - -# object files to build -obj-m += example.o -example-objs += example_driver.o - -all: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules - -clean: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean - diff --git a/example/VCU1525/fpga_axi/driver/example_driver.c b/example/VCU1525/fpga_axi/driver/example_driver.c deleted file mode 100644 index 67d654b32..000000000 --- a/example/VCU1525/fpga_axi/driver/example_driver.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -#include "example_driver.h" -#include -#include -#include -#include - -MODULE_DESCRIPTION("verilog-pcie example driver"); -MODULE_AUTHOR("Alex Forencich"); -MODULE_LICENSE("Dual MIT/GPL"); -MODULE_VERSION(DRIVER_VERSION); -MODULE_SUPPORTED_DEVICE(DRIVER_NAME); - -static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void edev_remove(struct pci_dev *pdev); -static void edev_shutdown(struct pci_dev *pdev); - -static int enumerate_bars(struct example_dev *edev, struct pci_dev *pdev); -static int map_bars(struct example_dev *edev, struct pci_dev *pdev); -static void free_bars(struct example_dev *edev, struct pci_dev *pdev); - -static const struct pci_device_id pci_ids[] = { - { PCI_DEVICE(0x1234, 0x0001) }, - { 0 /* end */ } -}; - -MODULE_DEVICE_TABLE(pci, pci_ids); - -static irqreturn_t edev_intr(int irq, void *data) -{ - struct example_dev *edev = data; - struct device *dev = &edev->pdev->dev; - - edev->irqcount++; - - dev_info(dev, "Interrupt"); - - return IRQ_HANDLED; -} - -static int edev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int ret = 0; - struct example_dev *edev; - struct device *dev = &pdev->dev; - - int k; - - dev_info(dev, "edev probe"); - dev_info(dev, " vendor: 0x%04x", pdev->vendor); - dev_info(dev, " device: 0x%04x", pdev->device); - dev_info(dev, " class: 0x%06x", pdev->class); - dev_info(dev, " pci id: %02x:%02x.%02x", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); - - if (!(edev = devm_kzalloc(dev, sizeof(struct example_dev), GFP_KERNEL))) { - return -ENOMEM; - } - - edev->pdev = pdev; - pci_set_drvdata(pdev, edev); - - // Allocate DMA buffer - edev->dma_region_len = 16*1024; - edev->dma_region = dma_alloc_coherent(dev, edev->dma_region_len, &edev->dma_region_addr, GFP_KERNEL | __GFP_ZERO); - if (!edev->dma_region) - { - dev_err(dev, "Failed to allocate DMA buffer"); - ret = -ENOMEM; - goto fail_dma_alloc; - } - - dev_info(dev, "Allocated DMA region virt %p, phys %p", edev->dma_region, (void *)edev->dma_region_addr); - - // Disable ASPM - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM); - - // Enable device - ret = pci_enable_device_mem(pdev); - if (ret) - { - dev_err(dev, "Failed to enable PCI device"); - //ret = -ENODEV; - goto fail_enable_device; - } - - // Enable bus mastering for DMA - pci_set_master(pdev); - - // Reserve regions - ret = pci_request_regions(pdev, DRIVER_NAME); - if (ret) - { - dev_err(dev, "Failed to reserve regions"); - //ret = -EBUSY; - goto fail_regions; - } - - // Enumerate BARs - enumerate_bars(edev, pdev); - - // Map BARs - ret = map_bars(edev, pdev); - if (ret) - { - dev_err(dev, "Failed to map BARs"); - goto fail_map_bars; - } - - // Allocate MSI IRQs - ret = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI); - if (ret < 0) - { - dev_err(dev, "Failed to allocate IRQs"); - goto fail_map_bars; - } - - // Set up interrupt - ret = pci_request_irq(pdev, 0, edev_intr, 0, edev, "edev"); - if (ret < 0) - { - dev_err(dev, "Failed to request IRQ"); - goto fail_irq; - } - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // Read/write test - dev_info(dev, "write to BAR1"); - iowrite32(0x11223344, edev->bar[1]); - - dev_info(dev, "read from BAR1"); - dev_info(dev, "%08x", ioread32(edev->bar[1])); - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // PCIe DMA test - dev_info(dev, "write test data"); - for (k = 0; k < 256; k++) - { - ((char *)edev->dma_region)[k] = k; - } - - dev_info(dev, "read test data"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, edev->dma_region, 256, true); - - dev_info(dev, "check DMA enable"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000000)); - - dev_info(dev, "enable DMA"); - iowrite32(0x1, edev->bar[0]+0x000000); - - dev_info(dev, "check DMA enable"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000000)); - - dev_info(dev, "start copy to card"); - iowrite32((edev->dma_region_addr+0x0000)&0xffffffff, edev->bar[0]+0x000100); - iowrite32(((edev->dma_region_addr+0x0000) >> 32)&0xffffffff, edev->bar[0]+0x000104); - iowrite32(0x100, edev->bar[0]+0x000108); - iowrite32(0, edev->bar[0]+0x00010C); - iowrite32(0x100, edev->bar[0]+0x000110); - iowrite32(0xAA, edev->bar[0]+0x000114); - - msleep(1); - - dev_info(dev, "Read status"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000118)); - - dev_info(dev, "start copy to host"); - iowrite32((edev->dma_region_addr+0x0200)&0xffffffff, edev->bar[0]+0x000200); - iowrite32(((edev->dma_region_addr+0x0200) >> 32)&0xffffffff, edev->bar[0]+0x000204); - iowrite32(0x100, edev->bar[0]+0x000208); - iowrite32(0, edev->bar[0]+0x00020C); - iowrite32(0x100, edev->bar[0]+0x000210); - iowrite32(0x55, edev->bar[0]+0x000214); - - msleep(1); - - dev_info(dev, "Read status"); - dev_info(dev, "%08x", ioread32(edev->bar[0]+0x000218)); - - dev_info(dev, "read test data"); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, edev->dma_region+0x0200, 256, true); - - // Dump counters - dev_info(dev, "TLP counters"); - dev_info(dev, "RQ: %d", ioread32(edev->bar[0]+0x000400)); - dev_info(dev, "RC: %d", ioread32(edev->bar[0]+0x000404)); - dev_info(dev, "CQ: %d", ioread32(edev->bar[0]+0x000408)); - dev_info(dev, "CC: %d", ioread32(edev->bar[0]+0x00040C)); - - // probe complete - return 0; - - // error handling -fail_irq: - pci_free_irq_vectors(pdev); -fail_map_bars: - free_bars(edev, pdev); - pci_release_regions(pdev); -fail_regions: - pci_clear_master(pdev); - pci_disable_device(pdev); -fail_enable_device: - dma_free_coherent(dev, edev->dma_region_len, edev->dma_region, edev->dma_region_addr); -fail_dma_alloc: - return ret; -} - -static void edev_remove(struct pci_dev *pdev) -{ - struct example_dev *edev; - struct device *dev = &pdev->dev; - - dev_info(dev, "edev remove"); - - if (!(edev = pci_get_drvdata(pdev))) { - return; - } - - pci_free_irq(pdev, 0, edev); - pci_free_irq_vectors(pdev); - free_bars(edev, pdev); - pci_release_regions(pdev); - pci_clear_master(pdev); - pci_disable_device(pdev); - dma_free_coherent(dev, edev->dma_region_len, edev->dma_region, edev->dma_region_addr); -} - -static void edev_shutdown(struct pci_dev *pdev) -{ - struct example_dev *edev = pci_get_drvdata(pdev); - struct device *dev = &pdev->dev; - - dev_info(dev, "edev shutdown"); - - if (!edev) { - return; - } - - // ensure DMA is disabled on shutdown - pci_clear_master(pdev); -} - -static int enumerate_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - resource_size_t bar_start = pci_resource_start(pdev, i); - if (bar_start) - { - resource_size_t bar_end = pci_resource_end(pdev, i); - unsigned long bar_flags = pci_resource_flags(pdev, i); - dev_info(dev, "BAR[%d] 0x%08llx-0x%08llx flags 0x%08lx", - i, bar_start, bar_end, bar_flags); - } - } - - return 0; -} - -static int map_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - resource_size_t bar_start = pci_resource_start(pdev, i); - resource_size_t bar_end = pci_resource_end(pdev, i); - resource_size_t bar_len = bar_end - bar_start + 1; - edev->bar_len[i] = bar_len; - - if (!bar_start || !bar_end) - { - edev->bar_len[i] = 0; - continue; - } - - if (bar_len < 1) - { - dev_warn(dev, "BAR[%d] is less than 1 byte", i); - continue; - } - - edev->bar[i] = pci_ioremap_bar(pdev, i); - - if (!edev->bar[i]) - { - dev_err(dev, "Could not map BAR[%d]", i); - return -1; - } - - dev_info(dev, "BAR[%d] mapped at 0x%p with length %llu", i, edev->bar[i], bar_len); - } - - return 0; -} - -static void free_bars(struct example_dev *edev, struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - int i; - - for (i = 0; i < DEV_BAR_CNT; i++) - { - if (edev->bar[i]) - { - pci_iounmap(pdev, edev->bar[i]); - edev->bar[i] = NULL; - dev_info(dev, "Unmapped BAR[%d]", i); - } - } -} - -static struct pci_driver pci_driver = { - .name = DRIVER_NAME, - .id_table = pci_ids, - .probe = edev_probe, - .remove = edev_remove, - .shutdown = edev_shutdown -}; - -static int __init edev_init(void) -{ - return pci_register_driver(&pci_driver); -} - -static void __exit edev_exit(void) -{ - pci_unregister_driver(&pci_driver); -} - -module_init(edev_init); -module_exit(edev_exit); - diff --git a/example/VCU1525/fpga_axi/driver/example_driver.h b/example/VCU1525/fpga_axi/driver/example_driver.h deleted file mode 100644 index 9054bbcaa..000000000 --- a/example/VCU1525/fpga_axi/driver/example_driver.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -#ifndef EXAMPLE_DRIVER_H -#define EXAMPLE_DRIVER_H - -#include - -#define DRIVER_NAME "edev" -#define DRIVER_VERSION "0.1" - -#define DEV_BAR_CNT 2 - -struct example_dev { - struct pci_dev *pdev; - - // BAR pointers - void * __iomem bar[DEV_BAR_CNT]; - resource_size_t bar_len[DEV_BAR_CNT]; - - // DMA buffer - size_t dma_region_len; - void *dma_region; - dma_addr_t dma_region_addr; - - int irqcount; -}; - -#endif /* EXAMPLE_DRIVER_H */ diff --git a/example/ADM_PCIE_9V3/fpga_axi_x8/driver/Makefile b/example/common/driver/Makefile similarity index 100% rename from example/ADM_PCIE_9V3/fpga_axi_x8/driver/Makefile rename to example/common/driver/Makefile diff --git a/example/ADM_PCIE_9V3/fpga_axi_x8/driver/example_driver.c b/example/common/driver/example_driver.c similarity index 100% rename from example/ADM_PCIE_9V3/fpga_axi_x8/driver/example_driver.c rename to example/common/driver/example_driver.c diff --git a/example/ADM_PCIE_9V3/fpga_axi_x8/driver/example_driver.h b/example/common/driver/example_driver.h similarity index 100% rename from example/ADM_PCIE_9V3/fpga_axi_x8/driver/example_driver.h rename to example/common/driver/example_driver.h From bd0482fc96d87e6a64f42e1d31ec090891a749bb Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 26 Feb 2020 12:21:36 -0800 Subject: [PATCH 2/2] Update script for sysfs changes --- scripts/pcie_hot_reset.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/pcie_hot_reset.sh b/scripts/pcie_hot_reset.sh index caf77b340..18c178f83 100755 --- a/scripts/pcie_hot_reset.sh +++ b/scripts/pcie_hot_reset.sh @@ -40,6 +40,10 @@ sleep 0.5 echo "Rescanning bus..." -echo 1 > "/sys/bus/pci/devices/$port/rescan" +if [ -e "/sys/bus/pci/devices/$port/dev_rescan" ]; then + echo 1 > "/sys/bus/pci/devices/$port/dev_rescan" +else + echo 1 > "/sys/bus/pci/devices/$port/rescan" +fi