initial import
[ps3linux_kernel_patches_40.git] / 0240-ps3lv1call.patch
blob6490aff8e36aea038acd27f55e77ca69bf6c5f60
1 --- a/drivers/char/Makefile 2012-10-27 02:15:23.000000000 -0800
2 +++ b/drivers/char/Makefile 2012-10-27 02:16:28.000000000 -0800
3 @@ -67,3 +67,4 @@
4 obj-$(CONFIG_PS3_PHYSMEM) += ps3physmem.o
5 obj-$(CONFIG_PS3_STRGMNGR) += ps3strgmngr.o
6 obj-$(CONFIG_PS3_ENCDEC) += ps3encdec.o
7 +obj-$(CONFIG_PS3_LV1CALL) += ps3lv1call/
8 --- a/arch/powerpc/platforms/ps3/Kconfig 2012-10-27 02:11:58.000000000 -0800
9 +++ b/arch/powerpc/platforms/ps3/Kconfig 2012-10-27 02:13:08.000000000 -0800
10 @@ -228,6 +228,12 @@
11 help
12 The isolated SPU loader file system is used to execute isolated SPU loaders.
14 +config PS3_LV1CALL
15 + tristate "PS3 LV1 Call Driver"
16 + depends on PPC_PS3
17 + help
18 + This driver allows you to execute LV1 calls.
20 config PS3GELIC_UDBG
21 bool "PS3 udbg output via UDP broadcasts on Ethernet"
22 depends on PPC_PS3
23 --- /dev/null 2012-10-27 01:55:30.097760558 -0800
24 +++ b/drivers/char/ps3lv1call/Makefile 2012-10-27 02:10:35.000000000 -0800
25 @@ -0,0 +1,4 @@
27 +ps3lv1call-y := ps3lv1call_misc.o generic_lv1call.o
29 +obj-$(CONFIG_PS3_LV1CALL) += ps3lv1call.o
30 --- /dev/null 2012-10-27 01:55:30.097760558 -0800
31 +++ b/drivers/char/ps3lv1call/generic_lv1call.S 2012-10-27 02:08:57.000000000 -0800
32 @@ -0,0 +1,54 @@
33 +/*
34 + * PS3 Generic LV1 Call
35 + *
36 + * Copyright (C) 2012 glevand <geoffrey.levand@mail.ru>
37 + * All rights reserved.
38 + *
39 + * This program is free software; you can redistribute it and/or modify it
40 + * under the terms of the GNU General Public License as published
41 + * by the Free Software Foundation; version 2 of the License.
42 + *
43 + * This program is distributed in the hope that it will be useful, but
44 + * WITHOUT ANY WARRANTY; without even the implied warranty of
45 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
46 + * General Public License for more details.
47 + *
48 + * You should have received a copy of the GNU General Public License along
49 + * with this program; if not, write to the Free Software Foundation, Inc.,
50 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
51 + */
53 +#include <asm/processor.h>
54 +#include <asm/ppc_asm.h>
56 +#define lv1call .long 0x44000022; extsw r3, r3
58 +_GLOBAL(generic_lv1call)
59 + mflr r0
60 + std r0, 16(r1)
61 + std r3, -8(r1)
62 + std r4, -16(r1)
63 + stdu r5, -24(r1)
64 + mr r11, r4
65 + ld r3, 0(r11)
66 + ld r4, 8(r11)
67 + ld r5, 16(r11)
68 + ld r6, 24(r11)
69 + ld r7, 32(r11)
70 + ld r8, 40(r11)
71 + ld r9, 48(r11)
72 + ld r10, 56(r11)
73 + ld r11, 16(r1)
74 + lv1call
75 + addi r1, r1, 24
76 + ld r11, -24(r1)
77 + std r4, 0(r11)
78 + std r5, 8(r11)
79 + std r6, 16(r11)
80 + std r7, 24(r11)
81 + std r8, 32(r11)
82 + std r9, 40(r11)
83 + std r10, 48(r11)
84 + ld r0, 16(r1)
85 + mtlr r0
86 + blr
87 --- /dev/null 2013-02-13 19:35:09.393146190 +0100
88 +++ b/drivers/char/ps3lv1call/ps3lv1call_misc.c 2013-02-12 20:22:36.473200805 +0100
89 @@ -0,0 +1,158 @@
90 +/*
91 + * PS3 LV1 Call
92 + *
93 + * Copyright (C) 2012, 2013 glevand <geoffrey.levand@mail.ru>
94 + * All rights reserved.
95 + *
96 + * This program is free software; you can redistribute it and/or modify it
97 + * under the terms of the GNU General Public License as published
98 + * by the Free Software Foundation; version 2 of the License.
99 + *
100 + * This program is distributed in the hope that it will be useful, but
101 + * WITHOUT ANY WARRANTY; without even the implied warranty of
102 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
103 + * General Public License for more details.
105 + * You should have received a copy of the GNU General Public License along
106 + * with this program; if not, write to the Free Software Foundation, Inc.,
107 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
108 + */
110 +#include <linux/module.h>
111 +#include <linux/kernel.h>
112 +#include <linux/init.h>
113 +#include <linux/mm.h>
114 +#include <linux/fs.h>
115 +#include <linux/uaccess.h>
116 +#include <linux/miscdevice.h>
118 +static struct
120 + int num_in_args;
121 + int num_out_args;
122 +} ps3lv1call_args[256] = {
123 + [8] = { 0, 1 }, /* lv1_undocumented_function_8 */
124 + [44] = { 1, 0 }, /* lv1_shutdown_logical_partition */
125 + [91] = { 5, 2 }, /* lv1_read_repository_node */
126 + [102] = { 0, 1 }, /* lv1_undocumented_function_102 */
127 + [105] = { 7, 0 }, /* lv1_undocumented_function_105 */
128 + [106] = { 1, 0 }, /* lv1_undocumented_function_106 */
129 + [107] = { 6, 1 }, /* lv1_undocumented_function_107 */
130 + [108] = { 1, 5 }, /* lv1_undocumented_function_108 */
131 + [109] = { 1, 0 }, /* lv1_undocumented_function_109 */
132 + [127] = { 0, 2 }, /* lv1_get_version_info */
133 + [194] = { 6, 2 }, /* lv1_net_control */
134 + [231] = { 1, 0 }, /* lv1_undocumented_function_231 */
135 + [232] = { 0, 2 }, /* lv1_get_rtc */
136 + [255] = { 1, 0 }, /* lv1_panic */
139 +extern int generic_lv1call(int num_lv1call, u64 *in_args, u64 *out_args);
141 +static ssize_t ps3lv1call_do_call(char *buf, size_t size)
143 + u64 num_lv1call;
144 + u64 args[8];
145 + s64 err;
146 + int num_args, i, rv;
148 + if (size < sizeof(u64))
149 + return (-EINVAL);
151 + if (size % sizeof(u64))
152 + return (-EINVAL);
154 + num_lv1call = *(u64 *) buf;
155 + if (num_lv1call > 255)
156 + return (-EINVAL);
158 + num_args = (size - sizeof(u64)) / sizeof(u64);
159 + if (num_args > 8)
160 + return (-EINVAL);
162 + memset(args, 0, sizeof(args));
164 + for (i = 0; i < num_args; i++)
165 + args[i] = *(u64 *) (buf + (i + 1) * sizeof(u64));
167 + err = generic_lv1call(num_lv1call, args, args);
169 + rv = sizeof(err);
170 + memcpy(buf, &err, sizeof(err));
172 + if (!err) {
173 + rv += ps3lv1call_args[num_lv1call].num_out_args * sizeof(u64);
174 + memcpy(buf + sizeof(err), args,
175 + ps3lv1call_args[num_lv1call].num_out_args * sizeof(u64));
178 + return (rv);
181 +static ssize_t ps3lv1call_write(struct file *file, const char __user *buf,
182 + size_t size, loff_t *pos)
184 + char *data;
185 + ssize_t rv;
187 + data = simple_transaction_get(file, buf, size);
188 + if (IS_ERR(data))
189 + return PTR_ERR(data);
191 + rv = ps3lv1call_do_call(data, size);
192 + if (rv >= 0) {
193 + simple_transaction_set(file, rv);
194 + rv = size;
197 + return (rv);
200 +static ssize_t ps3lv1call_read(struct file *file, char __user *buf,
201 + size_t size, loff_t *pos)
203 + ssize_t rv;
205 + if (!file->private_data) {
206 + rv = ps3lv1call_write(file, buf, 0, pos);
207 + if (rv < 0)
208 + return (rv);
211 + return simple_transaction_read(file, buf, size, pos);
214 +static const struct file_operations ps3lv1call_fops = {
215 + .owner = THIS_MODULE,
216 + .write = ps3lv1call_write,
217 + .read = ps3lv1call_read,
218 + .release = simple_transaction_release,
219 + .llseek = default_llseek,
222 +static struct miscdevice ps3lv1call_misc = {
223 + .minor = MISC_DYNAMIC_MINOR,
224 + .name = "ps3lv1call",
225 + .fops = &ps3lv1call_fops,
228 +static int __init ps3lv1call_init(void)
230 + int err;
232 + err = misc_register(&ps3lv1call_misc);
234 + return (err);
237 +static void __exit ps3lv1call_exit(void)
239 + misc_deregister(&ps3lv1call_misc);
242 +module_init(ps3lv1call_init);
243 +module_exit(ps3lv1call_exit);
245 +MODULE_AUTHOR("glevand");
246 +MODULE_DESCRIPTION("PS3 LV1 Call");
247 +MODULE_LICENSE("GPL");