3.7 PCIE的BAR是什么?为什么及怎么用


这是剖析PCIE协议的第17篇文章

内容简介

2024-01-29

    全文共1279字,阅读大约需要4分钟,bar寄存器算是配置项里面比较关键内容,本节内容就介绍下bar寄存器是什么?为什么需要它?我们该如何使用它?

01

为什么需要bar寄存器

    如下图标红的两部分几位bar寄存器,那么为什么需要有这个东西呢?

    一方面这还是和CPU、操作系统的机制有关,它们不允许PCI设备自己在内存中划拉片地方供自己使用,而是必须由系统统一分配。

    另一方面PCI设备需要一定内存空间来存储自身需要的些数据,例如功能相关的配置数据,而且不同设备不同功能的情况下需要的空间大小还不一致,所以就有了bar寄存器了,用于对不同设备进行量身定制内存空间

    PCI设备有6个bar寄存器,可以启用全部或其中几个,一旦Bar寄存器启用后,这个bar寄存器就与内存建立了关系,主机就可以通过BARs中所写入的地址范围进行访问。任何时候,当设备发现一个请求事务的地址是映射到自己的一个BAR时,它就会接收这个请求事务,因为它自己就是这个请求的目标设备。


02

bar寄存器如何使用?

    根据上图可知,type0和type1拥有的bar数量是不一样的,为什么不一样放在后面说,bar在使用上可分为三种,分别是

1、32bit内存地址空间请求

2、64bit内存地址空间请求

3、IO地址空间请求

但在配置机制上是一致的,均是分为三个步骤,

1

第一步

    主机发起配置请求向目标PCIE设备的目标bar寄存器,对这个bar寄存器进行1操作。

2

第二步

    主机发起通过读配置请求读取目标PCIE设备的目标bar寄存器的值,由于有写bit为主机是无法改写的,在商店就强制为固定值了,所以主机回读的值部分不是1。

3

第三步

    主机根据读取的值判断bar请求内存空间的大小并为其分配,并将起始地址写入目标bar寄存器,这就完成了两个功能,一是确定基地址,二是确定了寻址范围。

    具体是如何实现的呢?接下来以32bit内存地址空间请求为例详细看下bar寄存器的结构

    这里提到了预取和非预取,对于PCI来说,预取功能能提升性能,但在PCIE上不是很明显,只不过将此继承了过来,所以可以先忽略,等后面用到了再说了。


03

拿32bit的bar空间申请距离

    如下图是32bit非预取内存请求的申请过程描述,申请4KB大小的空间。

    bar寄存器的存在的目的是告诉使用这我需要多大的空间,在诉说之前自身肯定得先知道并做一定设置,这种设置呢就是将某些位写0,且不可更改。

    例如下图的(1)所描述的“Uninitialized bar”,bit0~bit3是固定内容,bit11~bit4的预设0就是表示申请内存大小的,12bit写0表示申请内存空间位4KB,因为2^12=4096嘛,如果bit13也是0,那就表示想要申请8KB的内存空间。

    那么为啥要这样搞呢?主机又是怎么知道的呢?

    首先说,主机是怎么知道的,首先会对bar寄存器各个bit位都写1(0XFFFFFFFF)然后再回读。对于我们这个例子回读内容就是0XFFFFF000,通过bit3~0知道了申请内存空间的属性,又因为bit12是1,所以知道了申请内存大小位4KB。

    随后主机再把内存基地址写入bar寄存器,例如下图的0xF9000000,如此主机就知道了这个设备的对应功能的bar0申请4KB内存。

    最后说,为什么要这样做,在我看来,这样做即实现了我们的目的,也节省了需要的配置字。我们需要告知主机需要多大的空间和属性,可以单独占一个字段,让主机读就行了。但再发TLP包时,主机寻址也需要知道目的地址,这样还需要一个字段。现在将两字段合一的,而且目的还实现了。

04

另外两种bar寄存器的使用

    如下图是对64bit的设置,申请一个64MB内存大小的过程,与32bit相比就是基地址更大了些。

    入下图是申请一个256Byte大小的过程,也就是bit8~2是固定为0,其中bit0为1表示是IO请求。






欢迎关注公众号点击【资料下载】领取相关资料







快来扫描下方二维码关注公众号,领取站内所有相关资料,所有哦~

有建议、有需求、有疑问、联系我

<