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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>, o  c8 D% _7 m* h7 H
#include <Windows.h>
$ G) J! O1 j3 U4 m0 u9 E. B#include "WinIo.h"* ~( Q! ^- r) R( A3 k
using namespace std;
3 a6 u0 ~( m/ y5 R. k
; J( I: t3 _1 B, Z#pragma comment(lib, "winio.lib")1 j3 {+ t! q1 k; j3 y  G
3 _, f4 j% f' Z; T

/ O- e" a6 {; M9 O9 B+ _int PMU_SC                =        0x6C;//命令端口
- z  R' r/ o- x& A5 ?3 `* Sint PMU_DATA                =        0x68;//数据端口3 e# U3 r+ g' o: h
int RD_EC_SMI                =        0x80;//读寄存器命令
5 L! `3 [2 p! W3 cint POLLING_DATA                =        0xE7;//CPU温度寄存器号: |6 X+ F6 l6 F) f# A

. {7 T+ @$ O/ d9 f; L2 n/ G" [DWORD dwTemp = 0;3 i4 M! q2 v' F$ a
/ `/ Y2 Z4 x, v' X' Z. r
void PMU_Wait4IBE(DWORD *_value);& \) L- s* O$ U) g" t# D
void PMU_Wait4OBF(DWORD *_value);3 S4 Z; A, k8 U+ Y" x. a# J+ h5 G

7 @( R2 I" j0 t: {2 O; l! |- q$ \) x
int main(int argc, char* argv[])1 B: g. z, o. b# _5 a7 D
{
8 b( Q: u1 o2 t        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;& S8 ]+ I1 i2 ^5 J! v
' `1 o' k: c& p' G
          R) k+ G9 S, ~8 v
        //1、mov            dx,PMU_SC                //
! h$ q8 |; [( k6 }+ P        //2、mov            al,RD_EC_SMI        //+ a( _  M/ c" m* V1 p
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
6 x" C7 C$ c$ [- ?6 c/ H/ y        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
0 a+ U" g; l/ K9 |5 }6 b6 H, @  L
% ?7 X$ ^! A% ~. o3 U        PMU_Wait4IBE(&dwTemp);
5 b; Y& h! U4 \. r- P        , D' J9 K2 I0 t' A2 {
        SetPortVal(PMU_SC, RD_EC_SMI, 1);3 B- O$ Q) D4 N* r5 o4 |

& v: q( @$ I& S4 `* c% ^, G( q        PMU_Wait4IBE(&dwTemp);' ^, V# [9 x) ]- ?: H4 i
        ) M7 e9 k/ r" L3 Z8 g. J
        SetPortVal(PMU_DATA, POLLING_DATA, 1);; G& E0 X; Z' I/ Y. K
5 h& d$ h5 m$ L
        PMU_Wait4IBE(&dwTemp);; l5 E# r- Y( \4 j4 p9 k

9 e) H' {3 F# @- o$ `! ?        cout << dwTemp << endl;               
! Y5 r4 t) ?8 U( q& X
9 M6 N7 |! v  ^* l, X  J        ShutdownWinIo();! P6 B+ w2 s% q4 i5 {6 q- }
, N* p. X4 Z3 z% s/ ]. C0 ~
        system("pause");8 P; ~. S& A) J+ D7 @& u. g7 ]
  G6 T, r8 F; }6 G
        return 0;
