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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
4 |( u4 B* L2 G7 N#include <Windows.h>, b8 {* ~$ Y4 o  D/ R
#include "WinIo.h"8 c4 b7 R9 f: {/ u
using namespace std;) k3 z/ r5 `# |, u

! H, ]; d5 R; K5 @5 R#pragma comment(lib, "winio.lib")$ m, G1 ?9 t- n# n# F4 V( z

8 F% a' F6 @! f9 f7 }# k1 N" f' ~
int PMU_SC                =        0x6C;//命令端口* r# m+ V. v$ `" U2 z* x% M
int PMU_DATA                =        0x68;//数据端口
% l. S. m; g* |int RD_EC_SMI                =        0x80;//读寄存器命令
# C0 x- |' K# U, ?' rint POLLING_DATA                =        0xE7;//CPU温度寄存器号
" x" p- d; F, R7 Q) E( }* ~9 }6 L$ Q4 I0 [# U0 k
DWORD dwTemp = 0;
" \  c8 Y3 @0 }2 @- y
! k+ N8 T. Q* K; S6 r! a# ovoid PMU_Wait4IBE(DWORD *_value);
9 ?: U6 @3 Y* i! c( {2 avoid PMU_Wait4OBF(DWORD *_value);2 X$ W0 d) X) P2 u1 x# L
% q. {. ?" s: R# f+ r

# P9 D7 f" V' F: O/ O4 S  gint main(int argc, char* argv[])8 b6 Z/ c$ w! f/ o2 O: b
{. o# n$ }& L0 J% s
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;' f% e; t2 o2 m' U* w6 M
) I) ?+ M. h' R" m8 {, C7 P  [. {
       
$ t9 L% M7 r2 d. ]; N        //1、mov            dx,PMU_SC                //
* |, {, k4 P$ S        //2、mov            al,RD_EC_SMI        //
6 K7 t; s# I: q        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了. F2 |7 x7 E2 |& ?) d" H
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
/ E% v" ]: ]) ?1 r' Q( X9 j9 t0 c& _6 y
        PMU_Wait4IBE(&dwTemp);+ K# i' H, j7 c& T8 p
       
( L+ `! k* N7 b5 ~1 k4 i2 s        SetPortVal(PMU_SC, RD_EC_SMI, 1);- U7 {! o; i7 y( y6 Q! V6 g- _! E

# w0 h1 n% {* o        PMU_Wait4IBE(&dwTemp);/ o( C+ f/ _0 ]2 Y
        + t8 c: b, b+ ^. X/ a
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
* ]+ K" e" X! X& [" e% D. v
$ d6 I% Y  K* y0 u6 O# @' I        PMU_Wait4IBE(&dwTemp);
* W, ?2 f2 h( ~7 @) \  w0 a% t) p( S& r* M: w5 V( x/ }$ F6 @8 J. t
        cout << dwTemp << endl;                7 f4 O8 n# M- H# [

$ T# l& w( P* u; U1 s        ShutdownWinIo();7 V2 X/ u( i5 k0 S0 H4 J3 ~
* m6 l  I6 Y! I
        system("pause");
# ?7 C5 x2 L# ~5 D9 o- p  C) e* x+ L; ]
        return 0;
5 t1 W. M; X$ e; g( z! R}
. P) a8 x/ I) V1 C
! v. m  q# A9 r1 o$ r) \2 w' |void PMU_Wait4IBE(DWORD *_value); e$ ]" j: u) M" J) o: q
{
/ @, T3 k8 P5 |2 k/ h        //#########################################################   5 e( z! b/ j& R, B7 G: a4 ]
        /*" u, w1 s9 k1 e2 X
        pmuWait4IBE proc     l  K# M. E  `) U- M: a. U
        PUSH        AX   - S; S$ m5 C4 E7 C8 C/ z( r
        PW4IBE:               
( ]* I( W; E$ E" m) F& P        IN          AL,  06CH                                //Read  PMU  status   
0 K2 [0 I- R" _9 U# |, P1 Z" }        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
) Y! ^" A# a5 R7 J4 r3 n! s        JNZ         PW4IBE                                        //Jmp  if  no   ( q% W0 p5 G* W
        POP         AX   % q4 T$ s$ P6 s7 B: P
        ret   
  L6 W' f' E: w" D        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE6 r# g- r) s: V% t+ I/ J4 ^/ |
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空) f" j7 f. H6 P
        //#########################################################
: l8 f3 o) T7 x" u  D( Q# _        /*do
. ~3 l0 Q: }0 B+ H: F. n+ N8 J" q        {
3 ]- e/ U/ C* ]. L                GetPortVal(PMU_SC, _value, 4);
  b4 W7 G" _! |% k9 ^: E6 I2 Y        }
