EP设备驱动架构
EP设备驱动,主要运行在RC侧,用于控制总线地址上的数据传输使用, 提供给应用层接口,应用层调用此接口完成数据传输,主要的分层结构如下
RC侧包含RC控制器驱动 和EP设备驱动
EP侧包含EP控制器驱动和EP端口驱动 (无需关心,一般厂商提供)
实现的主要是EP设备驱动
EP侧 Block图
主要分三层 PCI控制器层、EP中间层、EP功能层
pci-epf-test.c是EP功能层驱动 以上驱动不在本文分析范围
RC侧驱动代码原理
主要完成数据地址的拷贝,支持DMA数据传输
文章来源:https://www.toymoban.com/news/detail-401497.html
pci-endpoint-test设备驱动
这个驱动是TI写的,用于TI芯片进行PCIE级联使用,其他的平台可以参考此驱动进行移植调试
该驱动对大家写PCIE EP的设备驱动提供了很好的帮助,它提供了一种EP框架思路,可以加快PCIE的调试流程文章来源地址https://www.toymoban.com/news/detail-401497.html
#include <linux/crc32.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/pci_regs.h>
#include <uapi/linux/pcitest.h>
#define DRV_MODULE_NAME "pci-endpoint-test"
#define PCI_ENDPOINT_TEST_MAGIC 0x0
#define PCI_ENDPOINT_TEST_COMMAND 0x4
#define COMMAND_RAISE_LEGACY_IRQ BIT(0)
#define COMMAND_RAISE_MSI_IRQ BIT(1)
#define MSI_NUMBER_SHIFT 2
/* 6 bits for MSI number */
#define COMMAND_READ BIT(8)
#define COMMAND_WRITE BIT(9)
#define COMMAND_COPY BIT(10)
#define PCI_ENDPOINT_TEST_STATUS 0x8
#define STATUS_READ_SUCCESS BIT(0)
#define STATUS_READ_FAIL BIT(1)
#define STATUS_WRITE_SUCCESS BIT(2)
#define STATUS_WRITE_FAIL BIT(3)
#define STATUS_COPY_SUCCESS BIT(4)
#define STATUS_COPY_FAIL BIT(5)
#define STATUS_IRQ_RAISED BIT(6)
#define STATUS_SRC_ADDR_INVALID BIT(7)
#define STATUS_DST_ADDR_INVALID BIT(8)
#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0xc
#define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10
#define PCI_ENDPOINT_TEST_LOWER_DST_ADDR 0x14
#define PCI_ENDPOINT_TEST_UPPER_DST_ADDR 0x18
#define PCI_ENDPOINT_TEST_SIZE 0x1c
#define PCI_ENDPOINT_TEST_CHECKSUM 0x20
static DEFINE_IDA(pci_endpoint_test_ida);
#define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
miscdev)
static bool no_msi;
module_param(no_msi, bool, 0444);
MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test");
enum pci_barno {
BAR_0,
BAR_1,
BAR_2,
BAR_3,
BAR_4,
BAR_5,
};
struct pci_endpoint_test {
struct pci_dev *pdev;
void __iomem *base;
void __iomem *bar[6];
struct completion irq_raised;
int last_irq;
/* mutex to protect the ioctls */
struct mutex mutex;
struct miscdevice miscdev;
enum pci_barno test_reg_bar;
size_t alignment;
};
struct pci_endpoint_test_data {
enum pci_barno test_reg_bar;
size_t alignment;
bool no_msi;
};
static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test,
u32 offset)
{
return readl(test->base + offset);
}
static inline void pci_endpoint_test_writel(struct pci_endpoint_test *test,
u32 offset, u32 value)
{
writel(value, test->base + offset);
}
static inline u32 pci_endpoint_test_bar_readl(struct pci_endpoint_test *t
到了这里,关于PCIE那些事之linux下EP驱动实现方式二的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!