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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
2 E% x$ i4 L6 B3 {#include <Windows.h>( R- }" v( x7 t; j- H) X3 T
#include "WinIo.h"
* _2 F- Q: v# C; {- J  t# V/ ousing namespace std;9 x0 I0 |( v. r5 g6 j
9 u8 s; p( v  y3 a
#pragma comment(lib, "winio.lib"). n7 H1 [% D1 H  l8 y3 F5 Y

* I2 X: B- N* \  n8 _  t9 z9 C. i/ L' p- h2 F) N
int PMU_SC                =        0x6C;//命令端口7 {. a1 }8 R7 T+ c8 c* c
int PMU_DATA                =        0x68;//数据端口8 a( `2 u1 s5 G& U5 |. n
int RD_EC_SMI                =        0x80;//读寄存器命令+ m4 H! j7 B5 s9 Y4 n
int POLLING_DATA                =        0xE7;//CPU温度寄存器号# ]8 S! t$ Q- Y

8 }" t* R  @3 s. C! HDWORD dwTemp = 0;. o6 p: q3 M3 t4 y
( g5 b) t) r% w8 ]: Z
void PMU_Wait4IBE(DWORD *_value);2 m5 z: z$ E8 v1 i3 f
void PMU_Wait4OBF(DWORD *_value);
0 I$ x) E' ?! a3 f) D9 ?. E! `- u) I+ y

