大话PCIe:设备枚举

原创 2017年07月08日 22:46:17

人的一生是一个不断认识自我,发展自我的过程。

认识PCIe设备的枚举过程需要以下知识:

  1. 拓扑结构
  2. 设备的表征及配置空间的访问
  3. BAR空间的含义和访问

其中第1/2点在总线结构与配置空间已经介绍过了,第3点在BAR空间和TLP也已经进行过详细的介绍,可以说是万事具备。接下来涉及的过程有以下几个:

  1. 根据深度优先搜索进行设备总线号的分配
  2. BAR空间的映射和简单访问测试

上面就是枚举过程中做的事情了。

一、基于深度优先搜索的总线号分配

1.1 原理阐述

每一个switch代表一级bus,挂在该switch下的所有设备(包括SW和EP)都属于这级bus。

SW配置空间中的总线号有Primary Bus、Secondary Bus和Subordinate Bus。含义如下

总线号 含义
Primary Bus 当前级别的总线号,从该设备往下的所有设备都属于primary bus
Secondary Bus 下一级总线号
Subordinate Bus 从当前级别总线开始最远端的总线号

现在假设有一个tlp过来,首先瞅了瞅当前switch的subordinate bus number,发现比自己的bus number还小,那就很知趣的不往这级bus上路由了;如果发现subordinate bus比自己的大,她就知道我要去的地方在这一级bus上,然后就继续往secondary bus路由,继续重复上述过程。如果primary bus number等于tlp自己的bus number,那么这一级bus就是tlp的归宿了。上述这个tlp的路由过程由SW完成。

1.2 代码举例

init BUS[0]
push BUS[0] to bus_stack

while bus_stack != NULL:
    bus = pop(bus_stack)
    while find_next_sw(bus) is true:
        child.prim_bus = bus.prim_bus
        child.second_bus = bus.prim_bus+1
        child.subord_bus = bus.second_bus
        push(child)
    // find an EP
    update_subord_bus(bus_stack)

这个代码是刚敲的(风格似乎有点python的感觉),只是表示基于深度优先搜索的配置PCIe设备bus number的算法,其中的find_next_sw负责找到当前sw下游的设备(如果发现设备0是EP,那么应该继续根据是否是多功能设备来搜索设备1,2,…,直到找到SW,或者没有)。如果发现SW,则继续入栈,否则(是EP)更新当前栈上所有设备的subordinate bus number为最后一个SW的primary bus number,然后栈顶弹出SW,进行下一个分支的深度搜索。

二、映射BAR空间

前面的枚举过程是在链路上通过发送配置读写请求来进行的,PCIe协议规定:访问SW配置要通过类型1的配置请求,访问EP配置要通过类型0的配置请求。

那么如果我们想要访问PCIe设备内部的mem空间呢?就要通过mem rd/wr请求。请求里面包含了需要访问的mem地址,PCIe网络根据这个地址把tlp路由到对应的设备上去处理。所以我们需要在系统枚举的阶段配置好各个设备的BAR空间范围,这样mem/io tlp就能根据地址是不是在BAR范围内来判断是不是应该访问该设备。

这里再次注意:这里的tlp中的地址和系统ram空间的地址没有必然联系,只是PCIe内部分配的地址(上一篇文章已经提到过这个点了)。

而BAR的配置地址是在configuration空间的,所以在枚举阶段我们通过发送cfg rd/wr tlp来配置BAR就行,具体关于BAR的介绍在大话PCIe:BAR空间和TLP中有说明了。

上一篇文章遗留了两个问题,到这里可以进行解答了。

一是关于配置空间及其地址的问题。

每个设备都有其配置空间,而且是固定地址0~4096 Byte,前面64字节是PCI兼容的。这个配置空间的地址和外部总线地址并没有什么关系。通过指定tlp中的bus number、device number、function number+偏移地址(这个就是写到tlp中的地址)就可以访问到对应设备的配置空间。

二是关于如何发起cfg tlp的问题。

上篇文章介绍了一个功能模块ATU,这是和总线对接的一个模块,除了地址转换之外,还根据配置产生tlp。一般是这样的,系统会为PCIe设备预留256MB空间,访问这256MB空间的时候就会触发产生一个mem request tlp,然后ATU根据配置(如果配置了cfg type)将其转换成cfg request,其中的target地址就写入了tlp中。然后PCIe网络就将这个tlp路由到对应地址的设备功能上了。举例如下:

系统ram空间地址基址为0x40000000,ATU配置source address为0x40000000,target address为0x00000000,ATU type = cfg 0,size=0x10000000(256MB),那么CPU读0x40000000地址的时候触发了一个mem read request,经过ATU之后产生了一个cfg type 0 rd的request;同样的,如果往0x40000000写一笔数据,就会触发mem write request,处理过程也是类似的。如果访问0x40100000,转换后的target地址就成了0x100000。

关于PCIe设备的枚举过程内容都在这里了。接下来重点介绍PCIe dma和MSI(-X)中断。

下篇预告: PCIe设备dma和MSI(-X)

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

大话PCIe:总线结构与配置空间

把有限的精力花在真正有价值的事情上。 一、网络拓扑与设备端口上一篇已经讲到构成PCIe网络的三个角色:RC、SW和EP。其实这整个网络给人感觉就像乐高积木,上一级设备的下游端口接下级设备的上游端口,然...

访问PCIe BAR空间

对BAR空间以及配置空间的访问做一个系统的总结,其实就是在回答以下几个问题: 1. PCIe中四种tlp和BAR空间的关系是怎样的? 2. tlp是怎么发起的? 3. tlp是怎么到相应的下游设备的...

大话PCIe:BAR空间和TLP

上一篇文章中写到每个PCIe的function都有自己的configuration space,其实就是配置寄存器了(这个当然是要有的了,不然软件要怎么玩?只不过PCIe的配置寄存器要通过tlp才能去...

大话PCIe: 发展与应用

介绍PCIe的基本概念,用途。 一、串行总线PCIe作为串行总线的一种,它的发展必然和另一种总线架构密不可分:并行总线。早先,人们普遍认为提高数据位宽就能提高数据传输速率,这是谁都会想到的问题,早期的...

大话PCIe:DMA机制

PCIe控制器也提供DMA(Direct Memory access)功能,用来批量地异步数据传输。 一、PCIe中的DMA读和写 假设现在

PCI设备的DMA映射操作详解

上周认真学习了LDD3第15章直接内存访问部分,这周调试PCI的网卡和视频采集卡,结合代码对DMA映射有了进一步的理解,这里按照LDD315章的顺序总结一下,记一下笔记,以后忘了再来翻,本人刚毕业1年...

Linux下PCIe驱动以及DMA机制

1. 驱动程序作用: ·        设备驱动程序向应用程序屏蔽了硬件在实现上的细节,使得应用程序可以像操作普通文件一样操作外部设备。Linux操作系统抽象了对硬件的处理,可以使用和操作文件相同的...

FreeRTOS任务调度研究

这篇文章不介绍FreeRTOS移植,只是最近针对多核ARM Cortex系列平台做了移植后的一篇总结研究文章。所以不涉及对FreeRTOS整体的介绍,而只是分析任务调度这一块的机制。对应的Demo参考...

PCI/PCIe基础——配置空间

PCI/PCIe基础——配置空间

大话PCIe:Linux访问PCIe空间

Linux在枚举PCIe设备的过程由内核中的PCI框架负责,在EP配置完成之后,驱动通过以下接口访问PCIe空间,原理参考前文《大话PCIe:设备枚举》一、访问配置空间相关接口位于drivers/pc...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)