Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Dec 2013 22:26:25 +0000 (UTC)
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r259486 - in projects/specific_leg/sys/arm: arm include
Message-ID:  <201312162226.rBGMQPna048254@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: andrew
Date: Mon Dec 16 22:26:25 2013
New Revision: 259486
URL: http://svnweb.freebsd.org/changeset/base/259486

Log:
  Add support for runtime l2 cache type detection. Currently only correct for
  SoCs with a pl310 l2 cache. Other armv6+ SoCs don't appear to have any l2
  cache operations defined.

Modified:
  projects/specific_leg/sys/arm/arm/busdma_machdep-v6.c
  projects/specific_leg/sys/arm/arm/cpufunc.c
  projects/specific_leg/sys/arm/arm/pl310.c
  projects/specific_leg/sys/arm/arm/pmap-v6.c
  projects/specific_leg/sys/arm/include/pmap.h

Modified: projects/specific_leg/sys/arm/arm/busdma_machdep-v6.c
==============================================================================
--- projects/specific_leg/sys/arm/arm/busdma_machdep-v6.c	Mon Dec 16 22:07:49 2013	(r259485)
+++ projects/specific_leg/sys/arm/arm/busdma_machdep-v6.c	Mon Dec 16 22:26:25 2013	(r259486)
@@ -1049,9 +1049,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
 		} else {
 			sl = &map->slist[map->sync_count - 1];
 			if (map->sync_count == 0 ||
-#ifdef ARM_L2_PIPT
-			    curaddr != sl->busaddr + sl->datacount ||
-#endif
+			    (l2cache_type == L2CACHE_PIPT &&
+			     curaddr != sl->busaddr + sl->datacount) ||
 			    vaddr != sl->vaddr + sl->datacount) {
 				if (++map->sync_count > dmat->nsegments)
 					goto cleanup;
@@ -1171,15 +1170,38 @@ _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_inv_range(va, size)
-#endif
+static inline void
+l2cache_wb_range(vm_offset_t va, vm_offset_t pa, vm_size_t size)
+{
+	if (l2cache_type == L2CACHE_UNKNOWN)
+		return;
+	if (l2cache_type == L2CACHE_PIPT)
+		cpu_l2cache_wb_range(pa, size);
+	else
+		cpu_l2cache_wb_range(va, size);
+}
+
+static inline void
+l2cache_wbinv_range(vm_offset_t va, vm_offset_t pa, vm_size_t size)
+{
+	if (l2cache_type == L2CACHE_UNKNOWN)
+		return;
+	if (l2cache_type == L2CACHE_PIPT)
+		cpu_l2cache_wbinv_range(pa, size);
+	else
+		cpu_l2cache_wbinv_range(va, size);
+}
+
+static inline void
+l2cache_inv_range(vm_offset_t va, vm_offset_t pa, vm_size_t size)
+{
+	if (l2cache_type == L2CACHE_UNKNOWN)
+		return;
+	if (l2cache_type == L2CACHE_PIPT)
+		cpu_l2cache_inv_range(pa, size);
+	else
+		cpu_l2cache_inv_range(va, size);
+}
 
 void
 _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)

Modified: projects/specific_leg/sys/arm/arm/cpufunc.c
==============================================================================
--- projects/specific_leg/sys/arm/arm/cpufunc.c	Mon Dec 16 22:07:49 2013	(r259485)
+++ projects/specific_leg/sys/arm/arm/cpufunc.c	Mon Dec 16 22:26:25 2013	(r259486)
@@ -1111,6 +1111,7 @@ struct cpu_functions cortexa_cpufuncs = 
 struct cpu_functions cpufuncs;
 u_int cputype;
 u_int cpu_reset_needs_v4_MMU_disable;	/* flag used in locore.s */
+l2cache l2cache_type = L2CACHE_UNKNOWN;
 
 #if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) ||	\
   defined (CPU_ARM9E) || defined (CPU_ARM10) || defined (CPU_ARM1136) ||	\

Modified: projects/specific_leg/sys/arm/arm/pl310.c
==============================================================================
--- projects/specific_leg/sys/arm/arm/pl310.c	Mon Dec 16 22:07:49 2013	(r259485)
+++ projects/specific_leg/sys/arm/arm/pl310.c	Mon Dec 16 22:26:25 2013	(r259486)
@@ -393,6 +393,7 @@ pl310_attach(device_t dev)
 	cpufuncs.cf_l2cache_wbinv_range = pl310_wbinv_range;
 	cpufuncs.cf_l2cache_inv_range = pl310_inv_range;
 	cpufuncs.cf_l2cache_wb_range = pl310_wb_range;
+	l2cache_type = L2CACHE_PIPT;
 
 	return (0);
 }

Modified: projects/specific_leg/sys/arm/arm/pmap-v6.c
==============================================================================
--- projects/specific_leg/sys/arm/arm/pmap-v6.c	Mon Dec 16 22:07:49 2013	(r259485)
+++ projects/specific_leg/sys/arm/arm/pmap-v6.c	Mon Dec 16 22:26:25 2013	(r259486)
@@ -206,13 +206,18 @@ int pmap_debug_level = 0;
 
 #define	pa_to_pvh(pa)	(&pv_table[pa_index(pa)])
 
-#ifdef ARM_L2_PIPT
-#define pmap_l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range((pa), (size))
-#define pmap_l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range((pa), (size))
-#else
-#define pmap_l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range((va), (size))
-#define pmap_l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range((va), (size))
-#endif
+static void
+pmap_l2cache_wbinv_range(vm_offset_t va, vm_offset_t pa, vm_size_t size)
+{
+
+	if (l2cache_type == L2CACHE_UNKNOWN)
+		return;
+
+	if (l2cache_type == L2CACHE_PIPT)
+		cpu_l2cache_wbinv_range(pa, size);
+	else
+		cpu_l2cache_wbinv_range(va, size);
+}
 
 extern struct pv_addr systempage;
 

Modified: projects/specific_leg/sys/arm/include/pmap.h
==============================================================================
--- projects/specific_leg/sys/arm/include/pmap.h	Mon Dec 16 22:07:49 2013	(r259485)
+++ projects/specific_leg/sys/arm/include/pmap.h	Mon Dec 16 22:26:25 2013	(r259486)
@@ -52,6 +52,16 @@
 
 #include <machine/pte.h>
 #include <machine/cpuconf.h>
+
+typedef enum {
+	L2CACHE_UNKNOWN,
+	L2CACHE_VIVT,
+	L2CACHE_VIPT,
+	L2CACHE_PIPT,
+} l2cache;
+
+extern l2cache l2cache_type;
+
 /*
  * Pte related macros
  */
@@ -562,11 +572,14 @@ extern int pmap_needs_pte_sync;
 #define	PMAP_INCLUDE_PTE_SYNC
 #endif
 
-#ifdef ARM_L2_PIPT
-#define _sync_l2(pte, size) 	cpu_l2cache_wb_range(vtophys(pte), size)
-#else
-#define _sync_l2(pte, size) 	cpu_l2cache_wb_range(pte, size)
-#endif
+#define	_sync_l2(pte, size)			\
+do {						\
+	vm_offset_t __pte = (pte);		\
+						\
+	if (__pte == L2CACHE_PIPT)		\
+		__pte = vtophys(__pte);		\
+	cpu_l2cache_wb_range(__pte, size);	\
+} while (0)
 
 #define	PTE_SYNC(pte)							\
 do {									\



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