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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream># x0 c( Q/ I: Y# d1 B* x5 M, x
#include <Windows.h>
7 M: t7 x0 m8 X* H; ?#include "WinIo.h"
1 o! [4 e: c; [using namespace std;! J3 M3 ^1 v; ~6 z
) V7 ~5 c0 I2 |: r
#pragma comment(lib, "winio.lib")$ G4 O6 C( P9 {$ q' V/ @9 O

# @1 S  O: j% y( l9 k. l- k: m
! E# ]. a9 d4 T4 P" nint PMU_SC                =        0x6C;//命令端口
! K# F+ ?* p+ Y( L1 h: V! {int PMU_DATA                =        0x68;//数据端口
3 ^  a2 p( p0 Z/ `& c2 Iint RD_EC_SMI                =        0x80;//读寄存器命令9 b+ }  X! E2 Z! K* K1 l9 y6 y
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
1 ~2 k$ P0 {$ n: m+ N  ]1 M6 a
& M$ l. d) u6 |) {8 q0 `' O4 MDWORD dwTemp = 0;0 O6 K9 a' v% X+ h9 A' y

5 R; n+ I6 {/ Wvoid PMU_Wait4IBE(DWORD *_value);! S8 Y+ j1 G# S4 h
void PMU_Wait4OBF(DWORD *_value);
! N( w+ P. L8 }  s# C$ `  f; Q8 K9 z2 q) ?! N- I1 v

0 Z2 g1 i9 ?* z# X& i' k1 wint main(int argc, char* argv[])3 {& ?7 [) |# [) w
{
( P; m% r4 V4 m2 h/ r- z' u- }2 F. g        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;. d7 x& }" w, u7 W! `

  \9 r; [8 W/ s- r       
$ U- `& Y" I) k0 Q: L) I        //1、mov            dx,PMU_SC                /// ?$ {2 U, q* y
        //2、mov            al,RD_EC_SMI        //
+ Q% t( H8 U- c9 o% c4 t        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了# @+ X! W; J+ w  ?: U4 B) J
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。# y( x0 g! ]7 T% e" R4 A! [

+ H, C9 ^  ^& Y        PMU_Wait4IBE(&dwTemp);, P  _" F7 H( ?
       
; [+ ?, H* o7 X+ A/ R% }  ]        SetPortVal(PMU_SC, RD_EC_SMI, 1);
2 K" Z+ G( l6 r0 p7 f) Y' F
- C  @1 y$ ^5 H        PMU_Wait4IBE(&dwTemp);/ w# [7 C- u' d: C6 S7 M
       
. d- p' M/ Z) r9 ]3 Q& [1 q6 t        SetPortVal(PMU_DATA, POLLING_DATA, 1);
8 b  e3 b8 Q2 B" N( u7 J) n% f9 g" F* _5 ~- L( x& G& i: o6 M
        PMU_Wait4IBE(&dwTemp);: I, z8 \7 Q; `# |. `
* H/ U/ t9 a  C2 T- j9 ^- V
        cout << dwTemp << endl;                8 W9 o, m  \% Y6 ?

  N2 R( N% I1 K# V  i0 Z/ G        ShutdownWinIo();
" l) W8 T3 [7 k  m+ L
9 Y$ S  p+ s( q8 P. O- K1 e        system("pause");
6 w0 F" G+ F! a, I6 V& N1 c/ u4 ]
7 S& W3 {, O( a8 a: [8 A        return 0;4 x& c$ j6 z/ f" @
}, e1 j2 b9 [1 u. X# v# s" W) x
( G* J8 C' x& d
void PMU_Wait4IBE(DWORD *_value)% i3 @4 e0 p4 J: j1 f  H
{
" R, [: x1 m* e( v: G' m% w+ [3 p        //#########################################################   
. J! G1 Q" Q/ f: X' _7 w: o        /*
1 K5 S: ^0 v/ K* l7 d1 n; o$ K        pmuWait4IBE proc   9 {6 ?6 x# C! G9 l* {3 J7 R
        PUSH        AX   $ I. ?" O$ {6 k( D- x) R& r! K
        PW4IBE:               - E$ F% h, n( \8 m3 c
        IN          AL,  06CH                                //Read  PMU  status   # K% V* r; R& R; u, K/ u; I. T
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   8 Z5 D7 ?" u3 e& h& [" u7 T
        JNZ         PW4IBE                                        //Jmp  if  no   7 t+ G% O2 G7 @4 C
        POP         AX   0 E/ U* H  G! o, f
        ret   5 O7 |  s' ?- z$ V3 B8 t
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
. [" l' d5 ~; c# z, J( P        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
; |0 O4 f8 r0 T/ d1 ~        //######################################################### . Y, y7 o" I  Y2 ~# v+ f
        /*do
+ P8 J1 k: M( u6 t        {
7 M( f( k! ?' Y4 A/ S) p; c                GetPortVal(PMU_SC, _value, 4);; E8 i) H, h4 ~4 ~2 P: C
        }
3 F: Y+ S) o, {5 N. u        while ( *(_value) & 0x00000001 );*/
( `6 a: V* ?% v) E4 t        DWORD   dwRegVal=0;
5 H0 ?, w( K/ {( C- H        do
4 {- D( Y) ~- k. k& x) a        {  / `2 Q2 W& F& q1 O0 y4 ^
                GetPortVal(PMU_SC,&dwRegVal,1);
- W# T2 O  G; ^9 L        }: Q- G8 `8 j7 l' P; y% r9 ?
        while(dwRegVal!=0x2);% |( r1 R* a# }; G

- q% T+ t2 h5 f% d0 G8 Y  C: y6 ~}
" A8 n  n! g7 B* V' O" N% [
( x6 I& {( d5 P以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。* P, C2 _+ A8 i2 ~2 t& U
所以变成了死循环了。2 C: I4 O4 ]5 ?6 ^2 D" _2 k
) |9 s4 e$ A+ [; w! V# V$ ~
我对硬件编程不懂。又不知道从何下手。
2 t  N! v! U9 Z! T我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。2 L7 ?1 T5 q& d$ t
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
$ l0 E- i! s! E7 G* @
9 Y/ ~1 ]' B6 B: v' ^我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。% O8 h, D- q& a8 Z0 H  [) `% [
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。5 w/ L( Z9 m1 E& x  ?, ^" W
/ W* ^6 D  J6 X5 I# M+ J4 ]
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
# Y# v7 M, }& H; k$ c9 U1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
- i2 R& E% d$ }3 J2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
6 E, \! ~4 @- b5 H1 m2 r3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
1 Z' |: s5 H3 D) a, A% B' @
1 r. d6 t. }- f* B8 n$ o所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
9 r/ Q, T5 x! g4 d* F: M( h, k, ]; ?1 [$ p" B* |
那么有些什么可行的办法呢?' K" R) E# F5 L
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。& Q; ~$ G: @- x4 H: J/ o3 k( y) e
" w5 k) R2 |. d% H8 Q* ^4 S4 m
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?" e. v1 o/ l1 g8 y  V! W

3 w' ]# z7 I) S那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420; O" R$ \6 }- j! a0 L7 N8 \- E
# h1 k) x  O4 r, l5 ]# ~' @
http://www.ufoit.com/bbs/viewthread.php?tid=452
' x+ C# |8 ^, N' Z( v6 n! ]' i, G9 t
http://www.ufoit.com/bbs/viewthread.php?tid=241
9 w7 v: k, P- Y
# e- M8 ?6 n/ _  K% B, g+ F# p0 ~看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

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

: U; V1 K7 n* ~) s4 Q) P; W1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。- {2 _% y3 E. p( O  k
2、Driver最复杂,也需要BIOS配合,推荐。
0 H+ ~; B# u7 j8 C7 j" Y  K3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
0 I. ?' S3 j" V4 o4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。6 w' x. c& n$ }7 K8 G2 B
你可以混合使用。
1 I, l/ R: I( C; l: y- d
7 y' f6 k7 @9 t! _9 X===============================================================
$ y# T- I. Q1 ?9 Q% }3 e管理员的这句话:9 C8 S; r  f. E2 i" g7 \
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
! D+ ]" o. S9 P' p2 J6 C, p9 z ) W" O: n0 z7 ?0 d
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
1 D! \+ i% }$ \& p& Z6 \' ~( B+ h: ^8 O& f0 L5 K, @6 `, W
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
9 X& [4 t2 l8 y" |; Q( Q% W" u- H: F- [, U; l+ P
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?* R$ I, E9 |( a

4 w1 `2 P  B0 J  b0 x还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。& d( e2 w$ \  J# y; k
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?0 l/ F9 _+ d7 Z
; ^9 O+ k) F% |
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
8 J9 n& B% Z9 w( ]/ p2 T: h2 @7 ~你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
! y" a7 i( d# d  ?" O1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
) B3 G1 Y* z; B, ?$ j" ?. d
6 z9 ]8 k3 ?) i# x2 |
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。6 p# Q& C4 `, l* ~+ a  O

) W2 n+ m' k# `! [9 P, n5 |$ pvoid write66(unsigned char Data)+ i9 n! @/ }; h2 D8 W1 J
{/ O* F4 w1 u5 v5 u$ }: D; A
        DWORD Status,TimeOut=10000000;9 \9 a1 G9 T8 D- k% m
        do
- N+ i, F3 A& t% z        {; h; @+ C% |; E4 ~7 W: K/ X
                GetPortVal(0x66,&Status,1);3 p5 T  h) \! s; |% b. U
                TimeOut --;
; G! ^% W  ]5 C  u  z" D//                Sleep(1);( B$ ~# Q7 }( v/ O! J
        }while((Status & 2) ==2 && TimeOut>0);- r. |7 N% |: |2 r9 x! G* q! B9 Z+ j
  X3 a7 H, A& |- U& D/ i5 R) M9 U; i
        SetPortVal(0x66,(DWORD)Data,1);5 v( Q7 \' z: n: t) ?  E
}
+ w$ N6 K) `- ^" L7 u" [2 Pvoid write62(unsigned char Data): v+ R& J6 d% g7 p$ @- F
{; f- Z8 x! `3 y% i& y# d8 I7 U
        DWORD Status,TimeOut=10000000;2 ^4 s& z# p* y& y7 u; Z$ @: M1 [
        do) ]3 s' n) H* ~) T. v( X$ X4 P
        {
" B# d, b/ `- c' J, P+ f                GetPortVal(0x66,&Status,1);
$ v6 X. f0 m. H4 s4 K4 O: t9 x3 }- b                TimeOut --;$ c0 `+ V* R: r9 o- N* Y
//                Sleep(1);+ Y; i, G; I  s# v2 Q0 p
        }while((Status & 2) ==2 && TimeOut>0);& c" {9 Q8 c1 F- c& a( T
6 a% a' K4 `: S- o! Z1 d( {+ h: b
        SetPortVal(0x62,(DWORD)Data,1);
( U  x, p$ W% @$ D}
4 z! d, p% t' Qunsigned char read62()
' S9 Y9 T. h6 [/ ?{
. ?1 {8 _: Z. c* u4 M        DWORD Status,Data,TimeOut=10000000;
( i& X) |: D! e% k; i        do
( H* {2 Z$ Y& i, v# `1 u1 Z        {& p/ ^1 ^6 R: H' u
                GetPortVal(0x66,&Status,1);0 ]) F3 T/ C8 ^& B4 u, F! t
                TimeOut --;
8 U5 Q  x' Z7 m' N//                Sleep(1);' O5 b! v% j# l  p5 h# ^4 e9 \
        }while((Status & 1) ==0 && TimeOut>0);
/ j! b' }! @: j5 o
) r0 E  {" F, W  d
' m! u& `5 h( K  X" N$ V        GetPortVal(0x62,&Data,1);
" c! l5 B& [: C: f/ _        return (unsigned char)Data;. X" n5 Z+ x/ z9 Y* _
}
6 Q2 U5 M- G4 `8 ?& {  h: xunsigned char read_ec(unsigned char index)( y9 e0 `/ b9 W. N7 T/ k
{
. O6 Z3 x; V2 j        write66(0x80);4 Y4 k0 ], H( u$ s: [
        write62(index);
7 v* r( I$ \+ }! g  b% v        return read62();! N# a  r0 Z; s; r' c: v. ]
}
: a8 p9 A6 S8 w! F; i6 @& n. z0 {' A2 @/ M6 J5 v
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
$ X0 o* l' \& a9 W7 @% W! S% M  ~, ?7 X5 O$ U/ B  Y
6 Y  C, }5 s% O2 ~
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
5 X4 M" x: e* ^) n7 l
$ ]  q) m7 q$ U) U! f  ^% k
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,8 e9 ~8 |" r- i6 W
1 {' ?3 ^" x$ @& f# ^
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.# Z  P; L+ C& c4 D8 h. g3 u0 V+ H

( Y! w( o; _' q# R- o) y% U: t3. Then set bit16 of the IRQ to disable it., m6 l  V. o' `4 a# n* ?" F
0 a" @& D$ d, l5 a! z
    a.. Offset = IRQ# * 2 + 0x10;
" K0 e. w3 F+ j! s- T( k8 b% S! v/ B' D# O; _# T! z
    b. Write Offset to APIC base,
( l9 I( z9 J. Q- n' ], o2 ~( ^0 Q) H: G
    c. Read Data from APIC base + 0x10;- g2 W+ D4 t( Z
2 ?. H0 ]& r% ?! K
    d. Or bit16 to Data;
1 |% Y4 O7 D) ~# b) X% H/ G" v6 Q2 B( A( k  J. x+ z
    e. Write Data back to APIC base + 0x10;
( k% J/ |. P% l! r5 i2 f+ J0 b" @; \' f7 }. B* n& G

  E7 \1 D: Z6 w! v; A* |3 }2 j+ g2 X
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 3 s/ X) ~% \2 x, ?- S% e$ v
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
* Q* J; g% {& A+ T8 u) H! U' a- C

, i4 m* J( s4 B* n# D 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
9 R* Z; h* I  K% }==============================================
4 x1 K" o& y, I0 J$ ~ 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。, o; F! G+ Z9 B0 x

- H6 l) C/ @! X+ E7 E# Q* I* i因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
5 L" e1 |8 Q  G  O8 M) a但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
( r. I/ J7 D/ c2 v1 Z( D8 z. ^/ o; m: y
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。2 Q+ ~3 k2 J4 G6 d
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
: w% R5 w) o& p0 l1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
+ b4 Y1 b: \8 X- D. B5 P( n2、新手不要把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-4-16 04:03 , Processed in 0.047259 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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