自闭症康复网,内容丰富有趣,生活中的好帮手!
自闭症康复网 > PCI总线---深入理解PCI总线

PCI总线---深入理解PCI总线

时间:2018-10-07 11:25:54

相关推荐

PCI总线---深入理解PCI总线

补充:

PCI/PCIe基础——配置空间:

/jiangwei0512/article/details/51603525

8.1深入理解PCI总线

8.1.1PCI设备工作原理

8.1.2 PCI总线域

8.1.3PCI资源管理

为了管理PCI设备的I/O端口和I/O内存,内核定义了一个resource结构:

代表I/O端口的resource :

struct resource ioport_resource = {.name= "PCI IO",.start= 0,.end= IO_SPACE_LIMIT,.flags= IORESOURCE_IO,};

ioport_resource起始地址为 0 ,结束地址 0xffff ,这个变量定义了全部的I/O端口地址空间,每个PCI设备新加入系统,都要检查它的配置空间的I/O端口的结束地址是否大于0xffff ,和现存的设备是否冲突,是否可以插入I/O端口地址空间。

I/O内存的resource结构:

struct resource iomem_resource = {.name= "PCI mem",.start= 0,.end= -1,.flags= IORESOURCE_MEM,};EXPORT_SYMBOL(iomem_resource);

I/O内存需要映射到主机内存地址空间,所以结束地址为-1。当PCI设备加入系统的时候,检查它的配置空间的I/O内存和其他设备是否冲突,是否可以插入I/O内存地址空间。

8.1.4PCI配置空间读取和设置

第3章,PCI设备的读取通过I/O指令读一个特殊的I/O端口空间来完成。内核提供了一个pci_raw_ops结构来控制配置空间的读写。这个结构的读写和函数通常被设置为pci_confl_read函数和pci_confl_write函数,通过它们执行对PCI配置空间的读写。

/include/linux/pci.h

struct pci_raw_ops {int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,int reg, int len, u32 *val);int (*write)(unsigned int domain, unsigned int bus, unsigned int devfn,int reg, int len, u32 val);};

read和write函数指针的调用进行读写操作;

分析pci_confl_read函数对PCI配置空间的读取过程如下所示:

static int pci_conf1_read(unsigned int seg, unsigned int bus,unsigned int devfn, int reg, int len, u32 *value){unsigned long flags;if ((bus > 255) || (devfn > 255) || (reg > 4095)) {*value = -1;return -EINVAL;}raw_spin_lock_irqsave(&pci_config_lock, flags);outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);switch (len) {case 1:*value = inb(0xCFC + (reg & 3));break;case 2:*value = inw(0xCFC + (reg & 2));break;case 4:*value = inl(0xCFC);break;}raw_spin_unlock_irqrestore(&pci_config_lock, flags);return 0;}

pci_conf1_read函数首先往I/O端口0xCF8写入一个PCI地址,然后从I/O端口 0xCFC读取该地址的配置信息。

如果觉得《PCI总线---深入理解PCI总线》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。