最新消息:20190529 VPS服务器已从腾讯云香港换为Vultr新加坡,主题仍用朋友推荐的大前端D8

【已解决】ARM 922T 开启Icache,导致网卡读取的MAC地址不对,无法正常初始化

工作和技术 crifan 692浏览 0评论

【问题】

板子是通过NFS启动,uboot中网卡驱动正常,可以从server加载kernel并运行,kernel运行也OK,但是到了网卡初始化的时候,读取出来的网卡MAC地址不正常,后面的读取RevID也不对,然后初始化失败了。

【分析及解决】

找到了原因是,如果在uboot中加上,为了提高CPU性能,提高uboot读取kernel的速度,而去启用了Icache之后,系统速度是快了,包括从nfs读取kernel的速度也快了,但是到了kernel运行到网卡初始化的时候,其网卡地址读出来就不对了,而是随机的数,不是我们在uboot中写入的固定的那个MAC值。

去查了很多方面,都无法找到,Icache为何会影响到后面的Ethernet初始化读取的MAC地址。

然后,怀疑是cache没有flush正常,所以又按照ARM 922T手册中介绍,加上了单独flush Icache的代码,

i = 0;
/* flush I-cache */
asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i));

和清write buffer的代码:

/* drain write buffer */
i = 0;
asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i));

都还是问题依旧,没有影响。

后来想到,会不会在uboot跳转到kernel之前,MAC地址就已经不对了,所以在uboot掉转到kernel之前的cleanup_before_linux中加了对应的代码去读取MAC地址,此时发现读出来的数据是不对的,但是基本是固定的,至少MAC6个字节中,前3,4个字节,虽然是错的,但也是固定的。此处虽然MAC地址不对,但是这样运行到kernel初始化Ethernet的时候,网卡就正常工作了。

想不清楚,无意间百度的一个帖子:

关于ARM946ES的DCACHE一致性问题

http://www.study-bbs.com/dispbbs.asp?boardid=8&id=2291

也是遇到类似问题,不过其遇到的是dcache的write back问题。而我这里是icache的问题。。

所以,反推过去,觉得比较可能的原因就是:

由于开了ARM 922T的Icache,不知道为何,但是就是影响了部分数据,至少是网卡寄存器中的数值那段数据,被cache了,然后后面在uboot如果没有再次读取,后面即使去flush,好像也没有生效。只要去读了一次之后,估计会发生cache miss,然后后面kernel中再去读取网卡的MAC地址,就对了,网卡工作就正常了。不过自己都觉得这个解释不能解释清楚此问题。

【仍存疑问】

最后,虽然问题算是避开了,但是还存在如下疑问,希望高手看到,给解释一下:

1.我们打开的是Icache,但是却是影响了数据的访问,而不是代码的访问,觉得即使影响数据,那也应该是icache才对。。。

2.ARM 922T是Harvard结构,所以icache,更不改会影响dcache才对。。。

3.如果上面uboot中后面的读取网卡MAC地址,发生了cache miss,这时候,应该MAC地址数据就该读取对了,但是看到的是数据读出来的是不对的。

4.正常情况下,至少cleanup_before_linux中的先关闭cache,再cache flush,应该会将数据清空了,但是,如果前面没有读取MAC地址,此处的flush,就是不起作用,很奇怪。。。

转载请注明:在路上 » 【已解决】ARM 922T 开启Icache,导致网卡读取的MAC地址不对,无法正常初始化

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
53 queries in 0.105 seconds, using 18.65MB memory