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 | _PAGE_GUARDED); 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 | _PAGE_GUARDED); 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 | _PAGE_GUARDED); 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_mss_mmap_nopage(struct vm_area_struct *vma, 829 unsigned long address, int *type) 830 { 831 return spufs_ps_nopage(vma, address, type, 0x0000); 832 } 833 834 static struct vm_operations_struct spufs_mss_mmap_vmops = { 835 .nopage = spufs_mss_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_mss_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 | _PAGE_GUARDED); 854 855 vma->vm_ops = &spufs_mss_mmap_vmops; 856 return 0; 857 } 858 #endif 859 860 static int spufs_mss_open(struct inode *inode, struct file *file) 861 { 862 struct spufs_inode_info *i = SPUFS_I(inode); 863 864 file->private_data = i->i_ctx; 865 return nonseekable_open(inode, file); 866 } 867 868 static struct file_operations spufs_mss_fops = { 869 .open = spufs_mss_open, 870 #ifdef CONFIG_SPUFS_MMAP 871 .mmap = spufs_mss_mmap, 872 #endif 873 }; 874 875 876 #ifdef CONFIG_SPUFS_MMAP 877 static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma, 878 unsigned long address, int *type) 879 { 880 return spufs_ps_nopage(vma, address, type, 0x3000); 881 } 882 883 static struct vm_operations_struct spufs_mfc_mmap_vmops = { 884 .nopage = spufs_mfc_mmap_nopage, 885 }; 886 887 /* 888 * mmap support for problem state MFC DMA area [0x0000 - 0x0fff]. 889 * Mapping this area requires that the application have CAP_SYS_RAWIO, 890 * as these registers require special care when read/writing. 891 */ 892 static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) 893 { 894 if (!(vma->vm_flags & VM_SHARED)) 895 return -EINVAL; 896 897 if (!capable(CAP_SYS_RAWIO)) 898 return -EPERM; 899 900 vma->vm_flags |= VM_RESERVED; 901 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 902 | _PAGE_NO_CACHE | _PAGE_GUARDED); 903 904 vma->vm_ops = &spufs_mfc_mmap_vmops; 905 return 0; 906 } 907 #endif 908 909 static int spufs_mfc_open(struct inode *inode, struct file *file) 910 { 911 struct spufs_inode_info *i = SPUFS_I(inode); 912 struct spu_context *ctx = i->i_ctx; 913 914 /* we don't want to deal with DMA into other processes */ 915 if (ctx->owner != current->mm) 916 return -EINVAL; 917 918 if (atomic_read(&inode->i_count) != 1) 919 return -EBUSY; 920 921 file->private_data = ctx; 922 return nonseekable_open(inode, file); 923 } 924 925 /* interrupt-level mfc callback function. */ 926 void spufs_mfc_callback(struct spu *spu) 927 { 928 struct spu_context *ctx = spu->ctx; 929 930 wake_up_all(&ctx->mfc_wq); 931 932 pr_debug("%s %s\n", __FUNCTION__, spu->name); 933 if (ctx->mfc_fasync) { 934 u32 free_elements, tagstatus; 935 unsigned int mask; 936 937 /* no need for spu_acquire in interrupt context */ 938 free_elements = ctx->ops->get_mfc_free_elements(ctx); 939 tagstatus = ctx->ops->read_mfc_tagstatus(ctx); 940 941 mask = 0; 942 if (free_elements & 0xffff) 943 mask |= POLLOUT; 944 if (tagstatus & ctx->tagwait) 945 mask |= POLLIN; 946 947 kill_fasync(&ctx->mfc_fasync, SIGIO, mask); 948 } 949 } 950 951 static int spufs_read_mfc_tagstatus(struct spu_context *ctx, u32 *status) 952 { 953 /* See if there is one tag group is complete */ 954 /* FIXME we need locking around tagwait */ 955 *status = ctx->ops->read_mfc_tagstatus(ctx) & ctx->tagwait; 956 ctx->tagwait &= ~*status; 957 if (*status) 958 return 1; 959 960 /* enable interrupt waiting for any tag group, 961 may silently fail if interrupts are already enabled */ 962 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1); 963 return 0; 964 } 965 966 static ssize_t spufs_mfc_read(struct file *file, char __user *buffer, 967 size_t size, loff_t *pos) 968 { 969 struct spu_context *ctx = file->private_data; 970 int ret = -EINVAL; 971 u32 status; 972 973 if (size != 4) 974 goto out; 975 976 spu_acquire(ctx); 977 if (file->f_flags & O_NONBLOCK) { 978 status = ctx->ops->read_mfc_tagstatus(ctx); 979 if (!(status & ctx->tagwait)) 980 ret = -EAGAIN; 981 else 982 ctx->tagwait &= ~status; 983 } else { 984 ret = spufs_wait(ctx->mfc_wq, 985 spufs_read_mfc_tagstatus(ctx, &status)); 986 } 987 spu_release(ctx); 988 989 if (ret) 990 goto out; 991 992 ret = 4; 993 if (copy_to_user(buffer, &status, 4)) 994 ret = -EFAULT; 995 996 out: 997 return ret; 998 } 999 1000 static int spufs_check_valid_dma(struct mfc_dma_command *cmd) 1001 { 1002 pr_debug("queueing DMA %x %lx %x %x %x\n", cmd->lsa, 1003 cmd->ea, cmd->size, cmd->tag, cmd->cmd); 1004 1005 switch (cmd->cmd) { 1006 case MFC_PUT_CMD: 1007 case MFC_PUTF_CMD: 1008 case MFC_PUTB_CMD: 1009 case MFC_GET_CMD: 1010 case MFC_GETF_CMD: 1011 case MFC_GETB_CMD: 1012 break; 1013 default: 1014 pr_debug("invalid DMA opcode %x\n", cmd->cmd); 1015 return -EIO; 1016 } 1017 1018 if ((cmd->lsa & 0xf) != (cmd->ea &0xf)) { 1019 pr_debug("invalid DMA alignment, ea %lx lsa %x\n", 1020 cmd->ea, cmd->lsa); 1021 return -EIO; 1022 } 1023 1024 switch (cmd->size & 0xf) { 1025 case 1: 1026 break; 1027 case 2: 1028 if (cmd->lsa & 1) 1029 goto error; 1030 break; 1031 case 4: 1032 if (cmd->lsa & 3) 1033 goto error; 1034 break; 1035 case 8: 1036 if (cmd->lsa & 7) 1037 goto error; 1038 break; 1039 case 0: 1040 if (cmd->lsa & 15) 1041 goto error; 1042 break; 1043 error: 1044 default: 1045 pr_debug("invalid DMA alignment %x for size %x\n", 1046 cmd->lsa & 0xf, cmd->size); 1047 return -EIO; 1048 } 1049 1050 if (cmd->size > 16 * 1024) { 1051 pr_debug("invalid DMA size %x\n", cmd->size); 1052 return -EIO; 1053 } 1054 1055 if (cmd->tag & 0xfff0) { 1056 /* we reserve the higher tag numbers for kernel use */ 1057 pr_debug("invalid DMA tag\n"); 1058 return -EIO; 1059 } 1060 1061 if (cmd->class) { 1062 /* not supported in this version */ 1063 pr_debug("invalid DMA class\n"); 1064 return -EIO; 1065 } 1066 1067 return 0; 1068 } 1069 1070 static int spu_send_mfc_command(struct spu_context *ctx, 1071 struct mfc_dma_command cmd, 1072 int *error) 1073 { 1074 *error = ctx->ops->send_mfc_command(ctx, &cmd); 1075 if (*error == -EAGAIN) { 1076 /* wait for any tag group to complete 1077 so we have space for the new command */ 1078 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1); 1079 /* try again, because the queue might be 1080 empty again */ 1081 *error = ctx->ops->send_mfc_command(ctx, &cmd); 1082 if (*error == -EAGAIN) 1083 return 0; 1084 } 1085 return 1; 1086 } 1087 1088 static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer, 1089 size_t size, loff_t *pos) 1090 { 1091 struct spu_context *ctx = file->private_data; 1092 struct mfc_dma_command cmd; 1093 int ret = -EINVAL; 1094 1095 if (size != sizeof cmd) 1096 goto out; 1097 1098 ret = -EFAULT; 1099 if (copy_from_user(&cmd, buffer, sizeof cmd)) 1100 goto out; 1101 1102 ret = spufs_check_valid_dma(&cmd); 1103 if (ret) 1104 goto out; 1105 1106 spu_acquire_runnable(ctx); 1107 if (file->f_flags & O_NONBLOCK) { 1108 ret = ctx->ops->send_mfc_command(ctx, &cmd); 1109 } else { 1110 int status; 1111 ret = spufs_wait(ctx->mfc_wq, 1112 spu_send_mfc_command(ctx, cmd, &status)); 1113 if (status) 1114 ret = status; 1115 } 1116 spu_release(ctx); 1117 1118 if (ret) 1119 goto out; 1120 1121 ctx->tagwait |= 1 << cmd.tag; 1122 1123 out: 1124 return ret; 1125 } 1126 1127 static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait) 1128 { 1129 struct spu_context *ctx = file->private_data; 1130 u32 free_elements, tagstatus; 1131 unsigned int mask; 1132 1133 spu_acquire(ctx); 1134 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); 1135 free_elements = ctx->ops->get_mfc_free_elements(ctx); 1136 tagstatus = ctx->ops->read_mfc_tagstatus(ctx); 1137 spu_release(ctx); 1138 1139 poll_wait(file, &ctx->mfc_wq, wait); 1140 1141 mask = 0; 1142 if (free_elements & 0xffff) 1143 mask |= POLLOUT | POLLWRNORM; 1144 if (tagstatus & ctx->tagwait) 1145 mask |= POLLIN | POLLRDNORM; 1146 1147 pr_debug("%s: free %d tagstatus %d tagwait %d\n", __FUNCTION__, 1148 free_elements, tagstatus, ctx->tagwait); 1149 1150 return mask; 1151 } 1152 1153 static int spufs_mfc_flush(struct file *file, fl_owner_t id) 1154 { 1155 struct spu_context *ctx = file->private_data; 1156 int ret; 1157 1158 spu_acquire(ctx); 1159 #if 0 1160 /* this currently hangs */ 1161 ret = spufs_wait(ctx->mfc_wq, 1162 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2)); 1163 if (ret) 1164 goto out; 1165 ret = spufs_wait(ctx->mfc_wq, 1166 ctx->ops->read_mfc_tagstatus(ctx) == ctx->tagwait); 1167 out: 1168 #else 1169 ret = 0; 1170 #endif 1171 spu_release(ctx); 1172 1173 return ret; 1174 } 1175 1176 static int spufs_mfc_fsync(struct file *file, struct dentry *dentry, 1177 int datasync) 1178 { 1179 return spufs_mfc_flush(file, NULL); 1180 } 1181 1182 static int spufs_mfc_fasync(int fd, struct file *file, int on) 1183 { 1184 struct spu_context *ctx = file->private_data; 1185 1186 return fasync_helper(fd, file, on, &ctx->mfc_fasync); 1187 } 1188 1189 static struct file_operations spufs_mfc_fops = { 1190 .open = spufs_mfc_open, 1191 .read = spufs_mfc_read, 1192 .write = spufs_mfc_write, 1193 .poll = spufs_mfc_poll, 1194 .flush = spufs_mfc_flush, 1195 .fsync = spufs_mfc_fsync, 1196 .fasync = spufs_mfc_fasync, 1197 #ifdef CONFIG_SPUFS_MMAP 1198 .mmap = spufs_mfc_mmap, 1199 #endif 1200 }; 1201 1202 static void spufs_npc_set(void *data, u64 val) 1203 { 1204 struct spu_context *ctx = data; 1205 spu_acquire(ctx); 1206 ctx->ops->npc_write(ctx, val); 1207 spu_release(ctx); 1208 } 1209 1210 static u64 spufs_npc_get(void *data) 1211 { 1212 struct spu_context *ctx = data; 1213 u64 ret; 1214 spu_acquire(ctx); 1215 ret = ctx->ops->npc_read(ctx); 1216 spu_release(ctx); 1217 return ret; 1218 } 1219 DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, "%llx\n") 1220 1221 static void spufs_decr_set(void *data, u64 val) 1222 { 1223 struct spu_context *ctx = data; 1224 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1225 spu_acquire_saved(ctx); 1226 lscsa->decr.slot[0] = (u32) val; 1227 spu_release(ctx); 1228 } 1229 1230 static u64 spufs_decr_get(void *data) 1231 { 1232 struct spu_context *ctx = data; 1233 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1234 u64 ret; 1235 spu_acquire_saved(ctx); 1236 ret = lscsa->decr.slot[0]; 1237 spu_release(ctx); 1238 return ret; 1239 } 1240 DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, 1241 "%llx\n") 1242 1243 static void spufs_decr_status_set(void *data, u64 val) 1244 { 1245 struct spu_context *ctx = data; 1246 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1247 spu_acquire_saved(ctx); 1248 lscsa->decr_status.slot[0] = (u32) val; 1249 spu_release(ctx); 1250 } 1251 1252 static u64 spufs_decr_status_get(void *data) 1253 { 1254 struct spu_context *ctx = data; 1255 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1256 u64 ret; 1257 spu_acquire_saved(ctx); 1258 ret = lscsa->decr_status.slot[0]; 1259 spu_release(ctx); 1260 return ret; 1261 } 1262 DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get, 1263 spufs_decr_status_set, "%llx\n") 1264 1265 static void spufs_spu_tag_mask_set(void *data, u64 val) 1266 { 1267 struct spu_context *ctx = data; 1268 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1269 spu_acquire_saved(ctx); 1270 lscsa->tag_mask.slot[0] = (u32) val; 1271 spu_release(ctx); 1272 } 1273 1274 static u64 spufs_spu_tag_mask_get(void *data) 1275 { 1276 struct spu_context *ctx = data; 1277 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1278 u64 ret; 1279 spu_acquire_saved(ctx); 1280 ret = lscsa->tag_mask.slot[0]; 1281 spu_release(ctx); 1282 return ret; 1283 } 1284 DEFINE_SIMPLE_ATTRIBUTE(spufs_spu_tag_mask_ops, spufs_spu_tag_mask_get, 1285 spufs_spu_tag_mask_set, "%llx\n") 1286 1287 static void spufs_event_mask_set(void *data, u64 val) 1288 { 1289 struct spu_context *ctx = data; 1290 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1291 spu_acquire_saved(ctx); 1292 lscsa->event_mask.slot[0] = (u32) val; 1293 spu_release(ctx); 1294 } 1295 1296 static u64 spufs_event_mask_get(void *data) 1297 { 1298 struct spu_context *ctx = data; 1299 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1300 u64 ret; 1301 spu_acquire_saved(ctx); 1302 ret = lscsa->event_mask.slot[0]; 1303 spu_release(ctx); 1304 return ret; 1305 } 1306 DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, 1307 spufs_event_mask_set, "%llx\n") 1308 1309 static void spufs_srr0_set(void *data, u64 val) 1310 { 1311 struct spu_context *ctx = data; 1312 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1313 spu_acquire_saved(ctx); 1314 lscsa->srr0.slot[0] = (u32) val; 1315 spu_release(ctx); 1316 } 1317 1318 static u64 spufs_srr0_get(void *data) 1319 { 1320 struct spu_context *ctx = data; 1321 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1322 u64 ret; 1323 spu_acquire_saved(ctx); 1324 ret = lscsa->srr0.slot[0]; 1325 spu_release(ctx); 1326 return ret; 1327 } 1328 DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set, 1329 "%llx\n") 1330 1331 static u64 spufs_id_get(void *data) 1332 { 1333 struct spu_context *ctx = data; 1334 u64 num; 1335 1336 spu_acquire(ctx); 1337 if (ctx->state == SPU_STATE_RUNNABLE) 1338 num = ctx->spu->number; 1339 else 1340 num = (unsigned int)-1; 1341 spu_release(ctx); 1342 1343 return num; 1344 } 1345 DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, 0, "0x%llx\n") 1346 1347 struct tree_descr spufs_dir_contents[] = { 1348 { "mem", &spufs_mem_fops, 0666, }, 1349 { "regs", &spufs_regs_fops, 0666, }, 1350 { "mbox", &spufs_mbox_fops, 0444, }, 1351 { "ibox", &spufs_ibox_fops, 0444, }, 1352 { "wbox", &spufs_wbox_fops, 0222, }, 1353 { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, 1354 { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, 1355 { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, 1356 { "signal1", &spufs_signal1_fops, 0666, }, 1357 { "signal2", &spufs_signal2_fops, 0666, }, 1358 { "signal1_type", &spufs_signal1_type, 0666, }, 1359 { "signal2_type", &spufs_signal2_type, 0666, }, 1360 { "mss", &spufs_mss_fops, 0666, }, 1361 { "mfc", &spufs_mfc_fops, 0666, }, 1362 { "cntl", &spufs_cntl_fops, 0666, }, 1363 { "npc", &spufs_npc_ops, 0666, }, 1364 { "fpcr", &spufs_fpcr_fops, 0666, }, 1365 { "decr", &spufs_decr_ops, 0666, }, 1366 { "decr_status", &spufs_decr_status_ops, 0666, }, 1367 { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, 1368 { "event_mask", &spufs_event_mask_ops, 0666, }, 1369 { "srr0", &spufs_srr0_ops, 0666, }, 1370 { "phys-id", &spufs_id_ops, 0666, }, 1371 {}, 1372 }; 1373