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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>3 p) ], `# N$ b  W6 H
#include <Windows.h>/ e1 ?: u6 U8 c
#include "WinIo.h"
* _( ?/ r, u2 cusing namespace std;* F, Z( j7 x9 |+ m
  t: F7 v# X+ ~
#pragma comment(lib, "winio.lib")
, D( }, }8 J4 F+ q2 I" C3 B1 k
$ p* A8 T/ D8 z$ }4 ^6 W; z7 R% [7 v% j  m
int PMU_SC                =        0x6C;//命令端口3 d" r3 \/ A& g  I  D3 ]
int PMU_DATA                =        0x68;//数据端口7 `. _- L: G) K. k5 O: j# ?
int RD_EC_SMI                =        0x80;//读寄存器命令
* o( U/ z& w" ~int POLLING_DATA                =        0xE7;//CPU温度寄存器号
: P# w( w; T3 X; K! j  ]9 [+ {; W
DWORD dwTemp = 0;
4 E& s# W  _1 z8 s% v, p
9 _& D5 n9 y# |) J6 m3 cvoid PMU_Wait4IBE(DWORD *_value);; G: a; M7 j7 v* O" `0 ^' P
void PMU_Wait4OBF(DWORD *_value);  I1 _5 m' ~3 p4 }& ~. s  b! _

' n# k  U" b. S1 f6 x; A
3 h: q  R; j( U: Z9 `9 M6 Kint main(int argc, char* argv[])
; q9 i4 n/ k4 k+ L8 t. U{
: E! x8 X9 x" X. s$ B- l& {1 D        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
8 {: r6 M( F  ]7 Y
( b5 V6 Y0 `& g        # A, G* G) b& R4 W7 O8 A
        //1、mov            dx,PMU_SC                //! M8 Z0 i0 U6 |! i/ d
        //2、mov            al,RD_EC_SMI        //
! u+ i/ p/ B& R8 Y        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
/ S# H. O4 {* i  B, S* _        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
0 _7 x2 u% p1 f" I
; V9 q$ i5 o3 [- I3 Y) b        PMU_Wait4IBE(&dwTemp);
/ c/ y4 g3 c& L        7 n; f' I) ^9 a
        SetPortVal(PMU_SC, RD_EC_SMI, 1);" B5 K2 E8 G& e2 G6 ^3 I# ~
0 r$ b4 g, s7 a5 T* K. x- x
        PMU_Wait4IBE(&dwTemp);* ?( S4 p" m* t. x! @$ j% K
       
, M; ^0 t) Y2 @+ x' U0 a        SetPortVal(PMU_DATA, POLLING_DATA, 1);
6 U' M% }! F" B! o! P8 n% J( L0 Q+ R8 }5 p
        PMU_Wait4IBE(&dwTemp);
- A$ W; U7 n3 i# i; W3 r2 i5 x- @. q' D' v& E6 g
        cout << dwTemp << endl;               
. o) s; m& g" p7 [, R: A2 d6 G
* V6 r6 a8 E9 s4 O        ShutdownWinIo();) X, m! u9 m6 ~% I0 T0 n& `/ }

$ G9 z1 D" `4 _        system("pause");
. D7 y. M8 b0 F  `3 n
2 z0 |/ {& Z! M3 g. `        return 0;
( G  ~; d7 A2 c: D& W5 ^/ C" |}
8 K0 J+ b' s. m: R
8 a6 E  i5 L" `- H1 V7 S4 ^# Pvoid PMU_Wait4IBE(DWORD *_value)
+ V5 ~. E" y5 Y7 d* m" U$ M{
3 g" O, }) R2 I: F3 e& i        //#########################################################   
# A: X5 S( i! G! @# L. \; H        /*
4 p" S& ~# i3 j( ^! C$ G. S        pmuWait4IBE proc   
: ?$ k  ^( w; }3 H. [  R        PUSH        AX   & J" U6 y3 ~( d0 `
        PW4IBE:               
" L0 d# w1 s; \2 E        IN          AL,  06CH                                //Read  PMU  status   
- \. S9 b* i9 r' {( l! X  x$ {        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
0 H# D, H- M* l& Q' a& E        JNZ         PW4IBE                                        //Jmp  if  no   5 e) [/ y$ c, B: c2 e) v
        POP         AX   8 z+ w, Y& {2 x; l8 }, C2 s+ b7 f9 J
        ret   
: v2 {9 C  N5 l' F5 Q; }        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE! H4 J+ ~9 M0 A  Z  P+ H! z
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空  j; P3 v3 |9 K# a9 J2 P
        //#########################################################
' k. j: C: p0 e6 a$ X        /*do $ S/ Q5 d. a5 \3 ~2 {
        {. c0 a" g3 k0 z1 ]
                GetPortVal(PMU_SC, _value, 4);6 ?: B6 i* H0 a. c9 r& P
        }
9 f3 @9 ^# E- v5 S" \        while ( *(_value) & 0x00000001 );*/+ {/ ], J3 v4 Z7 y
        DWORD   dwRegVal=0;7 w+ a. j8 |1 }; [/ P# o
        do  @2 P1 p; r6 @# R/ R
        {  ( u/ Z, w3 g% @
                GetPortVal(PMU_SC,&dwRegVal,1);
6 f5 k% \6 f5 y        }: l# w8 D5 i9 ~: l8 O" W  J6 Z
        while(dwRegVal!=0x2);$ i: g, a  N: J  {5 @0 d& J- Y) V
: v) l0 v' V. U' w' a( Z+ Z
}( J1 r8 X( s) q4 |) C) D
7 o, d! k, |) n. Q0 U, x- b
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
' U0 @1 u. v* `* Q" c5 b% j; Q' }所以变成了死循环了。
) O9 C) Q, q( d4 U4 Y
: E8 H; H( C2 E2 @) ], K. i我对硬件编程不懂。又不知道从何下手。7 d: R- i3 J$ H% D
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
, z+ P! P  J9 R6 a2 F3 y但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。6 }! C- W4 P* C3 n3 ]) N  J4 I7 K' v

