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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
9 n4 S/ y# }) A: B#include <Windows.h>
+ V/ R- z& z3 N- x0 f- d! T#include "WinIo.h"* Z, X$ I% n7 }6 l: F, f
using namespace std;2 W& b- p6 A' v! z

( ^" G1 Q! v# X& g; y6 |4 Y#pragma comment(lib, "winio.lib")
) z0 v  V$ L9 t4 Y: L3 E/ y" ?  T, {( Z- Q3 d
/ H) l1 F4 O3 r) ~
int PMU_SC                =        0x6C;//命令端口
/ u, f* Z9 N: N3 U& @: zint PMU_DATA                =        0x68;//数据端口6 i$ P9 i7 ]1 z8 u, o  x0 r
int RD_EC_SMI                =        0x80;//读寄存器命令0 E1 u% s/ y% |3 l, W3 g" O
int POLLING_DATA                =        0xE7;//CPU温度寄存器号6 w. K( R- C2 H4 e, E  V) @1 [6 }) t

9 h1 z/ Q) I, c3 m5 cDWORD dwTemp = 0;
6 M0 f1 S) q$ h3 N' o
+ ~' Y; [- U6 c+ ?/ Cvoid PMU_Wait4IBE(DWORD *_value);
! r* ?( |* Q# F" y* Vvoid PMU_Wait4OBF(DWORD *_value);
/ \: A9 l* W# ^+ ?( j$ c( R
7 F) k, h( i! H( J( v
) M; A. Q1 ?: b) K* }4 ~& w6 xint main(int argc, char* argv[])
- F5 j# [( H! o: X{! m4 r; ^  g5 W0 q* @
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;6 w+ n& ]2 U& }3 d2 v
1 y9 a! }3 N' F2 F3 _( c9 m; D* R
        ; U* I9 S" ]- q. n( l
        //1、mov            dx,PMU_SC                //% K- S) p+ b2 }1 f* E
        //2、mov            al,RD_EC_SMI        //  a+ z. r" j" ~  c& f
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
* _/ M  B$ `0 [+ G7 ]8 q; y& ?) W3 o        //4、out            dx,al                        //将读寄存器命令放到命令端口中。' ^+ i3 H1 c+ Q3 W5 d

  @) e6 a2 |$ ^+ \        PMU_Wait4IBE(&dwTemp);
2 l5 ^3 r$ _2 S2 z        7 B2 A% r. o% C7 W0 R+ D
        SetPortVal(PMU_SC, RD_EC_SMI, 1);0 N# F8 ]' N/ F' o

  D* Y. }0 e, F+ u) E' r2 |        PMU_Wait4IBE(&dwTemp);" \  g) M9 x  l7 _0 h* g
        9 `5 c8 b& }0 i8 |9 O
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
% a" L' ~: u2 D) L/ ]$ f8 q8 e3 Q% s& f8 Q1 G
        PMU_Wait4IBE(&dwTemp);
1 d1 Q- s  s/ G  X6 v7 y8 D7 h
  t/ q$ H" }" M5 D4 V        cout << dwTemp << endl;                * m' W) A2 ^5 u7 X6 Q+ I  Z" e
7 O+ G- M, A5 M8 u' J' O  u, m
        ShutdownWinIo();
