From 4e23a51d534429aff52370964427d56504eb5ae0 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Mon, 27 Apr 2009 16:08:41 +0000 Subject: [PATCH] now inflash can upload stage2 --- flash-tool/main.c | 146 ++++++++++++++++++++++++++++++---- flash-tool/main.h | 4 +- flash-tool/usb.c | 26 ++++-- flash-tool/usb_boot_defines.h | 4 +- 4 files changed, 152 insertions(+), 28 deletions(-) diff --git a/flash-tool/main.c b/flash-tool/main.c index 8c88aac..efffda6 100644 --- a/flash-tool/main.c +++ b/flash-tool/main.c @@ -68,14 +68,100 @@ static int parse_configure(char * file_path) cfg_free(cfg); fw_args.cpu_id = 0x4740; + if (fw_args.bus_width == 32) + fw_args.bus_width = 0 ; + else + fw_args.bus_width = 1 ; + fw_args.bank_num = fw_args.bank_num / 4; + fw_args.cpu_speed = fw_args.cpu_speed / fw_args.ext_clk; - total_size = (unsigned int)(2 << (fw_args.row_addr + fw_args.col_addr - 1)) * 2 + total_size = (unsigned int) + (2 << (fw_args.row_addr + fw_args.col_addr - 1)) * 2 * (fw_args.bank_num + 1) * 2 * (2 - fw_args.bus_width); return 1; } +int check_dump_cfg() +{ + printf("\n Now checking whether all configure args valid: "); + /* check PLL */ + if (fw_args.ext_clk > 27 || fw_args.ext_clk < 12 ) { + printf("\n EXTCLK setting invalid!"); + return 0; + } + if (fw_args.phm_div > 32 || fw_args.ext_clk < 2 ) { + printf("\n PHMDIV setting invalid!"); + return 0; + } + if ( (fw_args.cpu_speed * fw_args.ext_clk ) % 12 != 0 ) { + printf("\n CPUSPEED setting invalid!"); + return 0; + } + + /* check SDRAM */ + if (fw_args.bus_width > 1 ) { + printf("\n SDRAMWIDTH setting invalid!"); + return 0; + } + if (fw_args.bank_num > 1 ) { + printf("\n BANKNUM setting invalid!"); + return 0; + } + if (fw_args.row_addr > 13 && fw_args.row_addr < 11 ) { + printf("\n ROWADDR setting invalid!"); + return 0; + } + if (fw_args.col_addr > 13 && fw_args.col_addr < 11 ) { + printf("\n COLADDR setting invalid!"); + return 0; + } + + /* check NAND */ + /* if ( Hand.nand_ps < 2048 && Hand.nand_os > 16 ) + { + printf("\n PAGESIZE or OOBSIZE setting invalid!"); + return 0; + } + if ( Hand.nand_ps < 2048 && Hand.nand_ppb > 32 ) + { + printf("\n PAGESIZE or PAGEPERBLOCK setting invalid!"); + return 0; + } + + if ( Hand.nand_ps > 512 && Hand.nand_os <= 16 ) + { + printf("\n PAGESIZE or OOBSIZE setting invalid!"); + return 0; + } + if ( Hand.nand_ps > 512 && Hand.nand_ppb < 64 ) + { + printf("\n PAGESIZE or PAGEPERBLOCK setting invalid!"); + return 0; + } */ + + printf("\n Current device information:"); + printf(" CPU is Jz%x",fw_args.cpu_id); + printf("\n Crystal work at %dMHz, the CCLK up to %dMHz and PMH_CLK up to %dMHz", + fw_args.ext_clk, + (unsigned int)fw_args.cpu_speed * fw_args.ext_clk, + ((unsigned int)fw_args.cpu_speed * fw_args.ext_clk) / fw_args.phm_div); + + printf("\n Total SDRAM size is %d MB, work in %d bank and %d bit mode", + total_size / 0x100000, 2 * (fw_args.bank_num + 1), 16 * (2 - fw_args.bus_width)); + + /* printf("\n Nand page size %d, ECC offset %d, ", + Hand.nand_ps,Hand.nand_eccpos); + + printf("bad block ID %d, ",Hand.nand_bbpage); + + printf("use %d plane mode",Hand.nand_plane); */ + + printf("\n"); + return 1; +} + static int load_file(struct ingenic_dev *ingenic_dev, const char *file_path) { struct stat fstat; @@ -130,6 +216,7 @@ int main(int argc, char **argv) struct ingenic_dev ingenic_dev; int res = EXIT_FAILURE; + int status; if ((getuid()) || (getgid())) { fprintf(stderr, "Error - you must be root to run '%s'\n", argv[0]); @@ -145,27 +232,54 @@ int main(int argc, char **argv) if (usb_ingenic_init(&ingenic_dev) < 1) goto out; - if (usb_get_ingenic_cpu(&ingenic_dev) < 1) + status = usb_get_ingenic_cpu(&ingenic_dev); + switch (status) { + case 1: /* Jz4740v1 */ + status = 0; + fw_args.cpu_id = 0x4740; + break; + case 2: /* Jz4750v1 */ + status = 0; + fw_args.cpu_id = 0x4750; + break; + case 3: /* Boot4740 */ + status = 1; + fw_args.cpu_id = 0x4740; + break; + case 4: /* Boot4750 */ + status = 1; + fw_args.cpu_id = 0x4750; + break; + default: goto out; + } - /* now we upload the usb boot stage1 */ - printf("upload usb boot stage1\n"); - if (load_file(&ingenic_dev, STAGE1_FILE_PATH) < 1) + if (status) { + printf("Booted"); goto out; + } else { + printf("Unboot"); + printf("\n Now booting device"); - if (usb_ingenic_upload(&ingenic_dev, 1) < 1) - goto cleanup; -#if 0 - /* now we upload the usb boot stage2 */ - sleep(1); - printf("upload usb boot stage2\n"); - if (load_file(&ingenic_dev, STAGE2_FILE_PATH) < 1) - goto cleanup; + /* now we upload the usb boot stage1 */ + printf("\n Upload usb boot stage1"); + if (load_file(&ingenic_dev, STAGE1_FILE_PATH) < 1) + goto out; - if (usb_ingenic_upload(&ingenic_dev, 2) < 1) - goto cleanup; + if (usb_ingenic_upload(&ingenic_dev, 1) < 1) + goto cleanup; + + /* now we upload the usb boot stage2 */ + sleep(1); + printf("\n Upload usb boot stage2"); + if (load_file(&ingenic_dev, STAGE2_FILE_PATH) < 1) + goto cleanup; + + if (usb_ingenic_upload(&ingenic_dev, 2) < 1) + goto cleanup; + check_dump_cfg(); + } -#endif res = EXIT_SUCCESS; cleanup: diff --git a/flash-tool/main.h b/flash-tool/main.h index c76c1e0..09d2770 100644 --- a/flash-tool/main.h +++ b/flash-tool/main.h @@ -35,10 +35,10 @@ struct ingenic_dev { struct usb_device *usb_dev; struct usb_dev_handle *usb_handle; uint8_t interface; - char cpu_info_buff[8]; + char cpu_info_buff[9]; char *file_buff; int file_len; }; -unsigned total_size; +unsigned int total_size; diff --git a/flash-tool/usb.c b/flash-tool/usb.c index 6268881..afbe5b7 100644 --- a/flash-tool/usb.c +++ b/flash-tool/usb.c @@ -149,19 +149,25 @@ int usb_get_ingenic_cpu(struct ingenic_dev *ingenic_dev) /* wLength */ 8, USB_TIMEOUT); - if (status != sizeof(ingenic_dev->cpu_info_buff)) { + if (status != sizeof(ingenic_dev->cpu_info_buff) - 1 ) { fprintf(stderr, "Error - can't retrieve Ingenic CPU information: %i\n", status); return status; } - printf("CPU data: %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x : %s\n", + ingenic_dev->cpu_info_buff[8] = '\0'; + printf("\n CPU data: %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x : %s\n", ingenic_dev->cpu_info_buff[0], ingenic_dev->cpu_info_buff[1], ingenic_dev->cpu_info_buff[2], ingenic_dev->cpu_info_buff[3], ingenic_dev->cpu_info_buff[4], ingenic_dev->cpu_info_buff[5], ingenic_dev->cpu_info_buff[6], ingenic_dev->cpu_info_buff[7], ingenic_dev->cpu_info_buff); - return 1; + if (!strcmp(ingenic_dev->cpu_info_buff,"JZ4740V1")) return 1; + if (!strcmp(ingenic_dev->cpu_info_buff,"JZ4750V1")) return 2; + if (!strcmp(ingenic_dev->cpu_info_buff,"Boot4740")) return 3; + if (!strcmp(ingenic_dev->cpu_info_buff,"Boot4750")) return 4; + + return 0; } int usb_ingenic_flush_cache(struct ingenic_dev *ingenic_dev) @@ -177,7 +183,7 @@ int usb_ingenic_flush_cache(struct ingenic_dev *ingenic_dev) /* wLength */ 0, USB_TIMEOUT); - if (status != sizeof(ingenic_dev->cpu_info_buff)) { + if (status != 0) { fprintf(stderr, "Error - can't flush cache: %i\n", status); return status; } @@ -192,13 +198,14 @@ int usb_ingenic_upload(struct ingenic_dev *ingenic_dev, int stage) unsigned int stage2_addr; stage2_addr = total_size + 0x80000000; stage2_addr -= CODE_SIZE; + int stage_addr = (stage == 1 ? 0x80002000 : stage2_addr); /* tell the device the RAM address to store the file */ status = usb_control_msg(ingenic_dev->usb_handle, /* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, /* bRequest */ VR_SET_DATA_ADDRESS, - /* wValue */ STAGE_ADDR_MSB(stage == 1 ? 0x80002000 : stage2_addr), - /* wIndex */ STAGE_ADDR_LSB(stage == 1 ? 0x80002000 : stage2_addr), + /* wValue */ STAGE_ADDR_MSB(stage_addr), + /* wIndex */ STAGE_ADDR_LSB(stage_addr), /* Data */ 0, /* wLength */ 0, USB_TIMEOUT); @@ -223,6 +230,7 @@ int usb_ingenic_upload(struct ingenic_dev *ingenic_dev, int stage) fprintf(stderr, "Error - can't set data length on Ingenic device: %i\n", status); #endif + printf("\n Download stage %d program and execute at 0x%08x ", stage, (stage_addr)); /* upload the file */ status = usb_bulk_write(ingenic_dev->usb_handle, /* endpoint */ INGENIC_OUT_ENDPOINT, @@ -236,6 +244,7 @@ int usb_ingenic_upload(struct ingenic_dev *ingenic_dev, int stage) } if (stage == 2) { + sleep(1); usb_get_ingenic_cpu(ingenic_dev); usb_ingenic_flush_cache(ingenic_dev); } @@ -244,8 +253,8 @@ int usb_ingenic_upload(struct ingenic_dev *ingenic_dev, int stage) status = usb_control_msg(ingenic_dev->usb_handle, /* bmRequestType */ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, /* bRequest */ (stage == 1 ? VR_PROGRAM_START1 : VR_PROGRAM_START2), - /* wValue */ STAGE_ADDR_MSB(stage == 1 ? 0x80002000 : stage2_addr), - /* wIndex */ STAGE_ADDR_LSB(stage == 1 ? 0x80002000 : stage2_addr), + /* wValue */ STAGE_ADDR_MSB(stage_addr), + /* wIndex */ STAGE_ADDR_LSB(stage_addr), /* Data */ 0, /* wLength */ 0, USB_TIMEOUT); @@ -255,6 +264,7 @@ int usb_ingenic_upload(struct ingenic_dev *ingenic_dev, int stage) goto out; } + sleep(1); usb_get_ingenic_cpu(ingenic_dev); status = 1; diff --git a/flash-tool/usb_boot_defines.h b/flash-tool/usb_boot_defines.h index 7a0c8c0..b90a166 100644 --- a/flash-tool/usb_boot_defines.h +++ b/flash-tool/usb_boot_defines.h @@ -107,7 +107,7 @@ typedef struct { /* for align */ /* unsigned char align1; */ /* unsigned char align2; */ -}fw_args_t; +} __attribute__((packed)) fw_args_t; typedef struct { @@ -130,6 +130,6 @@ typedef struct { fw_args_t fw_args; -} hand_t; +} __attribute__((packed)) hand_t; #endif /* __JZ4740_USBDEFINES__H_ */