1 _, c5 Q) O! G$ V        while ( *(_value) & 0x00000001 );*/* |1 C; Y2 ]- B' [; h: S+ l
        DWORD   dwRegVal=0;' _- w. n$ B, q6 r
        do4 q0 i% P% n! e
        {  
- m! l6 ]# h- T                GetPortVal(PMU_SC,&dwRegVal,1);9 T# E( a2 `' e4 }
        }
- ~" d) ~6 a% ^6 f6 l        while(dwRegVal!=0x2);! Y# U2 ]0 v$ X& `# u* M+ w
# k7 \+ k/ f5 N, b2 J+ P
}5 R- U- p/ B" G4 {

: |1 h) n! V# N! Q" G' r* f以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
8 L$ a. E* l5 x  \所以变成了死循环了。' A- O) B7 U. y' p$ X" f

6 e# R+ w; s' _我对硬件编程不懂。又不知道从何下手。
( C( o/ f; q% @' n* G- H9 Z$ I我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。& C! u  j; d) }( {
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。# Q. c3 k7 ?- E& D' k$ V
1 Q2 T4 _  l' \8 I
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。' e& \* \2 E6 |5 `4 o; L3 y
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。7 n; r) v% U* E8 P/ a! D5 p+ y

  p. t7 ^" k1 s. G感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。, o8 m% `" h; [, h& K5 q
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.3 H8 l& b7 i( t: b4 S. I1 H
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突4 _1 r) k* ^4 q$ h( s8 L
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
# i  U7 K/ ~2 b( e, M+ N' I4 B1 |7 P4 e3 j% E. c, H( \) K+ N) Q  q
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。. P1 L0 D9 u- R1 l* n& l

, r9 L% D% _) p* G那么有些什么可行的办法呢?
6 U; Z0 v2 l$ m$ D为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
- ^/ X+ B+ E. s7 {! c8 y! M0 P& k1 o
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
" Q% g' m+ u0 i, Q5 d! G: u/ |1 G3 D: E- ^8 P- j1 F/ p
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=4200 _; d8 G9 y$ g

4 ^; ^. n  a/ Ihttp://www.ufoit.com/bbs/viewthread.php?tid=452
0 O+ p) _5 J3 t% |. v, E& Y! W0 W0 \) A$ K2 N' i! A" q
http://www.ufoit.com/bbs/viewthread.php?tid=2412 P  I1 z" G! V+ S  y

% K% q2 n# r- a9 d* m3 e6 Q: V. R/ Z看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
# W$ K1 w& n/ H8 r3 C9 p
7 I; O- U7 f% T$ `' V1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
; I6 D* E% e( @) C0 G# n2、Driver最复杂,也需要BIOS配合,推荐。, q4 r8 O  W5 T* G8 `
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。7 O1 m+ w9 X# L* E; _% }: S" m' _
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
; ~  m) A- k+ l" \你可以混合使用。: C7 P1 o1 n! C; i2 @& L4 m( ^0 v

& ~3 f/ w* }3 c; X===============================================================8 K- j% O2 D' V; e
管理员的这句话:3 Y. c# \1 \2 L6 u  e4 O
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
9 v: W9 P. F2 v3 I
  f: W7 N/ Y( X. X  |9 z予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
0 ~0 v: q% |& [: z" p0 E8 i# j
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=2695 D$ T, O4 }5 h

1 M9 P: W$ ~+ N0 s2 t% _0 \% b这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
5 t1 B, C8 P/ b+ o
, u# S8 J+ E! w. B) @还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
& W6 R1 A3 s0 }8 \; T8 N. o' I- u里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?9 Q% L; \1 U# p/ n  [+ @) y

$ e) J; g* ?# D( U1 Y我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
4 a8 I2 V7 H/ h7 q) g: Y你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。# l3 H, p, T; Z% p
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
: R; F7 H# v- I/ X7 b  x

- S0 ]0 `; l" c$ p% G+ h您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。( b4 x1 U! w6 @' h" N) K

, V# U- f/ A. D- R3 d; _void write66(unsigned char Data)
/ ?  _! w+ ]; D& ^. t8 H{) I4 [5 ]9 t2 H7 x+ A  `# y
        DWORD Status,TimeOut=10000000;: r4 ], x( z3 F" X" Q
        do
1 k+ C' e$ ]: s, |1 A: A        {* v8 M: ~0 P, A8 m0 W
                GetPortVal(0x66,&Status,1);
3 |  e  ?5 q/ j3 E                TimeOut --;
- b5 o' S4 ?4 b8 {: @! X" t9 f; R//                Sleep(1);5 Q+ p. p4 h: P
        }while((Status & 2) ==2 && TimeOut>0);
$ z+ S  Q6 C3 f, D
+ \2 i0 D* W" i4 g        SetPortVal(0x66,(DWORD)Data,1);, W" Z- T6 H' C2 j9 n% \9 C8 I
}+ }) }" ^# Y" g$ C5 [
void write62(unsigned char Data)5 u8 C9 a5 r3 R1 v4 ~6 M' a
{
( l1 P1 Q2 m6 S( w, C        DWORD Status,TimeOut=10000000;+ p$ c  Y6 u% Q) q' G' [
        do
4 f7 x# e2 q! N/ U        {
2 r# k0 r5 K3 W8 d$ C                GetPortVal(0x66,&Status,1);# @* Y. m* k# ?: ]' Q- f
                TimeOut --;! j7 H; R4 @) e/ Y4 S- T
//                Sleep(1);
' T6 N4 ~2 `( r' |8 A9 K        }while((Status & 2) ==2 && TimeOut>0);
" |. l4 d/ E& \6 p3 L6 w* w
) |$ ^1 t" W3 `, [! n        SetPortVal(0x62,(DWORD)Data,1);$ H( c* h  u3 T, `5 U' o
}3 G. B$ I. p3 o* O/ V
unsigned char read62()
4 Y( s$ U( _- F+ d{& O( u- X" y6 ~0 Q' _3 v' |! Q# @
        DWORD Status,Data,TimeOut=10000000;5 K# }/ x; v5 X6 s
        do
) w  J% [4 N+ L        {
/ R( ^3 t0 F( i4 B                GetPortVal(0x66,&Status,1);
0 ]# x. g  o2 Z* `" v4 u0 G                TimeOut --;
3 W& |& B5 P3 F; ?1 s//                Sleep(1);6 t* R9 q/ ]; e2 M  u- }# }
        }while((Status & 1) ==0 && TimeOut>0);
9 e9 O; k8 [! B
' {2 p) I6 P# B) r8 K
0 T3 y, r' y9 ^- c0 `% U, x. X        GetPortVal(0x62,&Data,1);
. h" I7 A! W) Q8 j5 C        return (unsigned char)Data;
; m! g# D- J: y$ p}  n2 [5 v+ z) r4 i
unsigned char read_ec(unsigned char index), x8 D6 v! i3 o/ }# d' n* U
{
9 f6 O5 z$ m- q        write66(0x80);
: x  o9 w1 z) X- ~- |0 ~5 P        write62(index);) M: r5 d2 _, y; s
        return read62();3 E- `' N8 w+ N# B  S+ j- L6 I
}
" m9 x: m6 s, ^; B/ h
6 K2 ~/ i3 N* c8 p5 X9 g* ^/ K; ?0 x[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1767) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
3 z, T) X4 n  v4 w  Y4 [  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。' W% i8 Q2 f) {6 _+ h6 I# ^* l9 Z

3 {( @0 W" a% Q3 ?8 H  n[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
- r" g1 w, b6 }% R. c. a4 {7 u
* W; T4 f9 A! Q: F2 m+ i$ Q2 Z: q% S' T% p1 \" J
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
/ B/ y9 H6 }5 }
" c* A' o$ v% ~5 y2 s5 M
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
. n; r" F+ r  Y9 W! e
2 [! x6 b4 w, L% w" T2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.' h4 j5 ^' E! e. F& S

2 U4 ]3 i  b' ~- g8 o5 r3. Then set bit16 of the IRQ to disable it.
" k4 @" {  o; X9 p1 U* R. ?# I2 N+ f: q/ ~5 T9 m9 x$ ^1 m& f
    a.. Offset = IRQ# * 2 + 0x10;
2 V( S6 r" T  a+ Y" ~& Q. }# h* Z
+ q1 v* ]! C4 ^! N" B2 J3 [/ K% P    b. Write Offset to APIC base,
5 y3 L& `$ Y: W/ r9 _% w; m1 ^; s
) q9 e% V% }1 S    c. Read Data from APIC base + 0x10;
6 T. j1 l5 x1 G1 h' \0 R  W
; F$ y$ j9 T! G8 H( z. S+ t    d. Or bit16 to Data;
$ H( [8 @. U2 |; D* U5 h- e1 k+ ]- L
    e. Write Data back to APIC base + 0x10;
9 ~% f" E8 Q- D# F, @% c) c1 d0 R5 n' F# |6 W1 B: ~! G0 G
1 y6 q: d0 Z' q: \
* t6 f5 h  e- {+ E3 h
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 8 ^3 {* m- k' ?6 m8 O" y
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
6 P5 L" O, j1 Q) a4 }$ v, q9 g. I! B4 Y
) L6 S7 y% M: c/ w4 a
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
+ S5 w- A  y5 T( a  j==============================================
( |' ^6 x3 u/ v6 G; C: O5 Y 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。! @$ I' T. A) B9 }; f8 c2 X; g, \
: q1 X6 t# w  E  T& w
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
: R: @6 ~  f% J3 P但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。& h4 a3 H4 d, F3 @2 D9 g
( e. E* x3 U4 v$ C
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。7 r5 U2 @0 X6 T, e& s
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:# r% }- ]5 {1 F/ g
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
) ?6 o( s7 Q) m5 J( W  [- i4 m$ A2、新手不要把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-3-5 16:00 , Processed in 0.317616 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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