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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
" ^3 y# l& }* E% q#include <Windows.h>' _0 G2 k! S7 S( f4 p# F
#include "WinIo.h"" X! a: i' Z# R4 O# C
using namespace std;2 ]- h$ M' `* G# t' F9 K
6 w9 _) M7 ?9 Q1 y
#pragma comment(lib, "winio.lib")
  D* _& R4 w! E, @+ }. _% @7 `8 q" G/ @. u

' D9 @7 z3 E; [8 Fint PMU_SC                =        0x6C;//命令端口
2 y. [% S# D7 j7 V2 ~0 p6 j* |$ iint PMU_DATA                =        0x68;//数据端口( g7 _6 I0 N; ^8 H: N; P. o
int RD_EC_SMI                =        0x80;//读寄存器命令
; ]7 O8 B3 W5 C/ [1 |int POLLING_DATA                =        0xE7;//CPU温度寄存器号
' s5 k/ x" {: r0 ?( Z+ R2 x: S4 x, U/ k
DWORD dwTemp = 0;
' _+ b+ p6 u: y( R1 Y1 y
6 C# r2 X& ^3 F5 \: ~! Rvoid PMU_Wait4IBE(DWORD *_value);- p, g9 U/ |1 y6 a, p6 t7 ?" a) T; X
void PMU_Wait4OBF(DWORD *_value);
" T  q! V7 _0 x- Y- \) ^4 ^% D. G/ f7 M! I& c+ V- R, R- O' G
& N6 h5 e$ [2 n  g1 ^: o/ i
int main(int argc, char* argv[])
1 M- @/ N$ Z2 }; L{
0 d: L6 c( n+ s' x6 i5 f5 ~6 k' Q        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;: X- i6 a3 R+ [5 {2 R$ D  V/ Q5 F/ X
- {0 [# C/ ~! i$ [, ]) |
       
  `( E0 V6 V3 Z2 r: p        //1、mov            dx,PMU_SC                //# \3 y. N3 L6 C" R
        //2、mov            al,RD_EC_SMI        //
9 f: Z5 b) A8 C+ K( R        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了  i* I1 D+ n  _4 h9 y
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。$ n# G6 o: G; V0 R/ o( J

* U& M2 h- B, J2 M; f$ o        PMU_Wait4IBE(&dwTemp);
6 X6 N  i) X" z. m% [, R9 g        9 x! l- m* B& y0 f  I( m5 Q
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
6 n$ M( u4 }/ E* c0 ^* h3 J. B7 |9 k9 K+ c* S
        PMU_Wait4IBE(&dwTemp);3 f) @  X- h; w; ?
        . E0 P- `  d1 X4 A1 i+ D
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
1 P% J# j' ^. f7 X7 e
, G+ ~8 E( p; W, u        PMU_Wait4IBE(&dwTemp);
. T3 A: t% E, J7 Q# }0 R+ \# E0 L' J/ j5 i+ Y. E1 t2 L
        cout << dwTemp << endl;                4 d+ s2 v4 W" k( |

. u% n( W: j2 [& E        ShutdownWinIo();" o$ O" `4 {" k- D2 C% H

) M1 }4 M8 s  c$ g4 m        system("pause");" J: Z% m2 Q1 a/ C, Z7 ]  T
2 K* B: K' h2 x* z
        return 0;3 {1 V# S, f" Y7 c3 l4 C
}4 _$ @& m2 M  @0 \; _

