summaryrefslogtreecommitdiff
path: root/utils/jz4740_usbtool/jz4740_usbtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/jz4740_usbtool/jz4740_usbtool.c')
-rwxr-xr-xutils/jz4740_usbtool/jz4740_usbtool.c477
1 files changed, 477 insertions, 0 deletions
diff --git a/utils/jz4740_usbtool/jz4740_usbtool.c b/utils/jz4740_usbtool/jz4740_usbtool.c
new file mode 100755
index 0000000000..908cf723d0
--- /dev/null
+++ b/utils/jz4740_usbtool/jz4740_usbtool.c
@@ -0,0 +1,477 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Maurus Cuelenaere
11 *
12 * based on tcctool.c by Dave Chapman
13 *
14 * USB code based on ifp-line - http://ifp-driver.sourceforge.net
15 *
16 * ifp-line is (C) Pavel Kriz, Jun Yamishiro and Joe Roback and
17 * licensed under the GPL (v2)
18 *
19 *
20 * All files in this archive are subject to the GNU General Public License.
21 * See the file COPYING in the source tree root for full license agreement.
22 *
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
25 *
26 ****************************************************************************/
27
28#include <stdio.h>
29#include <inttypes.h>
30#include <usb.h>
31#include <string.h>
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <unistd.h>
35#include <fcntl.h>
36#include "jz4740.h"
37
38#define VERSION "0.2"
39
40#define MAX_FIRMWARESIZE (64*1024*1024) /* Arbitrary limit (for safety) */
41
42/* For win32 compatibility: */
43#ifndef O_BINARY
44#define O_BINARY 0
45#endif
46
47/* USB IDs for USB Boot Mode */
48#define VID 0x601A
49#define PID 0x4740
50
51#define EP_BULK_TO 0x01
52#define TOUT 5000
53
54#ifndef MAX
55#define MAX(a,b) (((a)>(b))?(a):(b))
56#endif
57
58enum USB_JZ4740_REQUEST
59{
60 VR_GET_CPU_INFO = 0,
61 VR_SET_DATA_ADDRESS,
62 VR_SET_DATA_LENGTH,
63 VR_FLUSH_CACHES,
64 VR_PROGRAM_START1,
65 VR_PROGRAM_START2,
66 VR_NOR_OPS,
67 VR_NAND_OPS,
68 VR_SDRAM_OPS,
69 VR_CONFIGURATION
70};
71
72enum NOR_OPS_TYPE
73{
74 NOR_INIT = 0,
75 NOR_QUERY,
76 NOR_WRITE,
77 NOR_ERASE_CHIP,
78 NOR_ERASE_SECTOR
79};
80
81enum NOR_FLASH_TYPE
82{
83 NOR_AM29 = 0,
84 NOR_SST28,
85 NOR_SST39x16,
86 NOR_SST39x8
87};
88
89enum NAND_OPS_TYPE
90{
91 NAND_QUERY = 0,
92 NAND_INIT,
93 NAND_MARK_BAD,
94 NAND_READ_OOB,
95 NAND_READ_RAW,
96 NAND_ERASE,
97 NAND_READ,
98 NAND_PROGRAM,
99 NAND_READ_TO_RAM
100};
101
102enum SDRAM_OPS_TYPE
103{
104 SDRAM_LOAD,
105
106};
107
108enum DATA_STRUCTURE_OB
109{
110 DS_flash_info ,
111 DS_hand
112};
113
114enum OPTION
115{
116 OOB_ECC,
117 OOB_NO_ECC,
118 NO_OOB,
119};
120
121#define SEND_COMMAND(cmd, arg) err = usb_control_msg(dh, USB_ENDPOINT_OUT | USB_TYPE_VENDOR, cmd, arg>>16, arg&0xFFFF, NULL, 0, TOUT);\
122 if (err < 0) \
123 { \
124 fprintf(stderr,"\n[ERR] Error sending control message (%d, %s)\n", err, usb_strerror()); \
125 return -1; \
126 }
127
128#define GET_CPU_INFO(s) err = usb_control_msg(dh, USB_ENDPOINT_IN | USB_TYPE_VENDOR, VR_GET_CPU_INFO, 0, 0, buf, 8, TOUT); \
129 if (err < 0) \
130 { \
131 fprintf(stderr,"\n[ERR] Error sending control message (%d, %s)\n", err, usb_strerror()); \
132 return -1; \
133 }
134
135#define SEND_DATA(ptr, size) err = usb_bulk_write(dh, USB_ENDPOINT_OUT | EP_BULK_TO, ptr, size, TOUT); \
136 if (err != len) \
137 { \
138 fprintf(stderr,"\n[ERR] Error writing data\n"); \
139 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err)); \
140 return -1; \
141 }
142
143#define GET_DATA(ptr, size) err = usb_bulk_read(dh, USB_ENDPOINT_IN | EP_BULK_TO, ptr, size, TOUT); \
144 if (err != size) \
145 { \
146 fprintf(stderr,"\n[ERR] Error writing data\n"); \
147 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err)); \
148 return -1; \
149 }
150
151int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len)
152{
153 int err;
154 char buf[8];
155 unsigned char* tmp_buf;
156
157 fprintf(stderr, "[INFO] GET_CPU_INFO: ");
158 GET_CPU_INFO(buf);
159 buf[8] = 0;
160 fprintf(stderr, "%s\n", buf);
161
162 fprintf(stderr, "[INFO] SET_DATA_ADDRESS to 0x%x...", address);
163 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
164 fprintf(stderr, " Done!\n");
165
166 fprintf(stderr, "[INFO] Sending data...");
167 /* Must not split the file in several packages! */
168 SEND_DATA(p, len);
169 fprintf(stderr, " Done!\n");
170
171 fprintf(stderr, "[INFO] Verifying data...");
172 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
173 SEND_COMMAND(VR_SET_DATA_LENGTH, len);
174 tmp_buf = malloc(len);
175 if (tmp_buf == NULL)
176 {
177 fprintf(stderr, "\n[ERR] Could not allocate memory.\n");
178 return -1;
179 }
180 GET_DATA(tmp_buf, len);
181 if (memcmp(tmp_buf, p, len) != 0)
182 {
183 fprintf(stderr, "\n[ERR] Sent data isn't the same as received data...\n");
184 free(tmp_buf);
185 return -1;
186 }
187 free(tmp_buf);
188 fprintf(stderr, " Done !\n");
189
190 fprintf(stderr, "[INFO] Booting device...");
191 SEND_COMMAND(VR_PROGRAM_START1, address);
192 fprintf(stderr, " Done!\n");
193
194 return 0;
195}
196
197int read_data(usb_dev_handle* dh, int address, unsigned char *p, int len)
198{
199 int err;
200 char buf[8];
201
202 fprintf(stderr, "[INFO] GET_CPU_INFO: ");
203 GET_CPU_INFO(buf);
204 buf[8] = 0;
205 fprintf(stderr, "%s\n", buf);
206
207 fprintf(stderr, "[INFO] Reading data...");
208 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
209 SEND_COMMAND(VR_SET_DATA_LENGTH, len);
210 GET_DATA(p, len);
211 fprintf(stderr, " Done!\n");
212 return 0;
213}
214
215unsigned int read_reg(usb_dev_handle* dh, int address)
216{
217 int err;
218 unsigned char buf[4];
219
220 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
221 SEND_COMMAND(VR_SET_DATA_LENGTH, 4);
222 GET_DATA(buf, 4);
223
224 return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
225}
226
227#define TEST(m) fprintf(stderr, "%s -> %x\n", #m, read_reg(dh, m));
228int test_device(usb_dev_handle* dh)
229{
230 TEST(INTC_ISR);
231 TEST(INTC_IMR);
232 TEST(INTC_IMSR);
233 TEST(INTC_IMCR);
234 TEST(INTC_IPR);
235
236 fprintf(stderr, "\n");
237 TEST(RTC_RCR);
238 TEST(RTC_RSR);
239 TEST(RTC_RSAR);
240 TEST(RTC_RGR);
241 TEST(RTC_HCR);
242 TEST(RTC_RCR);
243 TEST(RTC_HWFCR);
244 TEST(RTC_HRCR);
245 TEST(RTC_HWCR);
246 TEST(RTC_HWSR);
247
248 fprintf(stderr, "\n");
249 TEST(GPIO_PXPIN(0));
250 TEST(GPIO_PXPIN(1));
251 TEST(GPIO_PXPIN(2));
252 TEST(GPIO_PXPIN(3));
253 return 0;
254}
255
256void jzconnect(int address, unsigned char* buf, int len, int func)
257{
258 struct usb_bus *bus;
259 struct usb_device *tmp_dev;
260 struct usb_device *dev = NULL;
261 usb_dev_handle *dh;
262 int err;
263
264 fprintf(stderr,"[INFO] Searching for device...\n");
265
266 usb_init();
267 if(usb_find_busses() < 0)
268 {
269 fprintf(stderr, "[ERR] Could not find any USB busses.\n");
270 return;
271 }
272
273 if (usb_find_devices() < 0)
274 {
275 fprintf(stderr, "[ERR] USB devices not found(nor hubs!).\n");
276 return;
277 }
278
279 for (bus = usb_get_busses(); bus; bus = bus->next)
280 {
281 for (tmp_dev = bus->devices; tmp_dev; tmp_dev = tmp_dev->next)
282 {
283 //printf("Found Vendor %04x Product %04x\n",tmp_dev->descriptor.idVendor, tmp_dev->descriptor.idProduct);
284 if (tmp_dev->descriptor.idVendor == VID &&
285 tmp_dev->descriptor.idProduct == PID)
286 {
287 dev = tmp_dev;
288 goto found;
289
290 }
291 }
292 }
293
294 if (dev == NULL)
295 {
296 fprintf(stderr, "[ERR] Device not found.\n");
297 fprintf(stderr, "[ERR] Ensure your device is in USB boot mode and run usbtool again.\n");
298 return;
299 }
300
301found:
302 if ( (dh = usb_open(dev)) == NULL)
303 {
304 fprintf(stderr,"[ERR] Unable to open device.\n");
305 return;
306 }
307
308 err = usb_set_configuration(dh, 1);
309
310 if (err < 0)
311 {
312 fprintf(stderr, "[ERR] usb_set_configuration failed (%d, %s)\n", err, usb_strerror());
313 usb_close(dh);
314 return;
315 }
316
317 /* "must be called" written in the libusb documentation */
318 err = usb_claim_interface(dh, 0);
319 if (err < 0)
320 {
321 fprintf(stderr, "[ERR] Unable to claim interface (%d, %s)\n", err, usb_strerror());
322 usb_close(dh);
323 return;
324 }
325
326 fprintf(stderr,"[INFO] Found device, uploading application.\n");
327
328 /* Now we can transfer the application to the device. */
329
330 switch(func)
331 {
332 case 1:
333 err = upload_app(dh, address, buf, len);
334 break;
335 case 2:
336 err = read_data(dh, address, buf, len);
337 break;
338 case 3:
339 err = test_device(dh);
340 break;
341 }
342
343 /* release claimed interface */
344 usb_release_interface(dh, 0);
345
346 usb_close(dh);
347}
348
349int filesize(FILE* fd)
350{
351 int tmp;
352 tmp = fseek(fd, 0, SEEK_END);
353 fseek(fd, 0, SEEK_SET);
354 return tmp;
355}
356
357void print_usage(void)
358{
359#ifdef _WIN32
360 fprintf(stderr, "Usage: usbtool.exe [CMD] [FILE] [ADDRESS] [LEN]\n");
361#else
362 fprintf(stderr, "Usage: usbtool [CMD] [FILE] [ADDRESS] [LEN]\n");
363#endif
364 fprintf(stderr, "\t[ADDRESS] has to be in 0xHEXADECIMAL format\n");
365 fprintf(stderr, "\t[CMD]:\n\t\t1 -> upload file to specified address and boot from it\n\t\t2 -> read data from [ADDRESS] with length [LEN] to [FILE]\n");
366 fprintf(stderr, "\t\t3 -> read device status\n");
367#ifdef _WIN32
368 fprintf(stderr, "\nExample:\n\t usbtool.exe 1 fw.bin 0x80000000");
369 fprintf(stderr, "\n\t usbtool.exe 2 save.bin 0x81000000 1024");
370#else
371 fprintf(stderr, "\nExample:\n\t usbtool 1 fw.bin 0x80000000");
372 fprintf(stderr, "\n\t usbtool 2 save.bin 0x81000000 1024");
373#endif
374}
375
376int main(int argc, char* argv[])
377{
378 unsigned char* buf;
379 int n, len, address, cmd=0;
380 FILE* fd;
381
382 fprintf(stderr, "USBtool v" VERSION " - (C) 2008 Maurus Cuelenaere\n");
383 fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n");
384 fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
385
386 if(argc > 1)
387 sscanf(argv[1], "%d", &cmd);
388 switch(cmd)
389 {
390 case 1:
391 if (sscanf(argv[3], "0x%x", &address) <= 0)
392 {
393 print_usage();
394 return -1;
395 }
396
397 fd = fopen(argv[2], "rb");
398 if (fd < 0)
399 {
400 fprintf(stderr, "[ERR] Could not open %s\n", argv[2]);
401 return 4;
402 }
403
404 len = filesize(fd);
405
406 if (len > MAX_FIRMWARESIZE)
407 {
408 fprintf(stderr, "[ERR] Firmware file too big\n");
409 fclose(fd);
410 return 5;
411 }
412
413 buf = malloc(len);
414 if (buf == NULL)
415 {
416 fprintf(stderr, "[ERR] Could not allocate memory.\n");
417 fclose(fd);
418 return 6;
419 }
420
421 n = fread(buf, 1, len, fd);
422 if (n != len)
423 {
424 fprintf(stderr, "[ERR] Short read.\n");
425 fclose(fd);
426 return 7;
427 }
428 fclose(fd);
429
430 jzconnect(address, buf, len, 1);
431 break;
432 case 2:
433 if (sscanf(argv[3], "0x%x", &address) <= 0)
434 {
435 print_usage();
436 return -1;
437 }
438
439 fd = fopen(argv[2], "wb");
440 if (fd < 0)
441 {
442 fprintf(stderr, "[ERR] Could not open %s\n", argv[2]);
443 return 4;
444 }
445
446 sscanf(argv[4], "%d", &len);
447
448 buf = malloc(len);
449 if (buf == NULL)
450 {
451 fprintf(stderr, "[ERR] Could not allocate memory.\n");
452 fclose(fd);
453 return 6;
454 }
455
456 jzconnect(address, buf, len, 2);
457
458 n = fwrite(buf, 1, len, fd);
459 if (n != len)
460 {
461 fprintf(stderr, "[ERR] Short write.\n");
462 fclose(fd);
463 return 7;
464 }
465 fclose(fd);
466 break;
467 case 3:
468 jzconnect(address, NULL, 0, 3);
469 break;
470 default:
471 print_usage();
472 return 1;
473 break;
474 }
475
476 return 0;
477}