#include <asm/io.h>
#include <asm/semaphore.h>
#include <asm/spu.h>
+#include <asm/spu_info.h>
#include <asm/uaccess.h>
#include "spufs.h"
if (!(vma->vm_flags & VM_SHARED))
return -EINVAL;
- /* FIXME: */
+ vma->vm_flags |= VM_IO;
vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
| _PAGE_NO_CACHE);
if (!(vma->vm_flags & VM_SHARED))
return -EINVAL;
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_IO;
vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
| _PAGE_NO_CACHE | _PAGE_GUARDED);
size_t len, loff_t *pos)
{
struct spu_context *ctx = file->private_data;
+ int ret = 0;
u32 data;
if (len < 4)
return -EINVAL;
- spu_acquire(ctx);
- data = ctx->ops->signal1_read(ctx);
+ spu_acquire_saved(ctx);
+ if (ctx->csa.spu_chnlcnt_RW[3]) {
+ data = ctx->csa.spu_chnldata_RW[3];
+ ret = 4;
+ }
spu_release(ctx);
+ if (!ret)
+ goto out;
+
if (copy_to_user(buf, &data, 4))
return -EFAULT;
- return 4;
+out:
+ return ret;
}
static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
if (!(vma->vm_flags & VM_SHARED))
return -EINVAL;
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_IO;
vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
| _PAGE_NO_CACHE | _PAGE_GUARDED);
static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
size_t len, loff_t *pos)
{
- struct spu_context *ctx;
+ struct spu_context *ctx = file->private_data;
+ int ret = 0;
u32 data;
- ctx = file->private_data;
-
if (len < 4)
return -EINVAL;
- spu_acquire(ctx);
- data = ctx->ops->signal2_read(ctx);
+ spu_acquire_saved(ctx);
+ if (ctx->csa.spu_chnlcnt_RW[4]) {
+ data = ctx->csa.spu_chnldata_RW[4];
+ ret = 4;
+ }
spu_release(ctx);
+ if (!ret)
+ goto out;
+
if (copy_to_user(buf, &data, 4))
return -EFAULT;
+out:
return 4;
}
if (!(vma->vm_flags & VM_SHARED))
return -EINVAL;
- /* FIXME: */
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_IO;
vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
| _PAGE_NO_CACHE | _PAGE_GUARDED);
if (!(vma->vm_flags & VM_SHARED))
return -EINVAL;
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_IO;
vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
| _PAGE_NO_CACHE | _PAGE_GUARDED);
if (!(vma->vm_flags & VM_SHARED))
return -EINVAL;
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_IO;
vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
| _PAGE_NO_CACHE | _PAGE_GUARDED);
if (!(vma->vm_flags & VM_SHARED))
return -EINVAL;
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_IO;
vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
| _PAGE_NO_CACHE | _PAGE_GUARDED);
.mmap = spufs_mfc_mmap,
};
+
+static int spufs_recycle_open(struct inode *inode, struct file *file)
+{
+ file->private_data = SPUFS_I(inode)->i_ctx;
+ return nonseekable_open(inode, file);
+}
+
+static ssize_t spufs_recycle_write(struct file *file,
+ const char __user *buffer, size_t size, loff_t *pos)
+{
+ struct spu_context *ctx = file->private_data;
+ int ret;
+
+ if (!(ctx->flags & SPU_CREATE_ISOLATE))
+ return -EINVAL;
+
+ if (size < 1)
+ return -EINVAL;
+
+ ret = spu_recycle_isolated(ctx);
+
+ if (ret)
+ return ret;
+ return size;
+}
+
+static struct file_operations spufs_recycle_fops = {
+ .open = spufs_recycle_open,
+ .write = spufs_recycle_write,
+};
+
static void spufs_npc_set(void *data, u64 val)
{
struct spu_context *ctx = data;
spu_release(ctx);
return ret;
}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, "%llx\n")
+DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set,
+ "0x%llx\n")
static void spufs_decr_set(void *data, u64 val)
{
return ret;
}
DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
- "%llx\n")
+ "0x%llx\n")
static void spufs_decr_status_set(void *data, u64 val)
{
return ret;
}
DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get,
- spufs_decr_status_set, "%llx\n")
+ spufs_decr_status_set, "0x%llx\n")
-static void spufs_spu_tag_mask_set(void *data, u64 val)
+static void spufs_event_mask_set(void *data, u64 val)
{
struct spu_context *ctx = data;
struct spu_lscsa *lscsa = ctx->csa.lscsa;
spu_acquire_saved(ctx);
- lscsa->tag_mask.slot[0] = (u32) val;
+ lscsa->event_mask.slot[0] = (u32) val;
spu_release(ctx);
}
-static u64 spufs_spu_tag_mask_get(void *data)
+static u64 spufs_event_mask_get(void *data)
{
struct spu_context *ctx = data;
struct spu_lscsa *lscsa = ctx->csa.lscsa;
u64 ret;
spu_acquire_saved(ctx);
- ret = lscsa->tag_mask.slot[0];
+ ret = lscsa->event_mask.slot[0];
spu_release(ctx);
return ret;
}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_spu_tag_mask_ops, spufs_spu_tag_mask_get,
- spufs_spu_tag_mask_set, "%llx\n")
+DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
+ spufs_event_mask_set, "0x%llx\n")
-static void spufs_event_mask_set(void *data, u64 val)
+static u64 spufs_event_status_get(void *data)
{
struct spu_context *ctx = data;
- struct spu_lscsa *lscsa = ctx->csa.lscsa;
- spu_acquire_saved(ctx);
- lscsa->event_mask.slot[0] = (u32) val;
- spu_release(ctx);
-}
+ struct spu_state *state = &ctx->csa;
+ u64 ret = 0;
+ u64 stat;
-static u64 spufs_event_mask_get(void *data)
-{
- struct spu_context *ctx = data;
- struct spu_lscsa *lscsa = ctx->csa.lscsa;
- u64 ret;
spu_acquire_saved(ctx);
- ret = lscsa->event_mask.slot[0];
+ stat = state->spu_chnlcnt_RW[0];
+ if (stat)
+ ret = state->spu_chnldata_RW[0];
spu_release(ctx);
return ret;
}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
- spufs_event_mask_set, "%llx\n")
+DEFINE_SIMPLE_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get,
+ NULL, "0x%llx\n")
static void spufs_srr0_set(void *data, u64 val)
{
return ret;
}
DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set,
- "%llx\n")
+ "0x%llx\n")
static u64 spufs_id_get(void *data)
{
DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get,
spufs_object_id_set, "0x%llx\n");
+static u64 spufs_lslr_get(void *data)
+{
+ struct spu_context *ctx = data;
+ u64 ret;
+
+ spu_acquire_saved(ctx);
+ ret = ctx->csa.priv2.spu_lslr_RW;
+ spu_release(ctx);
+
+ return ret;
+}
+DEFINE_SIMPLE_ATTRIBUTE(spufs_lslr_ops, spufs_lslr_get, NULL, "0x%llx\n")
+
+static int spufs_info_open(struct inode *inode, struct file *file)
+{
+ struct spufs_inode_info *i = SPUFS_I(inode);
+ struct spu_context *ctx = i->i_ctx;
+ file->private_data = ctx;
+ return 0;
+}
+
+static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf,
+ size_t len, loff_t *pos)
+{
+ struct spu_context *ctx = file->private_data;
+ u32 mbox_stat;
+ u32 data;
+
+ if (!access_ok(VERIFY_WRITE, buf, len))
+ return -EFAULT;
+
+ spu_acquire_saved(ctx);
+ spin_lock(&ctx->csa.register_lock);
+ mbox_stat = ctx->csa.prob.mb_stat_R;
+ if (mbox_stat & 0x0000ff) {
+ data = ctx->csa.prob.pu_mb_R;
+ }
+ spin_unlock(&ctx->csa.register_lock);
+ spu_release(ctx);
+
+ return simple_read_from_buffer(buf, len, pos, &data, sizeof data);
+}
+
+static struct file_operations spufs_mbox_info_fops = {
+ .open = spufs_info_open,
+ .read = spufs_mbox_info_read,
+ .llseek = generic_file_llseek,
+};
+
+static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf,
+ size_t len, loff_t *pos)
+{
+ struct spu_context *ctx = file->private_data;
+ u32 ibox_stat;
+ u32 data;
+
+ if (!access_ok(VERIFY_WRITE, buf, len))
+ return -EFAULT;
+
+ spu_acquire_saved(ctx);
+ spin_lock(&ctx->csa.register_lock);
+ ibox_stat = ctx->csa.prob.mb_stat_R;
+ if (ibox_stat & 0xff0000) {
+ data = ctx->csa.priv2.puint_mb_R;
+ }
+ spin_unlock(&ctx->csa.register_lock);
+ spu_release(ctx);
+
+ return simple_read_from_buffer(buf, len, pos, &data, sizeof data);
+}
+
+static struct file_operations spufs_ibox_info_fops = {
+ .open = spufs_info_open,
+ .read = spufs_ibox_info_read,
+ .llseek = generic_file_llseek,
+};
+
+static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf,
+ size_t len, loff_t *pos)
+{
+ struct spu_context *ctx = file->private_data;
+ int i, cnt;
+ u32 data[4];
+ u32 wbox_stat;
+
+ if (!access_ok(VERIFY_WRITE, buf, len))
+ return -EFAULT;
+
+ spu_acquire_saved(ctx);
+ spin_lock(&ctx->csa.register_lock);
+ wbox_stat = ctx->csa.prob.mb_stat_R;
+ cnt = (wbox_stat & 0x00ff00) >> 8;
+ for (i = 0; i < cnt; i++) {
+ data[i] = ctx->csa.spu_mailbox_data[i];
+ }
+ spin_unlock(&ctx->csa.register_lock);
+ spu_release(ctx);
+
+ return simple_read_from_buffer(buf, len, pos, &data,
+ cnt * sizeof(u32));
+}
+
+static struct file_operations spufs_wbox_info_fops = {
+ .open = spufs_info_open,
+ .read = spufs_wbox_info_read,
+ .llseek = generic_file_llseek,
+};
+
+static ssize_t spufs_dma_info_read(struct file *file, char __user *buf,
+ size_t len, loff_t *pos)
+{
+ struct spu_context *ctx = file->private_data;
+ struct spu_dma_info info;
+ struct mfc_cq_sr *qp, *spuqp;
+ int i;
+
+ if (!access_ok(VERIFY_WRITE, buf, len))
+ return -EFAULT;
+
+ spu_acquire_saved(ctx);
+ spin_lock(&ctx->csa.register_lock);
+ info.dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW;
+ info.dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0];
+ info.dma_info_status = ctx->csa.spu_chnldata_RW[24];
+ info.dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25];
+ info.dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27];
+ for (i = 0; i < 16; i++) {
+ qp = &info.dma_info_command_data[i];
+ spuqp = &ctx->csa.priv2.spuq[i];
+
+ qp->mfc_cq_data0_RW = spuqp->mfc_cq_data0_RW;
+ qp->mfc_cq_data1_RW = spuqp->mfc_cq_data1_RW;
+ qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW;
+ qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW;
+ }
+ spin_unlock(&ctx->csa.register_lock);
+ spu_release(ctx);
+
+ return simple_read_from_buffer(buf, len, pos, &info,
+ sizeof info);
+}
+
+static struct file_operations spufs_dma_info_fops = {
+ .open = spufs_info_open,
+ .read = spufs_dma_info_read,
+};
+
+static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf,
+ size_t len, loff_t *pos)
+{
+ struct spu_context *ctx = file->private_data;
+ struct spu_proxydma_info info;
+ int ret = sizeof info;
+ struct mfc_cq_sr *qp, *puqp;
+ int i;
+
+ if (len < ret)
+ return -EINVAL;
+
+ if (!access_ok(VERIFY_WRITE, buf, len))
+ return -EFAULT;
+
+ spu_acquire_saved(ctx);
+ spin_lock(&ctx->csa.register_lock);
+ info.proxydma_info_type = ctx->csa.prob.dma_querytype_RW;
+ info.proxydma_info_mask = ctx->csa.prob.dma_querymask_RW;
+ info.proxydma_info_status = ctx->csa.prob.dma_tagstatus_R;
+ for (i = 0; i < 8; i++) {
+ qp = &info.proxydma_info_command_data[i];
+ puqp = &ctx->csa.priv2.puq[i];
+
+ qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW;
+ qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW;
+ qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW;
+ qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW;
+ }
+ spin_unlock(&ctx->csa.register_lock);
+ spu_release(ctx);
+
+ if (copy_to_user(buf, &info, sizeof info))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static struct file_operations spufs_proxydma_info_fops = {
+ .open = spufs_info_open,
+ .read = spufs_proxydma_info_read,
+};
+
struct tree_descr spufs_dir_contents[] = {
{ "mem", &spufs_mem_fops, 0666, },
{ "regs", &spufs_regs_fops, 0666, },
{ "signal2", &spufs_signal2_fops, 0666, },
{ "signal1_type", &spufs_signal1_type, 0666, },
{ "signal2_type", &spufs_signal2_type, 0666, },
- { "mss", &spufs_mss_fops, 0666, },
- { "mfc", &spufs_mfc_fops, 0666, },
{ "cntl", &spufs_cntl_fops, 0666, },
- { "npc", &spufs_npc_ops, 0666, },
{ "fpcr", &spufs_fpcr_fops, 0666, },
+ { "lslr", &spufs_lslr_ops, 0444, },
+ { "mfc", &spufs_mfc_fops, 0666, },
+ { "mss", &spufs_mss_fops, 0666, },
+ { "npc", &spufs_npc_ops, 0666, },
+ { "srr0", &spufs_srr0_ops, 0666, },
{ "decr", &spufs_decr_ops, 0666, },
{ "decr_status", &spufs_decr_status_ops, 0666, },
- { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, },
{ "event_mask", &spufs_event_mask_ops, 0666, },
- { "srr0", &spufs_srr0_ops, 0666, },
+ { "event_status", &spufs_event_status_ops, 0444, },
+ { "psmap", &spufs_psmap_fops, 0666, },
+ { "phys-id", &spufs_id_ops, 0666, },
+ { "object-id", &spufs_object_id_ops, 0666, },
+ { "mbox_info", &spufs_mbox_info_fops, 0444, },
+ { "ibox_info", &spufs_ibox_info_fops, 0444, },
+ { "wbox_info", &spufs_wbox_info_fops, 0444, },
+ { "dma_info", &spufs_dma_info_fops, 0444, },
+ { "proxydma_info", &spufs_proxydma_info_fops, 0444, },
+ {},
+};
+
+struct tree_descr spufs_dir_nosched_contents[] = {
+ { "mem", &spufs_mem_fops, 0666, },
+ { "mbox", &spufs_mbox_fops, 0444, },
+ { "ibox", &spufs_ibox_fops, 0444, },
+ { "wbox", &spufs_wbox_fops, 0222, },
+ { "mbox_stat", &spufs_mbox_stat_fops, 0444, },
+ { "ibox_stat", &spufs_ibox_stat_fops, 0444, },
+ { "wbox_stat", &spufs_wbox_stat_fops, 0444, },
+ { "signal1", &spufs_signal1_fops, 0666, },
+ { "signal2", &spufs_signal2_fops, 0666, },
+ { "signal1_type", &spufs_signal1_type, 0666, },
+ { "signal2_type", &spufs_signal2_type, 0666, },
+ { "mss", &spufs_mss_fops, 0666, },
+ { "mfc", &spufs_mfc_fops, 0666, },
+ { "cntl", &spufs_cntl_fops, 0666, },
+ { "npc", &spufs_npc_ops, 0666, },
{ "psmap", &spufs_psmap_fops, 0666, },
{ "phys-id", &spufs_id_ops, 0666, },
{ "object-id", &spufs_object_id_ops, 0666, },
+ { "recycle", &spufs_recycle_fops, 0222, },
{},
};