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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
( [5 Q6 C8 Q! B#include <Windows.h>
6 ^. _  R3 ^- j, K#include "WinIo.h"
( J3 ]+ @) Y0 gusing namespace std;
7 Y* y* `  ^5 F( n! G2 S
- z) H% I' B. @" q#pragma comment(lib, "winio.lib")
0 S7 F, b6 ]$ g9 H
7 H, z  f" n- {9 `3 f$ K  Y1 w$ |. U3 m/ U3 e
int PMU_SC                =        0x6C;//命令端口
! ~# u& ]" k8 K$ H1 C3 d* kint PMU_DATA                =        0x68;//数据端口
. |" M8 R% m$ N- J% b! a4 @int RD_EC_SMI                =        0x80;//读寄存器命令
2 ~, p; }; X+ g  n% |. rint POLLING_DATA                =        0xE7;//CPU温度寄存器号
9 z6 Z; `3 O: ]: [; V" A: p! P8 V. Y. m1 r5 N
DWORD dwTemp = 0;  b( N: ~  F- d" y6 Y" h/ z  z+ S

% D1 |0 N2 Z1 w! Evoid PMU_Wait4IBE(DWORD *_value);. y/ E. `$ ~- F, V! E: m. ^) ~; C8 M
void PMU_Wait4OBF(DWORD *_value);
# w) C  t: r2 L, T* m4 h& z! v, r& R' F7 d; w7 ]( [

$ O6 i; m. f6 d8 tint main(int argc, char* argv[])$ S3 T/ V4 ?( k$ d* p. Y
{
  ~) U0 V# h( I4 z; N        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;8 q$ E' R( x( x" f5 b7 D& j
) Q& C% }3 u' ~4 N7 N& K
        2 b+ T9 b" r( b( L1 p& i' ]
        //1、mov            dx,PMU_SC                //
0 R: d# [! I& x. r  C. _/ n        //2、mov            al,RD_EC_SMI        //
! S& V; o: p) X- j( k! v+ i* F        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了/ P* ?+ [  P" m4 L
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。6 i4 l! A& N  t1 U) d- v% i

* s8 a  _* D% ?+ _. |* u5 f, ?        PMU_Wait4IBE(&dwTemp);
% [5 X! Q' O6 @& R0 W        * [! y2 {  D! q
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
. v! c6 O7 @' U+ X# `$ B! O2 [# I0 w9 w) M' H
        PMU_Wait4IBE(&dwTemp);
) M3 V! H; `) W/ H2 b# x1 C3 K5 v        + T; W  U# n; X  Y2 d. w2 J5 u1 @
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
& b/ b- E8 X9 s
/ X1 x5 T- w) l6 B        PMU_Wait4IBE(&dwTemp);) i) s9 B& `% Q+ f" h
9 P3 @5 n2 v, }: N
        cout << dwTemp << endl;                3 Y" d' R1 Z1 q

0 P2 }1 p1 ^1 e8 t  x        ShutdownWinIo();
% x  Y0 u! j0 N! Y# k* j% J7 k6 `$ @8 m- Z
        system("pause");, ]" D- D, x5 [1 ^7 n
, J* w# T) `9 w# G
        return 0;
% r$ p' C1 d- V- |" T}
: p0 o$ J3 z$ P+ `2 X' [+ I+ {
% ]( W" h% a" j0 @& R' L9 M- Nvoid PMU_Wait4IBE(DWORD *_value)# x/ A/ Q: |( J* K+ N: g; O$ _
{
# Q7 K2 j* T/ T5 q$ n        //#########################################################   7 O$ ?2 N  H- X3 O$ `
        /*0 Q& V5 S# Z$ u# K; Z1 N9 a4 ]0 C
        pmuWait4IBE proc   
, n+ o) {/ E+ G  k# s4 D& V# p        PUSH        AX   % e  A4 s% o9 M  m& U
        PW4IBE:               
0 p6 n7 b4 s. W# e5 z        IN          AL,  06CH                                //Read  PMU  status   
+ J/ }; p% y9 i8 P2 A! `" N$ X  r        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   ' g: d8 _9 |2 r& q* j
        JNZ         PW4IBE                                        //Jmp  if  no   ( q# G  z1 i9 n/ t0 ?8 `
        POP         AX   , l+ U- M8 V0 `. N6 a% @7 Q
        ret   
1 \# F, J: B8 z8 |2 N        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
& m9 q3 p5 }; W: ^- M5 c        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
/ z0 w+ l8 W. E* R/ t        //######################################################### ( J. m% I# z9 `& w( E
        /*do
: d3 R6 o$ w  K3 H        {; s! q" R- Q  B& f4 B; P
                GetPortVal(PMU_SC, _value, 4);! z; Z. c( A: h3 n$ m3 V4 A+ S+ m
        }1 D5 z9 M3 Y7 b
        while ( *(_value) & 0x00000001 );*/8 H, d  Z. v6 V% `# l+ }4 I
        DWORD   dwRegVal=0;
# M- o7 T! S, u4 G- x+ t# y3 v        do5 N" r! k4 j* f
        {  0 S- T' G/ @- @- @
                GetPortVal(PMU_SC,&dwRegVal,1);
4 Q/ D6 \5 \8 m% _' \' s0 C/ t, J; ]. M        }1 q% U6 ?+ W% _3 X
        while(dwRegVal!=0x2);. c3 O) T! \' h3 I5 G. Z
7 e, b0 b' k. g! |+ Q
}" u! }5 ]/ M5 e" \/ \

$ U( H7 s/ P7 |' F以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
; b" Z% |/ P8 i4 U) G. u, }所以变成了死循环了。
4 a2 E, a4 e3 _- G& E4 C+ V' N! ^! A7 K1 |  m7 D& {4 ~
我对硬件编程不懂。又不知道从何下手。2 T! a% ], l# c5 I# l+ l5 E
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
7 j/ S) ^/ X2 z但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。8 K1 R( U7 Q/ h5 ]. x
: U! U  z! V$ ?4 E9 L
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。4 e% e- H3 Y: }) X9 b" d
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。6 n. F" I2 v1 z5 C! o1 v  T

1 G6 |1 M3 T$ K1 j+ ^感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
& X( \1 C' j! h+ M  i( O' N1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.4 b6 K  j2 m5 m/ J' D$ t
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
& C1 j, Z* g5 t2 R* Y( O4 H3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
4 X2 F% p2 \- w6 x  Q/ a- w* [+ b
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。) a( `1 t) h2 n$ |3 q  S

