找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 34111|回复: 14

菜鸟的求助啊!关于winio 得到cpu温度

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>! M) \# v+ |! ?* [5 M( [
#include <Windows.h>; m5 B+ C3 A& @* ^" O2 v5 G4 b, `
#include "WinIo.h"3 H% s: O8 a( p, i, a
using namespace std;) c( I4 V; i( H. \4 j1 g
+ u* J7 {# X& w0 [
#pragma comment(lib, "winio.lib")- J& ]& A1 D9 Q  W  }" l6 w1 `
3 l) a+ Q; i: s- G
: ?. r  F0 w1 W. A2 |) _% D6 I
int PMU_SC                =        0x6C;//命令端口
( }5 i% n, \; N- S( {- f6 iint PMU_DATA                =        0x68;//数据端口- }) K6 L3 d0 ~
int RD_EC_SMI                =        0x80;//读寄存器命令
! g9 {8 |, d2 \& T/ x% A; J) J  z' \int POLLING_DATA                =        0xE7;//CPU温度寄存器号* A4 n: z1 i/ |  d: W
& N/ F% U6 b8 A9 C
DWORD dwTemp = 0;
" S+ Z2 t; C2 H' o2 F+ ]* h9 W4 w' u+ p; D( q2 l
void PMU_Wait4IBE(DWORD *_value);
2 P, C% q; Y- T! d* C' svoid PMU_Wait4OBF(DWORD *_value);
* h3 K3 j9 @7 ^% n
# W( L8 d9 Q6 v" K- J% ?* O# V+ f; _5 ?  A
int main(int argc, char* argv[])
: k  ?% u; Q2 ?{: W4 D6 ]$ d( C5 |& v7 o
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
) U9 F/ S; T+ ~- |/ \' H& J0 D8 U0 q1 ?% d6 b% z/ H5 `* o
        # F  ^3 Q% N; |5 v5 `+ F6 \8 B+ s" m
        //1、mov            dx,PMU_SC                //  V! Y( q1 S* E
        //2、mov            al,RD_EC_SMI        //
6 d7 O5 v+ W. M: m6 j        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
9 e' v  O3 t' g        //4、out            dx,al                        //将读寄存器命令放到命令端口中。3 k' x- V' w! V5 L0 U7 I

/ s! ^. \5 ^/ u2 n5 _. n        PMU_Wait4IBE(&dwTemp);( G" I8 R5 t, q5 X" O* N  j, }- m* M( w
        $ U* l4 t- C+ C0 D) A
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
; v  b6 ?* t' u# b: L+ I( P
2 I1 c7 t8 q  |" V        PMU_Wait4IBE(&dwTemp);
, i1 G9 R$ [/ O9 ?6 F4 l       
" c4 D2 a5 @1 m" |$ H: a- I% ~        SetPortVal(PMU_DATA, POLLING_DATA, 1);4 ^! N$ L9 s3 [5 A
  j& Z$ ]: l5 b, V# V3 I
        PMU_Wait4IBE(&dwTemp);
3 o3 [/ D( k  V
5 {+ p) X! s" y; C" m9 ~        cout << dwTemp << endl;               
% o& B$ |% ?# d# N0 {" p
  I. U9 n+ H) Y' @        ShutdownWinIo();9 B* i- F! h% {# k3 b
4 Q5 t! p; A& z" ^
        system("pause");
* M+ [5 K$ T) Z" u# \5 g: [* F+ I9 G; u9 T' S* |
        return 0;
! D3 r5 ~: _- E}
: \/ M4 {! D4 M+ s; ^1 V
/ w* ?1 Z# K: D4 Svoid PMU_Wait4IBE(DWORD *_value)
/ ^6 R1 Y- ?9 W6 n8 f' r{$ ?. O( {' \' Y, e+ w* o
        //#########################################################   
( v* R; w$ R! w" w        /*! b* Q$ f1 ]+ {3 s/ g
        pmuWait4IBE proc   ' y) A# b. w) N0 D1 r
        PUSH        AX   / X' N& _5 y% D' u* K- D  F, j
        PW4IBE:               5 b9 I& }, R- C' |6 f+ s
        IN          AL,  06CH                                //Read  PMU  status   
5 v/ Q1 I( P6 U+ S9 C7 u. W        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   4 E1 }) m, V) n6 N$ B$ d1 I
        JNZ         PW4IBE                                        //Jmp  if  no   
* Q8 B) n; J- S0 c% U8 g        POP         AX   
$ Q; I" p: w! r        ret   # ?7 I4 z7 f5 T, n3 {
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE  P" A, w( c/ [! S, i
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空8 q9 e# [! ~8 Z* q" f( H
        //#########################################################
6 [. s  s, v5 |' Q        /*do
5 ]9 s* z. r. z        {
0 z4 m% u* N$ @                GetPortVal(PMU_SC, _value, 4);
0 B0 E  m4 {" V( i+ E        }3 U/ g8 i$ {# j: Z: `
        while ( *(_value) & 0x00000001 );*/$ p7 N. U+ ]! P& ?
        DWORD   dwRegVal=0;. i# T" M! P! J
        do
2 G; y% k: X' @1 P6 E" b1 O  h        {  
( r$ L; U( w: u( D, H$ `/ V6 c/ Z; }6 n7 L7 \                GetPortVal(PMU_SC,&dwRegVal,1);
6 o8 {' j2 s  v' j+ z3 L        }  `9 g8 d) z5 c# t* g
        while(dwRegVal!=0x2);6 G2 n) Z4 f2 u

3 ^: y9 k) t) |% B}. v$ i* u# V6 ]& I% }) o% y! j9 _8 _
8 w7 N# I: I2 y  A4 B. G. r2 I0 K
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
/ p" ?) T0 W% d) ~# h所以变成了死循环了。6 c% t# S" w2 z7 n1 y) V