6 r  H" [+ F9 j5 C! K- J8 J7 U$ f我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。) |! E& }% j; M. T% K. ^
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。8 o. p, q3 [8 n+ |, F( b, x

2 e2 F# T& k/ f+ j. X5 o! A/ 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.但是你这样做法应该是读不到的。
3 P) d5 @, N7 f' ~! J" d% v1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
' Z% v  p+ O' ]2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
/ ^3 f8 U4 j: K; t# S! C! U3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
# g, _2 i& ~/ N) @! {7 a' \
; `0 F: o: P2 ~6 U所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
) f4 B$ L( u# l- u6 j3 `7 ^
; E2 k# O- g  Q4 H! ?$ b% k$ f. u那么有些什么可行的办法呢?
- h% C* Z; s& z! g1 ?0 f& Y为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。8 o) O. [: h' g( ]
% S: g) U& L5 U- b
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?0 ^) g9 r4 e6 ~/ E  b% s( I; d' S
1 x& l3 p; i& M' Z
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
8 X. i; j3 ]2 I: {; q! j. _( b# q6 f7 C
http://www.ufoit.com/bbs/viewthread.php?tid=452
' e+ [  `1 c* ?! [( g
% K$ o9 Y" g; @http://www.ufoit.com/bbs/viewthread.php?tid=241
( S- }" N2 J: o' M
4 H! _0 @. k' S4 j6 n5 n( y% W看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。$ ~" d9 b& u8 y9 }1 m

/ k' h0 I; M  |, U1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。4 x% W9 [& t1 a; n" E, e
2、Driver最复杂,也需要BIOS配合,推荐。2 X3 C) n# l+ x3 A2 T" c! ^
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
  n+ U+ P- T6 R+ w4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。, w) _5 A4 @, u
你可以混合使用。  v# [% c- v2 [

2 x; K9 _" @8 ?7 ~# y4 n7 y2 T5 H# n===============================================================7 m5 S% b7 J0 u& O" @( R- Q
管理员的这句话:4 V/ ~" ], [/ L! W' _( \0 u
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
7 Z8 E6 S( T. s2 s' t
; C" A) m5 M% Y* H# F1 `7 l予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
1 d1 j" w: y. f+ A5 z/ Z  ^* T! y# a! P5 S/ J
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269& L- P, t8 b1 X1 y& r5 ]5 c

2 w5 A- r: z& \) J/ Y9 N; [这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
. q2 w2 |% b9 V! A& a% c. T7 z
& J( ~- r2 x: y还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
. ~% A, E8 ]2 ]里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
9 ~2 k3 l0 R  J6 s4 K/ f# W* H: I  \9 u
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 1 Q2 O) d; L9 w; E/ k: k9 y  x
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。! H$ i+ c7 S7 b! M' x
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

