|
|
AC In/Out OS Slow Response ; U+ J4 e# P4 m/ L; D, M
- Phenomenon
% }, C* {1 L+ e: [0 A7 X ' ?% J; L) O6 A# G6 n
手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:
* g, A( m! V" c8 ?% y: y0 l- Why???3 m! W/ d6 R; x7 s+ K
: r$ J& O5 q( e: |1 z
% Z6 N7 k( t' S/ r7 c刚看到这条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 如下述所示:
( m5 _1 V* g" o8 C1 l0 \// AC Change event. C) l4 R8 h& d$ b
% v6 W1 d: X! x9 g/ N
Method(_QXX), J( ^# v0 Y# g7 `$ M
% F5 @8 I6 I: n3 [( E6 g
{
' c) ?, y6 X% \3 k. z. s) Z8 m) c& {: v% G* m u
Store(0x09, DBG8)
2 | D0 n4 J: N0 \+ o. D# j' F2 H+ u3 z+ \/ x
Notify(\_SB. ADP,0x80)
$ E1 L( L# Q7 @4 v0 b" D//Power Source status changed5 `! P" I ~* U7 R
; w5 U7 i$ ^8 p9 |
Store(0x0A, DBG8)* u) g B: R; t
) P) ~. a8 d/ {! v T% A; h/ N
; T. m! C" V4 C' E7 a; {}- i4 a1 A6 y- v5 s7 N$ G# ^. A/ J
3 \3 a; \% o2 c0 U
0 m$ F3 W: d) m) G! U* I, M% F$ L9 `
" r( n" n. z: c5 D" c9 D% g. I
Method(_PSR,0)
9 q8 C% O, {' l
5 p: [. B0 B! z- I( c' }( O5 _0 `1 ?6 t" j5 @. t, ]1 }
{* E' t s! `( {& G. m
% U8 z( w6 G: | y) D( U2 a
$ d: s- \2 S4 Y0 {- Q' n {
Store(0x0B, DBG8)
$ q0 y2 U6 Z/ P: `) K; U; k) Q3 x+ M* Y: o# |& R' c
( c1 D! u1 F2 |5 @8 ~- ^If(ACST)
* }1 V* n, w: Q! @) S& Z9 r//check AC status1 \: M+ ?8 L7 P- R5 g4 }) }
; s. g2 X6 D, Z8 F
{
" U- u. l+ Z# U; Y
( [% ^5 }! N7 `5 h
% K3 H1 y; n7 u9 D& D& k0 d. \return(One)1 l- }) ^+ z% }6 P. V" Z
// AC Present
' \- J" X! J! M( p" j6 j' H5 d4 @7 j- q7 y8 w" e
}& p2 O6 X/ q5 b# h4 e7 T! Q0 j
4 p! ~; x6 r; Y3 f" P& f& C
else
( ^$ T+ _! j0 L9 W0 v; J4 X7 V5 v( l
{
. l/ ?9 \- m3 u0 v( j0 T: @& P# B
% z# _0 r% [/ d/ e, e- }return(Zero)
% c4 _( O! |; _! `// AC Not Present9 l( J* A3 f, L: H, H7 G
0 P/ r, _ ]( b. o. {. n}
2 @) A3 v' h- o6 P% e' }' q. S, c/ i
Store(0x0C, DBG8)5 ]- e, r8 h; Q, t$ r ~7 |
. b5 ^/ y7 d- y}8 l; [1 i9 D5 o* F4 z* v8 d
# d5 t5 Q* r8 w' H* f" H
' J7 v' m. R. J8 X我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。# F3 G, A3 i& j$ F% M
状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:
/ B. ?9 i! Y8 O$ dMethod(_BST)4 a1 l, x# J L4 _/ A
{
3 g$ S: l/ y7 h) M% }2 y% V4 @( r/ l# ]: i- v7 ]9 [9 V$ t
Store(BSTS,Local0)
7 g. Y$ c3 s' p6 \1 C/ T* A5 l1 [9 W3 O, V
3 n. O$ T+ v4 s% q4 Q; o
If(LEqual(Local0,1)) //Check Battery Present Bit
. V9 ~# ^& X: }& p
% N; Q5 t$ d9 M, d% R. x5 B{
. {5 W$ z# }; o" z
1 B, E, ]+ c) u7 A% e4 F* s7 R2 k6 G
: e1 o( Y8 C0 }' m7 J
1 e7 M" F7 l0 ~2 X4 @; A/ L+ I4 G: T9 M
//Read Battery information from EC
( ]- V5 W3 ?3 W% Q4 n) K
- e% Q' w0 z0 f) Q* @ H1 Q) |' d! w1 b) C… …& t- Y. o: [" N
, Z0 x5 b% t7 j3 M8 y8 X% w; R
& D4 |4 m$ b- H}! D* `# u, J0 `' Y
2 n# b; `( a5 X
Store(0x0D, DBG8): D/ Y6 f/ G' l. @" o$ y1 A& D
} 5 w8 K' X8 H. |- E0 n* B
那么问题好像是由读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所致。
8 j' Z& d& e: \* ?6 ?2 B, h. g那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:/ |1 V" p2 T& T5 b
" B7 T3 w$ t2 X4 t/ l+ r$ U7 S2 [+ q/ J3 L1 ? t) |
而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.3 ^+ { J7 `& q* |4 O1 c
; b% [+ @9 N8 ^4 ]. f5 n ~" f/ g R- x$ T: w0 L
4 I c7 H8 L: p: A2 i经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!
9 k- N8 O/ ]9 o0 n& S! r
+ A$ l& {' I0 N R* S* R: ?) q: Z( n- [$ L4 e
5 c- l0 R% D- E1 A# d2 U5 ~
/ m, Z+ E9 s8 ]That’s all!. b. g* a& L% y2 }4 x6 a
* o& Y) m Q$ B2 TPeter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|