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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
) w, ?* {+ h3 K* G; b- j5 @#include <Windows.h>
! M, I! j3 P& N" O6 I#include "WinIo.h"; x& f/ h# [; M( s! s3 u+ e
using namespace std;
9 |" [. G" e0 u: a; A2 ]! S0 M* r+ O" O4 u" y1 C: Q- @0 _/ i
#pragma comment(lib, "winio.lib")+ s, C! m  D  t! s, n+ ?% v" {* T

3 o; G# @$ `" I% U" F0 }: o% d' X$ O5 H. B! |& P  a
int PMU_SC                =        0x6C;//命令端口- ?5 p3 ^8 p$ v) u3 v
int PMU_DATA                =        0x68;//数据端口
# B* @. j, B' Y+ y5 F1 fint RD_EC_SMI                =        0x80;//读寄存器命令
" \1 g$ T- \' y" O  m2 _. C) J' b4 Bint POLLING_DATA                =        0xE7;//CPU温度寄存器号4 d8 l( Y* j' \  d
" E; e" C3 S7 K& p
DWORD dwTemp = 0;4 J3 p7 y9 @# t$ L* r

6 Y0 w' R6 `! f; R8 rvoid PMU_Wait4IBE(DWORD *_value);
) Y1 q5 A; g+ v1 u' f. i1 }void PMU_Wait4OBF(DWORD *_value);" ]% ?0 K! @$ d( i! m. h
2 v' O* q# c* ?: }
2 J! \+ P, A. i, i; E' x
int main(int argc, char* argv[])% h8 t- W3 q0 w9 s( g2 U
{
: g! [) L& o8 C4 ]+ F) |        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;/ j! e" j. b/ X" ^

4 }" ?! e' K+ Y* b$ u        8 q1 m, p) z/ U( e$ v/ f
        //1、mov            dx,PMU_SC                //
1 J$ s5 s+ D* V( L5 Z5 N        //2、mov            al,RD_EC_SMI        //
/ m- L+ O; x( O3 Q. S/ i- {        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了5 M6 g; F7 z. @6 b% Q
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
" E  g) j' d, Y- K! [) ^
# h; \& g! I* g        PMU_Wait4IBE(&dwTemp);3 ^. W3 ?# z2 R1 t
        8 O' M' _2 L4 L* I$ G4 s7 Q
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
* e: B. B. M, P5 H
3 J" `, N: |/ m, x        PMU_Wait4IBE(&dwTemp);: `+ x% Z* r+ T. g' _7 T
       
; G3 D2 M! }1 ?6 [/ ]+ N/ t        SetPortVal(PMU_DATA, POLLING_DATA, 1);9 u$ Z6 g& m. E: w4 j. y

2 I- l  H* K9 w6 x: Y4 G        PMU_Wait4IBE(&dwTemp);% Q; j+ s. F; z% f- W0 |. R3 v

9 u0 u& M; L; j. g        cout << dwTemp << endl;               
+ Z$ D& U9 _* w8 _+ K- g* u1 n  Q! K8 ^& b) ~* R( ~0 A
        ShutdownWinIo();! M' j5 F# m; }; w6 V2 c
# t% s. y  h  K7 G) m
        system("pause");4 t* }0 d9 F5 o
* r: {, D6 Q* d7 }( z2 l9 \
        return 0;5 x  i0 L/ y- W0 O
}8 u% U0 u4 U* W9 s* j
8 C+ P7 T: b% h2 E" s  I. b, b7 E
void PMU_Wait4IBE(DWORD *_value)9 q$ I$ E" W2 g& b8 V
{
1 w! T6 B/ h3 b+ k* a; V2 ]$ d: J        //#########################################################   
! _$ N; ]# ~9 m% c, }5 T: `  {        /*
6 d# W! g; L8 m        pmuWait4IBE proc   
# g9 m5 K7 f5 A+ J& _* O( X        PUSH        AX   ! g4 y4 E0 i  r4 C
        PW4IBE:               
  h5 [! G3 }2 H        IN          AL,  06CH                                //Read  PMU  status   
! F; X& N1 O5 @2 g: \1 \- a        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   " a9 Q$ r* u) Y0 n$ o% G% o9 Z
        JNZ         PW4IBE                                        //Jmp  if  no   
, T3 Z0 s- N& E9 m+ r8 m' I4 D. g        POP         AX   8 R3 P- S+ C; M4 S' Z
        ret   - l9 W4 I, s- h# g; G0 B, I
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE, Y: l% a) k0 j% H$ p, V3 Z  b, _
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空! ]1 v7 W: Q1 t! a9 ^8 s
        //######################################################### , ^9 G4 r( r; l
        /*do
  R2 [! v' @# m. m* Q        {8 ?: x" V2 v; n) P0 A+ p
                GetPortVal(PMU_SC, _value, 4);  M; l* |0 j8 I9 D! a4 t, i
        }
+ L4 M+ x( {$ K5 V& m, W        while ( *(_value) & 0x00000001 );*/7 `8 E1 ~$ y( i/ y
        DWORD   dwRegVal=0;$ \8 ~; w( L" G2 R6 K  Z3 f0 C) V
        do
. f' T4 U# K) Y' h. D- r! d        {  
, O+ B% c5 h4 W- a                GetPortVal(PMU_SC,&dwRegVal,1);1 P$ N2 _; a" r1 k4 |- F
        }2 p# j0 k6 L7 j  }, H+ Q1 U* [
        while(dwRegVal!=0x2);
5 d8 \$ k& Z( \8 ~) W" N: f0 \6 d1 r( t7 I# p! y
}
# h7 g6 n) W: n! U7 J/ q5 k' U
. T% x0 j. W3 x! f1 f以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
  q, k2 o& r$ I' X' |  d所以变成了死循环了。3 G/ o" D- ~7 w/ `

