PCI总线在VxWorks中的实现

来源:互联网 发布:windows平板应用商店 编辑:程序博客网 时间:2024/05/14 09:04
 

PCI总线在VxWorks中的实现

 1194人阅读 评论(0) 收藏 举报
 分类:
 

目录(?)[+]

                                                            PCI总线在VxWorks中的实现

 

1、Overview

在最近发布的BSP中,风河公司基本上都提供了对PCI BUS的支持,本文主要探讨PCI BUS在VxWorks系统中的实现。

2、PCI Address Space and Memory Mapping

PCI BUS有三种地址空间:IO Space、Memory Space and Configuration Space。每个PCI设备都通过Configuration Space中的Base Address Registers(BAR)映射到内存或者IO空间,这样就不用像ISA BUS那样,通过硬件Jumpers来设置板卡的Address。PCI BUS的所有配置基本上都是通过Configuration Space的寄存器来控制的。但是,每个PCI Device都必须先配置才能使用,这意味着PCI Device的基地址和中断都必须被系统分配到资源,并且PCI Device能够对正常的PCI配置操作做出回应。

WRS提供一个名为pciConfigLib.c的标准库给用户访问PCI配置空间,该标准库使用PCI规范中定义的访问机制1和机制2来支持Host-Bridge,风河本身提供的第三个访问机制,名为机制0是针对非标准PCI Bridge的,机制0主要是靠调用BSP包中的特定routine来实现PCI配置空间的read/write的,与此同时,这些特定的routine接口和前面的介绍的机制1和机制2是相同的。pciConfigLib.c提供访问PCI配置空间内任何寄存器的routine,该库同样提供一些用于扫描PCI BUS寻找特定PCI 设备实例的方法,另外该库也提供一些简单的配置接口用于配置简单的PCI设备。

3、PCI Interrupt Handling

PCI 规范并没有详细说明PCI中断信号是如何路由到中断控制器的。每个PCI设备都有4个可用的中断PIN,分别命名为A,B,C和D。每个单功能的PCI设备都被要求使用中断PIN A来产生中断,而对于多功能PCI设备,每个功能使用一个中断PIN,但是根据PCI规范,每个PCI设备最多可提供8个功能,这样就必须两个功能共用一个中断PIN。当产生PCI中断时,PCI中断处理系统需要调用多个中断服务程序,那么最简单的方法就是每个ISR都调用一遍,ISR必须有能力判断该次中断源是否是自己产生的,如果不是,则立即返回,并接着会调用下一个中断服务程序。

pciIntLib.c提供一些routine来挂接多个ISR到一个中断LINE上,该库通过挂接一个特殊的ISR,该ISR会遍历一个中断链表,所有共用同一个中断的ISRs都被放在这个链表中。pciIntConnect()用于将设备的ISR挂接到中断链表上,而pciIntDisConnect()用于删除中断链表上的一个ISR。

例子:

pciInitConnect(Vector, ISR1, PARAM1);

pciInitConnect(Vector, ISR2, PARAM2);

pciInitConnect(Vector, ISR3, PARAM3);

上面3个语句把ISR1,ISR2,和ISR3分别挂接到中断向量为Vector的链表intList里面,那么当中断发生时,会执行下面一个函数:

void sISR(void)

{

       while(intList->next !=NULL)

        {

                (*intList->INT_ISR)(PARAM);/*分别调用ISR1,ISR2,ISR3,没写很具体,只是个大概理解*/

        }

}

4、VxWorks中的PCI 配置策略

在BSP中,必须定义洪INCLUDE_PCI来支持PCI BUS,宏PCI_CFG_TYPE必须定义为一下几种类型:

4.1 静态配置:PCI_CFG_FORCE

这种方式要求程序员必须手动通过数据表、配置宏或者其他方法来配置每个PCI设备,PCI设备的基地址和使用的中断号必须事先知道。

4.2 动态配置:PCI_CFG_AUTO

这种配置方法是最常用的,它通过扫描PCI总线并且给每一个found的设备赋予独立的内存或者IO地址,这也是典型的X86 BIOS的PCI初始化方式。程序员并不需要事先知道分配给PCI设备的系统资源,这个功能主要被实现在pciAutoConfigLib.c模块中。

4.3 未配置:PCI_CFG_NONE

