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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
: ~8 ]9 Q, \9 |8 v#include <Windows.h>0 z; e. j0 @: `9 r2 M1 F
#include "WinIo.h"* F1 X& f3 `  T1 ?3 @
using namespace std;
# [# D0 H; j% a( _5 V2 v% ~, h% j" L7 k7 ]
#pragma comment(lib, "winio.lib")
+ V; V% z7 t. t- j( }& q2 V8 ]2 w& L9 i$ A. p
8 r% a8 ?% \$ V% q  O2 m
int PMU_SC                =        0x6C;//命令端口
- f9 |. k" {, n0 Mint PMU_DATA                =        0x68;//数据端口
/ X* o; J3 @" d3 L8 n9 uint RD_EC_SMI                =        0x80;//读寄存器命令
* t* j# `9 F; p5 p& y% Fint POLLING_DATA                =        0xE7;//CPU温度寄存器号+ m1 ~3 c' L# u
) A* [* S2 D1 A- @, Y8 O+ N/ U2 z
DWORD dwTemp = 0;
; E1 m! ^$ w) D" P4 q# f* Q0 w0 r) I" B
void PMU_Wait4IBE(DWORD *_value);+ b+ H, N2 y5 {# x8 G1 \. d7 ~
void PMU_Wait4OBF(DWORD *_value);
+ `- d: {$ v+ h" b8 T) `
8 {1 K; j! t8 u# P
, f. n  g0 o! o" g+ A0 d4 sint main(int argc, char* argv[]), q: w, ?4 K( v7 a
{8 @& M" g6 H! E
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
. k. K8 Q2 t& B+ n6 H3 X) n/ `4 h0 l  Q4 B5 ]1 [" O
        ' q  }8 Q  X; @) b' i
        //1、mov            dx,PMU_SC                //9 Z5 b4 C+ M4 J' a/ u( x
        //2、mov            al,RD_EC_SMI        //" @& x/ c  B: y! U3 a9 p
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
3 }' i3 M' q8 Z8 X5 ?+ c( F        //4、out            dx,al                        //将读寄存器命令放到命令端口中。5 t8 o' ]! t" a2 g4 Q7 s- X2 ^; d

4 i5 M$ E* W1 L3 b; `! Q2 W        PMU_Wait4IBE(&dwTemp);
! R6 J5 R/ [' E+ t$ |' @5 c$ Q        : n8 c% i7 @, ?6 G* }
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
) k' Z- ^6 D( x
, m5 ?1 l3 u8 m) W& I9 R# H        PMU_Wait4IBE(&dwTemp);
0 R4 V9 D9 s' ?" i+ h        2 u, ]* `& U8 p, N6 a* ~
        SetPortVal(PMU_DATA, POLLING_DATA, 1);4 f# S6 D0 G% Y) q1 G2 ~& w

+ X" T. ~, m- Z$ C, ^        PMU_Wait4IBE(&dwTemp);' l% e* b" y. y: B5 s
, n, Q& x) @: a- S: J
        cout << dwTemp << endl;               
