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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
2 b/ Z% n. a# B7 y) |#include <Windows.h>8 r5 {9 T/ }% L* |7 _
#include "WinIo.h"
' q0 E+ [. i) {- }- Tusing namespace std;
& P7 g+ G- F7 u' W4 Y( \1 ~; k7 g. m& h* b9 ?7 Y# t/ o, R2 C5 ?! v
#pragma comment(lib, "winio.lib")
, P% H9 a8 G: X0 `2 G" m% K# K% C& }6 n& ?- r0 O' K
- j- I3 Y. z) H/ p9 J
int PMU_SC                =        0x6C;//命令端口! l; Z& I3 t- I
int PMU_DATA                =        0x68;//数据端口
# g4 w$ Y+ i. a" {- Yint RD_EC_SMI                =        0x80;//读寄存器命令
6 W. c8 f! t- N+ J  D/ Uint POLLING_DATA                =        0xE7;//CPU温度寄存器号
, ]4 \: a9 g8 l3 v+ O& D" @3 S3 A+ s
DWORD dwTemp = 0;
; @* @& @9 s+ u& B* q- t, h" O& L4 [  @! ^) y
void PMU_Wait4IBE(DWORD *_value);8 I3 M3 a" v8 \) `! Y
void PMU_Wait4OBF(DWORD *_value);" a/ i% X% x  X9 m$ d+ y; ^
* U' q) c# \( i# c+ x2 m

