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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
( e2 {/ h, c& W5 e1 z#include <Windows.h>6 P1 S$ Y- K- P% `( D4 ]
#include "WinIo.h"' ~0 J2 q; S$ y5 U6 M
using namespace std;
. d% t: P* f1 ^; @; y, V8 _1 P! B" k2 J5 w8 Q& E
#pragma comment(lib, "winio.lib")
, }, ^+ X" J% X' V% o* n7 C$ ~# M3 Y1 _& n

% i: M2 |6 [# p6 m$ Y; q& Q4 tint PMU_SC                =        0x6C;//命令端口9 |6 }. k* h( R3 U' }  C" Y3 L8 C
int PMU_DATA                =        0x68;//数据端口
/ G" P& N$ {- I2 T1 n- G9 o; V+ Rint RD_EC_SMI                =        0x80;//读寄存器命令
5 d  V7 {: I( y7 X- lint POLLING_DATA                =        0xE7;//CPU温度寄存器号
+ i, i3 l' i# J' w" j( [/ `
& C, r, Q. Q7 j3 H2 tDWORD dwTemp = 0;
* ?9 ]( G0 M* }% C
1 M2 V  [% H9 T3 c; i- U! J8 y* Gvoid PMU_Wait4IBE(DWORD *_value);
% A, R0 o! |- _$ ^void PMU_Wait4OBF(DWORD *_value);+ \: k& D" a# |
8 f' g3 ]: R- w" {9 n9 w6 T- H

' i, g) b4 K$ F4 fint main(int argc, char* argv[])9 L' s; X! T+ }
{6 Y# y, o8 N0 |* b' v0 E- Q
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
) {" _4 V8 w& T0 ~1 o2 w7 Q. \+ S$ y% Z9 w$ v7 ~8 B5 j' h' z
        ! Q* M6 o: D8 H: X7 x# P  O3 e
        //1、mov            dx,PMU_SC                //
( ~' ], b; U# T7 q- w, J' |" z, e        //2、mov            al,RD_EC_SMI        //4 p4 {, E, f! }- d* _, Q( Y
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了( ?7 E! g8 x) o3 Z
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
6 _1 o; r# H: h  w/ e2 G* Z
6 I- ]8 |  I4 B7 E6 a        PMU_Wait4IBE(&dwTemp);
; w4 W1 q( f4 V( _  j/ `        ! V2 ^, [/ c* F( f' ?! w
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
, e9 v0 `# r! z* T) N0 v' L
# K. o4 X0 R. _& F# g        PMU_Wait4IBE(&dwTemp);
# Z6 V! n: b( ~( w* V       
" p6 A6 }2 ^4 G5 g; j        SetPortVal(PMU_DATA, POLLING_DATA, 1);
0 f; E) n' [7 L; f  @. G. {3 [/ A  o* w
        PMU_Wait4IBE(&dwTemp);. g  `& n6 m1 e' q
: |# d- N  v9 o6 ^7 U: G, M
        cout << dwTemp << endl;               
7 E6 I' O( h# N' s4 ~
+ L  p( K, u1 L( Z9 p0 D& M        ShutdownWinIo();0 s% T6 d# g( W; J. Z" j* j

1 k, `1 S6 V  F8 S1 C8 p        system("pause");5 X3 ~  c8 Q! `+ y+ R
& H& n7 y/ C7 K9 m% g9 d
        return 0;, c; e% [1 w2 F/ ?! t+ J
}
( t& Z3 O/ \! m$ F. X* q2 V4 s: J
void PMU_Wait4IBE(DWORD *_value)  i" y( o4 S- R1 v
{7 {7 e3 Z" k7 I: r- s
        //#########################################################   6 Y$ F0 I& D: x% T: L# N
        /*( Z, T8 ^5 P) L* }# ~
        pmuWait4IBE proc   ! w, t/ x* W3 e; ^( r# N8 J, X
        PUSH        AX   
9 O0 _( |1 v5 n- d        PW4IBE:               
3 j& L2 T3 P& E+ e) P& B! c        IN          AL,  06CH                                //Read  PMU  status   5 S5 r' t  o2 Z- @- j9 i7 |3 m
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   / V# h6 j4 a3 _8 E, }) r6 D
        JNZ         PW4IBE                                        //Jmp  if  no   * Z2 g, i1 s9 r* g# s6 W! ]
        POP         AX   
! R3 ^3 v7 r( o        ret   
# a2 [& O8 l( g$ B        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE! p5 J+ n6 s( R& t+ E7 d
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
' ~. `# {/ B8 W+ h$ s        //#########################################################
7 Y; `. {6 Y" A5 o        /*do
9 @. ?  Y& B7 D. h, @        {
' y  b* l/ {: ]$ f+ a* ]                GetPortVal(PMU_SC, _value, 4);( z: i8 g, S1 X
        }
5 t3 \. n- x: d! j: b& i8 j        while ( *(_value) & 0x00000001 );*/
, }2 `& N* k' a' W" d) Z  n' n        DWORD   dwRegVal=0;/ E3 F( N; [6 e! f- J
        do! t4 j% ~7 O1 O+ }. l2 M2 h
        {  
& o9 S7 V/ {" ~8 O' @8 `2 Q" ]                GetPortVal(PMU_SC,&dwRegVal,1);, |4 D5 ?* G8 \; w$ Z7 j5 C
        }
( g( C3 ?' t2 c: {" ], {1 N# \        while(dwRegVal!=0x2);+ ]  q- b$ a  B( }. a5 s
! {; ^" j# Y0 B3 i$ K' w
}9 \- c; ~! J( t7 a
; L+ m% i0 P- ?+ [+ Y# @
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
+ W. Z/ j& V8 L- e( m! ?+ V所以变成了死循环了。
) d" s3 o( `1 W$ {8 C
" i7 _- N; U0 i3 y( Z! R) r我对硬件编程不懂。又不知道从何下手。3 k& [! Q- E7 b
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
  ]+ V4 C) n8 A5 }: M但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。# m/ q+ ?7 H1 n# `4 \3 s
6 c) i( H& Z' Z: x3 _5 R* _
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
: a1 X. X) L( u1 A* K! h, X并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
) Z" y/ ]2 g) W. X6 Q+ A0 X/ p8 E# f) t7 F9 o) }- h
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。2 S8 k, O' n$ n8 ?( D8 V& N
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
" t9 e/ x9 V5 O+ I" }  Q( J/ m2 h5 _2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突* y5 s+ P8 g+ T3 R. L
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
; l% Y& {/ X* R# h
- q) K, k$ R' [# r) c所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。4 V0 B0 u8 c; z6 u  F' X0 W

3 W8 S+ E0 _0 d3 \4 i$ S那么有些什么可行的办法呢?
$ F8 b6 v# W8 r为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。# J( \. k  G" F8 x
* s' U/ V( Q+ D6 t
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?% ~& ?2 a1 `  F0 f& o3 P) |; A
1 s0 X) X& Z' {' J% F/ E2 m
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=4201 d3 y/ U4 g$ d3 ~
# w- k! ?( u& d0 J: Z
http://www.ufoit.com/bbs/viewthread.php?tid=452
5 ~/ ]. r4 o  Z8 N" a* {+ T8 T: j: h% g3 N/ ]4 @
http://www.ufoit.com/bbs/viewthread.php?tid=2412 u( y7 y% h  v: r# e0 U# x

% X: J7 s, w1 ^$ y/ P' [* P看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
' J: X+ i8 M  O% K- `. |. c$ E, m% U, u9 ?, q
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。6 d$ e1 L/ c$ T
2、Driver最复杂,也需要BIOS配合,推荐。0 Z- _8 C( S' p  R, y) D1 |
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。/ m. E; d3 `, T$ p
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。3 P; l) {- M5 j8 s9 |, k5 [9 r0 q1 o& d
你可以混合使用。. m, E9 y3 T4 i4 @1 w8 C

( |' ]: N) i9 [$ F===============================================================
" B1 V9 v! @" m1 V管理员的这句话:
3 e. @4 F$ i8 L: D如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?+ X: k3 O$ ?# v) Z
$ M2 i" t4 a1 C& W6 o: A
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
4 d. T$ C; [7 A; p) M$ O4 _1 |
& |: ]0 ?$ ], B" Z  I3 C另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
8 \/ f9 Z; v8 s2 ]
. c) [2 y* T' o这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
% V0 s3 T. Q3 W: F+ Z1 d
& P8 w4 ]& ?# N( \/ _: D0 a, W还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
' M0 v& J$ Z9 [" m; v+ m3 V0 G里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?# y  _' Q$ X3 T. B
0 o0 z" A/ p+ c, @
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 9 x. r. n5 x# ~
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
* i5 @1 W; L1 k8 X3 v& I) `1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

# K  Z% w  @( t% w- F$ ~; x8 [* n5 l0 V  U' k6 ]( X7 A  Y; m
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。* @9 w* ^5 _1 U: f
# i. y) W% [/ F. R- }- w, H
void write66(unsigned char Data)
- q* G9 N- M' \3 a% v& L{
& K4 C  \$ }$ h# D0 J! j( A        DWORD Status,TimeOut=10000000;
% N) A- ^. p  p' I, H        do& Y: r( @* T0 E
        {
) z1 g0 n3 n9 {* }                GetPortVal(0x66,&Status,1);. Y/ h* `1 I. A  X9 k
                TimeOut --;
' o" u  h+ j8 v) S) F//                Sleep(1);
* N" i0 L& W1 K6 F        }while((Status & 2) ==2 && TimeOut>0);; U) v( H/ w" T; _# \

  E- ~. _! G) c+ e        SetPortVal(0x66,(DWORD)Data,1);
3 d: P# u+ I8 v4 S9 r}
) @, Z3 }+ ^* \) ?( `void write62(unsigned char Data)
* L8 ?. o4 }7 ~9 x; _$ {{1 D* N  w6 |4 q. g% w& X
        DWORD Status,TimeOut=10000000;
% R. H7 K7 R7 \9 {" J        do
0 j" o! r  p( j- y  f. W8 m0 t% r        {1 j1 M! |3 D3 ~: g" D4 e
                GetPortVal(0x66,&Status,1);
$ a" H1 _! U  X, M( o                TimeOut --;
( n. C4 t6 _  o+ E//                Sleep(1);
% q1 w# o9 q( j& H" ^8 x8 U& x        }while((Status & 2) ==2 && TimeOut>0);2 x& X( L8 P; b& r8 P1 Y$ ^

; V5 U6 z2 x) _6 [- E1 J& q        SetPortVal(0x62,(DWORD)Data,1);3 J+ ]' J4 f* |9 }& c' G
}8 ]1 U7 Z3 G3 b+ @. b  r- t& G
unsigned char read62(); K: z) w5 P5 ~: D$ L
{0 q/ i: ^0 _0 S7 {
        DWORD Status,Data,TimeOut=10000000;1 v. D8 r! {$ {' D
        do
1 ]+ D, k( F! l2 u. C" u! \        {2 R& @3 Q1 @* P) h
                GetPortVal(0x66,&Status,1);
$ C; G# x/ J5 a6 g* a& Q% c                TimeOut --;" k  `- P2 Q% m3 D3 _9 L9 @$ R
//                Sleep(1);
1 l$ @) n% x. e        }while((Status & 1) ==0 && TimeOut>0);
) _: q* Q; ]3 e) \8 Q2 _' [9 r3 V4 }- l( r8 u! y& A( u
' J! l" q- g, v  ]8 O4 i; c
        GetPortVal(0x62,&Data,1);
0 _, B+ s8 l- r' e7 N, Q8 @, ]        return (unsigned char)Data;+ M3 c4 c$ X; G/ m, ]7 {
}
6 \/ f% Y' ^5 b+ runsigned char read_ec(unsigned char index)
4 B! p$ g( j! \& y: x& U5 U{, B$ V3 W( o' P% Q! j/ m
        write66(0x80);- V# K) ?6 N+ p! G
        write62(index);1 D$ U5 t& [5 {) d
        return read62();
) o. \  N* l$ M' @5 k}
( b7 Q5 u4 s9 J: _+ T
/ h# }( K- z. u: i6 [[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1767) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
: D. E8 o' q  U* d3 _  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
1 K: j2 N' b1 p! I
# T0 K2 A! D  ?' H/ x! S[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
  j5 F# ^) Z  T( |3 `; c+ t$ _6 Q9 h+ r7 ~. I
7 c( S$ c8 o, t" K- z" d8 g. u% ^4 r
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

- V+ g6 y6 s0 X" R  X5 ]6 k& V# ?
& r$ d: T- G& c6 ]& [1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
7 a6 S! E# Z9 E9 Y0 }7 I5 e) B3 m5 z. Q7 u4 n
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
  Z2 Q& v4 _( C2 b
/ ?$ B1 G3 B( l3. Then set bit16 of the IRQ to disable it.6 Q& f' O: s1 y  I8 B

3 r6 E  j7 i2 b/ R5 D" Q    a.. Offset = IRQ# * 2 + 0x10;
" u: ]8 a) F+ [( C. X/ t. Q8 ~: f& H5 q+ q6 J* G. |" _1 \
    b. Write Offset to APIC base," Y2 q8 ~1 w$ j8 ~4 F" Y9 ]

5 z: {0 x) l, s$ p5 J9 p! m    c. Read Data from APIC base + 0x10;; P5 e# ^  q, S) W" z
- d, Z0 o1 {* h
    d. Or bit16 to Data;' H; E; l0 f$ x- G, S. D) f# ?( O

8 T# z9 j* ^8 h    e. Write Data back to APIC base + 0x10;
7 I5 Y/ ~6 e) a& g' h* g5 s
3 x( F9 v8 p# S9 E( Y6 y * |2 H! k1 B% T$ }" \8 R8 A! }# e; y* g4 P
8 M" |# v8 l+ D6 C% `5 M6 s
You need to check APIC spec for details.
回复

使用道具 举报

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

6 p( j6 P1 d5 o6 ^: ?& z' K! G0 O" m# Y8 r$ c
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
5 s' r* a- g" ^0 g* e==============================================
, `$ E  v3 k# i9 R" e- N 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。" x" b+ \+ D5 B2 F  l& C1 B

0 R3 a3 Z% u: \因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
) X" @( u9 S9 v6 J4 t) s5 v但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。7 m2 G% S2 B, a7 {5 Y- R

, L  |; r# r! l因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
+ x- [* V* z# j" [0 I* c$ J当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:: a! c. w; d0 O4 K0 Z& T4 `
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。" C2 K1 D& O7 p' I, C
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-5 15:55 , Processed in 0.232707 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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