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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
- K& L: U" z, ]) {  Q* [- f" Q#include <Windows.h>; E/ w- P( n4 r
#include "WinIo.h"
8 X. {) `" E8 U) X6 xusing namespace std;
* G: I: Q7 D, {4 J9 G% D# w
$ k9 c* F  O4 q1 b" E6 J#pragma comment(lib, "winio.lib")
+ f5 O+ @+ R, q3 |  d  e0 d3 o  Q
6 b9 Y# ~# t" m
$ F. H/ T) z8 N( a/ pint PMU_SC                =        0x6C;//命令端口
' a- |8 h% U( F( `int PMU_DATA                =        0x68;//数据端口5 d( S9 N, t! Q( F, y# P
int RD_EC_SMI                =        0x80;//读寄存器命令" j, k# S4 i' P/ _+ W1 W" ?$ L, L
int POLLING_DATA                =        0xE7;//CPU温度寄存器号: n& S2 f' ^  _
  e, Q5 k& `8 p( ?# _3 Y9 G+ m
DWORD dwTemp = 0;1 D4 _8 f/ [0 n6 X
! B2 a% e% R! u0 V) `9 `
void PMU_Wait4IBE(DWORD *_value);
+ e4 B4 y$ G0 C7 K+ bvoid PMU_Wait4OBF(DWORD *_value);% h4 j+ c# T. m2 _5 ?  t

3 n/ b7 v5 d) L( r
5 S. H' C! ?; h  K- |int main(int argc, char* argv[])
2 j9 _( b6 {& D: ~% b$ f{5 Z2 o( e% Y; q, ?" q* p
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;1 R0 ^/ o% @- A2 K) q' e) ^' t

* a- p& \4 a' W* u  |, S# W        9 q. L1 ~/ t! K7 e$ U
        //1、mov            dx,PMU_SC                //
; d# ]# m6 A- |% s6 O/ q' V3 x% x        //2、mov            al,RD_EC_SMI        //) R! p! V: k6 B- v% y+ {) h9 w) [# ^
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
! b- N- F7 X' s( W8 }        //4、out            dx,al                        //将读寄存器命令放到命令端口中。; ~9 X" {$ t. M* i1 B8 ^$ B7 b$ j+ l
+ G/ J) J( S5 f
        PMU_Wait4IBE(&dwTemp);+ y7 B! d4 j$ N2 P$ B
        9 f1 R0 f# c/ r2 R3 m1 p9 P9 f
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
/ W! x4 N# F: f% Q" L& ~0 h* I8 b4 Z% A$ I4 W2 g0 y! Y; T
        PMU_Wait4IBE(&dwTemp);3 g5 }! q( |2 [
       
9 ~! P7 E: T; I3 u1 y% N        SetPortVal(PMU_DATA, POLLING_DATA, 1);) k/ d( Q# _  X- W. D: y

. c5 I# w. @1 r. \7 k$ s: |, x        PMU_Wait4IBE(&dwTemp);
% m) H' n: j* E# U% j% X7 M
0 q7 S! Q% j; Q& T: g        cout << dwTemp << endl;               
; |2 y' r. g6 r$ d' h, t- p2 J4 t4 }
        ShutdownWinIo();
& D$ P1 y- i; p0 B  g1 g/ E! a
% W$ c8 Y5 R5 s, B/ E) c9 v        system("pause");
2 x: A' n3 O: }7 |7 H- }  |2 b7 h4 j8 c
        return 0;
7 A0 ?$ O/ x8 l; H* r$ U}. l* x/ w/ ^/ `3 {$ x4 H& o6 G

! q) Y6 Q. i5 Bvoid PMU_Wait4IBE(DWORD *_value)3 \0 r" l" R* W: a1 |8 ]2 d
{/ d/ h5 v. R4 q* Z
        //#########################################################   
& t! J) Q6 C4 k2 l5 t1 n        /*
  O+ ?6 u' c' j) ?        pmuWait4IBE proc   $ W' T0 t1 u! M) K' q
        PUSH        AX   
' o% d* }: i  a3 K% l( b        PW4IBE:               ( L- m  M# B1 n& M6 `1 m8 M
        IN          AL,  06CH                                //Read  PMU  status   ( ?) n9 I+ B& z1 w
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
" n: L4 o7 E5 c7 o5 m" |2 D        JNZ         PW4IBE                                        //Jmp  if  no   
0 ~& d2 B' @4 x* j3 q( X        POP         AX   ) f( ^- ]! b& U
        ret   
$ A* R0 w& h5 c$ i; x  w        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
- ~/ B. s9 d+ T# k' d, F        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
$ Z# T% S+ q9 E' k, Z  D0 o        //#########################################################
" l6 g, ]# t! g3 R6 [. D2 @        /*do / r# x9 B$ W0 K1 z* m2 b2 z
        {' D5 Z9 N+ Q( i, s9 o
                GetPortVal(PMU_SC, _value, 4);8 ^1 T& P' ^, c6 |$ C9 ^3 D( j
        }, ?+ H0 B! _1 L" x1 `# T: D4 U
        while ( *(_value) & 0x00000001 );*/- s7 K4 M& d- |8 Q" I4 ]
        DWORD   dwRegVal=0;) c& x  i# {6 z' ^+ [" @
        do) ~$ K% S/ x0 d
        {  : R; X2 Y- o! I* N6 }( k3 `
                GetPortVal(PMU_SC,&dwRegVal,1);
( j% N3 Z3 W4 D, z- r! F4 v; U        }3 ?1 z2 F7 L, F. }6 E
        while(dwRegVal!=0x2);: f5 @" |- r0 e1 p

9 K" @+ U/ }8 I! T2 w}# D- S1 \7 ^( f1 f- F' C) _: c

2 f0 L8 H6 `+ P; a! V1 w0 j( t9 E以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
8 x! L4 p" m* n1 H0 D所以变成了死循环了。6 i* [. a2 \$ m, F; s! y+ y! W

# X8 H7 U& D2 i我对硬件编程不懂。又不知道从何下手。
9 U0 L2 ?8 q% i  D" S我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。, ^* T/ C- r; j$ T; Z
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
4 c; i- L. i2 f/ D' [  l8 c* |" g/ \% a: |$ |' q/ ^: s5 C
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
% B* W2 x+ U* {+ m+ Z& E并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
) Z3 H/ `) u% U( F& f4 m8 [
. L7 m0 t/ J( R# y% o5 F3 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.但是你这样做法应该是读不到的。
7 ?; o! ?0 Q% Q+ S7 c1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
3 \) c0 P+ O2 U: x+ I3 Y2 R& L2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突% I0 v8 L: K8 B6 [( q; {7 k# O* G* [
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.9 N" E- [( Q, C. E; l( p

$ B$ h% B1 X- B/ j; |所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
  t' _% z3 u" r" ]  c0 W; ]
6 s2 }8 }3 ?& D: }5 u! k- Z1 X$ z那么有些什么可行的办法呢?3 Z7 B( X3 O, e: k8 S4 a% U: Z
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。7 N9 l$ c' x4 t

( d. }  q1 Y2 F3 _! h它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
4 W2 E; M0 C% U3 j
, E9 d6 a% ?* `' e) X# N那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420" u* {  L& A  H0 M: K1 u) D
$ W" F* i. S% `8 z  ]" f" E) ]9 s
http://www.ufoit.com/bbs/viewthread.php?tid=4526 |! h* Z4 A( G" B1 f$ N
- E2 q# D( Z: ~& Q; F* \! A
http://www.ufoit.com/bbs/viewthread.php?tid=241
. F" ?# q6 I) Q" K/ R1 {! }+ c- p- c& b2 a2 b
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
& k; T, O' U& ^( l
: I$ c1 p  a, s! s7 b- o1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。/ o& W# U) y8 ?
2、Driver最复杂,也需要BIOS配合,推荐。: i% K* W! {) d- [( Q
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。. D0 |# q4 V. f. \# h. i3 \
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
* f: r* H& l1 U) }6 i9 g1 @你可以混合使用。5 l! O) D2 {* C8 ]1 ^
+ J2 y& t: N5 j9 F, ^5 g
===============================================================. H% H/ T- |* Z2 A% ^. m) t
管理员的这句话:5 d! D) x, y9 `- d( H+ K
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
2 d7 x, {  ]) j4 H* ^( g( L
2 s, v) [9 a/ a5 [予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
. }2 V, l4 i0 ^6 ?
9 ~/ v+ I# l3 A+ p另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
6 N5 w$ D  H7 @/ b  K4 q  Q: O% E% \8 ]3 Q
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
0 f: l7 q/ N! u/ E" x3 z. D* ?" b: t- h$ P& }" ?
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。6 E2 _$ ^1 R  [3 C( Y" m
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?% c& d/ U  V! Z$ z# o
% ~% g" e5 |6 l% l9 O6 x. q- I- w# @
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 & q* m9 b; e8 W: T# h* b
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
, `5 K% [' G9 a8 Q8 r1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
, s0 F5 I" x' e1 V* V
/ u% I9 P) b9 _) a
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。0 L+ L7 R1 P% q
5 Q; A5 A0 h  R0 K
void write66(unsigned char Data), F. K+ N2 x2 \. u, ~3 T/ A
{
8 i  F; D9 U5 O; w( k' E        DWORD Status,TimeOut=10000000;4 _3 |, M1 a3 ]$ _! J
        do8 v7 Q' w8 `8 a; [0 @  Z# s" Z2 N
        {
7 J. s. E: J4 K( b                GetPortVal(0x66,&Status,1);
# ?$ t# [# l6 d% G  [8 t) |/ }                TimeOut --;+ _' X4 p+ ?6 `; v8 r
//                Sleep(1);+ R$ i6 w" [# t3 m; i8 F5 b
        }while((Status & 2) ==2 && TimeOut>0);
! q5 ]( w6 u  ~4 x5 L9 [, ]% A* u4 q8 `2 Y- o
        SetPortVal(0x66,(DWORD)Data,1);
3 {+ J( w9 O. d}# h7 s* A" x/ j9 A1 e
void write62(unsigned char Data)
( |1 D( Z( n& ~4 U6 N. D, }1 b{
  D! h& [1 x% K) h        DWORD Status,TimeOut=10000000;0 ^4 s4 f% i% `" X( h* P
        do
4 J1 q$ ~) [) o7 r) v; N        {7 Q  F! {# d$ A
                GetPortVal(0x66,&Status,1);8 i, r% K' @$ `# r2 B
                TimeOut --;7 x$ H: a1 F; {$ O
//                Sleep(1);
% g3 b/ t  f' w) n& a2 o0 w& D, [4 k        }while((Status & 2) ==2 && TimeOut>0);
' P4 `& I: s: }
- V1 m+ k9 |1 j        SetPortVal(0x62,(DWORD)Data,1);% R, q  D, f8 \5 _
}) L4 G! O/ i" z5 W8 X
unsigned char read62()6 N$ C; b) e/ ?. f
{
0 V3 f/ W7 L& h; p        DWORD Status,Data,TimeOut=10000000;
2 U7 j; n% r( r, ^6 o1 u        do# `9 p& n/ q% M3 D
        {
) x) m$ H; g6 g' J" W$ Z  }                GetPortVal(0x66,&Status,1);
. \( b& f0 g$ ^0 q% b! A& `                TimeOut --;4 n( u5 O( r: ^. z3 r9 P
//                Sleep(1);
5 F* P, t& k/ `  w        }while((Status & 1) ==0 && TimeOut>0);) _( [5 G7 Y/ t$ ?) L0 W

8 D7 w0 Y3 ^" U5 m+ O- b6 n4 X+ ~% g& C) P3 W  w. R3 A
        GetPortVal(0x62,&Data,1);
9 B8 L$ u/ O0 _) q        return (unsigned char)Data;/ V' ?, P2 Z( V6 J: G+ @2 y" G
}
2 y- \! j0 a) g7 t( M6 Yunsigned char read_ec(unsigned char index)
7 i( g+ h" J4 M  h- q" a" ~{* c$ b* }, z2 l  x& M
        write66(0x80);3 R: |. _& N& J! C: r
        write62(index);) V% }: r1 Z- D  h$ O+ Z
        return read62();
