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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>! e* W$ v; M: P$ q) f& x* u) k9 n
#include <Windows.h>% o: r' d5 }8 U5 i. R
#include "WinIo.h", ~; l5 J$ \' j6 q; @
using namespace std;
+ D1 `) }' E$ k
! `7 O; Q# e* j8 |6 ?2 m#pragma comment(lib, "winio.lib")
- A! Q* @4 p; V8 K) N4 b: O- B* l8 x6 C

# [6 z$ y+ W0 Z5 hint PMU_SC                =        0x6C;//命令端口
% \) m0 p' j: ~6 aint PMU_DATA                =        0x68;//数据端口2 T+ L; m% D* y* N+ h
int RD_EC_SMI                =        0x80;//读寄存器命令( G: h* }8 `) B3 _7 x2 I
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
! i4 |0 V# n* }3 w, d6 Z3 y5 y! L' Q
DWORD dwTemp = 0;2 h# {$ J7 W$ r4 W/ p$ U

. k5 h3 y: y3 R  W" @0 mvoid PMU_Wait4IBE(DWORD *_value);0 r+ \, ]; _. @3 `& ~
void PMU_Wait4OBF(DWORD *_value);
: V8 `1 S9 S' u- ?  r  z, j$ i2 K' m7 f. [9 t7 `

0 |9 g) f8 ~: Kint main(int argc, char* argv[])
4 x* H2 g4 o! Z{
. B$ ^0 t/ \8 I0 W6 P        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;+ E1 F9 v; D9 B8 F8 B* P

0 o5 x% X* U4 \7 Z       
: y+ `; v8 C# T" g1 ~8 S7 O) b        //1、mov            dx,PMU_SC                //
" w, `! Q7 a" _6 s% S' n2 }        //2、mov            al,RD_EC_SMI        //' k8 x  C3 u; f+ g1 T) D& @
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
* i4 |0 \( T. ~6 M5 @' ^* G. ]        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
5 f! E" o' v7 w. v0 W3 W5 M- k1 S, T% Y- f9 A0 Z+ y2 z  f7 x
        PMU_Wait4IBE(&dwTemp);
$ K4 s; i" \, R4 r  O! T; z# s8 c1 A       
( c+ R9 F4 B  v) g2 g        SetPortVal(PMU_SC, RD_EC_SMI, 1);' r% C. Y" ~. f$ }6 s

$ V! g3 j2 T  I; Q" m4 b        PMU_Wait4IBE(&dwTemp);2 z0 h) `& j* A. v* |+ q
        . `/ T8 d" a" _0 B! N% m
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
3 ~7 D3 P2 N+ Y2 f  W" K0 J4 n0 {2 E9 l0 e* ~
        PMU_Wait4IBE(&dwTemp);. t% b0 [9 \/ _; e

3 Y* ]$ `2 O) V) y1 }        cout << dwTemp << endl;               
+ d! }3 |2 s% }" U* G# P
, Q3 {. x7 V4 q' X& G& K( g        ShutdownWinIo();
# P" O3 ^6 D# o' f
, c6 B( r$ u) H        system("pause");
) H4 G6 S; [1 A
! F9 t- X, }' O# k* b        return 0;
0 s6 F7 w7 ~! b- M4 b+ X5 ?}$ A# d$ t  X# n$ |
: A/ r: J, q& G4 X( ^; M
void PMU_Wait4IBE(DWORD *_value)
# G+ X: @6 `  u) }7 x) d{
( ?  X: w. p1 M* Y  V1 T( B        //#########################################################   
/ y' z! {: W, |; f9 V# W1 F        /*% d7 A1 k% i$ ^$ G
        pmuWait4IBE proc   3 M  r8 Y+ D) q
        PUSH        AX   
: w& ?- z/ X# s2 t; ?3 u  u        PW4IBE:               8 F/ w8 t$ a( i8 l$ i9 L
        IN          AL,  06CH                                //Read  PMU  status     a' M7 R6 G$ d
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   - P$ ^9 _2 z7 W3 s' }9 Z
        JNZ         PW4IBE                                        //Jmp  if  no   
6 u2 w  A; F/ i, E+ O        POP         AX   
' |5 _8 \' f& E, e( W1 V8 f- \/ @& S        ret   8 g: c# I+ Y* c; q" G& {  B
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
- b$ K" e# m3 Y  s: B        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空9 U4 R+ Z% q' `+ U: e1 `$ a* \
        //######################################################### , q2 g: |& Z, z/ k
        /*do
& m" Q9 X) R8 \9 k        {
/ ^0 N, z' {" R- Z7 |& ~3 j: ^                GetPortVal(PMU_SC, _value, 4);1 n7 X& f$ x& c
        }. W0 B! u. M3 W7 J% V
        while ( *(_value) & 0x00000001 );*/
6 h5 a# m$ R  C0 Q+ Z" I        DWORD   dwRegVal=0;2 {. E6 @/ u9 K0 h! T0 i
        do
% H5 f7 u8 n( I) m- H' u        {  / X0 M0 I) y" k! h
                GetPortVal(PMU_SC,&dwRegVal,1);: C$ h6 }  z: ~* n5 ^$ ]
        }% c' H( ?& c7 X2 y2 `) W
        while(dwRegVal!=0x2);
