Commit bbf8906b authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/fifo: audit and version fifo channel classes



The full object interfaces are about to be exposed to userspace, so we
need to check for any security-related issues and version the structs
to make it easier to handle any changes we may need in the future.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent a532da97
......@@ -52,10 +52,10 @@ nv04_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
if (!nv_iclass(parent, NV_ENGCTX_CLASS)) {
switch (nv_mclass(parent->parent)) {
case NV03_CHANNEL_DMA_CLASS:
case NV10_CHANNEL_DMA_CLASS:
case NV17_CHANNEL_DMA_CLASS:
case NV40_CHANNEL_DMA_CLASS:
case NV03_CHANNEL_DMA:
case NV10_CHANNEL_DMA:
case NV17_CHANNEL_DMA:
case NV40_CHANNEL_DMA:
break;
default:
return -EINVAL;
......
......@@ -48,10 +48,9 @@ nv50_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
if (!nv_iclass(parent, NV_ENGCTX_CLASS)) {
switch (nv_mclass(parent->parent)) {
case NV50_CHANNEL_DMA_CLASS:
case NV84_CHANNEL_DMA_CLASS:
case NV50_CHANNEL_IND_CLASS:
case NV84_CHANNEL_IND_CLASS:
case NV40_CHANNEL_DMA:
case NV50_CHANNEL_GPFIFO:
case G82_CHANNEL_GPFIFO:
case NV50_DISP_MAST_CLASS:
case NV84_DISP_MAST_CLASS:
case NV94_DISP_MAST_CLASS:
......
......@@ -26,7 +26,8 @@
#include <core/object.h>
#include <core/handle.h>
#include <core/event.h>
#include <core/class.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
......
......@@ -22,8 +22,9 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <core/engctx.h>
#include <core/namedb.h>
#include <core/handle.h>
......@@ -117,16 +118,23 @@ nv04_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
} *args = data;
struct nv04_fifo_priv *priv = (void *)engine;
struct nv04_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
nv_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(parent, "create channel dma vers %d pushbuf %08x "
"offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
} else
return ret;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
0x10000, args->pushbuf,
0x10000, args->v0.pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR), &chan);
......@@ -134,13 +142,15 @@ nv04_fifo_chan_ctor(struct nouveau_object *parent,
if (ret)
return ret;
args->v0.chid = chan->base.chid;
nv_parent(chan)->object_attach = nv04_fifo_object_attach;
nv_parent(chan)->object_detach = nv04_fifo_object_detach;
nv_parent(chan)->context_attach = nv04_fifo_context_attach;
chan->ramfc = chan->base.chid * 32;
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->v0.offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->v0.offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x08, chan->base.pushgpu->addr >> 4);
nv_wo32(priv->ramfc, chan->ramfc + 0x10,
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
......@@ -248,7 +258,7 @@ nv04_fifo_ofuncs = {
static struct nouveau_oclass
nv04_fifo_sclass[] = {
{ NV03_CHANNEL_DMA_CLASS, &nv04_fifo_ofuncs },
{ NV03_CHANNEL_DMA, &nv04_fifo_ofuncs },
{}
};
......
......@@ -22,8 +22,9 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <core/engctx.h>
#include <core/ramht.h>
......@@ -59,16 +60,23 @@ nv10_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
} *args = data;
struct nv04_fifo_priv *priv = (void *)engine;
struct nv04_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
nv_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(parent, "create channel dma vers %d pushbuf %08x "
"offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
} else
return ret;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
0x10000, args->pushbuf,
0x10000, args->v0.pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR), &chan);
......@@ -76,13 +84,15 @@ nv10_fifo_chan_ctor(struct nouveau_object *parent,
if (ret)
return ret;
args->v0.chid = chan->base.chid;
nv_parent(chan)->object_attach = nv04_fifo_object_attach;
nv_parent(chan)->object_detach = nv04_fifo_object_detach;
nv_parent(chan)->context_attach = nv04_fifo_context_attach;
chan->ramfc = chan->base.chid * 32;
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->v0.offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->v0.offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4);
nv_wo32(priv->ramfc, chan->ramfc + 0x14,
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
......@@ -106,7 +116,7 @@ nv10_fifo_ofuncs = {
static struct nouveau_oclass
nv10_fifo_sclass[] = {
{ NV10_CHANNEL_DMA_CLASS, &nv10_fifo_ofuncs },
{ NV10_CHANNEL_DMA, &nv10_fifo_ofuncs },
{}
};
......
......@@ -22,8 +22,9 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <core/engctx.h>
#include <core/ramht.h>
......@@ -64,16 +65,23 @@ nv17_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
} *args = data;
struct nv04_fifo_priv *priv = (void *)engine;
struct nv04_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
nv_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(parent, "create channel dma vers %d pushbuf %08x "
"offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
} else
return ret;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
0x10000, args->pushbuf,
0x10000, args->v0.pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
......@@ -83,13 +91,15 @@ nv17_fifo_chan_ctor(struct nouveau_object *parent,
if (ret)
return ret;
args->v0.chid = chan->base.chid;
nv_parent(chan)->object_attach = nv04_fifo_object_attach;
nv_parent(chan)->object_detach = nv04_fifo_object_detach;
nv_parent(chan)->context_attach = nv04_fifo_context_attach;
chan->ramfc = chan->base.chid * 64;
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->v0.offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->v0.offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4);
nv_wo32(priv->ramfc, chan->ramfc + 0x14,
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
......@@ -113,7 +123,7 @@ nv17_fifo_ofuncs = {
static struct nouveau_oclass
nv17_fifo_sclass[] = {
{ NV17_CHANNEL_DMA_CLASS, &nv17_fifo_ofuncs },
{ NV17_CHANNEL_DMA, &nv17_fifo_ofuncs },
{}
};
......
......@@ -22,8 +22,9 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <core/engctx.h>
#include <core/ramht.h>
......@@ -182,16 +183,23 @@ nv40_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
} *args = data;
struct nv04_fifo_priv *priv = (void *)engine;
struct nv04_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
nv_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(parent, "create channel dma vers %d pushbuf %08x "
"offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
} else
return ret;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
0x1000, args->pushbuf,
0x1000, args->v0.pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
......@@ -200,14 +208,16 @@ nv40_fifo_chan_ctor(struct nouveau_object *parent,
if (ret)
return ret;
args->v0.chid = chan->base.chid;
nv_parent(chan)->context_attach = nv40_fifo_context_attach;
nv_parent(chan)->context_detach = nv40_fifo_context_detach;
nv_parent(chan)->object_attach = nv40_fifo_object_attach;
nv_parent(chan)->object_detach = nv04_fifo_object_detach;
chan->ramfc = chan->base.chid * 128;
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->v0.offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->v0.offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4);
nv_wo32(priv->ramfc, chan->ramfc + 0x18, 0x30000000 |
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
......@@ -232,7 +242,7 @@ nv40_fifo_ofuncs = {
static struct nouveau_oclass
nv40_fifo_sclass[] = {
{ NV40_CHANNEL_DMA_CLASS, &nv40_fifo_ofuncs },
{ NV40_CHANNEL_DMA, &nv40_fifo_ofuncs },
{}
};
......
......@@ -25,7 +25,8 @@
#include <core/client.h>
#include <core/engctx.h>
#include <core/ramht.h>
#include <core/class.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <subdev/timer.h>
#include <subdev/bar.h>
......@@ -194,17 +195,24 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
} *args = data;
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
nv_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(parent, "create channel dma vers %d pushbuf %08x "
"offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
} else
return ret;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
0x2000, args->pushbuf,
0x2000, args->v0.pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
......@@ -213,6 +221,8 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
if (ret)
return ret;
args->v0.chid = chan->base.chid;
nv_parent(chan)->context_attach = nv50_fifo_context_attach;
nv_parent(chan)->context_detach = nv50_fifo_context_detach;
nv_parent(chan)->object_attach = nv50_fifo_object_attach;
......@@ -223,10 +233,10 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
if (ret)
return ret;
nv_wo32(base->ramfc, 0x08, lower_32_bits(args->offset));
nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->offset));
nv_wo32(base->ramfc, 0x10, lower_32_bits(args->offset));
nv_wo32(base->ramfc, 0x14, upper_32_bits(args->offset));
nv_wo32(base->ramfc, 0x08, lower_32_bits(args->v0.offset));
nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->v0.offset));
nv_wo32(base->ramfc, 0x10, lower_32_bits(args->v0.offset));
nv_wo32(base->ramfc, 0x14, upper_32_bits(args->v0.offset));
nv_wo32(base->ramfc, 0x3c, 0x003f6078);
nv_wo32(base->ramfc, 0x44, 0x01003fff);
nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
......@@ -247,18 +257,26 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_channel_ind_class *args = data;
union {
struct nv50_channel_gpfifo_v0 v0;
} *args = data;
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
u64 ioffset, ilength;
int ret;
if (size < sizeof(*args))
return -EINVAL;
nv_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x "
"ioffset %016llx ilength %08x\n",
args->v0.version, args->v0.pushbuf, args->v0.ioffset,
args->v0.ilength);
} else
return ret;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
0x2000, args->pushbuf,
0x2000, args->v0.pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
......@@ -267,6 +285,8 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
if (ret)
return ret;
args->v0.chid = chan->base.chid;
nv_parent(chan)->context_attach = nv50_fifo_context_attach;
nv_parent(chan)->context_detach = nv50_fifo_context_detach;
nv_parent(chan)->object_attach = nv50_fifo_object_attach;
......@@ -277,8 +297,8 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
if (ret)
return ret;
ioffset = args->ioffset;
ilength = order_base_2(args->ilength / 8);
ioffset = args->v0.ioffset;
ilength = order_base_2(args->v0.ilength / 8);
nv_wo32(base->ramfc, 0x3c, 0x403f6078);
nv_wo32(base->ramfc, 0x44, 0x01003fff);
......@@ -359,8 +379,8 @@ nv50_fifo_ofuncs_ind = {
static struct nouveau_oclass
nv50_fifo_sclass[] = {
{ NV50_CHANNEL_DMA_CLASS, &nv50_fifo_ofuncs_dma },
{ NV50_CHANNEL_IND_CLASS, &nv50_fifo_ofuncs_ind },
{ NV50_CHANNEL_DMA, &nv50_fifo_ofuncs_dma },
{ NV50_CHANNEL_GPFIFO, &nv50_fifo_ofuncs_ind },
{}
};
......
......@@ -27,7 +27,8 @@
#include <core/engctx.h>
#include <core/ramht.h>
#include <core/event.h>
#include <core/class.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <subdev/timer.h>
#include <subdev/bar.h>
......@@ -160,17 +161,24 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
} *args = data;
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
nv_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(parent, "create channel dma vers %d pushbuf %08x "
"offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
} else
return ret;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
0x2000, args->pushbuf,
0x2000, args->v0.pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
......@@ -186,6 +194,8 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
if (ret)
return ret;
args->v0.chid = chan->base.chid;
ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
&chan->ramht);
if (ret)
......@@ -196,10 +206,10 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
nv_parent(chan)->object_attach = nv84_fifo_object_attach;
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
nv_wo32(base->ramfc, 0x08, lower_32_bits(args->offset));
nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->offset));
nv_wo32(base->ramfc, 0x10, lower_32_bits(args->offset));
nv_wo32(base->ramfc, 0x14, upper_32_bits(args->offset));
nv_wo32(base->ramfc, 0x08, lower_32_bits(args->v0.offset));
nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->v0.offset));
nv_wo32(base->ramfc, 0x10, lower_32_bits(args->v0.offset));
nv_wo32(base->ramfc, 0x14, upper_32_bits(args->v0.offset));
nv_wo32(base->ramfc, 0x3c, 0x003f6078);
nv_wo32(base->ramfc, 0x44, 0x01003fff);
nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
......@@ -222,18 +232,26 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
union {
struct nv50_channel_gpfifo_v0 v0;
} *args = data;
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
struct nv50_channel_ind_class *args = data;
u64 ioffset, ilength;
int ret;
if (size < sizeof(*args))
return -EINVAL;
nv_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x "
"ioffset %016llx ilength %08x\n",
args->v0.version, args->v0.pushbuf, args->v0.ioffset,
args->v0.ilength);
} else
return ret;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
0x2000, args->pushbuf,
0x2000, args->v0.pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
......@@ -249,6 +267,8 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
if (ret)
return ret;
args->v0.chid = chan->base.chid;
ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
&chan->ramht);
if (ret)
......@@ -259,8 +279,8 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
nv_parent(chan)->object_attach = nv84_fifo_object_attach;
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
ioffset = args->ioffset;
ilength = order_base_2(args->ilength / 8);
ioffset = args->v0.ioffset;
ilength = order_base_2(args->v0.ilength / 8);
nv_wo32(base->ramfc, 0x3c, 0x403f6078);
nv_wo32(base->ramfc, 0x44, 0x01003fff);
......@@ -320,8 +340,8 @@ nv84_fifo_ofuncs_ind = {
static struct nouveau_oclass
nv84_fifo_sclass[] = {
{ NV84_CHANNEL_DMA_CLASS, &nv84_fifo_ofuncs_dma },
{ NV84_CHANNEL_IND_CLASS, &nv84_fifo_ofuncs_ind },
{ G82_CHANNEL_DMA, &nv84_fifo_ofuncs_dma },
{ G82_CHANNEL_GPFIFO, &nv84_fifo_ofuncs_ind },
{}
};
......
......@@ -28,7 +28,8 @@
#include <core/gpuobj.h>
#include <core/engctx.h>
#include <core/event.h>
#include <core/class.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <core/enum.h>
#include <subdev/timer.h>
......@@ -187,20 +188,28 @@ nvc0_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
union {
struct nv50_channel_gpfifo_v0 v0;
} *args = data;
struct nouveau_bar *bar = nouveau_bar(parent);
struct nvc0_fifo_priv *priv = (void *)engine;
struct nvc0_fifo_base *base = (void *)parent;
struct nvc0_fifo_chan *chan;
struct nv50_channel_ind_class *args = data;
u64 usermem, ioffset, ilength;
int ret, i;
if (size < sizeof(*args))
return -EINVAL;
nv_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x "
"ioffset %016llx ilength %08x\n",
args->v0.version, args->v0.pushbuf, args->v0.ioffset,
args->v0.ilength);
} else
return ret;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 1,
priv->user.bar.offset, 0x1000,
args->pushbuf,
args->v0.pushbuf,
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
(1ULL << NVDEV_ENGINE_COPY0) |
......@@ -212,12 +221,14 @@ nvc0_fifo_chan_ctor(struct nouveau_object *parent,
if (ret)
return ret;
args->v0.