2005-07-27 11:44:40 -07:00
# include <linux/init.h>
# include <linux/errno.h>
# include <linux/kernel.h>
# include <linux/proc_fs.h>
# include <linux/types.h>
# include <asm/ptrace.h>
# include <asm/uaccess.h>
# define SAMPLE_BUFFER_SIZE 8192
static char * sample_buffer ;
static char * sample_buffer_pos ;
static int prof_running = 0 ;
void
cris_profile_sample ( struct pt_regs * regs )
{
2007-05-06 14:50:56 -07:00
if ( ! prof_running )
return ;
if ( user_mode ( regs ) )
* ( unsigned int * ) sample_buffer_pos = current - > pid ;
else
* ( unsigned int * ) sample_buffer_pos = 0 ;
* ( unsigned int * ) ( sample_buffer_pos + 4 ) = instruction_pointer ( regs ) ;
sample_buffer_pos + = 8 ;
if ( sample_buffer_pos = = sample_buffer + SAMPLE_BUFFER_SIZE )
sample_buffer_pos = sample_buffer ;
2005-07-27 11:44:40 -07:00
}
static ssize_t
2007-05-06 14:50:56 -07:00
read_cris_profile ( struct file * file , char __user * buf ,
size_t count , loff_t * ppos )
2005-07-27 11:44:40 -07:00
{
2007-05-06 14:50:56 -07:00
unsigned long p = * ppos ;
2008-07-23 21:28:46 -07:00
ssize_t ret ;
2007-05-06 14:50:56 -07:00
2008-07-23 21:28:46 -07:00
ret = simple_read_from_buffer ( buf , count , ppos , sample_buffer ,
SAMPLE_BUFFER_SIZE ) ;
if ( ret < 0 )
return ret ;
2007-05-06 14:50:56 -07:00
2008-07-23 21:28:46 -07:00
memset ( sample_buffer + p , 0 , ret ) ;
2007-05-06 14:50:56 -07:00
2008-07-23 21:28:46 -07:00
return ret ;
2005-07-27 11:44:40 -07:00
}
static ssize_t
write_cris_profile ( struct file * file , const char __user * buf ,
2007-05-06 14:50:56 -07:00
size_t count , loff_t * ppos )
2005-07-27 11:44:40 -07:00
{
2007-05-06 14:50:56 -07:00
sample_buffer_pos = sample_buffer ;
memset ( sample_buffer , 0 , SAMPLE_BUFFER_SIZE ) ;
2005-07-27 11:44:40 -07:00
}
2007-02-12 00:55:31 -08:00
static const struct file_operations cris_proc_profile_operations = {
2005-07-27 11:44:40 -07:00
. read = read_cris_profile ,
. write = write_cris_profile ,
} ;
static int
__init init_cris_profile ( void )
{
2007-05-06 14:50:56 -07:00
struct proc_dir_entry * entry ;
sample_buffer = kmalloc ( SAMPLE_BUFFER_SIZE , GFP_KERNEL ) ;
if ( ! sample_buffer ) {
return - ENOMEM ;
}
sample_buffer_pos = sample_buffer ;
2008-04-29 01:02:23 -07:00
entry = proc_create ( " system_profile " , S_IWUSR | S_IRUGO , NULL ,
& cris_proc_profile_operations ) ;
2007-05-06 14:50:56 -07:00
if ( entry ) {
entry - > size = SAMPLE_BUFFER_SIZE ;
}
prof_running = 1 ;
return 0 ;
2005-07-27 11:44:40 -07:00
}
__initcall ( init_cris_profile ) ;