1 /* 2 * SPU file system 3 * 4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 5 * 6 * Author: Arnd Bergmann <arndb@de.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 #ifndef SPUFS_H 23 #define SPUFS_H 24 25 #include <linux/kref.h> 26 #include <linux/rwsem.h> 27 #include <linux/spinlock.h> 28 #include <linux/fs.h> 29 30 #include <asm/spu.h> 31 #include <asm/spu_csa.h> 32 33 /* The magic number for our file system */ 34 enum { 35 SPUFS_MAGIC = 0x23c9b64e, 36 }; 37 38 struct spu_context_ops; 39 40 #define SPU_CONTEXT_PREEMPT 0UL 41 42 struct spu_context { 43 struct spu *spu; /* pointer to a physical SPU */ 44 struct spu_state csa; /* SPU context save area. */ 45 spinlock_t mmio_lock; /* protects mmio access */ 46 struct address_space *local_store; /* local store mapping. */ 47 struct address_space *mfc; /* 'mfc' area mappings. */ 48 struct address_space *cntl; /* 'control' area mappings. */ 49 struct address_space *signal1; /* 'signal1' area mappings. */ 50 struct address_space *signal2; /* 'signal2' area mappings. */ 51 52 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; 53 struct rw_semaphore state_sema; 54 struct semaphore run_sema; 55 56 struct mm_struct *owner; 57 58 struct kref kref; 59 wait_queue_head_t ibox_wq; 60 wait_queue_head_t wbox_wq; 61 wait_queue_head_t stop_wq; 62 wait_queue_head_t mfc_wq; 63 struct fasync_struct *ibox_fasync; 64 struct fasync_struct *wbox_fasync; 65 struct fasync_struct *mfc_fasync; 66 u32 tagwait; 67 struct spu_context_ops *ops; 68 struct work_struct reap_work; 69 u64 flags; 70 }; 71 72 struct mfc_dma_command { 73 int32_t pad; /* reserved */ 74 uint32_t lsa; /* local storage address */ 75 uint64_t ea; /* effective address */ 76 uint16_t size; /* transfer size */ 77 uint16_t tag; /* command tag */ 78 uint16_t class; /* class ID */ 79 uint16_t cmd; /* command opcode */ 80 }; 81 82 83 /* SPU context query/set operations. */ 84 struct spu_context_ops { 85 int (*mbox_read) (struct spu_context * ctx, u32 * data); 86 u32(*mbox_stat_read) (struct spu_context * ctx); 87 unsigned int (*mbox_stat_poll)(struct spu_context *ctx, 88 unsigned int events); 89 int (*ibox_read) (struct spu_context * ctx, u32 * data); 90 int (*wbox_write) (struct spu_context * ctx, u32 data); 91 u32(*signal1_read) (struct spu_context * ctx); 92 void (*signal1_write) (struct spu_context * ctx, u32 data); 93 u32(*signal2_read) (struct spu_context * ctx); 94 void (*signal2_write) (struct spu_context * ctx, u32 data); 95 void (*signal1_type_set) (struct spu_context * ctx, u64 val); 96 u64(*signal1_type_get) (struct spu_context * ctx); 97 void (*signal2_type_set) (struct spu_context * ctx, u64 val); 98 u64(*signal2_type_get) (struct spu_context * ctx); 99 u32(*npc_read) (struct spu_context * ctx); 100 void (*npc_write) (struct spu_context * ctx, u32 data); 101 u32(*status_read) (struct spu_context * ctx); 102 char*(*get_ls) (struct spu_context * ctx); 103 void (*runcntl_write) (struct spu_context * ctx, u32 data); 104 void (*runcntl_stop) (struct spu_context * ctx); 105 int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); 106 u32 (*read_mfc_tagstatus)(struct spu_context * ctx); 107 u32 (*get_mfc_free_elements)(struct spu_context *ctx); 108 int (*send_mfc_command)(struct spu_context *ctx, 109 struct mfc_dma_command *cmd); 110 }; 111 112 extern struct spu_context_ops spu_hw_ops; 113 extern struct spu_context_ops spu_backing_ops; 114 115 struct spufs_inode_info { 116 struct spu_context *i_ctx; 117 struct inode vfs_inode; 118 }; 119 #define SPUFS_I(inode) \ 120 container_of(inode, struct spufs_inode_info, vfs_inode) 121 122 extern struct tree_descr spufs_dir_contents[]; 123 124 /* system call implementation */ 125 long spufs_run_spu(struct file *file, 126 struct spu_context *ctx, u32 *npc, u32 *status); 127 long spufs_create_thread(struct nameidata *nd, 128 unsigned int flags, mode_t mode); 129 extern struct file_operations spufs_context_fops; 130 131 /* context management */ 132 struct spu_context * alloc_spu_context(void); 133 void destroy_spu_context(struct kref *kref); 134 struct spu_context * get_spu_context(struct spu_context *ctx); 135 int put_spu_context(struct spu_context *ctx); 136 void spu_unmap_mappings(struct spu_context *ctx); 137 138 void spu_forget(struct spu_context *ctx); 139 void spu_acquire(struct spu_context *ctx); 140 void spu_release(struct spu_context *ctx); 141 int spu_acquire_runnable(struct spu_context *ctx); 142 void spu_acquire_saved(struct spu_context *ctx); 143 144 int spu_activate(struct spu_context *ctx, u64 flags); 145 void spu_deactivate(struct spu_context *ctx); 146 void spu_yield(struct spu_context *ctx); 147 int __init spu_sched_init(void); 148 void __exit spu_sched_exit(void); 149 150 /* 151 * spufs_wait 152 * Same as wait_event_interruptible(), except that here 153 * we need to call spu_release(ctx) before sleeping, and 154 * then spu_acquire(ctx) when awoken. 155 */ 156 157 #define spufs_wait(wq, condition) \ 158 ({ \ 159 int __ret = 0; \ 160 DEFINE_WAIT(__wait); \ 161 for (;;) { \ 162 prepare_to_wait(&(wq), &__wait, TASK_INTERRUPTIBLE); \ 163 if (condition) \ 164 break; \ 165 if (!signal_pending(current)) { \ 166 spu_release(ctx); \ 167 schedule(); \ 168 spu_acquire(ctx); \ 169 continue; \ 170 } \ 171 __ret = -ERESTARTSYS; \ 172 break; \ 173 } \ 174 finish_wait(&(wq), &__wait); \ 175 __ret; \ 176 }) 177 178 size_t spu_wbox_write(struct spu_context *ctx, u32 data); 179 size_t spu_ibox_read(struct spu_context *ctx, u32 *data); 180 181 /* irq callback funcs. */ 182 void spufs_ibox_callback(struct spu *spu); 183 void spufs_wbox_callback(struct spu *spu); 184 void spufs_stop_callback(struct spu *spu); 185 void spufs_mfc_callback(struct spu *spu); 186 187 #endif 188