summaryrefslogtreecommitdiffstats
path: root/sys/arm/include
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2015-02-13 17:53:11 +0000
committerian <ian@FreeBSD.org>2015-02-13 17:53:11 +0000
commite11cd4215f13e902be227c11ae437eb6ebe1a7c6 (patch)
tree2acfcfcdf1f6f409feafaf27416ed5b19879cbe8 /sys/arm/include
parent45adae0187fda949085e8fde3e477559574c5156 (diff)
downloadFreeBSD-src-e11cd4215f13e902be227c11ae437eb6ebe1a7c6.zip
FreeBSD-src-e11cd4215f13e902be227c11ae437eb6ebe1a7c6.tar.gz
MFC r276803, r276808:
Add accessors for the ARM CP15 performance monitor registers. Move the inclusion of cpu-v6.h inside the #ifdef _KERNEL block.
Diffstat (limited to 'sys/arm/include')
-rw-r--r--sys/arm/include/cpu-v6.h53
-rw-r--r--sys/arm/include/cpu.h29
-rw-r--r--sys/arm/include/sysreg.h25
3 files changed, 72 insertions, 35 deletions
diff --git a/sys/arm/include/cpu-v6.h b/sys/arm/include/cpu-v6.h
index 550fa47..8d1a413 100644
--- a/sys/arm/include/cpu-v6.h
+++ b/sys/arm/include/cpu-v6.h
@@ -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, vm_size_t size)
}
/* 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_size_t size)
_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 size)
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 size)
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 size)
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);
diff --git a/sys/arm/include/cpu.h b/sys/arm/include/cpu.h
index dd7b6ac..3411f32 100644
--- a/sys/arm/include/cpu.h
+++ b/sys/arm/include/cpu.h
@@ -4,6 +4,7 @@
#ifndef MACHINE_CPU_H
#define MACHINE_CPU_H
+#include <machine/acle-compat.h>
#include <machine/armreg.h>
#include <machine/frame.h>
@@ -11,32 +12,14 @@ void cpu_halt(void);
void swi_vm(void *);
#ifdef _KERNEL
+#if __ARM_ARCH >= 6
+#include <machine/cpu-v6.h>
+#endif
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;
diff --git a/sys/arm/include/sysreg.h b/sys/arm/include/sysreg.h
index ad29703..7eec727 100644
--- a/sys/arm/include/sysreg.h
+++ b/sys/arm/include/sysreg.h
@@ -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 */
OpenPOWER on IntegriCloud