1 --- a/drivers/char/Makefile 2012-02-03 21:39:51.000000000 +0100
2 +++ b/drivers/char/Makefile 2012-02-05 17:51:57.339262786 +0100
6 obj-$(CONFIG_TILE_SROM) += tile-srom.o
8 +obj-$(CONFIG_PS3_PHYSMEM) += ps3physmem.o
9 --- a/arch/powerpc/platforms/ps3/Kconfig 2012-02-04 21:13:42.539806178 +0100
10 +++ b/arch/powerpc/platforms/ps3/Kconfig 2012-02-05 17:54:38.698430717 +0100
12 profiling support of the Cell processor with programs like
13 oprofile and perfmon2, then say Y or M, otherwise say N.
16 + tristate "PS3 Physical Memory Driver"
19 + This driver allows you direct access to the PS3 physical memory.
22 bool "PS3 udbg output via UDP broadcasts on Ethernet"
24 --- /dev/null 2014-05-18 16:58:36.900768386 +0200
25 +++ b/drivers/char/ps3physmem.c 2014-05-19 00:35:46.782364178 +0200
28 + * PS3 Physical Memory Driver
30 + * Copyright (C) 2011 graf_chokolo <grafchokolo@gmail.com>
31 + * Copyright (C) 2011, 2012 glevand <geoffrey.levand@mail.ru>
32 + * All rights reserved.
34 + * This program is free software; you can redistribute it and/or modify it
35 + * under the terms of the GNU General Public License as published
36 + * by the Free Software Foundation; version 2 of the License.
38 + * This program is distributed in the hope that it will be useful, but
39 + * WITHOUT ANY WARRANTY; without even the implied warranty of
40 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41 + * General Public License for more details.
43 + * You should have received a copy of the GNU General Public License along
44 + * with this program; if not, write to the Free Software Foundation, Inc.,
45 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
48 +#include <linux/module.h>
49 +#include <linux/kernel.h>
50 +#include <linux/version.h>
51 +#include <linux/init.h>
52 +#include <linux/mm.h>
53 +#include <linux/fs.h>
54 +#include <linux/uaccess.h>
55 +#include <linux/miscdevice.h>
59 +#include <asm/lv1call.h>
61 +static unsigned long ps3physmem_start = 0;
62 +module_param(ps3physmem_start, ulong, 0);
64 +static unsigned long ps3physmem_size = 256 * 1024 * 1024;
65 +module_param(ps3physmem_size, ulong, 0);
67 +static unsigned long ps3physmem_pagesize = 24; /* 16MB */
68 +module_param(ps3physmem_pagesize, ulong, 0);
70 +static u64 ps3physmem_lpar;
71 +static char *ps3physmem_virt;
73 +static ssize_t ps3physmem_read(struct file *file, char __user *usrbuf,
74 + size_t count, loff_t *pos)
76 + if (*pos + count > ps3physmem_size)
77 + count = ps3physmem_size - *pos;
82 + if (copy_to_user(usrbuf, ps3physmem_virt + *pos, count))
90 +static ssize_t ps3physmem_write(struct file *file, const char __user *usrbuf,
91 + size_t count, loff_t *pos)
93 + if (*pos + count > ps3physmem_size)
94 + count = ps3physmem_size - *pos;
99 + if (copy_from_user(ps3physmem_virt + *pos, usrbuf, count))
107 +static loff_t ps3physmem_llseek(struct file *file, loff_t off, int whence)
112 + case 0: /* SEEK_SET */
115 + case 1: /* SEEK_CUR */
116 + newpos = file->f_pos + off;
118 + case 2: /* SEEK_END */
119 + newpos = ps3physmem_size + off;
121 + default: /* can't happen */
128 + file->f_pos = newpos;
133 +static void ps3physmem_vma_open(struct vm_area_struct *vma)
137 +static void ps3physmem_vma_close(struct vm_area_struct *vma)
141 +static struct vm_operations_struct ps3physmem_vm_ops = {
142 + .open = ps3physmem_vma_open,
143 + .close = ps3physmem_vma_close,
146 +static int ps3physmem_mmap(struct file *file, struct vm_area_struct *vma)
148 + unsigned long size, pfn;
151 + size = vma->vm_end - vma->vm_start;
153 + if (((vma->vm_pgoff << PAGE_SHIFT) + size) > ps3physmem_size)
156 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
157 + vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
159 + vma->vm_flags |= VM_RESERVED | VM_IO;
161 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
163 + pfn = (ps3physmem_lpar >> PAGE_SHIFT) + vma->vm_pgoff;
165 + res = io_remap_pfn_range(vma, vma->vm_start, pfn, size,
166 + vma->vm_page_prot);
170 + vma->vm_ops = &ps3physmem_vm_ops;
172 + ps3physmem_vma_open(vma);
177 +static const struct file_operations ps3physmem_fops = {
178 + .owner = THIS_MODULE,
179 + .read = ps3physmem_read,
180 + .write = ps3physmem_write,
181 + .llseek = ps3physmem_llseek,
182 + .mmap = ps3physmem_mmap,
185 +static struct miscdevice ps3physmem_misc = {
186 + .minor = MISC_DYNAMIC_MINOR,
187 + .name = "ps3physmem",
188 + .fops = &ps3physmem_fops,
191 +static int __init ps3physmem_init(void)
195 + res = lv1_undocumented_function_114(ps3physmem_start,
196 + ps3physmem_pagesize, ps3physmem_size, &ps3physmem_lpar);
198 + pr_info("%s:%u: lv1_undocumented_function_114 failed %d\n",
199 + __func__, __LINE__, res);
203 + ps3physmem_virt = ioremap_nocache(ps3physmem_lpar, ps3physmem_size);
204 + if (!ps3physmem_virt) {
205 + pr_info("%s:%u: ioremap_nocache failed\n", __func__, __LINE__);
209 + res = misc_register(&ps3physmem_misc);
211 + pr_info("%s:%u: misc_register failed %d\n",
212 + __func__, __LINE__, res);
220 + iounmap((void *) ps3physmem_virt);
224 + lv1_undocumented_function_115(ps3physmem_lpar);
229 +static void __exit ps3physmem_exit(void)
231 + misc_deregister(&ps3physmem_misc);
233 + iounmap((void *) ps3physmem_virt);
235 + lv1_undocumented_function_115(ps3physmem_lpar);
238 +module_init(ps3physmem_init);
239 +module_exit(ps3physmem_exit);
241 +MODULE_AUTHOR("glevand");
242 +MODULE_DESCRIPTION("PS3 Physical Memory Driver");
243 +MODULE_LICENSE("GPL");