|
AC In/Out OS Slow Response ! h- d) Z/ V8 n6 W" u z6 [
- Phenomenon
( {1 D6 }0 e# q1 B
/ [. D* K# q& D& c手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:4 G1 ]1 w! s6 [ s+ J2 W
: k4 C& y2 y& o
8 C, u3 h' h7 j% ^3 r3 [. j* `: b
刚看到这条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 如下述所示:# b$ z0 V" Y4 j% K; m3 d: J
// AC Change event1 E8 z( L9 o3 d, m
! L2 u" F) Z: M! W! T0 N7 P. U( aMethod(_QXX)- K7 Z* `9 [( L4 D8 L4 j3 J
, B ]+ ^. F. R/ l1 J) O1 T
{) y Z. \ c. j! _: y/ `
# o M+ F2 p1 L2 q- @8 Y. xStore(0x09, DBG8)
) q) M2 a8 R7 x5 J' o! f' X- L( A- \5 D. C# S( _5 e
Notify(\_SB. ADP,0x80)2 `; q' O- ~3 r" ]
//Power Source status changed
; H \& R; M9 y9 \
( R* S; _, S$ K* Y& G$ nStore(0x0A, DBG8)
. B$ ^6 N& H6 `- ]9 \2 `/ O
0 ]' R& K1 |, R# l* K) c1 ?. U& ~* u& p8 u1 T8 G! L
}; i8 t- j. W5 C9 o9 m' l
6 l5 d, m, t1 q, d) t8 O% s, [; u! y6 R; F
' g2 H# U7 t8 U
Method(_PSR,0)
9 r- t' [6 M# a O9 B$ h1 F+ \1 Y7 M3 q$ Q5 x; B: f' r2 O
& _! E& g. K1 C& j7 t
{
( P6 E' E. q$ Q
T! W) J3 o9 V/ |, B( C
8 g7 d0 P2 ^ g$ W# UStore(0x0B, DBG8)5 b+ h7 a5 U. `$ N$ N
# x8 ^9 o) F: Z3 ~! B( w' O1 B1 X
7 N0 @( r6 x3 u$ a
If(ACST) u/ v/ S l7 K. j
//check AC status- P. W$ Y6 \8 H
' S0 w& o9 Q" p{4 N0 _! B# T" v3 j* P5 z" s
5 O4 X7 \3 N% U U7 c3 S
+ @. L. }4 ~; }4 ~# z; t* J+ a! k
return(One) B# Z v* f1 v) M8 a5 e1 t4 h
// AC Present
N: u [0 V! P' J* E4 ]% ^/ D& g$ r
}
3 O' Q/ X$ c' C. x: r& i% @/ O$ s7 k. J4 i
else2 ]4 {. E$ [/ C i9 y
9 C+ Q$ ~+ _* j2 m! A ~
{% m4 G# n( `9 U3 f# A' p
, H! [) V, u/ t$ H/ ]5 C
return(Zero)
/ [& a% {: Q1 G. H \( H& A// AC Not Present
+ |0 X+ u2 A3 M) R) _5 h8 @3 F0 k, e( g" G( v# b6 Z
}8 A' J$ Q3 N8 n3 F# o! o% K: W
" L5 C$ v& N# \( XStore(0x0C, DBG8)* O# _2 p: P; R' w1 r0 B1 O$ |0 s
) m; s/ s7 p0 X
}
! B1 {$ T& L+ q, q
- Y% U P/ |$ _9 ]0 Y
6 a, u7 A# E- ^我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。 E7 a. |( |( ]
状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:
! ?- C0 Q p% n- ?3 w. x0 kMethod(_BST)
; T+ s8 G7 C: E{* h6 H- c2 V+ d$ O9 r( Y* Z3 o
: o( A7 j6 C! }' {. R# x
Store(BSTS,Local0)& _) e' _/ ]& p8 `" e* U0 T2 X- g O
3 r% v8 P: }2 k2 c( F
" \+ a. b# t! K, h* xIf(LEqual(Local0,1)) //Check Battery Present Bit4 O6 E* t1 C, N9 _0 T
5 B" R! r# [2 R: G0 s. d: _. O% z% e
{
8 G8 e3 y( E7 K9 G/ E& O6 b
( |8 _$ r/ T0 _+ ~
' o- f& s Y% e/ x& i! ~8 s8 c F/ Y) [$ o& h# e& m+ O: x% }
7 a) G% ?; O, C: p7 u, i
1 l, y( b a2 I% `4 G$ K' I- q4 F//Read Battery information from EC. r5 v$ x& A% c3 p
3 l, A' Z* X' ^. J… …2 Z9 H0 c* x3 u; P. r! L1 r0 C, u
^) c4 y* R" L1 n u, P5 q4 B% t# D H
}8 \6 o5 Y7 B2 g
@. \9 G+ V6 [) \' Q, e4 ZStore(0x0D, DBG8), F5 B! w6 ]# I6 D: X F
}
/ f4 [3 M9 K, r! e- f+ ^6 m那么问题好像是由读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所致。/ I1 {! ~; h% A
那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:
' a8 i7 ?" c3 I" u. y! s
6 m; B; M$ c; u# _6 h: P2 z6 x: V
而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.
2 o) }0 [1 U0 j# ~6 l 4 P: M/ v' E" A- l( {7 ?
3 |2 n4 k0 k- h" g, v
+ T( O/ |! E2 y3 z. x+ r
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!- A7 j( E" K! A
+ H* v( \4 V/ K1 {) l6 V5 d% Z- O, n9 o
% `3 L% |* U/ B- x. I) O8 r) i9 [* D0 L/ t) F: }2 }, q8 L8 m
& _+ M( B4 v7 S- K- x, z; ?That’s all!+ M) X" g: l4 V" |' G
) ]! c' S5 z7 T n& G
Peter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|