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.
This commit is contained in:
Ian Lepore 2015-01-08 01:28:46 +00:00
parent 9cebfb86a7
commit 8a474d01ee
3 changed files with 73 additions and 35 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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
@ -201,6 +206,26 @@
#define CP15_TLBIMVAA(rr) p15, 0, rr, c8, c7, 3 /* Invalidate unified TLB by MVA, all ASID */
#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
*/