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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
# f5 O* Q$ G5 I& \0 f, U3 ^# k( H#include <Windows.h>
  c4 c, ^! c8 Z* i, w' y#include "WinIo.h"
5 {: M% p% m* susing namespace std;
- q8 F/ {. E" L+ B8 v# e0 S) M: Y; I8 o* ^! b& c- p
#pragma comment(lib, "winio.lib")
1 {2 e* y, e. C2 i/ w
$ W; P6 R. K# d: |7 G( o! t, Y0 W* u+ X. x( f
int PMU_SC                =        0x6C;//命令端口- ?: g5 h- D6 ]& l1 v5 s( v  d
int PMU_DATA                =        0x68;//数据端口* ~4 _: q2 c6 L% r0 \) l. [! `% y. B
int RD_EC_SMI                =        0x80;//读寄存器命令
: M8 G! K# ?1 h  k9 hint POLLING_DATA                =        0xE7;//CPU温度寄存器号9 |- t' z; V1 q; A; [; R5 l

8 W/ N  b+ [1 W" k, ZDWORD dwTemp = 0;
# `8 k4 c) w" v( {% X0 J* U
& C% r4 R0 f; `0 |; w: L, ^% ^void PMU_Wait4IBE(DWORD *_value);6 o$ X3 V, U$ x( E- k& ^7 J
void PMU_Wait4OBF(DWORD *_value);
0 X# }. Y# O  W9 c* Q
! G  ^+ y! D2 {% w
% L9 o  A' r9 o+ J3 ~1 g2 e0 `int main(int argc, char* argv[])# b! b! }1 m/ _9 @
{. J  _6 X5 E0 L, R6 w/ G! x
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
; [) t0 X% f/ M5 Y
% L  P: B% H- p0 @       
; J4 M+ v0 o8 f, E        //1、mov            dx,PMU_SC                //
0 t2 ]0 D4 H9 O: l' W0 j) i. a- a        //2、mov            al,RD_EC_SMI        //
) @! l- g+ t- Q2 R6 {        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了) v( ], A3 Y3 _3 H" U  @
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
; w* m$ x# V% C  J, @# Z$ v( v: n! p0 C8 t6 N
        PMU_Wait4IBE(&dwTemp);
) k; a1 U8 J8 [6 E) ?       
- n1 |  u4 ]- o3 s+ z, S. K% }        SetPortVal(PMU_SC, RD_EC_SMI, 1);* U& c  ~5 r9 b! l9 j
' s  B! E1 K+ Z! c
        PMU_Wait4IBE(&dwTemp);' X8 r- s+ d( M" ]; J, |
       
- r2 y% ]2 e  [+ E3 n1 N        SetPortVal(PMU_DATA, POLLING_DATA, 1);
( K% I/ M$ Z4 F; r! A5 {) A
2 y: a: @, D8 ?3 b( K2 i        PMU_Wait4IBE(&dwTemp);
% d1 m5 F! T7 v3 Z: R! l
9 ?' Z, K& p9 E. ]7 L( @        cout << dwTemp << endl;               
1 a. E$ u; z* J
5 E+ b2 h/ F3 R, [        ShutdownWinIo();
3 [  v* _2 H( T' x' u* `' p2 q: ]5 P' h0 H; R. `  E! \  N
        system("pause");
/ R1 A2 e% k. v+ v( a: K: m
1 K$ E. T2 v2 F7 |/ _& F# S        return 0;
2 v! a. I, k5 P}
% Z5 l5 i3 S: z  r3 B9 L( J* s. m1 S2 a7 d
void PMU_Wait4IBE(DWORD *_value)2 J1 q1 `9 v" e, w9 j% ~
{
$ J: f0 {4 B; r4 |& X0 k        //#########################################################   ! G$ ^# q& I; S1 U# ^9 I
        /*
9 e) P/ z5 y* T+ l6 q1 S0 U        pmuWait4IBE proc   
- j' Y  j0 x" `        PUSH        AX   " _) \  q% |" l! M4 X: ~
        PW4IBE:               
6 J" s6 L! }* Y5 T        IN          AL,  06CH                                //Read  PMU  status   $ T/ Y# K2 i: z. m" [
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
9 f1 {0 y6 p) g) l2 p( @  C4 i) z        JNZ         PW4IBE                                        //Jmp  if  no   4 ^( N. C" O9 q% e( d/ I8 |: u
        POP         AX   
! R! e( ]$ Q+ r3 e3 c0 V3 s+ _+ j        ret   1 i7 v$ L/ R6 d" [: {  {# j
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE5 j7 p+ u7 X+ k* f$ C4 r9 A, D. Z$ _
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
* X' W. U1 D+ u- ?4 e        //#########################################################
5 X' E0 L6 _* R6 S' w" j  c2 G        /*do + C. V$ j9 p# F) y
        {
8 _: T9 V9 w* i3 D+ N( D                GetPortVal(PMU_SC, _value, 4);, e1 ^8 N) w: j+ S; a
        }
/ M& g2 ]. ]' c8 w1 \, y& Y2 D        while ( *(_value) & 0x00000001 );*/
  P2 [( u" d7 s! J5 c; j        DWORD   dwRegVal=0;
, w! M; H* z* S$ d) B% r        do2 {! A  @7 Y+ B# {5 y" T
        {  % C7 _5 y0 L" G" |+ L0 u8 Q( v2 `
                GetPortVal(PMU_SC,&dwRegVal,1);9 r, M$ w) H: j. @; g: u  Z
        }
7 D' Z5 s  \" C3 G& O$ n% x0 ?        while(dwRegVal!=0x2);& a. P8 l8 P- u4 b2 M0 g

$ p  }* n1 ~+ C" n! }+ L}8 y: W# f% j; }: l& t: e* `) Y; X
0 K' O' Q  D4 L
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
) e  g9 I0 f: C5 E; l7 K. R所以变成了死循环了。5 q# E% `7 o3 @, _: k; \
! n% n! B, W& p7 N6 Q
我对硬件编程不懂。又不知道从何下手。1 b/ ]; V2 _6 l3 J% x6 h
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。% a% _; b% Q: @% [% R
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
) D- W, C3 c( x3 e! W4 o
; b  V4 t$ D: Q( K我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。; O% h' ^: n- Y' T* A2 z
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。' _- L6 j- B" N* A
/ y9 s$ C+ ^) a4 ?6 o; T' H
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。7 v; `8 R7 L+ x7 |
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
; @+ O" D# u) g! j1 ]5 M1 y2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
; g$ y& O) K( J8 a8 Q1 |/ f3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.0 z# n' R9 m& ^( ~- w. i$ `/ j# e
. t8 T0 b& y7 O
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
  x0 M" V  _) C( K: s4 Z0 Q. @7 m3 {8 B$ e9 ?% G
那么有些什么可行的办法呢?
% Y9 x! t- T" M6 q9 O8 _, |; q为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
% D, ~% C: D" o( K0 O& v3 P/ q( y1 \, |1 \7 ?) F
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
7 P8 j. K- q8 `: P1 U9 M3 \* m% M* q* R/ G2 B6 p$ G# n$ c
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420. t3 Z8 f# T9 {3 T* T

: A1 M8 w0 S' A$ N: Jhttp://www.ufoit.com/bbs/viewthread.php?tid=452; N' R: E" l3 \
) X/ V6 B: i# x' U! [1 i. B% n7 ?& M
http://www.ufoit.com/bbs/viewthread.php?tid=241" _" B" {! i( U7 {
8 n" _9 O/ E- ~5 b7 O6 r- Q' j
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
; r9 d9 Q2 z0 r1 u. c3 G" [! F5 Q5 c' V( ?4 t# c7 e
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
. ~# w# I+ e( o. r1 D) G2、Driver最复杂,也需要BIOS配合,推荐。! i9 _  C. d& P; x
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
3 C& ?) q7 U, b. d, g0 J; d6 [' |' B0 ^4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。+ Y: G* d, `% Q/ C5 v
你可以混合使用。
8 y" `5 o' K; Y' q+ `5 H; z& l: H9 j5 c9 A/ [
===============================================================
, i) E% i+ @' l管理员的这句话:3 t; [: Q: H* |1 O1 V7 r
“如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
2 P+ K* a, G# p: X2 Q; g
9 H. q# x7 `) C) Y. e“予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵7 Q! a7 l6 z* n
- D, ~, @8 g; a' R( u
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269. y) k" h6 n3 N
: b9 i' j' ?, d& ]
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
# o, Q0 H4 l4 R$ w+ s
: [/ N0 a: [3 x. E$ X) X还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
3 B9 B. f- W2 B) F% C" `% P里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?; v5 E3 B' h: m5 W
2 d6 o) s& ]. b! C4 w9 h
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 6 _2 G9 {9 m) ?; M% p+ x7 w
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
$ g* M5 ]5 i5 a+ e7 v1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

8 Z, `, ?  N9 l5 ^8 ^  }5 b  o' ~7 n. X
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。; M5 A. k& P* F( }5 x% ^* X
. g7 D. X& v5 Q- A
void write66(unsigned char Data)* R( s; t+ v3 Y
{
! @7 \8 q/ ^% b& W' [$ j  ^        DWORD Status,TimeOut=10000000;+ Z( Y$ A3 K( h2 c- @' \, K
        do0 f" C% K! ]' E
        {
0 z* P1 S8 V6 v5 J7 w' l0 {9 z                GetPortVal(0x66,&Status,1);1 Z" V" _1 `/ }6 X( j' v
                TimeOut --;, k4 g' @1 F6 C4 a4 @4 I
//                Sleep(1);, ~8 U' W: T( u- d) @
        }while((Status & 2) ==2 && TimeOut>0);
6 Y! @1 q7 _+ a/ ~/ h% ^6 W$ \# }8 q
        SetPortVal(0x66,(DWORD)Data,1);* P+ d1 r+ J" D
}0 h) H- x# I0 o2 e
void write62(unsigned char Data)$ G9 i" K2 S6 j! p8 B
{
5 h$ |5 m0 g% e: c9 C8 `        DWORD Status,TimeOut=10000000;
& @9 J8 c1 ]; t6 T( j        do
5 G: I1 X6 s9 D' v        {  R  H1 v0 i7 M6 h+ }
                GetPortVal(0x66,&Status,1);5 j& w- {3 p7 Y. ?8 T0 J/ b8 t; s
                TimeOut --;
( L, s7 y+ X5 G" G//                Sleep(1);
/ }1 t) {% P) b( E+ ?% V        }while((Status & 2) ==2 && TimeOut>0);2 B8 f# I# z1 g' n& @
- A3 C! K4 `  f4 @) l8 d
        SetPortVal(0x62,(DWORD)Data,1);
% A* \' a3 a$ Z% }}
8 x3 V0 N, I. F' E) F8 {unsigned char read62()! w; E/ j& \& C; U& v& N1 D$ l6 A
{
* c) |0 c1 p0 N& v5 u$ ^        DWORD Status,Data,TimeOut=10000000;; I' ~6 |6 P( q5 j. ^0 `2 W
        do/ W7 w( d! L1 m
        {
; P1 T) M' V; o                GetPortVal(0x66,&Status,1);0 d9 S' L) H$ F3 ^* k
                TimeOut --;" L( W4 e5 o1 j. g( x
//                Sleep(1);5 G0 {! v7 \, m
        }while((Status & 1) ==0 && TimeOut>0);
; z9 C: [( @7 I' Q  P( T. @* g% Z) |# O# Q: i3 e* m4 _; G

7 M: e6 c5 n1 h. R        GetPortVal(0x62,&Data,1);
& f9 A% X! f: z; P% D& K- E0 M        return (unsigned char)Data;) |. N2 x1 d' V  }2 i
}
) ~% K2 `& ~* T% I9 K/ E" r& @/ f& zunsigned char read_ec(unsigned char index)# o! I6 b( M/ P( N2 b3 G
{
  U4 \( v8 B! t0 E" F        write66(0x80);
. u2 Q5 Q; h) j1 t1 ^0 a2 O        write62(index);( c- ^+ K: o# Y/ m+ @
        return read62();
; g6 E  {+ H/ F}
: {+ [2 d6 S# S2 t/ n+ e3 `9 {7 M) I0 z4 _4 S$ y) Q+ q7 a! Y
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1905) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
) U  {5 G7 j4 X& J  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
4 a/ \% Z$ g$ o) M
1 O% t/ v0 }! z6 U1 \[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
+ e3 }/ M* x, s2 u9 p0 B7 J: X6 n4 h) \! x5 N0 Y
$ M0 [* E; D9 S; |1 S4 U% m& M9 ^5 a( h0 |
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

+ ~- G  G5 W1 E, X7 X: O) @) B! `
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,5 t. r* P, K5 A' c
: ^$ ~( \* R& ]3 S- N2 B
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
8 Z7 F) [1 e: Y$ R8 R5 E# R) p* V6 k) h1 E
3. Then set bit16 of the IRQ to disable it.& G' B4 {- L& k% ?& f, [5 u

- b3 w8 u- D1 K( C' h' P5 |    a.. Offset = IRQ# * 2 + 0x10;; V+ _2 O" ~' V3 N

3 |6 ~" ^2 U4 _" |% `5 w4 ]0 F+ w    b. Write Offset to APIC base,% ~9 X6 E  i8 `# D5 e
) V8 v* B7 v5 J4 p+ P( j
    c. Read Data from APIC base + 0x10;; k$ k; Z% h, b# j- h5 n

: d8 s" E. @$ s9 w  ?$ l    d. Or bit16 to Data;* m" J  S- _- u# }" E( B. T. l

1 V7 G2 m$ A% X5 Y$ |    e. Write Data back to APIC base + 0x10;
( m$ w3 E4 O+ W# J! M$ q0 j
3 |3 U) E; N7 @6 X( T9 _7 |( D 3 n9 s( u+ i% m
6 @2 ]5 \$ }' M1 I4 w6 f
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
$ j$ L+ a8 O9 E% N545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
4 ^2 G4 I+ ^: G- W
' K2 J2 T9 d! R* [$ ]- o+ j/ [9 c, d
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
6 E3 l# |5 ]* M$ j==============================================
# j) O/ ?$ c6 P5 B: U( z# c 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
2 [6 x; F  L( z6 j; R3 N" H! Y, [! ]% B7 X! U. H' z
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)% k0 x7 s3 |7 J
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
. X' m$ q6 d, P( d" r) Y8 U' m; B' P) H* v5 M
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。% p6 h7 e- o. ^/ g% k& b
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
4 D* p7 ?+ {% r/ X* b8 I, k1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
- F$ }+ ]7 X) c2、新手不要把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-10-12 09:24 , Processed in 0.059369 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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