找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 24037|回复: 3

谁帮详细解释所有发给ec的60/64命令号码和意义

[复制链接]
发表于 2008-7-14 00:04:00 | 显示全部楼层 |阅读模式
bini殇,能帮详细解释一下bios post过程中的所有发给ec的60/64命令号码和意义吗?数据量比较大,截不住。
发表于 2008-7-14 12:09:38 | 显示全部楼层
转个别人发的,不知道LZ能不能用上  
( _$ ^% q+ h$ e% B* @6 i# k& m( c' `  q4 Z$ m
4.2.7 Command
( f: d8 I* z5 ?/ Y& S) U
- v( W& L) j1 w) [2 v# l通过8042芯片,可以:5 t) l7 |5 v0 b: {' B
向8042芯片发布命令(通过64h),并通过60h读取命令的返回结果(如果有的话),或通过60h端口写入命令所需的数据(如果需要的话)。  s6 t: y: D7 _, d. J8 A  y0 f; w1 f
读取Status Register的内容(通过64h);. G. b0 J, G6 u& _: ~5 o' h9 E
向8048发布命令(通过60h);
0 N5 u8 V, M! ]: e; d读取来自于Keyboard的数据(通过60h)。这些数据包括Scan Code(由按键和释放键引起的),对8048发送的命令的确认字节(ACK)及回复数据。+ U4 H/ L3 a3 L: ^

% @" v# X) \3 F9 C再次强调一遍,Command(命令)分为发送给8042芯片的命令和发送给8048的命令。它们是不相同的,并且使用的端口也是不相同的(分别为64h和60h)。
) Q9 }7 O8 I! C" p; @( }7 c1 Z  R+ l; w
  N# K: o& y0 w. \) T# U
