Advertisement
Guest User

Untitled

a guest
Sep 6th, 2017
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.88 KB | None | 0 0
  1. Makefile
  2. obj-m += ps3bemmio.o
  3.  
  4. all:
  5.     make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
  6.  
  7. clean:
  8.     make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
  9.  
  10. ps3bemmio.c
  11. /*
  12.  * PS3 Cell B.E. MMIO Driver
  13.  *
  14.  * This program is free software; you can redistribute it and/or modify it
  15.  * under the terms of the GNU General Public License as published
  16.  * by the Free Software Foundation; version 2 of the License.
  17.  *
  18.  * This program is distributed in the hope that it will be useful, but
  19.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  21.  * General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License along
  24.  * with this program; if not, write to the Free Software Foundation, Inc.,
  25.  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  26.  */
  27.  
  28. #include <linux/fs.h>
  29. #include <linux/miscdevice.h>
  30. #include <linux/slab.h>
  31. #include <linux/uaccess.h>
  32. #include <linux/mmzone.h>
  33. #include <linux/io.h>
  34. #include <linux/mm.h>
  35.  
  36. #include <asm/lv1call.h>
  37. #include <asm/ps3.h>
  38.  
  39. #define DEVICE_NAME "ps3bemmio"
  40.  
  41. #define MMAP_START_ADDR 0x20000000000ull
  42. #define MMAP_SIZE       0x00800000000ull
  43.  
  44. static u64 ps3be_mmio_lpar_addr;
  45.  
  46. static u8* ps3be_mmio;
  47.  
  48. static loff_t ps3be_mmio_llseek(struct file* file, loff_t offset, int origin)
  49. {
  50.     loff_t res;
  51.  
  52.     mutex_lock(&file->f_mapping->host->i_mutex);
  53.  
  54.     switch (origin) {
  55.         case 1:
  56.             offset += file->f_pos;
  57.             break;
  58.         case 2:
  59.             offset += MMAP_SIZE;
  60.             break;
  61.     }
  62.  
  63.     if (offset < 0) {
  64.         res = -EINVAL;
  65.         goto out;
  66.     }
  67.  
  68.     file->f_pos = offset;
  69.     res = file->f_pos;
  70.  
  71. out:
  72.     mutex_unlock(&file->f_mapping->host->i_mutex);
  73.  
  74.     return res;
  75. }
  76.  
  77. static ssize_t ps3be_mmio_read(struct file* file, char __user* buf, size_t count, loff_t* pos)
  78. {
  79.     u64 size;
  80.     u8* src;
  81.     int res;
  82.  
  83.     pr_debug("%s:%u: Reading %zu bytes at position %lld to U0x%p\n", __func__, __LINE__, count, *pos, buf);
  84.  
  85.     size = MMAP_SIZE;
  86.     if (*pos >= size || !count)
  87.         return 0;
  88.  
  89.     if (*pos + count > size) {
  90.         pr_debug("%s:%u Truncating count from %zu to %llu\n", __func__, __LINE__, count, size - *pos);
  91.         count = size - *pos;
  92.     }
  93.  
  94.     src = ps3be_mmio + *pos;
  95.  
  96.     pr_debug("%s:%u: copy %lu bytes from 0x%p to U0x%p\n", __func__, __LINE__, count, src, buf);
  97.  
  98.     if (buf) {
  99.         if (copy_to_user(buf, src, count)) {
  100.             res = -EFAULT;
  101.             goto fail;
  102.         }
  103.     }
  104.  
  105.     *pos += count;
  106.  
  107.     return count;
  108.  
  109. fail:
  110.     return res;
  111. }
  112.  
  113. static ssize_t ps3be_mmio_write(struct file* file, const char __user* buf, size_t count, loff_t* pos)
  114. {
  115.     u64 size;
  116.     u8* dst;
  117.     int res;
  118.  
  119.     pr_debug("%s:%u: Writing %zu bytes at position %lld from U0x%p\n", __func__, __LINE__, count, *pos, buf);
  120.  
  121.     size = MMAP_SIZE;
  122.     if (*pos >= size || !count)
  123.         return 0;
  124.  
  125.     if (*pos + count > size) {
  126.         pr_debug("%s:%u Truncating count from %zu to %llu\n", __func__, __LINE__, count, size - *pos);
  127.         count = size - *pos;
  128.     }
  129.  
  130.     dst = ps3be_mmio + *pos;
  131.  
  132.     pr_debug("%s:%u: copy %lu bytes from U0x%p to 0x%p\n", __func__, __LINE__, count, buf, dst);
  133.  
  134.     if (buf) {
  135.         if (copy_from_user(dst, buf, count)) {
  136.             res = -EFAULT;
  137.             goto fail;
  138.         }
  139.     }
  140.  
  141.     *pos += count;
  142.  
  143.     return count;
  144.  
  145. fail:
  146.  
  147.     return res;
  148. }
  149.  
  150. static const struct file_operations ps3be_mmio_fops = {
  151.     .owner = THIS_MODULE,
  152.     .llseek = ps3be_mmio_llseek,
  153.     .read = ps3be_mmio_read,
  154.     .write = ps3be_mmio_write,
  155. };
  156.  
  157. static struct miscdevice ps3be_mmio_misc = {
  158.     .minor = MISC_DYNAMIC_MINOR,
  159.     .name = DEVICE_NAME,
  160.     .fops = &ps3be_mmio_fops,
  161. };
  162.  
  163. static int __init ps3be_mmio_init(void)
  164. {
  165.     int res;
  166.  
  167.     res = lv1_undocumented_function_114(MMAP_START_ADDR, PAGE_SHIFT, MMAP_SIZE, &ps3be_mmio_lpar_addr);
  168.     if (res) {
  169.         pr_debug("%s:%u: lpar map failed %d\n", __func__, __LINE__, res);
  170.         res = -EFAULT;
  171.         goto fail;
  172.     }
  173.  
  174.     ps3be_mmio = ioremap_flags(ps3be_mmio_lpar_addr, MMAP_SIZE, _PAGE_NO_CACHE);
  175.     if (!ps3be_mmio) {
  176.         pr_debug("%s:%d: ioremap_flags failed\n", __func__, __LINE__);
  177.         res = -EFAULT;
  178.         goto fail_lpar_unmap;
  179.     }
  180.  
  181.     res = misc_register(&ps3be_mmio_misc);
  182.     if (res) {
  183.         pr_debug("%s:%u: misc_register failed %d\n", __func__, __LINE__, res);
  184.         goto fail_iounmap;
  185.     }
  186.  
  187.     pr_debug("%s:%u: registered misc device %d\n", __func__, __LINE__, ps3be_mmio_misc.minor);
  188.  
  189.     return 0;
  190.  
  191. fail_iounmap:
  192.     iounmap(ps3be_mmio);
  193.  
  194. fail_lpar_unmap:
  195.     lv1_undocumented_function_115(ps3be_mmio_lpar_addr);
  196.  
  197. fail:
  198.     return res;
  199. }
  200.  
  201. static void __exit ps3be_mmio_exit(void)
  202. {
  203.     misc_deregister(&ps3be_mmio_misc);
  204.  
  205.     iounmap(ps3be_mmio);
  206.  
  207.     lv1_undocumented_function_115(ps3be_mmio_lpar_addr);
  208. }
  209.  
  210. module_init(ps3be_mmio_init);
  211. module_exit(ps3be_mmio_exit);
  212.  
  213. MODULE_LICENSE("GPL v2");
  214. MODULE_DESCRIPTION("PS3 Cell B.E. MMIO Driver");
  215. MODULE_AUTHOR("flatz");
  216.  
  217. Example of getting a serial number (customer ID)
  218.  
  219. insmod ps3bemmio.ko
  220. dd if=/dev/ps3bemmio bs=1 count=8 skip=$((0x509C80)) status=noxfer | hexdump -C
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement