Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Mar 2009 09:57:31 GMT
From:      Ulf Lilleengen <lulf@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 158521 for review
Message-ID:  <200903010957.n219vVk1064821@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=158521

Change 158521 by lulf@lulf_carrot on 2009/03/01 09:57:00

	- Implement cache handling used by busdma.

Affected files ...

.. //depot/projects/avr32/src/sys/avr32/avr32/cache.c#2 edit

Differences ...

==== //depot/projects/avr32/src/sys/avr32/avr32/cache.c#2 (text+ko) ====

@@ -41,9 +41,24 @@
 #include <machine/reg_usart.h>
 #include <machine/at32ap700x.h>
 
-/* TODO:
-  - Implement l1 cache handling.
-*/
+/* Valid cache op codes. */
+#define ICACHE_INVALIDATE		0x01
+#define DCACHE_INVALIDATE		0x0b
+#define DCACHE_WRITEBACK		0x0c
+#define DCACHE_WRITEBACK_INVALIDATE	0x0d
+
+/* Next line boundary. */
+#define round_line(va, size) (((va) + ((size) - 1)) & ~((size) - 1))
+/* Previous line boundary. */
+#define trunc_line(va, size) ((va) & ~((size) - 1))
+
+/* Perform operation on cache line. */
+#define cache_line_op(va, op)			\
+	__asm__ __volatile(			\
+		"cache %0[0], %1"		\
+	    :					\
+	    : "r" (va), "n" (op)		\
+	    : "memory")
 
 struct avr32_cache_ops avr32_cache_ops;
 
@@ -58,14 +73,14 @@
 void avr32_nocache_wb_range(vm_offset_t, vm_size_t);
 
 /* For l1 cache. */
-void avr32_l1cache_sync_all(void);
-void avr32_l1cache_sync_range(vm_offset_t, vm_size_t);
-void avr32_l1cache_sync_range_index(vm_offset_t, vm_size_t);
-void avr32_l1cache_wbinv_all(void);
-void avr32_l1cache_wbinv_range(vm_offset_t, vm_size_t);
-void avr32_l1cache_wbinv_range_index(vm_offset_t, vm_size_t);
-void avr32_l1cache_inv_range(vm_offset_t, vm_size_t);
-void avr32_l1cache_wb_range(vm_offset_t, vm_size_t);
+void avr32_l1icache_sync_all(void);
+void avr32_l1icache_sync_range(vm_offset_t, vm_size_t);
+void avr32_l1icache_sync_range_index(vm_offset_t, vm_size_t);
+void avr32_l1dcache_wbinv_all(void);
+void avr32_l1dcache_wbinv_range(vm_offset_t, vm_size_t);
+void avr32_l1dcache_wbinv_range_index(vm_offset_t, vm_size_t);
+void avr32_l1dcache_inv_range(vm_offset_t, vm_size_t);
+void avr32_l1dcache_wb_range(vm_offset_t, vm_size_t);
 
 u_int avr32_icache_size;
 u_int avr32_icache_line_size;