4 o; N& d3 Y6 Z# {* a' O我对硬件编程不懂。又不知道从何下手。
9 D7 Y# I9 M. M+ R/ Y# f1 Q' S我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。/ g# o7 V, M& ~
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。- P. z- t( h# g+ h8 D5 Z; T, f7 w  g

9 h- X1 s# G% B我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。; x2 J( f# W+ x1 a+ f; Y
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。, s4 v  C3 ^6 `+ k

6 P1 F  K- y9 {+ x' Q感觉现在无从下手。我在网上google不到pmu的信息。比如说我想搞清楚0x6c到底是pmu的什么东西。我想这该有张表什么的吧?硬是没得。郎个办嘛?有哪位大侠给我指条明路吧!:
发表于 2010-2-6 12:02:36 | 显示全部楼层
这东西,底层实现是千差万别的。你如果没有主板的电路图的话,怎么知道温度这些东西是那种方式设计的? 一般的程序都是通过Windows的API读的
回复

使用道具 举报

发表于 2010-2-6 14:58:08 | 显示全部楼层
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。8 s# L; i0 {7 \! T2 @" R7 O
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.8 p' a  }+ A6 }0 x7 k* |
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突0 w( p5 `% d: X5 ~: q5 p  s1 r
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.& C( |' m; _0 q( x/ m
6 P" X, Z5 R! g; E& c& Y
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
$ q$ g% ]: L8 P( i! ]# h5 K
# I0 b- n! x$ R6 [. w( j那么有些什么可行的办法呢?
3 {0 w" S' U' Z# W0 t/ p为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。. `$ s& S( [$ O  ^

: `( e5 |4 ^7 s7 `& E; k% D6 s它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
0 ]) P% \& l/ s" Z* |& l& ?
* r1 k) H3 y& P那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
4 z9 H' v5 J0 r) O. }% F* }( l! C( V# A* r1 T% j
http://www.ufoit.com/bbs/viewthread.php?tid=452
; ~: y5 v1 ~# F- W: n# f. t8 P
1 P  L/ M$ \7 w: h( Qhttp://www.ufoit.com/bbs/viewthread.php?tid=2416 \0 w5 N) q% x6 U
: a8 |! T9 F, ], N3 ?  s
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。, R: i0 w. \. S% a2 C
) }. w! ]$ \) M, r5 {
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
) ~. A/ I9 G: l# L" \+ [8 B9 }9 X9 d2、Driver最复杂,也需要BIOS配合,推荐。
1 A# n3 k: S0 `- C3、Windows API只能获取到特定信息,不需要特定的BIOS配合。, \: x' _6 m4 g" {' N* f
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
! W. K  q3 F. `1 I你可以混合使用。& G) q% i7 `. d+ C4 p# i# q) w