( Q* ]/ ~! Q# N. ~& E8 x4 s8 v3 [4 e}1 t) q- Y- j1 r5 G
$ Z2 q. }5 {1 Q& I6 L
void PMU_Wait4IBE(DWORD *_value)
  L0 f6 {# j- h* c1 u0 w( b{5 i9 q/ A. [* E  {' y
        //#########################################################   - Z  E. H, t; M5 F
        /*
( b: M( ^4 e( C        pmuWait4IBE proc   $ U: @* T# c) L4 M; J% X3 K( H
        PUSH        AX   
% e/ P/ r9 _! B) W) A" o        PW4IBE:               
* C! b  \% ?5 o6 j0 B. j) @. D9 S        IN          AL,  06CH                                //Read  PMU  status   
) t7 a7 b3 F) y" y        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
9 o* R, E8 o3 V        JNZ         PW4IBE                                        //Jmp  if  no   
, Z6 N: v$ @9 _, S- f- h        POP         AX   
8 S. S$ Q7 d' y6 _4 C4 ?        ret   
0 w, s6 u- {7 }6 x" Z2 U# |6 i        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
: N* Q, _- p& m7 U8 E        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空/ x# v, }* P% |$ G2 U  w
        //######################################################### * f5 Q; ~; |/ `( \
        /*do
7 [  a% B2 J; @  L9 [        {
1 u# m/ N, d  V6 y# t2 U& v                GetPortVal(PMU_SC, _value, 4);
4 i- K9 t, Z1 f) n+ _# ^5 u" e- F        }
. }. M9 C: R  P/ y* @        while ( *(_value) & 0x00000001 );*/
5 `- \6 g: \) \        DWORD   dwRegVal=0;
; A8 B  v# H- V$ R  K8 d% L        do# d' O9 T: T8 u4 u
        {  
$ c. \' d. j7 |" c                GetPortVal(PMU_SC,&dwRegVal,1);0 }9 A: f9 V4 \" Y; c% q
        }
, c9 z* c) i, r( b2 q4 W5 o  [        while(dwRegVal!=0x2);5 P' e: g2 @' `  E; V7 X
  ?1 `' K; ~5 @$ [
}
' p4 u; |- w- f( I' z; R4 H( K4 h- d; {( T: @
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
4 E" P+ H- x2 r0 \% d$ m9 A所以变成了死循环了。$ O8 I* m$ o' r6 r8 _7 a2 z2 a, C
( L7 c/ J0 C3 B6 f
我对硬件编程不懂。又不知道从何下手。+ @7 o  s3 J% O
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。& X7 f' U: h8 M; y; {
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。& P9 n$ b+ p+ `" c9 b' `
1 l: X. ]8 Y: D' k$ f
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
, ^3 k: q0 [5 A( ]并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
5 D# k3 {" L5 m2 \4 r; b. g3 d* Y( s- w' A
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。! F# W; B4 ~3 {2 q1 K
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.% h4 [. [3 a) R# Q
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
  h- g- O5 i+ W; v( `! ]$ |3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
/ v9 C0 W7 O. f, \1 L* a9 K' U  r3 K( f. l' `
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
. h" ^, M* S- @7 o, }# W! C) h  ^% x( `. v# y7 ^0 N! K
那么有些什么可行的办法呢?3 L! }- l7 m/ Z0 u5 i$ V' c
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。; a5 f' ?0 ~# i5 V

4 q8 f+ q6 L+ F. T1 ^) M& |它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
: R* B5 |% E$ ^# }/ Q: Z0 z% J- J4 X9 B: \! q5 m# n8 H# L
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420" P6 Q# E4 c9 b* B# K4 y7 r
- R- x6 f1 C% r1 s
http://www.ufoit.com/bbs/viewthread.php?tid=452
: H  u- @. C# T, X' s+ V& X
5 l- l/ f$ y2 N% Nhttp://www.ufoit.com/bbs/viewthread.php?tid=241: N/ H! a$ O  w/ q
8 i# }" x+ w2 G" H, J
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
9 x% X" q4 @( t8 f( d" H/ O! L" |
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
" {- @' K8 t) s3 Q  P1 s2、Driver最复杂,也需要BIOS配合,推荐。
7 r+ T& q+ z# x& R5 g; g3、Windows API只能获取到特定信息,不需要特定的BIOS配合。( i. a3 @) n  ?& H
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。8 A  |1 ?( G6 T, p) b% h7 A+ ~
你可以混合使用。
- M! y0 Q. ]" n
$ D; [" ~3 _: n8 C===============================================================* t, E7 _* U) m, f/ r! h) {( a
管理员的这句话:
2 ~, V) S. i% ]' P8 J" n如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
& u! W' c, N' D- ~6 h/ E $ h0 p8 Q8 i4 V8 f- B
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
7 k: A) {3 g9 j# ]1 R. Q% G9 E* k% i8 N
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=2692 E- x& r9 r; [, j0 x$ N: [

& W  K, Y3 f2 E$ k这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?- j( O. |3 u$ @7 `2 ?! X! Q6 T# D
2 D: c# J7 M. r9 t, t8 ^
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。2 d. O2 X8 U3 A9 J4 S2 M
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
7 F7 M9 |5 A  |+ l1 {8 {& W% B% j6 X6 a' y  ?3 J. v
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 1 Q; M- |0 o; o- P5 {% s) }$ I
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
! v1 o, U& g) t8 q; v1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
; U' o, p! O8 L' i4 l( [; B5 A' M

8 q! u6 g. Y% k  I您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
: \( q! Y! e' f% j/ Q7 Z/ ?9 p1 C! ?( h3 i9 R$ m6 n  J
void write66(unsigned char Data)
9 y: p5 I( b$ z! {* w. z{
2 v, O0 Y: q8 O        DWORD Status,TimeOut=10000000;* }/ g# k1 }% n& c  b
        do
, j/ K' Z; ], X% W        {; m7 n8 t# {# I, r6 X
                GetPortVal(0x66,&Status,1);; N6 ^- i; E# H8 Q
                TimeOut --;
0 q8 j- D! y# Y& C7 c//                Sleep(1);
& f, S% u+ i# K        }while((Status & 2) ==2 && TimeOut>0);
) q7 I  z  z. ]
5 E. ~! Z* |1 _, B7 ?, y        SetPortVal(0x66,(DWORD)Data,1);2 Q  `" p2 S# |% y9 b" U0 V
}
' A& V) W* @! b/ i# \9 H) G$ p+ pvoid write62(unsigned char Data)% B6 {$ Q- O: W0 `" ~$ o
{
$ d; ]. w5 ~3 @$ q        DWORD Status,TimeOut=10000000;0 C# I# k, a8 x( }
        do
) n* S) }3 B% K/ F1 [        {
" _& s- q* m+ P                GetPortVal(0x66,&Status,1);# {' b; j/ h7 ]  d4 _
                TimeOut --;
) ?/ E, _0 D2 n) \* N8 e0 p* J//                Sleep(1);: O4 k" Z: ~$ J+ c; p- M  N% }
        }while((Status & 2) ==2 && TimeOut>0);
