svn commit: r227040 - in projects/armv6/sys: arm/arm conf

Olivier Houchard cognet at FreeBSD.org
Wed Nov 2 21:48:31 UTC 2011


Author: cognet
Date: Wed Nov  2 21:48:31 2011
New Revision: 227040
URL: http://svn.freebsd.org/changeset/base/227040

Log:
  Introduce ARM_L2_PIPT, as arm can have either a PIPT or a VIPT L2 cache.
  Based on work by Ben Gray, as found here :
  https://gitorious.org/+freebsd-omap-team/freebsd/freebsd-omap/commits/bengray-wip

Modified:
  projects/armv6/sys/arm/arm/busdma_machdep-v6.c
  projects/armv6/sys/arm/arm/pmap-v6.c
  projects/armv6/sys/arm/arm/vm_machdep.c
  projects/armv6/sys/conf/options.arm

Modified: projects/armv6/sys/arm/arm/busdma_machdep-v6.c
==============================================================================
--- projects/armv6/sys/arm/arm/busdma_machdep-v6.c	Wed Nov  2 21:46:22 2011	(r227039)
+++ projects/armv6/sys/arm/arm/busdma_machdep-v6.c	Wed Nov  2 21:48:31 2011	(r227040)
@@ -106,6 +106,7 @@ struct bounce_page {
 
 struct sync_list {
 	vm_offset_t	vaddr;		/* kva of bounce buffer */
+	bus_addr_t	busaddr;	/* Physical address */
 	bus_size_t	datacount;	/* client data count */
 	STAILQ_ENTRY(sync_list) slinks;
 };
@@ -785,6 +786,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
 			STAILQ_INSERT_TAIL(&(map->slist), sl, slinks);
 			sl->vaddr = vaddr;
 			sl->datacount = sgsize;
+			sl->busaddr = curaddr;
 		}
 
 
@@ -1090,6 +1092,16 @@ _bus_dmamap_fix_user(vm_offset_t buf, bu
 }
 #endif
 
+#ifdef ARM_L2_PIPT
+#define l2cache_wb_range(va, pa, size) cpu_l2cache_wb_range(pa, size)
+#define l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range(pa, size)
+#define l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range(pa, size)
+#else
+#define l2cache_wb_range(va, pa, size) cpu_l2cache_wb_range(va, size)
+#define l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range(va, size)
+#define l2cache_inv_range(va, pa, size) cpu_l2cache_wbinv_range(va, size)
+#endif
+
 void
 _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
 {
@@ -1101,6 +1113,7 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 	vm_offset_t bbuf;
 	char _tmp_cl[arm_dcache_align], _tmp_clend[arm_dcache_align];
 #endif
+	int listcount = 0;
 
 		/* if buffer was from user space, it it possible that this
 		 * is not the same vm map. The fix is to map each page in
@@ -1116,10 +1129,10 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 	if ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
 
 		/* Handle data bouncing. */
-
 		CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
 		    "performing bounce", __func__, dmat, dmat->flags, op);
 
