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 2012-02-05 10:06:29.087361680 +0100
25 +++ b/drivers/char/ps3physmem.c 2012-02-05 17:50:30.897909862 +0100
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/init.h>
51 +#include <linux/mm.h>
52 +#include <linux/fs.h>
53 +#include <linux/uaccess.h>
54 +#include <linux/miscdevice.h>
58 +#include <asm/lv1call.h>
60 +static unsigned long mem_start = 0;
61 +module_param(mem_start, ulong, 0);
63 +static unsigned long mem_size = 256 * 1024 * 1024;
64 +module_param(mem_size, ulong, 0);
66 +static unsigned long mem_pagesize = 24; /* 16MB */
67 +module_param(mem_pagesize, ulong, 0);
69 +static u64 ps3physmem_lpar;
70 +static char *ps3physmem_virt;
72 +static ssize_t ps3physmem_read(struct file *file, char __user *usrbuf,
73 + size_t count, loff_t *pos)
75 + if (*pos + count > mem_size)
76 + count = mem_size - *pos;
81 + if (copy_to_user(usrbuf, ps3physmem_virt + *pos, count))
89 +static ssize_t ps3physmem_write(struct file *file, const char __user *usrbuf,
90 + size_t count, loff_t *pos)
92 + if (*pos + count > mem_size)
93 + count = mem_size - *pos;
98 + if (copy_from_user(ps3physmem_virt + *pos, usrbuf, count))
106 +static void ps3physmem_vma_open(struct vm_area_struct *vma)
110 +static void ps3physmem_vma_close(struct vm_area_struct *vma)
114 +static struct vm_operations_struct ps3physmem_vm_ops = {
115 + .open = ps3physmem_vma_open,
116 + .close = ps3physmem_vma_close,
119 +static int ps3physmem_mmap(struct file *file, struct vm_area_struct *vma)
121 + unsigned long size, pfn;
124 + size = vma->vm_end - vma->vm_start;
126 + if (((vma->vm_pgoff << PAGE_SHIFT) + size) > mem_size)
129 + vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
130 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
132 + pfn = ((unsigned long) ps3physmem_virt >> PAGE_SHIFT) + vma->vm_pgoff;
134 + res = io_remap_pfn_range(vma, vma->vm_start, pfn, size,
135 + vma->vm_page_prot);
139 + vma->vm_ops = &ps3physmem_vm_ops;
141 + ps3physmem_vma_open(vma);
146 +static const struct file_operations ps3physmem_fops = {
147 + .owner = THIS_MODULE,
148 + .read = ps3physmem_read,
149 + .write = ps3physmem_write,
150 + .mmap = ps3physmem_mmap,
153 +static struct miscdevice ps3physmem_misc = {
154 + .minor = MISC_DYNAMIC_MINOR,
155 + .name = "ps3physmem",
156 + .fops = &ps3physmem_fops,
159 +static int __init ps3physmem_init(void)
163 + res = lv1_undocumented_function_114(mem_start,
164 + mem_pagesize, mem_size, &ps3physmem_lpar);
166 + pr_info("%s:%u: lv1_undocumented_function_114 failed %d\n",
167 + __func__, __LINE__, res);
171 + ps3physmem_virt = ioremap_nocache(ps3physmem_lpar, mem_size);
172 + if (!ps3physmem_virt) {
173 + pr_info("%s:%u: ioremap_nocache failed\n", __func__, __LINE__);
177 + res = misc_register(&ps3physmem_misc);
179 + pr_info("%s:%u: misc_register failed %d\n",
180 + __func__, __LINE__, res);
188 + iounmap((void *) ps3physmem_virt);
192 + lv1_undocumented_function_115(ps3physmem_lpar);
197 +static void __exit ps3physmem_exit(void)
199 + misc_deregister(&ps3physmem_misc);
201 + iounmap((void *) ps3physmem_virt);
203 + lv1_undocumented_function_115(ps3physmem_lpar);
206 +module_init(ps3physmem_init);
207 +module_exit(ps3physmem_exit);
209 +MODULE_AUTHOR("glevand");
210 +MODULE_DESCRIPTION("PS3 Physical Memory Driver");
211 +MODULE_LICENSE("GPL");