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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
2 F# D* X- f; ~#include <Windows.h>) ~$ a2 W: X! ^7 q7 h4 G3 y) O4 x
#include "WinIo.h"
9 f5 S- E' \6 u. Wusing namespace std;" b1 }7 p0 E8 {# Q- m! B8 ]

* S4 W6 _* Q  a1 N0 w& V#pragma comment(lib, "winio.lib")7 T+ j, Q# k8 o" P- q3 c3 j  }

: D5 ~. r0 G" h0 J; t4 k
9 V- k# l% |" ^) L9 Yint PMU_SC                =        0x6C;//命令端口
3 A# F4 R6 L5 L/ \8 U5 V2 _8 {int PMU_DATA                =        0x68;//数据端口
6 J+ T, ^4 W1 I, z0 n2 b8 kint RD_EC_SMI                =        0x80;//读寄存器命令! r0 ~, \/ L- ]8 k! c. H( p1 X% t! a
int POLLING_DATA                =        0xE7;//CPU温度寄存器号; y: k, i% X% `: S

' f& j, N1 U% |+ s7 x( JDWORD dwTemp = 0;
4 O6 f; P! o' v& Y
9 ~. u9 v0 F: Q: u+ f& Y) e  qvoid PMU_Wait4IBE(DWORD *_value);
4 f9 d+ e9 P5 v: qvoid PMU_Wait4OBF(DWORD *_value);
% y7 ~" S9 H. m; \3 ~3 m" Y2 Y+ h. {- n9 j; M  a

1 G# a4 N: h- _# b0 Xint main(int argc, char* argv[])
. ^! _: e" w, y( h3 j{
. O% K. M6 J# `        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;0 S8 \/ C1 {4 e6 Z* [3 X4 `

: `3 a# F; [9 T$ G       
- Z6 |2 D# _; w, N- v# ^; m        //1、mov            dx,PMU_SC                //2 C* J; m+ B) x& M% Y, A  O; M
        //2、mov            al,RD_EC_SMI        //
& U( D6 [4 G/ P% n# K0 [& W7 R# R        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了+ P1 s  w3 E$ o0 b! B4 v% H
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。( J! }: N+ W; z- S& \5 l

, ~; C( {, }/ v" r        PMU_Wait4IBE(&dwTemp);) ?2 A- [' @3 `" e: g. ]
       
$ o7 X$ p+ A! [' K        SetPortVal(PMU_SC, RD_EC_SMI, 1);
% e" T5 M& Z3 ]" z+ {& g3 Y, q
1 ]9 R" G- a0 k' Q# x* {1 L        PMU_Wait4IBE(&dwTemp);4 W6 [  v5 `& }2 i7 D
       
3 H1 J) G) H( p; U& h        SetPortVal(PMU_DATA, POLLING_DATA, 1);8 t  p/ G& x8 o. m: I" j# b

; K" r9 @" v7 x8 u6 @0 q        PMU_Wait4IBE(&dwTemp);2 V) A* V- U0 `1 H) f& U) K# ]# _
! g& d( P% }% t7 R% C) D
        cout << dwTemp << endl;               
; H. H7 D4 h9 G, Q. T; c7 ?- T
- a- p8 p  g$ z6 v        ShutdownWinIo();& L8 I& h) A( e  I: O
4 \5 o8 c6 t/ j  c, Y
        system("pause");
: d* e) x/ w6 X
* m$ q6 a  I. l" K        return 0;
$ O0 b& H7 S5 m' Z}; o7 X4 P) Y3 Q- o

# \6 k; y! M7 ]void PMU_Wait4IBE(DWORD *_value)
+ T( T, l6 r: f' U7 u{
  y. Y1 R2 K" k3 v: i  f        //#########################################################   9 P( Y1 i2 j0 B1 g
        /*3 Q0 S" D8 Q3 Y* g4 Z$ l$ ^
        pmuWait4IBE proc   
( t* i- h% x& d* s0 m: q        PUSH        AX   % l: B( w: E4 t$ S+ J
        PW4IBE:               
  n7 z& r( n  h9 _. K3 Y        IN          AL,  06CH                                //Read  PMU  status   
  T9 Y/ k( E0 l& ?        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   . B" Y2 `6 p% m) m# k0 M! M
        JNZ         PW4IBE                                        //Jmp  if  no   