这种方法主要是预留给那些不能使用上面的VxWorks配置方法的设备的。此时,所有的PCI设备都是在VxWorks内核启动之前配置好的,这种方法的困难在于VxWorks内核并没有在扫描过程中系统分配给PCI设备的资源信息,如果此时启用MMU,则在使用PCI设备之前,必须把PCI设备使用的地址动态映射到MMU。

5、PCI Initialization Sequences

当VxWorks内核起来之后,PCI设备的第一次使用都是必须在调用sysHwInit2()例程之后。但是由于MMU内存映射的初始化和激活是在例程sysHwInit()和sysHwInit2()之间的,所以推荐的PCI初始化顺序为:

  • sysHwInit()       默认的MMU table entries相当于将本地事务映射为PCI事务的HOST-Bridge的访问侧
  • sysHwInit2()    在该例程中,程序员必须静态配置所有的PCI设备,或者调用动态配置routine pciAutoConfig()

6、设备驱动程序初始化

传统的VxWorks的设备驱动模型一般都会设备创建routine called xxxDevCreate(),一般该routine都以设备的基地址和中断号做为参数。对于PCI设备,这种方式只适合于PCI_CFG_FORCE 配置策略,对于其他两种的配置策略,在编译阶段并不知道设备的基地址和中断号,这种情况下,在系统配置PCI设备完毕后,必须首先访问PCI配置空间获取相关的信息并传递给Device Driver。如果Drivers是针对于某些PCI设备的,那么Drivers通过设备的配置地址而不是内存或者IO地址来指定设备也是合乎情理的,但是PCI设备的配置地址并不是绝对和永恒不变的。

如果程序员使用总线号、设备号和功能号来定位地址的话,是可能会出现问题的,因为BIOS在扫描PCI BUS的过程中,会自动给BUS编号。例如某个设备的编号为(2,5,0)可能会由于通过PCI-PCI桥来扩展或者移除PCI设备而变为(1,5,0)。

PCI Device Driver的初始化应该是通过访问设备的配置空间来获取地址和其他对控制设备来说是必须的信息。如果这些信息已成功获取,那么PCI Device Driver的初始化就和以往一样了。在正常的设备操作过程中,不应该去访问PCI的配置空间。现在大多数PCI设备都把配置空间和其他寄存器都映射到内存空间,一般说来,访问Memory or IO Space比配置空间更加高效。

7、Dynamic MMU Mapping

和VME总线的模型一样,PCI主从访问必须根据标准的宏来操作,这些宏定义了BUS之间的对应关系。一般使用3个宏定义来描述两个总线之间的对应关系。

7.1 PCI Master Access Windows

第一个为host side的地址,采用宏PCI_XXX_LOCAL来定义,第二个为remote side 的地址,采用宏PCI_XXX_BUS来定义,第三个为描述内存大小的宏,采用PCI_XXX_SIZE来定义。可以通过设定PCI_XXX_SIZE宏为0来禁止相关的映射。

针对普通的Host-Bridge,从内存映射的角度看,有三种常用的映射方式:第一种为把本地内存访问映射为PCI IO访问,第二种把本地的内存访问映射为PCI MEMIO访问,这种方式是不可以prefectchable的,第三种是把本地的内存访问映射为PCI MEM 访问,这种方式可以prefectchable。由于主桥没有完整的详细规范,因此映射方式还不止这些,也有使用PCI-IACK signaling这种映射方式的。

The following is a typical excerpt from config.h in a typical PCI capable BSP:
/* Master window allows CPU to access PCI I/O addresses */
#define PCI_MSTR_IO_LOCAL 0xC0000000
#define PCI_MSTR_IO_BUS 0x00000000
#define PCI_MSTR_IO_SIZE 0x00010000


/* Master window allows CPU to access PCI Memory addresses (prefetch) */
#define PCI_MSTR_MEM_LOCAL 0x80000000
#define PCI_MSTR_MEM_BUS 0x00000000
#define PCI_MSTR_MEM_SIZE 0x01000000


/* Master window allows CPU to access PCI Memory (non-prefetch) */
#define PCI_MSTR_MEMIO_LOCAL 0x82000000
#define PCI_MSTR_MEMIO_BUS 0x00000000
#define PCI_MSTR_MEMIO_SIZE 0x01000000