+		printf("FAUT QUE CA BOUNCE\n");
 		if (op & BUS_DMASYNC_PREWRITE) {
 			while (bpage != NULL) {
 				bcopy((void *)bpage->datavaddr,
@@ -1127,6 +1140,9 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 				      bpage->datacount);
 				cpu_dcache_wb_range((vm_offset_t)bpage->vaddr,
 					bpage->datacount);
+				l2cache_wb_range((vm_offset_t)bpage->vaddr,
+				    (vm_offset_t)bpage->busaddr, 
+				    bpage->datacount);
 				bpage = STAILQ_NEXT(bpage, links);
 			}
 			dmat->bounce_zone->total_bounced++;
@@ -1138,6 +1154,9 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 
 			cpu_dcache_inv_range((vm_offset_t)bpage->vaddr,
 					bpage->datacount);
+			l2cache_inv_range((vm_offset_t)bpage->vaddr,
+			    (vm_offset_t)bpage->busaddr,
+			    bpage->datacount);
 			while (bpage != NULL) {
 				bcopy((void *)bpage->vaddr,
 				      (void *)bpage->datavaddr,
@@ -1148,6 +1167,11 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 		}
 	}
 
+	sl = STAILQ_FIRST(&map->slist);
+	while (sl) {
+		listcount++;
+		sl = STAILQ_NEXT(sl, slinks);
+	}
 	if ((sl = STAILQ_FIRST(&map->slist)) != NULL) {
 		/* ARM caches are not self-snooping for dma */
 
@@ -1158,6 +1182,8 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 		case BUS_DMASYNC_PREWRITE:
 			while (sl != NULL) {
 			    cpu_dcache_wb_range(sl->vaddr, sl->datacount);
+			    l2cache_wb_range(sl->vaddr, sl->busaddr,
+				sl->datacount);
 			    sl = STAILQ_NEXT(sl, slinks);
 			}
 			break;
@@ -1165,17 +1191,23 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 		case BUS_DMASYNC_PREREAD:
 			while (sl != NULL) {
 					/* write back the unaligned portions */
+				vm_paddr_t physaddr = sl->busaddr, ephysaddr;
 				buf = sl->vaddr;
 				len = sl->datacount;
 				ebuf = buf + len;	/* end of buffer */
+				ephysaddr = physaddr + len;
 				unalign = buf & arm_dcache_align_mask;
 				if (unalign) {
 						/* wbinv leading fragment */
 					buf &= ~arm_dcache_align_mask;
+					physaddr &= ~arm_dcache_align_mask;
 					cpu_dcache_wbinv_range(buf,
 							arm_dcache_align);
+					l2cache_wbinv_range(buf, physaddr,
+					    arm_dcache_align);
 					buf += arm_dcache_align;
-						/* number byte in buffer wbinv */
+					physaddr += arm_dcache_align;
+					/* number byte in buffer wbinv */
 					unalign = arm_dcache_align - unalign;
 					if (len > unalign)
 						len -= unalign;
@@ -1187,11 +1219,15 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 						/* wbinv trailing fragment */
 					len -= unalign;
 					ebuf -= unalign;
+					ephysaddr -= unalign;
 					cpu_dcache_wbinv_range(ebuf,
-								arm_dcache_align);
+							arm_dcache_align);
+					l2cache_wbinv_range(ebuf, ephysaddr,
+					    arm_dcache_align);
 				}
 				if (ebuf > buf) {
 					cpu_dcache_inv_range(buf, len);
+					l2cache_inv_range(buf, physaddr, len);
 				}
 				sl = STAILQ_NEXT(sl, slinks);
 			}
@@ -1200,6 +1236,8 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 		case BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD:
 			while (sl != NULL) {
 				cpu_dcache_wbinv_range(sl->vaddr, sl->datacount);
+				l2cache_wbinv_range(sl->vaddr,
+				    sl->busaddr, sl->datacount);
 				sl = STAILQ_NEXT(sl, slinks);
 			}
 			break;
@@ -1210,10 +1248,13 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 			     panic("_bus_dmamap_sync: wrong user map. apply fix");
 			while (sl != NULL) {
 					/* write back the unaligned portions */
+				vm_paddr_t physaddr;
 				buf = sl->vaddr;
 				len = sl->datacount;
+				physaddr = sl->busaddr;
 				bbuf = buf & ~arm_dcache_align_mask;
 				ebuf = buf + len;
+				physaddr = physaddr & ~arm_dcache_align_mask;
 				unalign = buf & arm_dcache_align_mask;
 				if (unalign) {
 					memcpy(_tmp_cl, (void *)bbuf, unalign);
@@ -1227,6 +1268,7 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 				}
 					/* inv are cache length aligned */
 				cpu_dcache_inv_range(bbuf, len);
+				l2cache_inv_range(bbuf, physaddr, len);
 
 				unalign = (vm_offset_t)buf & arm_dcache_align_mask;
 				if (unalign) {

Modified: projects/armv6/sys/arm/arm/pmap-v6.c
==============================================================================
--- projects/armv6/sys/arm/arm/pmap-v6.c	Wed Nov  2 21:46:22 2011	(r227039)
+++ projects/armv6/sys/arm/arm/pmap-v6.c	Wed Nov  2 21:48:31 2011	(r227040)
@@ -2372,7 +2372,11 @@ pmap_change_attr(vm_offset_t sva, vm_siz
 
 		pte = *ptep &~ L2_S_CACHE_MASK;
 		cpu_idcache_wbinv_range(tmpva, PAGE_SIZE);
+#ifdef ARM_L2_PIPT
+		cpu_l2cache_wbinv_range(pte & L2_S_FRAME, PAGE_SIZE);
+#else
 		cpu_l2cache_wbinv_range(tmpva, PAGE_SIZE);
+#endif
 		cpu_tlb_flushID_SE(tmpva);
 
 		dprintf("%s: for va:%x ptep:%x pte:%x\n",

Modified: projects/armv6/sys/arm/arm/vm_machdep.c
==============================================================================
--- projects/armv6/sys/arm/arm/vm_machdep.c	Wed Nov  2 21:46:22 2011	(r227039)
+++ projects/armv6/sys/arm/arm/vm_machdep.c	Wed Nov  2 21:48:31 2011	(r227040)
@@ -485,7 +485,11 @@ arm_remap_nocache(void *addr, vm_size_t 
 		for (; tomap < (vm_offset_t)ret + size; tomap += PAGE_SIZE,
 		    vaddr += PAGE_SIZE, physaddr += PAGE_SIZE, i++) {
 			cpu_idcache_wbinv_range(vaddr, PAGE_SIZE);
+#ifdef ARM_L2_PIPT
+			cpu_l2cache_wbinv_range(physaddr, PAGE_SIZE);
+#else
 			cpu_l2cache_wbinv_range(vaddr, PAGE_SIZE);
+#endif
 			pmap_kenter_nocache(tomap, physaddr);
 			cpu_tlb_flushID_SE(vaddr);
 			arm_nocache_allocated[i / BITS_PER_INT] |= 1 << (i % 

Modified: projects/armv6/sys/conf/options.arm
==============================================================================
--- projects/armv6/sys/conf/options.arm	Wed Nov  2 21:46:22 2011	(r227039)
+++ projects/armv6/sys/conf/options.arm	Wed Nov  2 21:48:31 2011	(r227040)
@@ -3,6 +3,7 @@ ARM9_CACHE_WRITE_THROUGH	opt_global.h
 ARM_CACHE_LOCK_ENABLE	opt_global.h
 ARMFPE			opt_global.h
 ARM_KERN_DIRECTMAP	opt_vm.h
+ARM_L2_PIPT		opt_global.h
 ARM_USE_SMALL_ALLOC	opt_global.h
 AT91C_MASTER_CLOCK	opt_global.h
 AT91C_MAIN_CLOCK	opt_at91.h


More information about the svn-src-projects mailing list