' y- b$ b8 p, B3 O4 ?4 n8 J0 c6 r8 g* w+ K
        system("pause");6 Q. h& X+ A) b: {% U
4 Q: F* E* f1 t  E/ K: ]
        return 0;. z# h/ a# f/ A8 y; b
}
' d# ?/ T" V  g8 ^' y0 z% L6 y5 Q# k* S# I  g
void PMU_Wait4IBE(DWORD *_value)
' W# b% b+ P/ l$ G{
/ Z4 U: l/ Q/ t% @+ U7 D        //#########################################################   
: n7 [, M5 L/ i) ^) U        /*
  a, }% U7 q* b$ q# y        pmuWait4IBE proc   . n! s( G& F  v( R, I- S4 z# [
        PUSH        AX   
+ U% |; `- h0 ?. w% R! {        PW4IBE:               ' p- ^' D. s1 u2 Y
        IN          AL,  06CH                                //Read  PMU  status   
% ~/ ~  X5 f6 m        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   + h. O8 L) E3 x- m5 R$ z. j
        JNZ         PW4IBE                                        //Jmp  if  no   ! b% q. R. l, x1 O' H
        POP         AX   % y) P- q9 ~# Y( X6 B
        ret   
& ]% |$ n2 u' d/ x) y        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE- @+ H% v! h8 I& G4 C( J
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空. h/ i3 s  _/ D) A5 v5 h
        //#########################################################
) k0 P0 ]8 z) p/ K# @2 Q6 N        /*do 0 U1 b- ~# }9 ^7 w3 b* z; M
        {
+ f7 u0 z& z7 b5 @                GetPortVal(PMU_SC, _value, 4);3 R3 K7 x3 J4 a. m7 i
        }
; a3 I* r  y; ~" @4 f: X, W9 @        while ( *(_value) & 0x00000001 );*/
; w5 v  z3 {( s# v5 L; s        DWORD   dwRegVal=0;& t" W8 W+ O* Y: l" C3 J8 ]( _
        do! x! {4 E! \7 U) t" N" D
        {  
! O+ m0 j: `1 C# f. n                GetPortVal(PMU_SC,&dwRegVal,1);
$ v. n1 W: ~) E) |/ C3 K        }4 K7 @" D4 Q; ^0 T5 l) O
        while(dwRegVal!=0x2);
6 w4 W/ M& u" K+ U" W4 O9 G9 x# x5 u9 E. k7 L; r7 @$ u
}  A6 ^5 q* p+ U' f

$ ]$ l7 ?$ D. \: B  O; t' f以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。, t. n: j1 o' r0 b$ j& Z# S" n
所以变成了死循环了。8 j" z; g4 Y. L% z

$ `- F" ~' A5 \我对硬件编程不懂。又不知道从何下手。, G7 D- Y1 _! r4 E1 H+ c- G
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。3 `1 m3 z. `" B
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
0 ]* D' y" [/ y7 [  p6 L- _
2 x! S% D8 |6 m我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。0 P8 v# d, Q) h
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。  u3 N9 F; i2 o

( s9 G) O* l, t+ G' t# d感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
" ?. |. T) P0 @# g+ k9 R) n1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook., a: F0 O8 [. y
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突. F0 w; H; K- y6 C/ Y9 w9 u; w5 K
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
1 O% I2 p0 x. L3 K0 v9 L2 D6 w
0 Z9 {6 v  r' D7 D& A所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。& k: c$ F9 k9 Z( q8 l  a0 A

  }# ^- _3 t) W6 @" S) S那么有些什么可行的办法呢?- f' H3 o% l8 B2 l- Z
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。8 t* y: }) S  o
, O( Q4 E% b. j% y7 n8 L
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?( e# |2 z! R3 `

9 ^5 J* d1 T7 F7 ~那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
1 V1 Q" \6 c& R) c- }6 v6 x3 [  N" N- b2 f% y9 v
http://www.ufoit.com/bbs/viewthread.php?tid=452, W: K' o3 Z: }* ~+ Y
; E4 r; |; P; ]$ W- @
http://www.ufoit.com/bbs/viewthread.php?tid=241
1 q& ]' i7 ^7 a1 {7 ^- N8 m% N; b) @
' o' E) O* X& T( ?3 W看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
$ |- ]  D% o0 B. [9 V8 ^# ^7 x% V; a" A. ]7 H% V
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
! \- k; Y) c" m2、Driver最复杂,也需要BIOS配合,推荐。4 R5 X" f" U& o- O* B- N
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
/ B' b+ n8 c  H9 w' C" f) [1 x: Y4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。% K, B  I, T$ h
你可以混合使用。& x9 X! K. Z! v5 }5 y5 z/ o

/ D$ Y8 B% I2 r===============================================================
) ]/ f* q5 U6 `" f* p% r$ r$ A管理员的这句话:8 y% C: u" S7 s4 ?: X# T, D
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?7 V; H) x& m) B  |5 S

: A% S5 \, v5 s予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵# k% V: }0 m' M7 V! _  [  H* H9 ?

# d' V+ r" s2 j8 B0 c4 [. z另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
+ I: L) m7 z$ _) w) {( @5 b9 y8 a/ [3 v5 }
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
. x9 v; ~2 l$ I5 G" v: t1 M
% ?; ^( `3 U. S0 Z# N" Y9 E还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
- ?( Q0 {8 ^2 V4 R! I$ D3 s里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
' ?) q) g! O7 [, r, T& L( j' F$ ?1 n
5 ~0 |. n" z0 O, L5 J+ Z我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
- T/ z( d; W" i你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
! B1 ]1 v% ]( ^4 d3 g5 f2 }1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
$ k( ~, z/ d5 h% n

4 s' ^" C8 ]% X  G, K1 ~您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。: e; D3 T! i, }: G, s
9 K# ?9 S" V8 ^6 o% v' |) b7 R
void write66(unsigned char Data)8 J  Z# d! V3 R1 {$ m# }6 H9 |) d
{
7 H$ F, c4 ^% h) s* j- a        DWORD Status,TimeOut=10000000;
: k% ^! H1 K% m% C- g1 h        do7 {# K, @6 M& B6 L/ M
        {& s8 e" Y- h3 u9 p, p& @
                GetPortVal(0x66,&Status,1);- F/ E& P) v) B1 c: u
                TimeOut --;
! v1 g/ w5 ]8 m; V, c0 H& C//                Sleep(1);
/ ?8 `4 T$ M$ m9 Q        }while((Status & 2) ==2 && TimeOut>0);
6 B# t$ {4 l& M9 X) @) ^( }  ~( ?  _* v! J8 ?. @* g$ [( c" g0 t
        SetPortVal(0x66,(DWORD)Data,1);% Z1 x$ M/ y/ o. ?
}
# g2 j: j  s7 _0 Vvoid write62(unsigned char Data)
- l- S6 p7 F5 I: W{, H/ B7 q. b1 T& S
        DWORD Status,TimeOut=10000000;
: G: v4 d1 ]' n' `        do
4 E, D: K7 I+ D8 u' h4 t2 K  J9 W        {
. j8 h2 D! {5 e9 T                GetPortVal(0x66,&Status,1);4 t( ^  Z) P, Y! T6 K9 O. h
                TimeOut --;/ _2 R+ y  ]0 ?% Q# t5 b
//                Sleep(1);, P6 g7 C' q' B+ Q
        }while((Status & 2) ==2 && TimeOut>0);
  Y* D" z" G) m9 x7 A& R' N$ V5 d" y$ Y  C$ @  C; V
        SetPortVal(0x62,(DWORD)Data,1);3 s; x# W" k* Y: _$ E
}( y6 n3 {& X) b" l. Q
unsigned char read62()3 r) H+ F: s  _0 X% N
{# _. f- M9 z& D/ M6 }
        DWORD Status,Data,TimeOut=10000000;# t$ e" f% h; E( K: P
        do  H# p2 `/ ~9 M( `8 x( p
        {! N' o2 m& J* b) _
                GetPortVal(0x66,&Status,1);3 e. z! Q- V+ o3 M: V* Y
                TimeOut --;. F# W# V% _5 T. y; n
//                Sleep(1);) X+ b, K( W% ?
        }while((Status & 1) ==0 && TimeOut>0);) b5 |  N  X7 S# M7 w

