diff options
Diffstat (limited to 'firmware/target/arm/pp')
-rw-r--r-- | firmware/target/arm/pp/system-pp502x.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/firmware/target/arm/pp/system-pp502x.c b/firmware/target/arm/pp/system-pp502x.c index bb083a5d16..d3331bf9f4 100644 --- a/firmware/target/arm/pp/system-pp502x.c +++ b/firmware/target/arm/pp/system-pp502x.c | |||
@@ -219,9 +219,26 @@ void ICODE_ATTR commit_discard_idcache(void) | |||
219 | { | 219 | { |
220 | if (CACHE_CTL & CACHE_CTL_ENABLE) | 220 | if (CACHE_CTL & CACHE_CTL_ENABLE) |
221 | { | 221 | { |
222 | CACHE_OPERATION |= CACHE_OP_FLUSH | CACHE_OP_INVALIDATE; | 222 | register int istat = disable_interrupt_save(IRQ_FIQ_STATUS); |
223 | while ((CACHE_CTL & CACHE_CTL_BUSY) != 0); | 223 | |
224 | nop; nop; nop; nop; | 224 | commit_dcache(); |
225 | |||
226 | /* Cache lines which are not marked as valid can cause memory | ||
227 | * corruption when there are many writes to and code fetches from | ||
228 | * cached memory. This workaround points all cache status words past | ||
229 | * end of RAM and marks them as valid, but not dirty. Since that area | ||
230 | * is never accessed, the cache lines don't affect anything, and | ||
231 | * they're effectively discarded. Interrupts must be disabled here | ||
232 | * because any change they make to cached memory could be discarded. | ||
233 | */ | ||
234 | |||
235 | register volatile unsigned long *p; | ||
236 | for (p = &CACHE_STATUS_BASE; | ||
237 | p < (&CACHE_STATUS_BASE) + 512*16/sizeof(*p); | ||
238 | p += 16/sizeof(*p)) | ||
239 | *p = ((MEMORYSIZE*0x100000) >> 11) | 0x800000; | ||
240 | |||
241 | restore_interrupt(istat); | ||
225 | } | 242 | } |
226 | } | 243 | } |
227 | 244 | ||
@@ -253,6 +270,13 @@ static void init_cache(void) | |||
253 | /* enable cache */ | 270 | /* enable cache */ |
254 | CACHE_CTL |= CACHE_CTL_INIT | CACHE_CTL_ENABLE | CACHE_CTL_RUN; | 271 | CACHE_CTL |= CACHE_CTL_INIT | CACHE_CTL_ENABLE | CACHE_CTL_RUN; |
255 | nop; nop; nop; nop; | 272 | nop; nop; nop; nop; |
273 | |||
274 | /* Ensure all cache lines are valid for the next flush. Since this | ||
275 | * can run from cached RAM, rewriting of cache status words may not | ||
276 | * be safe and the cache is filled instead by reading. */ | ||
277 | register volatile char *p; | ||
278 | for (p = (volatile char *)0; p < (volatile char *)0x2000; p += 0x10) | ||
279 | (void)*p; | ||
256 | } | 280 | } |
257 | #endif /* BOOTLOADER || HAVE_BOOTLOADER_USB_MODE */ | 281 | #endif /* BOOTLOADER || HAVE_BOOTLOADER_USB_MODE */ |
258 | 282 | ||