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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>  B* p# J* h2 z8 Z' Z2 j4 |
#include <Windows.h>
; U. q6 U+ N3 w9 \- a#include "WinIo.h"! u% E. J; C' `" c0 r3 Q4 b
using namespace std;; @. v# N+ Y3 {  j9 m
1 z: q0 l( F% b5 Q% I
#pragma comment(lib, "winio.lib")- y$ w( E2 w% q& g

$ Y& d3 ?# b% o. E/ {7 o2 W' X' e' b  j( ], ~5 Q
int PMU_SC                =        0x6C;//命令端口! u' b1 \, O7 H, t7 W  W* C0 B! D
int PMU_DATA                =        0x68;//数据端口
8 h6 B, B( Y7 Xint RD_EC_SMI                =        0x80;//读寄存器命令
% }1 w+ J; Q7 H( _& @, hint POLLING_DATA                =        0xE7;//CPU温度寄存器号
2 T- R4 f! R7 d! C6 |8 G# a. P' u, e7 x4 V
DWORD dwTemp = 0;
7 C( S' I, G3 z# j5 n3 S; G1 v, u
% t8 o6 g" p: F( i. w9 U- a9 lvoid PMU_Wait4IBE(DWORD *_value);' _6 F1 B+ B& Q$ {, g2 u# H
void PMU_Wait4OBF(DWORD *_value);7 R2 x- D0 `8 F& g/ K" Q( x( f
5 X* z, {, @8 X, I) I# R
! x  H6 R" P0 j9 l! \' b; F" b# U
int main(int argc, char* argv[])3 G) t' |, r0 W, X0 c
{
6 O1 H* x+ p' F, s; R- _, Z4 g        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
# Y; C$ t( [, ^5 x
4 t" g: t! u! T! P, p2 D. ~. x        . C  J* r$ e; S' b. `! F
        //1、mov            dx,PMU_SC                //- d4 R& Q8 U* ~* ?6 \
        //2、mov            al,RD_EC_SMI        //' j+ ]5 T" x% i9 F9 j2 B. T: {
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了; N( |5 f, B( z, f+ _! O, t
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
' C( z5 s5 B* c3 l/ c' E, M
! B# o) e# V9 Q+ B3 q, j/ p, e  d# u9 e4 z        PMU_Wait4IBE(&dwTemp);5 H) @& X8 }# t% }+ C
        0 S7 C1 L0 u4 \! }* O; q
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
' m* C# h' }7 D; G# `& o
+ J8 Y$ ~" z, P1 K5 v        PMU_Wait4IBE(&dwTemp);
& B) F4 _, }. Z' R5 ^( e       
: c. F1 l4 F  ~9 z0 ~# ]+ k  |        SetPortVal(PMU_DATA, POLLING_DATA, 1);# X. g6 p7 Z; D" X
, V  I; B; L- |, g2 j1 q* X
        PMU_Wait4IBE(&dwTemp);
4 V8 R& e9 e4 a3 u9 ~
# X( Z! a- [; L' m        cout << dwTemp << endl;               
3 Z" J& G# q3 g
9 ~% m/ i9 V* D" w        ShutdownWinIo();
$ W' o  m0 i( w  U
5 o6 F: B! m4 P2 b! K' f( _1 ~$ `% ^# n        system("pause");
6 Q" ^9 c$ `- R( E2 [" r# P
; c0 z' _8 r1 S3 O$ L        return 0;0 C$ i( o( I/ I+ L* Z2 ~: W/ ?
}6 S, B( z! ^8 {6 e, H1 c% F
2 z0 m& G) N; Z* m* U3 i
void PMU_Wait4IBE(DWORD *_value)6 `+ e) L0 N) h3 s, `5 _% W( \
{) }: K  q$ z; A* p: H# |! B; U
        //#########################################################   - H! r; a" c9 G9 X* V1 J
        /*
3 {) Y, O# D! c        pmuWait4IBE proc   
' c: n% A) V! D6 b/ a; }' ?9 Q        PUSH        AX   & Z( G; a6 R$ S  G
        PW4IBE:               . q; T7 a+ o5 O( R' `! B
        IN          AL,  06CH                                //Read  PMU  status   ( c; V( L( M2 n9 \3 d
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?     |- N. @' x' ?6 F
        JNZ         PW4IBE                                        //Jmp  if  no   
" i% Z1 O& l! p$ v        POP         AX   
1 ~+ Q) a& \& e! C        ret   / I! [$ x8 R% S; }8 ]+ M/ I8 o+ B
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE, Z: W9 Q8 Y) z( N# s$ W
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空2 V" V7 }1 j& H( K  |1 P
        //#########################################################
% m  I; F& `% k/ A0 V+ P6 Y+ ^: I        /*do
" @9 z* F; T/ j/ U& ?: @* x        {
5 R" t  Q) q: x9 v$ E                GetPortVal(PMU_SC, _value, 4);: N8 X2 O5 b4 n9 o) I
        }
5 E, @" ^: m% n* F6 W$ Z- [        while ( *(_value) & 0x00000001 );*/- d6 f( D9 p; m0 q- T8 [
        DWORD   dwRegVal=0;
0 U3 r9 L# L1 s1 y8 b$ m        do
# W" J7 x+ V( `        {  / y' L! l8 |& f1 t0 w5 R% b
                GetPortVal(PMU_SC,&dwRegVal,1);8 x# R) Q- k( f; D6 i2 t, n. ~+ Z) l
        }
. a2 K! F9 @# E* \- |9 J        while(dwRegVal!=0x2);* H8 q" V7 r9 x9 [8 }% j0 }
, f1 f, P% r/ t8 w+ `
}% E. N( q% t9 E) F& I1 V, V. [  g

4 e5 E9 n- j5 n以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
/ f% f# t0 _  h6 p' c3 s3 g: }( w所以变成了死循环了。
" c: B% l! M5 ]' {" p
" ?+ R: m  C* W6 b7 L+ M3 e我对硬件编程不懂。又不知道从何下手。7 n* p+ b- i- k7 P2 D$ Q) E3 h
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
0 X& }) l1 R! h$ q  r# x但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。. c8 T0 f, U  r' \( _) @
. n* c# T: ^/ ^
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。0 Q' h+ Y7 U& c$ L( b0 W
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
! ?# P( a8 O# ?5 r5 r8 I- _! ?$ Y) _" n+ d& 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.但是你这样做法应该是读不到的。6 R6 g$ U3 n  f2 N0 l/ Y3 I7 ]5 P; ^
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.- E( V) Y8 ]: X
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突: B% r5 K' h0 c+ _
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.& p7 o, X% y& m8 q6 }4 x

- h3 c5 h; Y5 \$ ^  M! g. |+ }7 q所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。: ?9 C6 `7 U1 B- P4 V( U
; M/ |, G3 F4 |3 A+ B2 H% o
那么有些什么可行的办法呢?
5 _7 j/ F5 r8 y, D" y' W为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
/ U$ G% W# S' ^" _% _7 P1 n' l- C( h  D! t& ~; y% m  h1 T. `9 J
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?- v4 [) g0 c" w. ?% G" W

7 I3 S9 a/ n  P$ T& e" V( I那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
( E  o( J% M; K9 L; R  m! Z) _- o$ q& G5 e, I
http://www.ufoit.com/bbs/viewthread.php?tid=4522 p3 Q( M" F7 H

7 P3 I4 ~6 B; o$ A; B1 D; L$ Ohttp://www.ufoit.com/bbs/viewthread.php?tid=2413 V8 F; Q9 O! b) P6 x# H
7 Q$ a( P4 r- a3 o
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

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

% b$ w$ c% ~$ J8 a1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
2 O: z; {5 e# N0 q! X2 R# U2、Driver最复杂,也需要BIOS配合,推荐。: Y) M7 V% e  V9 I/ U
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
2 n8 j! ?3 t3 n( p8 O+ T4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。4 c8 w2 y% F/ q" @+ k4 X3 g
你可以混合使用。
# I: b6 D, Q  N& A
' S3 j  w. A' C* B' v) z3 A===============================================================
0 q2 M% ~% E  e9 A8 S, M管理员的这句话:
+ F. N- J9 C$ ]! w# R) R如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
0 }/ C7 E& e6 h! p0 }( \7 h* r4 t" k- g
/ s6 F2 w- T0 A: C予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
4 f" z0 M" @" L. F0 I/ j! {" X# [$ H' o0 |
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269. t. }' Y# Q9 U2 O& D0 ?2 @# J) r
, f1 m, L' A6 e5 u, Y& }
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?$ K6 G! B( c+ a  {8 X& _4 v) p% x3 F
8 i% R3 l' a9 J% X6 j
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。- G$ i7 p8 U9 V4 L, W3 L3 V
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
0 q) i/ g! r7 U: a* j+ J% \; A. {0 j; K5 r; ^, n6 }  v  @# l) a
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 8 e1 d7 z. U: V9 X* G: p
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。; R) F; f( z; s& ?; N
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

3 |/ C- G- ]- \- ]& ^( ?2 l0 \7 V. Z( L+ V2 h
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。( e- W3 O5 x6 Y% U

$ l& {2 q4 \2 Qvoid write66(unsigned char Data)6 X7 j" M8 h! v$ ~6 o
{
/ I2 K) w% }) J! M        DWORD Status,TimeOut=10000000;
, @2 T  e; I1 M7 b        do1 n- Y9 |  s+ V. D8 N; |7 ?
        {3 b; i. l! ]4 N
                GetPortVal(0x66,&Status,1);
) v; q& J+ V3 d3 M                TimeOut --;: ~7 ?% ~2 g& V! V- o% _& g+ N
//                Sleep(1);6 K7 ~5 h8 L/ H' u3 e* r( F% [
        }while((Status & 2) ==2 && TimeOut>0);
0 _7 R# h+ F  D3 H5 ?; A* i1 K8 G' c/ [9 M7 `1 q6 ~4 D  X& o% L
        SetPortVal(0x66,(DWORD)Data,1);
8 b: k0 o( m; g( q: F& X# W2 }}
) l+ w$ ?" f, t4 Wvoid write62(unsigned char Data)
- ~' r7 Y! l  Q{
" ^, q9 V( I. m/ }( O( z        DWORD Status,TimeOut=10000000;# k) E7 j" }- D# g- f6 T
        do
4 R$ l5 p6 L  b        {# M+ ~: O& ^2 p3 v5 R
                GetPortVal(0x66,&Status,1);
4 Y1 ?4 X+ A) J                TimeOut --;
% F! m4 s' s1 Y1 k8 w" ~( ^//                Sleep(1);# @  c9 b1 U, d, ^$ T8 Q
        }while((Status & 2) ==2 && TimeOut>0);
7 Y% d% k5 F. W' L  f2 ?) ~0 ?/ g, f5 U2 f; g" w! k
        SetPortVal(0x62,(DWORD)Data,1);
* s4 A  D; B2 X) |2 ]) N}
9 q) N' b7 p, d7 p. Dunsigned char read62()
( H+ o# L9 o5 `4 s' S1 k0 e{. r% {) x/ b) [2 f7 F
        DWORD Status,Data,TimeOut=10000000;
5 J$ {; v8 v  q8 G        do
' m' K, X' `$ J$ u- v        {
+ f9 r9 Q4 }" R, L/ y: |2 R                GetPortVal(0x66,&Status,1);
& ?6 i8 W! ]5 [1 n  O                TimeOut --;1 l: Y+ [1 F* _* c& v+ H4 W. k
//                Sleep(1);* V' m) o7 o8 k% ]
        }while((Status & 1) ==0 && TimeOut>0);
6 G$ M9 l: M/ p8 {. E5 u$ n3 w; J8 _

$ Q+ z' W2 A; F8 @/ Y0 t8 H" {3 W        GetPortVal(0x62,&Data,1);
; }$ [& \2 y. l, E# e0 U        return (unsigned char)Data;
4 j4 E. P8 c  o/ \2 E" M}. t  [! \3 f; M. u$ a. k. z
unsigned char read_ec(unsigned char index)
- w8 N6 l- y# k{
2 \' E) A- y( r; I        write66(0x80);  z9 `) [5 H  a& P0 D6 k  P
        write62(index);/ i' k) ?9 M- W
        return read62();) O9 R4 T5 d/ V& T
}; W# n$ N& V$ T/ D1 Z
! {4 G4 W) W& X. {- o
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
+ v; R9 w% h) f% r/ o; f9 O3 e/ h( T) Q6 u7 @" [( M; F! {- L

