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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
. G& i" X& e# J" q: G#include <Windows.h>$ u- H  D) p- o7 e; j5 b% n5 D
#include "WinIo.h"
! }! Z1 p+ Q- i+ R9 I1 F1 H3 Kusing namespace std;9 {1 \9 J5 T: R5 t

. n4 a. \! G7 t6 o#pragma comment(lib, "winio.lib"). U( G. ]& w8 X. ~& R

( j' i% n/ @7 l0 f; k7 C2 R+ u
  x8 o. H1 m2 s* Rint PMU_SC                =        0x6C;//命令端口( v4 ^! {3 i! K4 l
int PMU_DATA                =        0x68;//数据端口
" k, q& R( u9 A: V* iint RD_EC_SMI                =        0x80;//读寄存器命令
4 t# f' A* ^% o9 r1 w0 U0 n7 O3 {- Wint POLLING_DATA                =        0xE7;//CPU温度寄存器号
; k) w4 y% `* w. e' h0 Y" F" P, R7 S8 O& Y9 h
DWORD dwTemp = 0;
  c! C; A# b; E+ [% c$ T* `
) P) `# }; K: ~' A+ s$ ^void PMU_Wait4IBE(DWORD *_value);
; Y- ^0 V7 v7 D2 Fvoid PMU_Wait4OBF(DWORD *_value);; x5 Z/ K. j0 t5 O
: u; }1 c* h( `; k) I# g! d4 r; ~; n

8 @1 M& i3 A' R0 U4 b* qint main(int argc, char* argv[])8 X+ T0 J. L  h2 }
{" R  S$ T6 l; @
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;) @) n3 D* E- J

0 k. j4 |7 `0 ]) `# B7 b) t        : l, o1 }9 g2 W% R% b
        //1、mov            dx,PMU_SC                //: w  u0 a+ {+ q: U  l
        //2、mov            al,RD_EC_SMI        //- E" a& K2 h+ `  w8 F
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了, _/ l9 H* p5 W/ J0 S& r
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
) f$ w4 \: e9 X
  ~' m: Q% [' C4 J0 f1 o7 ?        PMU_Wait4IBE(&dwTemp);1 \* C1 t' F8 a: ~' w
       
