|
|
AC In/Out OS Slow Response
/ ^$ Z) L( V' E' O7 {6 A- Phenomenon3 p# J. W( Z! _
& r# {- T, X/ C8 s手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:7 [& }( X% D- L0 x' i
- Why???
, M$ v; d6 u& X' @& v3 g; P
0 {" H: p5 l& b3 B. o- \& [) v d" W6 z
/ {" D- @' e# {2 Z3 x- 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 如下述所示:) `+ G, m$ G' ^1 w# e/ w
// AC Change event
) Y/ K! v* b2 x1 D$ I6 F: B9 D& { T* M& p, ~
Method(_QXX); |7 q a8 I: z3 P; s
! ]+ o$ @3 f9 ]" F{
; G+ j! Z2 X+ Z. ?0 J
1 g1 m/ V1 r- p3 fStore(0x09, DBG8)
/ a+ X" ~. D0 L3 p1 O7 h
$ l! _6 i( ]# Y, A" j) qNotify(\_SB. ADP,0x80)
0 }* ]2 w4 A( j0 W//Power Source status changed8 `0 [& A6 w) b" i* e9 W
* ] P: H# q3 m3 _. xStore(0x0A, DBG8)
" q2 W* g9 C; L [
8 v, |; |' x; E, ^# Z7 H" P& K4 ]: a5 d7 U! B1 N
}
" w9 I5 B) w& E0 v r9 n! K( ]3 l z F! m" K
$ L* V( Y: y9 O, ^# v9 a6 _7 _4 H* n, D% ^- ?1 z
Method(_PSR,0)( y( Z u1 V0 g3 [* g0 E
6 B7 R/ p4 a- Y- L9 h: ]
" E2 k# F- }3 j
{
5 ]: D4 O4 Q; {9 } L, x
, E. Z1 H4 q% a; O4 j0 S* m9 L" z$ s: }
7 b% k* |" \! b LStore(0x0B, DBG8)
& ]2 m8 X" \3 Y, |$ z) |
+ I. M3 k+ b' ^ A
: k4 N2 N6 i6 u& {0 oIf(ACST)
2 h- k% S m8 |9 g9 N! D+ V//check AC status) A: y, Z/ i, E+ k; `
, ?/ I6 O; e' n& W4 U{( t. e# i: ?) b) l6 m) k
* P4 V. @5 i* W$ m$ i) R) T. K- M
0 ?2 @" c& z* y7 u+ h, m4 ^
return(One)
6 Y: _. ~1 B/ c4 w: i2 Y3 x! s+ t// AC Present
& t: l1 T. H: W- w" f5 j9 p. P- G6 D+ h0 ^/ u4 f3 D3 S
}, \( L' q+ F4 o6 U! j4 u
. R# U) H; |7 T5 K9 m, {& L, Oelse% o: g* R5 P2 z$ X+ |
2 Q& u4 U+ w, }. ? ?: I' T& `{* J, y# O9 s8 b/ M' Q4 _ @
& Q9 H* b4 ]$ p5 q" ^ d1 b
return(Zero)
: B, @0 t& ~: o1 \// AC Not Present" c. o) ^5 i6 H1 U( m0 [ I
1 r8 ~9 T2 Y6 a3 ]}' T2 O3 g7 q' s. u7 I! c; Q& n8 c
2 n2 K" H% c6 R4 I1 S i) mStore(0x0C, DBG8)
0 a; m. z* e3 a7 v2 j
# ^* b% X) R: I8 B3 q" E0 n}7 b v9 X, {3 g( {0 R! b2 o
; n$ Q5 @/ N% E5 Q' g8 [4 r
& @2 I: ^$ O. u" j! N! V7 w我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。
7 F& e& P/ {3 |4 F3 A状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示: @+ P7 O c: I- e% P
Method(_BST)$ ]4 i' l( Y) n" K# Y5 V7 U1 ^
{
$ z6 V6 I# m3 j. Y
2 s/ Y" B- B, FStore(BSTS,Local0)# p0 n0 \. s1 f/ _4 H( Z
% j# y, i" `: O! E" F; |( q1 p B9 ^
9 x; b0 T m7 c2 ^4 l# |
If(LEqual(Local0,1)) //Check Battery Present Bit) ?6 _4 p$ _' d1 L. B& T O
: O# \, Z& D9 C" F J
{
2 G, }" c* q ~- p& G& A; h4 d Y7 _& A) y' o
7 J0 ]' W' W+ w+ e3 _* p
% B1 D5 G& g* v
# k& I, s* c5 X" J- f6 l9 ~8 z4 ~9 d3 G8 G' _
//Read Battery information from EC$ H! n) @) N, _+ U' I6 A" g
% e5 o! u5 W9 M$ k) w4 S- r+ C… …
2 S! ~6 |: Q- z- @4 {+ d3 n
" j/ v0 J1 S7 h* C; c" w
3 m, M8 j2 u: Z; m}
3 X$ {: M0 @$ T0 m, U5 q
- ]& D8 ]1 M- @- p$ QStore(0x0D, DBG8)
& e# \: B7 [# C @1 [}
$ Q, E5 }5 Q( b: T" |& _0 e5 l那么问题好像是由读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所致。% L5 V. M# `' A9 e; q
那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:
- _# Z& ?, F, C& a* W! m. w8 L
- Q2 A! S& D$ z$ }) W
0 {* {$ W/ t9 i& M. ]+ ^2 M6 s& D而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.3 L* b) H* r m+ h( ~6 o& v( |
# o* h" ]1 M: q8 R x: u
0 F% A, S9 {8 I1 ?7 r) D ^9 | M7 p
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!; a* ~3 d9 |" t5 P9 F
: ^0 x* M) B p5 h
/ r: f* q0 H$ z! N, Z+ t) o) s
( ^' V# h7 I) E ' @, d2 u" x8 u. b" Y- `( S
That’s all!1 A( @ Z- Q, o Y( o# O
; k% r3 @* F1 I. a8 wPeter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|