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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>' J% i/ Z/ X8 r$ B
#include <Windows.h>
; @. T/ q0 C, k. K, R" R#include "WinIo.h"
0 }) q) Q( G6 d; G3 j% Y5 X# U5 Iusing namespace std;
$ f5 c4 i+ g* |, d6 q# d5 N: m; i
; P9 g" }$ \8 Z* L) c2 I$ f#pragma comment(lib, "winio.lib")
$ q# ^9 j/ O4 \! F. f4 S4 h. |6 ]7 h* {2 u* r& T- i1 |
' G5 Q" i- j+ A4 d, m
int PMU_SC                =        0x6C;//命令端口6 v9 C& ~1 H' E, i
int PMU_DATA                =        0x68;//数据端口6 r, T, `/ f! J: F; N
int RD_EC_SMI                =        0x80;//读寄存器命令
  }* h- f* n% E  J8 w3 Vint POLLING_DATA                =        0xE7;//CPU温度寄存器号! {* I8 A% Z$ Y
: v! i5 U4 H- y
DWORD dwTemp = 0;, O9 ], y2 d9 Z. T1 g: ?9 Q

; w2 e+ p& f6 w) A% |void PMU_Wait4IBE(DWORD *_value);& E/ M( _8 C! z' F0 g
void PMU_Wait4OBF(DWORD *_value);+ D) A. O; z1 r  ^
' y! }7 u. n6 ~/ c' p" F. d9 i" \
+ R, o% k; O- Z, `1 d) e
int main(int argc, char* argv[])
% V0 B$ K- p' ~- c5 ?1 ]' s{- h: `: d$ t, F& R- `
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;* b& |' t9 L5 t: W

& O2 I0 Q4 H6 P6 r# P! }* ^& n        . ?5 R3 u- X1 y5 m1 ~
        //1、mov            dx,PMU_SC                //
, \2 \  O2 w- |# I; g) ]  Q. Y; _        //2、mov            al,RD_EC_SMI        //# b/ e* W, O  a' x4 S
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
% J+ k) V6 o/ x8 z4 H4 ?        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
6 v4 I- [, l/ W8 b$ }/ [6 i) j$ X; [0 c
) k4 m- R5 E9 X        PMU_Wait4IBE(&dwTemp);
  U5 R6 o/ k0 U: j! u+ h        ( `# ]5 Q: T  z1 c' e
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
9 W* z; |2 R+ V: ^
1 T( K9 _. L8 D! T- D. E        PMU_Wait4IBE(&dwTemp);
2 f6 T' A& J, T9 o& a        # \7 g& d, a. n7 z0 V7 N2 l
        SetPortVal(PMU_DATA, POLLING_DATA, 1);: ~& |; N2 }3 f7 x% X# ?5 J6 x
7 J/ ?) e  b% Z9 ?! l
        PMU_Wait4IBE(&dwTemp);2 w; W( `* a) Z% h
4 e9 p/ C- J4 |1 [( P$ b
        cout << dwTemp << endl;               
0 S& j" K# ]; S/ z( ]
1 o$ A/ }. G  a" _7 {3 s5 x8 E        ShutdownWinIo();% ]5 q* m' J: q0 O' F" G
1 N5 `1 W& p, L
        system("pause");) @9 F# d3 ?# P6 d  [
