2005-04-16 15:20:36 -07:00
/*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*
2005-02-07 02:54:29 +00:00
* Copyright ( C ) 2004 , 2005 Ralf Baechle
* Copyright ( C ) 2005 MIPS Technologies , Inc .
2005-04-16 15:20:36 -07:00
*/
2010-01-26 23:02:34 +08:00
# include <linux/compiler.h>
2005-04-16 15:20:36 -07:00
# include <linux/errno.h>
# include <linux/init.h>
# include <linux/oprofile.h>
# include <linux/smp.h>
# include <asm/cpu-info.h>
# include "op_impl.h"
2010-01-26 23:02:34 +08:00
extern struct op_mips_model op_model_mipsxx_ops __weak ;
extern struct op_mips_model op_model_rm9000_ops __weak ;
extern struct op_mips_model op_model_loongson2_ops __weak ;
2005-04-16 15:20:36 -07:00
static struct op_mips_model * model ;
static struct op_counter_config ctr [ 20 ] ;
static int op_mips_setup ( void )
{
/* Pre-compute the values to stuff in the hardware registers. */
model - > reg_setup ( ctr ) ;
/* Configure the registers on all cpus. */
2008-05-09 09:39:44 +02:00
on_each_cpu ( model - > cpu_setup , NULL , 1 ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
2008-09-05 17:12:36 +02:00
static int op_mips_create_files ( struct super_block * sb , struct dentry * root )
2005-04-16 15:20:36 -07:00
{
int i ;
for ( i = 0 ; i < model - > num_counters ; + + i ) {
struct dentry * dir ;
2006-06-26 00:24:34 -07:00
char buf [ 4 ] ;
2005-04-16 15:20:36 -07:00
snprintf ( buf , sizeof buf , " %d " , i ) ;
dir = oprofilefs_mkdir ( sb , root , buf ) ;
oprofilefs_create_ulong ( sb , dir , " enabled " , & ctr [ i ] . enabled ) ;
oprofilefs_create_ulong ( sb , dir , " event " , & ctr [ i ] . event ) ;
oprofilefs_create_ulong ( sb , dir , " count " , & ctr [ i ] . count ) ;
oprofilefs_create_ulong ( sb , dir , " kernel " , & ctr [ i ] . kernel ) ;
oprofilefs_create_ulong ( sb , dir , " user " , & ctr [ i ] . user ) ;
oprofilefs_create_ulong ( sb , dir , " exl " , & ctr [ i ] . exl ) ;
2005-02-07 02:54:29 +00:00
/* Dummy. */
2005-04-16 15:20:36 -07:00
oprofilefs_create_ulong ( sb , dir , " unit_mask " , & ctr [ i ] . unit_mask ) ;
}
return 0 ;
}
static int op_mips_start ( void )
{
2008-05-09 09:39:44 +02:00
on_each_cpu ( model - > cpu_start , NULL , 1 ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
static void op_mips_stop ( void )
{
/* Disable performance monitoring for all counters. */
2008-05-09 09:39:44 +02:00
on_each_cpu ( model - > cpu_stop , NULL , 1 ) ;
2005-04-16 15:20:36 -07:00
}
2005-02-07 02:54:29 +00:00
int __init oprofile_arch_init ( struct oprofile_operations * ops )
2005-04-16 15:20:36 -07:00
{
struct op_mips_model * lmodel = NULL ;
2005-02-07 02:54:29 +00:00
int res ;
2005-04-16 15:20:36 -07:00
2007-10-11 23:46:15 +01:00
switch ( current_cpu_type ( ) ) {
2005-12-09 12:42:13 +00:00
case CPU_5KC :
2012-07-06 23:56:00 +02:00
case CPU_M14KC :
2005-12-09 12:42:13 +00:00
case CPU_20KC :
2005-04-16 15:20:36 -07:00
case CPU_24K :
2005-12-09 12:42:13 +00:00
case CPU_25KF :
2006-02-01 17:54:30 +00:00
case CPU_34K :
2008-04-28 17:14:26 +01:00
case CPU_1004K :
2006-05-02 14:08:46 +01:00
case CPU_74K :
2006-01-17 12:06:32 -08:00
case CPU_SB1 :
case CPU_SB1A :
2006-10-23 00:44:02 +01:00
case CPU_R10000 :
case CPU_R12000 :
case CPU_R14000 :
2006-05-23 16:42:38 +09:00
lmodel = & op_model_mipsxx_ops ;
2005-04-16 15:20:36 -07:00
break ;
case CPU_RM9000 :
2006-05-23 16:42:38 +09:00
lmodel = & op_model_rm9000_ops ;
2005-04-16 15:20:36 -07:00
break ;
2009-07-02 23:25:46 +08:00
case CPU_LOONGSON2 :
lmodel = & op_model_loongson2_ops ;
break ;
2005-04-16 15:20:36 -07:00
} ;
if ( ! lmodel )
2005-02-07 02:54:29 +00:00
return - ENODEV ;
2005-04-16 15:20:36 -07:00
2005-02-07 02:54:29 +00:00
res = lmodel - > init ( ) ;
if ( res )
return res ;
2005-04-16 15:20:36 -07:00
model = lmodel ;
2005-02-07 02:54:29 +00:00
ops - > create_files = op_mips_create_files ;
ops - > setup = op_mips_setup ;
//ops->shutdown = op_mips_shutdown;
ops - > start = op_mips_start ;
ops - > stop = op_mips_stop ;
ops - > cpu_type = lmodel - > cpu_type ;
2011-05-13 08:38:05 -04:00
ops - > backtrace = op_mips_backtrace ;
2005-04-16 15:20:36 -07:00
printk ( KERN_INFO " oprofile: using %s performance monitoring. \n " ,
lmodel - > cpu_type ) ;
2005-02-07 02:54:29 +00:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
void oprofile_arch_exit ( void )
{
2006-04-24 10:48:54 +01:00
if ( model )
model - > exit ( ) ;
2005-04-16 15:20:36 -07:00
}