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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>% `: V( K: x+ E. C1 [
#include <Windows.h>
7 I' O+ m3 p- y/ L  g#include "WinIo.h"( x" L/ n! r' ^, J1 ?
using namespace std;
% Y8 p) B+ ?, o$ \. g$ i/ C
/ R. b) n9 U0 w; P#pragma comment(lib, "winio.lib"): u  C0 D' j. X3 _$ M3 z

2 ?$ |1 }  H  Q3 J, }0 C* ?. t1 ^6 l' f4 `9 e
int PMU_SC                =        0x6C;//命令端口
8 B1 |2 {8 L! m& k* hint PMU_DATA                =        0x68;//数据端口! U* ]2 A! M1 x0 Y
int RD_EC_SMI                =        0x80;//读寄存器命令7 p, W4 Y( a) J' j
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
1 M* q, D5 ?' |
; Z9 V3 g+ y8 YDWORD dwTemp = 0;
" d0 J; _4 y9 g/ B( v$ F" A* ?7 b( u& i
void PMU_Wait4IBE(DWORD *_value);* @2 d/ S4 L) [" ~3 D- z( y. [
void PMU_Wait4OBF(DWORD *_value);
$ a1 a8 U- b# w. v  j2 l1 i
0 w) x% `' x7 u" s
2 o. S. r1 h* A7 O! w) V4 dint main(int argc, char* argv[])5 o9 \7 C& b0 l$ _1 p
{; O: f% i1 X. m- [3 n- _2 D
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;. P2 X9 z" @" f2 b2 X6 h
% L2 @+ e2 S; L
       
1 n, l% g( m) h, d" Z        //1、mov            dx,PMU_SC                //
9 A  x8 J+ w  T( C0 ~        //2、mov            al,RD_EC_SMI        //
: W4 ?0 J  F  V; H/ N( G7 s$ l        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了8 o$ N. W  {8 e* G. D$ {1 K4 y
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。% @" E* P( v% N6 k+ _1 l0 P

8 T, c% z* Z1 J. _; E. D        PMU_Wait4IBE(&dwTemp);$ v- a2 a0 \, M4 a/ D/ [
       
. e5 `: t" B. Y( {' \        SetPortVal(PMU_SC, RD_EC_SMI, 1);8 B5 d$ J: _/ g$ G, y" Q
. S  v8 P& o: Z
        PMU_Wait4IBE(&dwTemp);$ m) s! Z& d# L" o+ z& c' i
        8 h1 _+ ?8 ^; i
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
# N/ W4 X* L7 Z
6 W2 [% q# h$ v) B/ U3 T- O        PMU_Wait4IBE(&dwTemp);8 Q0 D+ o  O* `
& c- q! m- c( c8 n+ e$ U5 {& b* o& ]
        cout << dwTemp << endl;               
9 q+ @% l3 Q+ B- f4 F; ~; t# I5 O+ ?7 x3 [# H2 P2 _
        ShutdownWinIo();
) `% r* ^, }& j. m' G2 I0 x0 x" z/ X, i8 X+ h! \
        system("pause");) A; v, @7 J7 n* y

2 V$ }; p: h, r$ e' }. x- T4 C        return 0;2 p- `6 C$ G+ X5 m! @& A
}8 a: P' j" o* {) V3 e

