|
|
AC In/Out OS Slow Response 8 k L! D$ T: C; b
- Phenomenon
* }8 k) B5 {" \
9 @) ]* o4 K& Z: Q4 t9 {8 |: i* w手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:
2 i. ~2 r. v0 X* C6 `9 K1 a9 X$ `- Why???. y+ C& d( s! N# v; @8 J& w% M
; D! I3 P7 p: m9 E" M( r
. c D9 w; D9 o9 U, _刚看到这条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 如下述所示:
) Z J. h# d% p: N// AC Change event
; Y) i+ A! u- P" Y3 Z; ^' N0 G3 M. J: Q0 `6 P) b" t
Method(_QXX)
/ a' K* j( L9 f- I. s
. S: K5 e1 k. d# l/ P{" \7 A0 u) h+ C7 r
" q. e$ Z' O8 p2 ~) jStore(0x09, DBG8)
, ~$ K( N4 Y9 |) ?. c$ l0 V% A
/ H# D$ J. n6 t4 wNotify(\_SB. ADP,0x80)
2 `- {7 |, p0 u5 V( J( b//Power Source status changed
! W6 c7 e9 }# N) K6 A& \+ ?5 r$ K
& s: L, O4 W; Q* I+ U$ I, F: Y+ {0 p( TStore(0x0A, DBG8): `) X {, B) y/ @ F
& o1 M& o3 {" A. T C) Q6 [/ N6 I! z4 F) j2 ?( `
}" j9 o0 g, s, [; p6 c: W+ s
6 B# D4 E" ~6 I$ O( T. X" k
5 t3 T! {6 S1 G$ P$ P/ d
" e5 k+ W: t# b/ s; U, [( V* N7 OMethod(_PSR,0)3 Y) x8 y Z7 d% Z' L3 E# ~3 O
3 i5 o! p' z" W! m2 k7 ^- ?
6 N0 B0 U# ]; E* I9 q; I{! }- W) [ `" Z2 L3 U; _2 U$ U
) P" E2 h9 F8 j
o" h% T/ H$ Q; x9 y; l
Store(0x0B, DBG8)3 m# V7 h/ R! w/ M7 g
* t2 G" L( t% d6 `1 q
; c( o- s8 _1 {+ w8 U
If(ACST)2 J; k! W& g# J4 ]4 K" O; H5 C
//check AC status. ~$ S+ H* b* K* W0 r
1 q* z, Z2 L/ G/ Q7 _! v# J1 h{6 B1 r$ s3 M* Y: L( s# N% Q6 B- S
: m9 G u5 f9 K a# s
! X, a. j8 B' ]return(One)) j/ D/ g) H8 `+ S
// AC Present
7 L/ b, ^# j1 r
6 V |- L5 @6 X9 @}
6 ?. D/ g0 R+ j, ]; E' s/ S0 t5 q3 }% g% u6 o
else
' T5 C2 u/ F8 t+ M p' d5 q* X: o4 z. x) |2 E
{
8 Q) Q& Z" x# m) t- l, d, k5 x1 P* w
return(Zero)5 V* Q( T; j0 K m$ b$ }
// AC Not Present
2 T/ O& K+ U; O* g
* ]4 @/ _( e. p}
, q, w0 m' y# o! I
2 I# K: @2 \) P6 z. vStore(0x0C, DBG8)6 S! i8 o+ Z& }$ h- Y" Z1 U
# p# q j. y2 C5 @! ^# A
}6 W/ P; j! X8 a# f/ M( B$ m
. ?3 w: V1 L# k! c5 w
( V: G$ j$ l& L- f4 V- J
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。, a5 M! t. p7 \: [
状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:
. I$ P# l: s! D2 x. qMethod(_BST)
" n' B2 j3 R( P, u{
% x `2 o- D0 n* C6 H5 _* \
0 b( B- t: r3 U1 Z T: R+ g3 [Store(BSTS,Local0)3 P9 s; }/ ]5 d7 M" R" o+ X0 \
8 y) R7 t* R, f9 T0 S: Q, v
2 P1 k, t* ~( O# e7 N, Y
If(LEqual(Local0,1)) //Check Battery Present Bit
0 H' }6 I D2 g+ r" Y! [
9 Q7 [- U9 j* z: }{' `) u# \# i3 A# S2 }
9 g: m3 c) f0 t+ @/ p4 i5 Q& B: q% X3 h( x
/ i F& y$ C7 `* g
& k4 C+ n5 m8 t1 \% I) F
1 M% ^% t# e' V2 L, Z
//Read Battery information from EC
m- ]! H/ ?: p7 W, U; ~
# A% {1 b8 M; }" Z+ ?3 R… …8 v( o, |; `) P+ ~
8 c/ x# B L/ b' M2 H/ v
$ _8 a3 u1 l# t* a5 M# F8 I0 t# M}7 s" W! M6 f9 s8 L% Y# G5 A
: r1 I- O }: u
Store(0x0D, DBG8)
) g, R0 J; f% V} * ?7 h- E! ~: p6 D# Y( B8 t
那么问题好像是由读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所致。 X* l' P3 p* j5 M& O" X4 C
那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:1 s' L* ?. d9 V6 t7 ?) t4 i
! O3 A7 l( u* P- x |
5 D1 a s) o% m5 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.
K% O; w& S+ a e) b7 L( N1 J - |- H" u( g5 G0 C% I& G& T- ?8 [
. J6 U, \; z. o# H! C- {
9 `: ?% D8 ]- U4 ^
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!" ~: w# E6 W6 A' B* J. U9 [4 W
5 I* e9 C5 w4 ?' `$ f9 B/ P* y+ j) Y# p1 z
( t- k# ^$ Z% x, F% \$ w* M4 ^( g
" B5 `8 D# D* {% K) fThat’s all!; u: w* b, g5 W6 u3 X
9 m) H1 _ ^1 |6 m& \: ^: s
Peter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|