/* Master window allows CPU to generate PCI_IACK cycles */
#define PCI_MSTR_IACK_LOCAL 0x8e000000
#define PCI_MSTR_IACK_BUS 0x0e000000

#define PCI_MSTR_IACK_SIZE 0x100

PCI中有三种地址空间:IO空间,配置空间,MEM空间。MEM和MEMIO并不是不同的地址空间,而是不同的总线操作,MEMIO是单纯的寄存器读写,而MEM访问会被翻译成该操作的CACHE类型,CACHE类型指明内存是否提前读取,写数据时是否采用CACHE的“write and invalidate”操作,其实这些都是考虑到CACHE数据完整性的问题。PCI规范并没有详细说明主桥如何把MEM访问映射为PCI总线事务,这是和特定主桥硬件相关的,需要参考主桥的相关手册。

为了访问特定的PCI内存位置,CPU必须该内存位置映射到本地的哪一个地址了,CPU操作都是使用本地地址,而不是设备的PCI地址。把PCI地址转换为本地地址的公式如下:

                                     Local Addr = PCI addr + (PCI_MSTR_XXX_LOCAL - PCI_MSTR_XXX_BUS)

For example:
#define PCI_MEM2LOCAL(x) \
((int)(x) + PCI_MSTR_MEM_LOCAL - PCI_MSTR_MEM_BUS)
#define PCI_MEMIO2LOCAL(x) \
((int)(x) + PCI_MSTR_MEMIO_LOCAL - PCI_MSTR_MEMIO_BUS)
#define PCI_IO2LOCAL(x) \
((int)(x) + PCI_MSTR_IO_LOCAL - PCI_MSTR_IO_BUS)

7.2 PCI Slave Window

上面描述的都是主设备侧的映射方式,使用这些映射方式的主控器都是CPU,Slave Window是被总线上其他设备发起总线事务的目标设备,Slave Window千差万别,但是几乎所有的设备都有至少一种Slave Window来使本地地址对其他PCI设备例如DMA总线主控器或者CPU是可访问的。

/*
* Slave window that makes local memory visible to PCI
* devices
*/
PCI_SLV_MEM_LOCAL /* Local address of window */
PCI_SLV_MEM_BUS /* PCI Bus address of window */
PCI_SLV_MEM_SIZE /* window size,0 means disabled */
/*
* For X86 it is possible to have a slave window mapping
* PCI IO to Local IO
*/

PCI_SLV_IO_LOCAL /* Local address of window */
PCI_SLV_IO_BUS /* PCI Bus address of window */
PCI_SLV_IO_SIZE /* window size,0 means disabled */

对于X86机器,Slave Window将会把PCI IO事务映射为本地总线的IO请求。为了传递一个内存地址给Remote端设备,本地地址必须被翻译为相应的PCI地址,计算本地地址翻译为PCI地址的公式如下:

PCI addr = Local Addr + (PCI_SLV_XXX_BUS - PCI_SLV_XXX_LOCAL)

For example:
#define LOCAL2PCI_MEM(x) \
((x) + PCI_SLV_MEM_BUS - PCI_SLV_MEM_LOCAL)

 

 

某些地方可能会讲的不清楚,我自己感觉都很别扭,主要是英文不好啊。若有错误的地方,请指正哈。

睡觉啦。得意

1
0
 
 

我的同类文章

 
  • VxWorks设备驱动程序开发指南(三)---驱动程序的分类2013-01-24
  • 访问PCIe配置空间using Intel Chipsets2013-01-20
猜你在找
Windows系统内核-保护模式
内核的配置和编译原理-uboot和系统移植第15部分
话说linux内核-uboot和系统移植第14部分
内核的启动过程分析-uboot和系统移植第16部分
从三星官方内核开始移植-uboot与系统移植第17部分
vxworks和Linux pci转串口卡调试
vxworks pci驱动解析
VxWorks PCI配置方法
VxWorks系统PCI设备网卡初始化代码分析
基于vxworks的PCI设备驱动编写
查看评论

  暂无评论

