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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>$ X( G% G5 G: Q( i$ K9 R  [
#include <Windows.h>
; x& R" {/ B6 P/ l- y( Q#include "WinIo.h"
6 P! ~+ r/ i4 u6 T5 w  J; Rusing namespace std;
! v2 E. j! ~# b) h
* U1 n7 k+ f; \' F* Z) f9 m#pragma comment(lib, "winio.lib")
0 ]8 j! ^; x5 [! v6 o! I3 W5 i* ~& x4 d) F( j  p

" C5 D$ L2 R: _. m! Xint PMU_SC                =        0x6C;//命令端口" X; M7 ~; \, W; W
int PMU_DATA                =        0x68;//数据端口
1 a! F, d4 n- ?7 l7 I( A! M8 u# t# oint RD_EC_SMI                =        0x80;//读寄存器命令
7 ~9 W% t% O7 R% r: Iint POLLING_DATA                =        0xE7;//CPU温度寄存器号3 i2 s; q6 @9 T; q; k4 t: A" h

: [7 |: r5 [9 v& G! DDWORD dwTemp = 0;4 q9 g3 H: L8 {0 m

7 V' q+ ^7 y5 z, a- ]$ {% avoid PMU_Wait4IBE(DWORD *_value);- f! z  ~3 H* u" X: a
void PMU_Wait4OBF(DWORD *_value);
  i  ?4 S. o8 t. }3 Z
4 U2 U# r5 D; k/ g5 h0 u6 }/ Y4 n2 j/ ]( r" ]3 l: _
int main(int argc, char* argv[])7 i( `+ [  ]3 D. L) i% K6 N
{
5 J# s( |% X/ z$ Z  C) W8 Y8 Z7 y        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
, e5 q! w: Y5 o" c% q, u. [; R# L- L3 c1 R
       
! S) V2 ]8 K# S; e        //1、mov            dx,PMU_SC                //
: X- D9 B+ {* F+ g9 h        //2、mov            al,RD_EC_SMI        //
4 q- ?2 h- ^6 n+ c        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了; D  H, }  f8 }$ s* D. u
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。4 [1 U( K% c* `" }* O
' T/ T; f1 v/ z
        PMU_Wait4IBE(&dwTemp);. c) y. x; e3 ~
        $ n% a0 x: I: V) E; D  g; T
        SetPortVal(PMU_SC, RD_EC_SMI, 1);2 s0 d7 R* K% f! G$ |

3 r; _! A5 q: _! O# r) H8 B# }        PMU_Wait4IBE(&dwTemp);
* F9 ]. b0 f$ b" ]        - \$ J, H& b# k2 _
        SetPortVal(PMU_DATA, POLLING_DATA, 1);& c& o1 y; f; X- M0 Y
( H' X/ a, q( a) n/ S  T* f! M, g8 K
        PMU_Wait4IBE(&dwTemp);2 L. y2 x" |, Z
+ S9 Y# p1 T4 \, g$ K
        cout << dwTemp << endl;                ) i- |- d1 j& H0 A

. n. I7 E$ m; Z8 @& \9 }        ShutdownWinIo();2 ~7 `+ M: Q/ @' `- D* \
% d7 e) h$ m# L9 c: j- s
        system("pause");
1 I* i' {5 j/ }* r8 k5 x+ M$ d) a& D8 {
        return 0;% G/ {. V- H& P4 r+ T' m
}# J  K. l8 x" _7 g

+ ^: u2 k' u2 _, g/ Z, O0 t: nvoid PMU_Wait4IBE(DWORD *_value)* r+ _1 l# |4 K1 q
{6 O$ n7 M, y) C$ c! a4 L
        //#########################################################   
" [1 r. R5 J8 G5 L# }  X        /*
$ T# j' L; ?$ q5 G        pmuWait4IBE proc   
( f) X) X; F- x+ e, X0 Q        PUSH        AX   1 r) d, M9 M: ]
        PW4IBE:               
5 P6 v; U8 Z% O1 }. H! N        IN          AL,  06CH                                //Read  PMU  status   
" y+ A: M( E$ o0 h        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
' _' i" t% [/ }6 I( C        JNZ         PW4IBE                                        //Jmp  if  no   " J4 K5 n; g# T! T
        POP         AX   