. T7 z9 Y5 o1 _$ y2 d% C$ L3 ^6 d
' C0 M/ ^* |9 p: x9 ]        ShutdownWinIo();# W' i2 t. [* s

3 w+ Q0 t6 v0 k: [; @* ~% @) z& I        system("pause");
- ?* |" a( A9 J' W. Q9 ]% Z, u+ C+ j7 j5 P# d" c3 z5 e/ g' m
        return 0;6 _7 O5 o/ f* {6 |( R" M) ^/ W
}! v( I  a  X! V/ C' E* b) N: B

+ n1 c+ Z! A* n% g+ O9 jvoid PMU_Wait4IBE(DWORD *_value)8 R7 W. ^+ T" T6 y5 t& v
{
4 n, j, K& F2 ?4 L        //#########################################################   
& l9 h! l- K& ]; w0 F  V        /*
3 A; t+ S9 P) P& M" h, x4 W        pmuWait4IBE proc   4 T6 S. E; ^6 N* J  Y" I  h
        PUSH        AX   2 H* I! Z8 A& z, \+ }% {* W# Q2 B- |4 k
        PW4IBE:               ! h% G7 J7 k3 S8 o2 F
        IN          AL,  06CH                                //Read  PMU  status   5 @/ \" }" c4 @4 y
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   . M6 }& w$ k( b( d$ n
        JNZ         PW4IBE                                        //Jmp  if  no   
. _  p; s4 ^4 c: d- B; g        POP         AX   
  b3 M8 m0 B- ~% ?! s        ret   " E6 K0 F4 N' a4 H( u$ \- i; Z
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE, t. G0 I7 o5 Y
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空2 B& M$ L2 Z0 z( O7 W
        //#########################################################
) r" w3 f/ M$ F; D9 c        /*do 3 X3 e- t' ~( F& o2 W6 ?  z
        {  Z- B0 F: Y7 k0 }9 V
                GetPortVal(PMU_SC, _value, 4);
4 X, i3 p! B4 n/ E5 ~7 n5 f        }
' S4 `+ V( \# J; m8 p4 t        while ( *(_value) & 0x00000001 );*/
! {  f! z! J+ @. [        DWORD   dwRegVal=0;. v/ K- K/ ]4 n# w+ _3 \
        do
% k" f- Y6 M* ?        {  ( S+ A/ P; P9 L$ U
                GetPortVal(PMU_SC,&dwRegVal,1);1 x2 H1 M" r8 t8 c" }3 c: F
        }
. k. U9 F; t, w4 f% `; a* [2 I        while(dwRegVal!=0x2);8 E3 l+ @  ?/ t4 ^) o

" K  L4 C# z) e  z7 T}
2 i" Z' c( n: @& _8 l. R
- M2 A. G2 }0 k! N以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
# }% R$ v' z9 a/ E0 G) [- Q$ y所以变成了死循环了。( ]; _9 a  Y& z9 U# A

  d0 Q6 C; |! F3 R0 a我对硬件编程不懂。又不知道从何下手。
( q. A4 a$ e, @% R: I我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
2 w, e# s" i9 Z0 t: Y但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。8 _# o2 w. ?) X9 N) S/ |" A6 N% P" s

- N" \0 M) ]; a/ s' G) f" ~+ D我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。9 H+ ?9 A/ U$ f7 e  i1 a: Z  i) e2 x
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
1 A/ i2 l/ e* `0 X3 Z  B
) R* n5 L* Y( z- o) Y9 x7 ?9 @8 }0 {感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
5 l% s' ^* \* e+ O) d6 c& m1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.: d* ~$ `; G' z$ w" h
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突9 {( P. [- L' U0 x4 ?2 W' r! b9 m5 n+ i
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
. Z5 K" t' L$ j3 Y' w" e) ^! U
9 x2 a5 U, T! P2 O) ], ~所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。& F" n, D0 |  h
/ a4 E: m7 R8 q+ H& i- a
那么有些什么可行的办法呢?
/ x! Q& @! }) T0 g- T+ P为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
  N8 s  ~$ N8 U9 u, ?; y+ \; \7 T
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
/ k" y* p" n/ s2 {, j6 {
3 O; o) n" [! h  a' A9 t" Z, ^那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420! P. O/ q- A" f; d4 w
1 H! }" H4 U+ G5 e7 _7 T4 _
http://www.ufoit.com/bbs/viewthread.php?tid=4528 `0 u. ^9 _. c3 k, q, P- U- i7 i

