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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
; D/ y" l8 e* r% d) {) ^#include <Windows.h>
! W' f4 K3 d* U8 u1 Z+ Q8 E/ v#include "WinIo.h"3 Y- N5 G" G9 G
using namespace std;' z! c/ w, l# [
3 j. E7 o- D8 P# d. t: _" E, M/ i: v
#pragma comment(lib, "winio.lib")
( W8 D* C5 ~8 U' N' [) R
5 z% T3 d6 F% n2 I& @; t4 M
- V# r; n" E% T$ W  Uint PMU_SC                =        0x6C;//命令端口' v- L8 W- d  z9 m0 s: c* N. F: y
int PMU_DATA                =        0x68;//数据端口. R+ y: \" p; Y, w* i! B: h
int RD_EC_SMI                =        0x80;//读寄存器命令
9 Y) E# r8 F  I+ Vint POLLING_DATA                =        0xE7;//CPU温度寄存器号  I/ e) p& a* e: Y3 l' U

0 I: M* |$ W: l3 \* LDWORD dwTemp = 0;
8 U# x, E7 }2 _! N4 i3 T
: B# X* \! f7 fvoid PMU_Wait4IBE(DWORD *_value);
6 K3 M! f( z/ K8 Zvoid PMU_Wait4OBF(DWORD *_value);7 M$ P' u, p  R: r. }% v1 n6 u

4 F/ q  ~  j+ L! z& v" X1 O& b$ B: ?6 Z. q+ P+ t3 ~  r' P$ f
int main(int argc, char* argv[])
4 ^& y1 \4 a6 z1 J$ I{3 c6 o' U7 d0 O: J8 @" e1 M3 W
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
  }1 n) p  y( T8 H! ?% V6 y# F( O+ a6 n  C: o7 I0 H
        9 t+ I1 j& q/ v/ D% E5 w: `
        //1、mov            dx,PMU_SC                //
$ C2 ]( f" _$ l1 e- n. k2 ^        //2、mov            al,RD_EC_SMI        //7 \5 r" c" h' O. b5 F
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了* f) G6 Q5 [5 j8 n
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
5 }) R( b, @# l9 C7 p7 `9 C+ H" x9 s3 G
        PMU_Wait4IBE(&dwTemp);
# N4 h$ V3 b5 [- B. g       
) C# P) b- _! W        SetPortVal(PMU_SC, RD_EC_SMI, 1);
4 y/ B9 ?, e2 d3 O$ A
% S8 F" A) e1 j" _        PMU_Wait4IBE(&dwTemp);
, ?4 W" ?* p6 e" _0 s- H4 U! F       
1 x& M* |$ o  ]+ ~8 t        SetPortVal(PMU_DATA, POLLING_DATA, 1);! R. S6 W$ |* a$ j* w$ r  p8 H/ j: n
1 [) ~& t( e  t5 J) l
        PMU_Wait4IBE(&dwTemp);
' o# R* S# t- X  V4 ?1 P- j! _- T4 V. @1 j  u- l' B
        cout << dwTemp << endl;                . _6 b9 Y. J, `& u9 d) F1 Z

8 p' x4 Z: V0 _( X9 u+ j        ShutdownWinIo();+ h& O& Y+ Q: b7 ]9 S. `

! M) t, |& X9 w' t$ @        system("pause");! f1 y* i, j7 q# n5 a6 L& f) \! h
7 S( H! E; b8 W" C% c  G
        return 0;
; ?* v. W2 W* \/ `3 C- `}
- B' t1 W/ z+ h, e( c
! g. T# m) l  K4 j" [( fvoid PMU_Wait4IBE(DWORD *_value)
) t" t: G( s4 s, o% K{; [  M* q1 d! [3 s  h
        //#########################################################   4 E& Q* ]) n) P8 ?( D
        /*( S- _# I/ u/ b) E( c& n* ]
        pmuWait4IBE proc   
+ U/ r2 w8 O7 k0 x0 N5 n  w+ x$ v1 J        PUSH        AX   & `. g1 j* |0 g& Z. w5 b# `
        PW4IBE:                 L$ [6 m! B3 I9 D7 _+ c7 s% U% E
        IN          AL,  06CH                                //Read  PMU  status   1 C) }0 L4 C6 C' R9 W% j
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
1 r" c1 l4 a# L        JNZ         PW4IBE                                        //Jmp  if  no   
; V; u' D0 G3 M! b$ L. p        POP         AX   # K2 d2 P. R/ k/ a
        ret     H4 F; B! Q, v" E
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
& c& z& @$ }' R- j1 u        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
/ @4 d, K" K! q3 Y* t% t        //######################################################### " V2 w. L, B3 o  C/ b( o
        /*do / U% P" Y! U9 n
        {0 S# {; U# z0 `8 J. @! I. ]
                GetPortVal(PMU_SC, _value, 4);
2 l9 `& Q$ z: l, O- _- S- W* e5 i# Y        }
2 X+ m, S. `) h. L& f        while ( *(_value) & 0x00000001 );*/- l5 @8 k" E+ l, k+ y7 H9 D
        DWORD   dwRegVal=0;: l* s1 w2 k  p' I  w! o$ C
        do
