|
|
AC In/Out OS Slow Response ; q3 u& G+ r5 Y! @2 H$ J; [
- Phenomenon1 k" P/ |( u5 N4 R& o
) L7 r% Q3 V& O/ R! S2 t, J
手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:
1 W. B2 u' `4 e: v& X3 d0 ?; _( U* J- Why???
4 m0 H5 X) S2 \ C. G! W1 e
# r; ?. |( ]$ p
6 E7 R% W X) h. v刚看到这条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 如下述所示:
, Y( g+ V# d( Z: ^6 m) K- O// AC Change event
" B5 d6 K+ m- k' B# ~" Z! r- d. b- D7 D8 B
Method(_QXX)
! F4 v. J* U8 Q7 W/ |0 q6 I3 G: i
5 k2 a" B/ Y5 j& q) B{( K0 ~3 j3 J& m* f# ]
! e* U4 l" S* c
Store(0x09, DBG8)
2 d+ t5 h: P" R( x Y3 Z% U
. d$ h* q8 @- }( N8 {! iNotify(\_SB. ADP,0x80)
7 {- w* W. K l v" |2 j2 N//Power Source status changed
' H( m- ? ?" \& X# V2 s# i9 E7 U8 v1 \8 ]
Store(0x0A, DBG8)
0 f( U' ]$ H. ?- T' N6 ^ ! R7 y$ c( p- m0 [2 }1 M
* V6 C! O1 w1 W}
& f, B5 E3 t8 _! V0 f8 G3 z$ C! Z* o3 z Z6 O% q
/ Y. E% A: I) L5 u) ~/ @9 R5 Z
7 W6 e, }4 \7 ^Method(_PSR,0)- I8 {, [$ I: k! S
" B' q/ r7 \, Q# \3 _
0 _7 D9 B) I: x2 V0 ]- C* o{
1 C! A0 h j0 c2 P% M: v
1 k! `. B. R/ g7 \& O5 f
( z- h8 _6 a/ r: }Store(0x0B, DBG8)/ i' ]2 G/ u9 s* h5 G/ f5 T. }
) n" N2 j; X5 R6 i6 t
9 L1 C9 _" ], E: kIf(ACST)
7 W# a; X; E# s8 B3 @//check AC status/ u( A! k3 p/ w# q9 i' ~8 T
6 A2 r- j" z/ J# ~/ k* W. U{
6 v8 L- q r. `! p& k) r. m6 L* o- Y4 B- H, T
/ Q( A5 R* F( ^2 `6 [5 ireturn(One)7 ]4 v9 M" f% |
// AC Present* {, L1 Q" m0 Q* H, C
1 [; Q+ m# H7 z# l. ~* j! J}" d: ?2 V w5 h/ ? O
- r- l' R" }! B2 ]9 Q- u+ }* R/ U5 Q- T& Z
else
3 q$ Z9 T1 ?4 w0 A
/ Q8 U$ d7 n6 O{
. c# {/ `- p, _' q/ N; d( d: N5 q8 o6 e2 a9 S
return(Zero)
( E7 F) O9 s; O! B0 f5 U5 k. o// AC Not Present
$ O4 A- V J% L7 V% t
9 M# w; m- H* K/ B& A}
/ M; z9 ^$ J" K" |8 F2 W
- O& {5 r; G9 _+ b7 D& r& H9 v) |/ N5 sStore(0x0C, DBG8)
3 ?9 Y( q& Z: @# o' l) o3 H; j( P1 F2 D& q4 X5 g( M
}# p( l# \) I, k5 }" u9 i0 S5 J
- ^: s; P. Y9 I0 o5 I
g, t( X) _9 F2 J5 K) z
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。
( i. Q0 l" J4 j: v+ H( O$ I: P; G* G状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:
1 E9 F& Y# ~2 b$ bMethod(_BST)
! l7 ~9 k3 {: v6 j [{
! Q% b5 g) g! G$ H7 @6 [8 k+ r& S
& i/ Q" l4 f! Z a7 UStore(BSTS,Local0)
; V: [! |* f' C5 i; k
1 D1 u* `7 [7 |2 _" |/ E& B+ s; e" {& F; y7 K, ?, x9 w" V9 {$ O2 B$ j
If(LEqual(Local0,1)) //Check Battery Present Bit
* n/ c, h" E9 ?! x& j( h0 W- R& x: w4 |& w* k3 \
{9 v% @( l2 D9 B* \ e) n! S7 T3 S' O
# O5 [/ Z% t4 T! F9 _9 w
: J! c9 C: I9 L* s. I1 ~9 d
+ m( O# W' g" b4 N( ?* F' L
8 E; r5 A; B1 j, k; @3 j( S/ o
0 O* q. q8 @9 Y, D//Read Battery information from EC
5 _: P) L# B; ?, j
# c4 y5 S6 A- J1 R3 N, c# X… …
+ t0 F* v' z4 D$ g) X' S! P+ n, g. N6 S& P% u% y% Q
! K0 }% J9 o7 p) }- ]
}
, P: ]" q) t) D. o
6 P1 `/ _$ v- T' b% [& s, ]2 OStore(0x0D, DBG8)
3 m6 Z2 ~% T& @% s}
+ y& x; L7 y! G, d, v5 U+ B; ^# }0 P那么问题好像是由读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所致。
; w9 D: q p9 _% I( Q7 ?1 V3 z) H$ k+ X那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:
% C. p5 p3 i h9 Y! j+ u
' B/ O" U- i& G+ n- H N' Z& 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.
; O( f# n/ I: k$ X* n; W9 s& V
( B( g2 J# w0 m# E$ y" |) w. n: h% J5 a6 @+ b
; a. @ i/ Z, ~ ?经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!
9 |8 u1 ^$ `2 B& o& t/ ^1 P
6 ^# t$ p) h; f! b) c$ ?+ C' ^8 B# k0 W' }. |
9 H/ _( q& t/ S K2 T: o" H1 A
/ H9 c+ ?: _! S/ `& \That’s all!7 L6 @) ?" N) {2 @/ \. X
/ }3 [, Q, j6 ~* n9 h3 N LPeter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|