ps3dm_sm: set_del_encdec_key: fixed description for default key
[ps3dm-utils.git] / ps3dm_scm.c
blob82a5c2b4484828dc506c71d94dce0d4bdbe1d157
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 "ps3dm_proxy.h"
24 #include "ps3dm.h"
25 #include "ps3ss.h"
27 #define PS3DM_SCM_VERSION "0.0.1"
29 #define PS3DM_SCM_LAID 0x1070000002000001ull
30 #define PS3DM_SCM_PAID 0x10700003ff000001ull
32 struct opts
34 char *device_name;
35 char *cmd;
36 int do_help;
37 int do_verbose;
38 int do_version;
41 static struct option long_opts[] = {
42 { "help", no_argument, NULL, 'h' },
43 { "verbose", no_argument, NULL, 'v' },
44 { "version", no_argument, NULL, 'V' },
45 { NULL, 0, NULL, 0 }
49 * usage
51 static void usage(void) {
52 fprintf(stderr,
53 "Usage: ps3dm_scm [OPTIONS] DEVICE COMMAND [ARGS]\n"
54 "\n"
55 "Options:\n"
56 " -h, --help Show this message and exit\n"
57 " -v, --verbose Increase verbosity\n"
58 " -V, --version Show version information and exit\n"
59 "Commands:\n"
60 " get_region_data ID Reads region data\n"
61 " get_time TID Returns RTC time\n"
62 " read_eprom OFFSET SIZE Reads EPROM data\n"
63 " get_sc_status Returns SYSCON status\n"
64 "\n\n"
65 "Simple example: Get SYSCON status:\n"
66 " ps3dm_scm /dev/ps3dmproxy get_sc_status\n");
70 * version
72 static void version(void)
74 fprintf(stderr,
75 "ps3dm_scm " PS3DM_SCM_VERSION "\n"
76 "Copyright (C) 2011 graf_chokolo <grafchokolo@googlemail.com>\n"
77 "This is free software. You may redistribute copies of it "
78 "under the terms of\n"
79 "the GNU General Public License 2 "
80 "<http://www.gnu.org/licenses/gpl2.html>.\n"
81 "There is NO WARRANTY, to the extent permitted by law.\n");
85 * process_opts
87 static int process_opts(int argc, char **argv, struct opts *opts)
89 int c;
91 while ((c = getopt_long(argc, argv, "hvV", long_opts, NULL)) != -1) {
92 switch (c) {
93 case 'h':
94 case '?':
95 opts->do_help = 1;
96 return 0;
98 case 'v':
99 opts->do_verbose++;
100 break;
102 case 'V':
103 opts->do_version = 1;
104 return 0;
106 default:
107 fprintf(stderr, "Invalid command option: %c\n", c);
108 return -1;
112 if (optind >= argc) {
113 fprintf(stderr, "No device specified\n");
114 return -1;
117 opts->device_name = argv[optind];
118 optind++;
120 if (optind >= argc) {
121 fprintf(stderr, "No command specified\n");
122 return -1;
125 opts->cmd = argv[optind];
126 optind++;
128 return 0;
132 * cmd_get_region_data
134 static int cmd_get_region_data(int fd, struct opts *opts, int argc, char **argv)
136 uint64_t id;
137 char *endptr;
138 uint8_t buf[256];
139 struct ps3dm_hdr *dm_hdr;
140 struct ps3ss_hdr *ss_hdr;
141 struct ps3ss_scm_get_region_data *ss_scm_get_region_data;
142 int error, i;
144 if (optind >= argc) {
145 fprintf(stderr, "No id specified\n");
146 return -1;
149 id = strtoul(argv[optind], &endptr, 0);
150 if (*endptr != '\0') {
151 fprintf(stderr, "Invalid id specified: %s\n", argv[optind]);
152 return -1;
155 optind++;
157 memset(buf, 0, sizeof(buf));
158 dm_hdr = (struct ps3dm_hdr *) buf;
159 ss_hdr = (struct ps3ss_hdr *)(dm_hdr + 1);
160 ss_scm_get_region_data = (struct ps3ss_scm_get_region_data *)(ss_hdr + 1);
162 dm_hdr->request_id = 1;
163 dm_hdr->function_id = PS3SS_FID_SCM;
164 dm_hdr->request_size = PS3SS_HDR_SIZE + sizeof(struct ps3ss_scm_get_region_data) + 0x30;
165 dm_hdr->response_size = PS3SS_HDR_SIZE + sizeof(struct ps3ss_scm_get_region_data) + 0x30;
167 ss_hdr->packet_id = PS3SS_PID_SCM_GET_REGION_DATA;
168 ss_hdr->function_id = PS3SS_FID_SCM;
169 ss_hdr->laid = PS3DM_SCM_LAID;
170 ss_hdr->paid = PS3DM_SCM_PAID;
172 ss_scm_get_region_data->id = id;
173 ss_scm_get_region_data->data_size = 0x30;
175 error = ps3dm_proxy_do_request(fd, dm_hdr, PS3DM_HDR_SIZE + dm_hdr->request_size,
176 dm_hdr, PS3DM_HDR_SIZE + dm_hdr->response_size);
178 if (error) {
179 fprintf(stderr, "%s: %s\n", opts->device_name, strerror(errno));
180 } else if (ss_hdr->retval) {
181 fprintf(stderr, "%s: SS retval %d\n", opts->device_name, ss_hdr->retval);
182 error = -1;
183 } else {
184 for (i = 0; i < ss_scm_get_region_data->data_size; i++)
185 fprintf(stdout, "0x%02x ", ss_scm_get_region_data->data[i]);
187 fprintf(stdout, "\n");
190 return error;
194 * cmd_get_time
196 static int cmd_get_time(int fd, struct opts *opts, int argc, char **argv)
198 uint64_t tid;
199 char *endptr;
200 uint8_t buf[128];
201 struct ps3dm_hdr *dm_hdr;
202 struct ps3ss_hdr *ss_hdr;
203 struct ps3ss_scm_get_time *ss_scm_get_time;
204 int error;
206 if (optind >= argc) {
207 fprintf(stderr, "No TID specified\n");
208 return -1;
211 tid = strtoul(argv[optind], &endptr, 0);
212 if (*endptr != '\0') {
213 fprintf(stderr, "Invalid TID specified: %s\n", argv[optind]);
214 return -1;
217 optind++;
219 memset(buf, 0, sizeof(buf));
220 dm_hdr = (struct ps3dm_hdr *) buf;
221 ss_hdr = (struct ps3ss_hdr *)(dm_hdr + 1);
222 ss_scm_get_time = (struct ps3ss_scm_get_time *)(ss_hdr + 1);
224 dm_hdr->request_id = 1;
225 dm_hdr->function_id = PS3SS_FID_SCM;
226 dm_hdr->request_size = PS3SS_HDR_SIZE + sizeof(struct ps3ss_scm_get_time);
227 dm_hdr->response_size = PS3SS_HDR_SIZE + sizeof(struct ps3ss_scm_get_time);
229 ss_hdr->packet_id = PS3SS_PID_SCM_GET_TIME;
230 ss_hdr->function_id = PS3SS_FID_SCM;
231 ss_hdr->laid = PS3DM_SCM_LAID;
232 ss_hdr->paid = PS3DM_SCM_PAID;
234 ss_scm_get_time->tid = tid;
236 error = ps3dm_proxy_do_request(fd, dm_hdr, PS3DM_HDR_SIZE + dm_hdr->request_size,
237 dm_hdr, PS3DM_HDR_SIZE + dm_hdr->response_size);
239 if (error) {
240 fprintf(stderr, "%s: %s\n", opts->device_name, strerror(errno));
241 } else if (ss_hdr->retval != 0) {
242 fprintf(stderr, "%s: SS retval %d\n", opts->device_name, ss_hdr->retval);
243 error = -1;
244 } else {
245 fprintf(stdout, "0x%016lx 0x%016lx\n", ss_scm_get_time->field8,
246 ss_scm_get_time->field10);
248 fprintf(stdout, "\n");
251 return error;
255 * cmd_read_eprom
257 static int cmd_read_eprom(int fd, struct opts *opts, int argc, char **argv)
259 uint32_t eprom_offset;
260 uint64_t size;
261 char *endptr;
262 uint8_t buf[512];
263 struct ps3dm_hdr *dm_hdr;
264 struct ps3ss_hdr *ss_hdr;
265 struct ps3ss_scm_read_eprom *ss_scm_read_eprom;
266 int error, i;
268 if (optind >= argc) {
269 fprintf(stderr, "No EPROM offset specified\n");
270 return -1;
273 eprom_offset = strtoul(argv[optind], &endptr, 0);
274 if (*endptr != '\0') {
275 fprintf(stderr, "Invalid EPROM offset specified: %s\n", argv[optind]);
276 return -1;
279 optind++;
281 if (optind >= argc) {
282 fprintf(stderr, "No size specified\n");
283 return -1;
286 size = strtoull(argv[optind], &endptr, 0);
287 if ((*endptr != '\0') || (size > 0x100)) {
288 fprintf(stderr, "Invalid size specified: %s\n", argv[optind]);
289 return -1;
292 optind++;
294 memset(buf, 0, sizeof(buf));
295 dm_hdr = (struct ps3dm_hdr *) buf;
296 ss_hdr = (struct ps3ss_hdr *)(dm_hdr + 1);
297 ss_scm_read_eprom = (struct ps3ss_scm_read_eprom *)(ss_hdr + 1);
299 dm_hdr->request_id = 1;
300 dm_hdr->function_id = PS3SS_FID_SCM;
301 dm_hdr->request_size = PS3SS_HDR_SIZE + sizeof(struct ps3ss_scm_read_eprom) + size;
302 dm_hdr->response_size = PS3SS_HDR_SIZE + sizeof(struct ps3ss_scm_read_eprom) + size;
304 ss_hdr->packet_id = PS3SS_PID_SCM_READ_EPROM;
305 ss_hdr->function_id = PS3SS_FID_SCM;
306 ss_hdr->laid = PS3DM_SCM_LAID;
307 ss_hdr->paid = PS3DM_SCM_PAID;
309 ss_scm_read_eprom->offset = eprom_offset;
310 ss_scm_read_eprom->nread = size;
311 ss_scm_read_eprom->buf_size = size;
313 error = ps3dm_proxy_do_request(fd, dm_hdr, PS3DM_HDR_SIZE + dm_hdr->request_size,
314 dm_hdr, PS3DM_HDR_SIZE + dm_hdr->response_size);
316 if (error) {
317 fprintf(stderr, "%s: %s\n", opts->device_name, strerror(errno));
318 } else if (ss_hdr->retval) {
319 fprintf(stderr, "%s: SS retval %d\n", opts->device_name, ss_hdr->retval);
320 error = -1;
321 } else {
322 for (i = 0; i < ss_scm_read_eprom->nread; i++)
323 fprintf(stdout, "0x%02x ", ss_scm_read_eprom->buf[i]);
325 fprintf(stdout, "\n");
328 return error;
332 * cmd_get_sc_status
334 static int cmd_get_sc_status(int fd, struct opts *opts, int argc, char **argv)
336 uint8_t buf[128];
337 struct ps3dm_hdr *dm_hdr;
338 struct ps3ss_hdr *ss_hdr;
339 struct ps3ss_scm_get_sc_status *ss_scm_get_sc_status;
340 int error;
342 memset(buf, 0, sizeof(buf));
343 dm_hdr = (struct ps3dm_hdr *) buf;
344 ss_hdr = (struct ps3ss_hdr *)(dm_hdr + 1);
345 ss_scm_get_sc_status = (struct ps3ss_scm_get_sc_status *)(ss_hdr + 1);
347 dm_hdr->request_id = 1;
348 dm_hdr->function_id = PS3SS_FID_SCM;
349 dm_hdr->request_size = PS3SS_HDR_SIZE + sizeof(struct ps3ss_scm_get_sc_status);
350 dm_hdr->response_size = PS3SS_HDR_SIZE + sizeof(struct ps3ss_scm_get_sc_status);
352 ss_hdr->packet_id = PS3SS_PID_SCM_GET_SC_STATUS;
353 ss_hdr->function_id = PS3SS_FID_SCM;
354 ss_hdr->laid = PS3DM_SCM_LAID;
355 ss_hdr->paid = PS3DM_SCM_PAID;
357 error = ps3dm_proxy_do_request(fd, dm_hdr, PS3DM_HDR_SIZE + dm_hdr->request_size,
358 dm_hdr, PS3DM_HDR_SIZE + dm_hdr->response_size);
360 if (error) {
361 fprintf(stderr, "%s: %s\n", opts->device_name, strerror(errno));
362 } else if (ss_hdr->retval) {
363 fprintf(stderr, "%s: SS retval %d\n", opts->device_name, ss_hdr->retval);
364 error = -1;
365 } else {
366 fprintf(stdout, "0x%08x 0x%08x\n", ss_scm_get_sc_status->version,
367 ss_scm_get_sc_status->mode);
370 return error;
374 * main
376 int main(int argc, char **argv)
378 struct opts opts;
379 int fd = 0, error = 0;
381 memset(&opts, 0, sizeof(opts));
383 if (process_opts(argc, argv, &opts)) {
384 usage();
385 error = 1;
386 goto done;
389 if (opts.do_help) {
390 usage();
391 goto done;
392 } else if (opts.do_version) {
393 version();
394 goto done;
397 fd = ps3dm_proxy_open(opts.device_name);
398 if (fd < 0) {
399 fprintf(stderr, "%s: %s\n", opts.device_name, strerror(errno));
400 error = 2;
401 goto done;
404 if (!strcmp(opts.cmd, "get_region_data")) {
405 error = cmd_get_region_data(fd, &opts, argc, argv);
406 } else if (!strcmp(opts.cmd, "get_time")) {
407 error = cmd_get_time(fd, &opts, argc, argv);
408 } else if (!strcmp(opts.cmd, "read_eprom")) {
409 error = cmd_read_eprom(fd, &opts, argc, argv);
410 } else if (!strcmp(opts.cmd, "get_sc_status")) {
411 error = cmd_get_sc_status(fd, &opts, argc, argv);
412 } else {
413 usage();
414 error = 1;
415 goto done;
418 if (error)
419 error = 3;
421 done:
423 if (fd >= 0)
424 ps3dm_proxy_close(fd);
426 exit(error);