+ T6 \" m. t! `: M! H        POP         AX   4 ?/ n4 z$ u* m% ?, U8 W, X
        ret   % {( ^+ h- Y( M1 k
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
' B* ]' l& C: T7 o        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空) _/ A! J. u, T! {- l  G6 |
        //######################################################### 9 d5 H2 t3 Z9 `0 d' b/ [7 b
        /*do ' j- ^0 `! U/ }+ O; U" d) ~+ q
        {  r. n* C/ \- ~- m& u* k4 }
                GetPortVal(PMU_SC, _value, 4);
: z% {. d$ a, F: [2 A0 f: i' @        }& [# `1 A6 f$ r5 i: C' U% `6 E
        while ( *(_value) & 0x00000001 );*/% T: [9 b, K* f3 C  l
        DWORD   dwRegVal=0;
3 P( K! l5 M! j! f7 E5 r& M1 q% u. H$ Z        do
8 p$ v5 f; s% j* T4 U* V' D        {  
' D. E0 a7 y; e8 b* V, \* ]                GetPortVal(PMU_SC,&dwRegVal,1);
7 M9 O: a1 `/ P6 B2 P8 ~        }0 e4 ~! ^- G. k, N' f3 q$ D
        while(dwRegVal!=0x2);
% ^6 G! S" N1 l! [9 P7 n
  {- f: V2 z2 R0 `3 }}- j/ _, _$ n* x/ ~
$ L/ [( J5 ^9 c$ }0 D
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。0 e$ Y! y  M2 c  W% ?# e# c, D
所以变成了死循环了。
+ F$ @( ]# l) n  b, u
* G: i3 u- c% i我对硬件编程不懂。又不知道从何下手。% ?* F! e- L4 K: v: c6 y
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。) d8 O% h9 ^. y( i. A% ], {
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
2 ~2 t) E8 L! O, @5 y3 T7 x/ Q! I7 _& m* g5 W1 o* V
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
) o3 w4 ]3 l/ e; _: R并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
# k& A. X, M" k# u6 V1 B
1 A5 O2 o9 O, d" |/ Z" W: ]感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
$ c8 A! J6 r6 r: o' B1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
# k& z% ?' ~) U3 r0 r, n* e2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突( u- B9 M2 n4 }
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.0 _( Z! B' i6 }$ J8 u
6 B2 P: i! U' T6 e
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。: v. ^# [+ e% ~

; d. d4 K+ {; J8 n# [7 @# t那么有些什么可行的办法呢?: @, V8 A$ m/ d; q; T- P1 N, E
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
' {! a# {$ m3 r2 i( y' ]$ c$ X! z2 w9 M( k. G+ M- J3 V
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?& a& W; K* W( b, b1 q' H( B( `
( h7 R: C6 I8 T, b3 z
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
7 u/ ^$ j9 U% |, J% P
& q& B% X; T4 Y8 Shttp://www.ufoit.com/bbs/viewthread.php?tid=452
+ a) R7 D5 S6 b
! e! g0 `% M: n# C7 E& `http://www.ufoit.com/bbs/viewthread.php?tid=2410 T5 t( [; K& c) D% o6 o' A
0 \/ Z7 }( m) z) e$ P) a
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

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

