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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
5 ~# |$ u) h% T1 ~- M& \#include <Windows.h>: h# `  Y9 A2 F( e9 d
#include "WinIo.h"
$ S% q7 ?/ j  i7 i+ w( A2 {* kusing namespace std;
+ j3 f# R, b- [; q# A$ |4 y$ b$ u/ i2 c$ w
#pragma comment(lib, "winio.lib"). S; J7 T: a( |

5 N' o# u( g! \. B$ m0 J- B3 x+ u; h5 e
int PMU_SC                =        0x6C;//命令端口' l( ~4 _4 h. q
int PMU_DATA                =        0x68;//数据端口
1 A- }0 z  c# o! V& cint RD_EC_SMI                =        0x80;//读寄存器命令/ f: g" z4 I8 ^7 s0 o3 H9 G* [4 ]
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
' j, a( g5 t: g8 q9 }* A& G6 Z& V4 ~" I
DWORD dwTemp = 0;6 f( p* l, A) @8 D% |$ v
8 R* `9 r2 a7 a4 S( c& C# q4 K( @! C- F
void PMU_Wait4IBE(DWORD *_value);
, I/ V  Y0 i1 P' x8 y, Bvoid PMU_Wait4OBF(DWORD *_value);
0 c! P0 d: ]4 \5 }4 V0 z0 _' k% @9 W+ \$ u& L

9 ^' W/ _7 c$ w2 e) s5 mint main(int argc, char* argv[]), g' e9 Q' C2 l2 h" v8 f3 M
{% i5 O8 l/ H& a5 `: z" e0 {: L' b
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
$ W9 r. Z# P, X$ \- {) k: z! R# y) ?( z) s, v
        / ]; _; |$ ]# C* a8 G6 S4 i9 H0 O4 b
        //1、mov            dx,PMU_SC                //
% {% g5 v! i# e  O' u, _2 o- n: w        //2、mov            al,RD_EC_SMI        //
) M! W( s- ]4 e" j0 c: `; p" P        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了. T/ Q4 B- Z! u3 G# m8 Q
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
- l' n6 Z6 o! P+ j6 Z' I$ O8 [) O! V6 ]  j9 F+ z6 g
        PMU_Wait4IBE(&dwTemp);( S# M6 A4 V" @1 ?4 [- v
       
6 l5 D5 q+ R0 G; W* f        SetPortVal(PMU_SC, RD_EC_SMI, 1);
4 g2 I) H/ h; M$ B$ a! H! _& n! w8 M$ M6 h
        PMU_Wait4IBE(&dwTemp);
: w; H5 U4 D- y4 F- y        & a' v9 w9 M3 G9 k! t, P
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
# K4 e; P3 I  j# |  [
7 K& B7 \3 F  n6 e        PMU_Wait4IBE(&dwTemp);$ R  F6 l' X# V1 L, ^

7 V; {! T6 A7 @6 H9 ^+ i. ]$ U# a9 |3 {& m        cout << dwTemp << endl;               
# @/ p+ K2 |6 p& V+ j# j5 b7 b$ w/ y8 Z8 E- W* c% g
        ShutdownWinIo();