. [& m1 c* z2 A' X( p
        return 0;( p3 B( {7 ?" B& L% O
}, f" T. W# _/ o2 z2 l# O8 c- G# V: f

  g! C! N5 n7 W3 Z3 G# x9 ]void PMU_Wait4IBE(DWORD *_value)
0 _8 G' V6 l& _2 b, ]# \9 {{
6 {. S/ f) N! c        //#########################################################   ! S0 r( A' g! A( `& {' I8 o5 C& B
        /*
1 H+ }, U5 L3 H; O; @        pmuWait4IBE proc   + A) J- [- M9 j) w+ ~; `: M$ e
        PUSH        AX   
+ ]+ Y) O( D: j1 J! f7 d( f* E$ f9 u        PW4IBE:               4 h  p+ r# ?% q% U6 y: y, G
        IN          AL,  06CH                                //Read  PMU  status   
* ?# O3 Y2 ?1 O8 i7 A9 ^9 U3 N" y! H        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
+ U" ^/ o4 W/ |" w        JNZ         PW4IBE                                        //Jmp  if  no   
( l3 }) {! ^" G! ?" T. H        POP         AX   / ~7 p, O. m; v
        ret   
8 @' l$ n, O) U; R* L  y9 C        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE# U. e% K# ?9 }* t
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空$ y1 `- H! N7 q
        //######################################################### 2 b; m0 V% w! N" n8 Z: M) m) x% P. [
        /*do ' R6 H8 }) ^0 |4 ?1 _% z
        {
# v1 l& a. ?* |$ R. c) E* |                GetPortVal(PMU_SC, _value, 4);
# T! x: o8 w: W4 s        }
  f* H( \. q9 W        while ( *(_value) & 0x00000001 );*/" s- O! G, ?1 \0 c5 K9 n
        DWORD   dwRegVal=0;7 P/ I- A! B! t5 q
        do
! y, S5 o: p. x, v% {. L# v        {  . l9 h3 w$ K3 d- @9 x) s
                GetPortVal(PMU_SC,&dwRegVal,1);
# ~0 X* t* |: L! q- b        }4 k* T  R& r( h# m" a) K3 G+ l
        while(dwRegVal!=0x2);
: k# N3 V- H; f  k, \1 k( j9 Q! ^3 W3 |3 G; ?* Z( t
}
1 w0 q2 N! c0 L0 L  z% p/ I7 O$ J& P! y( F7 i) x
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。, w5 p# z6 {  N3 F& p3 ~
所以变成了死循环了。
2 G+ y6 c* x$ g2 Z' s
- R4 E8 e, k  M+ N0 h; }我对硬件编程不懂。又不知道从何下手。
6 q; ^% F7 J2 |1 r5 H8 e5 c我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。% k- ?3 w; r3 G% ~+ K% |
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。2 l& ?" a+ Y1 G0 e  k6 l% m
6 ?7 r0 ^% t( p+ X7 L% _
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。; i1 G- p8 ?. t* ]
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。5 u. L1 i1 G+ h8 M# u8 ], ^1 ]

- B9 \. Q& \! R! J1 \9 J; ]感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
3 M: g5 w5 Q& p5 k1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
! t& |" \) a6 V* X6 `/ v, n2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
' q1 ~( K: c9 w/ _7 [  {3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.6 y6 D1 t& y& c) t- |$ i
! x0 }" v) d; W7 ]* W
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。) J3 K5 l$ S9 M1 a( n+ [5 y( a

" i' |4 e0 M0 ]/ P/ M8 {9 h那么有些什么可行的办法呢?
) x9 w& [: @3 k3 [为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
' C# S, ?9 p. m, K
- A3 I/ \" C5 ]! h' ^7 |它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
7 P% k) L- |7 y  @6 i8 B; `4 a0 r" ]) q& Y
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420# O! ?% ^1 ]% V8 G3 n
7 @6 e+ S3 s* x: ?0 X9 A+ ~+ |. Z
http://www.ufoit.com/bbs/viewthread.php?tid=452
' N6 d& z2 y" ?  J9 [/ e, Z' E6 ?
http://www.ufoit.com/bbs/viewthread.php?tid=241
7 q  `8 M/ h. t, Q) Q( E4 R6 o' ~- L3 y
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
0 V" }, g- F6 A. G9 L$ h% _/ |6 B  b. Y' ?
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
1 Z, g- {, q' W4 J) i* ^3 `8 H1 e2、Driver最复杂,也需要BIOS配合,推荐。
+ u/ w0 @/ f! z; T! `3、Windows API只能获取到特定信息,不需要特定的BIOS配合。" `6 j6 r1 t4 `* h3 `( P& T+ v2 ?
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
1 C) {9 f# c$ _: d) }' q( }你可以混合使用。
" U- I8 c2 p# j0 t
( R. Z' [7 A4 c. K# F7 l8 ^" L===============================================================
5 r( e- v. N6 N% ?' c, E3 C管理员的这句话:& f1 G5 a% s, h4 @% G5 u9 n( {, s
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?$ T- O) T+ ~5 {1 I; O, Y) g5 \; d5 y& I

1 R3 y2 x# t4 f5 |& |$ Y  f8 _& f予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵/ p4 Q# E/ r1 H5 G! a& c
+ G3 v- G. v) k3 m& v- q
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
# w+ K/ U/ D) W2 i' h7 {, P+ h# o
- a9 c4 I) D( n# Z这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?& e4 Y+ V) O9 S" I6 ?: N- U' x+ u0 G

3 j% E+ C/ i6 C6 _3 \. J& \还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。# v( m* Q. X7 e1 k* Q% t) B
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?- h7 x  T4 o$ u8 _
9 e( u2 |. Z3 p' W7 ~/ A
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 0 h6 D" t1 c, x
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。2 @" N) [7 ?5 l9 V3 z
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
; l# `- a- |& d3 c$ p" L8 x

/ e, J. v; _0 z6 f/ O: ~4 L' m您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
5 L- g1 x, l( u% r- m7 I5 O. i: T
5 {7 T0 c. ?2 J* w  [& X& M( ]void write66(unsigned char Data)
& H$ B" g% g* V3 i( b{
( a9 A4 H% H# v4 L" e& o        DWORD Status,TimeOut=10000000;2 P" _0 s( G2 f7 f9 V1 C  {- U7 V
        do
' `: `/ s6 Q5 K7 |0 y9 {        {, P$ P8 s% T0 O0 m# U  R
                GetPortVal(0x66,&Status,1);5 a- e: z  s, w: ?$ ~
                TimeOut --;
6 U7 u- `( G0 U" @//                Sleep(1);1 L0 u: \- s2 L4 h' ^% n" D3 K. o* }
        }while((Status & 2) ==2 && TimeOut>0);
' S" u( ]: P7 N  r5 j
8 M: P: z4 I) j9 l4 S9 h3 I        SetPortVal(0x66,(DWORD)Data,1);
' Y% U$ @9 n+ y}
+ X3 x4 i6 I% k- q, |% evoid write62(unsigned char Data)
7 P. O% ]; [$ v8 i: |3 s: N& e{
* W+ `- z; M5 p; _& I8 _1 e        DWORD Status,TimeOut=10000000;
; z  f  c' S* Y" e        do
' d/ w' s" z+ L" e        {  z6 L) g7 h# D) T$ P, P1 b$ A
                GetPortVal(0x66,&Status,1);1 }% l. d8 B% _& B
                TimeOut --;
- X  P/ ?8 w* ^2 b' D% X//                Sleep(1);
. q% W% S7 a. ^" N8 U: R! K5 y        }while((Status & 2) ==2 && TimeOut>0);: |+ m6 R9 G! m* J, ]

9 |1 I/ Y& _3 E- t; u        SetPortVal(0x62,(DWORD)Data,1);; n: g3 s6 |7 p7 s! J  F9 ^
}% Q  y* t( c' ^3 x$ }1 K4 v- f
unsigned char read62()
% t3 K' g  H! m4 r2 g% K: I{
5 S/ N6 W* K7 q' ]' t3 [        DWORD Status,Data,TimeOut=10000000;/ V' v+ i# ~# |" e1 a/ T* A/ L
        do
7 f: P% O# r( e' A1 m0 e        {
- R" S. {) \2 A# M                GetPortVal(0x66,&Status,1);+ Q" H( j: b# ]9 o+ e- P- G
                TimeOut --;
" _' D" R4 n% w( f//                Sleep(1);
  b0 [- ~1 b$ L/ i6 Q        }while((Status & 1) ==0 && TimeOut>0);7 ~5 U; `6 x! Q6 D5 a
2 K0 l3 h% |0 Q" I3 K
; v% V$ X% X; i$ {
        GetPortVal(0x62,&Data,1);7 g$ V, @2 ~% p- V5 s& g
        return (unsigned char)Data;, T) }1 [1 d) h2 }; L9 V
}
( k9 `  i0 \& Gunsigned char read_ec(unsigned char index)
0 q- ]6 V  t; E1 L{
. a( C0 Y* F* ]% b+ Z3 Y4 G        write66(0x80);% e0 D' l- m% y; s
        write62(index);
) p1 |, B6 A9 W4 ]. }1 ]( B. _& Y6 U        return read62();* c5 h: C; q& n
}' c  R5 u3 x/ y4 m
8 d& o/ h& |$ a  ~5 Q1 ?& v2 j
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1897) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。3 V8 ~) z: k0 n/ \/ D
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
" K! a2 \! C" |) U6 {$ ~, ]$ Y: l" z, s' V( v5 I' u0 U4 x
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
) h0 [* ?; `% K$ q! M/ F3 K. Q  D/ i( l* n: n6 i
" _% L+ }1 w* p7 H1 ?2 b
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

8 Z: c4 s0 F! L  C2 C% V! k' R
3 t, B- n4 F' w; h' M* r1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,1 J9 c* ^0 G" ^
5 a8 n9 v* a5 ^/ F
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
$ i2 n" Z7 j" f0 _1 m' f/ O( l8 ?0 W# \
3. Then set bit16 of the IRQ to disable it.
% M8 c7 Z$ g! F& f) Z/ U4 \% a( U/ m
8 K8 G. m0 P4 n$ t7 M) T: u    a.. Offset = IRQ# * 2 + 0x10;
' V) V4 e2 A7 s2 D2 N' I3 N2 V. z- F7 W/ g" E
    b. Write Offset to APIC base,  W7 p- X, z- K. K/ |+ v/ ~+ k

; q9 W% |7 ]& j+ e: k    c. Read Data from APIC base + 0x10;
6 Z: h$ S* I: H2 i  X% D& U0 Z3 Q, }6 _
    d. Or bit16 to Data;# B2 s" G5 V5 ~* u, t
$ T  h1 D) s1 C
    e. Write Data back to APIC base + 0x10;. ~, Z5 X2 h9 G

0 x. O/ x7 d9 l0 m: |8 | 7 Y# V  \+ u% d

" `% I1 @: ^4 p: K3 w( a9 WYou need to check APIC spec for details.
回复

使用道具 举报

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

5 f+ _# @$ h5 R5 f- s* h# k, Q8 p! _% N  S% v/ \" i! v
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。# U* z  b0 C5 G1 V
==============================================# A- `& Y- m5 B( n; q
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
! k7 D% q9 e$ n# X" T! N+ \7 K  X
' w" Y& P7 d2 f# i因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
/ \( S  }: }$ p5 z6 U但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
) `/ b3 l- C- Q+ n9 L$ B) \3 L( ^4 t4 \2 e6 b* l
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
: A; y5 O: T* f/ l. M当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:. K0 W4 e7 F: J) g! J
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
& D# V2 s0 Q: @3 y) P7 y7 U7 k2、新手不要把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-9-22 15:13 , Processed in 0.122368 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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