# |5 C2 e) x' B# l        ret   
7 q  S; M+ V% D$ g        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
3 d' T* }# s' Y3 Z5 o$ @        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空* I, W  ^' q6 [- b. h
        //######################################################### 8 B: G( k; O4 b' y- O
        /*do
4 g5 E6 E. E( E, z- z        {
7 U4 G* n+ y4 G! [1 h; N& h; |* ~                GetPortVal(PMU_SC, _value, 4);6 w( ]! |3 J- E* Z9 o8 N
        }
+ N( `( J9 W4 k5 M8 R        while ( *(_value) & 0x00000001 );*/
) Y; j! ?3 h9 S& r0 C        DWORD   dwRegVal=0;
& t# {' b0 L( ]  m        do
5 d; F3 W2 `, ^+ l! O/ L        {  
' s# p! E. u6 C                GetPortVal(PMU_SC,&dwRegVal,1);
6 O1 a. v+ ?1 f% h  A- Q7 j        }, K8 _. X& F4 k
        while(dwRegVal!=0x2);( z' U7 B% ?3 ]: I& ~9 x

; f7 P3 ~7 k4 g}
) I) j! \+ {: Q( U8 ?) Y% r" e' `
. v# \' T; y+ q) y以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。$ `' [6 i% v% U7 ]/ \: c
所以变成了死循环了。
1 q3 i3 T+ S) _  ?. P3 d( {' I9 h/ d" V& w& t8 c2 z
我对硬件编程不懂。又不知道从何下手。
8 x: W9 T, Z# F! |, M( H5 G我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
% ?" d/ B' C, n8 z但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
2 S* n' s0 x9 T3 u# C
, ~$ y& h6 w5 [) c  M5 Q我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。, }4 F/ `* G& L
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
4 _7 h1 R" L) G8 E
; D% A7 z; X7 p2 p2 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.但是你这样做法应该是读不到的。
1 J* K6 e: z$ H  U6 |/ Z1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
/ w. s5 b5 Y. o, b6 }( w2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突4 y7 b. `& r' N+ M
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
, D; H( x+ P  C1 [& A6 l. P9 k
. d" n, j5 ^/ l" S! Q4 v2 U4 _所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
8 I. d/ V% {  v  f$ [2 ]+ x' f9 g
- ^6 H* G$ w, V3 g' F! j& I那么有些什么可行的办法呢?- A. a( a1 b6 V+ V- }. J
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。% j- W( L1 K7 U1 `$ l1 J) m
2 b  q2 H: ~" S. d
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
) p- i$ t/ K- ]  M2 Y+ R- G% v' F
( _% h8 Y4 z1 w: a那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420- q% D5 I7 N. r5 H

) k# J7 ?/ U  t! P; U) N5 jhttp://www.ufoit.com/bbs/viewthread.php?tid=452, E; n% g0 e2 m# j! r

- Y9 B- s3 [3 q2 ohttp://www.ufoit.com/bbs/viewthread.php?tid=241
6 }) _: G' G' l0 v) t
( W/ Q+ ]/ C- H9 T! g看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
* `/ ~' _0 r9 j) f
  Y& r6 o  r# P. A% v6 l1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
. f6 E1 J" d) X2、Driver最复杂,也需要BIOS配合,推荐。! ?; j" }# b) M2 U% F+ u/ V
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
& v& \" v; c' n9 ^- l4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。  h" i# }$ h8 _) o
你可以混合使用。; Z" F# f7 e* H5 h6 p
1 P' Y4 V/ D1 T) B  R
===============================================================
0 [, m" Y' L& q1 Z管理员的这句话:# u# w" ^- E  T! m! \" k6 ]
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
; O: q: B5 a2 N
5 w" o& N/ a2 l予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵* D$ X5 C( ]% P  U
7 u9 B3 s' W0 \7 X+ D% i
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
! T7 \; \0 r9 A$ k7 ]# A6 J, A+ c$ d; `9 @
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
9 i2 t. t$ m4 A, F1 B
& @) A" ~9 Q) ?. ]$ m! E还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
* _8 O' \. f/ i% h* }8 M: F里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?+ V  u. R$ c  K( x  `& J

. E4 d" q' I7 t: }我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 ) m" \: Z6 Z& a2 B7 L
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。/ h  j+ T0 y9 F
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

* y# [7 x3 }. ?! W. @7 S9 _/ a
5 [* Y* T( k: i您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。* d- K5 D, P) _

- ?8 D0 [! D; Gvoid write66(unsigned char Data)7 Y6 J/ \7 D* G5 i9 \7 D' F- l- H* C
{
0 }# e8 {* ^6 d        DWORD Status,TimeOut=10000000;
" f1 \& _- d0 `        do
7 s4 K; O3 I6 i( O( N( D2 s" \9 k# k' g        {
  O) _/ H3 O7 y. F2 e- }                GetPortVal(0x66,&Status,1);  Q* M/ z4 O' r# C) }; q
                TimeOut --;
, \6 c. f; \7 z) T) X//                Sleep(1);% ^6 q7 z2 ?' J6 h6 U: s& m+ V
        }while((Status & 2) ==2 && TimeOut>0);
( @( A+ {. P, i# S1 v7 ?+ J: |
8 R6 d; [; x, G6 n2 l        SetPortVal(0x66,(DWORD)Data,1);, F% C1 R8 Y* j% G$ j; m
}  x( `# |$ ~$ j  S
void write62(unsigned char Data)
& L- m) G4 j5 L0 N- Y{
3 Y& A& T2 I! `# V3 B1 h, k        DWORD Status,TimeOut=10000000;
* |5 t4 I, d# @3 p' ?: f! W        do7 s! q6 A/ H  x8 t% n+ |( l
        {  F& t9 g) w/ G. k" Z) k8 }) B
                GetPortVal(0x66,&Status,1);, g( o! A' ~3 R- i1 T2 D
                TimeOut --;, v( F+ R, l/ v1 a& s* D
//                Sleep(1);
- ?/ }# [+ p% E/ A/ a5 {6 G" X0 O8 j        }while((Status & 2) ==2 && TimeOut>0);+ W% s+ U" {8 o( }
+ i- s; S7 u0 x3 ?. \0 n0 e
        SetPortVal(0x62,(DWORD)Data,1);
$ \6 {) m9 }  A7 x+ B7 l9 E, j* B' p}
& L7 g  M8 M8 o" y# r' o2 D! }unsigned char read62()
0 V0 N, x" N1 K3 S7 r{0 _  k6 }, Z* {& \9 P
        DWORD Status,Data,TimeOut=10000000;
( Z; v3 K; L, W        do
+ T5 X8 P% \3 c& F( @. y; H' Q        {
* D" U: [( Z9 B3 Y  j% I                GetPortVal(0x66,&Status,1);' T" n6 B! f* p
                TimeOut --;
9 Y: D1 V: T# @8 W  E//                Sleep(1);3 S  a& r8 w+ X
        }while((Status & 1) ==0 && TimeOut>0);/ \7 ?$ }0 Z7 i) |4 g* J6 K

* u; G6 ?% z: T+ Q+ ~+ @
" q2 k, Q; m: Y$ I9 @$ |% t        GetPortVal(0x62,&Data,1);% s7 `, `5 ?$ u! F3 b
        return (unsigned char)Data;0 H2 w+ q4 r' ?- C; i3 a
}$ Y% O) _$ s  g  d2 T; ^+ U
unsigned char read_ec(unsigned char index)7 m# b! B, Y) p/ B) B0 R, z! v
{
0 e& T. N* s4 g! z8 U        write66(0x80);
$ C8 ]# ^( d! E) Q        write62(index);
% O" t% K- \+ O! n4 `0 A4 t. x7 V        return read62();& i- F& j1 h9 [6 t4 T' S: t7 Z6 B, z
}
5 R& @; Y# `7 V" a3 o4 W+ x: O. N; t( R
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

" T- l6 n4 g; J, H6 N[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
: E/ O/ \0 z) a- E9 P2 u5 p
) @: y8 D3 g2 V- x. D6 g- G
4 D4 S; F( d9 z您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

- N' Z3 E$ x: J( b2 q. V! [" H. O  j3 m9 a3 X: v' v$ Q
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,( i1 {; y% h; e; O

# s& ?2 H( _" f# p' v2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.6 h, ~1 U/ Q2 W
% ], J! ^! t8 F* O) t/ K6 L
3. Then set bit16 of the IRQ to disable it.) w7 s- n- N8 ]$ v% _& Y, ?$ r

