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>
2013-09-17 10:25:47 +02:00
# include <asm/cpu-type.h>
2005-04-16 15:20:36 -07:00
# 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_loongson2_ops __weak ;
2014-11-04 14:15:07 +08:00
extern struct op_mips_model op_model_loongson3_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 ) ;
2013-01-22 12:59:30 +01:00
/* 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
2013-01-22 12:59:30 +01:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
2013-07-19 15:52:42 +04:00
static int op_mips_create_files ( 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 ) ;
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 02:54:29 +00:00
/* Dummy. */
2013-07-19 16:10:36 +04:00
oprofilefs_create_ulong ( dir , " unit_mask " , & ctr [ i ] . unit_mask ) ;
2005-04-16 15:20:36 -07:00
}
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
2015-12-09 11:15:27 +08:00
switch ( boot_cpu_type ( ) ) {
2005-12-09 12:42:13 +00:00
case CPU_5KC :
2012-07-06 23:56:00 +02:00
case CPU_M14KC :
2012-12-07 03:51:35 +00:00
case CPU_M14KEC :
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 :
2014-01-17 15:03:50 -06:00
case CPU_1074K :
2013-11-27 10:07:53 +00:00
case CPU_INTERAPTIV :
2013-11-14 16:12:27 +00:00
case CPU_PROAPTIV :
2014-01-22 16:19:41 +00:00
case CPU_P5600 :
2015-07-09 10:40:36 +01:00
case CPU_I6400 :
2014-03-04 13:34:43 +00:00
case CPU_M5150 :
2019-11-04 14:11:20 +08:00
case CPU_LOONGSON32 :
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 :
2015-01-21 07:59:45 -05:00
case CPU_R16000 :
2012-10-31 12:01:27 +00:00
case CPU_XLR :
2006-05-23 16:42:38 +09:00
lmodel = & op_model_mipsxx_ops ;
2005-04-16 15:20:36 -07:00
break ;
2019-10-20 22:43:13 +08:00
case CPU_LOONGSON2EF :
2009-07-02 23:25:46 +08:00
lmodel = & op_model_loongson2_ops ;
break ;
2019-10-20 22:43:13 +08:00
case CPU_LOONGSON64 :
2014-11-04 14:15:07 +08:00
lmodel = & op_model_loongson3_ops ;
break ;
2020-04-28 14:32:54 +08:00
}
2005-04-16 15:20:36 -07:00
2014-10-17 18:10:25 +03:00
/*
* Always set the backtrace . This allows unsupported CPU types to still
* use timer - based oprofile .
*/
ops - > backtrace = op_mips_backtrace ;
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 ;
2013-01-22 12:59:30 +01:00
//ops->shutdown = op_mips_shutdown;
2005-02-07 02:54:29 +00:00
ops - > start = op_mips_start ;
ops - > stop = op_mips_stop ;
ops - > cpu_type = lmodel - > cpu_type ;
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
}