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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>& v( H5 x9 s6 _7 K% Z4 M4 g3 T- v* }
#include <Windows.h>
) e# m$ i6 A* X. l# _0 R#include "WinIo.h"
7 j1 X0 X* i: \* u% w  vusing namespace std;
) R3 M" B/ {. u
, W% A, O+ ^4 K9 ~, Z& D#pragma comment(lib, "winio.lib")3 z6 U* w) F3 u( I9 t

( s( X" ?. N: P7 U7 [7 L+ _  O$ C  d0 [/ ?6 [
int PMU_SC                =        0x6C;//命令端口/ ?' x3 v) h7 K' j* a' A5 f
int PMU_DATA                =        0x68;//数据端口9 z* M" U. {! n" k7 O; a; B
int RD_EC_SMI                =        0x80;//读寄存器命令. F! x4 h: N* b3 ], N2 ^
int POLLING_DATA                =        0xE7;//CPU温度寄存器号# S" x+ T8 j1 x. [

& r9 V( Q( f" p7 P& R) j* O3 KDWORD dwTemp = 0;
3 u4 T( A1 X4 b6 g" ]
5 V! o8 s/ c3 o+ v* Svoid PMU_Wait4IBE(DWORD *_value);; H4 {6 b5 V, {/ }5 K
void PMU_Wait4OBF(DWORD *_value);
8 X  T% m6 @9 ^" d
  |1 x$ _" T/ \0 I" h9 {0 |3 J" g
/ Q, I3 |2 [! @& J- w8 Vint main(int argc, char* argv[])! i: j/ {4 j/ F7 v7 l! b% v: K" j5 J! c
{
1 J+ K- a+ n: v6 {: R5 }        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;5 P* R0 J( B- v

2 \( U" j+ [2 d* V/ w' t        ; Q5 r) m- I4 t% Q6 [( P" j
        //1、mov            dx,PMU_SC                //3 o2 Y& ^0 l3 j' v6 d0 i  ]
        //2、mov            al,RD_EC_SMI        //
8 ?0 d! ]+ Z7 T" J        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
- A6 \7 U/ M2 r2 V6 h& y1 {        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
$ `/ c& i+ P0 g  E% K; _0 q
% ~+ p, U9 m6 j- L. G: [, l2 s        PMU_Wait4IBE(&dwTemp);8 p1 R4 \' X6 ?+ z, z% I. ~# z! P
        1 I% t" P! F5 ^
        SetPortVal(PMU_SC, RD_EC_SMI, 1);  A3 R: E3 Q( c$ o* v
& O; g, L& @. [# P1 d
        PMU_Wait4IBE(&dwTemp);, @9 r% ~6 n4 Y! _
       
) x0 K! _4 m7 f9 q2 h        SetPortVal(PMU_DATA, POLLING_DATA, 1);: @' [8 R, J6 I* L: o
9 \! V( \/ H% ~0 X$ e) Y
        PMU_Wait4IBE(&dwTemp);
! m7 n/ x+ J* }5 c/ p! T/ j. u  K+ D
        cout << dwTemp << endl;                & A- ^* N% j# P, G* w, [
) s% ^! p2 q3 _9 Z* k
        ShutdownWinIo();
- a& r& d% @( I0 J7 n  b7 D* [! k) i  D$ f6 R* V  k7 k- r
        system("pause");
5 n0 c1 C( l& y$ M8 W( q; l3 o
5 ?, T: Q- `5 q* G: `9 d1 C: @" [        return 0;
, i' v. b8 E; C! E* C- b7 l}0 A; g: n! f/ z* R* Z) K6 X# U
: H$ p: S" R' i3 o& C, z
void PMU_Wait4IBE(DWORD *_value)! _9 R8 S6 u4 m3 G9 _
{
1 U% n& W1 e4 t! j! C        //#########################################################   , x% c, p; U( s, h. K1 l
        /*/ t8 ~" f8 u, v+ {( r0 w' D
        pmuWait4IBE proc   * o1 h$ N! p8 }$ A$ O
        PUSH        AX   " H# c) W5 b2 S$ n: x
        PW4IBE:               
7 m6 d0 S) u  X; \2 U4 r        IN          AL,  06CH                                //Read  PMU  status   
- E! }- c. H6 R9 F+ k# E8 U2 U        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
6 i* C: T6 F+ i" W  \! o& K        JNZ         PW4IBE                                        //Jmp  if  no   
( X, H: p) d+ K* n# b# Y  ~        POP         AX   + k5 G$ T& \) N. c' |; _" r* M1 m1 _
        ret   
0 x- [% i$ ~: G# ^0 q) n3 W        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE, Y0 `! \9 T  z- z; R% B
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空2 z7 S0 [. ~* F1 f2 H$ M
        //#########################################################
; v/ |- _3 ?7 |. \; C" r3 p2 E        /*do
: y; h0 o: \+ ^6 ^7 h/ y$ s        {8 R, o" J5 X+ R* V
                GetPortVal(PMU_SC, _value, 4);
# m: N" t7 T$ ^        }0 |( {1 S) I* ~4 M8 U5 n0 }/ X
        while ( *(_value) & 0x00000001 );*/  ]# v0 r6 `- |( N5 F. X: O
        DWORD   dwRegVal=0;
' J1 d2 a9 B) j6 [! K2 \! o        do. \( p  {) Z8 o
        {  3 O8 P. D2 p( j0 k/ q
                GetPortVal(PMU_SC,&dwRegVal,1);
1 y8 z5 z1 J" I2 |2 u        }$ w5 V7 u0 R- c7 Q5 R
        while(dwRegVal!=0x2);* _, t( Z* x; ~1 S  l+ W) J
9 Z; a$ {0 e! Z8 G. b/ X
}* \) k, f8 W& X8 s/ r! B

( V9 }% d+ s* a- Z% n3 L以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。0 M  b* C+ U$ ]; \: _
所以变成了死循环了。. Q8 j; q) l9 r, i
9 o8 u, R1 s0 t7 U
我对硬件编程不懂。又不知道从何下手。( \) q: R, c4 i4 G( ^! k
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
) S5 }2 C6 S: A  W$ o6 J$ {但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。! [$ E# r, W9 t  [! h
4 Z4 X1 N  s' Y, t. V0 Y- y+ C1 q
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
6 K1 C* f, Y) _并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。6 J0 e0 R9 p! A2 c; w
! c2 i( c( q& P- q
感觉现在无从下手。我在网上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 U2 q3 n# D  o' Q  a6 l: D1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
$ Z& ~3 \/ \* f& {3 m2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突' K# N6 h6 W% [1 y5 Z
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
  i: W- J; n0 I2 f6 K1 X
" {& F2 ^7 Y0 @7 F所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
) R3 F8 ], S0 J  {& R+ [* ^- M# r5 |) D0 d7 H
那么有些什么可行的办法呢?& x" [$ I( P4 o0 T2 |
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
9 o- {- q3 g6 u- h2 n; g* V/ U9 [) m3 y
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
; Q! i( a! N* Q% J
5 L+ T4 o$ o$ c; p  }那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420' Z9 Y4 _0 U, _. s6 x- z# v; n

' {& N; B% `. L- l" h3 ihttp://www.ufoit.com/bbs/viewthread.php?tid=452* M6 L& ~* M! [2 U8 f
; l; c7 I1 y* O: q  K
http://www.ufoit.com/bbs/viewthread.php?tid=2418 p8 B4 W" t& H
+ d! @7 n2 B$ `, T( w  w  l
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
! s& N2 x& _. I. ^4 c, k
# t/ ]: Z+ ~3 b# n1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
) v7 N; v- T- @2、Driver最复杂,也需要BIOS配合,推荐。
. |2 g. ?4 X+ W/ v6 j. C1 e3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
. t0 l* z+ x7 _( y6 v0 l4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
7 H+ j# Y. k" j, q你可以混合使用。9 a; B+ V6 Q# ^" Q& G( K2 ?- {

3 l* j/ o9 [1 w" [8 L* C0 D===============================================================
, z# |& R4 T) E8 C' Y8 j& V管理员的这句话:
2 r" a6 r$ B' q% P如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
1 ?5 L$ _" C5 s* v6 d2 K+ b' A
9 s. z- H2 I3 b4 ^$ C予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
: f; d: T5 U  F- I" Q) W! C  O1 Y: n# F3 d
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269. a& P9 x; M" ]% z6 _

4 o) D" m( s) s6 [% R( l这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
1 Y  T- G! |! h4 J
" ]. p1 S4 W2 N. J- S还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。: ~- p' H8 N& M( i& A5 Q$ E
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
4 G: E' A$ y1 L5 w9 a8 Z3 E
; {1 G" V+ ]- j1 \7 x! p我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
1 o: g7 ]* z# k) M4 z$ Q你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。* ^# \4 Y1 e' C  s8 f& g
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

) B7 W# F3 Z) c3 X/ Z& @
; ^$ a4 N: ?( v8 z3 f' B您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。, u+ w8 T" r2 q7 o( o
$ ?: F. C2 R# x6 _; n- ~, Q
void write66(unsigned char Data)/ O0 J% f7 Q; @' w  k
{
* Z# m( S$ F3 R7 O+ f        DWORD Status,TimeOut=10000000;
. U! x0 {, X( P& L- ~) L' Z        do  i; b  L" p' \5 o% m$ a9 Y
        {
0 r% D. e3 \6 S1 y                GetPortVal(0x66,&Status,1);
+ L' R/ Y4 f1 ]( Z, k                TimeOut --;
/ S) O5 R4 g, P7 R5 @  D//                Sleep(1);
, |9 x8 l  E4 t/ L) h        }while((Status & 2) ==2 && TimeOut>0);
! I! o, t3 }% v) b- m; j( E. }- e+ Q0 x  R
        SetPortVal(0x66,(DWORD)Data,1);/ m: U2 ?% D1 X/ G
}/ b2 o. I7 V5 G+ ^0 e3 U7 w# U
void write62(unsigned char Data)! X! c2 E3 m. J- k) V5 t- x
{
* \4 q5 _4 _  c, ^4 a$ e) k        DWORD Status,TimeOut=10000000;" v& r; A3 K; i) P6 d( A1 _3 q, N
        do
* _/ W# n' c3 Z: J4 ^' s        {5 ?) j0 ?+ k2 T8 s7 [6 W! C: A
                GetPortVal(0x66,&Status,1);
- `4 ?+ k- W& {. r( m% O7 d                TimeOut --;1 ]& B! R9 R( ^
//                Sleep(1);" L* F$ {  p; w! A" N$ Z& L  ^1 w
        }while((Status & 2) ==2 && TimeOut>0);. E. ?3 B3 o: ?$ C9 v
8 w$ Q( P( `, l  t
        SetPortVal(0x62,(DWORD)Data,1);
# d: k, l% [. m3 R. _}$ H# o0 u" y: i7 A) b5 ^* o' N
unsigned char read62()0 d* L& R' g$ g: z7 K; K: y
{# X5 v# Q* x3 F5 u. e
        DWORD Status,Data,TimeOut=10000000;$ m# W+ [1 D8 c# F1 n# c3 [
        do5 B& x3 G9 Q2 o+ u4 }+ C2 s
        {+ Z- Q! Y- P; B6 _" ~  H
                GetPortVal(0x66,&Status,1);
  w! ?* z1 w. e: n/ ~- ]/ w- F3 V' o                TimeOut --;/ L8 A& H( _. A
//                Sleep(1);  C5 E+ T( O# c& e6 U. h* K8 E& W& @
        }while((Status & 1) ==0 && TimeOut>0);* {5 j4 }# u: t8 c* `" F/ e0 X, ~

% L" L' D3 |& c/ q# B% g2 u9 V$ }' Q: P4 g1 a* g. X- ~. T1 }
        GetPortVal(0x62,&Data,1);3 G1 q/ s' _: e$ {
        return (unsigned char)Data;8 o% F' i: a/ d1 D+ H0 e, N; |
}/ W4 W1 P; X9 z0 i( j- ^  \( r; U1 n
unsigned char read_ec(unsigned char index)
' i3 b1 U5 W. e3 {2 y  _3 I6 b{/ I8 _" r6 W  M
        write66(0x80);
3 V# k+ q0 c9 L* i! g        write62(index);$ r/ H, t! v. G& Z( S/ y6 H5 j" K
        return read62();* ~& F. {+ F9 s9 E7 g
}
" x6 G9 x' F; u. b
4 ]2 V* U" n7 C% k* i[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1119) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。8 _' p; `$ R1 n  H, T
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。+ {2 B  }$ N" C7 I1 Y
" [/ e, r' H4 }% L3 u
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 # K; i: {' m* P. B0 F  _. ~' V  r

; Z( ?: I  {# V; C- [
# |6 ~! {/ l* C: v* T4 R: f/ ^您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

( Z5 s; A  H; z) `4 `5 m5 Q
6 z& \; Z0 H) S+ Q! s1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,' Q4 d* y, B2 R, V
* J: J7 q, _: `# l& G
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.' t# {7 L9 Q( Z: C

& Y- @- m/ [+ T9 t, `  I3. Then set bit16 of the IRQ to disable it.4 g! R0 q" E3 _) @' O% ^* M+ r
1 ?/ [# k- o0 @' ^) q5 o4 `
    a.. Offset = IRQ# * 2 + 0x10;
- l$ m& l" j- W% M5 U4 y: [: P6 Z7 c& z
    b. Write Offset to APIC base,
! D) _+ H! k* ^& M- M: m* j
( o0 O; _" w& I& ~5 j  d    c. Read Data from APIC base + 0x10;( L$ w+ j7 S, v, M# o

* r# Q) @/ Y1 K: a/ {) ^    d. Or bit16 to Data;/ }+ d- x. R& l  D+ t

. f0 N  x' L0 s3 s    e. Write Data back to APIC base + 0x10;
# h& u* ?- V2 Y  e
2 k; l& m3 y: l- I( j# q2 `- r % ?- @3 P) F, R

$ H! m) |- h& N; x/ Z/ zYou need to check APIC spec for details.
回复

使用道具 举报

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

" F  j" c4 M) B- r
2 G0 d2 D! i# {& d* }" L0 x  V" Y 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
3 k5 r3 `( q1 E, R, T6 z  T==============================================4 x5 ~) B; h4 F# }
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。! i7 n; l' W2 ]/ {1 N5 c3 }+ f

' \! N, B# U. B: \因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
* Z9 J) B' F  I7 ]9 k' C但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。5 U7 F8 n! I4 o6 R/ Y: E

$ Y; N4 l1 Z8 Z* k2 Z' B因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
5 Z" P* q% F0 X( d6 a. T当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:6 d, O. V6 C% J# p4 [
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。- A% o8 U, r2 E1 O- @' b) N9 n/ N
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-4-12 06:56 , Processed in 0.090312 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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