#ifndef _arch_arm_include_asm_performance_h_ #define _arch_arm_include_asm_performance_h_ #define PMCR "p15, 0, %0, c15, c12, 0" #define PMCCNTR "p15, 0, %0, c15, c12, 1" #define PMEVCNTR0 "p15, 0, %0, c15, c12, 2" #define PMEVCNTR1 "p15, 0, %0, c15, c12, 3" #define PM_EVENT_L1I_CACHE_MISS_SPEC 0x00 #define PM_EVENT_L1I_CACHE_STALL 0x01 #define PM_EVENT_DATA_DEP_STALL 0x02 #define PM_EVENT_L1I_TLB_MISS 0x03 #define PM_EVENT_L1D_TLB_MISS 0x04 #define PM_EVENT_BR_EXEC 0x05 #define PM_EVENT_BR_MIS_PRED 0x06 #define PM_EVENT_INST_EXEC 0x07 #define PM_EVENT_L1D_CACHABLE_ACCESS 0x09 #define PM_EVENT_L1D_CACHE_ACCESS 0x0A #define PM_EVENT_L1D_CACHE_MISS 0x0B #define PM_EVENT_L1D_CACHE_WB 0x0C #define PM_EVENT_PC_WRITE 0x0D #define PM_EVENT_MAIN_TLB_MISS 0x0F #define PM_EVENT_EXT_DATA_ACCESS 0x10 #define PM_EVENT_LDST_UNIT_STALL 0x11 #define PM_EVENT_WB_DRAIN 0x12 #define PM_EVENT_ETM_EXT_OUT0 0x20 #define PM_EVENT_ETM_EXT_OUT1 0x21 #define PM_EVENT_ETM_EXT_OUT01 0x22 #define PM_EVENT_CALL_EXEC 0x23 #define PM_EVENT_RETURN_EXEC 0x24 #define PM_EVENT_RETURN_EXEC_PRED_VAL 0x25 #define PM_EVENT_RETURN_EXEC_PRED_INVAL 0x26 #define PM_EVENT_CPU_CYCLES 0xFF #define PM_EVENT_LAST PM_EVENT_CPU_CYCLES + 1 union __performance_monitor_control { struct _performance_monitor_control { unsigned int reserved1 : 4; /* 31:28 */ unsigned int EvtCount0 : 8; /* 27:20 */ unsigned int EvtCount1 : 8; /* 19:12 */ unsigned int EventBusEnable : 1; /* 11 */ unsigned int CycleCounterOverflow : 1; /* 10 */ unsigned int Counter0_Overflow : 1; /* 9 */ unsigned int Counter1_Overflow : 1; /* 8 */ unsigned int reserved2 : 1; /* 7 */ unsigned int CycleCounterIrqEnable : 1; /* 6 */ unsigned int Counter0_IrqEnable : 1; /* 5 */ unsigned int Counter1_IrqEnable : 1; /* 4 */ unsigned int CycleCounterDivider : 1; /* 3 */ unsigned int CycleCounterReset : 1; /* 2 */ unsigned int CounterReset : 1; /* 2 */ unsigned int EnableCounters : 1; } Bits; volatile unsigned int Register; }; /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static inline unsigned int read_p15_performance_monitor_control(void) { unsigned int value; __asm__ __volatile__ ("mrc " PMCR : "=r" (value)); return value; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static inline void write_p15_performance_monitor_control(unsigned int value) { __asm__ __volatile__ ("mcr " PMCR : : "r" (value)); return; } static inline void write_p15_cycle_counter(unsigned int value) { __asm__ __volatile__ ("mcr " PMCCNTR : : "r" (value)); return; } static inline void write_p15_performance_counter(unsigned int counter, unsigned int value) { if(counter & 0x01) __asm__ __volatile__ ("mcr " PMEVCNTR1 : : "r" (value)); else __asm__ __volatile__ ("mcr " PMEVCNTR0 : : "r" (value)); return; } static inline void p15_reset_performance_counter(unsigned int counter) { write_p15_performance_counter(counter, 0); return; } static inline void write_p15_performance_event_type(unsigned int counter, unsigned int value) { unsigned int shift = ((1 - (counter & 0x01)) << 3) + 12; unsigned int preserve = read_p15_performance_monitor_control() & (~(0xFF << shift)); __asm__ __volatile__ ("mcr " PMCR : : "r" (preserve | ((value & 0xFF) << shift))); return; } static inline void write_p15_performance_event_type_with_cnt_reset(unsigned int counter, unsigned int value) { write_p15_performance_event_type(counter, value); p15_reset_performance_counter(counter); return; } static inline void write_p15_performance_count_enable(unsigned int state) { unsigned int mask = !(state & 0x01); unsigned int preserve = read_p15_performance_monitor_control() & (~(mask)); __asm__ __volatile__ ("mcr " PMCR : : "r" (preserve | (state & 0x01))); return; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static inline unsigned int read_p15_cycle_counter(void) { unsigned int value; __asm__ __volatile__ ("mrc " PMCCNTR : "=r" (value)); return value; } static inline unsigned int read_p15_performance_counter(unsigned int counter) { unsigned int value; if(counter & 0x01) __asm__ __volatile__ ("mrc " PMEVCNTR1 : "=r" (value)); else __asm__ __volatile__ ("mrc " PMEVCNTR0 : "=r" (value)); return value; } static inline unsigned int read_p15_performance_counter_with_reset(unsigned int counter) { unsigned int value = read_p15_performance_counter(counter); p15_reset_performance_counter(counter); return value; } static inline unsigned int read_p15_performance_event_type(unsigned int counter) { unsigned int shift = ((1 - (counter & 0x01)) << 3) + 12; return( (read_p15_performance_monitor_control() >> shift) & 0xFF ); } static inline unsigned int read_p15_performance_count_enable(void) { return( read_p15_performance_monitor_control() & 0x01 ); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static inline void write_secure_debug_enable_register(unsigned int suiden, unsigned int suniden) { unsigned int value = (suiden << 0) | (suniden << 1); #if 0 unsigned int wert, i; __asm__ __volatile__ (" MRC p15, 0, %0, c1, c0, 0\n" : "=r" (wert)); for(i = 0 ; i < 13 ; i++) { printk(KERN_ERR "[%s] Coprozessor %d: %s\n", __FUNCTION__, i, ((wert >> (i << 1)) & 0x3) == 0 ? "Access denied" : ((wert >> (i << 1)) & 0x3) == 0 ? "Privileged access only" : ((wert >> (i << 1)) & 0x3) == 0 ? "reserved" : "Privileged and User access "); } #endif __asm__ __volatile__ (" MCR p15, 0, %0, c1, c1, 1\n" : : "r" (value)); __asm__ __volatile__ (" MRC p15, 0, %0, c1, c1, 1\n" : "=r" (value)); if((value & 0x3) != ((suiden << 0) | (suniden << 1))) { printk(KERN_ERR "[%s] write failed 0x%x (written) <> 0x%x (read)\n", __FUNCTION__, (suiden << 0) | (suniden << 1), value); } } #endif /*--- #ifndef _arch_arm_include_asm_performance_h_ ---*/