5 g  ?0 |* U6 s* @4 z. p0 w- z% R% \' W; a1 T
}
5 W: O* L/ l" G  o% ?2 I* i0 f$ R8 D, k1 d  a4 k
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
. J/ I  L* S: Q" u4 c7 `. W所以变成了死循环了。
% H$ H3 f; L9 |/ j  C% L# f& d
2 h  e9 t2 m; _+ k我对硬件编程不懂。又不知道从何下手。$ c9 `' ~; v6 q! x
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
( [2 a* |8 T: c# R1 h9 g但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。/ ~/ u" s) |* h) \# Y- @% o5 v

% O' a% V- Y% I. ?8 w我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
3 Z+ S% ?  k7 g* t: W, |; W. L' j并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。, g& @2 @8 Z0 B! W- r
! O/ E, b3 E6 Y' H) E$ p2 u, [; s
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。$ R: E5 R5 m% v# G$ c
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.+ `( Y8 F0 B: Q' w* e
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突6 I& }2 |- r9 F* s  w
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.( V5 J# ^- G' _- E0 l

& ]: z1 G. n1 ~所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。: i# p( l8 o. Z' u- @2 e5 j" j

9 y2 {0 u$ Q7 H$ k, u那么有些什么可行的办法呢?
% o6 q0 h6 k' Z9 H1 u为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。) n) b+ G$ W8 Q/ {
: k/ \, a1 \1 U1 A7 I# k# ~
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?, H9 }* \" Y* ~% o
7 `2 l( O1 k+ t9 p
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
. v3 S- Z- Z5 E& N& O3 i7 R6 {, I( @$ T; d, t) a
http://www.ufoit.com/bbs/viewthread.php?tid=452
& ^* z: h$ c0 R1 L: `3 V% i+ Q% Y" t' x, A1 D1 H
http://www.ufoit.com/bbs/viewthread.php?tid=2419 I& f0 j0 _& P3 n$ i
( X1 }; o8 l. c+ }
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

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

