diff options
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/backing_ops.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/file.c | 133 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 9 | ||||
-rw-r--r-- | include/asm-powerpc/Kbuild | 1 | ||||
-rw-r--r-- | include/asm-powerpc/spu_info.h | 54 |
5 files changed, 192 insertions, 6 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c index 2d22cd59d6fc..21b28f61b00f 100644 --- a/arch/powerpc/platforms/cell/spufs/backing_ops.c +++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <asm/io.h> | 36 | #include <asm/io.h> |
37 | #include <asm/spu.h> | 37 | #include <asm/spu.h> |
38 | #include <asm/spu_csa.h> | 38 | #include <asm/spu_csa.h> |
39 | #include <asm/spu_info.h> | ||
39 | #include <asm/mmu_context.h> | 40 | #include <asm/mmu_context.h> |
40 | #include "spufs.h" | 41 | #include "spufs.h" |
41 | 42 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 7f1262706671..5bfabffd117e 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/io.h> | 32 | #include <asm/io.h> |
33 | #include <asm/semaphore.h> | 33 | #include <asm/semaphore.h> |
34 | #include <asm/spu.h> | 34 | #include <asm/spu.h> |
35 | #include <asm/spu_info.h> | ||
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
36 | 37 | ||
37 | #include "spufs.h" | 38 | #include "spufs.h" |
@@ -1482,6 +1483,23 @@ static u64 spufs_event_mask_get(void *data) | |||
1482 | DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, | 1483 | DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, |
1483 | spufs_event_mask_set, "0x%llx\n") | 1484 | spufs_event_mask_set, "0x%llx\n") |
1484 | 1485 | ||
1486 | static u64 spufs_event_status_get(void *data) | ||
1487 | { | ||
1488 | struct spu_context *ctx = data; | ||
1489 | struct spu_state *state = &ctx->csa; | ||
1490 | u64 ret = 0; | ||
1491 | u64 stat; | ||
1492 | |||
1493 | spu_acquire_saved(ctx); | ||
1494 | stat = state->spu_chnlcnt_RW[0]; | ||
1495 | if (stat) | ||
1496 | ret = state->spu_chnldata_RW[0]; | ||
1497 | spu_release(ctx); | ||
1498 | return ret; | ||
1499 | } | ||
1500 | DEFINE_SIMPLE_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get, | ||
1501 | NULL, "0x%llx\n") | ||
1502 | |||
1485 | static void spufs_srr0_set(void *data, u64 val) | 1503 | static void spufs_srr0_set(void *data, u64 val) |
1486 | { | 1504 | { |
1487 | struct spu_context *ctx = data; | 1505 | struct spu_context *ctx = data; |
@@ -1535,6 +1553,109 @@ static void spufs_object_id_set(void *data, u64 id) | |||
1535 | DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get, | 1553 | DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get, |
1536 | spufs_object_id_set, "0x%llx\n"); | 1554 | spufs_object_id_set, "0x%llx\n"); |
1537 | 1555 | ||
1556 | static u64 spufs_lslr_get(void *data) | ||
1557 | { | ||
1558 | struct spu_context *ctx = data; | ||
1559 | u64 ret; | ||
1560 | |||
1561 | spu_acquire_saved(ctx); | ||
1562 | ret = ctx->csa.priv2.spu_lslr_RW; | ||
1563 | spu_release(ctx); | ||
1564 | |||
1565 | return ret; | ||
1566 | } | ||
1567 | DEFINE_SIMPLE_ATTRIBUTE(spufs_lslr_ops, spufs_lslr_get, NULL, "0x%llx\n") | ||
1568 | |||
1569 | static int spufs_info_open(struct inode *inode, struct file *file) | ||
1570 | { | ||
1571 | struct spufs_inode_info *i = SPUFS_I(inode); | ||
1572 | struct spu_context *ctx = i->i_ctx; | ||
1573 | file->private_data = ctx; | ||
1574 | return 0; | ||
1575 | } | ||
1576 | |||
1577 | static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, | ||
1578 | size_t len, loff_t *pos) | ||
1579 | { | ||
1580 | struct spu_context *ctx = file->private_data; | ||
1581 | struct spu_dma_info info; | ||
1582 | struct mfc_cq_sr *qp, *spuqp; | ||
1583 | int i; | ||
1584 | |||
1585 | if (!access_ok(VERIFY_WRITE, buf, len)) | ||
1586 | return -EFAULT; | ||
1587 | |||
1588 | spu_acquire_saved(ctx); | ||
1589 | spin_lock(&ctx->csa.register_lock); | ||
1590 | info.dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW; | ||
1591 | info.dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0]; | ||
1592 | info.dma_info_status = ctx->csa.spu_chnldata_RW[24]; | ||
1593 | info.dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25]; | ||
1594 | info.dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27]; | ||
1595 | for (i = 0; i < 16; i++) { | ||
1596 | qp = &info.dma_info_command_data[i]; | ||
1597 | spuqp = &ctx->csa.priv2.spuq[i]; | ||
1598 | |||
1599 | qp->mfc_cq_data0_RW = spuqp->mfc_cq_data0_RW; | ||
1600 | qp->mfc_cq_data1_RW = spuqp->mfc_cq_data1_RW; | ||
1601 | qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW; | ||
1602 | qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW; | ||
1603 | } | ||
1604 | spin_unlock(&ctx->csa.register_lock); | ||
1605 | spu_release(ctx); | ||
1606 | |||
1607 | return simple_read_from_buffer(buf, len, pos, &info, | ||
1608 | sizeof info); | ||
1609 | } | ||
1610 | |||
1611 | static struct file_operations spufs_dma_info_fops = { | ||
1612 | .open = spufs_info_open, | ||
1613 | .read = spufs_dma_info_read, | ||
1614 | }; | ||
1615 | |||
1616 | static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, | ||
1617 | size_t len, loff_t *pos) | ||
1618 | { | ||
1619 | struct spu_context *ctx = file->private_data; | ||
1620 | struct spu_proxydma_info info; | ||
1621 | int ret = sizeof info; | ||
1622 | struct mfc_cq_sr *qp, *puqp; | ||
1623 | int i; | ||
1624 | |||
1625 | if (len < ret) | ||
1626 | return -EINVAL; | ||
1627 | |||
1628 | if (!access_ok(VERIFY_WRITE, buf, len)) | ||
1629 | return -EFAULT; | ||
1630 | |||
1631 | spu_acquire_saved(ctx); | ||
1632 | spin_lock(&ctx->csa.register_lock); | ||
1633 | info.proxydma_info_type = ctx->csa.prob.dma_querytype_RW; | ||
1634 | info.proxydma_info_mask = ctx->csa.prob.dma_querymask_RW; | ||
1635 | info.proxydma_info_status = ctx->csa.prob.dma_tagstatus_R; | ||
1636 | for (i = 0; i < 8; i++) { | ||
1637 | qp = &info.proxydma_info_command_data[i]; | ||
1638 | puqp = &ctx->csa.priv2.puq[i]; | ||
1639 | |||
1640 | qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW; | ||
1641 | qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW; | ||
1642 | qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW; | ||
1643 | qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW; | ||
1644 | } | ||
1645 | spin_unlock(&ctx->csa.register_lock); | ||
1646 | spu_release(ctx); | ||
1647 | |||
1648 | if (copy_to_user(buf, &info, sizeof info)) | ||
1649 | ret = -EFAULT; | ||
1650 | |||
1651 | return ret; | ||
1652 | } | ||
1653 | |||
1654 | static struct file_operations spufs_proxydma_info_fops = { | ||
1655 | .open = spufs_info_open, | ||
1656 | .read = spufs_proxydma_info_read, | ||
1657 | }; | ||
1658 | |||
1538 | struct tree_descr spufs_dir_contents[] = { | 1659 | struct tree_descr spufs_dir_contents[] = { |
1539 | { "mem", &spufs_mem_fops, 0666, }, | 1660 | { "mem", &spufs_mem_fops, 0666, }, |
1540 | { "regs", &spufs_regs_fops, 0666, }, | 1661 | { "regs", &spufs_regs_fops, 0666, }, |
@@ -1548,19 +1669,23 @@ struct tree_descr spufs_dir_contents[] = { | |||
1548 | { "signal2", &spufs_signal2_fops, 0666, }, | 1669 | { "signal2", &spufs_signal2_fops, 0666, }, |
1549 | { "signal1_type", &spufs_signal1_type, 0666, }, | 1670 | { "signal1_type", &spufs_signal1_type, 0666, }, |
1550 | { "signal2_type", &spufs_signal2_type, 0666, }, | 1671 | { "signal2_type", &spufs_signal2_type, 0666, }, |
1551 | { "mss", &spufs_mss_fops, 0666, }, | ||
1552 | { "mfc", &spufs_mfc_fops, 0666, }, | ||
1553 | { "cntl", &spufs_cntl_fops, 0666, }, | 1672 | { "cntl", &spufs_cntl_fops, 0666, }, |
1554 | { "npc", &spufs_npc_ops, 0666, }, | ||
1555 | { "fpcr", &spufs_fpcr_fops, 0666, }, | 1673 | { "fpcr", &spufs_fpcr_fops, 0666, }, |
1674 | { "lslr", &spufs_lslr_ops, 0444, }, | ||
1675 | { "mfc", &spufs_mfc_fops, 0666, }, | ||
1676 | { "mss", &spufs_mss_fops, 0666, }, | ||
1677 | { "npc", &spufs_npc_ops, 0666, }, | ||
1678 | { "srr0", &spufs_srr0_ops, 0666, }, | ||
1556 | { "decr", &spufs_decr_ops, 0666, }, | 1679 | { "decr", &spufs_decr_ops, 0666, }, |
1557 | { "decr_status", &spufs_decr_status_ops, 0666, }, | 1680 | { "decr_status", &spufs_decr_status_ops, 0666, }, |
1558 | { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, | 1681 | { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, |
1559 | { "event_mask", &spufs_event_mask_ops, 0666, }, | 1682 | { "event_mask", &spufs_event_mask_ops, 0666, }, |
1560 | { "srr0", &spufs_srr0_ops, 0666, }, | 1683 | { "event_status", &spufs_event_status_ops, 0444, }, |
1561 | { "psmap", &spufs_psmap_fops, 0666, }, | 1684 | { "psmap", &spufs_psmap_fops, 0666, }, |
1562 | { "phys-id", &spufs_id_ops, 0666, }, | 1685 | { "phys-id", &spufs_id_ops, 0666, }, |
1563 | { "object-id", &spufs_object_id_ops, 0666, }, | 1686 | { "object-id", &spufs_object_id_ops, 0666, }, |
1687 | { "dma_info", &spufs_dma_info_fops, 0444, }, | ||
1688 | { "proxydma_info", &spufs_proxydma_info_fops, 0444, }, | ||
1564 | {}, | 1689 | {}, |
1565 | }; | 1690 | }; |
1566 | 1691 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index f438f0b8525d..3e7cfc246147 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <asm/spu.h> | 30 | #include <asm/spu.h> |
31 | #include <asm/spu_csa.h> | 31 | #include <asm/spu_csa.h> |
32 | #include <asm/spu_info.h> | ||
32 | 33 | ||
33 | /* The magic number for our file system */ | 34 | /* The magic number for our file system */ |
34 | enum { | 35 | enum { |
@@ -119,8 +120,12 @@ struct spu_context_ops { | |||
119 | int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); | 120 | int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); |
120 | u32 (*read_mfc_tagstatus)(struct spu_context * ctx); | 121 | u32 (*read_mfc_tagstatus)(struct spu_context * ctx); |
121 | u32 (*get_mfc_free_elements)(struct spu_context *ctx); | 122 | u32 (*get_mfc_free_elements)(struct spu_context *ctx); |
122 | int (*send_mfc_command)(struct spu_context *ctx, | 123 | int (*send_mfc_command)(struct spu_context * ctx, |
123 | struct mfc_dma_command *cmd); | 124 | struct mfc_dma_command * cmd); |
125 | void (*dma_info_read) (struct spu_context * ctx, | ||
126 | struct spu_dma_info * info); | ||
127 | void (*proxydma_info_read) (struct spu_context * ctx, | ||
128 | struct spu_proxydma_info * info); | ||
124 | }; | 129 | }; |
125 | 130 | ||
126 | extern struct spu_context_ops spu_hw_ops; | 131 | extern struct spu_context_ops spu_hw_ops; |
diff --git a/include/asm-powerpc/Kbuild b/include/asm-powerpc/Kbuild index 9827849953a3..1e637381c118 100644 --- a/include/asm-powerpc/Kbuild +++ b/include/asm-powerpc/Kbuild | |||
@@ -17,6 +17,7 @@ header-y += ipc.h | |||
17 | header-y += poll.h | 17 | header-y += poll.h |
18 | header-y += shmparam.h | 18 | header-y += shmparam.h |
19 | header-y += sockios.h | 19 | header-y += sockios.h |
20 | header-y += spu_info.h | ||
20 | header-y += ucontext.h | 21 | header-y += ucontext.h |
21 | header-y += ioctl.h | 22 | header-y += ioctl.h |
22 | header-y += linkage.h | 23 | header-y += linkage.h |
diff --git a/include/asm-powerpc/spu_info.h b/include/asm-powerpc/spu_info.h new file mode 100644 index 000000000000..3545efbf9891 --- /dev/null +++ b/include/asm-powerpc/spu_info.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * SPU info structures | ||
3 | * | ||
4 | * (C) Copyright 2006 IBM Corp. | ||
5 | * | ||
6 | * Author: Dwayne Grant McConnell <decimal@us.ibm.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #ifndef _SPU_INFO_H | ||
24 | #define _SPU_INFO_H | ||
25 | |||
26 | #ifdef __KERNEL__ | ||
27 | #include <asm/spu.h> | ||
28 | #include <linux/types.h> | ||
29 | #else | ||
30 | struct mfc_cq_sr { | ||
31 | __u64 mfc_cq_data0_RW; | ||
32 | __u64 mfc_cq_data1_RW; | ||
33 | __u64 mfc_cq_data2_RW; | ||
34 | __u64 mfc_cq_data3_RW; | ||
35 | }; | ||
36 | #endif /* __KERNEL__ */ | ||
37 | |||
38 | struct spu_dma_info { | ||
39 | __u64 dma_info_type; | ||
40 | __u64 dma_info_mask; | ||
41 | __u64 dma_info_status; | ||
42 | __u64 dma_info_stall_and_notify; | ||
43 | __u64 dma_info_atomic_command_status; | ||
44 | struct mfc_cq_sr dma_info_command_data[16]; | ||
45 | }; | ||
46 | |||
47 | struct spu_proxydma_info { | ||
48 | __u64 proxydma_info_type; | ||
49 | __u64 proxydma_info_mask; | ||
50 | __u64 proxydma_info_status; | ||
51 | struct mfc_cq_sr proxydma_info_command_data[8]; | ||
52 | }; | ||
53 | |||
54 | #endif | ||