* p3 v4 `) d- H1 `. e0 {' T4 `
    * 64h端口(读操作)
% a5 b- P+ w1 Q1 N: X: z. k. d: K" i

, J% K$ S  N! A对64h端口进行读操作,会读取Status Register的内容。
) u( x, u2 X/ a& l% n: I+ h
& _$ `, p  s# rinb %0x643 I+ N" W$ Y* F" r/ c+ k& J" L7 \) f
执行这个指令之后,AL寄存器中存放的就是Status Register的内容。
8 V  Z3 E& L3 `3 L4 m: X: r/ V4 i4 v1 F3 R3 E0 R
    * 64h端口(写操作)
, Q7 p% {. Z% R$ x; d' x8 `$ z
+ c; `0 Z4 [: D& t) T; V" o向64h端口写入的字节,被认为是对8042芯片发布的命令(Command):
' |2 R, g: _9 U, x3 w% j  z: zŸ
* W# v  ]/ ]8 _  C, w/ J写入的字节将会被存放在Input Register中;  w  s: Z9 V6 ~' |9 w! q6 {. W
Ÿ" ?/ p- j  U5 j. y. _  i% Q
同时会引起Status Register的Bit-3自动被设置为1,表示现在放在Input Register中的数据是一个Command,而不是一个Data;
  X& \5 \) N. j- F( lŸ
8 \3 R, O  y' a$ I  o1 N8 J- N在向64h端口写某些命令之前必须确保键盘是被禁止的,因为这些被写入的命令的返回结果将会放到Output Register中,而键盘如果不被禁止,则也会将数据放入到Output Register中,会引起相互之间的数据覆盖;0 w! o. U: d; D! U6 K' g+ m" Y% U
Ÿ& t" ?& O( O3 ]% w, h' k2 X
在向64h端口写数据之前必须确保Input Register是空的(通过判断Status Register的Bit-1是否为0)。, l1 q& ^0 |# h* f, n' w

1 R$ ]6 E& @3 Z# Mvoid wait_input_empty(void)
7 c3 M+ W) M: V# G) I{
1 h% e, M3 s7 d* B8 S! g& C   char __b;! ?) {8 m1 @/ [  M( j7 ?" ]( N

& I+ Y8 k  O. V/ u$ i; P   do{7 H+ S% {$ h4 X6 S4 A
     __b = inb(0x64);
$ u8 k4 k- R) \   }while(!(__b&0x02));6 G$ v6 ~' b+ }2 Z6 v) j; ]$ e+ q0 m4 R4 z
}
* M- d: }% I) ]8 g' @. B9 u
% q3 D  t/ Y4 q/ Ovoid disable_keyboard(void)
; z8 W, ^" f1 ?' i{
" q" j+ [7 p0 P5 N   wait_input_empty();9 X/ F8 F1 g  B; ?" b, J7 ~
   outb(0x64, 0xAD);3 g3 N% p" A) a+ i0 E& w
}[size=+0]
4 a' p8 Q6 q7 [5 O& S7 y
- w: k8 }1 W- I/ {3 P    * 60h端口(读操作)
$ \5 M. U2 V6 |* w! F2 j
: }$ i8 y% Z! D- K- K' S$ O2 o对60h端口进行读操作,将会读取Output Register的内容。Output Register的内容可能是:% e  h7 D$ \' _' p- v0 n% _
Ÿ           来自于8048的数据。这些数据包括Scan Code,对8048发送的命令的确认字节(ACK)及回复数据。( p/ l/ A& I- ~# y7 p9 u
Ÿ           通过64h端口对8042发布的命令的返回结果。2 `5 @$ ?- `/ K# `
7 B2 x  V" `& e- Z7 e; n$ Z
在向60h端口读取数据之前必须确保Output Register中有数据(通过判断Status Register的Bit-0是否为1)。
- ~8 n4 h; S, z6 \8 _- T/ c  @void wait_output_full(void)
- R3 q2 ]5 G9 S, r& {5 c, ~{4 A7 \% y2 h7 a# |: u
   char __b;
- i: H0 {$ ^  f7 d# o! a$ F
2 c- t# H" E! X& k& n% h: R. W   do{2 `8 ]! \$ i1 T! m/ I( u) s* F! q
     __b = inb(0x64);, v- e  _3 w) d1 Z0 m& D
   }while(__b&0x01);+ c- [; b# n9 U8 a4 Y8 h4 Q
}: R# u7 h8 l/ |- z. |

( c& \, `* m  ^unsigned char read_output(void)/ U! [) p1 S: x
{4 i8 h! X2 k# A9 Y4 C9 x, s7 O
   wait_output_full();
: n: a+ W3 D4 [; U  C0 Y  }   return inb(0x60);
( p" O3 Q4 H; ^. a$ W- v}
) |2 s9 K& k, x( S. z6 _" j& ^/ R! E
    * 60h端口(写操作)
( Z5 \# F4 k5 u& d
  I7 g+ B) R# R% D3 X: q向60h端口写入的字节,有两种可能:9 B, k3 b$ o: |# X. x
1.如果之前通过64h端口向8042芯片发布的命令需要进一步的数据,则此时写入的字节就被认为是数据;
6 J! O! @6 B& r- x; O! ~2.否则,此字节被认为是发送给8048的命令。
" I2 g" s( Y1 A
6 n7 s: S( {  ^" u7 M4 L0 b4 T" Y在向60h端口写数据之前,必须确保Input Register是空的(通过判断Status Register的Bit-1是否为0)。: K2 s$ E* Y8 h. D4 v9 n- ~3 X, l

' g3 F; U: t1 a/ F
7 y* Q5 K9 }4 h2 n[size=+0]4.2.7.1 发给8042的命令) J1 c0 o# V! e3 S) v+ f8 _7 G) w) l$ ?

, I4 l: ?. @/ s9 U% V* L    * 20h
# q$ v/ i+ p$ w) {$ {
/ q) @0 X6 n3 Y4 ?2 K$ w; F2 H0 c准备读取8042芯片的Command Byte;其行为是将当前8042 Command Byte的内容放置于Output Register中,下一个从60H端口的读操作将会将其读取出来。9 T0 E! z, I5 N0 U3 v. L! c1 i
  T# {; o% Q5 u8 b( }

7 ?' g1 d" p& s( a! }  ?+ ^/ J! a- junsigned char read_command_byte(void)4 V3 O& V; f& R5 x2 i
{2 t% p5 \8 _& {* R/ P4 x/ L
   wait_input_empty();
& B$ f" v! c" J3 y1 P   outb(0x64,0x20);' T# R( }6 T# s9 [1 I- y
   wait_output_full();, d3 ^" o" L9 G  I3 e: ]: I
   return inb(0x60);   ! Z! e; B* W# d! k: O" H. m0 ]
}
7 r6 L7 {" r) v! v: F+ k
! h& U5 e$ P9 M( N) t' H) ?5 E" x  T    * 60h
/ J+ W% P- k  w9 ?% m# z2 [$ m( K, B1 O6 `0 e
准备写入8042芯片的Command Byte;下一个通过60h写入的字节将会被放入Command Byte。
5 q# a1 T$ H# e: x6 ~3 z) J7 g' ^/ t0 N, J8 ~- \6 R) d6 O5 e' i
/ Y( r# [5 I' A  Z
void write_command_byte(unsigned char command_byte)- D: K! [, h, {2 X) `" H+ E& ^
{
, {9 O: o! O+ E+ o   wait_input_empty();$ |& a6 N5 A( g* h
   outb(0x64,0x60);
9 ~% F. z- Y. V; ^8 F- s7 y   wait_input_empty();$ E' [' E$ C) }+ k
   outb(0x60,command_byte);
  \2 b8 a! q7 F9 W& ]* Q}
" U* `/ p- e9 J. ]/ [: p8 a, E# D& Q( [7 [5 d, Y3 l
# \& k1 Q9 G5 o
    * A4h
' p& {6 W( m( L& Y3 a9 Y5 l% y0 b+ O* }$ c: G' U& `" G/ x/ |
测试一下键盘密码是否被设置;测试结果放置在Output Register,然后可以通过60h读取出来。测试结果可以有两种值:FAh=密码被设置;F1h=没有密码。0 C, Q" V  b+ u
bool is_set_password(void)
( u) G# B& Q* V, Q) ?) h3 Y{3 g+ N: F9 s# X: P4 Q
   wait_input_empty();# H# ~. ]3 [. w7 `/ e9 F% r  \
   outb(0x64,0xA4);" A8 @  l& _3 X
   wait_output_full();& U$ b. I; P; E* q
   return inb(0x60)==0xFA?true:false;   + J1 i7 s. g* Q. F! R6 x3 @
}- Z0 V$ ]" d' J/ M
: k4 w+ @1 w/ t0 ?! y- ^' o
    * A5h
& u3 P! ?0 e2 @. a  S+ V$ E$ I3 \3 ?8 @1 e9 }) a% ?# X
设置键盘密码。其结果被按照顺序通过60h端口一个一个被放置在Input Register中。密码的最后是一个空字节(内容为0)。9 N" `/ C5 |) w7 p; l- W9 u
void set_password(unsigned char* password)
" U6 l9 T, s+ a* a; X3 C/ r% V2 `{
! O" a) H- p' T   char* p = password;
, R+ c1 t& P0 N; {9 N1 M: C& C3 z2 q# O& I
   if(p == NULL)7 }/ m5 N& S, l/ E( s
      return;
9 E" v/ D) }+ \: S8 W
* s& @9 W9 y" b6 H   wait_input_empty();
; s: j  F6 ~2 n) P& j   outb(0x64,0xA5);
% @$ \$ V+ J, M, ]: u! E- n$ E/ @, K
) u: u# J- r# u$ n& K; p+ P) J   do{- g+ [, V- L( ]) N* e8 J
      wait_input_empty();
