Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH 2/2] hwmon: (coretemp) Get TjMax value from MSR

57 views
Skip to first unread message

Huaxu Wan

unread,
May 7, 2010, 5:50:52 AM5/7/10
to linux-...@vger.kernel.org, lm-se...@lm-sensors.org, huax...@intel.com, kh...@linux-fr.org

The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer
processers.

Signed-off-by: Huaxu Wan <huax...@linux.intel.com>
---
drivers/hwmon/coretemp.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 44 insertions(+), 1 deletions(-)

diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 237c68d..7a01032 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -241,6 +241,49 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
return tjmax;
}

+static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
+{
+ /* The 100C is default for both mobile and non mobile CPUs */
+ int err;
+ u32 eax, edx;
+ u32 val;
+
+ /* A new feature of current Intel(R) processors, the
+ IA32_TEMPERATURE_TARGET(0x1a2) contains the TjMax value */
+ err = rdmsr_safe_on_cpu(id, 0x1a2, &eax, &edx);
+ if (err){
+ printk_once(KERN_WARNING DRVNAME " : Unable to read TjMax from CPU.\n");
+ } else {
+ val = (eax >> 16 ) & 0xff;
+ /* If the TjMax is not reasonable, an assumption value
+ will be used */
+ if (( val > 80) && (val < 120)){
+ printk_once(KERN_INFO DRVNAME " : The TjMax is %d C. \n", val);
+ return val * 1000;
+ }
+ }
+
+ /* For the early CPUs, an approximation is given.
+ NOTE: the given value may not be correct. */
+ switch(c->x86_model){
+ case 0xe :
+ case 0xf :
+ case 0x16 :
+ case 0x1a :
+ printk_once(KERN_WARNING DRVNAME " : TjMax is assumed as 100 C! \n");
+ return 100000;
+ break;
+ case 0x17 :
+ case 0x1c : /* Atom CPUs */
+ return adjust_tjmax(c, id, dev);
+ break;
+ default :
+ printk_once(KERN_WARNING DRVNAME " : Your CPU is not support yet,"
+ "using the default TjMax: 100 C.\n");
+ return 100000;
+ }
+}
+
static int __devinit coretemp_probe(struct platform_device *pdev)
{
struct coretemp_data *data;
@@ -283,7 +326,7 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
}
}

- data->tjmax = adjust_tjmax(c, data->id, &pdev->dev);
+ data->tjmax = get_tjmax(c, data->id, &pdev->dev);
platform_set_drvdata(pdev, data);

/* read the still undocumented IA32_TEMPERATURE_TARGET it exists
--
1.6.3.3.363.g725cf7
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Carsten Emde

unread,
May 7, 2010, 9:30:41 AM5/7/10
to Huaxu Wan, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, Huaxu Wan
Hi Huaxu,

> The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer
> processers.

I took the liberty to make some very minor changes to your patch:
- Unified and adapted messages and comments
- Added a definition of MSR_IA32_TEMPERATURE_TARGET to the arch header
- Replaced 0x1a2 by MSR_IA32_TEMPERATURE_TARGET
- Applied changes suggested by checkpatch

Hope you like it.

Signed-off-by: Carsten Emde <C.E...@osadl.org>

coretemp-add-tjmax-method-for-i-series-processors.patch

Huaxu Wan

unread,
May 9, 2010, 11:00:12 PM5/9/10
to Carsten Emde, Huaxu Wan, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, Huaxu Wan
On 15:29 Fri 07 May, Carsten Emde wrote:

> + err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
> + if (err)
> + dev_warn(dev, "Unable to read TjMax from CPU.\n");


> + else {
> + val = (eax >> 16) & 0xff;

> + if (val > 80 && val < 120) {
> + dev_info(dev, "TjMax is %dC.\n", val);


> + return val * 1000;

> + } else {
> + dev_warn(dev, "TjMax of %dC not plausible,"
> + " using 100C instead." , val);


> + return 100000;
> + }
> + }

The CPU, in the following case switch, may return no err at the above rdmsr. The
val is 0 with CPU model 0x0f in my test. The function should not return when
(val > 80 && val < 120) is false.

> +
> + /*
> + * An assumption is made for early CPUs and unreadable MSR.
> + * NOTE: the given value may not be correct.
> + */
> + switch (c->x86_model) {
> + case 0x0e:
> + case 0x0f:


> + case 0x16:
> + case 0x1a:

> + dev_warn(dev, "TjMax is assumed as 100C!\n");


> + return 100000;
> + break;
> + case 0x17:
> + case 0x1c: /* Atom CPUs */
> + return adjust_tjmax(c, id, dev);
> + break;
> + default:

> + dev_warn(dev, "CPU (model=0x%x) is not supported yet,"
> + " using default TjMax of 100C.\n", c->x86_model);


> + return 100000;
> + }
> +}