0 B# p$ z9 t2 M* `3 c5 E! L- `8 F3 C! {0 o
        system("pause");
  E2 S( ]0 ^  ~! ]' O3 b% r/ N& x3 P6 H; D: ?
        return 0;+ e- z, h* C# C5 \, g" w
}
0 o& I& s3 \5 A) @" s" o# o+ X% b0 e9 W: r4 h
void PMU_Wait4IBE(DWORD *_value)4 s; H. ]( [, \) [! h  s' [
{  p2 J, Q" e% G& O" m3 n* ^
        //#########################################################   
5 w- d) o8 m; \, s4 t        /*8 p$ Q1 v* x- b
        pmuWait4IBE proc   3 C2 d/ y1 _# S- G! e" k* T8 I
        PUSH        AX   
! _  |* T9 b3 ]& u! {) P        PW4IBE:               " t: X3 P- o* k: r  o
        IN          AL,  06CH                                //Read  PMU  status   4 t3 h6 j* c& i: D! s1 a
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
. @8 B/ }  c2 n4 L% s3 Y        JNZ         PW4IBE                                        //Jmp  if  no   ( a5 R  j& F; h5 g/ Z
        POP         AX   8 L) k& g) }& C# g' B
        ret   
4 c, o0 m9 u. `$ S  g! w/ ]        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE( G3 u, s( J! I
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空  i- W- v0 v. y1 d
        //######################################################### 5 T5 i% n; n* J5 g
        /*do
  ^6 s: A. x. q" U8 O! p$ G        {: q4 C$ r& H4 l# r* I4 H
                GetPortVal(PMU_SC, _value, 4);9 V2 z/ v0 Y- i5 P% Y% ?: q) V
        }5 Q9 P! J0 C6 Y% j) Q2 C: z! Z
        while ( *(_value) & 0x00000001 );*/, ]% H- C4 H. r6 g: \* T) t
        DWORD   dwRegVal=0;; o& m( O+ V  `; I( V, K: y
        do  Q) u8 g' c" m/ `
        {  
4 z1 m' F7 e- p: a2 {% n- X                GetPortVal(PMU_SC,&dwRegVal,1);
& `5 H. f) i1 H* L0 w: x: S        }5 G: m8 O! K8 K' J+ {$ N
        while(dwRegVal!=0x2);) E% l# l% v) B8 ^' [

4 F0 ~) x- v5 ^, X}
/ [" B. W0 I8 Y7 a4 I# O; Q
. A. y8 u" B$ m$ Z6 E' y以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
  {$ K5 B" r4 c( i$ \所以变成了死循环了。
; v$ R3 e. n4 [; o1 K( c
( N9 j% ^: o/ s& t9 P0 p. B我对硬件编程不懂。又不知道从何下手。; M7 S1 Q: l% n/ f6 U2 e
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。. I& x% V$ ], Q: g6 U: x0 G9 \4 _  [
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。6 f0 P" B& z' p" o
6 ^) u; j6 \1 r
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。+ J: I* u7 Q' U- {) y' [: w
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。0 L; X+ b6 o0 _' B! l; ]
. B8 j; D! F: \( M: O
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。7 ?! P( B& E9 O1 z+ G
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.2 ?; U) w7 i+ R3 v" f: ^
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突' G/ g( i4 k, a) {8 }
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
- W" n! f* h+ A4 s
; e: H3 R% h. N6 ~* Q3 F( x所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
; p6 b  g  |; d3 ~( C& }6 [! P2 x" z" Z# R" q9 c
那么有些什么可行的办法呢?5 K* L1 O- d1 A' E, F
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。5 D, Z9 n9 ]. x  k. {3 \& w1 [) t
1 y/ R% S6 A( G, b
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
- U5 M3 H  A( m8 n( u" P% X9 V* M
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420& o- f7 n  i5 k4 x/ R% G) H

: h. e% D0 t' Y/ B# R4 u3 ~0 Thttp://www.ufoit.com/bbs/viewthread.php?tid=4520 ]* g' C2 j' j$ B4 y% N2 X5 F

- e  U" h0 ]5 R5 S! N/ C* thttp://www.ufoit.com/bbs/viewthread.php?tid=241
7 L5 b" d: M; z) ^1 r, _. \$ e- X) m3 J
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
& W0 N% v/ _2 D2 V! {4 `1 }
1 q8 c# Y, t; h3 ^5 R; {6 |1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。1 g7 V# F7 i3 I0 o
2、Driver最复杂,也需要BIOS配合,推荐。/ Q$ i7 z" Y+ s( z( w
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。2 T, I5 A* H7 v( p% k$ {* f3 |, Q: e
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
6 E8 d. w) \; l, R% _你可以混合使用。
) ]1 `* d) w9 A8 ~6 Q
: F! d6 C& f0 p( P5 o===============================================================
/ o3 ^2 G2 M' G$ ]2 r! R管理员的这句话:, s* W; H- e* ]1 i# k5 N2 {" o
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
) T* E0 I; l& z; l
6 T# G# u$ o5 w& k' M# Q4 |予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵7 J  U& w6 y/ c( V
8 m  J+ a* \# z7 `2 a- s! O
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
* m1 D6 \; I! J4 e
3 g( {$ l) _6 w# d, ~6 I2 V这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
* ~* D! |4 Q) P) R- J; g; n3 M
, ^, d+ D8 e1 W0 B还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
; v: y# c; k( Y$ P( S里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
" f. E( o: ]7 d* S3 ?; x( v( B* b6 T8 g  g( x
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 ! D6 T5 o; S: R  _( n5 c2 v
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。/ y+ N% ?2 k9 B+ z& C: {
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

- Q) L- T  W8 [; H9 \
( p6 W' z$ ]# t3 o' m& |5 Q+ z您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。( x8 W3 ?& [% h( H' y2 K) f0 `
  ~& t/ R5 K8 M8 \
void write66(unsigned char Data)
' N% j! z' C9 Q# X( w/ d{* D5 w. j- v0 s0 k( Q( J
        DWORD Status,TimeOut=10000000;
/ N& s' O2 m6 G4 e+ y* O        do
3 a1 U$ k: r" b; W        {
' W, s% u! @5 p$ Z                GetPortVal(0x66,&Status,1);0 R" u: j% U, |. x, N
                TimeOut --;
; K6 f3 m" D$ I& v//                Sleep(1);
- q- k' r+ E  h+ E$ X        }while((Status & 2) ==2 && TimeOut>0);
4 e3 W1 u3 K& J- _  z0 {  C: `6 X1 s8 e) J. g4 x) s+ ]7 G( [
        SetPortVal(0x66,(DWORD)Data,1);7 b8 W& p9 J4 I0 ^0 N9 h. x3 x& E4 g
}- h: V5 p1 L, F2 U
void write62(unsigned char Data)
- a4 v8 y- A+ `9 K; \3 @! `0 F{
  q- r) i+ g/ \1 Y, o        DWORD Status,TimeOut=10000000;
/ _5 g* k- d8 J1 g4 ]        do
9 M% I' A; w; k+ i5 s9 z9 m        {: o" w( t8 Z1 [! C+ a
                GetPortVal(0x66,&Status,1);
  Q4 ]. \+ n' F  W' S7 A                TimeOut --;
' B; C* ~3 G" Y4 V) o! s//                Sleep(1);* c9 x$ d! e# E5 o
        }while((Status & 2) ==2 && TimeOut>0);
6 q& i: W2 ~" s# E% ?& ~0 v1 d# Z$ o1 t5 f& F+ E4 ?
        SetPortVal(0x62,(DWORD)Data,1);
! P5 `; \, [0 Y4 A0 m, u}
3 G9 l' T/ `; z! x: L4 |unsigned char read62()! M. @- q5 l4 d1 P
{. ^' C6 n/ j8 J: w6 a
        DWORD Status,Data,TimeOut=10000000;
/ c* R, O0 P- U  v$ d4 b( f: P        do
+ o  [0 e7 s% P  M# H4 T        {
0 p4 S. @4 N% j% C+ j% P# E                GetPortVal(0x66,&Status,1);$ |; ~* d. ^. W' [$ e7 B
                TimeOut --;
0 @, n! g& b8 I0 c/ c//                Sleep(1);: A* J9 ]+ X5 M1 G6 i$ ?
        }while((Status & 1) ==0 && TimeOut>0);! N4 y2 `' D& [

9 w+ r7 q  R) l1 w7 r2 s# C0 T. G! e" O% j6 i7 ]0 F  I
        GetPortVal(0x62,&Data,1);
) i/ Q5 ?2 s, b' W+ }6 P$ p+ S        return (unsigned char)Data;
( ]" ]& G5 X3 }}* q9 O: x' Z3 S0 M
unsigned char read_ec(unsigned char index)
3 s7 l& q( k% K. A{
( o4 w4 O6 d) \6 C/ U4 M        write66(0x80);' |, X$ L) a( \- C: R* W7 O
        write62(index);
( c; g9 K6 y, @0 i9 _# v        return read62();
5 J* }& X) F8 |1 V! r- @8 U}$ J/ ]6 }) u( }' u" w1 o4 h+ q9 |
: b/ a2 Y. q! @( `4 G4 j# X
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
/ r! B. c6 R; n2 `4 n0 f1 ?) K" U; ^( i) _: a' F5 P/ T  V5 [, |

! H* d7 i+ m4 W您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

% j* \0 z3 c! c: Y8 Z1 q, P/ O
0 s0 z9 ?  p& z  _8 r8 s+ r% [! s1 |5 V1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
& v+ x9 |1 X) `% f: ]& @( I, R8 @& a
' l- ]! p! p& Y% `2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
$ ~, E* X2 x# M* ?0 ~. n, F2 `; ]5 `+ z( h' L  f5 K1 y* l& s
3. Then set bit16 of the IRQ to disable it.
$ a8 n4 ^. _# I% \* m
- U: ^# N, }7 C; E% ~1 B9 v    a.. Offset = IRQ# * 2 + 0x10;
: w- J. l7 G; @# J" {
' n1 x. I% F9 V0 U% a: W! U    b. Write Offset to APIC base,' X& I! |" x; I7 c% o) L
  q0 U7 f" U; J" o
    c. Read Data from APIC base + 0x10;* n; w$ D' h" a2 K7 ?% S

# U  Q$ @& Z4 E3 U    d. Or bit16 to Data;
! M6 c( |& |3 D7 V' X, T8 @: F% k: I1 t. F
    e. Write Data back to APIC base + 0x10;
/ J1 `1 K) ^/ r$ d$ F
) B( z& }+ `! r6 t' F" }
! }) F8 l% U  G9 _& D/ L6 e) P) ~0 H: z; L5 f3 G8 l$ ^" ]
You need to check APIC spec for details.
回复

使用道具 举报

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

( ?- y2 T" u  w4 s  ], r& ?/ o0 g( X, Q' Z) h
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。: o, y* D1 U( \5 N) n1 o
==============================================
- }; c0 \% \. Q" C# J 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
# X9 m) e$ V7 O, K! g
# @/ J' q% M! |) ^, y因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
2 C. ?6 b2 [  t) N$ F; [但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
. O4 u. j1 N! x% D2 w) F% K' W) q! E+ k4 B. q# F7 P
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。5 g6 b$ f7 z( X
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
' Y, t/ m6 t0 Z5 G9 o) V1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。% T# R" K3 W' o& H# X
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-4-4 16:17 , Processed in 0.139567 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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