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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
; |2 s/ y9 N" D/ Y2 }#include <Windows.h>
0 `+ ^3 k. r# S1 V( _0 W#include "WinIo.h"- }) h- k1 }% N  G1 s
using namespace std;
: T  m/ N$ g" W# R  h3 C5 @# p5 H+ o4 M, x% l( {
#pragma comment(lib, "winio.lib"): V# V3 W* N  B: |2 Y: o

0 Y+ F' ]/ T! A$ K# k' {7 X/ o$ f+ q. B; I
int PMU_SC                =        0x6C;//命令端口/ m: f% f2 A: [2 [
int PMU_DATA                =        0x68;//数据端口! e2 j4 ^! u7 f' T, m/ Z/ U6 R
int RD_EC_SMI                =        0x80;//读寄存器命令9 r. {# j7 C- f: c) `, K. p! R
int POLLING_DATA                =        0xE7;//CPU温度寄存器号" O- q: |& u5 L! `, U
, ^) E+ g, V* A5 c. {) V7 J
DWORD dwTemp = 0;
" j! n' D" ^% Y9 v9 K% v7 I# H( e2 }
void PMU_Wait4IBE(DWORD *_value);
$ z! ?5 ?" l! d9 b$ i; L; }- [0 ?5 |void PMU_Wait4OBF(DWORD *_value);$ o7 c2 k! a" l

