- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello experts,
I want to monitor DTS measurements for Atom D510 on QNX. Thanks to MSangalli, he gave me an example codes (lists as following) using MSR which I think it is for CORE series CPU. So there are some more technical details need to be comfirmed here.
1. what are the parameters for D510, 100C Tjunction_max? 0x19C for x86_msr_read() call?
2. how to get values for each core?
3. the sample codes can run OK. But the result prints that 100-th=100-84=16C, much different from BIOS monitoring result 58~64C. how to modify the codes for D510?
Any suggestions are greatly appreciated!!
Allen Chen
- Tags:
- Intel Atom®
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The example codes list here.
/*
* msrsup.c
*
* Created on: 25/lug/2013
* Author: MSangalli
*
* NOTES ABOUT CPU TEMPERATURES:
* Intel defines a certain Tjunction temperature for the processor.
* This value is usually in the range between 85癈 and 105癈.
* In the later generation of processors, starting with Nehalem, the exact
* Tjunction Max value is available for software to read in an MSR.
* A different MSR contains the temperature data.
* The data is represented as a Delta in 癈 between current temperature and Tjunction.
* So the actual temperature is calculated like this 'Core Temp = Tjunction - Delta'
* The size of the data field is 7 bits.
* This means a Delta of 0 - 127癈 can be reported in theory.
* In fact the reported temperature can rarely go below 0癈 and in some cases
* (Core 2 - 45nm series) temperatures below 30?or even 40癈 are not reported.
*
* AMD processors report the temperature via a special register in the CPU's northbridge.
* Core Temp reads the value from the register and uses a formula provided by AMD
* to calculate the current temperature.
* The formula for the Athlon 64 series, early Opterons and Semprons (K8 architecture) is:
* 'Core Temp = Value - 49'.
* For the newer generation of AMD processors like Phenom, Phenom II, newer Athlons,
* Semprons and Opterons (K10 architecture and up), and their derivatives, there is a
* different formula:
* 'CPU Temp* = Value / 8'.
* CPU Temp is because the Phenom\Opteron (K10) have only one sensor per package,
* meaning there is only one reading per processor.
*
* VIA processors are capable of reporting the temperature of each core.
* The thermal sensor provides an absolute temperature value in Celsius, there is
* no need for any conversion or manipulation.
* The Tjunction or TjMax temperature on VIA chips is usually between 70 and 90C.
* 90C for the mobile and low power versions and 70C is for the desktop variants.
*/
# include
# include
# include
# include
# include
# include
# include
# include
# include
/*
* LOw WORD temperature into
*/
typedef struct x86_term_info
{
uint32_t th_sts: 1;
uint32_t th_sts_log: 1;
uint32_t prochot_forcepr: 1;
uint32_t prochot_forcepr_log: 1;
uint32_t out_of_spec_sts: 1;
uint32_t out_of_spec_sts_log: 1;
uint32_t th_threshold_status1: 1;
uint32_t th_threshold_status1_log: 1;
uint32_t th_threshold_status2: 1;
uint32_t th_threshold_status2_log: 1;
uint32_t reserved0: 6;
uint32_t dig_readout: 7;
uint32_t rsv1: 4;
uint32_t res_in_degrees_celsius: 4;
uint32_t rd_valid: 1;
uint32_t rsv2;
}X86_TERM_T;
typedef struct msr{
struct sigevent IntrEvent;
intrspin_t sLock;
int IntrId; // Int id
int msrOp; // Operation to do
volatile uint32_t reg_sel; // msr Register index
volatile uint64_t val64; // value to read/write
}MSR_T;
static MSR_T lv_msr;
static
const struct sigevent* msr_irq(void* area, int size)
{
/*
* rdmsr/wrmsr are privileged instruction that can be executed
* only in the kernel space, so use the interrupt to do the work.
*/
InterruptLock(&lv_msr.sLock );
{
switch(lv_msr.msrOp)
{
default:{;}break;
case 1:{
// Read MSR register
if ( lv_msr.reg_sel )
{
lv_msr.val64 = rdmsr( lv_msr.reg_sel );
lv_msr.reg_sel = 0;
}
}break;
case 2:{
// Write MSR register
if ( lv_msr.reg_sel )
{
wrmsr( lv_msr.reg_sel, lv_msr.val64 );
}
}break;
}
lv_msr.msrOp =0; //NOP
lv_msr.reg_sel=0;
}InterruptUnlock( &lv_msr.sLock );
return(&lv_msr.IntrEvent);
}
uint64_t x86_msr_read( uint32_t idx )
{
uint64_t res;
if(0 >= lv_msr.IntrId) return(-1);
// Set command
InterruptMask( 0, lv_msr.IntrId );
{
InterruptLock( &lv_msr.sLock );
{
lv_msr.reg_sel= idx;
lv_msr.msrOp =1;
}InterruptUnlock( &lv_msr.sLock );
}InterruptUnmask( 0, lv_msr.IntrId );
// Eventually, use a TimerTimeot here...
/*********************************************/
InterruptWait( 0, NULL );
/*********************************************/
// Read result
InterruptMask( 0, lv_msr.IntrId );
{
InterruptLock( &lv_msr.s...
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page