* S+ U4 Z2 O9 i0 E# P      outb(0x60, *p);  d" h9 [( S: C: G% C1 }9 L
   }while(*p++ != 0);. Z8 L6 r/ f  w9 ]3 G
}
8 P+ z2 J  T0 K; o% z% d+ @9 c/ N7 o7 G
    * A6h0 i4 p% N& G9 B1 q% E4 j* h0 o

" B) U  [" ]1 Q让密码生效。在发布这个命令之前,必须首先使用A5h命令设置密码。
9 Y8 @  H5 @4 d+ T0 u/ g9 ~void enable_password(void)
5 [/ a7 e/ C9 u+ b. ~! z' U& k( F{; }$ l1 v: R' I! I- B  I$ h# |+ i
   if(!is_set_password())
8 ]$ ^, ?) S& _9 ~8 h: O# X  V& A; _      return;
1 I. a! C- E3 Z" V
' i2 A3 I( T. n0 _   wait_input_empty();! r- t* g+ z/ }: z
   outb(0x64,0xA6);   - M# _% O! }! w% r* m' X
}. R1 z) z+ [  x# g- V" \
% m+ |( `* R, c! ?0 j2 F/ G* F+ t
    * AAh
- X$ h9 @+ J$ Q/ p9 W/ m  p
% A# N+ F0 s) Z$ w% b) A自检。诊断结果放置在Output Register中,可以通过60h读取。55h=OK。: Y0 J7 \  Y% H
: \- \7 r8 g! Q, T; n

% f- j, G! Z' R9 xbool is_test_ok(void)
8 @8 _3 {- G8 o* p5 [# K( `{
8 Z$ v+ M, p% W% n: m. ?( i   wait_input_empty();
% a$ v% u( R2 a; U; H" L   outb(0x64,0xAA);
. T* p+ o- V0 E$ Z: r
5 v& e, a; s- T& ^+ ?7 \
4 G/ G$ z0 n4 ~6 ^& g4 f   wait_output_full();
/ l: o  Z/ X* Q   return inb(0x60)==0x55?true:false;   7 D3 z2 N& h1 c* x# R: a8 u9 `
}
6 Y1 S$ {) ]2 d% M' ]2 Q: F1 y) _3 _& |) p" j1 G

' S) M5 w$ U) N    * ADh
% M) R$ h6 O2 y/ D4 O6 ]$ `+ `# i" a4 n- L
禁止键盘接口。Command Byte的bit-4被设置。当此命令被发布后,Keyboard将被禁止发送数据到Output Register。
2 ?; {& G4 h6 ~5 j8 ]# D, J  [5 Yvoid disable_keyboard(void)" D' z) }, ?# v
{) J! L; S$ s: o( f, b6 N+ ?
   wait_input_empty();; @! a  ]- a0 F8 F" j. O
   outb(0x64,0xAD);; |0 h& _3 K) \/ r5 S