2 m. _. S2 E" E+ X' y. Nvoid PMU_Wait4IBE(DWORD *_value)9 `/ I5 z8 `% ?- d) Y
{. u% u( f: t% B+ }# \. x
        //#########################################################   : x% X7 H6 T" A
        /*
- z( ?, n  C' i+ `        pmuWait4IBE proc   # }* c2 N* `+ _$ I
        PUSH        AX   
+ K0 h& F3 X, `" N/ s        PW4IBE:               
% p7 ^1 Q& G2 A% X# X        IN          AL,  06CH                                //Read  PMU  status   
8 B# @; @9 ~0 e& p+ q5 G  n! n        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
; x2 l- j: E4 r. A! f( [        JNZ         PW4IBE                                        //Jmp  if  no   * l' z5 M% [1 A7 w
        POP         AX   
! a8 j% B$ B; R        ret   
$ U0 x" _9 c- s% W5 r- q) ?, p        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
4 Q% O2 X; K6 n% r        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空& t- v1 C6 o( i( u: s
        //######################################################### 8 U; [  s; F3 P0 C3 [& x
        /*do
6 e' M4 E4 E9 g' e5 z+ I# @  H        {
' t# t2 Z" r2 o2 `! V                GetPortVal(PMU_SC, _value, 4);6 y& v  Y7 N2 y, S8 R  a  d
        }
& X7 A4 c% G8 H        while ( *(_value) & 0x00000001 );*/  t( @7 s6 @$ @. ^3 r4 F& x
        DWORD   dwRegVal=0;
8 w7 }" r# ?1 e7 M        do. ~  I! V: D9 F& r1 J8 q% W
        {  
# X9 U" u( t* |0 @- q, x" y9 h                GetPortVal(PMU_SC,&dwRegVal,1);8 z+ c' |% k( h; S3 s3 H) h, x
        }2 I6 ^8 I0 `9 c& e" q5 E: h
        while(dwRegVal!=0x2);
- q  W) w) s* A/ f* w. g
8 q0 z7 w8 h6 o) I6 {}: C0 Y3 E. l( C$ _' i: S* U1 e

; X) t, q0 x  N+ V以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
9 s& J# o8 D7 _1 J2 X* c0 A所以变成了死循环了。
* v' w( U- @( u. y( y2 C- a
' K6 v* S% }* \0 }我对硬件编程不懂。又不知道从何下手。
; [+ E6 a9 c. o2 h! E4 ]; m. B2 `7 ]我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。. g% ~) ]" _% R$ X# Z
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
! A1 R, O; ?; S* j
( U3 S6 A$ x7 A# U9 }我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。- U8 _, ~, x8 E
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
+ _; b7 k4 z4 D9 {. W& c; k/ U9 r: X5 D  v, S& d3 N+ ^
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。( Y# y+ \2 U+ `, c) U
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
/ }. t. D- l( m7 L. u0 v2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突5 }/ y, e9 l" ?
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的./ _) B% [3 U( O" N( D
( s- V% I; V5 d8 V" u' ]4 S
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
, e2 f' L0 Q+ P1 p
. H9 K- h$ i7 e, f* V- {那么有些什么可行的办法呢?# k8 ]6 t- {7 @6 ~+ [5 s
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
! n8 Y/ F+ a4 f: K
) j; Y0 t' k1 L$ ^( X2 T" q它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?1 Z+ \+ H6 w: C/ `3 \
) S: y& q. T' b5 W6 u) g4 G
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=4203 h( M0 z0 C& j* f: {2 w
7 {4 k! R& {$ s# B& f
http://www.ufoit.com/bbs/viewthread.php?tid=452
! n1 X" A+ ~& ~, W
: \# V6 r# }* mhttp://www.ufoit.com/bbs/viewthread.php?tid=241
' o$ n2 H  {  ~1 }0 x6 m) L! `  U; L+ R
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
! v7 i* s# ?3 z) V. Y2 b9 I! e" O3 [3 D' S6 h1 E
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。) z& p# F/ g) \+ S' l
2、Driver最复杂,也需要BIOS配合,推荐。' t4 Z0 @5 Y: l& K% b7 H$ I
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
& l# B& Y$ A9 D; C4 y; T4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
. Q4 G$ E& g; ^2 N2 z你可以混合使用。. b: a+ h+ S1 d; G

4 K/ d/ ^: ~$ m% e! U===============================================================
' v0 }. u% s! k1 i; i2 `/ U管理员的这句话:
9 o2 K# N5 a! G" V" F9 o8 k如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
) l7 r# V' r$ X+ k
2 c& W7 K+ e- v. d3 h  m0 D予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
" p1 {) [  d+ E# ~2 O0 j
# s# @+ G3 d' _另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269) G2 F+ Q, j7 X% p) p

& c: ?- {7 O  v) u+ v! ~这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
% B+ Y+ i8 k- o. l$ ]. o" s
1 G# p; y, Q* s还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。9 [4 {. o* U4 J( P, w! N3 W
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?. r- P& k3 j' S  n! f0 B' g: u
& h. s, Y# Z- _4 q% _
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
. o, Q$ u) R3 Q; Y- a6 k4 D你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。* f& H" l% C" r/ {- j* `
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

6 C# |( x. N# z* Y, ~* n; T, i9 T7 R% Q* z+ K. L
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。. ^9 N0 B* P( t2 ~/ K2 c

/ ]( u2 r* c- f. \. ]' n6 H; O! xvoid write66(unsigned char Data)
+ t* t' T' f/ @{
( \, ]5 \  E! W9 Q        DWORD Status,TimeOut=10000000;8 R. n3 s( [" V
        do
3 @( b( L7 B' E/ a        {
/ V0 K7 ^+ d5 k8 V* V7 \                GetPortVal(0x66,&Status,1);3 V0 u4 t/ s3 R
                TimeOut --;
$ z' G' U1 s+ ~* R//                Sleep(1);
) v5 ?* Q0 @4 a- D4 W6 A- v        }while((Status & 2) ==2 && TimeOut>0);
5 ^6 P2 ^$ ~. F! \5 J+ I6 q8 f" c  V* \$ q, A: o) Y
        SetPortVal(0x66,(DWORD)Data,1);* W* S2 n" q. H  j* l3 t9 \
}
2 x+ A$ c9 E! {- ?  j9 rvoid write62(unsigned char Data)
5 B# c! U4 p' a, _0 ?{
" H7 p9 }; c& b2 \4 }3 g+ B0 d        DWORD Status,TimeOut=10000000;
- Y# X! w  ?+ G# k/ l$ i' B        do. f  r8 {: |$ q3 Y8 y: t
        {
1 b# W2 I4 ]7 k& @7 Y) {  H                GetPortVal(0x66,&Status,1);
1 G& b/ m4 Y3 E7 |2 W4 ]" k                TimeOut --;9 g; [( m( k8 ~/ E* S, H
//                Sleep(1);$ Z# R2 ?! E1 p1 b8 v$ d! l7 E
        }while((Status & 2) ==2 && TimeOut>0);9 D* [) N0 _9 u3 {& H2 _8 W

( N$ o( B! I; @. H0 z6 n, F        SetPortVal(0x62,(DWORD)Data,1);
) R$ J7 b8 F- ^8 j% a0 X1 \2 U}( c$ ^1 W' l2 z$ M  F+ [" |$ G
unsigned char read62(); ~  V& j6 z4 E" y+ r; H
{
% G& k  s2 ?& P        DWORD Status,Data,TimeOut=10000000;$ n8 j! W# I' R& b5 J* P- S
        do* Q; p1 j3 D/ ?# P) I
        {
3 l. `7 Y" e8 z: A9 q4 V0 h                GetPortVal(0x66,&Status,1);: [. U9 d: R  }( R* X
                TimeOut --;
* B; ^% ]. X2 B//                Sleep(1);
, O& y3 |# p* w& e" C& f        }while((Status & 1) ==0 && TimeOut>0);
3 ?' e: u5 g5 W. ?* W/ Z- ^* a- x* W
0 B! w0 M- s" o$ m
        GetPortVal(0x62,&Data,1);
# m2 j' e$ W9 E$ `# ?1 ?        return (unsigned char)Data;% o! z8 M; o7 _) S, J& k
}9 A5 o9 Z0 s0 Z9 E, L: M4 f
unsigned char read_ec(unsigned char index). Y3 H2 C9 T$ f/ M/ o
{
0 f8 X( {: W' i1 Q- h+ F        write66(0x80);
- B# Q4 R* l: N3 q2 K: P        write62(index);
2 p) c+ y* g& I2 [# G, {        return read62();. A9 _1 z/ m+ p5 W& T( [0 T, V
}4 \; r0 }, p2 P
; r4 U$ T6 Y7 f/ C" n
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1894) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。. x' m7 P0 J! b3 Q) S
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
2 x7 N$ F! M7 v! S8 u
- q! ~4 ]- k. b[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
* ^! ?5 |9 d, ]! T$ X; V+ f+ b. ]. ^% V' |# c0 p

