dslinux/linux-2.6.x/arch/arm/mm cache-v4wb.S

amadeus dslinux_amadeus at user.in-berlin.de
Fri Aug 25 12:35:04 CEST 2006


Update of /cvsroot/dslinux/dslinux/linux-2.6.x/arch/arm/mm
In directory antilope:/tmp/cvs-serv31984/linux-2.6.x/arch/arm/mm

Modified Files:
	cache-v4wb.S 
Log Message:
Improve ARM9 cache functions; especially for large memory ranges.

Index: cache-v4wb.S
===================================================================
RCS file: /cvsroot/dslinux/dslinux/linux-2.6.x/arch/arm/mm/cache-v4wb.S,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cache-v4wb.S	9 Jun 2006 20:32:43 -0000	1.4
+++ cache-v4wb.S	25 Aug 2006 10:35:02 -0000	1.5
@@ -62,15 +62,36 @@
  *	Clean and invalidate the entire cache.
  */
 ENTRY(v4wb_flush_kern_cache_all)
-	mov	ip, #0
-	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
-__flush_whole_cache:
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	/* FALLTHROUGH */
+/*
+ *	flush_dcache_all()
+ *
+ *	Clean and invalidate the entire d-cache.
+ */
+ENTRY(v4wb_flush_dcache_all)
+#ifdef CONFIG_ARCH_NDS				/* we can flush the D-cache line by line */
+	mov	r0, #(CACHE_DSIZE/4)
+1:	sub	r0, r0, #CACHE_DLINESIZE	@ next line
+	mcr	p15, 0, r0, c7, c14, 2		@ clean and flush a D-cache line
+	add	r0, r0, #0x40000000		@ next segment
+	mcr	p15, 0, r0, c7, c14, 2		@ clean and flush a D-cache line
+	add	r0, r0, #0x40000000		@ next segment
+	mcr	p15, 0, r0, c7, c14, 2		@ clean and flush a D-cache line
+	add	r0, r0, #0x40000000		@ next segment
+	mcr	p15, 0, r0, c7, c14, 2		@ clean and flush a D-cache line
+	adds	r0, r0, #0x40000000		@ next segment
+	bne	1b				@ next cache line
+#else
 	mov	r0, #FLUSH_BASE
 	add	r1, r0, #CACHE_DSIZE
 1:	ldr	r2, [r0], #32
 	cmp	r0, r1
 	blo	1b
-	mcr	p15, 0, ip, c7, c10, 4		@ drain write buffer
+#endif
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
 	mov	pc, lr
 
 /*
@@ -84,20 +105,47 @@
  *	- flags	- vma_area_struct flags describing address space
  */
 ENTRY(v4wb_flush_user_cache_range)
-	sub	r3, r1, r0			@ calculate total size
 	tst	r2, #VM_EXEC			@ executable region?
-	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	bne	v4wb_flush_cache_range		@ yes: flush i-cache and d-cache
+	/* FALLTHROUGH */
 
-	cmp	r3, #CACHE_DLIMIT		@ total size >= limit?
-	bhs	__flush_whole_cache		@ flush whole D cache
+/*
+ *	dma_flush_range(start, end)
+ *
+ *	Clean and invalidate the specified virtual address range.
+ *
+ *	- start  - virtual start address
+ *	- end	 - virtual end address
+ */
+ENTRY(v4wb_dma_flush_range)
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+	/* FALLTHROUGH */
 
-1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+/*
+ *	flush_dcache_range(start, end)
+ *
+ *	Invalidate a range of D cache entries in the specified
+ *	address space.
+ *
+ *	- start - start address (inclusive, page aligned)
+ *	- end	- end address (exclusive, page aligned)
+ */
+ENTRY(v4wb_flush_dcache_range)
+	sub	ip, r1, r0			@ calculate total size
+	cmp	ip, #CACHE_DLIMIT		@ total size >= limit?
+	bhs	v4wb_flush_dcache_all		@ yes: flush the complete d-cache
+1:
+#ifdef CONFIG_ARCH_NDS				/* we can clean and invalidate at once */
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and flush a D-cache line
+#else
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+#endif
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
 	blo	1b