* c: {. m: }5 W1 P===============================================================* L3 d- s+ m' {* `& G) k5 e
管理员的这句话:3 t6 ?& I1 S/ ~6 R, j; K1 g" O7 i. J
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?, r9 x9 h1 l4 B- K: _3 T
8 N6 C5 m' [& c9 k0 [3 p
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
' W- E: }0 M/ p' s$ }
6 a2 B3 w7 `+ h另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269% y$ o9 p% g% @+ z, u
; e- K. m! x' P- m% ]0 d3 [8 P1 v
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
; W7 S2 `$ J) q, q$ K8 b; k8 ?: g; J: g9 i2 r% W. `7 R
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
$ }, I+ n9 i- [里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
" t# _' I0 ?+ T7 c: P  G
0 x, n! x6 b/ C/ M6 \我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
1 g# b) I) h' k+ B. H你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
6 V; `* e+ l7 w8 H& P% C$ Y) K& U1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

7 d" f/ @" s1 l% X
/ ]- b8 s. `8 u0 w( u2 w$ O1 {您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

发表于 2010-2-8 09:25:24 | 显示全部楼层
找个APIC spec看看就知道了
回复

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。" i# N2 p& p0 g/ I+ C3 m

& {1 y4 M  e+ U# A# {( avoid write66(unsigned char Data)
1 {" b: b! t$ m) N{
6 S0 l+ U! e8 S        DWORD Status,TimeOut=10000000;# ^5 Z$ o8 H" v, G
        do
& G/ N6 R4 P- e- C" ~        {
5 K* {6 r7 W5 S                GetPortVal(0x66,&Status,1);
7 D) Y( X# Z: b4 Y, ?                TimeOut --;) r9 ]# |% n7 a' @6 [0 Y
//                Sleep(1);3 M, k; o  Q* Y  E
        }while((Status & 2) ==2 && TimeOut>0);. v4 _% w' {; P8 _* m" L

* f6 h3 u+ M$ O6 N: X. ?        SetPortVal(0x66,(DWORD)Data,1);
- B6 B1 g* o5 d" ]}
! k% u/ A8 g. P; S4 Gvoid write62(unsigned char Data)
* l8 v% t$ }$ |: c0 [& ^9 ]0 J{
, W0 E  V! ]0 p" _! W. [        DWORD Status,TimeOut=10000000;- C3 @5 N, d/ z9 t
        do
. s1 V5 n+ s) W' I- ]& |        {
, W& q5 ]  f6 _7 ]4 R: P                GetPortVal(0x66,&Status,1);
* D' H6 ^$ @2 s8 t                TimeOut --;0 k. P# R! D3 k+ N* f9 ], s! C
//                Sleep(1);1 R7 ?% V) d4 x2 a0 ~9 T
        }while((Status & 2) ==2 && TimeOut>0);
1 ^8 r8 v+ y0 A( \/ }: C9 c% e; k! s! v! ?. m; S
        SetPortVal(0x62,(DWORD)Data,1);
% z  _3 \( e" T- L3 \}, @9 \: j9 r1 G, r- U# r
unsigned char read62()
3 Z  A& G+ T, ]{* v$ \# d; |% g& b
        DWORD Status,Data,TimeOut=10000000;
8 @, R: p# @3 A8 i; R- o* N        do/ d/ A+ O. U2 {' M  `. D" A! D- s  i
        {
/ a, ]* I3 C: A: i3 Q                GetPortVal(0x66,&Status,1);* X) M4 [4 I- O! O2 U) s' a
                TimeOut --;4 y' t& Y  v; k9 r
