Module Name:    src
Committed By:   matt
Date:           Fri Mar 29 13:27:09 UTC 2013

Modified Files:
        src/sys/arch/arm/arm32: pmap.c

Log Message:
Fix pmap_flush_page to also flush the secondary cache, if there is one.
This solves a bus_dma problem with DMA from uncached pages.


To generate a diff of this commit:
cvs rdiff -u -r1.253 -r1.254 src/sys/arch/arm/arm32/pmap.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/arm32/pmap.c
diff -u src/sys/arch/arm/arm32/pmap.c:1.253 src/sys/arch/arm/arm32/pmap.c:1.254
--- src/sys/arch/arm/arm32/pmap.c:1.253	Wed Feb 13 23:14:35 2013
+++ src/sys/arch/arm/arm32/pmap.c	Fri Mar 29 13:27:08 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.253 2013/02/13 23:14:35 matt Exp $	*/
+/*	$NetBSD: pmap.c,v 1.254 2013/03/29 13:27:08 matt Exp $	*/
 
 /*
  * Copyright 2003 Wasabi Systems, Inc.
@@ -212,7 +212,7 @@
 #include <arm/cpuconf.h>
 #include <arm/arm32/katelib.h>
 
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.253 2013/02/13 23:14:35 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.254 2013/03/29 13:27:08 matt Exp $");
 
 #ifdef PMAP_DEBUG
 
@@ -2502,7 +2502,7 @@ void
 pmap_flush_page(struct vm_page_md *md, paddr_t pa, enum pmap_flush_op flush)
 {
 	vsize_t va_offset, end_va;
-	void (*cf)(vaddr_t, vsize_t);
+	bool wbinv_p;
 
 	if (arm_cache_prefer_mask == 0)
 		return;
@@ -2523,19 +2523,19 @@ pmap_flush_page(struct vm_page_md *md, p
 		 * Mark that the page is no longer dirty.
 		 */
 		md->pvh_attrs &= ~PVF_DIRTY;
-		cf = cpufuncs.cf_idcache_wbinv_range;
+		wbinv_p = true;
 		break;
 	case PMAP_FLUSH_SECONDARY:
 		va_offset = 0;
 		end_va = arm_cache_prefer_mask;
-		cf = cpufuncs.cf_idcache_wbinv_range;
+		wbinv_p = true;
 		md->pvh_attrs &= ~PVF_MULTCLR;
 		PMAPCOUNT(vac_flush_lots);
 		break;
 	case PMAP_CLEAN_PRIMARY:
 		va_offset = md->pvh_attrs & arm_cache_prefer_mask;
 		end_va = va_offset;
-		cf = cpufuncs.cf_dcache_wb_range;
+		wbinv_p = false;
 		/*
 		 * Mark that the page is no longer dirty.
 		 */
@@ -2552,6 +2552,8 @@ pmap_flush_page(struct vm_page_md *md, p
 	NPDEBUG(PDB_VAC, printf("pmap_flush_page: md=%p (attrs=%#x)\n",
 	    md, md->pvh_attrs));
 
+	const size_t scache_line_size = arm_scache.dcache_line_size;
+
 	for (; va_offset <= end_va; va_offset += PAGE_SIZE) {
 		const size_t pte_offset = va_offset >> PGSHIFT;
 		pt_entry_t * const ptep = &cdst_pte[pte_offset];
@@ -2575,7 +2577,22 @@ pmap_flush_page(struct vm_page_md *md, p
 		/*
 		 * Flush it.
 		 */
-		(*cf)(cdstp + va_offset, PAGE_SIZE);
+                vaddr_t va = cdstp + va_offset;  
+		if (scache_line_size != 0) {
+			cpu_dcache_wb_range(va, PAGE_SIZE); 
+			if (wbinv_p) {
+				cpu_sdcache_wbinv_range(va, pa, PAGE_SIZE); 
+				cpu_dcache_inv_range(va, PAGE_SIZE);
+			} else {
+				cpu_sdcache_wb_range(va, pa, PAGE_SIZE);
+			}
+		} else {
+			if (wbinv_p) {
+				cpu_dcache_wbinv_range(va, PAGE_SIZE);
+			} else {
+				cpu_dcache_wb_range(va, PAGE_SIZE);
+			}
+		}
 
 		/*
 		 * Restore the page table entry since we might have interrupted

Reply via email to