2 F- ^, j) X4 ]+ M  f4 hint main(int argc, char* argv[])" M. E7 R' `( ?" m
{
: m9 N& l& G3 ?# W0 Z        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;6 n8 @- B8 R. k
& q3 h  |. o4 `
       
9 e% Z, |, T1 h6 R8 G. A        //1、mov            dx,PMU_SC                //! U# X( A  m' i- v' O  b
        //2、mov            al,RD_EC_SMI        //
* T5 z; Z' V% |0 G7 r& O        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了7 H) r$ e5 p; X+ ~
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。% S; T& H7 Z+ Q# W$ e6 C
* t* X! j9 k- {2 b* L! A5 @( W1 p
        PMU_Wait4IBE(&dwTemp);
: p" s  F  ?8 ~& G. m) E       
* T$ L) e  E& c        SetPortVal(PMU_SC, RD_EC_SMI, 1);
* y% p1 Z# q6 b6 B8 ?) a5 ]0 B8 g4 f8 Q2 P
        PMU_Wait4IBE(&dwTemp);, p3 |" i% K7 b/ F$ V( v( V" S5 Q
        * [; n4 }0 Z  o$ f8 d
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
8 O) I) n. R: u# ?, g: W+ z1 b' ^, e6 |7 X- x. v1 e" n/ A3 Q: A2 ]
        PMU_Wait4IBE(&dwTemp);
/ X2 @  @2 i) A/ L/ O
, q* _* b2 g! V$ _3 ^0 w9 Z        cout << dwTemp << endl;               
( s8 V; G1 }# ~5 C4 K' ]
' b( H) t9 E0 E6 z# b& f. y        ShutdownWinIo();4 F8 j  v* N  j- i; r* l& ?/ L7 a

2 y% U& z  u  P& r+ Z5 P# x: v        system("pause");$ a1 h/ b$ P7 p  _3 H

4 e5 u8 _8 A% ?/ N        return 0;4 T4 j$ b# l3 b$ i/ `/ i
}7 [5 O" i: ?5 a/ V. U& k) Q

& }, B* P/ U  @; W! Avoid PMU_Wait4IBE(DWORD *_value)
% ~8 I5 z( J- I! ^  q9 h  R{% Y2 c' f& s! U' M2 c) p& D
        //#########################################################   " I: n$ D" w* Y# o9 q$ C
        /*7 {6 a. q3 A# C# h, @. b6 N! j
        pmuWait4IBE proc   9 X+ R0 Z' ]; B7 S% {
        PUSH        AX   6 T, T: N9 f; t, `( T3 x) @
        PW4IBE:               0 H) x% b3 k4 |; ?
        IN          AL,  06CH                                //Read  PMU  status   
+ D8 |* ~. ^! V# b        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   - I: p1 ^- M1 f7 s9 W& A
        JNZ         PW4IBE                                        //Jmp  if  no   ; c# j8 b7 w$ k5 ^4 O/ N
        POP         AX   
+ f4 H% x" d$ c3 {( T        ret   
* e0 a+ @# H9 i, d3 I8 v! o& N        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
( D! X: \" M+ v# x4 |6 t% J5 A/ I        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
+ @' ^9 P2 |/ @: k" v6 ^        //#########################################################
4 _/ ]" c% r9 f- b) R        /*do 6 A; E4 l0 `1 O3 I9 Y# `
        {$ V7 a8 S$ |& ~8 c0 E
                GetPortVal(PMU_SC, _value, 4);
9 u$ P- V* o4 Z        }
0 k8 W! M+ q+ v/ O1 D# `        while ( *(_value) & 0x00000001 );*/5 w3 a! W! P% v& l5 \2 d# r+ r# Y
        DWORD   dwRegVal=0;- ?# t7 A3 k/ S6 s6 Z
        do
+ G: B) g8 p& g        {  
6 d+ w+ T3 m, z3 {0 O. i' h                GetPortVal(PMU_SC,&dwRegVal,1);
$ ]  x/ G# \, \% H        }$ F( ~& ^# k! U" s& _# Z! r& f2 G
        while(dwRegVal!=0x2);2 B' p6 V2 n1 I- Y" H" K

- h, _; X+ \8 B# l+ v- r}
; S8 n3 }' }7 i  L8 i7 Y8 b
/ g5 l! E/ s7 [9 j$ A# A以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
9 l2 A6 V6 `& |( {0 ~; E$ C* |所以变成了死循环了。; h" A& m: j  U0 i

4 M! d& W7 @4 m3 I; h4 e* s! l# P我对硬件编程不懂。又不知道从何下手。
& _' O) u7 U6 @3 i# r) H我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。& _% G; k* ~* M1 H4 r  N" P
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
" n/ _& |& }5 w0 J6 Y- [- X6 X5 Z5 Q, g" ], W# Z
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。+ O7 s0 d6 {& A4 A  O$ X3 T
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
- K  d& z) b/ l. X# I6 @4 A
5 a' G: I8 \9 X+ w感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。# R4 ?" \& u( N
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
5 m# h4 j- w7 H& k& _5 F2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
* @8 ?2 b% P6 Y4 B3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
: l8 z! a, B" _$ u* `' D. d6 [
' o0 v) N. ^! F9 P* K! N所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
/ R* _6 G( s4 z& ]7 ~; u9 k' g" C0 ?* j& I  c2 ?1 v+ Z1 k
那么有些什么可行的办法呢?/ J5 K/ ], }; R8 ?
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
( K+ z  H" o* C7 I) w! X1 \" }# T  u# |! l6 e( M. U
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
1 D7 B4 G$ E( i" D" m) e0 e) m6 `5 Y* m! Z4 @; Q8 {+ d- J3 C* n
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
2 z* I8 q5 K8 Q+ |$ m& j: _9 ]6 q) h/ }: D8 ?6 e3 Q
http://www.ufoit.com/bbs/viewthread.php?tid=452
% p5 P* m; w# G. {( C7 Q) Q( |' @  g& |( w  ?
http://www.ufoit.com/bbs/viewthread.php?tid=241
- e: m: x1 {. ^' [
0 p/ z  A. F2 b) N看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

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

) [" u0 y: P1 u) q0 J. ^8 [1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
- u5 [3 F! \7 @8 U8 k6 @. V2、Driver最复杂,也需要BIOS配合,推荐。; {9 ]- C5 Y# J* i  m
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。/ v+ ~, U- K/ S& z6 L- N  }3 q
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
  O; J9 i5 v+ S! D. G) V" Z你可以混合使用。
4 ?, P0 d! O* p- z+ a
# t& W8 z: n% U: |+ L* g===============================================================6 J4 }, h& ~  J+ Q, B& e8 B
管理员的这句话:
  o" l  s# z0 C% q, A7 X如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?% I5 B; X% N) U! k+ l7 ]+ T! L

9 l) U4 J; _) X2 H1 O予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵1 ~3 n4 ~7 Z: \2 a  {% m+ x

4 e/ t2 _2 X& K! W. G1 u: k$ X7 ^; u另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
% ]8 h* }$ w: K$ C* s7 V0 C8 D
' [' @  o9 G5 U% Q这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
& l* D2 y# x' S9 S% C7 y( x, R5 s, x$ h
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。  E) V# Q% |+ j! i0 C4 y
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?4 g0 ^" B/ |( p1 o& Q

+ f" [! D! |( q我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
/ Z3 N/ `' m4 e. N0 @7 b- d你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。8 n& Q) e5 m! _6 Q; r( E
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
; X, {& |3 @  W" R% B/ H

* ]  |& J) \0 ~' f您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
2 n& k1 j- h2 K% N- W+ v; y
, q- u& e0 }5 F  `* {void write66(unsigned char Data)) @4 k" F+ C2 G( _5 c
{! a( d5 V$ A  u! g
        DWORD Status,TimeOut=10000000;
) y  O. k; k3 a7 I3 j# I- ]        do
* ^) s* J1 R# K$ T7 m4 [8 e        {8 [. a) ~/ I  P. {- A
                GetPortVal(0x66,&Status,1);
) |" k" l6 V: E! a+ h5 X% `                TimeOut --;# ?8 F& h" f' m- g( N& ~) H1 O: J
//                Sleep(1);
+ G: j& J/ W+ P        }while((Status & 2) ==2 && TimeOut>0);
* ^: g8 z  r, k$ j5 s7 l' i2 G9 p$ S: c- |# @( \$ ]
        SetPortVal(0x66,(DWORD)Data,1);
