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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
9 S5 D# d, y( t0 q* q. X4 L#include <Windows.h>
. j! `& k$ }0 s6 Z& ^7 B#include "WinIo.h"
- o# P& Z. B% Q' L. v* k0 W. U3 dusing namespace std;
( D  @$ u$ D$ _$ d4 B: \2 u+ {1 U2 X4 S$ \9 r6 d
#pragma comment(lib, "winio.lib")% y' o  L4 ]% v9 x8 v+ U" {1 \
. @& f9 f, \+ }9 S% X- z

; [* V% V2 S# [; m2 l9 n7 k: [int PMU_SC                =        0x6C;//命令端口4 U% x& I1 ]" z) ^3 j5 P
int PMU_DATA                =        0x68;//数据端口
+ ~9 }3 h) }1 e2 R8 \" |# c6 tint RD_EC_SMI                =        0x80;//读寄存器命令
6 b+ p3 I7 C% G* T6 w$ rint POLLING_DATA                =        0xE7;//CPU温度寄存器号
/ n2 C! E( U9 X8 @7 R0 l
; @- \$ j' M6 ?4 L. m. D0 f5 |9 u: hDWORD dwTemp = 0;
; ~6 b4 b1 l3 d) G$ s; K! I, J5 i$ c
2 h! ]$ y0 U8 P4 Pvoid PMU_Wait4IBE(DWORD *_value);+ H* y4 o3 n. c) f& l, v
void PMU_Wait4OBF(DWORD *_value);! A9 b! N% G: q/ \! ^8 @  }. L
# w5 E# D/ A- V

! ~" m1 u0 _' S$ _) C0 Z% B# `. qint main(int argc, char* argv[])+ m# y6 [* U, O/ `- ^
{1 A* `; a% {8 H2 h5 N4 r8 u
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;' H& {: t' N: B8 Q$ y2 j

% ?# H  L: r' `       
) Y/ f7 ~% L4 M7 ~        //1、mov            dx,PMU_SC                //2 d) |" S' V2 B8 U; [6 S* {- R
        //2、mov            al,RD_EC_SMI        //
2 k. T. g' y  {        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
; e  v. r, C; O2 @; I2 S" @5 E        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
4 R8 H  a& @  ]# ~3 T8 n5 B" m$ r: {8 {2 K7 U! B
        PMU_Wait4IBE(&dwTemp);- z# {. v0 Q3 {6 f% i; L
        $ d4 w1 C5 G/ f* L0 f
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
3 Q" n# p/ j  L% \. H$ c' r8 k/ U. R0 `6 @; i
        PMU_Wait4IBE(&dwTemp);1 O; |6 k4 m1 h. j# ]! s' s9 Z
        9 p5 w9 ]7 V0 C! I6 |, N
        SetPortVal(PMU_DATA, POLLING_DATA, 1);+ K, n3 N: m" _

( W4 Z, z" z6 Z, _7 P& _        PMU_Wait4IBE(&dwTemp);
0 D! `# o0 l2 C' ~" P! P5 h/ _- U8 V) x; A* u* Q& a8 \
        cout << dwTemp << endl;                  J+ m8 A* O# W, K' s. T  p# N4 G

. Y7 f* r  q, w" Z/ I        ShutdownWinIo();
: D( h3 d- i8 F; g# \8 O# }. m
: \# k7 J7 A. f' L/ i        system("pause");0 _5 w7 ~; B2 {2 D+ |( M( r" t7 l

- P# |) _) V5 h2 P- o; x        return 0;; S. Y) o# O6 Q+ o" b; s( I" {' b
}
3 L. m3 B* e* R
- T* @7 G) g( a+ W: r  J' ]- \; B0 n( `void PMU_Wait4IBE(DWORD *_value)
5 Y3 K# l7 @' ~) j{) d/ k& G4 ^' q8 |3 ^
        //#########################################################   
1 r7 p5 ^, h1 s6 |4 E- @. A, o/ z        /*
5 o; ^! W2 \% D- C( m' u/ u        pmuWait4IBE proc   
# v# `% I  H$ K        PUSH        AX   
5 {3 {8 b9 j* i8 u: j6 N, H, J5 `        PW4IBE:               
7 m. m: Y/ b9 X7 ?4 p2 @; w, C        IN          AL,  06CH                                //Read  PMU  status   
; ?4 ^1 Z1 _) Z0 [' y& @        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
0 Z3 U8 [! z! g% i        JNZ         PW4IBE                                        //Jmp  if  no   
- R3 l" q1 h7 W        POP         AX   ; p0 [4 A' W' T2 `' t0 H- K
        ret   2 b# b/ I; x$ g* U2 [
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE" j" ?  P. M9 d( [
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空! i2 E; m7 P$ j1 ]/ e/ l
        //#########################################################
/ z7 v0 k: u9 O9 S$ F        /*do # h; k( g6 B' ^; Y
        {
! W) q+ h$ @6 h! \                GetPortVal(PMU_SC, _value, 4);+ p: W0 |7 D/ S# t; j% {
        }- _) i( f3 I) x# }/ g8 W) _$ E
        while ( *(_value) & 0x00000001 );*/4 s( c" o9 Z+ t% t* ^
        DWORD   dwRegVal=0;
+ q- ?. B- ?; n& V+ [; }8 b6 [. S        do% S8 L2 N$ a: N* F  b$ Z
        {  
% u. s' m  s% q5 v, l                GetPortVal(PMU_SC,&dwRegVal,1);
2 I' b' X% ~+ \# B5 u5 ^9 C0 N0 I) E; ~- r1 ?        }
2 V2 s2 p0 g* M  g, k. ]: _0 n  H! y        while(dwRegVal!=0x2);2 j" K( k. r3 I  l* }* z+ e

. ]% i+ Z: W1 ^- T}
# D/ w: v# ~* b  \  m4 X  B
2 M1 _  N/ O9 s- z& p2 {以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。3 @2 I) T: k$ k6 O
所以变成了死循环了。7 Z( k0 l1 Y( D0 {1 w

' `% H  \. @% A3 [我对硬件编程不懂。又不知道从何下手。
+ \3 [5 J5 @! A, c  R+ @我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。; u9 o& ^" f6 B9 Q9 W4 d2 y
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。9 W% t  V) f1 Y6 X+ w$ H
, \/ a0 F9 j# T( |! I
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
/ ~+ y5 J* [& J! j) N1 s/ d并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。0 {0 G3 o% ?4 D, u

' ^! o' c- k7 U, y; I感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
& H+ o  Z' s4 H% f2 E: y* K/ c1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.$ G8 g9 y' ^5 D; N1 i8 D  F
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突* T$ L. y, b# m
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
9 n. Z! Q& T4 a: o4 I) j( B6 V0 R3 U# X* k3 B; ]- |& e
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
$ L# M+ j" I' B( b3 c1 M) j# I
1 b0 C2 O' |% l" `6 C0 S  M& x" C) v0 v$ F那么有些什么可行的办法呢?
5 B$ _  r9 r& s- [为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
1 A0 `+ F: S) i9 P, }9 J  P+ M8 q9 c# f% U
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?* e* I* v* k" r% o2 M
0 e( }4 z2 V$ o4 K5 ?& x) W
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
6 v0 ?  K4 h4 J3 B/ x& O5 m9 q+ o& e
http://www.ufoit.com/bbs/viewthread.php?tid=452
# Q0 c3 V, C, l  h. N8 `
( M6 L; T; a$ W! y6 o6 uhttp://www.ufoit.com/bbs/viewthread.php?tid=2411 }' Z5 Z5 G& _- l) }

* ~' Y7 _( [6 ^! r$ [3 v' A# f看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
' }4 P8 R- g* `" c. R' a( D( _' k
+ u  g! B, ]' R8 ^8 H7 }1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
- K" h" P$ j3 U3 a7 L2、Driver最复杂,也需要BIOS配合,推荐。
3 \2 _, R" t$ g. ~: j3、Windows API只能获取到特定信息,不需要特定的BIOS配合。, l- K! i8 L$ I5 K& @+ s
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
; k+ E% {0 X+ P* j3 N% d. F你可以混合使用。
# K% y5 o+ J8 c
* c  j6 i5 K& E3 P' h+ W===============================================================
) v- F' _. F8 _! ~管理员的这句话:. ~- h. g% Q! F9 P( m( Q& w' ^
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?5 ~/ ^% z$ z7 h( P
6 K+ m* j- @9 q3 B8 |8 N# w
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵1 j- w' _. Y( q3 D

1 N" b3 b6 _* {, k2 I另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
4 \9 [8 F5 x& S3 Z
; l- z% T; i; d这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?8 @) a  i% c# t( B- j- e

0 M) r: x# \, n. k2 f( g还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
1 p8 k$ y% }0 W! P$ h- h里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?  O) D6 q% _0 ]3 Y

0 K: b, a2 U3 Q$ q我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
7 c% @  q0 w2 J4 c6 _你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
1 T) A* E1 \, l( N1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
, s) K4 y$ W! l2 C4 U7 A- H

1 A, [+ D. n/ J8 `+ R您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
* t: l% u( [  P; M$ G9 n
% e6 b0 w7 E4 {# [: c+ q8 Z+ Yvoid write66(unsigned char Data)
5 p& `/ L* u) f( V! E; Z" R{
8 k% f. k( ]- w: c6 F4 u0 R* ?6 Y        DWORD Status,TimeOut=10000000;4 E5 c( Q( P7 H  m
        do
/ r: H/ w, u" g/ R" Z        {+ E  F4 l! [5 E
                GetPortVal(0x66,&Status,1);
7 z: ~- P2 z% U2 N: l. O0 z! t                TimeOut --;, @5 ~+ s& w( Y+ P2 c
//                Sleep(1);
+ o8 a' j, L" }' e        }while((Status & 2) ==2 && TimeOut>0);
  N2 [+ h7 i8 B) }5 t4 v2 @3 Y$ A) s( C& {/ l
        SetPortVal(0x66,(DWORD)Data,1);
2 w6 L& T4 D/ n* k}& D5 z9 M1 N- n' O8 m
void write62(unsigned char Data)* E6 ~' ]& m/ l/ m! d3 i
{! a% x5 u& U4 W1 h6 P
        DWORD Status,TimeOut=10000000;8 L, h( ^) ], |0 j6 U; x
        do& r- k" y6 A4 p4 l8 ?1 _
        {
4 g! d$ P+ \: w; t) Q2 ]# j                GetPortVal(0x66,&Status,1);
, e5 h* U; x4 U5 X; J  z                TimeOut --;
' b% X2 P4 R7 @: T+ m//                Sleep(1);: a2 Z6 N  ~6 t, N
        }while((Status & 2) ==2 && TimeOut>0);" _2 r7 Z2 O- l

# M! W5 q2 k+ }2 v! x: b. [" {        SetPortVal(0x62,(DWORD)Data,1);* X( g4 Y- [; z) l/ \+ m
}1 g' |( @9 F2 e* N/ Q: R
unsigned char read62()+ j0 J2 `& B5 i) I- R
{+ [% M8 L" r6 J" z
        DWORD Status,Data,TimeOut=10000000;! e3 v2 W8 B& q: |
        do
( @7 ]" S  {! w, d9 g1 ?" o        {
8 W6 ?2 Q) v7 ~& Y+ S, C                GetPortVal(0x66,&Status,1);
; A: I" i5 t9 W% z2 B, E! c6 ^                TimeOut --;! C+ n2 H8 r" B/ x# I
//                Sleep(1);4 \% ~# p# S8 @& j" N4 T) B
        }while((Status & 1) ==0 && TimeOut>0);
! o* z9 {. z* _# J( ~4 @) o9 u

6 i/ O! e, u* q6 K0 b: ~6 k/ d        GetPortVal(0x62,&Data,1);
9 B$ y+ ~' e; I! t( o        return (unsigned char)Data;
' [! i& E* \/ [3 c' r6 j' j}  y& P2 O$ P  K+ p
unsigned char read_ec(unsigned char index)
- W/ L9 N/ P" u& G{
: j8 [+ Z* c; G; i& r2 U8 N        write66(0x80);! r' T8 L, {/ C! M6 i
        write62(index);' t1 O6 I8 u0 a- U6 j8 ]
        return read62();) _# m  o! j! Y" g! s' A+ E1 f% _
}
+ c# h0 ?, f& O1 n1 S/ e& x7 }% t( u
- [9 W% C; Y. g[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 + i' J3 V- d5 H& v2 W6 o

2 W8 m0 u3 O+ U; r/ A2 t  L0 N$ ~3 y
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

$ d9 o' v" ]; I8 h3 m; E5 h+ [, R) X" q3 W7 Z- ?6 w2 \- q
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
. E4 k; p7 v5 e- l
! c2 J7 Z3 e. a! ?5 k5 ~2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
3 i, j) R9 s! m. S4 ~0 |' H/ y$ ]
3. Then set bit16 of the IRQ to disable it.
" E7 G5 ?+ y$ f+ \- t5 t% i2 J5 y; F0 Z: |5 I+ u
    a.. Offset = IRQ# * 2 + 0x10;
( y7 `0 n+ Q" P' U9 L# A
0 G$ c' D* q& {, u    b. Write Offset to APIC base,
# _0 v, X9 I8 i8 H# C) S& [3 }) d
0 a' _6 d8 H" j3 ]' ^# R    c. Read Data from APIC base + 0x10;% E; {; X- H/ {+ G0 E

+ n6 N) m5 N5 Y$ m4 j; |    d. Or bit16 to Data;. v  R' Y8 I0 ]; o2 {: I
( {0 @1 G! p8 Z2 S7 e: H0 i
    e. Write Data back to APIC base + 0x10;- e: t2 U, ^0 e
3 P) h4 \- _- _; Q. _
5 C: n: \3 e4 ]
5 z- L, _2 T, J) S: U! k
You need to check APIC spec for details.
回复

使用道具 举报

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

3 C; L; s! D% h% ~! B' X4 U" |6 L7 m9 W7 C! u# o! G
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
8 }5 K  B% P8 s( h2 @8 @6 z/ p==============================================/ F& _- n- G$ c( l! ]$ S6 }+ I
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。! z7 m& z3 E9 e/ U! t/ j+ A
! q. @7 [: }7 [1 `" {! ]9 X, g6 s
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)9 ]0 o6 b: u, U8 a$ _9 r* o
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
, A1 S8 ~9 b: c1 e  @) i
  ^3 B9 c! X: Y1 g因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。+ W& @% F( l; B9 b. W
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
1 X6 P! M! b; Z- r2 K! T) E1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
3 ~  X4 d9 B8 h# t% E2、新手不要把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-12-1 02:08 , Processed in 0.096379 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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