2006-10-03 13:14:04 +09:00
/*
2006-12-25 10:19:56 +09:00
* arch / sh / kernel / setup . c
2005-04-16 15:20:36 -07:00
*
* This file handles the architecture - dependent parts of initialization
2006-12-25 10:19:56 +09:00
*
* Copyright ( C ) 1999 Niibe Yutaka
2007-03-28 16:38:13 +09:00
* Copyright ( C ) 2002 - 2007 Paul Mundt
2005-04-16 15:20:36 -07:00
*/
2006-07-10 04:44:13 -07:00
# include <linux/screen_info.h>
2005-04-16 15:20:36 -07:00
# include <linux/ioport.h>
# include <linux/init.h>
# include <linux/initrd.h>
# include <linux/bootmem.h>
# include <linux/console.h>
# include <linux/seq_file.h>
# include <linux/root_dev.h>
# include <linux/utsname.h>
2007-03-28 16:38:13 +09:00
# include <linux/nodemask.h>
2005-04-16 15:20:36 -07:00
# include <linux/cpu.h>
2006-03-27 01:16:04 -08:00
# include <linux/pfn.h>
2006-10-03 13:14:04 +09:00
# include <linux/fs.h>
2007-03-28 16:38:13 +09:00
# include <linux/mm.h>
2007-04-27 11:25:57 +09:00
# include <linux/kexec.h>
2007-07-20 16:59:49 +09:00
# include <linux/module.h>
2007-09-21 18:39:49 +09:00
# include <linux/smp.h>
2008-03-07 17:19:58 +09:00
# include <linux/err.h>
# include <linux/debugfs.h>
2008-07-30 10:29:39 +10:00
# include <linux/crash_dump.h>
2008-09-04 18:53:58 +09:00
# include <linux/mmzone.h>
2008-09-08 20:47:42 +09:00
# include <linux/clk.h>
# include <linux/delay.h>
2005-04-16 15:20:36 -07:00
# include <asm/uaccess.h>
# include <asm/io.h>
2007-05-14 12:50:43 +09:00
# include <asm/page.h>
2007-12-10 15:50:28 +09:00
# include <asm/elf.h>
2005-04-16 15:20:36 -07:00
# include <asm/sections.h>
# include <asm/irq.h>
# include <asm/setup.h>
2006-02-01 03:06:02 -08:00
# include <asm/clock.h>
2007-03-28 16:38:13 +09:00
# include <asm/mmu_context.h>
2005-04-16 15:20:36 -07:00
/*
* Initialize loops_per_jiffy as 10000000 ( 1000 MIPS ) .
* This value will be used at the very early stage of serial setup .
* The bigger value means no problem .
*/
2007-09-21 18:01:40 +09:00
struct sh_cpuinfo cpu_data [ NR_CPUS ] __read_mostly = {
[ 0 ] = {
. type = CPU_SH_NONE ,
. loops_per_jiffy = 10000000 ,
} ,
} ;
EXPORT_SYMBOL ( cpu_data ) ;
2007-05-15 15:19:34 +09:00
/*
* The machine vector . First entry in . machvec . init , or clobbered by
* sh_mv = on the command line , prior to . machvec . init teardown .
*/
2007-05-15 15:38:30 +09:00
struct sh_machine_vector sh_mv = { . mv_name = " generic " , } ;
2008-04-25 16:01:38 +09:00
EXPORT_SYMBOL ( sh_mv ) ;
2007-05-15 15:19:34 +09:00
2006-09-27 18:17:31 +09:00
# ifdef CONFIG_VT
2005-04-16 15:20:36 -07:00
struct screen_info screen_info ;
2006-09-27 18:17:31 +09:00
# endif
2005-04-16 15:20:36 -07:00
extern int root_mountflags ;
2005-11-07 00:58:24 -08:00
# define RAMDISK_IMAGE_START_MASK 0x07FF
2005-04-16 15:20:36 -07:00
# define RAMDISK_PROMPT_FLAG 0x8000
2005-11-07 00:58:24 -08:00
# define RAMDISK_LOAD_FLAG 0x4000
2005-04-16 15:20:36 -07:00
2007-02-12 00:54:19 -08:00
static char __initdata command_line [ COMMAND_LINE_SIZE ] = { 0 , } ;
2005-04-16 15:20:36 -07:00
2007-10-30 17:32:08 +09:00
static struct resource code_resource = {
. name = " Kernel code " ,
. flags = IORESOURCE_BUSY | IORESOURCE_MEM ,
} ;
static struct resource data_resource = {
. name = " Kernel data " ,
. flags = IORESOURCE_BUSY | IORESOURCE_MEM ,
} ;
2005-04-16 15:20:36 -07:00
2008-04-23 20:50:27 +09:00
static struct resource bss_resource = {
. name = " Kernel bss " ,
. flags = IORESOURCE_BUSY | IORESOURCE_MEM ,
} ;
2007-07-20 16:59:49 +09:00
unsigned long memory_start ;
EXPORT_SYMBOL ( memory_start ) ;
2007-10-30 17:18:08 +09:00
unsigned long memory_end = 0 ;
2007-07-20 16:59:49 +09:00
EXPORT_SYMBOL ( memory_end ) ;
2005-04-16 15:20:36 -07:00
2008-04-23 20:56:44 +09:00
static struct resource mem_resources [ MAX_NUMNODES ] ;
2007-12-10 15:50:28 +09:00
int l1i_cache_shape , l1d_cache_shape , l2_cache_shape ;
2007-05-14 15:59:09 +09:00
static int __init early_parse_mem ( char * p )
2005-04-16 15:20:36 -07:00
{
2007-05-14 15:59:09 +09:00
unsigned long size ;
2005-04-16 15:20:36 -07:00
2007-11-30 17:52:53 +09:00
memory_start = ( unsigned long ) __va ( __MEMORY_START ) ;
2007-05-14 15:59:09 +09:00
size = memparse ( p , & p ) ;
2007-11-26 21:16:09 +09:00
if ( size > __MEMORY_SIZE ) {
static char msg [ ] __initdata = KERN_ERR
" Using mem= to increase the size of kernel memory "
" is not allowed. \n "
" Recompile the kernel with the correct value for "
" CONFIG_MEMORY_SIZE. \n " ;
printk ( msg ) ;
return 0 ;
}
2007-05-14 15:59:09 +09:00
memory_end = memory_start + size ;
2006-09-27 18:17:31 +09:00
2005-04-16 15:20:36 -07:00
return 0 ;
}
2007-05-14 15:59:09 +09:00
early_param ( " mem " , early_parse_mem ) ;
2005-04-16 15:20:36 -07:00
2007-03-28 16:38:13 +09:00
/*
* Register fully available low RAM pages with the bootmem allocator .
*/
static void __init register_bootmem_low_pages ( void )
2005-04-16 15:20:36 -07:00
{
2007-03-28 16:38:13 +09:00
unsigned long curr_pfn , last_pfn , pages ;
2006-12-12 09:00:47 +09:00
2005-04-16 15:20:36 -07:00
/*
2007-03-28 16:38:13 +09:00
* We are rounding up the start address of usable memory :
2005-04-16 15:20:36 -07:00
*/
2007-03-28 16:38:13 +09:00
curr_pfn = PFN_UP ( __MEMORY_START ) ;
2005-04-16 15:20:36 -07:00
/*
2007-03-28 16:38:13 +09:00
* . . . and at the end of the usable range downwards :
2005-04-16 15:20:36 -07:00
*/
2007-03-28 16:38:13 +09:00
last_pfn = PFN_DOWN ( __pa ( memory_end ) ) ;
2005-04-16 15:20:36 -07:00
2007-03-28 16:38:13 +09:00
if ( last_pfn > max_low_pfn )
last_pfn = max_low_pfn ;
pages = last_pfn - curr_pfn ;
free_bootmem ( PFN_PHYS ( curr_pfn ) , PFN_PHYS ( pages ) ) ;
}
2007-10-18 23:41:02 -07:00
# ifdef CONFIG_KEXEC
static void __init reserve_crashkernel ( void )
{
unsigned long long free_mem ;
unsigned long long crash_size , crash_base ;
2008-10-09 18:42:55 +09:00
void * vp ;
2007-10-18 23:41:02 -07:00
int ret ;
free_mem = ( ( unsigned long long ) max_low_pfn - min_low_pfn ) < < PAGE_SHIFT ;
ret = parse_crashkernel ( boot_command_line , free_mem ,
& crash_size , & crash_base ) ;
if ( ret = = 0 & & crash_size ) {
2008-02-07 00:15:19 -08:00
if ( crash_base < = 0 ) {
2008-10-09 18:42:55 +09:00
vp = alloc_bootmem_nopanic ( crash_size ) ;
if ( ! vp ) {
printk ( KERN_INFO " crashkernel allocation "
" failed \n " ) ;
return ;
}
crash_base = __pa ( vp ) ;
} else if ( reserve_bootmem ( crash_base , crash_size ,
2008-02-07 00:15:19 -08:00
BOOTMEM_EXCLUSIVE ) < 0 ) {
printk ( KERN_INFO " crashkernel reservation failed - "
" memory is in use \n " ) ;
return ;
}
printk ( KERN_INFO " Reserving %ldMB of memory at %ldMB "
" for crashkernel (System RAM: %ldMB) \n " ,
( unsigned long ) ( crash_size > > 20 ) ,
( unsigned long ) ( crash_base > > 20 ) ,
( unsigned long ) ( free_mem > > 20 ) ) ;
crashk_res . start = crash_base ;
crashk_res . end = crash_base + crash_size - 1 ;
2008-08-27 18:15:43 +09:00
insert_resource ( & iomem_resource , & crashk_res ) ;
2007-10-18 23:41:02 -07:00
}
}
# else
static inline void __init reserve_crashkernel ( void )
{ }
# endif
2008-09-08 20:47:42 +09:00
# ifndef CONFIG_GENERIC_CALIBRATE_DELAY
void __cpuinit calibrate_delay ( void )
{
struct clk * clk = clk_get ( NULL , " cpu_clk " ) ;
if ( IS_ERR ( clk ) )
panic ( " Need a sane CPU clock definition! " ) ;
loops_per_jiffy = ( clk_get_rate ( clk ) > > 1 ) / HZ ;
printk ( KERN_INFO " Calibrating delay loop (skipped)... "
" %lu.%02lu BogoMIPS PRESET (lpj=%lu) \n " ,
loops_per_jiffy / ( 500000 / HZ ) ,
( loops_per_jiffy / ( 5000 / HZ ) ) % 100 ,
loops_per_jiffy ) ;
}
# endif
2008-04-23 20:56:44 +09:00
void __init __add_active_range ( unsigned int nid , unsigned long start_pfn ,
unsigned long end_pfn )
{
struct resource * res = & mem_resources [ nid ] ;
WARN_ON ( res - > name ) ; /* max one active range per node for now */
res - > name = " System RAM " ;
res - > start = start_pfn < < PAGE_SHIFT ;
res - > end = ( end_pfn < < PAGE_SHIFT ) - 1 ;
res - > flags = IORESOURCE_MEM | IORESOURCE_BUSY ;
if ( request_resource ( & iomem_resource , res ) ) {
pr_err ( " unable to request memory_resource 0x%lx 0x%lx \n " ,
start_pfn , end_pfn ) ;
return ;
}
/*
* We don ' t know which RAM region contains kernel data ,
* so we try it repeatedly and let the resource manager
* test it .
*/
request_resource ( res , & code_resource ) ;
request_resource ( res , & data_resource ) ;
request_resource ( res , & bss_resource ) ;
add_active_range ( nid , start_pfn , end_pfn ) ;
}
2007-06-01 17:04:36 +09:00
void __init setup_bootmem_allocator ( unsigned long free_pfn )
2007-03-28 16:38:13 +09:00
{
unsigned long bootmap_size ;
2005-04-16 15:20:36 -07:00
/*
* Find a proper area for the bootmem bitmap . After this
* bootstrap step all allocations ( until the page allocator
* is intact ) must be done via bootmem_alloc ( ) .
*/
2007-06-01 17:04:36 +09:00
bootmap_size = init_bootmem_node ( NODE_DATA ( 0 ) , free_pfn ,
2007-03-28 16:38:13 +09:00
min_low_pfn , max_low_pfn ) ;
2005-04-16 15:20:36 -07:00
2008-04-23 20:56:44 +09:00
__add_active_range ( 0 , min_low_pfn , max_low_pfn ) ;
2007-03-28 16:38:13 +09:00
register_bootmem_low_pages ( ) ;
2005-04-16 15:20:36 -07:00
2007-03-28 16:38:13 +09:00
node_set_online ( 0 ) ;
2006-12-12 09:00:47 +09:00
2005-04-16 15:20:36 -07:00
/*
* Reserve the kernel text and
* Reserve the bootmem bitmap . We do this in two steps ( first step
* was init_bootmem ( ) ) , because this catches the ( definitely buggy )
* case of us accidentally initializing the bootmem allocator with
* an invalid RAM area .
*/
2008-09-05 16:29:40 +09:00
reserve_bootmem ( __MEMORY_START + CONFIG_ZERO_PAGE_OFFSET ,
( PFN_PHYS ( free_pfn ) + bootmap_size + PAGE_SIZE - 1 ) -
( __MEMORY_START + CONFIG_ZERO_PAGE_OFFSET ) ,
BOOTMEM_DEFAULT ) ;
2005-04-16 15:20:36 -07:00
/*
* reserve physical page 0 - it ' s a special BIOS page on many boxes ,
* enabling clean reboots , SMP operation , laptop functions .
*/
2008-09-05 16:29:40 +09:00
reserve_bootmem ( __MEMORY_START , CONFIG_ZERO_PAGE_OFFSET ,
BOOTMEM_DEFAULT ) ;
2005-04-16 15:20:36 -07:00
2007-06-01 17:04:36 +09:00
sparse_memory_present_with_active_regions ( 0 ) ;
2005-04-16 15:20:36 -07:00
# ifdef CONFIG_BLK_DEV_INITRD
2007-10-30 17:25:29 +09:00
ROOT_DEV = Root_RAM0 ;
2005-04-16 15:20:36 -07:00
if ( LOADER_TYPE & & INITRD_START ) {
2008-09-05 16:14:17 +09:00
unsigned long initrd_start_phys = INITRD_START + __MEMORY_START ;
if ( initrd_start_phys + INITRD_SIZE < = PFN_PHYS ( max_low_pfn ) ) {
reserve_bootmem ( initrd_start_phys , INITRD_SIZE ,
BOOTMEM_DEFAULT ) ;
initrd_start = ( unsigned long ) __va ( initrd_start_phys ) ;
2005-04-16 15:20:36 -07:00
initrd_end = initrd_start + INITRD_SIZE ;
} else {
printk ( " initrd extends beyond end of memory "
2008-09-05 16:14:17 +09:00
" (0x%08lx > 0x%08lx) \n disabling initrd \n " ,
initrd_start_phys + INITRD_SIZE ,
2008-10-20 11:37:58 +09:00
( unsigned long ) PFN_PHYS ( max_low_pfn ) ) ;
2005-04-16 15:20:36 -07:00
initrd_start = 0 ;
}
}
# endif
2007-10-18 23:41:02 -07:00
reserve_crashkernel ( ) ;
2007-03-28 16:38:13 +09:00
}
# ifndef CONFIG_NEED_MULTIPLE_NODES
static void __init setup_memory ( void )
{
unsigned long start_pfn ;
/*
* Partially used pages are not usable - thus
* we are rounding upwards :
*/
start_pfn = PFN_UP ( __pa ( _end ) ) ;
setup_bootmem_allocator ( start_pfn ) ;
}
# else
extern void __init setup_memory ( void ) ;
# endif
2008-07-30 10:29:39 +10:00
/*
* Note : elfcorehdr_addr is not just limited to vmcore . It is also used by
* is_kdump_kernel ( ) to determine if we are booting after a panic . Hence
* ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE .
*/
# ifdef CONFIG_CRASH_DUMP
/* elfcorehdr= specifies the location of elf core header
* stored by the crashed kernel .
*/
static int __init parse_elfcorehdr ( char * arg )
{
if ( ! arg )
return - EINVAL ;
elfcorehdr_addr = memparse ( arg , & arg ) ;
return 0 ;
}
early_param ( " elfcorehdr " , parse_elfcorehdr ) ;
# endif
2007-03-28 16:38:13 +09:00
void __init setup_arch ( char * * cmdline_p )
{
enable_mmu ( ) ;
ROOT_DEV = old_decode_dev ( ORIG_ROOT_DEV ) ;
2008-05-13 17:40:17 +09:00
printk ( KERN_NOTICE " Boot params: \n "
" ... MOUNT_ROOT_RDONLY - %08lx \n "
" ... RAMDISK_FLAGS - %08lx \n "
" ... ORIG_ROOT_DEV - %08lx \n "
" ... LOADER_TYPE - %08lx \n "
" ... INITRD_START - %08lx \n "
" ... INITRD_SIZE - %08lx \n " ,
MOUNT_ROOT_RDONLY , RAMDISK_FLAGS ,
ORIG_ROOT_DEV , LOADER_TYPE ,
INITRD_START , INITRD_SIZE ) ;
2007-03-28 16:38:13 +09:00
# ifdef CONFIG_BLK_DEV_RAM
rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK ;
rd_prompt = ( ( RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG ) ! = 0 ) ;
rd_doload = ( ( RAMDISK_FLAGS & RAMDISK_LOAD_FLAG ) ! = 0 ) ;
# endif
if ( ! MOUNT_ROOT_RDONLY )
root_mountflags & = ~ MS_RDONLY ;
init_mm . start_code = ( unsigned long ) _text ;
init_mm . end_code = ( unsigned long ) _etext ;
init_mm . end_data = ( unsigned long ) _edata ;
init_mm . brk = ( unsigned long ) _end ;
code_resource . start = virt_to_phys ( _text ) ;
code_resource . end = virt_to_phys ( _etext ) - 1 ;
data_resource . start = virt_to_phys ( _etext ) ;
data_resource . end = virt_to_phys ( _edata ) - 1 ;
2008-04-23 20:50:27 +09:00
bss_resource . start = virt_to_phys ( __bss_start ) ;
bss_resource . end = virt_to_phys ( _ebss ) - 1 ;
2007-03-28 16:38:13 +09:00
2007-11-30 17:52:53 +09:00
memory_start = ( unsigned long ) __va ( __MEMORY_START ) ;
2007-10-30 17:18:08 +09:00
if ( ! memory_end )
memory_end = memory_start + __MEMORY_SIZE ;
2007-05-14 15:59:09 +09:00
2007-05-14 17:48:00 +09:00
# ifdef CONFIG_CMDLINE_BOOL
strlcpy ( command_line , CONFIG_CMDLINE , sizeof ( command_line ) ) ;
# else
strlcpy ( command_line , COMMAND_LINE , sizeof ( command_line ) ) ;
# endif
2007-05-14 15:59:09 +09:00
2007-05-14 17:48:00 +09:00
/* Save unparsed command line copy for /proc/cmdline */
memcpy ( boot_command_line , command_line , COMMAND_LINE_SIZE ) ;
2007-05-14 15:59:09 +09:00
* cmdline_p = command_line ;
2007-03-28 16:38:13 +09:00
parse_early_param ( ) ;
2007-05-14 15:59:09 +09:00
sh_mv_setup ( ) ;
2007-03-28 16:38:13 +09:00
/*
* Find the highest page frame number we have available
*/
max_pfn = PFN_DOWN ( __pa ( memory_end ) ) ;
/*
* Determine low and high memory ranges :
*/
max_low_pfn = max_pfn ;
min_low_pfn = __MEMORY_START > > PAGE_SHIFT ;
nodes_clear ( node_online_map ) ;
2007-05-23 17:48:36 +09:00
/* Setup bootmem with available RAM */
2007-03-28 16:38:13 +09:00
setup_memory ( ) ;
sparse_init ( ) ;
2005-04-16 15:20:36 -07:00
# ifdef CONFIG_DUMMY_CONSOLE
conswitchp = & dummy_con ;
# endif
/* Perform the machine specific initialisation */
2006-09-27 18:17:31 +09:00
if ( likely ( sh_mv . mv_setup ) )
sh_mv . mv_setup ( cmdline_p ) ;
2005-04-16 15:20:36 -07:00
2007-05-23 17:48:36 +09:00
paging_init ( ) ;
2007-09-21 18:39:49 +09:00
# ifdef CONFIG_SMP
plat_smp_setup ( ) ;
# endif
2007-05-23 17:48:36 +09:00
}
2005-04-16 15:20:36 -07:00
static const char * cpu_name [ ] = {
2007-11-26 19:54:02 +09:00
[ CPU_SH7203 ] = " SH7203 " , [ CPU_SH7263 ] = " SH7263 " ,
2006-11-20 14:14:29 +09:00
[ CPU_SH7206 ] = " SH7206 " , [ CPU_SH7619 ] = " SH7619 " ,
2006-09-27 17:38:11 +09:00
[ CPU_SH7705 ] = " SH7705 " , [ CPU_SH7706 ] = " SH7706 " ,
[ CPU_SH7707 ] = " SH7707 " , [ CPU_SH7708 ] = " SH7708 " ,
[ CPU_SH7709 ] = " SH7709 " , [ CPU_SH7710 ] = " SH7710 " ,
2007-08-20 08:59:33 +09:00
[ CPU_SH7712 ] = " SH7712 " , [ CPU_SH7720 ] = " SH7720 " ,
2007-12-26 11:45:06 +09:00
[ CPU_SH7721 ] = " SH7721 " , [ CPU_SH7729 ] = " SH7729 " ,
[ CPU_SH7750 ] = " SH7750 " , [ CPU_SH7750S ] = " SH7750S " ,
[ CPU_SH7750R ] = " SH7750R " , [ CPU_SH7751 ] = " SH7751 " ,
[ CPU_SH7751R ] = " SH7751R " , [ CPU_SH7760 ] = " SH7760 " ,
2006-09-27 17:38:11 +09:00
[ CPU_SH4_202 ] = " SH4-202 " , [ CPU_SH4_501 ] = " SH4-501 " ,
2008-01-07 14:40:07 +09:00
[ CPU_SH7763 ] = " SH7763 " , [ CPU_SH7770 ] = " SH7770 " ,
[ CPU_SH7780 ] = " SH7780 " , [ CPU_SH7781 ] = " SH7781 " ,
[ CPU_SH7343 ] = " SH7343 " , [ CPU_SH7785 ] = " SH7785 " ,
[ CPU_SH7722 ] = " SH7722 " , [ CPU_SHX3 ] = " SH-X3 " ,
2007-11-20 18:29:00 +09:00
[ CPU_SH5_101 ] = " SH5-101 " , [ CPU_SH5_103 ] = " SH5-103 " ,
2008-04-09 17:56:18 +09:00
[ CPU_MXG ] = " MX-G " , [ CPU_SH7723 ] = " SH7723 " ,
2008-02-08 17:31:24 +09:00
[ CPU_SH7366 ] = " SH7366 " , [ CPU_SH_NONE ] = " Unknown "
2005-04-16 15:20:36 -07:00
} ;
2006-12-25 10:19:56 +09:00
const char * get_cpu_subtype ( struct sh_cpuinfo * c )
2005-04-16 15:20:36 -07:00
{
2006-12-25 10:19:56 +09:00
return cpu_name [ c - > type ] ;
2005-04-16 15:20:36 -07:00
}
2008-06-18 01:30:24 +03:00
EXPORT_SYMBOL ( get_cpu_subtype ) ;
2005-04-16 15:20:36 -07:00
# ifdef CONFIG_PROC_FS
2006-09-27 18:24:28 +09:00
/* Symbolic CPU flags, keep in sync with asm/cpu-features.h */
2005-04-16 15:20:36 -07:00
static const char * cpu_flags [ ] = {
2006-09-27 18:24:28 +09:00
" none " , " fpu " , " p2flush " , " mmuassoc " , " dsp " , " perfctr " ,
2007-05-08 15:45:33 +09:00
" ptea " , " llsc " , " l2 " , " op32 " , NULL
2005-04-16 15:20:36 -07:00
} ;
2006-12-25 10:19:56 +09:00
static void show_cpuflags ( struct seq_file * m , struct sh_cpuinfo * c )
2005-04-16 15:20:36 -07:00
{
unsigned long i ;
seq_printf ( m , " cpu flags \t : " ) ;
2006-12-25 10:19:56 +09:00
if ( ! c - > flags ) {
2005-04-16 15:20:36 -07:00
seq_printf ( m , " %s \n " , cpu_flags [ 0 ] ) ;
return ;
}
2006-02-01 03:06:02 -08:00
for ( i = 0 ; cpu_flags [ i ] ; i + + )
2006-12-25 10:19:56 +09:00
if ( ( c - > flags & ( 1 < < i ) ) )
2005-04-16 15:20:36 -07:00
seq_printf ( m , " %s " , cpu_flags [ i + 1 ] ) ;
seq_printf ( m , " \n " ) ;
}
2006-09-27 18:17:31 +09:00
static void show_cacheinfo ( struct seq_file * m , const char * type ,
struct cache_info info )
2005-04-16 15:20:36 -07:00
{
unsigned int cache_size ;
cache_size = info . ways * info . sets * info . linesz ;
2006-02-01 03:06:02 -08:00
seq_printf ( m , " %s size \t : %2dKiB (%d-way) \n " ,
type , cache_size > > 10 , info . ways ) ;
2005-04-16 15:20:36 -07:00
}
/*
* Get CPU information for use by the procfs .
*/
static int show_cpuinfo ( struct seq_file * m , void * v )
{
2006-12-25 10:19:56 +09:00
struct sh_cpuinfo * c = v ;
unsigned int cpu = c - cpu_data ;
if ( ! cpu_online ( cpu ) )
return 0 ;
2005-04-16 15:20:36 -07:00
2006-12-25 10:19:56 +09:00
if ( cpu = = 0 )
2005-04-16 15:20:36 -07:00
seq_printf ( m , " machine \t \t : %s \n " , get_system_type ( ) ) ;
seq_printf ( m , " processor \t : %d \n " , cpu ) ;
2006-10-02 02:18:13 -07:00
seq_printf ( m , " cpu family \t : %s \n " , init_utsname ( ) - > machine ) ;
2006-12-25 10:19:56 +09:00
seq_printf ( m , " cpu type \t : %s \n " , get_cpu_subtype ( c ) ) ;
2008-07-02 15:15:09 +09:00
if ( c - > cut_major = = - 1 )
seq_printf ( m , " cut \t \t : unknown \n " ) ;
else if ( c - > cut_minor = = - 1 )
seq_printf ( m , " cut \t \t : %d.x \n " , c - > cut_major ) ;
else
seq_printf ( m , " cut \t \t : %d.%d \n " , c - > cut_major , c - > cut_minor ) ;
2005-04-16 15:20:36 -07:00
2006-12-25 10:19:56 +09:00
show_cpuflags ( m , c ) ;
2005-04-16 15:20:36 -07:00
seq_printf ( m , " cache type \t : " ) ;
/*
* Check for what type of cache we have , we support both the
* unified cache on the SH - 2 and SH - 3 , as well as the harvard
* style cache on the SH - 4.
*/
2006-12-25 10:19:56 +09:00
if ( c - > icache . flags & SH_CACHE_COMBINED ) {
2005-04-16 15:20:36 -07:00
seq_printf ( m , " unified \n " ) ;
2006-12-25 10:19:56 +09:00
show_cacheinfo ( m , " cache " , c - > icache ) ;
2005-04-16 15:20:36 -07:00
} else {
seq_printf ( m , " split (harvard) \n " ) ;
2006-12-25 10:19:56 +09:00
show_cacheinfo ( m , " icache " , c - > icache ) ;
show_cacheinfo ( m , " dcache " , c - > dcache ) ;
2005-04-16 15:20:36 -07:00
}
2006-09-27 18:27:43 +09:00
/* Optional secondary cache */
2006-12-25 10:19:56 +09:00
if ( c - > flags & CPU_HAS_L2_CACHE )
show_cacheinfo ( m , " scache " , c - > scache ) ;
2006-09-27 18:27:43 +09:00
2005-04-16 15:20:36 -07:00
seq_printf ( m , " bogomips \t : %lu.%02lu \n " ,
2006-12-25 10:19:56 +09:00
c - > loops_per_jiffy / ( 500000 / HZ ) ,
( c - > loops_per_jiffy / ( 5000 / HZ ) ) % 100 ) ;
2005-04-16 15:20:36 -07:00
2007-04-26 12:17:20 +09:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
static void * c_start ( struct seq_file * m , loff_t * pos )
{
return * pos < NR_CPUS ? cpu_data + * pos : 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-23 12:47:48 +09:00
const struct seq_operations cpuinfo_op = {
2005-04-16 15:20:36 -07:00
. start = c_start ,
. next = c_next ,
. stop = c_stop ,
. show = show_cpuinfo ,
} ;
# endif /* CONFIG_PROC_FS */
2008-03-07 17:19:58 +09:00
struct dentry * sh_debugfs_root ;
static int __init sh_debugfs_init ( void )
{
sh_debugfs_root = debugfs_create_dir ( " sh " , NULL ) ;
2008-10-17 19:25:03 +08:00
if ( ! sh_debugfs_root )
return - ENOMEM ;
2008-03-07 17:19:58 +09:00
if ( IS_ERR ( sh_debugfs_root ) )
return PTR_ERR ( sh_debugfs_root ) ;
return 0 ;
}
arch_initcall ( sh_debugfs_init ) ;