|
AC In/Out OS Slow Response
) i+ E1 i- j# P7 x( H" X- Phenomenon& e- D. y' H5 E0 k2 e
6 b4 ^- e- p) E7 V! h& F" Y3 k
手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:- P, X& I# H" z5 y
- Why???3 G6 `- I& g' ^% [# ]2 }2 E
% ^, m) w }( A2 O* o. n! R
4 t5 `6 ^! B% F) [( Y ]3 v刚看到这条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 如下述所示:
, V& Z1 K" |7 ?- F8 V! }6 t% Z// AC Change event
) C( p3 E T0 ^: h6 f' [0 b3 M
/ u5 X+ m3 \0 A0 M& T4 E9 S8 x& BMethod(_QXX)
$ |& J% o6 w2 o9 x6 ]7 N( b# ] y
" U4 y: ?" P( t( x( U{7 c t; L2 C+ v' A& q3 F' j% t9 o
4 R0 W* m8 n8 F) K: HStore(0x09, DBG8)- u" F% U4 F" n3 e T
2 V/ ] P- L; P q5 QNotify(\_SB. ADP,0x80)/ _1 l" b8 e2 R+ w6 ~+ y* J
//Power Source status changed
1 T; y8 r* x7 K, K( m
, A( v. y0 t( m. |: O1 SStore(0x0A, DBG8). Z* i: r3 V8 j1 n. R! i
P0 ?2 D0 J/ c; X* S
% u- ]3 S! N e9 b% d S2 U5 k
}
9 P; q. A6 W2 P1 o2 c% a: y" o W& M7 Q! }! Q: O
0 c( ]) j# H s# P; l
6 O! D- P, J1 c ^6 M" X/ ~* s
Method(_PSR,0)3 W, |$ R$ z4 R! y7 n6 @0 Q
6 X7 W3 h* b- F
+ t" K7 _, u( D1 l
{, [9 U1 G4 g! Y W
7 I1 ^: Y2 w& q, h3 |( ~% c9 }. O) m/ j6 O- Y, s7 p* D
Store(0x0B, DBG8). Q1 }- x8 b+ m! B/ ?$ S, V
$ Y" g2 S( c2 b9 n3 u3 n- d( m
+ R, ]4 g8 D# X- ?1 F& i; n) v) z, U
If(ACST)( a* j7 X/ p6 |
//check AC status7 ^8 E3 f0 X, B% t( u- X
' V- ?# C: x+ l7 I" o5 B{' d6 v7 I. A% z' s* ?! l2 y6 h S
4 C; j# k J& ]9 B
3 \' N: ^& B' freturn(One)& \1 p( y& k" A, h8 e
// AC Present
$ h1 Z G: [2 \! |; k
+ U! ^4 l c* x- _8 ~}+ b0 D1 @, S% q6 l! y+ h
+ p5 M! \; E, k# |! ~
else4 M, i# `0 R1 x7 G
' W- O$ u7 f% o4 `
{4 |, W$ o0 Q4 L! I) a" B: |/ z
' |& f! I" T: i4 l0 Rreturn(Zero), u. ^3 ~2 ^/ e& P
// AC Not Present
( j, p4 i# M# L3 R$ ?3 [; k
+ t6 w, o M4 s7 V}- T3 B z" w5 ^' g' s# t
, q( m) w. v/ R# A2 ~
Store(0x0C, DBG8)* F& G. s: |& f7 ?) j6 T
- O5 j4 L% d5 h; I5 o! G# Y}3 N* Y% H$ M: V& ]( O$ \
+ E; M2 [: w( v7 `6 u
; l7 w+ C. x% n: L+ h. e$ a
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。
$ R8 |6 i. F8 @6 ] c4 c: d- A状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:" E* [' o+ Z/ W4 I2 q" ~
Method(_BST)
3 r7 m; r9 V/ r0 s" R" K. g5 z{
9 e2 ~2 k9 l6 @/ I6 n0 v. ]5 G: d$ q" S4 F8 v2 S6 H- Q X0 s/ \" t
Store(BSTS,Local0)
9 E) R# B% K6 n7 B5 }- B/ `7 Q7 w9 G% W# f4 i$ e
% @+ H/ v/ n/ H4 e" P+ x) {! m
If(LEqual(Local0,1)) //Check Battery Present Bit
: k; u1 i6 ]4 P2 ?" o' Y" d, }5 t. R F8 X( I8 i# x
{+ _/ v# Z3 W) W9 f; ~" H) r
. Y- r0 E ]+ C" x L
/ E2 i* T+ F8 y# ~
/ F, U1 t- R9 S' f1 }& d$ k3 Z: k0 U, _! |9 F/ [& o) q
8 I0 t ?. v" u- O( q3 b5 b( |
//Read Battery information from EC$ d7 g) t- I6 v: K; Q- i& I) Y
- V0 N, C) _( ?$ o% S… …
" H a% {/ q, b) h+ G7 {
6 A( A* e2 a. ?6 z
' v5 ~) M" D4 w8 U/ J}
4 X0 C' [7 p7 H' `% b2 N, O. h/ s) B% l: w+ R1 J. ]& q
Store(0x0D, DBG8)
9 F9 Z9 \( ?6 V. _& A} ; Q L( M6 r5 D" E" E
那么问题好像是由读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所致。
/ m3 r9 P5 d+ ^) y4 {8 {- \. ^$ o那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:
0 J& j7 q- K, e- M. h! s5 _, l: H# ^$ L$ E' M
& o+ {# h/ [5 b而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.
; o/ L9 F" K3 W. |( t 2 w( Q$ h* Y R0 M
, ~: R% j/ @5 [+ r. ^* e
2 t* N$ i9 Z$ F; C
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!
% X4 g& ~% Z0 [4 s; |) g
" G. b) H$ L) r/ {: w) `0 R5 k) B3 s
+ @$ b' W$ z) N' B' B B2 n 2 [7 \% t. z2 _5 _* I3 C ~
That’s all!3 A- o& t( p/ h! M
8 b3 g0 y I8 e: N- ~Peter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|