2005-04-16 15:20:36 -07:00
# include <linux/kernel.h>
2006-02-16 23:41:58 +01:00
# include <linux/mm.h>
2005-04-16 15:20:36 -07:00
# include <linux/init.h>
# include <asm/processor.h>
# include <asm/msr.h>
# include "cpu.h"
2008-09-14 02:33:16 -07:00
static void __cpuinit early_init_transmeta ( struct cpuinfo_x86 * c )
{
u32 xlvl ;
/* Transmeta-defined flags: level 0x80860001 */
xlvl = cpuid_eax ( 0x80860000 ) ;
if ( ( xlvl & 0xffff0000 ) = = 0x80860000 ) {
if ( xlvl > = 0x80860001 )
c - > x86_capability [ 2 ] = cpuid_edx ( 0x80860001 ) ;
}
}
2006-09-26 10:52:36 +02:00
static void __cpuinit init_transmeta ( struct cpuinfo_x86 * c )
2005-04-16 15:20:36 -07:00
{
unsigned int cap_mask , uk , max , dummy ;
unsigned int cms_rev1 , cms_rev2 ;
2007-02-13 13:26:25 +01:00
unsigned int cpu_rev , cpu_freq = 0 , cpu_flags , new_cpu_rev ;
2005-04-16 15:20:36 -07:00
char cpu_info [ 65 ] ;
2008-09-14 02:33:16 -07:00
early_init_transmeta ( c ) ;
2005-04-16 15:20:36 -07:00
display_cacheinfo ( c ) ;
/* Print CMS and CPU revision */
max = cpuid_eax ( 0x80860000 ) ;
cpu_rev = 0 ;
2008-02-22 23:10:28 +01:00
if ( max > = 0x80860001 ) {
cpuid ( 0x80860001 , & dummy , & cpu_rev , & cpu_freq , & cpu_flags ) ;
2005-04-16 15:20:36 -07:00
if ( cpu_rev ! = 0x02000000 ) {
printk ( KERN_INFO " CPU: Processor revision %u.%u.%u.%u, %u MHz \n " ,
( cpu_rev > > 24 ) & 0xff ,
( cpu_rev > > 16 ) & 0xff ,
( cpu_rev > > 8 ) & 0xff ,
cpu_rev & 0xff ,
cpu_freq ) ;
}
}
2008-02-22 23:10:28 +01:00
if ( max > = 0x80860002 ) {
2005-04-16 15:20:36 -07:00
cpuid ( 0x80860002 , & new_cpu_rev , & cms_rev1 , & cms_rev2 , & dummy ) ;
if ( cpu_rev = = 0x02000000 ) {
printk ( KERN_INFO " CPU: Processor revision %08X, %u MHz \n " ,
new_cpu_rev , cpu_freq ) ;
}
printk ( KERN_INFO " CPU: Code Morphing Software revision %u.%u.%u-%u-%u \n " ,
( cms_rev1 > > 24 ) & 0xff ,
( cms_rev1 > > 16 ) & 0xff ,
( cms_rev1 > > 8 ) & 0xff ,
cms_rev1 & 0xff ,
cms_rev2 ) ;
}
2008-02-22 23:10:28 +01:00
if ( max > = 0x80860006 ) {
2005-04-16 15:20:36 -07:00
cpuid ( 0x80860003 ,
( void * ) & cpu_info [ 0 ] ,
( void * ) & cpu_info [ 4 ] ,
( void * ) & cpu_info [ 8 ] ,
( void * ) & cpu_info [ 12 ] ) ;
cpuid ( 0x80860004 ,
( void * ) & cpu_info [ 16 ] ,
( void * ) & cpu_info [ 20 ] ,
( void * ) & cpu_info [ 24 ] ,
( void * ) & cpu_info [ 28 ] ) ;
cpuid ( 0x80860005 ,
( void * ) & cpu_info [ 32 ] ,
( void * ) & cpu_info [ 36 ] ,
( void * ) & cpu_info [ 40 ] ,
( void * ) & cpu_info [ 44 ] ) ;
cpuid ( 0x80860006 ,
( void * ) & cpu_info [ 48 ] ,
( void * ) & cpu_info [ 52 ] ,
( void * ) & cpu_info [ 56 ] ,
( void * ) & cpu_info [ 60 ] ) ;
cpu_info [ 64 ] = ' \0 ' ;
printk ( KERN_INFO " CPU: %s \n " , cpu_info ) ;
}
/* Unhide possibly hidden capability flags */
rdmsr ( 0x80860004 , cap_mask , uk ) ;
wrmsr ( 0x80860004 , ~ 0 , uk ) ;
c - > x86_capability [ 0 ] = cpuid_edx ( 0x00000001 ) ;
wrmsr ( 0x80860004 , cap_mask , uk ) ;
2007-02-13 13:26:24 +01:00
/* All Transmeta CPUs have a constant TSC */
2008-02-26 08:52:39 +01:00
set_cpu_cap ( c , X86_FEATURE_CONSTANT_TSC ) ;
2008-02-22 23:10:28 +01:00
2005-08-01 21:11:44 -07:00
# ifdef CONFIG_SYSCTL
2008-02-22 23:10:28 +01:00
/*
* randomize_va_space slows us down enormously ;
* it probably triggers retranslation of x86 - > native bytecode
*/
2005-07-31 22:34:42 -07:00
randomize_va_space = 0 ;
2005-08-01 21:11:44 -07:00
# endif
2005-04-16 15:20:36 -07:00
}
2009-03-12 12:08:49 +00:00
static const struct cpu_dev __cpuinitconst transmeta_cpu_dev = {
2005-04-16 15:20:36 -07:00
. c_vendor = " Transmeta " ,
. c_ident = { " GenuineTMx86 " , " TransmetaCPU " } ,
2008-09-14 02:33:16 -07:00
. c_early_init = early_init_transmeta ,
2005-04-16 15:20:36 -07:00
. c_init = init_transmeta ,
2008-09-04 21:09:45 +02:00
. c_x86_vendor = X86_VENDOR_TRANSMETA ,
2005-04-16 15:20:36 -07:00
} ;
2008-09-04 21:09:45 +02:00
cpu_dev_register ( transmeta_cpu_dev ) ;