Over
驱动牛犊
驱动牛犊
  • 注册日期2001-09-26
  • 最后登录2002-08-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2081回复:11

Amcc5933异步方式DMA驱动程序问题求助!!

楼主#
更多 发布于:2001-10-29 21:55
自己做的板子,使用amcc5933作pci接口控制芯片。

把amcc5933设置为pci master方式,使用addon to pci的fifo(以下简称fifo),异步方式,dma传输。基本上用的是这个驱动开发网上的amcc5933pciwdmv1.4.zip那个例子。已经可以传输。但是只要过一小段时间,就会自动停止,不传了!

    状态如下:
    1、正常传输时,mcsr为0x666,intcsr为0x4000。intcsr保持不变。mwtc和mwar设置也一直正确。
    2、突然不传输时,mcsr刚设置时为0x666(或0x676),但因为不传输了,很快就变为0x64e。
    3、之后就无法传输了,mcsr保持0x64e。

    关于2,不明白为什么突然就不传数了??难道没有申请到总线控制权吗?请高手指教!!

    关于3,我想因为设置的传输策略为burst方式(mcsr第9位为1),也就是只有当fifo已经4+满时才申请控制总线,但0x64e这个状态却是fifo已经满,但没有4+满!!可能5933只看fifo4+满标志,认为没有数据需要传,就没有发出申请吧(检查pci接口req#管脚确实没有发请求)。这是不是amcc5933的一个bug呢?

    所以每当不能传数时,就写mcsr的第26位,也就是重新设置amcc的addon to pci的fifo标志,清为0x65e,这样可以继续传输。在amcc的手册中说,重设fifo标志应该每次dma传输前都(建议!!)作一次的。
    
    但是过一阵子计算机就死了!(键盘、鼠标没有反应,屏幕没响应,但不蓝屏)。象是死锁吧。这是最严重的问题!

    请教各位大虾,以上情况该怎么解决呢?特别是那个例子程序,哪里会引起死锁呢?
    
    好像也蓝屏过,说是什么内存的问题,真是让人头大!!

    谢谢各位大虾看到这里,再问最后一个问题,怎么调试啊?softice可以不让driver把机器弄死吗?

    特着急,谢谢任何解答和帮助!!

    我的email:regainworld@263.net,或者yt1972@263.net都可。
当我们仰望星空,其实是在回顾历史
Over
驱动牛犊
驱动牛犊
  • 注册日期2001-09-26
  • 最后登录2002-08-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2001-10-30 14:12
现在每次dma传输前都重设一次fifo标志,并让这次写mcsr和下次写mcsr的11、10位之间的时间尽量长,已经可以在1M(32位数据线也就是4MBPS)的时钟下基本正常工作。
问题是一加到1.5M就很快死掉了!这是怎么回事?
那位大虾能给出意见和建议吗?
谢谢!

当我们仰望星空,其实是在回顾历史
Over
驱动牛犊
驱动牛犊
  • 注册日期2001-09-26
  • 最后登录2002-08-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2001-11-01 11:31
把fifo策略改了(4+full -> 0)以后,机器不死了。
而且多高的速度都支持。。。。只是每次传输完成后fifo就会满150微秒左右。这样导致数据严重丢失。
按理说中断处理和延时处理例程不应该这么慢才对,下面是传输完成后到启动下一次传输中的关键代码,请大虾帮忙找找慢的原因:dpc()
{
    //
    //完成当前DMA传输完成的irp
    //
    baseVa = (PUCHAR)MmGetMdlVirtualAddress(irp->MdlAddress)+devExt->ReadStartingOffset;

    IoFlushAdapterBuffers(devExt->ReadAdapter,
                          irp->MdlAddress,
                          devExt->ReadMapRegBase,
                          baseVa,
                          devExt->ReadSoFar-devExt->ReadStartingOffset,
                          FALSE);

    IoFreeMapRegisters(devExt->ReadAdapter,
                          devExt->ReadMapRegBase,
                          devExt->MapRegsThisRead);

    irp->IoStatus.Information = devExt->ReadTotalLength;
    irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(irp, IO_NO_INCREMENT);    


    //
    //开始队列中下一个irp的DMA传输
    //
    devExt->CurrentReadIrp = 队列中下一个irp;

    KeFlushIoBuffers(Irp->MdlAddress, TRUE, TRUE);

    mapRegsNeeded =
        ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Irp->MdlAddress),ioStack->Parameters.Read.Length);
        
    devExt->MapRegsThisRead = ((mapRegsNeeded > devExt->ReadMapRegsGot) ?
                              devExt->ReadMapRegsGot : mapRegsNeeded);

    IoAllocateAdapterChannel(devExt->ReadAdapter,
                             DeviceObject,
                             devExt->MapRegsThisRead,
                             OsrAdapterControlRead,  <--分配成功后的回调函数
                             Irp);
}

OsrAdapterControlRead()
{
    baseVa = (unsigned char *)MmGetMdlVirtualAddress(irp->MdlAddress);

    devExt->ReadPaToDevice = IoMapTransfer(devExt->ReadAdapter,
                                   irp->MdlAddress,
                                   MapRegisterBase,
                                   baseVa+(devExt->ReadSoFar),
                                   &devExt->ReadLength,
                                   FALSE);

    (VOID)KeSynchronizeExecution(devExt->InterruptObject,
                            OsrStartReadOnDevice,
                            DeviceObject);
}