8 j* `; {5 f/ n, m
! E' u7 S( i0 c! v& c, S        SetPortVal(0x62,(DWORD)Data,1);" O8 W, |9 h2 Z9 h
}8 L7 z5 k2 b2 q: S- P' R$ H
unsigned char read62()
4 w0 F; k8 s$ {{
: W9 K% t( m/ \. I, o8 g9 a8 K        DWORD Status,Data,TimeOut=10000000;2 H7 m" H9 g6 \1 q0 n& G
        do
  m( e  x) b# }( Y) Z, ^& C        {
8 N5 e- S9 ?7 `7 q0 r. r                GetPortVal(0x66,&Status,1);! B' \0 j: n: ~, U1 j/ F6 q
                TimeOut --;2 r7 I0 v$ F1 c: V% C" _
//                Sleep(1);
& ?/ P5 _  M# h: r8 D# e        }while((Status & 1) ==0 && TimeOut>0);; F, P9 D. o% q4 w6 b5 g2 a

: x6 [- R  M( B) q# T9 D& Z1 k
0 w; C$ U, U( Q) b5 M7 x" H/ Y        GetPortVal(0x62,&Data,1);) W; e  q/ a" n4 c- ^. d
        return (unsigned char)Data;  X; D7 D4 M& b( d  s  t! \0 L& ]2 e
}$ R  L/ A) q2 p
unsigned char read_ec(unsigned char index)
/ S7 Y( M, o- J: A6 l% z{
9 p9 c7 a$ o& T: V5 C        write66(0x80);- U: H2 I. k1 F0 e0 |
        write62(index);
' G; w' W# p) n3 K9 A        return read62();4 m3 T4 ~$ A. `: r! r& @8 _! K8 z
}  q1 o+ s3 a+ [& ^$ |
) x5 t# U' X( @9 b
[ 本帖最后由 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忽略掉的。
" O% [- P% x, M% x% H9 B  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
$ v: F8 V. D9 A2 ]0 h- R' }( l. P$ E* I+ r
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 0 ^* f6 ^; s, C: B, \
8 v+ M# o$ E0 w

  B! u0 z% u3 d, R. [您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
( h) F- H# o# u2 t3 q- A

1 p! q( Q$ O" s4 A+ w1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,4 ^7 y! W4 r, s# }, V3 w
2 r# z; r6 N8 G! t
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9./ H; K8 {+ i3 ?$ t8 ^

% q8 I, ?! J6 r0 i& c3. Then set bit16 of the IRQ to disable it.
) M7 q! T$ L$ x0 v  Y! I  f  J# ~7 |) e9 q
    a.. Offset = IRQ# * 2 + 0x10;
* L5 A( @. A5 B% w. f- L6 b" x$ m) w$ J( O( m
    b. Write Offset to APIC base,
) M5 j8 a" a2 h5 a( x- Z7 s6 O" v, @' u9 ~
    c. Read Data from APIC base + 0x10;6 J! e  R7 V) R" O0 ?7 K$ ^- v
3 }3 ?9 k# H8 @, ]& R  Q9 q" s" r& M
    d. Or bit16 to Data;9 F2 ~! e4 M) ]
4 h  P+ A9 c6 q; O2 D" k( g
    e. Write Data back to APIC base + 0x10;0 i, i! S- M: `5 E# `
0 \4 ~0 ^0 [+ @: h0 p

% b) j- m' V* ~3 J
. j2 {7 n4 `; s: J6 }9 MYou need to check APIC spec for details.
回复

使用道具 举报

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

. p4 T$ ?& P2 E* c
. E/ Z, t8 J$ U0 ?9 E 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。  H* b( @& W# X% t
==============================================
) ~+ m3 x4 T) Y, V9 r& b 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
4 {1 F- a* N) x9 t( x1 P6 X* D2 t) j& g  h
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
) I6 U- Z9 |0 p1 z% J7 X但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。  n1 j: M: ]! b- N: V, f+ P, `) q, _
- f# m! s1 Q: Y0 P! ~. B
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。6 w8 {/ {- _  J  I, [# x
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:9 C9 {+ n4 l  \/ s
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。2 v2 \" X; r0 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, 2026-8-11 17:59 , Processed in 0.095705 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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