& }* ^2 A$ I) `2 w! V/ [  f: ]}
/ @; t' M: R) j& |2 tvoid write62(unsigned char Data)  d. n/ s0 s8 T6 U! W$ Z
{; `- Q- l/ [. ]$ l5 ^
        DWORD Status,TimeOut=10000000;; E0 ?" @% N9 N9 X/ y6 c' G
        do
& D9 [( s! r7 b" d        {, _8 d0 X8 Y# B. Q, D0 F( x
                GetPortVal(0x66,&Status,1);/ i/ q2 z+ a9 M2 P, j
                TimeOut --;+ ^$ I  C/ Q0 k1 A. v: U
//                Sleep(1);2 Z* r1 ]) z9 e7 U! q( \
        }while((Status & 2) ==2 && TimeOut>0);2 X8 }# v' o6 _0 w6 D

1 |, u/ |+ o8 d7 g) o( R        SetPortVal(0x62,(DWORD)Data,1);8 ?; c3 F6 u1 {  ]0 g7 r& [
}
2 T4 a5 {% R- I2 P( F3 s- {8 funsigned char read62()
" [- t! M$ F* d( t0 x1 U{+ H' F% C* a! C3 x! p# N  r& m
        DWORD Status,Data,TimeOut=10000000;2 ^* |' v  v* H: J' G0 K
        do  e$ C* v2 W9 M- ~8 A; E, p
        {' m5 e" R' p# G: O9 O; |
                GetPortVal(0x66,&Status,1);2 o5 t" n7 H5 y; S' X
                TimeOut --;
/ h4 n( }; X2 X* i# z$ t//                Sleep(1);5 ]6 Y0 Z8 X9 X2 h
        }while((Status & 1) ==0 && TimeOut>0);
# c1 z* F; R$ i1 b( e& x+ H4 g
7 l" p: s9 \" M8 W" n3 Z. `7 i6 p, x$ I# x: a) k
        GetPortVal(0x62,&Data,1);3 J* V( f9 Q5 i8 M; T8 V6 w" }
        return (unsigned char)Data;7 F$ n$ P3 A3 d, Y
}
8 b. M3 z, h# Y% p2 N. w# `unsigned char read_ec(unsigned char index)0 u: D) d/ j. @/ u
{
9 X# E" C# K( b8 ]! e5 ]        write66(0x80);
# G. a- z1 [+ ^        write62(index);
1 ?4 n! |/ G# t4 _+ H        return read62();
& z$ r- L. H( L, ]}
0 U' \9 R0 X( A6 O8 z$ o, s/ I" i1 |6 a# E# N3 d2 N1 \
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

# i( m0 _0 _9 J% X[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 $ \. r( R" G# ~' U' G+ I2 l

# o+ v: W: d1 }; i& ~# l4 Y0 ~+ v* Q9 z2 P, y& \
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

- t+ h) B/ v5 h' v; K6 p; _
# c# X+ T9 z% R% I! z, E1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,2 g) x8 O" r/ h' J4 F7 C/ |

  |) S; Z& ]  Y9 N  q' U2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
6 z, n: K$ M6 R* P- @: b9 N! m$ X! h+ x6 k1 U
3. Then set bit16 of the IRQ to disable it.. {' z. g. d5 R  W* [6 h
9 P# o2 a- H, D
    a.. Offset = IRQ# * 2 + 0x10;+ v6 G4 B; _* A

- `4 P+ @9 Q9 n% e# r! Z7 i    b. Write Offset to APIC base,3 p1 T) |* l' o

& @' w3 U7 r, b+ y    c. Read Data from APIC base + 0x10;- T. K# F. K% @( k: K! |/ Q" t9 Y
' t3 U3 N* p" W( n% @
    d. Or bit16 to Data;
7 H( \. z/ L% j, }( S& G; a
0 Y8 y* |' h* N/ ^7 h    e. Write Data back to APIC base + 0x10;3 v# B; j1 h; O( s1 u: @: a4 |

7 s# s4 n- W; S / @( W. E, K" [$ _3 @
, _# G$ J- w  V
You need to check APIC spec for details.
回复

使用道具 举报

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

! g% Q6 q& d$ I/ L$ L+ K' f/ I) V9 p
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
; L4 y' T4 K( F* K==============================================
, `5 t+ K1 A  O* r6 u( {- i8 a; T 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
' ?$ H; x2 Z2 _3 l: D
) `( r% p: @$ [. B' W因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
: G& E* R$ p: M3 C% X( X9 C; }1 i但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。' `7 [' d% s! h6 @7 m# {
0 t0 C  X  r1 L) w0 v4 _
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
: p5 z' l6 |/ K" u当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
( ~' g! X" ~: Y6 s1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。+ w! [% {& g- }1 @* Y# p) |+ k
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, 2025-12-13 14:05 , Processed in 0.130132 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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