centaur.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. #include <linux/bitops.h>
  2. #include <linux/kernel.h>
  3. #include <linux/init.h>
  4. #include <asm/processor.h>
  5. #include <asm/e820.h>
  6. #include <asm/mtrr.h>
  7. #include <asm/msr.h>
  8. #include "cpu.h"
  9. #ifdef CONFIG_X86_OOSTORE
  10. static u32 __cpuinit power2(u32 x)
  11. {
  12. u32 s = 1;
  13. while (s <= x)
  14. s <<= 1;
  15. return s >>= 1;
  16. }
  17. /*
  18. * Set up an actual MCR
  19. */
  20. static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key)
  21. {
  22. u32 lo, hi;
  23. hi = base & ~0xFFF;
  24. lo = ~(size-1); /* Size is a power of 2 so this makes a mask */
  25. lo &= ~0xFFF; /* Remove the ctrl value bits */
  26. lo |= key; /* Attribute we wish to set */
  27. wrmsr(reg+MSR_IDT_MCR0, lo, hi);
  28. mtrr_centaur_report_mcr(reg, lo, hi); /* Tell the mtrr driver */
  29. }
  30. /*
  31. * Figure what we can cover with MCR's
  32. *
  33. * Shortcut: We know you can't put 4Gig of RAM on a winchip
  34. */
  35. static u32 __cpuinit ramtop(void)
  36. {
  37. u32 clip = 0xFFFFFFFFUL;
  38. u32 top = 0;
  39. int i;
  40. for (i = 0; i < e820.nr_map; i++) {
  41. unsigned long start, end;
  42. if (e820.map[i].addr > 0xFFFFFFFFUL)
  43. continue;
  44. /*
  45. * Don't MCR over reserved space. Ignore the ISA hole
  46. * we frob around that catastrophe already
  47. */
  48. if (e820.map[i].type == E820_RESERVED) {
  49. if (e820.map[i].addr >= 0x100000UL &&
  50. e820.map[i].addr < clip)
  51. clip = e820.map[i].addr;
  52. continue;
  53. }
  54. start = e820.map[i].addr;
  55. end = e820.map[i].addr + e820.map[i].size;
  56. if (start >= end)
  57. continue;
  58. if (end > top)
  59. top = end;
  60. }
  61. /*
  62. * Everything below 'top' should be RAM except for the ISA hole.
  63. * Because of the limited MCR's we want to map NV/ACPI into our
  64. * MCR range for gunk in RAM
  65. *
  66. * Clip might cause us to MCR insufficient RAM but that is an
  67. * acceptable failure mode and should only bite obscure boxes with
  68. * a VESA hole at 15Mb
  69. *
  70. * The second case Clip sometimes kicks in is when the EBDA is marked
  71. * as reserved. Again we fail safe with reasonable results
  72. */
  73. if (top > clip)
  74. top = clip;
  75. return top;
  76. }
  77. /*
  78. * Compute a set of MCR's to give maximum coverage
  79. */
  80. static int __cpuinit centaur_mcr_compute(int nr, int key)
  81. {
  82. u32 mem = ramtop();
  83. u32 root = power2(mem);
  84. u32 base = root;
  85. u32 top = root;
  86. u32 floor = 0;
  87. int ct = 0;
  88. while (ct < nr) {
  89. u32 fspace = 0;
  90. u32 high;
  91. u32 low;
  92. /*
  93. * Find the largest block we will fill going upwards
  94. */
  95. high = power2(mem-top);
  96. /*
  97. * Find the largest block we will fill going downwards
  98. */
  99. low = base/2;
  100. /*
  101. * Don't fill below 1Mb going downwards as there
  102. * is an ISA hole in the way.
  103. */
  104. if (base <= 1024*1024)
  105. low = 0;
  106. /*
  107. * See how much space we could cover by filling below
  108. * the ISA hole
  109. */
  110. if (floor == 0)
  111. fspace = 512*1024;
  112. else if (floor == 512*1024)
  113. fspace = 128*1024;
  114. /* And forget ROM space */
  115. /*
  116. * Now install the largest coverage we get
  117. */
  118. if (fspace > high && fspace > low) {
  119. centaur_mcr_insert(ct, floor, fspace, key);
  120. floor += fspace;
  121. } else if (high > low) {
  122. centaur_mcr_insert(ct, top, high, key);
  123. top += high;
  124. } else if (low > 0) {
  125. base -= low;
  126. centaur_mcr_insert(ct, base, low, key);
  127. } else
  128. break;
  129. ct++;
  130. }
  131. /*
  132. * We loaded ct values. We now need to set the mask. The caller
  133. * must do this bit.
  134. */
  135. return ct;
  136. }
  137. static void __cpuinit centaur_create_optimal_mcr(void)
  138. {
  139. int used;
  140. int i;
  141. /*
  142. * Allocate up to 6 mcrs to mark as much of ram as possible
  143. * as write combining and weak write ordered.
  144. *
  145. * To experiment with: Linux never uses stack operations for
  146. * mmio spaces so we could globally enable stack operation wc
  147. *
  148. * Load the registers with type 31 - full write combining, all
  149. * writes weakly ordered.
  150. */
  151. used = centaur_mcr_compute(6, 31);
  152. /*
  153. * Wipe unused MCRs
  154. */
  155. for (i = used; i < 8; i++)
  156. wrmsr(MSR_IDT_MCR0+i, 0, 0);
  157. }
  158. static void __cpuinit winchip2_create_optimal_mcr(void)
  159. {
  160. u32 lo, hi;
  161. int used;
  162. int i;
  163. /*
  164. * Allocate up to 6 mcrs to mark as much of ram as possible
  165. * as write combining, weak store ordered.
  166. *
  167. * Load the registers with type 25
  168. * 8 - weak write ordering
  169. * 16 - weak read ordering
  170. * 1 - write combining
  171. */
  172. used = centaur_mcr_compute(6, 25);
  173. /*
  174. * Mark the registers we are using.
  175. */
  176. rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
  177. for (i = 0; i < used; i++)
  178. lo |= 1<<(9+i);
  179. wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
  180. /*
  181. * Wipe unused MCRs
  182. */
  183. for (i = used; i < 8; i++)
  184. wrmsr(MSR_IDT_MCR0+i, 0, 0);
  185. }
  186. /*
  187. * Handle the MCR key on the Winchip 2.
  188. */
  189. static void __cpuinit winchip2_unprotect_mcr(void)
  190. {
  191. u32 lo, hi;
  192. u32 key;
  193. rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
  194. lo &= ~0x1C0; /* blank bits 8-6 */
  195. key = (lo>>17) & 7;
  196. lo |= key<<6; /* replace with unlock key */
  197. wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
  198. }
  199. static void __cpuinit winchip2_protect_mcr(void)
  200. {
  201. u32 lo, hi;
  202. rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
  203. lo &= ~0x1C0; /* blank bits 8-6 */
  204. wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
  205. }
  206. #endif /* CONFIG_X86_OOSTORE */
  207. #define ACE_PRESENT (1 << 6)
  208. #define ACE_ENABLED (1 << 7)
  209. #define ACE_FCR (1 << 28) /* MSR_VIA_FCR */
  210. #define RNG_PRESENT (1 << 2)
  211. #define RNG_ENABLED (1 << 3)
  212. #define RNG_ENABLE (1 << 6) /* MSR_VIA_RNG */
  213. static void __cpuinit init_c3(struct cpuinfo_x86 *c)
  214. {
  215. u32 lo, hi;
  216. /* Test for Centaur Extended Feature Flags presence */
  217. if (cpuid_eax(0xC0000000) >= 0xC0000001) {
  218. u32 tmp = cpuid_edx(0xC0000001);
  219. /* enable ACE unit, if present and disabled */
  220. if ((tmp & (ACE_PRESENT | ACE_ENABLED)) == ACE_PRESENT) {
  221. rdmsr(MSR_VIA_FCR, lo, hi);
  222. lo |= ACE_FCR; /* enable ACE unit */
  223. wrmsr(MSR_VIA_FCR, lo, hi);
  224. printk(KERN_INFO "CPU: Enabled ACE h/w crypto\n");
  225. }
  226. /* enable RNG unit, if present and disabled */
  227. if ((tmp & (RNG_PRESENT | RNG_ENABLED)) == RNG_PRESENT) {
  228. rdmsr(MSR_VIA_RNG, lo, hi);
  229. lo |= RNG_ENABLE; /* enable RNG unit */
  230. wrmsr(MSR_VIA_RNG, lo, hi);
  231. printk(KERN_INFO "CPU: Enabled h/w RNG\n");
  232. }
  233. /* store Centaur Extended Feature Flags as
  234. * word 5 of the CPU capability bit array
  235. */
  236. c->x86_capability[5] = cpuid_edx(0xC0000001);
  237. }
  238. #ifdef CONFIG_X86_32
  239. /* Cyrix III family needs CX8 & PGE explicitly enabled. */
  240. if (c->x86_model >= 6 && c->x86_model <= 9) {
  241. rdmsr(MSR_VIA_FCR, lo, hi);
  242. lo |= (1<<1 | 1<<7);
  243. wrmsr(MSR_VIA_FCR, lo, hi);
  244. set_cpu_cap(c, X86_FEATURE_CX8);
  245. }
  246. /* Before Nehemiah, the C3's had 3dNOW! */
  247. if (c->x86_model >= 6 && c->x86_model < 9)
  248. set_cpu_cap(c, X86_FEATURE_3DNOW);
  249. #endif
  250. if (c->x86 == 0x6 && c->x86_model >= 0xf) {
  251. c->x86_cache_alignment = c->x86_clflush_size * 2;
  252. set_cpu_cap(c, X86_FEATURE_REP_GOOD);
  253. }
  254. cpu_detect_cache_sizes(c);
  255. }
  256. enum {
  257. ECX8 = 1<<1,
  258. EIERRINT = 1<<2,
  259. DPM = 1<<3,
  260. DMCE = 1<<4,
  261. DSTPCLK = 1<<5,
  262. ELINEAR = 1<<6,
  263. DSMC = 1<<7,
  264. DTLOCK = 1<<8,
  265. EDCTLB = 1<<8,
  266. EMMX = 1<<9,
  267. DPDC = 1<<11,
  268. EBRPRED = 1<<12,
  269. DIC = 1<<13,
  270. DDC = 1<<14,
  271. DNA = 1<<15,
  272. ERETSTK = 1<<16,
  273. E2MMX = 1<<19,
  274. EAMD3D = 1<<20,
  275. };
  276. static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
  277. {
  278. switch (c->x86) {
  279. #ifdef CONFIG_X86_32
  280. case 5:
  281. /* Emulate MTRRs using Centaur's MCR. */
  282. set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR);
  283. break;
  284. #endif
  285. case 6:
  286. if (c->x86_model >= 0xf)
  287. set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
  288. break;
  289. }
  290. #ifdef CONFIG_X86_64
  291. set_cpu_cap(c, X86_FEATURE_SYSENTER32);
  292. #endif
  293. }
  294. static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
  295. {
  296. #ifdef CONFIG_X86_32
  297. char *name;
  298. u32 fcr_set = 0;
  299. u32 fcr_clr = 0;
  300. u32 lo, hi, newlo;
  301. u32 aa, bb, cc, dd;
  302. /*
  303. * Bit 31 in normal CPUID used for nonstandard 3DNow ID;
  304. * 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway
  305. */
  306. clear_cpu_cap(c, 0*32+31);
  307. #endif
  308. early_init_centaur(c);
  309. switch (c->x86) {
  310. #ifdef CONFIG_X86_32
  311. case 5:
  312. switch (c->x86_model) {
  313. case 4:
  314. name = "C6";
  315. fcr_set = ECX8|DSMC|EDCTLB|EMMX|ERETSTK;
  316. fcr_clr = DPDC;
  317. printk(KERN_NOTICE "Disabling bugged TSC.\n");
  318. clear_cpu_cap(c, X86_FEATURE_TSC);
  319. #ifdef CONFIG_X86_OOSTORE
  320. centaur_create_optimal_mcr();
  321. /*
  322. * Enable:
  323. * write combining on non-stack, non-string
  324. * write combining on string, all types
  325. * weak write ordering
  326. *
  327. * The C6 original lacks weak read order
  328. *
  329. * Note 0x120 is write only on Winchip 1
  330. */
  331. wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);
  332. #endif
  333. break;
  334. case 8:
  335. switch (c->x86_mask) {
  336. default:
  337. name = "2";
  338. break;
  339. case 7 ... 9:
  340. name = "2A";
  341. break;
  342. case 10 ... 15:
  343. name = "2B";
  344. break;
  345. }
  346. fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|
  347. E2MMX|EAMD3D;
  348. fcr_clr = DPDC;
  349. #ifdef CONFIG_X86_OOSTORE
  350. winchip2_unprotect_mcr();
  351. winchip2_create_optimal_mcr();
  352. rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
  353. /*
  354. * Enable:
  355. * write combining on non-stack, non-string
  356. * write combining on string, all types
  357. * weak write ordering
  358. */
  359. lo |= 31;
  360. wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
  361. winchip2_protect_mcr();
  362. #endif
  363. break;
  364. case 9:
  365. name = "3";
  366. fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|
  367. E2MMX|EAMD3D;
  368. fcr_clr = DPDC;
  369. #ifdef CONFIG_X86_OOSTORE
  370. winchip2_unprotect_mcr();
  371. winchip2_create_optimal_mcr();
  372. rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
  373. /*
  374. * Enable:
  375. * write combining on non-stack, non-string
  376. * write combining on string, all types
  377. * weak write ordering
  378. */
  379. lo |= 31;
  380. wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
  381. winchip2_protect_mcr();
  382. #endif
  383. break;
  384. default:
  385. name = "??";
  386. }
  387. rdmsr(MSR_IDT_FCR1, lo, hi);
  388. newlo = (lo|fcr_set) & (~fcr_clr);
  389. if (newlo != lo) {
  390. printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n",
  391. lo, newlo);
  392. wrmsr(MSR_IDT_FCR1, newlo, hi);
  393. } else {
  394. printk(KERN_INFO "Centaur FCR is 0x%X\n", lo);
  395. }
  396. /* Emulate MTRRs using Centaur's MCR. */
  397. set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR);
  398. /* Report CX8 */
  399. set_cpu_cap(c, X86_FEATURE_CX8);
  400. /* Set 3DNow! on Winchip 2 and above. */
  401. if (c->x86_model >= 8)
  402. set_cpu_cap(c, X86_FEATURE_3DNOW);
  403. /* See if we can find out some more. */
  404. if (cpuid_eax(0x80000000) >= 0x80000005) {
  405. /* Yes, we can. */
  406. cpuid(0x80000005, &aa, &bb, &cc, &dd);
  407. /* Add L1 data and code cache sizes. */
  408. c->x86_cache_size = (cc>>24)+(dd>>24);
  409. }
  410. sprintf(c->x86_model_id, "WinChip %s", name);
  411. break;
  412. #endif
  413. case 6:
  414. init_c3(c);
  415. break;
  416. }
  417. #ifdef CONFIG_X86_64
  418. set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
  419. #endif
  420. }
  421. static unsigned int __cpuinit
  422. centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size)
  423. {
  424. #ifdef CONFIG_X86_32
  425. /* VIA C3 CPUs (670-68F) need further shifting. */
  426. if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8)))
  427. size >>= 8;
  428. /*
  429. * There's also an erratum in Nehemiah stepping 1, which
  430. * returns '65KB' instead of '64KB'
  431. * - Note, it seems this may only be in engineering samples.
  432. */
  433. if ((c->x86 == 6) && (c->x86_model == 9) &&
  434. (c->x86_mask == 1) && (size == 65))
  435. size -= 1;
  436. #endif
  437. return size;
  438. }
  439. static const struct cpu_dev __cpuinitconst centaur_cpu_dev = {
  440. .c_vendor = "Centaur",
  441. .c_ident = { "CentaurHauls" },
  442. .c_early_init = early_init_centaur,
  443. .c_init = init_centaur,
  444. .c_size_cache = centaur_size_cache,
  445. .c_x86_vendor = X86_VENDOR_CENTAUR,
  446. };
  447. cpu_dev_register(centaur_cpu_dev);