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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>: F: B- y( l: F" a$ E
#include <Windows.h>: c, V) N# o& V9 T8 }' x
#include "WinIo.h"
3 u6 Q& N- ~# K7 I$ g/ Y1 Cusing namespace std;
# T  C  e5 {1 j2 J6 M
3 C3 Z: W7 O% M+ |7 U  S5 B#pragma comment(lib, "winio.lib")+ m! b3 ^( V+ N5 K% B8 Z3 l
0 V, [1 s+ g) N! g( z/ b, N
8 u" _/ E, O) r7 {0 @: G
int PMU_SC                =        0x6C;//命令端口
+ P0 s6 D4 k, E7 P$ n  eint PMU_DATA                =        0x68;//数据端口; D- F" \# r# B, |5 z
int RD_EC_SMI                =        0x80;//读寄存器命令
; |) V( w5 b$ g+ ?int POLLING_DATA                =        0xE7;//CPU温度寄存器号& F2 e' ~" d  X: B

( ]& q! \( |3 Q) f4 Q2 i1 U0 ]DWORD dwTemp = 0;% o2 Y) _; v1 `
- C/ I7 z8 m" d6 R+ _
void PMU_Wait4IBE(DWORD *_value);' R# z# U! W( Z
void PMU_Wait4OBF(DWORD *_value);
6 v4 V" w6 b8 E) ^# `2 {
9 }) }7 D/ x0 b8 }6 ^7 _( J5 J) x1 Q) q7 v4 a2 w) ]4 F
int main(int argc, char* argv[])& [! ^. G: u( [( M: h! ?% O
{0 ^1 P( r+ {0 I+ e) ?4 C7 Q$ X
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
6 Q: J7 p9 n' _) G3 M4 c3 V- m0 l. }& G
       
8 g# w/ I7 |1 x0 C        //1、mov            dx,PMU_SC                //
6 @$ @6 ^/ q+ W& R0 i/ y; B        //2、mov            al,RD_EC_SMI        //
! W, @& j; ?# ?) p+ n! k  f3 A/ v6 c        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了( {* ?- a. [0 g' B
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
, D1 n4 d" \/ v0 X- d/ t3 d4 y
; y1 G; u6 f* r7 `) v" H* p        PMU_Wait4IBE(&dwTemp);
8 K) |4 p" A! r) W$ Q        9 _2 S/ x/ f- f# |4 C4 |8 @9 r
        SetPortVal(PMU_SC, RD_EC_SMI, 1);- o( d/ z  [7 {* m' ?

- X- K* b8 v; b* p" ^) k2 w/ T- s        PMU_Wait4IBE(&dwTemp);
2 C5 }* k/ Q) @2 M        ! h$ h$ p5 w+ `* e' H
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
/ W1 }& E. a5 O" _- I- n3 `5 f
1 \5 N9 R1 X  y! v2 f, z  n        PMU_Wait4IBE(&dwTemp);; r- g; w2 B- O0 v; Q- K+ w
1 {0 [8 O* I3 f: ?, f  F( S
        cout << dwTemp << endl;               
' X- Q: Z/ p; x0 h9 T1 Q% h# A9 t3 K$ Q* e7 C6 b' X! A6 @7 ~
        ShutdownWinIo();0 w3 N( b4 p2 |0 b
* `/ i6 `: s2 D. u+ f. _" P/ z
        system("pause");
+ t) w+ X+ |& x: }% o# M. ]1 k7 o+ d4 R! b* p' {) ?
        return 0;: t" c9 ~: T9 ]" ]4 I: @
}
; _$ p  u# M, E2 Y$ g& v/ L) l$ F$ @# k  j# m9 Y, [
void PMU_Wait4IBE(DWORD *_value)
1 d( A0 u$ y# P{8 |4 k: R7 D  C7 r
        //#########################################################   . L. \( B" ?+ H; k7 N' B/ V/ \
        /*
1 J, u, m8 H0 X9 M" O        pmuWait4IBE proc   
5 T$ l2 m  M4 a$ y1 y        PUSH        AX   5 D! L4 r3 U% L* J
        PW4IBE:               7 U  @9 Z! Z* L5 Q3 g
        IN          AL,  06CH                                //Read  PMU  status   
, l$ X, @. ~% U9 p: s# P        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
5 c) `; J0 M% @        JNZ         PW4IBE                                        //Jmp  if  no   7 m9 D( o2 z1 [  A+ p# R
        POP         AX   
4 @1 n% l3 [, E1 }# k/ h7 F        ret   
* m# h+ y" x. S- \3 [4 Q. b% P        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
4 r3 q' q( E9 z4 E        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
- L5 }  u! o1 d' E) Q        //#########################################################
  u$ O: p/ W- l  e- y        /*do 4 E4 Q( P4 J% ~% H# {+ E
        {+ @9 R) {4 K/ l4 y* W4 P" d
                GetPortVal(PMU_SC, _value, 4);, ]# \- j$ j/ r9 L! Y% v
        }! u, `; L& |% k  g% I
        while ( *(_value) & 0x00000001 );*/
& ^, Y; m$ H5 D/ g% j        DWORD   dwRegVal=0;
% f4 T+ v" g% ?/ {" @4 E        do" a# p0 [- _- Z+ n2 n6 [
        {  
# K$ w2 n/ Y1 ?                GetPortVal(PMU_SC,&dwRegVal,1);
. a3 M" z" r) A# w8 l4 V        }( ^$ u8 y6 u2 F
        while(dwRegVal!=0x2);. V; W# t( w, g' X

) K" [$ Q9 X7 N, b}+ S& p, b9 k; g/ H* q% L# @) Q

# J! W9 E; D+ T9 X% k% I以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
; Q. m9 r3 ~- l: m* {  F所以变成了死循环了。
! C3 l5 Z5 n( R7 a' I6 ]3 k8 U* z7 Q) y! M: B. w5 g" J* ~% U
我对硬件编程不懂。又不知道从何下手。
1 {/ U0 S- [8 |" N: N我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。( B0 Q0 b2 w- x8 q: J8 @1 |( _
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
; Y1 Z: }* _8 d9 K2 u, X6 m% z8 I) m" K
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
2 k: J' b9 F$ P& o+ @并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
5 h$ W  D- S' }5 x% Y: _) d# c6 v& x
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
9 g7 d8 e. ^. u6 L4 C. j. m1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook." J' c$ e, n0 y0 l8 ^6 W( P
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突( o, O1 O- M8 ]
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.% K; p# Q( m  E8 W" n  B
, g9 \* B7 `' F: c4 B' T
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
3 `7 d' d; U( n
$ s) @. P8 z# m! ^9 M那么有些什么可行的办法呢?( \- H1 _" Q! b- R& u# w5 K
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
& w6 P/ k  R- K2 R$ @9 V  o  ^) k. W) K% r* i$ n' C; w2 V& b
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?. Z' ?" k% g" C$ {' J

2 e8 r* ?. k" ~1 P- f3 G那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
/ w6 A& S: e5 g) @+ g# n% g0 }, z8 I' i
2 t" B$ L+ x2 F  chttp://www.ufoit.com/bbs/viewthread.php?tid=452: r* \/ ]! J; {, T% {5 u

3 Z  z3 x2 M4 N- P) d. F) q# Z3 b- Bhttp://www.ufoit.com/bbs/viewthread.php?tid=241
  X# H( Z* d4 g9 d0 R9 O) `: i) }5 O" w
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
: S/ |" ^8 D3 P8 V1 D% A# ~
; C3 Q9 q) [: |* m( a$ |  m6 z1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。0 m. Y8 J- X6 b( M
2、Driver最复杂,也需要BIOS配合,推荐。6 Q; ~, k2 ^# [( O, ~8 g& i' X
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
8 i7 ?/ z: G- a' }% E4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。& b2 U9 f; W# L. _
你可以混合使用。3 [! d# ?7 `1 K5 @/ j3 b( T

" {3 @% i& v; K. U0 O===============================================================
, Y( D; Y2 C8 e: F/ U" _* \管理员的这句话:
7 Q; x. _* l) a9 D( |: L' l2 u2 U( C如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
: z, Y; Z# J/ S1 |) {) |% H$ U( ^6 L
8 I5 A4 ?& n& U7 T) L予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
. C! i/ S0 l" Q
- Y0 C4 F5 o" j3 q4 v0 n另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
* t- I9 g$ l1 p: Q2 @& v0 `  G
5 A& `7 A% d1 A( Z. V3 z这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
9 L" T- l4 A5 ]" N* u2 y' W8 }  u
- B+ e# E0 U5 {% [还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
& G3 R; f8 V/ L- f/ \8 n% E5 V里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?, O- U9 u4 K& X* b2 @( U

/ ]% ^; p; [4 K- P! [/ Y我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
9 @3 l7 k" w! `# L% A+ t% [4 o) y) Q你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
5 [. Y" J$ V+ l) e- D3 p2 l1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

& l# X/ q6 [+ b' u: u
) E" \) S9 V* K# I您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
6 j1 J/ s2 E7 v! D/ f( }2 J/ e  M6 d+ s( P$ N* b
void write66(unsigned char Data)- i- K  s- t7 n. ?$ w" T2 o
{
# W0 O( b+ f  _1 i4 Z; d        DWORD Status,TimeOut=10000000;
* N' p" a- Y1 q) x4 \4 m" K' t' {# g        do
7 i3 F+ W% A* E+ P$ s3 \% S        {, d, v$ A- I3 |; J3 ?- N# E" z
                GetPortVal(0x66,&Status,1);
) ?# B/ ?: _3 n% e1 i& t" E                TimeOut --;0 R" l3 X# F' y& h
//                Sleep(1);4 e! d0 K% p/ m. {# _- u( L$ B) r
        }while((Status & 2) ==2 && TimeOut>0);/ ^, j9 W/ g! [( ^6 Y0 ?
8 Z- V+ K5 N8 p6 H7 t
        SetPortVal(0x66,(DWORD)Data,1);
( ^* N# c% s1 I" V1 Y2 c}4 j) u* d, H4 \0 c/ D) _
void write62(unsigned char Data)
7 N3 U3 y- V2 M8 x( a{
/ y- Q5 o/ {) O& l* ]        DWORD Status,TimeOut=10000000;
! m) V' r- ~9 A& f% H' @$ u        do( `9 H  \1 e6 [  c' u% i5 K! k
        {. r0 d* B- n' ]# d8 T( Q
                GetPortVal(0x66,&Status,1);
# e: N8 {' ?! m' ~6 W# r                TimeOut --;" I/ H+ [1 I, r2 z  k
//                Sleep(1);( }+ o7 h: F/ I
        }while((Status & 2) ==2 && TimeOut>0);
# C- S/ k: k1 |" W% Q
; p" k3 {. H% a  X        SetPortVal(0x62,(DWORD)Data,1);. x: O. C% G% d7 b' |; v# x
}
- @. Y' m+ S$ Y4 V! Tunsigned char read62()+ Y  h, n$ N6 M* u* |6 P) a
{8 {, ]8 N* {% C
        DWORD Status,Data,TimeOut=10000000;3 k1 u3 q/ V+ _2 O& m' S8 g  U
        do
' i% u3 ^* D3 L7 K( K3 |        {% A1 J+ f5 U. }: r) n/ D
                GetPortVal(0x66,&Status,1);
% P2 A: B& G' M) `9 x( r0 a" R; ~" ?& n* d                TimeOut --;( n% A6 E/ e/ P- o' A! ^$ t
//                Sleep(1);
' e* N9 F9 C; f, S        }while((Status & 1) ==0 && TimeOut>0);/ N% B* G0 m  `. O' ]8 B

/ @3 x. f& q9 C
5 D0 Q6 c/ O8 _6 c! q; t        GetPortVal(0x62,&Data,1);) V* i9 i# ?2 Q6 i+ [8 v# B
        return (unsigned char)Data;
. a; L, j8 F! h- o0 F2 B8 d* y}) _3 c4 X/ V) E
unsigned char read_ec(unsigned char index)
1 l8 [0 S: g) x5 l% v& W+ k9 V{
5 @) ~; ?6 p) y8 q7 L2 n4 G2 a        write66(0x80);) o/ G4 W6 ]" D2 b* `( i+ [; ]
        write62(index);' T- [) @' Z+ e: A( ^( z: ?$ n
        return read62();
+ K4 R# `! M5 [; R4 ?}( K) V, m& ]: [1 B8 T# U! z3 }; x
" Y* p% k1 S& q
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 629) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
" u: j$ ^" w4 }, n$ e  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
/ h( u2 |# D7 }5 C# \# H: `. E8 u
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 7 q$ x4 N9 V- `$ M, [, C

4 x! Y0 Z% X& D2 Q  n& w! ~; s4 _, S6 k: O& Q7 T+ F
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

- k/ D4 k0 V+ ^. L( z$ @8 Q
$ K! ]0 ]2 k' p1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
8 w  l0 E; p7 z3 y% n, K: O- x# D) m: {
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.5 p9 F% }  |' f% M* I4 i
6 Q' y8 |9 [& y
3. Then set bit16 of the IRQ to disable it.* R  n& M5 @; z
' l* w0 ~  [* L. V, W) O
    a.. Offset = IRQ# * 2 + 0x10;- G" M0 c7 \, u' ^- b! d6 t

% P$ ^4 N" o# ?- S- e5 [8 s- N  Y    b. Write Offset to APIC base,
, |5 _! }/ E; ]; T( \7 {. b! }* e) y6 z2 U
    c. Read Data from APIC base + 0x10;4 J4 }4 I9 V3 P2 u0 ~: H
  O6 s  d$ H1 w2 V8 ?2 {
    d. Or bit16 to Data;
6 Q* e( L. q1 R/ Y1 ]4 W! Z6 }6 }: }# A( f6 h, }
    e. Write Data back to APIC base + 0x10;- V8 i1 m, _& l5 y# Q7 W2 P
' M6 S7 G: t& P

7 h, n) i6 t& ~8 \( o$ H3 C# E! |8 N" A+ S2 }
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
1 V( c! b% [- e" A0 n545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
# G8 {0 v( P- D2 N/ ^" \  s+ n
1 b6 ]& ?" p& g7 _7 k- `: C
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。  C" m( E0 l2 r% {
==============================================6 f  |+ a! ~4 \5 e- |
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。. U% \  k( S7 @3 M& G( s/ u

( u3 r0 P/ a; n: e3 V0 K& {, R/ R因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
2 i+ P: ]! Q3 c( k但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
/ I4 s: c# P- {4 B
$ ~& M$ A4 U0 X: p3 T+ J  M' Q4 x因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
6 Z  c5 u& N! l) S/ D! X" N- ]6 k当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
' I. G! |" [& A3 ]0 j1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。8 p2 r& M; D+ x1 g& c  R2 p
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, 2024-5-20 12:13 , Processed in 0.029392 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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