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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>' {5 V. N* N) ^
#include <Windows.h># E3 H( q+ T# e$ [5 }8 Z. b
#include "WinIo.h"
9 [& h5 O" M% q1 \/ b5 _/ o, fusing namespace std;) a1 z& d- q6 L8 |+ b

4 a( |2 b8 i" J9 t; \( h$ B#pragma comment(lib, "winio.lib")
! m0 T- V: t! K% c  d/ u6 }4 F5 k1 A& q$ O( N
7 d7 T; S; t! f& Q  U9 n0 T5 g
int PMU_SC                =        0x6C;//命令端口* v! ]7 z) q+ Q+ U7 s/ l
int PMU_DATA                =        0x68;//数据端口8 C2 t4 E: P  V9 n5 j! i
int RD_EC_SMI                =        0x80;//读寄存器命令
, o2 M6 `$ ?; k4 \: Sint POLLING_DATA                =        0xE7;//CPU温度寄存器号+ P+ ^% G. M1 |+ b( d, ^
3 J# B9 l1 U5 ^' B' E
DWORD dwTemp = 0;
9 f" x/ T% e$ s( r. z' s5 C9 K2 J6 F
void PMU_Wait4IBE(DWORD *_value);4 s8 {9 @/ q" m* o# S
void PMU_Wait4OBF(DWORD *_value);- T, q, C% G- p6 M" e3 `/ G
" Z4 R; b; F6 w; w) |2 ^  x

6 x% F& n: K6 U  g7 fint main(int argc, char* argv[])
2 c7 r3 k- o; \{' r: q. O, o2 a. H/ `# N
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
* H% b; s/ \4 _- s6 [
- m' x, p: n0 R) @) z. R- S       
* K+ T( V- E, s$ _' b' ~% O5 G- f        //1、mov            dx,PMU_SC                //
, I( Q3 q( u2 y  A3 k        //2、mov            al,RD_EC_SMI        //
& _, l0 i. y) Y# L5 T        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了* R! `4 i$ u% ~1 U: J+ F
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。$ ?2 Q0 O3 E! p8 Z5 i
. }9 v( F8 D" ~3 C
        PMU_Wait4IBE(&dwTemp);
3 |- Y0 G/ h8 [3 _  s3 k        / s$ `' t5 R9 K! U" f, s* U
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
& U& a4 v/ N, V* T3 {6 K, J, L6 z" O  A! \- v
        PMU_Wait4IBE(&dwTemp);+ C# ]1 M) A' }" g; ^, L
       
+ H1 g) d) \5 b+ @) Z4 N        SetPortVal(PMU_DATA, POLLING_DATA, 1);6 m. q' ?. j; r) _" O+ ]; b* x

) R8 ?1 a* G( i' `& _        PMU_Wait4IBE(&dwTemp);3 L+ Z+ d) d3 Z4 o7 ^. E3 S5 Q% r
7 q. m! G. @) O0 p. r; e
        cout << dwTemp << endl;               
, I0 r+ j1 {  m  x3 U, H9 Y+ j% @
        ShutdownWinIo();( p5 S1 h8 ^& n: i

" Q: u" P; K" {6 s7 G( K        system("pause");+ P+ K4 s' k" O! z, z: K, b$ s9 ]
% w; x6 C8 t( G/ A
        return 0;. W& L% ~9 a) l
}
5 w3 P. G! A' a1 s  h
$ S+ b2 j7 x3 o5 |3 k  `void PMU_Wait4IBE(DWORD *_value)
5 A% [$ Q& ^% r, K{4 R% {& q" b; ^* ?1 R% |' g
        //#########################################################   
4 g+ L2 e' d, B4 P) u, O( @$ P        /*
7 m7 C* y. s- {1 p# O+ j3 }        pmuWait4IBE proc   4 u& G/ U" k, {! g9 u
        PUSH        AX   * o) G% S3 g" V; Y8 \& }2 _3 I# x4 P
        PW4IBE:               
& O' j0 J; f' G, l+ g; V1 T        IN          AL,  06CH                                //Read  PMU  status   : b, h& _9 N, E/ c# r8 t3 P
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   + c, N1 q6 l. L1 S* U( J
        JNZ         PW4IBE                                        //Jmp  if  no   
5 I8 p  x2 [' M        POP         AX   
, T0 \- ^+ J! E8 [: `4 J8 v2 T/ I        ret   * s$ j  x% [9 m# I+ i
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
3 u0 ?& k9 R% K# q  \8 k        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
+ h/ c/ l  v4 D) O. i1 w3 R# N  g        //#########################################################
6 A- w& N1 [) T        /*do
# _$ |% b- x4 R: r, `! u9 a, y        {1 j" y  \! K$ P7 b* I$ L
                GetPortVal(PMU_SC, _value, 4);
/ \% S# a6 a. \  j. \        }7 }  L$ ^4 r1 I
        while ( *(_value) & 0x00000001 );*/. z+ O9 g7 O  p8 x7 W: r; I
        DWORD   dwRegVal=0;
: L+ q$ F* f% \        do
1 g* _: Y! s! W/ ^+ d( Y1 j        {  
0 V  l  M- x; |) C1 t                GetPortVal(PMU_SC,&dwRegVal,1);
- A) M  K) g3 J' j4 |% f# p        }
- L9 J0 V* x% q5 V! U* F- U$ h6 ^+ _        while(dwRegVal!=0x2);  `; M3 y2 q) X7 B

  h: |' r: A" ?" U$ @6 p}
  h: y1 w, Q, v1 p% X0 h# O& F& C( K3 [0 n7 o
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
0 G( r, x) P" D" K7 y6 t" j( j+ l所以变成了死循环了。$ h8 Z9 ]+ ?8 x% |% u, _1 ~
7 H* G7 t& M" @- @0 U. h$ B/ D% y% w
我对硬件编程不懂。又不知道从何下手。
5 ~% B6 I: j4 C! C( x+ Z我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
, t* _+ J4 L/ w$ K+ G$ M; m但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
' n' g9 J4 Q" f3 F/ }) @$ V* k7 u$ {& l: U' k) }" Z. G
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。- x5 I5 m' z2 E( \5 M! B
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
  p/ }: n( Y: b& H9 S4 ]% t* A9 y/ m$ _' N; n+ u
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。, ^) p; `: r) G
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
- Z% [) ]) u$ I* Y7 q, ?2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
6 U% w4 v% v" f+ d3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.0 ]& w3 m- @) k% }5 V0 J+ A

( H9 R" X3 V1 p  x  g1 a7 P# A所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。" l5 I( T+ u$ j6 f/ G( u+ k- u: n

, N4 h: k3 V$ c- R那么有些什么可行的办法呢?. J( A. K0 R. {! g- u
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。* x* V& Y2 B$ A" Q2 ^1 W: J
$ Z- s/ u; A. _" g$ D- a& B9 N& i
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?/ ~5 d1 |9 X$ I1 R* l6 \/ S

( y3 \1 P2 Q: `' n7 K/ l那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
' V3 g. l! M% g9 s7 D0 b2 Q2 O+ y, Z
http://www.ufoit.com/bbs/viewthread.php?tid=452- ^) o( q3 ]7 J. F5 a
/ o/ P+ C+ Z; j
http://www.ufoit.com/bbs/viewthread.php?tid=241
6 E3 m; k7 D) x
8 I! G& ?# l* l看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。$ T4 B. J1 }+ n1 C# B
- g8 {3 `* c4 T" o0 E0 p- z
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。/ o& ?! L) `$ h! e: q1 V" M) z
2、Driver最复杂,也需要BIOS配合,推荐。
( |0 q) t) Y7 k8 `9 n0 V3、Windows API只能获取到特定信息,不需要特定的BIOS配合。4 U3 F- V0 T, @2 U
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。4 h+ Q0 c$ p" v
你可以混合使用。9 o/ r  v9 Q$ I' s4 q$ q/ N4 e* A9 Z

$ B5 V9 L. b. @6 i===============================================================
5 t5 N( f7 }1 W管理员的这句话:/ W- G( Q: o4 B" L4 e0 ]
“如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?3 W- T0 l; V7 r+ i% I

# s7 `9 S( d" I5 J4 O/ b“予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
4 s' l0 y' h! @# M6 F8 W# b
4 O& M/ [* R$ o. Q9 {3 w另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
0 n  I9 c9 _0 L/ h# P& m# q
% K2 R9 V/ z/ k7 K这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
  I3 y+ P0 U1 q0 n; D5 Y& D, X7 X$ A
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。3 _1 }' x0 R, k% f
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?' }4 H/ \( H/ ?

! ]+ Q# B( G# }# ^# v5 x我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 * J5 Z: Z8 ^  d" s1 q4 b
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。4 U9 X- H0 A( K: K9 P- V
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

( d7 i/ z. ]& P& R- L3 p
4 ^9 o0 p" B3 c$ l  J9 R* H+ X您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。! u+ ?" [" f# `. e- D0 t9 S! q6 v1 S
/ N3 ^, s- X, ^; i( y. y
void write66(unsigned char Data)) s/ j* N. W3 m$ W; E% G9 m9 \
{3 h' T" K9 O8 u  x) y8 `$ j
        DWORD Status,TimeOut=10000000;, a) n3 W0 x1 H9 J3 F  e
        do
- q& I7 x  L% [2 s# j2 \0 B        {
" N; T. L  p( v6 q- v- C                GetPortVal(0x66,&Status,1);1 B/ X# d; V4 w1 f2 Z
                TimeOut --;- O" i' d; e$ r& u6 y7 K- ~
//                Sleep(1);
* A2 Z( a; N; [        }while((Status & 2) ==2 && TimeOut>0);. B; s  ^' ?- P; P" ?

+ R, ]$ T# Y9 @: ]        SetPortVal(0x66,(DWORD)Data,1);- q1 V7 G6 G) C6 f+ F+ N
}
4 Z  A/ k0 _: y# n( ]& Y; H# ?void write62(unsigned char Data)3 _" u2 f0 n$ @. f
{
$ @. @. R! g2 ?! t$ X        DWORD Status,TimeOut=10000000;# N% r/ y) @. Q! T7 U
        do
2 q" b4 y8 I& P% V3 y5 H        {! W2 A4 V& O$ a
                GetPortVal(0x66,&Status,1);% C3 ]" i+ |. ~, {
                TimeOut --;/ n9 I+ O7 g% E" A
//                Sleep(1);; j) X( b+ o% R. F9 I, ~, u$ b
        }while((Status & 2) ==2 && TimeOut>0);
! ], n+ q  y. D5 c$ J9 [
* W7 \( R7 z) \* G' {. Y6 n        SetPortVal(0x62,(DWORD)Data,1);
% n% a9 k8 [2 e) m- B% l}
9 y/ ^$ i2 q" V3 o# \( e! q/ m+ tunsigned char read62()
4 m$ ?8 e. X" s( @5 ?{
; g, d" J6 L6 T2 q        DWORD Status,Data,TimeOut=10000000;
# `5 D4 E  D% r5 }8 U/ h        do
. C- v9 E* [* r# t5 q+ ^* H        {
7 y4 C7 `. H1 ?( v                GetPortVal(0x66,&Status,1);" R5 U% F% H; y$ l
                TimeOut --;
1 C. f# X7 ^& t" z+ u//                Sleep(1);
) E. t$ b# E" {4 y  e$ ^- X        }while((Status & 1) ==0 && TimeOut>0);" H: d% {8 f9 @, l2 a* o

. z) ~4 X8 t2 _' F
* W) @/ g8 x- L4 t! v; Q) D. D" w        GetPortVal(0x62,&Data,1);
* o. V$ e8 t% g  o# h# U        return (unsigned char)Data;; g4 I' H# ^: V1 ~2 ~
}+ L7 l9 J) I- j; S
unsigned char read_ec(unsigned char index)
, d5 y- p( T% @{
/ K% [; g, A$ f        write66(0x80);7 W: \6 Z6 X6 M/ P) v5 E
        write62(index);) y/ n* C" _+ j6 ~5 |! `% ^
        return read62();5 k& d5 }/ W, K( V/ V
}! C% N8 y) `. t1 j6 f
0 H% B3 O' a5 G
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1938) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。( w0 x6 D; I5 Y: ]7 Y8 i+ a
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
6 H+ H: j* J8 e: y( `
4 ^) o" {4 C- V% e  o) I, w[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 . ]8 f) r7 P* X* W

# X9 B2 H# n: r4 j2 y  s8 h; h) j3 Y
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
0 C' O* g3 d- o0 h$ K! y* T

( J$ a4 u* I2 C- W0 U1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,, z3 D! {( q# b% ~! \: S! C
: c6 {# z' W- ?& m9 r9 X1 F
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
8 J5 f8 {/ U' W( |: [4 z3 y
. @$ R- ]1 G2 U# |( u1 r3. Then set bit16 of the IRQ to disable it.  ~7 ]2 I& \. ]6 T  K
$ l+ X% ^% p) J$ u4 u
    a.. Offset = IRQ# * 2 + 0x10;, [5 \8 r, A6 \  y: M
) m+ g3 C# X: j$ M$ p
    b. Write Offset to APIC base,
+ S9 [0 S" C) q, h: A1 w4 i5 @; [  _* u
    c. Read Data from APIC base + 0x10;
% F* a; P* x0 z$ w" |" t7 U- y: j7 A7 U) I7 P; @
    d. Or bit16 to Data;7 t  r4 K  O  i5 F0 @, Y
* f' G* v. _6 I: a1 p; p
    e. Write Data back to APIC base + 0x10;
- g8 _1 r1 N5 [& s1 g8 h' `  \0 n& n
9 k5 n9 R' G% l4 Q
; C" s5 X  C/ Y  E; V
You need to check APIC spec for details.
回复

使用道具 举报

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

9 J  E1 j1 Z! @4 y3 m 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
* d7 r4 j) a: k; _. q& Q9 F1 g==============================================
8 }+ q8 _2 I2 a8 T2 X 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
3 S8 x9 O* D3 n3 d. F
: q; v# _& J6 V因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
7 F9 f2 @8 [  N/ k+ x$ X& H3 N但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。0 H# Q" m3 B" A7 |

0 V- z- q1 l1 p9 w* H因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
- s. d" U  a3 D/ G当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:+ I: I& u% `# x. G
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
' H5 g( J$ R5 s: Q2、新手不要把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-11-1 20:29 , Processed in 0.270914 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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