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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
5 X: j% @& ]$ [; n#include <Windows.h>
' ^& H/ z' T8 ]7 S- x: ~4 t#include "WinIo.h"
2 i  G/ T. @9 u7 k9 qusing namespace std;0 Z' S3 K4 ?! g  L, }/ V

5 m7 R( P6 R! p+ U* k& h5 ]5 g#pragma comment(lib, "winio.lib")
0 i7 P: H& u2 e; P1 j1 v
- P* z' ~/ e8 r0 s& L8 g
% t$ e$ Q5 R' |4 M) lint PMU_SC                =        0x6C;//命令端口3 c4 y# e2 e! V$ @5 P7 h7 a" ~
int PMU_DATA                =        0x68;//数据端口
! \: Z( A1 I) }, F3 G# Nint RD_EC_SMI                =        0x80;//读寄存器命令$ }6 D/ ?8 k2 d% o2 j+ H7 g$ `0 w* t
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
' `& U7 M! U9 R4 M9 z6 H
  R  e4 B  l5 M3 t  IDWORD dwTemp = 0;
" u$ d* Y5 ]& j- [2 |) R# G+ k# {5 P+ t" u$ k
void PMU_Wait4IBE(DWORD *_value);% Y" `5 [& K7 u
void PMU_Wait4OBF(DWORD *_value);1 ~+ D& H4 D; D