-	tst	r2, #VM_EXEC
-	mcrne	p15, 0, ip, c7, c10, 4		@ drain write buffer
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
 	mov	pc, lr
 
 /*
@@ -136,18 +184,35 @@
  *	- end	 - virtual end address
  */
 ENTRY(v4wb_coherent_user_range)
-	bic	r0, r0, #CACHE_DLINESIZE - 1
-1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	bic	r0, r0, #CACHE_DLINESIZE - 1	@ align to cache line
+	/* fall through */
+/*
+ *	flush_cache_range(start, end)
+ *
+ *	Invalidate a range of I+D cache entries in the specified
+ *	address space.
+ *
+ *	- start - start address (inclusive, page aligned)
+ *	- end	- end address (exclusive, page aligned)
+ */
+ENTRY(v4wb_flush_cache_range)
+	sub	ip, r1, r0			@ calculate total size
+	cmp	ip, #CACHE_DLIMIT		@ total size >= limit?
+	bhs	v4wb_flush_kern_cache_all	@ yes: flush the complete i+d-cache
+2:
+#ifdef CONFIG_ARCH_NDS				/* we can clean and invalidate at once */
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and flush a D-cache line
+#else
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+#endif
+	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
-	blo	1b
+	blo	2b
 	mov	ip, #0
-	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
-	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain write buffer
 	mov	pc, lr
-
-
 /*
  *	dma_inv_range(start, end)
  *
@@ -169,6 +234,7 @@
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
 	blo	1b
+	mov	r0, #0
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
 	mov	pc, lr
 
@@ -182,32 +248,43 @@
  */
 ENTRY(v4wb_dma_clean_range)
 	bic	r0, r0, #CACHE_DLINESIZE - 1
+	sub	ip, r1, r0			@ calculate total size
+	cmp	ip, #CACHE_DLIMIT		@ total size >= limit?
+	bhs	v4wb_dma_clean_all		@ yes: clean the complete d-cache
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
 	blo	1b
+	mov	r0, #0
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
 	mov	pc, lr
 
-/*
- *	dma_flush_range(start, end)
- *
- *	Clean and invalidate the specified virtual address range.
- *
- *	- start  - virtual start address
- *	- end	 - virtual end address
- */
-ENTRY(v4wb_dma_flush_range)
-	bic	r0, r0, #CACHE_DLINESIZE - 1
-1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
-	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
-	add	r0, r0, #CACHE_DLINESIZE
+ENTRY(v4wb_dma_clean_all)
+#ifdef CONFIG_ARCH_NDS				/* we can clean the D-cache line by line */
+	mov	r0, #(CACHE_DSIZE/4)
+1:	sub	r0, r0, #CACHE_DLINESIZE	@ next line
+	mcr	p15, 0, r0, c7, c10, 2		@ clean a D-cache line
+	add	r0, r0, #0x40000000		@ next segment
+	mcr	p15, 0, r0, c7, c10, 2		@ clean a D-cache line
+	add	r0, r0, #0x40000000		@ next segment
+	mcr	p15, 0, r0, c7, c10, 2		@ clean a D-cache line
+	add	r0, r0, #0x40000000		@ next segment
+	mcr	p15, 0, r0, c7, c10, 2		@ clean a D-cache line
+	adds	r0, r0, #0x40000000		@ next segment
+	bne	1b				@ next cache line
+#else
+	mov	r0, #FLUSH_BASE
+	add	r1, r0, #CACHE_DSIZE
+1:	ldr	r2, [r0], #32
 	cmp	r0, r1
 	blo	1b
+#endif
+	mov	r0, #0
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
 	mov	pc, lr
 
 
+
 	__INITDATA
 
 	.type	v4wb_cache_fns, #object




More information about the dslinux-commit mailing list