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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
5 B8 I. `$ |5 I& M9 S8 {( |#include <Windows.h>% Z6 I! w; g9 O8 u3 {
#include "WinIo.h"
( _( [6 W* O( J- \4 {: m1 p* Wusing namespace std;
9 Q& v9 C$ P% Q$ j7 x( p* {
' q& q2 D% b! H#pragma comment(lib, "winio.lib")
" i  D) S+ k4 u/ i$ L$ G4 \& L2 l0 z2 j( a) t' r

* B6 n& d: t- Lint PMU_SC                =        0x6C;//命令端口$ ]- H6 U; t6 p2 F
int PMU_DATA                =        0x68;//数据端口/ C5 T  @* z2 G2 L  E9 v
int RD_EC_SMI                =        0x80;//读寄存器命令
2 `  ^4 s4 h: h1 @; V; m* eint POLLING_DATA                =        0xE7;//CPU温度寄存器号
, V) C! w) y$ x8 o! W$ A! j8 P0 |5 R" K4 @) h6 M, o- ~) A
DWORD dwTemp = 0;
9 e& J- |# X  S
$ o: B6 E% W- |" a0 Y9 T8 I, mvoid PMU_Wait4IBE(DWORD *_value);
0 m& c$ u9 U4 ^( b. }void PMU_Wait4OBF(DWORD *_value);
! |/ ^/ ]2 A. N! V( ]
/ d0 f0 o% S7 X! m/ e3 S
2 D- y; y; P4 s0 k% e3 u7 lint main(int argc, char* argv[])  f+ Y9 {+ [3 _, V7 k' D
{0 {. u2 @7 R) W! C0 D
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;; D7 j, m3 V( N& H: i6 z/ h
" Z" V( V3 \1 q$ s! \: D2 k4 K
       
' L1 @7 Z9 o1 Q3 \: Z/ H        //1、mov            dx,PMU_SC                //' M; J6 Z5 ^  ~" f, g, @3 `( G
        //2、mov            al,RD_EC_SMI        //! I) l) ~$ r, |# @
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了8 n5 v$ v9 L8 h. m
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
; Z3 X- N- m8 p# L* y
' Z- a4 }1 o, c* l% t$ X8 [6 k) |        PMU_Wait4IBE(&dwTemp);9 m8 _- V" P& K9 Q
        4 f) v2 T. [8 [8 Z
        SetPortVal(PMU_SC, RD_EC_SMI, 1);1 y9 P( _% t  _& `
, o5 @  g  k$ }( {9 W; m
        PMU_Wait4IBE(&dwTemp);
) n  g/ e3 g( A0 |7 [9 `6 T        7 }- ^% v; t% |0 A  H
        SetPortVal(PMU_DATA, POLLING_DATA, 1);+ T7 P% W+ [8 V' Q9 K5 B

6 h1 O) L! S* C; j) e: v        PMU_Wait4IBE(&dwTemp);' X$ U2 B# `4 G  B! G
, s, ^4 T8 Z4 w- o
        cout << dwTemp << endl;                : Y3 \+ B. N1 ]; U9 a

1 K# a" k* _' j, Z+ X2 [* y& z        ShutdownWinIo();
. p: |/ Q: Y: Q0 H  ~9 c, G. c# t/ x5 P  @
        system("pause");
6 v* p, m! J" v0 K. k# X, ?% C( r: M2 d" x/ j6 U+ ~- l9 d7 D
        return 0;; x( s# W, p6 y# I2 O
}
  M& J6 u/ P3 M1 T% A/ A' d8 ~+ O' N9 W% z
void PMU_Wait4IBE(DWORD *_value)
" w- t4 Z- F7 G) b$ L4 n{6 v+ X% T! h; ~% ]
        //#########################################################   3 V" b( f$ ?. {: D
        /*4 w& w- _9 m, o5 `7 F. b: [3 |; n
        pmuWait4IBE proc   
  ^! S+ I6 j* L, x. i8 t        PUSH        AX   ! [9 D" A9 @9 k, K: z6 e
        PW4IBE:               
& ]& u  W9 L  Q. u2 f- E" L! F1 r/ _        IN          AL,  06CH                                //Read  PMU  status   
) _- X' n# _; V5 D        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
( _, {. ~; F3 @        JNZ         PW4IBE                                        //Jmp  if  no   # O# {5 }1 {5 s  [  s# s$ a
        POP         AX   $ b' c# H0 x% Y* l- A7 C" |( g
        ret   : U" r6 F1 O# z# W  j4 M0 q
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE6 _2 j9 D" D$ |3 Z1 D7 T+ E5 H
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
8 c5 W4 t  _, n        //#########################################################
7 @- M5 q9 n) ^6 H& s! \, {9 O        /*do
, v% O. A0 h! u; D' r$ _        {
. E/ G5 Y3 H' m5 T" A5 E+ _                GetPortVal(PMU_SC, _value, 4);5 {/ H* V% G1 }; c8 {
        }
- e4 X2 H2 e0 m$ \3 j        while ( *(_value) & 0x00000001 );*/6 |; n5 p) ?( e9 p" x9 [3 d; n
        DWORD   dwRegVal=0;% e- [' J, H' z+ ^
        do! {8 ~& N! r' i# t  T" o
        {  , ?) j6 W  J+ K& T9 A, ]; F- D
                GetPortVal(PMU_SC,&dwRegVal,1);
7 I# v$ e7 l, p2 X, R5 G% {        }: v0 U9 z1 V* o- W
        while(dwRegVal!=0x2);6 |) L( o1 Y$ j* h; d# a, g& X* t
9 s+ g* {  q1 k$ `) Y
}1 [; c2 b9 W; e" u

2 }; h9 c8 ^, N0 i* Q6 N( g以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。' I6 \1 c# M% h1 Y1 @! m1 x
所以变成了死循环了。: u9 o- `2 N/ Q8 I
5 |. i' @5 E& }3 j) ]
我对硬件编程不懂。又不知道从何下手。% W7 J0 d2 }/ i. Z
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
4 e9 y2 I- p& n但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。; }$ f0 r2 D" v- e" d( q. ^7 ?

' M1 }6 B: Q9 U& C我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
( C. Z; K, n# @8 f( ?并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。* C2 p8 J7 r' @! ^4 N4 N8 q! p4 H
9 _+ \! _) C8 C7 d5 ?6 x
感觉现在无从下手。我在网上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# O. y% [
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
( n+ B4 a; K2 Z: h4 p2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突( @/ u/ o/ f) _8 h
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
) E, ^) W* W. d
0 e. R. `& Y) Y. i4 |所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。" v  k$ T4 P- ?0 [* z- i

7 m8 O: I* k8 K8 y( R那么有些什么可行的办法呢?  {/ s. A( ?- p
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
4 L1 m/ p+ I, M% X3 @$ q$ r+ _  c& K4 B6 D+ V# v2 l, B& _
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
" [) ^. b" h* ^& c% d8 L; x: o2 m* c  f- E' [! p; w
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
$ s- f' t- x( X6 P
9 e# r( S+ V& W' y* W* u0 b, Khttp://www.ufoit.com/bbs/viewthread.php?tid=452, Q$ N) F9 |5 R- C2 a

' X: e/ Q1 S1 ~, X: thttp://www.ufoit.com/bbs/viewthread.php?tid=241* l! c# W. s6 [" d$ J( E/ H. s" d
% s, v  X) W/ H, C$ x3 }- V
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
& h% G8 \8 `# K6 F
4 l, f# |2 \9 _4 G3 K+ t. i1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。" d$ r3 ~9 i- v/ H! g1 ?
2、Driver最复杂,也需要BIOS配合,推荐。
1 o1 f, V* F% _9 b' n3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
  I6 I0 n; \. \6 q  K1 P4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
2 [5 O8 F9 R0 u你可以混合使用。; R2 V3 T4 C  |: ^5 M2 Q; \
/ E, z, S( |! J2 s* Q0 J2 V
===============================================================, l% u" \8 d2 L2 w
管理员的这句话:# v! k5 B3 A! }5 {
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?# h3 c, M0 s! C7 |
) Z+ R% V  T1 f. g5 E
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
/ Z* x6 C6 D( Z# y! j) t3 Y: b, N5 Z) k! O* ]" u$ b& N+ }; p
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
2 m$ p  R2 Y4 k' }- [
6 K/ V  c0 D4 M/ x/ P2 k这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?: _+ f* s/ [) w; [# ]  ]  b5 z
3 W" I. g  W' y; n& m/ h/ y" k
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。4 T" }! l5 X% o* z8 g8 s
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?/ [# R# S/ U8 q" a' W/ y

7 S, t- v9 T) ?我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 ' K3 o3 S  S) D5 u  U
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。3 }: i0 n4 Y9 u: E$ G  Q% t
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

7 `( l# H" {" _! D0 f# h/ a# N8 ?7 H8 @* j, l/ _8 y0 Q2 s
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
$ y/ V- L# t* _4 O6 K0 ]! T2 L: x$ e8 ]1 L
void write66(unsigned char Data)9 U, f: z7 L6 P: v, X9 y
{/ l- I/ V, `% X$ P) @+ i
        DWORD Status,TimeOut=10000000;
% x3 ?3 w' D) \/ s9 k* U        do5 G: `* z& w# l6 m6 u; y( {
        {
3 C4 B) E1 V6 d- [3 d. A* {5 m                GetPortVal(0x66,&Status,1);$ u$ ], X: h2 {/ G8 t9 j0 e
                TimeOut --;
5 s( _. ~3 |, H0 n3 I. k: ]5 {) m0 F//                Sleep(1);3 }; b! j. r- d( G( w
        }while((Status & 2) ==2 && TimeOut>0);
6 {4 p- y) z1 G& S" a7 a# H
6 m/ `; `+ O3 @3 e  p8 z        SetPortVal(0x66,(DWORD)Data,1);6 C' m4 Z, h9 {) J
}
. L9 I8 h. W0 b% Uvoid write62(unsigned char Data)  P2 V0 ~9 [" |+ G, `
{2 F/ F; j; F( V( Q& o$ Z" s4 g
        DWORD Status,TimeOut=10000000;
. r  P/ V3 a, u0 i: Q8 }4 w, X' q        do* ~& G- w. u5 n) M$ D+ c
        {
% Q+ N+ [6 l- p- M- x6 X7 r1 e                GetPortVal(0x66,&Status,1);
2 {  |7 `) x& ^3 Q2 P                TimeOut --;% X2 n- {/ b! z* [2 H3 m
//                Sleep(1);
, a, ?$ J" y, E0 P8 e        }while((Status & 2) ==2 && TimeOut>0);* P: G* \( n3 l# ^
6 R2 O- m/ V& d
        SetPortVal(0x62,(DWORD)Data,1);
' R: ^) m) E. i& A$ S}! ]' q0 _9 k6 C9 b+ M5 E4 z* l
unsigned char read62()
3 z5 Z7 F$ U, n2 l6 ^+ a{  [4 ?- a- q4 O: F9 m/ A/ q2 {5 \6 O
        DWORD Status,Data,TimeOut=10000000;+ @4 N0 }- Y' \2 O
        do
- q# O; z, R& F% @2 x7 u        {( z% y! j2 C6 c
                GetPortVal(0x66,&Status,1);
" t8 q7 E, M" U6 n! ]; U                TimeOut --;
# D% i( ^* U4 J, B  `" B! Z//                Sleep(1);% c9 z$ a0 t& {  P6 z
        }while((Status & 1) ==0 && TimeOut>0);3 |* @% x8 I  h, i% |4 n

( m+ i. q! o! Y8 A5 M! a& T1 E$ z0 G% }( v9 Z0 O
        GetPortVal(0x62,&Data,1);
) O' c0 W7 e- W: y% g  I# W        return (unsigned char)Data;
9 ]( U% w, v$ A) E}+ Z: K" Q/ m9 a' n3 R3 ~
unsigned char read_ec(unsigned char index)
6 n9 c1 y: g' v. o0 Z{$ G. m& k! w$ u3 m
        write66(0x80);0 Q) `' I& S# S. H
        write62(index);7 ~1 H% M* M/ }# H
        return read62();% O6 \) h/ h& H
}6 _! O; d6 ]0 d, }" P# a" @
6 v! q- k$ u1 L) U9 Z
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 709) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
# V) a6 P9 ]/ `  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。( g' a& Y0 W3 e- w! _
& P2 }8 G  |! J- }! x+ N
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 : D  m0 U- f- e5 F& T

) f# }4 f, W/ ^' r1 r0 z
3 r" Y: n( M: O( ?0 {4 C: ~您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
% Z/ d% b5 }5 y5 C1 G! }6 m

' n# [0 E5 c+ s9 s4 c+ `; B1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,& x. f5 F- U4 V; [$ w# k

+ |5 C9 o) E. z: m8 w/ [2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
& `0 Z4 J  m& g" f$ m5 T
+ f' V" \5 f  w3 q$ m; v, P! x3 N3. Then set bit16 of the IRQ to disable it.
' Q! l8 q- s; K6 i3 ^9 `5 a
) x5 H, f; U; b9 j: x    a.. Offset = IRQ# * 2 + 0x10;4 m5 z% Q) \7 l* j5 @. V3 }. {
7 t) M' |% H: L* k
    b. Write Offset to APIC base,) C3 Z: n2 k- j3 P8 P6 n, x

  Y+ {( ^" d/ R$ ]( N: ~# Z5 t  B    c. Read Data from APIC base + 0x10;
7 R- a8 Q" \7 H6 ^0 ^6 f" n" |! L4 Z8 y9 J( G
    d. Or bit16 to Data;) T% x8 V7 c3 p
, D5 Y9 m2 }, _' z
    e. Write Data back to APIC base + 0x10;0 _4 E2 k* J+ a7 o1 J3 k5 V
3 Y. Z/ f+ E# d2 m+ c, x

$ s  e2 n- h! E! I, {, Y
! r( ~' V+ k" _" d( v$ sYou need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 7 ~3 G$ Q% {' O7 ^6 @: P* Y0 _1 r6 J
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
5 k7 d* K2 V) O
6 \3 ^# E# d1 S- m
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。0 Y$ L# b0 N& I- T4 H* w8 N
==============================================  s$ d# E2 s' H% l! g
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。; {8 P! ~) W2 T6 `/ f: D
+ `) d- X# |. Y$ p  u: R7 p% E
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)' x: o/ C( I; v
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。$ H0 ]  b' c0 |9 ]

% O* b8 ~" @1 a6 U因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。* N0 H( z9 Q- |- X! }/ u
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
3 g! c( ], n& c# L4 x4 _( l1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。7 G7 D  c. {, 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-14 14:49 , Processed in 0.056450 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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