summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/jz4760_tools/Makefile4
-rw-r--r--utils/jz4760_tools/packtools.cpp9
-rw-r--r--utils/jz4760_tools/usbboot.c349
3 files changed, 357 insertions, 5 deletions
diff --git a/utils/jz4760_tools/Makefile b/utils/jz4760_tools/Makefile
index 847539e38c..f181fa5c70 100644
--- a/utils/jz4760_tools/Makefile
+++ b/utils/jz4760_tools/Makefile
@@ -2,9 +2,9 @@ DEFINES=
2CC?=gcc 2CC?=gcc
3CXX?=g++ 3CXX?=g++
4LD?=g++ 4LD?=g++
5CFLAGS=-g -std=c99 -Wall $(DEFINES) -Ilib 5CFLAGS=-g -std=c99 -Wall $(DEFINES) `pkg-config --cflags libusb-1.0`
6CXXFLAGS=-g -Wall $(DEFINES) 6CXXFLAGS=-g -Wall $(DEFINES)
7LDFLAGS= 7LDFLAGS=`pkg-config --libs libusb-1.0`
8SRC=$(wildcard *.c) 8SRC=$(wildcard *.c)
9SRCXX=$(wildcard *.cpp) 9SRCXX=$(wildcard *.cpp)
10EXEC=$(SRC:.c=) $(SRCXX:.cpp=) 10EXEC=$(SRC:.c=) $(SRCXX:.cpp=)
diff --git a/utils/jz4760_tools/packtools.cpp b/utils/jz4760_tools/packtools.cpp
index 6bd5ec0330..b594525978 100644
--- a/utils/jz4760_tools/packtools.cpp
+++ b/utils/jz4760_tools/packtools.cpp
@@ -96,6 +96,9 @@ const uint32_t jz4760_crc_key[256] =
96 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, 96 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
97}; 97};
98 98
99/* This table is generated programmatically: it contains two copies of a 172-bytes
100 * table. This table contains the lower 8-bit of the first 172 prime numbers:
101 * 2, 3, 5, 7, ..., 251(=0xfb), 257(=0x101 -> 0x01), ... */
99const unsigned JZ4760_XOR_KEY_SIZE = 344; 102const unsigned JZ4760_XOR_KEY_SIZE = 344;
100uint8_t jz4760_xor_key[JZ4760_XOR_KEY_SIZE] = 103uint8_t jz4760_xor_key[JZ4760_XOR_KEY_SIZE] =
101{ 104{
@@ -530,7 +533,7 @@ int descramble(int argc, char **argv)
530 533
531void usage() 534void usage()
532{ 535{
533 printf("usage: [--pack|--unpack|--descramble] <options>\n"); 536 printf("usage: [--pack|--unpack|--descramble|--scramble] <options>\n");
534 printf(" unpack options:\n"); 537 printf(" unpack options:\n");
535 printf(" -i <file> Input file\n"); 538 printf(" -i <file> Input file\n");
536 printf(" -o <dir> Output directory\n"); 539 printf(" -o <dir> Output directory\n");
@@ -541,7 +544,7 @@ void usage()
541 printf(" -m <mach> Machine flags\n"); 544 printf(" -m <mach> Machine flags\n");
542 printf(" -v Verbose output\n"); 545 printf(" -v Verbose output\n");
543 printf(" -t <time> Override date/time (dd/mm/yy hh:mm)\n"); 546 printf(" -t <time> Override date/time (dd/mm/yy hh:mm)\n");
544 printf(" descramble options:\n"); 547 printf(" (de)scramble options:\n");
545 printf(" -i <file> Input file\n"); 548 printf(" -i <file> Input file\n");
546 printf(" -o <file> Output file\n"); 549 printf(" -o <file> Output file\n");
547 exit(1); 550 exit(1);
@@ -555,7 +558,7 @@ int main(int argc, char **argv)
555 return unpack(argc - 1, argv + 1); 558 return unpack(argc - 1, argv + 1);
556 if(strcmp(argv[1], "--pack") == 0) 559 if(strcmp(argv[1], "--pack") == 0)
557 return pack(argc - 1, argv + 1); 560 return pack(argc - 1, argv + 1);
558 if(strcmp(argv[1], "--descramble") == 0) 561 if(strcmp(argv[1], "--descramble") == 0 || strcmp(argv[1], "--scramble") == 0)
559 return descramble(argc - 1, argv + 1); 562 return descramble(argc - 1, argv + 1);
560 usage(); 563 usage();
561 return 1; 564 return 1;
diff --git a/utils/jz4760_tools/usbboot.c b/utils/jz4760_tools/usbboot.c
new file mode 100644
index 0000000000..0d7c7242fd
--- /dev/null
+++ b/utils/jz4760_tools/usbboot.c
@@ -0,0 +1,349 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2015 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <stdint.h>
25#include <libusb.h>
26#include <getopt.h>
27#include <stdbool.h>
28
29#define VR_GET_CPU_INFO 0
30#define VR_SET_DATA_ADDRESS 1
31#define VR_SET_DATA_LENGTH 2
32#define VR_FLUSH_CACHES 3
33#define VR_PROGRAM_START1 4
34#define VR_PROGRAM_START2 5
35
36bool g_verbose = false;
37
38int jz_cpuinfo(libusb_device_handle *dev)
39{
40 if(g_verbose)
41 printf("Get CPU Info...\n");
42 uint8_t cpuinfo[9];
43 int ret = libusb_control_transfer(dev,
44 LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
45 VR_GET_CPU_INFO, 0, 0, cpuinfo, 8, 1000);
46 if(ret != 8)
47 {
48 printf("Cannot get CPU info: %d\n", ret);
49 return ret;
50 }
51 cpuinfo[8] = 0;
52 printf("CPU Info: %s\n", cpuinfo);
53 return 0;
54}
55
56int jz_set_addr(libusb_device_handle *dev, unsigned long addr)
57{
58 if(g_verbose)
59 printf("Set address to 0x%lx...\n", addr);
60 int ret = libusb_control_transfer(dev,
61 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
62 VR_SET_DATA_ADDRESS, addr >> 16, addr & 0xffff, NULL, 0, 1000);
63 if(ret != 0)
64 printf("Cannot set address: %d\n", ret);
65 return ret;
66}
67
68int jz_set_length(libusb_device_handle *dev, unsigned long length)
69{
70 if(g_verbose)
71 printf("Set length to 0x%lx...\n", length);
72 int ret = libusb_control_transfer(dev,
73 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
74 VR_SET_DATA_LENGTH, length >> 16, length & 0xffff, NULL, 0, 1000);
75 if(ret != 0)
76 printf("Cannot set length: %d\n", ret);
77 return ret;
78}
79
80int jz_start1(libusb_device_handle *dev, unsigned long addr)
81{
82 if(g_verbose)
83 printf("Start 1 at 0x%lx...\n", addr);
84 int ret = libusb_control_transfer(dev,
85 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
86 VR_PROGRAM_START1, addr >> 16, addr & 0xffff, NULL, 0, 1000);
87 if(ret != 0)
88 printf("Cannot start1: %d\n", ret);
89 return ret;
90}
91
92int jz_start2(libusb_device_handle *dev, unsigned long addr)
93{
94 if(g_verbose)
95 printf("Start 2 at 0x%lx...\n", addr);
96 int ret = libusb_control_transfer(dev,
97 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
98 VR_PROGRAM_START2, addr >> 16, addr & 0xffff, NULL, 0, 1000);
99 if(ret != 0)
100 printf("Cannot start2: %d\n", ret);
101 return ret;
102}
103
104int jz_flush_caches(libusb_device_handle *dev)
105{
106 if(g_verbose)
107 printf("Flush caches...\n");
108 int ret = libusb_control_transfer(dev,
109 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
110 VR_FLUSH_CACHES, 0, 0, NULL, 0, 1000);
111 if(ret != 0)
112 printf("Cannot flush caches: %d\n", ret);
113 return ret;
114}
115
116int jz_upload(libusb_device_handle *dev, const char *file, unsigned long length)
117{
118 if(g_verbose)
119 printf("Upload %lu bytes...\n", length);
120 void *data = malloc(length);
121 int xfered;
122 int ret = libusb_bulk_transfer(dev, LIBUSB_ENDPOINT_IN | 1, data, length,
123 &xfered, 10000);
124 if(ret != 0)
125 printf("Cannot upload data from device: %d\n", ret);
126 if(ret == 0 && xfered != length)
127 {
128 printf("Device did not send all the data\n");
129 ret = -1;
130 }
131 if(ret == 0)
132 {
133 FILE *f = fopen(file, "wb");
134 if(f != NULL)
135 {
136 if(fwrite(data, length, 1, f) != 1)
137 {
138 printf("Cannot write file\n");
139 ret = -3;
140 }
141 fclose(f);
142 }
143 else
144 {
145 printf("Cannot open file for writing\n");
146 ret = -2;
147 }
148 }
149 free(data);
150 return ret;
151}
152
153int jz_download(libusb_device_handle *dev, const char *file)
154{
155 FILE *f = fopen(file, "rb");
156 if(f == NULL)
157 {
158 printf("Cannot open file for reading\n");
159 return -1;
160 }
161 fseek(f, 0, SEEK_END);
162 size_t length = ftell(f);
163 fseek(f, 0, SEEK_SET);
164 if(g_verbose)
165 printf("Download %lu bytes..\n", length);
166 void *data = malloc(length);
167 if(fread(data, length, 1, f) != 1)
168 {
169 printf("Cannot read file\n");
170 free(data);
171 fclose(f);
172 return -1;
173 }
174 fclose(f);
175 int xfered;
176 int ret = libusb_bulk_transfer(dev, LIBUSB_ENDPOINT_OUT | 1, data, length,
177 &xfered, 1000);
178 if(ret != 0)
179 printf("Cannot download data from device: %d\n", ret);
180 if(ret == 0 && xfered != length)
181 {
182 printf("Device did not receive all the data\n");
183 ret = -1;
184 }
185 free(data);
186 return ret;
187}
188
189int renumerate(libusb_device_handle **dev)
190{
191 if(g_verbose)
192 printf("Look for device again...\n");
193 libusb_close(*dev);
194 *dev = libusb_open_device_with_vid_pid(NULL, 0x601a, 0x4760);
195 if(dev == NULL)
196 {
197 printf("Cannot open device\n");
198 return -1;
199 }
200 return 0;
201}
202
203void usage()
204{
205 printf("Usage: usbboot [options]\n");
206 printf("\n");
207 printf("Basic options:\n");
208 printf(" --stage1 <file> Upload first stage program (<=16Kio)\n");
209 printf(" --stage2 <file> Upload second stage program to SDRAM\n");
210 printf(" --s2-addr <addr> Change second stage address (default is 0x80000000)\n");
211 printf(" --ram <target> Setup SDRAM for <target>, see list below\n");
212 printf("\n");
213 printf("Advanced options:\n");
214 printf(" --addr <addr> Set address for next operation\n");
215 printf(" --length <len> Set length for next operation\n");
216 printf(" --download <file> Download data in file to the device (use file length)\n");
217 printf(" --upload <file> Upload data from the device to the file\n");
218 printf(" --cpuinfo Print CPU info\n");
219 printf(" --flush-caches Flush CPU caches\n");
220 printf(" --start1 <addr> Execute first stage from I-cache\n");
221 printf(" --start2 <addr> Execute second stage\n");
222 printf(" --wait <time> Wait <time> seconds\n");
223 printf(" --renumerate Try to look for device again\n");
224 printf(" --ram <ramopt> Setup SDRAM with parameters, see descrition below\n");
225 printf(" -v Be verbose\n");
226 printf("\n");
227 printf("Targets for RAM setup:\n");
228 printf(" fiiox1 Use <>\n");
229 printf("\n");
230 printf("Format of <ramopt> for RAM setup:\n");
231 exit(1);
232}
233
234int main(int argc, char **argv)
235{
236 if(argc <= 1)
237 usage();
238 int ret = 0;
239 libusb_init(NULL);
240 libusb_device_handle *dev = libusb_open_device_with_vid_pid(NULL, 0x601a, 0x4760);
241 if(dev == NULL)
242 {
243 printf("Cannot open device\n");
244 return -1;
245 }
246 if(libusb_claim_interface(dev, 0) != 0)
247 {
248 printf("Cannot claim interface\n");
249 libusb_close(dev);
250 return -2;
251 }
252
253 enum
254 {
255 OPT_ADDR = 0x100, OPT_LENGTH, OPT_UPLOAD, OPT_CPUINFO, OPT_DOWNLOAD,
256 OPT_START1, OPT_WAIT, OPT_RENUMERATE, OPT_START2, OPT_FLUSH_CACHES
257 };
258 unsigned long last_length = 0;
259 while(1)
260 {
261 static struct option long_options[] =
262 {
263 {"help", no_argument, 0, 'h'},
264 {"cpuinfo", no_argument, 0, OPT_CPUINFO},
265 {"addr", required_argument, 0, OPT_ADDR},
266 {"length", required_argument, 0, OPT_LENGTH},
267 {"upload", required_argument, 0, OPT_UPLOAD},
268 {"download", required_argument, 0, OPT_DOWNLOAD},
269 {"start1", required_argument, 0, OPT_START1},
270 {"wait", required_argument, 0, OPT_WAIT},
271 {"renumerate", no_argument, 0, OPT_RENUMERATE},
272 {"start2", required_argument, 0, OPT_START2},
273 {"flush-caches", no_argument, 0, OPT_FLUSH_CACHES},
274 {0, 0, 0, 0}
275 };
276
277 int c = getopt_long(argc, argv, "hv", long_options, NULL);
278 char *end = 0;
279 unsigned long param;
280 if(c == OPT_ADDR || c == OPT_LENGTH || c == OPT_START1 || c== OPT_WAIT)
281 {
282 param = strtoul(optarg, &end, 0);
283 if(*end)
284 {
285 printf("Invalid argument '%s'\n", optarg);
286 ret = 1;
287 break;
288 }
289 }
290 if(c == -1)
291 break;
292 switch(c)
293 {
294 default:
295 case -1:
296 break;
297 case 'h':
298 usage();
299 break;
300 case 'v':
301 g_verbose = true;
302 break;
303 case OPT_ADDR:
304 ret = jz_set_addr(dev, param);
305 break;
306 case OPT_LENGTH:
307 last_length = param;
308 ret = jz_set_length(dev, param);
309 break;
310 case OPT_UPLOAD:
311 ret = jz_upload(dev, optarg, last_length);
312 break;
313 case OPT_DOWNLOAD:
314 ret = jz_download(dev, optarg);
315 break;
316 case OPT_CPUINFO:
317 ret = jz_cpuinfo(dev);
318 break;
319 case OPT_START1:
320 ret = jz_start1(dev, param);
321 break;
322 case OPT_WAIT:
323 if(g_verbose)
324 printf("Wait for %lu seconds...\n", param);
325 sleep(param);
326 break;
327 case OPT_RENUMERATE:
328 ret = renumerate(&dev);
329 break;
330 case OPT_START2:
331 ret = jz_start2(dev, param);
332 break;
333 case OPT_FLUSH_CACHES:
334 ret = jz_flush_caches(dev);
335 break;
336 }
337 if(ret != 0)
338 break;
339 }
340 if(optind != argc)
341 {
342 printf("Error: extra arguments on command line\n");
343 ret = 1;
344 }
345
346 libusb_close(dev);
347 libusb_exit(NULL);
348 return ret;
349} \ No newline at end of file