/*------------------------------------------------------------------------------------------*\ * * Copyright (C) 2006 AVM GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \*------------------------------------------------------------------------------------------*/ #ifndef _avm_profile_h_ #define _avm_profile_h_ #define AVM_PROFILING_VERSION 3 #ifndef CONFIG_AVM_PROFILING_TRACE_MODE #define CONFIG_AVM_PROFILING_TRACE_MODE 50 #endif /*--- #ifndef CONFIG_AVM_PROFILING_TRACE_MODE ---*/ #if defined(CONFIG_MIPS) || defined(CONFIG_ARCH_PUMA5) || defined(CONFIG_MACH_PUMA6) #define AVM_PROFILE_ACTIVITY_INCLUDED #endif/*--- #if defined(CONFIG_MIPS) || defined(CONFIG_ARCH_PUMA5) || defined(CONFIG_MACH_PUMA6) ---*/ #define AVM_PROFILE_CURRENT_COMM_INCLUDED 8 /*--- max len of comm ---*/ #define AVM_PROFILE_PAGE_FAULT_ID ((0x1 << 16) -2) #define AVM_PROFILE_IDLE_ID ((0x1 << 16) -1) enum _avm_profile_data_type { avm_profile_data_type_code_address_info = 0, avm_profile_data_type_trace_skb = 1, avm_profile_data_type_hw_irq_begin = 2, avm_profile_data_type_hw_irq_end = 3, avm_profile_data_type_sw_irq_begin = 4, avm_profile_data_type_sw_irq_end = 5, avm_profile_data_type_timer_begin = 6, avm_profile_data_type_timer_end = 7, avm_profile_data_type_tasklet_begin = 8, avm_profile_data_type_tasklet_end = 9, avm_profile_data_type_hi_tasklet_begin = 10, avm_profile_data_type_hi_tasklet_end = 11, avm_profile_data_type_workitem_begin = 12, avm_profile_data_type_workitem_end = 13, avm_profile_data_type_func_begin = 14, avm_profile_data_type_func_end = 15, avm_profile_data_type_trigger_tasklet_begin = 16, avm_profile_data_type_trigger_tasklet_end = 17, avm_profile_data_type_trigger_user_begin = 18, avm_profile_data_type_trigger_user_end = 19, avm_profile_data_type_code_begin = 20, avm_profile_data_type_code_end = 21, avm_profile_data_type_unknown }; struct _avm_profile_data { enum _avm_profile_data_type type : 8; unsigned int core_id : 2; unsigned int tc_id : 3; unsigned int cpu_id : 3; unsigned int id : 16; unsigned int cpu_status; unsigned int addr; unsigned int lr; unsigned int time; #if defined(AVM_PROFILE_ACTIVITY_INCLUDED) unsigned int total_access; unsigned int total_activate; #endif/*--- #if defined(AVM_PROFILE_ACTIVITY_INCLUDED) ---*/ #if defined(AVM_PROFILE_CURRENT_COMM_INCLUDED) char comm[AVM_PROFILE_CURRENT_COMM_INCLUDED]; /*--- short current name ---*/ #endif/*--- #if defined(AVM_PROFILE_CURRENT_COMM_INCLUDED) ---*/ } __attribute__((packed)); #if defined(CONFIG_AVM_SIMPLE_PROFILING) #include #include #define profile_DataSetsPerBlock ((1 << PAGE_SHIFT) / sizeof(struct _avm_profile_data)) extern unsigned int profile_BlockNeeded; #if defined(AVM_PROFILING_VERSION) struct _simple_profiling { void **data; atomic_t pos; unsigned int len; unsigned int enabled; unsigned int mask; unsigned long start_time; unsigned long end_time; unsigned int wraparround; atomic_t busy; spinlock_t lock; }; #endif/*--- #if defined(AVM_PROFILING_VERSION) ---*/ extern struct _simple_profiling simple_profiling; #define avm_simple_profiling_is_enabled() unlikely(simple_profiling.enabled) extern void __avm_simple_profiling_skb(unsigned int addr, unsigned int where, struct sk_buff *skb); /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static inline void avm_simple_profiling_skb(unsigned int addr, unsigned int where, struct sk_buff *skb){ if(avm_simple_profiling_is_enabled()) { __avm_simple_profiling_skb(addr, where, skb); } } extern void __avm_simple_profiling_log(enum _avm_profile_data_type type, unsigned int addr, unsigned int id); /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static inline void avm_simple_profiling_log(enum _avm_profile_data_type type, unsigned int addr, unsigned int id){ if(avm_simple_profiling_is_enabled()) { __avm_simple_profiling_log(type, addr, id); } } extern void __avm_simple_profiling_irqcontext(unsigned int epc); /*--------------------------------------------------------------------------------*\ * switch to irq-context * addr = interrupted epc \*--------------------------------------------------------------------------------*/ static inline void avm_simple_profiling_enter_irqcontext(unsigned int epc){ if(avm_simple_profiling_is_enabled()) { __avm_simple_profiling_irqcontext(epc); } } extern void __avm_simple_profiling_enter_irq(unsigned int irq); /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static inline void avm_simple_profiling_enter_irq(unsigned int irq){ if(avm_simple_profiling_is_enabled()) { __avm_simple_profiling_enter_irq(irq); } } extern void __avm_simple_profiling_leave_irq(unsigned int irq); /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static inline void avm_simple_profiling_leave_irq(unsigned int irq){ if(avm_simple_profiling_is_enabled()) { __avm_simple_profiling_leave_irq(irq); } } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static inline void avm_simple_profiling_schedule_begin(void *task){ if(avm_simple_profiling_is_enabled()) { __avm_simple_profiling_log(avm_profile_data_type_code_begin, (unsigned int)task, 0); } } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static inline void avm_simple_profiling_schedule_end(void *task){ if(avm_simple_profiling_is_enabled()) { __avm_simple_profiling_log(avm_profile_data_type_code_end, (unsigned int)task, 0); } } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static inline void avm_simple_profiling_enter_idle(unsigned int addr){ if(avm_simple_profiling_is_enabled()) { __avm_simple_profiling_log(avm_profile_data_type_code_address_info, addr, AVM_PROFILE_IDLE_ID); } } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ static inline void avm_simple_profiling_unset_busy(void) { atomic_set(&simple_profiling.busy, 0); } enum _simple_profile_enable_mode { sp_enable_off = 0, sp_enable_on = 1, sp_enable_wrap = 2, sp_enable_uart = 3, sp_enable_max = 4, }; /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ int avm_simple_profiling_enable(enum _simple_profile_enable_mode on, unsigned int enable_perfcnt, unsigned int mask, unsigned int *count, unsigned long *timediff, unsigned int set_busy); void avm_simple_profiling_memresize(unsigned int BlockNeeded); struct _avm_profile_data *avm_simple_profiling_by_idx(unsigned int idx); void avm_simple_profiling_restart(void); #else /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ #define avm_simple_profiling_enter_irqcontext(epc) 0 #define avm_simple_profiling_log(addr, id) #define avm_simple_profiling(regs) #define avm_simple_profiling_enable(on, enable_perfcnt, mask, count, timediff, setbusy) #define avm_simple_profiling_is_enabled() 0 #endif /*--- #else ---*/ /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ #endif /*--- #ifndef _avm_profile_h_ ---*/