[PATCH] spufs: cooperative scheduler support
[linux-2.6] / arch / powerpc / platforms / cell / spufs / file.c
1 /*
2  * SPU file system -- file contents
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
23 #include <linux/fs.h>
24 #include <linux/ioctl.h>
25 #include <linux/module.h>
26 #include <linux/poll.h>
27
28 #include <asm/io.h>
29 #include <asm/semaphore.h>
30 #include <asm/spu.h>
31 #include <asm/uaccess.h>
32
33 #include "spufs.h"
34
35
36 static int
37 spufs_mem_open(struct inode *inode, struct file *file)
38 {
39         struct spufs_inode_info *i = SPUFS_I(inode);
40         file->private_data = i->i_ctx;
41         file->f_mapping = i->i_ctx->local_store;
42         return 0;
43 }
44
45 static ssize_t
46 spufs_mem_read(struct file *file, char __user *buffer,
47                                 size_t size, loff_t *pos)
48 {
49         struct spu_context *ctx = file->private_data;
50         char *local_store;
51         int ret;
52
53         spu_acquire(ctx);
54
55         local_store = ctx->ops->get_ls(ctx);
56         ret = simple_read_from_buffer(buffer, size, pos, local_store, LS_SIZE);
57
58         spu_release(ctx);
59         return ret;
60 }
61
62 static ssize_t
63 spufs_mem_write(struct file *file, const char __user *buffer,
64                                         size_t size, loff_t *pos)
65 {
66         struct spu_context *ctx = file->private_data;
67         char *local_store;
68         int ret;
69
70         size = min_t(ssize_t, LS_SIZE - *pos, size);
71         if (size <= 0)
72                 return -EFBIG;
73         *pos += size;
74
75         spu_acquire(ctx);
76
77         local_store = ctx->ops->get_ls(ctx);
78         ret = copy_from_user(local_store + *pos - size,
79                              buffer, size) ? -EFAULT : size;
80
81         spu_release(ctx);
82         return ret;
83 }
84
85 #ifdef CONFIG_SPARSEMEM
86 static struct page *
87 spufs_mem_mmap_nopage(struct vm_area_struct *vma,
88                       unsigned long address, int *type)
89 {
90         struct page *page = NOPAGE_SIGBUS;
91
92         struct spu_context *ctx = vma->vm_file->private_data;
93         unsigned long offset = address - vma->vm_start;
94         offset += vma->vm_pgoff << PAGE_SHIFT;
95
96         spu_acquire(ctx);
97
98         if (ctx->state == SPU_STATE_SAVED)
99                 page = vmalloc_to_page(ctx->csa.lscsa->ls + offset);
100         else
101                 page = pfn_to_page((ctx->spu->local_store_phys + offset)
102                                    >> PAGE_SHIFT);
103
104         spu_release(ctx);
105
106         if (type)
107                 *type = VM_FAULT_MINOR;
108
109         return page;
110 }
111
112 static struct vm_operations_struct spufs_mem_mmap_vmops = {
113         .nopage = spufs_mem_mmap_nopage,
114 };
115
116 static int
117 spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)
118 {
119         if (!(vma->vm_flags & VM_SHARED))
120                 return -EINVAL;
121
122         /* FIXME: */
123         vma->vm_flags |= VM_RESERVED;
124         vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
125                                      | _PAGE_NO_CACHE);
126
127         vma->vm_ops = &spufs_mem_mmap_vmops;
128         return 0;
129 }
130 #endif
131
132 static struct file_operations spufs_mem_fops = {
133         .open    = spufs_mem_open,
134         .read    = spufs_mem_read,
135         .write   = spufs_mem_write,
136         .llseek  = generic_file_llseek,
137 #ifdef CONFIG_SPARSEMEM
138         .mmap    = spufs_mem_mmap,
139 #endif
140 };
141
142 static int
143 spufs_regs_open(struct inode *inode, struct file *file)
144 {
145         struct spufs_inode_info *i = SPUFS_I(inode);
146         file->private_data = i->i_ctx;
147         return 0;
148 }
149
150 static ssize_t
151 spufs_regs_read(struct file *file, char __user *buffer,
152                 size_t size, loff_t *pos)
153 {
154         struct spu_context *ctx = file->private_data;
155         struct spu_lscsa *lscsa = ctx->csa.lscsa;
156         int ret;
157
158         spu_acquire_saved(ctx);
159
160         ret = simple_read_from_buffer(buffer, size, pos,
161                                       lscsa->gprs, sizeof lscsa->gprs);
162
163         spu_release(ctx);
164         return ret;
165 }
166
167 static ssize_t
168 spufs_regs_write(struct file *file, const char __user *buffer,
169                  size_t size, loff_t *pos)
170 {
171         struct spu_context *ctx = file->private_data;
172         struct spu_lscsa *lscsa = ctx->csa.lscsa;
173         int ret;
174
175         size = min_t(ssize_t, sizeof lscsa->gprs - *pos, size);
176         if (size <= 0)
177                 return -EFBIG;
178         *pos += size;
179
180         spu_acquire_saved(ctx);
181
182         ret = copy_from_user(lscsa->gprs + *pos - size,
183                              buffer, size) ? -EFAULT : size;
184
185         spu_release(ctx);
186         return ret;
187 }
188
189 static struct file_operations spufs_regs_fops = {
190         .open    = spufs_regs_open,
191         .read    = spufs_regs_read,
192         .write   = spufs_regs_write,
193         .llseek  = generic_file_llseek,
194 };
195
196 static ssize_t
197 spufs_fpcr_read(struct file *file, char __user * buffer,
198                 size_t size, loff_t * pos)
199 {
200         struct spu_context *ctx = file->private_data;
201         struct spu_lscsa *lscsa = ctx->csa.lscsa;
202         int ret;
203
204         spu_acquire_saved(ctx);
205
206         ret = simple_read_from_buffer(buffer, size, pos,
207                                       &lscsa->fpcr, sizeof(lscsa->fpcr));
208
209         spu_release(ctx);
210         return ret;
211 }
212
213 static ssize_t
214 spufs_fpcr_write(struct file *file, const char __user * buffer,
215                  size_t size, loff_t * pos)
216 {
217         struct spu_context *ctx = file->private_data;
218         struct spu_lscsa *lscsa = ctx->csa.lscsa;
219         int ret;
220
221         size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
222         if (size <= 0)
223                 return -EFBIG;
224         *pos += size;
225
226         spu_acquire_saved(ctx);
227
228         ret = copy_from_user((char *)&lscsa->fpcr + *pos - size,
229                              buffer, size) ? -EFAULT : size;
230
231         spu_release(ctx);
232         return ret;
233 }
234
235 static struct file_operations spufs_fpcr_fops = {
236         .open = spufs_regs_open,
237         .read = spufs_fpcr_read,
238         .write = spufs_fpcr_write,
239         .llseek = generic_file_llseek,
240 };
241
242 /* generic open function for all pipe-like files */
243 static int spufs_pipe_open(struct inode *inode, struct file *file)
244 {
245         struct spufs_inode_info *i = SPUFS_I(inode);
246         file->private_data = i->i_ctx;
247
248         return nonseekable_open(inode, file);
249 }
250
251 static ssize_t spufs_mbox_read(struct file *file, char __user *buf,
252                         size_t len, loff_t *pos)
253 {
254         struct spu_context *ctx = file->private_data;
255         u32 mbox_data;
256         int ret;
257
258         if (len < 4)
259                 return -EINVAL;
260
261         spu_acquire(ctx);
262         ret = ctx->ops->mbox_read(ctx, &mbox_data);
263         spu_release(ctx);
264
265         if (!ret)
266                 return -EAGAIN;
267
268         if (copy_to_user(buf, &mbox_data, sizeof mbox_data))
269                 return -EFAULT;
270
271         return 4;
272 }
273
274 static struct file_operations spufs_mbox_fops = {
275         .open   = spufs_pipe_open,
276         .read   = spufs_mbox_read,
277 };
278
279 static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf,
280                         size_t len, loff_t *pos)
281 {
282         struct spu_context *ctx = file->private_data;
283         u32 mbox_stat;
284
285         if (len < 4)
286                 return -EINVAL;
287
288         spu_acquire(ctx);
289
290         mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff;
291
292         spu_release(ctx);
293
294         if (copy_to_user(buf, &mbox_stat, sizeof mbox_stat))
295                 return -EFAULT;
296
297         return 4;
298 }
299
300 static struct file_operations spufs_mbox_stat_fops = {
301         .open   = spufs_pipe_open,
302         .read   = spufs_mbox_stat_read,
303 };
304
305 /*
306  * spufs_wait
307  *      Same as wait_event_interruptible(), except that here
308  *      we need to call spu_release(ctx) before sleeping, and
309  *      then spu_acquire(ctx) when awoken.
310  */
311
312 #define spufs_wait(wq, condition)                                       \
313 ({                                                                      \
314         int __ret = 0;                                                  \
315         DEFINE_WAIT(__wait);                                            \
316         for (;;) {                                                      \
317                 prepare_to_wait(&(wq), &__wait, TASK_INTERRUPTIBLE);    \
318                 if (condition)                                          \
319                         break;                                          \
320                 if (!signal_pending(current)) {                         \
321                         spu_release(ctx);                               \
322                         schedule();                                     \
323                         spu_acquire(ctx);                               \
324                         continue;                                       \
325                 }                                                       \
326                 __ret = -ERESTARTSYS;                                   \
327                 break;                                                  \
328         }                                                               \
329         finish_wait(&(wq), &__wait);                                    \
330         __ret;                                                          \
331 })
332
333 /* low-level ibox access function */
334 size_t spu_ibox_read(struct spu_context *ctx, u32 *data)
335 {
336         return ctx->ops->ibox_read(ctx, data);
337 }
338
339 static int spufs_ibox_fasync(int fd, struct file *file, int on)
340 {
341         struct spu_context *ctx = file->private_data;
342
343         return fasync_helper(fd, file, on, &ctx->ibox_fasync);
344 }
345
346 /* interrupt-level ibox callback function. */
347 void spufs_ibox_callback(struct spu *spu)
348 {
349         struct spu_context *ctx = spu->ctx;
350
351         wake_up_all(&ctx->ibox_wq);
352         kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN);
353 }
354
355 static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
356                         size_t len, loff_t *pos)
357 {
358         struct spu_context *ctx = file->private_data;
359         u32 ibox_data;
360         ssize_t ret;
361
362         if (len < 4)
363                 return -EINVAL;
364
365         spu_acquire(ctx);
366
367         ret = 0;
368         if (file->f_flags & O_NONBLOCK) {
369                 if (!spu_ibox_read(ctx, &ibox_data))
370                         ret = -EAGAIN;
371         } else {
372                 ret = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data));
373         }
374
375         spu_release(ctx);
376
377         if (ret)
378                 return ret;
379
380         ret = 4;
381         if (copy_to_user(buf, &ibox_data, sizeof ibox_data))
382                 ret = -EFAULT;
383
384         return ret;
385 }
386
387 static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait)
388 {
389         struct spu_context *ctx = file->private_data;
390         u32 mbox_stat;
391         unsigned int mask;
392
393         spu_acquire(ctx);
394
395         mbox_stat = ctx->ops->mbox_stat_read(ctx);
396
397         spu_release(ctx);
398
399         poll_wait(file, &ctx->ibox_wq, wait);
400
401         mask = 0;
402         if (mbox_stat & 0xff0000)
403                 mask |= POLLIN | POLLRDNORM;
404
405         return mask;
406 }
407
408 static struct file_operations spufs_ibox_fops = {
409         .open   = spufs_pipe_open,
410         .read   = spufs_ibox_read,
411         .poll   = spufs_ibox_poll,
412         .fasync = spufs_ibox_fasync,
413 };
414
415 static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf,
416                         size_t len, loff_t *pos)
417 {
418         struct spu_context *ctx = file->private_data;
419         u32 ibox_stat;
420
421         if (len < 4)
422                 return -EINVAL;
423
424         spu_acquire(ctx);
425         ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff;
426         spu_release(ctx);
427
428         if (copy_to_user(buf, &ibox_stat, sizeof ibox_stat))
429                 return -EFAULT;
430
431         return 4;
432 }
433
434 static struct file_operations spufs_ibox_stat_fops = {
435         .open   = spufs_pipe_open,
436         .read   = spufs_ibox_stat_read,
437 };
438
439 /* low-level mailbox write */
440 size_t spu_wbox_write(struct spu_context *ctx, u32 data)
441 {
442         return ctx->ops->wbox_write(ctx, data);
443 }
444
445 static int spufs_wbox_fasync(int fd, struct file *file, int on)
446 {
447         struct spu_context *ctx = file->private_data;
448         int ret;
449
450         ret = fasync_helper(fd, file, on, &ctx->wbox_fasync);
451
452         return ret;
453 }
454
455 /* interrupt-level wbox callback function. */
456 void spufs_wbox_callback(struct spu *spu)
457 {
458         struct spu_context *ctx = spu->ctx;
459
460         wake_up_all(&ctx->wbox_wq);
461         kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT);
462 }
463
464 static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
465                         size_t len, loff_t *pos)
466 {
467         struct spu_context *ctx = file->private_data;
468         u32 wbox_data;
469         int ret;
470
471         if (len < 4)
472                 return -EINVAL;
473
474         if (copy_from_user(&wbox_data, buf, sizeof wbox_data))
475                 return -EFAULT;
476
477         spu_acquire(ctx);
478
479         ret = 0;
480         if (file->f_flags & O_NONBLOCK) {
481                 if (!spu_wbox_write(ctx, wbox_data))
482                         ret = -EAGAIN;
483         } else {
484                 ret = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data));
485         }
486
487         spu_release(ctx);
488
489         return ret ? ret : sizeof wbox_data;
490 }
491
492 static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait)
493 {
494         struct spu_context *ctx = file->private_data;
495         u32 mbox_stat;
496         unsigned int mask;
497
498         spu_acquire(ctx);
499         mbox_stat = ctx->ops->mbox_stat_read(ctx);
500         spu_release(ctx);
501
502         poll_wait(file, &ctx->wbox_wq, wait);
503
504         mask = 0;
505         if (mbox_stat & 0x00ff00)
506                 mask = POLLOUT | POLLWRNORM;
507
508         return mask;
509 }
510
511 static struct file_operations spufs_wbox_fops = {
512         .open   = spufs_pipe_open,
513         .write  = spufs_wbox_write,
514         .poll   = spufs_wbox_poll,
515         .fasync = spufs_wbox_fasync,
516 };
517
518 static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf,
519                         size_t len, loff_t *pos)
520 {
521         struct spu_context *ctx = file->private_data;
522         u32 wbox_stat;
523
524         if (len < 4)
525                 return -EINVAL;
526
527         spu_acquire(ctx);
528         wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff;
529         spu_release(ctx);
530
531         if (copy_to_user(buf, &wbox_stat, sizeof wbox_stat))
532                 return -EFAULT;
533
534         return 4;
535 }
536
537 static struct file_operations spufs_wbox_stat_fops = {
538         .open   = spufs_pipe_open,
539         .read   = spufs_wbox_stat_read,
540 };
541
542 long spufs_run_spu(struct file *file, struct spu_context *ctx,
543                                 u32 *npc, u32 *status)
544 {
545         int ret;
546
547         ret = spu_acquire_runnable(ctx);
548         if (ret)
549                 return ret;
550
551         ctx->ops->npc_write(ctx, *npc);
552
553         ret = spu_run(ctx->spu);
554
555         if (!ret)
556                 ret = ctx->ops->status_read(ctx);
557
558         *npc = ctx->ops->npc_read(ctx);
559
560         spu_release(ctx);
561         spu_yield(ctx);
562         return ret;
563 }
564
565 static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
566                         size_t len, loff_t *pos)
567 {
568         struct spu_context *ctx = file->private_data;
569         u32 data;
570
571         if (len < 4)
572                 return -EINVAL;
573
574         spu_acquire(ctx);
575         data = ctx->ops->signal1_read(ctx);
576         spu_release(ctx);
577
578         if (copy_to_user(buf, &data, 4))
579                 return -EFAULT;
580
581         return 4;
582 }
583
584 static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
585                         size_t len, loff_t *pos)
586 {
587         struct spu_context *ctx;
588         u32 data;
589
590         ctx = file->private_data;
591
592         if (len < 4)
593                 return -EINVAL;
594
595         if (copy_from_user(&data, buf, 4))
596                 return -EFAULT;
597
598         spu_acquire(ctx);
599         ctx->ops->signal1_write(ctx, data);
600         spu_release(ctx);
601
602         return 4;
603 }
604
605 static struct file_operations spufs_signal1_fops = {
606         .open = spufs_pipe_open,
607         .read = spufs_signal1_read,
608         .write = spufs_signal1_write,
609 };
610
611 static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
612                         size_t len, loff_t *pos)
613 {
614         struct spu_context *ctx;
615         u32 data;
616
617         ctx = file->private_data;
618
619         if (len < 4)
620                 return -EINVAL;
621
622         spu_acquire(ctx);
623         data = ctx->ops->signal2_read(ctx);
624         spu_release(ctx);
625
626         if (copy_to_user(buf, &data, 4))
627                 return -EFAULT;
628
629         return 4;
630 }
631
632 static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
633                         size_t len, loff_t *pos)
634 {
635         struct spu_context *ctx;
636         u32 data;
637
638         ctx = file->private_data;
639
640         if (len < 4)
641                 return -EINVAL;
642
643         if (copy_from_user(&data, buf, 4))
644                 return -EFAULT;
645
646         spu_acquire(ctx);
647         ctx->ops->signal2_write(ctx, data);
648         spu_release(ctx);
649
650         return 4;
651 }
652
653 static struct file_operations spufs_signal2_fops = {
654         .open = spufs_pipe_open,
655         .read = spufs_signal2_read,
656         .write = spufs_signal2_write,
657 };
658
659 static void spufs_signal1_type_set(void *data, u64 val)
660 {
661         struct spu_context *ctx = data;
662
663         spu_acquire(ctx);
664         ctx->ops->signal1_type_set(ctx, val);
665         spu_release(ctx);
666 }
667
668 static u64 spufs_signal1_type_get(void *data)
669 {
670         struct spu_context *ctx = data;
671         u64 ret;
672
673         spu_acquire(ctx);
674         ret = ctx->ops->signal1_type_get(ctx);
675         spu_release(ctx);
676
677         return ret;
678 }
679 DEFINE_SIMPLE_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get,
680                                         spufs_signal1_type_set, "%llu");
681
682 static void spufs_signal2_type_set(void *data, u64 val)
683 {
684         struct spu_context *ctx = data;
685
686         spu_acquire(ctx);
687         ctx->ops->signal2_type_set(ctx, val);
688         spu_release(ctx);
689 }
690
691 static u64 spufs_signal2_type_get(void *data)
692 {
693         struct spu_context *ctx = data;
694         u64 ret;
695
696         spu_acquire(ctx);
697         ret = ctx->ops->signal2_type_get(ctx);
698         spu_release(ctx);
699
700         return ret;
701 }
702 DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
703                                         spufs_signal2_type_set, "%llu");
704
705 static void spufs_npc_set(void *data, u64 val)
706 {
707         struct spu_context *ctx = data;
708         spu_acquire(ctx);
709         ctx->ops->npc_write(ctx, val);
710         spu_release(ctx);
711 }
712
713 static u64 spufs_npc_get(void *data)
714 {
715         struct spu_context *ctx = data;
716         u64 ret;
717         spu_acquire(ctx);
718         ret = ctx->ops->npc_read(ctx);
719         spu_release(ctx);
720         return ret;
721 }
722 DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, "%llx\n")
723
724 static void spufs_decr_set(void *data, u64 val)
725 {
726         struct spu_context *ctx = data;
727         struct spu_lscsa *lscsa = ctx->csa.lscsa;
728         spu_acquire_saved(ctx);
729         lscsa->decr.slot[0] = (u32) val;
730         spu_release(ctx);
731 }
732
733 static u64 spufs_decr_get(void *data)
734 {
735         struct spu_context *ctx = data;
736         struct spu_lscsa *lscsa = ctx->csa.lscsa;
737         u64 ret;
738         spu_acquire_saved(ctx);
739         ret = lscsa->decr.slot[0];
740         spu_release(ctx);
741         return ret;
742 }
743 DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
744                         "%llx\n")
745
746 static void spufs_decr_status_set(void *data, u64 val)
747 {
748         struct spu_context *ctx = data;
749         struct spu_lscsa *lscsa = ctx->csa.lscsa;
750         spu_acquire_saved(ctx);
751         lscsa->decr_status.slot[0] = (u32) val;
752         spu_release(ctx);
753 }
754
755 static u64 spufs_decr_status_get(void *data)
756 {
757         struct spu_context *ctx = data;
758         struct spu_lscsa *lscsa = ctx->csa.lscsa;
759         u64 ret;
760         spu_acquire_saved(ctx);
761         ret = lscsa->decr_status.slot[0];
762         spu_release(ctx);
763         return ret;
764 }
765 DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get,
766                         spufs_decr_status_set, "%llx\n")
767
768 static void spufs_spu_tag_mask_set(void *data, u64 val)
769 {
770         struct spu_context *ctx = data;
771         struct spu_lscsa *lscsa = ctx->csa.lscsa;
772         spu_acquire_saved(ctx);
773         lscsa->tag_mask.slot[0] = (u32) val;
774         spu_release(ctx);
775 }
776
777 static u64 spufs_spu_tag_mask_get(void *data)
778 {
779         struct spu_context *ctx = data;
780         struct spu_lscsa *lscsa = ctx->csa.lscsa;
781         u64 ret;
782         spu_acquire_saved(ctx);
783         ret = lscsa->tag_mask.slot[0];
784         spu_release(ctx);
785         return ret;
786 }
787 DEFINE_SIMPLE_ATTRIBUTE(spufs_spu_tag_mask_ops, spufs_spu_tag_mask_get,
788                         spufs_spu_tag_mask_set, "%llx\n")
789
790 static void spufs_event_mask_set(void *data, u64 val)
791 {
792         struct spu_context *ctx = data;
793         struct spu_lscsa *lscsa = ctx->csa.lscsa;
794         spu_acquire_saved(ctx);
795         lscsa->event_mask.slot[0] = (u32) val;
796         spu_release(ctx);
797 }
798
799 static u64 spufs_event_mask_get(void *data)
800 {
801         struct spu_context *ctx = data;
802         struct spu_lscsa *lscsa = ctx->csa.lscsa;
803         u64 ret;
804         spu_acquire_saved(ctx);
805         ret = lscsa->event_mask.slot[0];
806         spu_release(ctx);
807         return ret;
808 }
809 DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
810                         spufs_event_mask_set, "%llx\n")
811
812 static void spufs_srr0_set(void *data, u64 val)
813 {
814         struct spu_context *ctx = data;
815         struct spu_lscsa *lscsa = ctx->csa.lscsa;
816         spu_acquire_saved(ctx);
817         lscsa->srr0.slot[0] = (u32) val;
818         spu_release(ctx);
819 }
820
821 static u64 spufs_srr0_get(void *data)
822 {
823         struct spu_context *ctx = data;
824         struct spu_lscsa *lscsa = ctx->csa.lscsa;
825         u64 ret;
826         spu_acquire_saved(ctx);
827         ret = lscsa->srr0.slot[0];
828         spu_release(ctx);
829         return ret;
830 }
831 DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set,
832                         "%llx\n")
833
834 struct tree_descr spufs_dir_contents[] = {
835         { "mem",  &spufs_mem_fops,  0666, },
836         { "regs", &spufs_regs_fops,  0666, },
837         { "mbox", &spufs_mbox_fops, 0444, },
838         { "ibox", &spufs_ibox_fops, 0444, },
839         { "wbox", &spufs_wbox_fops, 0222, },
840         { "mbox_stat", &spufs_mbox_stat_fops, 0444, },
841         { "ibox_stat", &spufs_ibox_stat_fops, 0444, },
842         { "wbox_stat", &spufs_wbox_stat_fops, 0444, },
843         { "signal1", &spufs_signal1_fops, 0666, },
844         { "signal2", &spufs_signal2_fops, 0666, },
845         { "signal1_type", &spufs_signal1_type, 0666, },
846         { "signal2_type", &spufs_signal2_type, 0666, },
847         { "npc", &spufs_npc_ops, 0666, },
848         { "fpcr", &spufs_fpcr_fops, 0666, },
849         { "decr", &spufs_decr_ops, 0666, },
850         { "decr_status", &spufs_decr_status_ops, 0666, },
851         { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, },
852         { "event_mask", &spufs_event_mask_ops, 0666, },
853         { "srr0", &spufs_srr0_ops, 0666, },
854         {},
855 };