& c- s: l# i$ n, }        {  
: a! f3 s2 o; r. ]$ |7 I                GetPortVal(PMU_SC,&dwRegVal,1);
3 }' ^1 X: G' B        }$ i; r: Y! ?+ [
        while(dwRegVal!=0x2);" Q' }$ j8 h2 y& D0 M
' D6 M! b0 O3 K9 k- l5 d
}2 Q4 ~. q6 \" o0 u
6 \* i: n! Q, x7 d. j5 Z- p. ]
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。/ L0 K% X4 s2 w. Q
所以变成了死循环了。
6 {4 B: i! v" O; e# V% @7 O) B9 N2 T8 s& \$ \
我对硬件编程不懂。又不知道从何下手。) K% \, t# T3 K! |
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。2 n* N$ e/ i: B7 ^) E
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
" e6 i. m; A, ^$ ^; q* O+ ?/ U5 ^, C4 C! ?% K* }* W
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
9 i+ W6 a: Q% D' n0 G" Q1 v8 H+ v! V并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。7 p9 ~$ H% ^- u/ K  p9 v9 U

7 n6 ~5 K! N3 M. k! A9 d. h/ ^感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。4 X4 p' j  J. y. C. o  w
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.# X  X7 l. E+ ]
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突* \- b6 A8 K: ^" y# c4 |$ v
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.3 H$ m" i! N3 Q7 I; O/ [4 l* T: x
7 P, ]' D* G7 G$ u
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
1 \/ P. h/ M: o% i5 k5 ?2 q
$ q/ J, ?" `; S* V那么有些什么可行的办法呢?
0 H5 D4 d  r' A* \为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。- l) v+ T5 q: L$ u$ P" G
/ x2 J& Q% i7 ]7 W! W
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?! l" s( S, W- W' c- V; I) |
8 P5 P. C  r5 _4 N; Z, \8 d: r) U/ }+ @
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
  K" m! R, a* }3 g& Q( m; j3 r3 d' V5 S0 X) n; v. L6 F* L
http://www.ufoit.com/bbs/viewthread.php?tid=452; X5 Y4 Q: j* Z- h/ T" x
( M$ G7 {6 c$ S/ X! D
http://www.ufoit.com/bbs/viewthread.php?tid=241" _4 M$ q7 P7 ?! I" h1 N3 y3 k2 E
: D! I0 b: G, w3 t5 q) j! e4 B
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

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

! g. d( B& ~5 N6 S2 M+ K1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。; J9 @1 A$ m: T  X
2、Driver最复杂,也需要BIOS配合,推荐。
* a7 j$ y& j9 F+ s& F; m3、Windows API只能获取到特定信息,不需要特定的BIOS配合。* ?" S& E* z- W/ \
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
0 @7 M. @, a3 {. [* W! l1 N4 ^你可以混合使用。$ f% l$ D( u! A5 W# N- P

! H/ h& w; u* _& ~/ M, w===============================================================
, C7 R* g! u7 [$ @: V- `管理员的这句话:/ R0 e9 S' D# o0 Q% A& \  C
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?) t" n: g8 i" a) Z: z/ {+ x
: J( y4 l% [2 I- F3 ?
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵; h  A' n8 `* t8 l: a

# @  F( {2 K" L6 T  U* W7 D6 p+ f另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
$ D3 @1 H) m7 i4 M/ ?# }  _7 y# J- R4 E) C+ t7 o/ D
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
! w/ ?; N. G0 M& L! n4 `2 [6 @' `  a9 x) ~- \0 O+ S
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。; O0 x- \8 V3 g8 v% W/ D: P# q
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
* {2 i5 M, D( E8 W; o) a; ^& v' X
8 m# r- j. V$ I: K* x8 r我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
: Z, `5 z8 p  z你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。# K: A( n9 {. J- S$ T' ~
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
% o: E% ^0 m, Z1 A( F

/ q- o6 s3 W& w+ ?- M1 B您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
' i, z3 @# a7 |+ g) S3 K3 d! q& g6 R& P7 l% x1 y
void write66(unsigned char Data)
+ Z; a" l, r3 _0 [" p{
5 X, a, n5 ?' y8 M; U        DWORD Status,TimeOut=10000000;9 M! T$ p; M' s7 @" s9 D
        do
4 b7 i$ K: ?2 c( X: y; ]8 ~& l: ?        {
' n; t" G* y& h( o3 h) H2 y$ c                GetPortVal(0x66,&Status,1);& w$ Z5 ~- i* P1 T
                TimeOut --;2 Z, `9 z8 D, C0 o
//                Sleep(1);+ V5 g& K* g6 z& t, A- E
        }while((Status & 2) ==2 && TimeOut>0);; O. Y2 Q  |3 f9 ~1 @6 m/ s. i

4 ^9 b$ }6 n% K        SetPortVal(0x66,(DWORD)Data,1);
, X& @; ]: B% G- y}6 C/ z1 f  J7 Z1 O# I7 ?
void write62(unsigned char Data)( u- g' n$ |7 @
{
7 E0 h" y( e7 m0 U9 @2 h! z        DWORD Status,TimeOut=10000000;
3 o. |. W5 @; e8 g8 E6 L- ~( t        do. _5 _- M1 _$ a1 Z- u+ V; H8 J6 s
        {) ]$ x/ N' p, \. a' t" F
                GetPortVal(0x66,&Status,1);# F7 G& @- k' ~) l8 ~! A
                TimeOut --;+ ]0 N" D; G4 D  b* R/ @; l: u
//                Sleep(1);, h% @$ T% H( s, k  F3 @, Z
        }while((Status & 2) ==2 && TimeOut>0);
3 }1 K+ h' ]' q- j. D2 |: v& h4 \9 X5 }+ U7 k
        SetPortVal(0x62,(DWORD)Data,1);1 B: q6 K0 k! `# W9 }/ }/ l
}  F# x& `( k  ]
unsigned char read62()
% A. Q4 \  \" N$ X% [9 Y9 @{3 m, s$ c$ v) T9 P% V8 d
        DWORD Status,Data,TimeOut=10000000;
