`
yuanjinxiu
  • 浏览: 657951 次
文章分类
社区版块
存档分类
最新评论

龙芯软件开发(31)-- PCI设备查找细节

 
阅读更多
这段时间,又在对龙芯盒子的PCI的总线进行编程。目前有了一点点进展,发现PCI总线也是很复杂的东西。由于所有其它外设都是挂在PCI总线上,如果要对外设进行编程,就得对PCI比较了解,并且可以对它编程。
PCI总线是一条平等的总线,所有设备都是平等的。在某一时刻会有一个设备是主设备。PCI的设备是一棵树的结构,以CPU为根,桥设备为树干,其它设备为叶子。由于PCI的设备是即插即用的,因此它的总线有多少设备不是固定的,那么它又是怎么样发现所有的设备的呢?它就是通过枚举所有设备,也就是由总线上寻找所有设备,比如从总线0开始,就会找到一个桥设备,这个桥设备就是在北桥那里。然后通过这个总线,就可以向下查找,就会找到南桥设备,找到显示卡设备,找到USB的主控器等等。PCI的设备为了能有自动配置的功能,就需要在固定的位置里放置一些寄存器。在PCI的规范里,定义了一段叫做配置空间的寄存器组,CPU就是通过北桥里的寄存器设置,然后根据总线号和设备号就会到PCI设备的第一个功能设备。接着读取PCI配置空间里的寄存器,就可以知道这个PCI设备是做什么使用了,这个就是class编码。比如龙芯里的USB的主控器的分类编码就是0x0C031043,从这个分类码中的0C03就可以知道它是USB的设备,后面的10说明它是OHCI协议接口,43是USB主控器的版本。这样就可以分类不同的设备了。
找到了设备之后,就是需要对它编程。而编程,就需要对寄存器的操作。那么PCI设备的寄存器在那里呢?原来PCI设备的配置空间里就定义了这个设备的访问方式,比如是通过IO空间方式访问,还是通过内存映射的方式访问呢。在配置空间里就会找到相应的基地址寄存器,比如在龙芯电脑的USB基地址就是通过0x10这个寄存器读取的,寄存器的大小是4字节。只要把这个寄存器的值读取出来,然后再作判断它是IO方式,还是内存映射方式。如果是内存映射方式,就需要把这个设备的基址和系统内存空间的基址加起来,才能形成系统内存空间的地址。比如在龙芯盒子里的就是这样:
0xB000_0000 + 0x0600_0000.
前面一个是系统IO访问的基址,后面一个是PCI设备的基址。
通过上面的查找后,就可以定义设备的基地址,这样就可以对它进行编程了。但目前的系统,还是采用中断的方式的,因此还需要读取它的中断设置,才知道这个设备是连接到那个中断线上,以便在8259A那里知道是什么设备产生的中断。
这样就可以进行设备的驱动程序的编写了。在这里总结一下,PCI设备有三个空间:
配置空间,IO空间,内存空间。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics