diff options
author | Gilbert Gilb's <gilbsgilbert@gmail.com> | 2023-11-13 12:36:24 +0100 |
---|---|---|
committer | Han Gao/Revy/Rabenda <rabenda.cn@gmail.com> | 2023-12-15 23:35:31 +0800 |
commit | adec30ace4cebb0554bb246b52eebaf37c1545c4 (patch) | |
tree | e704f5a68664c7968c3e379cc478e4b2d3ff0d90 /cmd/ddrscan.c | |
parent | 76320896523519fceedd9f347b6cf6aeabf91eb7 (diff) |
fix(c9xx): don't flush dcache when invalidating
The data cache invalidation function for c9xx CPUs uses `dcache.cipa`
instruction. According to T-Head extension specification[1] section
3.1.5, this instruction also performs a cache clean along with the
invalidation.
On top of being incorrect, this leads to a serious issue on the
designware ethernet driver, where stalled cache may get flushed each
time we handle a new received packet[2]. As a result, received packet
are randomly corrupted with old cached data. This can easily be
reproduced by sending an ARP request to the device during a TFTP
transfer. The last TFTP block is treated as the ARP reply we just sent,
which makes U-Boot hang on the block.
Always use `dcache.ipa` instruction to invalidate dcache. Replace
existing usages of `dcache.ipa` with our implementation.
Note that this fix is slightly intrusive as it changes the cache
invalidation behavior in all drivers. However, I have not noticed any
side-effect during my tests.
[1] https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.3.0/xthead-2023-11-10-2.3.0.pdf
[2] https://github.com/revyos/thead-u-boot/blob/918a8c89e056e3462031d6a498bb4fcc0c3526ce/drivers/net/designware.c#L475
Diffstat (limited to 'cmd/ddrscan.c')
-rw-r--r-- | cmd/ddrscan.c | 1 |
1 files changed, 0 insertions, 1 deletions
diff --git a/cmd/ddrscan.c b/cmd/ddrscan.c index 0f2b78c6..c550e03d 100644 --- a/cmd/ddrscan.c +++ b/cmd/ddrscan.c @@ -73,7 +73,6 @@ extern ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, #endif extern void flush_dcache_range(unsigned long start, unsigned long end); extern void invalidate_dcache_range(unsigned long start, unsigned long end); -extern void invalid_dcache_range(unsigned long start, unsigned long end); #ifdef CONFIG_CMD_MEMTEST int test_stuck_address(ulv *bufa, ulong count); |