1 c2 T( {$ G3 b; lvoid PMU_Wait4IBE(DWORD *_value)' r7 s7 P" u  c
{
# u9 a( n) Y& a4 }6 j        //#########################################################   3 H, ^  P  _9 i0 M; P+ Y( U2 D
        /*
6 b1 |  n1 i1 I; c        pmuWait4IBE proc   - A* v2 O: E: y2 t# a( ~3 O
        PUSH        AX   
! c4 n" U6 s! p- V- c' `        PW4IBE:               
5 O+ J, F- @$ D  h( F6 D        IN          AL,  06CH                                //Read  PMU  status   
7 m6 \7 J- s+ V' y        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   & s6 ?3 G* Z6 K, y
        JNZ         PW4IBE                                        //Jmp  if  no   ! ~+ W. I$ F* p8 Q( R
        POP         AX   
3 d' c  N  K/ ~6 S# K) H& n( z        ret   # J+ v0 m2 G. l5 g2 J
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
. @: `% W: h4 P" R( m* z. y        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空; W# j# j+ X1 M: }2 j, \
        //######################################################### $ O( {) m6 v) {
        /*do
9 u3 B) v: m$ G3 _: r        {. }( E9 D4 ?; d$ Q4 H9 h
                GetPortVal(PMU_SC, _value, 4);- S" y: B7 e4 w7 v" j
        }" E& a: N! E# F. Z) a
        while ( *(_value) & 0x00000001 );*/
! H$ |- F! {8 P) Z8 j        DWORD   dwRegVal=0;' X. a8 M) z" D) R9 V; s
        do8 G- G. A8 |7 M" F& L' c
        {  1 w% k2 k; b; G: Q& ~
                GetPortVal(PMU_SC,&dwRegVal,1);
; {5 X/ W/ n9 m* C! [# r        }
# t8 H! I5 \* _/ y8 U        while(dwRegVal!=0x2);& m7 |4 Y7 B# M. _, g& b  {
) y7 z* t1 v* I& r7 m' w
}
( |; h3 N" }' y6 ^  I( p9 K. q* d( I2 X% T5 @* |7 [7 _" v& R0 o, U
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
" W# a" `6 D$ D- @所以变成了死循环了。) \2 t+ d" a7 S. J2 l

; ~1 q0 V! ?& ]) N, R6 Q我对硬件编程不懂。又不知道从何下手。
  ^+ |( g- m% O0 p3 I3 X我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
& d7 o. Z6 t3 [7 _% I但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。6 W% J& q( I: t7 ]; |. H/ n, F/ N
9 P& @( Q1 j$ V
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
4 W$ o7 c9 _' n' \& d+ @并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。& |- U9 r! s6 i: z" `2 d! u; s

2 D* M) r8 a6 x9 t3 M7 j2 z感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。1 H8 u8 M* N$ a! x% q4 O# e% i. d
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
- @: e7 Z) d4 _; e/ y2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突+ o3 }9 P& ?' K, ?
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
3 T$ h8 x- v6 b  I  F& ~* D+ E& {! H2 ^% G8 w, s: |& L4 g9 \
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。- }3 d+ Z& t% y! N9 h3 z8 |
( h6 O5 |8 f$ k0 }% s+ A3 v" C
那么有些什么可行的办法呢?
7 x' R2 Y5 [: a& q% A7 _/ F为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
5 H; Y* ]. ?- c0 J% Z
$ ~6 v: p' [, ^% u它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?- q* w- {1 S: Q! j, v  w% Z

& g8 i2 Y: o3 O: [9 v! T6 b那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
$ {& J* h& i3 v% u9 S3 J/ ?  R0 d$ J5 z: X/ V5 e
http://www.ufoit.com/bbs/viewthread.php?tid=452
: U  }% M' g4 s
; |# t8 J  D6 bhttp://www.ufoit.com/bbs/viewthread.php?tid=241
* z4 Y, {* ]0 p, T% X% s  Z; w
2 K% y" W- x- K看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
2 {+ e& k$ g1 x' g4 n1 u7 Q+ @$ z# F  i8 K2 T+ K8 `' ]1 }
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。/ ?5 Z9 ^! Z- ^5 J5 ~4 i
2、Driver最复杂,也需要BIOS配合,推荐。
8 i2 H( [+ _& ^! t( T3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
+ j1 C% _* q% t8 w% C4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。3 B$ z& F0 v* f' D" G  |
你可以混合使用。
4 y+ J! B1 E/ y* V, P$ F, L+ d
( d. H( h6 c' b2 r===============================================================# @: Y  L- a1 I# I4 B. y
管理员的这句话:% p3 R, ^" y+ ?7 P
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
/ E/ D9 a( m4 F0 t/ V
8 v  a' c1 K' H7 H0 B) h予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵5 T; p7 |2 ]7 }3 B' W7 k& i" S- n

  ]3 m2 ^: F  e9 o% }另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=2695 Y( b" Y: O  B3 {! s* e+ g- K

6 X2 d) s+ ?4 {# z+ B! [, d% G这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
' d, F, Z1 }" a" m; G9 P6 A# j) g
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
: Q/ o% R# I5 }2 m, R里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?  F+ q( f5 ~+ N( ]

' k( P! y9 p6 k& i! z我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
# T9 w% @8 a+ y  W2 }: m& e你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
! x2 V# O- E8 i( U) S1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

6 U- c. a; C0 A0 q$ w& ^9 {9 S& h6 b3 @+ @% u; W6 a* T( i
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
/ ]1 x" D: B$ {5 z2 Z( b% e, f: s/ q
void write66(unsigned char Data)& i! S( l& m& A& `; N/ ]
{
5 g7 B7 h$ z: m1 g        DWORD Status,TimeOut=10000000;# {, ]& X' U/ Z2 }
        do6 M. I& T2 P$ L# r
        {2 c7 Y6 l7 X. z- F  o, ~
                GetPortVal(0x66,&Status,1);  w1 u* b, h  ?+ s5 z0 ^
                TimeOut --;
& Z- q6 {  F* X2 J0 T& d* h/ f: R, S) t9 X//                Sleep(1);
5 A3 ]' ~& p: A        }while((Status & 2) ==2 && TimeOut>0);8 n0 v3 K2 V5 t8 b# R
- @0 t0 ^. K% Q1 O' N
        SetPortVal(0x66,(DWORD)Data,1);$ a) b1 B1 H9 v' U/ h7 X6 J1 d/ T
}
8 I( w( h9 J) O0 H. Ivoid write62(unsigned char Data)
5 W, \) f; t: t2 `8 W: w) a- H{9 U7 p4 C* L, j+ Z  t; S
        DWORD Status,TimeOut=10000000;; j0 |* N7 o2 J# l( \
        do
6 c1 n: U! J- ]+ U        {9 ]0 z# M7 |7 z, i& @% F4 Q' [# t' _
                GetPortVal(0x66,&Status,1);: o6 G" Z" |$ x1 ]$ c
                TimeOut --;
& }( _) `# d* u' t  l+ L  @3 w4 z8 |//                Sleep(1);
' A0 N) W! @  I1 \2 P        }while((Status & 2) ==2 && TimeOut>0);
  B6 \( g* V+ {% U$ H- P
/ A# B/ B# B- P  ]        SetPortVal(0x62,(DWORD)Data,1);* s$ h. Y8 f+ Z. E2 T2 u
}
7 l8 i$ I5 a* }- v1 k% gunsigned char read62()
$ O/ m" {% J9 k! L/ ?{' P* y: f( ]# Z6 \% M
        DWORD Status,Data,TimeOut=10000000;  q5 ~0 L% b6 O" V  _' D
        do& u( C7 W# q) k* Z, m5 m
        {
: L9 t$ z. J  z7 E, C( w6 T                GetPortVal(0x66,&Status,1);
- Y/ h1 ?( M3 e) S; E" C. Z                TimeOut --;
. G3 m* ]2 P/ q# S2 s  `; Q9 A//                Sleep(1);
! c* p/ _' W9 B* t        }while((Status & 1) ==0 && TimeOut>0);
- H1 W5 t& e* q3 W" M9 f* W3 O$ `9 Z" Q, ]7 x) q, }  W# x/ r+ c

