SylixOS PCIe开发(三)

gewenbin
gewenbin
gewenbin
188
文章
15
评论
2020年12月26日20:26:24 评论 1,187

1. SylixOS主控驱动支持多个控制器

SylixOS中的pci框架目前只支持单个控制器,如果需要在主控驱动中支持多个控制器,就需要将多个控制器虚拟成一个控制器给SylixOS。

在vx下用户的pci设备驱动中,经常会调用到vxbPciConfigInWord类似的接口来读写设备的配置空间,先来看看这个函数的原型:

IMPORT STATUS vxbPciConfigInWord

    (

    VXB_DEVICE_ID busCtrlID,

    int busNo,      /* bus number */

    int deviceNo,   /* device number */

    int funcNo,     /* function number */

    int offset,     /* offset into the configuration space */

    UINT16 * pData  /* data read from the offset */

    );

可以看出,vx这个接口的第一个参数表示的是要操作哪个控制器,也就是vx的pci驱动是支持多个控制器的,在SylixOS下,我们可以找到类似的如下接口:

INT  API_PciConfigInWord (INT iBus, INT iSlot, INT iFunc, INT iOft, UINT16 *pusValue);

可以看出的是SylixOS下此接口的第一个参数是总线号,而不是控制器的ID,如果不做处理直接调用这个接口,主控驱动是不知道调用者到底想使用哪个控制器的,那么有什么办法能让主控驱动知道调用者想使用的是哪个控制器呢?

答案就是从第一个参数总线号入手,规范中虽然规定了pci可以有256个总线,但是实际应用中不会使用到全部的总线号,那么我们就可以将总线号做划分,通过不同的总线号来确定要操作的控制器。在这种方式下,我们可以将总线号称作为虚拟总线号。比如某个平台有3个控制器,那么我们可以做如下的划分:

  • 总线号0~9上的设备是控制器1的
  • 总线号10~19上的设备是控制器2的
  • 总线号20~29上的设备是控制器3的

那么如果我们想操作控制器2上总线3上的设备的话,那么调用 API_PciConfigInWord时传入的虚拟总线号应该是10+3=13,在主控驱动中需要通过虚拟总线号来确定要操作哪个控制器,然后再减去其对应的虚拟总线号起始值得到真正要操作的总线号,最后进行访问。

2. ECAM方式访问配置空间崩溃问题

在ARM平台和龙芯2k1000平台上,当通过ECAM方式访问没有实际设备的配置空间时会产生内存访问错误或者bus error错误,这是由于平台特性决定的,这时需要在bsp中重新实现bspCpuExcHook函数,大致的内容就是判断当前崩溃的地址是否在ECAM空间内,如果在,那么做一些平台相关处理后返回1,否则返回0.

3. pci设备驱动从vx下移植到SylixOS下注意点

  • 客户的驱动中访问pci bar空间的寄存器可能会直接定义一个指针变量,然后操作这个指针变量来读写寄存器,比如:
int *reg = xxxx;
*reg =  2;

这种代码在使用gcc编译器编译时可能会被优化,解决方法就是在指针变量前加上volatile修饰,如下:

volatile int *reg = xxxx;
*reg = 2;

通过volatile修饰符来告诉编译器禁止优化reg这个变量。

  • 客户驱动中可能会使用如下方式来实现延时:
int i;
for(i=0;i<2000;i++)

这种代码同样可能会被gcc编译器优化掉,目前的解决方法是使用usleep之类的接口延时确定的时间。不过我觉得i变量是不是同样可以用volatile来修饰来禁止编译器优化,这个得修改用户代码再确认。

gewenbin
  • 本文由 发表于 2020年12月26日20:26:24
  • 转载请务必保留本文链接:http://www.databusworld.cn/9884.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: