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

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

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/cell/spufs/hw_ops.c
Extension
.c
Size
8751 bytes
Lines
336
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

// SPDX-License-Identifier: GPL-2.0-or-later
/* hw_ops.c - query/set operations on active SPU context.
 *
 * Copyright (C) IBM 2005
 * Author: Mark Nutter <mnutter@us.ibm.com>
 */

#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/smp.h>
#include <linux/stddef.h>
#include <linux/unistd.h>

#include <asm/io.h>
#include <asm/spu.h>
#include <asm/spu_priv1.h>
#include <asm/spu_csa.h>
#include <asm/mmu_context.h>
#include "spufs.h"

static int spu_hw_mbox_read(struct spu_context *ctx, u32 * data)
{
	struct spu *spu = ctx->spu;
	struct spu_problem __iomem *prob = spu->problem;
	u32 mbox_stat;
	int ret = 0;

	spin_lock_irq(&spu->register_lock);
	mbox_stat = in_be32(&prob->mb_stat_R);
	if (mbox_stat & 0x0000ff) {
		*data = in_be32(&prob->pu_mb_R);
		ret = 4;
	}
	spin_unlock_irq(&spu->register_lock);
	return ret;
}

static u32 spu_hw_mbox_stat_read(struct spu_context *ctx)
{
	return in_be32(&ctx->spu->problem->mb_stat_R);
}

static __poll_t spu_hw_mbox_stat_poll(struct spu_context *ctx, __poll_t events)
{
	struct spu *spu = ctx->spu;
	__poll_t ret = 0;
	u32 stat;

	spin_lock_irq(&spu->register_lock);
	stat = in_be32(&spu->problem->mb_stat_R);

	/* if the requested event is there, return the poll
	   mask, otherwise enable the interrupt to get notified,
	   but first mark any pending interrupts as done so
	   we don't get woken up unnecessarily */

	if (events & (EPOLLIN | EPOLLRDNORM)) {
		if (stat & 0xff0000)
			ret |= EPOLLIN | EPOLLRDNORM;
		else {
			spu_int_stat_clear(spu, 2, CLASS2_MAILBOX_INTR);
			spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_INTR);
		}
	}
	if (events & (EPOLLOUT | EPOLLWRNORM)) {
		if (stat & 0x00ff00)
			ret = EPOLLOUT | EPOLLWRNORM;
		else {
			spu_int_stat_clear(spu, 2,
					CLASS2_MAILBOX_THRESHOLD_INTR);
			spu_int_mask_or(spu, 2,
					CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR);
		}
	}
	spin_unlock_irq(&spu->register_lock);
	return ret;
}

static int spu_hw_ibox_read(struct spu_context *ctx, u32 * data)
{
	struct spu *spu = ctx->spu;
	struct spu_problem __iomem *prob = spu->problem;
	struct spu_priv2 __iomem *priv2 = spu->priv2;
	int ret;

	spin_lock_irq(&spu->register_lock);
	if (in_be32(&prob->mb_stat_R) & 0xff0000) {

Annotation

Implementation Notes