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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>3 A; W+ e3 f: w& E1 C
#include <Windows.h>5 p- ?3 n9 Y3 x% _" Z. P) @' C
#include "WinIo.h"
( O3 D5 K' S0 g6 Q: U/ g! k& j" ~using namespace std;" h5 @+ @$ D1 {
( i$ ^; P& \& M# A
#pragma comment(lib, "winio.lib")
( c. _+ Y$ y4 z) h1 [
2 p  \' \3 R# [7 ?
* P3 H9 N' L) e- P. F, ~) Sint PMU_SC                =        0x6C;//命令端口
0 L) o; L: H, j! t' l: H1 wint PMU_DATA                =        0x68;//数据端口
8 r0 {) A0 l" j- W) t$ Eint RD_EC_SMI                =        0x80;//读寄存器命令' _1 K' J8 Z  m4 [7 m
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
9 G+ ~, Y9 C- {
4 P6 |, y; Y7 \1 C1 |+ a1 IDWORD dwTemp = 0;
7 {3 i+ X1 C- ^' P
! v: X* u, `7 R* hvoid PMU_Wait4IBE(DWORD *_value);7 y" q  |. P- n4 `% y! B
void PMU_Wait4OBF(DWORD *_value);
* Q: a. N2 q& P6 S6 R
: R% V/ P) V: {3 _+ H! t6 B) F' P
; A# K* m  c- J4 d* I& o% N5 pint main(int argc, char* argv[])& `* u  i0 z" e$ U5 s- d
{
* H: Q8 h4 U$ h$ A- U) S  A8 l& I        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
( w. R% r3 d9 R; X7 c9 N5 i% s9 s
0 w, W9 L, i& F  n3 I       
/ u- A( W9 n! m. q$ ]8 t        //1、mov            dx,PMU_SC                //% T7 y- A  ]( b; M/ {5 K
        //2、mov            al,RD_EC_SMI        //" S3 N* m+ y- ~
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了4 X6 x" l+ i$ G& |7 m7 p
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。4 Z9 y/ R: b+ N4 m0 M0 j

! J# m& `6 [1 B, c9 V        PMU_Wait4IBE(&dwTemp);
- w/ J4 [) d/ y, u6 s        + p2 O1 C7 U. U/ Q
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
$ F8 E! V* \/ C5 w! G. X8 ]( _' B  H# Y+ a' `  t! L
        PMU_Wait4IBE(&dwTemp);
$ v- k7 \2 K1 }7 a        / i' I& R% w' S! ~0 i) t
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
! i3 Z* v4 E3 Y# O8 P, s: d  r
% M4 n' r7 q& ^: |; Q4 I, h3 a        PMU_Wait4IBE(&dwTemp);
, Y3 O$ C$ {- A; K  g, {1 ~0 J& y
, Z" ], p1 Z" G  r        cout << dwTemp << endl;                ; |: }! _- @  ~6 w) B

5 @1 _) x% V* s$ `        ShutdownWinIo();
5 H# k* W, s2 u' p2 [, ~# ~! B
% ], }- _7 E! H$ I6 I        system("pause");; W* a  k* _' o
/ b4 E, G  X6 g% L
        return 0;
( r0 q0 s3 D* b9 P: _# }}
, k6 G  c. K) ~- b1 ~  D& ]
$ n% P2 L  n0 D  L- I2 ^1 \void PMU_Wait4IBE(DWORD *_value)) y' O4 q9 b$ U+ K* A/ p' @
{0 B7 x, R, T$ n( n* a
        //#########################################################   : ~! X( c4 S: p; X  h
        /*7 c5 W% g# [. i0 @8 G6 q
        pmuWait4IBE proc   
) V; ]; ~; A2 K/ P  d        PUSH        AX   : [4 |' u  p, N" ]5 \9 o8 g+ |
        PW4IBE:               
( e  W) N& s7 D1 O( Q* v        IN          AL,  06CH                                //Read  PMU  status   
! u1 U& t* C: T        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   ; J, ]7 d$ `1 H( I8 ?# w
        JNZ         PW4IBE                                        //Jmp  if  no   
: K' `( a+ t7 ~& f! x6 B        POP         AX   / R9 s) o0 o( m- b6 b8 ^/ `
        ret   , F1 u# E* [9 H2 `  B# o
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE$ Z- l6 W& {2 m" |  S
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
$ u# Q6 C, I% b. _        //######################################################### 2 M  x6 i$ `3 m8 W* g5 Y: r
        /*do
% h* i0 ~; x- [" v) F% I8 O' f        {& j4 v& H: P$ S7 }8 ]9 j0 b, U
                GetPortVal(PMU_SC, _value, 4);
3 [; v9 L) J7 k6 ~        }# h. @3 p# q3 O6 L# M( U
        while ( *(_value) & 0x00000001 );*/
/ a& [) v6 B: b# T& f4 s        DWORD   dwRegVal=0;, S+ N) z/ {! O' P
        do
4 ~2 Z; M% m; W$ K8 k. U        {  1 T3 U' Q8 I7 c8 T' V/ ~. o
                GetPortVal(PMU_SC,&dwRegVal,1);5 W6 G$ {9 {& b3 M0 _3 d6 x4 m( M
        }0 H! n+ K4 }$ ~6 q  \. n9 C7 X
        while(dwRegVal!=0x2);
7 n3 t" {7 O, Z, c
# q) G  Z+ _/ c! J. n}
6 ^! p% X# z( z& X6 s, j6 J6 S4 Y) v9 K8 H& G/ v: H
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
9 C" [7 ]! a) z- B+ `3 ]5 }4 C所以变成了死循环了。
, s# X1 C7 O3 l) u6 U2 U
" ?4 _- t, Q3 ]9 x& o我对硬件编程不懂。又不知道从何下手。# c0 b% J* p" K; D$ v9 u
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。8 t; G0 d4 c' x5 q* v
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
4 S( ^0 n% V( j: {( T9 ?( O+ V' N9 @' d. d( g/ o
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。( _+ l3 {9 P: S
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。# f* n+ {" A7 W# s0 U- R3 D

* Y* x% U  i  h( }  I" [感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。! V, B* G3 [7 U. z
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
9 n/ k' Z2 B9 Y4 h: k% L2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
# S$ c$ _( `( F: F3 z6 {( T3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
2 l5 n9 q! Y/ b1 U2 X) Z5 t1 b/ Y6 w1 o: A  G& k
所以.....呵呵
回复

使用道具 举报

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

+ e- P/ d4 P, g3 m, {9 q那么有些什么可行的办法呢?
$ {% g  ?# O6 a# q5 a2 Q6 G' u为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
8 e8 w) [# i' o. c/ _& o
% A2 M. {9 y+ l  p* @+ U4 N2 W它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
8 E9 m% R. K# v
1 l3 @. d! q" U1 H- ~' ~( l; Q3 K9 B那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
; x2 e9 w3 n7 o/ B& j7 \8 M4 G5 e
http://www.ufoit.com/bbs/viewthread.php?tid=452& S1 }5 Y/ V: @) B5 x) C% c  I

7 {, T* t1 \9 T( B1 k; a" nhttp://www.ufoit.com/bbs/viewthread.php?tid=241" t, R- k  X5 [$ m) v8 b
" w6 }: B: T1 ?* W$ L' M
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
1 V) ]& ?( g/ V, J0 V, n: c" q) o7 j9 v; c
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
4 v* t* _7 |- e' _0 c2、Driver最复杂,也需要BIOS配合,推荐。* ?1 [4 M+ E$ _, A+ V
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。4 R, l0 v+ X# s
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。+ |3 G0 Y6 J% i
你可以混合使用。4 [( c7 n& j" W4 I& B( h

/ m& W( a$ A$ H5 M===============================================================2 g# r5 J! A: a8 {: ~; D% J( H
管理员的这句话:- u' U2 g3 N3 B3 E. K; F8 W
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
4 l% d7 r/ R- p0 I! P# M
: ~+ o$ P/ J9 F* {$ h& ^1 i予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
7 [4 Z. v+ s1 ]. W  {0 ^! }
; V- e6 n: T6 s# H- U, |% B另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269, ]/ M# V1 w) j$ C7 t

$ `: E- x4 l' \# v, k. D这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?. A- P, @; M% L& H  I* _

& b9 r' s5 J' O: X" K还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。0 ?$ h: P2 `) R4 q+ X8 c( b
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?7 m4 i+ E$ ]. \7 L4 c! p
2 f& b/ s. [1 D5 _
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 $ Z) N' C4 Y0 u) y9 R' O
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。6 V, T3 ^7 u7 W8 V; y( V; h7 i
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
+ G( Z+ b3 i" C% B3 N
& a1 k2 b; d7 D0 }, P, c7 L
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
1 n% ^+ \, X' {$ l1 Y: w
0 e( B; s7 E. |" Z3 wvoid write66(unsigned char Data)0 K* ?/ y  X  V& Q4 p% R
{; [$ G7 A  ?2 x! s& w
        DWORD Status,TimeOut=10000000;
. X8 V! E( U! K0 N, i! ]        do
6 M# |  ]0 ]* n1 R8 ]' ~        {" w; e' u* z; ?) D  k( P
                GetPortVal(0x66,&Status,1);
5 z& j$ {2 s0 ]+ _9 ^0 u( O                TimeOut --;
' ?$ e: a1 K5 [9 r: F' ]//                Sleep(1);
+ @% j" P& S! N        }while((Status & 2) ==2 && TimeOut>0);
6 T# _5 N- L8 K7 P5 V4 a1 A
& O+ y% d4 N$ ?0 t        SetPortVal(0x66,(DWORD)Data,1);
' ?) p7 V5 J) Y) w}
9 e+ ^2 f7 P. F; E7 rvoid write62(unsigned char Data)
' C1 |' S- M3 K{. ~5 k5 Z& F  g& y
        DWORD Status,TimeOut=10000000;
9 {+ L1 {, S! B5 T, ^% o        do. k8 p# W1 r3 N+ J
        {6 [6 A: r' j& H% i8 E
                GetPortVal(0x66,&Status,1);! a/ }- E' I( `4 R- K
                TimeOut --;6 Y" t8 E5 E; s  J, K# c) r7 g
//                Sleep(1);/ ?" f3 w4 E) d. Q5 [9 t
        }while((Status & 2) ==2 && TimeOut>0);
9 d6 k! W% i: h* Z. |- J! `; ?0 L/ L
        SetPortVal(0x62,(DWORD)Data,1);
3 j4 ?; U7 R% B/ L}1 E+ ~, i- K% r( T, W# u
unsigned char read62()
0 ~7 h" c+ ^/ t* f+ h{  n! V* ^' I0 e1 V9 @
        DWORD Status,Data,TimeOut=10000000;: F, L3 G6 W3 X7 p; c
        do$ V5 ~# j0 `1 S' S, E$ I; F
        {
8 u- @" x% Q  ?4 }! g0 o                GetPortVal(0x66,&Status,1);4 K2 T2 \: N- o5 _: \
                TimeOut --;
# ^" C- n5 V! V! _6 H3 F8 n5 D) e- c" ~//                Sleep(1);
# [8 ^, K  I, B6 Y; C, T1 p1 n* J        }while((Status & 1) ==0 && TimeOut>0);* d& ]; x0 n- ]8 f) g! u
: z' O* a( U5 u5 [( [7 [) d1 F
" C+ n4 Q& h$ Z4 J
        GetPortVal(0x62,&Data,1);- q$ X- ?7 F! {* p
        return (unsigned char)Data;! v: M) @* [6 ]  `
}
' E$ e" R% q7 yunsigned char read_ec(unsigned char index)
2 j3 e6 P" j6 |% K{# o9 H4 y) W& c3 k9 B* C6 E
        write66(0x80);
! y0 y! _' z% i6 @) l0 K7 ?9 v0 \        write62(index);- |, R9 x4 g' [' m7 U' y5 J0 c
        return read62();
- i- u0 }3 k' W) G5 h}
$ U( l$ m6 O! r1 v  g. \* E
7 P& w: a0 \& `; y4 T2 z/ X- `( T[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

+ P# L' P3 ~3 i. A# A) r3 i0 U: I[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 3 R3 Q7 x4 T1 ?
* G2 R: e8 t( w" p% E7 |
9 V2 u8 d5 H$ ?' o6 b; i  K
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

- j" c1 ^- D" Q# Q
) T2 C0 l' V$ ~) C. e, J9 c1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
# x4 |) w# r% g1 E* ]1 z
! k& A# s# t& \. |2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
9 x, G) @7 [0 |; e
+ n+ K- x( \! N) I) h1 b: n- k3. Then set bit16 of the IRQ to disable it./ Y4 |# t0 D( l2 J) ^7 |7 q, L
2 W$ t; _4 u0 n! D
    a.. Offset = IRQ# * 2 + 0x10;
7 \' e# R4 N  H) B7 R% O6 t% `* O
    b. Write Offset to APIC base,
" N# ?5 f# ^" S9 q( H$ _6 Z; F* h
& H) r1 W$ Y- Z0 D* ]0 b    c. Read Data from APIC base + 0x10;
$ T6 H: K7 j. R- v' P
7 E4 U- h7 ^; m+ X6 s2 {    d. Or bit16 to Data;
3 G4 M( ?! j$ R& y; H5 [" y4 h* a/ ]: l3 O
    e. Write Data back to APIC base + 0x10;: r* Y9 P* a, \$ P  O
! {- }# }$ W& ?) ~1 b3 X
+ b1 X: S4 q' c7 W5 P( ]
: d/ N- a: x1 I3 g- m8 [/ ]
You need to check APIC spec for details.
回复

使用道具 举报

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

# f. Q' ]4 E; w1 v& S1 @3 E: b: g1 Q
( a5 q. Y. `' P 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
5 x/ i' f6 e! y: ?8 |==============================================8 u& n" W  }) ^6 H; W) v
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。, q% m. @! S8 d  _6 t+ e
* k& F  M2 g1 q# S* p
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
% \. V, n% F5 Q; V9 Y' k; Z但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。$ o& k; B* [7 G6 b# h2 E
- [% J4 d5 R% |( O
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
( g+ _  a; d9 {3 ?  q& t当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:, e8 M) {; z3 O& F" O) g
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。* h% }( J) R4 x* b$ F" q3 P$ E
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-3-15 06:45 , Processed in 0.624056 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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