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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>; A8 y* y, K2 y; @
#include <Windows.h>
- O* d; ]# L) v0 H#include "WinIo.h"
( k  ~6 c! ]% G6 [using namespace std;
0 V! m, o2 C. ?2 N3 ]
8 ~/ I3 W$ W/ D#pragma comment(lib, "winio.lib")
- ^8 m, [* ]! ?9 E* C4 O  c8 ^( Q! v+ W  E0 U

, v* ]5 c, F! p; ~) |9 g- k1 Q) Yint PMU_SC                =        0x6C;//命令端口* e4 H& {+ @/ h9 u/ X" v
int PMU_DATA                =        0x68;//数据端口' ?; f8 ~! T* B3 u
int RD_EC_SMI                =        0x80;//读寄存器命令2 C, k+ [" M2 i5 v' f
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
5 W- U" f7 O! i/ i5 a5 v. ?) B! _
DWORD dwTemp = 0;
* d' v8 ~8 d( h% x% e2 r% D  K7 V' Y5 ?8 M! @2 c) v7 B
void PMU_Wait4IBE(DWORD *_value);2 g. _/ ~2 Y  v& o9 n5 f
void PMU_Wait4OBF(DWORD *_value);: b1 K5 X" @1 b7 D& d

  Y  b- J8 B& L0 m5 \" Q9 ?
' A  X; n" \* H! t: r! Gint main(int argc, char* argv[])  u( H+ x) l1 ^1 r' U' _
{7 T) F$ m6 E( O6 }, p
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
+ q8 T0 G6 t5 E/ D% a; B+ [: T0 c7 U) ^3 [3 P" Q
        ; L6 f. s: _+ u
        //1、mov            dx,PMU_SC                /// ~5 H$ X) f! n: \, T& ~$ V
        //2、mov            al,RD_EC_SMI        //' I5 ?* D  l& \% y8 ^. u
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
1 T; y) A- w7 U. g% O& o* p7 s        //4、out            dx,al                        //将读寄存器命令放到命令端口中。, A9 d- H: m. F* x. T
" C: f. s. G9 w
        PMU_Wait4IBE(&dwTemp);
1 B( T) Z" T6 k        8 ~' D  E) l' k* {
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
$ O' a2 p2 o1 Y1 T; \4 X- d: {
( V2 _4 N, Z& i9 ~" }        PMU_Wait4IBE(&dwTemp);+ b! f/ t) v" ?5 L0 J
       
7 U1 Y5 D9 ?& `% \- d4 V+ u9 \2 O* F        SetPortVal(PMU_DATA, POLLING_DATA, 1);
9 y1 ?5 i/ Q( B. a6 e9 E4 }2 I6 a
# ]* b3 I* l: X6 \) g        PMU_Wait4IBE(&dwTemp);
" O) O* Z5 w( n+ K: x
2 ]9 [! U3 v6 y8 y% k3 d        cout << dwTemp << endl;                * k9 k; o' ^' y0 `1 O

" n% N2 k3 C  P# X        ShutdownWinIo();
6 h4 b2 ]/ [+ {$ ?7 ^# w
  Q5 }7 N) i9 L* v8 z0 Q9 z" W        system("pause");
