Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 38990
b: refs/heads/master
c: 9add11d
h: refs/heads/master
v: v3
  • Loading branch information
Arnd Bergmann authored and Paul Mackerras committed Oct 4, 2006
1 parent df433d7 commit 4c96dc5
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 25 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 28347bce8a837258e737873a55d31f2f424a6ea6
refs/heads/master: 9add11daeee2f6d69f6b86237f197824332a4a3b
6 changes: 3 additions & 3 deletions trunk/arch/powerpc/platforms/cell/spu_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,21 @@ EXPORT_SYMBOL_GPL(spu_priv1_ops);
static int __spu_trap_invalid_dma(struct spu *spu)
{
pr_debug("%s\n", __FUNCTION__);
force_sig(SIGBUS, /* info, */ current);
spu->dma_callback(spu, SPE_EVENT_INVALID_DMA);
return 0;
}

static int __spu_trap_dma_align(struct spu *spu)
{
pr_debug("%s\n", __FUNCTION__);
force_sig(SIGBUS, /* info, */ current);
spu->dma_callback(spu, SPE_EVENT_DMA_ALIGNMENT);
return 0;
}

static int __spu_trap_error(struct spu *spu)
{
pr_debug("%s\n", __FUNCTION__);
force_sig(SIGILL, /* info, */ current);
spu->dma_callback(spu, SPE_EVENT_SPE_ERROR);
return 0;
}

Expand Down
9 changes: 6 additions & 3 deletions trunk/arch/powerpc/platforms/cell/spufs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ struct file_operations spufs_context_fops = {
};

static int
spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
int mode)
{
int ret;
struct inode *inode;
Expand All @@ -244,6 +245,8 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (!ctx)
goto out_iput;

ctx->flags = flags;

inode->i_op = &spufs_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx);
Expand Down Expand Up @@ -304,7 +307,7 @@ long spufs_create_thread(struct nameidata *nd,
goto out;

/* all flags are reserved */
if (flags)
if (flags & (~SPU_CREATE_FLAG_ALL))
goto out;

dentry = lookup_create(nd, 1);
Expand All @@ -317,7 +320,7 @@ long spufs_create_thread(struct nameidata *nd,
goto out_dput;

mode &= ~current->fs->umask;
ret = spufs_mkdir(nd->dentry->d_inode, dentry, mode & S_IRWXUGO);
ret = spufs_mkdir(nd->dentry->d_inode, dentry, flags, mode & S_IRWXUGO);
if (ret)
goto out_dput;

Expand Down
48 changes: 35 additions & 13 deletions trunk/arch/powerpc/platforms/cell/spufs/run.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@ void spufs_stop_callback(struct spu *spu)
wake_up_all(&ctx->stop_wq);
}

void spufs_dma_callback(struct spu *spu, int type)
{
struct spu_context *ctx = spu->ctx;

if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) {
ctx->event_return |= type;
wake_up_all(&ctx->stop_wq);
} else {
switch (type) {
case SPE_EVENT_DMA_ALIGNMENT:
case SPE_EVENT_INVALID_DMA:
force_sig(SIGBUS, /* info, */ current);
break;
case SPE_EVENT_SPE_ERROR:
force_sig(SIGILL, /* info */ current);
break;
}
}
}

static inline int spu_stopped(struct spu_context *ctx, u32 * stat)
{
struct spu *spu;
Expand All @@ -28,8 +48,7 @@ static inline int spu_stopped(struct spu_context *ctx, u32 * stat)
return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0;
}

static inline int spu_run_init(struct spu_context *ctx, u32 * npc,
u32 * status)
static inline int spu_run_init(struct spu_context *ctx, u32 * npc)
{
int ret;

Expand Down Expand Up @@ -72,7 +91,7 @@ static inline int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc,
SPU_STATUS_STOPPED_BY_HALT)) {
return *status;
}
if ((ret = spu_run_init(ctx, npc, status)) != 0)
if ((ret = spu_run_init(ctx, npc)) != 0)
return ret;
return 0;
}
Expand Down Expand Up @@ -177,46 +196,49 @@ static inline int spu_process_events(struct spu_context *ctx)
}

long spufs_run_spu(struct file *file, struct spu_context *ctx,
u32 * npc, u32 * status)
u32 *npc, u32 *event)
{
int ret;
u32 status;

if (down_interruptible(&ctx->run_sema))
return -ERESTARTSYS;

ret = spu_run_init(ctx, npc, status);
ctx->event_return = 0;
ret = spu_run_init(ctx, npc);
if (ret)
goto out;

do {
ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status));
ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, &status));
if (unlikely(ret))
break;
if ((*status & SPU_STATUS_STOPPED_BY_STOP) &&
(*status >> SPU_STOP_STATUS_SHIFT == 0x2104)) {
if ((status & SPU_STATUS_STOPPED_BY_STOP) &&
(status >> SPU_STOP_STATUS_SHIFT == 0x2104)) {
ret = spu_process_callback(ctx);
if (ret)
break;
*status &= ~SPU_STATUS_STOPPED_BY_STOP;
status &= ~SPU_STATUS_STOPPED_BY_STOP;
}
if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
ret = spu_reacquire_runnable(ctx, npc, status);
ret = spu_reacquire_runnable(ctx, npc, &status);
if (ret)
goto out;
continue;
}
ret = spu_process_events(ctx);

} while (!ret && !(*status & (SPU_STATUS_STOPPED_BY_STOP |
} while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP |
SPU_STATUS_STOPPED_BY_HALT)));

