博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SylixOS PCI BAR寄存器
阅读量:7117 次
发布时间:2019-06-28

本文共 3286 字,大约阅读时间需要 10 分钟。

<ol>

<li>
<div>
<span style="color:#17365d; font-size:15pt"><strong>PCI BAR简介</strong></span>
</div>
<p>
PCI设备都有独立的配置空间,HOST主桥通过配置读写事务访问这段空间。PCI设备的配置空间大小为256字节,其中头部64字节为PCI标准规定,剩余部分为PCI设备自定义的。PCI配置空间头部包含6个BAR(Base Address Registers)寄存器,BAR寄存器保存了PCI设备使用的地址空间的类型(Memory 空间或者I/O 空间),基地址以及其他属性。其中基地址保存的是该设备在PCI总线域中的地址,但在x86中一般与存储器域地址直接相等。
</p>
<p>
PCI设备复位之后,该寄存器将存放PCI设备需要使用的基址空间大小,这段空间是I/O空间还是Memory空间,如果是Memory空间该空间是否预取。当BAR寄存器映射到Memory空间时,Bit 0等于0,如图1.1所示。当BAR寄存器映射到I/O空间时,Bit 0等于1,如图1.2所示。
</p>
<p style="text-align:center">
<img src="" alt="" />
</p>
<p style="text-align:center">
<span style="font-size:9pt"><span style="font-family:黑体">图</span><span style="font-family:Arial"> 1.1 Memory Space</span><span style="font-family:黑体">的</span><span style="font-family:Arial">BAR</span><span style="font-family:黑体">寄存器</span><span style="font-family:Arial"></span></span>
</p>
<p>
 
</p>
<p style="text-align:center">
<img src="" alt="" />
</p>
<p style="text-align:center">
<span style="font-size:9pt"><span style="font-family:黑体">图</span><span style="font-family:Arial"> 1.2 I/O Space</span><span style="font-family:黑体">的</span><span style="font-family:Arial">BAR</span><span style="font-family:黑体">寄存器</span><span style="font-family:宋体"></span></span>
</p>
<p>
I/O 空间是x86系统上面的专用空间,与内存独立编址,使用专用指令进行读写。现在的I/O空间大小是64KB,从0x0000到0xFFFF,可以供设备使用。目前多数PCI设备都不支持I/O空间,而仅支持Memory空间,但是仍有部分PCI设备同时包含I/O空间和Memory空间。
</p>
<p>
系统软件对PCI总线进行配置时,首先获得BAR寄存器中的初始化信息,之后根据处理器系统的配置,将合理的基地址写入相应的BAR寄存器中。系统软件还可以使用该寄存器,获得PCI设备使用的BAR空间的长度,其方法是向BAR寄存器写入0xFFFF_FFFF,之后再读取该寄存器。
</p>
</li>
<li>
<div>
<span style="color:#17365d; font-size:15pt"><strong>技术实现</strong></span>
</div>
<p>
当BAR寄存器映射到Memory空间时,I/O地址空间是物理主存的一部分,对于编程而言,我们只能操作虚拟内存,所以,访问的第一步就是要把设备所处的物理地址映射到虚拟地址。然后,我们可以直接通过指针访问这些地址,一般的使用过程如程序清单2.1所示。
</p>
<p style="text-align:center">
<span style="font-size:9pt"><span style="font-family:黑体">程序清单</span><span style="font-family:Arial"> 2.1 Memory</span><span style="font-family:黑体">资源使用流程</span><span style="font-family:Arial"></span></span>
</p>
<p>
</p>
<pre name="code" class="cpp"> hResource = API_PciDevResourceGet(hPciDevHandle, PCI_IORESOURCE_MEM, 0);
if (!hResource) {
return (PX_ERROR);
}

ulBaseAddr = (ULONG)(PCI_RESOURCE_START(hResource));stBaseSize = (size_t)(PCI_RESOURCE_SIZE(hResource));pvBaseAddr = API_PciDevIoRemap((PVOID)ulBaseAddr, stBaseSize);if (!pvBaseAddr) {    return  (PX_ERROR);}

</pre>

<br />
当BAR寄存器映射到I/O空间时,有2种访问途径,即I/O映射方式(I/O - mapped)和内存映射方式(Memory - mapped)。前一种途径不映射到内存空间,直接使用in8/out8之类的函数进行访问I/O端口;后一种途径是先把I/O端口映射到I/O内存,再使用访问I/O内存的函数来访问I/O端口。其中第一种途径的使用流程如程序清单2.2所示。
<p>
</p>
<p style="text-align:center">
<span style="font-size:9pt"><span style="font-family:黑体">程序清单</span><span style="font-family:Arial"> 2.2 I/O</span><span style="font-family:黑体">资源使用流程</span></span>
</p>
<pre name="code" class="cpp"> hResource = API_PciDevResourceGet(hPciDevHandle, PCI_IORESOURCE_IO, 0);
if (!hResource) {
return (PX_ERROR);
}

ulBaseAddr = (ULONG)(PCI_RESOURCE_START(hResource));stBaseSize = (size_t)(PCI_RESOURCE_SIZE(hResource));out8(0x1, ulBaseAddr + 0x10);

</pre>

<br />
<span style="font-family:Arial"></span>
<p>
</p>
</li>
<li>
<div>
<span style="color:#17365d; font-size:15pt"><strong>参考资料</strong></span>
</div>
<p>
</p>
</li>
</ol>

转载于:https://blog.51cto.com/12557713/2043939

你可能感兴趣的文章
Golang、python中的字符串、slice、list性能研究。
查看>>
我的友情链接
查看>>
SQLite Administrator 中文乱码的问题
查看>>
某网贷平台遭受***
查看>>
ElasticSearch 查询
查看>>
Zabbix通过JMX监控tomcat
查看>>
第七天 date
查看>>
整数数字转读音
查看>>
《大话设计模式》读书总结
查看>>
zabbix_proxy部署
查看>>
CentOS 6.5 apache源码安装2.0版
查看>>
文件属性设置常量
查看>>
如何理解阻塞和非阻塞同步和异步
查看>>
马哥LINUX高薪LINUX高薪就业入门教程-虚拟机篇幅-学习笔记-11
查看>>
杭电 hdu 2503
查看>>
ie6下png透明
查看>>
linux里边的显示结果有乱码(输入LANG=en无效)
查看>>
Citrix XenDesktop发布Centos 7.2桌面(三)--基本配置Centos7.2
查看>>
移动开发必备!15款jQuery Mobile插件
查看>>
es6从零学习(三):Class的基本用法
查看>>