|
AC In/Out OS Slow Response
, Y* A* j h2 I' I- Q( f- I. H2 l- Phenomenon2 n( Y& R, F5 z7 D% q* S
* C" |, o4 @1 o8 {
手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:
5 ^; {, y5 u8 E; N- `- Why???
) j, o: K8 S( |& e0 A9 `( D+ `
& _8 A; k3 _# R+ H+ m/ Y- o+ k A/ X Z
刚看到这条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 如下述所示:( I$ W. j# a! Z( u5 s
// AC Change event: o8 X. c2 I. j
* ]( J9 K/ c0 F5 J0 oMethod(_QXX) C( E8 [* F: e0 k/ L! X8 r& r7 K
$ Z$ U5 x: T* r5 b7 N- C{
2 J$ e2 @7 d! |' r. r
1 O& |$ |- R) c6 |2 sStore(0x09, DBG8)
" @ G; X4 P5 b6 F7 i* Z5 ~1 {5 b) K6 K/ S/ P) ^% K1 I& t1 R2 [& g
Notify(\_SB. ADP,0x80)- B' W; h7 R; U; ]
//Power Source status changed
" u8 }7 o9 [( t8 M9 H' t' G; Z$ ?; y% b* G
Store(0x0A, DBG8)
2 `3 p- Z' m3 i \
0 W( z5 T) ^3 q6 J! B( y$ q
/ z ^$ l9 H2 x& I" N# s9 D" O}! g4 ^ J$ a. a$ g/ W \
, A Y5 V6 t1 Z# o2 \
0 b; C. Q& D* }# d8 w: G6 Z; C
. P) J9 k& R' J5 |$ Y" i. _Method(_PSR,0)+ h ]& S/ a8 N' H: F+ H
/ X" }3 k5 D6 p# E' a' R
3 h- G' A' K% E, U9 R4 g{0 N6 w- Y+ T& Y
$ {% x- k2 N& y( t8 m# w
0 Y! Q2 s2 R3 J; HStore(0x0B, DBG8)
8 W9 y$ r0 Q4 ~
/ `3 f) a2 B2 S1 J S, i8 D# T8 q- W! G( u0 [) \ R1 `2 G
If(ACST)
0 @" E% s2 U" X% p- e//check AC status* G, j6 C0 Z& j5 A$ M# W$ T8 L
$ F' V# \7 G! h; e( E/ `/ @" K2 n{8 C3 } T. J8 a, ^* _
/ ]* G+ k& |, g! { [0 _& |- d
0 |7 G B4 W5 h; breturn(One)7 Y; l. [9 ^% z" m. a: ~ c; B" G
// AC Present
8 X6 B" n2 E" z8 b \. m/ G' [( u4 m" F- `
}
$ Q' A- q" U" P9 O/ F. c) |: O e8 r$ C! i( b& c: u- _1 B% i, ]1 b+ m; {
else
! E s8 s0 w/ t; i- c i" y( T' F! R# i, Z: H- O: i1 G
{
; h2 N- j) Y2 m6 g9 j/ ?( q7 ?$ F( m6 h& K: E! \5 S, N: _
return(Zero)' O4 L8 J3 \, Y, ~
// AC Not Present
9 @; S/ r% L7 S! x* L6 N3 C. i, @2 i+ J4 J2 @9 o2 D
}
" y( |' m" G' h$ O" m- {
\) j+ r9 b% {( w6 n6 a# gStore(0x0C, DBG8)5 |8 g* g* e, x* V2 e
: I# ~- U" Q/ R0 Y& y0 g}
# a' ]4 m; [3 c8 ~" R
9 Q, }4 y1 e* e/ [6 s( N L( Q- |6 k/ r- a$ V
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。
4 t9 n3 N' p1 P' z% O) Z状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:0 u5 ~5 p7 A# c- {5 I
Method(_BST)) L `- }$ L u5 W! G% F- R
{* ^/ z" _4 v3 a% V
U* t) G: {9 v! z. `Store(BSTS,Local0)
1 u4 _1 Q* c* P; J- C/ g8 W/ L+ |1 u7 j0 `, T5 i
4 ?1 C* G! M* n& t9 U. K8 o+ ~+ ~If(LEqual(Local0,1)) //Check Battery Present Bit3 n: g' b0 I6 e6 u
5 G; b+ F8 J9 h* \5 T) X0 w; F{3 s) b5 @6 [* D$ r
- @- J0 P$ l4 C3 U% i! u& `1 T' B" M, t- j
' t0 b" i* M. _6 C. ?
& Z3 d3 c( P+ H+ j
% t% p: i* }2 e4 w! |$ R; ?//Read Battery information from EC( e) r& z: q5 @! ]' t6 T0 E! t
5 o8 U! y! l( j$ n$ R
… …8 i3 A2 n: E, ?3 b! ~ \3 \! X
; @. T! D8 o; d9 D7 `+ @+ X
# @' v7 ?- q9 T6 Z7 W2 p
}9 g& N* ~' [6 S4 K& L5 r
T* Y1 \& {: V: V+ p4 P' g g: B
Store(0x0D, DBG8)
" D8 r! D$ N2 ^4 N/ P, l( r}
0 V' P9 r; y9 }' n% V- H2 T& P" G那么问题好像是由读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 l! @' }' a, O. v& v& y8 R那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:6 S0 W& ]8 Z0 M4 D5 | D
& e1 i0 H5 m# Z
Z# A. c0 y+ [& j$ M$ Q: 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.. s4 W$ f$ ^! B7 E
. i8 g+ S3 A" l3 A/ K- _
. f k& U2 N2 t% |5 l; W/ y# W, K' I" s
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!) i( F P' d$ f7 u
7 ~+ V/ N/ B6 q7 k% h
- Q, d A9 c5 D# g" G& q% F$ I- ~2 @
; W: O9 t) |- q/ b1 _$ |/ O* J
That’s all!
, L- E, _0 D( V) {
# Z+ o* G/ l# o, _Peter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|