/ x/ w* I% v3 _; j" F+ @- r. [        do
! v' O" A! p! r        {: t6 O4 F3 T" Y: a& j
                GetPortVal(0x66,&Status,1);
% j1 k  T9 H6 j/ @) X* @; M4 `                TimeOut --;. z6 F5 G! U% H$ g
//                Sleep(1);
6 R2 R# V% V4 r( R, `0 y$ _        }while((Status & 1) ==0 && TimeOut>0);
' W! e4 C4 H) u! t+ H9 A4 p1 ]# @

; L! g' O: q& f( G  J/ d, X        GetPortVal(0x62,&Data,1);6 s2 m8 Y9 M/ K1 A* q4 J$ V5 o1 u+ l
        return (unsigned char)Data;
* J/ G: _# {+ u% K" ~}7 f1 R! r9 a" G9 v1 J. v
unsigned char read_ec(unsigned char index)
6 D- u$ h2 l1 J1 Z{, [6 u4 `$ \% ?7 D* d
        write66(0x80);
5 D! k# @1 B, n' _5 X        write62(index);
; T7 Z3 ^8 B: n* q        return read62();+ N0 S1 G- `1 t0 A5 A$ O+ z, z
}# g7 R. V& f4 O) ~4 d( Z

9 l/ }1 z  A8 {! H[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

  _) A5 }$ h8 N" O4 O( W[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
% t; ]- Q+ K9 X* Z" U7 b3 J1 U3 u0 K
! ?$ X0 t; ]* j6 ~
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

6 ~  l" E' J6 b* g! F' ~  s( R
& V. l9 _5 C  o5 C2 Z1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,; I5 H: s0 ^5 ?9 t
, h" Z3 I9 w# x5 s2 y
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
# q3 C! ~! t) z4 ]; @& K8 f- d4 L/ {  q  I& g- R8 e( r- a
3. Then set bit16 of the IRQ to disable it.- }3 @: I1 T( o$ ~: B3 t& k- ~8 ^

6 h' a6 c2 _7 o+ E7 }    a.. Offset = IRQ# * 2 + 0x10;8 x# J' B8 }, f; O4 m% W% F
" D! f4 R. L% U+ `8 O
    b. Write Offset to APIC base,
4 g+ j9 }6 {( Q0 k# g+ f
  R. e3 [: m9 E" t. K9 Q& y  m    c. Read Data from APIC base + 0x10;. X" u2 o+ o4 U$ r8 e, j

- Z1 G- L; A: m+ m5 G- w, `    d. Or bit16 to Data;+ Z! H) {1 ~- I. K' n+ e# E" l; Z

- w% }) D2 {: ]7 z! _    e. Write Data back to APIC base + 0x10;, C3 r2 u- U; y( {" d9 o

8 O' s. h" W; ^2 h , Q, F2 v4 O8 p  K& r7 \5 A
' M/ F" `8 _' K! _4 x" L5 Z
You need to check APIC spec for details.
回复

使用道具 举报

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

5 M+ {9 J- a+ L+ T0 L
- a; h; |6 M4 h4 [( j' \5 H+ ?' Y/ Y9 E 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
1 ^0 K. j" N: Z1 n==============================================
* s% m  K0 h2 T+ h4 M 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。7 q% ?# n1 \0 B9 x$ M$ d0 c
; [- q$ `) i0 N- n9 W
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
8 x1 c8 D  [. D! ]但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。: k" \* c7 o5 ~9 \7 p/ |4 Z1 l
/ j! i$ G; a' Y7 c( K
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。7 l+ q# ^6 d9 h  M) A0 u* p
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:- j$ b; z2 ?& Z7 G
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
. [4 I6 m- Z& U% A2、新手不要把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-1 09:13 , Processed in 0.187705 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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