免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: albcamus
打印 上一主题 下一主题

PCI规范里BAR寄存器的一段话看不懂 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2008-09-02 09:53 |只看该作者
原帖由 flw2 于 2008-9-2 09:45 发表
恩,区间大小貌似应该是2的倍数,写全1而不是直接用base肯定有原因的,不过我不知道(比如不知是否是因为如果直接用base,那么一旦更改,即配置了,再也找不到原始的值了),而设备会根据这个全1来给出设备支持 ...

写全1读出来的不是base,刚才终于问到了。现在忙,待会来回

论坛徽章:
0
22 [报告]
发表于 2008-09-02 16:09 |只看该作者

回复 #21 zx_wing 的帖子

帮你回答算了

PCI spec里面有一句话,叫“don't care bit”, 就是说,不管写什么进去,这些bit读出来的值都是0.
换句话说,写1进去读回来是0,那么就表示这个位是“don't care”的,也就决定了PCI Mem bar的长度最多只有2G

写全1进去读回来的值不是base的值,因为base只要求按“长度大小”对齐,比如大小为1M的base可能是0x0FF00000,写全1进去读回来的就是0xFFF0000了(没有考虑低4bit的值)

评分

参与人数 1可用积分 +6 收起 理由
Solaris12 + 6 我很赞同

查看全部评分

论坛徽章:
0
23 [报告]
发表于 2008-09-02 16:14 |只看该作者

回复 #11 albcamus 的帖子

>>X86上把 这些区间 放在物理地址空间中靠近4G的地方, 是硬性限制, 还是仅仅Linux的习惯?

似乎放在4G附近是最好的选择了吧

论坛徽章:
0
24 [报告]
发表于 2008-09-02 17:28 |只看该作者
原帖由 bluesky_jxc 于 2008-9-2 16:09 发表
帮你回答算了

PCI spec里面有一句话,叫“don't care bit”, 就是说,不管写什么进去,这些bit读出来的值都是0.
换句话说,写1进去读回来是0,那么就表示这个位是“don't care”的,也就决定了PCI Mem bar的 ...

哦,看错了,你搞懂了的。
关键是在于“按长度对齐”,回去再re。

[ 本帖最后由 zx_wing 于 2008-9-2 17:31 编辑 ]

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
25 [报告]
发表于 2008-09-02 17:56 |只看该作者
头回用linux回帖,真她娘鸡动.

PCI的bar有这么个2G的限制,关键就在于flw贴出的,那段计算size的代码中

size只能为1*16, 2*16, 4*16, 8*16, 16*16...........128M*16,是个离散的.

即读出来的值,除了低4位没用外; 高28位中,从低往高数,一旦出现为1的位,其他位就全没用了,don't care是指的这样的位. 最多就到1000,0000,0000,0000,0000,0000,0000,xxxx,这是2G.

论坛徽章:
0
26 [报告]
发表于 2008-09-02 22:51 |只看该作者
首先我以前举的那个例子(start =0xFF00 000,end=0xFFFF 0000)是不成立的,不会出现这种情况。spec规定size是2的次方,而此例中size = end - start + 1 =0xFF 0001不对。
关于2G的限制,bluesky_jxc同学已经点出原因了,关键在于BAR的基地址是按BAR长度对齐的
举例来说就是当bar的size是1M时,其基地址只能是1M的倍数,如1M、2M …… 而不会有小于1M的base出现。当BAR的size是2G时,其base也是2G的倍数,对于32bit的BAR来说,这个base只能是2G,不会其他值出现,更不会小于2G。

评分

参与人数 1可用积分 +6 收起 理由
Solaris12 + 6 我很赞同

查看全部评分

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
27 [报告]
发表于 2008-09-02 23:33 |只看该作者
原帖由 flw2 于 2008-8-31 15:28 发表

#define  PCI_BASE_ADDRESS_MEM_MASK    (~0x0fUL)

  1. static u32 pci_size(u32 base, u32 maxbase, u32 mask)
  2. {
  3.     u32 size = mask & maxbase;    /* Find the significant bits */
  4.     if (!size)
  5.         return 0;

  6.     /* Get the lowest of them to find the decode size, and from that the extent.  */
  7.     size = (size & ~(size-1)) - 1;
  8.         ...
  9. }
复制代码



我觉得这个是关键。

这段代码的意思就是,
size = mask & maxbase              // maskbase中最低几位取0(依照spec,是低4bit)
size = (size & ~(size-1)) - 1;       //自bit0向bit31搜索,第一个为1的bit既代表了size大小

低4bit已经为0,所以size只可能为xx....xx10000,xx....xx100000,xx....xx1000000,xx....xx10000000.................
最小16byte,对应xx....xx10000;最大2G,对应0x80000000。


另外为PCI分配物理地址好象没什么限制,依据的就是两个:
1) resource树

2) 一个全局变量,在start_kernel中设置,表示可分配给pci设备的最小物理地址。
无高端内存时,是MAX(rom及ram已占用的地址)以16M向高对齐的一个值;或者有高端内存,是896M+固定的洞

论坛徽章:
0
28 [报告]
发表于 2008-09-03 09:26 |只看该作者
两位说的是类似的, 设备对base只支持高位,就是zx_wing说的
不过pci_size函数更直接,因为查大小和base无关,可以不设置base,也能查大小

论坛徽章:
0
29 [报告]
发表于 2008-09-03 17:10 |只看该作者
原帖由 塑料袋 于 2008-9-2 23:33 发表



我觉得这个是关键。

这段代码的意思就是,
size = mask & maxbase              // maskbase中最低几位取0(依照spec,是低4bit)
size = (size & ~(size-1)) - 1;       //自bit0向bit31搜索,第一个 ...

linux用这种方法来计算size,但并不是写全1进去读出来的值只有一个bit为1哈,而don't care bit是指这个第一个为1的bit前面全部为0的bit。
比如base是0xf000 0000 长度为0x100 0000的BAR,写全1进去读出来的是0xff00 0000。
另外内核分配物理地址的规则来源于E820表,一直想写篇文章介绍E820表是如何描述物理地址空间的,但最近太忙了,等过段时间闲了写写。

评分

参与人数 1可用积分 +6 收起 理由
Solaris12 + 6 我很赞同

查看全部评分

论坛徽章:
0
30 [报告]
发表于 2008-09-03 17:29 |只看该作者
这个问题结合MCH来看比较容易明白,回头再仔细看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP