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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
! R, l3 x/ t: [/ {. }- o#include <Windows.h>
# W5 X. }4 v6 M5 @) A# W#include "WinIo.h"4 O! m1 X" ?3 `! d4 y6 M8 H
using namespace std;
* X3 l3 ~. e$ [( @; ~3 Z6 `% Q! ~* Q
#pragma comment(lib, "winio.lib")" H7 G* Q1 G0 V2 q( Z  X+ Z8 O
0 X8 K* o* S) z# V& {
; Z! r# O& \# n& Q0 V3 |
int PMU_SC                =        0x6C;//命令端口
/ K4 V& t  M" z: gint PMU_DATA                =        0x68;//数据端口+ Y# f1 Z6 G7 o- w# ]1 M2 k
int RD_EC_SMI                =        0x80;//读寄存器命令
, H' T- G; K4 f0 h* Gint POLLING_DATA                =        0xE7;//CPU温度寄存器号# }- b% O9 @6 w

( J% ^6 y3 p5 t5 Q4 r; Z: c7 |DWORD dwTemp = 0;
/ G& r( e( x7 Q; s4 e: s* L' d* u% a* r/ ?/ I
void PMU_Wait4IBE(DWORD *_value);
7 V. f7 \( ?! u* {2 E9 xvoid PMU_Wait4OBF(DWORD *_value);% P$ A' \( h" A1 Z1 Z% M

1 B1 O  |- L- O- p) q1 e2 I$ M  ?( W0 `% ^# ?/ H$ n" n
int main(int argc, char* argv[])2 G; Q9 E4 I' F+ l
{
+ d+ o( z7 F* ?        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;+ j4 r5 d2 Z: q/ O) M" ]

* l& p! s% J- r* G8 ?" @& d       
. P( M' b; Y! o) M        //1、mov            dx,PMU_SC                //+ V( m, Y; j6 ^4 _+ o
        //2、mov            al,RD_EC_SMI        //
( J- C) ^& O* ?/ i4 o        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
# M4 [  _2 r" h& R" Q( ?5 X        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
& ^3 m# u0 r/ S: V+ K& a/ k) o" g3 Z
) j& b0 e# G, q, j+ ?        PMU_Wait4IBE(&dwTemp);
8 s* ]' n  G  I5 I$ F% I. Q       
4 o# Z/ n0 ?- c/ Q/ ^, e# S# H        SetPortVal(PMU_SC, RD_EC_SMI, 1);
7 S( D0 d0 d3 _$ e# e/ @8 A; j7 N' u+ n  \0 u5 ^, H; N, v
        PMU_Wait4IBE(&dwTemp);$ x- f& M4 n- @& n9 H* I* C) p$ V
        : [0 O! M+ v8 c+ b! h5 U$ I
        SetPortVal(PMU_DATA, POLLING_DATA, 1);* I5 O/ Q3 Y, R2 ~4 B3 L
3 V, g3 Z* v, l
        PMU_Wait4IBE(&dwTemp);
1 F5 }; h4 y. V
3 R2 _1 h/ j0 H7 Q' x        cout << dwTemp << endl;                4 m# u$ }& d& F4 t- q" `, e
3 J! m8 G! ?- H, t5 Q0 {6 [
        ShutdownWinIo();$ ~. z0 R+ m. ]% o) C, q
1 |, A7 a7 k* H
        system("pause");
8 ]" n/ H0 o6 Z7 R. O* g9 k6 H8 I" P! R" [. j: C+ b
        return 0;1 T' L. ?4 N# U. z0 t: |1 W
}
5 e# ^8 \4 r# Y: A7 m! W* y2 P) ^! \5 V: H: R
void PMU_Wait4IBE(DWORD *_value)
4 P/ }# q5 ~3 j8 p9 Y) c/ W{2 K7 X9 A4 q* E( {" S# I# V8 `% s
        //#########################################################   
- m. ]; ]3 L& [; P+ }6 A! m. a% L        /*: c/ ]6 X) [. r) V  P. g
        pmuWait4IBE proc   + N  }' I8 F; W9 A, {% y+ \) b
        PUSH        AX   
! }: x1 s  J% ~6 n+ X3 Y        PW4IBE:               
- g7 |7 G# X" K* C0 p  B: \        IN          AL,  06CH                                //Read  PMU  status   5 h! \2 p, s% d& `5 ~3 @8 M
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
# A0 Q0 C: E/ K, d( s! V        JNZ         PW4IBE                                        //Jmp  if  no   
$ ?- e' x4 n8 S' K, \$ c% c% R8 }        POP         AX   8 i+ h7 K) D# {4 u
        ret   
  Y4 \5 N$ E! E/ n9 K2 d: [. k        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
1 `) E1 c. g; P& x4 L        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空" t2 O, Y# b: L# z7 y5 b
        //######################################################### 0 P# R/ P3 [$ _  {
        /*do 3 e7 F; D* Y  j( M
        {
, j6 |: ^0 E0 c  A! J9 h# E                GetPortVal(PMU_SC, _value, 4);
2 {0 k) V& N7 }! s# u        }: x, V- ~  [5 y3 W, Z# o; c, s
        while ( *(_value) & 0x00000001 );*/
9 z# |7 w! k& A8 X0 [9 Y, Z        DWORD   dwRegVal=0;# f& K; w& L& p' E5 m) o7 w* q
        do; n- _8 [1 T( @  ]
        {  * E/ N' R- q/ q) Y2 I
                GetPortVal(PMU_SC,&dwRegVal,1);
; |% h) |8 K4 r0 V5 o0 _        }
) `/ t- e( |" P5 N5 S        while(dwRegVal!=0x2);5 x* X2 g+ b0 M. \8 a& K6 m' N

5 {0 e0 i: r% Z}
' |4 d5 v, w& o0 W
; }  ^4 [. A8 d& k( o5 `2 k以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。( ]8 I7 c5 t+ \3 b
所以变成了死循环了。
. ~7 l1 v/ w2 H* c  h
3 h& l: g. W" e/ E我对硬件编程不懂。又不知道从何下手。% U/ v0 T  ^3 q
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。* x% G% P& o: e4 c7 n
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。5 Q1 o3 b  Z$ I; P) ~( C
) \6 B& S$ S. ~: L
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
2 ~; G0 y6 d! I" T* u& S1 T& s$ P5 X. I并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
& w- A# |7 ^  N4 ^/ T2 H, v
* z8 C8 V/ t% O9 G感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
* K% Y3 P0 x% Z  g9 o( F1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
- y6 e1 G% W+ i& V: X, T2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
4 [4 ]5 i& x6 u" j. l3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
5 a& ]; T8 w9 B9 c1 g2 u% h2 F; |/ |+ [
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。# f" S+ Y- G2 M# Q8 k2 r* J# a

7 H: W( J# N# s/ q3 }! z; P: x8 `; ]那么有些什么可行的办法呢?
  e/ e6 p  I" O. q7 e为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
. [8 s$ Q. \( K% h( f" \
( d. }$ x1 B. f8 T: l它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?4 e) E( D) v1 I+ d% J2 i6 W0 L
3 Q+ F( F1 Z9 j" v7 g
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420  N8 B. d! k) q4 z0 j) t
0 Z8 }# {# `& d& @2 i( [7 a% Q
http://www.ufoit.com/bbs/viewthread.php?tid=452
- h7 Q% y2 h" T" O  h, {* E# ?& j/ `" t" f9 l
http://www.ufoit.com/bbs/viewthread.php?tid=241
5 V. s3 n+ q7 ?' }, w1 [! k
1 Y+ E) J& j$ M" k' h7 {看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

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

2 g% {* C! O1 b, F% C5 m9 a$ v1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。( m" z, Z5 K3 N
2、Driver最复杂,也需要BIOS配合,推荐。- b" j1 b0 J) v- p3 M5 ^! H
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。; m1 q: ]5 y9 R' o5 C
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
1 d- Z6 C; W; o' x你可以混合使用。- T. X; W2 V7 K1 X4 ?0 e

, C2 A% q( y$ W7 b===============================================================! n2 E5 f! u9 s% m! _6 u4 v; p& h
管理员的这句话:
- V) m( K0 k& E5 ]7 a* C. D' }; E5 I如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?/ l5 ]9 r( P" `: w1 F

- m8 j3 c& [3 n, D; f1 q5 g予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵$ |0 y! `+ r9 }
$ k6 i: {  [: L5 w
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
, r2 e2 K, W( d# Z9 o. h' Q8 ]8 G; M
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
; o5 O% F# G8 I; H# c1 B% j: o5 U) m6 I9 K' M
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。  b, X( q' P+ Y) p7 i
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?4 Y4 B( v" s: k! u" s

6 K  L0 h: n1 p1 u我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 7 u+ V7 ?# }8 ^
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
# C, i9 q$ T& R2 K4 j1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
$ \- d1 Z9 ~4 p* n  y0 b1 t
9 C, ^9 |- p# ^4 j& [
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
: y- ~9 E3 [4 Y
5 P7 g2 O# Y2 z+ Ovoid write66(unsigned char Data)+ M! e+ c: u* B
{
/ k3 a9 v; l, J! ^( F3 b% ^        DWORD Status,TimeOut=10000000;
. [- q$ E: |' c* M3 E        do- d& O* I1 q4 F. [
        {
% ]7 l7 p( X1 \) b4 B                GetPortVal(0x66,&Status,1);9 _, L& }/ y) \- r
                TimeOut --;9 q6 {6 U' {+ P* u2 h( X
//                Sleep(1);
. b) `! S& v, Q9 y" n7 i        }while((Status & 2) ==2 && TimeOut>0);- x$ I: R2 }8 k+ G* y- a0 g+ M

- O% M% J$ B* O        SetPortVal(0x66,(DWORD)Data,1);) a: ^( m+ N" g1 _! ]
}* Z8 x& K# Z- b9 L7 \
void write62(unsigned char Data)
- m$ U9 E1 f( Q9 X, ~0 V{. i" p1 i4 ], P! B# s) t( [$ U" c0 S
        DWORD Status,TimeOut=10000000;  \" }" e; G# O5 l
        do6 o2 b5 Z# Y' \2 M8 t; o' T: D
        {
8 _) K9 m- z, y, e& W3 R                GetPortVal(0x66,&Status,1);, U# B7 e" u% F9 H3 t3 R9 z
                TimeOut --;
% }  X9 \! H& X$ U2 a, Q5 X6 J" }1 ]//                Sleep(1);
7 Z2 K& Y# j1 s        }while((Status & 2) ==2 && TimeOut>0);
' ~# h# v& r# t5 K2 q( i2 `4 V0 p% Q3 Z# O* i
        SetPortVal(0x62,(DWORD)Data,1);. z& r0 e+ E5 B; _" x
}% G6 c1 J( e( T6 M2 G4 V$ g7 m
unsigned char read62()8 i1 l4 x" {9 N
{( G# C/ S. Q- `9 q% d; T
        DWORD Status,Data,TimeOut=10000000;/ {8 j: f3 t* D) I0 L; o
        do, g* W6 y% E) D9 T
        {
/ d1 [* G+ I7 q- ^                GetPortVal(0x66,&Status,1);
/ X& @% u: F- e                TimeOut --;# O6 L' K, D3 X
//                Sleep(1);$ d5 q- }/ v  B7 {) i0 ~3 s
        }while((Status & 1) ==0 && TimeOut>0);
, O7 U6 S, C8 |) h2 r1 D# n8 g( h$ e
# E# g4 f/ {+ C7 s9 g8 b  D: D
        GetPortVal(0x62,&Data,1);
7 ~/ \9 u% s8 N. Q, |6 |  ^4 e        return (unsigned char)Data;
9 Y, H8 D+ u0 N}& M$ l% _- ]( I4 l: `) N
unsigned char read_ec(unsigned char index)
+ \( U5 F; }9 Y# G8 E7 s# k{
/ g4 N2 z( F# r* f        write66(0x80);% w) D2 J& I. t( m
        write62(index);
' ?# l5 h& V7 b0 E& [        return read62();
( h& K' B9 }$ h1 c}6 I0 Y! h8 r! P! p8 w: {) z: M3 a

# c' ~- L  x. J: h% V$ Y) D[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 709) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
; U$ F! u8 Q* u  k; Z2 }  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。' k( ?+ m& u3 i5 G, s2 W0 G$ d
0 _- t0 ?, v$ _- R* T; s
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
7 @4 Q1 m/ q6 {
& D  @& n$ l" C) w* n
( a) ]3 w) ~" t* x: V; @* c2 C您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
1 ?' B+ o. f3 o6 c5 B6 [0 O0 e

6 I2 m. N2 Y1 x7 E3 h; S- K$ T! s+ I1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,. j: M: Q" l: h6 B* `

7 ?0 G, O" u6 u$ |4 U4 X' R. i! h2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
. W; ?9 s  x6 H( J% Y8 Q$ ^6 q% _0 h( `: t
3. Then set bit16 of the IRQ to disable it.
) g# w) W  S+ X' c5 W2 [& m" z" o1 f  V) l
    a.. Offset = IRQ# * 2 + 0x10;5 X- M6 ^& z* F/ m8 y$ a& z& ~- k
" e5 m) J6 |/ d) n! l: G$ a  i+ j
    b. Write Offset to APIC base,. U9 x/ M- q; j! g* \

& }- C- W/ @) g$ n# q( G& y    c. Read Data from APIC base + 0x10;
' c: R) W) j" `7 I' ?; G
; h& W$ x. ?, F% z    d. Or bit16 to Data;
$ w' X8 k, X# \, ~4 h8 a# \, H
' b  b8 W9 j/ E8 X; E3 e3 _    e. Write Data back to APIC base + 0x10;
9 f, b, [% P4 w9 h7 u+ s& o) V" a1 M' f' Y1 Q& J) N
* O5 k8 T, U4 y0 O0 H* Y
8 ^7 y' P( b8 W& o/ L
You need to check APIC spec for details.
回复

使用道具 举报

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

- W( B) r$ M' E, [' p, |' H7 F. S$ \+ [7 q
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。7 ~, E4 r. P0 D4 v  r
==============================================
. x' R6 ]7 d/ _$ Z! F' f8 Q' g 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
1 B9 T0 i% ?& I# h$ q: y, ^
9 l2 {# e: o% Z) s因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
- V# p6 @7 V. B" r9 I. R但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。2 F. t" M$ d) e# a% l; p

. {4 t2 T3 ?5 I- b( Z因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
- o7 ?/ d3 z2 X$ h( z7 G9 c当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
! n/ Q' D( L! i, v; u& }5 Y7 x7 M1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。9 ~: ?1 M2 U* m7 o+ v
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, 2024-11-15 01:58 , Processed in 0.037053 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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