|
AC In/Out OS Slow Response ) R5 }4 a$ H8 ~5 N) H" P
- Phenomenon; ]% |! S {! c: E; _" u
3 {9 ~+ r7 c$ _- O8 v4 ?/ B手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:5 r. {1 ^4 A m, M
- Why???6 }+ s5 g1 c K' R, W* U5 B" l
$ e, q2 n. F* Y z" f
$ W# B2 }+ B) ?. v- S; ]* y刚看到这条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 如下述所示:8 o& \6 N: {! x9 H. K0 s
// AC Change event
1 j( T1 Q. \* m( `; q; g5 r
1 u1 @+ F5 O3 SMethod(_QXX)
' v9 X* U! s; q0 c: {4 }
3 d- i2 O- k1 V T. F7 z{
) u# J$ q4 a; G- K+ K& X# s8 o' |1 v) ]( F: ~) L
Store(0x09, DBG8)/ }( }) t, ]7 E# _" o& l
0 b! F5 P& t7 L' K6 U8 N+ C7 ZNotify(\_SB. ADP,0x80)' i a# E& F- F$ U
//Power Source status changed6 X e# B/ k/ k( S/ ]# k
4 U7 |4 s/ K# b5 h# K; @
Store(0x0A, DBG8)3 K" ]" K6 w( n d3 |
& f" c% e; P# p& X; u! b7 {/ {6 Z. [! n% x9 ^' T
}
) P$ j) G+ H7 d9 ?' C2 ` w. N
( z) \* G5 t% K, V- x' Z; j+ v6 r: F6 l' }% ]
4 L5 f1 {1 @) Y- z0 i& I
Method(_PSR,0)8 ]8 x H0 O3 s( C0 s
, N5 a9 ?* J- y" A
5 v8 S" l" [4 R2 n{
! r2 E5 `8 i/ A; ^1 ^5 k$ P* u! V4 t
" K* t1 L- x3 P
Store(0x0B, DBG8)' |. B! Q2 _& v3 \
7 |; y& O9 _/ t( \
( Q) T2 v! I2 x( k+ k, U$ VIf(ACST)
* M. ?* M5 A7 v5 h//check AC status; m2 k j0 h+ Q, \0 ]% M4 u7 X
7 M. N6 O- L. E8 Y$ z{& g# h! h% d" t2 B" i$ R
& |- u& F7 T7 A7 O
4 J/ q) D3 z# g5 _3 Z. Q: [& \return(One)
+ d+ F, f3 i/ |& P W5 ^// AC Present
/ C" h% c' ^2 V8 _. i
9 ]" ]+ `1 _+ [6 I( J}9 S' }4 X2 q, w+ K# S# t
) J0 x1 Y6 E. S0 _3 Lelse
8 u5 `% K; J. ]+ y) ` [* U4 E9 ~( V4 K" v G& a# _
{5 F. ]7 d7 B4 }6 o1 C+ w
7 |/ N8 u0 M7 X. A, g7 A6 Lreturn(Zero)9 g5 _, P3 M: ~- U, B- a
// AC Not Present% U: F& J1 c! `7 G
! C5 o9 b8 \% I6 u6 P& }}
$ T! C. R- H$ m
) L5 X; F m$ n. R0 {7 HStore(0x0C, DBG8)$ @. Z f* |0 K# Q( |+ r
0 L3 z8 r) D6 k$ l/ x3 H; k}7 X3 a; f) Y' N# x
/ t! w! Y6 ]. q* f7 s t
. Z0 }* M w% w$ f' f( b8 x7 B我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。0 P! j: U( k/ b8 u7 m( r) ?
状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:
& M, l. B1 Z2 a/ H- A4 g' m( MMethod(_BST)
- G% c6 U3 ?8 t/ ]{
, y) o/ x O( c
H' z& i0 X1 k- D _4 k8 z( i- KStore(BSTS,Local0) f6 j! L8 M; N3 q
% x: A- r( u" P- ?9 x. I( k
! L4 N; v( t/ x4 ]If(LEqual(Local0,1)) //Check Battery Present Bit
: z/ Z! j/ H. P" w; B/ s# B/ R# y; Y* E0 N, s' N, h
{
# ], Q2 ]- [' v) P% ~
3 n) ^. X- {; p: M8 Z0 C
: o/ T& d) s+ U& x
: P' V2 `& ?& p9 q# g- w+ _3 Q- c b3 E9 p s
1 X- @- k( t" Y4 Y7 E- m
//Read Battery information from EC
3 o7 w {; Q# u1 G( L% {2 m
D# O. d; ?; E% m* V$ `! E% l# G… … l. m$ r% n: A3 |! `) Z4 C
- ]+ U! ?) d% o
' O/ z, A, l/ i2 e* V}1 s$ v" Z9 a' h7 O
. {5 b& x2 P' A2 y2 v2 e$ p( S5 P z
Store(0x0D, DBG8)
5 x& S# N6 u) l/ T9 A}
' } K7 F) ^0 r2 `那么问题好像是由读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所致。4 U7 Z+ ^% x4 q$ s, Y
那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:
# d' R) n. o: G8 X
3 ~$ ]4 {- J2 N, w/ g* I1 ?* `0 j. ]9 p- d$ o$ |. o
而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.$ L% }; ~5 @0 K
5 U) G8 A: I' d5 \ C% P1 \
/ V+ _' m7 F, z& P) F- k& A4 `2 t6 I& H! ]3 G
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!
. X2 W! w( l0 X0 |0 q
3 a" k1 t( y# Z& {& A5 i( {- n- J3 r1 N$ @/ L$ T
9 v' Z, @" w) v
) H# R1 B) B( f4 SThat’s all!4 L3 \4 P! }9 |' B7 H |* l
: ~2 z2 B9 E# X
Peter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|