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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>* R' ]8 X/ I" h0 _* }. Q- n, H6 x
#include <Windows.h>& k  [1 k; V/ _2 K  @
#include "WinIo.h"
8 s% S. I: o" C0 g: R1 L/ Z! Cusing namespace std;/ u) p4 s6 O! g. b, C0 C
% {4 Z; M2 W0 `% h; w5 J
#pragma comment(lib, "winio.lib")& o8 S/ D- ~1 ], f8 j7 Y9 y+ z/ o' v: w
8 h6 v2 e& W: K' d& d  v5 D
- J( j# P) Y3 g$ Y
int PMU_SC                =        0x6C;//命令端口
1 H  V+ Y, B8 v: z. m  ^5 ]int PMU_DATA                =        0x68;//数据端口
0 u/ J! A* u7 }& S% fint RD_EC_SMI                =        0x80;//读寄存器命令
! j5 U/ K  A- I" C5 ^int POLLING_DATA                =        0xE7;//CPU温度寄存器号0 [( r$ a) z) o
; Y4 o7 S5 c, [4 M! V; K
DWORD dwTemp = 0;- W( j" k. i. \& ]! M9 j1 Q
. I1 g4 e. V. E3 m$ h5 @7 H
void PMU_Wait4IBE(DWORD *_value);( [5 l1 ^4 v+ G* [8 {, C- J1 d
void PMU_Wait4OBF(DWORD *_value);
5 A1 d, c: @. z* q" n; ?4 V4 M3 ~# [6 l* a5 |$ n& N! Y

1 B. ^; d, l) Kint main(int argc, char* argv[])
6 m$ y; A& [0 Q' i* `{- Q4 D5 X- F& b  L, T
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;) F: `8 C6 }: A, _, d) n
) m* y2 a+ e5 l
       
7 `* V( @& q* V" |9 Z        //1、mov            dx,PMU_SC                /// m4 e+ {, Q( }- d4 \/ s  @
        //2、mov            al,RD_EC_SMI        //9 I* H9 p0 x2 ?4 M- B- q
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
& H$ `; D' T1 V9 W# T        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
7 C5 F9 g; \! w0 e# A0 j/ t. C) [1 h
        PMU_Wait4IBE(&dwTemp);
3 ^- h; g+ `4 U# k1 R  E       
- N( S- _/ r3 A        SetPortVal(PMU_SC, RD_EC_SMI, 1);- N$ k/ N  Y/ ?& d4 h7 Y: O4 I' I
6 v; }! Z% {# d$ H! }) ]% Z. b7 I
        PMU_Wait4IBE(&dwTemp);
- o$ V+ m. `: q- D& K+ n       
: Q# L+ U& U! P! k        SetPortVal(PMU_DATA, POLLING_DATA, 1);* V5 j- X' k) b$ p' W7 J

% x9 o5 x/ h4 m% H, [, T8 |$ i        PMU_Wait4IBE(&dwTemp);
: K8 q2 ?5 C3 \* I" e- Q# ^9 E+ t
        cout << dwTemp << endl;                8 r. ~1 n* V0 d7 Z  V) K/ r
2 n: [. J4 E; h; a- d: u% T4 r+ R
        ShutdownWinIo();
$ ^  H5 A: l2 N: q6 f+ W3 ]! f7 g5 U2 G4 g5 ^# K
        system("pause");' B4 ]) C) ^8 @5 V2 R% h
* B3 N1 E; ]0 R3 y* d9 G
        return 0;
: N' O: K2 M; y1 |5 W0 l}" b; y+ Z1 S+ V& u1 Z+ n7 g$ \8 ?0 p
' t7 _; s* u1 [; J5 O1 Z! |
void PMU_Wait4IBE(DWORD *_value)
0 E2 [- _# Z2 H, x{) Y6 m' v0 E# U  ?+ {$ T( |( d
        //#########################################################   
9 ?$ t% U) q; K- p% B        /*
% ^% {7 i1 ^1 I6 r        pmuWait4IBE proc   ; s0 v0 F2 v6 v+ _
        PUSH        AX   
+ ?* \3 K, |' \$ N0 X  R        PW4IBE:               
0 ], B7 B, H8 y3 R        IN          AL,  06CH                                //Read  PMU  status   
" p2 C( u: k% d1 K2 ?        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   : q8 N2 n# D2 p/ y2 N+ t
        JNZ         PW4IBE                                        //Jmp  if  no   
& k8 t; y. A+ e- y" H        POP         AX   ) _8 t! B" Q( m5 g9 n) d; r; S
        ret   / o' o2 B+ A6 U1 s; q+ R
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE4 @5 N3 d- ]- \, P6 Z
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
+ F! A; p% n' O# d        //######################################################### " d7 D# ?1 d. c; K' l. j& B# E
        /*do 3 S8 c+ }) @$ a" A, {
        {
7 Y- B; K- R$ J4 _+ u5 O                GetPortVal(PMU_SC, _value, 4);* U: y1 k* I7 n
        }
9 Z7 {0 H2 m$ ^        while ( *(_value) & 0x00000001 );*/
# g; U9 R- `. m( B* H) F5 E9 O& f1 s        DWORD   dwRegVal=0;# K1 c* k" g' P5 n$ m/ c
        do
- ^( O4 f. h3 n- B" [1 A        {  / \8 M$ R) A# j8 s/ [
                GetPortVal(PMU_SC,&dwRegVal,1);' P- {$ b, m  q* f- P' m
        }
( m/ \4 a* \' V        while(dwRegVal!=0x2);
' a' @' V, ?6 v! s; w2 U
5 S2 ~  R. l- Z}; M( {. X) N. p5 D  g
1 D6 C8 b: j, h9 o
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
9 X7 s8 l! u. o6 e所以变成了死循环了。
' k! d1 ]5 [: D, z! {9 [' Z8 K: \$ b( N; G$ R$ C
我对硬件编程不懂。又不知道从何下手。
/ j4 H. [  V1 y$ C7 r7 G我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
! ]! Z, P: O0 o( r但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。# X/ Y) o; w, ]3 p

! Z, e: R0 j$ W7 U; S我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
, w6 a- U7 j0 m2 k; S% t: V, e并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
" J* O. T7 B6 ]9 X2 C5 g, F2 M3 ~+ K& o0 B
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。* c2 _& a5 p: f* n7 P" n* s
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.  q9 U* o2 W! H1 d
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突) d4 R7 w! e5 m! q  r2 k
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.8 ?) ~5 z9 p1 P: w) h5 }( R/ p
7 D* H* m; m8 S$ m% q- C
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。- w) O* t2 v/ j6 z/ Y% S, e& T
3 V) F( I" v+ H! e
那么有些什么可行的办法呢?. l0 N. d" ~' M2 k2 R  j8 C0 K0 {
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。8 D( Q) |1 K0 D2 {5 Z5 L

+ y# Y5 c' n9 q1 k. o5 S它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?' f! E$ Q" P! [

' c' J1 s4 N# d那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420+ K4 I: @$ H' W- {* H

& c2 b  o- c1 _% i  W5 Z: fhttp://www.ufoit.com/bbs/viewthread.php?tid=452
2 y0 B5 [7 _* T% `. ]; ]* n0 z) {; [" G" _
http://www.ufoit.com/bbs/viewthread.php?tid=241
/ R8 {. v0 ^  `( M5 {( l0 h& J
1 c5 \1 p+ b& t3 s% l6 J3 ]" b/ {看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。. E; s6 N7 N& J# W1 _" @
" U5 _5 x! s$ X1 M( D- c# {1 F
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。% O* T8 Q! s, n
2、Driver最复杂,也需要BIOS配合,推荐。4 n. [0 z3 U# |; U; r. j+ }; e
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
$ l& S, \: H' ]. ^1 k$ E" C4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
% F+ u) W! Y4 o5 A1 `( V+ W9 |你可以混合使用。% _: V' d0 N" B; j8 y, m1 K; U
( m" X& e& l, D  T* W5 E& B
===============================================================
% X0 d. Z( D9 E+ T/ K  Z( X% x管理员的这句话:: N% x) c! u% T
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?( P5 m8 L2 c  W) O, D% j

7 K& I6 f0 _! o$ _0 D# l予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵) K; B8 F' e7 K

6 y# M1 O7 I7 `) p6 m另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269; N0 m( A" b: M/ b, \6 a6 `$ Q* M
8 z% m1 H$ S7 O" m
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
7 `2 M2 x! n4 A) ]. z/ U8 [; W0 p
: j. Z0 d" K: i$ T# n, W$ A还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。6 A6 @9 }; y" [8 K
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
, s2 z4 i! h! q! G  |$ f3 ?. x
: y. n) c6 U% w1 J' F0 h( `5 h我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 1 j  @6 u) a4 V3 z
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。2 k4 M! V2 }4 n% ^
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

, ?0 S+ H$ [* Q8 f5 n: c! \' I. Z4 V2 W2 C' H, j9 Z
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
) w& L$ S) L, _  y
! Q3 }- I1 X' I5 uvoid write66(unsigned char Data)
/ X2 e! p; V' V( S) O7 H. O{
* u3 s7 w! d7 T5 k$ l; s" S) d$ `        DWORD Status,TimeOut=10000000;$ R) `! s# T2 ~* j
        do( ~" ^+ N2 G1 U% e
        {/ v8 q6 b! O$ p6 Z) A9 G
                GetPortVal(0x66,&Status,1);
. P/ i0 V4 Q: v; O2 U                TimeOut --;" ~# d7 R; N4 a$ V0 z3 g; f
//                Sleep(1);
( J6 S' d  q+ A. {        }while((Status & 2) ==2 && TimeOut>0);
) R, k( ^9 b! M% K8 j4 K5 [3 V" o; V* E9 c) W7 M7 l% W
        SetPortVal(0x66,(DWORD)Data,1);
$ R# a' @6 k: E, f}
" E% ]( Q  l* ]0 n0 k  i' N9 Rvoid write62(unsigned char Data)
! q; w4 s  v2 k& g' u+ _{
2 p, y$ I- [. W* l* z3 Y! |( D, S0 T        DWORD Status,TimeOut=10000000;
& W8 M$ M8 t; |& [1 p. S9 I  r% Y        do
3 _& V' x$ t8 G% p" a0 ~        {
2 w3 E% f; b3 R; H                GetPortVal(0x66,&Status,1);/ N& e: Z& {9 ]5 P
                TimeOut --;
# C4 k# J6 I  z- L% @4 ~3 E//                Sleep(1);
- t/ M+ V, V! ~( s8 [& V* {        }while((Status & 2) ==2 && TimeOut>0);4 @# `$ X1 m- H  G0 y/ |* o
# M* V+ v7 l7 p! \' t; m9 {2 H
        SetPortVal(0x62,(DWORD)Data,1);/ }% g5 X3 m0 ^# c0 e! J  Z# F
}. Y% ?. [/ J* v0 n
unsigned char read62()  E7 I% K8 }$ k( g
{. a' y  u" T: i, s. c
        DWORD Status,Data,TimeOut=10000000;
" p* ~" r, E5 E2 ~        do
$ O/ x5 ]" }2 G  }        {& E0 k! z- b, c: q* Q: ^& W) H
                GetPortVal(0x66,&Status,1);
# B9 n4 O% C1 B! \0 j$ S                TimeOut --;
& k# ?1 l- M: Z5 i. C6 |) n% q* k//                Sleep(1);
$ R9 q, b! C" O6 h; L% m$ A0 }8 N        }while((Status & 1) ==0 && TimeOut>0);
+ |  J6 d. D( T6 L) {. c4 m
' ^2 h( Z& W* a2 D
. Y& @6 h; {  @4 f* ~6 O5 Z) K        GetPortVal(0x62,&Data,1);
7 z) r  k4 i  c1 @- ]! b        return (unsigned char)Data;
# x& {: I( f2 K( s  b% a) E}4 p3 I. N3 U7 L2 v# H
unsigned char read_ec(unsigned char index)# ?/ j: F" D- ?7 E+ \6 ~$ G
{
4 b6 Q8 @9 w0 h        write66(0x80);3 V& ^; T) }( d
        write62(index);- J0 |8 J9 ]* h8 L
        return read62();
* g7 U5 z; e2 Y0 a}
2 R1 J8 z, P, u. X$ h9 H6 N0 j, Z1 l9 a/ ~4 }; C" m& r
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1955) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
4 z. j/ I1 K7 v% Q  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
8 P' ?# `8 O, h& D% z) N) z" p9 X# v3 y, |" y' q
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
) D( ~$ g' \- w) S5 B, T; ~2 t3 Y* W/ N( v+ l
- k- a; J4 g  d; q; k
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

& r8 \( b/ T, P7 L5 Q2 S$ B8 D6 L/ i/ M" {8 [
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
0 c4 N4 M, K* N' a. B$ a! _
: k$ E! m& `# M, X/ n2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.2 |; Y& ~# Y) Y' ^

" n/ u. }* O& c3 c' o! S3. Then set bit16 of the IRQ to disable it.
. H5 z8 O: D7 q7 B3 a5 r9 o8 ^8 t3 |% ?; \/ X0 n& @- }- ~# O
    a.. Offset = IRQ# * 2 + 0x10;. V8 v" w& o! |$ E# I
$ K; ~. A: s; i3 d, |1 M2 {
    b. Write Offset to APIC base,
4 L! N3 h$ k0 K, T% O$ T; @' h+ ?( g0 P  R# [( d: P
    c. Read Data from APIC base + 0x10;
1 l9 S+ P6 x/ B2 X) M2 G- g* I. V) s
    d. Or bit16 to Data;" i7 A7 G; b) ~- G1 Q

, a+ L0 K& |; Y0 \% E/ s( F. E    e. Write Data back to APIC base + 0x10;$ ^: u+ ?0 Y  {
; K" c* V; }! ?5 c

1 }# B9 @& ?" e& M  F, ~/ d& Q9 {: H) r4 F
You need to check APIC spec for details.
回复

使用道具 举报

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

' Z* Z" U$ y7 X1 u) }' K+ o8 n+ H# R+ S) k8 q7 }
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
/ K5 w9 _2 F1 \: v4 n4 V==============================================1 k7 s% d, F+ |- c9 I! ^6 R! I$ ]% @
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
7 r0 X: k/ z" T; J  U: Z3 g
/ v# Z& x  ^% a( c9 e* _% ~2 C- X1 r5 M因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
; G) c1 `; Q& e: H( z9 ]但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。% e$ b9 Q  R% d

9 N7 N0 u; H1 M- |1 `% |因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。6 ]4 f& t' w1 M1 o
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:8 V" ]8 a% [" o9 Z
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
  D8 H# U9 H4 {' H2、新手不要把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-29 04:06 , Processed in 1.529508 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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