0 l8 O1 R' ~/ L0 u$ W$ v& h
}
. |, [8 H& T* A. c
9 Y5 |5 R; e! F& l6 s- G+ s" `    * AEh. c( E0 V5 n( N! z( d( y
- X; F% @* D, G9 S- w# ]
打开键盘接口。Command Byte的bit-4被清除。当此命令被发布后,Keyboard将被允许发送数据到Output Register。
$ ]6 h, q, C* K, _  S" Ovoid enable_keyboard(void)- b- C$ ^; N; ]
{, J' a, f- X) P* w; U3 ^
   wait_input_empty();
, D) `& h% J4 T; @( v8 j" H9 R   outb(0x64,0xAE);
2 x9 r) C; M5 a: E. d- n1 N' [9 f1 ~- |3 q2 F) ]
}
6 G2 _  B# ?+ D) r* N5 h9 p4 w
/ B+ X1 z" R7 x: \    * C0h
3 G) W6 S$ B  n) O: S* U* p% j* M  _6 W; F
准备读取Input Port。Input Port的内容被放置于Output Register中,随后可以通过60h端口读取。8 |1 E' r$ g' H7 N1 g0 O
unsigned char read_input_port(void)
- c4 M3 \; D; F( ~& j. l7 ~0 `4 w{& n" L) t$ O" \- W
   wait_input_empty();
7 U, Z, T" h1 i! o( `9 \   outb(0x64,0xC0);$ K# s# p# V$ @3 K, d

$ C. N  J$ d# Z$ D$ w/ A2 \   wait_output_full();' I& W( ]( e' O% ^
8 Y3 \* N6 j% s! q. g1 C2 w& Q
   return inb(0x60);
$ h/ q- ?; t: R) P$ E7 c) L, w9 a}; ^6 J1 _3 W8 F

+ U2 O3 b/ \  M: c* k! `6 @6 `    * D0h. y: }! V8 ]( q2 E; v  S2 u5 |
: c. y2 z* g7 ]& k) T
准备读取Outport端口。结果被放在Output Register中,随后通过60h端口读取出来。2 i" \/ N( o( P7 {8 F  n9 D
unsigned char read_output_port(void)
) \# I' C" x! Y, b$ L9 J{# t' ?3 D. G- d% {% L  q# B
   wait_input_empty();/ g! s, g% w. z% t1 m6 ]6 E9 J
   outb(0x64,0xD0);