ctx->ops->runcntl_stop(ctx);
ret = spu_run_fini(ctx, npc, status);
ret = spu_run_fini(ctx, npc, &status);
if (!ret)
ret = *status;
ret = status;
spu_yield(ctx);

out:
*event = ctx->event_return;
up(&ctx->run_sema);
return ret;
}
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/powerpc/platforms/cell/spufs/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ static inline void bind_context(struct spu *spu, struct spu_context *ctx)
spu->number, spu->node);
spu->ctx = ctx;
spu->flags = 0;
ctx->flags = 0;
ctx->spu = spu;
ctx->ops = &spu_hw_ops;
spu->pid = current->pid;
Expand All @@ -92,6 +91,7 @@ static inline void bind_context(struct spu *spu, struct spu_context *ctx)
spu->wbox_callback = spufs_wbox_callback;
spu->stop_callback = spufs_stop_callback;
spu->mfc_callback = spufs_mfc_callback;
spu->dma_callback = spufs_dma_callback;
mb();
spu_unmap_mappings(ctx);
spu_restore(&ctx->csa, spu);
Expand All @@ -111,12 +111,12 @@ static inline void unbind_context(struct spu *spu, struct spu_context *ctx)
spu->wbox_callback = NULL;
spu->stop_callback = NULL;
spu->mfc_callback = NULL;
spu->dma_callback = NULL;
spu->mm = NULL;
spu->pid = 0;
spu->prio = MAX_PRIO;
ctx->ops = &spu_backing_ops;
ctx->spu = NULL;
ctx->flags = 0;
spu->flags = 0;
spu->ctx = NULL;
}
Expand Down
4 changes: 3 additions & 1 deletion trunk/arch/powerpc/platforms/cell/spufs/spufs.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ struct spu_context {
u32 tagwait;
struct spu_context_ops *ops;
struct work_struct reap_work;
u64 flags;
unsigned long flags;
unsigned long event_return;
};

struct mfc_dma_command {
Expand Down Expand Up @@ -183,5 +184,6 @@ void spufs_ibox_callback(struct spu *spu);
void spufs_wbox_callback(struct spu *spu);
void spufs_stop_callback(struct spu *spu);
void spufs_mfc_callback(struct spu *spu);
void spufs_dma_callback(struct spu *spu, int type);

#endif
7 changes: 5 additions & 2 deletions trunk/arch/powerpc/platforms/cell/spufs/syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static long do_spu_run(struct file *filp,
u32 npc, status;

ret = -EFAULT;
if (get_user(npc, unpc) || get_user(status, ustatus))
if (get_user(npc, unpc))
goto out;

/* check if this file was created by spu_create */
Expand All @@ -49,7 +49,10 @@ static long do_spu_run(struct file *filp,
i = SPUFS_I(filp->f_dentry->d_inode);
ret = spufs_run_spu(filp, i->i_ctx, &npc, &status);

if (put_user(npc, unpc) || put_user(status, ustatus))
if (put_user(npc, unpc))
ret = -EFAULT;

if (ustatus && put_user(status, ustatus))
ret = -EFAULT;
out:
return ret;
Expand Down
14 changes: 14 additions & 0 deletions trunk/include/asm-powerpc/spu.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ struct spu {
void (* ibox_callback)(struct spu *spu);
void (* stop_callback)(struct spu *spu);
void (* mfc_callback)(struct spu *spu);
void (* dma_callback)(struct spu *spu, int type);

char irq_c0[8];
char irq_c1[8];
Expand Down Expand Up @@ -169,6 +170,19 @@ extern struct spufs_calls {
struct module *owner;
} spufs_calls;

/* return status from spu_run, same as in libspe */
#define SPE_EVENT_DMA_ALIGNMENT 0x0008 /*A DMA alignment error */
#define SPE_EVENT_SPE_ERROR 0x0010 /*An illegal instruction error*/
#define SPE_EVENT_SPE_DATA_SEGMENT 0x0020 /*A DMA segmentation error */
#define SPE_EVENT_SPE_DATA_STORAGE 0x0040 /*A DMA storage error */
#define SPE_EVENT_INVALID_DMA 0x0800 /* Invalid MFC DMA */

/*
* Flags for sys_spu_create.
*/
#define SPU_CREATE_EVENTS_ENABLED 0x0001
#define SPU_CREATE_FLAG_ALL 0x0001 /* mask of all valid flags */

#ifdef CONFIG_SPU_FS_MODULE
int register_spu_syscalls(struct spufs_calls *calls);
void unregister_spu_syscalls(struct spufs_calls *calls);
Expand Down

0 comments on commit 4c96dc5

Please sign in to comment.