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