: l# G0 D5 B2 @# b
4 t+ ]7 j0 p$ `& ?4 ?* B+ F2 n! }2 q   wait_output_full();
2 |- w8 X; d. b* L. W- v, R% M& c3 A5 d5 O; L
   return inb(0x60);
5 |0 b/ v  Z2 W0 S7 ~% D) Q}1 g: O6 L1 Z0 U3 M- o! e- D6 L9 n

3 x# M) A8 Q) A4 N# {6 H    * D1h/ m$ Y; T- }9 W' @& G% ?$ e$ t
& F' V( U5 T1 E: w' Y% M" X3 R& X
准备写Output端口。随后通过60h端口写入的字节,会被放置在Output Port中。$ S8 k- |1 k2 ?% J4 N6 M+ I
void write_output_port(unsigned char __c)
2 b# T2 \, B, D{
. ^; y9 F6 C) j! T/ ?4 q& `) I( |   wait_input_empty();
' P8 R2 T$ A4 ]4 S' t2 p6 a   outb(0x64,0xD1);
7 G; q6 j9 ?: ^. }$ I- o- a
8 Y4 L* x( Q/ D' [1 V   wait_input_empty();
0 s$ h1 D3 I4 V2 g# @( U6 \0 z   outb(0x60,__c);
+ ~- i) b$ y4 p6 ~
8 p! C' u+ _) R- [8 [& O: m}
/ C* S) ?. k5 \! e) _! w
8 m5 o9 D8 z6 l' ?3 ]5 P- Z) B, J% v6 s8 K4 C9 {4 t
    * D2h' e7 k) J7 Y3 I; s6 X$ r: g+ W
9 ~* B# W7 \) ~+ _9 x
准备写数据到Output Register中。随后通过60h写入到Input Register的字节会被放入到Output Register中,此功能被用来模拟来自于Keyboard发送的数据。如果中断被允许,则会触发一个中断。& Z& ~' z8 p. g5 d
void put_data_to_output_register(unsigned char __data)
3 Z: @+ T0 ]( ]6 ?3 B* z{7 [, [; S; K* M- a; S# p
   wait_input_empty();
5 b3 `4 _0 }8 I: q   outb(0x64,0xD2);* `4 J/ ]/ h: F9 j1 j; I( x( |/ r
& [4 @: W- \/ l$ }) r( J5 T
   wait_input_empty();4 N- G* L# ~9 d& w
   outb(0x60,__c);6 \+ A3 D9 n/ X3 Z! E/ b1 k
}
; R) a( L$ [9 h# R. R
* p7 A) }, X0 T6 H& F4.2.7.2 发给8048的命令& E9 R# K" r. v$ b* _: b" R
/ X: R. N) R* }4 ^7 t0 I5 R

