addon_cpuid_features.c 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. * Routines to indentify additional cpu features that are scattered in
  3. * cpuid space.
  4. */
  5. #include <linux/cpu.h>
  6. #include <asm/pat.h>
  7. #include <asm/processor.h>
  8. struct cpuid_bit {
  9. u16 feature;
  10. u8 reg;
  11. u8 bit;
  12. u32 level;
  13. };
  14. enum cpuid_regs {
  15. CR_EAX = 0,
  16. CR_ECX,
  17. CR_EDX,
  18. CR_EBX
  19. };
  20. void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
  21. {
  22. u32 max_level;
  23. u32 regs[4];
  24. const struct cpuid_bit *cb;
  25. static const struct cpuid_bit cpuid_bits[] = {
  26. { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
  27. { 0, 0, 0, 0 }
  28. };
  29. for (cb = cpuid_bits; cb->feature; cb++) {
  30. /* Verify that the level is valid */
  31. max_level = cpuid_eax(cb->level & 0xffff0000);
  32. if (max_level < cb->level ||
  33. max_level > (cb->level | 0xffff))
  34. continue;
  35. cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
  36. &regs[CR_ECX], &regs[CR_EDX]);
  37. if (regs[cb->reg] & (1 << cb->bit))
  38. set_cpu_cap(c, cb->feature);
  39. }
  40. }
  41. #ifdef CONFIG_X86_PAT
  42. void __cpuinit validate_pat_support(struct cpuinfo_x86 *c)
  43. {
  44. if (!cpu_has_pat)
  45. pat_disable("PAT not supported by CPU.");
  46. switch (c->x86_vendor) {
  47. case X86_VENDOR_INTEL:
  48. if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
  49. return;
  50. break;
  51. case X86_VENDOR_AMD:
  52. case X86_VENDOR_CENTAUR:
  53. case X86_VENDOR_TRANSMETA:
  54. return;
  55. }
  56. pat_disable("PAT disabled. Not yet verified on this CPU type.");
  57. }
  58. #endif