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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>' D( K$ B+ `, w2 M% i  i4 _5 [: S
#include <Windows.h>
3 j  @1 }& r- N7 _. P8 ?  q#include "WinIo.h"
9 c3 |1 t  Q, F4 h$ R7 U, h2 Y" `using namespace std;: \( f* W/ T- x9 |6 g

' s4 H1 k" ]: h" L3 X! w9 v#pragma comment(lib, "winio.lib")  I& ]5 a2 t# u! D) K" J; L

: s2 |5 i2 T# D  `3 X# x4 {. z7 l' H' s' D, l) f7 p/ L, m
int PMU_SC                =        0x6C;//命令端口# {2 o/ B" S) b" x6 f
int PMU_DATA                =        0x68;//数据端口
4 c+ x0 J* r3 t' Qint RD_EC_SMI                =        0x80;//读寄存器命令4 C& f& Z6 O, g* \
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
  ?" L/ d% d/ l8 R" N& z" M, L8 m7 a1 J+ [- K) ^
DWORD dwTemp = 0;. U0 r7 }9 p; T
+ s: [% u" X% p2 W% f: K
void PMU_Wait4IBE(DWORD *_value);' S/ k# L+ Z9 w& D
void PMU_Wait4OBF(DWORD *_value);
& B2 J1 @+ v! ~' b! p, p+ R0 R& Z! h2 t8 w4 q7 a
) {/ d) E) H2 Q) n5 w& h( s5 F: M3 d0 W
int main(int argc, char* argv[])4 A! t9 [, X% Q, {4 {4 `" S' b2 E
{
( O! m2 w& o. H, A2 k5 C* V        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;. U0 F- n& B! k/ t7 Z" `  z

5 O5 p, R) d( r% ]0 `       
' p8 l2 D% g& p! T2 N: P        //1、mov            dx,PMU_SC                //% p7 f0 y9 l8 O  ~+ ~& v- S
        //2、mov            al,RD_EC_SMI        //
% b  R% e7 ?+ e6 J/ u% z( u: S) E# p        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了* F# ?' s3 s, V, r0 k$ O( [1 [
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
* f3 a3 Q, Y# L9 J0 d7 _7 I! p3 b8 i# y
1 w8 x- F1 @- \        PMU_Wait4IBE(&dwTemp);
1 @# n& `$ {& p       
% ?% L: d( n% d( k1 z( m: R        SetPortVal(PMU_SC, RD_EC_SMI, 1);7 E8 c7 ^% k) }& q6 S$ D3 i

: K) Q. q' ~! I& U$ L        PMU_Wait4IBE(&dwTemp);7 P! U. q6 d6 J% V! J( U
        , h9 @2 S+ K  C7 H4 z
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
% `3 F1 W% B6 s  B
2 \% Y% g% [) {: I/ [        PMU_Wait4IBE(&dwTemp);* Y) ~$ K. K5 \* Y+ L; U( I0 u
+ A: ~- z) v* k" k4 X
        cout << dwTemp << endl;               
) }& o, W  O: l* Q. ?" e
: {/ w6 G  B# s7 A; j        ShutdownWinIo();8 T' j- E& N$ Y* B1 |' ^* J, ]

" r6 M4 _( A" B$ O7 P/ V. W( p        system("pause");
( h+ M3 J1 O4 Y5 d  Q+ }7 e8 K/ [$ s$ E7 f* U
        return 0;3 h; Q$ x+ B  h- X* k
}
2 j, P6 L) G3 x" Q% O" _
" e" i9 E1 G" c% \. j7 `1 Jvoid PMU_Wait4IBE(DWORD *_value)! s  ?' a; V+ x0 u; P2 m: K
{% L( O% p. O+ B. q$ w* j: i
        //#########################################################   9 d$ |' t" j5 {. _# C
        /*
& B: ?" u) \9 d' d& {/ W$ q        pmuWait4IBE proc   & z( l. F9 q9 M/ ?) n. e
        PUSH        AX   8 a0 g0 k' \9 t  e: m; v. _
        PW4IBE:               / J4 Y) V7 P3 ]8 R# A) A. c
        IN          AL,  06CH                                //Read  PMU  status   4 ?6 e. W( r9 Q
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
7 p2 W2 k' N, F7 B; s* f: ]        JNZ         PW4IBE                                        //Jmp  if  no   
/ D( O3 K# h, [        POP         AX   
. L+ x" ]; q) Q7 B        ret   % k# [- U: q& \3 l
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
4 f, F5 I6 F3 l, e& b        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空% ~/ O$ @4 i' J, b, _! C
        //######################################################### ! b: g4 j0 j( H. O4 ~& ?) B
        /*do
# b- H4 T% Q4 I# {% {* p4 N) }& p        {: h) |8 c' l& x" M4 Q/ b
                GetPortVal(PMU_SC, _value, 4);0 n; s. t9 Y7 T& ]* D
        }
5 \% P9 h$ ]2 X0 p$ S3 b5 b        while ( *(_value) & 0x00000001 );*/
0 e( d* K. x1 \8 W8 G" P1 z        DWORD   dwRegVal=0;$ w! t. B; `) J* y1 Z9 i2 P
        do4 A1 A$ F! q' }  P7 I
        {  
$ B- T9 p, s, [' M: b                GetPortVal(PMU_SC,&dwRegVal,1);  j- v$ i6 P, q, ]2 ?2 N7 O
        }* R# M6 b" ^# I$ e7 n. i. O
        while(dwRegVal!=0x2);9 R7 O$ T7 D- H; B
. e! w% `; M; T* C) f! u2 k. z
}* C# J- E+ X4 v: b" p

# [' T# ]. v2 E5 M以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。  {0 z, k3 u+ T& c
所以变成了死循环了。" k: r% ~$ o: y

/ z1 k6 E/ P* Z7 D) y5 [! G2 N8 m我对硬件编程不懂。又不知道从何下手。+ B+ j  S: D: m. w( `2 ~
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
9 _, P1 F( P6 S" r但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。, {8 W/ q: p, \- M( G

5 k/ K$ k( S- @" A1 T+ W. q我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。/ k( w- I' Y: Z0 ^5 G& I
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
4 k! F7 r* r% M( I/ i: E4 T. z# B) c7 i4 s( _4 _& L: ^
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
, p& h5 S6 A1 |1 m, V1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.; u. D* d8 W6 L; f% g
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突7 H4 {) }+ a; Q9 r1 `) \7 e
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.) q! B3 T! k+ \1 b& K, ]

6 C8 Q4 B4 ?) G  ~所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。6 H. g" D, m% j- |' V6 X

0 r1 Y3 h. |# g0 U. r4 x那么有些什么可行的办法呢?
7 ~6 n- c  T+ R9 b: x+ E8 I' T为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
3 w. d9 f2 v6 g. z, T! ^
3 {( N3 ^5 t7 a3 I5 _. a它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
, T- z* h: P9 B$ U5 P" L; K8 G
% J- a5 j8 f0 q* }那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
5 H+ _- p4 k0 }; {, v
7 J3 y# z$ \' x! ^2 z) ahttp://www.ufoit.com/bbs/viewthread.php?tid=452+ ~* k0 R  b. @3 N6 A% f3 ?
5 s' V! x6 b& H' r  O+ I
http://www.ufoit.com/bbs/viewthread.php?tid=241  \" h8 b# n; h  Z$ l! W/ b
! _' M- m- L9 M( h$ ?
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。$ l6 J" E8 ]0 M; g. O# ^  ]

5 u& G5 r. U! K/ r) \  f1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
. X. S" @4 ]' t2、Driver最复杂,也需要BIOS配合,推荐。1 K+ h& G2 J+ H) e$ }- z
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。; `1 g# D3 y6 S6 {+ M6 L/ I
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
/ y5 s* P' F# ?* K, B你可以混合使用。
, o" j( _: I, C/ d, t
5 J/ K, j9 [# n% R! N0 N" I: b6 [===============================================================
1 P  L- _* \) d$ h% {9 w$ x管理员的这句话:
- S- c& Z7 E6 e& z  g如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?! R6 p& j" P+ `7 S( C. P8 z4 M6 q- z

% h  T8 f4 Q6 A( e8 X8 l予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
8 U/ K3 `. |. r1 P! Z' [3 A5 o' X
9 \9 C0 ~# }# h9 b4 V) Q3 ]另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
; N7 N6 g* g+ i* J3 f! t. p) Y) y- u1 }6 N7 `6 d9 x
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?& U8 b- S9 i& {4 B5 C
, Q' G( }8 e& @2 c& E
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。' D# a; F0 H4 J& G
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?! U2 P5 {& A7 s  w3 y& A
8 p6 ~3 I# K6 d) ?4 {# [
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表   G1 \  M7 k- K4 ?0 Z+ l6 e; C
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
  d9 K/ I+ Q& i: ]2 A/ u1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
6 n/ n. ]: G1 j  ^

6 f4 m1 g, F2 m0 b您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
4 W( C1 i1 j  z% x8 C( j: l# i" K" n6 J# C. _& m5 W: m
void write66(unsigned char Data)
8 ?" D% Q: h1 N# W" B1 Y. a- z6 c) P{
$ g" T6 R) X. F2 V/ i        DWORD Status,TimeOut=10000000;* d# |  S' H( v
        do
+ \8 I. z2 o* j, x$ ?/ b& w2 Y0 _        {! g# i) s9 _9 E: H
                GetPortVal(0x66,&Status,1);
- f8 k) Y0 W" @/ t7 Y7 }                TimeOut --;' a4 _  @, S# Q. }! k- B
//                Sleep(1);+ `& G" S, q" N
        }while((Status & 2) ==2 && TimeOut>0);" N4 ~5 `/ i; z8 b7 W$ z
8 h6 |! h' \6 u
        SetPortVal(0x66,(DWORD)Data,1);7 Z: J& O# l3 B5 X7 Q4 q
}
/ p" T8 F0 \  ?) o2 w" m5 |void write62(unsigned char Data)* p7 N& ?! l: [+ i9 f
{" b1 v% }( N  o3 {* S# [
        DWORD Status,TimeOut=10000000;' E9 G* Z" ?  T, W% l3 S
        do
% j/ \. _. M% m" G8 Q5 s/ P! ], f9 ]        {+ L: W- X( ~6 o3 u6 `/ n# y
                GetPortVal(0x66,&Status,1);1 R+ Q/ x, f) f! K! N3 i
                TimeOut --;
$ a/ v- m* l1 T9 a8 W//                Sleep(1);2 y9 B% R8 M$ I) Z5 _, P
        }while((Status & 2) ==2 && TimeOut>0);
% i6 r) e7 H$ a, c$ T2 H# F0 Q1 j" p5 N
        SetPortVal(0x62,(DWORD)Data,1);
" d3 C/ V! d5 [- x( a: g}
5 Z  o5 o7 X' v* kunsigned char read62()
; y3 _) f8 b$ s& W' p: [{" V0 H. M, b6 @: l+ X
        DWORD Status,Data,TimeOut=10000000;4 D8 \" ^+ W" H! [" v3 ]. M
        do1 T7 q8 \5 L5 q9 D( ~) s
        {
1 P$ b- i: m4 {- I" d                GetPortVal(0x66,&Status,1);7 y2 l8 v: ~/ [1 `
                TimeOut --;- J2 j5 o6 K" E# P; @
//                Sleep(1);
, R, R: L3 W; h" _        }while((Status & 1) ==0 && TimeOut>0);
& e# Q# \2 _- G; j5 I$ P
7 m' U0 ~, g7 }
- P0 j- @% i2 R* G5 B! f5 ^        GetPortVal(0x62,&Data,1);
. `, Z. d. J, R8 J% B        return (unsigned char)Data;
; g% d0 v/ `- G9 q. y}" J0 s1 s( o+ K& b  \# r2 B" t
unsigned char read_ec(unsigned char index)
0 V* G" g4 U: Y{8 M0 C4 M9 `$ [! p: c
        write66(0x80);1 ~: p6 L* Z$ j3 X9 G
        write62(index);
% F* o8 E1 K/ P9 f$ `        return read62();
0 k% w5 m8 x& P- @# a/ D) j: N}
2 }; C& A: M( t' d0 t1 b# T
$ c9 y+ E7 {! m: T2 x2 \) K. {) [6 ?[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1766) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。) @& M' L2 `: k% p6 G0 h
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。9 }" a; K5 s7 G) ]) j& D- V
6 Q+ v1 e9 e8 Q' B/ l% m
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 . [6 \4 u) {) ~! j+ g, n/ r1 @( K
, n  D, c2 Z5 m* F# a

% d/ N! h4 q/ _/ _您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
$ T( k& x$ y2 m
$ c# t  F/ Z" Z& @- ~+ p
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
6 ]# h% K  v/ \0 t
% N, B  G9 E0 F  L3 W8 j  z2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.! [; A9 z" W) N
0 c3 v7 @. u0 \5 r& N; K/ b
3. Then set bit16 of the IRQ to disable it.5 S, S5 w: K$ |8 R1 p. j6 L

% `- G: ]/ V1 N- ]0 `. p6 x6 \    a.. Offset = IRQ# * 2 + 0x10;1 {# s* |; n& P. v& `: H
  J4 s5 q; C* z! X. \
    b. Write Offset to APIC base,
7 ^; E2 y. ^% h/ w- Y% n2 F* X
5 b% g! c* v) `) u* F: S    c. Read Data from APIC base + 0x10;6 Y2 v7 }. [6 K* [6 w1 v% l

5 D$ c9 n8 \# O0 j3 G" _    d. Or bit16 to Data;  }! q1 {9 x3 Q% t

9 o- t$ ~: I% {3 f    e. Write Data back to APIC base + 0x10;0 N  A2 u' M4 R8 ?
, D2 E+ p* Z. q% b- r- p
7 Y: l5 y8 p- H5 @

. |2 Y7 A  o# t' ?; r2 [You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
4 K& f. h* `2 C8 T5 ^0 U9 C6 Y8 R& M! [545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...

1 q' ?1 S# j, W$ D$ y( H0 P- `9 d0 W1 g. ~  y! @" ]
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。" X/ U9 y' b# \* b3 Y# p' b, o4 }1 ^
==============================================
& ?( v0 G  R6 Q( O* N 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
* s0 f% m5 p7 T% _2 A. l  H' G. N' P2 L+ J1 c
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
( X, ]8 n5 U( |( f% c但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
. Z+ o; M, n8 ?8 ]  t0 r; |& \, f' G' ?; N
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
5 ^- l" A, Y) f  x; I; p0 E9 ?) D当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:; Y. B: F+ W% ]* f1 Y# B
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。; s/ [; h( t  Z6 @3 t
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-3-5 14:25 , Processed in 0.179050 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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