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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>$ w* C1 j- ]8 n
#include <Windows.h>
4 s- G( ~* a* b6 r! k#include "WinIo.h"
! {2 N: @5 \  e0 Z1 {using namespace std;% r" h* k( B+ g& y0 F6 v- T* ?
4 X5 K' p* z: W0 V& X9 _
#pragma comment(lib, "winio.lib")8 i5 j+ T5 q: O) I% C  ?+ u

: [8 k$ c2 d- s- B" F( f4 J" _0 @$ c5 F+ P) L9 F" d
int PMU_SC                =        0x6C;//命令端口# E8 B, a' W$ T+ V9 l: F- c' Q
int PMU_DATA                =        0x68;//数据端口; b7 n# D* z+ @) c( D, S% o# W
int RD_EC_SMI                =        0x80;//读寄存器命令. t7 ^/ Z5 Q8 K6 ?& G
int POLLING_DATA                =        0xE7;//CPU温度寄存器号' e# X) p4 C; h& _0 C
: D8 H6 E% d* P. K$ N
DWORD dwTemp = 0;
% N; R& B8 X5 ]- ~- D
1 ]+ V9 B9 I2 ~" R9 n+ }  Gvoid PMU_Wait4IBE(DWORD *_value);
! h8 W: y- ?- a. `5 Tvoid PMU_Wait4OBF(DWORD *_value);' o" u( x6 _# c- P

- F5 z1 l# @, i  i0 O; |9 B( q4 l& ]! P& \' n( E1 k
int main(int argc, char* argv[])5 L# y" X  a* P- A/ W. S
{: D% k7 c( [  F& D" U
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
( e6 a7 v) y, d9 m! d$ X9 r) _# s$ z, P3 P, V
        . @6 g% u! @% G# d
        //1、mov            dx,PMU_SC                //" q9 U- n1 ^/ R8 k
        //2、mov            al,RD_EC_SMI        //6 Y' K9 B- `  g" }) S  v7 |
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了/ |( `& s- s7 \
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。& m( D7 m8 ?' K9 u% J' T$ k

6 J0 h0 Q! v, T. a        PMU_Wait4IBE(&dwTemp);
6 X" s, M) c) i# E1 f       
. G/ P: w  J6 J' A0 H! F  {        SetPortVal(PMU_SC, RD_EC_SMI, 1);
+ \! x0 S$ k5 A! {  G1 C4 n# i# m5 S; e, ~6 L5 g! {; S: i
        PMU_Wait4IBE(&dwTemp);$ ~8 u7 b# t3 `" }, F
        2 P; g+ ^# n. o8 f) a4 f" M
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
: ^' `! Y5 E5 a" L  }. H/ w9 b7 |" P) h0 v
        PMU_Wait4IBE(&dwTemp);7 n# w! x: g4 a/ |* f# y

' }  K5 u9 t- K5 S$ s5 t% ?9 {        cout << dwTemp << endl;                0 i3 g$ q  R5 E+ m3 V* Z
$ t9 }9 v* u0 N4 N0 u1 P) G; p
        ShutdownWinIo();/ f5 i0 z/ D" w" N
3 Y4 x( A4 Q5 W) s# S0 K! [
        system("pause");
" ^8 }: e" ^" s# e- l- v0 E7 z$ G4 p* O2 N
        return 0;
: s' a# f0 F% z/ H0 l, Q3 F}
  ?* ~# R, N" j
; j+ T2 B. t! Cvoid PMU_Wait4IBE(DWORD *_value)+ Y! n& _5 g/ `& Z/ R' O* S5 \5 `
{4 ?4 b9 g' a2 W  d: J0 y& A
        //#########################################################   . A) \( p" X2 k& u7 z6 r% j
        /*
( x5 u* N8 X7 w" Z. G0 G        pmuWait4IBE proc     t( ?7 y$ a4 A2 X, o" s; x
        PUSH        AX   : j/ r& Z3 n4 x4 E/ D6 s( q  I
        PW4IBE:               ( |5 _9 w8 ?- D
        IN          AL,  06CH                                //Read  PMU  status   ) u  w* F# q5 y. x
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
" |$ T+ H8 m: r. |/ k* B8 s        JNZ         PW4IBE                                        //Jmp  if  no   
# g1 h* y) b* `% L* y: ]- ]0 m        POP         AX   
9 q! S9 a- P9 x8 z* x        ret     I$ @2 J- z0 D5 Z) `0 G
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE* Z- }1 Q( B$ z% t
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空- [9 ^6 y' r# Z$ \- i' v
        //#########################################################
+ s1 Y) ~8 W4 `) u        /*do
; F' u0 }$ l  ?/ \: C  o) ]9 |7 z5 {        {" U# o2 M/ u$ J( p6 C2 h7 F
                GetPortVal(PMU_SC, _value, 4);% p8 S' f2 m9 J" F
        }4 V  S, R' p1 v8 y( E
        while ( *(_value) & 0x00000001 );*/
9 j$ \. V% g+ a- f: h4 i$ H% C        DWORD   dwRegVal=0;
% d/ H7 N! ~* ]& D# i: ^        do
2 m8 Y6 E) @' o9 f$ X) e        {  7 v- H* p5 Q& u" \; ]& P
                GetPortVal(PMU_SC,&dwRegVal,1);* Y4 A9 J! c1 A# ^- ~6 B( S$ l% P
        }