@@ -116,11 +131,11 @@
 		avr32_cache_ops.mco_icache_sync_range_index =
 		    avr32_nocache_sync_range_index;
 	} else {
-		avr32_cache_ops.mco_icache_sync_all = avr32_l1cache_sync_all;
+		avr32_cache_ops.mco_icache_sync_all = avr32_l1icache_sync_all;
 		avr32_cache_ops.mco_icache_sync_range =
-		    avr32_l1cache_sync_range;
+		    avr32_l1icache_sync_range;
 		avr32_cache_ops.mco_icache_sync_range_index =
-		    avr32_l1cache_sync_range_index;
+		    avr32_l1icache_sync_range_index;
 	}
 
 	if (avr32_dcache_line_size == 1) {
@@ -132,13 +147,13 @@
         	avr32_cache_ops.mco_dcache_inv_range = avr32_nocache_inv_range;
         	avr32_cache_ops.mco_dcache_wb_range = avr32_nocache_wb_range;
 	} else {
-		avr32_cache_ops.mco_dcache_wbinv_all = avr32_l1cache_wbinv_all;
+		avr32_cache_ops.mco_dcache_wbinv_all = avr32_l1dcache_wbinv_all;
        		avr32_cache_ops.mco_dcache_wbinv_range =
-		    avr32_l1cache_wbinv_range;
+		    avr32_l1dcache_wbinv_range;
         	avr32_cache_ops.mco_dcache_wbinv_range_index =
-		    avr32_l1cache_wbinv_range_index;
-        	avr32_cache_ops.mco_dcache_inv_range = avr32_l1cache_inv_range;
-        	avr32_cache_ops.mco_dcache_wb_range = avr32_l1cache_wb_range;
+		    avr32_l1dcache_wbinv_range_index;
+        	avr32_cache_ops.mco_dcache_inv_range = avr32_l1dcache_inv_range;
+        	avr32_cache_ops.mco_dcache_wb_range = avr32_l1dcache_wb_range;
 
 	}
 }
@@ -155,35 +170,77 @@
 
 /* Operations for l1 cache. */
 void
-avr32_l1cache_sync_all(void)
+avr32_l1icache_sync_all(void)
 {
+	avr32_impl();
 }
 
 void
-avr32_l1cache_sync_range(vm_offset_t from, vm_size_t size)
+avr32_l1icache_sync_range(vm_offset_t from, vm_size_t size)
 {
+	avr32_impl();
 }
 
 void
-avr32_l1cache_sync_range_index(vm_offset_t from, vm_size_t size)
-{}
+avr32_l1icache_sync_range_index(vm_offset_t from, vm_size_t size)
+{
+	avr32_impl();
+}
 
 void
-avr32_l1cache_wbinv_all(void)
-{}
+avr32_l1dcache_wbinv_all(void)
+{
+	avr32_impl();
+}
 
 void
-avr32_l1cache_wbinv_range(vm_offset_t from, vm_size_t size)
-{}
+avr32_l1dcache_wbinv_range_index(vm_offset_t from, vm_size_t size)
+{
+	avr32_impl();
+}
 
 void
-avr32_l1cache_wbinv_range_index(vm_offset_t from, vm_size_t size)
-{}
+avr32_l1dcache_wbinv_range(vm_offset_t from, vm_size_t size)
+{
+	vm_offset_t va, va_end;
+
+	/* Put address at a cache line boundary. */
+	va = trunc_line(from, avr32_dcache_line_size);
+	va_end = round_line(from + size, avr32_dcache_line_size);
+
+	while (va < va_end) {
+		cache_line_op(va, DCACHE_WRITEBACK_INVALIDATE);
+		va += avr32_dcache_line_size;
+	}
+}
+
 
 void
-avr32_l1cache_inv_range(vm_offset_t from, vm_size_t size)
-{}
+avr32_l1dcache_inv_range(vm_offset_t from, vm_size_t size)
+{
+	vm_offset_t va, va_end;
+
+	/* Put address at a cache line boundary. */
+	va = trunc_line(from, avr32_dcache_line_size);
+	va_end = round_line(from + size, avr32_dcache_line_size);
+
+	while (va < va_end) {
+		cache_line_op(va, DCACHE_INVALIDATE);
+		va += avr32_dcache_line_size;
+	}
+}
 
 void
-avr32_l1cache_wb_range(vm_offset_t from, vm_size_t size)
-{}
+avr32_l1dcache_wb_range(vm_offset_t from, vm_size_t size)
+{
+	vm_offset_t va, va_end;
+
+	/* Put address at a cache line boundary. */
+	va = trunc_line(from, avr32_dcache_line_size);
+	va_end = round_line(from + size, avr32_dcache_line_size);
+
+	while (va < va_end) {
+		cache_line_op(va, DCACHE_WRITEBACK);
+		va += avr32_dcache_line_size;
+	}
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903010957.n219vVk1064821>