|
|
AC In/Out OS Slow Response
8 q2 |: p6 d. q& F: I5 g; q- Phenomenon1 d+ R; F; j: l7 z- ~' S
" M- [1 W# K) F! V! W$ K% u) f9 X# ^, y
手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:0 }, m" b0 W2 p9 M" R9 H! v- a
- Why???
5 q9 q$ T1 f7 m% ?# Y! v7 b2 w
/ i" [, Y9 h% a
+ T: ]' y8 v: P) Z2 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 如下述所示:: {, B4 Y3 _$ A/ c* I
// AC Change event1 V$ B4 J& w, O& k" W
5 `& x( U: z& oMethod(_QXX)
0 {) E# B- R" f/ W$ V' O9 I% j* G: D2 u
+ G4 C5 n# a( I3 y' M{# s% i% e. i3 Q9 b7 ?
" i# \! Z) f, `8 Z
Store(0x09, DBG8)
: S+ \, K, p7 [9 i
( f) }. ^% P% e4 r3 f9 J) _. U8 z( dNotify(\_SB. ADP,0x80)6 x) u5 F9 h- u1 P4 m( a
//Power Source status changed( e& a$ \, x% j4 V: e
7 y( O3 c' Z5 Z/ v
Store(0x0A, DBG8)! y0 x, w& h* e
& G$ c! h0 ~1 I9 m
0 R+ t% c8 Z' _}: ?2 b) M5 G. C+ X; j7 |% W
% e0 @* C0 l4 S
1 v( m* r3 l" k) U1 a. q m; k2 y1 d& D/ b
Method(_PSR,0)2 H' Z9 b; M8 R. W0 v
3 r3 n5 W9 K- o, r7 s( F
/ z. z) v+ ^9 [{" @% M9 Q8 V9 F+ q! \
9 X8 n1 d( @$ o* g0 G
- ?% C- b3 ?. u% _
Store(0x0B, DBG8)" _, h2 N, P6 H' H* U
; k9 k, l2 o7 b. V6 f* f9 C2 \$ _! ]- d2 x; l: z
If(ACST)3 C9 g9 I9 B7 S
//check AC status6 i: P" W( T! x: G- Y( [' M) K
! U1 {- p2 o; {$ A+ i& _' k
{, G1 O( {& `: _* R5 W: v# P
1 b% S/ `/ W( P( ^3 v
6 T& W8 b: X! X% w9 H/ J4 D$ \return(One)
: q/ l) U- @! Z- N// AC Present
: L4 b' @9 X' [* P( T; j( E0 h4 B; i- j
7 y; [8 y9 W4 ~! C5 W0 [}
( K- R: W* d; {' U( ]
7 E. z' \, B% |9 relse
8 Y8 |& z4 J+ D3 S! M7 j. ~, g" o- S- r. O" R
{- i: j8 D- F. {: H9 \
% E$ ^# @6 J" b) G5 m9 M7 U8 b/ J
return(Zero)% A0 T3 D! U0 i7 \4 b0 ~
// AC Not Present
! E# h# n' M9 i7 ?/ T' G9 S+ \* ~/ q% B$ E
}
( b; ]) L/ p$ i6 `. w
4 q3 G* i5 k7 C5 b" cStore(0x0C, DBG8)
1 y( ~ l: L7 j& s$ _6 j7 h6 a% O/ U0 f0 D2 k% `5 F
}, u8 k6 W3 S. E6 i9 F1 y1 I9 V* D
+ k( f4 r1 m- b$ [/ y" q) F( e" }8 o' m7 s' O; H6 w
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。
& ^" \2 s8 e+ m! x8 U- F状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:
/ T/ i6 U4 R o! [- p& l' gMethod(_BST)1 E' f8 f$ P, t {; r
{
0 ^/ v! I5 X& ]' j, Q/ X7 e8 s8 j% X5 w& [) y' f
Store(BSTS,Local0). _7 J2 d1 {% q4 W$ c- \. f& i. P+ S
. }9 w2 d. }" d; Z% w5 `: t) x, L2 c p
If(LEqual(Local0,1)) //Check Battery Present Bit3 w9 d3 q; G0 i% F
1 u! Q. @7 s) T$ _, m{8 Z! E8 G7 _/ A* d
9 A6 \4 B" |% G0 v; e8 ]9 Y
: |+ n$ g4 p6 v( @
9 m: M {; g# c7 G4 r; p2 t
2 d+ w+ }0 M$ i7 N9 S' z" m2 \5 u% n& |" p# |9 C h
//Read Battery information from EC
% ]* G% |4 ~9 e, W; J, A! n+ M9 O9 B8 Y" G; O) q5 @
… …4 a8 D/ R1 p D9 `
( ^; Y) R5 v5 t" i' ^& M* x2 b5 r
5 I( Y) t3 ^" u0 C( i/ E0 v}% [" U# w2 q4 a1 E! d) I0 z0 J5 S
( Q9 d4 Q% H0 O! k; d( T+ G) dStore(0x0D, DBG8)
5 [ k' Z9 U3 B; H7 L2 ^} + f# s2 L$ j/ _& q1 i
那么问题好像是由读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所致。
! c! _ L6 X) j! \那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:4 o$ T3 |- T$ e7 r" l1 x. b" J
* H/ M9 ~2 j; h3 u
! L# e; ~7 w! v& P/ [/ d而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.; K: j3 H2 ^9 k/ C* y/ g4 [
( b# D5 p: D4 n% ?6 }- z7 B; L
) @5 ^- A$ y# t, k! B( L' W
- L* \ {: n0 R/ V经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!
3 m6 Z+ c. r) K- \: W) R7 E
- u, b, _! r9 M2 B; I# L, t" u4 M( Y4 _ G: f) ?$ k
/ F+ ^% O9 A+ g! M" F5 m3 \. O
" D& f Q3 g* O+ B* uThat’s all!
3 \- a7 j- r) t4 X
7 \9 i7 r( t2 _- x% g, lPeter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|