revised usage message
[ps3hvc-utils.git] / ps3hvc_hvcall.c
blob5c81c3616972f201944ce47f1b62f33235f33036
2 /*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; version 2 of the License.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <getopt.h>
21 #include <errno.h>
23 #include "ps3hvc_dev.h"
25 #define PS3HVC_HVCALL_VERSION "0.0.1"
27 struct opts
29 char *device_name;
30 char *cmd;
31 int do_help;
32 int do_verbose;
33 int do_version;
36 static struct option long_opts[] = {
37 { "help", no_argument, NULL, 'h' },
38 { "verbose", no_argument, NULL, 'v' },
39 { "version", no_argument, NULL, 'V' },
40 { NULL, 0, NULL, 0 }
44 * usage
46 static void usage(void) {
47 fprintf(stderr,
48 "Usage: ps3hvc_hvcall [OPTIONS] DEVICE COMMAND [ARGS]\n"
49 "\n"
50 "Options:\n"
51 " -h, --help Show this message and exit\n"
52 " -v, --verbose Increase verbosity\n"
53 " -V, --version Show version information and exit\n"
54 "Commands:\n"
55 " undocumented_function_8 Returns current uptime\n"
56 " construct_event_receive_port Constructs outlet\n"
57 " destruct_event_receive_port OUTLETID Destructs outlet\n"
58 " get_repo_node_val LPARID KEY0 KEY1 KEY2 KEY3 Returns repository node value\n"
59 " panic ARG1 Panics\n"
60 "\n\n"
61 "Simple example: Reboot after panic:\n"
62 " ps3hvc_hvcall /dev/ps3hvc panic 1\n");
66 * version
68 static void version(void)
70 fprintf(stderr,
71 "ps3hvc_hvcall " PS3HVC_HVCALL_VERSION "\n"
72 "Copyright (C) 2011 graf_chokolo <grafchokolo@googlemail.com>\n"
73 "This is free software. You may redistribute copies of it "
74 "under the terms of\n"
75 "the GNU General Public License 2 "
76 "<http://www.gnu.org/licenses/gpl2.html>.\n"
77 "There is NO WARRANTY, to the extent permitted by law.\n");
81 * process_opts
83 static int process_opts(int argc, char **argv, struct opts *opts)
85 int c;
87 while ((c = getopt_long(argc, argv, "hvV", long_opts, NULL)) != -1) {
88 switch (c) {
89 case 'h':
90 case '?':
91 opts->do_help = 1;
92 return 0;
94 case 'v':
95 opts->do_verbose++;
96 break;
98 case 'V':
99 opts->do_version = 1;
100 return 0;
102 default:
103 fprintf(stderr, "Invalid command option: %c\n", c);
104 return -1;
108 if (optind >= argc) {
109 fprintf(stderr, "No device specified\n");
110 return -1;
113 opts->device_name = argv[optind];
114 optind++;
116 if (optind >= argc) {
117 fprintf(stderr, "No command specified\n");
118 return -1;
121 opts->cmd = argv[optind];
122 optind++;
124 return 0;
128 * cmd_undocumented_function_8
130 static int cmd_undocumented_function_8(int fd, struct opts *opts, int argc, char **argv)
132 uint64_t args[1];
133 int64_t result;
134 int error;
136 error = ps3hvc_dev_hvcall(fd, PS3HVC_HVCALL_UNDOCUMENTED_FUNCTION_8, 0, 1, args, &result);
138 if (error)
139 fprintf(stderr, "%s: %s\n", opts->device_name, strerror(errno));
140 else if (result)
141 fprintf(stderr, "hvcall result: 0x%016lx\n", result);
142 else
143 fprintf(stdout, "0x%016lx\n", args[0]);
145 return error;
149 * cmd_construct_event_receive_port
151 static int cmd_construct_event_receive_port(int fd, struct opts *opts, int argc, char **argv)
153 uint64_t args[1];
154 int64_t result;
155 int error;
157 error = ps3hvc_dev_hvcall(fd, PS3HVC_HVCALL_CONSTRUCT_EVENT_RECEIVE_PORT, 0, 1, args, &result);
159 if (error)
160 fprintf(stderr, "%s: %s\n", opts->device_name, strerror(errno));
161 else if (result)
162 fprintf(stderr, "hvcall result: 0x%016lx\n", result);
163 else
164 fprintf(stdout, "0x%016lx\n", args[0]);
166 return error;
170 * cmd_destruct_event_receive_port
172 static int cmd_destruct_event_receive_port(int fd, struct opts *opts, int argc, char **argv)
174 uint64_t outletid;
175 char *endptr;
176 uint64_t args[1];
177 int64_t result;
178 int error;
180 if (optind >= argc) {
181 fprintf(stderr, "No outlet identifier specified\n");
182 return -1;
185 outletid = strtoull(argv[optind], &endptr, 0);
186 if (*endptr != '\0') {
187 fprintf(stderr, "Invalid outlet identifier specified: %s\n", argv[optind]);
188 return -1;
191 optind++;
193 args[0] = outletid;
195 error = ps3hvc_dev_hvcall(fd, PS3HVC_HVCALL_DESTRUCT_EVENT_RECEIVE_PORT, 1, 0, args, &result);
197 if (error)
198 fprintf(stderr, "%s: %s\n", opts->device_name, strerror(errno));
199 else
200 fprintf(stderr, "hvcall result: 0x%016lx\n", result);
202 return error;
206 * cmd_get_repo_node_val
208 static int cmd_get_repo_node_val(int fd, struct opts *opts, int argc, char **argv)
210 uint64_t lpar_id, key[4];
211 char *endptr, *opt;
212 uint64_t args[7];
213 int64_t result;
214 int i, error;
216 if (optind >= argc) {
217 fprintf(stderr, "No LPAR identifier specified\n");
218 return -1;
221 lpar_id = strtoull(argv[optind], &endptr, 0);
222 if (*endptr != '\0') {
223 fprintf(stderr, "Invalid LPAR identifier specified: %s\n", argv[optind]);
224 return -1;
227 optind++;
229 for (i = 0; i < 4; i++) {
230 if (optind >= argc) {
231 fprintf(stderr, "No key #%d specified\n", i);
232 return -1;
235 opt = argv[optind++];
236 key[i] = strtoull(opt, &endptr, 0);
237 if ((*opt == '\0') || (*endptr != '\0')) {
238 fprintf(stderr, "Invalid key #%d specified: %s\n", i, opt);
239 return -1;
243 args[0] = lpar_id;
244 memcpy(&args[1], key, sizeof(key));
246 error = ps3hvc_dev_hvcall(fd, PS3HVC_HVCALL_GET_REPO_NODE_VAL, 5, 2, args, &result);
248 if (error) {
249 fprintf(stderr, "%s: %s\n", opts->device_name, strerror(errno));
250 } else if (result) {
251 fprintf(stderr, "hvcall result: 0x%016lx\n", result);
252 } else {
253 fprintf(stdout, "0x%016lx 0x%016lx\n", args[5], args[6]);
256 return error;
260 * cmd_panic
262 static int cmd_panic(int fd, struct opts *opts, int argc, char **argv)
264 uint64_t arg1;
265 char *endptr;
266 uint64_t args[1];
267 int64_t result;
268 int error;
270 if (optind >= argc) {
271 fprintf(stderr, "No ARG1 specified\n");
272 return -1;
275 arg1 = strtoull(argv[optind], &endptr, 0);
276 if (*endptr != '\0') {
277 fprintf(stderr, "Invalid ARG1 specified: %s\n", argv[optind]);
278 return -1;
281 optind++;
283 args[0] = arg1;
285 error = ps3hvc_dev_hvcall(fd, PS3HVC_HVCALL_PANIC, 1, 0, args, &result);
287 if (error)
288 fprintf(stderr, "%s: %s\n", opts->device_name, strerror(errno));
289 else
290 fprintf(stderr, "hvcall result: 0x%016lx\n", result);
292 return error;
296 * main
298 int main(int argc, char **argv)
300 struct opts opts;
301 int fd = 0, error = 0;
303 memset(&opts, 0, sizeof(opts));
305 if (process_opts(argc, argv, &opts)) {
306 usage();
307 error = 1;
308 goto done;
311 if (opts.do_help) {
312 usage();
313 goto done;
314 } else if (opts.do_version) {
315 version();
316 goto done;
319 fd = ps3hvc_dev_open(opts.device_name);
320 if (fd < 0) {
321 fprintf(stderr, "%s: %s\n", opts.device_name, strerror(errno));
322 error = 2;
323 goto done;
326 if (!strcmp(opts.cmd, "undocumented_function_8")) {
327 error = cmd_undocumented_function_8(fd, &opts, argc, argv);
328 } else if (!strcmp(opts.cmd, "construct_event_receive_port")) {
329 error = cmd_construct_event_receive_port(fd, &opts, argc, argv);
330 } else if (!strcmp(opts.cmd, "destruct_event_receive_port")) {
331 error = cmd_destruct_event_receive_port(fd, &opts, argc, argv);
332 } else if (!strcmp(opts.cmd, "get_repo_node_val")) {
333 error = cmd_get_repo_node_val(fd, &opts, argc, argv);
334 } else if (!strcmp(opts.cmd, "panic")) {
335 error = cmd_panic(fd, &opts, argc, argv);
336 } else {
337 usage();
338 error = 1;
339 goto done;
342 if (error)
343 error = 3;
345 done:
347 if (fd >= 0)
348 ps3hvc_dev_close(fd);
350 exit(error);