3 @) w. d  c+ b1 p" t! O7 oint main(int argc, char* argv[])6 r& [: z" ?8 |2 R2 x
{- B7 W/ w. M( C, X6 w2 g
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;- {) w/ {  j* S3 \( `
4 j5 K& U( C$ c: s
       
- V. G/ n, S: Z4 L/ o- U2 T  e        //1、mov            dx,PMU_SC                //
# j2 B7 ~* {& D& M4 x" Q; X        //2、mov            al,RD_EC_SMI        //+ r8 _. p6 Z: l
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
: U1 Y0 _% i& a( @. m* \% c        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
1 Z/ t' ~. N; ^5 `. P  \, x/ {2 b7 t: L+ C3 D
        PMU_Wait4IBE(&dwTemp);
3 i; ?( {8 x  r  u& S       
9 Z- {" ?2 Y5 d: e6 F9 K        SetPortVal(PMU_SC, RD_EC_SMI, 1);
% ?+ p& o( T7 R$ }/ p8 p& D1 i% W* S6 V: Q- A9 D  i. x
        PMU_Wait4IBE(&dwTemp);6 `8 P4 s( b9 a, ^
        ' y, [1 N# r5 S) H$ h, `
        SetPortVal(PMU_DATA, POLLING_DATA, 1);0 v/ j6 I8 N0 J! y4 @
3 |' U/ }: K3 Q1 r3 d
        PMU_Wait4IBE(&dwTemp);
9 l& j3 s& G  S3 u3 _/ s
# r1 M$ q8 J; t9 X5 D. b' X) }        cout << dwTemp << endl;                $ v2 R+ B- U/ @& W# _: `

9 Q3 X3 F- W4 e" Y9 K        ShutdownWinIo();% {% Y: z( e( R  L' G: R8 q

  e0 Z/ g/ N7 b2 ?' s$ c        system("pause");
( [+ w/ H6 |5 d- t2 U7 O4 H; N% F3 L* K* }) L. f# R+ U
        return 0;! {# w4 O" y: R5 Y% c& M
}. o$ }( [( F1 v% Y: d2 b

) ~- K" h- l  j. ivoid PMU_Wait4IBE(DWORD *_value)
& q; D5 L- ^* y" Z- Z- L& g9 @{
9 S5 B( X# m% n) u' _) ^        //#########################################################     k  t) P8 p# ?/ U' m& K2 G8 U
        /*
, m; p- S9 d+ H+ i3 w) b        pmuWait4IBE proc   ( e/ ^& E4 n+ f9 h  f
        PUSH        AX   
% Z! `1 W, h! E& f1 l4 h+ ^5 N        PW4IBE:               
+ R7 C8 Y( S% i6 O        IN          AL,  06CH                                //Read  PMU  status   
" D. X$ Y& |/ p: H! s3 M5 B5 _, `6 a        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
' c  {6 p( Z+ p% V0 Y        JNZ         PW4IBE                                        //Jmp  if  no   0 {5 A* y/ `; H
        POP         AX   
. B$ q- @) b5 N5 S        ret   
* ^2 t  V' \6 k1 \1 N        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
: I0 y& f4 b0 k        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
4 O! |' l; j/ f' U5 q- H: u        //#########################################################
: e' O- j1 l. Q6 o, f        /*do
4 W2 ]3 i% i6 g        {
; ?8 D6 S! `2 Y2 O' h) k# g( W                GetPortVal(PMU_SC, _value, 4);+ w3 U( E) ~! r- J. H
        }) Y  q$ |! j+ ~. N( D& W4 m# {9 `) y+ v
        while ( *(_value) & 0x00000001 );*/6 k, m* x) s) v
        DWORD   dwRegVal=0;
2 R& m4 Y0 z  L- Z1 f5 t        do
& \, X& |" I6 c5 i" s: c4 Z8 H. L        {  1 ~7 x' Y' A% F7 {* H+ B
                GetPortVal(PMU_SC,&dwRegVal,1);2 ]% V- v0 q# J+ s% q
        }# n; O! s" X7 e# R3 s- O
        while(dwRegVal!=0x2);; ?( S" u/ _% W4 ^5 d3 ]: F

) O; Y$ T" z4 P+ e}0 j& O* O) P6 G- L" b9 h

' i8 c9 T/ t' b/ t9 D; B. l以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。! e2 J0 S& \4 C# W4 l6 ~
所以变成了死循环了。
  K" G: a8 l" Y! L% F- w7 w1 m" m
5 u) H) I1 V1 L' k1 ?, R我对硬件编程不懂。又不知道从何下手。0 P9 Q! g% h4 b5 ], ^( O
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
) G! n5 b  W# r$ ?" R9 k- m但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
3 \; T- k1 T, ?  J" D- M) L# f8 c, N2 P
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
) O. |* M, \8 j8 X1 N并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
. E) j5 G3 m- l* K5 s' n  Z7 e$ m6 y, f8 J& B" v. U
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。5 s" V! M# v2 I- k  i
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.7 h' c: K& s, Z0 |. G
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突# S6 F. Y) ~/ A  N% d# o- o# D
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
- r1 I: W# A0 F2 n5 I0 T" S. g% c& W4 S
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。+ h1 P1 A3 ?  |

- ^+ W3 }1 O+ l那么有些什么可行的办法呢?% e& n. R2 Z; y5 ~0 W# l1 D
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。' M) |' E) _& Y; f) K7 A) {
5 K7 k5 t4 |- U; H4 V6 C9 P
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?2 w1 `& @0 j, Q% q  V  }

: d$ m8 C+ ]  j. H/ A那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
5 F' x4 n; X& L* I! i) N# J  T4 S! w, f, S7 y
http://www.ufoit.com/bbs/viewthread.php?tid=452
5 q# m1 n8 X0 M1 y: {
  O- c; C$ P6 j$ T! @/ ~http://www.ufoit.com/bbs/viewthread.php?tid=241
' F+ L( [) C3 }: T- E% x9 R3 f
! Z# `/ D/ t) c: b: c0 m( T看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。$ X( ]( @% s# B, E! N& \

+ |# U/ r% U- [  ^3 A6 {+ a1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
& x1 I2 D; i5 \- L3 w4 b2、Driver最复杂,也需要BIOS配合,推荐。
& h( h4 w/ U) k$ \* R2 M3、Windows API只能获取到特定信息,不需要特定的BIOS配合。7 v4 i' B& V( ?; w( {
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。2 T  p, J# ^4 b' B# ^. z- U, R/ P
你可以混合使用。
9 O! q3 O( T& e" F0 K* w. t9 b4 }! T) O8 F5 t% R
===============================================================' w1 p7 @: u1 m& p' _
管理员的这句话:
7 O- \% e+ L7 s如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
2 m- a# z+ _6 Z* @ " `" x' ~5 A" G) a7 }& f, m
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
3 A5 f, T- r. t' b! ^8 R
/ ~/ J6 R% m: x另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=2691 y5 e/ \% X& N1 N" ~! s& t5 k

' v5 _" q% H0 Z6 x这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?/ g6 X0 c) b# B9 |7 j
( S( g8 q' z; W- g# x0 u; k7 z1 w
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
5 H4 l. d* q" ~/ d里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?$ k4 Q% g; d0 v9 D

) ?. V4 P' z( |7 t  ]我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 2 P! D) I& [6 U7 _- G, G
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。8 n& J2 w: n7 q" k5 Z
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
/ ]1 I* d+ z; u6 C$ j3 u  s
$ E. w2 Q+ A! D7 ?! @1 u, B/ n( A
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。! A6 t- ?, _2 u  `) y$ b/ I6 P' x3 {

+ o& `" d: E8 n: v; @3 i( Svoid write66(unsigned char Data)
& _' V) e8 a  p0 y{
* \9 k7 h" t. E: v" f        DWORD Status,TimeOut=10000000;
( {7 m3 B* W. c2 D5 E! e! x        do" a. H7 z  V, k# B: n7 q  R( I
        {
2 U, m3 F7 U9 J, b  h5 L                GetPortVal(0x66,&Status,1);
& P& c& c; L5 t  Y; B& s( R% F' N                TimeOut --;; ?; _1 @' j( {  m
//                Sleep(1);
' U( n7 J3 L. _        }while((Status & 2) ==2 && TimeOut>0);
+ T* z; v! V$ g0 `
* d* ?# U& B: v6 o9 z        SetPortVal(0x66,(DWORD)Data,1);
$ v" S8 O6 v9 O% i; ?* E; ~}
. [; ]) t+ {' U! `% kvoid write62(unsigned char Data)0 E3 B/ Z/ X0 g7 [0 P
{
1 t5 S% P, n8 n/ W; x6 K3 g# W+ L        DWORD Status,TimeOut=10000000;& V! m0 i9 N- @; C7 G9 R7 Q3 q
        do
% H: |$ y2 ?& n' M) b# Q        {  M2 R: P6 K8 `9 O" [+ s
                GetPortVal(0x66,&Status,1);
$ a( q) ^8 g+ V) _" L                TimeOut --;
1 Q- j/ V! Q! g//                Sleep(1);; Q& y( {6 s6 ~1 o/ Z  t
        }while((Status & 2) ==2 && TimeOut>0);, g, g' z$ q7 F$ \5 g3 }% ^1 P
& `7 u$ v5 _  `: m
        SetPortVal(0x62,(DWORD)Data,1);
, @" [& r. {9 s}6 P( U6 B# `: W! Y/ g
unsigned char read62()
. m% B) Y( j1 x' ~{' p* g4 ?0 w+ \- r! e
        DWORD Status,Data,TimeOut=10000000;% a$ G( H. q! X: G* g7 P% @
        do
7 A* f" z* u! w* _: u4 g        {
; K4 d0 i, j6 l2 s                GetPortVal(0x66,&Status,1);  t1 o0 o9 q' f5 U1 O8 }
                TimeOut --;
4 q) M9 y! a7 z1 N1 F2 E9 b//                Sleep(1);
6 n) A6 i7 _! Y! W; H$ s        }while((Status & 1) ==0 && TimeOut>0);
" t) _: @. K9 c: ?" u( |6 B& g% L
, L( q7 A# e. W  b5 F0 P" b! V( j* [' l* n7 w; h, C
        GetPortVal(0x62,&Data,1);
4 _; k8 d: ]' @& {        return (unsigned char)Data;- M2 g9 p& E6 l: d
}
% x4 J- Y8 ^# p+ c7 Punsigned char read_ec(unsigned char index)
- M2 L2 e8 }3 q6 G; O# m7 D{' B" l$ A1 D/ m) y  h! d
        write66(0x80);
* m, @; x& _1 k1 y8 m$ w        write62(index);
: ^, n  }- G% ]+ D% X! m        return read62();
) o+ X" {! I& U+ g) j) s7 A3 c3 x}
$ t/ `$ I: p5 ^) x* ^2 D5 m" b5 b4 a: H/ \! h
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

3 ~# v* O& V' d: i# |" S[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表   n* x$ E5 u  G; Q% |
7 D7 `: }* H  A( C

! O6 D' v/ w- G  k) E您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
9 h5 A8 `4 H* K# l
+ ]4 V, I4 M/ L$ Y
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,) o5 ^$ o% @' ]2 c- j! d

; v; k9 O8 l4 Y3 `( S( s2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.! L4 F4 w' u* X4 S5 w

2 q+ S- O0 ]% N3. Then set bit16 of the IRQ to disable it.
$ X4 [3 u, E* O0 H3 p/ V2 q# ?
! W8 o" g0 u9 L( Q9 j  M' s! T" L    a.. Offset = IRQ# * 2 + 0x10;
2 f/ E; i/ d7 N3 ?+ g6 v7 b' S" v6 ?
    b. Write Offset to APIC base,; f+ t0 Y& I: s# x
  i5 e) {8 I) K
    c. Read Data from APIC base + 0x10;6 Z# L, s! t7 b0 G9 H. J+ f

( P' k) j4 R- L+ q% t$ C    d. Or bit16 to Data;6 u/ w" T, Q/ I8 [' w( B
9 E) D; X1 p6 y* l
    e. Write Data back to APIC base + 0x10;
  L* q  {9 r- |8 C! q8 Q! X+ u( }' C# A6 J0 @+ |7 M$ c/ Q
1 t& M/ J5 v6 \: d. `& m+ e+ U) h9 s

8 V/ s* x9 c' \You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
2 @9 ?3 r/ @5 F5 q+ W: h0 m545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...

+ R  g, [/ A' n6 c9 m' b3 O& b& D9 G
% {# h0 k4 J1 N 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。/ ]. A) z' L! D7 v, }! d' S1 b) x
==============================================* x7 k7 V# s6 @
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。" s+ W$ q) f2 D! `0 U( Y8 S
  O+ h" h+ @3 v! w
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)2 q8 J) H! _2 u8 K: L& b9 Y
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
# m: s' X, s# a$ N, j9 y
% s, i2 e6 n& _- o因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
- X3 }* }" n6 ?当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:3 k* ?+ e4 }! r& t
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。% @( \" T' m3 P& K* j
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-2-22 02:08 , Processed in 0.074586 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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