Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
72a14827
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
72a14827
编写于
8月 13, 2012
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/nouveau: restore fifo chid information in engine error messages
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
4c2d4222
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
213 addition
and
132 deletion
+213
-132
drivers/gpu/drm/nouveau/core/core/engctx.c
drivers/gpu/drm/nouveau/core/core/engctx.c
+13
-44
drivers/gpu/drm/nouveau/core/core/handle.c
drivers/gpu/drm/nouveau/core/core/handle.c
+34
-0
drivers/gpu/drm/nouveau/core/engine/copy/nva3.c
drivers/gpu/drm/nouveau/core/engine/copy/nva3.c
+12
-3
drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c
drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c
+12
-2
drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c
drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c
+11
-2
drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c
drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c
+11
-2
drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
+8
-5
drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
+14
-6
drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
+22
-12
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+20
-12
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
+1
-0
drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
+28
-18
drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
+19
-12
drivers/gpu/drm/nouveau/core/include/core/engctx.h
drivers/gpu/drm/nouveau/core/include/core/engctx.h
+3
-14
drivers/gpu/drm/nouveau/core/include/core/handle.h
drivers/gpu/drm/nouveau/core/include/core/handle.h
+5
-0
未找到文件。
drivers/gpu/drm/nouveau/core/core/engctx.c
浏览文件 @
72a14827
...
...
@@ -59,7 +59,6 @@ nouveau_engctx_create_(struct nouveau_object *parent,
{
struct
nouveau_client
*
client
=
nouveau_client
(
parent
);
struct
nouveau_engine
*
engine
=
nv_engine
(
engobj
);
struct
nouveau_subdev
*
subdev
=
nv_subdev
(
engine
);
struct
nouveau_object
*
engctx
;
unsigned
long
save
;
int
ret
;
...
...
@@ -210,58 +209,28 @@ _nouveau_engctx_fini(struct nouveau_object *object, bool suspend)
}
struct
nouveau_object
*
nouveau_engctx_
lookup
(
struct
nouveau_engine
*
engine
,
u64
addr
)
nouveau_engctx_
get
(
struct
nouveau_engine
*
engine
,
u64
addr
)
{
struct
nouveau_engctx
*
engctx
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
engine
->
lock
,
flags
);
list_for_each_entry
(
engctx
,
&
engine
->
contexts
,
head
)
{
if
(
engctx
->
base
.
size
&&
nv_gpuobj
(
engctx
)
->
addr
==
addr
)
if
(
engctx
->
addr
==
addr
)
{
engctx
->
save
=
flags
;
return
nv_object
(
engctx
);
}
}
return
NULL
;
}
struct
nouveau_handle
*
nouveau_engctx_lookup_class
(
struct
nouveau_engine
*
engine
,
u64
addr
,
u16
oclass
)
{
struct
nouveau_object
*
engctx
=
nouveau_engctx_lookup
(
engine
,
addr
);
struct
nouveau_namedb
*
namedb
;
if
(
engctx
&&
(
namedb
=
(
void
*
)
nv_pclass
(
engctx
,
NV_NAMEDB_CLASS
)))
return
nouveau_namedb_get_class
(
namedb
,
oclass
);
return
NULL
;
}
struct
nouveau_handle
*
nouveau_engctx_lookup_vinst
(
struct
nouveau_engine
*
engine
,
u64
addr
,
u64
vinst
)
{
struct
nouveau_object
*
engctx
=
nouveau_engctx_lookup
(
engine
,
addr
);
struct
nouveau_namedb
*
namedb
;
if
(
engctx
&&
(
namedb
=
(
void
*
)
nv_pclass
(
engctx
,
NV_NAMEDB_CLASS
)))
return
nouveau_namedb_get_vinst
(
namedb
,
vinst
);
return
NULL
;
}
struct
nouveau_handle
*
nouveau_engctx_lookup_cinst
(
struct
nouveau_engine
*
engine
,
u64
addr
,
u32
cinst
)
{
struct
nouveau_object
*
engctx
=
nouveau_engctx_lookup
(
engine
,
addr
);
struct
nouveau_namedb
*
namedb
;
if
(
engctx
&&
(
namedb
=
(
void
*
)
nv_pclass
(
engctx
,
NV_NAMEDB_CLASS
)))
return
nouveau_namedb_get_cinst
(
namedb
,
cinst
);
spin_unlock_irqrestore
(
&
engine
->
lock
,
flags
);
return
NULL
;
}
void
nouveau_engctx_
handle_put
(
struct
nouveau_handle
*
handle
)
nouveau_engctx_
put
(
struct
nouveau_object
*
object
)
{
if
(
handle
)
nouveau_namedb_put
(
handle
);
if
(
object
)
{
struct
nouveau_engine
*
engine
=
nv_engine
(
object
->
engine
);
struct
nouveau_engctx
*
engctx
=
nv_engctx
(
object
);
spin_unlock_irqrestore
(
&
engine
->
lock
,
engctx
->
save
);
}
}
drivers/gpu/drm/nouveau/core/core/handle.c
浏览文件 @
72a14827
...
...
@@ -187,3 +187,37 @@ nouveau_handle_ref(struct nouveau_object *parent, u32 name)
return
object
;
}
struct
nouveau_handle
*
nouveau_handle_get_class
(
struct
nouveau_object
*
engctx
,
u16
oclass
)
{
struct
nouveau_namedb
*
namedb
;
if
(
engctx
&&
(
namedb
=
(
void
*
)
nv_pclass
(
engctx
,
NV_NAMEDB_CLASS
)))
return
nouveau_namedb_get_class
(
namedb
,
oclass
);
return
NULL
;
}
struct
nouveau_handle
*
nouveau_handle_get_vinst
(
struct
nouveau_object
*
engctx
,
u64
vinst
)
{
struct
nouveau_namedb
*
namedb
;
if
(
engctx
&&
(
namedb
=
(
void
*
)
nv_pclass
(
engctx
,
NV_NAMEDB_CLASS
)))
return
nouveau_namedb_get_vinst
(
namedb
,
vinst
);
return
NULL
;
}
struct
nouveau_handle
*
nouveau_handle_get_cinst
(
struct
nouveau_object
*
engctx
,
u32
cinst
)
{
struct
nouveau_namedb
*
namedb
;
if
(
engctx
&&
(
namedb
=
(
void
*
)
nv_pclass
(
engctx
,
NV_NAMEDB_CLASS
)))
return
nouveau_namedb_get_cinst
(
namedb
,
cinst
);
return
NULL
;
}
void
nouveau_handle_put
(
struct
nouveau_handle
*
handle
)
{
if
(
handle
)
nouveau_namedb_put
(
handle
);
}
drivers/gpu/drm/nouveau/core/engine/copy/nva3.c
浏览文件 @
72a14827
...
...
@@ -30,6 +30,7 @@
#include <subdev/fb.h>
#include <subdev/vm.h>
#include <engine/fifo.h>
#include <engine/copy.h>
#include "fuc/nva3.fuc.h"
...
...
@@ -102,21 +103,28 @@ static struct nouveau_enum nva3_copy_isr_error_name[] = {
static
void
nva3_copy_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
nouveau_fifo
*
pfifo
=
nouveau_fifo
(
subdev
);
struct
nouveau_engine
*
engine
=
nv_engine
(
subdev
);
struct
nouveau_object
*
engctx
;
struct
nva3_copy_priv
*
priv
=
(
void
*
)
subdev
;
u32
dispatch
=
nv_rd32
(
priv
,
0x10401c
);
u32
stat
=
nv_rd32
(
priv
,
0x104008
)
&
dispatch
&
~
(
dispatch
>>
16
);
u
32
inst
=
nv_rd32
(
priv
,
0x104050
)
&
0x3fffffff
;
u
64
inst
=
nv_rd32
(
priv
,
0x104050
)
&
0x3fffffff
;
u32
ssta
=
nv_rd32
(
priv
,
0x104040
)
&
0x0000ffff
;
u32
addr
=
nv_rd32
(
priv
,
0x104040
)
>>
16
;
u32
mthd
=
(
addr
&
0x07ff
)
<<
2
;
u32
subc
=
(
addr
&
0x3800
)
>>
11
;
u32
data
=
nv_rd32
(
priv
,
0x104044
);
int
chid
;
engctx
=
nouveau_engctx_get
(
engine
,
inst
);
chid
=
pfifo
->
chid
(
pfifo
,
engctx
);
if
(
stat
&
0x00000040
)
{
nv_error
(
priv
,
"DISPATCH_ERROR ["
);
nouveau_enum_print
(
nva3_copy_isr_error_name
,
ssta
);
printk
(
"] ch
0x%08x
subc %d mthd 0x%04x data 0x%08x
\n
"
,
inst
,
subc
,
mthd
,
data
);
printk
(
"] ch
%d [0x%010llx]
subc %d mthd 0x%04x data 0x%08x
\n
"
,
chid
,
inst
<<
12
,
subc
,
mthd
,
data
);
nv_wr32
(
priv
,
0x104004
,
0x00000040
);
stat
&=
~
0x00000040
;
}
...
...
@@ -127,6 +135,7 @@ nva3_copy_intr(struct nouveau_subdev *subdev)
}
nv50_fb_trap
(
nouveau_fb
(
priv
),
1
);
nouveau_engctx_put
(
engctx
);
}
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c
浏览文件 @
72a14827
...
...
@@ -27,6 +27,7 @@
#include <core/class.h>
#include <core/engctx.h>
#include <engine/fifo.h>
#include <engine/copy.h>
#include "fuc/nvc0.fuc.h"
...
...
@@ -113,6 +114,9 @@ static struct nouveau_enum nvc0_copy_isr_error_name[] = {
static
void
nvc0_copy_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
nouveau_fifo
*
pfifo
=
nouveau_fifo
(
subdev
);
struct
nouveau_engine
*
engine
=
nv_engine
(
subdev
);
struct
nouveau_object
*
engctx
;
int
idx
=
nv_engidx
(
nv_object
(
subdev
))
-
NVDEV_ENGINE_COPY0
;
struct
nvc0_copy_priv
*
priv
=
(
void
*
)
subdev
;
u32
disp
=
nv_rd32
(
priv
,
0x10401c
+
(
idx
*
0x1000
));
...
...
@@ -124,12 +128,16 @@ nvc0_copy_intr(struct nouveau_subdev *subdev)
u32
mthd
=
(
addr
&
0x07ff
)
<<
2
;
u32
subc
=
(
addr
&
0x3800
)
>>
11
;
u32
data
=
nv_rd32
(
priv
,
0x104044
+
(
idx
*
0x1000
));
int
chid
;
engctx
=
nouveau_engctx_get
(
engine
,
inst
);
chid
=
pfifo
->
chid
(
pfifo
,
engctx
);
if
(
stat
&
0x00000040
)
{
nv_error
(
priv
,
"DISPATCH_ERROR ["
);
nouveau_enum_print
(
nvc0_copy_isr_error_name
,
ssta
);
printk
(
"] ch
0x%010llx
subc %d mthd 0x%04x data 0x%08x
\n
"
,
(
u64
)
inst
<<
12
,
subc
,
mthd
,
data
);
printk
(
"] ch
%d [0x%010llx]
subc %d mthd 0x%04x data 0x%08x
\n
"
,
chid
,
(
u64
)
inst
<<
12
,
subc
,
mthd
,
data
);
nv_wr32
(
priv
,
0x104004
+
(
idx
*
0x1000
),
0x00000040
);
stat
&=
~
0x00000040
;
}
...
...
@@ -138,6 +146,8 @@ nvc0_copy_intr(struct nouveau_subdev *subdev)
nv_error
(
priv
,
"unhandled intr 0x%08x
\n
"
,
stat
);
nv_wr32
(
priv
,
0x104004
+
(
idx
*
0x1000
),
stat
);
}
nouveau_engctx_put
(
engctx
);
}
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c
浏览文件 @
72a14827
...
...
@@ -30,6 +30,7 @@
#include <subdev/fb.h>
#include <engine/fifo.h>
#include <engine/crypt.h>
struct
nv84_crypt_priv
{
...
...
@@ -133,23 +134,31 @@ static struct nouveau_bitfield nv84_crypt_intr_mask[] = {
static
void
nv84_crypt_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
nouveau_fifo
*
pfifo
=
nouveau_fifo
(
subdev
);
struct
nouveau_engine
*
engine
=
nv_engine
(
subdev
);
struct
nouveau_object
*
engctx
;
struct
nv84_crypt_priv
*
priv
=
(
void
*
)
subdev
;
u32
stat
=
nv_rd32
(
priv
,
0x102130
);
u32
mthd
=
nv_rd32
(
priv
,
0x102190
);
u32
data
=
nv_rd32
(
priv
,
0x102194
);
u32
inst
=
nv_rd32
(
priv
,
0x102188
)
&
0x7fffffff
;
int
chid
;
engctx
=
nouveau_engctx_get
(
engine
,
inst
);
chid
=
pfifo
->
chid
(
pfifo
,
engctx
);
if
(
stat
)
{
nv_error
(
priv
,
""
);
nouveau_bitfield_print
(
nv84_crypt_intr_mask
,
stat
);
printk
(
" ch
0x%010llx
mthd 0x%04x data 0x%08x
\n
"
,
(
u64
)
inst
<<
12
,
mthd
,
data
);
printk
(
" ch
%d [0x%010llx]
mthd 0x%04x data 0x%08x
\n
"
,
chid
,
(
u64
)
inst
<<
12
,
mthd
,
data
);
}
nv_wr32
(
priv
,
0x102130
,
stat
);
nv_wr32
(
priv
,
0x10200c
,
0x10
);
nv50_fb_trap
(
nouveau_fb
(
priv
),
1
);
nouveau_engctx_put
(
engctx
);
}
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c
浏览文件 @
72a14827
...
...
@@ -30,6 +30,7 @@
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <engine/fifo.h>
#include <engine/crypt.h>
#include "fuc/nv98.fuc.h"
...
...
@@ -102,6 +103,9 @@ static struct nouveau_enum nv98_crypt_isr_error_name[] = {
static
void
nv98_crypt_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
nouveau_fifo
*
pfifo
=
nouveau_fifo
(
subdev
);
struct
nouveau_engine
*
engine
=
nv_engine
(
subdev
);
struct
nouveau_object
*
engctx
;
struct
nv98_crypt_priv
*
priv
=
(
void
*
)
subdev
;
u32
disp
=
nv_rd32
(
priv
,
0x08701c
);
u32
stat
=
nv_rd32
(
priv
,
0x087008
)
&
disp
&
~
(
disp
>>
16
);
...
...
@@ -111,12 +115,16 @@ nv98_crypt_intr(struct nouveau_subdev *subdev)
u32
mthd
=
(
addr
&
0x07ff
)
<<
2
;
u32
subc
=
(
addr
&
0x3800
)
>>
11
;
u32
data
=
nv_rd32
(
priv
,
0x087044
);
int
chid
;
engctx
=
nouveau_engctx_get
(
engine
,
inst
);
chid
=
pfifo
->
chid
(
pfifo
,
engctx
);
if
(
stat
&
0x00000040
)
{
nv_error
(
priv
,
"DISPATCH_ERROR ["
);
nouveau_enum_print
(
nv98_crypt_isr_error_name
,
ssta
);
printk
(
"] ch
0x%08x
subc %d mthd 0x%04x data 0x%08x
\n
"
,
inst
,
subc
,
mthd
,
data
);
printk
(
"] ch
%d [0x%010llx]
subc %d mthd 0x%04x data 0x%08x
\n
"
,
chid
,
(
u64
)
inst
<<
12
,
subc
,
mthd
,
data
);
nv_wr32
(
priv
,
0x087004
,
0x00000040
);
stat
&=
~
0x00000040
;
}
...
...
@@ -127,6 +135,7 @@ nv98_crypt_intr(struct nouveau_subdev *subdev)
}
nv50_fb_trap
(
nouveau_fb
(
priv
),
1
);
nouveau_engctx_put
(
engctx
);
}
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
浏览文件 @
72a14827
...
...
@@ -195,9 +195,10 @@ nv20_graph_tile_prog(struct nouveau_engine *engine, int i)
void
nv20_graph_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
nv20_graph_priv
*
priv
=
(
void
*
)
subdev
;
struct
nouveau_engine
*
engine
=
nv_engine
(
subdev
);
struct
nouveau_handle
*
handle
=
NULL
;
struct
nouveau_object
*
engctx
;
struct
nouveau_handle
*
handle
;
struct
nv20_graph_priv
*
priv
=
(
void
*
)
subdev
;
u32
stat
=
nv_rd32
(
priv
,
NV03_PGRAPH_INTR
);
u32
nsource
=
nv_rd32
(
priv
,
NV03_PGRAPH_NSOURCE
);
u32
nstatus
=
nv_rd32
(
priv
,
NV03_PGRAPH_NSTATUS
);
...
...
@@ -207,15 +208,15 @@ nv20_graph_intr(struct nouveau_subdev *subdev)
u32
mthd
=
(
addr
&
0x00001ffc
);
u32
data
=
nv_rd32
(
priv
,
NV04_PGRAPH_TRAPPED_DATA
);
u32
class
=
nv_rd32
(
priv
,
0x400160
+
subc
*
4
)
&
0xfff
;
u32
inst
=
nv_ro32
(
priv
->
ctxtab
,
(
chid
*
4
))
<<
4
;
u32
show
=
stat
;
engctx
=
nouveau_engctx_get
(
engine
,
chid
);
if
(
stat
&
NV_PGRAPH_INTR_ERROR
)
{
if
(
nsource
&
NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD
)
{
handle
=
nouveau_
engctx_lookup_class
(
engine
,
inst
,
class
);
handle
=
nouveau_
handle_get_class
(
engctx
,
class
);
if
(
handle
&&
!
nv_call
(
handle
->
object
,
mthd
,
data
))
show
&=
~
NV_PGRAPH_INTR_ERROR
;
nouveau_
engctx_
handle_put
(
handle
);
nouveau_handle_put
(
handle
);
}
}
...
...
@@ -233,6 +234,8 @@ nv20_graph_intr(struct nouveau_subdev *subdev)
nv_info
(
priv
,
"ch %d/%d class 0x%04x mthd 0x%04x data 0x%08x
\n
"
,
chid
,
subc
,
class
,
mthd
,
data
);
}
nouveau_engctx_put
(
engctx
);
}
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
浏览文件 @
72a14827
...
...
@@ -256,26 +256,32 @@ nv40_graph_tile_prog(struct nouveau_engine *engine, int i)
static
void
nv40_graph_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
n
v40_graph_priv
*
priv
=
(
void
*
)
subdev
;
struct
n
ouveau_fifo
*
pfifo
=
nouveau_fifo
(
subdev
)
;
struct
nouveau_engine
*
engine
=
nv_engine
(
subdev
);
struct
nouveau_object
*
engctx
;
struct
nouveau_handle
*
handle
=
NULL
;
struct
nv40_graph_priv
*
priv
=
(
void
*
)
subdev
;
u32
stat
=
nv_rd32
(
priv
,
NV03_PGRAPH_INTR
);
u32
nsource
=
nv_rd32
(
priv
,
NV03_PGRAPH_NSOURCE
);
u32
nstatus
=
nv_rd32
(
priv
,
NV03_PGRAPH_NSTATUS
);
u32
inst
=
(
nv_rd32
(
priv
,
0x40032c
)
&
0x000fffff
)
<<
4
;
u32
inst
=
nv_rd32
(
priv
,
0x40032c
)
&
0x000fffff
;
u32
addr
=
nv_rd32
(
priv
,
NV04_PGRAPH_TRAPPED_ADDR
);
u32
subc
=
(
addr
&
0x00070000
)
>>
16
;
u32
mthd
=
(
addr
&
0x00001ffc
);
u32
data
=
nv_rd32
(
priv
,
NV04_PGRAPH_TRAPPED_DATA
);
u32
class
=
nv_rd32
(
priv
,
0x400160
+
subc
*
4
)
&
0xffff
;
u32
show
=
stat
;
int
chid
;
engctx
=
nouveau_engctx_get
(
engine
,
inst
);
chid
=
pfifo
->
chid
(
pfifo
,
engctx
);
if
(
stat
&
NV_PGRAPH_INTR_ERROR
)
{
if
(
nsource
&
NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD
)
{
handle
=
nouveau_
engctx_lookup_class
(
engine
,
inst
,
class
);
handle
=
nouveau_
handle_get_class
(
engctx
,
class
);
if
(
handle
&&
!
nv_call
(
handle
->
object
,
mthd
,
data
))
show
&=
~
NV_PGRAPH_INTR_ERROR
;
nouveau_
engctx_
handle_put
(
handle
);
nouveau_handle_put
(
handle
);
}
if
(
nsource
&
NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION
)
{
...
...
@@ -294,10 +300,12 @@ nv40_graph_intr(struct nouveau_subdev *subdev)
printk
(
" nstatus:"
);
nouveau_bitfield_print
(
nv10_graph_nstatus
,
nstatus
);
printk
(
"
\n
"
);
nv_error
(
priv
,
"ch
0x%08x
subc %d class 0x%04x "
nv_error
(
priv
,
"ch
%d [0x%08x]
subc %d class 0x%04x "
"mthd 0x%04x data 0x%08x
\n
"
,
inst
,
subc
,
class
,
mthd
,
data
);
chid
,
inst
<<
4
,
subc
,
class
,
mthd
,
data
);
}
nouveau_engctx_put
(
engctx
);
}
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
浏览文件 @
72a14827
...
...
@@ -32,6 +32,7 @@
#include <subdev/vm.h>
#include <subdev/timer.h>
#include <engine/fifo.h>
#include <engine/graph.h>
#include "nv50.h"
...
...
@@ -462,7 +463,8 @@ nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old,
}
static
int
nv50_graph_trap_handler
(
struct
nv50_graph_priv
*
priv
,
u32
display
,
u64
inst
)
nv50_graph_trap_handler
(
struct
nv50_graph_priv
*
priv
,
u32
display
,
int
chid
,
u64
inst
)
{
u32
status
=
nv_rd32
(
priv
,
0x400108
);
u32
ustatus
;
...
...
@@ -495,11 +497,11 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, u64 inst)
nv_error
(
priv
,
"TRAP DISPATCH_FAULT
\n
"
);
if
(
display
&&
(
addr
&
0x80000000
))
{
nv_error
(
priv
,
"ch
0x%010llx
"
nv_error
(
priv
,
"ch
%d [0x%010llx]
"
"subc %d class 0x%04x mthd 0x%04x "
"data 0x%08x%08x "
"400808 0x%08x 400848 0x%08x
\n
"
,
inst
,
subc
,
class
,
mthd
,
datah
,
chid
,
inst
,
subc
,
class
,
mthd
,
datah
,
datal
,
addr
,
r848
);
}
else
if
(
display
)
{
...
...
@@ -521,10 +523,10 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, u64 inst)
nv_error
(
priv
,
"TRAP DISPATCH_QUERY
\n
"
);
if
(
display
&&
(
addr
&
0x80000000
))
{
nv_error
(
priv
,
"ch
0x%010llx
"
nv_error
(
priv
,
"ch
%d [0x%010llx]
"
"subc %d class 0x%04x mthd 0x%04x "
"data 0x%08x 40084c 0x%08x
\n
"
,
inst
,
subc
,
class
,
mthd
,
chid
,
inst
,
subc
,
class
,
mthd
,
data
,
addr
);
}
else
if
(
display
)
{
...
...
@@ -675,23 +677,29 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, u64 inst)
static
void
nv50_graph_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
n
v50_graph_priv
*
priv
=
(
void
*
)
subdev
;
struct
n
ouveau_fifo
*
pfifo
=
nouveau_fifo
(
subdev
)
;
struct
nouveau_engine
*
engine
=
nv_engine
(
subdev
);
struct
nouveau_object
*
engctx
;
struct
nouveau_handle
*
handle
=
NULL
;
struct
nv50_graph_priv
*
priv
=
(
void
*
)
subdev
;
u32
stat
=
nv_rd32
(
priv
,
0x400100
);
u
64
inst
=
(
u64
)(
nv_rd32
(
priv
,
0x40032c
)
&
0x0fffffff
)
<<
12
;
u
32
inst
=
nv_rd32
(
priv
,
0x40032c
)
&
0x0fffffff
;
u32
addr
=
nv_rd32
(
priv
,
0x400704
);
u32
subc
=
(
addr
&
0x00070000
)
>>
16
;
u32
mthd
=
(
addr
&
0x00001ffc
);
u32
data
=
nv_rd32
(
priv
,
0x400708
);
u32
class
=
nv_rd32
(
priv
,
0x400814
);
u32
show
=
stat
;
int
chid
;
engctx
=
nouveau_engctx_get
(
engine
,
inst
);
chid
=
pfifo
->
chid
(
pfifo
,
engctx
);
if
(
stat
&
0x00000010
)
{
handle
=
nouveau_
engctx_lookup_class
(
engine
,
inst
,
class
);
handle
=
nouveau_
handle_get_class
(
engctx
,
class
);
if
(
handle
&&
!
nv_call
(
handle
->
object
,
mthd
,
data
))
show
&=
~
0x00000010
;
nouveau_
engctx_
handle_put
(
handle
);
nouveau_handle_put
(
handle
);
}
if
(
show
&
0x00100000
)
{
...
...
@@ -702,7 +710,7 @@ nv50_graph_intr(struct nouveau_subdev *subdev)
}
if
(
stat
&
0x00200000
)
{
if
(
!
nv50_graph_trap_handler
(
priv
,
show
,
inst
))
if
(
!
nv50_graph_trap_handler
(
priv
,
show
,
chid
,
(
u64
)
inst
<<
12
))
show
&=
~
0x00200000
;
}
...
...
@@ -713,14 +721,16 @@ nv50_graph_intr(struct nouveau_subdev *subdev)
nv_info
(
priv
,
""
);
nouveau_bitfield_print
(
nv50_graph_intr_name
,
show
);
printk
(
"
\n
"
);
nv_error
(
priv
,
"ch
0x%010llx
subc %d class 0x%04x "
nv_error
(
priv
,
"ch
%d [0x%010llx]
subc %d class 0x%04x "
"mthd 0x%04x data 0x%08x
\n
"
,
inst
,
subc
,
class
,
mthd
,
data
);
chid
,
(
u64
)
inst
<<
12
,
subc
,
class
,
mthd
,
data
);
nv50_fb_trap
(
nouveau_fb
(
priv
),
1
);
}
if
(
nv_rd32
(
priv
,
0x400824
)
&
(
1
<<
31
))
nv_wr32
(
priv
,
0x400824
,
nv_rd32
(
priv
,
0x400824
)
&
~
(
1
<<
31
));
nouveau_engctx_put
(
engctx
);
}
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
浏览文件 @
72a14827
...
...
@@ -226,10 +226,12 @@ nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
static
void
nvc0_graph_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
n
vc0_graph_priv
*
priv
=
(
void
*
)
subdev
;
struct
n
ouveau_fifo
*
pfifo
=
nouveau_fifo
(
subdev
)
;
struct
nouveau_engine
*
engine
=
nv_engine
(
subdev
);
struct
nouveau_handle
*
handle
=
NULL
;
u64
inst
=
(
u64
)(
nv_rd32
(
priv
,
0x409b00
)
&
0x0fffffff
)
<<
12
;
struct
nouveau_object
*
engctx
;
struct
nouveau_handle
*
handle
;
struct
nvc0_graph_priv
*
priv
=
(
void
*
)
subdev
;
u64
inst
=
nv_rd32
(
priv
,
0x409b00
)
&
0x0fffffff
;
u32
stat
=
nv_rd32
(
priv
,
0x400100
);
u32
addr
=
nv_rd32
(
priv
,
0x400704
);
u32
mthd
=
(
addr
&
0x00003ffc
);
...
...
@@ -237,24 +239,28 @@ nvc0_graph_intr(struct nouveau_subdev *subdev)
u32
data
=
nv_rd32
(
priv
,
0x400708
);
u32
code
=
nv_rd32
(
priv
,
0x400110
);
u32
class
=
nv_rd32
(
priv
,
0x404200
+
(
subc
*
4
));
int
chid
;
engctx
=
nouveau_engctx_get
(
engine
,
inst
);
chid
=
pfifo
->
chid
(
pfifo
,
engctx
);
if
(
stat
&
0x00000010
)
{
handle
=
nouveau_
engctx_lookup_class
(
engine
,
inst
,
class
);
handle
=
nouveau_
handle_get_class
(
engctx
,
class
);
if
(
!
handle
||
nv_call
(
handle
->
object
,
mthd
,
data
))
{
nv_error
(
priv
,
"ILLEGAL_MTHD ch
0x%010llx
"
nv_error
(
priv
,
"ILLEGAL_MTHD ch
%d [0x%010llx]
"
"subc %d class 0x%04x mthd 0x%04x "
"data 0x%08x
\n
"
,
inst
,
subc
,
class
,
mthd
,
data
);
chid
,
inst
<<
12
,
subc
,
class
,
mthd
,
data
);
}
nouveau_
engctx_
handle_put
(
handle
);
nouveau_handle_put
(
handle
);
nv_wr32
(
priv
,
0x400100
,
0x00000010
);
stat
&=
~
0x00000010
;
}
if
(
stat
&
0x00000020
)
{
nv_error
(
priv
,
"ILLEGAL_CLASS ch
0x%010llx
subc %d "
nv_error
(
priv
,
"ILLEGAL_CLASS ch
%d [0x%010llx]
subc %d "
"class 0x%04x mthd 0x%04x data 0x%08x
\n
"
,
inst
,
subc
,
class
,
mthd
,
data
);
chid
,
inst
<<
12
,
subc
,
class
,
mthd
,
data
);
nv_wr32
(
priv
,
0x400100
,
0x00000020
);
stat
&=
~
0x00000020
;
}
...
...
@@ -262,16 +268,17 @@ nvc0_graph_intr(struct nouveau_subdev *subdev)
if
(
stat
&
0x00100000
)
{
nv_error
(
priv
,
"DATA_ERROR ["
);
nouveau_enum_print
(
nv50_data_error_names
,
code
);
printk
(
"] ch
0x%010llx
subc %d class 0x%04x "
printk
(
"] ch
%d [0x%010llx]
subc %d class 0x%04x "
"mthd 0x%04x data 0x%08x
\n
"
,
inst
,
subc
,
class
,
mthd
,
data
);
chid
,
inst
<<
12
,
subc
,
class
,
mthd
,
data
);
nv_wr32
(
priv
,
0x400100
,
0x00100000
);
stat
&=
~
0x00100000
;
}
if
(
stat
&
0x00200000
)
{
u32
trap
=
nv_rd32
(
priv
,
0x400108
);
nv_error
(
priv
,
"TRAP ch 0x%010llx status 0x%08x
\n
"
,
inst
,
trap
);
nv_error
(
priv
,
"TRAP ch %d [0x%010llx] status 0x%08x
\n
"
,
chid
,
inst
<<
12
,
trap
);
nv_wr32
(
priv
,
0x400108
,
trap
);
nv_wr32
(
priv
,
0x400100
,
0x00200000
);
stat
&=
~
0x00200000
;
...
...
@@ -289,6 +296,7 @@ nvc0_graph_intr(struct nouveau_subdev *subdev)
}
nv_wr32
(
priv
,
0x400500
,
0x00010001
);
nouveau_engctx_put
(
engctx
);
}
int
...
...
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
浏览文件 @
72a14827
...
...
@@ -35,6 +35,7 @@
#include <subdev/bar.h>
#include <subdev/timer.h>
#include <engine/fifo.h>
#include <engine/graph.h>
#define GPC_MAX 4
...
...
drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
浏览文件 @
72a14827
...
...
@@ -76,14 +76,15 @@ nve0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
}
static
void
nve0_graph_trap_isr
(
struct
nvc0_graph_priv
*
priv
,
u64
inst
)
nve0_graph_trap_isr
(
struct
nvc0_graph_priv
*
priv
,
int
chid
,
u64
inst
)
{
u32
trap
=
nv_rd32
(
priv
,
0x400108
);
int
rop
;
if
(
trap
&
0x00000001
)
{
u32
stat
=
nv_rd32
(
priv
,
0x404000
);
nv_error
(
priv
,
"DISPATCH ch 0x%010llx 0x%08x
\n
"
,
inst
,
stat
);
nv_error
(
priv
,
"DISPATCH ch %d [0x%010llx] 0x%08x
\n
"
,
chid
,
inst
,
stat
);
nv_wr32
(
priv
,
0x404000
,
0xc0000000
);
nv_wr32
(
priv
,
0x400108
,
0x00000001
);
trap
&=
~
0x00000001
;
...
...
@@ -91,7 +92,8 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, u64 inst)
if
(
trap
&
0x00000010
)
{
u32
stat
=
nv_rd32
(
priv
,
0x405840
);
nv_error
(
priv
,
"SHADER ch 0x%010llx 0x%08x
\n
"
,
inst
,
stat
);
nv_error
(
priv
,
"SHADER ch %d [0x%010llx] 0x%08x
\n
"
,
chid
,
inst
,
stat
);
nv_wr32
(
priv
,
0x405840
,
0xc0000000
);
nv_wr32
(
priv
,
0x400108
,
0x00000010
);
trap
&=
~
0x00000010
;
...
...
@@ -101,8 +103,8 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, u64 inst)
for
(
rop
=
0
;
rop
<
priv
->
rop_nr
;
rop
++
)
{
u32
statz
=
nv_rd32
(
priv
,
ROP_UNIT
(
rop
,
0x070
));
u32
statc
=
nv_rd32
(
priv
,
ROP_UNIT
(
rop
,
0x144
));
nv_error
(
priv
,
"ROP%d ch
0x%010llx
0x%08x 0x%08x
\n
"
,
rop
,
inst
,
statz
,
statc
);
nv_error
(
priv
,
"ROP%d ch
%d [0x%010llx]
0x%08x 0x%08x
\n
"
,
rop
,
chid
,
inst
,
statz
,
statc
);
nv_wr32
(
priv
,
ROP_UNIT
(
rop
,
0x070
),
0xc0000000
);
nv_wr32
(
priv
,
ROP_UNIT
(
rop
,
0x144
),
0xc0000000
);
}
...
...
@@ -111,7 +113,8 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, u64 inst)
}
if
(
trap
)
{
nv_error
(
priv
,
"TRAP ch 0x%010llx 0x%08x
\n
"
,
inst
,
trap
);
nv_error
(
priv
,
"TRAP ch %d [0x%010llx] 0x%08x
\n
"
,
chid
,
inst
,
trap
);
nv_wr32
(
priv
,
0x400108
,
trap
);
}
}
...
...
@@ -119,10 +122,12 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, u64 inst)
static
void
nve0_graph_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
n
vc0_graph_priv
*
priv
=
(
void
*
)
subdev
;
struct
n
ouveau_fifo
*
pfifo
=
nouveau_fifo
(
subdev
)
;
struct
nouveau_engine
*
engine
=
nv_engine
(
subdev
);
struct
nouveau_handle
*
handle
=
NULL
;
u64
inst
=
(
u64
)(
nv_rd32
(
priv
,
0x409b00
)
&
0x0fffffff
)
<<
12
;
struct
nouveau_object
*
engctx
;
struct
nouveau_handle
*
handle
;
struct
nvc0_graph_priv
*
priv
=
(
void
*
)
subdev
;
u64
inst
=
nv_rd32
(
priv
,
0x409b00
)
&
0x0fffffff
;
u32
stat
=
nv_rd32
(
priv
,
0x400100
);
u32
addr
=
nv_rd32
(
priv
,
0x400704
);
u32
mthd
=
(
addr
&
0x00003ffc
);
...
...
@@ -130,24 +135,28 @@ nve0_graph_intr(struct nouveau_subdev *subdev)
u32
data
=
nv_rd32
(
priv
,
0x400708
);
u32
code
=
nv_rd32
(
priv
,
0x400110
);
u32
class
=
nv_rd32
(
priv
,
0x404200
+
(
subc
*
4
));
int
chid
;
engctx
=
nouveau_engctx_get
(
engine
,
inst
);
chid
=
pfifo
->
chid
(
pfifo
,
engctx
);
if
(
stat
&
0x00000010
)
{
handle
=
nouveau_
engctx_lookup_class
(
engine
,
inst
,
class
);
handle
=
nouveau_
handle_get_class
(
engctx
,
class
);
if
(
!
handle
||
nv_call
(
handle
->
object
,
mthd
,
data
))
{
nv_error
(
priv
,
"ILLEGAL_MTHD ch
0x%010llx
"
nv_error
(
priv
,
"ILLEGAL_MTHD ch
%d [0x%010llx]
"
"subc %d class 0x%04x mthd 0x%04x "
"data 0x%08x
\n
"
,
inst
,
subc
,
class
,
mthd
,
data
);
chid
,
inst
,
subc
,
class
,
mthd
,
data
);
}
nouveau_
engctx_
handle_put
(
handle
);
nouveau_handle_put
(
handle
);
nv_wr32
(
priv
,
0x400100
,
0x00000010
);
stat
&=
~
0x00000010
;
}
if
(
stat
&
0x00000020
)
{
nv_error
(
priv
,
"ILLEGAL_CLASS ch
0x%010llx
subc %d "
nv_error
(
priv
,
"ILLEGAL_CLASS ch
%d [0x%010llx]
subc %d "
"class 0x%04x mthd 0x%04x data 0x%08x
\n
"
,
inst
,
subc
,
class
,
mthd
,
data
);
chid
,
inst
,
subc
,
class
,
mthd
,
data
);
nv_wr32
(
priv
,
0x400100
,
0x00000020
);
stat
&=
~
0x00000020
;
}
...
...
@@ -155,15 +164,15 @@ nve0_graph_intr(struct nouveau_subdev *subdev)
if
(
stat
&
0x00100000
)
{
nv_error
(
priv
,
"DATA_ERROR ["
);
nouveau_enum_print
(
nv50_data_error_names
,
code
);
printk
(
"] ch
0x%010llx
subc %d class 0x%04x "
printk
(
"] ch
%d [0x%010llx]
subc %d class 0x%04x "
"mthd 0x%04x data 0x%08x
\n
"
,
inst
,
subc
,
class
,
mthd
,
data
);
chid
,
inst
,
subc
,
class
,
mthd
,
data
);
nv_wr32
(
priv
,
0x400100
,
0x00100000
);
stat
&=
~
0x00100000
;
}
if
(
stat
&
0x00200000
)
{
nve0_graph_trap_isr
(
priv
,
inst
);
nve0_graph_trap_isr
(
priv
,
chid
,
inst
);
nv_wr32
(
priv
,
0x400100
,
0x00200000
);
stat
&=
~
0x00200000
;
}
...
...
@@ -180,6 +189,7 @@ nve0_graph_intr(struct nouveau_subdev *subdev)
}
nv_wr32
(
priv
,
0x400500
,
0x00010001
);
nouveau_engctx_put
(
engctx
);
}
static
int
...
...
drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
浏览文件 @
72a14827
...
...
@@ -26,13 +26,14 @@
#include <core/class.h>
#include <core/engctx.h>
#include <core/handle.h>
#include <core/engine/graph/nv40.h>
#include <subdev/fb.h>
#include <subdev/timer.h>
#include <subdev/instmem.h>
#include <engine/fifo.h>
#include <engine/mpeg.h>
#include <engine/graph/nv40.h>
struct
nv31_mpeg_priv
{
struct
nouveau_mpeg
base
;
...
...
@@ -195,30 +196,34 @@ nv31_mpeg_tile_prog(struct nouveau_engine *engine, int i)
void
nv31_mpeg_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
n
v31_mpeg_priv
*
priv
=
(
void
*
)
subdev
;
struct
n
ouveau_fifo
*
pfifo
=
nouveau_fifo
(
subdev
)
;
struct
nouveau_engine
*
engine
=
nv_engine
(
subdev
);
struct
nouveau_handle
*
handle
=
NULL
;
u32
inst
=
(
nv_rd32
(
priv
,
0x00b318
)
&
0x000fffff
)
<<
4
;
struct
nouveau_object
*
engctx
;
struct
nouveau_handle
*
handle
;
struct
nv31_mpeg_priv
*
priv
=
(
void
*
)
subdev
;
u32
inst
=
nv_rd32
(
priv
,
0x00b318
)
&
0x000fffff
;
u32
stat
=
nv_rd32
(
priv
,
0x00b100
);
u32
type
=
nv_rd32
(
priv
,
0x00b230
);
u32
mthd
=
nv_rd32
(
priv
,
0x00b234
);
u32
data
=
nv_rd32
(
priv
,
0x00b238
);
u32
show
=
stat
;
int
chid
;
engctx
=
nouveau_engctx_get
(
engine
,
inst
);
chid
=
pfifo
->
chid
(
pfifo
,
engctx
);
if
(
stat
&
0x01000000
)
{
/* happens on initial binding of the object */
if
(
handle
&&
type
==
0x00000020
&&
mthd
==
0x0000
)
{
if
(
type
==
0x00000020
&&
mthd
==
0x0000
)
{
nv_mask
(
priv
,
0x00b308
,
0x00000000
,
0x00000000
);
show
&=
~
0x01000000
;
}
if
(
handle
&&
type
==
0x00000010
)
{
handle
=
nouveau_engctx_lookup_class
(
engine
,
inst
,
0x3174
);
if
(
handle
&&
!
nv_call
(
handle
->
object
,
mthd
,
data
))
{
nouveau_engctx_handle_put
(
handle
);
if
(
type
==
0x00000010
)
{
handle
=
nouveau_handle_get_class
(
engctx
,
0x3174
);
if
(
handle
&&
!
nv_call
(
handle
->
object
,
mthd
,
data
))
show
&=
~
0x01000000
;
}
nouveau_handle_put
(
handle
);
}
}
...
...
@@ -227,8 +232,10 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
if
(
show
)
{
nv_error
(
priv
,
"ch %d [0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x
\n
"
,
inst
,
stat
,
type
,
mthd
,
data
);
chid
,
inst
<<
4
,
stat
,
type
,
mthd
,
data
);
}
nouveau_engctx_put
(
engctx
);
}
static
int
...
...
drivers/gpu/drm/nouveau/core/include/core/engctx.h
浏览文件 @
72a14827
...
...
@@ -13,6 +13,7 @@ struct nouveau_engctx {
struct
nouveau_gpuobj
base
;
struct
nouveau_vma
vma
;
struct
list_head
head
;
unsigned
long
save
;
u64
addr
;
};
...
...
@@ -44,19 +45,7 @@ int _nouveau_engctx_fini(struct nouveau_object *, bool suspend);
#define _nouveau_engctx_rd32 _nouveau_gpuobj_rd32
#define _nouveau_engctx_wr32 _nouveau_gpuobj_wr32
struct
nouveau_object
*
nouveau_engctx_lookup
(
struct
nouveau_engine
*
,
u64
addr
);
struct
nouveau_handle
*
nouveau_engctx_lookup_class
(
struct
nouveau_engine
*
,
u64
,
u16
);
struct
nouveau_handle
*
nouveau_engctx_lookup_vinst
(
struct
nouveau_engine
*
,
u64
,
u64
);
struct
nouveau_handle
*
nouveau_engctx_lookup_cinst
(
struct
nouveau_engine
*
,
u64
,
u32
);
void
nouveau_engctx_handle_put
(
struct
nouveau_handle
*
);
struct
nouveau_object
*
nouveau_engctx_get
(
struct
nouveau_engine
*
,
u64
addr
);
void
nouveau_engctx_put
(
struct
nouveau_object
*
);
#endif
drivers/gpu/drm/nouveau/core/include/core/handle.h
浏览文件 @
72a14827
...
...
@@ -23,4 +23,9 @@ int nouveau_handle_fini(struct nouveau_handle *, bool suspend);
struct
nouveau_object
*
nouveau_handle_ref
(
struct
nouveau_object
*
,
u32
name
);
struct
nouveau_handle
*
nouveau_handle_get_class
(
struct
nouveau_object
*
,
u16
);
struct
nouveau_handle
*
nouveau_handle_get_vinst
(
struct
nouveau_object
*
,
u64
);
struct
nouveau_handle
*
nouveau_handle_get_cinst
(
struct
nouveau_object
*
,
u32
);
void
nouveau_handle_put
(
struct
nouveau_handle
*
);
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录