--
Thanks
Huaxu

Huaxu Wan

unread,
May 9, 2010, 11:41:26 PM5/9/10
to Huaxu Wan, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, huax...@intel.com, Carsten Emde
The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer
processers.

Signed-off-by: Huaxu Wan <huax...@linux.intel.com>
Signed-off-by: Carsten Emde <C.E...@osadl.org>
---
arch/x86/include/asm/msr-index.h | 2 +
drivers/hwmon/coretemp.c | 52 ++++++++++++++++++++++++++++++++++++-
2 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 4604e6a..9bc0cf8 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -232,6 +232,8 @@

#define MSR_IA32_MISC_ENABLE 0x000001a0

+#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
+
/* MISC_ENABLE bits: architectural */
#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0)
#define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1)
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index d194207..9959390 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -241,6 +241,54 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *


return tjmax;
}

+static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
+{
+ /* The 100C is default for both mobile and non mobile CPUs */
+ int err;
+ u32 eax, edx;
+ u32 val;
+
+ /* A new feature of current Intel(R) processors, the

+ IA32_TEMPERATURE_TARGET contains the TjMax value */
+ err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
+ if (err){
+ dev_warn(dev, "Unable to read TjMax from CPU.\n");


+ } else {
+ val = (eax >> 16 ) & 0xff;
+ /*

+ * If the TjMax is not plausible, an assumption
+ * will be used
+ */


+ if (( val > 80) && (val < 120)){

+ dev_info(dev, "TjMax is %d C. \n", val);


+ return val * 1000;
+ }
+ }
+
+ /*

+ * An assumption is made for early CPUs and unreadable MSR.

+ * NOTE: the given value may not be correct.
+ */
+


+ switch(c->x86_model){
+ case 0xe :
+ case 0xf :
+ case 0x16 :
+ case 0x1a :

+ dev_warn(dev, "TjMax is assumed as 100 C! \n");


+ return 100000;
+ break;
+ case 0x17 :
+ case 0x1c : /* Atom CPUs */
+ return adjust_tjmax(c, id, dev);
+ break;
+ default :

+ dev_warn(dev, "CPU (model=0x%x) is not supported yet,"
+ " using default TjMax of 100C.\n", c->x86_model);

+ return 100000;
+ }
+}
+
static int __devinit coretemp_probe(struct platform_device *pdev)
{
struct coretemp_data *data;

@@ -283,14 +331,14 @@ static int __devinit coretemp_probe(struct platform_device *pdev)


}
}

- data->tjmax = adjust_tjmax(c, data->id, &pdev->dev);
+ data->tjmax = get_tjmax(c, data->id, &pdev->dev);
platform_set_drvdata(pdev, data);

/* read the still undocumented IA32_TEMPERATURE_TARGET it exists

on older CPUs but not in this register, Atoms don't have it either */

