From: William Jhun <wjhun@ayrnetworks.com>
To: "linux-mips@oss.sgi.com"@ayrnetworks.com
Subject: [PATCH] dma_cache_wback, pci DMA cache coherency changes
Date: Tue, 18 Jun 2002 10:03:47 -0700 [thread overview]
Message-ID: <20020618100347.A1361@ayrnetworks.com> (raw)
This is a re-hash of patches I sent out a while ago which do a more
optimal cache-flushing for pci_map_*() and pci_dma_sync_*(). It
basically does an invalidate for PCI_DMA_FROMDEVICE operations and a
writeback for PCI_DMA_TODEVICE pci_map_* (or writeback/invalidate if
PCI_DMA_BIDIRECTIONAL). This is similar to the ARM implementation.
Additionally, I filled in the _dma_cache_wback calls in the
arch/mips/c-*.c to call *_dma_cache_wback_inv* instead of calling
panic(). Some architectures could probably do a real writeback instead
of just wback_inv, but this will at least allow code that can use
writeback-only if available.
Note: I'm not familiar with a lot of these CPUs, but the change should
be innocuous. Could someone validate/improve these?
Thanks,
William
Index: include/asm/pci.h
===================================================================
RCS file: /cvs/linux/include/asm-mips/pci.h,v
retrieving revision 1.24.2.1
diff -u -r1.24.2.1 pci.h
--- include/asm/pci.h 2002/02/26 06:00:25 1.24.2.1
+++ include/asm/pci.h 2002/06/18 16:51:30
@@ -79,7 +79,40 @@
extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+#ifdef CONFIG_NONCOHERENT_IO
+/*
+ * Prepare buffer for DMA transfer
+ */
+static inline void prep_buffer(void *ptr, size_t size, int direction)
+{
+ switch(direction) {
+ case PCI_DMA_TODEVICE:
+ dma_cache_wback((unsigned long)ptr, size);
+ break;
+ case PCI_DMA_FROMDEVICE:
+ dma_cache_inv((unsigned long)ptr, size);
+ break;
+ case PCI_DMA_BIDIRECTIONAL:
+ dma_cache_wback_inv((unsigned long)ptr, size);
+ break;
+ }
+}
+
/*
+ * Prepare buffer for CPU access after DMA transfer
+ */
+static inline void sync_buffer(void *ptr, size_t size, int direction)
+{
+ switch(direction) {
+ case PCI_DMA_FROMDEVICE:
+ case PCI_DMA_BIDIRECTIONAL:
+ dma_cache_inv((unsigned long)ptr, size);
+ break;
+ }
+}
+#endif
+
+/*
* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
*
@@ -93,7 +126,7 @@
BUG();
#ifdef CONFIG_NONCOHERENT_IO
- dma_cache_wback_inv((unsigned long)ptr, size);
+ prep_buffer(ptr, size, direction);
#endif
return virt_to_bus(ptr);
@@ -132,7 +165,7 @@
addr = (unsigned long) page_address(page);
addr += offset;
#ifdef CONFIG_NONCOHERENT_IO
- dma_cache_wback_inv(addr, size);
+ prep_buffer((void*)addr, size, direction);
#endif
return virt_to_bus((void *)addr);
@@ -183,7 +216,7 @@
#ifdef CONFIG_NONCOHERENT_IO
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nents; i++, sg++)
- dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+ prep_buffer(sg->address, sg->length, direction);
#endif
return nents;
@@ -221,7 +254,7 @@
BUG();
#ifdef CONFIG_NONCOHERENT_IO
- dma_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), size);
+ sync_buffer(bus_to_virt(dma_handle), size, direction);
#endif
}
@@ -246,8 +279,9 @@
/* Make sure that gcc doesn't leave the empty loop body. */
#ifdef CONFIG_NONCOHERENT_IO
for (i = 0; i < nelems; i++, sg++)
- dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+ sync_buffer(sg->address, sg->length, direction);
#endif
+
}
/* Return whether the given PCI device DMA address mask can
Index: arch/mips/mm/c-mips32.c
===================================================================
RCS file: /cvs/linux/arch/mips/mm/c-mips32.c,v
retrieving revision 1.3.2.4
diff -u -r1.3.2.4 c-mips32.c
--- arch/mips/mm/c-mips32.c 2002/05/29 03:03:17 1.3.2.4
+++ arch/mips/mm/c-mips32.c 2002/06/18 16:52:21
@@ -393,12 +393,6 @@
}
}
-static void
-mips32_dma_cache_wback(unsigned long addr, unsigned long size)
-{
- panic("mips32_dma_cache called - should not happen.");
-}
-
/*
* While we're protected against bad userland addresses we don't care
* very much about what happens in that case. Usually a segmentation
@@ -603,7 +597,7 @@
_flush_icache_page = mips32_flush_icache_page;
_dma_cache_wback_inv = mips32_dma_cache_wback_inv_pc;
- _dma_cache_wback = mips32_dma_cache_wback;
+ _dma_cache_wback = mips32_dma_cache_wback_inv_pc;
_dma_cache_inv = mips32_dma_cache_inv_pc;
}
@@ -621,7 +615,7 @@
_flush_icache_page = mips32_flush_icache_page_s;
_dma_cache_wback_inv = mips32_dma_cache_wback_inv_sc;
- _dma_cache_wback = mips32_dma_cache_wback;
+ _dma_cache_wback = mips32_dma_cache_wback_inv_sc;
_dma_cache_inv = mips32_dma_cache_inv_sc;
}
Index: arch/mips/mm/c-r3k.c
===================================================================
RCS file: /cvs/linux/arch/mips/mm/c-r3k.c,v
retrieving revision 1.4.2.1
diff -u -r1.4.2.1 c-r3k.c
--- arch/mips/mm/c-r3k.c 2002/02/18 15:22:30 1.4.2.1
+++ arch/mips/mm/c-r3k.c 2002/06/18 16:52:21
@@ -337,7 +337,9 @@
_flush_icache_page = r3k_flush_icache_page;
_flush_icache_range = r3k_flush_icache_range;
+ _dma_cache_inv = r3k_dma_cache_wback_inv;
_dma_cache_wback_inv = r3k_dma_cache_wback_inv;
+ _dma_cache_wback = r3k_dma_cache_wback_inv;
printk("Primary instruction cache %dkb, linesize %d bytes\n",
(int) (icache_size >> 10), (int) icache_lsize);
Index: arch/mips/mm/c-r4k.c
===================================================================
RCS file: /cvs/linux/arch/mips/mm/c-r4k.c,v
retrieving revision 1.3.2.3
diff -u -r1.3.2.3 c-r4k.c
--- arch/mips/mm/c-r4k.c 2002/05/29 03:03:17 1.3.2.3
+++ arch/mips/mm/c-r4k.c 2002/06/18 16:52:21
@@ -1150,12 +1150,6 @@
}
}
-static void
-r4k_dma_cache_wback(unsigned long addr, unsigned long size)
-{
- panic("r4k_dma_cache called - should not happen.");
-}
-
/*
* While we're protected against bad userland addresses we don't care
* very much about what happens in that case. Usually a segmentation
@@ -1358,7 +1352,7 @@
_flush_icache_page = r4k_flush_icache_page_p;
_dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
- _dma_cache_wback = r4k_dma_cache_wback;
+ _dma_cache_wback = r4k_dma_cache_wback_inv_pc;
_dma_cache_inv = r4k_dma_cache_inv_pc;
}
@@ -1441,7 +1435,7 @@
___flush_cache_all = _flush_cache_all;
_flush_icache_page = r4k_flush_icache_page_s;
_dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
- _dma_cache_wback = r4k_dma_cache_wback;
+ _dma_cache_wback = r4k_dma_cache_wback_inv_sc;
_dma_cache_inv = r4k_dma_cache_inv_sc;
}
Index: arch/mips/mm/c-r5432.c
===================================================================
RCS file: /cvs/linux/arch/mips/mm/c-r5432.c,v
retrieving revision 1.4
diff -u -r1.4 c-r5432.c
--- arch/mips/mm/c-r5432.c 2001/11/30 13:28:06 1.4
+++ arch/mips/mm/c-r5432.c 2002/06/18 16:52:21
@@ -414,12 +414,6 @@
bc_inv(addr, size);
}
-static void
-r5432_dma_cache_wback(unsigned long addr, unsigned long size)
-{
- panic("r5432_dma_cache called - should not happen.");
-}
-
/*
* While we're protected against bad userland addresses we don't care
* very much about what happens in that case. Usually a segmentation
@@ -470,7 +464,7 @@
_flush_cache_page = r5432_flush_cache_page_d32i32;
_flush_icache_page = r5432_flush_icache_page_i32;
_dma_cache_wback_inv = r5432_dma_cache_wback_inv_pc;
- _dma_cache_wback = r5432_dma_cache_wback;
+ _dma_cache_wback = r5432_dma_cache_wback_inv_pc;
_dma_cache_inv = r5432_dma_cache_inv_pc;
_flush_cache_sigtramp = r5432_flush_cache_sigtramp;
Index: arch/mips/mm/c-rm7k.c
===================================================================
RCS file: /cvs/linux/arch/mips/mm/c-rm7k.c,v
retrieving revision 1.4.2.2
diff -u -r1.4.2.2 c-rm7k.c
--- arch/mips/mm/c-rm7k.c 2002/05/29 03:03:17 1.4.2.2
+++ arch/mips/mm/c-rm7k.c 2002/06/18 16:52:21
@@ -177,12 +177,6 @@
}
}
-static void
-rm7k_dma_cache_wback(unsigned long addr, unsigned long size)
-{
- panic("rm7k_dma_cache_wback called - should not happen.");
-}
-
/*
* While we're protected against bad userland addresses we don't care
* very much about what happens in that case. Usually a segmentation
@@ -342,7 +336,7 @@
_flush_icache_page = rm7k_flush_icache_page;
_dma_cache_wback_inv = rm7k_dma_cache_wback_inv;
- _dma_cache_wback = rm7k_dma_cache_wback;
+ _dma_cache_wback = rm7k_dma_cache_wback_inv;
_dma_cache_inv = rm7k_dma_cache_inv;
__flush_cache_all_d32i32();
Index: arch/mips/mm/c-tx39.c
===================================================================
RCS file: /cvs/linux/arch/mips/mm/c-tx39.c,v
retrieving revision 1.4
diff -u -r1.4 c-tx39.c
--- arch/mips/mm/c-tx39.c 2001/11/30 13:28:06 1.4
+++ arch/mips/mm/c-tx39.c 2002/06/18 16:52:21
@@ -225,11 +225,6 @@
}
}
-static void tx39_dma_cache_wback(unsigned long addr, unsigned long size)
-{
- panic("tx39_dma_cache called - should not happen.");
-}
-
static void tx39_flush_cache_sigtramp(unsigned long addr)
{
unsigned long config;
@@ -317,7 +312,7 @@
_flush_icache_range = tx39_flush_icache_range;
_dma_cache_wback_inv = tx39_dma_cache_wback_inv;
- _dma_cache_wback = tx39_dma_cache_wback;
+ _dma_cache_wback = tx39_dma_cache_wback_inv;
_dma_cache_inv = tx39_dma_cache_inv;
break;
Index: arch/mips/mm/c-tx49.c
===================================================================
RCS file: /cvs/linux/arch/mips/mm/c-tx49.c,v
retrieving revision 1.3.2.1
diff -u -r1.3.2.1 c-tx49.c
--- arch/mips/mm/c-tx49.c 2002/05/29 03:03:17 1.3.2.1
+++ arch/mips/mm/c-tx49.c 2002/06/18 16:52:21
@@ -343,12 +343,6 @@
}
}
-static void
-r4k_dma_cache_wback(unsigned long addr, unsigned long size)
-{
- panic("r4k_dma_cache called - should not happen.");
-}
-
/*
* While we're protected against bad userland addresses we don't care
* very much about what happens in that case. Usually a segmentation
@@ -429,7 +423,7 @@
_flush_icache_page = r4k_flush_icache_page;
_dma_cache_wback_inv = r4k_dma_cache_wback_inv;
- _dma_cache_wback = r4k_dma_cache_wback;
+ _dma_cache_wback = r4k_dma_cache_wback_inv;
_dma_cache_inv = r4k_dma_cache_inv;
_flush_cache_sigtramp = r4k_flush_cache_sigtramp;
next reply other threads:[~2002-06-18 17:04 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-06-18 17:03 William Jhun [this message]
2002-06-19 9:39 ` [PATCH] dma_cache_wback, pci DMA cache coherency changes Ralf Baechle
2002-06-19 18:22 ` [PATCH] include/asm-mips/pci.h William Jhun
2002-06-19 20:38 ` Paul Jackson
2002-06-19 20:38 ` Paul Jackson
2002-06-20 10:25 ` Ralf Baechle
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20020618100347.A1361@ayrnetworks.com \
--to=wjhun@ayrnetworks.com \
--cc="linux-mips@oss.sgi.com"@ayrnetworks.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.