Project Home
Project Home
Trackers
Trackers
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - Read CPU Temperature: (3 Items)
   
Read CPU Temperature  
Hello,

I would like to read the temperature of the CPU Core (same as shown in the BIOS). I'am using a Digital Logic MSM800XEL 
(AMD Geode) PC/104 Board. Is the Temperature stored in a MSR? How can I access MSRs in QNX?

Thanx in advance,

Andi
Re: Read CPU Temperature  
Dunno if its going to work on Geode but on desktop intel i use this.

You can do RDMSR only in interrupt handler, so just register the -1 timer interrupt and read the "ThermStatus" MSR now 
and then.

You are interested in the "digital_readout" which SHOULD be core temperature in degree celsius.
Hope this helps..


#include <stdlib.h>
#include <sys/types.h>
#include <sys/kernel.h>
#include <sys/psinfo.h>
#include <sys/proxy.h>
#include <sys/irqinfo.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <stdio.h>
#include <errno.h> 

typedef unsigned uint32_t;

typedef struct UINT64_T
{
	uint32_t lo;
	uint32_t hi;
} uint64_t;
 
typedef struct THERM_STATUS_T
{
	union
	{
		struct
		{
			uint32_t thermal_status: 1;
			uint32_t thermal_status_log: 1;
			uint32_t prochot_forcepr: 1;
			uint32_t prochot_forcepr_log: 1;
			uint32_t out_of_spec_status: 1;
			uint32_t out_of_spec_status_log: 1;
			uint32_t thermal_threshold_status1: 1;
			uint32_t thermal_threshold_status1_log: 1;
			uint32_t thermal_threshold_status2: 1;
			uint32_t thermal_threshold_status2_log: 1;
			uint32_t reserved0: 6;
			uint32_t digital_readout: 7;
			uint32_t reserved1: 4;
			uint32_t resolution_in_degrees_celsius: 4;
			uint32_t reading_valid: 1;
			
			uint32_t reserved2;
		};
		
		struct
		{
			uint32_t lo;
			uint32_t hi;
		};
	};
} therm_status_t; 

/* operation: EDX:EAX <- MSR[ECX] (ECX = t; out->lo = EAX, out->hi = EDX) */
void RDMSR (uint32_t t, uint64_t *out);

#pragma aux RDMSR = \
	".586 " \
	"rdmsr " \
	"mov [ebx],eax " \
	"mov [ebx+4],edx " \
	parm [ecx] [ebx] \
	modify exact [eax edx];

volatile pid_t timer_intr_proxy;
volatile int timer_intr_counter = 0;
volatile therm_status_t therm_status;

#pragma off(check_stack)
pid_t far intr_handler ()
{
	if (++timer_intr_counter == 20)
	{
		timer_intr_counter = 0;
		// 0x19c is ThermStatus register
		RDMSR(0x19c, (uint64_t *)&therm_status);
		return timer_intr_proxy;
	}
	
	return 0;
}
#pragma on(check_stack) 

int main (int argc, char *argv [])
{
	int timer_intr_id, rpid;
	pid_t program_pid; 
	const char *program;
	therm_status_t therm_status0, therm_status1;

	program = (const char *)basename(argv[0]);
	program_pid = getpid();

 	if ((timer_intr_proxy = qnx_proxy_attach(0, NULL, 0, -1)) == -1)
	{
		// error
		return 1;
	}
	
	if (timer_intr_id = qnx_hint_attach(-1, &intr_handler, FP_SEG(&timer_intr_proxy)) == -1)
	{
		// error
		return 1;
	}
	
	for (;;)
	{
		rpid = Receive(0, NULL, 0);
		
		if (rpid == timer_intr_proxy)
		{
			// double read
			therm_status0.lo = therm_status.lo;
			therm_status0.hi = therm_status.hi;
			therm_status1.lo = therm_status.lo;
			therm_status1.hi = therm_status.hi;
			
			// check double read
			if ((therm_status0.lo == therm_status1.lo) && (therm_status0.hi == therm_status1.hi))
			{
				printf("%05d: %s: %s: %s=%d\n", program_pid, program, "therm_status", "thermal_status", therm_status0.
thermal_status);
				printf("%05d: %s: %s: %s=%d\n", program_pid, program, "therm_status", "thermal_status_log", therm_status0.
thermal_status_log);
				printf("%05d: %s: %s: %s=%d\n", program_pid, program, "therm_status", "prochot_forcepr", therm_status0.
prochot_forcepr);
				printf("%05d: %s: %s: %s=%d\n", program_pid, program, "therm_status", "prochot_forcepr_log", therm_status0.
prochot_forcepr_log);
				printf("%05d: %s: %s: %s=%d\n", program_pid, program, "therm_status", "out_of_spec_status", therm_status0.
out_of_spec_status);
				printf("%05d: %s: %s: %s=%d\n", program_pid, program, "therm_status", "out_of_spec_status_log", therm_status0.
out_of_spec_status_log);
				printf("%05d: %s: %s: %s=%d\n", program_pid, program, "therm_status", "thermal_threshold_status1", therm_status0.
thermal_threshold_status1);
				printf("%05d: %s: %s: %s=%d\n",...
View Full Message
Re: Read CPU Temperature  
I am sorry, i just realized i wrote something silly there.
Here's correction.

The "digital_readout" is the difference between Thermal Control Circuit (TCC) activation temperature and current core 
temperature.
The unit is degree celsius.
The value is valid if the "reading_valid" bit is set.