* [2.5 PATCH] R10K DMA cache flushing routines for non-coherent systems
@ 2002-07-14 21:17 Vivien Chappelier
2002-07-15 13:06 ` Ralf Baechle
0 siblings, 1 reply; 2+ messages in thread
From: Vivien Chappelier @ 2002-07-14 21:17 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Hi,
This patch adds support for DMA cache flushing for the R10000
processor on non-coherent systems (Indy and O2).
Vivien.
================================================================================
--- linux/arch/mips64/mm/andes.c Mon Jul 8 22:26:10 2002
+++ linux.patch/arch/mips64/mm/andes.c Sun Jul 7 14:48:26 2002
@@ -11,13 +11,17 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <asm/io.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/r10kcache.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
-static int scache_lsz64;
+/* Secondary cache parameters. */
+static unsigned int scache_size, sc_lsize; /* Again, in bytes */
+
+#include <asm/r10kcache.h>
+
/*
* This version has been tuned on an Origin. For other machines the arguments
@@ -98,7 +102,7 @@
*/
static void andes_flush_cache_l2(void)
{
- switch (sc_lsize()) {
+ switch (sc_lsize) {
case 64:
blast_scache64();
break;
@@ -111,13 +115,96 @@
}
}
+static void
+andes_flush_cache_all(void)
+{
+ andes_flush_cache_l1();
+ andes_flush_cache_l2();
+}
+
void
andes_flush_icache_page(unsigned long page)
{
- if (scache_lsz64)
- blast_scache64_page(page);
- else
- blast_scache128_page(page);
+ switch (sc_lsize) {
+ case 64:
+ blast_scache64_page(page);
+ break;
+ case 128:
+ blast_scache128_page(page);
+ break;
+ default:
+ printk(KERN_EMERG "Unknown L2 line size\n");
+ while(1);
+ }
+}
+
+/*
+ * Writeback and invalidate the cache before DMA.
+ */
+
+static void andes_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+ unsigned long end, a;
+
+
+ if (size >= (unsigned long)dcache_size) {
+ flush_cache_l1();
+ } else {
+ a = addr & ~((unsigned long)dc_lsize - 1);
+ end = (addr + size) & ~((unsigned long)dc_lsize - 1);
+ while (1) {
+ flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+ if (a == end) break;
+ a += dc_lsize;
+ }
+ }
+
+ if (size >= (unsigned long)scache_size) {
+ flush_cache_l2();
+ } else {
+ a = addr & ~((unsigned long) sc_lsize - 1);
+ end = (addr + size) & ~((unsigned long) sc_lsize - 1);
+ while (1) {
+ flush_scache_line(a); /* Hit_Writeback_Inv_S */
+ if (a == end) break;
+ a += sc_lsize;
+ }
+ }
+}
+
+static void andes_dma_cache_inv(unsigned long addr, unsigned long size)
+{
+ unsigned long end, a;
+
+
+ if (size >= (unsigned long)dcache_size) {
+ flush_cache_l1();
+ } else {
+ a = addr & ~((unsigned long)dc_lsize - 1);
+ end = (addr + size) & ~((unsigned long)dc_lsize - 1);
+ while (1) {
+ flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+ if (a == end) break;
+ a += dc_lsize;
+ }
+ }
+
+ if (size >= (unsigned long)scache_size) {
+ flush_cache_l2();
+ } else {
+ a = addr & ~((unsigned long) sc_lsize - 1);
+ end = (addr + size) & ~((unsigned long) sc_lsize - 1);
+ while (1) {
+ flush_scache_line(a); /* Hit_Writeback_Inv_S */
+ if (a == end) break;
+ a += sc_lsize;
+ }
+ }
+}
+
+static void andes_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+ panic("andes_dma_cache called - should not happen.");
}
static void
@@ -176,11 +263,9 @@
}
}
-void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
- struct mm_struct *mm = vma->vm_mm;
-
if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
unsigned long flags;
int size;
@@ -305,31 +390,28 @@
void __init ld_mmu_andes(void)
{
+ /* get secondary cache parameters */
+ scache_size = scache_size();
+ sc_lsize = sc_lsize();
+
printk("Primary instruction cache %dkb, linesize %d bytes\n",
icache_size >> 10, ic_lsize);
printk("Primary data cache %dkb, linesize %d bytes\n",
dcache_size >> 10, dc_lsize);
printk("Secondary cache sized at %ldK, linesize %ld\n",
- scache_size() >> 10, sc_lsize());
+ scache_size >> 10, sc_lsize);
_clear_page = andes_clear_page;
_copy_page = andes_copy_page;
+ _flush_cache_all = andes_flush_cache_all;
_flush_cache_l1 = andes_flush_cache_l1;
_flush_cache_l2 = andes_flush_cache_l2;
_flush_cache_sigtramp = andes_flush_cache_sigtramp;
- switch (sc_lsize()) {
- case 64:
- scache_lsz64 = 1;
- break;
- case 128:
- scache_lsz64 = 0;
- break;
- default:
- printk(KERN_EMERG "Unknown L2 line size\n");
- while(1);
- }
+ _dma_cache_wback_inv = andes_dma_cache_wback_inv;
+ _dma_cache_wback = andes_dma_cache_wback;
+ _dma_cache_inv = andes_dma_cache_inv;
update_mmu_cache = andes_update_mmu_cache;
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [2.5 PATCH] R10K DMA cache flushing routines for non-coherent systems
2002-07-14 21:17 [2.5 PATCH] R10K DMA cache flushing routines for non-coherent systems Vivien Chappelier
@ 2002-07-15 13:06 ` Ralf Baechle
0 siblings, 0 replies; 2+ messages in thread
From: Ralf Baechle @ 2002-07-15 13:06 UTC (permalink / raw)
To: Vivien Chappelier; +Cc: linux-mips
On Sun, Jul 14, 2002 at 11:17:39PM +0200, Vivien Chappelier wrote:
> @@ -111,13 +115,96 @@
> }
> }
>
> +static void
> +andes_flush_cache_all(void)
> +{
> + andes_flush_cache_l1();
> + andes_flush_cache_l2();
> +}
We can optimize that slightly. By leaving it an empty function as it is :-)
> void
> andes_flush_icache_page(unsigned long page)
> {
> - if (scache_lsz64)
> - blast_scache64_page(page);
> - else
> - blast_scache128_page(page);
> + switch (sc_lsize) {
> + case 64:
> + blast_scache64_page(page);
> + break;
> + case 128:
> + blast_scache128_page(page);
> + break;
Eh...
So this is replacing a wrong version with another wrong piece of code.
There simply is no reason to flush the second level cache at this point.
That forcing instructions to be re-fetched from memory and that's slooow.
> + _dma_cache_wback_inv = andes_dma_cache_wback_inv;
> + _dma_cache_wback = andes_dma_cache_wback;
> + _dma_cache_inv = andes_dma_cache_inv;
This is breaking cache coherent machines.
Encore une fois :-)
Ralf
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2002-07-15 21:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-07-14 21:17 [2.5 PATCH] R10K DMA cache flushing routines for non-coherent systems Vivien Chappelier
2002-07-15 13:06 ` Ralf Baechle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox