2005-04-17 02:20:36 +04:00
/*
* Copyright ( C ) 1995 , 1996 , 2001 Ralf Baechle
2005-05-05 20:45:59 +04:00
* Copyright ( C ) 2001 , 2004 MIPS Technologies , Inc .
2013-01-22 15:59:30 +04:00
* Copyright ( C ) 2004 Maciej W . Rozycki
2005-04-17 02:20:36 +04:00
*/
# include <linux/delay.h>
# include <linux/kernel.h>
# include <linux/sched.h>
# include <linux/seq_file.h>
# include <asm/bootinfo.h>
# include <asm/cpu.h>
# include <asm/cpu-features.h>
2013-05-21 18:59:19 +04:00
# include <asm/idle.h>
2005-04-17 02:20:36 +04:00
# include <asm/mipsregs.h>
# include <asm/processor.h>
2013-04-11 09:34:59 +04:00
# include <asm/prom.h>
2005-04-17 02:20:36 +04:00
unsigned int vced_count , vcei_count ;
2013-10-16 19:10:07 +04:00
/*
* * No lock ; only written during early bootup by CPU 0.
* */
static RAW_NOTIFIER_HEAD ( proc_cpuinfo_chain ) ;
int __ref register_proc_cpuinfo_notifier ( struct notifier_block * nb )
{
return raw_notifier_chain_register ( & proc_cpuinfo_chain , nb ) ;
}
int proc_cpuinfo_notifier_call_chain ( unsigned long val , void * v )
{
return raw_notifier_call_chain ( & proc_cpuinfo_chain , val , v ) ;
}
2005-04-17 02:20:36 +04:00
static int show_cpuinfo ( struct seq_file * m , void * v )
{
2013-10-16 19:10:07 +04:00
struct proc_cpuinfo_notifier_args proc_cpuinfo_notifier_args ;
2005-04-17 02:20:36 +04:00
unsigned long n = ( unsigned long ) v - 1 ;
2006-10-08 03:15:02 +04:00
unsigned int version = cpu_data [ n ] . processor_id ;
unsigned int fp_vers = cpu_data [ n ] . fpu_id ;
2005-04-17 02:20:36 +04:00
char fmt [ 64 ] ;
2008-09-23 11:07:16 +04:00
int i ;
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_SMP
2012-03-29 09:08:30 +04:00
if ( ! cpu_online ( n ) )
2005-04-17 02:20:36 +04:00
return 0 ;
# endif
/*
* For the first processor also print the system type
*/
2010-11-23 18:06:25 +03:00
if ( n = = 0 ) {
2005-04-17 02:20:36 +04:00
seq_printf ( m , " system type \t \t : %s \n " , get_system_type ( ) ) ;
2010-11-23 18:06:25 +03:00
if ( mips_get_machine_name ( ) )
seq_printf ( m , " machine \t \t \t : %s \n " ,
mips_get_machine_name ( ) ) ;
}
2005-04-17 02:20:36 +04:00
seq_printf ( m , " processor \t \t : %ld \n " , n ) ;
sprintf ( fmt , " cpu model \t \t : %%s V%%d.%%d%s \n " ,
2012-05-11 08:21:18 +04:00
cpu_data [ n ] . options & MIPS_CPU_FPU ? " FPU V%d.%d " : " " ) ;
2008-10-13 21:36:21 +04:00
seq_printf ( m , fmt , __cpu_name [ n ] ,
2012-05-11 08:21:18 +04:00
( version > > 4 ) & 0x0f , version & 0x0f ,
( fp_vers > > 4 ) & 0x0f , fp_vers & 0x0f ) ;
2009-02-28 12:44:28 +03:00
seq_printf ( m , " BogoMIPS \t \t : %u.%02u \n " ,
2012-05-11 08:21:18 +04:00
cpu_data [ n ] . udelay_val / ( 500000 / HZ ) ,
( cpu_data [ n ] . udelay_val / ( 5000 / HZ ) ) % 100 ) ;
2005-04-17 02:20:36 +04:00
seq_printf ( m , " wait instruction \t : %s \n " , cpu_wait ? " yes " : " no " ) ;
seq_printf ( m , " microsecond timers \t : %s \n " ,
2012-05-11 08:21:18 +04:00
cpu_has_counter ? " yes " : " no " ) ;
2006-10-08 03:15:02 +04:00
seq_printf ( m , " tlb_entries \t \t : %d \n " , cpu_data [ n ] . tlbsize ) ;
2005-04-17 02:20:36 +04:00
seq_printf ( m , " extra interrupt vector \t : %s \n " ,
2012-05-11 08:21:18 +04:00
cpu_has_divec ? " yes " : " no " ) ;
2008-09-23 11:07:16 +04:00
seq_printf ( m , " hardware watchpoint \t : %s " ,
2012-05-11 08:21:18 +04:00
cpu_has_watch ? " yes, " : " no \n " ) ;
2008-09-23 11:07:16 +04:00
if ( cpu_has_watch ) {
seq_printf ( m , " count: %d, address/irw mask: [ " ,
2012-05-11 08:21:18 +04:00
cpu_data [ n ] . watch_reg_count ) ;
2008-09-23 11:07:16 +04:00
for ( i = 0 ; i < cpu_data [ n ] . watch_reg_count ; i + + )
seq_printf ( m , " %s0x%04x " , i ? " , " : " " ,
2012-05-11 08:21:18 +04:00
cpu_data [ n ] . watch_reg_masks [ i ] ) ;
2008-09-23 11:07:16 +04:00
seq_printf ( m , " ] \n " ) ;
}
2013-12-31 03:26:31 +04:00
seq_printf ( m , " isa \t \t \t : mips1 " ) ;
if ( cpu_has_mips_2 )
seq_printf ( m , " %s " , " mips2 " ) ;
if ( cpu_has_mips_3 )
seq_printf ( m , " %s " , " mips3 " ) ;
if ( cpu_has_mips_4 )
seq_printf ( m , " %s " , " mips4 " ) ;
if ( cpu_has_mips_5 )
seq_printf ( m , " %s " , " mips5 " ) ;
if ( cpu_has_mips32r1 )
seq_printf ( m , " %s " , " mips32r1 " ) ;
if ( cpu_has_mips32r2 )
seq_printf ( m , " %s " , " mips32r2 " ) ;
if ( cpu_has_mips64r1 )
seq_printf ( m , " %s " , " mips64r1 " ) ;
if ( cpu_has_mips64r2 )
seq_printf ( m , " %s " , " mips64r2 " ) ;
seq_printf ( m , " \n " ) ;
2012-08-20 18:39:11 +04:00
seq_printf ( m , " ASEs implemented \t : " ) ;
if ( cpu_has_mips16 ) seq_printf ( m , " %s " , " mips16 " ) ;
if ( cpu_has_mdmx ) seq_printf ( m , " %s " , " mdmx " ) ;
if ( cpu_has_mips3d ) seq_printf ( m , " %s " , " mips3d " ) ;
if ( cpu_has_smartmips ) seq_printf ( m , " %s " , " smartmips " ) ;
if ( cpu_has_dsp ) seq_printf ( m , " %s " , " dsp " ) ;
if ( cpu_has_dsp2 ) seq_printf ( m , " %s " , " dsp2 " ) ;
if ( cpu_has_mipsmt ) seq_printf ( m , " %s " , " mt " ) ;
2012-12-07 07:51:35 +04:00
if ( cpu_has_mmips ) seq_printf ( m , " %s " , " micromips " ) ;
2013-02-17 02:42:43 +04:00
if ( cpu_has_vz ) seq_printf ( m , " %s " , " vz " ) ;
2014-01-27 19:23:10 +04:00
if ( cpu_has_msa ) seq_printf ( m , " %s " , " msa " ) ;
2014-01-27 19:10:40 +04:00
if ( cpu_has_eva ) seq_printf ( m , " %s " , " eva " ) ;
2012-08-20 18:39:11 +04:00
seq_printf ( m , " \n " ) ;
2013-03-25 22:27:11 +04:00
if ( cpu_has_mmips ) {
seq_printf ( m , " micromips kernel \t : %s \n " ,
( read_c0_config3 ( ) & MIPS_CONF3_ISA_OE ) ? " yes " : " no " ) ;
}
2007-11-08 21:02:29 +03:00
seq_printf ( m , " shadow register sets \t : %d \n " ,
2012-05-11 08:21:18 +04:00
cpu_data [ n ] . srsets ) ;
2010-12-22 01:19:09 +03:00
seq_printf ( m , " kscratch registers \t : %d \n " ,
2012-05-11 08:21:18 +04:00
hweight8 ( cpu_data [ n ] . kscratch_mask ) ) ;
2014-06-26 07:41:26 +04:00
seq_printf ( m , " package \t \t \t : %d \n " , cpu_data [ n ] . package ) ;
2007-03-02 23:42:04 +03:00
seq_printf ( m , " core \t \t \t : %d \n " , cpu_data [ n ] . core ) ;
2014-04-03 15:14:05 +04:00
2005-04-17 02:20:36 +04:00
sprintf ( fmt , " VCE%%c exceptions \t \t : %s \n " ,
2012-05-11 08:21:18 +04:00
cpu_has_vce ? " %u " : " not available " ) ;
2005-04-17 02:20:36 +04:00
seq_printf ( m , fmt , ' D ' , vced_count ) ;
seq_printf ( m , fmt , ' I ' , vcei_count ) ;
2013-10-16 19:10:07 +04:00
proc_cpuinfo_notifier_args . m = m ;
proc_cpuinfo_notifier_args . n = n ;
raw_notifier_call_chain ( & proc_cpuinfo_chain , 0 ,
& proc_cpuinfo_notifier_args ) ;
2006-03-20 05:51:20 +03:00
seq_printf ( m , " \n " ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
static void * c_start ( struct seq_file * m , loff_t * pos )
{
unsigned long i = * pos ;
return i < NR_CPUS ? ( void * ) ( i + 1 ) : NULL ;
}
static void * c_next ( struct seq_file * m , void * v , loff_t * pos )
{
+ + * pos ;
return c_start ( m , pos ) ;
}
static void c_stop ( struct seq_file * m , void * v )
{
}
2008-01-22 22:42:33 +03:00
const struct seq_operations cpuinfo_op = {
2005-04-17 02:20:36 +04:00
. start = c_start ,
. next = c_next ,
. stop = c_stop ,
. show = show_cpuinfo ,
} ;