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:
parent
9cebfb86a7
commit
8a474d01ee
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user