; r2 d) l2 b6 Y( C7 V' Q4 Q/ E那么有些什么可行的办法呢?! a- p! H) i! v2 Y5 p5 z8 O1 H
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
# y9 T  Y' \( n0 W- e3 `6 j; w, I9 {5 T, h) o* T* _! |
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?9 N4 \/ ~# u' ]
, s) `0 B! w/ Y+ A9 r
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420# U: q5 @& h. g
# S* R" f$ o) X" v6 S. v) S
http://www.ufoit.com/bbs/viewthread.php?tid=452) \; V; B! F9 J" a& \$ t% k/ i0 h

. L7 h5 K9 g6 H8 D' d( Mhttp://www.ufoit.com/bbs/viewthread.php?tid=241. ]: L6 t/ y" n4 g* A7 Z
4 k$ G7 H  q# S! a- K7 n
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
3 k! G, F& G6 Y( B7 f2 u, w8 Y( y3 z- Q9 O1 q3 @* L. W  {
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。) J) w% @# D0 i' P
2、Driver最复杂,也需要BIOS配合,推荐。
/ E  f9 l" H, b5 I( G2 p0 W/ M# N, @3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
4 t0 u- O' Y6 G' H4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
) {- G! v, l* a8 j# d你可以混合使用。4 ^% V( ~+ Q% D" k2 h5 a$ p

  o( k4 _. H) r5 a# W& _===============================================================
% F! G2 N- O* z: G8 g2 y: |管理员的这句话:
: H4 ]6 K8 ]% C9 |) q如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
! x) j8 B; {4 q6 ~9 N$ o4 f ) e/ z# v( q& G% A$ U9 B/ u* `8 D
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
0 T2 O7 ?" ^& D- J6 s! p0 U# X
' b- Y! n" I0 Q4 [' j' X另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269* j7 d% b! d1 @5 b. Z
2 N1 t1 m* C% |. U
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
9 c3 J) b& r2 o: W
! r; G: Z2 C' O9 J; R, A, k还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。1 \/ E0 l: ~) Z' p. u
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?& e- E/ f' |& g0 y
! v* t  o3 S  w7 Q
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 1 S, @6 l0 n  K$ [6 j* C0 R4 F$ Z
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。7 {- p. Q! h' O$ p2 t& b! o+ w
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
! i1 x1 }+ T  Z' V& Y
9 T# O9 S) N1 Q
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。1 `5 U$ S6 T( ?: U+ ~2 c

  \. |8 Q& P9 x1 J1 O/ _void write66(unsigned char Data)9 U% ?$ p3 u& Y' C! m2 C% d; H
{
" v; e/ v2 I. ]6 b( h( s$ h        DWORD Status,TimeOut=10000000;
& R* L' M; S# h3 l, v6 H        do
$ U& w" r; f& W0 m        {. D' j* ~1 K% D: J
                GetPortVal(0x66,&Status,1);. Y1 E2 [  [8 B4 A* I3 n9 I
                TimeOut --;* f# ~# D( j1 c* g  {+ @
//                Sleep(1);
2 |6 o" C9 e4 y        }while((Status & 2) ==2 && TimeOut>0);$ y2 U; i- r  ~* w, z# v+ r
1 A2 R% B1 v5 M/ s4 S+ Q, @9 W% {
        SetPortVal(0x66,(DWORD)Data,1);
( F$ m# p2 C! m- c* c" l% G}" s( a8 }' e0 K* j& W1 w
void write62(unsigned char Data)
/ o) {& P  F2 A; S+ }, P4 M  @: `0 h{
) L; [; L* K2 w' _        DWORD Status,TimeOut=10000000;" e' n% p: h# ?: N2 n# o- x
        do, }, B9 B0 k9 ]3 Z& \3 W: e
        {
  F4 A5 U: O$ [8 o                GetPortVal(0x66,&Status,1);
; u* f, z. d6 E- L' k8 \) t                TimeOut --;
" h9 r: b" `: u$ d# s" @//                Sleep(1);8 E4 Y& {1 d$ s1 X
        }while((Status & 2) ==2 && TimeOut>0);
* N# }% l0 {' O; H. P3 ^. b3 `. y1 J5 Q
        SetPortVal(0x62,(DWORD)Data,1);
: h( q3 `: ^! E/ o0 Y, w  x( `5 W}
* g" h; n; E" R8 runsigned char read62()& Q6 c% t1 f; x
{
1 J& n& X4 h+ s/ n5 M2 R8 H2 C: ]        DWORD Status,Data,TimeOut=10000000;
; B% R; C2 j. _* T" k) Y3 C        do8 ^$ Z2 f! ~( w; p' h4 y8 Z  P( g
        {
+ o. f: ^' M; W1 _  q! z                GetPortVal(0x66,&Status,1);
% N: s. b8 K" m( Z                TimeOut --;4 f0 K2 P5 u/ }& V2 h: R
//                Sleep(1);0 z( ~+ w. V/ ]0 |  m
        }while((Status & 1) ==0 && TimeOut>0);( M' a+ Z0 f7 Z; I6 t
6 x6 E9 ~9 _) }: T
+ D% a7 Z  M, D, g' U1 F
        GetPortVal(0x62,&Data,1);
7 K0 w6 g- N1 E        return (unsigned char)Data;
1 C2 l* z& X3 F5 `& N8 q}% a0 n2 b9 _* J% i
unsigned char read_ec(unsigned char index)
* R" {; q% m: y. L# {# ~{
5 ]; W: U0 k7 S: q        write66(0x80);  Z4 x( T0 M7 g; p) R; {* X
        write62(index);
1 [- l, U" ~5 `$ Z  I+ f        return read62();9 V" Z  v6 r2 c
}! c* H6 O: V, l: w6 w& T

