1 #include <xen/lib.h>
2 #include <xen/init.h>
3 #include <xen/bitops.h>
4 #include <asm/processor.h>
5 #include <asm/msr.h>
6 #include <asm/e820.h>
7 #include "cpu.h"
8 
9 #define ACE_PRESENT	(1 << 6)
10 #define ACE_ENABLED	(1 << 7)
11 #define ACE_FCR		(1 << 28)	/* MSR_VIA_FCR */
12 
13 #define RNG_PRESENT	(1 << 2)
14 #define RNG_ENABLED	(1 << 3)
15 #define RNG_ENABLE	(1 << 6)	/* MSR_VIA_RNG */
16 
init_c3(struct cpuinfo_x86 * c)17 static void init_c3(struct cpuinfo_x86 *c)
18 {
19 	uint64_t msr_content;
20 
21 	/* Test for Centaur Extended Feature Flags presence */
22 	if (cpuid_eax(0xC0000000) >= 0xC0000001) {
23 		u32 tmp = cpuid_edx(0xC0000001);
24 
25 		/* enable ACE unit, if present and disabled */
26 		if ((tmp & (ACE_PRESENT | ACE_ENABLED)) == ACE_PRESENT) {
27 			rdmsrl(MSR_VIA_FCR, msr_content);
28 			/* enable ACE unit */
29 			wrmsrl(MSR_VIA_FCR, msr_content | ACE_FCR);
30 			printk(KERN_INFO "CPU: Enabled ACE h/w crypto\n");
31 		}
32 
33 		/* enable RNG unit, if present and disabled */
34 		if ((tmp & (RNG_PRESENT | RNG_ENABLED)) == RNG_PRESENT) {
35 			rdmsrl(MSR_VIA_RNG, msr_content);
36 			/* enable RNG unit */
37 			wrmsrl(MSR_VIA_RNG, msr_content | RNG_ENABLE);
38 			printk(KERN_INFO "CPU: Enabled h/w RNG\n");
39 		}
40 	}
41 
42 	if (c->x86 == 0x6 && c->x86_model >= 0xf) {
43 		c->x86_cache_alignment = c->x86_clflush_size * 2;
44 		__set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
45 	}
46 
47 	get_model_name(c);
48 	display_cacheinfo(c);
49 }
50 
init_centaur(struct cpuinfo_x86 * c)51 static void init_centaur(struct cpuinfo_x86 *c)
52 {
53 	if (c->x86 == 6)
54 		init_c3(c);
55 }
56 
57 static const struct cpu_dev centaur_cpu_dev = {
58 	.c_vendor	= "Centaur",
59 	.c_ident	= { "CentaurHauls" },
60 	.c_init		= init_centaur,
61 };
62 
centaur_init_cpu(void)63 int __init centaur_init_cpu(void)
64 {
65 	cpu_devs[X86_VENDOR_CENTAUR] = &centaur_cpu_dev;
66 	return 0;
67 }
68