aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spufs/hw_ops.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2006-11-20 18:45:08 +0100
committerPaul Mackerras <paulus@samba.org>2006-12-04 20:40:02 +1100
commitee2d7340cbf3b123e1c3b7454f3e2b7e65d33bb2 (patch)
tree2953689e0efdb35195e46c75148bfb91030f71fa /arch/powerpc/platforms/cell/spufs/hw_ops.c
parent[POWERPC] spufs: Fix return value of spufs_mfc_write (diff)
downloadlinux-dev-ee2d7340cbf3b123e1c3b7454f3e2b7e65d33bb2.tar.xz
linux-dev-ee2d7340cbf3b123e1c3b7454f3e2b7e65d33bb2.zip
[POWERPC] spufs: Use SPU master control to prevent wild SPU execution
When the user changes the runcontrol register, an SPU might be running without a process being attached to it and waiting for events. In order to prevent this, make sure we always disable the priv1 master control when we're not inside of spu_run. Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/hw_ops.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/hw_ops.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
index 79c304e815a1..69fc342e063d 100644
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -216,13 +216,26 @@ static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val)
spin_unlock_irq(&ctx->spu->register_lock);
}
-static void spu_hw_runcntl_stop(struct spu_context *ctx)
+static void spu_hw_master_start(struct spu_context *ctx)
{
- spin_lock_irq(&ctx->spu->register_lock);
- out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP);
- while (in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING)
- cpu_relax();
- spin_unlock_irq(&ctx->spu->register_lock);
+ struct spu *spu = ctx->spu;
+ u64 sr1;
+
+ spin_lock_irq(&spu->register_lock);
+ sr1 = spu_mfc_sr1_get(spu) | MFC_STATE1_MASTER_RUN_CONTROL_MASK;
+ spu_mfc_sr1_set(spu, sr1);
+ spin_unlock_irq(&spu->register_lock);
+}
+
+static void spu_hw_master_stop(struct spu_context *ctx)
+{
+ struct spu *spu = ctx->spu;
+ u64 sr1;
+
+ spin_lock_irq(&spu->register_lock);
+ sr1 = spu_mfc_sr1_get(spu) & ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
+ spu_mfc_sr1_set(spu, sr1);
+ spin_unlock_irq(&spu->register_lock);
}
static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode)
@@ -295,7 +308,8 @@ struct spu_context_ops spu_hw_ops = {
.status_read = spu_hw_status_read,
.get_ls = spu_hw_get_ls,
.runcntl_write = spu_hw_runcntl_write,
- .runcntl_stop = spu_hw_runcntl_stop,
+ .master_start = spu_hw_master_start,
+ .master_stop = spu_hw_master_stop,
.set_mfc_query = spu_hw_set_mfc_query,
.read_mfc_tagstatus = spu_hw_read_mfc_tagstatus,
.get_mfc_free_elements = spu_hw_get_mfc_free_elements,