( |+ w* x+ A) l  _! ~% @: {        while(dwRegVal!=0x2);6 h: N# F8 U* b  v' R% R
# n3 J# n3 R8 W+ T& Q7 ~
}
# L$ E  m6 N: h) |, q% z5 T- I- L* U- R$ A" R9 z! a
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
% F8 v  {- N$ H0 d所以变成了死循环了。
0 o6 `  B( F9 y& R. t6 g% \" }# v9 I! r* S1 {$ t9 g
我对硬件编程不懂。又不知道从何下手。- J& M7 J$ v) K& L6 d1 y( R& ~$ C& T
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
! x8 W7 P3 a( j# k% h+ Q但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。. ?1 z3 K& u2 Y9 [6 T& r

  U# d/ U; R# _( K7 x/ a: @# Y我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。* c; e5 s0 S/ d
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。# p" Y: Q! V) E) o2 [/ N8 N  g

: {( x; B+ t, W8 D感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。0 @1 B- _' K4 b3 O
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
0 a% V- [0 o. H5 r2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
7 f4 ~+ Q6 J4 `- y( X; Q3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.3 x: f8 B' ~6 S3 H. }' k! }

+ V: B8 _8 ?7 f/ y( {' Y- `5 J/ i+ a& p所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。0 y5 g" W2 [* j9 o" M8 @
0 Y1 f. q8 w# E' O9 P$ h
那么有些什么可行的办法呢?
& F8 V" ]+ V' I, K2 L; s为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
& U6 U9 b8 d7 P% ?7 n6 s& L) {. Z. k1 h# [
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
" D& c; p9 c. y: p. E( Z) e6 E/ @/ q; {( a
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
- W7 o0 u1 b  W, j- ?9 g" g3 B
: f7 J4 I" K" I3 o( W5 Ghttp://www.ufoit.com/bbs/viewthread.php?tid=452
4 D9 L% b; {; P7 K% i( U
* S% c( a, k) _  W0 fhttp://www.ufoit.com/bbs/viewthread.php?tid=241
; c3 b7 C" [6 T5 E' H$ A8 \) M* h+ D7 q# x7 L
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

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

7 N# A4 Q. ~& b0 i' ~  Z/ d1 A1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
5 [3 w$ y2 N' R- q. k! S2、Driver最复杂,也需要BIOS配合,推荐。
' S& D" ]( ^8 R) G  Z3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
5 w( L" U/ i, e/ V1 R- v4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
5 T: C& g5 w8 Q3 _2 u+ c3 x3 q- t; g你可以混合使用。
* {  M6 E, {$ H: E
% y9 J/ `+ m: _2 H5 f===============================================================: E& X5 a% k) [) T0 N$ r7 r
管理员的这句话:/ }% U% ]: g& w# E* r% ^5 ~' |# a
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
/ p, f4 K8 Y- j. W) y# w 7 r# a7 x" E" a; Y. ^5 {% N% I$ h
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
9 f7 ^: g6 @4 p
: I; g- z! s' Q6 m另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269- F" e+ J( D) T6 T3 G2 s3 a, E
, h+ Z# Z1 I& f& }  B
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?- t6 @- b, ~5 k7 l* m
) h; P8 h1 b6 G- D4 p
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
7 T+ E) J: K4 {, A8 x$ U( v8 g里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
- _4 u& Y# W/ {6 L9 d7 F% J
2 c6 V6 A! C3 ~  X我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 2 U" a- t' O3 e. H; T8 }# ]
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。- F  b4 \1 P1 `, ?" }4 I
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

. ?% s+ w  P% z2 |2 O% U! Q
0 Z3 C1 p5 a) _4 Z您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
6 ]  S3 i. j& G
: d  Y3 A6 V2 \0 w" i4 {- hvoid write66(unsigned char Data). d1 K' @( s9 N3 Y* c) Q
{, ~& T- i. r* E$ p$ |  \% g- U: e: F
        DWORD Status,TimeOut=10000000;
% }& m( D- o) H! o        do6 {$ U" Z1 W$ D9 a: A
        {" Q$ [! R2 U5 O; X+ y
                GetPortVal(0x66,&Status,1);
6 S" ?" V/ Q; O# C1 }                TimeOut --;
3 h' J% g- c( c6 U1 z//                Sleep(1);; z+ ]( a& t' e$ k. Z; D% ~
        }while((Status & 2) ==2 && TimeOut>0);) e  s# a# j+ u8 }
* ~& j- Z- O& q1 ~
        SetPortVal(0x66,(DWORD)Data,1);
5 m* V; M+ A% {" z4 D6 V' y# q}
, w2 J% J+ c5 p$ ^; _* }' Cvoid write62(unsigned char Data)
- h$ I  l* J' X' @' Q. [: ^& R{
' O% ^+ \! H+ N        DWORD Status,TimeOut=10000000;
" ^$ T/ k$ e1 d  [' k3 c! R+ X        do. e  C7 n8 z7 @3 T. Z3 Z6 \" P: J6 c
        {
  T" c6 e. D2 V' l                GetPortVal(0x66,&Status,1);
& T" d7 w# J8 b                TimeOut --;
( U$ M8 q% u/ C; c& A3 k8 x//                Sleep(1);$ |- h: S. i8 X' J( q6 l
        }while((Status & 2) ==2 && TimeOut>0);
) p4 B& a( k& J9 U0 e0 U9 B1 }  I' Y8 R
        SetPortVal(0x62,(DWORD)Data,1);9 p4 k4 n% }% P" w( @! s
}
$ n4 }' k# R# b$ S* K8 hunsigned char read62()7 M9 r( d) [& A1 b, U0 {
{  ?. z# z1 q2 M$ w' x6 M: b
        DWORD Status,Data,TimeOut=10000000;
+ u2 g6 x% G4 W% `, _        do9 B. e) ~6 t* E3 o4 s
        {
2 V' @4 I5 S4 I: [; ~1 c5 ~                GetPortVal(0x66,&Status,1);
7 a# C% f, {& N$ Z0 ^2 C                TimeOut --;
; \9 h' }9 F8 V4 r/ h! i/ H//                Sleep(1);
4 I/ ^! ]- x( i, m1 Z        }while((Status & 1) ==0 && TimeOut>0);
" T/ [2 V$ c6 W" x3 L# R; b1 X
' t! b! e1 A" w, s$ {0 R& z
7 R5 ~$ p- r- w        GetPortVal(0x62,&Data,1);
7 N6 q, {5 M4 d% r" ]        return (unsigned char)Data;
8 O1 |1 h" b6 d/ m9 j7 L: c}7 Q7 }2 {: y" k/ J; X
unsigned char read_ec(unsigned char index)
! p/ a, r& k/ Z. N# F8 T- ~6 G8 y{
5 M3 @3 I! w( [! P' I+ U- _# _        write66(0x80);) a, f! X! @( H* u6 o' y
        write62(index);
* d6 M/ C1 o* K        return read62();4 \9 p" G4 l' w& d
}
9 m& u; ~% K- X0 `& ~# d5 H' C7 f7 z
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

, M! U5 U3 N$ E5 _- L3 U7 z0 E4 z[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
2 h0 A0 K/ [0 m; N; d% w
2 ]+ L3 ]( _4 T. r' k9 y# v5 f( f
" b3 ~: ^4 @# _6 A您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
1 v7 W4 [* W& B' G. |

( o, [& y: Q& X0 r7 r) b0 S1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,: L0 k4 W0 k( \1 [# R

* W* S1 C- b8 j/ c# ?2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
" ~$ o+ w9 N; ~% ?7 t4 G  k7 n- m9 k
3. Then set bit16 of the IRQ to disable it.
$ o- K- Y" k8 N& I; e, M' a2 c, t8 _* p0 Y7 K
    a.. Offset = IRQ# * 2 + 0x10;
; B4 K3 d8 |! [( z7 U. D6 M+ A; j8 h2 O3 }
    b. Write Offset to APIC base,
* U8 M+ K. m) E) |" b2 a
+ Q) d! k; y. M! s& _3 ~: H    c. Read Data from APIC base + 0x10;1 s8 K9 H# t; q: l1 A; U8 u
* I/ Y6 t# H) L: B+ V+ E$ _
    d. Or bit16 to Data;7 \% ?: L; u! ^6 Y, N' N) p4 X
; z( N0 g7 P+ _' E, ^
    e. Write Data back to APIC base + 0x10;
8 r6 i- s/ e' C! G% {, U( r; W3 a! _; P2 `8 o3 l4 h8 {, g
! R3 ~: v$ Y5 Q3 ~4 ?
% E7 d8 i4 O& u/ h9 z0 S
You need to check APIC spec for details.
回复

使用道具 举报

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

/ \0 _( Z1 n( m% V% M
# T* F. g' {4 E" h9 k 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。- ^; m" R( y# U% L  d3 g
==============================================
- y7 x' W2 B+ R7 @ 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。9 c4 n% U( s" |+ Y; c* ^

9 K+ o, u; D2 Z* l2 G0 [因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)) i' Y& W, M3 B3 }
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
. {' s+ f" A3 B3 L
$ q2 {" g: r( {" G* w6 J  h因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
0 ]7 U- |6 `; ]3 o9 i. v当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
7 \! o- V" Z4 i1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。/ I4 ]1 f, ?* y, v6 O- D
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-8 08:13 , Processed in 0.071253 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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