8 p: ^" n5 X* U
7 z. y- K! @9 t6 B8 ?' k8 D7 F+ B. R        GetPortVal(0x62,&Data,1);
* J* {+ X7 A& C        return (unsigned char)Data;6 C9 u$ `% W5 s8 p, l
}
  j: S9 C3 H: d7 O% n# i8 Sunsigned char read_ec(unsigned char index)
7 W. D9 s; O" x4 |6 G{
/ N$ e8 q' t1 {        write66(0x80);( n2 |, u% G6 P
        write62(index);6 A( _3 R( _6 h6 O8 O% l
        return read62();
. g5 o8 _) M2 U$ A+ R/ Z}
7 D' j- W% s% @9 ?+ S
! |( ]: I8 I9 D( V[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1135) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。7 P* S- v# e# z4 X+ H3 R, x
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
3 ]- D: s3 w  R# {8 V0 h& L+ x7 k
; x$ U% @6 l7 Y. W[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
) X2 M/ k% E, n
& ~) R, a$ _1 \5 d7 a5 H7 F( k! g
6 H! V6 @# T* O& h4 j; B- m! h您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

1 e5 {5 X0 H7 z4 x7 M8 V
' Z2 N1 S6 h, e3 Q$ K# I1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
9 E9 L0 B% k) U9 v* M1 S, @! {! H6 |& b
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.4 Q+ K8 o1 T% [# ?2 k
0 I/ p! n$ E* F+ U: z7 \* S
3. Then set bit16 of the IRQ to disable it.
0 V' L* M6 |. ~0 f
9 N2 k# q% Q8 {( x! s6 _* t1 q    a.. Offset = IRQ# * 2 + 0x10;
# J: _, A) d" `% x8 g2 h6 n* N* F7 d9 i: a5 X! G1 s! W) {2 g1 V
    b. Write Offset to APIC base,
3 ~  @: R* j4 B4 S  |* a" k2 ?3 x$ R* F5 L! b1 E
    c. Read Data from APIC base + 0x10;
" q7 z/ M* _% L) `9 |
# n0 E1 V( h" v: E    d. Or bit16 to Data;
. [& R" _) f4 m2 s
' w  _. t) o, m) D& m    e. Write Data back to APIC base + 0x10;
4 h+ m  ^: d2 q$ `8 H
4 m9 b" k1 C" ]. ?6 I" b7 `; p) T 3 T" \5 W. X/ _6 ]  N
7 {7 E  e& _6 ]9 M! S
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 0 m* e  _2 S* g- |0 J6 n6 d
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
8 r4 M& d' v' Q% f

- h# T" Q) }" X6 n 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
- R1 t5 m. Z4 Z6 e==============================================5 M1 k/ u& c. t' r9 x
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
& H5 I/ B: b/ m- X+ r$ b+ }4 H' _6 B3 Z/ F  I/ d* Q6 ]: U( g2 L, e
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
; j, V$ ]# h6 L! B5 z1 h* }但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
) I7 `8 w' l6 w" R9 R( P
# g( N! C7 O3 ^8 _) v因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。* _* u( g6 R! c4 Q4 `. g2 C; A
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:( w' }8 r8 q3 R3 y3 M$ T- b. `
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
( u& U1 K8 r8 o/ r2、新手不要把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-4-29 05:53 , Processed in 0.036088 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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