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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
: P4 P0 a/ r4 s/ v6 A#include <Windows.h>
0 r+ c1 s0 t9 K7 D9 h#include "WinIo.h"
! D% w' `$ w# b5 J- p7 i  Q  Lusing namespace std;$ d/ U' p3 M1 N4 Q1 |1 b) h7 k' ~
1 `6 Y* n, `3 U1 L7 i! c
#pragma comment(lib, "winio.lib")$ s' j8 T6 J( S5 M

) x- F. o4 `# r  o3 K; I( Z* n; F
int PMU_SC                =        0x6C;//命令端口
3 R# i; \$ L  E' @" jint PMU_DATA                =        0x68;//数据端口/ d7 o1 Z/ @9 t& o) ^
int RD_EC_SMI                =        0x80;//读寄存器命令
/ b1 l) g  P8 E7 Gint POLLING_DATA                =        0xE7;//CPU温度寄存器号! o: d, ^  c  @5 Q( v3 M

5 i7 _+ v# W* W+ r& o- tDWORD dwTemp = 0;
( u2 r- |" H, }2 u! R1 _8 o0 L# M6 J$ ]( P
void PMU_Wait4IBE(DWORD *_value);& z! e9 F# J& z7 c- B
void PMU_Wait4OBF(DWORD *_value);3 g1 Z; H+ ^1 h  K3 l) N

! y# q* |5 a8 v1 G; t- p
" D. R% x; Q2 E. yint main(int argc, char* argv[])* H* R8 l: E3 t' A
{- K' o  q3 e8 p
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
4 l6 Q. v, }3 {6 z( }5 C  Z1 H, h  f6 N5 q) e1 J: K
       
2 t. w5 h/ z+ b        //1、mov            dx,PMU_SC                //' w9 e- c) C* p4 b# u, w
        //2、mov            al,RD_EC_SMI        //
& f9 O3 S. `4 C        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
$ \1 N4 L3 _( C  J: t( D- e$ \        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
2 X: T  N2 S4 U  g
: k. f( B! O$ @" V5 W; H& Q. n% b        PMU_Wait4IBE(&dwTemp);
; k2 c% L- v9 u: {1 W        & [0 \1 {  _4 {6 V9 t
        SetPortVal(PMU_SC, RD_EC_SMI, 1);) }7 [4 R& }2 d' ?
6 n$ F1 C7 E) {% L0 K- c
        PMU_Wait4IBE(&dwTemp);- ^: A7 `# l" {! y
       
% t+ d7 {0 d2 ~/ `1 j0 V8 c, C        SetPortVal(PMU_DATA, POLLING_DATA, 1);- s' S1 x9 T/ C7 l+ O5 ~( R

% p1 T' E5 `4 ]9 [1 Z4 I        PMU_Wait4IBE(&dwTemp);9 e9 V- S  G3 @( V% O

8 E7 q/ _* x2 Z/ x/ Z9 k        cout << dwTemp << endl;               
1 M( g! t3 |% x
8 j: S6 w1 K9 {        ShutdownWinIo();
# {9 H( ?4 i$ T& p6 m) D0 S8 A9 i7 v  d" b  K; @! a( B7 p
        system("pause");
3 F+ ~( a  n' H
$ u2 x- ]  I* F- J0 e6 T        return 0;
9 c' ^- S2 @5 }5 q) v}
" u! j! Q: I) ~, Q
$ S% @9 z/ @. k6 A- A8 fvoid PMU_Wait4IBE(DWORD *_value)
$ @$ E& N9 A; }) C1 q8 u{
4 A. v  T9 O# C+ Q        //#########################################################   : U* ]  @: K% @+ i3 J
        /*
' ~+ l5 M1 r6 `# |        pmuWait4IBE proc   8 P' |, s; v, g
        PUSH        AX   
* Q! I% |7 x- D* h  n% N        PW4IBE:               
% U0 T# [- G0 m% U        IN          AL,  06CH                                //Read  PMU  status   . x2 c1 L) c! p
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   ( E7 J$ Y4 u/ M6 Y$ F9 G( z
        JNZ         PW4IBE                                        //Jmp  if  no   2 F" U; T# L- Q+ n; r& C
        POP         AX   
9 g* A/ i* M7 ?        ret   - H9 O7 p0 B" I$ A
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
. \8 g9 @+ ~1 @5 ?0 n        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空+ ]" \7 l' C# G. m# u
        //######################################################### ( I, ^! z7 V: n7 Y3 p' p
        /*do
4 e& B: v5 F5 [# w        {
% x) \% c/ Q: A% _, U2 f) M+ J                GetPortVal(PMU_SC, _value, 4);
7 l  [& u; A7 `0 Y" [* U8 \        }; p9 f! K4 Z1 v* ?  g. _) ^% c( R
        while ( *(_value) & 0x00000001 );*/8 @" W- X# d1 f* }& w! Y
        DWORD   dwRegVal=0;
2 g8 z7 i3 L# `' X) {( [        do0 ]! s& ]$ h3 K0 Q- t* D
        {  
1 l4 h( R. D* Q' S2 Y4 v6 `7 E                GetPortVal(PMU_SC,&dwRegVal,1);" Y, ?0 f: J$ x; A: e
        }, |2 w3 U  m7 Q3 O5 N
        while(dwRegVal!=0x2);# j! v& l) i# Q

1 |1 Z5 a$ f9 Z) R. i- y  [0 ]}
7 s1 q0 V: D4 Z) ]  O6 _# K7 |9 q' n4 c& o
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
0 _2 \  P6 L. l+ B, b所以变成了死循环了。+ `1 q+ Z5 [" N- v3 K2 w% j
) _$ ~  Y' d5 a3 F8 D  D
我对硬件编程不懂。又不知道从何下手。
( O/ k6 x% v( Q% t: v我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
3 W8 S3 n$ o; i' q" o但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
& {4 `; X; O( R- x
( U0 K: K! H% M& Q% J我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。& x; i. f$ U: C" ]# P3 n
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
& r1 S6 j/ ?) I7 X% q8 ]7 B
  J: A/ H7 Z8 ^2 z# U4 U2 \感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
4 s7 l8 U: e% `2 ^/ }1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
, J/ e2 _- z. f! J1 b( X& p/ u2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突% x8 I5 o  I4 Y
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.- g% t% B( i0 H% Q

) S. Y" T/ V) d+ P9 Q' b所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
  ^" y, C' Y' m4 m) A" z$ k+ Z
; ~1 m- ~  H" D$ A& D# j那么有些什么可行的办法呢?
- ?: G% J/ R5 M  w为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
, ~9 s' u1 }8 @: L9 r- a" R3 n. K* G# m4 d
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?' U1 y9 X5 d! T7 n1 Y  E
& F: _; N" j+ K, m- w; J, T
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420; a6 I" ^# q$ O$ s9 c( S

( w7 L* e; [2 l2 j, [+ Ehttp://www.ufoit.com/bbs/viewthread.php?tid=452( N/ ^6 C6 l2 F) D' o1 x

+ d6 u5 @; H  Ihttp://www.ufoit.com/bbs/viewthread.php?tid=241
( [7 L( c: r* d- b, k4 I0 k
8 G9 D4 C, g0 F看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
# U7 ~* {3 b# W1 f1 w- `- ?. w- p2 |: K; s# J1 c! K' i
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。' {* V/ G  `; q7 u2 b- V8 ]; Q' @
2、Driver最复杂,也需要BIOS配合,推荐。6 D8 G6 b0 }) e" X& A' e; G* R( O
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
( m) m4 C. w7 l4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
! l: \" p  d! W) P: ?7 U9 J9 X你可以混合使用。
! ~% Y: f. S4 c( Z
& O' M' K& t; [+ g  {* I* f% i===============================================================
  d% X6 P! ?" F' Q: m管理员的这句话:! K0 s  ?) t) ?/ q& y
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
( h7 I6 D3 H" w/ W  ^6 e ) M! \! G5 @- E# O9 C
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵/ G; ^; q& q/ b2 X8 V; Z
% n3 ~# n4 t, Y. I4 |
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
* {9 A- {4 E! _# I+ l/ p- \7 n0 `3 w- [! V9 g/ m6 |% Z
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
2 ]' D; r1 I3 G4 q% a! N% b
+ @; k4 D6 A! u5 b& R还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
. \$ ?7 B* q4 Y里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
7 i: L# H% R5 m% P: m+ J/ [9 r- X/ O. h, h4 S0 a# t! h5 @
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
) ]$ ~8 N/ f, q+ L% k  S  P% h$ D6 F9 J你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。# a4 d$ r3 D8 B* W$ f( s
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
- g/ B4 F6 \5 M, F* m! j

# U0 f% P3 P* e  o8 A您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。( H9 K& j9 C) x. `/ R& P: X& v* ~
2 S# x8 s/ ?- h7 F4 [+ s
void write66(unsigned char Data)
; j' C) F6 G2 t& b# b{  j" ~  }, u$ M* h" l+ S
        DWORD Status,TimeOut=10000000;
0 B! y" s  b8 I) k) e        do
" X6 |: \+ m2 a9 J! @        {
8 g+ ^! t3 Y3 s                GetPortVal(0x66,&Status,1);! x6 N! B1 Q% f; P" m: [5 S
                TimeOut --;
3 `  [6 I: t  M& O  i9 ^//                Sleep(1);
6 J4 T; v" z! l1 ^& ^        }while((Status & 2) ==2 && TimeOut>0);6 _/ Y/ `2 ~) R/ H
; g# D7 A9 K0 j; R) w, y- I$ Q0 B
        SetPortVal(0x66,(DWORD)Data,1);5 `7 M  w6 L/ S/ c) ~. Z$ `0 ^5 E
}
5 x: _1 B/ O" z6 u' ?0 \" Wvoid write62(unsigned char Data)  b' p, ^8 B, r/ m
{, x! e* F/ Y/ v( J. Q. u$ W
        DWORD Status,TimeOut=10000000;
: k6 F6 j+ d# i0 j3 J% }+ @        do3 ?2 T% R* R; D  F
        {6 H& U6 J5 a4 l% T  s& V) ~5 X/ [; T
                GetPortVal(0x66,&Status,1);
. b( Y0 b3 z% C& ]& p8 l                TimeOut --;
9 n7 K5 o; p. z" C5 a2 }//                Sleep(1);
: S5 s& h8 g1 f' [: c  o3 O        }while((Status & 2) ==2 && TimeOut>0);4 O0 q: `  h% a
4 F; l, V3 U! Z) a7 e
        SetPortVal(0x62,(DWORD)Data,1);3 x  [2 A9 X; h; W' ?$ ~
}
" a" v8 G' r, J! o9 Y! kunsigned char read62()
( e2 k$ O) m, G! T4 Z+ O3 h{" h5 s( U2 p# a5 j) P* _
        DWORD Status,Data,TimeOut=10000000;6 B5 x. z. ~  E, L
        do
" d% I$ v2 e0 L4 ]* L3 m7 x6 m2 A! t        {
  \4 b' M2 I& I) }4 O  B                GetPortVal(0x66,&Status,1);6 t% j$ |  q! N6 @
                TimeOut --;5 y2 ?2 g) T6 K9 y, [/ F- a
//                Sleep(1);
0 V& R! v: D; }% r; S& R        }while((Status & 1) ==0 && TimeOut>0);! G9 S% Q' k, Y) A8 i( U  `

3 N2 a( Y: I- V$ g
) o3 q( B) k/ ^        GetPortVal(0x62,&Data,1);
( I% }8 c/ T1 {        return (unsigned char)Data;
' @; m" k! X( h7 S}; a+ @# h. R( H9 X' V9 M# R
unsigned char read_ec(unsigned char index)  Q* ~  t  [% G6 a$ r$ ?$ Y/ @
{( G- B( d0 Q* ?# M( a6 ?9 K
        write66(0x80);# t7 `* ^0 Y: H6 o! e
        write62(index);( k+ R7 l2 ]4 o, `- c
        return read62();! N& f( R# A1 c5 T2 K1 B3 p3 Y
}
7 l8 W! s' A& O$ i7 w# E. x
. v, D4 v7 Q6 j5 W2 f[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

# o7 z" q0 P7 w+ n, `6 Z; \[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 5 s  ]4 Y; U4 W* u# z! ^

& W/ d7 |7 D5 f, u( }& V2 D2 x4 l3 ]" `- \0 b* E, B
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
, P8 M# F0 q; F8 S9 O7 q8 N+ H

6 _9 G8 Z0 Q# y; T4 l4 i7 @% }1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
/ J( x% s& `4 z2 U9 w2 M' L' u  d. g9 G2 j8 K
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.% t& K  u7 N4 j+ A4 z8 g& A0 _

5 p/ f3 [" g6 g: }& \8 D2 q3. Then set bit16 of the IRQ to disable it.
' \  P6 a+ ^6 C5 Y$ H, @1 C4 c4 Z' w+ W
    a.. Offset = IRQ# * 2 + 0x10;
/ V  [/ O' `/ h* U( `& J' R4 M: L
    b. Write Offset to APIC base,6 e4 c/ V" s$ Z1 `
. _' r; F  N1 f7 r
    c. Read Data from APIC base + 0x10;
4 B% L1 E: G) N( p% f
. \* W# g' ~  l6 i7 \% f- J7 w, b    d. Or bit16 to Data;4 k4 e5 Q7 I) H
& J: S+ S/ B. r) u1 M* I$ I
    e. Write Data back to APIC base + 0x10;4 U1 B/ }! J( F% f0 G

3 N7 J) S& t1 c
! H+ V) R" p5 h- Q" r9 N, ^3 X9 q- M" g
You need to check APIC spec for details.
回复

使用道具 举报

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

! e2 y8 R% j$ H0 u5 b4 a8 {
! R0 v# z7 N9 k 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
: v# S8 Z, J2 `2 T==============================================
* |( X' U5 X# e/ J$ U6 q; T 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
* d- p. Q3 X3 ~' B6 h% r  ~
& M( s. `1 [7 ^) T: y. H+ m. o% h因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)1 I, R) ]  R5 m
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。; c. G+ G# O: Y2 U3 X

3 a, @6 ^. c1 u  L. y5 u* V% N1 m因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。& n7 h( w, @* K( u
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
! Y: x, r2 \8 @: Z' y- U2 }) ^1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。3 V6 Z/ h+ a1 M) y! a* ?
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-8-11 17:05 , Processed in 0.060194 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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