-/* $OpenBSD: identcpu.c,v 1.57 2014/12/16 21:02:58 sf Exp $ */
+/* $OpenBSD: identcpu.c,v 1.58 2015/01/19 16:01:43 jsg Exp $ */
/* $NetBSD: identcpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */
/*
/*
* Temperature read on the CPU is relative to the maximum
* temperature supported by the CPU, Tj(Max).
- * Poorly documented, refer to:
- * http://softwarecommunity.intel.com/isn/Community/
- * en-US/forums/thread/30228638.aspx
- * Basically, depending on a bit in one msr, the max is either 85 or 100.
- * Then we subtract the temperature portion of thermal status from
- * max to get current temperature.
+ * Refer to:
+ * 64-ia-32-architectures-software-developer-vol-3c-part-3-manual.pdf
+ * Section 35 and
+ * http://www.intel.com/content/dam/www/public/us/en/documents/
+ * white-papers/cpu-monitoring-dts-peci-paper.pdf
+ *
+ * The temperature on Intel CPUs can be between 70 and 105 degC, since
+ * Westmere we can read the TJmax from the die. For older CPUs we have
+ * to guess or use undocumented MSRs. Then we subtract the temperature
+ * portion of thermal status from max to get current temperature.
*/
void
intelcore_update_sensor(void *args)
int max = 100;
/* Only some Core family chips have MSR_TEMPERATURE_TARGET. */
- if (ci->ci_model == 0xe &&
- (rdmsr(MSR_TEMPERATURE_TARGET) & MSR_TEMPERATURE_TARGET_LOW_BIT))
+ if (ci->ci_model == 0x0e &&
+ (rdmsr(MSR_TEMPERATURE_TARGET_UNDOCUMENTED) &
+ MSR_TEMPERATURE_TARGET_LOW_BIT_UNDOCUMENTED))
max = 85;
+ /*
+ * Newer CPUs can tell you what their max temperature is.
+ * See: '64-ia-32-architectures-software-developer-
+ * vol-3c-part-3-manual.pdf'
+ */
+ if (ci->ci_model > 0x17 && ci->ci_model != 0x1c &&
+ ci->ci_model != 0x26 && ci->ci_model != 0x27 &&
+ ci->ci_model != 0x35 && ci->ci_model != 0x36)
+ max = MSR_TEMPERATURE_TARGET_TJMAX(
+ rdmsr(MSR_TEMPERATURE_TARGET));
+
msr = rdmsr(MSR_THERM_STATUS);
if (msr & MSR_THERM_STATUS_VALID_BIT) {
ci->ci_sensor.value = max - MSR_THERM_STATUS_TEMP(msr);
-/* $OpenBSD: specialreg.h,v 1.31 2014/12/22 22:33:51 mlarkin Exp $ */
+/* $OpenBSD: specialreg.h,v 1.32 2015/01/19 16:01:43 jsg Exp $ */
/* $NetBSD: specialreg.h,v 1.1 2003/04/26 18:39:48 fvdl Exp $ */
/* $NetBSD: x86/specialreg.h,v 1.2 2003/04/25 21:54:30 fvdl Exp $ */
#define MSR_PERFCTR0 0x0c1
#define MSR_PERFCTR1 0x0c2
#define MSR_FSB_FREQ 0x0cd /* Core Duo/Solo only */
-/* not documented anywhere, see intelcore_update_sensor() */
-#define MSR_TEMPERATURE_TARGET 0x0ee
-#define MSR_TEMPERATURE_TARGET_LOW_BIT 0x40000000
+/*
+ * for Core i Series and newer Xeons, see
+ * http://www.intel.com/content/dam/www/public/us/en/
+ * documents/white-papers/cpu-monitoring-dts-peci-paper.pdf
+ */
+#define MSR_TEMPERATURE_TARGET 0x1a2 /* Core i Series, Newer Xeons */
+#define MSR_TEMPERATURE_TARGET_TJMAX(msr) (((msr) >> 16) & 0xff)
+/*
+ * not documented anywhere, see intelcore_update_sensor()
+ * only available Core Duo and Core Solo Processors
+ */
+#define MSR_TEMPERATURE_TARGET_UNDOCUMENTED 0x0ee
+#define MSR_TEMPERATURE_TARGET_LOW_BIT_UNDOCUMENTED 0x40000000
#define MSR_MTRRcap 0x0fe
#define MSR_BBL_CR_ADDR 0x116 /* PII+ only */
#define MSR_BBL_CR_DECC 0x118 /* PII+ only */
-/* $OpenBSD: machdep.c,v 1.562 2015/01/15 13:58:55 sf Exp $ */
+/* $OpenBSD: machdep.c,v 1.563 2015/01/19 16:01:44 jsg Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
/*
* Temperature read on the CPU is relative to the maximum
* temperature supported by the CPU, Tj(Max).
- * Poorly documented, refer to:
- * http://softwarecommunity.intel.com/isn/Community/
- * en-US/forums/thread/30228638.aspx
- * Basically, depending on a bit in one msr, the max is either 85 or 100.
- * Then we subtract the temperature portion of thermal status from
- * max to get current temperature.
+ * Refer to:
+ * 64-ia-32-architectures-software-developer-vol-3c-part-3-manual.pdf
+ * Section 35 and
+ * http://www.intel.com/content/dam/www/public/us/en/documents/
+ * white-papers/cpu-monitoring-dts-peci-paper.pdf
+ *
+ * The temperature on Intel CPUs can be between 70 and 105 degC, since
+ * Westmere we can read the TJmax from the die. For older CPUs we have
+ * to guess or use undocumented MSRs. Then we subtract the temperature
+ * portion of thermal status from max to get current temperature.
*/
void
intelcore_update_sensor(void *args)
int max = 100;
/* Only some Core family chips have MSR_TEMPERATURE_TARGET. */
- if (ci->ci_model == 0xe &&
- (rdmsr(MSR_TEMPERATURE_TARGET) & MSR_TEMPERATURE_TARGET_LOW_BIT))
+ if (ci->ci_model == 0x0e &&
+ (rdmsr(MSR_TEMPERATURE_TARGET_UNDOCUMENTED) &
+ MSR_TEMPERATURE_TARGET_LOW_BIT_UNDOCUMENTED))
max = 85;
+ /*
+ * Newer CPUs can tell you what their max temperature is.
+ * See: '64-ia-32-architectures-software-developer-
+ * vol-3c-part-3-manual.pdf'
+ */
+ if (ci->ci_model > 0x17 && ci->ci_model != 0x1c &&
+ ci->ci_model != 0x26 && ci->ci_model != 0x27 &&
+ ci->ci_model != 0x35 && ci->ci_model != 0x36)
+ max = MSR_TEMPERATURE_TARGET_TJMAX(
+ rdmsr(MSR_TEMPERATURE_TARGET));
+
msr = rdmsr(MSR_THERM_STATUS);
if (msr & MSR_THERM_STATUS_VALID_BIT) {
ci->ci_sensor.value = max - MSR_THERM_STATUS_TEMP(msr);
-/* $OpenBSD: specialreg.h,v 1.48 2015/01/15 13:58:55 sf Exp $ */
+/* $OpenBSD: specialreg.h,v 1.49 2015/01/19 16:01:43 jsg Exp $ */
/* $NetBSD: specialreg.h,v 1.7 1994/10/27 04:16:26 cgd Exp $ */
/*-
#define P6MSR_CTR0 0x0c1
#define P6MSR_CTR1 0x0c2
#define MSR_FSB_FREQ 0x0cd /* Core Duo/Solo only */
-#define MSR_TEMPERATURE_TARGET 0x0ee
-#define MSR_TEMPERATURE_TARGET_LOW_BIT 0x40000000
+/*
+ * for Core i Series and newer Xeons, see
+ * http://www.intel.com/content/dam/www/public/us/en/
+ * documents/white-papers/cpu-monitoring-dts-peci-paper.pdf
+ */
+#define MSR_TEMPERATURE_TARGET 0x1a2 /* Core i Series, Newer Xeons */
+#define MSR_TEMPERATURE_TARGET_TJMAX(r) (((r) >> 16) & 0xff)
+/*
+ * not documented anywhere, see intelcore_update_sensor()
+ * only available Core Duo and Core Solo Processors
+ */
+#define MSR_TEMPERATURE_TARGET_UNDOCUMENTED 0x0ee
+#define MSR_TEMPERATURE_TARGET_LOW_BIT_UNDOCUMENTED 0x40000000
#define MSR_MTRRcap 0x0fe
#define MSR_BBL_CR_ADDR 0x116 /* PII+ only */
#define MSR_BBL_CR_DECC 0x118 /* PII+ only */