" Y. M# y9 d$ }) m; y. }6 v4 V您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
& S& y% ~- u9 X7 l3 _2 Y, R

6 ]+ p1 F7 ^" d% _9 E1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
7 p! O% @2 T# r
# R) K6 x& i/ L1 ]  V: J2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.% f$ x) }/ L  U8 g
0 ?: g/ ^; s2 ^2 d) _0 |
3. Then set bit16 of the IRQ to disable it.
3 U' o6 E7 q: ^& f( N3 z
9 d% m0 e  b# |- c: t    a.. Offset = IRQ# * 2 + 0x10;; m# w3 Y3 @# l( M4 @

) L7 N4 |% V( L% y8 q( j. d    b. Write Offset to APIC base,, i6 d4 G' i( G& m9 E# Y0 ~
; G4 I4 ~. ~" K. s# {" y5 U
    c. Read Data from APIC base + 0x10;
3 Z- W* _! l8 j" p' {1 T/ _" ^6 Z1 v( J( E" }& E9 N/ Z9 E. T7 k
    d. Or bit16 to Data;
$ N: [' M, G! \) C, \
6 b: Y% [( E# ~  G% y- n  z    e. Write Data back to APIC base + 0x10;
+ B, e2 J, x  F' J* t/ J
( O, K* w; N: f6 o) N$ w! E
/ E, N1 Q) r" p; [8 m0 p' |. |8 g+ G( F% Z  l" g1 A3 D
You need to check APIC spec for details.
回复

使用道具 举报

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

) M3 t3 D( M$ F
+ S6 W$ x' t. | 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。5 ]/ ^! ~2 g" j8 Q
==============================================. b  r, d. @& _
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
- E$ P+ ]0 q( ?$ K+ Q2 k4 f! V. n  J, Z; m( M* X
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
: i! }& y( p0 K9 ~& z/ z但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
  j5 K' _4 F0 c' A# i/ W' b6 U' H& h9 {+ w/ A* a2 H
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
+ b3 l( P( h8 k0 J当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
3 J8 o2 ~% e$ c1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。' G, t' r1 j# L' `. n$ H
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-5-16 07:34 , Processed in 0.069004 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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