, X# M7 n* ~- i3 V% Q1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。0 s. C7 t) O4 b' n' W8 f. R; {
2、Driver最复杂,也需要BIOS配合,推荐。' @+ Z' H8 d4 a% _9 q
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。! B, @' Q) `4 ]
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
3 D$ U" x5 \  \你可以混合使用。1 W! Y0 N0 e" |
. n% V5 d! {* }) p* f: l
===============================================================9 d7 N: t" Y1 n) p( x. P8 N
管理员的这句话:7 k" r: K5 H) g' A( T; D( A
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
: c8 K9 k3 k  T0 T3 S) f+ m ) E# T4 G# v3 V+ \; `! L7 h" L
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵7 D: C( h& c9 K6 u, V4 i3 ^

2 K* L; v/ s8 O' c# a) q8 H另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
" I. p  A2 W8 B" q. V7 G0 h, h7 G0 ?6 L9 F$ r# a
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?( M; i* _6 M9 W6 {) Z; x4 y
6 P9 y) A0 O/ e2 y2 X
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
8 h/ t4 l) U* s& l, |, A里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?6 R8 T: {7 E% a8 k8 d9 I( q
9 |+ W6 t  a3 G
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
1 j+ q$ I6 J' R$ _( r4 T- h# P你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
" H3 P* d6 j6 N. m9 U. C1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
! C( x  r: Y* r
( o% G% T! W" d* |
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
5 l- S5 y1 B' }% F: I6 V
$ D5 X- z* t9 B. m8 ovoid write66(unsigned char Data)! ~3 g# D2 u7 b% m" ~& P/ q+ M
{
* s6 z+ f3 F" Q' |* @; Q8 Q        DWORD Status,TimeOut=10000000;9 J+ p6 S* B9 o5 ?7 E
        do
2 Q5 d/ V0 U5 [  R        {
7 p; f$ X: _$ s  l5 j5 N                GetPortVal(0x66,&Status,1);
# j+ q$ s) r! G. n! i5 O5 j2 g                TimeOut --;5 ?- w3 b- p- w6 ?: b
//                Sleep(1);
4 n2 O+ _3 q8 ]$ a4 g        }while((Status & 2) ==2 && TimeOut>0);6 I; u3 V9 M7 c. b( i
- D# N0 |; c5 l6 L* V" |5 _
        SetPortVal(0x66,(DWORD)Data,1);
9 u/ L, c+ [( Y1 G; R& k}4 V9 G! s9 F1 Q; R
void write62(unsigned char Data)6 n4 a0 a# p! i  r; D
{
8 T5 q% i  h" s. ?  r        DWORD Status,TimeOut=10000000;
# ?- g) K' T0 |6 Q+ E        do
' j* h2 [; n8 h( k+ n1 N$ L) z        {8 V6 U7 i& u6 o, E- D. }
                GetPortVal(0x66,&Status,1);! U0 M) h6 Y  \& u
                TimeOut --;7 ^2 z" y; |3 f. a2 k7 {) e8 ?' }
//                Sleep(1);
2 I, |: W9 X8 L- w2 W        }while((Status & 2) ==2 && TimeOut>0);
- f+ g$ X1 P1 I* d( |: v
8 b- d5 Q7 \" m% y, v% @        SetPortVal(0x62,(DWORD)Data,1);0 E0 V$ a- b: f4 y, f) d( N
}
  @6 d% p* u! ^. ?+ z. M( [9 `unsigned char read62(): d0 W- n/ I  R: ~
{
# E0 r& M! g8 Z- y4 ^        DWORD Status,Data,TimeOut=10000000;8 l9 J2 d: F# \' [2 G& _
        do
8 k- H  I, K7 g8 J% w5 P) U8 ^        {& q6 I- I8 z/ L6 t! T
                GetPortVal(0x66,&Status,1);
) G" ?2 Q: Q( b8 t                TimeOut --;: X' @% q3 j5 J, I) S
//                Sleep(1);
5 Y3 S8 j8 A& N) ~: @        }while((Status & 1) ==0 && TimeOut>0);" P5 s  S, i$ D1 ?* R
, M0 P8 l; g9 M) M5 L! P

( N& F6 _/ [/ X0 S9 }3 `        GetPortVal(0x62,&Data,1);
: o/ }( H: ^# G# _6 z7 G        return (unsigned char)Data;
" o9 `+ p/ t# y! X6 r# t8 n( A2 L/ g}# P2 M/ u( L% p$ |( |) y, @' J2 S
unsigned char read_ec(unsigned char index)
6 a( A! E- K1 b0 w0 G{
) i' ?9 ?+ Q/ e# K- f2 e        write66(0x80);
+ X+ Y. s3 l  z        write62(index);) W; H* ~) D; ]* n; M8 Y
        return read62();) S% O" a# v! W4 X( w/ C
}
6 e) S$ N, _' k# g5 e6 o7 j+ i0 L- F: G& V& J* D; C
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 ' R- X- }% q! |# @' }8 `9 |

, t9 G! Z3 C: P1 e* u4 V: A8 g* f0 W
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
3 E9 R" I$ s1 x+ p; P2 y. |
1 f" W+ V3 d  @+ E
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,! f: X2 V( [) y
6 e( o  v& u" a6 k6 O( l
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
' P8 p% y8 c; Q% R7 i2 H" b
3 }! |: d; V2 c2 ~# c" o0 v$ G3 [3. Then set bit16 of the IRQ to disable it.! [  t. |( V2 m8 ?( T# @

# G3 x# `% u; X$ d8 R0 O1 x    a.. Offset = IRQ# * 2 + 0x10;
: \2 ^) _7 R% Z& i9 J" L' Q+ I
) I4 |: W( f1 e4 u5 i# q    b. Write Offset to APIC base,6 p% @, c1 G9 ^: b0 _- D
( }; z  a' r# Q) m: \- N" M
    c. Read Data from APIC base + 0x10;2 S6 t8 Q2 k+ `; L0 a: F
) k3 S  x8 j' I  I6 \7 @
    d. Or bit16 to Data;% l: H# Q/ X  A5 S! c3 Y

  ]. u& ~2 |# M! p$ x    e. Write Data back to APIC base + 0x10;
- ]  K* o% p% x3 K$ O+ e/ K8 g0 X. ]
4 y: V8 l0 O$ X. c

$ _. z! ~! J4 `5 {+ PYou need to check APIC spec for details.
回复

使用道具 举报

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

3 I/ F+ d7 R, v: U% D( I6 J4 ^, v$ F3 i3 J3 A/ \; ]
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
) |! a" i. G# E1 U==============================================" O  \- g8 k6 T! f, y7 J7 h
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
- I9 l$ d+ I( w. N2 d
* }( Z+ z6 I" z2 D. T2 w# Y3 V8 @因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)3 t. i( o9 u) j: P; P, v
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
/ l  O0 k. b: |/ j  ~$ F8 j( W' o; B: E6 w- F: h# \: V5 y
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。$ m* i; N: Y+ k7 w
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
+ U1 G8 c+ @, Y9 ^; ?1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
% [4 T5 E+ B' P/ b  [+ q# T- ?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-6-15 17:06 , Processed in 0.060549 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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