( R0 D' m% X3 K( S* U0 U[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
2 P3 S  P; j4 k' [2 i' K6 V- w5 Z! ?, e+ _. u$ ^+ ~$ s& V
2 H$ V" ~7 ~: j
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

/ n! L  t! p9 {+ g3 B* R* z% B2 R! O( B2 G7 _$ P$ V8 }
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,9 A9 k( {3 U, q& F6 r) k& |5 p
9 k( S& l7 k- }5 q
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.+ Y# c, j- G  E+ M- [* J9 Z

# u- K8 Z4 ]1 x9 o2 M  p3. Then set bit16 of the IRQ to disable it.' W4 P& o  R; W  b
% @3 Q! y, O2 N3 x
    a.. Offset = IRQ# * 2 + 0x10;
0 ^8 b' k% \( W
2 Z  c9 V( P6 {) ^* s5 m    b. Write Offset to APIC base,
5 x8 E/ t* f3 N, N3 X! j+ O* x3 k8 O& W4 \1 Z
    c. Read Data from APIC base + 0x10;
0 \: P0 ~& q1 H9 |; h
! i3 B" H$ s% g1 Z: e7 b    d. Or bit16 to Data;# A8 `0 V7 B) y
) F7 C; J7 }) g
    e. Write Data back to APIC base + 0x10;
" R6 `2 t+ j# }* r; ^- \6 u) }- P5 j7 q# m( Y0 ]

+ g0 ], y- F# V3 q& I2 e/ M/ d: [7 W; M% @1 i8 M
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
' x& F# p+ K' `) m/ M, g545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...

, ?  r3 K& O3 `: {% j& K& f( B1 H+ n' m+ j# m' ?
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
9 ]9 I) n& I9 m! I==============================================7 w2 _% S$ P" a* }% Y
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
1 z9 c3 g3 O; U3 _+ t$ I% ^" K3 N( h
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)% V1 K: O  H2 D* L4 u0 D( x: p
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。; Q, R. n( q  G. k7 C. X4 v

: q: R* q/ o- D因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
0 F: l! v8 W9 t* Z* C9 r当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:8 D' s# D. l! Y% |
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。! P3 r4 C7 l( T) Q% a$ b
2、新手不要把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, 2026-7-19 19:02 , Processed in 3.212852 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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