+ O5 `2 z4 H. O( }) ^5 p2 T; [) Z% p6 i
6 l& m" p# y# S) y' Yint main(int argc, char* argv[]); f4 t2 W5 c: H: D& [% N( x
{
% i5 B2 K6 h; h& J; h1 A        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;9 Q0 g" L0 d7 x2 q; V# p9 V( N9 s

' H+ z( V" L" |& x  [        , p5 f1 [! s% C  m+ |5 Z( y3 x
        //1、mov            dx,PMU_SC                //
' y: i3 B7 C; _2 l( l. f* ?8 b        //2、mov            al,RD_EC_SMI        /// g5 _; T5 H' v
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了+ X9 U* W# j# n% b4 ?
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。# n  L/ H' s9 R- U: R! W

; W) O6 s4 R4 O% W' O7 v        PMU_Wait4IBE(&dwTemp);3 ~: Z# I$ k5 w6 Q% w, ?. _, z( q
       
- S0 r$ I. c& V, d: b8 v2 j( n        SetPortVal(PMU_SC, RD_EC_SMI, 1);
& p) H" o8 K% q! h- y" c7 N" G
# K, b; v' P# y2 ~# B) ~* q        PMU_Wait4IBE(&dwTemp);, P- q7 b7 `$ p2 \" Z$ A
        ( t2 Y; `1 O( n! P5 x/ h  v
        SetPortVal(PMU_DATA, POLLING_DATA, 1);0 U7 j# v9 g5 F& b" \# w7 e

3 s+ L- b% p4 k' q: ^        PMU_Wait4IBE(&dwTemp);
, q& M% V3 V5 @5 {" f% U) e
: g3 d4 v8 w/ Z5 t* @0 n        cout << dwTemp << endl;               
. Y: N9 P, ^4 F6 @" @& ~! Z1 [2 z9 I+ p1 \& W* t* c+ P3 ^) u9 |: n
        ShutdownWinIo();
2 P4 L1 U+ C8 F7 D5 E# N, i8 Z2 D" {! Z! W9 M9 k& C
        system("pause");: V1 N1 ?0 B; R" v. Z3 T5 |

, z2 y' ~# U0 k        return 0;; c' H  M8 Z  d9 l- S! c6 L
}
" k" j" w! S" k. u4 r) a" h2 r# H
void PMU_Wait4IBE(DWORD *_value)
# J& ]' b. G( g# H1 |{
' T& `6 D) w- P        //#########################################################   ) W5 _- f+ A- p% X1 U9 D4 A
        /*
! [3 S7 F2 R8 h$ r        pmuWait4IBE proc   
% F9 P  ?# s+ J' g) S6 J        PUSH        AX   5 r0 d: L2 Z; k. d* y
        PW4IBE:               
9 I" @5 n) e+ g  l8 u, Y        IN          AL,  06CH                                //Read  PMU  status   9 E' c* s1 ^- A" ]
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
. H+ m/ Q, x3 V: R% ]        JNZ         PW4IBE                                        //Jmp  if  no   9 @: z0 M# p% Q9 x
        POP         AX   
0 F& J4 q1 `6 k+ ^* @8 E, k        ret   
" b+ v' v& [% J4 z% v        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE  a0 x8 c" y# f9 D* d* ^( j
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空6 ^  J9 F; t$ r- ]& z/ S
        //#########################################################
5 u7 k2 H- W, E# F  P" w; x        /*do
" W0 o" q/ I8 G4 k8 s% |        {
& W" w8 z% {: |- X; z- k; M& H                GetPortVal(PMU_SC, _value, 4);1 ]/ {3 R( f$ x, J! m' k8 g
        }
9 J/ s: i3 @+ o9 t        while ( *(_value) & 0x00000001 );*/6 k8 G1 c7 u, Q: `
        DWORD   dwRegVal=0;3 p: Z3 b, y8 g/ |7 n  u2 S
        do
8 C1 s* T4 H& c' q; N6 N, V  _$ L        {  
( C2 Y+ Q/ d8 F3 b+ ?                GetPortVal(PMU_SC,&dwRegVal,1);( D" c& n+ \7 o6 B0 i4 D
        }' N2 U+ K% F) E+ u1 S% E
        while(dwRegVal!=0x2);9 t* d4 f/ [# ~; O9 l6 t2 a

- a" w, w3 E- k6 o! `+ i- z, ~& X}3 e( H0 Z" c- K9 y$ r3 ^. ^
3 G# f4 u& E* c, n. y1 F
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。6 {* P: _6 I- j8 ~
所以变成了死循环了。4 G' H( ^' z& G' O+ e) g
7 r* q+ F- A0 Z4 |- N
我对硬件编程不懂。又不知道从何下手。
& L( ]) G4 r* U5 {' R我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。1 n. o$ x7 H) `( w8 I  I
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
2 m9 c3 p5 m* I
6 B9 M$ f: X4 l* l% z" A9 Q6 \6 `我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。+ Z4 h% Z& j! _. j& T+ S. f& `/ M# G
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
) m  E3 |  L. ~% S3 [1 z
! ~$ a) R. F3 O2 R; l# n4 k% ~感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。, a/ @" O& U& e
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
% I# x- B' [2 }2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
  Y( w' w. @* R8 _! h& |. {* O3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.) m8 G4 V4 q" Y6 g( v1 M& S

  h& a( m$ N4 v所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
/ J5 X  P! e; I* H9 Q& o8 \8 G7 w) |
那么有些什么可行的办法呢?5 q1 z, d# w$ V% n
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。% t$ e8 k, F% z' A; v! ~; X

0 ~  m- G0 {6 v" {7 v它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
5 t3 u1 J, F# Y
+ J9 _- `1 K9 w1 S* m那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
/ X2 }8 z+ o  ]$ |, i: O
6 F5 S& J7 j; r' Q! Xhttp://www.ufoit.com/bbs/viewthread.php?tid=452
4 u9 K/ _' T" q" H# r1 P: T) H- c
2 J% J; V4 w! ]http://www.ufoit.com/bbs/viewthread.php?tid=241
* Z+ B/ k6 h3 Y
$ E4 W# r1 l# k* R$ J看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。+ b1 E- S% R' l6 O, w" A
6 V3 r7 u8 ~: l, l: H1 y7 H! p+ R
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
3 R* c8 e* x* i  q2、Driver最复杂,也需要BIOS配合,推荐。
: i$ N! t& J+ W% A# X% t/ n5 l% f3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
3 i' p1 r7 }* x4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。. c' I- w: Z; K3 x& S8 k
你可以混合使用。
) {8 u  q0 h7 x) w  Y4 ?& ^
9 l6 T0 a. `* B) S===============================================================
* D6 }$ K& ~4 }& M管理员的这句话:* {' O! c8 D' e( C8 ^8 T' j
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
- q  I6 d; H- b7 ?. R+ c 6 W9 g3 {0 k4 u- d2 x% N
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
7 T$ D# K( ?# {* R& p- O) j: y2 b1 J+ |; c, U% g! q$ R. B9 G# d) k
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
) j( T+ c) J7 K4 ^
3 ^/ S6 A' z3 l7 M. W/ y$ X) ~7 a; @6 D这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?" H: y. s0 _3 g7 o  N$ Z9 Q

( t8 [. p! n- o. D# `还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
# l) {( K8 A! K里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
7 J( m0 ?7 S, k+ G& Y/ B, u- n9 a, s2 @, X9 H
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
$ Y& Q% `  O. n& ]9 I1 ^' `) G. {9 ?, e你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
& S3 ?( {; W; U9 m- Q" d( _1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
. H8 R  d& h/ e- K; M

6 B2 Q/ A% E- m, p6 C% q, n您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。! F# A% b7 V6 I$ J5 f  f

! N, T2 z% {+ d+ ?* Avoid write66(unsigned char Data)
( ?1 p, L/ g, {, ]2 [{
( X* z, ?5 E" q! Y1 \        DWORD Status,TimeOut=10000000;
. E9 o* Y3 L) v  b9 e        do
( T3 g: U/ P4 h% C        {
3 e0 p3 s* k  m" S, D1 n% s                GetPortVal(0x66,&Status,1);% y. `2 ]: t* ~; f  S
                TimeOut --;
: m- W4 h8 ]  W9 P2 n9 `( d//                Sleep(1);* F7 L9 f$ S' ^) y7 O
        }while((Status & 2) ==2 && TimeOut>0);
1 j7 P1 W2 ^+ G2 _' x, e
2 d6 g; N" _/ t4 }% p, k! Q- A- _        SetPortVal(0x66,(DWORD)Data,1);, _' `" B; y0 z, n
}
% d( A7 O7 x5 E3 Z9 e$ Rvoid write62(unsigned char Data)1 j) ~( P: {5 [
{  s' I+ {6 C( U/ R3 E* z) o' ]/ v/ G" P
        DWORD Status,TimeOut=10000000;
; z% v7 o6 a/ {- c$ @        do: G0 w# q% f: h0 j3 _* Q
        {
$ |& t6 n' R& w8 T* s5 t                GetPortVal(0x66,&Status,1);( o0 r2 B$ }, n, C6 L
                TimeOut --;* s, |( ?9 b/ P/ l
//                Sleep(1);
* @+ H; x$ P: ]; K) p        }while((Status & 2) ==2 && TimeOut>0);$ E: G1 s) f0 v1 I& l, f, P3 m
8 \7 H+ L9 T, m, N
        SetPortVal(0x62,(DWORD)Data,1);3 F+ X* _  g" f
}& x0 }" d0 }) _' R- K6 }2 d% F8 e
unsigned char read62()  }/ {' o6 u( o# _! U
{6 z3 F( g2 H8 E$ m7 {
        DWORD Status,Data,TimeOut=10000000;
0 E/ Q1 W7 J, Y# Z+ W        do/ b! C6 @8 M' H+ v  g+ H% d
        {
+ @! w) X) ~( }- c. g  s: N                GetPortVal(0x66,&Status,1);
0 }4 {" K. g7 d, w+ D; ]$ C0 x                TimeOut --;
9 i9 |5 q! j$ l  C/ |5 v* i9 ?//                Sleep(1);* y( j6 U& X/ e5 H9 W2 j: _
        }while((Status & 1) ==0 && TimeOut>0);! L3 k4 P+ }2 V
1 ]) E8 k/ L8 A
5 z1 @# O" W  C" W8 [: X! r
        GetPortVal(0x62,&Data,1);. ]7 O. I7 H2 S2 y8 x' h6 m9 w
        return (unsigned char)Data;2 k; n2 r  ?$ T  l9 f6 H+ k
}
$ I5 A! Z) Q, |& b% m* N. Cunsigned char read_ec(unsigned char index); I" `( ?4 X) c% ~, [* U
{
  Q, |1 n, `% u9 S( u' V& e        write66(0x80);- S3 n+ }. d' J4 i# P
        write62(index);1 U( }( ?; u' g7 K+ g  j+ m& \8 g
        return read62();
( P3 i' [% o3 g}1 V0 j5 t( n1 V1 m' B( V
  l% t  E) T. V8 a9 \7 i
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 7 v* i6 b2 M9 q7 `* e0 H
6 n/ r. O$ p# I( M2 j( N% ?
2 f8 g: c+ {* Q, P& ]' q* V
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
6 h: l$ x0 ~/ E/ T. p* w
3 z9 n& X4 v% i" A/ z0 x
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,, ]8 L& Q  z4 r, r" a) R5 {- ^
/ l$ q6 T& W' f8 [) p# t/ S+ E% d
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.1 B7 y% G7 U+ f: L7 E; d5 O
- z) s! a# R9 G  k6 Y3 S) ^
3. Then set bit16 of the IRQ to disable it.
3 M% r8 N: L* l9 S3 h9 \2 N, Z- J* f4 W
    a.. Offset = IRQ# * 2 + 0x10;# C. q3 D0 l8 L7 S8 G5 V
6 @- y/ \) R, J8 {6 X$ K0 ~! x# H
    b. Write Offset to APIC base,
! n; Q1 Z4 Q2 h8 L- N1 T6 t3 M9 z' o
    c. Read Data from APIC base + 0x10;2 j, H2 F: F9 y

3 Y. H( |9 S' `    d. Or bit16 to Data;/ c+ p! @/ m& w5 f' L
7 [/ q' u* f" m! Z. a
    e. Write Data back to APIC base + 0x10;5 C6 _, o* M' A5 v0 l1 z
+ [9 z0 [( \6 N6 V1 S

* |0 m' S2 G) B! U
6 ?% }' \& F% D% Y( s4 c% eYou need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 & C3 z: b& Q+ q8 A! \# R0 W
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
* H0 }4 b) s; k: M& N2 Y

1 `' i* d4 }3 y: b& l1 V& K 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。6 |: m: a+ u7 l" Z# T
==============================================4 K3 Q5 ~/ s. y' O1 A7 Q  t8 M9 H
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
: p& ^- }1 y9 R0 R8 m& p$ |+ d
- E9 a4 {" y( R$ l因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
  L) @6 y0 E- X但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。6 f# E1 G$ U# h2 v
5 W3 Y) K% j: p+ e8 X7 Q
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。8 \1 A; }3 o1 y; D3 U$ j0 b
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
* I( }4 X$ A% V) U0 i6 Q# e5 \1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。3 s/ O7 B4 K- h0 r) o* L9 l0 ?0 T
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, 2024-11-24 04:06 , Processed in 0.067542 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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