3 h% W% u, J  I" I/ n  _    * EDh
9 q& P2 R9 ?% s  t  C( m
1 x( L) }5 S( ~' x设置LED。Keyboard收到此命令后,一个LED设置会话开始。Keyboard首先回复一个ACK(FAh),然后等待从60h端口写入的LED设置字节,如果等到一个,则再次回复一个ACK,然后根据此字节设置LED。然后接着等待。。。直到等到一个非LED设置字节(高位被设置),此时LED设置会话结束。
2 Z) {+ R& F' k4 C  f2 p( u. Z6 {3 e
    * EEh
) T$ z5 n; g7 b' @" O& k. y) T/ }5 |9 y, R; t7 |5 |/ @) J+ z
诊断Echo。此命令纯粹为了检测Keyboard是否正常,如果正常,当Keyboard收到此命令后,将会回复一个EEh字节。
/ X/ [+ n" m, N( o! e9 l" [3 K# N: z
    * F0h
+ `( X  Y0 a$ `; @( U: m9 J+ K# ?+ g8 e5 x9 }
选择Scan code set。Keyboard系统共可能有3个Scan code set。当Keyboard收到此命令后,将回复一个ACK,然后等待一个来自于60h端口的Scan code set代码。系统必须在此命令之后发送给Keyboard一个Scan code set代码。当Keyboard收到此代码后,将再次回复一个ACK,然后将Scan code set设置为收到的Scan code set代码所要求的。, `# I- u6 V9 \& n8 I; F7 l" W
- s5 O8 Q0 J6 E. S
    * F2  i* C; u5 M6 g9 H+ t% M

! @6 A2 d; b' v! r* r读取Keyboard ID。由于8042芯片后不仅仅能够接Keyboard。此命令是为了读取8042后所接的设备ID。设备ID为2个字节,Keyboard ID为83ABh。当键盘收到此命令后,会首先回复一个ACK,然后,将2字节的Keyboard ID一个一个回复回去。  ~; a8 v; A: d. A  f& N

- |4 L% g% z3 U( ^    * F3h  D, R( ^8 P! I
  x$ }$ u5 Q1 \( s% p: H- t' G/ S
设置Typematic Rate/Delay。当Keyboard收到此命令后,将回复一个ACK。然后等待来自于60h的设置字节。一旦收到,将回复一个ACK,然后将Keyboard Rate/Delay设置为相应的值。
3 g, |& K; y5 k; N7 q
3 \7 e9 I' M- D, @7 u    * F4h
7 @# b$ a3 S$ y0 Z5 \4 e% K: G8 n8 h: ]( j, J4 \: [
清理键盘的Output Buffer。一旦Keyboard收到此命令,将会将Output buffer清空,然后回复一个ACK。然后继续接受Keyboard的击键。  y+ r( Y4 K; X! ^

: `( V8 r7 k& O- d5 m2 @* v% t    * F5h. F+ d3 p( l* k/ D. D$ \& W

# w. }" V4 o" g$ Y: J) F设置默认状态(w/Disable)。一旦Keyboard收到此命令,将会将Keyboard完全初始化成默认状态。之前所有对它的设置都将失效——Output buffer被清空,Typematic Rate/Delay被设置成默认值。然后回复一个ACK,接着等待下一个命令。需要注意的是,这个命令被执行后,键盘的击键接受是禁止的。如果想让键盘接受击键输入,必须Enable Keyboard。/ C# {$ [' B/ h, R/ o+ r8 C2 T( q5 m, S
2 E% _& A* W& @  K) N! n: @& R
    * F6h+ H$ l2 P3 s& _6 Z, g  C

2 [$ s1 G, s0 \) m设置默认状态。和F5命令唯一不同的是,当此命令被执行之后,键盘的击键接收是允许的。. n9 r! }9 |% N
! k. h6 [8 ^, v; _7 ]. Y+ [
    * FEh; R0 ]8 ?0 f' J& {0 ^

" C0 K0 Y  W* CResend。如果Keyboard收到此命令,则必须将刚才发送到8042 Output Register中的数据重新发送一遍。当系统检测到一个来自于Keyboard的错误之后,可以使用自命令让Keyboard重新发送刚才发送的字节。
! Z# J; Y7 K9 B/ o! d0 o8 M. X
9 C8 c0 k8 h1 \; }/ r  n: S    * FFh
0 `, K: j; j- C  H: x4 v+ t5 |7 |1 Z# g) n  ]2 j1 }3 w% U
Reset Keyboard。如果Keyboard收到此命令,则首先回复一个ACK,然后启动自身的Reset程序,并进行自身基本正确性检测(BAT-Basic Assurance Test)。等这一切结束之后,将返回给系统一个单字节的结束码(AAh=Success, FCh=Failed),并将键盘的Scan code set设置为2。
回复

使用道具 举报

发表于 2009-1-14 13:49:16 | 显示全部楼层
好贴!5 G$ e3 ?6 B/ y& y) u' Z3 o
非常详细!
  n6 V$ i, X  S4 P# i谢谢!
回复

使用道具 举报

发表于 2009-2-25 17:37:28 | 显示全部楼层
2楼好帖!在helppc的Hardware Data and Specifications栏里有相应的寄存器和命令详细描述。' R( i4 }) o, {5 O! f

/ o' p  m# w, h; E我的问题是,上述描述应该是针对老的8042的,在目前的使用EC的系统中,这些status register和command描述在哪个文档中可以找到?比如intel的santarosa,使用renessas的H8s 2104 EC,按道理上述状态寄存器,命令等的描述应该在2104 datasheet里,但是我怎么找都没有。还是有某个spec定义了这些命令格式?新手问题,高手莫笑
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2026-3-5 15:56 , Processed in 0.069545 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表