我知道PCI配置空间中的基址寄存器(BAR)定义了PCI地址的起始位置,但是这个区域的大小是如何确定的呢?
当然,这是硬件的一个属性,因为只有它知道它可以处理的地址空间有多大。但是,我似乎在PCI配置结构中看不到条大小字段。
发布于 2016-09-21 21:51:50
首先,条大小必须是2的幂(例如,1 KiB,2 MiB),并且每个区域必须在存储器中对齐,使得基地址的低log2(size)
位始终为零。例如,假设一个端点有一个4 KiB的内存区,其地址范围为0-0xfff
。主机可能会将此区域的起点重新映射到f.x。通过写入BAR寄存器实现0x1000
或0xabcd000
,但不写入0x1080
或0xabcd100
。
写入BAR寄存器时,端点将忽略LSB,并在读取时始终返回零。因此,将0xffffffff
写入寄存器,然后读回该值,即可指示区域的大小。对于4 KiB示例,它返回0xfffff00X
(低4位是保留的,参见规范)。确定大小的步骤:
将低四位清除为0,并将所有32位(0xfffff000
)
0xfff
)
0x1000 = 4096 bytes
)
这也适用于64位区域。下一个基址寄存器的值形成基地址的MSB。这在PCI 3.0规范的6.2.5.1节中进行了描述。
发布于 2013-09-26 22:20:14
在OSDev Wiki上找到了答案
要确定PCI设备所需的地址空间量,必须保存条形图的原始值,将全为1的值写入寄存器,然后将其读回。
发布于 2016-02-05 03:14:52
PCIe设备可以具有类型0(端点)或类型1( RC或交换机或网桥)配置空间。
--Type-0设备总共可以有6个BARs,而Type-1只能有2个BARs。
--BAR提供有关设备所需地址空间的信息。
--每个条形为32位,其中前4位3:0始终为只读。
-- 2^(最低有效位起最后一个读/写位的位置)=特定条码所需的地址窗口。
如何知道任何栏所代表的区域的地址窗口或大小:
1)最初读取任何条形图(假设本例中为BAR0 ),我们得到的值是32'h0000_000F。(记住:最后4位是只读的!!)
2)将所有1写入BAR0。
3)再次读取BAR0,假设我们得到的值为32'hFFFF_000F。因此,位位置16是最低有效的R/W位。因此BAR0所需地址空间将为2^16。
https://stackoverflow.com/questions/19006632
复制相似问题