From: Luke Browning Date: Thu, 20 Dec 2007 07:39:59 +0000 (+0900) Subject: [POWERPC] spufs: add backing ops for privcntl register X-Git-Tag: v2.6.25-rc1~1131^2~218 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cc210b3ec5e4d9c690549e07aa5853e8de8dbff9;p=linux-2.6 [POWERPC] spufs: add backing ops for privcntl register This change encapsulates the spu_privcntl_RW register so that it can be written through backing ops. This is necessary so that spu contexts can be initialized and queued to the scheduler in spufs_run_spu. Signed-off-by: Luke Browning Signed-off-by: Jeremy Kerr Signed-off-by: Paul Mackerras --- diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c index a64a0044df..15f9158137 100644 --- a/arch/powerpc/platforms/cell/spufs/backing_ops.c +++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c @@ -268,6 +268,11 @@ static char *spu_backing_get_ls(struct spu_context *ctx) return ctx->csa.lscsa->ls; } +static void spu_backing_privcntl_write(struct spu_context *ctx, u64 val) +{ + ctx->csa.priv2.spu_privcntl_RW = val; +} + static u32 spu_backing_runcntl_read(struct spu_context *ctx) { return ctx->csa.prob.spu_runcntl_RW; @@ -384,6 +389,7 @@ struct spu_context_ops spu_backing_ops = { .npc_write = spu_backing_npc_write, .status_read = spu_backing_status_read, .get_ls = spu_backing_get_ls, + .privcntl_write = spu_backing_privcntl_write, .runcntl_read = spu_backing_runcntl_read, .runcntl_write = spu_backing_runcntl_write, .runcntl_stop = spu_backing_runcntl_stop, diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c index e09616733c..a7767e3b08 100644 --- a/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -206,6 +206,11 @@ static char *spu_hw_get_ls(struct spu_context *ctx) return ctx->spu->local_store; } +static void spu_hw_privcntl_write(struct spu_context *ctx, u64 val) +{ + out_be64(&ctx->spu->priv2->spu_privcntl_RW, val); +} + static u32 spu_hw_runcntl_read(struct spu_context *ctx) { return in_be32(&ctx->spu->problem->spu_runcntl_RW); @@ -215,7 +220,8 @@ static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val) { spin_lock_irq(&ctx->spu->register_lock); if (val & SPU_RUNCNTL_ISOLATE) - out_be64(&ctx->spu->priv2->spu_privcntl_RW, 4LL); + spu_hw_privcntl_write(ctx, + SPU_PRIVCNT_LOAD_REQUEST_ENABLE_MASK); out_be32(&ctx->spu->problem->spu_runcntl_RW, val); spin_unlock_irq(&ctx->spu->register_lock); } @@ -328,6 +334,7 @@ struct spu_context_ops spu_hw_ops = { .npc_write = spu_hw_npc_write, .status_read = spu_hw_status_read, .get_ls = spu_hw_get_ls, + .privcntl_write = spu_hw_privcntl_write, .runcntl_read = spu_hw_runcntl_read, .runcntl_write = spu_hw_runcntl_write, .runcntl_stop = spu_hw_runcntl_stop, diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index aad163ff46..b3cc1dd721 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -128,10 +128,11 @@ out: static int spu_run_init(struct spu_context *ctx, u32 *npc) { + unsigned long runcntl; + spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); if (ctx->flags & SPU_CREATE_ISOLATE) { - unsigned long runcntl; if (!(ctx->ops->status_read(ctx) & SPU_STATUS_ISOLATED_STATE)) { int ret = spu_setup_isolated(ctx); @@ -145,16 +146,21 @@ static int spu_run_init(struct spu_context *ctx, u32 *npc) (SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE); if (runcntl == 0) runcntl = SPU_RUNCNTL_RUNNABLE; - ctx->ops->runcntl_write(ctx, runcntl); } else { - unsigned long mode = SPU_PRIVCNTL_MODE_NORMAL; - ctx->ops->npc_write(ctx, *npc); + unsigned long privcntl; + if (test_thread_flag(TIF_SINGLESTEP)) - mode = SPU_PRIVCNTL_MODE_SINGLE_STEP; - out_be64(&ctx->spu->priv2->spu_privcntl_RW, mode); - ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); + privcntl = SPU_PRIVCNTL_MODE_SINGLE_STEP; + else + privcntl = SPU_PRIVCNTL_MODE_NORMAL; + runcntl = SPU_RUNCNTL_RUNNABLE; + + ctx->ops->npc_write(ctx, *npc); + ctx->ops->privcntl_write(ctx, privcntl); } + ctx->ops->runcntl_write(ctx, runcntl); + spuctx_switch_state(ctx, SPU_UTIL_USER); return 0; diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index fcab1504f1..afdddbc8cf 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -169,6 +169,7 @@ struct spu_context_ops { void (*npc_write) (struct spu_context * ctx, u32 data); u32(*status_read) (struct spu_context * ctx); char*(*get_ls) (struct spu_context * ctx); + void (*privcntl_write) (struct spu_context *ctx, u64 data); u32 (*runcntl_read) (struct spu_context * ctx); void (*runcntl_write) (struct spu_context * ctx, u32 data); void (*runcntl_stop) (struct spu_context * ctx);