免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: albcamus

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

论坛徽章:
0
发表于 2008-09-01 12:42 |显示全部楼层
X86上把 这些区间 放在物理地址空间中靠近4G的地方, 是硬性限制, 还是仅仅Linux的习惯?

PCI spec上说:
Table 6-4: Memory Base Address Register Bits 2/1 Encoding
  Bits 2/1                         Meaning
     00     Base register is 32 bits wide and mapping can be
            done anywhere in the 32-bit Memory Space.
     01     Reserved46
     10     Base register is 64 bits wide and can be mapped
            anywhere in the 64-bit address space.
     11     Reserved

论坛徽章:
0
发表于 2008-09-01 16:41 |显示全部楼层
原帖由 albcamus 于 2008-9-1 12:42 发表
X86上把 这些区间 放在物理地址空间中靠近4G的地方, 是硬性限制, 还是仅仅Linux的习惯?

PCI spec上说:
Table 6-4: Memory Base Address Register Bits 2/1 Encoding
  Bits 2/1                       ...

x86的spec上我没看到过有这样的规定,我估计有这个规定也是在北桥的spec上。不过这应该没有硬性规定,不然就不会提供寄存器给你改了。
应该是BIOS传统上是这样分配的,windows的地址也在这个范围

论坛徽章:
0
发表于 2008-09-01 17:08 |显示全部楼层
原帖由 zx_wing 于 2008-9-1 16:41 发表

x86的spec上我没看到过有这样的规定,我估计有这个规定也是在北桥的spec上。不过这应该没有硬性规定,不然就不会提供寄存器给你改了。
应该是BIOS传统上是这样分配的,windows的地址也在这个范围


应该是这样的。 而且PCI的region到底映射在哪个物理地址区间, 估计在BIOS之后, Linux还是可以改的。

看了一下G45 主桥datasheet, 主桥硬件本身并不保证各个PCI的region之间互不重叠, 也不保证它们和RAM是否重叠: 都需要由configuration software来保证。 这里的configuration software,我猜测BIOS和linux都可以是。

论坛徽章:
0
发表于 2008-09-01 17:08 |显示全部楼层
原帖由 zx_wing 于 2008-8-31 20:18 发表

我明天看看代码,我看的也是3.0的PCI spec,应该是我们什么地方理解错了。


这个问题搞懂了吗? 我还在糊涂中。。

论坛徽章:
0
发表于 2008-09-01 17:25 |显示全部楼层
原帖由 albcamus 于 2008-9-1 17:08 发表


应该是这样的。 而且PCI的region到底映射在哪个物理地址区间, 估计在BIOS之后, Linux还是可以改的。

看了一下G45 主桥datasheet, 主桥硬件本身并不保证各个PCI的region之间互不重叠, 也不保证它们和 ...

OS是可以改的,hotplug时可能会重排MMIO空间,这个时候就就要改。
实际上linux没用BIOS那一套,它起来的时候都是改了的

论坛徽章:
0
发表于 2008-09-01 17:26 |显示全部楼层
原帖由 albcamus 于 2008-9-1 17:08 发表


这个问题搞懂了吗? 我还在糊涂中。。

今天有问了一下,大概有点懂了,不过上班没时间总结一下。
回家细想一下再发上来。应该就是flw2说的那样

论坛徽章:
0
发表于 2008-09-01 23:02 |显示全部楼层
原帖由 zx_wing 于 2008-9-1 17:26 发表

今天有问了一下,大概有点懂了,不过上班没时间总结一下。
回家细想一下再发上来。应该就是flw2说的那样

哇哇哇啊哇!!!!!!!!还是没想通!!!!
举个例子:
某个寄存器起始地址是base = 0xFF00 0000,结束地址是end = 0xFFFF 0000,那么长度就是size = 0xFFFF 0000 - 0xFF00 0000 = 0xFF 0000
按照linux代码里的算法:
size = (base & ~(base - 1) ) - 1 就是对的
但按spec里的说法应该是写全1进去,读回来的值中,设备care的地址线bit为1.
这里哪些bit是设备care的呢,读回来的是0xFFFF 0000?还是其它什么值呢?

论坛徽章:
0
发表于 2008-09-02 09:28 |显示全部楼层
原帖由 zx_wing 于 2008-9-1 23:02 发表 哇哇哇啊哇!!!!!!!!还是没想通!!!!举个例子:某个寄存器起始地址是base = 0xFF00 0000,结束地址是end = 0xFFFF 0000,那么长度就是size = 0xFFFF 0000 - 0xFF00 0000 = 0xFF 0000按照linu ...


spec里没有end寄存器,这个end应该是你自己捏造的
写进全1读出来为0xff000000,我上面贴的有这个操作
        next = pos+1;
        res = &dev->resource[pos];
        res->name = pci_name(dev);
        reg = PCI_BASE_ADDRESS_0 + (pos << 2);
        pci_read_config_dword(dev, reg, &l);
        pci_write_config_dword(dev, reg, ~0);
        pci_read_config_dword(dev, reg, &sz);
        pci_write_config_dword(dev, reg, l);
        if (!sz || sz == 0xffffffff)
            continue;
        if (l == 0xffffffff)
            l = 0;
        raw_sz = sz;
        if ((l & PCI_BASE_ADDRESS_SPACE) ==
                PCI_BASE_ADDRESS_SPACE_MEMORY) {
            sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK);

论坛徽章:
0
发表于 2008-09-02 09:38 |显示全部楼层
原帖由 flw2 于 2008-9-2 09:28 发表


spec里没有end寄存器,这个end应该是你自己捏造的
写进全1读出来为0xff000000,我上面贴的有这个操作
        next = pos+1;
        res = &dev->resource[pos];
        res->name = pci_name(dev);
...

我没说end是个寄存器,我是在假设区间的大小。
你确定读出来是0xff00 0000,那这个和读出来的base有什么区别?既然这样直接用base就好了,为啥还要写全1再读?
代码根本就没反应出读出来的值是多少,它用的就是base值

论坛徽章:
0
发表于 2008-09-02 09:45 |显示全部楼层
恩,区间大小貌似应该是2的倍数,写全1而不是直接用base肯定有原因的,不过我不知道(比如不知是否是因为如果直接用base,那么一旦更改,即配置了,再也找不到原始的值了),而设备会根据这个全1来给出设备支持的区间长度。所以什么时候都可用
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP