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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>! d8 {' k5 p+ s, M
#include <Windows.h>
" \6 [! u9 T9 \* v* q: I) c2 D" w#include "WinIo.h"$ T; k; R) N$ |8 T: F! @
using namespace std;( x" \9 I$ i, m' k

9 C. S8 A+ P7 f% Y2 e. i3 ]) o, s2 N#pragma comment(lib, "winio.lib")
" L2 m- U, K$ ]4 s/ `0 s5 P/ w6 h! u# a
9 N' R, r, c6 g4 e% i( o
int PMU_SC                =        0x6C;//命令端口( K" F  h/ |  O  |' A
int PMU_DATA                =        0x68;//数据端口
% e) F/ h+ n4 A1 C$ {$ i# g0 uint RD_EC_SMI                =        0x80;//读寄存器命令
3 V" v& n  u. M3 ^! b+ Sint POLLING_DATA                =        0xE7;//CPU温度寄存器号3 j6 ^* P# T8 @5 R
. p8 P. p. d9 i) R4 w7 W0 [3 r' o
DWORD dwTemp = 0;
2 {3 v, F% d0 V* ~+ ~* q) q
7 f6 R7 u7 P4 ?void PMU_Wait4IBE(DWORD *_value);
' S! R4 G6 u9 j3 Jvoid PMU_Wait4OBF(DWORD *_value);
7 g! P- f+ }; F* U( d" X# {' ~% F6 K; j/ Y
6 _  {7 R4 y* \& X; V% R5 D- C# Y0 l
int main(int argc, char* argv[])& {/ p) ]* I8 U7 Z8 t/ U9 E& F: k
{/ v& T3 b" X  x3 k/ ~! y
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;& H% V1 S8 g2 ?, c* N/ Y# ]4 a
0 W7 k$ @) |8 }  d
       
. v, X) K6 c- g- Y& R3 a) \* y; B        //1、mov            dx,PMU_SC                //
7 u% ^2 O/ C9 \6 S6 }- B        //2、mov            al,RD_EC_SMI        //
8 C$ p0 ?! F& F2 Q  f        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
$ K/ z; u, y0 _" y        //4、out            dx,al                        //将读寄存器命令放到命令端口中。( ?+ }' s- p5 L
1 ~) v1 p0 b# Y* x1 R
        PMU_Wait4IBE(&dwTemp);8 ~, S, A2 I& A# I6 e4 M0 Y) W1 J" Y
        - b- W* d) S" O% |) [
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
- X- o3 {; @4 q: l) q) ?- }8 A$ {
, R1 ]# N* I1 c+ d& a5 _/ ^        PMU_Wait4IBE(&dwTemp);- N  ~$ \2 H8 m( R6 p; ?' g
        6 Q& E6 X% r* u: L5 o
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
3 o& n. A! s' U+ @& a' u' A- S2 \$ g% H1 j' s
        PMU_Wait4IBE(&dwTemp);
' [4 x' O, N2 @# w/ \
1 Y0 U! v7 H, P' F2 A7 i8 z        cout << dwTemp << endl;               
5 s7 N7 _$ ^+ t; q  z# E7 _
: {0 s2 n2 v+ v1 \0 O/ `        ShutdownWinIo();3 a+ K- T) w8 X

$ E% A" M* N! S        system("pause");
0 |) k9 C& G4 ^, C5 ~
8 J0 q7 [4 t% o5 N* x        return 0;" k+ A/ a& H8 Y" E
}
8 }" c$ b  z0 ?, J
; N/ U( q1 o4 ~$ Rvoid PMU_Wait4IBE(DWORD *_value)
: ~2 W+ i5 ?! m& X6 w/ g8 o{5 f# \4 F' b! K" `+ ?0 \; m* |; b3 l8 \
        //#########################################################   
/ L0 L/ p+ ^$ V& K9 V        /*
) a( J1 |* z# v' [6 ~9 B( P* a! O        pmuWait4IBE proc   
) z( a* Z" k& a; E2 t        PUSH        AX   : s' s) E- q4 W1 Q. q; q& H+ _
        PW4IBE:               
3 r7 |+ g: [* ^; Q# ^        IN          AL,  06CH                                //Read  PMU  status   3 D& g7 Y+ `. o9 {3 `# X0 |, w
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
. j4 y! {0 M0 e% j! r; I' n* @        JNZ         PW4IBE                                        //Jmp  if  no   8 t( Z# ]+ E6 _/ i
        POP         AX   ; [% p+ f; B" ^0 N" Z* y# d
        ret   6 Y' a4 |: _1 }$ R
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE- K$ B7 [8 J' w2 x2 ?7 V
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空  c# S( b" r: D3 Z8 A
        //#########################################################
7 m" c1 B0 a$ u' o        /*do 0 c% b! x& M1 x# F# O5 p( x
        {
1 e- P+ ~: l, ]* d/ A9 a                GetPortVal(PMU_SC, _value, 4);/ w2 L3 H, [& `+ o! A/ Q
        }6 y' R6 A  y3 _! r% u! h
        while ( *(_value) & 0x00000001 );*/
2 t- O/ h/ |7 q) g' A0 K        DWORD   dwRegVal=0;# ~5 I6 A# }8 K3 g( i
        do/ |; q; x1 n6 Z/ f9 g' ?$ G% x- v
        {  & v2 _+ {8 v5 `! }. }7 y+ R  `
                GetPortVal(PMU_SC,&dwRegVal,1);
: ?1 Q$ v: B1 i; J9 B+ X$ v        }' ^; Z( R3 @% v
        while(dwRegVal!=0x2);& D1 V" D. [+ {' I' w  E

# k3 a; g6 A* _( J}: u; Z1 L5 R; W/ a) Q

  G; n) O9 ^+ L1 n! `' g3 L: d! K以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
. \4 j# t+ e+ b; H: e所以变成了死循环了。
2 b' A# r2 q7 ]3 c  i
% T1 E% ?1 F) |5 L1 e$ z: G! o我对硬件编程不懂。又不知道从何下手。
# J0 L# z; h: t9 N/ i我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
$ o8 q# a, n/ q$ H但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
: u- }$ v# m) Q4 G( N( Q" t( t9 w# A/ n2 l; k! g9 Q6 a
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
8 h0 |$ I1 z) z4 f并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。$ s4 f& ]& |; _3 w
, l" l" o) x: O: d) F
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。$ D* w) w0 c( ?. I
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
/ p# U0 c" V' r2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突4 |& E3 Q& w! H0 ]
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
6 O/ [, ?# m6 y# |' Q/ J$ H
, F! W  ]9 S- U# d* @& l- P6 o所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。# l  f" r( P/ @% p$ p3 ^. t9 e

# T8 F8 v7 Z$ F那么有些什么可行的办法呢?
# q* @) X% Z- c4 L0 E, L. W1 M为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
) |% F( o$ v; N/ p2 s$ C, m$ S
7 Q7 X' _4 P& Y1 d它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?* t, m, Q5 e# G
& ?+ Q. x# ]+ W) O% r: r+ K
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420; a9 I+ [5 y5 g4 u

+ V$ e$ N$ e; |1 rhttp://www.ufoit.com/bbs/viewthread.php?tid=4526 L7 W' k  J+ g
1 Y( R. ~  Z0 D
http://www.ufoit.com/bbs/viewthread.php?tid=241  H/ a2 r% y/ O& k. E

' h/ n$ W: O& R看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
; _7 O: t5 _' o' h+ e
1 _+ h: t# M* [: f( u- Z0 H2 M$ ?1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
" N  h% E8 A: u8 x% H2、Driver最复杂,也需要BIOS配合,推荐。
; g. _& p2 ?: ]( z  n3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
: P5 E) T2 y  T- ]4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
! W# r( R* M  v. _: A1 m& S你可以混合使用。
( S! `5 c  f( H# G, V, H+ Q7 |" C& i! z
===============================================================" c, k' G" f$ _% n
管理员的这句话:: |5 j6 _, v* [+ z, R
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
& r* w) v5 x, r2 ]7 c% g& K & f  t1 m" L) \
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵1 [' y  [' L: O9 g" E0 l2 F; d
+ x2 L& u3 W5 x  i
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269) E" r2 r9 d6 `: {

+ Y2 p- C' V4 s" g这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?* A( c9 q: j" `
$ `: n6 z2 M8 W3 I1 L
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。) `2 y, `; F$ ?: ~1 c1 s' r
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
* _1 ?2 P0 b6 Z) p
) g- J6 ~( A' A: D我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表   X# v) t4 g- W# @/ Z
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
% f. k: y  P. s6 h, M$ C1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

7 }: P/ y& ^8 u: p/ E9 w7 I  D! V2 s" v9 L% C7 y& Z) r( j/ K
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。) ]4 q: q$ `0 \% X; b' {! _: s
- H: @- T  U: p4 O4 _% T; E
void write66(unsigned char Data)
1 n5 V2 P+ b! v7 z; J{
7 \: W* c$ {  q0 _1 D        DWORD Status,TimeOut=10000000;1 Z1 z0 t% v7 N3 h7 X3 t
        do$ d, U( ~% X3 H$ W6 R3 A. C) h
        {! H+ {% b' a. t( \
                GetPortVal(0x66,&Status,1);
/ f0 X( m( l1 Y4 E# G  _                TimeOut --;0 E" ]- o5 W# J/ }% c- q6 J3 n
//                Sleep(1);
9 b6 A# g/ D, M0 Q        }while((Status & 2) ==2 && TimeOut>0);
6 G1 d" \' v" l! L/ S0 L( v# L8 r* H1 O7 @2 n9 p+ r8 e1 S5 W
        SetPortVal(0x66,(DWORD)Data,1);
8 A; U  e) W" p}
% _  h; ]1 H: {* k3 z. p2 ^void write62(unsigned char Data)
' ]) x; z; ^2 V& ?( x, k- k4 c{" G( S0 q. w% Y& \4 r
        DWORD Status,TimeOut=10000000;1 Q5 l. a. v6 |9 o
        do! s$ ^9 \9 r3 d3 l4 A5 _
        {
4 J+ }% V0 H* N2 l                GetPortVal(0x66,&Status,1);
' k2 J9 N8 ^4 e, F1 P                TimeOut --;+ P) h% l8 l9 ~
//                Sleep(1);
/ j. w6 F( `; u3 h# w5 M" G        }while((Status & 2) ==2 && TimeOut>0);
# G/ B4 ^5 V2 y7 V4 ~# R
3 B6 I/ i/ J# [) P9 [6 F' z        SetPortVal(0x62,(DWORD)Data,1);- c- W7 W4 l* N- e$ }  [
}
: P* Q- l$ A+ d7 `% B$ D# ounsigned char read62()$ K! h- l' I, p
{
$ A0 h0 {: {& h9 t3 j        DWORD Status,Data,TimeOut=10000000;
. Q4 q* n* `, j% U6 u  i1 S, Q; i        do
9 S( k+ q- C; |8 Z        {7 n. O( `3 _: |. i; K# i7 {
                GetPortVal(0x66,&Status,1);
. K& J! n6 W2 v* s6 w                TimeOut --;
: ^* l' w' {1 z) i! B; s//                Sleep(1);
8 k8 I& z' P6 C  n+ `$ G        }while((Status & 1) ==0 && TimeOut>0);7 S( [" [3 G7 H5 T
  _/ i0 ]2 V6 ]" h
" V3 o' ?- F/ [' E# c
        GetPortVal(0x62,&Data,1);% z/ q0 K# r/ [) a
        return (unsigned char)Data;! x' D9 G, d& j6 r4 o/ _) e1 \
}
" R' N( p7 S/ F( D( \2 y9 Lunsigned char read_ec(unsigned char index)
/ F: w$ ?/ S- m7 b) O3 _{
8 K. s2 m3 B4 @, r8 X  U& |        write66(0x80);
  J' G1 g( p$ C" x% {' O& {. [        write62(index);
4 T7 ?8 }4 G4 U+ t+ [4 @3 R: q& w        return read62();3 f% s5 G% A) t% q' n
}
- @& e$ M& A. n% ~7 Z' @* L- z  I- A6 c+ A$ `7 w1 F# K; q
[ 本帖最后由 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 H! I. N3 r/ [4 F' ?6 z
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。( s3 p. Z/ R) ]

8 z: Y0 D, O6 F0 J0 }  Y3 N1 j[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
, f: }3 ]2 [! Q7 ?  k" j
" ]. W9 j3 Z, [1 J# `8 L/ S- y& |( T; G$ p2 J7 F. r, ^
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
" D7 l3 U5 B; h! H
  I1 W  F% H3 E1 `" l0 k
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,, v/ x7 |- L, ?# |/ T  t
: F. M) n$ v; y  v
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.* V  ~/ `; l) F" B% b

# q/ u9 Y1 a- Z7 M1 _3. Then set bit16 of the IRQ to disable it.
0 P1 C2 ?5 I( b2 u4 d# c. N
2 m6 ~% a& D" L* D4 s0 f+ B    a.. Offset = IRQ# * 2 + 0x10;
7 o/ d$ E0 ~/ \! s( o: m0 ~( `* J4 c( f+ N# ?
    b. Write Offset to APIC base,# b7 j: f; X8 T4 r' M7 O: f
- s- u0 r  Q8 Q8 x; S; m2 U9 {& Z) ]/ g
    c. Read Data from APIC base + 0x10;
' c6 R8 U. k- d/ k* c3 x
. P9 o8 S. z2 g    d. Or bit16 to Data;: h4 |6 p( e$ f6 D, P8 [7 J
5 J' [4 X* S' n0 v: p& F/ E% z6 @; ?
    e. Write Data back to APIC base + 0x10;
% @. b0 Y' B& B4 W# ^: r
. P* U" h' @; | # f' J. d$ u# a" ~

4 `% v% F5 e: }( H3 ~* ]  GYou need to check APIC spec for details.
回复

使用道具 举报

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

* M  X3 ?+ W7 Z1 W! ^" N3 Y5 N* ?
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。# B1 ~) s/ P9 n! [4 ?# b$ u) Y
==============================================
0 s. d1 L1 h+ x# n! J" I2 s7 G 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。( Z4 n; h9 G8 x- m5 E; Y8 E6 E
0 q8 y3 P% Q3 W1 l1 h7 P, ?
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)- ]$ ]+ _. H$ J, z. W  d
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
: j0 G1 ?. e/ Q" }; \. W% a& _) E& w# D$ _/ H! m4 q9 g
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
4 G( B7 f3 \: `" G* v当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:+ g9 c  [  W. D- }0 [" Z0 S) K6 ?
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
" D1 F+ a6 R0 T+ [/ I/ G2、新手不要把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 14:00 , Processed in 0.597280 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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