OsrStartReadOnDevice()
{
    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+MWAR_OFF, devExt->ReadPaToDevice.LowPart);
    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+MWTC_OFF, devExt->ReadLength);

    temp = READ_PORT_ULONG(devExt->AmccBaseRegisterAddress+ICSR_OFF);

    temp &= ~AMCC_INT_ACK_BITS;
    temp |= AMCC_INT_INT_ON_WRITE;
    
    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+ICSR_OFF, temp);
    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+MCSR_OFF, AMCC_MCSR_WRITE_ENABLE | AMCC_MCSR_ATOP_RESET);
}

当我们仰望星空,其实是在回顾历史
lxf
lxf
驱动小牛
驱动小牛
  • 注册日期2001-03-26
  • 最后登录2013-05-04
  • 粉丝4
  • 关注0
  • 积分76分
  • 威望30点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
地板#
发布于:2001-11-01 21:20
我也在做AMCC5933/C6X的DMA,还在初步TEST阶段,现在有一个问题是:当做DMA读时经常发生数据偏离,不知道你有没有碰到,是不是每次启动DMA读之前都要清一下FIFO?
你的DMA速度(保证正确的情况下)是多少?

谢谢!
别着急,慢慢来!
Over
驱动牛犊
驱动牛犊
  • 注册日期2001-09-26
  • 最后登录2002-08-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2001-11-03 19:05
对不起,数据偏离我不太清楚什么意思,我这儿现在只能通过fifo一满就停止时钟来保证数据不丢,但还没有做过数据正确性检测:(
                            ^^^^^^^^^^^^^^^^^^^^^
速度问题没有验证不敢乱说,不过目前看最多15MB/s。

为什么人家的板子就可以33MB/s,我的板子就只能一半?郁闷!

现在每次启动dma读都清fifo,这是amcc5933资料里推荐的做法。不过我怀疑这只是应付“4+满标志”混乱的,也许用“队列空标志”就用不着了?

你的驱动程序在两次DMA中间fifo会满吗?昨天试验了一下只进行板子到系统内核内存的dma传输(数据不传到应用程序的缓冲区),两次DMA之间也需要有35微秒左右的处理时间,而fifo不到8微秒就满了,可这35微秒大概是必需的时间吧?(因为这次是先开一块物理连续的内存块,dma设置时直接把其地址指针写入mwar,所以这个处理只包括“假”完成irp包、写四个dma相关寄存器和中断后写intcsr确认中断这几个必要动作)

急需大虾指点如何DMA传输才可以保证数据流连续,fifo不满。是不是需要什么别的技术?在win2k ddk的帮助里没找到别的方法啊。

谢谢你。
当我们仰望星空,其实是在回顾历史
whutwx
驱动牛犊
驱动牛犊
  • 注册日期2001-08-06
  • 最后登录2003-03-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2001-11-05 15:49
你用两片的FIFO,用分时的办法。
whutwx
Over
驱动牛犊
驱动牛犊
  • 注册日期2001-09-26
  • 最后登录2002-08-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2001-11-05 23:11
--你用两片的FIFO,用分时的办法。

谢谢你的建议:)
我一定会给你分的,不过能具体点儿吗,amcc本身只有一个fifo可用来读,另一个fifo是写的,是不是需要外部加fifo呢?分时是什么意思?
当我们仰望星空,其实是在回顾历史
lxf
lxf
驱动小牛
驱动小牛
  • 注册日期2001-03-26
  • 最后登录2013-05-04
  • 粉丝4
  • 关注0
  • 积分76分
  • 威望30点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2001-11-06 10:44
搞定了,原来是因为AMCC资料说明理解的问题。在DSP那边是以双字记数的,而HOST是以字节记数的。
不知你是什么原因?
为什么人家的板子就可以33MB/s,B 是BYTE还是BIT?
别着急,慢慢来!
Over
驱动牛犊
驱动牛犊
  • 注册日期2001-09-26
  • 最后登录2002-08-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2001-11-07 11:47
B 是BYTE还是BIT?
byte,是不是太夸张了?amcc手册里这么写着,可以充分利用pci总线速率。

大虾,你的数据流一直往fifo里面扔,为什么没有满过呢,我特想知道这个原因。

说说你Dma的过程吧,再做不出来就只好买商业板子了:(
当我们仰望星空,其实是在回顾历史
whutwx
驱动牛犊
驱动牛犊
  • 注册日期2001-08-06
  • 最后登录2003-03-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2001-11-12 15:39
请问OVER,你的异步,ADD-ON的时钟频率是多少!
whutwx
lxf
lxf
驱动小牛
驱动小牛
  • 注册日期2001-03-26
  • 最后登录2013-05-04
  • 粉丝4
  • 关注0
  • 积分76分
  • 威望30点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2001-11-16 09:34
我弄好了,可以到8-9M BYTE/S, 据说有些硬件还可以做得更高。
别着急,慢慢来!
Over
驱动牛犊
驱动牛犊
  • 注册日期2001-09-26
  • 最后登录2002-08-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2001-11-28 23:10
lxf:
我弄好了,可以到8-9M BYTE/S, 据说有些硬件还可以做得更高。

可我已经做不下去了,被老板炒了。告诉我你的dma怎么做得好吗?我实在不甘心啊:(
regainworld@263.net

whutwx:
请问OVER,你的异步,ADD-ON的时钟频率是多少!

5MB/s。
问题是即使比这小很多,比如1MB/s,也会丢数的

当我们仰望星空,其实是在回顾历史
游客

返回顶部