9 ^7 R$ V" c9 y( x% O+ |. \; c0 Y2 F
& u( ~5 w% ~0 M# r' l6 x- J) z$ }9 Lint main(int argc, char* argv[])* H7 K: B4 [1 C# A4 w" I
{  \' X4 n- [& ]; I+ q9 z% B& V4 ^* L
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;- G' r5 g2 p1 D, |% X  l9 c
* }$ @& C. _9 i2 b
        . E; i4 z9 r( e* _7 z! x
        //1、mov            dx,PMU_SC                //5 g7 d" R! V  D
        //2、mov            al,RD_EC_SMI        //  {8 m, m$ h/ _. p. W  O/ t5 m$ s
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
/ n1 P# V" e4 F        //4、out            dx,al                        //将读寄存器命令放到命令端口中。) @* v  K* p+ D: {8 d. S! U/ P, ^

6 p# m* b; z, r: p; }/ b        PMU_Wait4IBE(&dwTemp);
# b- U" \& e+ [- ^       
* v8 J" S! }! b# B0 k+ z        SetPortVal(PMU_SC, RD_EC_SMI, 1);! j( ]+ n" X4 {# l
2 R3 Y  }2 r4 Z4 S
        PMU_Wait4IBE(&dwTemp);
! n5 ~  C5 n1 p        : G! f  W5 X5 i( ^/ j
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
# f. G& I0 n4 M
# R& u6 Q$ S4 d$ r+ k( [        PMU_Wait4IBE(&dwTemp);4 K7 S! v3 ~& m: f# I
- {, l8 W# ~6 g: s3 P4 @
        cout << dwTemp << endl;               
7 d9 p; x% l  _
0 H! X; [5 |2 p' j- u7 u" \        ShutdownWinIo();: `8 {. T1 U1 {" m/ X, G1 D

/ m. c" j! N* i2 T& p        system("pause");
0 C/ y: z! ?" ?5 |7 H' A; a, [, v  z2 i' P: T- ~
        return 0;
' h9 Z" F, v7 Z3 j; X# a}
2 b" P% ?) X- z; r3 e3 w) x- }) r. M, j. t1 z
void PMU_Wait4IBE(DWORD *_value)
! R4 u" G* G- p' R( i2 Z. X{6 {5 @* @/ B; o3 V2 |9 k9 i5 c, w
        //#########################################################   2 m+ q: A& R& Q1 y* K' x
        /*& L3 x' G  M6 b& R  L# v
        pmuWait4IBE proc   1 O4 f1 _7 W% y2 z) G
        PUSH        AX   
% J/ w! G" v# t  ~2 c        PW4IBE:               - Y0 Q0 I2 O, W" V! y. y4 l% c% k
        IN          AL,  06CH                                //Read  PMU  status     c' i; S6 R( ~, J" n8 k! e
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
& i" ?4 G$ d) m' T# I- d        JNZ         PW4IBE                                        //Jmp  if  no   
1 r* e0 \4 ]0 E; ]4 j        POP         AX   
5 W. K+ d0 ?5 i* t        ret   - F' s# b# v) q! D8 v
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE/ b: o8 }9 }% L" u2 u7 A% r
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
, \0 q( ]' p2 M        //#########################################################
* {/ S- t$ {9 b' Q2 A        /*do
3 R6 v) i! d0 U3 a7 I" ^        {( G2 ]" o  I$ ~" d. }7 b$ _. B
                GetPortVal(PMU_SC, _value, 4);
! M) q4 ], K; o9 e        }" s. P) P2 a4 q7 D
        while ( *(_value) & 0x00000001 );*/' x) c$ ^2 R9 L5 f, M
        DWORD   dwRegVal=0;0 d2 n) p( C% F4 O1 e( N5 B
        do
6 S/ d5 V% @8 C# R( u* K9 C        {  0 h$ @( ^  o6 ]
                GetPortVal(PMU_SC,&dwRegVal,1);+ }7 M, i+ s" L% R
        }- j$ l6 U# d, J- Z+ T( s
        while(dwRegVal!=0x2);$ ?) I8 T$ e: L

! q1 U! T, D7 l1 r}
, c+ m: k7 g( a; X( |* J7 Q) K' D3 e4 ~4 ^" T2 \( n2 k9 ^: ?% `# b
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
  U7 g9 X1 i) _- f% N1 F所以变成了死循环了。$ U& k: M0 q2 a  ~! x# K' W

# s; U$ ^" x/ ~/ W- z6 U我对硬件编程不懂。又不知道从何下手。
+ b1 m" ?+ a! |3 g我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
' M/ @1 J) u$ t8 k$ S8 b7 m: T但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。1 A7 E1 s6 b  g- @0 W* A

6 W7 ^- Q/ {7 B* `, X我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。+ G1 Z/ F: Z) q+ Q
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。  o% b7 I( A, ?7 [- k4 R

! Q) h+ c+ R. D% I) }# h感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。2 K( q7 T4 y3 s
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.2 Y8 C* }5 p  _
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
( g0 x) v6 b4 c/ K) z1 C5 d3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
% C3 z4 S2 W. g, X9 Z, P+ q9 p1 N$ K: t
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
3 B# b3 N. M" I& @$ J8 o* {* k
9 _) J: q; w. g% i那么有些什么可行的办法呢?0 m: a3 N* @1 D' q' U
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
# d: h2 S( A. r: R- E! Z: F0 Z9 _) p; Z" i0 W! d
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?, M& q6 c6 p; t- |7 [9 Q

( a& i7 z% C% P- v$ W9 X3 X那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
" ~- S6 G& w  Z  ]3 @/ r+ U7 C: ^: C4 s  P
http://www.ufoit.com/bbs/viewthread.php?tid=452& |; V4 c' {% X8 P- F
# ?* U' l2 N, J$ B
http://www.ufoit.com/bbs/viewthread.php?tid=241
* l$ L1 ]. ^$ }/ N# T4 z" F4 {- v$ }  c3 }. N1 h
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
$ w! I! R2 W) f3 |: A: B& q* ^8 ^, J; \
# i$ F, E2 L# T: {, r" d; r* E1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。+ y6 m3 d- A/ Z
2、Driver最复杂,也需要BIOS配合,推荐。! |  d! u+ R0 C3 P
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
& a1 \, e$ o( ]2 |- X) f, S4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。* W$ N% x0 b7 @( S
你可以混合使用。$ {9 b. q& |6 o1 l, G+ A9 S# X

* n, q5 g  b- m% X===============================================================
* ~/ \7 ^! `; O( s6 T/ C管理员的这句话:, ]  n8 K5 v$ O
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?* W4 z1 D& |5 h+ e. E7 g
/ k/ f# y& }9 }1 J, ]
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵9 S% P; x" s3 C4 {: ~8 k

% {) c6 `/ m( h另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
5 Q7 C1 R9 n: H* _  q2 V# b( d" w# ?0 C" O& i
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
& k' W+ @+ K# {
5 |* a( \' V' x还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
, }, u! `- H. c+ D) w+ O; B  {& M6 b里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
+ ]# h4 n  D. z+ h: @$ U+ e9 C/ p  K, a" ~' B1 M7 m
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 % i7 X* S6 \, \9 k- X! V. ?
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
5 k& g2 x' A* s/ ]: x6 d1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

% c8 u+ l( D" d5 l$ p4 g
1 Q0 V0 }. @) S您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
; f+ l% e4 c; N) {( x8 t$ a1 A; K' {% b5 E# g: d. q/ |% u0 X3 a
void write66(unsigned char Data)
! y; z* }( D4 m7 B{: k, T- d  v. z3 @& N' d4 q
        DWORD Status,TimeOut=10000000;
- Q/ J5 O! ]# l/ H6 C$ Q        do; \* y4 A- o% h+ G# Z* O
        {, b- l+ g' s9 j8 T% A
                GetPortVal(0x66,&Status,1);
% r% F; p: j, f+ @/ n& a                TimeOut --;5 _8 e5 A7 T8 E- X8 c8 [. o0 E9 Y. U
//                Sleep(1);8 }% f; R0 w3 y! t* m; a; W
        }while((Status & 2) ==2 && TimeOut>0);$ y. B( T  A" M8 ]

/ [& X! v: _- j& o3 B$ a        SetPortVal(0x66,(DWORD)Data,1);. C$ J- e+ K4 ]+ k4 l
}( u! k% _6 `7 Q$ k
void write62(unsigned char Data)
5 u1 q  Q' c3 h& K& B) L- N; R{
/ n$ m. D, s% t7 g) O. y' k        DWORD Status,TimeOut=10000000;( P/ D! e. s, \5 p
        do* |8 o& p9 P( C, P) j+ s, g$ |6 A8 B
        {5 m# N0 A! ~0 B8 [
                GetPortVal(0x66,&Status,1);' x$ X* X6 W' Z) u3 g! w' K
                TimeOut --;
7 ~: P+ D1 D& I//                Sleep(1);9 a5 [+ G* c0 N( P9 \
        }while((Status & 2) ==2 && TimeOut>0);/ ^  A& o. u) e5 D' p2 t" l
# k3 e4 E! ]- t8 t8 Y( Q
        SetPortVal(0x62,(DWORD)Data,1);
# Y/ \6 F1 T+ X/ `1 F+ N/ X}9 e$ _- w8 o$ h0 P( |
unsigned char read62()
2 m% {7 V9 p1 E# ]{2 P/ ^4 {$ ^9 y/ ^
        DWORD Status,Data,TimeOut=10000000;+ _5 q! Q3 }$ D* j0 z' s, W
        do
7 a, k) z* S* [2 q        {( o! _. t" `  ?. w7 g9 o: c
                GetPortVal(0x66,&Status,1);
4 d  f! q. D  d7 X1 @" M8 B                TimeOut --;
9 t# U4 e* z. C( M//                Sleep(1);. h. ~7 l7 O: u+ R" p  J
        }while((Status & 1) ==0 && TimeOut>0);
4 D" s8 [1 R1 M; H4 V' q
' T8 p5 Q! O0 J
9 i! O7 L; v) n2 @5 h+ \! a        GetPortVal(0x62,&Data,1);% y0 D* t+ }& }  g+ M
        return (unsigned char)Data;
' m9 S- h' P/ o}
2 t+ O- Q1 N$ T: N- uunsigned char read_ec(unsigned char index)" D% ?; v/ `' m6 g
{
  n# w! y3 q2 o; g+ n$ N        write66(0x80);2 {5 F* L( A  j- _% q$ Y
        write62(index);
8 I. }' f. l, @# p+ B        return read62();
2 a) A5 o6 i- Y' ~: `+ X}
! d% t! D) u2 k0 v# w( H! L+ V1 ?8 w9 N* o' o
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1499) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。( A4 [7 z& y  h+ Y" D8 V
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。: i# I# c/ s' G9 e7 U( J% Q

5 A' Q0 |( p+ {: _6 R* Z. l[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 & e& g2 C) f: v; B1 @% Q
1 m# e- i1 F6 u* y0 o& A- F
( D" I% R) k  H4 p
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
* H# j0 w8 G4 h2 H: M

% m3 s! q; S+ g: B% v0 ^& A; P1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,/ I" e5 u  u& L; K- a* @

) d1 T8 q( X' y. c6 n1 W  J2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9." W9 u$ z: B; ~9 ]
9 Y) ]1 E1 d1 a( _
3. Then set bit16 of the IRQ to disable it.
) d5 K. R# S% S9 h" D
% ?0 @6 i# E9 I+ m    a.. Offset = IRQ# * 2 + 0x10;
, M( g. H2 W/ ~5 n( a- m
: a3 r# e! _% L7 Y" r9 ?    b. Write Offset to APIC base,
* v. O* ]. }  k5 N  S. O0 G
- _" A- m/ d$ _# m; f9 _    c. Read Data from APIC base + 0x10;
- @3 {& p/ l+ D. f3 ~% n
* r% R. {* _3 o! U' J+ ?* A4 l6 R    d. Or bit16 to Data;! O) l9 w: n/ z9 F  Y3 N1 p5 ^
; v# `2 o! s/ P. @- l+ J
    e. Write Data back to APIC base + 0x10;* Q7 B2 G, u* U9 k

. [: E! S0 U( A' N- L 5 C  l; [9 _" K( P# F5 `& {, Z7 j) |
% E* s5 C9 E+ H. ~: R
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 ( U: b6 \* }% Z  n0 Q
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
/ s) j( n3 C$ X* _
) {" k4 Q+ P& j2 p6 @; `7 O
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。1 S1 N7 C( T7 y" z) L9 ?+ F
==============================================
/ G, q% X# I4 U4 J 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
9 q+ e* B; g1 ]$ a- m" S& ~
+ _0 U, n% r/ T  h6 R) g因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
! Y2 J$ T' \: h/ i/ j* |但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
5 L5 n( d  u3 R" [, @3 E6 d- x1 z, a6 C5 }+ ?- {/ S' Z+ T
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。6 o$ L- Y0 ^3 T  ~- W& p0 c
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:' Y4 W9 A+ `; |( l8 I
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。# {/ g$ a" g2 Y2 _
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, 2026-2-1 05:35 , Processed in 0.071594 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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