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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
3 |# n8 }: {3 Z/ H/ E) ]6 }4 a. e#include <Windows.h>
! \6 U- G) J  e" u( i& ~; S#include "WinIo.h"  G8 ~1 P$ A( p/ ~3 d) e6 o
using namespace std;; M. y" W9 {+ Z0 Y* n+ b9 L0 m5 ^' I

* L! L. ^+ z; [- m3 B6 l#pragma comment(lib, "winio.lib")
' X% o( O( M3 `6 x6 G5 A9 H4 u  ]% b5 K' `# M$ p" D0 |7 P

9 A( i& B5 z# I6 Q% s7 }2 u0 Dint PMU_SC                =        0x6C;//命令端口
" c# c0 [; A" `6 ^. ~. m% xint PMU_DATA                =        0x68;//数据端口
+ o5 K: j7 p# j  o8 D, ~" vint RD_EC_SMI                =        0x80;//读寄存器命令- K4 N- B+ S+ b0 {/ ~9 }" e2 ?
int POLLING_DATA                =        0xE7;//CPU温度寄存器号6 s$ K: x3 t! t* _5 D" J, z, K+ m
( }3 S" g% t5 u0 L0 \. f- i' H. ~* t
DWORD dwTemp = 0;
% r9 a6 D. p$ v) @! B1 _  J9 n/ F8 X- H+ }( K1 `& ~& N0 d1 z
void PMU_Wait4IBE(DWORD *_value);
$ V& S8 o1 H' k" ]8 e, }void PMU_Wait4OBF(DWORD *_value);+ M$ ]. A( y# e

8 S% z3 }# z- \2 R) W4 u
( ?9 G0 j% ]$ v4 |( \' U: }  vint main(int argc, char* argv[])
; h2 H) F' N6 o{
! x& m- n- ]+ i0 l/ E! }: h        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;  r. h$ e5 N/ g& C4 y! L! f3 w

  ~0 W2 b; J: G       
3 y8 F* T% [" n8 n- M: r; C) R        //1、mov            dx,PMU_SC                //
4 R2 h5 E! _2 R& D: t( f2 ^        //2、mov            al,RD_EC_SMI        //- E: i+ n7 T' W* ?* m7 L7 l
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了% v& u& r" h( r7 R
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
5 Q2 A3 U, c! W3 e  `1 l  j8 Z9 {1 p2 M6 z8 V! A* X
        PMU_Wait4IBE(&dwTemp);7 a8 U# T, q) N1 P/ a
        4 b+ x5 ]0 L& o- T! k1 H
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
( @4 o: r9 F# u  X9 |# i- g" `$ u% J$ x) o
        PMU_Wait4IBE(&dwTemp);
2 X) j+ `8 z, c0 `8 o6 ?        8 X3 |9 }' @9 r% `
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
* a; G) L0 Z, @" O
# Y$ y8 c; x0 J" d% F        PMU_Wait4IBE(&dwTemp);
7 i! A4 O  {/ \8 {0 P. F3 p; u* C: t
        cout << dwTemp << endl;               
& x, o0 U+ s: w3 _3 m* W: o# }. U( H
        ShutdownWinIo();
; N3 N2 x$ I& f" S) x, t" I
4 ^1 y, Z# l$ ^        system("pause");2 A4 w$ U/ p. N  o' @4 _
' |- ^+ Y6 k2 \4 D
        return 0;+ b0 I# [* \8 X. t5 e0 Q- X0 @- r0 ^
}
8 g0 L  Y) Y! ^
$ t! ^. v0 y; [# `void PMU_Wait4IBE(DWORD *_value)7 m7 n% D: R, y+ X$ R
{" [  t0 U* g. f2 k
        //#########################################################   
) y' F' E5 U0 m  U' O1 u# s        /*$ K! G5 d5 z8 g* b3 \$ J0 S& ?
        pmuWait4IBE proc   5 O1 `7 N# A. s. q, I$ @% b
        PUSH        AX   ' \/ e% N3 X9 F* X# P
        PW4IBE:               ( j' ~' w. @/ J) g2 _
        IN          AL,  06CH                                //Read  PMU  status   
% h& C; |& N" k5 p        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
! ?& P/ U; A! F1 o" x  J        JNZ         PW4IBE                                        //Jmp  if  no   - m( v7 ]( N' _( S: C& f
        POP         AX   
1 I3 r" V. T) G" ]2 [- u+ `1 k        ret   ( k' T3 e" O' p3 C$ \+ r
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
/ b" r3 y/ g, K  d        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空; @. o) ^4 m% J6 A- @# M& W7 ^5 B1 P
        //######################################################### 1 E0 H; T, o4 I; m4 C: O
        /*do
3 \; Y. m  Y- X        {
1 G4 y6 t+ S, K1 h8 x                GetPortVal(PMU_SC, _value, 4);: B8 X1 H" o) U! s( `
        }
" j: u6 K5 ?9 ]        while ( *(_value) & 0x00000001 );*/0 A1 _6 q& t& f' }+ l) N" \
        DWORD   dwRegVal=0;
, G# `' ~5 i, ?: r        do
2 d8 T% T7 U& O9 S# ]        {  6 D) X; {9 _0 y. U! R8 D1 _3 ~
                GetPortVal(PMU_SC,&dwRegVal,1);
# s+ x7 s% w! X1 l/ A, E3 H        }
" N8 r1 a* q, }% u6 f        while(dwRegVal!=0x2);
: b4 M) B' }; h5 u9 R' A3 z9 d( d; J$ J/ I, n2 [
}* Z  r8 G+ ]5 l3 ?

  w) G$ p! b6 I0 t) z1 @以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。3 H5 ]: V5 H: N8 ~" O4 M: [
