From 5caf1bb8ba91afe6e75cede6875e47fe1f3b1270 Mon Sep 17 00:00:00 2001 From: mcuelenaere Date: Tue, 24 Jun 2008 20:14:00 +0000 Subject: [PATCH] More improvements to jz4740_usbtool git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17785 a1c6a512-1295-4272-9138-f99709370657 --- utils/jz4740_usbtool/jz4740_usbtool.c | 359 ++++++++++++++++++++++++++++------ 1 file changed, 303 insertions(+), 56 deletions(-) diff --git a/utils/jz4740_usbtool/jz4740_usbtool.c b/utils/jz4740_usbtool/jz4740_usbtool.c index 84ffbf709..4634f0502 100755 --- a/utils/jz4740_usbtool/jz4740_usbtool.c +++ b/utils/jz4740_usbtool/jz4740_usbtool.c @@ -34,8 +34,10 @@ #include #include #include "jz4740.h" +#include +#include -#define VERSION "0.2" +#define VERSION "0.3" #define MAX_FIRMWARESIZE (64*1024*1024) /* Arbitrary limit (for safety) */ @@ -51,10 +53,6 @@ #define EP_BULK_TO 0x01 #define TOUT 5000 -#ifndef MAX -#define MAX(a,b) (((a)>(b))?(a):(b)) -#endif - enum USB_JZ4740_REQUEST { VR_GET_CPU_INFO = 0, @@ -118,6 +116,15 @@ enum OPTION NO_OOB, }; +int filesize(FILE* fd) +{ + int tmp; + fseek(fd, 0, SEEK_END); + tmp = ftell(fd); + fseek(fd, 0, SEEK_SET); + return tmp; +} + #define SEND_COMMAND(cmd, arg) err = usb_control_msg(dh, USB_ENDPOINT_OUT | USB_TYPE_VENDOR, cmd, arg>>16, arg&0xFFFF, NULL, 0, TOUT);\ if (err < 0) \ { \ @@ -125,7 +132,7 @@ enum OPTION return -1; \ } -#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); \ +#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); \ if (err < 0) \ { \ fprintf(stderr,"\n[ERR] Error sending control message (%d, %s)\n", err, usb_strerror()); \ @@ -133,7 +140,7 @@ enum OPTION } #define SEND_DATA(ptr, size) err = usb_bulk_write(dh, USB_ENDPOINT_OUT | EP_BULK_TO, ptr, size, TOUT); \ - if (err != len) \ + if (err != size) \ { \ fprintf(stderr,"\n[ERR] Error writing data\n"); \ fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err)); \ @@ -148,7 +155,7 @@ enum OPTION return -1; \ } -int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len) +int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len, bool stage2) { int err; char buf[8]; @@ -158,6 +165,11 @@ int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len) GET_CPU_INFO(buf); buf[8] = 0; fprintf(stderr, "%s\n", buf); +#if 0 + fprintf(stderr, "[INFO] Flushing cache..."); + SEND_COMMAND(VR_FLUSH_CACHES, 0); + fprintf(stderr, " Done!\n"); +#endif fprintf(stderr, "[INFO] SET_DATA_ADDRESS to 0x%x...", address); 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) } GET_DATA(tmp_buf, len); if (memcmp(tmp_buf, p, len) != 0) - { - fprintf(stderr, "\n[ERR] Sent data isn't the same as received data...\n"); - free(tmp_buf); - return -1; - } + fprintf(stderr, "\n[WARN] Sent data isn't the same as received data...\n"); + else + fprintf(stderr, " Done!\n"); free(tmp_buf); - fprintf(stderr, " Done !\n"); - fprintf(stderr, "[INFO] Booting device..."); - SEND_COMMAND(VR_PROGRAM_START1, address); + fprintf(stderr, "[INFO] Booting device [STAGE%d]...", (stage2 ? 2 : 1)); + SEND_COMMAND((stage2 ? VR_PROGRAM_START2 : VR_PROGRAM_START1), (address+(stage2 ? 8 : 0)) ); fprintf(stderr, " Done!\n"); return 0; @@ -212,44 +221,275 @@ int read_data(usb_dev_handle* dh, int address, unsigned char *p, int len) return 0; } -unsigned int read_reg(usb_dev_handle* dh, int address) +unsigned int read_reg(usb_dev_handle* dh, int address, int size) { int err; unsigned char buf[4]; SEND_COMMAND(VR_SET_DATA_ADDRESS, address); - SEND_COMMAND(VR_SET_DATA_LENGTH, 4); - GET_DATA(buf, 4); + SEND_COMMAND(VR_SET_DATA_LENGTH, size); + GET_DATA(buf, size); + + if(size == 1) + return buf[0]; + else if(size == 2) + return (buf[1] << 8) | buf[0]; + else if(size == 4) + return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; + else + return 0; +} - return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; +int set_reg(usb_dev_handle* dh, int address, unsigned int val, int size) +{ + int err, i; + unsigned char buf[4]; + + buf[0] = val & 0xff; + if(i > 1) + { + buf[1] = (val >> 8) & 0xff; + if(i > 2) + { + buf[2] = (val >> 16) & 0xff; + buf[3] = (val >> 24) & 0xff; + } + } + + SEND_COMMAND(VR_SET_DATA_ADDRESS, address); + SEND_DATA(buf, size); + + return 0; } +#define or_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) | (val)), size); +#define and_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) & (val)), size); +#define bc_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) & ~(val)), size); +#define xor_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) ^ (val)), size); -#define TEST(m) fprintf(stderr, "%s -> %x\n", #m, read_reg(dh, m)); +#define TEST(m, size) fprintf(stderr, "%s -> %x\n", #m, read_reg(dh, m, size)); int test_device(usb_dev_handle* dh) { - TEST(INTC_ISR); - TEST(INTC_IMR); - TEST(INTC_IMSR); - TEST(INTC_IMCR); - TEST(INTC_IPR); + TEST(INTC_ISR, 4); + TEST(INTC_IMR, 4); + TEST(INTC_IMSR, 4); + TEST(INTC_IMCR, 4); + TEST(INTC_IPR, 4); + + fprintf(stderr, "\n"); + TEST(RTC_RCR, 4); + TEST(RTC_RSR, 4); + TEST(RTC_RSAR, 4); + TEST(RTC_RGR, 4); + TEST(RTC_HCR, 4); + TEST(RTC_RCR, 4); + TEST(RTC_HWFCR, 4); + TEST(RTC_HRCR, 4); + TEST(RTC_HWCR, 4); + TEST(RTC_HWSR, 4); + + fprintf(stderr, "\n"); + TEST(GPIO_PXPIN(0), 4); + TEST(GPIO_PXPIN(1), 4); + TEST(GPIO_PXPIN(2), 4); + TEST(GPIO_PXPIN(3), 4); + + fprintf(stderr, "\n"); + TEST(CPM_CLKGR, 4); fprintf(stderr, "\n"); - TEST(RTC_RCR); - TEST(RTC_RSR); - TEST(RTC_RSAR); - TEST(RTC_RGR); - TEST(RTC_HCR); - TEST(RTC_RCR); - TEST(RTC_HWFCR); - TEST(RTC_HRCR); - TEST(RTC_HWCR); - TEST(RTC_HWSR); + //or_reg(dh, SADC_ENA, SADC_ENA_TSEN, 1); + TEST(SADC_ENA, 1); + TEST(SADC_CTRL, 1); + TEST(SADC_TSDAT, 4); + TEST(SADC_BATDAT, 2); + TEST(SADC_STATE, 1); fprintf(stderr, "\n"); - TEST(GPIO_PXPIN(0)); - TEST(GPIO_PXPIN(1)); - TEST(GPIO_PXPIN(2)); - TEST(GPIO_PXPIN(3)); + + TEST(SLCD_CFG, 4); + TEST(SLCD_CTRL, 1); + TEST(SLCD_STATE, 1); + + return 0; +} + +#define VOL_DOWN (1 << 27) +#define VOL_UP (1 << 0) +#define MENU (1 << 1) +#define HOLD (1 << 16) +#define OFF (1 << 29) +#define MASK (VOL_DOWN|VOL_UP|MENU|HOLD|OFF) +#define TS_MASK (SADC_STATE_PEND|SADC_STATE_PENU|SADC_STATE_TSRDY) +int probe_device(usb_dev_handle* dh) +{ + int tmp; + + //or_reg(dh, SADC_ENA, SADC_ENA_TSEN, 1); + while(1) + { + if(read_reg(dh, SADC_STATE, 1) & SADC_STATE_TSRDY) + { + printf("%x\n", read_reg(dh, SADC_TSDAT, 4)); + or_reg(dh, SADC_CTRL, read_reg(dh, SADC_STATE, 1) & TS_MASK, 1); + } + + tmp = read_reg(dh, GPIO_PXPIN(3), 4); + if(tmp < 0) + return tmp; + if(tmp ^ MASK) + { + if(!(tmp & VOL_DOWN)) + printf("VOL_DOWN\t"); + if(!(tmp & VOL_UP)) + printf("VOL_UP\t"); + if(!(tmp & MENU)) + printf("MENU\t"); + if(!(tmp & OFF)) + printf("OFF\t"); + if(!(tmp & HOLD)) + printf("HOLD\t"); + printf("\n"); + } + } + return 0; +} + +unsigned int read_file(const char *name, unsigned char **buffer) +{ + FILE *fd; + int len, n; + + fd = fopen(name, "rb"); + if (fd < 0) + { + fprintf(stderr, "[ERR] Could not open %s\n", name); + return 0; + } + + len = filesize(fd); + + *buffer = (unsigned char*)malloc(len); + if (*buffer == NULL) + { + fprintf(stderr, "[ERR] Could not allocate memory.\n"); + fclose(fd); + return 0; + } + + n = fread(*buffer, 1, len, fd); + if (n != len) + { + fprintf(stderr, "[ERR] Short read.\n"); + fclose(fd); + return 0; + } + fclose(fd); + + return len; +} +#define _GET_CPU fprintf(stderr, "[INFO] GET_CPU_INFO:"); \ + GET_CPU_INFO(cpu); \ + cpu[8] = 0; \ + fprintf(stderr, " %s\n", cpu); +#define _SET_ADDR(a) fprintf(stderr, "[INFO] Set address to 0x%x...", a); \ + SEND_COMMAND(VR_SET_DATA_ADDRESS, a); \ + fprintf(stderr, " Done!\n"); +#define _SEND_FILE(a) fsize = read_file(a, &buffer); \ + fprintf(stderr, "[INFO] Sending file %s: %d bytes...", a, fsize); \ + SEND_DATA(buffer, fsize); \ + free(buffer); \ + fprintf(stderr, " Done!\n"); +#define _VERIFY_DATA(a,b,c) fprintf(stderr, "[INFO] Verifying data (%s)...", a); \ + fsize = read_file(a, &buffer); \ + buffer2 = (unsigned char*)malloc(fsize); \ + SEND_COMMAND(VR_SET_DATA_ADDRESS, c); \ + SEND_COMMAND(VR_SET_DATA_LENGTH, fsize); \ + GET_DATA(buffer2, fsize); \ + if(memcmp(buffer, buffer2, fsize) != 0) \ + fprintf(stderr, "\n[WARN] Sent data isn't the same as received data...\n"); \ + else \ + fprintf(stderr, " Done!\n"); \ + free(buffer); \ + free(buffer2); +#define _STAGE1(a) fprintf(stderr, "[INFO] Stage 1 at 0x%x\n", a); \ + SEND_COMMAND(VR_PROGRAM_START1, a); +#define _STAGE2(a) fprintf(stderr, "[INFO] Stage 2 at 0x%x\n", a); \ + SEND_COMMAND(VR_PROGRAM_START2, a); +#define _FLUSH fprintf(stderr, "[INFO] Flushing caches...\n"); \ + SEND_COMMAND(VR_FLUSH_CACHES, 0); +int mimic_of(usb_dev_handle *dh) +{ + int err, fsize; + unsigned char *buffer, *buffer2; + char cpu[8]; + + fprintf(stderr, "[INFO] Start!\n"); + _GET_CPU; + _SET_ADDR(0x8000 << 16); + _SEND_FILE("1.bin"); + _GET_CPU; + _VERIFY_DATA("1.bin", 0, 0x8000 << 16); + _STAGE1(0x8000 << 16); + Sleep(3000); + _VERIFY_DATA("2.bin", 0, 0xB3020060); + _GET_CPU; + _GET_CPU; + _FLUSH; + _GET_CPU; + _GET_CPU; + _SET_ADDR(0x8000 << 16); + _SEND_FILE("3.bin"); + _GET_CPU; + _VERIFY_DATA("3.bin", 0, 0x8000 << 16); + _GET_CPU; + _FLUSH; + _GET_CPU; + _GET_CPU; + _SET_ADDR(0x80D0 << 16); + _SEND_FILE("4.bin"); + _GET_CPU; + _VERIFY_DATA("4.bin", 0, 0x80D0 << 16); + _GET_CPU; + _FLUSH; + _GET_CPU; + _GET_CPU; + _SET_ADDR(0x80E0 << 16); + _SEND_FILE("5.bin"); + _GET_CPU; + _VERIFY_DATA("5.bin", 3 << 16, 0x80E0 << 16); + _GET_CPU; + _FLUSH; + _GET_CPU; + _GET_CPU; + _SET_ADDR(0x80004000); + _SEND_FILE("6.bin"); + _GET_CPU; + _VERIFY_DATA("6.bin", 0, 0x80004000); + _GET_CPU; + _FLUSH; + _GET_CPU; + _GET_CPU; + _SET_ADDR(0x80FD << 16); + _SEND_FILE("7.bin"); + _GET_CPU; + _VERIFY_DATA("7.bin", 0, 0x80FD << 16); + _GET_CPU; + _FLUSH; + _GET_CPU; + _STAGE2(0x80FD0004); + _VERIFY_DATA("8.bin", 0, 0x80004004); + _VERIFY_DATA("9.bin", 0, 0x80004008); + Sleep(2000); + _GET_CPU; + _SET_ADDR(0x80E0 << 16); + _SEND_FILE("verminkt.bin"); + _GET_CPU; + _VERIFY_DATA("verminkt.bin", 3 << 16, 0x80E0 << 16); + _GET_CPU; + _FLUSH; + _GET_CPU; + _STAGE2(0x80E0 << 16); + fprintf(stderr, "[INFO] Done!\n"); return 0; } @@ -330,7 +570,8 @@ found: switch(func) { case 1: - err = upload_app(dh, address, buf, len); + case 5: + err = upload_app(dh, address, buf, len, (func == 5)); break; case 2: err = read_data(dh, address, buf, len); @@ -338,6 +579,12 @@ found: case 3: err = test_device(dh); break; + case 4: + err = probe_device(dh); + break; + case 6: + err = mimic_of(dh); + break; } /* release claimed interface */ @@ -346,15 +593,6 @@ found: usb_close(dh); } -int filesize(FILE* fd) -{ - int tmp; - fseek(fd, 0, SEEK_END); - tmp = ftell(fd); - fseek(fd, 0, SEEK_SET); - return tmp; -} - void print_usage(void) { #ifdef _WIN32 @@ -364,7 +602,8 @@ void print_usage(void) #endif fprintf(stderr, "\t[ADDRESS] has to be in 0xHEXADECIMAL format\n"); 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"); - fprintf(stderr, "\t\t3 -> read device status\n"); + fprintf(stderr, "\t\t3 -> read device status\n\t\t4 -> probe keys (only Onda VX747)\n"); + fprintf(stderr, "\t\t5 -> same as 1 but do a stage 2 boot\n\t\t6 -> mimic OF fw recovery\n"); #ifdef _WIN32 fprintf(stderr, "\nExample:\n\t usbtool.exe 1 fw.bin 0x80000000"); fprintf(stderr, "\n\t usbtool.exe 2 save.bin 0x81000000 1024"); @@ -388,11 +627,17 @@ int main(int argc, char* argv[]) sscanf(argv[1], "%d", &cmd); switch(cmd) { + case 5: case 1: - if (sscanf(argv[3], "0x%x", &address) <= 0) + if (strcmp(argv[3], "-1") == 0) + address = 0x80000000; + else { - print_usage(); - return -1; + if (sscanf(argv[3], "0x%x", &address) <= 0) + { + print_usage(); + return -1; + } } fd = fopen(argv[2], "rb"); @@ -430,7 +675,7 @@ int main(int argc, char* argv[]) fprintf(stderr, "[INFO] File size: %d bytes\n", n); - jzconnect(address, buf, len, 1); + jzconnect(address, buf, len, cmd); break; case 2: if (sscanf(argv[3], "0x%x", &address) <= 0) @@ -468,7 +713,9 @@ int main(int argc, char* argv[]) fclose(fd); break; case 3: - jzconnect(address, NULL, 0, 3); + case 4: + case 6: + jzconnect(address, NULL, 0, cmd); break; default: print_usage(); -- 2.11.4.GIT