- S3 R! Y$ v  U. n3 d5 [7 I        SetPortVal(PMU_SC, RD_EC_SMI, 1);! m' ^, a  u& t) |9 S4 d% q
" H1 ?# s! {7 ?, Z; H
        PMU_Wait4IBE(&dwTemp);  A5 N# }7 E0 G1 s+ I& {9 l8 O6 _
        7 J4 @  f# ?0 d, r) ]
        SetPortVal(PMU_DATA, POLLING_DATA, 1);2 p5 r! p, V, Z9 R& o7 s

, C% J6 y3 y& {        PMU_Wait4IBE(&dwTemp);
  Y! R0 S9 k8 j1 C, ?7 x: P, G  B% i; Z; b/ N/ `
        cout << dwTemp << endl;               
6 y; n+ d- o8 i9 {* P, U+ {( {: M9 O) E9 j+ q
        ShutdownWinIo();! i1 a; R) o6 L' `

8 D$ x/ p  v# @2 z  \& b        system("pause");
& R2 O+ c$ Z6 P  E3 _* ^( k! d/ _, T0 K
        return 0;
9 G: T  c& f6 |9 \* N! H}
7 D7 J) i# L3 ?9 V0 s# F" Y% Z# f* s
void PMU_Wait4IBE(DWORD *_value)
( ?" }) _0 `: G" z  T. ~3 Z{
, f( R- v" o3 \        //#########################################################   
; x0 h' x# w5 k8 S; D0 p7 {0 @/ V        /*
6 L9 y; [+ U& u2 H( s        pmuWait4IBE proc   - _: s' }$ |# c/ f) k$ r) i- j
        PUSH        AX   
7 }& ]7 ?- s! B        PW4IBE:               
, ~$ ?- o$ H/ E$ C, b/ @* I$ t        IN          AL,  06CH                                //Read  PMU  status   
: N2 q; ^* W& C% }        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
% `* ]6 L7 {; T4 E) _3 ^$ ?        JNZ         PW4IBE                                        //Jmp  if  no   7 h5 K- F" v0 X
        POP         AX   
5 K7 e% N. v  X5 C* U% [% Y        ret   5 S% O  W1 t4 ?( {7 c+ Q
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE* R& F4 x1 }, E  k
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空: Y4 A' ?8 K+ U' ^) U
        //######################################################### # U; c$ }0 Z- ?8 z
        /*do 6 N  s4 K+ A7 y- N* q9 A
        {
5 j8 \$ }% C9 v: R7 Q                GetPortVal(PMU_SC, _value, 4);
# {1 U  @, [; F% x8 r$ A4 F        }. z. C8 C/ d9 R) a: A$ z% ~6 z
        while ( *(_value) & 0x00000001 );*/
' M, z, A+ ]! V. l        DWORD   dwRegVal=0;" R3 x6 Z2 t; _% L& P3 \
        do
5 F3 A$ b9 {: M) R* P& c) Z        {  1 x' ], R$ a0 o3 I
                GetPortVal(PMU_SC,&dwRegVal,1);  j# A/ |' N8 X% Z% J8 q8 ~0 m: W2 D$ ^
        }
. {( v8 x; ?, Z8 L8 |        while(dwRegVal!=0x2);7 ^6 X7 J  j( E0 z- ~
- z# `4 E0 o0 K  Z0 ^+ G9 V
}, U" z+ h% r: N

" f- d* u4 @5 i4 X/ B: M  b. t$ c以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
- U) L! b0 Q4 q- j. y所以变成了死循环了。
$ y2 O9 ]0 O; [' m
1 v1 U: w3 H6 a我对硬件编程不懂。又不知道从何下手。
% T) k9 y, T. ], {% I我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。6 m6 v/ F: \: [. E6 ]: {
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
& ]8 L, ?6 J! `8 o' i8 l6 @( k" f0 Z9 c
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
" o, x& m6 y! F8 t, c2 M2 E并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。, X+ }5 h# P4 F0 }3 _2 ~. F

3 [6 X4 T3 z* W2 p5 a% n感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。' w/ x6 Z) |* K6 V  f% E) b
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
8 [  g3 c' q4 N4 r2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突! P0 ~, F$ o( g" a- i/ R4 w7 X
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
) }' B) h% ?6 x) y+ |- a) F* F0 F& w' G7 A. Q- W
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。$ I4 o3 ?4 Z) T7 s. k* N

! t# _" y7 G1 ~& \7 S, G那么有些什么可行的办法呢?
, Z4 B1 H- T/ Q. G为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。+ u; x6 }4 i, I  g( U; q3 @
9 E. [% j! J5 a$ \) K
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?1 K: J8 [& Y1 I) j1 z- y8 T/ B+ w

. |( \; {3 C: T6 R那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
: B7 b& d5 v$ s. ?% G0 \! G9 \/ ?' |( [* J
http://www.ufoit.com/bbs/viewthread.php?tid=452" z9 a/ C: _3 V; E8 d; z/ e

* I& ^. f9 V8 C& W8 Q3 hhttp://www.ufoit.com/bbs/viewthread.php?tid=2417 P7 `# I7 T/ ^& z6 _! @

6 s2 ]3 C& S  t/ \5 z看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
0 |( e  z' D! a, J6 @+ o
8 e4 b- Q+ s  }* }! O1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
% f3 ?) ~7 C, K" |) F2、Driver最复杂,也需要BIOS配合,推荐。8 U& \8 a! M9 E% C
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。: {& D, V$ v0 F; @: c" k, E- K
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
6 M' i5 Z# V; A" M7 |6 m你可以混合使用。% E1 l3 H! A2 c9 U
; b- O1 Y1 O: v- N6 \* n
===============================================================
) x- f6 }0 o: C0 L( c1 F管理员的这句话:: l( O* f+ o% P( U5 F$ p# ~, V; Q) A
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
- F9 V% m4 B. W' a, I, s
# n8 D: o9 l4 n5 M1 T予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵* M. e- B% Z: f. \

8 ~& O, v: r+ C0 U& ?( Q! Y8 V; }5 k另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
. \5 j" l! p. T% p8 A+ I$ U9 M$ s: o: }" L" X) }
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
' K' b- q, \8 F. b' }. D$ ?
  q, j- \: e" T8 y- x还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。# h! z( E0 q* Q5 P& P( x
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?: Y3 O& n0 A) `4 C4 F3 N

% |; G2 }' x3 p( p# ~我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
! l! h" ^& a( |/ @你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
/ ~) m8 ^3 X3 ^3 |1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

$ F3 s# D8 l- V+ `# `9 ~
' I+ N, F2 c) ^+ Y% r3 y3 l1 K1 a您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
& l" o" n& H' `& q  c6 A: }6 V9 R$ V& z1 v9 X7 l& b8 f
void write66(unsigned char Data)
; ?: Z4 I2 F  ?2 }{
1 q  o$ a0 L  T3 u1 }$ r        DWORD Status,TimeOut=10000000;. i/ P8 u/ @! R
        do2 W6 G. }7 d+ o9 O
        {, P% N) c9 p3 C! {
                GetPortVal(0x66,&Status,1);
& ~( Q& V. U+ S/ z                TimeOut --;
  Z+ Y; Z3 Z! v# s1 R//                Sleep(1);
7 G; a* G2 [5 n5 S% q& P/ Y+ a        }while((Status & 2) ==2 && TimeOut>0);6 b% m0 f" W/ ]. [; z

0 l- u2 B+ @. F! A        SetPortVal(0x66,(DWORD)Data,1);4 `5 v2 K  v1 B1 Q- r# H& b7 }
}4 T+ l* x! g& E
void write62(unsigned char Data)/ a! k: e. o6 k2 g9 d* t9 E2 [1 a
{
4 O6 f& o1 G9 Z+ h        DWORD Status,TimeOut=10000000;3 a4 q3 v+ h+ y- g, ^# I7 p3 {
        do, F, n6 O7 j8 h0 N9 E
        {
- p! k# F! \) C5 Y8 \8 d0 w9 s; w; Z( B# u                GetPortVal(0x66,&Status,1);! M; d% t8 @' h# m
                TimeOut --;! U3 m& Y0 s: O2 G
//                Sleep(1);
* J% B9 Q' w: F" g: N4 C        }while((Status & 2) ==2 && TimeOut>0);
  t( j# }" D) k5 V* M+ W  J4 U: x+ i. G4 @9 B+ c
        SetPortVal(0x62,(DWORD)Data,1);
( E2 H* ^" u) h; ?. R$ c}
/ V3 H. L* P0 V8 Runsigned char read62()& |  o/ w& T! c
{
; b* o, d' R, h7 E# q        DWORD Status,Data,TimeOut=10000000;
& N4 F3 n7 d3 q4 v; ^7 f# p" x        do) C8 X* d* V6 y5 M
        {
8 S5 Q" D! r4 {- B! a                GetPortVal(0x66,&Status,1);: J) S. P% F' O# B$ O" V
                TimeOut --;7 T+ z& D. K) o, d+ P! A2 F8 _. J
//                Sleep(1);8 G8 M: ?$ i' G5 G: {
        }while((Status & 1) ==0 && TimeOut>0);
) b' b/ f2 ?6 X( W4 J+ H+ [7 j
' N" K; ~1 \: Z- j5 e; P& {5 T! O/ g9 y; [/ `
        GetPortVal(0x62,&Data,1);
$ u, E  B# o% m4 u        return (unsigned char)Data;' U# x( A+ Y2 K5 K' Q( v$ o% E1 h
}. A3 g& ^6 O4 B& v
unsigned char read_ec(unsigned char index)
/ w8 [4 z: j2 Q& j{5 O: L3 S3 r; |  {- \8 Q; n" C, D
        write66(0x80);1 q3 X. t$ y5 M8 p8 R  ~; T
        write62(index);
& `, E0 k. {5 [        return read62();
1 j# G/ N/ X- D0 t}4 G! e% U* ~7 h( b, a% }+ ]2 G

2 ^- p* r% z2 I( b[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 729) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
) ]% q, I: H  l+ S  ?  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。6 n4 j! ~1 I" u8 `% ^1 d" ?$ Q
; B( V% `% b6 g3 w6 y; N. f& L
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 . A5 Z4 R( D7 |. C
' L1 z. r* N7 C0 R+ w

8 W9 L# W; m  Q- B9 w您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
/ y! H( t; b" d. J# O
' B  H! B+ z. v
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,. [$ t2 o& `2 ^; z4 S& `
- C- r* P) Q5 P$ Z5 j( l
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
9 `& |. J/ f& O: t) ?4 S
% Y) J* t. H7 G7 }& @; L3. Then set bit16 of the IRQ to disable it.2 E5 k0 K. e" J

* Q+ p9 T% m- u6 D    a.. Offset = IRQ# * 2 + 0x10;9 }8 o) B0 u. T
$ m9 w8 @$ e2 r
    b. Write Offset to APIC base,9 q# E7 }% J8 B+ P$ l

& B3 o% P7 B4 G+ R: U    c. Read Data from APIC base + 0x10;! T( P7 B! j: B* I

  L! T" u: O; q7 F2 c7 W    d. Or bit16 to Data;
6 V1 {8 {: v# q$ o$ [9 }
. i& M  G$ l8 ~! b6 y! X    e. Write Data back to APIC base + 0x10;, o, z2 a7 l  ^5 d7 N- {$ d9 f
3 x3 q2 b1 u) v1 S
$ y, T) b: d, d5 W0 ]; i- b* K% X

* a; w; I6 M  E, S4 c, }You need to check APIC spec for details.
回复

使用道具 举报

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

5 x8 W2 L& v  a
- k* ]" _( [8 Z8 L" V8 S 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。' e2 f6 O' @" z* J4 k; D
==============================================
" z3 w4 _; D7 f: M9 s$ n+ l 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
# `. t- h( a9 B* @/ z3 j, p, S( h+ m2 Y
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)+ b; y( H$ g) Q' ?
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。1 \+ c1 v/ g! A! ?

& G2 `2 i4 g/ }' a; O5 ?因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
7 [0 h0 n7 X' o1 O" }* z当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
0 v( V- n( x" ^! V: G) ^1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
4 k5 p  O9 i4 z+ R) V) t2、新手不要把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, 2024-12-24 01:23 , Processed in 0.038648 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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