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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
3 G1 h2 [3 U, S0 E! d& O) _#include <Windows.h>" Y! b& o, p# _! v% j& u
#include "WinIo.h"0 h  v: l% Z/ j4 A: K" h
using namespace std;
& t0 C' @1 h, @. F; i: J" y  m. E
$ `* |" o& ~/ m#pragma comment(lib, "winio.lib"): ]6 D' l" H3 b: B1 P, `5 f0 S

. s0 K4 F2 s" L/ w6 z; H% x8 T' c% [4 J$ Z
int PMU_SC                =        0x6C;//命令端口/ q. U6 X( g+ X7 h% {
int PMU_DATA                =        0x68;//数据端口0 w! J! ^  j2 f5 b( F; d
int RD_EC_SMI                =        0x80;//读寄存器命令6 N  l& g( ?! q+ a9 k' @  L, B: n
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
5 w" U  K2 y7 D$ b0 K" l
' g3 I  |  @& O$ @1 GDWORD dwTemp = 0;
6 U! K; e1 ~1 C0 l# [2 V
4 O, ?  T& j# K" }9 `void PMU_Wait4IBE(DWORD *_value);0 `6 ]5 k5 ?. W, @! \) O
void PMU_Wait4OBF(DWORD *_value);6 F- o. x* ?! u3 `: t
/ V5 k: T9 i5 L& ]/ ]/ ]5 |# [
! Z* N& P$ I1 a/ N1 g# T
int main(int argc, char* argv[])
7 ~7 d& t+ z$ {- `. L{2 J# n( p- N. [- Q1 H7 ?: K
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
/ Z2 ~9 z0 I, n( y9 L: `5 g" L* H' B( |
        5 t- r2 i, X7 e( P- L" h3 Q
        //1、mov            dx,PMU_SC                //1 l' K2 a8 t: d7 a+ p. b
        //2、mov            al,RD_EC_SMI        //* {% \9 a6 W+ Y6 n! G
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
0 F; ~2 \: Y) f+ R  l/ v        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
3 N# i1 C* u$ s
. ^# k& [& Z0 e6 {        PMU_Wait4IBE(&dwTemp);
5 A8 c( |  F* X# F( e       
% o. i2 u+ ]) k5 t" C/ q: x        SetPortVal(PMU_SC, RD_EC_SMI, 1);
  H7 C: v) o+ T1 S- l
4 z5 N$ I3 \! Q- ]  _        PMU_Wait4IBE(&dwTemp);* {% B; ~$ _9 {4 Y4 G* f
       
9 z5 l" ^2 N% M        SetPortVal(PMU_DATA, POLLING_DATA, 1);" l0 v& G( t+ v

' K/ K6 H# M. B. g, O( T        PMU_Wait4IBE(&dwTemp);+ k' ~1 ~; P' e) a3 F; n

( s3 e" o, U; q$ l5 V) e' Y6 z5 K0 u9 r        cout << dwTemp << endl;               
3 ]6 I" b( Z0 o9 Q0 M
' H, V& k* D; v$ d        ShutdownWinIo();6 u; A1 @# ~: }  Y) ]- Y6 W
6 z! r% y& q, N* R3 J
        system("pause");
( f5 V6 K6 P, ~% E
4 x0 o: Y% \- z+ r* U        return 0;
$ N% B8 E  B7 ~/ d}0 I, W6 Q/ @  ]

! H! B$ h# ~2 P, _+ B8 }; ^# Rvoid PMU_Wait4IBE(DWORD *_value)  C: l6 g0 Q  z* Y/ T2 e# J! U# W% d1 s
{2 Y  `$ A& y/ T
        //#########################################################   
  z- V& o0 q5 O' d: B& y4 J        /*
/ l5 o/ w5 d* f        pmuWait4IBE proc   4 e' Z9 ]/ v% h
        PUSH        AX   
" ?/ z! `) y, M2 u; F7 i1 O        PW4IBE:               . L7 P( S6 o9 f
        IN          AL,  06CH                                //Read  PMU  status   
! D1 n+ q& _. r; g; _* x        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
& J9 P  r, M& `; o        JNZ         PW4IBE                                        //Jmp  if  no   2 V* M" O* O2 l+ [. W/ Y
        POP         AX   
6 Q& \% e5 \; X' Y" a1 k        ret   , w" O2 ?4 ^" D8 Q% _: o5 r0 }
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
2 u" c* ?, U! U. ]! w9 q% U7 J        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空3 y! a5 k5 G, f- {1 g
        //######################################################### " U- d  g* v2 M3 A9 N- R
        /*do - Y, m6 l) f5 g; W- t
        {! s  X  o+ w" _) Q; L5 u! E! N
                GetPortVal(PMU_SC, _value, 4);
( k) ]: V5 I( s        }' n" m9 ^4 R- t. M# i
        while ( *(_value) & 0x00000001 );*/
( x6 I9 B4 v7 e3 y        DWORD   dwRegVal=0;
" [7 y6 ~3 U& I/ s        do
0 {- X5 w! L/ o7 ~        {  ( q9 T- W% }& [* X8 }4 h
                GetPortVal(PMU_SC,&dwRegVal,1);) a5 u( d' d" d/ f
        }% Y* K- m# E6 s! o( y. |& e
        while(dwRegVal!=0x2);3 P8 q6 s; a! |3 M
3 t- v. W8 n. H" d: A! L
}
9 F) _3 o! F4 K! }+ r9 f% M) \) N8 S2 i7 M+ l
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。( L/ B3 M0 S" {( Y! M
所以变成了死循环了。: I. c; P- a4 y1 r
: l# [$ S6 F/ U) v* d" u
我对硬件编程不懂。又不知道从何下手。
2 Q% C* t$ f/ P. l; T9 }我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。& y# q7 o* H* h: a) f
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。+ N7 C# H; x4 u0 e# J
) {2 y1 N4 o2 ?1 S% W# B; y/ P4 @. F
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
; h6 k. p' l" ^' q3 w- Y并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
) v! a, {$ K6 b% Y& g% ^- ~( a1 i9 L: |
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
2 I" {" U( F. |9 R% U9 _5 x7 K1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
/ W" A6 U7 V1 K' Z9 \2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突8 o; E3 |# `1 ^- C0 g& H2 e2 q
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
* s/ p+ {, b" }- w! g
: K" N5 y& S9 c7 n% E" B8 i' y所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。4 q; |" g1 C. c. @
5 B, ]; ?( b' v- l2 Q
那么有些什么可行的办法呢?
& L, B" r6 j& p; k" |- ~8 e; Z$ R" B为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。& K* {. N2 |" M* v6 Y; Z, J: E3 o

+ ~" x+ @" G, ^; x" `" J+ z3 R) S5 L它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?# t/ X3 M2 \6 K$ g+ N
, n% m+ H. G) {. d3 C! I
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420. d: B+ x9 c; _) X. e
7 X, j1 i0 p7 m0 k; d2 P& p
http://www.ufoit.com/bbs/viewthread.php?tid=452
+ g7 O5 o* g) e& \3 ^) ]) e" c7 v/ I9 t
http://www.ufoit.com/bbs/viewthread.php?tid=241
& S7 o- }& C5 W+ Q/ J2 s& q
+ O; `, l2 k6 }  k% K7 @看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

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

# m0 U3 n+ J$ s$ V; L- m$ i  u1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。: @- }# j( e: j
2、Driver最复杂,也需要BIOS配合,推荐。
6 l! s. W9 J' l* w8 O7 S3、Windows API只能获取到特定信息,不需要特定的BIOS配合。1 F1 ^% i, v. w$ M; H
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。; [$ G$ D8 h- W' e
你可以混合使用。
6 H  w( O( k" A( o
$ |- L  z2 Q; Y( h1 ?2 S- D1 c6 }===============================================================+ I& p9 z: x( |; l0 U
管理员的这句话:% N7 D9 G( V6 W* w% A
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?, ?  w. |. l! x% ^6 Y# W: K
& f( r, X6 V9 v& Z  v- D3 E- \+ Y
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
9 |  `$ M2 `: q
' E) a- I6 k  Q6 m/ t( F8 F/ v( v另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269% n1 o; Y2 D6 A: C% [. Z9 t

" p7 N' L# m$ A$ a, b这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
/ u5 m# |8 ?% _- U3 _6 s( q# N4 M6 ~+ V! s0 b6 y% [
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
! [5 S# l3 N; J+ C+ }里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
! V  t" z" G$ A- Q: y( _* X( Q) x9 y! G+ J6 u& O9 R* w9 y
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 ; }. V: z5 P, L/ g( `  R
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
' W$ a( {+ L. {# l, q' P1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
+ s) C$ {0 l1 X4 b
" j8 ?% j0 Z& {4 {) K4 }. S
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。0 a/ M- x  f9 z( q
% Q! }" j# d; P& p6 H  R. C2 W
void write66(unsigned char Data)8 n4 }. R8 P5 Z/ r7 d
{
1 Z5 v7 `, v4 `) Q& E- {        DWORD Status,TimeOut=10000000;+ k% o4 ]# b3 N: ^7 q
        do. l( V' d7 x- @
        {
% q" C: Z5 b2 h/ d3 L7 C/ t  |+ T                GetPortVal(0x66,&Status,1);( B' O# H+ R6 Z+ h
                TimeOut --;
+ y+ \9 L, A4 Y7 t//                Sleep(1);& m6 y1 r$ b$ _" s$ E! q$ n& y
        }while((Status & 2) ==2 && TimeOut>0);- H- b9 Q% U! r6 Y* i/ H3 m

; S$ [5 \- ?3 ~* E        SetPortVal(0x66,(DWORD)Data,1);; P4 b6 t8 B5 g8 r1 }5 T) [
}. }# `+ M# `" R
void write62(unsigned char Data)7 l0 W4 R! u5 x
{$ Z1 C; g6 }( R* p! E" ?
        DWORD Status,TimeOut=10000000;, S8 v- c% M! _- C3 \. c( f
        do$ i5 j; S1 e1 B+ }' ]1 P5 y: n
        {
0 f2 C: }7 P# W" a3 s                GetPortVal(0x66,&Status,1);0 R! d0 y: k+ x- j% `) e- C- G
                TimeOut --;
$ l0 N3 D; y( G, T$ s* \2 X//                Sleep(1);- |! N% Y- _" q! f
        }while((Status & 2) ==2 && TimeOut>0);
9 s  c/ N4 G$ q% M
2 w- n' J7 @1 K3 `1 _( N, H- B        SetPortVal(0x62,(DWORD)Data,1);
8 k$ {7 Z' |3 b; A5 H}4 t( C# `4 }5 u+ D4 q+ i( Z
unsigned char read62()
# Y% `4 K6 a0 @- J& l! P{
0 h$ {& |$ L& K+ O3 i* N0 ?3 O        DWORD Status,Data,TimeOut=10000000;
, U( @! y/ _! C4 d% _: H        do; B! ?& ?9 O" Z+ E
        {. w2 D+ C" v& y: f
                GetPortVal(0x66,&Status,1);
; b" X5 A6 S# p  m: A: H9 Q; e                TimeOut --;& n' {6 T3 O% m& t, l
//                Sleep(1);
) _5 O8 a; T# H* s3 Q5 k0 o. r        }while((Status & 1) ==0 && TimeOut>0);
8 w0 J7 i6 _6 o7 C& ?/ _, D+ w
" g( P2 e$ B" D  J  M9 i/ q6 `% m! ~
        GetPortVal(0x62,&Data,1);
, G: X8 ^$ N& S  f  i        return (unsigned char)Data;
) B8 N1 [! {8 u5 c: f}6 u4 b% z8 m+ W5 p6 }
unsigned char read_ec(unsigned char index)
0 i7 Z, a# f+ o9 r- r" ?2 }{
/ _9 C( q+ q# A) n4 q        write66(0x80);
3 ]! o- H2 @* `- k& ?        write62(index);& f9 U* l( K$ `5 E" ?
        return read62();
; |  I/ K" D8 O}" |6 F  G0 D# `& F/ m9 T8 G3 v

9 c7 T3 O; R% W9 l6 Q/ e[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

4 f+ G6 t% K1 _; W; M6 I. k- H[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 6 F4 u3 |5 P- F/ B
9 t5 o. G! T/ o3 O$ o5 v
2 F3 C/ e+ \, H4 X' m1 ?8 C; y6 I/ g
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
5 g" q$ ~) X: S' M; F7 K

% K+ P+ s$ o6 i3 p% R* w1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
3 a( o7 b9 G# {. H1 ^* l( i
( L! @1 X) k. h" i+ Y+ [2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
% j, u1 w. E! B. ?( V4 m$ p. f8 u5 ?+ e% K8 R
3. Then set bit16 of the IRQ to disable it.4 x* J- J2 t, N3 L

8 P6 r6 d' N% }7 k+ b    a.. Offset = IRQ# * 2 + 0x10;$ a& _7 ~- C5 G; J/ Y7 ?

, m7 X4 y  A2 }; D7 y) u' W    b. Write Offset to APIC base,
1 g% t: V* ?1 ^2 v1 x/ @, y2 @1 R3 d* \3 U) P( B5 ], L( S( [6 F
    c. Read Data from APIC base + 0x10;
2 g0 E. v" t8 e
2 ~# ]9 `" w7 D7 _: F- A    d. Or bit16 to Data;
: U9 @  Y' V( d5 c! {
- P6 Y+ h+ D, ?    e. Write Data back to APIC base + 0x10;0 {& r& o. x: c, I8 K, j! ~% S! l) y

% h1 x1 l4 J7 ^ : f; o2 P! h' J: N& R
" g- g5 K5 ^* ^+ y  z; w0 I7 `8 [
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
6 M- L2 [. q* t545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
5 c" k3 v2 o) G4 {: Z
# x* z: p8 s8 S5 o9 n9 Q+ i
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
$ G; h4 G5 q7 w! E" N==============================================
; E" h1 y( W1 ^3 I9 u. h 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
1 J& x/ p! O. q9 Q+ b. O: V
; ]0 r; X; h# ^/ S" ]4 Z3 Q: D因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
+ \0 w* T& d1 a- t9 R但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。' m0 W0 i' s% }' I; O1 x7 s
: n5 F% H) r- F% K; i2 j
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
4 ~2 j2 `% P5 [当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:( R! k; a2 m$ A  i8 b
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
6 w! }5 d4 I. s0 _  o' T2、新手不要把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-13 12:31 , Processed in 0.083641 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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