所以变成了死循环了。
4 O& O$ e' W& Q1 i* q
" P5 D* }( _2 S我对硬件编程不懂。又不知道从何下手。
( C( X% n8 u3 Q+ u我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
, }6 p. e: O2 I/ S) c! T1 K  P/ Q但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。( }: P4 S1 W$ k9 \6 M$ o( s4 N% E" t

1 ]7 O9 ~' c- }0 [! V* V我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
; m6 O% H, M5 E* n; \并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
4 }1 X; c* @6 @7 {9 e: ?. d
- @/ s: \) ~: Z感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。1 B% e3 p  c  F9 n2 T$ t) m
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
- q7 q$ Q% @! ]+ n' T& A3 _2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突7 B) w: Q7 B$ G
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.) r7 m+ [0 b; \1 }% Q1 z

- ?4 D$ c8 ^% b* p: {) X8 x5 A所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
  z- |! `8 T, z0 ?' ^0 T0 o
& q  Q$ T" P/ Z9 \# N那么有些什么可行的办法呢?6 {; G4 U5 @. f) j( t
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。# Y& \" v: Z. Z0 V2 }( v. [. y

# E- A& _/ j3 @它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
/ t5 C( \6 h# E9 d
% F9 T' q4 V, i# J1 n/ q那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420: H! H8 o, Z+ L  t2 A7 Q) q

7 i* [2 V. Y8 ?1 G1 Ohttp://www.ufoit.com/bbs/viewthread.php?tid=452
$ W+ y4 ?+ |( l
1 Q6 ^; h. }+ E3 F- P! ^1 qhttp://www.ufoit.com/bbs/viewthread.php?tid=241
( k3 Y; n0 C2 e1 I/ ^: }: S* K# l4 }6 B+ s2 G  C
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
  ~9 q& F; D! m$ _$ ?& {, f$ U. u! q( L& v0 L
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。! K+ ?& K; B) p
2、Driver最复杂,也需要BIOS配合,推荐。
5 \5 k" [! ~( e& l. ^: M3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
. A  C7 v1 r7 a4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。  h  [$ v  g! O4 a
你可以混合使用。$ D) ^  t: d, G  z7 b2 p
: y5 N5 d. C$ g; ^. D$ y
===============================================================  ^% M0 k3 f" E0 m) J
管理员的这句话:
8 {* x7 h% C& ~% v- z8 Y: `- f' I如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?& Q$ R: J/ M! H. K8 i
4 P9 q1 p) q7 s; X
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵' ~8 ~1 N% R% I! c6 l
% R( \: H9 h. L/ p( D* v
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269" g( q/ Z# G- g/ N
) f- o, e+ G3 H/ z# N. @
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
# Z2 ^! @; `: E/ v+ l$ q9 A  _  }! {7 E+ k3 X4 B
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。. e5 `) I: X  i$ U( W
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
; x4 \: p# [$ r+ P  z* f) ?, X5 E1 v3 ]
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 / X( w& r& \% @! S: A; }
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。% V2 b' p0 s/ q6 n; D
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
' w% [- d3 a* J% Z7 k  Q( G
5 G  F. I; Z2 f
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。5 ?" P" J1 q$ H& H& n5 c* [4 ^

  M# M" l. o7 R3 dvoid write66(unsigned char Data)
3 j/ ]3 K3 u9 o! q% z) V" ^$ c6 F{
: H3 B8 s1 N- r- u  Q9 |/ q- q        DWORD Status,TimeOut=10000000;' w. d5 \1 w: [3 o% C- f  n( B/ u
        do
5 l/ x, C/ ^' m6 V        {- \7 `& F! S' e# H. F) L
                GetPortVal(0x66,&Status,1);
$ `9 i- {% k. \  C                TimeOut --;: B9 }) n4 Z# q) O9 X
//                Sleep(1);; S  }* T9 `( B6 |
        }while((Status & 2) ==2 && TimeOut>0);
1 }" o9 t% l- P4 [4 N3 V% ^! V0 n& W3 C5 a
        SetPortVal(0x66,(DWORD)Data,1);# {4 `# S, g* o% T$ k
}8 j6 @& T4 m3 J4 v# T( e: F
void write62(unsigned char Data)6 O# x& n$ k  \4 }+ P
{) Q) t$ G- _5 {2 E9 R. B- ]7 p
        DWORD Status,TimeOut=10000000;
