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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
  j) X. s, h4 u* t; l7 B2 d& {#include <Windows.h>
# _( v1 s$ a$ }' |. m- R% F) g0 x; P#include "WinIo.h"
: ~; _7 z/ k& H3 E6 r1 o3 F8 Tusing namespace std;) u8 L; t+ t6 ]& \4 s$ |* [0 \

* T! d$ m, c- |9 K% q2 v% S% i& ^#pragma comment(lib, "winio.lib")) A' ^% k! @3 Z. D0 j8 T. }

& Z. b) x2 d* e2 @- R& |$ L) `+ n( V6 z) C: S8 P7 ~$ y; V( |
int PMU_SC                =        0x6C;//命令端口
1 J( l, l: a" O- P" w: \int PMU_DATA                =        0x68;//数据端口
' E, [0 c+ g6 H! xint RD_EC_SMI                =        0x80;//读寄存器命令
4 E' G8 U: T- N, m' lint POLLING_DATA                =        0xE7;//CPU温度寄存器号
5 f! _. L! T( V" r4 i* R8 s) \3 w2 d3 G4 w7 J  y1 U5 X" W# t. G
DWORD dwTemp = 0;4 g) Q4 b2 T& N: X( `0 w9 H

+ B! X) I5 E5 h8 P  P7 y4 Lvoid PMU_Wait4IBE(DWORD *_value);
* [* d' s1 O9 N- y+ Pvoid PMU_Wait4OBF(DWORD *_value);, I: t% `8 ]& H( K( S7 T
$ S" c" \/ @9 ^7 B6 N$ s' \

+ y7 M  M% ?: y+ Z- x( Xint main(int argc, char* argv[]); A( w. p  }. b7 G6 ]6 E
{. L8 E3 k, J! p/ |; d, j8 D( h
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;$ i2 h$ J% y  f( k3 u' x3 g
% O1 p( i" S# G3 D1 G1 v  {9 \
       
+ R6 l( y2 o* c8 M& L        //1、mov            dx,PMU_SC                //
( O7 }3 x5 L" l! F* g- O/ k        //2、mov            al,RD_EC_SMI        //) \4 B3 i1 k6 X) U  `1 Q/ [
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
$ M) W, z6 U/ ?$ r        //4、out            dx,al                        //将读寄存器命令放到命令端口中。& B% R7 P$ D5 v: Z

1 |# R1 }: l$ A* N( Z  l        PMU_Wait4IBE(&dwTemp);
7 |* s! B7 y5 w/ N+ R        : ^9 A( A$ [" ^/ B
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
/ Z4 _+ ?' t9 e; x
) V" G0 l1 ], O- d. c        PMU_Wait4IBE(&dwTemp);
& o& \3 Y9 h& M& e2 S! L; P7 d       
9 E5 ]$ h* U) \        SetPortVal(PMU_DATA, POLLING_DATA, 1);
, [. P1 p4 e! w' F7 z8 V) e
  T& j( `/ ], x6 T        PMU_Wait4IBE(&dwTemp);* ~& g* h8 d  i) M6 o. q& ?# u( w1 V

& w, t0 |6 y9 l8 O        cout << dwTemp << endl;               
) p- i; F4 \4 K/ _- [  @  V
" l4 q: H5 f# R: y2 W( P, d        ShutdownWinIo();) }  l; G/ z9 K8 @% s

% w: K; f7 ]- x6 C3 Z' Z        system("pause");
% x. o$ C( a/ z) R4 w
- _) V4 ]4 T0 v3 n5 H- i. Q2 H* z6 L        return 0;% h7 r% x5 \( m* A+ D9 f
}% O* H* o; ^) e% U: y# q
) ^2 h# p$ ]( U' X  G; E
void PMU_Wait4IBE(DWORD *_value)2 B* t: }3 y$ ]& e
{
: n% H9 [- ?+ @* `8 v        //#########################################################   # W5 S* v) U' O9 Q) j3 F' U4 J0 |8 [! y
        /*
* Z/ A+ \9 x, F0 L: E4 [  t        pmuWait4IBE proc   / \4 y1 Y: _% m! U# A  p/ L9 A* W& Z8 K
        PUSH        AX   $ }1 e! G/ h! s, j6 B1 E$ t5 V
        PW4IBE:                 k2 E6 m/ `7 q  |( K6 u
        IN          AL,  06CH                                //Read  PMU  status   " c* ~& X, ]' G/ H. h  F2 v
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
# z& K+ I9 i! G& J3 a. z        JNZ         PW4IBE                                        //Jmp  if  no   ; p0 M6 t* O: D9 P2 n" @- e
        POP         AX   
. \) H" O5 H0 E5 I# {* e        ret   8 U3 ]7 _, v: m" q. _& k
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE2 y/ \% F1 ~) i* x0 P
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空0 M. ]; g' \5 V/ E8 d) N% R  D
        //######################################################### 2 w1 i( y( J. U- f$ E4 Z! h! {
        /*do ! f- U1 v) b4 N% j5 s3 x
        {6 k; c* N; y* A. F& Y+ G0 C4 W
                GetPortVal(PMU_SC, _value, 4);4 s6 m5 ]+ x  y
        }
6 Z$ x7 I4 [$ C. a) K- J        while ( *(_value) & 0x00000001 );*/
+ b9 S1 c5 N& x* k# q" _5 N; I" G* ?        DWORD   dwRegVal=0;3 ~, d& o: M( D, G, W! F! I
        do- r& Z$ }% q& _
        {  & ]6 b; i8 t/ P" h  D$ G* b
                GetPortVal(PMU_SC,&dwRegVal,1);1 x5 V0 F/ \% P
        }
9 R$ K8 O1 s) A# s" j1 u. M        while(dwRegVal!=0x2);
+ o5 ^  p- |3 N9 c: G6 e: k. Z$ H3 }, F  B5 J
}
' x( w. N3 L/ n, [0 @
3 z( {' @" L: ?6 A9 n以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。* ?% E' }! A7 O
所以变成了死循环了。
& Y4 [+ D. ^: ^* w7 r0 b% @  E2 Z4 I) k0 Y+ |  c+ j5 t5 p( z& b
我对硬件编程不懂。又不知道从何下手。
  f- ~9 T2 H# o; b" z% k我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。0 _1 V, y4 v9 M" B3 w' p
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
* m4 _8 X2 {  u6 x: L3 t. V6 }
. q& T2 E8 I+ e" K我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
$ N: [' n1 v- w7 J6 Y! T( o并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。$ x# w1 L& n8 e- J( p* w

4 E4 u9 }" u  _/ y, ^& v感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
* _( M; l! s3 q- X: V8 M( _! P1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.9 A3 [6 Z  x) _5 i% P3 L. q
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
( R+ e( ~4 k+ B, E3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
) R2 l3 g+ F/ q* z' m; v
, b3 H2 H2 m" m& }0 z& _  {" z! y所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
; ]: `% q4 k$ d0 m0 I
; ?" v3 C. g( P0 }; J那么有些什么可行的办法呢?& R6 |0 ~' U4 N3 s3 q/ c5 n
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
5 ~8 y' ?+ }4 T5 L$ ?$ |. N6 t& d0 k& ?; x' c
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?0 i' v9 `' F& f5 k6 d3 c
9 L% k6 |1 H* L2 ^' f$ [' G
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
& K6 y7 D- w, Y" t9 b! B$ p+ e9 p
6 f8 q( H. W" K# B% R8 t8 X! B  l, q+ Uhttp://www.ufoit.com/bbs/viewthread.php?tid=452; G3 T! _5 _; T  p# y6 m- J
5 j" @) }4 [$ p& ^+ X
http://www.ufoit.com/bbs/viewthread.php?tid=241
! d" M) E. x; e; z4 H+ R) c
" c6 A( r7 o4 }8 r4 F3 u! v看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。0 j$ g. P! W4 I4 ^5 g- q
1 {( _: ]  I4 t& ^$ w
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
7 v  }2 ?0 Y; j6 ~2、Driver最复杂,也需要BIOS配合,推荐。: L. |8 L% ]# |; B
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。0 i% K3 [3 N1 e' w" n, k- V1 Q
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。3 v* T/ H! W# x! K5 f$ s
你可以混合使用。
+ L3 L5 [. F. A, |( T- J0 |5 c( p6 k9 |* l0 @
===============================================================
- {3 e6 L0 m( k' R  S" x管理员的这句话:
& b7 L- C% b3 z7 P( t2 g% V" ^如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?- O. I6 N5 ^5 ?$ U0 E% X
' ^' _  V; H  W
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
' z& A' V( g5 S$ ^3 y8 Q: W% ?! m9 c/ k7 i2 h9 H
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269' }  H4 O1 O  P/ P1 i
6 E* G/ u% {; W) A& q
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?2 W8 Q- C& `( C5 P7 n) E( R: g5 U& {

3 L+ d! i& f% W4 G7 e8 h还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
# M. D. Q& T1 O% s# {: y* b8 Y里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
( @+ Y3 U( C8 l  u  j* H8 U+ v& {9 |2 x8 D* U- n* }1 o
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 0 X0 Z2 N, v' W* |4 L0 O* k6 ]
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
& ], H" I4 X% }& x+ }1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
: @" ~$ u- L! X5 H
' I. X6 e* f% [' r% S$ o
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
0 V* l# r: E# g, W/ i- F- R
+ t9 {  q) T$ \void write66(unsigned char Data)6 M  t; R8 z/ N
{, a6 @" p5 {$ L, L6 J. @& I' Q
        DWORD Status,TimeOut=10000000;/ R+ ]% p3 S- f1 k
        do$ ~" i" C8 n* m8 q2 t
        {
% j! \# d$ N# _# g( d7 Y- `6 w                GetPortVal(0x66,&Status,1);; @% A5 @6 L; d2 h6 w
                TimeOut --;4 _4 s& `, H# }; }/ c
//                Sleep(1);( a# D; g  x( g' A
        }while((Status & 2) ==2 && TimeOut>0);2 h, x7 O* h) }' F5 J  h) ^

/ \; }8 [  D; u0 b  E+ r1 I- [, j5 i        SetPortVal(0x66,(DWORD)Data,1);
$ F6 h9 }) y! @) s- Y}9 e8 q. P1 f6 J) E. {
void write62(unsigned char Data)6 q4 ~" W" d- p8 E; u
{" _6 N& n8 e% o/ W& V
        DWORD Status,TimeOut=10000000;$ n5 M  ^0 {; q: l
        do/ l; h0 ^) {7 y+ F; D
        {  K, P' a2 @. J+ p, r
                GetPortVal(0x66,&Status,1);
1 h' X9 V$ d( L$ X7 F& F, m1 r9 I" }                TimeOut --;! `3 t' J: m# P3 c
//                Sleep(1);
. ]  a. c8 N% @4 m0 E        }while((Status & 2) ==2 && TimeOut>0);
' Z# U9 u( |  D- v
3 R+ I5 K: E7 ]1 [- [( M        SetPortVal(0x62,(DWORD)Data,1);
) X9 z' J1 J2 j! l}/ b, F% J2 e0 o4 m. {
unsigned char read62()' ?, ~; |' _, N: ]( B
{' ~' c. l" p0 p+ @
        DWORD Status,Data,TimeOut=10000000;
6 K, \( t. c# j# ]9 N1 l4 d3 A& U% ^        do
. [4 A+ X0 ^0 p" Z7 T4 i0 p1 o        {  @$ J0 }/ `9 e: B9 q6 g; ~4 k# {
                GetPortVal(0x66,&Status,1);0 N4 w" v1 y+ a  H# S+ I$ ?
                TimeOut --;3 u5 b- m$ E/ S- m. I+ S
//                Sleep(1);
0 U6 W; E% m) P; U0 q3 k* j' T! Y        }while((Status & 1) ==0 && TimeOut>0);0 K  H) O. O0 Q0 S+ F& N1 h1 _
/ N  V7 R" u( @; j' A
5 S: ]+ }) p' O( a/ W, _) D. ~
        GetPortVal(0x62,&Data,1);
' z' [& Z! X# c) V" q% o' R3 e! D        return (unsigned char)Data;: [8 M6 x% h: M5 F* j* K
}
8 q' t5 m" c! }' X2 c+ i2 d+ D2 w! Kunsigned char read_ec(unsigned char index)5 K0 Z0 p' @. J& O+ p
{+ Q8 z4 X3 c0 F' G* O) a
        write66(0x80);
) `9 p  U7 S# d: s) e( l        write62(index);( i( k2 e3 M! Y" h+ _
        return read62();
6 ~4 L1 o9 `, q: [5 R% S# p}; v9 j# O9 x0 {9 J, ]6 p( S

  W/ c; m. @7 M* h; Y- }[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

/ S, j6 {; W8 R2 ^! `[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 ) g: N3 m# g- F1 l- x$ s/ U! e& s0 }

* ?/ D2 s  `1 V  B( ~4 c9 |  n1 J! H7 t5 T5 K2 N: D: I
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
0 @4 I- m; k* F" H) _/ _/ t2 @
3 v7 L: z0 O4 l; t$ [+ r. h  p
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
7 H& {) D, L! |- `. P' s7 V% g
/ _/ y* U0 ~7 G9 v: ?9 ]0 v2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.2 O1 Z% ?, u1 o8 I' j

2 O7 S, y; S. s% y3. Then set bit16 of the IRQ to disable it." S* n* y9 K6 {. h# _) F0 C
) I" ]: Y- A0 l! B( Y1 G
    a.. Offset = IRQ# * 2 + 0x10;2 Q* m$ T3 ?4 ^( G! z9 \  w
" t0 X" U: g( i5 \# V
    b. Write Offset to APIC base,$ K0 i' S+ \/ z$ Z) k/ u
6 h5 G# _* R6 o7 a" w- W
    c. Read Data from APIC base + 0x10;
, y/ t* |3 i' n0 n: Z4 F! b" ?
. V! V) Q& A) A8 M2 i7 T3 X: n9 A    d. Or bit16 to Data;
7 ~1 o9 A( X# w" K* `# l- k, ^+ ?% ~6 ~( m4 X2 `/ _* z1 T% ]
    e. Write Data back to APIC base + 0x10;
- ?- v1 D- s3 U
0 y& U+ ?7 c0 S; L0 t: {
$ Z6 S1 U; z( k$ w2 r) E
: ]! U/ m; G1 ?" _+ jYou need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
  c; p# ^- e+ t- k) V545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
! s$ U0 I5 {0 k9 S2 B
: b: B" q/ j8 J, |3 W
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
7 A  F  p/ |( p: W==============================================* V3 p; G& U7 Y' B% S( }
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
( u" ?0 R! K4 ?
7 Y: V; v# ~4 G" U$ a因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)6 w( z4 {8 t6 }2 u' W; p
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。: v/ {9 Q8 o+ [5 B, }- M' v
4 h9 d8 N1 ~% b& X5 E+ O
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
& F0 ]! T8 B6 G* @2 Y# Z当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:7 k, _. @/ ~9 P- y
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。4 M& c) d: Y. Y" \& [9 E# o9 s2 C  }6 f
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-8-12 20:01 , Processed in 0.176454 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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