|
|
AC In/Out OS Slow Response * `5 l d8 M& d0 ~) }' @
- Phenomenon9 T$ h- [2 d8 ^ |% {9 K( I
5 y, G; |+ E/ v" _% Q1 `6 m) c手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:) A1 |+ f0 M- O4 z! d" S1 M
- Why???
) r+ E+ ~! F5 g7 d
; X8 ~5 w1 Q; K2 \0 l7 ^
& a- c$ d9 p. I+ h刚看到这条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 如下述所示:1 L3 s8 `1 E4 q C [7 s* m8 R% r
// AC Change event( r9 ~/ O# @ C, V1 E3 E4 _& M
+ J% H" Z3 o1 i6 U |8 E
Method(_QXX)6 G& u1 w P& E9 [, x
" R( b: q5 h7 Y, R
{3 P1 g1 V; Z% R1 U! n- |
, }* }6 |8 \' |& [7 j* j$ }
Store(0x09, DBG8)
8 n. \, ]' K! b6 m& o% n: d' D, l& a4 c
Notify(\_SB. ADP,0x80)5 j: P0 h) C' ^' c
//Power Source status changed6 y$ J! k: `4 ~4 Y) r6 Y
9 A& Q) g9 H8 F0 C3 YStore(0x0A, DBG8)5 v2 G |, ^2 v! t" v
, I- {/ x2 b, Z% v2 P. {
$ N/ M/ J0 c( ~, N, s% E}
# Q+ b B, D! E: W6 w, V$ x9 v4 x% K8 x, C) x
* V- h7 u7 J! z
& _1 q% @' k- I }6 A& \( \
Method(_PSR,0)+ U1 X t) o1 X/ y" ]8 W5 e
5 h% Q5 O% u6 \% \0 _3 R/ E* Q, T% L" D$ H
{% G% W* V; K ^& i' V
0 E/ \! g5 m% S9 w4 V+ Z
# k. g4 _7 s N, z2 F: s$ }) N3 uStore(0x0B, DBG8)- I7 S) Z( X' }9 Y9 s2 a2 X
: W$ A3 D6 ]$ D
9 a" c) ~4 h9 q. j9 U9 pIf(ACST)5 e& H8 G" o5 A4 r& Y# M
//check AC status: { ^+ D' Q0 C. o% U# U9 } x0 s
B& B0 a( T% M% ]
{
% g* k7 J8 [7 c! J, P# s$ p' k7 z, g. W9 f! j- A9 W( c3 L
0 U# A% L( ?$ ?1 ereturn(One)$ v) S2 K% c0 h8 A6 J
// AC Present! g% P' d5 f6 |" p" {; F
; P+ S6 v, z' H7 ?% j6 i8 |}2 r6 T/ u$ e& J- X$ Z+ |, J
- x& j7 E+ ^6 d Z) s/ {: o& Q
else ~7 l5 C4 J3 z, a* G7 a F/ O
5 T! g( B; g3 ?1 g5 ?# c" H- g
{5 ~3 G$ c! x: v0 H8 k+ f
- z1 e# z0 U6 Qreturn(Zero)+ Y" Z+ N# N4 G# h
// AC Not Present' T8 ?, h% b* V& L6 F/ m
. W# k8 s" z8 T7 K+ F}7 ?5 x% _2 C, e! m, x, W
! d+ y: s6 ~1 m8 H; xStore(0x0C, DBG8)7 u: ~. Y, ]: X/ Q
" I6 ^: @2 Z7 d2 W# `4 x
}) s2 n6 E% ~: W# Z- e0 Y- s0 G8 i
' q% x8 @6 h, w ]) N
5 K: K% `* W: A: y# o) B我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。+ t) R' k& \% o5 r! {$ e7 s3 R
状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:
e0 z u; u$ f3 N9 i4 {5 oMethod(_BST)! p" K. V3 W. Q! ?) K& }% D
{
2 ?' h- a% a) D( m
3 t0 p( M) [5 V, j, XStore(BSTS,Local0)
1 p6 I0 P- L) b& K
$ N6 m, T' ^' h# _. _+ G% W
/ k% `( c* h: v9 S; n) r# JIf(LEqual(Local0,1)) //Check Battery Present Bit
, j# h: [5 p# Z. E' W; `0 z& T. p( N* b9 a# E9 N, }: _
{
5 X6 q" _( z# a, J- I, M" F' c
, K# i, [6 I) K$ T1 a/ V0 Z; r) C8 E6 S( r {( H$ ~) W5 @
& g* |8 m4 |' `$ H
8 G, |! \$ X5 v* J
( f$ K7 L( U- L# [" m# V: E& c
//Read Battery information from EC
2 W9 J7 q6 V3 I# E$ p) l) D5 i0 {2 n- K# q$ l. ~) ~
… …; y8 g) E2 }: i2 Z% d' | J+ `
; i& E- I; } [+ D- g3 K9 X
- H2 d- U' {2 j( d; E4 c) x) K0 p}
, Z( |: S% N, c% R
3 ~/ |2 l5 V) C% n7 NStore(0x0D, DBG8)$ q7 }- C6 e7 B, L/ p. t5 ]- B+ M
}
c& V/ _ m( ~" z9 _, Q' N$ U- S3 a那么问题好像是由读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所致。
9 B4 E4 H& C2 W那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:
( e9 Z( K a. t6 X3 T0 R# H
. k- a! n* R/ }& c1 c( u: v) J8 A" }0 F; \0 V6 J* N
而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.* X$ C) i- @; ?1 L+ T' N+ h% c
: z. `) C9 V6 e% C. `( Z5 {4 I, b
5 s0 X. y4 C H# w( O$ X8 W) x7 F n: c" @
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!
& l2 H! z! K- n6 m% D2 a: B% b
, s* m( U! Q p# `7 R [/ J
5 d5 W( o& z* Y, f8 P, m( D3 E1 E
3 t) e, A5 P) @/ C
That’s all!4 U* J% r6 ~ l7 U" N
2 h1 \/ Q8 p' Z5 `$ DPeter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|