. ]4 _0 U- U" a3 g7 O9 }2 U' ^0 J$ M7 l2 P) a
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
- ]; z7 V  L$ a. w3 F+ l+ J% [. Z# g3 @9 k8 v5 w
void write66(unsigned char Data)0 H: r. u" R4 v& B) H
{& q/ b( K  B" G! @
        DWORD Status,TimeOut=10000000;# P3 w7 ^9 f: m
        do6 b7 R' `- K! w9 `" B0 A
        {
( f4 M: l0 H" \+ Q& K5 y                GetPortVal(0x66,&Status,1);
4 z% l2 J! c- x7 B/ t                TimeOut --;1 N. v2 \- A# W$ _8 D* x+ Z- s; @
//                Sleep(1);
1 o9 \+ S( U& \2 P, v/ y6 O' b        }while((Status & 2) ==2 && TimeOut>0);7 g" z9 |( |1 F0 @2 f
# s+ O! R' A+ b+ f% W
        SetPortVal(0x66,(DWORD)Data,1);! r1 J- M' }3 O. Y
}* Z/ e& a$ _7 V2 u. E6 E
void write62(unsigned char Data)
9 E& M' W9 l# U# T- v' Z6 [' \/ o4 O{
& O" Q0 ?  |4 y& ^$ k+ j% T2 V        DWORD Status,TimeOut=10000000;
( s" E0 ~, ?. K6 \1 m6 V        do- |/ j$ }5 p8 [# b6 y
        {# b' ?8 \5 C- q2 U; C1 X
                GetPortVal(0x66,&Status,1);% H/ R) z4 H- O0 L, u
                TimeOut --;
! A* K& A" ?7 H: u//                Sleep(1);' l4 }/ g# ^! Z5 R/ d4 j
        }while((Status & 2) ==2 && TimeOut>0);- q; O0 k) P, ]) ~3 W% x/ T) z0 u! G
3 Z) L) y! o. J5 b! e2 ^8 q
        SetPortVal(0x62,(DWORD)Data,1);' _: n+ U, v6 [2 E$ L
}: H1 R; \( C, u
unsigned char read62()' o, d! G! I: ?
{( }/ I: q8 ?  Y2 d3 Y( h
        DWORD Status,Data,TimeOut=10000000;
. H  A# G6 \) K# W! e; K. \$ r5 Z* v2 {        do
- T' M/ C/ @% P  ~9 b0 o        {- Q3 W0 E  ?) N7 Q% J; @. u
                GetPortVal(0x66,&Status,1);
3 A) C4 x) F! i0 ~# H                TimeOut --;
, G: t$ e, T% Y) z& @/ g5 x//                Sleep(1);. I' t! y4 q* B! m9 }6 J. \; u
        }while((Status & 1) ==0 && TimeOut>0);
2 U( u- R. k8 H* {& t, s+ g, i- X) H2 R. ~  E" Q1 ^- r* a
& `& @" p, V9 ^
        GetPortVal(0x62,&Data,1);- O8 f7 u$ W; t3 O- V; y, T
        return (unsigned char)Data;3 m+ W' u2 L  {+ L: h9 e
}" y- Q" Z; m3 a6 n+ B# R
unsigned char read_ec(unsigned char index)9 e; @+ ]+ V6 P( d* `2 M
{
1 z" d* [. J% a. b        write66(0x80);3 N$ g: f7 a$ }: m2 b: B7 N: A
        write62(index);
. {+ t1 U: O' O6 d* k& P$ _        return read62();6 Q% N/ R9 u% ^. E" z- O! h5 t& }. ?! r
}/ t) V  p7 y. z0 f; W- g

& K/ b* K, z" P$ V, `; Z2 g[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1245) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
6 u/ i. X) Q+ O/ @: v& X+ w& W  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
) N# i4 M8 S) y# k
6 `2 P2 l- W3 U' m" H[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
$ q4 y: u: u5 k3 Z3 e: N. I" l: k) Q1 ?0 b' l' r+ j1 M) ]5 e$ ]
/ q) }% Q% Z+ e' B2 s, D$ h
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

2 s+ ]4 }0 ^: i" X  e( ?; Y4 f- p; O/ S6 s" E
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
/ Z4 k; B1 O9 ~) o. l# g# z3 R- J: ^; j& l" Q1 ~% L4 _5 @2 c
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.. `; R4 u3 C6 o- z7 k7 P7 L

7 C, c) U2 B' [8 C3. Then set bit16 of the IRQ to disable it.7 r% y' u6 v8 V" Q, u6 b7 R$ y

% `2 M8 D  M1 ?1 r    a.. Offset = IRQ# * 2 + 0x10;
- ~- T# H# c8 ~" v, U1 y$ K5 X* w! j+ A8 P* _$ s
    b. Write Offset to APIC base,
# O9 o% N* i3 F" `- u& _3 P- V$ z- ~7 G) f0 e6 e! K
    c. Read Data from APIC base + 0x10;
" n+ z, k$ K( T7 O; ]+ s- _  Y* |* y0 i6 W+ B; j  i9 |0 c: p7 ]
    d. Or bit16 to Data;
3 h% y3 b; y6 Y
$ L8 {. P5 o0 d. Z+ S4 F    e. Write Data back to APIC base + 0x10;4 i' ]1 J, H9 `7 r' Q! }

( |/ |  C5 R- _+ R) y
' \* w0 H8 U+ p! Y4 ]: }+ m) \7 M2 c
You need to check APIC spec for details.
回复

使用道具 举报

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

: p5 N1 h9 \! C) E6 g
1 E0 x& \! z$ j* @ 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
8 V5 ]! ?7 H+ i6 Y==============================================
0 r' }) ~0 a+ u- R 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。% M3 \+ j# G9 x2 t5 e4 X: f. Q! T% d

7 i' B5 i, H3 P0 _. l- Z9 a! x因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
0 p+ w/ z4 ]# |& t但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
+ j/ Y* B) F& \! J1 z& ?& `: Q4 D9 Q. m" z
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。6 E+ G7 D& B4 z, h9 j
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
6 ^, A& \7 p1 e* \* Y1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
2 \  t, w( ?( H" g/ I2、新手不要把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-12-21 17:12 , Processed in 6.038768 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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