|
|
AC In/Out OS Slow Response # e7 {% R6 n' ^, S
- Phenomenon5 R' e0 Q9 m& u# Y M: U7 X
: ]; a1 j7 z7 a2 E( o" g
手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:$ x4 c0 o/ K. S" P8 C S# p1 M7 P
- Why???7 ~' P2 o: h; Q! j; P& {
" r+ q- h# s1 F) ?
5 r' d* v' o0 `& a8 L- A# 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 如下述所示:
8 _4 F R" G* ^ F9 @: r0 W3 B! m// AC Change event
- D9 n9 ^) k- S. a/ i- F9 O. Q- C1 C; t7 W0 K
Method(_QXX)
5 M# v. n8 k4 x# h' [
; [+ Z6 _" F( {- v% B{
% N5 F9 y! ^8 w5 s3 `5 }
- e5 h3 t" f5 @5 I% HStore(0x09, DBG8)
# M0 O% ^: X9 f: b3 b; F1 `- s# w* P' u4 n
Notify(\_SB. ADP,0x80)2 {3 U# l- Q4 }' b- a/ _
//Power Source status changed
) \' y3 k7 [( R+ Z% q
d2 l7 n" {2 ^" `. `Store(0x0A, DBG8)+ A0 j0 W2 R5 W. V8 [5 v
, n- u. _! g% t; R& F- a6 _/ h3 Y+ L3 R1 S j2 V3 T
}
. O" ~6 i& g# y8 C7 C( w6 \+ j
/ b8 t; {% C4 T% x6 ]9 b) C
* n Q5 A5 m8 l' I1 C1 J& K
0 Z; Q& W/ Y+ a9 ]Method(_PSR,0)
( l) L* D, W8 {) [8 @" {' K* p2 x6 ~, J" X& ^( h P9 P. Z! L: B
& W- j d# ?! h+ I2 v9 B, S# B7 }( M{
+ o( C. Y' Z8 K5 ^+ L, l7 P7 {9 p
5 E! y; k# v! d2 Z/ K+ UStore(0x0B, DBG8)0 S1 x- k* w/ ]% Z# Y; ?, v5 f
2 E8 I5 y6 u, a. }) l2 ~
- V3 k7 E9 U1 O- X- v9 }2 hIf(ACST)" I# }% N$ {. M+ J
//check AC status
, d8 j2 J* q n8 G0 f' Q3 f2 ]9 a0 r# y/ I7 \8 K' b" W& w! E
{3 C- ^6 e4 y" i
* @$ \ q7 I" l+ r
" Q& a! |7 [ D, h& l8 v3 Y
return(One)2 \" M6 D0 \; N9 j* t
// AC Present
& c8 k1 b2 j5 X) c3 f" o2 {- ^1 ]! y" D i
}
) W4 d7 a! M9 r
5 A6 V- f, M, Melse
. b8 p7 U, u; U3 ^$ o* H' Y/ e! S) J0 ]; m) W+ z' }3 j
{: ~9 L: `; x, R& E( ?# e# ]3 [8 N
; [- u0 a' G8 p0 l7 t
return(Zero)
: X4 D+ }- D3 M/ Q. }0 i// AC Not Present
9 e6 s5 }$ v" a' w4 |$ j) J9 P6 S" D
}: ]( q) v3 u3 t. C+ |8 E4 j' s
8 w0 [: a) o- O& }; W- f& [Store(0x0C, DBG8)
0 I4 P% y! A; Z9 X9 `3 T& |( M& D
4 p8 ~& k, D6 p0 N6 C}
1 W! l e7 H$ r; N) \! y$ t4 m: o% e H0 f& ?
) S' u. Q& @+ s/ i1 G
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。 `1 ~7 m: v- e+ r" t
状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:+ `( \$ \/ c' L) A; A& I+ a
Method(_BST)! R V( W( j+ a9 n
{, m$ w6 n9 l) U
) b2 `; E4 g: G' D3 U" R
Store(BSTS,Local0)" K1 B7 t/ q7 J* C' v
% B4 ~9 t' ~- ~, b! }1 `3 m' U9 Z: W6 ~5 | Q
If(LEqual(Local0,1)) //Check Battery Present Bit
6 P" h7 n# C' [$ {1 v4 |- m; z9 z' T, g, b# u
{
* s* n0 K v9 X% \, S/ v; ]) s
) \9 p# \9 C( s" Z: a
* m/ K* F" {9 C E+ m' S! E
( Q1 N% d% D% f7 P: e
" ^" |9 U9 n2 P+ s
$ i- t+ s4 E, ~, t+ f3 E% x/ c. a* u//Read Battery information from EC
1 O- G8 [( r- u) g' E; X7 v1 I/ a4 y( {
… …6 O9 e9 r& v1 i% E8 [* I' g/ |- d" ~+ L
& R# j' t" g) v6 G
! k- ^0 {# p! u6 Z' n}4 y* ~/ W; }4 B
/ ~/ S) r3 f& P
Store(0x0D, DBG8)$ b! B8 ^' L" V4 ] A; g
}
7 @, L* G2 G2 l" Y6 }2 u9 B9 Z+ j那么问题好像是由读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所致。! t% \1 \. ]7 R; `' i
那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:7 g" {7 j% k0 U- G9 |
' E2 ^$ L+ v7 S! d
7 G- C2 E5 g5 k, C而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.
7 W4 V/ Q5 C) }' O: t* Q# t # G8 n( {* {) s( M; b( T
9 G" w9 l3 g' w4 `# A
6 o4 ]0 N; E+ K3 e% a6 W- |4 P经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!
3 p+ v& T Y; j" d
( u; x2 \3 x5 T" b! Z. X% i( w& R9 e/ U5 t
+ ]5 i y" g& C1 C# G* |& _; N/ }
# X" y: z' Y! }That’s all!2 i) q( s" A/ c6 D: m+ e
5 a5 I; [/ W; C4 ^9 R
Peter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|