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.c359
1 files changed, 303 insertions, 56 deletions
diff --git a/utils/jz4740_usbtool/jz4740_usbtool.c b/utils/jz4740_usbtool/jz4740_usbtool.c
index 84ffbf7098..4634f0502b 100755
--- a/utils/jz4740_usbtool/jz4740_usbtool.c
+++ b/utils/jz4740_usbtool/jz4740_usbtool.c
@@ -34,8 +34,10 @@
34#include <unistd.h> 34#include <unistd.h>
35#include <fcntl.h> 35#include <fcntl.h>
36#include "jz4740.h" 36#include "jz4740.h"
37#include <stdbool.h>
38#include <unistd.h>
37 39
38#define VERSION "0.2" 40#define VERSION "0.3"
39 41
40#define MAX_FIRMWARESIZE (64*1024*1024) /* Arbitrary limit (for safety) */ 42#define MAX_FIRMWARESIZE (64*1024*1024) /* Arbitrary limit (for safety) */
41 43
@@ -51,10 +53,6 @@
51#define EP_BULK_TO 0x01 53#define EP_BULK_TO 0x01
52#define TOUT 5000 54#define TOUT 5000
53 55
54#ifndef MAX
55#define MAX(a,b) (((a)>(b))?(a):(b))
56#endif
57
58enum USB_JZ4740_REQUEST 56enum USB_JZ4740_REQUEST
59{ 57{
60 VR_GET_CPU_INFO = 0, 58 VR_GET_CPU_INFO = 0,
@@ -118,6 +116,15 @@ enum OPTION
118 NO_OOB, 116 NO_OOB,
119}; 117};
120 118
119int filesize(FILE* fd)
120{
121 int tmp;
122 fseek(fd, 0, SEEK_END);
123 tmp = ftell(fd);
124 fseek(fd, 0, SEEK_SET);
125 return tmp;
126}
127
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);\ 128#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) \ 129 if (err < 0) \
123 { \ 130 { \
@@ -125,7 +132,7 @@ enum OPTION
125 return -1; \ 132 return -1; \
126 } 133 }
127 134
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); \ 135#define GET_CPU_INFO(s) err = usb_control_msg(dh, USB_ENDPOINT_IN | USB_TYPE_VENDOR, VR_GET_CPU_INFO, 0, 0, s, 8, TOUT); \
129 if (err < 0) \ 136 if (err < 0) \
130 { \ 137 { \
131 fprintf(stderr,"\n[ERR] Error sending control message (%d, %s)\n", err, usb_strerror()); \ 138 fprintf(stderr,"\n[ERR] Error sending control message (%d, %s)\n", err, usb_strerror()); \
@@ -133,7 +140,7 @@ enum OPTION
133 } 140 }
134 141
135#define SEND_DATA(ptr, size) err = usb_bulk_write(dh, USB_ENDPOINT_OUT | EP_BULK_TO, ptr, size, TOUT); \ 142#define SEND_DATA(ptr, size) err = usb_bulk_write(dh, USB_ENDPOINT_OUT | EP_BULK_TO, ptr, size, TOUT); \
136 if (err != len) \ 143 if (err != size) \
137 { \ 144 { \
138 fprintf(stderr,"\n[ERR] Error writing data\n"); \ 145 fprintf(stderr,"\n[ERR] Error writing data\n"); \
139 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err)); \ 146 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err)); \
@@ -148,7 +155,7 @@ enum OPTION
148 return -1; \ 155 return -1; \
149 } 156 }
150 157
151int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len) 158int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len, bool stage2)
152{ 159{
153 int err; 160 int err;
154 char buf[8]; 161 char buf[8];
@@ -158,6 +165,11 @@ int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len)
158 GET_CPU_INFO(buf); 165 GET_CPU_INFO(buf);
159 buf[8] = 0; 166 buf[8] = 0;
160 fprintf(stderr, "%s\n", buf); 167 fprintf(stderr, "%s\n", buf);
168#if 0
169 fprintf(stderr, "[INFO] Flushing cache...");
170 SEND_COMMAND(VR_FLUSH_CACHES, 0);
171 fprintf(stderr, " Done!\n");
172#endif
161 173
162 fprintf(stderr, "[INFO] SET_DATA_ADDRESS to 0x%x...", address); 174 fprintf(stderr, "[INFO] SET_DATA_ADDRESS to 0x%x...", address);
163 SEND_COMMAND(VR_SET_DATA_ADDRESS, address); 175 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
@@ -179,16 +191,13 @@ int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len)
179 } 191 }
180 GET_DATA(tmp_buf, len); 192 GET_DATA(tmp_buf, len);
181 if (memcmp(tmp_buf, p, len) != 0) 193 if (memcmp(tmp_buf, p, len) != 0)
182 { 194 fprintf(stderr, "\n[WARN] Sent data isn't the same as received data...\n");
183 fprintf(stderr, "\n[ERR] Sent data isn't the same as received data...\n"); 195 else
184 free(tmp_buf); 196 fprintf(stderr, " Done!\n");
185 return -1;
186 }
187 free(tmp_buf); 197 free(tmp_buf);
188 fprintf(stderr, " Done !\n");
189 198
190 fprintf(stderr, "[INFO] Booting device..."); 199 fprintf(stderr, "[INFO] Booting device [STAGE%d]...", (stage2 ? 2 : 1));
191 SEND_COMMAND(VR_PROGRAM_START1, address); 200 SEND_COMMAND((stage2 ? VR_PROGRAM_START2 : VR_PROGRAM_START1), (address+(stage2 ? 8 : 0)) );
192 fprintf(stderr, " Done!\n"); 201 fprintf(stderr, " Done!\n");
193 202
194 return 0; 203 return 0;
@@ -212,44 +221,275 @@ int read_data(usb_dev_handle* dh, int address, unsigned char *p, int len)
212 return 0; 221 return 0;
213} 222}
214 223
215unsigned int read_reg(usb_dev_handle* dh, int address) 224unsigned int read_reg(usb_dev_handle* dh, int address, int size)
216{ 225{
217 int err; 226 int err;
218 unsigned char buf[4]; 227 unsigned char buf[4];
219 228
220 SEND_COMMAND(VR_SET_DATA_ADDRESS, address); 229 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
221 SEND_COMMAND(VR_SET_DATA_LENGTH, 4); 230 SEND_COMMAND(VR_SET_DATA_LENGTH, size);
222 GET_DATA(buf, 4); 231 GET_DATA(buf, size);
232
233 if(size == 1)
234 return buf[0];
235 else if(size == 2)
236 return (buf[1] << 8) | buf[0];
237 else if(size == 4)
238 return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
239 else
240 return 0;
241}
223 242
224 return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 243int set_reg(usb_dev_handle* dh, int address, unsigned int val, int size)
244{
245 int err, i;
246 unsigned char buf[4];
247
248 buf[0] = val & 0xff;
249 if(i > 1)
250 {
251 buf[1] = (val >> 8) & 0xff;
252 if(i > 2)
253 {
254 buf[2] = (val >> 16) & 0xff;
255 buf[3] = (val >> 24) & 0xff;
256 }
257 }
258
259 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
260 SEND_DATA(buf, size);
261
262 return 0;
225} 263}
264#define or_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) | (val)), size);
265#define and_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) & (val)), size);
266#define bc_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) & ~(val)), size);
267#define xor_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) ^ (val)), size);
226 268
227#define TEST(m) fprintf(stderr, "%s -> %x\n", #m, read_reg(dh, m)); 269#define TEST(m, size) fprintf(stderr, "%s -> %x\n", #m, read_reg(dh, m, size));
228int test_device(usb_dev_handle* dh) 270int test_device(usb_dev_handle* dh)
229{ 271{
230 TEST(INTC_ISR); 272 TEST(INTC_ISR, 4);
231 TEST(INTC_IMR); 273 TEST(INTC_IMR, 4);
232 TEST(INTC_IMSR); 274 TEST(INTC_IMSR, 4);
233 TEST(INTC_IMCR); 275 TEST(INTC_IMCR, 4);
234 TEST(INTC_IPR); 276 TEST(INTC_IPR, 4);
277
278 fprintf(stderr, "\n");
279 TEST(RTC_RCR, 4);
280 TEST(RTC_RSR, 4);
281 TEST(RTC_RSAR, 4);
282 TEST(RTC_RGR, 4);
283 TEST(RTC_HCR, 4);
284 TEST(RTC_RCR, 4);
285 TEST(RTC_HWFCR, 4);
286 TEST(RTC_HRCR, 4);
287 TEST(RTC_HWCR, 4);
288 TEST(RTC_HWSR, 4);
289
290 fprintf(stderr, "\n");
291 TEST(GPIO_PXPIN(0), 4);
292 TEST(GPIO_PXPIN(1), 4);
293 TEST(GPIO_PXPIN(2), 4);
294 TEST(GPIO_PXPIN(3), 4);
295
296 fprintf(stderr, "\n");
297 TEST(CPM_CLKGR, 4);
235 298
236 fprintf(stderr, "\n"); 299 fprintf(stderr, "\n");
237 TEST(RTC_RCR); 300 //or_reg(dh, SADC_ENA, SADC_ENA_TSEN, 1);
238 TEST(RTC_RSR); 301 TEST(SADC_ENA, 1);
239 TEST(RTC_RSAR); 302 TEST(SADC_CTRL, 1);
240 TEST(RTC_RGR); 303 TEST(SADC_TSDAT, 4);
241 TEST(RTC_HCR); 304 TEST(SADC_BATDAT, 2);
242 TEST(RTC_RCR); 305 TEST(SADC_STATE, 1);
243 TEST(RTC_HWFCR);
244 TEST(RTC_HRCR);
245 TEST(RTC_HWCR);
246 TEST(RTC_HWSR);
247 306
248 fprintf(stderr, "\n"); 307 fprintf(stderr, "\n");
249 TEST(GPIO_PXPIN(0)); 308
250 TEST(GPIO_PXPIN(1)); 309 TEST(SLCD_CFG, 4);
251 TEST(GPIO_PXPIN(2)); 310 TEST(SLCD_CTRL, 1);
252 TEST(GPIO_PXPIN(3)); 311 TEST(SLCD_STATE, 1);
312
313 return 0;
314}
315
316#define VOL_DOWN (1 << 27)
317#define VOL_UP (1 << 0)
318#define MENU (1 << 1)
319#define HOLD (1 << 16)
320#define OFF (1 << 29)
321#define MASK (VOL_DOWN|VOL_UP|MENU|HOLD|OFF)
322#define TS_MASK (SADC_STATE_PEND|SADC_STATE_PENU|SADC_STATE_TSRDY)
323int probe_device(usb_dev_handle* dh)
324{
325 int tmp;
326
327 //or_reg(dh, SADC_ENA, SADC_ENA_TSEN, 1);
328 while(1)
329 {
330 if(read_reg(dh, SADC_STATE, 1) & SADC_STATE_TSRDY)
331 {
332 printf("%x\n", read_reg(dh, SADC_TSDAT, 4));
333 or_reg(dh, SADC_CTRL, read_reg(dh, SADC_STATE, 1) & TS_MASK, 1);
334 }
335
336 tmp = read_reg(dh, GPIO_PXPIN(3), 4);
337 if(tmp < 0)
338 return tmp;
339 if(tmp ^ MASK)
340 {
341 if(!(tmp & VOL_DOWN))
342 printf("VOL_DOWN\t");
343 if(!(tmp & VOL_UP))
344 printf("VOL_UP\t");
345 if(!(tmp & MENU))
346 printf("MENU\t");
347 if(!(tmp & OFF))
348 printf("OFF\t");
349 if(!(tmp & HOLD))
350 printf("HOLD\t");
351 printf("\n");
352 }
353 }
354 return 0;
355}
356
357unsigned int read_file(const char *name, unsigned char **buffer)
358{
359 FILE *fd;
360 int len, n;
361
362 fd = fopen(name, "rb");
363 if (fd < 0)
364 {
365 fprintf(stderr, "[ERR] Could not open %s\n", name);
366 return 0;
367 }
368
369 len = filesize(fd);
370
371 *buffer = (unsigned char*)malloc(len);
372 if (*buffer == NULL)
373 {
374 fprintf(stderr, "[ERR] Could not allocate memory.\n");
375 fclose(fd);
376 return 0;
377 }
378
379 n = fread(*buffer, 1, len, fd);
380 if (n != len)
381 {
382 fprintf(stderr, "[ERR] Short read.\n");
383 fclose(fd);
384 return 0;
385 }
386 fclose(fd);
387
388 return len;
389}
390#define _GET_CPU fprintf(stderr, "[INFO] GET_CPU_INFO:"); \
391 GET_CPU_INFO(cpu); \
392 cpu[8] = 0; \
393 fprintf(stderr, " %s\n", cpu);
394#define _SET_ADDR(a) fprintf(stderr, "[INFO] Set address to 0x%x...", a); \
395 SEND_COMMAND(VR_SET_DATA_ADDRESS, a); \
396 fprintf(stderr, " Done!\n");
397#define _SEND_FILE(a) fsize = read_file(a, &buffer); \
398 fprintf(stderr, "[INFO] Sending file %s: %d bytes...", a, fsize); \
399 SEND_DATA(buffer, fsize); \
400 free(buffer); \
401 fprintf(stderr, " Done!\n");
402#define _VERIFY_DATA(a,b,c) fprintf(stderr, "[INFO] Verifying data (%s)...", a); \
403 fsize = read_file(a, &buffer); \
404 buffer2 = (unsigned char*)malloc(fsize); \
405 SEND_COMMAND(VR_SET_DATA_ADDRESS, c); \
406 SEND_COMMAND(VR_SET_DATA_LENGTH, fsize); \
407 GET_DATA(buffer2, fsize); \
408 if(memcmp(buffer, buffer2, fsize) != 0) \
409 fprintf(stderr, "\n[WARN] Sent data isn't the same as received data...\n"); \
410 else \
411 fprintf(stderr, " Done!\n"); \
412 free(buffer); \
413 free(buffer2);
414#define _STAGE1(a) fprintf(stderr, "[INFO] Stage 1 at 0x%x\n", a); \
415 SEND_COMMAND(VR_PROGRAM_START1, a);
416#define _STAGE2(a) fprintf(stderr, "[INFO] Stage 2 at 0x%x\n", a); \
417 SEND_COMMAND(VR_PROGRAM_START2, a);
418#define _FLUSH fprintf(stderr, "[INFO] Flushing caches...\n"); \
419 SEND_COMMAND(VR_FLUSH_CACHES, 0);
420int mimic_of(usb_dev_handle *dh)
421{
422 int err, fsize;
423 unsigned char *buffer, *buffer2;
424 char cpu[8];
425
426 fprintf(stderr, "[INFO] Start!\n");
427 _GET_CPU;
428 _SET_ADDR(0x8000 << 16);
429 _SEND_FILE("1.bin");
430 _GET_CPU;
431 _VERIFY_DATA("1.bin", 0, 0x8000 << 16);
432 _STAGE1(0x8000 << 16);
433 Sleep(3000);
434 _VERIFY_DATA("2.bin", 0, 0xB3020060);
435 _GET_CPU;
436 _GET_CPU;
437 _FLUSH;
438 _GET_CPU;
439 _GET_CPU;
440 _SET_ADDR(0x8000 << 16);
441 _SEND_FILE("3.bin");
442 _GET_CPU;
443 _VERIFY_DATA("3.bin", 0, 0x8000 << 16);
444 _GET_CPU;
445 _FLUSH;
446 _GET_CPU;
447 _GET_CPU;
448 _SET_ADDR(0x80D0 << 16);
449 _SEND_FILE("4.bin");
450 _GET_CPU;
451 _VERIFY_DATA("4.bin", 0, 0x80D0 << 16);
452 _GET_CPU;
453 _FLUSH;
454 _GET_CPU;
455 _GET_CPU;
456 _SET_ADDR(0x80E0 << 16);
457 _SEND_FILE("5.bin");
458 _GET_CPU;
459 _VERIFY_DATA("5.bin", 3 << 16, 0x80E0 << 16);
460 _GET_CPU;
461 _FLUSH;
462 _GET_CPU;
463 _GET_CPU;
464 _SET_ADDR(0x80004000);
465 _SEND_FILE("6.bin");
466 _GET_CPU;
467 _VERIFY_DATA("6.bin", 0, 0x80004000);
468 _GET_CPU;
469 _FLUSH;
470 _GET_CPU;
471 _GET_CPU;
472 _SET_ADDR(0x80FD << 16);
473 _SEND_FILE("7.bin");
474 _GET_CPU;
475 _VERIFY_DATA("7.bin", 0, 0x80FD << 16);
476 _GET_CPU;
477 _FLUSH;
478 _GET_CPU;
479 _STAGE2(0x80FD0004);
480 _VERIFY_DATA("8.bin", 0, 0x80004004);
481 _VERIFY_DATA("9.bin", 0, 0x80004008);
482 Sleep(2000);
483 _GET_CPU;
484 _SET_ADDR(0x80E0 << 16);
485 _SEND_FILE("verminkt.bin");
486 _GET_CPU;
487 _VERIFY_DATA("verminkt.bin", 3 << 16, 0x80E0 << 16);
488 _GET_CPU;
489 _FLUSH;
490 _GET_CPU;
491 _STAGE2(0x80E0 << 16);
492 fprintf(stderr, "[INFO] Done!\n");
253 return 0; 493 return 0;
254} 494}
255 495
@@ -330,7 +570,8 @@ found:
330 switch(func) 570 switch(func)
331 { 571 {
332 case 1: 572 case 1:
333 err = upload_app(dh, address, buf, len); 573 case 5:
574 err = upload_app(dh, address, buf, len, (func == 5));
334 break; 575 break;
335 case 2: 576 case 2:
336 err = read_data(dh, address, buf, len); 577 err = read_data(dh, address, buf, len);
@@ -338,6 +579,12 @@ found:
338 case 3: 579 case 3:
339 err = test_device(dh); 580 err = test_device(dh);
340 break; 581 break;
582 case 4:
583 err = probe_device(dh);
584 break;
585 case 6:
586 err = mimic_of(dh);
587 break;
341 } 588 }
342 589
343 /* release claimed interface */ 590 /* release claimed interface */
@@ -346,15 +593,6 @@ found:
346 usb_close(dh); 593 usb_close(dh);
347} 594}
348 595
349int filesize(FILE* fd)
350{
351 int tmp;
352 fseek(fd, 0, SEEK_END);
353 tmp = ftell(fd);
354 fseek(fd, 0, SEEK_SET);
355 return tmp;
356}
357
358void print_usage(void) 596void print_usage(void)
359{ 597{
360#ifdef _WIN32 598#ifdef _WIN32
@@ -364,7 +602,8 @@ void print_usage(void)
364#endif 602#endif
365 fprintf(stderr, "\t[ADDRESS] has to be in 0xHEXADECIMAL format\n"); 603 fprintf(stderr, "\t[ADDRESS] has to be in 0xHEXADECIMAL format\n");
366 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"); 604 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");
367 fprintf(stderr, "\t\t3 -> read device status\n"); 605 fprintf(stderr, "\t\t3 -> read device status\n\t\t4 -> probe keys (only Onda VX747)\n");
606 fprintf(stderr, "\t\t5 -> same as 1 but do a stage 2 boot\n\t\t6 -> mimic OF fw recovery\n");
368#ifdef _WIN32 607#ifdef _WIN32
369 fprintf(stderr, "\nExample:\n\t usbtool.exe 1 fw.bin 0x80000000"); 608 fprintf(stderr, "\nExample:\n\t usbtool.exe 1 fw.bin 0x80000000");
370 fprintf(stderr, "\n\t usbtool.exe 2 save.bin 0x81000000 1024"); 609 fprintf(stderr, "\n\t usbtool.exe 2 save.bin 0x81000000 1024");
@@ -388,11 +627,17 @@ int main(int argc, char* argv[])
388 sscanf(argv[1], "%d", &cmd); 627 sscanf(argv[1], "%d", &cmd);
389 switch(cmd) 628 switch(cmd)
390 { 629 {
630 case 5:
391 case 1: 631 case 1:
392 if (sscanf(argv[3], "0x%x", &address) <= 0) 632 if (strcmp(argv[3], "-1") == 0)
633 address = 0x80000000;
634 else
393 { 635 {
394 print_usage(); 636 if (sscanf(argv[3], "0x%x", &address) <= 0)
395 return -1; 637 {
638 print_usage();
639 return -1;
640 }
396 } 641 }
397 642
398 fd = fopen(argv[2], "rb"); 643 fd = fopen(argv[2], "rb");
@@ -430,7 +675,7 @@ int main(int argc, char* argv[])
430 675
431 fprintf(stderr, "[INFO] File size: %d bytes\n", n); 676 fprintf(stderr, "[INFO] File size: %d bytes\n", n);
432 677
433 jzconnect(address, buf, len, 1); 678 jzconnect(address, buf, len, cmd);
434 break; 679 break;
435 case 2: 680 case 2:
436 if (sscanf(argv[3], "0x%x", &address) <= 0) 681 if (sscanf(argv[3], "0x%x", &address) <= 0)
@@ -468,7 +713,9 @@ int main(int argc, char* argv[])
468 fclose(fd); 713 fclose(fd);
469 break; 714 break;
470 case 3: 715 case 3:
471 jzconnect(address, NULL, 0, 3); 716 case 4:
717 case 6:
718 jzconnect(address, NULL, 0, cmd);
472 break; 719 break;
473 default: 720 default:
474 print_usage(); 721 print_usage();