aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spufs/file.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2006-01-04 14:31:29 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 23:44:45 -0500
commitce8ab8541203f6c7be5b2eeaa97f14f1d8d44e4f (patch)
treeabdb994ac4ded9a90684f0cdc71ea58e6247ab43 /arch/powerpc/platforms/cell/spufs/file.c
parent8837d9216f99048636fbb2c11347358e99e06181 (diff)
[PATCH] spufs: move spu_run call to its own file
The logic for sys_spu_run keeps growing and it does not really belong into file.c any more since we moved away from using regular file operations to our own syscall. No functional change in here. Signed-off-by: Arnd Bergmann <arndb@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/file.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c152
1 files changed, 0 insertions, 152 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index e63426822fd5..dfa649c9b956 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -304,34 +304,6 @@ static struct file_operations spufs_mbox_stat_fops = {
304 .read = spufs_mbox_stat_read, 304 .read = spufs_mbox_stat_read,
305}; 305};
306 306
307/*
308 * spufs_wait
309 * Same as wait_event_interruptible(), except that here
310 * we need to call spu_release(ctx) before sleeping, and
311 * then spu_acquire(ctx) when awoken.
312 */
313
314#define spufs_wait(wq, condition) \
315({ \
316 int __ret = 0; \
317 DEFINE_WAIT(__wait); \
318 for (;;) { \
319 prepare_to_wait(&(wq), &__wait, TASK_INTERRUPTIBLE); \
320 if (condition) \
321 break; \
322 if (!signal_pending(current)) { \
323 spu_release(ctx); \
324 schedule(); \
325 spu_acquire(ctx); \
326 continue; \
327 } \
328 __ret = -ERESTARTSYS; \
329 break; \
330 } \
331 finish_wait(&(wq), &__wait); \
332 __ret; \
333})
334
335/* low-level ibox access function */ 307/* low-level ibox access function */
336size_t spu_ibox_read(struct spu_context *ctx, u32 *data) 308size_t spu_ibox_read(struct spu_context *ctx, u32 *data)
337{ 309{
@@ -529,130 +501,6 @@ static struct file_operations spufs_wbox_stat_fops = {
529 .read = spufs_wbox_stat_read, 501 .read = spufs_wbox_stat_read,
530}; 502};
531 503
532/* interrupt-level stop callback function. */
533void spufs_stop_callback(struct spu *spu)
534{
535 struct spu_context *ctx = spu->ctx;
536
537 wake_up_all(&ctx->stop_wq);
538}
539
540static inline int spu_stopped(struct spu_context *ctx, u32 * stat)
541{
542 struct spu *spu;
543 u64 pte_fault;
544
545 *stat = ctx->ops->status_read(ctx);
546 if (ctx->state != SPU_STATE_RUNNABLE)
547 return 1;
548 spu = ctx->spu;
549 pte_fault = spu->dsisr &
550 (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED);
551 return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0;
552}
553
554static inline int spu_run_init(struct spu_context *ctx, u32 * npc,
555 u32 * status)
556{
557 int ret;
558
559 if ((ret = spu_acquire_runnable(ctx)) != 0)
560 return ret;
561 ctx->ops->npc_write(ctx, *npc);
562 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE);
563 return 0;
564}
565
566static inline int spu_run_fini(struct spu_context *ctx, u32 * npc,
567 u32 * status)
568{
569 int ret = 0;
570
571 *status = ctx->ops->status_read(ctx);
572 *npc = ctx->ops->npc_read(ctx);
573 spu_release(ctx);
574
575 if (signal_pending(current))
576 ret = -ERESTARTSYS;
577 if (unlikely(current->ptrace & PT_PTRACED)) {
578 if ((*status & SPU_STATUS_STOPPED_BY_STOP)
579 && (*status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) {
580 force_sig(SIGTRAP, current);
581 ret = -ERESTARTSYS;
582 }
583 }
584 return ret;
585}
586
587static inline int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc,
588 u32 *status)
589{
590 int ret;
591
592 if ((ret = spu_run_fini(ctx, npc, status)) != 0)
593 return ret;
594 if (*status & (SPU_STATUS_STOPPED_BY_STOP |
595 SPU_STATUS_STOPPED_BY_HALT)) {
596 return *status;
597 }
598 if ((ret = spu_run_init(ctx, npc, status)) != 0)
599 return ret;
600 return 0;
601}
602
603static inline int spu_process_events(struct spu_context *ctx)
604{
605 struct spu *spu = ctx->spu;
606 u64 pte_fault = MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED;
607 int ret = 0;
608
609 if (spu->dsisr & pte_fault)
610 ret = spu_irq_class_1_bottom(spu);
611 if (spu->class_0_pending)
612 ret = spu_irq_class_0_bottom(spu);
613 if (!ret && signal_pending(current))
614 ret = -ERESTARTSYS;
615 return ret;
616}
617
618long spufs_run_spu(struct file *file, struct spu_context *ctx,
619 u32 * npc, u32 * status)
620{
621 int ret;
622
623 if (down_interruptible(&ctx->run_sema))
624 return -ERESTARTSYS;
625
626 ret = spu_run_init(ctx, npc, status);
627 if (ret)
628 goto out;
629
630 do {
631 ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status));
632 if (unlikely(ret))
633 break;
634 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
635 ret = spu_reacquire_runnable(ctx, npc, status);
636 if (ret)
637 goto out;
638 continue;
639 }
640 ret = spu_process_events(ctx);
641
642 } while (!ret && !(*status & (SPU_STATUS_STOPPED_BY_STOP |
643 SPU_STATUS_STOPPED_BY_HALT)));
644
645 ctx->ops->runcntl_stop(ctx);
646 ret = spu_run_fini(ctx, npc, status);
647 if (!ret)
648 ret = *status;
649 spu_yield(ctx);
650
651out:
652 up(&ctx->run_sema);
653 return ret;
654}
655
656static ssize_t spufs_signal1_read(struct file *file, char __user *buf, 504static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
657 size_t len, loff_t *pos) 505 size_t len, loff_t *pos)
658{ 506{