% y. ]2 Z2 U9 s' ?9 q3 W/ S9 Z: o7 c  v0 G) X9 L
        return 0;
  o, s( I! S; H2 m: T4 {' T8 z}
6 u0 c$ a- h  q" c+ J9 e" F* B7 b4 s% f) x0 q1 r1 I4 C# |0 j1 {& \
void PMU_Wait4IBE(DWORD *_value)& V3 w* i- E4 U8 [; P/ m% x
{
" X+ y0 I0 D! n7 w7 T8 X* U        //#########################################################   
/ W& d; a& s: x7 r+ @' A        /*$ U0 t; y+ e/ B) x
        pmuWait4IBE proc   0 b4 c& N$ v0 l( F1 o+ ~# i2 g
        PUSH        AX   . `0 ?0 n+ v, S' {, Z1 g0 R
        PW4IBE:               " a; b% z4 g/ R/ I
        IN          AL,  06CH                                //Read  PMU  status   
8 n  D6 S6 L' F# y# l: I$ G+ C        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   ' x" A% y5 Y9 t5 m. g( Q
        JNZ         PW4IBE                                        //Jmp  if  no   5 I& t! T9 {0 \8 z' L6 h
        POP         AX   
7 j/ l( K6 y  Y: u: {4 R& J        ret   ( P0 Y% H* Z# E; V  f
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE1 A0 Q. _& [/ o2 ]1 t4 J
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空$ [7 @. l* d+ m# Q" @
        //######################################################### / u' u( f# E. a
        /*do
  A2 n& f3 ?7 X! h        {+ `1 d0 u$ `- ~: d
                GetPortVal(PMU_SC, _value, 4);; }5 |# S5 Q0 @8 D% W1 t
        }
: L* p) f; w. F6 r3 d        while ( *(_value) & 0x00000001 );*/
  p" ~. T6 }5 U" Q0 M8 ]        DWORD   dwRegVal=0;
* g' l$ w& Y& g7 O2 r. M        do
$ i6 S3 e. L1 @* }) i2 o$ v        {  2 C: p. I) u" U3 ^7 u: u+ e
                GetPortVal(PMU_SC,&dwRegVal,1);
# }/ `' F. S9 \) S/ C7 ?        }' J, Q+ P* L# _/ S! m* O+ s, U' i
        while(dwRegVal!=0x2);" [3 q$ Q. U2 B3 [
$ I& b/ W4 u  t; l. ~6 W2 x0 r
}0 j) K4 D8 u3 y* J9 v

' k9 a) ?6 s. `1 M* S4 X. t以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。* ~% m: F- x2 |0 G2 s; N
所以变成了死循环了。
6 Y- N. `$ z: C1 ]" [8 U1 D9 T
: T) Y7 C4 H( M* Y我对硬件编程不懂。又不知道从何下手。% K" ]* M  U5 b: w
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。  i/ e) ]  U* ?# n0 w5 k8 C
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
1 f6 U( o& E  ]+ a% T; K5 U
3 v  t$ D) i4 y5 [/ t( Z我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
; R! z3 w, I4 Q/ v) t并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。' g* h. L# x6 }* H

- k/ M6 B5 `- Z; j# L6 g) t感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
  k  n2 |4 e# P: ^- {1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
  p% U2 D# j7 q9 I( g3 I2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突  b+ z- o. h2 a  c+ |4 \) V* x+ S4 C4 c; @
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
' I% X. J2 x+ S( {" B
' M5 N: ~& a8 F7 ^6 Z4 n所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
6 n+ z. j3 K: H$ @* F, ]  ~3 R: L# I4 c  B7 I
那么有些什么可行的办法呢?, k! d/ ~! N9 ?& F& u
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。' p& G/ s4 f. K! s6 f

6 @1 J8 P7 n  ]' y它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
' ]; x, C( y/ |+ d  ?: G# |
/ o* C! @8 C3 X( y* ~那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=4206 \# P0 y, R& j) d
& J; w$ C" \$ n. p- a- D2 C
http://www.ufoit.com/bbs/viewthread.php?tid=4524 B# C' ^- {& n- c& Y& @

& Y9 v+ [6 W+ s" u1 \http://www.ufoit.com/bbs/viewthread.php?tid=241( E; r7 t) l2 L0 W0 n# f1 P. @

* t, J: A5 x6 ~看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
" }* l  P; w8 k3 T- x( _! R; J; w+ @. n6 |
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
# }2 l  g& z. [2、Driver最复杂,也需要BIOS配合,推荐。
: I3 B- h" u# d' G& }& J0 F6 v3、Windows API只能获取到特定信息,不需要特定的BIOS配合。7 r  e+ w. ^/ Q, g# {# `0 X7 R, W
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。% |# ^% `! T8 ~& H# D
你可以混合使用。
2 M- ]3 `3 i% h7 k: y, p+ G0 z% I) ^% V3 i" \/ J  I
===============================================================/ |$ E, m9 `, U2 {
管理员的这句话:
" m  r! B) x* E- _2 a7 d如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
( z7 J9 x$ \3 C6 J 3 j6 A3 W! ]3 b0 q! |* ^
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵; @: X$ F) |7 t
: k/ K6 `; z; E- J$ P/ J0 N. t
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269+ S/ a7 l6 [/ c

' b5 ~' \5 B+ O7 D4 A" M% \8 b这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
3 ?" h! U0 H/ c! k$ |3 L3 V1 c/ D# Y- Q3 X- ]& d- {0 A
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。2 k* G, n+ B( ?2 X$ T
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
3 ]% f/ H& [( ^9 U
, q- i% u+ A" K! D6 z7 n' E我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
- w! F4 D9 l' l# A+ n你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
+ H: ?2 Z5 E5 R$ p0 X& r1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

0 ]/ k* x1 M; g" Z; U1 M% e9 ?: r- k* t9 C# i' t6 E
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
: N# u' W% v8 u& _! {- S
) `" r2 m/ l- d9 m# m9 B+ {void write66(unsigned char Data)
: q5 M+ `' _: G" K% i0 Z{, A" w# P, H. u  I3 m) j
        DWORD Status,TimeOut=10000000;
& E; d6 |2 J) P; S. q$ R+ N        do
. O7 y2 x* u% X        {
1 J! M. h# N& J! Y( M; @1 e$ U                GetPortVal(0x66,&Status,1);4 _6 r8 q0 _6 ^: }3 _' a7 u( y$ C
                TimeOut --;
0 e8 q+ d& T" x! s9 ^7 z. B//                Sleep(1);
4 W4 b. s2 J9 I* `        }while((Status & 2) ==2 && TimeOut>0);" L" o9 w/ g, ^2 E! ]6 |