2 ^! B' }. t7 W( k( u# ~9 o7 e您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

+ s, |! \- A  B# x' A1 U7 X: H8 K( t8 h% V( R0 p
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
1 m, D& U4 h1 u; i/ t% Q
2 V' s  J6 t- t% ~' M7 t2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
' w: h; r# m8 M: E+ \  R* H; d, X, X! a9 E, S8 K# m
3. Then set bit16 of the IRQ to disable it.
3 L( J7 U, m# [! E, B; ?& O
6 |8 y$ j1 \2 M7 L    a.. Offset = IRQ# * 2 + 0x10;
* V7 t! {* C- m/ }" E4 C$ {" ?* S  [  i5 b; v& b# H
    b. Write Offset to APIC base,- ?  ^! n- D3 \6 m0 @
& W$ A+ R- L+ _! c4 j
    c. Read Data from APIC base + 0x10;
( {) ^' A9 g6 o
" C( t3 y$ [) r5 I2 E; n4 _, E    d. Or bit16 to Data;1 h, Z0 |' B% [9 O

6 J0 Z- D7 o6 ]- A. g    e. Write Data back to APIC base + 0x10;$ j' y+ X, {" @1 v/ D
& t# m/ r# X, t) E  B& \
3 W7 i: _, H& F; P* L  {  N
2 j4 C4 P4 v. K2 g' R7 J' s
You need to check APIC spec for details.
回复

使用道具 举报

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

# @* D6 z0 k$ k7 J* v. }# c
$ l# Y1 x; H( q' m- S* F 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
/ E9 ^* u+ i" `" [' ?==============================================9 g# F$ ], B9 L" @
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。; z/ G+ V& _7 O% j
' ~7 I$ o/ a4 Q( R; a) @$ {
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
4 ?9 r. n1 H9 y$ h+ r但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
  {/ {3 `9 @0 b; s8 a& e  |5 ?& v/ {" ?3 [% f( {6 w  m
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。- T( E; N" J! x7 U$ ^4 Q
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:/ |. @# D$ h9 U3 ~
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。% F  B! a1 P  G9 R( p/ E+ ]
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-6-8 10:36 , Processed in 0.308803 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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