6 T% D/ O9 g' @  c7 T. A# I我对硬件编程不懂。又不知道从何下手。. P$ L) E! H6 g4 F/ t* Z' h
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
$ H" a: I) U$ \但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。% H' A8 \# U1 _  t" D2 q8 y- A
. t4 D) ?% n; V: P) v) s
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。/ N4 U& s& S; r9 v7 }6 z% F
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。/ F# ]. a% \4 r& @0 d
8 \' q8 u. {0 l6 e& 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.但是你这样做法应该是读不到的。
$ F' X9 f  P& p. f$ g1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
  A2 `' g& X: z4 H6 J0 G5 Y2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
- V' p$ l- {9 w$ O# J/ [9 P3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
2 C- d) f' w9 p& X8 }6 `
5 s' r. ^  `' c2 [所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
) b! V) G8 B$ P1 o9 O8 I, f5 P4 w( ?7 x. K& W9 J* z2 _
那么有些什么可行的办法呢?
7 t+ L$ C! K0 U) v为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。$ D. ~4 r0 q6 g. t+ {
1 M5 m% n: A0 Z; r& Z; V
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
% v& E) S2 f% A0 d
9 |$ F+ @+ |/ g9 R8 t/ t& C那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
4 P* A$ _! z8 O0 ]- j" q
+ k  o4 W) |, C8 O7 }4 ^http://www.ufoit.com/bbs/viewthread.php?tid=452
  \- E4 B; g  d' Q" ^0 b8 g* q3 R* |: W5 N# e# }
http://www.ufoit.com/bbs/viewthread.php?tid=241
5 J, t' I% U2 a5 Y: _. |/ G$ Z) _$ _0 H. v3 j7 t1 Q
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
0 w5 y$ F( W2 L1 J' P1 H0 D  U
' Q9 {1 D* L5 o/ a1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
4 G8 O2 l4 }/ c2 ~2 a2、Driver最复杂,也需要BIOS配合,推荐。3 q! h. A. [6 W' q+ b: b2 i4 o
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。7 A- G1 C3 T# J& T! \- c) i. o. S
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
* M  ^) j4 f: q' X; _* X9 Y  c你可以混合使用。$ _+ A* f1 D, E( H- `
3 R6 q6 D, Z- E
===============================================================, |2 C/ O1 ~6 Z1 v4 E
管理员的这句话:7 s* s- B7 c) r$ {" N
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
. a  S) x7 b- c7 v9 s; G
+ l0 ]$ {) {+ }. H9 G# {- @8 h, b予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
, U: T% X- z$ c/ E) L- ?: Q  Z! E( y: f) ~4 i% Q/ u  ^
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
: a. R0 b1 u" X) s) _' b: \, K" `' P
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?8 B( V' z4 V. ]
5 t2 ~$ C4 z. O! r7 L
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
4 S$ D6 }  K, }9 H里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
/ l6 {$ I" n! G+ e# z9 ?" @2 ?7 {. @% S, O
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
  C1 A. t# X/ P& o/ M( {你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。9 B+ w3 h4 I, }; J' E) g/ y$ R
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

) c2 A) o  N& j$ W2 a4 m
8 k4 y& b6 A/ r& R" q9 X+ d% ]您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
+ m, o7 I/ s2 Q; K0 `
- d$ ]9 s" {4 s5 ], n/ ], Ovoid write66(unsigned char Data)" ~  m- b8 {- @$ e- Q+ B0 N2 c2 U
{
7 E8 {) A6 b2 Q! S7 {7 K/ @: G        DWORD Status,TimeOut=10000000;  b' n1 r+ \6 A& e
        do
$ a- Z1 w, z$ T8 j9 f$ H4 ~        {0 G. Y  ?4 F9 E, x. u" k7 ?; z, j
                GetPortVal(0x66,&Status,1);
" y* y! D1 Q* t, w                TimeOut --;6 @7 B# K9 S$ }" Y( A# F- l  F
//                Sleep(1);
# |2 }+ ?1 A7 {/ M0 h+ V& f        }while((Status & 2) ==2 && TimeOut>0);
$ P. @+ K" x- x, w( T! q
( ?) ~  u2 N7 x5 e7 X/ t& T        SetPortVal(0x66,(DWORD)Data,1);; f3 Y3 r$ P; u9 g
}
/ A: \2 d8 U7 s- l$ ~6 svoid write62(unsigned char Data)
  X( A; {6 a" ~& f{
* u: r* d4 s/ K& p! R: b        DWORD Status,TimeOut=10000000;$ ]+ P/ R8 P1 [$ Y  f
        do
- G" H, y! d* D  |, v        {2 i# M. @" L/ M5 Y, x( g
                GetPortVal(0x66,&Status,1);7 N2 O$ |8 R3 g& v
                TimeOut --;
4 s5 H  P$ Y: I6 |, e# I* p//                Sleep(1);& R$ s5 \4 M* [& T/ V. ?
        }while((Status & 2) ==2 && TimeOut>0);
! ^2 T/ f. s1 G' K, l6 C8 }$ m1 c1 Q: P+ b9 A
        SetPortVal(0x62,(DWORD)Data,1);( d5 R4 E5 T! _: I: n% a* S
}
' r1 m8 |* }: e# }9 Q$ Cunsigned char read62()
# }1 i7 B( t1 {( a/ }& ~. M' `. S{) n" }; J: A% e% b8 Y8 T: N% q/ Z
        DWORD Status,Data,TimeOut=10000000;. i5 p7 y- @* d" _, @
        do- a; [9 w' N$ z% |" B3 Q; x0 v9 v
        {
4 y' s' B0 R( X" Z3 R- P                GetPortVal(0x66,&Status,1);
4 p5 f$ S9 C( w7 K                TimeOut --;
2 p" g" j* o0 g  E//                Sleep(1);7 `! s% f0 R/ b+ J
        }while((Status & 1) ==0 && TimeOut>0);9 F# V2 ]- y6 B
2 J+ ~* W1 r1 n- m1 r
0 \1 ^8 ?  |) V9 _" Q; |
        GetPortVal(0x62,&Data,1);
  L% @, u' N, s# _        return (unsigned char)Data;: j- C2 x$ ]* s# Q: k
}$ T1 o) G) y* W) w0 U, L
unsigned char read_ec(unsigned char index), J7 m7 [1 k& x+ e; _4 l* ~" H
{, ]  w- r/ L$ F; p/ r! G) v1 K* U
        write66(0x80);- }3 {& s+ k) Y, W* ~
        write62(index);
- l1 s  V# \8 q* t        return read62();
* G/ w" n" H% P) n% k8 s}
& @# c/ O9 N0 S! Y& U: d2 r. T4 Z+ M' w! j) q- Q0 H7 j; y
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1880) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。" S& r1 C8 d+ W* }, H7 w2 G; O
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。- p7 @/ u! q- U4 n+ A9 r