发表评论
  • 用 户 名:
  • yz2010
  • 评论内容:
  • 插入代码
      
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
核心技术类目
全部主题 Hadoop AWS 移动游戏 Java Android iOS Swift 智能硬件 Docker OpenStack VPN Spark ERP IE10Eclipse CRM JavaScript 数据库 Ubuntu NFC WAP jQuery BI HTML5 Spring Apache .NET API HTML SDK IISFedora XML LBS Unity Splashtop UML components Windows Mobile Rails QEMU KDE Cassandra CloudStack FTCcoremail OPhone CouchBase 云计算 iOS6 Rackspace Web App SpringSide Maemo Compuware 大数据 aptech PerlTornado Ruby Hibernate ThinkPHP HBase Pure Solr Angular Cloud Foundry Redis Scala Django Bootstrap
    个人资料
     
    8度空间
     
    • 访问:36779次
    • 积分:660
    • 等级: 
    • 排名:千里之外
    • 原创:29篇
    • 转载:3篇
    • 译文:2篇
    • 评论:6条
    Blog
    • 常高伟的专栏
    • (ITRA)团队
    • 计算机视觉小菜鸟的专栏
    • 计算机视觉最新资讯网
    文章分类
  • C++(5)
  • Code Optimization(0)
  • HardWare(4)
  • Buses(3)
  • 954(1)
  • vxworks(3)
  • vxbus(1)
  • 软件使用tips(1)
    文章存档
  • 2013年03月(2)
  • 2013年01月(9)
  • 2012年01月(2)
  • 2011年08月(1)
  • 2011年07月(5)
    展开
    阅读排行
  • Fisher 线性分类器(1)----Fisher准则函数(4003)
  • 基于OpenCV的三次多项式曲线拟合(3536)
  • VxWorks设备驱动开发指南(二)--VxBus And VxBus Device Driver(2016)
  • 访问PCIe配置空间using Intel Chipsets(1984)
  • VxWorks驱动程序开发指南(四)--驱动程序的组织结构(1693)
  • VxWorks设备驱动程序开发指南(三)---驱动程序的分类(1213)
  • PCI总线在VxWorks中的实现(1193)
  • 贝叶斯定理及典型应用(1069)
  • VxWorks 设备驱动开发指南(一)--Getting Started(1000)
  • 三角形的平移&旋转&缩放程序(基于OPENCV)(966)
    评论排行
  • Fisher 线性分类器(1)----Fisher准则函数(3)
  • 三角形的平移&旋转&缩放程序(基于OPENCV)(1)
  • 谷歌研发人脸识别手机应用 拍照可获个人信息(1)
  • NVRAM 和FLASH的区别(1)
  • 采用递归去掉string里面的所有空格(0)
  • 以二进制输出整型数(0)
  • Matlab GUI设计相关(0)
  • 运动目标检测、阴影检测及目标跟踪中用得到的标准测试视频下载(0)
  • Depth of Field Math(0)
  • Adjust structure size to power of two(0)
    推荐文章
    • * 云计算的那些事儿之计算虚拟化
    • * 微服务--分布式事务的实现方法及替代方案
    • * 你应该知道的 Android 数据库更新策略
    • * HDFS副本放置节点选择的优化
    • * CSDN日报20170416 ——《为什么程序员话少钱多死得早?》
    • * 凡人视角C++之string(上)
    最新评论
  • NVRAM 和FLASH的区别

    yanpeifeng2011: 你好,最近也在学习Vxworks,近期需要写一个NVRam驱动,对于系统中vxbFileNvRam....

  • 谷歌研发人脸识别手机应用 拍照可获个人信息

    keshi1990: 现在的科技都发展这么快了,仅凭一张照片就能获得个人信息,有点神奇。。。

  • Fisher 线性分类器(1)----Fisher准则函数

    S20070319: 楼主,将fisher应用到说话人识别中,F比,来衡量MFCC参数(一般都取12维也就是12列)中各维...

  • Fisher 线性分类器(1)----Fisher准则函数

    S20070319: 楼主,请教个问题啊,用fisher准则来衡量说话人识别中特征参数(MFCC)的有效性时,是一维的情况...

  • Fisher 线性分类器(1)----Fisher准则函数

    8度空间: 在一维Y空间是指y = wx + wo, 它把X映射到Y空间。

  • 三角形的平移&旋转&缩放程序(基于OPENCV)

    8度空间: 如果页面没代码,请点击expand code!!

0 0
原创粉丝点击