|
|
AC In/Out OS Slow Response ; [2 W( u5 S. ~. B# e/ H# P
- Phenomenon% Y8 `- ^) S( n" [8 _1 n" ?
K( f6 z# p d1 y! \" ]8 i手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:
6 O3 g1 r6 h, }9 a4 q* k$ V- Why???
. O# G0 O; s* s+ o1 X 5 R C$ X! P7 x' d2 L
7 N/ h' r0 h' l5 F W& r0 \刚看到这条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 如下述所示:6 Y- [7 a& G" `" [/ l
// AC Change event
" m: P7 {% W, [* u' {7 A" [$ x8 A6 D% ]4 t2 } ]" }" S8 ^
Method(_QXX)
$ X0 S% }$ N; q9 x: K5 m1 b4 H2 e
4 b# o# c# D& Y1 V{- z. h5 H# O$ R+ o
# v, `5 V9 ?! l ^* R4 G( O! sStore(0x09, DBG8)1 ^* Z9 u1 `: T. ~; i
4 k c1 d. l8 Y- x/ t
Notify(\_SB. ADP,0x80)9 z {# l* @4 U3 x; E& m3 m" J
//Power Source status changed
# g1 H. s$ @/ P) u8 `5 Q/ W: L6 A( Q2 z% P7 }' s3 X/ Y
Store(0x0A, DBG8)0 o2 ^% E) ^7 N7 i
0 Y5 Q& d! c& }8 C2 Q8 B; J+ a7 s
' z( t$ z1 S% j. u& d+ p" Q+ G
}- d" b2 ]( m- N: J
$ Q+ z$ m* O1 a& {# V
" {, R3 ` }- O) S6 d" X) A: f# T5 v R! G
Method(_PSR,0). @# f5 X1 S6 K. G/ U( _7 ] k3 u3 Q
4 b% H; p! N, m
8 J8 f N0 ]/ T( W5 j{
9 E9 J K B" @# U" Y- A, ^+ l/ P' q' E0 i$ z- x5 p! Q0 h
5 H& W" @3 G' GStore(0x0B, DBG8)
& Q' @. K2 R! B: [( `0 ~" ?6 {& a+ u7 B* }5 f. H
Z" U$ I: B# f, t
If(ACST); S! b1 |( H! `. O( e
//check AC status
* U! ]1 n, R4 h; j
9 _. Q0 x+ A8 R" [{* x/ z$ a) I; g0 f5 P3 q V
0 i5 \$ q% k3 e, d2 y
3 a4 Q+ {. O0 q; U
return(One)
3 \' i) r$ c! S: B* i2 Q* w1 ^) [1 E// AC Present
$ E: S) _6 C- U: x$ h, k G5 i
; _ {8 S; k* `$ X$ j; o2 L}3 N S) W- ^9 t$ m
. ]" y" u4 h' [' f- I$ S
else' _' @3 E3 r' t% l7 m1 d3 p; C
% ?: m: L( X4 b: u
{
+ D& u+ |- R) d9 w
3 n0 L! G, U9 j0 [" _/ Nreturn(Zero)
7 J A9 @) ?9 {" \' }// AC Not Present
0 p5 R0 J8 Y, q; |- B1 N
2 n6 ? x. l- ~% \}3 f* r' U' @+ b- C9 D
" N- h8 h$ i/ s- g) v' g C
Store(0x0C, DBG8)
1 k) e& S& R. |8 q7 i0 ^, m- Z. z
9 Z$ t9 e8 d( w+ N/ D}+ p7 C/ W* t& r
: \$ u* o9 z# V R( i1 x3 D
" v" T- C G4 D' Q6 N" X! i5 B
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。* T, R$ B$ f! E: l
状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:; q) I. c2 R- D; F' t
Method(_BST) x: C+ X( d J- u
{
/ \* h) N8 Q5 Q! H$ A
" a7 j. y+ C! |. k+ ?) _9 R$ lStore(BSTS,Local0)+ o3 q2 _. D0 K a; N4 |$ G" H
4 y* H2 ^% d5 C. r! T
9 E2 o' w1 H' W% o4 YIf(LEqual(Local0,1)) //Check Battery Present Bit
p: O, P, m% r) [& B- {
& T8 O0 ?6 J* O& q{
- k3 Z3 n W9 \# f
1 v, q) i ]9 Z( Q2 j% o. m! w9 f2 v/ E! T2 v' l) Y' Q: @
R' W C% e7 N* J2 w$ x. x! }& Z
, B) `) S% S% E
+ V: T& ^4 a9 w% N9 E E& W
//Read Battery information from EC$ W5 L. q+ U) R& \5 h' u
6 j5 y/ q0 W- b# f
… …8 u7 V/ ~8 w& ^# T. z
2 Y# r0 w& O* K0 n$ J6 a
w" D8 M8 r( |6 N! U3 M- J- O5 e I- M}0 n: P" q# `& T D0 T4 X% ^. N
. l @* L" U$ A% y2 |Store(0x0D, DBG8). e! y3 [. l O9 A9 r( i+ W
}
$ \& @' y0 y2 o那么问题好像是由读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 z! G" f0 `* a/ z9 Q/ `6 ^那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:2 n& f3 A0 t+ b8 r3 T6 N: L
, P0 i# W$ g& k# Z5 g
% U" s9 O6 W K而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.$ j. Z! v @# p2 K( K; {' m
# d4 g/ f. r5 ~+ X
& x! z6 T( V5 A; x& x
8 ?5 R" q' i1 e# ?5 d经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!& c' f% s3 E2 ~0 M4 \7 O
7 e6 ^+ z$ ` ~$ F* G; ^9 }1 Q3 E2 q/ N# ^; K
; `1 {+ }6 H6 P 2 c( \8 q% B- Z, U! A9 g2 T! D
That’s all!$ I8 M% C: K a
% J* s2 n0 E: p1 s9 m$ z, zPeter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|