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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
. T5 p5 m0 o& j#include <Windows.h>& g8 J& R, I9 E* }! T$ P: d
#include "WinIo.h"8 f3 d% A, p* H5 g" _
using namespace std;9 I! T: o  k; G. X, d+ a

" U/ S: @" ~/ N7 t; ~  R#pragma comment(lib, "winio.lib")6 o6 @& g$ I9 U) B. S5 d
2 i$ H4 q1 Q5 Q4 F6 }' m4 E6 _0 C

: |0 x# p6 u9 A& Yint PMU_SC                =        0x6C;//命令端口
. a& r  Y1 m0 C; m% Nint PMU_DATA                =        0x68;//数据端口
4 q3 ^$ {, x5 T+ S7 t: a' _' k, O! Y8 \% mint RD_EC_SMI                =        0x80;//读寄存器命令
6 s8 d& d) G3 |+ x  I1 ?( Gint POLLING_DATA                =        0xE7;//CPU温度寄存器号1 q1 `) H( U3 H/ ~

$ e4 g$ c2 ~4 {5 _  A" S0 K- NDWORD dwTemp = 0;
8 R2 H5 k- y% X( b, N( D. B- F& A
- ?" I! w5 K/ [1 Dvoid PMU_Wait4IBE(DWORD *_value);; b# h% e+ B1 S
void PMU_Wait4OBF(DWORD *_value);3 q: S8 F. E* k* U/ I% ?, p+ X/ ]
! V: J2 r8 w6 i  {! v) x

3 ^9 O' q9 \3 W: vint main(int argc, char* argv[])
7 |: m3 w7 [: e& Y) k- r- h{
/ z5 K5 X2 ]- Z        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
% o' D3 s1 O+ L! A7 ]- Z
1 [4 f' {3 P( ^" w        ! O0 `# V* j$ r1 n) D2 J9 C
        //1、mov            dx,PMU_SC                //' e  N' g1 D& d4 J( k
        //2、mov            al,RD_EC_SMI        //2 M0 @9 M' }4 d
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
1 q2 l+ ?) f" f2 ]  @        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
# K8 p5 ~& {0 ~3 X% C8 Z( C2 V: s
- |1 A, F8 D$ ^4 o        PMU_Wait4IBE(&dwTemp);2 w! O" \. f; |4 b' I
        1 Y" K; d3 t* ?+ k3 Y
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
7 f  ^' ]1 g8 ~5 R9 v( C8 }
8 v1 @) V: Y  i, C2 f5 d& J        PMU_Wait4IBE(&dwTemp);- h7 A$ r) i! Z7 W
        8 p% p. v* w& F- D, F- g0 I
        SetPortVal(PMU_DATA, POLLING_DATA, 1);* a+ q+ Y0 S; `$ o, ~

2 p) w; d" p8 q: e' T        PMU_Wait4IBE(&dwTemp);
6 r' c% L" `5 B  t# N5 c* Q! S
' y3 {0 g1 p/ f, A& j! [        cout << dwTemp << endl;               
' O- Y4 D* O3 n$ ~4 z% [
, _" a9 m; @2 S" w5 n7 C        ShutdownWinIo();
- ~5 q# |) ?# C& L: F3 ^/ x! d! ~- Q  j# U
        system("pause");
, }: ], u  X) C
& e9 n6 Q2 a; i5 }! L$ [9 _$ ^; B        return 0;
8 g5 f( V! m6 N! D  }5 Q}
% u4 C: E  g! T! b8 Z( }7 f$ b, |' M2 ?9 O0 ?
void PMU_Wait4IBE(DWORD *_value)
& ?* h2 r9 e7 h) x{$ {0 v! G" m: w' t6 s* W
        //#########################################################   
, J6 Z! @  E$ Y& G' t% W        /*
( T0 R% V/ {) V) u$ W        pmuWait4IBE proc   
  D7 Y8 P7 J. o/ F: \7 c. r' U        PUSH        AX   1 a/ U1 r0 y/ y% r
        PW4IBE:               ' P; x1 q' d7 h# I
        IN          AL,  06CH                                //Read  PMU  status   
7 N; C6 G8 O- W        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   $ @0 j* D1 ^* V9 k6 Y4 h
        JNZ         PW4IBE                                        //Jmp  if  no   0 t1 G, c+ k+ b: h' K
        POP         AX   * [7 H6 b$ y. B' B4 n- P* C2 y* y4 Y
        ret   
4 j+ X. T6 Z; _. S7 o( {! B2 M        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
% B3 u* s5 J( d9 K& V) A' b7 A9 f9 w& w        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
8 z* v! e& a/ a) @3 |' G! c( q9 N        //######################################################### 0 z3 O6 M4 U* M/ t% @0 D
        /*do - n% U7 R5 u$ Y9 ^1 v/ f9 F
        {% h! D8 G7 w& z, X$ x  |1 Y
                GetPortVal(PMU_SC, _value, 4);
' Q/ R' q$ @& q$ x" b, [        }. K8 N3 P( U) j1 ]( l. N7 P
        while ( *(_value) & 0x00000001 );*/
) h; w# M0 q, Q6 m        DWORD   dwRegVal=0;' D; q! B4 i4 l) N1 M: ]
        do6 Q1 a* S' F1 L& x& Q% I: g, [
        {  
" f+ {  x: f6 Y3 r9 |                GetPortVal(PMU_SC,&dwRegVal,1);, |8 v2 D6 P; T/ T( c
        }
1 p5 L6 `* t% H; Y9 G5 X& `; e: l        while(dwRegVal!=0x2);
7 b1 z4 ]  J( B' ^8 ?, ^2 c( K2 {
}
/ W$ L$ h( g4 F5 b7 [1 Y2 C, m6 q
6 x2 q! F/ v5 R以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
& H: t, t: z5 B+ G4 N所以变成了死循环了。" P7 R% Q; ?6 H: I

- L+ w% u" Q3 n: S6 u0 B我对硬件编程不懂。又不知道从何下手。. Y3 `- I5 V9 A5 Q
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
3 N$ s' w$ a" S1 {( L. x但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。. z9 G6 ?8 w; @& f# M% b

) o* m6 v9 t- y. u; ?我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
" j! \* m6 D8 o: a8 F. k3 z' G并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。! A/ m0 N+ [! |
: i  V' R& T& P3 r& O; D; @
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。$ [$ C# B* ?5 T6 ?+ P( [) W
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.- U  P( e# w. Q1 W# U4 j( F4 Y& F7 c
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
5 {7 Z  R5 q4 p) e  S9 C, ]3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
* l! a. I# C1 C4 k/ {
- Q9 G  K( J* d- N- q4 R6 H% f所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。1 E( I( j) t1 \- [
; N2 R) u; ^" O# m
那么有些什么可行的办法呢?
0 X4 F3 w9 i/ i" I- v为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
) c8 o! v, K( n1 F, Y2 P' k, O( W, m: v; Y* \5 g1 P" k
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
* H2 {% K8 T+ d2 y  K8 O3 _) ?; M+ ?* h
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=4208 O) }! o$ `4 i8 I+ T% X

) n3 A2 _5 t: yhttp://www.ufoit.com/bbs/viewthread.php?tid=4521 [) p8 y  K0 z2 ?  Z& C/ p
  P. ~( s  V/ e! K
http://www.ufoit.com/bbs/viewthread.php?tid=2417 a; A7 o, o! U+ T: T  K

- t' \( R; _# @6 R- J; e看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

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

3 I- [) L$ r: K9 X" n& S9 ?1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。8 f6 @) X5 T& _; N& `  T) R
2、Driver最复杂,也需要BIOS配合,推荐。/ ?( G; w, a9 O( ~
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。+ s5 R7 n; E. G! Z
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。  P9 d3 r2 m; ~
你可以混合使用。' L) g7 h; m0 W5 R3 z( y
: R- q5 |, }; ?5 ~5 b& X6 m9 L
===============================================================
3 W7 {* G9 }! E) `3 E# ^. Z管理员的这句话:
% a; p1 x$ P7 `如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
' X  }& H& b4 r, K; c 6 |, `- |1 V; U$ A
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
$ M& x9 m3 _7 e6 ^( i! u. }
9 Z% K8 f: T; H另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=2699 J* }& ^' j5 {- E4 l6 R( j* v
: d- \$ D3 O3 N# Q7 o
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
0 g$ H- q, n4 o/ s  t, i
, _( a9 v' X$ b. n- ]: S# y还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。, V' x1 _2 U% `4 t/ P/ \% G
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
7 T* X& _  e( v9 q* A! h9 f' V
. [9 Y5 e5 G  q/ L5 w2 N; ~我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
2 o  C0 l/ c, @) h( `5 ~0 p& s你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。% m1 L5 A0 z: ~# {4 E  e* J
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

* z# k' @0 \5 d; I
( ~; q0 c- A0 U您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。9 |. a4 O' c  [" [/ L

+ c! ~0 _- R, b4 c) P3 L! Ovoid write66(unsigned char Data)( v+ Z; P. w$ q# e! j, a- D: N6 [
{
1 Q  ?, A- ]0 X, A        DWORD Status,TimeOut=10000000;
1 t7 E( b4 _& {; H3 r        do9 {$ f! x, E0 H8 o+ K6 |+ D7 V" T
        {  c& p; F/ C9 s; G1 y
                GetPortVal(0x66,&Status,1);
% e/ ]0 Q+ X3 T, L$ g# c! I                TimeOut --;7 _0 U7 ]. }3 W. f0 l9 }8 H
//                Sleep(1);2 h. B3 `6 ]: c2 R/ ~; k) p# M/ h
        }while((Status & 2) ==2 && TimeOut>0);5 w; T! f1 Q9 K+ b( Q0 d
, ^" y. U; W' T
        SetPortVal(0x66,(DWORD)Data,1);
/ t4 `* Z( d- I5 R1 [9 A}  j* Z1 S) v+ b
void write62(unsigned char Data)
' v. c- V7 s# \* L) B- n{
5 v  c, j. b; e0 j' L' V: J6 w        DWORD Status,TimeOut=10000000;' A5 z: ^& e" M. I5 O: ]
        do
( o) l6 h: r, }        {3 S+ W8 z" b8 S. Z- C3 Z! V1 h
                GetPortVal(0x66,&Status,1);
# U3 L3 `" u4 f. B$ ~' \7 E  N+ e                TimeOut --;: I' j5 D1 K- f" Q0 o4 ?  `4 G
//                Sleep(1);
+ o1 k1 ?  J/ \! O& H: R! I- t        }while((Status & 2) ==2 && TimeOut>0);
( V" n0 P3 K3 L2 h- `& G2 ^
" G6 ^  o) u4 n/ [        SetPortVal(0x62,(DWORD)Data,1);
) Z, E( A) a1 v+ y* g}9 b+ P. o, O- V  V
unsigned char read62()
  N4 V8 S* e# P+ ?$ E{! d- k. |1 ^/ V4 j
        DWORD Status,Data,TimeOut=10000000;
, Q) w  x, ?1 d        do
7 j0 f1 F0 D3 a! H& f+ U        {) O0 |% Y5 k. W; K+ ^; Z: ?5 n
                GetPortVal(0x66,&Status,1);# m+ T& Y( n$ t8 I6 d) y' z& y
                TimeOut --;
# b. T& U; R$ K; g  o2 E2 |0 p//                Sleep(1);4 g6 _! q# h5 t9 ?& z$ F7 J
        }while((Status & 1) ==0 && TimeOut>0);/ c$ t+ Q, G# A' l; C/ {
: d2 N  B2 ~2 t  @# C, D5 k# }7 d! i

9 B4 W! x& d/ i6 S8 q  s        GetPortVal(0x62,&Data,1);
8 s) X) Z; D8 u5 C        return (unsigned char)Data;9 V8 e' P% J& ~0 d, Y- D  D
}6 M. M/ s4 V3 a; d% K* C0 u- t2 G
unsigned char read_ec(unsigned char index)& _8 s3 g9 g: r" x
{
. }/ e8 C+ {: M1 y8 j, ?8 O% ^        write66(0x80);
* t; G) G, H2 r        write62(index);. J! F. K3 x0 n& z7 ^* o
        return read62();4 `, b1 p/ d' X( G
}7 P: U6 W+ w& }/ R3 n2 L
3 v7 y- X( e9 h( Z" Y  n. M) y
[ 本帖最后由 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忽略掉的。
6 q5 ?0 r: \* G3 F2 N  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。6 X1 Y0 E' j% \. _( b" L# |% E

, W- R! ~, i8 O4 U; g. ][ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 9 {% }) K9 g8 C1 u% r) m

4 x& S0 v; R* T" Y, K! N/ Y! [
7 d9 Z% L7 J- g6 Z8 I, Z2 T7 D您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

; O! o3 W# g# ~  m, b( E  b! Q0 ^1 v4 I( J. s- k3 d. z
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,. d+ g) k! Q: }/ }
7 D+ V+ O0 B8 H' y# D
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
5 m& b" v; P( B; k, P) f
7 D, ]1 W6 O: O! }3. Then set bit16 of the IRQ to disable it." h2 p- J7 o. P9 v* }6 j
( [" a$ X9 b2 m
    a.. Offset = IRQ# * 2 + 0x10;
9 E4 h& g0 T$ U- ^1 d9 S1 @5 E6 F
3 t; _" H+ y5 q4 w- a9 Y' {    b. Write Offset to APIC base,
# e6 x! U# X% ]- r6 w
5 R% z5 `0 G5 Y1 X    c. Read Data from APIC base + 0x10;* g- _& D% K# n/ |6 I$ ]
/ r- [3 q8 W2 U6 ~
    d. Or bit16 to Data;
# `$ n/ g- ^( Q4 j. e2 q4 B' y0 D7 l; f8 j/ Z
    e. Write Data back to APIC base + 0x10;
9 e* N' T( n) c+ R# T* [5 U
( H+ h. A. L- _+ Y( Y 9 A! \1 c/ J# S( Q& ?4 f  M

. Q( B6 f: u- T4 ^/ t6 wYou need to check APIC spec for details.
回复

使用道具 举报

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

5 d2 r# M* B0 S% R" B  j 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
& w0 n3 x! q8 Q% z==============================================2 `1 _+ ^5 S/ o! s
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。5 Y) h0 D4 J/ P" z" |0 Q
" H% b# c. N( h( I
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
6 O9 K) |7 m& @  q2 [3 G1 `" E4 F但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。  P, c$ E1 ]. w5 s2 U: R6 o
# [& E! G4 S" P4 ~8 d
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。( H* |/ T$ p5 d4 l5 i% x3 h
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
* j1 k# \! ?' B  x3 Y# n1 T5 U1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。3 \0 M  F9 S4 k
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, 2025-12-1 01:28 , Processed in 0.555465 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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