//                Sleep(1);
6 ~7 C% ^- X& N- A6 T! b        }while((Status & 1) ==0 && TimeOut>0);9 z1 f8 z7 y  B* V  I; K

7 @0 t& r8 }3 |8 V( L0 h2 Y$ g, o3 [. I
        GetPortVal(0x62,&Data,1);/ \: ~, W7 ^7 V% t; }! T
        return (unsigned char)Data;% y) C2 X  G: A/ u+ i
}: T% g+ {1 U  b6 _3 }
unsigned char read_ec(unsigned char index)
9 l' m6 E9 P" l" B. L{
2 F3 n) G- e# _/ z        write66(0x80);
- W% z0 b% _- X. O        write62(index);
: r! h. w* K# |1 U9 A' k4 F& I7 R        return read62();5 B, x) K" N+ V$ x/ x
}3 h3 y1 e7 W! B
% I# O- m2 Z8 Q5 R
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1155) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
9 Y% I" P$ J* c/ u" U  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
+ [; q9 s8 o3 P" e
5 L0 f; b9 z2 g[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 9 D, X* N: \2 I

; z* H& O  V2 S- \( \# ]" }
' h5 N  i& O! h- p6 r您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
' C2 e+ Y5 [7 ?% w' z
% U8 s8 }$ n( G/ j2 _/ ~8 K
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
" E6 ?" z& I) \% b# O+ I0 M/ p# x/ m7 A+ W+ @4 Y4 J# R! m
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
# r/ q7 Y$ \$ d/ P/ t+ R% F
, d; X4 z! X2 x' [: O2 j: ~3. Then set bit16 of the IRQ to disable it.9 z& s! B  A# F( J3 x+ D( R

+ d7 l$ \! z7 T9 A7 J    a.. Offset = IRQ# * 2 + 0x10;/ q/ u# {0 l: w; X8 p

, e0 n+ W! Q+ I' g: F& p  s% t    b. Write Offset to APIC base,# C" P5 w9 |) l9 r
1 B2 k. Q- k: J: q  E# `
    c. Read Data from APIC base + 0x10;
4 M& Q2 ~; y) ~! P: P! o* V
6 S+ S0 y* V/ L6 T0 q    d. Or bit16 to Data;
* |/ R6 U3 k0 o0 S  i) U2 n
9 p0 g6 l  m7 P. i" ]4 i    e. Write Data back to APIC base + 0x10;# W/ [, e: ]. A. m, E4 S& T

' w% ]: ]( m* H" B9 ^! ]( u ( Q; u; Y- E+ t: l& V  B, y
; K$ M5 s4 B0 r. q1 \% K- s
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
7 h" G' |" P9 Y' e545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
9 C* P9 I* F7 ~# h3 j

8 o5 F" J5 K2 k* z 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
+ ^3 q/ N6 J0 G5 r6 W==============================================% h0 {8 l. {, g- M& B! v- Y! F+ X
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
3 p' W  v2 H/ M7 o* v" b$ m6 d' \1 F
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)+ f- x0 _0 E) ]( M2 B
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。3 A3 V! w7 ], i
  ]) b$ v, @, E3 g1 r
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。/ o0 ^, w! T4 g
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
3 e- u( V, ]* B$ X1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
5 r9 q* b, `8 c+ L! G/ Q2、新手不要把EC Space和EC Ram space搞混了。在DOS下,ACPI中定义的EC Space是由OS发8x command给EC去访问的,这个访问到的地方,或许是EC Ram space一样,也许是另一块地方,也许是EC ram space中的某一块地方,这个要看EC自己的做法,平常我们所说的EC Space基本上就是ACPI中定议的EC Space.
回复

使用道具 举报

发表于 2010-5-14 20:38:27 | 显示全部楼层
讲得很好,哈哈,学习了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2025-6-17 17:32 , Processed in 0.053645 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表