mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-09 23:53:28 -04:00
rk27xx: invalidate the cache with the cache controller off
commit_discard_idcache() invalidated both cache ways while running from cached SDRAM. When the loop polling for the invalidate to finish starts on a cache line of its own, it is fetched through the ways being invalidated and the CPU takes a data abort, reported at the loop's branch. Whether it crashed thus depended on where the linker put the function. usb_storage calls it on every USB connect. On rk27generic a jpeg change that grew clip_jpeg_fd by 8 bytes moved the loop onto a new line, and the firmware crashed as the USB screen came up, with an empty backtrace. Turn the cache controller off around the invalidate, as crt0.S does at start-up. The cache is write-through, so no data is lost. Tested on a generic rk2705 with the function padded so the poll loop starts a new cache line: without this change it crashes at the first USB connect, with it the device enumerates as a mass storage device. The normally linked build works too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Change-Id: I319b811fdef30717999b60132000e70f410001fc
This commit is contained in:
parent
70c546113d
commit
0e1952a4d1
1 changed files with 10 additions and 0 deletions
|
|
@ -208,11 +208,21 @@ static void cache_invalidate_way(int way)
|
|||
void commit_discard_idcache(void)
|
||||
{
|
||||
int old_irq = disable_irq_save();
|
||||
unsigned long devid = DEVID;
|
||||
|
||||
/* Invalidate with the cache off, as crt0 does. This code runs from
|
||||
* cached SDRAM: invalidating the ways while fetching through them fails
|
||||
* when the poll loop starts on a cache line of its own, depending on
|
||||
* where the linker happened to put it. The cache is write-through, so
|
||||
* nothing is lost by turning it off. */
|
||||
DEVID = devid & ~(1UL << 31);
|
||||
|
||||
cache_invalidate_way(0);
|
||||
|
||||
cache_invalidate_way(1);
|
||||
|
||||
DEVID = devid;
|
||||
|
||||
restore_irq(old_irq);
|
||||
}
|
||||
void commit_discard_dcache (void) __attribute__((alias("commit_discard_idcache")));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue