xref: /linux/arch/x86/kernel/cpu/transmeta.c (revision a16cb91ad9c4bb959e7d1be69d83d8c24a88e9f2)
1 #include <linux/kernel.h>
2 #include <linux/sched.h>
3 #include <linux/sched/clock.h>
4 #include <linux/mm.h>
5 #include <asm/cpufeature.h>
6 #include <asm/msr.h>
7 #include "cpu.h"
8 
9 static void early_init_transmeta(struct cpuinfo_x86 *c)
10 {
11 	u32 xlvl;
12 
13 	/* Transmeta-defined flags: level 0x80860001 */
14 	xlvl = cpuid_eax(0x80860000);
15 	if ((xlvl & 0xffff0000) == 0x80860000) {
16 		if (xlvl >= 0x80860001)
17 			c->x86_capability[CPUID_8086_0001_EDX] = cpuid_edx(0x80860001);
18 	}
19 
20 	clear_sched_clock_stable();
21 }
22 
23 static void init_transmeta(struct cpuinfo_x86 *c)
24 {
25 	unsigned int cap_mask, uk, max, dummy;
26 	unsigned int cms_rev1, cms_rev2;
27 	unsigned int cpu_rev, cpu_freq = 0, cpu_flags, new_cpu_rev;
28 	char cpu_info[65];
29 
30 	early_init_transmeta(c);
31 
32 	cpu_detect_cache_sizes(c);
33 
34 	/* Print CMS and CPU revision */
35 	max = cpuid_eax(0x80860000);
36 	cpu_rev = 0;
37 	if (max >= 0x80860001) {
38 		cpuid(0x80860001, &dummy, &cpu_rev, &cpu_freq, &cpu_flags);
39 		if (cpu_rev != 0x02000000) {
40 			pr_info("CPU: Processor revision %u.%u.%u.%u, %u MHz\n",
41 				(cpu_rev >> 24) & 0xff,
42 				(cpu_rev >> 16) & 0xff,
43 				(cpu_rev >> 8) & 0xff,
44 				cpu_rev & 0xff,
45 				cpu_freq);
46 		}
47 	}
48 	if (max >= 0x80860002) {
49 		cpuid(0x80860002, &new_cpu_rev, &cms_rev1, &cms_rev2, &dummy);
50 		if (cpu_rev == 0x02000000) {
51 			pr_info("CPU: Processor revision %08X, %u MHz\n",
52 				new_cpu_rev, cpu_freq);
53 		}
54 		pr_info("CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n",
55 		       (cms_rev1 >> 24) & 0xff,
56 		       (cms_rev1 >> 16) & 0xff,
57 		       (cms_rev1 >> 8) & 0xff,
58 		       cms_rev1 & 0xff,
59 		       cms_rev2);
60 	}
61 	if (max >= 0x80860006) {
62 		cpuid(0x80860003,
63 		      (void *)&cpu_info[0],
64 		      (void *)&cpu_info[4],
65 		      (void *)&cpu_info[8],
66 		      (void *)&cpu_info[12]);
67 		cpuid(0x80860004,
68 		      (void *)&cpu_info[16],
69 		      (void *)&cpu_info[20],
70 		      (void *)&cpu_info[24],
71 		      (void *)&cpu_info[28]);
72 		cpuid(0x80860005,
73 		      (void *)&cpu_info[32],
74 		      (void *)&cpu_info[36],
75 		      (void *)&cpu_info[40],
76 		      (void *)&cpu_info[44]);
77 		cpuid(0x80860006,
78 		      (void *)&cpu_info[48],
79 		      (void *)&cpu_info[52],
80 		      (void *)&cpu_info[56],
81 		      (void *)&cpu_info[60]);
82 		cpu_info[64] = '\0';
83 		pr_info("CPU: %s\n", cpu_info);
84 	}
85 
86 	/* Unhide possibly hidden capability flags */
87 	rdmsr(0x80860004, cap_mask, uk);
88 	wrmsr(0x80860004, ~0, uk);
89 	c->x86_capability[CPUID_1_EDX] = cpuid_edx(0x00000001);
90 	wrmsr(0x80860004, cap_mask, uk);
91 
92 	/* All Transmeta CPUs have a constant TSC */
93 	set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
94 
95 #ifdef CONFIG_SYSCTL
96 	/*
97 	 * randomize_va_space slows us down enormously;
98 	 * it probably triggers retranslation of x86->native bytecode
99 	 */
100 	randomize_va_space = 0;
101 #endif
102 }
103 
104 static const struct cpu_dev transmeta_cpu_dev = {
105 	.c_vendor	= "Transmeta",
106 	.c_ident	= { "GenuineTMx86", "TransmetaCPU" },
107 	.c_early_init	= early_init_transmeta,
108 	.c_init		= init_transmeta,
109 	.c_x86_vendor	= X86_VENDOR_TRANSMETA,
110 };
111 
112 cpu_dev_register(transmeta_cpu_dev);
113