5 S3 Y' p7 \5 g' U2 g        GetPortVal(0x62,&Data,1);6 |0 u8 \& J! _, l2 u9 A8 c; n) J
        return (unsigned char)Data;2 u' M1 Y; I8 y: C7 J
}
. [. f+ Z* g( @( G; Hunsigned char read_ec(unsigned char index)
! G* O; e3 o4 t- f# ^{: R) J% }6 T  ^% ]/ B" R0 V+ n9 E
        write66(0x80);
% `  E. r- |/ Y        write62(index);( ~, K0 [. u5 u/ c$ Y( G6 I
        return read62();
7 \/ _( E$ E) x* r}
  B" p7 p& L, x2 p
9 Z6 v7 W) z6 E  n) [+ p[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1894) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
5 m2 L; u# h8 \% C; {6 x  Q1 D: a  l  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
( H# ?& j, `: p4 ~
: P- m8 T/ o8 `9 P* c$ ~3 F5 H[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 4 |3 J& _; `3 ]) E9 g7 Y7 z
9 r) O! N- U- k. d( l1 w

% v# Z; V/ Q7 p, ]您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
0 W! S/ N3 \1 |8 G# D

# C# a$ G% G- F7 N9 }1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
) a% E; A4 |  o1 \1 T9 i' z$ S0 b9 o( s! Y
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
, k3 F. b4 x: ~7 ^2 w7 K0 D
+ ?. P2 _4 g) p& M" r  ]- I! ~$ {  o3. Then set bit16 of the IRQ to disable it.
) M5 `6 Q5 _, o, \& R; U# a9 l6 [0 ^5 {$ k' v& N- O
    a.. Offset = IRQ# * 2 + 0x10;
9 l0 E0 m  i( @! t4 N$ O" ?: C2 Y+ F2 g( u* B  M
    b. Write Offset to APIC base,& z' L9 o2 l* I+ t5 D
$ b3 y7 h8 g$ ^; |! b# j3 E
    c. Read Data from APIC base + 0x10;) p1 u; f* Q- H3 m' T# {  S

  b! G6 u. l; |# _4 b    d. Or bit16 to Data;& s' O/ z# t* p  q2 r2 a; j# y
( s0 K8 p5 H. _6 U
    e. Write Data back to APIC base + 0x10;' d, Z; q+ U5 q% u' P  d
* ^- L9 i, D8 {, S! A5 C, W- Y

/ p1 e- E. A5 {% G9 l2 A5 z
) u$ Z# k( Y! h3 cYou need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 - H- m4 Z) {7 d: V2 s+ o
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
/ C* \, P/ L! y4 o" d8 Y1 \
, \) u1 O$ p' X- X
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
1 A6 J8 I, X$ @. @* C0 _==============================================8 H- c( g& D1 N7 X* m5 P' {* t- q$ ]
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
; o6 R6 q; f' r* e  [" _9 `3 o  H, u
9 u7 K; ]+ d. u5 [; e; _1 K( j因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
8 S- F1 o6 i3 c0 f( g但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。, f: w% ?0 J. C  _. ?1 M5 d. u, s( s5 Z
- |/ q7 H' N$ U0 g! P
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。# ?6 H! y( w1 S, ~- f1 Y
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:% h# r! J: i  p8 s% u
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
5 m3 ]; @  T) U# ?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-9-18 20:09 , Processed in 0.305291 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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