- D5 y  n9 f2 `& Y2 ~: {        SetPortVal(0x66,(DWORD)Data,1);
( E) ~* I/ n, B( y: A# k}
' t& z) ^! r2 @) `3 cvoid write62(unsigned char Data)
; h/ G) f, V6 M$ V1 m{- y4 E( i" P- v: y4 P) e2 h0 ~
        DWORD Status,TimeOut=10000000;( [" U$ W9 |+ |8 E: x. I
        do3 H: e- C# X) }5 K+ d, r! E! F5 v- s
        {" L7 \0 H" |! S# d1 r+ J
                GetPortVal(0x66,&Status,1);
; f1 d$ S% J7 c                TimeOut --;6 h: V1 J$ K6 L
//                Sleep(1);
4 o3 L0 A. m$ Z4 b! y  ^) ^4 K8 H        }while((Status & 2) ==2 && TimeOut>0);
$ k$ p* B# {7 S3 p- r) v! U7 P: e! Y9 h
        SetPortVal(0x62,(DWORD)Data,1);  G& P" e9 j" E
}  G. ^/ `' l0 \
unsigned char read62()9 Q( N  [/ P/ I% Z5 K9 ~4 D
{
: f& a2 s7 N; _3 {$ {2 V        DWORD Status,Data,TimeOut=10000000;
3 D  N# b# S  L: A        do
8 I" @& I0 m( C4 m8 \9 ?        {
5 I2 [) W% H7 Z5 b( U5 `5 b, y4 |                GetPortVal(0x66,&Status,1);
: b2 Q5 E! P+ z6 j1 Z                TimeOut --;9 u0 C5 I3 `) w6 b- ^6 @. Y6 Y
//                Sleep(1);7 C$ E1 t. Q( q. K# ~
        }while((Status & 1) ==0 && TimeOut>0);
" G( X- z0 I; V  Q0 T, v6 ]7 u- V- z, b5 _: A) ?( h3 j* X
# ~" f9 T# N9 ]; `
        GetPortVal(0x62,&Data,1);
# w8 H- t% ?5 n& H/ M5 ~        return (unsigned char)Data;
3 B7 M: S7 G( s! g( C8 a}
7 R8 |/ w) J4 s# p# G8 punsigned char read_ec(unsigned char index)) R/ k& w. U" L0 J0 x
{
6 j! `. A5 W! e% B        write66(0x80);% W3 d9 B& }3 ?4 }. N. J! L, n
        write62(index);
' R/ f- s1 G' U7 V- d( H        return read62();
0 d! h3 S5 g) h* v$ J/ h1 V7 D* N}/ Z9 ]  F( i" u8 V; e- @. }# |$ V

8 [1 F: p1 c8 L* B9 h+ b: t/ k[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

# J9 R4 C$ Y- j[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 1 u! n* Z( |0 _# z& x5 k
$ ~1 k3 X0 L2 \1 u0 ?

- I0 Y  |3 H9 C* n! q7 k) e+ }您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

  Z, o6 l2 N- U2 k0 H+ C+ ?8 b* j! r6 J9 Y$ ?% j6 \' R8 T5 C
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,* a# v/ M) O* o  c

% a5 _, J8 R6 P1 \* B4 y2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
) Y, J' Q: U8 X3 F  B! r- l2 m2 b, H/ S. ]; f$ O
3. Then set bit16 of the IRQ to disable it.
9 Y/ ?! g# v/ Z5 O5 k( j9 n6 m* i0 N! u+ t
    a.. Offset = IRQ# * 2 + 0x10;* x+ y5 h! t' u8 j8 [, Q2 f- k, d
9 y7 f. C8 r0 `
    b. Write Offset to APIC base,
. f7 ^. ^& c* \* `9 A& Z9 Q
) M" l, e/ Z% O/ X    c. Read Data from APIC base + 0x10;
4 z. c' g- t- }
, h8 M: P; y, M# c# j3 f+ a) u    d. Or bit16 to Data;
4 R1 C9 e& v+ \* l4 B
' T' p, s! c+ v, P    e. Write Data back to APIC base + 0x10;
7 K5 S6 A* y% K/ W7 Z3 {, w
* x" S8 x- u/ t
& m; A. d$ r: V4 E
* q3 Z3 L1 ~6 @' R; xYou need to check APIC spec for details.
回复

使用道具 举报

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

' c- l- A& A2 I. {% M0 H+ N: H$ _" U2 B
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
. B. @+ H& m. f! f==============================================
. ]5 H. W9 m$ F( f$ }/ d# x5 E5 Z 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
" P& D; \* b6 h* F& Y) a' V* P3 Q. b$ t- a
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)7 t1 H, `6 J* z# u
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
9 {# A; F* V; z, b( S9 i  o
7 O; V: e$ Y9 p' k- {  R  X2 ?因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。9 m7 n/ c( ?; ]
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
/ |4 K; ~7 k/ ?! E, Y9 F. e1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
4 `+ c/ e) _' i4 M' U7 ]4 Y2、新手不要把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-25 03:38 , Processed in 0.046564 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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