Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Jan 2015 01:28:47 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r276803 - head/sys/arm/include
Message-ID:  <201501080128.t081SlBS035335@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Thu Jan  8 01:28:46 2015
New Revision: 276803
URL: https://svnweb.freebsd.org/changeset/base/276803

Log:
  Add accessors for the ARM CP15 performance monitor registers.  Also ensure
  that some #ifdef SMP code is also conditional on __ARM_ARCH >= 7; we don't
  support SMP on armv6, but some drivers and modules are compiled with it
  forced on via the compiler command line.

Modified:
  head/sys/arm/include/cpu-v6.h
  head/sys/arm/include/cpu.h
  head/sys/arm/include/sysreg.h

Modified: head/sys/arm/include/cpu-v6.h
==============================================================================
--- head/sys/arm/include/cpu-v6.h	Thu Jan  8 01:27:43 2015	(r276802)
+++ head/sys/arm/include/cpu-v6.h	Thu Jan  8 01:28:46 2015	(r276803)
@@ -150,6 +150,35 @@ _RF0(cp15_id_isar4_get, CP15_ID_ISAR4(%0
 _RF0(cp15_id_isar5_get, CP15_ID_ISAR5(%0))
 _RF0(cp15_cbar_get, CP15_CBAR(%0))
 
+/* Performance Monitor registers */
+
+#if __ARM_ARCH == 6 && defined(CPU_ARM1176)
+_RF0(cp15_pmccntr_get, CP15_PMCCNTR(%0))
+_WF1(cp15_pmccntr_set, CP15_PMCCNTR(%0))
+#elif __ARM_ARCH > 6
+_RF0(cp15_pmcr_get, CP15_PMCR(%0))
+_WF1(cp15_pmcr_set, CP15_PMCR(%0))
+_RF0(cp15_pmcnten_get, CP15_PMCNTENSET(%0))
+_WF1(cp15_pmcnten_set, CP15_PMCNTENSET(%0))
+_WF1(cp15_pmcnten_clr, CP15_PMCNTENCLR(%0))
+_RF0(cp15_pmovsr_get, CP15_PMOVSR(%0))
+_WF1(cp15_pmovsr_set, CP15_PMOVSR(%0))
+_WF1(cp15_pmswinc_set, CP15_PMSWINC(%0))
+_RF0(cp15_pmselr_get, CP15_PMSELR(%0))
+_WF1(cp15_pmselr_set, CP15_PMSELR(%0))
+_RF0(cp15_pmccntr_get, CP15_PMCCNTR(%0))
+_WF1(cp15_pmccntr_set, CP15_PMCCNTR(%0))
+_RF0(cp15_pmxevtyper_get, CP15_PMXEVTYPER(%0))
+_WF1(cp15_pmxevtyper_set, CP15_PMXEVTYPER(%0))
+_RF0(cp15_pmxevcntr_get, CP15_PMXEVCNTRR(%0))
+_WF1(cp15_pmxevcntr_set, CP15_PMXEVCNTRR(%0))
+_RF0(cp15_pmuserenr_get, CP15_PMUSERENR(%0))
+_WF1(cp15_pmuserenr_set, CP15_PMUSERENR(%0))
+_RF0(cp15_pminten_get, CP15_PMINTENSET(%0))
+_WF1(cp15_pminten_set, CP15_PMINTENSET(%0))
+_WF1(cp15_pminten_clr, CP15_PMINTENCLR(%0))
+#endif
+
 #undef	_FX
 #undef	_RF0
 #undef	_WF0
@@ -205,14 +234,7 @@ tlb_flush_range_local(vm_offset_t sva, v
 }
 
 /* Broadcasting operations. */
-#ifndef SMP
-
-#define tlb_flush_all() 		tlb_flush_all_local()
-#define tlb_flush_all_ng() 		tlb_flush_all_ng_local()
-#define tlb_flush(sva) 			tlb_flush_local(sva)
-#define tlb_flush_range(sva, size) 	tlb_flush_range_local(sva, size)
-
-#else /* SMP */
+#if __ARM_ARCH >= 7 && defined SMP
 
 static __inline void
 tlb_flush_all(void)
@@ -252,6 +274,13 @@ tlb_flush_range(vm_offset_t sva,  vm_siz
 		_CP15_TLBIMVAAIS(va);
 	dsb();
 }
+#else /* SMP */
+
+#define tlb_flush_all() 		tlb_flush_all_local()
+#define tlb_flush_all_ng() 		tlb_flush_all_ng_local()
+#define tlb_flush(sva) 			tlb_flush_local(sva)
+#define tlb_flush_range(sva, size) 	tlb_flush_range_local(sva, size)
+
 #endif /* SMP */
 
 /*
@@ -267,14 +296,14 @@ icache_sync(vm_offset_t sva, vm_size_t s
 
 	dsb();
 	for (va = sva; va < eva; va += arm_dcache_align) {
-#ifdef SMP
+#if __ARM_ARCH >= 7 && defined SMP
 		_CP15_DCCMVAU(va);
 #else
 		_CP15_DCCMVAC(va);
 #endif
 	}
 	dsb();
-#ifdef SMP
+#if __ARM_ARCH >= 7 && defined SMP
 	_CP15_ICIALLUIS();
 #else
 	_CP15_ICIALLU();
@@ -287,7 +316,7 @@ icache_sync(vm_offset_t sva, vm_size_t s
 static __inline void
 icache_inv_all(void)
 {
-#ifdef SMP
+#if __ARM_ARCH >= 7 && defined SMP
 	_CP15_ICIALLUIS();
 #else
 	_CP15_ICIALLU();
@@ -305,7 +334,7 @@ dcache_wb_pou(vm_offset_t sva, vm_size_t
 
 	dsb();
 	for (va = sva; va < eva; va += arm_dcache_align) {
-#ifdef SMP
+#if __ARM_ARCH >= 7 && defined SMP
 		_CP15_DCCMVAU(va);
 #else
 		_CP15_DCCMVAC(va);

Modified: head/sys/arm/include/cpu.h
==============================================================================
--- head/sys/arm/include/cpu.h	Thu Jan  8 01:27:43 2015	(r276802)
+++ head/sys/arm/include/cpu.h	Thu Jan  8 01:28:46 2015	(r276803)
@@ -4,9 +4,14 @@
 #ifndef MACHINE_CPU_H
 #define MACHINE_CPU_H
 
+#include <machine/acle-compat.h>
 #include <machine/armreg.h>
 #include <machine/frame.h>
 
+#if __ARM_ARCH >= 6
+#include <machine/cpu-v6.h>
+#endif
+
 void	cpu_halt(void);
 void	swi_vm(void *);
 
@@ -14,29 +19,8 @@ void	swi_vm(void *);
 static __inline uint64_t
 get_cyclecount(void)
 {
-/* This '#if' asks the question 'Does CP15/SCC include performance counters?' */
-#if defined(CPU_ARM1136) || defined(CPU_ARM1176) \
- || defined(CPU_MV_PJ4B) \
- || defined(CPU_CORTEXA) || defined(CPU_KRAIT)
-	uint32_t ccnt;
-	uint64_t ccnt64;
-
-	/*
-	 * Read PMCCNTR. Curses! Its only 32 bits.
-	 * TODO: Fix this by catching overflow with interrupt?
-	 */
-/* The ARMv6 vs ARMv7 divide is going to need a better way of
- * distinguishing between them.
- */
-#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
-	/* ARMv6 - Earlier model SCCs */
-	__asm __volatile("mrc p15, 0, %0, c15, c12, 1": "=r" (ccnt));
-#else
-	/* ARMv7 - Later model SCCs */
-	__asm __volatile("mrc p15, 0, %0, c9, c13, 0": "=r" (ccnt));
-#endif
-	ccnt64 = (uint64_t)ccnt;
-	return (ccnt64);
+#if __ARM_ARCH >= 6
+	return cp15_pmccntr_get();
 #else /* No performance counters, so use binuptime(9). This is slooooow */
 	struct bintime bt;
 

Modified: head/sys/arm/include/sysreg.h
==============================================================================
--- head/sys/arm/include/sysreg.h	Thu Jan  8 01:27:43 2015	(r276802)
+++ head/sys/arm/include/sysreg.h	Thu Jan  8 01:28:46 2015	(r276803)
@@ -29,6 +29,11 @@
 
 /*
  * Macros to make working with the System Control Registers simpler.
+ *
+ * Note that when register r0 is hard-coded in these definitions it means the
+ * cp15 operation neither reads nor writes the register, and r0 is used only
+ * because some syntatically-valid register name has to appear at that point to
+ * keep the asm parser happy.
  */
 
 #ifndef MACHINE_SYSREG_H
@@ -202,6 +207,26 @@
 #endif
 
 /*
+ * CP15 C9 registers
+ */
+#if __ARM_ARCH == 6 && defined(CPU_ARM1176)
+#define	CP15_PMCCNTR(rr)	p15, 0, rr, c15, c12, 1 /* PM Cycle Count Register */
+#elif __ARM_ARCH > 6
+#define	CP15_PMCR(rr)		p15, 0, rr,  c9, c12, 0 /* Performance Monitor Control Register */
+#define	CP15_PMCNTENSET(rr)	p15, 0, rr,  c9, c12, 1 /* PM Count Enable Set Register */
+#define	CP15_PMCNTENCLR(rr)	p15, 0, rr,  c9, c12, 2 /* PM Count Enable Clear Register */
+#define	CP15_PMOVSR(rr)		p15, 0, rr,  c9, c12, 3 /* PM Overflow Flag Status Register */
+#define	CP15_PMSWINC(rr)	p15, 0, rr,  c9, c12, 4 /* PM Software Increment Register */
+#define	CP15_PMSELR(rr)		p15, 0, rr,  c9, c12, 5 /* PM Event Counter Selection Register */
+#define	CP15_PMCCNTR(rr)	p15, 0, rr,  c9, c13, 0 /* PM Cycle Count Register */
+#define	CP15_PMXEVTYPER(rr)	p15, 0, rr,  c9, c13, 1 /* PM Event Type Select Register */
+#define	CP15_PMXEVCNTRR(rr)	p15, 0, rr,  c9, c13, 2 /* PM Event Count Register */
+#define	CP15_PMUSERENR(rr)	p15, 0, rr,  c9, c14, 0 /* PM User Enable Register */
+#define	CP15_PMINTENSET(rr)	p15, 0, rr,  c9, c14, 1 /* PM Interrupt Enable Set Register */
+#define	CP15_PMINTENCLR(rr)	p15, 0, rr,  c9, c14, 2 /* PM Interrupt Enable Clear Register */
+#endif
+
+/*
  * CP15 C10 registers
  */
 /* Without LPAE this is PRRR, with LPAE it's MAIR0 */



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