From 13bb6b0e1ce5754457842787244804817a1c1326 Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Mon, 24 Aug 2009 18:39:39 +0900 Subject: [PATCH] --- yaml --- r: 163535 b: refs/heads/master c: ffad9d7a54a5e809007135595c778715aa0fb07a h: refs/heads/master i: 163533: 3be5056346786bb7ea35960fd80c697b999b49e8 163531: ccc88b5d0e79cb0060c93197e08f97f1e27f557a 163527: c749f9e38d2273994e29954a5796a0c18c6f0cc3 163519: d169526ac0d852dbdfcf70ecda12bc4e03ce2e54 v: v3 --- [refs] | 2 +- trunk/arch/sh/mm/cache-sh4.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index c4d715b1476c..a440d5bd0994 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a1fce732359b80ead84efba23059a5f1b572b85a +refs/heads/master: ffad9d7a54a5e809007135595c778715aa0fb07a diff --git a/trunk/arch/sh/mm/cache-sh4.c b/trunk/arch/sh/mm/cache-sh4.c index 7ce816188313..397c1030c7a6 100644 --- a/trunk/arch/sh/mm/cache-sh4.c +++ b/trunk/arch/sh/mm/cache-sh4.c @@ -592,6 +592,20 @@ static void __flush_cache_4096(unsigned long addr, unsigned long phys, * this with a cache invalidate to mark the cache line invalid. And do all * this with interrupts disabled, to avoid the cache line being accidently * evicted while it is holding garbage. + * + * This also breaks in a number of circumstances: + * - if there are modifications to the region of memory just above + * empty_zero_page (for example because a breakpoint has been placed + * there), then these can be lost. + * + * This is because the the memory address which the cache temporarily + * caches in the above description is empty_zero_page. So the + * movca.l hits the cache (it is assumed that it misses, or at least + * isn't dirty), modifies the line and then invalidates it, losing the + * required change. + * + * - If caches are disabled or configured in write-through mode, then + * the movca.l writes garbage directly into memory. */ static void __flush_dcache_segment_1way(unsigned long start, unsigned long extent_per_way) @@ -641,6 +655,25 @@ static void __flush_dcache_segment_1way(unsigned long start, } while (a0 < a0e); } +#ifdef CONFIG_CACHE_WRITETHROUGH +/* This method of cache flushing avoids the problems discussed + * in the comment above if writethrough caches are enabled. */ +static void __flush_dcache_segment_2way(unsigned long start, + unsigned long extent_per_way) +{ + unsigned long array_addr; + + array_addr = CACHE_OC_ADDRESS_ARRAY | + (start & cpu_data->dcache.entry_mask); + + while (extent_per_way) { + ctrl_outl(0, array_addr); + ctrl_outl(0, array_addr + cpu_data->dcache.way_incr); + array_addr += cpu_data->dcache.linesz; + extent_per_way -= cpu_data->dcache.linesz; + } +} +#else static void __flush_dcache_segment_2way(unsigned long start, unsigned long extent_per_way) { @@ -699,6 +732,7 @@ static void __flush_dcache_segment_2way(unsigned long start, a1 += linesz; } while (a0 < a0e); } +#endif static void __flush_dcache_segment_4way(unsigned long start, unsigned long extent_per_way)