|
|
AC In/Out OS Slow Response 7 u* W- n+ X8 e% i( y; E
- Phenomenon
$ e; K2 Q" ]2 b* E
9 I6 T' q9 C; P* Y! t手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:
O! @# k' T6 i) o; }" S5 ]- Why???
; p s3 r2 F: U/ T! m" \3 i
. { K. \" j7 @" A, ?: {7 b3 H, D( B3 c4 k& z+ s* O# G) E) P' K. o/ I
刚看到这条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 如下述所示:
: \: E5 f0 P. p4 Z( F. l// AC Change event
/ _7 }- j: M$ I" S1 ^4 j" ~7 q" ] [- X
Method(_QXX)
+ M- l( r% y( x( ^
4 ~! e/ Y0 G5 _{9 ]( `- ?- s& k1 V
, i& q4 v1 ?, J' _7 W
Store(0x09, DBG8)
) C" ]* ~ x; M Z6 x( H$ k
* K1 f- F, s: c* Z9 m2 pNotify(\_SB. ADP,0x80)0 J; ~( k0 e X0 E. G! |
//Power Source status changed
; f& G5 ]2 ~9 Q# o1 F
/ `) |0 V! C/ b- Y8 \Store(0x0A, DBG8): X, ~. S; W" D& j4 ?' {) ~3 ^
1 Y3 j) B9 s% c
- q* p8 W4 p" z2 W' t5 C, m( U
}
+ _! W) X9 X3 x) _1 F3 P) C% N7 b2 x8 h1 ?1 H, }: }
/ x% W; |" o- V3 ]! A; m/ v' ]
; X: E0 g, v/ v9 B, eMethod(_PSR,0)/ X, b5 c& d) c
- K- c# m( f- p
- j, n' q' {0 p( M. F- }{
" ~3 C- n$ A* d9 ^$ p' S4 K# a4 g
8 c, C9 {# O9 c0 {( @) o
7 N+ t, t% `6 d6 i/ fStore(0x0B, DBG8): u8 w6 A* h* @; v! J/ h) R
6 i; \+ L3 f3 A
' ?! {! v7 ?3 t! L6 ]1 s8 Y
If(ACST)
# P1 R) \$ F2 k/ Y5 [//check AC status( ]% V" f+ c' }7 t, G
% |1 L5 \9 i* P. s, a* |, B8 d{
9 [" R2 u" @2 L3 k3 i0 R3 B( \$ e' s, o
6 R7 Y: N$ n$ w# |2 D4 g" T5 ireturn(One)
/ Y+ s! r+ [) ^' r/ K4 b// AC Present1 n( H$ g7 }, }% e4 X) T& i: I0 R% Y
% u9 q2 K2 i6 d6 f7 } a}
! k: ]4 x M% k8 Z6 }
; g$ a; f5 f' ^" Relse
! C' Y9 [5 d" }' d J$ r. U% e9 C$ z3 c8 ~8 X1 k
{
, G6 }, ]7 H. S; o% v" j) l5 ~/ M C
return(Zero)
5 U* A! z, }! z, |// AC Not Present
& w$ ~" A7 }! P4 k' B v) B2 T
2 t+ Q9 F$ Y2 g" g- f* J6 a2 x7 ?}+ n! W# G+ f- E s {1 u5 @2 k2 E
+ U" t, t r. U! d% ^Store(0x0C, DBG8)
8 M) a) e$ k) F# |
# V# K$ r. {! j9 [}
9 L7 ^0 s- C* u2 J" x! J) Q1 d, ^/ \% {* i# J
" O5 w( G7 k, U9 u' ~
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。
e) o r0 d! n4 l& W# G状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:, Q; J9 {, p+ i% Z% D; C
Method(_BST)
$ h" g; `8 J5 f{
& N7 A$ o, s6 d z% N$ l; y' [+ |
3 Q! J, p( f8 g/ q! ^% mStore(BSTS,Local0)6 F9 c- r) P2 m2 r+ W; w/ ?
* m( Y8 D: w% \7 w
/ m- B: n; h! U3 y# L6 b9 [
If(LEqual(Local0,1)) //Check Battery Present Bit
2 ?. F4 o& v* V* r9 ~- Z
, A+ s* f# {' p9 _' d$ {- \{
- t7 G y7 \0 h- s( h) _% _3 ~* n# `
% G; \3 u$ k) n; i( \( |3 i
5 e0 w$ ^1 y5 ? N# a/ z5 I; \4 T: R0 K/ z& |+ w8 L7 {
; g- i5 i, C2 r0 N2 k
//Read Battery information from EC7 _, n H; k# c$ z, B0 |/ z
. x Z4 `* f+ b+ c( R+ ^
… …. Z* T; F# U' i. W0 Z+ D( m
7 u! m, }2 \" b: g" k
: ~2 |" Z" q9 g5 A% \3 l# k
}
6 ? }6 E& t' X
6 X' Z. W' Y' e* ?# f0 d' {& AStore(0x0D, DBG8)
7 Q! R3 O" Y2 q2 H. e- ~4 ^* h} 4 M ^0 C5 M' ]9 [# X% w' ?( c
那么问题好像是由读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所致。1 d6 |, _* v8 S3 h) m% q
那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:* ?2 r0 y1 E6 ^( R7 u0 X
5 s- ]! t% T+ t$ E
& K: b2 T5 a; \2 ^2 |! 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.! H: H7 ~0 c+ ~3 h6 _; k
6 p0 H2 _" I4 k; c' g# a. X
0 S/ r8 C; l: R
# h+ U; f( b- H; B经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证! T; e3 l; d+ o7 w; e& l8 d. g
1 b6 N6 a" ` |4 o+ K4 l# v) u0 Q) v. V% V* m7 j
2 X$ U" ]' {1 B, t 3 c3 }- O& U2 e$ _' U" O2 w( u
That’s all!; w+ M& R3 ^' O; Q+ a* h
+ h0 o" j2 Q2 t8 ^Peter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|