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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
) t& g8 |) Z6 k5 Y: ^5 P( U1 ~. {' L#include <Windows.h>2 c8 l, y/ p3 T/ y5 _& r
#include "WinIo.h"9 S+ ]+ |7 H! R3 h3 ^9 k
using namespace std;
2 {, U/ f7 W, \
6 ~8 g* a  `& G3 p3 d; f% d+ a#pragma comment(lib, "winio.lib")
: m7 R0 Z$ h" G* L) {
  _3 J& o6 e$ @- D; W8 [9 U; H. E# I$ x6 F5 v9 e) T5 q: T- G( c
int PMU_SC                =        0x6C;//命令端口
& F1 d7 S# \; a4 nint PMU_DATA                =        0x68;//数据端口, r7 K$ v- @2 H$ u, j+ y6 H
int RD_EC_SMI                =        0x80;//读寄存器命令
& M$ |5 y# L& }; Eint POLLING_DATA                =        0xE7;//CPU温度寄存器号
0 [, E% z/ t1 |$ b/ v" s, ?
; ?# K" k: \* a# K0 ^' M" N: C) D. ODWORD dwTemp = 0;4 @1 z% A. c8 z6 u. S
7 M! g+ o1 s; i" ?. }
void PMU_Wait4IBE(DWORD *_value);
, |  v  h9 L9 Uvoid PMU_Wait4OBF(DWORD *_value);
: ^: a, u7 `0 {6 {* d2 x, W5 o( E! H/ H. V) I
9 L$ t8 Y0 \: r9 o
int main(int argc, char* argv[])6 S+ a% ^% c) h. E1 z; p: i
{
$ L1 ?: M( S7 j, a- L6 d" K        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;  a( {* d7 U3 U0 n# u( s
. n0 d$ p5 z1 O% H( Z
       
2 L7 k; s  W0 e% j- B  Q        //1、mov            dx,PMU_SC                //1 w* g" Y# I# U4 V. v7 C
        //2、mov            al,RD_EC_SMI        //
: `7 o: a4 N1 q        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了3 p2 ^7 U$ q, Y9 F; ]
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
/ \/ a$ i( m* q" v
' b4 E5 Z" \8 x- i% L        PMU_Wait4IBE(&dwTemp);& y3 d7 B9 z# T( I9 k8 |1 A& B
        8 x% V- Q  b( W
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
' ?0 z3 V; S; P6 \4 q8 Q; K- y0 H. t7 P* c3 Y+ _1 G$ w
        PMU_Wait4IBE(&dwTemp);
+ \  ~! \8 _1 g; ~' i6 W% b       
- {3 d/ T6 V2 B2 c" i; z        SetPortVal(PMU_DATA, POLLING_DATA, 1);; b, D5 v4 z7 n. ?4 y3 h* U: |
1 ], E* j* A7 l3 ^. J
        PMU_Wait4IBE(&dwTemp);  R9 I. @( ~8 }" k" {
0 y+ U) _8 W# R4 l
        cout << dwTemp << endl;                0 l- Z" E/ g& Y) Q9 R9 ~

% Y6 f  L7 S7 [3 a6 @# P) U/ ?1 N        ShutdownWinIo();) l9 n8 S- m1 x! _+ }. e; x' l

7 q9 [, ~& U- c. N) E9 V: T5 K7 p        system("pause");
8 Z: z) {7 S0 n6 Z! S- @. W4 N: S% n/ |6 n1 b% T  ^7 j
        return 0;2 T2 X& c! Q8 A, Y: F0 g
}! L. A* ~9 p; C% e; @

) U+ X8 ?) G9 h/ evoid PMU_Wait4IBE(DWORD *_value)
% c! @- [0 Y0 C3 w" p8 r{0 E2 }7 y+ M. y4 @0 n3 Z6 c
        //#########################################################   2 d/ W$ u1 u9 R" Z' v% J- e) \
        /*2 ~3 l7 s7 g! V4 y
        pmuWait4IBE proc   6 c4 H% Q& M$ k8 {
        PUSH        AX   
+ W/ {/ r/ I& m5 D7 ^7 l        PW4IBE:               3 ~/ H' B% x3 Q; {2 U: I4 [
        IN          AL,  06CH                                //Read  PMU  status   ; m! u: l3 Z5 M" M2 ^0 k9 l: V# _
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
) V2 \, g* V% q0 p" t- M% P2 Y        JNZ         PW4IBE                                        //Jmp  if  no   
: v3 T& Q) y5 T& v. e( j* B        POP         AX   ; y3 a, ], M6 }$ r( A
        ret     p6 ?2 p" o; N  E2 a. Y  @+ O4 h
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE  n4 ^$ H% }1 X6 z
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
1 U* }  U: S3 ~. f7 v# W        //######################################################### ' u& I" O% a4 o6 O' R) ^
        /*do
5 V1 i+ |: k8 s* C5 C        {1 N# A" U$ h) g% A* ^% o0 L
                GetPortVal(PMU_SC, _value, 4);
/ S2 v; H: r) l! z1 {        }
) D, d2 o9 Y( z        while ( *(_value) & 0x00000001 );*/
7 t9 Z7 `' k' e        DWORD   dwRegVal=0;2 m* N0 B, j: T7 s: J" m
        do
: p( u) d  C; a, F; \7 Q* n. D# \        {  8 G4 k& x3 U' F' ^( n  V5 {5 V6 Y
                GetPortVal(PMU_SC,&dwRegVal,1);
( f0 X7 K1 g- B. Y1 c% U% M        }$ N- R3 s2 W) \! l
        while(dwRegVal!=0x2);* N0 x) P0 M5 J- j* h

2 W& [3 t: ^# T}
  `# e' i+ U# X+ v4 F$ ~: G* P# x: i, _" U5 N8 w7 t) {8 o
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
  Y  P& J" D8 H! X4 f所以变成了死循环了。" G4 e( N* p, _2 b

% j8 p9 D' t# O1 W7 c我对硬件编程不懂。又不知道从何下手。
4 H! L) |! B; v3 g8 G我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。# \0 s' _4 ?$ x' X1 B: D
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。* X4 d5 z; Y: L/ |( u3 n, v) g' w1 x
" v$ O8 G/ p3 i3 m: D# n
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
5 u9 P, S: h+ f/ `并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。6 z0 x( ~( l% V3 g# x1 ?7 o" y

0 S! Z4 N+ ]0 s感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。, i/ ?  C# l* d, P
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.9 _7 F5 ]4 ]/ f
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
( Y# O8 h" f: n& u4 \# q) v, y! S3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的." b9 V6 d/ y4 U$ }: g
  U4 L6 V" h& X+ p4 t
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。$ W' L$ `: M" m2 E5 t8 d+ e  c( ]
2 O+ `* P7 Z+ Z$ y; A, C* k: ?
那么有些什么可行的办法呢?! M$ e1 P9 U8 f9 u! D  m/ c
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
2 o0 x6 ^. n; k/ {, T
4 ^6 v6 r2 M6 M$ L1 Y它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?) k; p" A9 a+ ]- E

8 J! Y9 B9 {, N  e9 Z# Z0 v! r那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
8 a, ?, \* z- W5 ]3 R1 H: L: A. k3 R2 L: T' F3 L
http://www.ufoit.com/bbs/viewthread.php?tid=4524 A5 p3 z9 U( Y8 s3 r
2 \; [6 L% s# |& N% O
http://www.ufoit.com/bbs/viewthread.php?tid=241
! a5 G' Z8 b3 h/ m( p, [8 r1 |6 B
  v1 m/ _& D% ?" M0 ~8 N看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
, n( c3 j$ o# t# O; {8 t$ M, l. X# S/ o
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
" f$ e9 t. ^' R3 b& f. U2、Driver最复杂,也需要BIOS配合,推荐。* f3 G* t3 L/ \7 u
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。2 s! |% n2 A8 f: R5 y+ W
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。, ?2 h) r/ f$ `* U1 V
你可以混合使用。4 g/ m- G" W; y- E- ^& E
( t; I2 _* Q  K& j0 X$ x
===============================================================
, B- z# L' p$ P. C( ^/ q管理员的这句话:  }9 Z- o0 d# v
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
$ l1 _& G- t$ K
4 g2 a8 F! V& }0 Y- T予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵+ l: J" K  b6 ^, B
6 \% m  I3 r+ B! i0 m& Z' _2 W
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
% W- R( A. a% `8 B
- m3 m$ `" k( `- T& `- G. _这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?" X* ?, Z' J9 P2 [

/ O. @$ y, o+ J" s还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。+ d) }# d- P; O4 P& [0 q5 Y% l' n
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?3 R5 U! R' k9 D) w8 E
- F9 o/ `& P+ X$ \, A6 ~
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 " b! e: P5 u7 r
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
2 F3 u- \, U% ^' }1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
2 S9 q4 Q2 O8 D) q
( K. h7 Y/ L$ K- @# Y  S( O
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。/ ^8 X' N1 \1 I
$ R# `  b  H* |* X
void write66(unsigned char Data)
, P% ?4 I( G8 o8 V' Y% W. [{( F6 l0 Z: N) @! Q6 }) ^
        DWORD Status,TimeOut=10000000;
+ i& L; O, A/ K        do
) I; I) j$ H! W3 p- t" @+ r        {
7 }* d7 k& k, N3 c$ l% ^                GetPortVal(0x66,&Status,1);$ K4 l6 a" R! Y; o8 z
                TimeOut --;
1 t, H! G* z4 v//                Sleep(1);5 H# ?/ }, _1 R; }& F; O
        }while((Status & 2) ==2 && TimeOut>0);; o8 f% Z. j7 r' A+ S
$ [9 W* K# T( L0 v; k
        SetPortVal(0x66,(DWORD)Data,1);+ r8 _8 [$ }1 K8 X7 K/ v
}
2 k! e8 L( K, \7 Kvoid write62(unsigned char Data)
: k' ^6 J5 R+ X2 R0 Y{  ~* f0 W0 y" {0 B, ^
        DWORD Status,TimeOut=10000000;
: `1 ^( G, T# p. @4 z6 m0 H8 M8 t4 i        do
, u6 Z) v: c* [) T3 I& ^        {/ g7 O* X6 ?# a$ H# ?
                GetPortVal(0x66,&Status,1);
& Y) m. l( j% F$ x$ ?                TimeOut --;
0 K% p: A3 \/ x/ h7 y//                Sleep(1);
* y* l( x4 X6 A4 W        }while((Status & 2) ==2 && TimeOut>0);
9 H# r% q% g" ~5 Y  ?8 s- P/ O% n  B& G: S% `
        SetPortVal(0x62,(DWORD)Data,1);
0 l. I- Z- b' w& G}: D5 `- V% z  |* @% A4 q' p
unsigned char read62()
7 ^- v2 M+ h6 A9 i) d. Y{1 g& X7 r3 L) x
        DWORD Status,Data,TimeOut=10000000;3 H; m1 O  [5 J7 }$ U6 T4 n
        do1 y9 c, r. ]; _5 o/ U
        {3 W2 A7 t( w9 q. C+ Y: d4 ^* d
                GetPortVal(0x66,&Status,1);( k' R0 f- D4 N/ q7 q5 C
                TimeOut --;: r# w' y  |* f* i" l
//                Sleep(1);
, s1 t! K& W  j$ K. P        }while((Status & 1) ==0 && TimeOut>0);% v3 m8 o, l9 D' R' F$ s1 ^

. W3 B2 o+ s( A* u$ w7 N& z
# O8 V3 n. j& M8 K) C9 ^        GetPortVal(0x62,&Data,1);
* |' o* J' T4 m        return (unsigned char)Data;
% f* m5 a; Q4 u, ?3 y}1 q" @$ X5 @. x/ v  t# p
unsigned char read_ec(unsigned char index)
8 l  E( H. \7 p( b9 v{: `6 ~+ t/ ]3 p, |+ t
        write66(0x80);
' I- r# @/ {, Q% _, j" E, g3 P        write62(index);% M: t1 C/ w: ~6 a- h/ ]4 D
        return read62();
/ v5 @  ~# c1 }" Q}
3 F+ |$ p1 |" W; P  I5 e$ O9 Y- _& p- Y+ ^* W
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
; L/ i4 S6 q: g4 E6 e' J* x/ A2 `- I+ o% J
; t5 u# V- H/ p
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
& b) c2 O! }  ^) T
* C% n% s: W6 c5 ]
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
# H6 e5 r, T" C* C  k* D
! z+ B# r2 q) _  [4 U& t1 a/ }2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.2 ~  n9 X5 \0 w0 K$ M! z, \
' Z. r5 U$ t6 L
3. Then set bit16 of the IRQ to disable it.0 j- e2 ?3 r+ x9 f+ L8 `+ @; h

9 o2 @1 `) q$ n, d' ~+ ^) s    a.. Offset = IRQ# * 2 + 0x10;. M* ^; t2 x2 f& H

7 K, `9 i# D! m8 F5 Z. b* T6 r    b. Write Offset to APIC base,7 ?- O# ^! V& O) c/ R
( c' X; u6 s3 p
    c. Read Data from APIC base + 0x10;% u7 p( q! y: u/ k% J: s9 W7 W
6 ~( D" r% T$ p  Q
    d. Or bit16 to Data;  S* Q4 c; u5 L1 f

" m) k  T. w/ R9 |: {1 n( S. [    e. Write Data back to APIC base + 0x10;
9 K& z; e& d5 h4 y
2 C6 t# U( v2 w0 p; O5 Z9 y
( b0 c5 m% l7 S+ R  ~
1 s, f: ?6 d" \; O% g2 c, E* yYou need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 - d& p5 K- E- J( X
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
$ s6 z* Y; F/ g. c% Q
  C! r/ T( I& o' P0 {( S6 n
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。: K( x' s  m+ S% b
==============================================1 T, X$ b# p9 K( ^( I; ^
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。3 p3 y1 ~. u0 C8 }
9 E! V. U, i; ]& D& d/ |
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
1 e/ j& {1 O0 a. s' r- w但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
4 y, s9 K& X6 Z3 I6 h+ M4 l7 J9 ^- o$ W) ?. i+ ^
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
2 s6 C2 l7 e% K当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:9 [! W, [* o( K, H4 X, `
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。1 G7 E6 M/ W9 j
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-4-20 01:44 , Processed in 0.071928 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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