|
|
AC In/Out OS Slow Response
. g' t; ]) E8 d- Phenomenon
# D }) N, R1 i2 T. `
r' ^# t% e2 w& r! c. W/ C1 A- E- A手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:
; g& Q( e. C4 @: N- Why???' M& W. J) `3 m7 G9 ? q
- n' `6 P2 H" T" ~! |
+ x4 M! y' P2 K( L+ ?" `* u3 B刚看到这条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 如下述所示:+ q# K, ~* j0 i$ A) {
// AC Change event
" G- R+ z% s ]8 n0 n5 R' P6 H+ I+ `0 ^$ m* v' y; F( v
Method(_QXX)
* m5 g- X6 m2 _, W) B. M* n
5 H- W0 S9 y. W" C{
8 q3 O& P9 P7 J( J6 N1 {: j! j: c! Z3 Q+ }5 N& ^+ e
Store(0x09, DBG8), ]) ]* ]) L7 A& k ^9 E9 W
0 f% v8 Q% \0 z d! `: {3 MNotify(\_SB. ADP,0x80)) h7 G' s6 t4 Z0 M, w1 P
//Power Source status changed
; R6 x9 y2 C3 f r2 X, {" i8 a+ R
# c7 Z* G! v+ o- T5 R+ U& g& bStore(0x0A, DBG8): ?5 L. w* r& F
5 N2 f/ {$ F- ?
9 d8 R# Y7 Y( Y}. R7 F; M: b% ~9 a2 F" ]
( [2 |5 K. G% @1 j8 R) M
9 |7 i5 A: R4 _! o- `- d" a
1 d3 {! t- V! Y( h* H5 GMethod(_PSR,0)
5 A2 w: H8 g' D4 e
3 K$ Q: j; ~+ q: H& z( ~! K! ]9 E
5 j3 G9 |* I. x2 i{
& R6 O, v- C+ E" a8 @5 U) v8 C4 e3 N! o/ h/ L4 u
4 e h8 m9 k; F! H1 j4 B. }: z2 `Store(0x0B, DBG8)
6 `/ g* z7 f, L# J2 y
( j/ X+ ?, _( s/ ?/ U( r
& o+ i+ h; m) }If(ACST): Z6 r" u; Y8 o2 e
//check AC status
- ?( W, Q1 q5 `9 L. @) x( W
: q, n) Z+ D8 G5 _{
2 i$ j: f0 W# b! c3 y; u% a. K( N1 k+ s) C' R
: G% U8 i/ B S! T: a8 Q3 G \. I Hreturn(One)
^. d' q* @& O. [5 z// AC Present
4 p& T# R" p; y9 d( A( w# @7 i$ z. n- ^* e, A+ ^
}7 B: k$ x; @' `& Q& H# U5 J
' T9 C) ~& }! P" C6 q- X/ Pelse
! d4 j' b' y* E, ^" y O# N. R. Q" M l+ ?3 c1 ~4 L F$ J
{
* p1 S4 v6 ^' q( N3 \* X$ a" k/ X$ d( |1 x5 [% V
return(Zero)
. z0 ]8 ^0 T. A8 s9 [$ S( U' s// AC Not Present) r/ x% a1 R8 L' n
O% j* ^2 I& E6 t+ V0 `
}. n4 }" t" n7 d" ?
* K4 q' O. o% F0 ?Store(0x0C, DBG8)
: N4 I# {9 J& z; K0 n7 S8 L$ T' {2 v5 M2 w; j$ O! i7 O! B
}
9 K' G) ]8 p% X: Z6 Y8 S: H3 Y1 b* I! u6 h2 o( `
0 q5 v# |5 |9 P7 t" D) [' ]5 J
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。" I- L! ?" [2 N. a6 V4 g
状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:
1 S6 K, L9 e; `9 w3 XMethod(_BST)
. q5 t. L9 l4 k s( C6 n{% o( M1 a7 n3 @- g: h3 l
: ^' M: u' w2 T z/ {# i7 B
Store(BSTS,Local0)
( E$ X& ~. }, ?9 d/ {% m
3 h' v8 o9 p! |8 v/ ~1 Z1 G, h! c8 M D, f
If(LEqual(Local0,1)) //Check Battery Present Bit
) R7 x- k7 e# `1 ^& z/ O3 x& @3 d }" d8 |+ x
{
3 m& \1 U% I2 z/ W; J5 l/ G2 a) s9 h, C, I- t
; j0 _% j) X- R+ B! f8 E6 k3 U b2 Z, F" Q2 e
8 ?1 g, [' @7 w3 x0 d9 |' i1 \! t/ p3 I0 a
//Read Battery information from EC
% U2 Y7 u9 E7 o6 L# v% G/ ~" Q# D2 r/ S3 Z4 l
… …
% Q% w* d! ~! ?( C" ^. y0 `. n8 m/ O+ M" H. C6 p
; i! x0 y9 L* o% Y( u}# Z: L4 Q2 Y" Z; p* U4 @
4 E7 s& x1 C* A* w9 j# z
Store(0x0D, DBG8)/ {6 A+ j, T, T" Q% ]
} & r7 T) q) u4 e- J4 o
那么问题好像是由读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所致。0 R5 }+ k( M2 J G7 k y
那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:
, o G8 g$ @* x+ u- B: K0 a# P! T0 s7 v( {# o4 R8 v' n- m2 \6 i
4 ^3 G; r! Q c9 V
而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 k# Q. D$ t8 S3 r; |& j4 \
+ j$ Q$ x3 i) n1 _* U; P; e% l, q! g0 {( n; H& d
( \9 Q% l m8 U. o8 w: T+ { K/ _# s
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!+ x1 P0 z6 H5 _2 t/ w
: S! l2 [) }# Q8 y
2 J( n: j% H( f( U% {% u
; Z9 h2 R# Y( ^7 l- P. ^1 P 9 K8 x- i" a- s! r
That’s all!
/ t" e0 j& W- G: k! u( W
# H+ t" m! J: T8 F! n oPeter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|