0 k# H7 ?' [0 Q1 ]: M        do$ U7 f" {) i- _  a
        {
2 d, a% U  C5 b& ~% f: s+ `' N                GetPortVal(0x66,&Status,1);
( U$ o4 Z7 \+ G                TimeOut --;0 j5 U; s) |" ]% `) T
//                Sleep(1);
7 m) f& f% E* u  e, o5 A        }while((Status & 2) ==2 && TimeOut>0);) E+ i8 q" R. C, {; s6 r/ \- `6 X& R) }
5 ]0 j) k7 b: \7 w- \  z% c
        SetPortVal(0x62,(DWORD)Data,1);
! N1 C# a5 N9 `* ]: i}, L; f5 {+ w6 q0 h( Y
unsigned char read62()
% q" X# f" |& h, }9 z* g8 J/ U{
  D4 F- h$ _4 K) o        DWORD Status,Data,TimeOut=10000000;' n# {& N* `+ r# r5 m
        do. ~  n. e7 I4 N
        {
- e! i+ x2 q% u2 }. f                GetPortVal(0x66,&Status,1);
2 G& O& f7 s- k                TimeOut --;
& D" c& M2 D8 u8 i//                Sleep(1);
' g; p6 ?/ t. n        }while((Status & 1) ==0 && TimeOut>0);
4 r- f2 r5 L7 _# }6 a6 h" i1 L6 X4 u5 o% X
  {8 a3 h2 o& v
        GetPortVal(0x62,&Data,1);# M6 m! R$ @) z' G) G
        return (unsigned char)Data;
1 E1 u& _# M+ F/ A7 @' z4 ^+ ~}" D9 c8 v% J0 [- f# k
unsigned char read_ec(unsigned char index)
% o* _+ E" g* w{4 c" H! M* p7 N; l
        write66(0x80);! t6 c5 t& J  R8 L3 R* v* `
        write62(index);+ M. A: y1 r; S. ^
        return read62();: X4 R7 k: ]) z" [
}
! i% T2 X8 N0 L0 w6 F8 g2 K4 I+ z  b  e! Z7 e& L% ]
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 0 l) W+ k7 }! P2 Y6 f# U
' d4 s4 t. L" U8 d+ @. a2 p
9 @0 a' l: F+ g8 M2 @; M5 j+ n& _
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
( X2 {3 a9 ~$ ?, ]' y# c

$ F$ p% P1 @# K% e3 l/ X* O1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
5 H& R/ y/ ?/ Y  G" e/ p" c- ^  ^' I, m
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
# p5 G# i  s" ^# V" E. U0 k. l* T7 g2 S- E
3. Then set bit16 of the IRQ to disable it.
) I+ D: ?) X+ y, V! P2 q: W" A$ f  T$ h% {0 B: k: n
    a.. Offset = IRQ# * 2 + 0x10;  {4 N2 }! {" N4 W9 ~$ i4 ^

2 Z, R& P. |1 l: a) B- z    b. Write Offset to APIC base,
+ Z2 ~; I3 T& H/ ~4 k% r$ j7 F, ^* g. C) M  v+ |! l+ \& I
    c. Read Data from APIC base + 0x10;
& n8 \& _; V  `: x
" B' a" p8 U5 Y; x    d. Or bit16 to Data;
0 G0 A2 e. Z1 N/ `9 W' J
, Y! ?; f0 `3 W1 a9 d; X    e. Write Data back to APIC base + 0x10;
  p5 i7 }: b; E0 t( [/ E
+ ]+ V( Z3 X& }, Z% B  u 1 n. _# P9 q! A" Y9 p5 m, l5 i

. A5 t/ J* y4 J# M) |$ `) s0 lYou need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 - U% d5 ?- \8 ?. v
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
7 S" y, @9 S' x* A1 U% w* S
3 n# m5 |; n) o
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
; ^5 m: ~2 o+ B" u0 F==============================================
4 h9 j3 {& E. p0 ~1 C, P 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。: p( |; b1 K' T# k5 }* _
2 e( {9 X8 S/ n
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)( V& H$ O# P3 _+ k: Q6 o. ]
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。& K) J1 l# P# X0 c, |' ?5 x

8 O- g, k- I7 I, I) b因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。' E  Y; X2 p5 C( N. k' N- x4 l
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
0 h0 F1 r* i0 ]9 s# D& |1 s1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
: G/ \6 R; U. v# j1 l3 ~4 H: F2、新手不要把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-5-20 17:47 , Processed in 0.029880 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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