commit 5b823310b05148739c25af1fd753d7c4f5039edf Author: adrian chadd Date: Sun Dec 20 20:46:08 2015 -0800 Handle non-coherent L2 caches and busdma. The cache line flushing and partial flushing bits need to know about the L1 /and/ L2 size. So, introduce a new variable which is the max of L1/L2 cache and use it when doing partial flushes and memory allocation. This drastically improves USB behaviour! diff --git a/sys/mips/include/cache.h b/sys/mips/include/cache.h index 9fc9159..98198e1 100644 --- a/sys/mips/include/cache.h +++ b/sys/mips/include/cache.h @@ -161,6 +161,8 @@ extern struct mips_cache_ops mips_cache_ops; /* PRIMARY CACHE VARIABLES */ extern int mips_picache_linesize; extern int mips_pdcache_linesize; +extern int mips_scache_linesize; +extern int mips_dcache_max_linesize; #define __mco_noargs(prefix, x) \ do { \ diff --git a/sys/mips/mips/busdma_machdep.c b/sys/mips/mips/busdma_machdep.c index 90ec399..36a92b9 100644 --- a/sys/mips/mips/busdma_machdep.c +++ b/sys/mips/mips/busdma_machdep.c @@ -1015,10 +1015,10 @@ _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map) static void bus_dmamap_sync_buf(vm_offset_t buf, int len, bus_dmasync_op_t op) { - char tmp_cl[mips_pdcache_linesize], tmp_clend[mips_pdcache_linesize]; + char tmp_cl[mips_dcache_max_linesize], tmp_clend[mips_dcache_max_linesize]; vm_offset_t buf_cl, buf_clend; vm_size_t size_cl, size_clend; - int cache_linesize_mask = mips_pdcache_linesize - 1; + int cache_linesize_mask = mips_dcache_max_linesize - 1; /* * dcache invalidation operates on cache line aligned addresses @@ -1030,7 +1030,7 @@ bus_dmamap_sync_buf(vm_offset_t buf, int len, bus_dmasync_op_t op) buf_cl = buf & ~cache_linesize_mask; size_cl = buf & cache_linesize_mask; buf_clend = buf + len; - size_clend = (mips_pdcache_linesize - + size_clend = (mips_dcache_max_linesize - (buf_clend & cache_linesize_mask)) & cache_linesize_mask; switch (op) { @@ -1061,7 +1061,7 @@ bus_dmamap_sync_buf(vm_offset_t buf, int len, bus_dmasync_op_t op) if (size_cl) mips_dcache_wbinv_range(buf_cl, size_cl); if (size_clend && (size_cl == 0 || - buf_clend - buf_cl > mips_pdcache_linesize)) + buf_clend - buf_cl > mips_dcache_max_linesize)) mips_dcache_wbinv_range(buf_clend, size_clend); break; @@ -1094,7 +1094,7 @@ bus_dmamap_sync_buf(vm_offset_t buf, int len, bus_dmasync_op_t op) if (size_cl) mips_dcache_wbinv_range(buf_cl, size_cl); if (size_clend && (size_cl == 0 || - buf_clend - buf_cl > mips_pdcache_linesize)) + buf_clend - buf_cl > mips_dcache_max_linesize)) mips_dcache_wbinv_range(buf_clend, size_clend); break; diff --git a/sys/mips/mips/cache_mipsNN.c b/sys/mips/mips/cache_mipsNN.c index 50eb76b..a9b4bc1 100644 --- a/sys/mips/mips/cache_mipsNN.c +++ b/sys/mips/mips/cache_mipsNN.c @@ -97,6 +97,8 @@ xlp_sync(void) */ int mips_picache_linesize; int mips_pdcache_linesize; +int mips_scache_linesize; +int mips_dcache_max_linesize; static int picache_size; static int picache_stride; @@ -147,6 +149,10 @@ mipsNN_cache_init(struct mips_cpuinfo * cpuinfo) mips_picache_linesize = cpuinfo->l1.ic_linesize; mips_pdcache_linesize = cpuinfo->l1.dc_linesize; + /* Defaults */ + mips_scache_linesize = 0; + mips_dcache_max_linesize = mips_pdcache_linesize; + picache_size = cpuinfo->l1.ic_size; picache_way_mask = cpuinfo->l1.ic_nways - 1; pdcache_size = cpuinfo->l1.dc_size; @@ -157,6 +163,12 @@ mipsNN_cache_init(struct mips_cpuinfo * cpuinfo) sdcache_size = cpuinfo->l2.dc_size; sdcache_way_mask = cpuinfo->l2.dc_nways - 1; + if (cpuinfo->l2.dc_size) { + mips_scache_linesize = cpuinfo->l2.dc_linesize; + if (cpuinfo->l2.dc_linesize > mips_dcache_max_linesize) + mips_dcache_max_linesize = cpuinfo->l2.dc_linesize; + } + #define CACHE_DEBUG #ifdef CACHE_DEBUG printf("Cache info:\n"); @@ -166,6 +178,7 @@ mipsNN_cache_init(struct mips_cpuinfo * cpuinfo) printf(" picache_loopcount = %d\n", picache_loopcount); printf(" pdcache_stride = %d\n", pdcache_stride); printf(" pdcache_loopcount = %d\n", pdcache_loopcount); + printf(" max line size = %d\n", mips_dcache_max_linesize); #endif }