On 05/02/14 15:39, Izumi Tsutsui wrote:
skrll@ wrote:
[snip]
- BUS_DMASYNC_PREREAD seems incomplete
I think it's complete, but not as well optimized as, for example, the
cobalt one.
Probably depends on the definition of "complete."
(as a person who modified the cobalt one)

How about the attached?

---
Izumi Tsutsui

Index: sys/arch/mips/mips/bus_dma.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/bus_dma.c,v
retrieving revision 1.30
diff -u -p -r1.30 bus_dma.c
--- sys/arch/mips/mips/bus_dma.c        5 Feb 2014 19:09:06 -0000       1.30
+++ sys/arch/mips/mips/bus_dma.c        6 May 2014 07:28:13 -0000
@@ -856,13 +856,27 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm
                        mips_dcache_wbinv_range(vaddr, minlen);
                        break;
 
-               case BUS_DMASYNC_PREREAD:
-#if 1
-                       mips_dcache_wbinv_range(vaddr, minlen);
-#else
-                       mips_dcache_inv_range(vaddr, minlen);
-#endif
+               case BUS_DMASYNC_PREREAD: {
+                       struct mips_cache_info * const mci = &mips_cache_info;
+                       vaddr_t start = vaddr;
+                       vaddr_t end = vaddr + minlen;
+                       vaddr_t preboundary, firstboundary, lastboundary;
+
+                       preboundary = start & ~mci->mci_dcache_align_mask;
+                       firstboundary = (start + mci->mci_dcache_align_mask)
+                           & ~mci->mci_dcache_align_mask;
+                       lastboundary = end & ~mci->mci_dcache_align_mask;
+                       if (preboundary < start && preboundary < lastboundary)
+                               mips_dcache_wbinv_range(preboundary,
+                                   mci->mci_dcache_align);
+                       if (firstboundary < lastboundary)
+                               mips_dcache_inv_range(firstboundary,
+                                   lastboundary - firstboundary);
+                       if (lastboundary < end)
+                               mips_dcache_wbinv_range(lastboundary,
+                                   mci->mci_dcache_align);
                        break;
+               }
 
                case BUS_DMASYNC_PREWRITE:
                        mips_dcache_wb_range(vaddr, minlen);

Reply via email to