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 #undef DEBUG 24 25 #include <linux/fs.h> 26 #include <linux/ioctl.h> 27 #include <linux/module.h> 28 #include <linux/pagemap.h> 29 #include <linux/poll.h> 30 #include <linux/ptrace.h> 31 32 #include <asm/io.h> 33 #include <asm/semaphore.h> 34 #include <asm/spu.h> 35 #include <asm/uaccess.h> 36 37 #include "spufs.h" 38 39 40 static int 41 spufs_mem_open(struct inode *inode, struct file *file) 42 { 43 struct spufs_inode_info *i = SPUFS_I(inode); 44 struct spu_context *ctx = i->i_ctx; 45 file->private_data = ctx; 46 file->f_mapping = inode->i_mapping; 47 ctx->local_store = inode->i_mapping; 48 return 0; 49 } 50 51 static ssize_t 52 spufs_mem_read(struct file *file, char __user *buffer, 53 size_t size, loff_t *pos) 54 { 55 struct spu_context *ctx = file->private_data; 56 char *local_store; 57 int ret; 58 59 spu_acquire(ctx); 60 61 local_store = ctx->ops->get_ls(ctx); 62 ret = simple_read_from_buffer(buffer, size, pos, local_store, LS_SIZE); 63 64 spu_release(ctx); 65 return ret; 66 } 67 68 static ssize_t 69 spufs_mem_write(struct file *file, const char __user *buffer, 70 size_t size, loff_t *pos) 71 { 72 struct spu_context *ctx = file->private_data; 73 char *local_store; 74 int ret; 75 76 size = min_t(ssize_t, LS_SIZE - *pos, size); 77 if (size <= 0) 78 return -EFBIG; 79 *pos += size; 80 81 spu_acquire(ctx); 82 83 local_store = ctx->ops->get_ls(ctx); 84 ret = copy_from_user(local_store + *pos - size, 85 buffer, size) ? -EFAULT : size; 86 87 spu_release(ctx); 88 return ret; 89 } 90 91 #ifdef CONFIG_SPUFS_MMAP 92 static struct page * 93 spufs_mem_mmap_nopage(struct vm_area_struct *vma, 94 unsigned long address, int *type) 95 { 96 struct page *page = NOPAGE_SIGBUS; 97 98 struct spu_context *ctx = vma->vm_file->private_data; 99 unsigned long offset = address - vma->vm_start; 100 offset += vma->vm_pgoff << PAGE_SHIFT; 101 102 spu_acquire(ctx); 103 104 if (ctx->state == SPU_STATE_SAVED) 105 page = vmalloc_to_page(ctx->csa.lscsa->ls + offset); 106 else 107 page = pfn_to_page((ctx->spu->local_store_phys + offset) 108 >> PAGE_SHIFT); 109 110 spu_release(ctx); 111 112 if (type) 113 *type = VM_FAULT_MINOR; 114 115 page_cache_get(page); 116 return page; 117 } 118 119 static struct vm_operations_struct spufs_mem_mmap_vmops = { 120 .nopage = spufs_mem_mmap_nopage, 121 }; 122 123 static int 124 spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) 125 { 126 if (!(vma->vm_flags & VM_SHARED)) 127 return -EINVAL; 128 129 /* FIXME: */ 130 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 131 | _PAGE_NO_CACHE); 132 133 vma->vm_ops = &spufs_mem_mmap_vmops; 134 return 0; 135 } 136 #endif 137 138 static struct file_operations spufs_mem_fops = { 139 .open = spufs_mem_open, 140 .read = spufs_mem_read, 141 .write = spufs_mem_write, 142 .llseek = generic_file_llseek, 143 #ifdef CONFIG_SPUFS_MMAP 144 .mmap = spufs_mem_mmap, 145 #endif 146 }; 147 148 #ifdef CONFIG_SPUFS_MMAP 149 static struct page *spufs_ps_nopage(struct vm_area_struct *vma, 150 unsigned long address, 151 int *type, unsigned long ps_offs) 152 { 153 struct page *page = NOPAGE_SIGBUS; 154 int fault_type = VM_FAULT_SIGBUS; 155 struct spu_context *ctx = vma->vm_file->private_data; 156 unsigned long offset = address - vma->vm_start; 157 unsigned long area; 158 int ret; 159 160 offset += vma->vm_pgoff << PAGE_SHIFT; 161 if (offset >= 0x4000) 162 goto out; 163 164 ret = spu_acquire_runnable(ctx); 165 if (ret) 166 goto out; 167 168 area = ctx->spu->problem_phys + ps_offs; 169 page = pfn_to_page((area + offset) >> PAGE_SHIFT); 170 fault_type = VM_FAULT_MINOR; 171 page_cache_get(page); 172 173 spu_release(ctx); 174 175 out: 176 if (type) 177 *type = fault_type; 178 179 return page; 180 } 181 182 static struct page *spufs_cntl_mmap_nopage(struct vm_area_struct *vma, 183 unsigned long address, int *type) 184 { 185 return spufs_ps_nopage(vma, address, type, 0x4000); 186 } 187 188 static struct vm_operations_struct spufs_cntl_mmap_vmops = { 189 .nopage = spufs_cntl_mmap_nopage, 190 }; 191 192 /* 193 * mmap support for problem state control area [0x4000 - 0x4fff]. 194 * Mapping this area requires that the application have CAP_SYS_RAWIO, 195 * as these registers require special care when read/writing. 196 */ 197 static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) 198 { 199 if (!(vma->vm_flags & VM_SHARED)) 200 return -EINVAL; 201 202 if (!capable(CAP_SYS_RAWIO)) 203 return -EPERM; 204 205 vma->vm_flags |= VM_RESERVED; 206 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 207 | _PAGE_NO_CACHE); 208 209 vma->vm_ops = &spufs_cntl_mmap_vmops; 210 return 0; 211 } 212 #endif 213 214 static int spufs_cntl_open(struct inode *inode, struct file *file) 215 { 216 struct spufs_inode_info *i = SPUFS_I(inode); 217 struct spu_context *ctx = i->i_ctx; 218 219 file->private_data = ctx; 220 file->f_mapping = inode->i_mapping; 221 ctx->cntl = inode->i_mapping; 222 return 0; 223 } 224 225 static ssize_t 226 spufs_cntl_read(struct file *file, char __user *buffer, 227 size_t size, loff_t *pos) 228 { 229 /* FIXME: read from spu status */ 230 return -EINVAL; 231 } 232 233 static ssize_t 234 spufs_cntl_write(struct file *file, const char __user *buffer, 235 size_t size, loff_t *pos) 236 { 237 /* FIXME: write to runctl bit */ 238 return -EINVAL; 239 } 240 241 static struct file_operations spufs_cntl_fops = { 242 .open = spufs_cntl_open, 243 .read = spufs_cntl_read, 244 .write = spufs_cntl_write, 245 #ifdef CONFIG_SPUFS_MMAP 246 .mmap = spufs_cntl_mmap, 247 #endif 248 }; 249 250 static int 251 spufs_regs_open(struct inode *inode, struct file *file) 252 { 253 struct spufs_inode_info *i = SPUFS_I(inode); 254 file->private_data = i->i_ctx; 255 return 0; 256 } 257 258 static ssize_t 259 spufs_regs_read(struct file *file, char __user *buffer, 260 size_t size, loff_t *pos) 261 { 262 struct spu_context *ctx = file->private_data; 263 struct spu_lscsa *lscsa = ctx->csa.lscsa; 264 int ret; 265 266 spu_acquire_saved(ctx); 267 268 ret = simple_read_from_buffer(buffer, size, pos, 269 lscsa->gprs, sizeof lscsa->gprs); 270 271 spu_release(ctx); 272 return ret; 273 } 274 275 static ssize_t 276 spufs_regs_write(struct file *file, const char __user *buffer, 277 size_t size, loff_t *pos) 278 { 279 struct spu_context *ctx = file->private_data; 280 struct spu_lscsa *lscsa = ctx->csa.lscsa; 281 int ret; 282 283 size = min_t(ssize_t, sizeof lscsa->gprs - *pos, size); 284 if (size <= 0) 285 return -EFBIG; 286 *pos += size; 287 288 spu_acquire_saved(ctx); 289 290 ret = copy_from_user(lscsa->gprs + *pos - size, 291 buffer, size) ? -EFAULT : size; 292 293 spu_release(ctx); 294 return ret; 295 } 296 297 static struct file_operations spufs_regs_fops = { 298 .open = spufs_regs_open, 299 .read = spufs_regs_read, 300 .write = spufs_regs_write, 301 .llseek = generic_file_llseek, 302 }; 303 304 static ssize_t 305 spufs_fpcr_read(struct file *file, char __user * buffer, 306 size_t size, loff_t * pos) 307 { 308 struct spu_context *ctx = file->private_data; 309 struct spu_lscsa *lscsa = ctx->csa.lscsa; 310 int ret; 311 312 spu_acquire_saved(ctx); 313 314 ret = simple_read_from_buffer(buffer, size, pos, 315 &lscsa->fpcr, sizeof(lscsa->fpcr)); 316 317 spu_release(ctx); 318 return ret; 319 } 320 321 static ssize_t 322 spufs_fpcr_write(struct file *file, const char __user * buffer, 323 size_t size, loff_t * pos) 324 { 325 struct spu_context *ctx = file->private_data; 326 struct spu_lscsa *lscsa = ctx->csa.lscsa; 327 int ret; 328 329 size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size); 330 if (size <= 0) 331 return -EFBIG; 332 *pos += size; 333 334 spu_acquire_saved(ctx); 335 336 ret = copy_from_user((char *)&lscsa->fpcr + *pos - size, 337 buffer, size) ? -EFAULT : size; 338 339 spu_release(ctx); 340 return ret; 341 } 342 343 static struct file_operations spufs_fpcr_fops = { 344 .open = spufs_regs_open, 345 .read = spufs_fpcr_read, 346 .write = spufs_fpcr_write, 347 .llseek = generic_file_llseek, 348 }; 349 350 /* generic open function for all pipe-like files */ 351 static int spufs_pipe_open(struct inode *inode, struct file *file) 352 { 353 struct spufs_inode_info *i = SPUFS_I(inode); 354 file->private_data = i->i_ctx; 355 356 return nonseekable_open(inode, file); 357 } 358 359 static ssize_t spufs_mbox_read(struct file *file, char __user *buf, 360 size_t len, loff_t *pos) 361 { 362 struct spu_context *ctx = file->private_data; 363 u32 mbox_data; 364 int ret; 365 366 if (len < 4) 367 return -EINVAL; 368 369 spu_acquire(ctx); 370 ret = ctx->ops->mbox_read(ctx, &mbox_data); 371 spu_release(ctx); 372 373 if (!ret) 374 return -EAGAIN; 375 376 if (copy_to_user(buf, &mbox_data, sizeof mbox_data)) 377 return -EFAULT; 378 379 return 4; 380 } 381 382 static struct file_operations spufs_mbox_fops = { 383 .open = spufs_pipe_open, 384 .read = spufs_mbox_read, 385 }; 386 387 static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf, 388 size_t len, loff_t *pos) 389 { 390 struct spu_context *ctx = file->private_data; 391 u32 mbox_stat; 392 393 if (len < 4) 394 return -EINVAL; 395 396 spu_acquire(ctx); 397 398 mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff; 399 400 spu_release(ctx); 401 402 if (copy_to_user(buf, &mbox_stat, sizeof mbox_stat)) 403 return -EFAULT; 404 405 return 4; 406 } 407 408 static struct file_operations spufs_mbox_stat_fops = { 409 .open = spufs_pipe_open, 410 .read = spufs_mbox_stat_read, 411 }; 412 413 /* low-level ibox access function */ 414 size_t spu_ibox_read(struct spu_context *ctx, u32 *data) 415 { 416 return ctx->ops->ibox_read(ctx, data); 417 } 418 419 static int spufs_ibox_fasync(int fd, struct file *file, int on) 420 { 421 struct spu_context *ctx = file->private_data; 422 423 return fasync_helper(fd, file, on, &ctx->ibox_fasync); 424 } 425 426 /* interrupt-level ibox callback function. */ 427 void spufs_ibox_callback(struct spu *spu) 428 { 429 struct spu_context *ctx = spu->ctx; 430 431 wake_up_all(&ctx->ibox_wq); 432 kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN); 433 } 434 435 static ssize_t spufs_ibox_read(struct file *file, char __user *buf, 436 size_t len, loff_t *pos) 437 { 438 struct spu_context *ctx = file->private_data; 439 u32 ibox_data; 440 ssize_t ret; 441 442 if (len < 4) 443 return -EINVAL; 444 445 spu_acquire(ctx); 446 447 ret = 0; 448 if (file->f_flags & O_NONBLOCK) { 449 if (!spu_ibox_read(ctx, &ibox_data)) 450 ret = -EAGAIN; 451 } else { 452 ret = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data)); 453 } 454 455 spu_release(ctx); 456 457 if (ret) 458 return ret; 459 460 ret = 4; 461 if (copy_to_user(buf, &ibox_data, sizeof ibox_data)) 462 ret = -EFAULT; 463 464 return ret; 465 } 466 467 static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait) 468 { 469 struct spu_context *ctx = file->private_data; 470 unsigned int mask; 471 472 poll_wait(file, &ctx->ibox_wq, wait); 473 474 spu_acquire(ctx); 475 mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM); 476 spu_release(ctx); 477 478 return mask; 479 } 480 481 static struct file_operations spufs_ibox_fops = { 482 .open = spufs_pipe_open, 483 .read = spufs_ibox_read, 484 .poll = spufs_ibox_poll, 485 .fasync = spufs_ibox_fasync, 486 }; 487 488 static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf, 489 size_t len, loff_t *pos) 490 { 491 struct spu_context *ctx = file->private_data; 492 u32 ibox_stat; 493 494 if (len < 4) 495 return -EINVAL; 496 497 spu_acquire(ctx); 498 ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff; 499 spu_release(ctx); 500 501 if (copy_to_user(buf, &ibox_stat, sizeof ibox_stat)) 502 return -EFAULT; 503 504 return 4; 505 } 506 507 static struct file_operations spufs_ibox_stat_fops = { 508 .open = spufs_pipe_open, 509 .read = spufs_ibox_stat_read, 510 }; 511 512 /* low-level mailbox write */ 513 size_t spu_wbox_write(struct spu_context *ctx, u32 data) 514 { 515 return ctx->ops->wbox_write(ctx, data); 516 } 517 518 static int spufs_wbox_fasync(int fd, struct file *file, int on) 519 { 520 struct spu_context *ctx = file->private_data; 521 int ret; 522 523 ret = fasync_helper(fd, file, on, &ctx->wbox_fasync); 524 525 return ret; 526 } 527 528 /* interrupt-level wbox callback function. */ 529 void spufs_wbox_callback(struct spu *spu) 530 { 531 struct spu_context *ctx = spu->ctx; 532 533 wake_up_all(&ctx->wbox_wq); 534 kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT); 535 } 536 537 static ssize_t spufs_wbox_write(struct file *file, const char __user *buf, 538 size_t len, loff_t *pos) 539 { 540 struct spu_context *ctx = file->private_data; 541 u32 wbox_data; 542 int ret; 543 544 if (len < 4) 545 return -EINVAL; 546 547 if (copy_from_user(&wbox_data, buf, sizeof wbox_data)) 548 return -EFAULT; 549 550 spu_acquire(ctx); 551 552 ret = 0; 553 if (file->f_flags & O_NONBLOCK) { 554 if (!spu_wbox_write(ctx, wbox_data)) 555 ret = -EAGAIN; 556 } else { 557 ret = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data)); 558 } 559 560 spu_release(ctx); 561 562 return ret ? ret : sizeof wbox_data; 563 } 564 565 static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait) 566 { 567 struct spu_context *ctx = file->private_data; 568 unsigned int mask; 569 570 poll_wait(file, &ctx->wbox_wq, wait); 571 572 spu_acquire(ctx); 573 mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM); 574 spu_release(ctx); 575 576 return mask; 577 } 578 579 static struct file_operations spufs_wbox_fops = { 580 .open = spufs_pipe_open, 581 .write = spufs_wbox_write, 582 .poll = spufs_wbox_poll, 583 .fasync = spufs_wbox_fasync, 584 }; 585 586 static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf, 587 size_t len, loff_t *pos) 588 { 589 struct spu_context *ctx = file->private_data; 590 u32 wbox_stat; 591 592 if (len < 4) 593 return -EINVAL; 594 595 spu_acquire(ctx); 596 wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff; 597 spu_release(ctx); 598 599 if (copy_to_user(buf, &wbox_stat, sizeof wbox_stat)) 600 return -EFAULT; 601 602 return 4; 603 } 604 605 static struct file_operations spufs_wbox_stat_fops = { 606 .open = spufs_pipe_open, 607 .read = spufs_wbox_stat_read, 608 }; 609 610 static int spufs_signal1_open(struct inode *inode, struct file *file) 611 { 612 struct spufs_inode_info *i = SPUFS_I(inode); 613 struct spu_context *ctx = i->i_ctx; 614 file->private_data = ctx; 615 file->f_mapping = inode->i_mapping; 616 ctx->signal1 = inode->i_mapping; 617 return nonseekable_open(inode, file); 618 } 619 620 static ssize_t spufs_signal1_read(struct file *file, char __user *buf, 621 size_t len, loff_t *pos) 622 { 623 struct spu_context *ctx = file->private_data; 624 u32 data; 625 626 if (len < 4) 627 return -EINVAL; 628 629 spu_acquire(ctx); 630 data = ctx->ops->signal1_read(ctx); 631 spu_release(ctx); 632 633 if (copy_to_user(buf, &data, 4)) 634 return -EFAULT; 635 636 return 4; 637 } 638 639 static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, 640 size_t len, loff_t *pos) 641 { 642 struct spu_context *ctx; 643 u32 data; 644 645 ctx = file->private_data; 646 647 if (len < 4) 648 return -EINVAL; 649 650 if (copy_from_user(&data, buf, 4)) 651 return -EFAULT; 652 653 spu_acquire(ctx); 654 ctx->ops->signal1_write(ctx, data); 655 spu_release(ctx); 656 657 return 4; 658 } 659 660 #ifdef CONFIG_SPUFS_MMAP 661 static struct page *spufs_signal1_mmap_nopage(struct vm_area_struct *vma, 662 unsigned long address, int *type) 663 { 664 return spufs_ps_nopage(vma, address, type, 0x14000); 665 } 666 667 static struct vm_operations_struct spufs_signal1_mmap_vmops = { 668 .nopage = spufs_signal1_mmap_nopage, 669 }; 670 671 static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) 672 { 673 if (!(vma->vm_flags & VM_SHARED)) 674 return -EINVAL; 675 676 vma->vm_flags |= VM_RESERVED; 677 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 678 | _PAGE_NO_CACHE); 679 680 vma->vm_ops = &spufs_signal1_mmap_vmops; 681 return 0; 682 } 683 #endif 684 685 static struct file_operations spufs_signal1_fops = { 686 .open = spufs_signal1_open, 687 .read = spufs_signal1_read, 688 .write = spufs_signal1_write, 689 #ifdef CONFIG_SPUFS_MMAP 690 .mmap = spufs_signal1_mmap, 691 #endif 692 }; 693 694 static int spufs_signal2_open(struct inode *inode, struct file *file) 695 { 696 struct spufs_inode_info *i = SPUFS_I(inode); 697 struct spu_context *ctx = i->i_ctx; 698 file->private_data = ctx; 699 file->f_mapping = inode->i_mapping; 700 ctx->signal2 = inode->i_mapping; 701 return nonseekable_open(inode, file); 702 } 703 704 static ssize_t spufs_signal2_read(struct file *file, char __user *buf, 705 size_t len, loff_t *pos) 706 { 707 struct spu_context *ctx; 708 u32 data; 709 710 ctx = file->private_data; 711 712 if (len < 4) 713 return -EINVAL; 714 715 spu_acquire(ctx); 716 data = ctx->ops->signal2_read(ctx); 717 spu_release(ctx); 718 719 if (copy_to_user(buf, &data, 4)) 720 return -EFAULT; 721 722 return 4; 723 } 724 725 static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, 726 size_t len, loff_t *pos) 727 { 728 struct spu_context *ctx; 729 u32 data; 730 731 ctx = file->private_data; 732 733 if (len < 4) 734 return -EINVAL; 735 736 if (copy_from_user(&data, buf, 4)) 737 return -EFAULT; 738 739 spu_acquire(ctx); 740 ctx->ops->signal2_write(ctx, data); 741 spu_release(ctx); 742 743 return 4; 744 } 745 746 #ifdef CONFIG_SPUFS_MMAP 747 static struct page *spufs_signal2_mmap_nopage(struct vm_area_struct *vma, 748 unsigned long address, int *type) 749 { 750 return spufs_ps_nopage(vma, address, type, 0x1c000); 751 } 752 753 static struct vm_operations_struct spufs_signal2_mmap_vmops = { 754 .nopage = spufs_signal2_mmap_nopage, 755 }; 756 757 static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) 758 { 759 if (!(vma->vm_flags & VM_SHARED)) 760 return -EINVAL; 761 762 /* FIXME: */ 763 vma->vm_flags |= VM_RESERVED; 764 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 765 | _PAGE_NO_CACHE); 766 767 vma->vm_ops = &spufs_signal2_mmap_vmops; 768 return 0; 769 } 770 #endif 771 772 static struct file_operations spufs_signal2_fops = { 773 .open = spufs_signal2_open, 774 .read = spufs_signal2_read, 775 .write = spufs_signal2_write, 776 #ifdef CONFIG_SPUFS_MMAP 777 .mmap = spufs_signal2_mmap, 778 #endif 779 }; 780 781 static void spufs_signal1_type_set(void *data, u64 val) 782 { 783 struct spu_context *ctx = data; 784 785 spu_acquire(ctx); 786 ctx->ops->signal1_type_set(ctx, val); 787 spu_release(ctx); 788 } 789 790 static u64 spufs_signal1_type_get(void *data) 791 { 792 struct spu_context *ctx = data; 793 u64 ret; 794 795 spu_acquire(ctx); 796 ret = ctx->ops->signal1_type_get(ctx); 797 spu_release(ctx); 798 799 return ret; 800 } 801 DEFINE_SIMPLE_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get, 802 spufs_signal1_type_set, "%llu"); 803 804 static void spufs_signal2_type_set(void *data, u64 val) 805 { 806 struct spu_context *ctx = data; 807 808 spu_acquire(ctx); 809 ctx->ops->signal2_type_set(ctx, val); 810 spu_release(ctx); 811 } 812 813 static u64 spufs_signal2_type_get(void *data) 814 { 815 struct spu_context *ctx = data; 816 u64 ret; 817 818 spu_acquire(ctx); 819 ret = ctx->ops->signal2_type_get(ctx); 820 spu_release(ctx); 821 822 return ret; 823 } 824 DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, 825 spufs_signal2_type_set, "%llu"); 826 827 #ifdef CONFIG_SPUFS_MMAP 828 static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma, 829 unsigned long address, int *type) 830 { 831 return spufs_ps_nopage(vma, address, type, 0x3000); 832 } 833 834 static struct vm_operations_struct spufs_mfc_mmap_vmops = { 835 .nopage = spufs_mfc_mmap_nopage, 836 }; 837 838 /* 839 * mmap support for problem state MFC DMA area [0x0000 - 0x0fff]. 840 * Mapping this area requires that the application have CAP_SYS_RAWIO, 841 * as these registers require special care when read/writing. 842 */ 843 static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) 844 { 845 if (!(vma->vm_flags & VM_SHARED)) 846 return -EINVAL; 847 848 if (!capable(CAP_SYS_RAWIO)) 849 return -EPERM; 850 851 vma->vm_flags |= VM_RESERVED; 852 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 853 | _PAGE_NO_CACHE); 854 855 vma->vm_ops = &spufs_mfc_mmap_vmops; 856 return 0; 857 } 858 #endif 859 860 static int spufs_mfc_open(struct inode *inode, struct file *file) 861 { 862 struct spufs_inode_info *i = SPUFS_I(inode); 863 struct spu_context *ctx = i->i_ctx; 864 865 /* we don't want to deal with DMA into other processes */ 866 if (ctx->owner != current->mm) 867 return -EINVAL; 868 869 if (atomic_read(&inode->i_count) != 1) 870 return -EBUSY; 871 872 file->private_data = ctx; 873 return nonseekable_open(inode, file); 874 } 875 876 /* interrupt-level mfc callback function. */ 877 void spufs_mfc_callback(struct spu *spu) 878 { 879 struct spu_context *ctx = spu->ctx; 880 881 wake_up_all(&ctx->mfc_wq); 882 883 pr_debug("%s %s\n", __FUNCTION__, spu->name); 884 if (ctx->mfc_fasync) { 885 u32 free_elements, tagstatus; 886 unsigned int mask; 887 888 /* no need for spu_acquire in interrupt context */ 889 free_elements = ctx->ops->get_mfc_free_elements(ctx); 890 tagstatus = ctx->ops->read_mfc_tagstatus(ctx); 891 892 mask = 0; 893 if (free_elements & 0xffff) 894 mask |= POLLOUT; 895 if (tagstatus & ctx->tagwait) 896 mask |= POLLIN; 897 898 kill_fasync(&ctx->mfc_fasync, SIGIO, mask); 899 } 900 } 901 902 static int spufs_read_mfc_tagstatus(struct spu_context *ctx, u32 *status) 903 { 904 /* See if there is one tag group is complete */ 905 /* FIXME we need locking around tagwait */ 906 *status = ctx->ops->read_mfc_tagstatus(ctx) & ctx->tagwait; 907 ctx->tagwait &= ~*status; 908 if (*status) 909 return 1; 910 911 /* enable interrupt waiting for any tag group, 912 may silently fail if interrupts are already enabled */ 913 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1); 914 return 0; 915 } 916 917 static ssize_t spufs_mfc_read(struct file *file, char __user *buffer, 918 size_t size, loff_t *pos) 919 { 920 struct spu_context *ctx = file->private_data; 921 int ret = -EINVAL; 922 u32 status; 923 924 if (size != 4) 925 goto out; 926 927 spu_acquire(ctx); 928 if (file->f_flags & O_NONBLOCK) { 929 status = ctx->ops->read_mfc_tagstatus(ctx); 930 if (!(status & ctx->tagwait)) 931 ret = -EAGAIN; 932 else 933 ctx->tagwait &= ~status; 934 } else { 935 ret = spufs_wait(ctx->mfc_wq, 936 spufs_read_mfc_tagstatus(ctx, &status)); 937 } 938 spu_release(ctx); 939 940 if (ret) 941 goto out; 942 943 ret = 4; 944 if (copy_to_user(buffer, &status, 4)) 945 ret = -EFAULT; 946 947 out: 948 return ret; 949 } 950 951 static int spufs_check_valid_dma(struct mfc_dma_command *cmd) 952 { 953 pr_debug("queueing DMA %x %lx %x %x %x\n", cmd->lsa, 954 cmd->ea, cmd->size, cmd->tag, cmd->cmd); 955 956 switch (cmd->cmd) { 957 case MFC_PUT_CMD: 958 case MFC_PUTF_CMD: 959 case MFC_PUTB_CMD: 960 case MFC_GET_CMD: 961 case MFC_GETF_CMD: 962 case MFC_GETB_CMD: 963 break; 964 default: 965 pr_debug("invalid DMA opcode %x\n", cmd->cmd); 966 return -EIO; 967 } 968 969 if ((cmd->lsa & 0xf) != (cmd->ea &0xf)) { 970 pr_debug("invalid DMA alignment, ea %lx lsa %x\n", 971 cmd->ea, cmd->lsa); 972 return -EIO; 973 } 974 975 switch (cmd->size & 0xf) { 976 case 1: 977 break; 978 case 2: 979 if (cmd->lsa & 1) 980 goto error; 981 break; 982 case 4: 983 if (cmd->lsa & 3) 984 goto error; 985 break; 986 case 8: 987 if (cmd->lsa & 7) 988 goto error; 989 break; 990 case 0: 991 if (cmd->lsa & 15) 992 goto error; 993 break; 994 error: 995 default: 996 pr_debug("invalid DMA alignment %x for size %x\n", 997 cmd->lsa & 0xf, cmd->size); 998 return -EIO; 999 } 1000 1001 if (cmd->size > 16 * 1024) { 1002 pr_debug("invalid DMA size %x\n", cmd->size); 1003 return -EIO; 1004 } 1005 1006 if (cmd->tag & 0xfff0) { 1007 /* we reserve the higher tag numbers for kernel use */ 1008 pr_debug("invalid DMA tag\n"); 1009 return -EIO; 1010 } 1011 1012 if (cmd->class) { 1013 /* not supported in this version */ 1014 pr_debug("invalid DMA class\n"); 1015 return -EIO; 1016 } 1017 1018 return 0; 1019 } 1020 1021 static int spu_send_mfc_command(struct spu_context *ctx, 1022 struct mfc_dma_command cmd, 1023 int *error) 1024 { 1025 *error = ctx->ops->send_mfc_command(ctx, &cmd); 1026 if (*error == -EAGAIN) { 1027 /* wait for any tag group to complete 1028 so we have space for the new command */ 1029 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1); 1030 /* try again, because the queue might be 1031 empty again */ 1032 *error = ctx->ops->send_mfc_command(ctx, &cmd); 1033 if (*error == -EAGAIN) 1034 return 0; 1035 } 1036 return 1; 1037 } 1038 1039 static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer, 1040 size_t size, loff_t *pos) 1041 { 1042 struct spu_context *ctx = file->private_data; 1043 struct mfc_dma_command cmd; 1044 int ret = -EINVAL; 1045 1046 if (size != sizeof cmd) 1047 goto out; 1048 1049 ret = -EFAULT; 1050 if (copy_from_user(&cmd, buffer, sizeof cmd)) 1051 goto out; 1052 1053 ret = spufs_check_valid_dma(&cmd); 1054 if (ret) 1055 goto out; 1056 1057 spu_acquire_runnable(ctx); 1058 if (file->f_flags & O_NONBLOCK) { 1059 ret = ctx->ops->send_mfc_command(ctx, &cmd); 1060 } else { 1061 int status; 1062 ret = spufs_wait(ctx->mfc_wq, 1063 spu_send_mfc_command(ctx, cmd, &status)); 1064 if (status) 1065 ret = status; 1066 } 1067 spu_release(ctx); 1068 1069 if (ret) 1070 goto out; 1071 1072 ctx->tagwait |= 1 << cmd.tag; 1073 1074 out: 1075 return ret; 1076 } 1077 1078 static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait) 1079 { 1080 struct spu_context *ctx = file->private_data; 1081 u32 free_elements, tagstatus; 1082 unsigned int mask; 1083 1084 spu_acquire(ctx); 1085 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); 1086 free_elements = ctx->ops->get_mfc_free_elements(ctx); 1087 tagstatus = ctx->ops->read_mfc_tagstatus(ctx); 1088 spu_release(ctx); 1089 1090 poll_wait(file, &ctx->mfc_wq, wait); 1091 1092 mask = 0; 1093 if (free_elements & 0xffff) 1094 mask |= POLLOUT | POLLWRNORM; 1095 if (tagstatus & ctx->tagwait) 1096 mask |= POLLIN | POLLRDNORM; 1097 1098 pr_debug("%s: free %d tagstatus %d tagwait %d\n", __FUNCTION__, 1099 free_elements, tagstatus, ctx->tagwait); 1100 1101 return mask; 1102 } 1103 1104 static int spufs_mfc_flush(struct file *file) 1105 { 1106 struct spu_context *ctx = file->private_data; 1107 int ret; 1108 1109 spu_acquire(ctx); 1110 #if 0 1111 /* this currently hangs */ 1112 ret = spufs_wait(ctx->mfc_wq, 1113 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2)); 1114 if (ret) 1115 goto out; 1116 ret = spufs_wait(ctx->mfc_wq, 1117 ctx->ops->read_mfc_tagstatus(ctx) == ctx->tagwait); 1118 out: 1119 #else 1120 ret = 0; 1121 #endif 1122 spu_release(ctx); 1123 1124 return ret; 1125 } 1126 1127 static int spufs_mfc_fsync(struct file *file, struct dentry *dentry, 1128 int datasync) 1129 { 1130 return spufs_mfc_flush(file); 1131 } 1132 1133 static int spufs_mfc_fasync(int fd, struct file *file, int on) 1134 { 1135 struct spu_context *ctx = file->private_data; 1136 1137 return fasync_helper(fd, file, on, &ctx->mfc_fasync); 1138 } 1139 1140 static struct file_operations spufs_mfc_fops = { 1141 .open = spufs_mfc_open, 1142 .read = spufs_mfc_read, 1143 .write = spufs_mfc_write, 1144 .poll = spufs_mfc_poll, 1145 .flush = spufs_mfc_flush, 1146 .fsync = spufs_mfc_fsync, 1147 .fasync = spufs_mfc_fasync, 1148 #ifdef CONFIG_SPUFS_MMAP 1149 .mmap = spufs_mfc_mmap, 1150 #endif 1151 }; 1152 1153 static void spufs_npc_set(void *data, u64 val) 1154 { 1155 struct spu_context *ctx = data; 1156 spu_acquire(ctx); 1157 ctx->ops->npc_write(ctx, val); 1158 spu_release(ctx); 1159 } 1160 1161 static u64 spufs_npc_get(void *data) 1162 { 1163 struct spu_context *ctx = data; 1164 u64 ret; 1165 spu_acquire(ctx); 1166 ret = ctx->ops->npc_read(ctx); 1167 spu_release(ctx); 1168 return ret; 1169 } 1170 DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, "%llx\n") 1171 1172 static void spufs_decr_set(void *data, u64 val) 1173 { 1174 struct spu_context *ctx = data; 1175 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1176 spu_acquire_saved(ctx); 1177 lscsa->decr.slot[0] = (u32) val; 1178 spu_release(ctx); 1179 } 1180 1181 static u64 spufs_decr_get(void *data) 1182 { 1183 struct spu_context *ctx = data; 1184 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1185 u64 ret; 1186 spu_acquire_saved(ctx); 1187 ret = lscsa->decr.slot[0]; 1188 spu_release(ctx); 1189 return ret; 1190 } 1191 DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, 1192 "%llx\n") 1193 1194 static void spufs_decr_status_set(void *data, u64 val) 1195 { 1196 struct spu_context *ctx = data; 1197 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1198 spu_acquire_saved(ctx); 1199 lscsa->decr_status.slot[0] = (u32) val; 1200 spu_release(ctx); 1201 } 1202 1203 static u64 spufs_decr_status_get(void *data) 1204 { 1205 struct spu_context *ctx = data; 1206 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1207 u64 ret; 1208 spu_acquire_saved(ctx); 1209 ret = lscsa->decr_status.slot[0]; 1210 spu_release(ctx); 1211 return ret; 1212 } 1213 DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get, 1214 spufs_decr_status_set, "%llx\n") 1215 1216 static void spufs_spu_tag_mask_set(void *data, u64 val) 1217 { 1218 struct spu_context *ctx = data; 1219 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1220 spu_acquire_saved(ctx); 1221 lscsa->tag_mask.slot[0] = (u32) val; 1222 spu_release(ctx); 1223 } 1224 1225 static u64 spufs_spu_tag_mask_get(void *data) 1226 { 1227 struct spu_context *ctx = data; 1228 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1229 u64 ret; 1230 spu_acquire_saved(ctx); 1231 ret = lscsa->tag_mask.slot[0]; 1232 spu_release(ctx); 1233 return ret; 1234 } 1235 DEFINE_SIMPLE_ATTRIBUTE(spufs_spu_tag_mask_ops, spufs_spu_tag_mask_get, 1236 spufs_spu_tag_mask_set, "%llx\n") 1237 1238 static void spufs_event_mask_set(void *data, u64 val) 1239 { 1240 struct spu_context *ctx = data; 1241 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1242 spu_acquire_saved(ctx); 1243 lscsa->event_mask.slot[0] = (u32) val; 1244 spu_release(ctx); 1245 } 1246 1247 static u64 spufs_event_mask_get(void *data) 1248 { 1249 struct spu_context *ctx = data; 1250 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1251 u64 ret; 1252 spu_acquire_saved(ctx); 1253 ret = lscsa->event_mask.slot[0]; 1254 spu_release(ctx); 1255 return ret; 1256 } 1257 DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, 1258 spufs_event_mask_set, "%llx\n") 1259 1260 static void spufs_srr0_set(void *data, u64 val) 1261 { 1262 struct spu_context *ctx = data; 1263 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1264 spu_acquire_saved(ctx); 1265 lscsa->srr0.slot[0] = (u32) val; 1266 spu_release(ctx); 1267 } 1268 1269 static u64 spufs_srr0_get(void *data) 1270 { 1271 struct spu_context *ctx = data; 1272 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1273 u64 ret; 1274 spu_acquire_saved(ctx); 1275 ret = lscsa->srr0.slot[0]; 1276 spu_release(ctx); 1277 return ret; 1278 } 1279 DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set, 1280 "%llx\n") 1281 1282 struct tree_descr spufs_dir_contents[] = { 1283 { "mem", &spufs_mem_fops, 0666, }, 1284 { "regs", &spufs_regs_fops, 0666, }, 1285 { "mbox", &spufs_mbox_fops, 0444, }, 1286 { "ibox", &spufs_ibox_fops, 0444, }, 1287 { "wbox", &spufs_wbox_fops, 0222, }, 1288 { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, 1289 { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, 1290 { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, 1291 { "signal1", &spufs_signal1_fops, 0666, }, 1292 { "signal2", &spufs_signal2_fops, 0666, }, 1293 { "signal1_type", &spufs_signal1_type, 0666, }, 1294 { "signal2_type", &spufs_signal2_type, 0666, }, 1295 { "mfc", &spufs_mfc_fops, 0666, }, 1296 { "cntl", &spufs_cntl_fops, 0666, }, 1297 { "npc", &spufs_npc_ops, 0666, }, 1298 { "fpcr", &spufs_fpcr_fops, 0666, }, 1299 { "decr", &spufs_decr_ops, 0666, }, 1300 { "decr_status", &spufs_decr_status_ops, 0666, }, 1301 { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, 1302 { "event_mask", &spufs_event_mask_ops, 0666, }, 1303 { "srr0", &spufs_srr0_ops, 0666, }, 1304 {}, 1305 }; 1306