summaryrefslogtreecommitdiff
path: root/firmware/target/arm/pp/system-pp502x.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/pp/system-pp502x.c')
-rw-r--r--firmware/target/arm/pp/system-pp502x.c30
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