5 {7 s7 L1 F9 T5 B6 d    a.. Offset = IRQ# * 2 + 0x10;" r! ^+ W, T+ n6 m& p6 D* F

4 D: ~5 \0 p" D( x8 z4 p, e    b. Write Offset to APIC base,
1 m  g- @5 u2 N9 s) |, O" e) @8 h% W. h  b1 r
    c. Read Data from APIC base + 0x10;) ^$ s' y/ D  w, d0 r; l

" G& v9 X0 h7 n, l! ~0 t    d. Or bit16 to Data;& q" N. _7 F6 R/ ^4 z; f8 p1 W- ?
( |- Z' f! W0 G6 K* n& M) ~; ]
    e. Write Data back to APIC base + 0x10;- O5 L+ Q; W% h6 e6 F* h/ c3 {
0 Y% ?+ p* A5 Q# q1 c

  t4 f5 ^( c# j
1 k; T; l! _" w0 ~2 }2 A* aYou need to check APIC spec for details.
回复

使用道具 举报

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

; V9 r4 I7 v' l. y
" z+ [8 c# ^- s' j 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
8 N' G# V! C8 C+ S+ i: g==============================================. w# d. b+ @3 G
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。* z9 Q5 u* I; t* o

/ E7 r- N2 U7 L1 o因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)4 O6 r  S# |/ i4 ^' J
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。5 D- L% b' H# p& N, j
; o# v/ I1 t# Q( W2 Y
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
. C, }) g6 y4 A- x) h1 {; L7 z9 O当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
& z: ]# C1 |. |# o7 W' J1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
+ I8 e& e. r/ w* h# K- o- v. ~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-5-22 10:39 , Processed in 0.156917 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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