|
|
AC In/Out OS Slow Response 4 U) r2 ^+ O, H/ J9 \# l/ Q
- Phenomenon
2 d C! ^( q+ B
: U' a0 l, c4 l* v7 s! d手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:
/ u$ n. c. L; |3 b: n* l- Why???
( v, k8 w) H2 \! X ) o. K6 s0 t1 ]( g" i" T% s
( p8 p- S$ o: y+ L' A' W
刚看到这条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 如下述所示:
: F/ Z& W3 W2 p) M* C// AC Change event }: Z) i0 S& K4 O
$ G6 d, g9 L0 a' _: R1 H0 \
Method(_QXX)
* _/ t' N+ }5 m9 r, |7 M. e
+ k0 z m( u7 t% _0 |( P+ N{
- |! K: Q9 A3 [$ t, |" D/ M3 Z2 ]! B9 S! k6 V
Store(0x09, DBG8)
+ T `. q' ~9 K: h2 j
. ?* Z# n8 n8 Q5 j6 h) Y% FNotify(\_SB. ADP,0x80)
! P" L2 q6 j- t) q- V//Power Source status changed `" M6 A: d- t4 Y* V& I9 d( {
- W$ D& m* k3 u
Store(0x0A, DBG8)
, }( b4 z, j7 q8 c. }( P: M $ C( g2 o% w; k7 T3 L, B! O. L
5 v1 B9 ]* Z2 H}
- I& f/ w6 j( K7 T
; w' L% t* D5 r7 _7 V- F6 {; L* }, J; O" V( _/ f2 u3 E+ v
7 S2 i8 T3 K1 ]& g# o8 |- pMethod(_PSR,0)
9 j6 W2 u+ [* ]1 ~! Q6 c0 b: Z6 y% R
. Y. d& x" `9 A+ o3 v
E/ L% f8 H) a. r F9 y{
" O: N/ _9 k; n5 C; N
9 z, X4 |! d+ L2 [. g4 I7 K+ F4 H2 L# G$ o9 i
Store(0x0B, DBG8)- l5 b/ i$ g& Y& m( ]! r' \- s
j% W1 S \' J: _6 L
. i7 h& A/ i# n/ P+ V. O9 f- ^; \If(ACST)2 i5 B4 B# {' k& W+ B L) h9 Z
//check AC status
- W; a7 G7 i( l2 p1 }0 F4 Y3 x* y0 k; g- X8 U+ o4 g$ @) [: [
{) U E4 X) @, y% j8 j9 @" M
# u+ v5 W9 T) V1 R( Q2 Y
0 _+ a; X4 l! t2 Nreturn(One)0 b' }# k' s) @1 `0 Y) i3 {/ i
// AC Present
& [! i1 Z$ p/ m- {" q/ _! V$ f, Z( Y0 L- `' w
}8 w: D' D# N7 ]) a+ D
! F& @! M) ]" }$ E: ?, ?9 welse, B. k3 U* ^8 ]' @3 V h0 a7 k. i. u
# U( V/ K& W9 Z7 e' N, @1 k: J7 T{
# x9 }! X, C, U0 S9 F4 }& [9 ^$ ]3 S1 H
return(Zero)
: v9 u! y) T/ J3 `& G8 J( T// AC Not Present; y, q6 d, u C! J- j* f6 G# y
& E' B S/ ^2 {5 _9 k$ w
}. h `* k0 @# [6 _
2 l/ s& Y5 Y0 r, J( b0 A0 h, A
Store(0x0C, DBG8)
) h* {9 A5 y1 y1 f/ K( s) B/ b! h. t7 E+ M! u q
}
$ o0 K& \. G' r; Z: C0 p* f
' e' D7 C y0 j5 W* |6 J3 b6 v8 w* g) f G" Z3 P8 d, u' X3 a
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。9 h: n. M8 R1 n3 C
状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:
% H- S# V1 C' N! vMethod(_BST)
" n! i) t& C4 u0 T2 O{
9 l: I* K0 Y& f! n' q" L! |
3 m+ W$ U. ~/ ^2 P) V( R2 |7 lStore(BSTS,Local0)
, o# K2 \$ g; ~9 o. x% B8 R' D% z! ?- B7 F
# X, ]$ S# Y# E. q7 [If(LEqual(Local0,1)) //Check Battery Present Bit
- l: j4 m; K7 M6 d
( @7 V, Y* E7 D+ S0 e. s" M{ C% `- N9 f3 ~6 t* T+ W$ V
. e5 w$ I% d8 K# A8 |2 R1 b2 r4 S! q& h
' G- F' n1 n0 g2 \- o( y0 o
; K, i9 u; r1 R; m. Q
* x1 u" ^9 M( M% |( i6 K* v
//Read Battery information from EC; `; O; `$ _5 `* l; r! q+ u1 O( f
* d7 J2 Z& Z0 a5 J7 u* {
… …) d# f4 x7 ^/ h1 w) c
1 y: \" Q% @( u3 ]' b& r) t" h" N2 s( ?3 ?: i
}" _% o! e! s% m. S' R
; d0 S F* N" X4 O- B% dStore(0x0D, DBG8)( O! B' [4 [+ m' o; f
}
5 p* h* |, j# x+ ?8 n( ~1 t) e) ^6 D那么问题好像是由读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所致。
( ^, {' u+ O5 x- m/ a那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:
: x; v, o# X- L5 ]
& t0 S- Q5 O9 P7 `& p
6 i, Z* G' p) r而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.
& c- p9 H! d8 \. t6 U" A 3 ?. [. H; o( v; N! g2 Z
- v3 `. c, Y, D9 i, n6 P
+ ]! N2 Z& m8 o
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!
6 U4 q, y% x; ?& M. @
/ m }" e* n4 L' H8 G. t3 D& x* x, `* W: S) m
* c, l. O* h* Y0 W/ F
( n* y. J: R" ~; o1 P1 {That’s all!
) m9 c; e5 O$ \9 w t1 j: A - ]/ {* e, y& {/ n; ]( A- ]
Peter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|