1 V& h- y; H: U+ R. m% Q4 H1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。( l* ^, A) S- J; H; {. h
2、Driver最复杂,也需要BIOS配合,推荐。
/ r1 ~% N4 Y3 c/ f3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
( _+ N- _& {1 \8 f& M4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。9 J+ O8 N. ?4 ?$ E" c
你可以混合使用。
# p/ |  R- k1 ~# g/ }
8 U* N' v+ V2 B9 A. S- e===============================================================
' n' j" U& B# c. Z3 X管理员的这句话:" B$ y2 q! Z9 Y
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
' _* E, t( w+ {% Y% U/ |
- ?! {' j5 G1 S! {8 @0 o予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
) O7 h0 L) L+ W% H+ H; V
; j# c: t$ W0 P. A' C另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269, n/ W2 T1 D7 |/ f3 j
/ u% i3 Z9 I# P  ~
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?6 p8 C% H9 [8 r# V- t3 [: C
( l! g$ b/ p5 [
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。+ f  k$ U5 r" P# C- p1 h
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?3 a  [3 A# Q* [# |( z' A

  z( k) y( A& m# ]) l" i我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 . u/ _( W, e) P# C
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。8 w% B$ t  ?& E$ C
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
  x' Z) O" z  p) i

8 k- J+ F, g% J9 H7 D您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。& q2 a1 P! A$ q- `: f

4 T* [2 Q: ?' {7 \0 g. h8 u8 Lvoid write66(unsigned char Data)# D( n3 v- D2 V. ~% v0 l' _2 r
{
5 P6 B/ }5 |' r        DWORD Status,TimeOut=10000000;
& k! ~: K+ R. I        do0 L. r1 [0 b" E% N8 F. g. [2 i
        {
! t/ c; p+ w# a# M. N! s! P" I                GetPortVal(0x66,&Status,1);
0 v. ?! Y, v% Q! }' J$ I' E. ^                TimeOut --;5 q7 h' J- @& G+ L5 b) R& P- v; t3 G, L
//                Sleep(1);
$ q3 r0 @  e& Q7 e% k, b% f7 }        }while((Status & 2) ==2 && TimeOut>0);
& C4 M7 i8 V4 ?4 W" M* e: i1 D
; I3 {8 I7 n2 r5 ~& c2 h        SetPortVal(0x66,(DWORD)Data,1);
2 z# l% q/ {, p}& R% V+ x) R2 S: h5 ?, [
void write62(unsigned char Data); q4 V; _2 M/ b2 J& j
{
2 s6 y8 ]6 j% e. ~' t3 g1 @5 T        DWORD Status,TimeOut=10000000;
* z- @* ?0 C/ ]" L$ a0 i        do
5 T: t0 t: ~% O7 j        {
" E& @. V# h3 F1 @                GetPortVal(0x66,&Status,1);
2 P3 g% b; f0 v: u- _& P                TimeOut --;# s- {% Q+ G1 u) h/ c5 K* d& ]7 ^6 w. \
//                Sleep(1);- Y: M' j- ^# y3 o: b, {& j
        }while((Status & 2) ==2 && TimeOut>0);
# E/ V. v2 t, u5 s) t7 \
% S' Q- |+ ~5 [* J/ [! E        SetPortVal(0x62,(DWORD)Data,1);; A* ]! W1 q, A7 v
}
8 J% T0 |4 z1 L; k( p- Cunsigned char read62()
" b: f/ Z% f( _  c9 y% ]{' Z, K. D% ?6 W
        DWORD Status,Data,TimeOut=10000000;
9 W7 D0 ?6 J6 N6 h) d. {        do) U  O5 |& j1 _+ A, {$ m( n& C
        {/ J! a/ L4 K9 K$ }8 O; A4 Q
                GetPortVal(0x66,&Status,1);
8 ?; N. A2 m& ?- [+ {                TimeOut --;
, Z6 b; j; E7 O. z4 Q5 d' ?  b) R//                Sleep(1);
1 m) A+ o6 K7 T9 r: M! k" I        }while((Status & 1) ==0 && TimeOut>0);: ^7 Q3 s: s* O4 i, K/ w
. I0 e1 Z' j/ [0 |
  [" c$ \9 ?3 ]' i6 W+ N
        GetPortVal(0x62,&Data,1);
+ g& h9 o0 U9 m        return (unsigned char)Data;0 ~, Q+ m6 L# N; o1 f9 j
}
7 U3 T8 R" E/ u. d# F4 @* ounsigned char read_ec(unsigned char index)/ J" n) H9 d' v/ z( l* p
{
' s* h" D8 T3 k; T" R        write66(0x80);7 U$ X2 Q% z1 S% b" m7 @
        write62(index);; V6 s! ]& U! e+ W
        return read62();- q: ?& |5 R  j3 C# s
}
9 }  Z3 p: r2 P. w4 [& M# J) u4 ~3 R+ b9 J( E
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1444) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
8 l6 b  @( F& z5 r  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。6 o$ P; S2 z0 ?1 [1 _

2 R' g; g+ L8 c! D5 x: F5 N$ j[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 ! C' r$ O1 `, V  Z. S8 B
# I3 U) h8 ]! }6 a& R5 p9 U
3 M; a! G- S. I
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
+ y8 E: y9 ?9 M  o

; a8 o! K4 a, T. T  q3 m. M1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,: C$ v# B% V8 M* q9 U

: }1 M& ^# |! ^2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.$ u" b8 ?. L2 j
# q/ C5 ?) Y# L5 z9 c7 e8 q
3. Then set bit16 of the IRQ to disable it.* O. K0 n; |" `

3 D* {' V+ `9 @! a0 E! ?& K    a.. Offset = IRQ# * 2 + 0x10;7 S& R8 k7 H' H! r

" m$ U& C) \6 f$ p8 ~; s: N    b. Write Offset to APIC base,
7 U0 i3 E! {$ Z, Q1 M3 n( y: Q) u" p4 g9 F- p* x$ q3 ^+ X
    c. Read Data from APIC base + 0x10;! ^" a! }6 B3 p' t8 f  r/ `

- ?+ F) \8 }5 A/ c- q    d. Or bit16 to Data;
" W3 I/ \/ x; q: ~" J* v# C7 q9 M6 j- B$ n/ x
    e. Write Data back to APIC base + 0x10;8 ?% y! I- {( e+ N! x0 V

" L# F6 Z, W0 o. x% c2 b! S* Y+ D 9 K0 m' y6 R8 N7 Q4 d! t7 w

& Y! B: Q) F* V% q  c' X' OYou need to check APIC spec for details.
回复

使用道具 举报

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

/ B4 h. ~* ?1 q, }9 U( w( w1 b4 C
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
3 F4 \/ Y: B9 f$ w==============================================% o7 M9 Q1 h* I/ q- d9 h/ ?
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。" J# b4 A  h2 F0 r

) C1 t" o" B% W- _! h6 m因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
6 D% O8 |( B" A- {0 I& f但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
4 w/ c- B4 a5 |# ]$ |0 ^. b) b. Q( t( _- l: O
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
9 a; l5 a9 u- V当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
, I, N; B' q- @2 c1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
7 h- N/ a6 Q) K4 D. T* U0 Y' a6 W/ z3 n2 ]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-1-12 05:36 , Processed in 0.062590 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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