各位老师好,我在musecard板卡上适配操作系统时候遇到一个网络驱动上的问题。
操作系统启动时需要重新初始化网络,我在重新设置了发送描述符基址寄存器(0x1c)后,发现当前发送描述符寄存器(0x30)和当前发送缓冲区寄存器(0x34)的值不对,分别变成了0x584b0和0x51430。
我在uboot下也能够复现此问题,使用tftpboot命令后,使用mm命令修改了0x1c寄存器,再使用tftpboot命令,打断后查看内存,发现0x30和0x34寄存器的值也变成了0x584b0和0x51430。
请问设置发送描述符基址寄存器前需要做什么额外的操作吗?
目前能够确认的是,我已经在重设0x1c寄存器之前,复位了DMA,并关闭设备的发送与接收进程(通过清除MAC GLOBAL寄存器与DMA控制寄存器的某些位)。除此之外,还有哪些操作是必须执行的?
上述问题已定位,在使能DMA控制寄存器的发送位时,如果当前发送描述符的own位不为1,就会出现这个现象。
但是我现在又有另外一个问题,当前发送描述符寄存器为什么会一次性跳64字节?DMA配置寄存器里我设置描述符是连续的,它应该一次性只跳16字节才合理。而且当前发送缓冲区寄存器指向的内存空间与我的发送描述符设置的buffer地址不一致。有哪些操作会影响当前发送缓冲区和描述符这两个寄存器的自动跳转哦
您好。这是使用官方驱动发现的现象还是个人开发驱动? DMA_CONFIGURATION(0x0000) 这个寄存器的bit 8-12 有设置值吗?另外可贴一下这个寄存器完整值不,软件上控制DMA行为主要是这个寄存器。
DMA Configuration寄存器的完整值是0x60002。我这个是移植官方网络驱动代码后个人开发的驱动。
我想知道当前发送缓冲区寄存器的值是由什么来控制的,这个值目前看下来与我在描述符中设置的值有所不同?
而且0x30和0x34这两个寄存器的值为什么会变成0x584b0和0x51430?在什么时机下它们会变成这样的值?
我过了一遍相关寄存器,0x0034 的行为理论上主要受 0x001C 和 0x0000 影响。
软件会先在 0x001C 写入 TX 描述符基地址,DMA 启动后控制器会轮询读取描述符。当发现某个描述符的 OWN bit = 1 时,会解析该描述符中的 buffer 地址字段,并更新到 0x0034,进行后续数据传输流程。
下一个描述符地址由 0x0000[12:8] 控制。如果该字段全为 0,则控制器按 16B 步长读取下一个描述符;当读取到某个描述符的 des1.EOR = 1 时,会回绕到第一个描述符继续处理。
如果这几个寄存器配置都确认无误,而 0x0034 的值仍然异常,我倾向于认为控制器读取到的描述符内容本身不是预期值。建议重点排查 cache 一致性和内存屏障问题,确保 CPU 在写 OWN = 1 之前,buffer 物理地址及描述符其他字段已经完整写回到 memory。
好的,此问题已定位完毕。我的驱动在申请描述符空间时,给这段空间清零但并没有将cache里的内容刷新到内存里去,这就导致内存里的值是随机值,可能存在own位为1的情况。当使能DMA寄存器的发送位时,DMA误以为我的发送描述符已准备就绪,因此开启了发送动作,这个动作很可能会访问非法地址,进而导致发送进程错误。
正确的做法是,先申请发送描述符的内存空间,将其清零,然后调用cache维护指令,手动将0值刷新至内存,这样能够确保我的发送描述符在准备就绪之前,DMA并不会开始启动发送流程。
1 Like