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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>+ {$ x& P: l4 K7 B# ]9 n
#include <Windows.h>
4 d, R2 Q9 s( h; G#include "WinIo.h"
3 n( `, t' t% t' \2 ~using namespace std;; q0 K: g7 C# O6 \+ c

! P; b' E/ e% f$ M#pragma comment(lib, "winio.lib")4 l* m$ ~- P1 m) W% G4 [
8 X+ ~5 N9 X# B# ^8 [# F5 _2 w
: {: u/ M* }" B8 H: q. e! h
int PMU_SC                =        0x6C;//命令端口- A% [, v* i6 j
int PMU_DATA                =        0x68;//数据端口$ P+ i% [* J2 S! C6 V8 F
int RD_EC_SMI                =        0x80;//读寄存器命令
; q3 @% m5 [* ]: x3 ^9 gint POLLING_DATA                =        0xE7;//CPU温度寄存器号
5 ^: M, z( z* \
& _! c% s! f  O, Z8 D) @' m, wDWORD dwTemp = 0;6 Z8 T+ g' G- b2 z5 l
2 \9 l, S6 E, `& y- W( j$ L' ~
void PMU_Wait4IBE(DWORD *_value);
& d8 O8 |6 U( w  ]void PMU_Wait4OBF(DWORD *_value);
! [6 c  ?0 z( S1 I3 c: r' w1 `4 ]+ g- i+ T! X
! d% ~/ P+ a0 L; Q' L  `
int main(int argc, char* argv[])
0 J4 `$ G1 F! w/ _{
4 }% z2 |0 T) x( H        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
% L! n( z2 x% S, n9 [
9 O$ t2 B) b. Y. r        ; E1 {- W+ X5 s  v( M/ o  N
        //1、mov            dx,PMU_SC                //
, i: P4 p) b% M        //2、mov            al,RD_EC_SMI        //5 X5 f9 {+ U3 E4 G0 k
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了6 _) a% `, d! L
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
0 K/ L& p  r3 A$ h+ a' ?8 c% ^& N! x1 j7 a7 h
        PMU_Wait4IBE(&dwTemp);# K0 V. W8 _9 N: b  l: t) @. @
        0 x. S( T9 Q# N. Y
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
% s; B) X  C( M( m- ^# ?* }# J. J: ^7 i+ H
        PMU_Wait4IBE(&dwTemp);
" T, U) g1 L$ V( h1 M& E9 S% c        8 A5 n, y  ?0 }  ]& |* Y6 G
        SetPortVal(PMU_DATA, POLLING_DATA, 1);& E( f0 n+ Y5 x$ }0 Z; ~

, h1 r" H! F. \        PMU_Wait4IBE(&dwTemp);
2 N1 _  i9 L/ m6 c' v5 R9 v2 i2 ~. L4 b4 g( `! j' u1 {6 J( t/ {
        cout << dwTemp << endl;                + G! x% n9 e2 {6 I# `
8 J' b, Q" ^6 l- E; E* J) J
        ShutdownWinIo();
( Q0 C8 Q3 [4 b$ U# g+ ^5 m/ G7 D. [3 Y, D" @& P
        system("pause");
) {, U% U$ C% ]- X$ @- V% i' G  b  R0 R2 w# b6 U
        return 0;
6 F6 _: L# a) @. n}
& Z4 i7 p  q' `1 A" Y4 V
% R4 d6 d; V7 D' W; r+ gvoid PMU_Wait4IBE(DWORD *_value)
% v9 L" r( R" R0 l: }{
4 z/ A$ g6 w8 x* A- }9 B4 v7 h        //#########################################################   
+ K) Z1 Q$ a. n& |        /*% _/ f) u7 I) F4 V; p/ d* T  [# c& |
        pmuWait4IBE proc   
7 R5 ]4 R& Z. Z/ N0 ~8 c* o        PUSH        AX   
( l( u: M& w. E) N        PW4IBE:               
4 C4 z- ]! q6 X' m) r        IN          AL,  06CH                                //Read  PMU  status   
' w& r7 y# D% I- K        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
# p) u, f/ Y0 C- R! W) G' ~        JNZ         PW4IBE                                        //Jmp  if  no   
/ C+ w6 Y9 O& w+ ^( p% w" |1 |        POP         AX   
9 [6 c" x8 M  P! I+ U( C        ret   2 b# [0 T% j' `) A
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
6 U( @2 m6 d; [3 Y% X        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
# y  u, Q2 T& A! ]6 N: X- F        //#########################################################
, d7 f9 |; n, g- G        /*do + ]5 ~9 L/ M- S
        {% r( ~+ c& W* c! k9 S( X- }$ i7 }
                GetPortVal(PMU_SC, _value, 4);
8 L1 _% O# `" M/ J  j6 v0 b% F4 ?" {        }
9 ~; L  E+ q% w, ]8 A3 B        while ( *(_value) & 0x00000001 );*/
3 \- e9 t  {! f; \0 P1 o4 W        DWORD   dwRegVal=0;
- \- _3 d1 U; @! A8 {; N        do
* ?! V; `1 J1 Q2 F        {  
8 v1 m( d$ d% J) ?' C4 J                GetPortVal(PMU_SC,&dwRegVal,1);, D, X% j4 e' T8 d8 r
        }- K4 g( y& A# e1 z
        while(dwRegVal!=0x2);5 _3 v) a9 j) ^( S; s: r
1 n" l' E/ j* r1 v
}0 J. t' h( q+ I' u

6 d3 _1 P+ P8 S3 d; I& T以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。3 o" L: Z9 ^! h% e& R
所以变成了死循环了。
- r2 D5 m& s1 }0 Y6 }' |3 A  I$ U, I# ^5 X0 I
我对硬件编程不懂。又不知道从何下手。5 @2 C( y, f& i$ N0 h2 m1 [. }2 T3 x5 B& ^
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
) z. B; i, u/ ~& e但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
3 t: u! c+ X5 C2 X- V3 {8 A8 ]7 B9 z2 G  H/ V+ V9 b6 ?
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。: k5 a: l) e% @3 g
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。% L8 j' `# _: C% g; h  M
9 E$ H9 f+ y; N) W  w2 i
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
* H; o  p7 \0 }( z0 e) V1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.  d5 |% L% |  m7 h* V+ E: {
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
( s8 c4 t1 ^3 p$ @0 A3 J3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.* k8 _# L  S1 r% {; O+ S- z* t
: ~# G, X% W" g1 X, u
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
: X1 F1 n! E3 }6 X8 l) c5 T7 R
- i2 [$ n6 ]$ c  [( o0 ?那么有些什么可行的办法呢?+ N- x1 e. o& F& ?$ M: ~! x' X
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
! ?7 s4 \; l8 m3 N% X7 l3 b. g$ Y& P: p+ o% M9 W4 d6 F
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
7 v: ]0 o- E3 d/ m0 [
6 |) u3 A; }9 @4 m2 F7 h5 l2 L那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
  U  F% S6 c( _5 B. U3 v3 A3 `- C7 z6 d* {7 P+ s0 h
http://www.ufoit.com/bbs/viewthread.php?tid=452
. G" U% g7 U  m. I8 D4 \' k$ n1 D
) r# E# ]' H9 a) mhttp://www.ufoit.com/bbs/viewthread.php?tid=241& k6 o2 t4 S7 X" U
7 m) n! n, P/ w% ]- c
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
% _1 b+ |7 N8 M& i6 D/ K1 f& o' w" Y2 }. U( K9 c/ d# N, `
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。+ o% q5 H. x, p( Y/ r' q
2、Driver最复杂,也需要BIOS配合,推荐。
6 [1 z5 r4 f% l  X5 n3、Windows API只能获取到特定信息,不需要特定的BIOS配合。+ U0 h- g4 B. J- K5 D8 c2 l2 C
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。( {' K+ I* @  w5 H" ?
你可以混合使用。5 f$ u' o1 ~8 Q) z! f# |
; l. G) N. Y) v3 L
===============================================================
* }* B, z4 g/ `管理员的这句话:
1 m: O  p: `. U* Z- i如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
5 Z+ f: p& S* K0 v
8 X4 W. V) _* g( o, K% d予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
1 G) M# Y# R4 {! C4 J% s6 O
; ~) N& J7 y0 r另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269! ~4 n* U% T* X$ [# n

7 b) s. F% ~3 E" `( ]' {! k8 x这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
) D1 g0 I1 h2 ~7 H* B* G: r3 X$ r: l
7 A5 }: M" M$ I4 w还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
; g% G; Q# x8 ^( v# i里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?$ z2 H! H' H( `( o1 a8 |. E
' U; [$ X. C( w1 {4 x
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 7 X' g/ Y+ s: Z  o3 I) B: e2 v
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
6 S; s! i- L- |9 F$ b7 O( C# U9 }1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

. n; i4 {5 V* ?" V/ B9 D2 ]& ~$ `- `! a6 R# E% }# p  K
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
* I: q, G! a' q$ S0 _- [5 X) k& e& N2 B5 X6 V8 P4 t
void write66(unsigned char Data)
! h' w$ O) g! e0 j9 a, K; |{5 w$ V) O  e9 L  ^. k8 j
        DWORD Status,TimeOut=10000000;
8 Y. {/ ?& z% t/ \5 w        do6 M$ T. v9 f( R8 ]2 y
        {
, P4 W% h" l. Q6 e# w                GetPortVal(0x66,&Status,1);. i4 g0 f( o% F2 S! X) T, W" |
                TimeOut --;
# @; R' b' {) [/ W//                Sleep(1);
. z  \& o) q/ n% G, l. Q( B) X        }while((Status & 2) ==2 && TimeOut>0);' I$ R* u4 r1 V) i0 f( l

$ y# H  r7 E! n. {        SetPortVal(0x66,(DWORD)Data,1);$ T( Q6 ~1 a) i4 C+ h% N+ Z0 E. s0 [- C
}
, y" f. b' w4 e5 Cvoid write62(unsigned char Data)
/ z- l8 k) t6 n{, Z, a1 i8 Y( O: Y: v
        DWORD Status,TimeOut=10000000;
+ l7 Y' \+ P& Y6 V. Z# ?1 }        do2 [6 {- I7 d) w. R' u! w% Z  L6 [
        {
  d* s2 J$ q& H                GetPortVal(0x66,&Status,1);4 H! h3 ^+ w5 R" i9 |
                TimeOut --;
6 `0 g. [% J7 b//                Sleep(1);; N7 r& P/ }, y* M1 C4 E" k
        }while((Status & 2) ==2 && TimeOut>0);$ ^, E& c. l, X! s. A
2 K) ]. w" p4 f7 y
        SetPortVal(0x62,(DWORD)Data,1);0 [9 h) V5 M1 p: A$ g; X8 B
}9 f/ k2 w6 I; L9 L
unsigned char read62(). o1 v% {. J7 I! d- W5 v6 t
{
( z% Q, A, q) m4 {        DWORD Status,Data,TimeOut=10000000;
2 p5 V+ ?- e0 \3 S# C        do; Y! _, A0 ]1 i# \
        {
1 r9 |7 j. S  e6 t# ~! O& f                GetPortVal(0x66,&Status,1);' f4 e& Q# d1 T/ T2 f
                TimeOut --;$ Z0 V0 c1 v( u
//                Sleep(1);
# e  t" X# {7 y9 w% J7 V5 V        }while((Status & 1) ==0 && TimeOut>0);4 f8 ]" V4 X4 v# C8 D0 U

( S  n" I) u  q, v, i
; B; @+ _+ S1 W3 R9 C- ^: @        GetPortVal(0x62,&Data,1);  w. i  w! t! L! ~$ Y( Y
        return (unsigned char)Data;
1 l) f- z( i$ M  B( f; W9 U) l}
8 B4 \# ]3 D+ }* g, ^; A$ bunsigned char read_ec(unsigned char index)2 h6 r. E( V9 c7 l- \
{
4 T  m9 ~5 |- _: Y4 a' M5 ~        write66(0x80);
2 V- |6 M$ j& w# D  _        write62(index);0 q* [  g5 Q4 j9 i
        return read62();1 j. {1 V- C" }
}
( d1 i4 T* z# m* D
- h; D$ ?1 w: Z! ?: ?[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1155) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
6 G0 ]/ U! `3 u3 g2 r( r  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。" y: O  x8 W2 x6 e

% e; {+ }/ B. e. e8 t! Q* L" z[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
1 ^. T# p' _, L5 ], a8 q# _( X' B- K6 [$ H4 Y
4 P$ m+ ]" ]; f5 n# X0 M/ _7 M
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
( R) [! h1 W9 G/ K$ [* v

' ]- f  f: b3 X6 X2 @, v; F; S1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,& p) q% H9 F& ~! ?% D
/ e! l+ H" E* O8 w1 r
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.* J, L6 U4 E) j  A% h' u  ]! F

4 Z/ U! t4 Y1 ?% M# G0 [6 E3. Then set bit16 of the IRQ to disable it.
7 K6 G# t, T1 W: u' u1 a! l1 P) V- q. T2 I. ~
    a.. Offset = IRQ# * 2 + 0x10;, x$ X& z) f& @$ k# a
. f, y' I, E8 B7 W# @' R; \
    b. Write Offset to APIC base,; b7 \/ Y& O. S2 J0 O

0 z/ S1 S. O+ X+ C5 P( D* x    c. Read Data from APIC base + 0x10;
( d9 Q$ X* q, d7 \
% c4 e" b! [* u, J! R    d. Or bit16 to Data;
& I( K3 z. }( t. t; }1 ?! a  |/ x4 V2 q
    e. Write Data back to APIC base + 0x10;, D* p; L: I) t# t' K9 l" N

; O8 c9 C: U. e  [+ g8 U6 b! I
, _! x) l, ~+ D/ \& V5 ~- l+ ]2 ^. q0 u
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
- s9 G6 A1 c7 c4 F4 J% `# h545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
% y5 M! ?. Q1 G: o* q

7 c! Z/ W1 u. F 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
* F1 p4 I) l  m/ C+ ]==============================================# L1 k- x9 L5 n, [& K  c+ x
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。' x4 g0 N* y& h/ j8 f7 o) ~

' G/ `4 k2 `, ?. j- m1 y因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
' S1 E& L/ j+ `  \8 D- _- `# l8 Q  i但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。9 A7 s7 s% I! Y+ |
# }0 t4 J$ O8 Q! C' \- M
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
: q% _/ ]9 G8 t+ d当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:. s5 ~# k$ K! {2 [6 e- V
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。* F! w3 i6 ?3 r
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-6-16 12:28 , Processed in 0.073619 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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