Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[POWERPC] spufs: Add /lslr, /dma_info and /proxydma files

The /lslr file gives read access to the SPU_LSLR register in hex; 0x3fff
for example The /dma_info file provides read access to the SPU Command
Queue in a binary format. The /proxydma_info files provides read access
access to the Proxy Command Queue in a binary format. The spu_info.h
file provides data structures for interpreting the binary format of
/dma_info and /proxydma_info.

Signed-off-by: Dwayne Grant McConnell <decimal@us.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>

authored by

Dwayne Grant McConnell and committed by
Paul Mackerras
b9e3bd77 9b5047e2

+192 -6
+1
arch/powerpc/platforms/cell/spufs/backing_ops.c
··· 36 36 #include <asm/io.h> 37 37 #include <asm/spu.h> 38 38 #include <asm/spu_csa.h> 39 + #include <asm/spu_info.h> 39 40 #include <asm/mmu_context.h> 40 41 #include "spufs.h" 41 42
+129 -4
arch/powerpc/platforms/cell/spufs/file.c
··· 32 32 #include <asm/io.h> 33 33 #include <asm/semaphore.h> 34 34 #include <asm/spu.h> 35 + #include <asm/spu_info.h> 35 36 #include <asm/uaccess.h> 36 37 37 38 #include "spufs.h" ··· 1483 1482 DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, 1484 1483 spufs_event_mask_set, "0x%llx\n") 1485 1484 1485 + static u64 spufs_event_status_get(void *data) 1486 + { 1487 + struct spu_context *ctx = data; 1488 + struct spu_state *state = &ctx->csa; 1489 + u64 ret = 0; 1490 + u64 stat; 1491 + 1492 + spu_acquire_saved(ctx); 1493 + stat = state->spu_chnlcnt_RW[0]; 1494 + if (stat) 1495 + ret = state->spu_chnldata_RW[0]; 1496 + spu_release(ctx); 1497 + return ret; 1498 + } 1499 + DEFINE_SIMPLE_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get, 1500 + NULL, "0x%llx\n") 1501 + 1486 1502 static void spufs_srr0_set(void *data, u64 val) 1487 1503 { 1488 1504 struct spu_context *ctx = data; ··· 1553 1535 DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get, 1554 1536 spufs_object_id_set, "0x%llx\n"); 1555 1537 1538 + static u64 spufs_lslr_get(void *data) 1539 + { 1540 + struct spu_context *ctx = data; 1541 + u64 ret; 1542 + 1543 + spu_acquire_saved(ctx); 1544 + ret = ctx->csa.priv2.spu_lslr_RW; 1545 + spu_release(ctx); 1546 + 1547 + return ret; 1548 + } 1549 + DEFINE_SIMPLE_ATTRIBUTE(spufs_lslr_ops, spufs_lslr_get, NULL, "0x%llx\n") 1550 + 1551 + static int spufs_info_open(struct inode *inode, struct file *file) 1552 + { 1553 + struct spufs_inode_info *i = SPUFS_I(inode); 1554 + struct spu_context *ctx = i->i_ctx; 1555 + file->private_data = ctx; 1556 + return 0; 1557 + } 1558 + 1559 + static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, 1560 + size_t len, loff_t *pos) 1561 + { 1562 + struct spu_context *ctx = file->private_data; 1563 + struct spu_dma_info info; 1564 + struct mfc_cq_sr *qp, *spuqp; 1565 + int i; 1566 + 1567 + if (!access_ok(VERIFY_WRITE, buf, len)) 1568 + return -EFAULT; 1569 + 1570 + spu_acquire_saved(ctx); 1571 + spin_lock(&ctx->csa.register_lock); 1572 + info.dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW; 1573 + info.dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0]; 1574 + info.dma_info_status = ctx->csa.spu_chnldata_RW[24]; 1575 + info.dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25]; 1576 + info.dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27]; 1577 + for (i = 0; i < 16; i++) { 1578 + qp = &info.dma_info_command_data[i]; 1579 + spuqp = &ctx->csa.priv2.spuq[i]; 1580 + 1581 + qp->mfc_cq_data0_RW = spuqp->mfc_cq_data0_RW; 1582 + qp->mfc_cq_data1_RW = spuqp->mfc_cq_data1_RW; 1583 + qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW; 1584 + qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW; 1585 + } 1586 + spin_unlock(&ctx->csa.register_lock); 1587 + spu_release(ctx); 1588 + 1589 + return simple_read_from_buffer(buf, len, pos, &info, 1590 + sizeof info); 1591 + } 1592 + 1593 + static struct file_operations spufs_dma_info_fops = { 1594 + .open = spufs_info_open, 1595 + .read = spufs_dma_info_read, 1596 + }; 1597 + 1598 + static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, 1599 + size_t len, loff_t *pos) 1600 + { 1601 + struct spu_context *ctx = file->private_data; 1602 + struct spu_proxydma_info info; 1603 + int ret = sizeof info; 1604 + struct mfc_cq_sr *qp, *puqp; 1605 + int i; 1606 + 1607 + if (len < ret) 1608 + return -EINVAL; 1609 + 1610 + if (!access_ok(VERIFY_WRITE, buf, len)) 1611 + return -EFAULT; 1612 + 1613 + spu_acquire_saved(ctx); 1614 + spin_lock(&ctx->csa.register_lock); 1615 + info.proxydma_info_type = ctx->csa.prob.dma_querytype_RW; 1616 + info.proxydma_info_mask = ctx->csa.prob.dma_querymask_RW; 1617 + info.proxydma_info_status = ctx->csa.prob.dma_tagstatus_R; 1618 + for (i = 0; i < 8; i++) { 1619 + qp = &info.proxydma_info_command_data[i]; 1620 + puqp = &ctx->csa.priv2.puq[i]; 1621 + 1622 + qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW; 1623 + qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW; 1624 + qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW; 1625 + qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW; 1626 + } 1627 + spin_unlock(&ctx->csa.register_lock); 1628 + spu_release(ctx); 1629 + 1630 + if (copy_to_user(buf, &info, sizeof info)) 1631 + ret = -EFAULT; 1632 + 1633 + return ret; 1634 + } 1635 + 1636 + static struct file_operations spufs_proxydma_info_fops = { 1637 + .open = spufs_info_open, 1638 + .read = spufs_proxydma_info_read, 1639 + }; 1640 + 1556 1641 struct tree_descr spufs_dir_contents[] = { 1557 1642 { "mem", &spufs_mem_fops, 0666, }, 1558 1643 { "regs", &spufs_regs_fops, 0666, }, ··· 1669 1548 { "signal2", &spufs_signal2_fops, 0666, }, 1670 1549 { "signal1_type", &spufs_signal1_type, 0666, }, 1671 1550 { "signal2_type", &spufs_signal2_type, 0666, }, 1672 - { "mss", &spufs_mss_fops, 0666, }, 1673 - { "mfc", &spufs_mfc_fops, 0666, }, 1674 1551 { "cntl", &spufs_cntl_fops, 0666, }, 1675 - { "npc", &spufs_npc_ops, 0666, }, 1676 1552 { "fpcr", &spufs_fpcr_fops, 0666, }, 1553 + { "lslr", &spufs_lslr_ops, 0444, }, 1554 + { "mfc", &spufs_mfc_fops, 0666, }, 1555 + { "mss", &spufs_mss_fops, 0666, }, 1556 + { "npc", &spufs_npc_ops, 0666, }, 1557 + { "srr0", &spufs_srr0_ops, 0666, }, 1677 1558 { "decr", &spufs_decr_ops, 0666, }, 1678 1559 { "decr_status", &spufs_decr_status_ops, 0666, }, 1679 1560 { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, 1680 1561 { "event_mask", &spufs_event_mask_ops, 0666, }, 1681 - { "srr0", &spufs_srr0_ops, 0666, }, 1562 + { "event_status", &spufs_event_status_ops, 0444, }, 1682 1563 { "psmap", &spufs_psmap_fops, 0666, }, 1683 1564 { "phys-id", &spufs_id_ops, 0666, }, 1684 1565 { "object-id", &spufs_object_id_ops, 0666, }, 1566 + { "dma_info", &spufs_dma_info_fops, 0444, }, 1567 + { "proxydma_info", &spufs_proxydma_info_fops, 0444, }, 1685 1568 {}, 1686 1569 }; 1687 1570
+7 -2
arch/powerpc/platforms/cell/spufs/spufs.h
··· 29 29 30 30 #include <asm/spu.h> 31 31 #include <asm/spu_csa.h> 32 + #include <asm/spu_info.h> 32 33 33 34 /* The magic number for our file system */ 34 35 enum { ··· 120 119 int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); 121 120 u32 (*read_mfc_tagstatus)(struct spu_context * ctx); 122 121 u32 (*get_mfc_free_elements)(struct spu_context *ctx); 123 - int (*send_mfc_command)(struct spu_context *ctx, 124 - struct mfc_dma_command *cmd); 122 + int (*send_mfc_command)(struct spu_context * ctx, 123 + struct mfc_dma_command * cmd); 124 + void (*dma_info_read) (struct spu_context * ctx, 125 + struct spu_dma_info * info); 126 + void (*proxydma_info_read) (struct spu_context * ctx, 127 + struct spu_proxydma_info * info); 125 128 }; 126 129 127 130 extern struct spu_context_ops spu_hw_ops;
+1
include/asm-powerpc/Kbuild
··· 17 17 header-y += poll.h 18 18 header-y += shmparam.h 19 19 header-y += sockios.h 20 + header-y += spu_info.h 20 21 header-y += ucontext.h 21 22 header-y += ioctl.h 22 23 header-y += linkage.h
+54
include/asm-powerpc/spu_info.h
··· 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