|
|
AC In/Out OS Slow Response . i: |/ i4 z' E5 t5 M
- Phenomenon0 y. B" `: f1 N: k/ H
2 ?7 [9 Q* J# D1 ^: K$ y! x
手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:4 P3 g- T# E0 d r$ Z6 R
- Why???3 }! Z6 \! Z v" c) I+ m
: f& i' X9 j0 t. o6 J3 d
; f5 u3 H( B" A3 O- s5 E刚看到这条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 如下述所示:
, l2 D) }* \ p8 T8 T2 ?0 s// AC Change event: E, g7 O/ ^0 Y0 e9 Y
+ _# T7 ^8 o, m% T3 z, ~/ aMethod(_QXX)
c6 g( v* _( t& l$ c- s" h
4 d% c) ~0 _, b2 x Z{
7 L8 L2 `* ]- L. V9 r7 b
, B; Y: L- ~: H/ W4 K7 V6 v! \% t; S. CStore(0x09, DBG8)6 ^/ }* ?" N e' A+ v- r
- W& \7 w% f- y4 k
Notify(\_SB. ADP,0x80)
: W8 J9 V2 @/ x" s9 r$ ^7 g# A) d4 e0 N5 b//Power Source status changed
' s5 c5 y4 a8 g$ g7 b. f( {( ?1 U7 q/ c' Z3 R6 s( [4 g6 Z9 Q& R- p5 w
Store(0x0A, DBG8)2 `% g% F$ e- e2 {$ b+ U- e4 J
/ C/ s. ^( k+ X+ Z* t' y' ~, X0 {) Q' f6 B" X; l, M
}' s$ J# @9 D3 K5 r* I7 P: f, a' }
% {# N% }% l5 t" A% y
- R- A" H$ G* n" b, R8 ^
* W8 P* i$ y' t$ b2 b& O% u7 M c
Method(_PSR,0)* I6 W, I. ]+ F5 C& s2 k7 h+ v
8 s& J' Z! D4 l' E5 I3 p6 Z
3 N! J+ T7 Q/ k/ Z( b; {) d8 R9 s
{
* j9 c7 Q* x( A" q4 q5 f
9 a. t) n2 |6 {" ?
/ D. S' l$ q: KStore(0x0B, DBG8)
' j9 {* n* ?) k* M
! s- @' D! o0 o, Q0 X& y7 R
) P7 r. Q$ p# a1 J" V. JIf(ACST)
, N3 z! `- B) N5 c) J5 A6 ~; _' V//check AC status
; F8 a. f: `; @9 o9 u: J$ B
* {* j! n9 N" R( d' Z7 ^; e{
! g; e1 U9 q/ V' ^
2 P" R( I, q0 r) t+ p+ L$ Q I5 E; u) K2 {9 W9 s1 l7 Z
return(One)& e6 c& C- x; s
// AC Present, b; }6 q$ n8 R+ L
4 ^/ s& L2 C! I( B. H* D7 o5 P ^}
2 h8 b# ~ G! w( x! q' E3 L+ x4 {1 |/ j; A0 [
else
' b3 t, Y" b* j; [& }9 K/ X( K; w; k& f: o
{' C. ]/ S8 y# M. s* A' A
6 }* \: ^) U( `0 Dreturn(Zero)
% G' W) J0 N! J9 J* g! |// AC Not Present; T4 X& r P) X6 P
5 x' k& f/ z; ]! j4 c}
" [8 J6 }+ F: j5 u
- `5 L1 @! D8 wStore(0x0C, DBG8)
/ {2 L+ c& M/ X, S @9 ~* S6 h
}
+ I3 t0 m) o S) r1 `7 w4 t8 j9 V* n7 u( H
% G2 E* e1 ^+ G3 q1 p: i! p
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。$ p( u$ I s9 b; y; V
状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:$ f" \ T9 g! I: i. F7 p
Method(_BST)0 P3 G; o8 I0 q1 v& C- S: D
{ e6 g4 ]. z" y
/ q4 L) k3 X6 S! M6 k
Store(BSTS,Local0)) u1 V, _3 j" s1 \
3 |( t* G4 t: D
5 x, C* D( [2 x4 C7 ?2 N2 W( p
If(LEqual(Local0,1)) //Check Battery Present Bit
( \1 F |0 r* X- e( h9 P
" B C6 j) M# g ~{6 N8 ]' {# e5 X5 V* K1 w
% y3 }2 d9 r% D. ?2 l$ k
/ ]) O4 i9 ^2 t, y4 D7 b5 n- ^6 ?9 j4 Z$ h y
) k9 h+ N! s% b% C8 [$ \! o( v+ k9 T' [
//Read Battery information from EC& u$ |2 m' q& ~' _! ^$ x
' z8 v& i4 j$ S* {, K… …! k' u% ~" e k( [' ~
3 c4 c" Y5 h- W+ H% S
. v& p% I6 `9 J% a1 l4 \- ?+ [}0 ]. E& F: v3 M2 o" h' a8 e' K
) f8 w, R8 @5 C) S# z+ b
Store(0x0D, DBG8)
' l2 V0 j: [2 u} ! d# M# N9 m2 G. f6 Y! \1 W
那么问题好像是由读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所致。& Z- B8 s5 d* _6 Z3 ~9 |' T0 u4 ^
那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:+ o. G( C- A; r, J
" G5 M7 u" ^, d6 N4 z
' S3 r/ T- q3 \+ r) r6 A而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.
; o0 r3 l2 |: b* s6 W3 e: ~' j* ]
7 W1 m9 E6 p' N g* j; K
* y5 ~& |. |+ u {! e6 y* t. g8 B+ L5 N9 G/ q
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!
, ?# P# m7 m! W7 o
* ?* Q0 c4 `" d/ t) m
6 k' j1 q V, v! ?, I- W/ E2 R3 S# V8 G; K& B/ u
?1 m1 p% O; q# @9 i! s+ K, G1 S
That’s all!
* J% P8 s& I1 H6 H9 ?; u; } 5 w% B# V2 q# N* T6 ^
Peter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|