- l  v$ ^8 }9 s6 ghttp://www.ufoit.com/bbs/viewthread.php?tid=241( j* @' h6 Z  W
, e) L4 c" O7 ]! {/ j
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
$ X3 d- o+ s- T; M4 A
0 b" r7 [6 J: e4 z% u1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。% D( r7 C& h1 f! q+ @0 A+ v" S
2、Driver最复杂,也需要BIOS配合,推荐。$ G$ Z" H7 o+ d0 E) q
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。. T% P6 D" D  X. Q; p. z
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。. X3 S% _) k! [/ D( m( f, y9 j
你可以混合使用。8 `+ b& c2 s/ L. o" ]% E9 l* S
" r1 W0 K! c! g* x, f! F, A1 P) y
===============================================================6 W% ?; B/ c9 S1 R& c
管理员的这句话:& j- N/ M) G0 I) s! U
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
8 M/ U0 ]1 j2 Z* p7 ? ; g' h" H2 f: ^8 a4 m: f
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵, t4 V, t- w, w; g2 d; `) E

& I6 t. D- B) O+ Z9 m2 W. k& r另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
- x2 ^/ K, H/ H1 M: v; z; s. v, U
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
: a! Q+ E6 D" z& B. _) }& _
. r4 n1 N/ v6 }  m. X5 G% T" ~还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
8 @, c2 x% d# W# m) H3 E里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
! b/ y1 n# J0 q4 g3 [5 A3 ^5 `2 D4 B, i# H
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
3 o" o; C) Z' F) `7 K  R/ w: [你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
9 m. E( U4 z" c, z1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
2 [' J; R5 }! f( R5 C4 p2 Z; G
- W% ?! W; X+ t4 |! h; d* ~
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
% j9 U! l- Z$ T) q# C4 d5 N1 [# O, E/ H  x" L( c9 q) m
void write66(unsigned char Data)
; j( ^' U: l3 A8 d& D1 m" M{8 f6 K4 w0 y  J0 N$ l5 [- u
        DWORD Status,TimeOut=10000000;
1 g. n8 q; v# t8 I- Z        do
) ~# `! L8 f% i3 |8 A, }  P6 j        {
) K/ k+ z* g2 t8 i2 D+ I1 u/ `                GetPortVal(0x66,&Status,1);
! R: f" e! [/ g2 Q                TimeOut --;
' H4 l9 u+ ~, A9 O7 h//                Sleep(1);- K8 F" @: a& Q% ~) t
        }while((Status & 2) ==2 && TimeOut>0);
2 o, e( O' }' M6 T; O5 \3 p; u. V1 i  T$ S. o0 F( n* l
        SetPortVal(0x66,(DWORD)Data,1);' `9 u+ }. @& g5 d
}  J/ e, q( [: c( x& n' J: C
void write62(unsigned char Data)
+ G/ `! K. Y0 r{# g* ]' Z  s" \' `% G4 M% I8 ?' q
        DWORD Status,TimeOut=10000000;$ y0 v% P2 X/ c* ]  R$ m
        do* w9 [  s1 t, n
        {
0 c1 o, y2 M) J- r; n- k7 J! W# h                GetPortVal(0x66,&Status,1);
& j$ r& [0 H4 g: D+ E                TimeOut --;
! F; N* J2 q) _! M//                Sleep(1);
) g% [: U2 ?& h+ f# b        }while((Status & 2) ==2 && TimeOut>0);! ^4 _# q% q, _- _# S7 v- x

" K- }/ `" A: C4 Y7 [        SetPortVal(0x62,(DWORD)Data,1);* {! l; g+ _- t/ y+ O
}
4 }0 t& ]: O" B: U) iunsigned char read62()* K8 c' j) ]/ d+ ~- ^% A9 t; v
{/ T- f/ F8 v8 @3 q
        DWORD Status,Data,TimeOut=10000000;
3 O) i4 \, h6 K+ o+ T1 r7 n        do5 f$ j) k1 c' }
        {
: E# X; Z* U/ @" t* C, c6 S+ k( w                GetPortVal(0x66,&Status,1);
$ Z+ T: x6 \: |# b. A                TimeOut --;
' |0 M4 M4 K. h# \1 r//                Sleep(1);; U9 O- p2 H4 e
        }while((Status & 1) ==0 && TimeOut>0);
4 f# D+ q3 ^; Z+ U: z2 ]: s% j/ q* X8 E  ?8 M! f6 T& n( t3 o+ N

; W" W6 M5 e* C' w9 y* A        GetPortVal(0x62,&Data,1);
, c, X; l$ g7 D& _  x( d; Q+ \        return (unsigned char)Data;
0 `9 a" A5 P5 v5 B; K}
) F5 u" N5 p1 a' C+ cunsigned char read_ec(unsigned char index); r) w  t3 x; R; _. D9 i1 W% B
{
" h- U- f0 q! Z' {, u# ]' n2 R- q5 K        write66(0x80);) Q' P  q- c5 _( `/ C9 M+ x
        write62(index);
! z/ E0 C. V! v% N) }5 W        return read62();
4 i' `, X' i( [$ `% `}3 c- |& e% d% h! I! `& P) O; {* ]6 T/ i
# e/ V  h% [0 r4 X5 h) s3 d8 J
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 5 e* j: b0 h6 }: z" g4 @

7 s  I8 |3 H; H" W: D
# V9 a5 Q5 d. n: T) O( k您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

. t5 E" \/ w. V- @* `8 w8 M2 z- ~; E' M/ H9 C7 S7 Y5 |  L
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
8 j# H' m9 f: e+ J* F  n! ~4 m* V) n  |  q  c
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
# w( E  B% t( d4 I& ?
  Y4 }0 Y/ r6 v- u3 `0 V$ N# y3. Then set bit16 of the IRQ to disable it.) |9 T- V: ]" r' V# v0 d" m2 Q

& U7 \' i' f) }    a.. Offset = IRQ# * 2 + 0x10;% {% z5 h+ `6 |- B/ ~

, E$ R3 J! x$ K& A- [" l8 s- g    b. Write Offset to APIC base,# [# m: P3 f# C" q8 |

4 f# O& |9 @5 O3 J+ n' y1 c; g, e    c. Read Data from APIC base + 0x10;1 Z* ]8 d, o0 e2 k

) c" j+ w" V1 ^1 W4 W( b% E8 }    d. Or bit16 to Data;4 o1 M, ~9 E6 b1 B! E
. L. ]3 ~% Q  n  U
    e. Write Data back to APIC base + 0x10;( d. e- c1 \2 r3 C7 Y3 h  }
5 |$ f7 A5 C/ ~( _  F* }2 S
$ w2 f2 w% b/ L" t# D  ~
2 J9 P0 W% z$ k6 |* S; \/ w
You need to check APIC spec for details.
回复

使用道具 举报

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

. K  t! o& f+ W4 \; x- V! h$ M  Q
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。9 U' d8 o5 C3 v- l2 Y+ [! Z
==============================================, P" r5 ?" n; Z3 k( n$ }, _
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
8 U2 k- A! ]8 h
. T% G* f& ?  x: F8 k4 ]因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)3 N2 M& r. C! @6 C, ~
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
" v! P# w1 S0 k& N% V$ C* u5 m
% S8 @, S- r3 _& D0 [, Q; A因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。0 w& B' z, A. \
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:/ ^* j$ l0 J$ `
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。, U$ V2 V3 Q: X8 ~8 R; d
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-7-15 12:13 , Processed in 0.086860 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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