$ Q) |9 ~8 f; @) O; J! I* t}
- \$ W) }- }8 F5 d* _) ?. t; e2 y/ z. z% }: _
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

3 w3 G' ]( u- u! {$ Z[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 $ ?; q- Z9 [( d+ C7 ?
: W( }$ b$ d& A/ D) X8 D1 A
0 k- c" }+ j# u- U* l: s
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

5 E+ ~1 [* H3 l. }" G) G; F. H/ f
% `% F+ K0 h- w; ~$ N! H* v1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
# W$ h9 m- q3 A: ?' \1 W6 U/ U7 [( W- P( @& h
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
! o: A+ t$ Y/ N0 k9 r& |4 O0 H2 P2 e3 M) S& Z4 n
3. Then set bit16 of the IRQ to disable it.
; ~+ I3 e9 D; S1 C$ @3 [  B1 O9 {$ f
# b# I0 Y8 F' ]2 J  g& k    a.. Offset = IRQ# * 2 + 0x10;9 _: h1 I% a5 w

' Q3 l2 g8 q# K& d    b. Write Offset to APIC base,
! J, K$ K4 O9 I8 ~0 C/ X# @. Y
! D6 C; ^' K/ J    c. Read Data from APIC base + 0x10;+ B7 H. n9 i3 w% X) P) i

1 u3 P  [( W' w1 ]* L    d. Or bit16 to Data;
- d* J4 w8 P+ r# C5 g3 \
/ Q; e- r6 O  T    e. Write Data back to APIC base + 0x10;: z" J5 Y4 ^5 X3 A9 P& @
3 H3 k8 X" r6 r( F& T

1 Z, a1 ~' P7 M& U+ w# k7 S+ {: q7 r1 C, N) ~
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
1 S7 a5 L( D5 T3 W5 f545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
4 @" t1 ?  K: C* ]1 W

, U6 l1 w. V+ D# L4 ^6 ]' q" n 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。( ^' [! k5 }# d( H- `
==============================================
: P* e6 g5 d- _1 M% f, [1 G 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
# E$ h" W4 ?# M3 o* P$ m5 ~3 J% _" n5 Y7 z; p6 f% O% s  Z
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
  L4 f9 O2 z* R' f: t0 A7 l但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。% {5 g0 f# F- E

" E4 M) c) I( H因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。9 D1 ?, x! M7 k, x  u' l# F. q
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:; Z  g6 ~# a6 A$ q; l( f( a
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。8 T9 c. b) M( |4 ^( m
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, 2025-12-1 02:46 , Processed in 0.081244 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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