|
|
AC In/Out OS Slow Response
" m2 R0 J5 y+ D4 B2 _" | H2 ]5 V- Phenomenon
0 z# l) Y- m& y/ m% c& \% @5 F9 N , J/ o% ~, D' e# a) s U8 U6 \
手上一个超薄NB的案子DQA报了这样一条bug:频繁的插拔AC,vista右下角的power icon有时反应很慢,AC插拔过后有时需要等几秒或十几秒才发现power icon有变化。Power icon指的是下图红色圆圈标出的部分:
v" q8 C! B' D0 q2 w9 T, I- Why???' A. F& V7 a+ e; @0 p+ y( p
: F5 ?" o8 {6 {, n( V; W
' B, E8 Z& y3 Z5 r8 a, w刚看到这条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 如下述所示:9 z' S# A, @3 _) Q( [
// AC Change event
3 F% m- Y2 ~, C+ z& {3 d
, t: J2 U5 |2 M) k$ W! lMethod(_QXX)
- V) h! q! m4 K) ]6 K/ _2 F% i" d) Y* y- M/ f) n. e1 k' o8 j/ o6 {$ @
{" L' `5 y/ ]3 u$ I
" @9 @/ h$ D7 D
Store(0x09, DBG8)* @% K9 ^6 U/ O8 S6 d5 M L" ]
3 P! i) Q, A3 }7 TNotify(\_SB. ADP,0x80)
7 b Y( h/ G S- C# D+ F1 g//Power Source status changed# E, @ d# z' c& \# M/ t
0 G1 {3 M( _. n7 O% Q9 u( Y/ C5 H+ ^Store(0x0A, DBG8)
* ~% W' Z5 ]9 Z |* T3 y $ a5 a6 ?. d% d
. {! F. k `, I}
+ ~5 J4 z3 f. `; J5 N$ I* s
1 `- S9 O# Z# F. O- r. b7 b# g( r% N; E m$ O
, M' }" L2 B$ P$ \4 B
Method(_PSR,0)
+ ^1 S7 Q" ?% ~# S* ~" T
7 n8 f( J0 o+ o! H4 `3 k- j- s( [; r' s! }
{
: F9 A3 n: g' P: q; Q
. M5 m7 S" T- f# X5 {. v" @" Z
: G. K' B" X1 k2 b4 |! dStore(0x0B, DBG8)
& L0 ]( D7 T B, ^$ S0 V0 a# D. ]# s* E, j
# O1 G: E' k% K- A0 c- N( V! I5 UIf(ACST)$ w3 l4 A* ]; u% _# `* t& ^# [
//check AC status
" @! B( a, p0 `0 e
5 u f% a' f, f% k{
1 Q* x) L' R: F8 r' N, U) S) J; \) L0 w( K9 {$ {1 l
$ U; p3 E, |8 U$ y& L$ Z( H$ O
return(One)
/ o U) j, R6 J8 n0 E// AC Present
) U+ ^! u8 _; \, A8 _# l' d" v
- u9 j2 t; v8 y3 I+ O# Z- d+ ~}( ^0 g4 @9 t# y2 l3 k- f
. w7 o3 f( o5 ~6 \& Lelse/ z0 Y. \5 [# R1 @% P
3 ]; U8 g+ G" t2 i1 X" g{& e! v+ a, w% H( g4 Y/ g
) T: y2 t# I0 b, z0 y" G% J
return(Zero); M) g, x; ~5 ?2 f; h2 c
// AC Not Present1 J' M1 e' K6 E3 W
: K4 _1 R4 r2 h$ Q0 v}; q! D8 U+ _% ~' E
+ x3 M9 i4 r4 R/ c# tStore(0x0C, DBG8); H5 z& y2 j$ i
8 c& O! s6 R. b3 Z3 J, O t# w; H}
6 w% U/ m, r% B/ i5 x. c7 \$ Q
2 X: c' V, o0 y2 _. G {7 P; W+ [: {& n; ?8 D
我能猜到的大概的流程应该就是这样了。那我们就从头开始追,先在AC change qevent中抛点,可是发现AC change对应的_Q method反应很快,一旦AC in/out debug card马上就会有显示。那么说明什么呢?跟EC没有关系吗?接着抛,又发现有时停在’0x0A’比较久才会出现,有时’0x0C’比较久。
/ h* ]) d: b$ {: Y& k! u# _状况不太一致;没感觉就把网撒大点,在几乎所有的ACPI method中都抛上点然后再try,试了几个回合以后有感觉了,我们发现一旦现象出现在Device Battery _BST method中停的久的几率非常高,也就是说AC in/out OS还会更新battery的信息。这段代码最明显的特征就是它会从EC ram中获取非常多的电池信息,sample code如下所示:4 S" S, \$ F8 b1 L. v. e, g8 y
Method(_BST)
0 g. e" J) L [9 {) X/ O5 K: v{" J! z( x- o- E0 ]# K
, l' c. x* k9 e |# ~7 BStore(BSTS,Local0)
8 n! o6 k* R# Q+ }% q6 I* M
) |4 m, Q# X+ d0 l4 _
, Y5 \* q7 n1 n" c/ s _5 vIf(LEqual(Local0,1)) //Check Battery Present Bit$ y$ v" T$ D8 C @# j; ^# y8 i6 m
) X2 ~) O- z" n3 R m+ U
{
2 `/ q- s+ _% d& E
4 q1 [$ s c, i& R
7 s L) k8 Q0 B) Z G
# [% ?" j/ T% E
4 B/ w; e8 Q. ^
* F7 T3 {2 Q$ C: k+ U8 |2 e/ P//Read Battery information from EC* G9 Y$ i9 }8 \4 ]3 K8 S
5 g4 r- g2 a9 @0 W% s
… …8 M9 S5 Q$ e9 e$ L$ ^
9 [0 [6 N, S9 g/ } A6 g `7 z/ h, h" [; S& s g. l) l$ s, _
}
2 @6 c9 p) w$ d7 a
# t) i" `3 q7 \: }0 H6 O5 hStore(0x0D, DBG8)
2 d6 N/ r" r5 r3 W7 D7 t% N}
. C1 P" H( k7 o* u, q那么问题好像是由读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所致。2 u! e y/ U; E) ?6 I+ M
那么SCI中断机制是怎样的呢?EC SCICFG register通常将SCI IRQ配置成HLH的pulse trigger,而且L的时间通常设置成64us,如下图2所示:6 s2 [/ w0 P1 R9 J0 B
, H8 ]( R( a8 F8 o N4 D; I! m
, r d" o; d. l# a, @8 z而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.
6 T( ~; \0 M% R1 q% ~2 e- `1 | / }, F% @8 b3 y0 y+ h
+ f, W x9 W9 j# h) {+ q6 r3 p1 o) {; |- E, B: Z8 u5 O
经过上面的分析,大概的原因已经清楚了。所以解决问题的方法应该是调整SCI IRQ pulse width,将保持低电平的时间调短,这样就可以有效的避免这条bug。通过这条bug我发现在分析问题的过程中需要理清问题的各个环节,并且对各个环节所涉及到的细节也要深入分析。不能够看到现象就轻易的下结论,更不能想当然,正确的态度是不放过任何蛛丝马迹,大胆假设多方求证!0 b& }6 o( Q b0 V' ~, e
& {7 f. `- F( }3 p4 d
( p8 c/ e9 s8 E3 }2 z u
5 a4 S" ^, C$ V q5 p: P + z- h- ^% P( K
That’s all!" {6 {; e- Q" `; k7 @ H" `
) V e7 s ^4 x0 D2 l" V" q; @
Peter |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入计匠网
×
|