2005-04-17 02:20:36 +04: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 05:54:29 +03:00
* Copyright ( C ) 2004 , 2005 Ralf Baechle
* Copyright ( C ) 2005 MIPS Technologies , Inc .
2005-04-17 02:20:36 +04:00
*/
2010-01-26 18:02:34 +03:00
# include <linux/compiler.h>
2005-04-17 02:20:36 +04:00
# include <linux/errno.h>
# include <linux/init.h>
# include <linux/oprofile.h>
# include <linux/smp.h>
# include <asm/cpu-info.h>
2013-09-17 12:25:47 +04:00
# include <asm/cpu-type.h>
2005-04-17 02:20:36 +04:00
# include "op_impl.h"
2010-01-26 18:02:34 +03:00
extern struct op_mips_model op_model_mipsxx_ops __weak ;
extern struct op_mips_model op_model_loongson2_ops __weak ;
2014-11-04 09:15:07 +03:00
extern struct op_mips_model op_model_loongson3_ops __weak ;
2005-04-17 02:20:36 +04: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 ) ;
2013-01-22 15:59:30 +04:00
/* Configure the registers on all cpus. */
2008-05-09 11:39:44 +04:00
on_each_cpu ( model - > cpu_setup , NULL , 1 ) ;
2005-04-17 02:20:36 +04:00
2013-01-22 15:59:30 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2013-07-19 15:52:42 +04:00
static int op_mips_create_files ( struct dentry * root )
2005-04-17 02:20:36 +04:00
{
int i ;
for ( i = 0 ; i < model - > num_counters ; + + i ) {
struct dentry * dir ;
2006-06-26 11:24:34 +04:00
char buf [ 4 ] ;
2005-04-17 02:20:36 +04:00
snprintf ( buf , sizeof buf , " %d " , i ) ;
2013-07-19 15:58:27 +04:00
dir = oprofilefs_mkdir ( root , buf ) ;
2013-07-19 15:52:42 +04:00
2013-07-19 16:10:36 +04:00
oprofilefs_create_ulong ( dir , " enabled " , & ctr [ i ] . enabled ) ;
oprofilefs_create_ulong ( dir , " event " , & ctr [ i ] . event ) ;
oprofilefs_create_ulong ( dir , " count " , & ctr [ i ] . count ) ;
oprofilefs_create_ulong ( dir , " kernel " , & ctr [ i ] . kernel ) ;
oprofilefs_create_ulong ( dir , " user " , & ctr [ i ] . user ) ;
oprofilefs_create_ulong ( dir , " exl " , & ctr [ i ] . exl ) ;
2005-02-07 05:54:29 +03:00
/* Dummy. */
2013-07-19 16:10:36 +04:00
oprofilefs_create_ulong ( dir , " unit_mask " , & ctr [ i ] . unit_mask ) ;
2005-04-17 02:20:36 +04:00
}
return 0 ;
}
static int op_mips_start ( void )
{
2008-05-09 11:39:44 +04:00
on_each_cpu ( model - > cpu_start , NULL , 1 ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
static void op_mips_stop ( void )
{
/* Disable performance monitoring for all counters. */
2008-05-09 11:39:44 +04:00
on_each_cpu ( model - > cpu_stop , NULL , 1 ) ;
2005-04-17 02:20:36 +04:00
}
2005-02-07 05:54:29 +03:00
int __init oprofile_arch_init ( struct oprofile_operations * ops )
2005-04-17 02:20:36 +04:00
{
struct op_mips_model * lmodel = NULL ;
2005-02-07 05:54:29 +03:00
int res ;
2005-04-17 02:20:36 +04:00
2015-12-09 06:15:27 +03:00
switch ( boot_cpu_type ( ) ) {
2005-12-09 15:42:13 +03:00
case CPU_5KC :
2012-07-07 01:56:00 +04:00
case CPU_M14KC :
2012-12-07 07:51:35 +04:00
case CPU_M14KEC :
2005-12-09 15:42:13 +03:00
case CPU_20KC :
2005-04-17 02:20:36 +04:00
case CPU_24K :
2005-12-09 15:42:13 +03:00
case CPU_25KF :
2006-02-01 20:54:30 +03:00
case CPU_34K :
2008-04-28 20:14:26 +04:00
case CPU_1004K :
2006-05-02 17:08:46 +04:00
case CPU_74K :
2014-01-18 01:03:50 +04:00
case CPU_1074K :
2013-11-27 14:07:53 +04:00
case CPU_INTERAPTIV :
2013-11-14 20:12:27 +04:00
case CPU_PROAPTIV :
2014-01-22 20:19:41 +04:00
case CPU_P5600 :
2015-07-09 12:40:36 +03:00
case CPU_I6400 :
2014-03-04 17:34:43 +04:00
case CPU_M5150 :
2012-06-20 23:05:32 +04:00
case CPU_LOONGSON1 :
2006-01-17 23:06:32 +03:00
case CPU_SB1 :
case CPU_SB1A :
2006-10-23 03:44:02 +04:00
case CPU_R10000 :
case CPU_R12000 :
case CPU_R14000 :
2015-01-21 15:59:45 +03:00
case CPU_R16000 :
2012-10-31 16:01:27 +04:00
case CPU_XLR :
2006-05-23 11:42:38 +04:00
lmodel = & op_model_mipsxx_ops ;
2005-04-17 02:20:36 +04:00
break ;
2009-07-02 19:25:46 +04:00
case CPU_LOONGSON2 :
lmodel = & op_model_loongson2_ops ;
break ;
2014-11-04 09:15:07 +03:00
case CPU_LOONGSON3 :
lmodel = & op_model_loongson3_ops ;
break ;
2005-04-17 02:20:36 +04:00
} ;
2014-10-17 19:10:25 +04:00
/*
* Always set the backtrace . This allows unsupported CPU types to still
* use timer - based oprofile .
*/
ops - > backtrace = op_mips_backtrace ;
2005-04-17 02:20:36 +04:00
if ( ! lmodel )
2005-02-07 05:54:29 +03:00
return - ENODEV ;
2005-04-17 02:20:36 +04:00
2005-02-07 05:54:29 +03:00
res = lmodel - > init ( ) ;
if ( res )
return res ;
2005-04-17 02:20:36 +04:00
model = lmodel ;
2005-02-07 05:54:29 +03:00
ops - > create_files = op_mips_create_files ;
ops - > setup = op_mips_setup ;
2013-01-22 15:59:30 +04:00
//ops->shutdown = op_mips_shutdown;
2005-02-07 05:54:29 +03:00
ops - > start = op_mips_start ;
ops - > stop = op_mips_stop ;
ops - > cpu_type = lmodel - > cpu_type ;
2005-04-17 02:20:36 +04:00
printk ( KERN_INFO " oprofile: using %s performance monitoring. \n " ,
lmodel - > cpu_type ) ;
2005-02-07 05:54:29 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
void oprofile_arch_exit ( void )
{
2006-04-24 13:48:54 +04:00
if ( model )
model - > exit ( ) ;
2005-04-17 02:20:36 +04:00
}