5 d; o0 t( b; i[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
8 K$ G; ]! o9 H& `$ n7 e* |  Q- q, @8 m5 I! j
% y. X: F. G3 c6 a' H1 X; P
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

1 L4 w# D  F" |6 z7 k+ f: W) v" f& k- L* S5 b- I% v5 i
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,* n7 H3 J7 ~1 J: H0 j1 M
: \0 Y' E0 Y  i' Y
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
( \0 ?% p3 `! R  A8 F9 F6 ^; t+ |& r$ `; a% ^# K. r3 s* R6 u# ?
3. Then set bit16 of the IRQ to disable it.
9 }- }" u) Q5 |+ [
+ K/ u8 J) G! F1 t) J    a.. Offset = IRQ# * 2 + 0x10;3 ^7 j$ I' G8 W' H; ]5 }6 G/ e
' n  k7 g4 q  {6 [( N
    b. Write Offset to APIC base,5 K* t0 p9 n9 d( x$ A
6 H7 D" a6 d& C! V0 g
    c. Read Data from APIC base + 0x10;6 l( c- C8 ^' i

1 l% R" k. n* ]- ^9 ~' O    d. Or bit16 to Data;
2 r* h7 Q* n( n* Y# }: j1 E# f
, k( v+ v/ o3 G8 d7 e& q1 C1 ]    e. Write Data back to APIC base + 0x10;% y# m2 c7 h/ ~' ?" b+ y) n
) h7 \" O* B3 P# Q# F4 P
) F( m8 `; ^# B$ u7 ?) @. [
/ ^2 x) o3 m, Z; N. l
You need to check APIC spec for details.
回复

使用道具 举报

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

) x$ q! j0 d- ^: \5 [. l9 s% V: b, Z. J- W
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。5 l7 g: g% J2 n4 Z8 z
==============================================4 L; h# q6 @( b6 p2 E- B
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
) h4 e1 Q. E  M, O. p% _) D3 W' Z% ]$ Y6 }+ X  j) O) k, Q
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)+ D. p. {( |/ Y- T' `5 I
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
7 a8 v3 {. u0 V6 N3 |4 A+ b; V, ]! M  Q/ M! P1 \, I
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。. p4 r) n6 W! _6 ~
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:; s* G0 }8 n* i- Z
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。, `% V2 Z0 {" o
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-4-20 03:47 , Processed in 0.045158 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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