arch/powerpc/platforms/cell/spufs/run.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/cell/spufs/run.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/cell/spufs/run.c
Extension
.c
Size
10980 bytes
Lines
452
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

switch(irq) {
		case 0 :
			ctx->csa.class_0_pending = spu->class_0_pending;
			ctx->csa.class_0_dar = spu->class_0_dar;
			break;
		case 1 :
			ctx->csa.class_1_dsisr = spu->class_1_dsisr;
			ctx->csa.class_1_dar = spu->class_1_dar;
			break;
		case 2 :
			break;
		}

		/* ensure that the exception status has hit memory before a
		 * thread waiting on the context's stop queue is woken */
		smp_wmb();

		wake_up_all(&ctx->stop_wq);
	}
}

int spu_stopped(struct spu_context *ctx, u32 *stat)
{
	u64 dsisr;
	u32 stopped;

	stopped = SPU_STATUS_INVALID_INSTR | SPU_STATUS_SINGLE_STEP |
		SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP;

top:
	*stat = ctx->ops->status_read(ctx);
	if (*stat & stopped) {
		/*
		 * If the spu hasn't finished stopping, we need to
		 * re-read the register to get the stopped value.
		 */
		if (*stat & SPU_STATUS_RUNNING)
			goto top;
		return 1;
	}

	if (test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags))
		return 1;

	dsisr = ctx->csa.class_1_dsisr;
	if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))
		return 1;

	if (ctx->csa.class_0_pending)
		return 1;

	return 0;
}

static int spu_setup_isolated(struct spu_context *ctx)
{
	int ret;
	u64 __iomem *mfc_cntl;
	u64 sr1;
	u32 status;
	unsigned long timeout;
	const u32 status_loading = SPU_STATUS_RUNNING
		| SPU_STATUS_ISOLATED_STATE | SPU_STATUS_ISOLATED_LOAD_STATUS;

	ret = -ENODEV;
	if (!isolated_loader)
		goto out;

	/*
	 * We need to exclude userspace access to the context.
	 *
	 * To protect against memory access we invalidate all ptes
	 * and make sure the pagefault handlers block on the mutex.
	 */
	spu_unmap_mappings(ctx);

	mfc_cntl = &ctx->spu->priv2->mfc_control_RW;

	/* purge the MFC DMA queue to ensure no spurious accesses before we
	 * enter kernel mode */
	timeout = jiffies + HZ;
	out_be64(mfc_cntl, MFC_CNTL_PURGE_DMA_REQUEST);
	while ((in_be64(mfc_cntl) & MFC_CNTL_PURGE_DMA_STATUS_MASK)
			!= MFC_CNTL_PURGE_DMA_COMPLETE) {
		if (time_after(jiffies, timeout)) {
			printk(KERN_ERR "%s: timeout flushing MFC DMA queue\n",
					__func__);
			ret = -EIO;
			goto out;
		}

Annotation

Implementation Notes