mce_intel.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. * Common code for Intel machine checks
  3. */
  4. #include <linux/interrupt.h>
  5. #include <linux/kernel.h>
  6. #include <linux/types.h>
  7. #include <linux/init.h>
  8. #include <linux/smp.h>
  9. #include <asm/therm_throt.h>
  10. #include <asm/processor.h>
  11. #include <asm/system.h>
  12. #include <asm/apic.h>
  13. #include <asm/msr.h>
  14. #include "mce.h"
  15. void intel_init_thermal(struct cpuinfo_x86 *c)
  16. {
  17. unsigned int cpu = smp_processor_id();
  18. int tm2 = 0;
  19. u32 l, h;
  20. /* Thermal monitoring depends on ACPI and clock modulation*/
  21. if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC))
  22. return;
  23. /*
  24. * First check if its enabled already, in which case there might
  25. * be some SMM goo which handles it, so we can't even put a handler
  26. * since it might be delivered via SMI already:
  27. */
  28. rdmsr(MSR_IA32_MISC_ENABLE, l, h);
  29. h = apic_read(APIC_LVTTHMR);
  30. if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
  31. printk(KERN_DEBUG
  32. "CPU%d: Thermal monitoring handled by SMI\n", cpu);
  33. return;
  34. }
  35. if (cpu_has(c, X86_FEATURE_TM2) && (l & MSR_IA32_MISC_ENABLE_TM2))
  36. tm2 = 1;
  37. /* Check whether a vector already exists */
  38. if (h & APIC_VECTOR_MASK) {
  39. printk(KERN_DEBUG
  40. "CPU%d: Thermal LVT vector (%#x) already installed\n",
  41. cpu, (h & APIC_VECTOR_MASK));
  42. return;
  43. }
  44. /* We'll mask the thermal vector in the lapic till we're ready: */
  45. h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED;
  46. apic_write(APIC_LVTTHMR, h);
  47. rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
  48. wrmsr(MSR_IA32_THERM_INTERRUPT,
  49. l | (THERM_INT_LOW_ENABLE | THERM_INT_HIGH_ENABLE), h);
  50. intel_set_thermal_handler();
  51. rdmsr(MSR_IA32_MISC_ENABLE, l, h);
  52. wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h);
  53. /* Unmask the thermal vector: */
  54. l = apic_read(APIC_LVTTHMR);
  55. apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
  56. printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n",
  57. cpu, tm2 ? "TM2" : "TM1");
  58. /* enable thermal throttle processing */
  59. atomic_set(&therm_throt_en, 1);
  60. }