|
|
AC In/Out OS Slow Response ; _7 t6 L& q2 w& q2 { J% ^4 i
- Phenomenon
# X- G# _- V3 L b ! M5 Y' y. z3 ^4 R) K5 x
手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:
7 w% P" v6 e, B) o9 O& C- Why???6 U; j0 i/ q9 a) `% o D
1 _1 d% t% n- F" [
# U7 m- e" B. x( M0 ^1 e1 v% X# {4 ?
刚看到这条bug时,我有点不以为然,因为有些机种也有这样的状况,所以我以为这个有可能是不同的测试人员认知上差异。而且超薄NB为了解决好功耗、导热的问题都使用比较低的配置,我最初还觉得可能跟配置有关。但是他们找了个相同chipset的机器去试,反应很流畅没有这样的现象L!我的猜测站不住脚了,这时我觉得应该是FW有些地方没有处理好导致的了。随后我们开始debug,首先我们要理清AC in/out 过程中EC、BIOS、OS都做了哪些动作,我所知道的状况是这样:1. EC检测到AC in/out的中断,更新EC ram中的AC状态并引发SCI IRQ通知OS。2.OS收到SCI IRQ后调用BIOS中的_Q method并通过Notify function通知OS power source change。3.OS调用_PSR function获取AC的状态并据此更新power icon显示。上述過程sample code 如下述所示:
* q& L1 j: }( S7 U// AC Change event
& j! H$ ^) P# o( ?/ _( R4 @! J, F( Y T
Method(_QXX)
! ^/ _/ t% ^& o( m" Q0 P
6 A, A1 ?3 t2 u) v{
$ _7 g+ l, K2 Q$ ^* y5 y
+ G& M5 r9 w2 r2 k- B( r$ Y. ^# B m* ~Store(0x09, DBG8)% j0 \' L H$ q- t: j/ U7 _
+ N- _- H& \: Z0 k
Notify(\_SB. ADP,0x80), l* Z) \6 T: N/ M" r2 [$ ]* N
//Power Source status changed( _/ [% z) r. V8 v/ {$ q
# a7 c5 z' s) d; IStore(0x0A, DBG8)5 L* [& j- j2 N# [; f* h
8 s) d v0 t' G. Q
+ m4 U/ X# v9 m}+ ~' `* T& v* X g8 @
9 F, _! z1 N* {2 T: x
g4 W! i/ a: A1 G
8 n0 T) q A5 j- v- j
Method(_PSR,0)7 z+ C3 e& x/ [- n, Z, O7 U
# d6 `6 ?' {2 ]& F/ W6 B8 y
6 L$ |; f% m! z' I( w( |{4 X1 O4 F! W% v* I/ ~/ q
& j3 _/ b& z8 ]4 e& _6 O2 Y" H" M5 L6 S4 F$ S+ A( M: v) z" L$ R+ T- P) G
Store(0x0B, DBG8)
3 u$ G2 _0 Z' g3 V! z. X1 ]* O) D" ^! u# f8 J% Y8 K1 e" U
; }- I: }+ c3 J7 w9 f1 }! ~If(ACST)$ a$ y# Q3 P ~5 X
//check AC status# Y" x# R, L) A' l; p, f5 [% M5 g
) C; w& v+ f8 k4 U8 @) j{
, S# ?1 a4 ?. q h A g$ p7 c7 F$ h0 r3 ^' G- c
5 q, Y9 }/ N6 X7 `return(One)
9 N6 X K! o( {% H// AC Present# L+ V9 J0 E) O% G
# _. {4 w# R3 K3 w5 T}
- d' B0 x* m6 O* k8 C- b; B( s! s2 A$ U. @0 F% R
else
0 M( c: r p: W- ?+ s6 Z5 g4 A! F, n) H( r
{
. `, g3 A4 n8 s Z( A# X$ B9 c: E2 R, P2 {
return(Zero)
) ]8 j8 l9 |/ M$ Y. ~, R% A. v// AC Not Present+ t" \( |9 t5 t3 B
( ] t% j6 ~) }" \( g
}0 n4 F* M. ~: S: G2 |# |
& {7 i$ }# _* W# |! s
Store(0x0C, DBG8)- ]* f7 B6 E& _. M
1 @& a/ q8 H6 L$ c/ V! t}9 U/ G9 W/ q9 Y! `4 d9 c' O& T
5 v( W1 @9 J" e- N+ F( Y% o
3 x% [ a' O6 Y2 ]- O我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。
; ~5 P* z/ F7 X c状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:4 P) Q% p# c' C
Method(_BST)
; J5 J3 ?2 ]9 z: _+ d- E{0 I) z+ o4 Y1 M
3 w7 R$ ^5 F" Y D" W& XStore(BSTS,Local0)+ O7 z; O1 Q/ h6 R
8 ^# f X2 g" Y$ X& Q
/ t% R4 A' n5 t: T7 ^4 }8 D2 n
If(LEqual(Local0,1)) //Check Battery Present Bit/ B) Q. }- c" }$ y
6 T( u" O2 M% V3 z) {{
" j9 r; M% ]8 [2 @. m1 Q( }
! R9 ~& n, w5 S L1 h! V+ q+ n; T! b5 X5 I
, p" }7 k7 ], b1 L7 g. c; s( q! {% `7 @8 F
* ^" ~. M; t, C; P8 p# n! B//Read Battery information from EC# X* j2 p5 X! J1 j( k
$ n8 A7 b7 f1 Z4 W4 {
… …
+ ^& X% T* Y% p8 A. N+ o9 \( A' B2 k; K3 R& t# Z+ Q# I
/ a6 o6 Q$ Z* s. f/ O$ b}: ~2 v+ |8 u2 ]9 T/ c; M; h0 u
3 w7 z4 c) [( eStore(0x0D, DBG8)* ]' w, \% H0 m# Y" e) c3 G
}
: p9 f, W4 e2 o( r7 w那么问题好像是由读EC ram导致的,ACPI中读取EC内容的方式是发0x80 cmd到ox66 port,随后EC产生一个SCI通知OS,接着OS将EC ram index发给0x62 port,EC将数据送给0x62 port再产生一个SCI通知0S,接着OS读0x62 port就获得了EC ram指定位置的数据了。我在EC 端加入debug信息,发现出现状况时0x80 cmd EC很晚才收到,0x80 cmd是OS发的,所以貌似和EC也没什么关系吗?继续思考,EC产生一个SCI的目的应该是产生一个IRQ让ACPI driver获悉前面的指令已经完成,ACPI driver可以继续送指令下来了。如果某一条指令慢则有可能是前一个SCI IRQ通知 ACPI drive而 driver还没有处理好导致,也有可能ACPI driver已经处理好但是EC没有ready所致。3 L9 M; R4 ~! V' G7 Z$ l8 v2 E7 v
那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:5 b& M$ q S+ p3 g/ W" x
$ O) C# b0 z" d6 e! D' a* N) ?
% p+ z8 d9 _! |- ?" z) `而BIOS对SB SCI pin通常配置成low edge trig, SCI的pulse trig有个优点就是它能够自动复位,产生一个中断后SCI pin会pull high。可是因为BIOS是下降沿触发,所以EC SCI保持64us低电平会不会太长呢?会不会导致ACPI driver收到IRQ后下命令给EC,而EC SCI pin还没有复位而太久才收到?又或者说EC SCI pin保持低会影响到ACPI driver IRQ latency?有了这个想法以后,我就开始放大它,修改EC SCICFG将SCI IRQ配置成128 us pulse trig,然后再做AC in/out的实验,嘿嘿病情加重了,fail率接近了80%之前只有10%;那我再将pulse width调整为16us再试,结果200次竟然没有一次出现症状J.+ n/ q& ^* P! b
7 J# v" m" z, x v% o
3 U0 L5 ]# H$ _/ i' N9 |$ N/ V7 K% m& E. T: e
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!* B( Y) Y9 L. V/ j# G
/ l; M. A9 S0 z& j3 u
: ]9 h' M- ~# H8 T# G! Q
) q G+ Z7 P/ H5 R- y
# s! P( h5 }- Y) EThat’s all!$ l) X. Z @1 w _
3 _* |$ K4 I% |2 u( F' ^6 }Peter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|