if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) {
- err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx);
+ err = rdmsr_safe_on_cpu(data->id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
if (err) {
dev_warn(&pdev->dev, "Unable to read"
" IA32_TEMPERATURE_TARGET MSR\n");

Maxim Levitsky

unread,
May 29, 2010, 1:39:29 AM5/29/10
to Huaxu Wan, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, huax...@intel.com, kh...@linux-fr.org
On Fri, 2010-05-07 at 17:59 +0800, Huaxu Wan wrote:
> The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer
> processers.

I know that TjMax on my system is 85, and now coretemp reports wrong
temperatures.
First of all BIOS using stupid tricks actualy reports CPU temperature
through ACPI, and assuming it was correct TjMax is 85.
It also shuts down the system if I 'lie' to it that cpu temperature is
85C.

Coretemp was working correctly in 2.6.34

cat /proc/cpuinfo

processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 15
model name : Intel(R) Core(TM)2 Duo CPU T5450 @ 1.66GHz
stepping : 13
cpu MHz : 1667.000
cache size : 2048 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 10
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm lahf_lm
bogomips : 3324.70
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:

processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 15
model name : Intel(R) Core(TM)2 Duo CPU T5450 @ 1.66GHz
stepping : 13
cpu MHz : 1667.000
cache size : 2048 KB
physical id : 0
siblings : 2
core id : 1
cpu cores : 2
apicid : 1
initial apicid : 1
fpu : yes
fpu_exception : yes
cpuid level : 10
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm lahf_lm
bogomips : 3324.99
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:


Best regards,
Maxim Levitsky

Maxim Levitsky

unread,
May 30, 2010, 10:44:19 AM5/30/10
to Huaxu Wan, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, huax...@intel.com, kh...@linux-fr.org
On Sat, 2010-05-29 at 08:39 +0300, Maxim Levitsky wrote:
> On Fri, 2010-05-07 at 17:59 +0800, Huaxu Wan wrote:
> > The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer
> > processers.
>
> I know that TjMax on my system is 85, and now coretemp reports wrong
> temperatures.
> First of all BIOS using stupid tricks actualy reports CPU temperature
> through ACPI, and assuming it was correct TjMax is 85.
> It also shuts down the system if I 'lie' to it that cpu temperature is
> 85C.
>
> Coretemp was working correctly in 2.6.34

The following patch unbreaks the driver:


commit 8ff4f666908dd208a10f1b6b38286303fdb774fc
Author: Maxim Levitsky <maximl...@gmail.com>
Date: Sat May 29 08:57:09 2010 +0300

coretemp: unbreak tjmax reports on Core2 CPUs

Core2 CPUS don't report TjMax, but its not always 100C

Signed-off-by: Maxim Levitsky <maximl...@gmail.com>


diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 2988da1..fb100a4 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -276,11 +276,8 @@ static int __devinit get_tjmax(struct cpuinfo_x86
*c, u32 id,
case 0xf:
case 0x16:
case 0x1a:
- dev_warn(dev, "TjMax is assumed as 100 C!\n");
- return 100000;
- break;
case 0x17:
- case 0x1c: /* Atom CPUs */
+ case 0x1c:
return adjust_tjmax(c, id, dev);
break;
default:

Huaxu Wan

unread,
May 30, 2010, 9:38:41 PM5/30/10
to Maxim Levitsky, Huaxu Wan, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, huax...@intel.com, kh...@linux-fr.org
On 08:39 Sat 29 May, Maxim Levitsky wrote:
> On Fri, 2010-05-07 at 17:59 +0800, Huaxu Wan wrote:
> > The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer
> > processers.
>
> I know that TjMax on my system is 85, and now coretemp reports wrong
> temperatures.
> First of all BIOS using stupid tricks actualy reports CPU temperature
> through ACPI, and assuming it was correct TjMax is 85.
> It also shuts down the system if I 'lie' to it that cpu temperature is
> 85C.

From the list at [1], the TjMax(Tjunction) of T5450 is 100C. Does anyone
here can make a double check?

[1] http://ark.intel.com/Product.aspx?id=30787&processor=T5450&spec-codes=SLA4F

Thanks
Huaxu

Maxim Levitsky

unread,
Jun 2, 2010, 12:34:26 PM6/2/10
to Huaxu Wan, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, huax...@intel.com, kh...@linux-fr.org
On Mon, 2010-05-31 at 09:39 +0800, Huaxu Wan wrote:
> On 08:39 Sat 29 May, Maxim Levitsky wrote:
> > On Fri, 2010-05-07 at 17:59 +0800, Huaxu Wan wrote:
> > > The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer
> > > processers.
> >
> > I know that TjMax on my system is 85, and now coretemp reports wrong
> > temperatures.
> > First of all BIOS using stupid tricks actualy reports CPU temperature
> > through ACPI, and assuming it was correct TjMax is 85.
> > It also shuts down the system if I 'lie' to it that cpu temperature is
> > 85C.
>
> From the list at [1], the TjMax(Tjunction) of T5450 is 100C. Does anyone
> here can make a double check?
>
> [1] http://ark.intel.com/Product.aspx?id=30787&processor=T5450&spec-codes=SLA4F

This is very interesting.

With TjMax 85C, the CPUs idle temperature is reported at around 45~50C
GPU temperature that is around 60C

BIOS also reports 45~50C.

BIOS hooks an SMI to CPU thermal report, and stores the temperature it
read in ram, then ACPI code reads it, reports and passes to the EC
(embedded controller).

If I write myself 85 to embedded controller, systems shuts down.
(values less that 85, eg 84 don't shut system).

Thats all I know.

Maxim Levitsky

unread,
Jun 2, 2010, 4:10:31 PM6/2/10
to Huaxu Wan, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, huax...@intel.com, kh...@linux-fr.org
On Wed, 2010-06-02 at 19:34 +0300, Maxim Levitsky wrote:
> On Mon, 2010-05-31 at 09:39 +0800, Huaxu Wan wrote:
> > On 08:39 Sat 29 May, Maxim Levitsky wrote:
> > > On Fri, 2010-05-07 at 17:59 +0800, Huaxu Wan wrote:
> > > > The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer
> > > > processers.
> > >
> > > I know that TjMax on my system is 85, and now coretemp reports wrong
> > > temperatures.
> > > First of all BIOS using stupid tricks actualy reports CPU temperature
> > > through ACPI, and assuming it was correct TjMax is 85.
> > > It also shuts down the system if I 'lie' to it that cpu temperature is
> > > 85C.
> >
> > From the list at [1], the TjMax(Tjunction) of T5450 is 100C. Does anyone
> > here can make a double check?
> >
> > [1] http://ark.intel.com/Product.aspx?id=30787&processor=T5450&spec-codes=SLA4F
>
> This is very interesting.
>
> With TjMax 85C, the CPUs idle temperature is reported at around 45~50C
> GPU temperature that is around 60C
>
> BIOS also reports 45~50C.
>
> BIOS hooks an SMI to CPU thermal report, and stores the temperature it
> read in ram, then ACPI code reads it, reports and passes to the EC
> (embedded controller).
>
> If I write myself 85 to embedded controller, systems shuts down.
> (values less that 85, eg 84 don't shut system).


Another clue is that right after resume from ram, after long delay
(~hour) the displayed temperature with TjMax 85 is 33C. Since room
temperature here is around 27C, this seems more plausible that
33 + 15 = 48C

Maxim Levitsky

unread,
Jun 12, 2010, 9:04:18 AM6/12/10
to Huaxu Wan, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, huax...@intel.com, kh...@linux-fr.org


Any update?

Wan, Huaxu

unread,
Jun 12, 2010, 10:32:27 PM6/12/10
to Maxim Levitsky, Huaxu Wan, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, kh...@linux-fr.org
>> > GPU temperature that is around 50C
>> >
>> > BIOS also reports 45~50C.
>> >
>> > BIOS hooks an SMI to CPU thermal report, and stores the
>temperature it
>> > read in ram, then ACPI code reads it, reports and passes to the EC
>> > (embedded controller).
>> >
>> > If I write myself 85 to embedded controller, systems shuts down.
>> > (values less that 85, eg 84 don't shut system).
>>
>>
>> Another clue is that right after resume from ram, after long delay
>> (~hour) the displayed temperature with TjMax 85 is 33C. Since room
>> temperature here is around 27C, this seems more plausible that
>> 33 + 15 = 48C
>
>
>Any update?

I'm occupied by other things, sorry for slow response. But, as said in a
spec, I can't remember which one now, there are too many, the relative
value read from DTS is accurate approaching to TjMax. The accuracy
deteriorates to +-10C at 50C. Any DTS reading below 50C should be
considered to indicate only a temperature below 50C and not a specific
temperature.

So, the value around 50C can't be taken as real chip temperature. I
would like this issue could be confirmed by more users to avoid it as a
particular case. At the meantime, I still looking for a laptop with T5450,
this may take some time.

Thanks
Huaxu --

Maxim Levitsky

unread,
Jul 26, 2010, 4:16:39 AM7/26/10
to Wan, Huaxu, Huaxu Wan, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, kh...@linux-fr.org

Any update?

Best regards,
Maxim Levitsky

--

Huaxu Wan

unread,
Aug 29, 2010, 9:40:17 PM8/29/10
to Maxim Levitsky, Fenghua Yu, Wan, Huaxu, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, kh...@linux-fr.org
CC Fenghua.

Could you found a Laptop with T5450 at hand? I can't found anywhere.

-Huaxu

Fenghua Yu

unread,
Aug 31, 2010, 5:10:54 PM8/31/10
to Huaxu Wan, Maxim Levitsky, Yu, Fenghua, Wan, Huaxu, linux-...@vger.kernel.org, lm-se...@lm-sensors.org, kh...@linux-fr.org

Hi, Maxim,

Could you send out thermal zone info under /proc/acpi/thermal_zone/TZ*?

Thanks.

-Fenghua

0 new messages