|
|
AC In/Out OS Slow Response D, J! b) c0 T% w. ~
- Phenomenon
2 y) G) S P5 H
) e! O( c6 L9 @9 L- I" O( }2 p2 q手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:( K/ P1 ~. }6 \( O; L7 L
- Why???
5 U7 ^( F9 f9 ]/ ~2 F k! I
+ Y1 U8 t1 F$ }% x: K. K2 D# B! S6 ~( i
刚看到这条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 如下述所示:
& x. s6 }/ s- K* G7 H' r+ n9 }// AC Change event, \& i+ S, c( N% L& m d- y. Y) g
8 R$ p7 A+ ?, A5 y
Method(_QXX)" B1 S6 z7 A0 w- Y/ r4 ?: S
[2 z3 O8 p2 r, K+ o
{
" L4 f: g8 L* B$ h! z" K) X/ A3 A) p9 z( e W& Y! S0 \1 }% ?0 ~
Store(0x09, DBG8)
" y4 ]: m) U g, E! y; C+ n! |% m3 N
: N1 {1 `2 Z8 P. m4 j( V: G3 F3 ?8 YNotify(\_SB. ADP,0x80)
7 I2 o$ Z; ~ m5 `; u" s//Power Source status changed
9 R: U x* j) ]% D- g: `. w& b* x" D7 ^
Store(0x0A, DBG8)# F* a5 n2 u8 x
/ c$ z7 S! K5 @1 k" p; }9 M( T& C
5 ?# P/ ], t0 i, V' J1 p7 X}4 n/ \2 _$ ^$ r
' y: j$ k6 V3 m6 r9 n2 z% X3 R3 V% S. d) N
+ k+ \/ ^% |) q& K. g9 v# O
Method(_PSR,0)9 s# G& d P2 S/ I+ g+ m
! _3 _! b; M, ` w" t" N4 { G8 z
, a! i/ |6 k& {* Z3 E' L8 y2 K{
r7 |/ A6 K( k) F% Z* q+ m
2 f+ _: F/ c; Z" G; M% I% X) a
. }; B$ L" H7 @8 x2 w2 D- H4 iStore(0x0B, DBG8)* @# i; X% _. w2 i
2 ^3 Y$ @# A7 F8 J- R& A7 d3 B9 j: u& ]% `6 A& q2 c
If(ACST)
6 ^* G! E$ L/ g6 O p3 T//check AC status8 H! e8 D1 ]* Y/ A# y
8 ~1 f* w( i. t+ j9 u0 b* o0 G
{# }$ f* r/ |- l7 g3 ~1 s. w
9 O! r, b- O4 s! V1 I/ g
/ r# z Y) Q, A2 b) N7 u9 lreturn(One)
( R( V' t$ K; F$ k" c" Q// AC Present
( h- O/ J$ @" H# i: D
n! W' _* l2 @+ N7 ]% J2 o}3 ?( C, I4 ~) x2 h7 O
4 k# k) N# k+ I8 ^* H
else
/ q0 ~, S/ @& O n9 r9 D2 h/ f2 l$ y8 b. Y
{7 q9 r8 i7 r1 E* S& E
9 J; v) e! |; w" o
return(Zero)$ l( P) H$ M1 k
// AC Not Present% n2 x0 z0 m( a+ k7 \( F% _* |8 i! n; y
% G0 u" Q @+ e. P0 Z; Q- j9 y
}7 N5 F; D, h& y0 \
9 D6 K! {: ?! dStore(0x0C, DBG8)# q9 m* f# E/ q4 M" s5 O
9 N* e/ D- ~* K/ F9 J y
}. j3 t& }' y* X: z+ C
* x0 L6 T- [8 \1 D( L5 Q
( X! h( [- R" r( C: \# Q% \7 B我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。
6 E) |$ a$ u3 }2 m( Z4 Z2 \- M状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:# p. s2 m8 n% I9 S% M0 L4 N
Method(_BST)
- ?1 _' y: p$ \8 s( `: Z* ~4 M{+ n) l' e" d) l0 m- D/ u
3 S% t' g/ }+ Z1 OStore(BSTS,Local0)
' H E1 m' Y! @( b* W; K$ m( m8 |' v
$ }) z: \8 \2 r; X
6 J6 h& m. \# K& R3 L& A- {If(LEqual(Local0,1)) //Check Battery Present Bit
2 p- x- o1 k4 M* g: U6 o
( E/ q) \1 E" t( g{- \9 M. Q% V. r5 P S
1 y7 w6 O) }7 c6 b8 K
% Z7 q+ K; j- P' T
9 v) m+ g& S3 n: p
5 W+ ^$ w+ s# R- c9 m C8 c5 a* e( S
//Read Battery information from EC
1 L8 X) C) C7 M/ J7 B$ {) }% N1 c* j$ v' p* H1 k( Y
… …: M/ K6 R D7 F! \7 @
K& W# n2 t- q6 D' i- L
. a' M7 N- Q4 G- r}
e) y6 s& a3 S# N) v% ~
! |6 U* o8 G+ h9 T$ w; a7 SStore(0x0D, DBG8)
4 J" S; Q: Y9 A4 O}
( b+ F: Y; y+ s" j那么问题好像是由读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所致。
( s7 m# l$ `1 |$ T那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:
) B- ?- b" P+ ]8 a! @8 @% L: {1 f7 ^ H$ c
' m# E4 Z1 \' i- v: Z. U, 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.8 J0 w( [1 Z9 ]) v D* \
/ g7 v0 Q5 p* |4 ~
7 u5 l. X) a5 u/ F
$ A) E& r c g
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!) ^' v" N2 N* B! W
+ W2 v) F0 `. H6 x. x) C4 S9 U# `2 U. v3 k. [1 y- A( g% D k
1 @4 }/ A# S! v$ } j& g6 [0 x0 y
( W, k$ t* w1 x6 RThat’s all!
4 s" k" J% o" U2 X3 @7 H
, n }% V! c- j0 dPeter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|