2 * USB Downloader for SAMSUNG Platform
4 * Copyright (C) 2007-2008 Samsung Electronics
5 * Minkyu Kang <mk7.kang@samsung.com>
11 #include <asm/errno.h>
14 /* version of USB Downloader Application */
15 #define APP_VERSION "1.6.0"
20 #ifdef CONFIG_CMD_MTDPARTS
21 #include <jffs2/load_kernel.h>
22 static struct part_info *parts[16];
25 #ifdef CONFIG_UBIFS_MK
26 #include <mkfs.ubifs.h>
35 static const char pszMe[] = "usbd: ";
37 static struct usbd_ops usbd_ops;
39 static unsigned int part_id;
40 static unsigned int write_part = 0;
41 static unsigned int fs_offset = 0x0;
43 #ifdef CONFIG_USE_YAFFS
44 static unsigned int yaffs_len = 0;
45 static unsigned char yaffs_data[2112];
46 #define YAFFS_PAGE 2112
49 #define NAND_PAGE_SIZE 2048
51 static unsigned long down_ram_addr;
55 /* cpu/${CPU} dependent */
56 extern void do_reset(void);
59 extern int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
60 extern int do_run(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
62 int mtdparts_init(void);
63 int find_dev_and_part(const char*, struct mtd_device**, u8*, struct part_info**);
65 /* common/cmd_jffs2.c */
66 extern struct list_head devices;
68 static u8 count_mtdparts(void)
70 struct list_head *dentry, *pentry;
71 struct mtd_device *dev;
74 list_for_each(dentry, &devices) {
75 dev = list_entry(dentry, struct mtd_device, link);
77 /* list partitions for given device */
78 list_for_each(pentry, &dev->parts)
86 static int check_ubi_mode(void)
91 env_ubifs = getenv("ubi");
92 ubi_mode = !strcmp(env_ubifs, "enabled");
97 #define check_ubi_mode() 0
100 #ifdef CONFIG_MTD_PARTITIONS
101 static int get_part_info(void)
103 struct mtd_device *dev;
111 #if defined(CONFIG_CMD_NAND)
112 sprintf(nand_name, "nand0");
113 #elif defined(CONFIG_CMD_ONENAND)
114 sprintf(nand_name, "onenand0");
116 printf("Configure your NAND sub-system\n");
123 ubi_mode = check_ubi_mode();
125 part_num = count_mtdparts();
126 for (i = 0; i < part_num; i++) {
127 sprintf(part_name, "%s,%d", nand_name, i);
129 if (find_dev_and_part(part_name, &dev, &out_partnum, &parts[i]))
136 static int get_part_id(char *name)
138 int nparts = count_mtdparts();
141 for (i = 0; i < nparts; i++) {
142 if (strcmp(parts[i]->name, name) == 0)
146 printf("Error: Unknown partition -> %s\n", name);
150 static int get_part_info(void)
152 printf("Error: Can't get patition information\n");
156 static int get_part_id(char *name)
162 static void boot_cmd(char *addr)
164 char *argv[] = { "bootm", addr };
165 do_bootm(NULL, 0, 2, argv);
168 static void run_cmd(char *cmd)
170 char *argv[] = { "run", cmd };
171 do_run(NULL, 0, 2, argv);
174 #if defined(CONFIG_CMD_NAND)
175 extern int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
176 #elif defined(CONFIG_CMD_ONENAND)
177 extern int do_onenand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
180 /* NAND erase and write using nand command */
181 static int nand_cmd(int type, char *p1, char *p2, char *p3)
185 int (*nand_func) (cmd_tbl_t *, int, int, char **);
187 #if defined(CONFIG_CMD_NAND)
188 sprintf(nand_name, "nand");
190 #elif defined(CONFIG_CMD_ONENAND)
191 sprintf(nand_name, "onenand");
192 nand_func = do_onenand;
194 printf("Configure your NAND sub-system\n");
199 char *argv[] = {nand_name, "erase", p1, p2};
200 printf("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
201 ret = nand_func(NULL, 0, 4, argv);
202 } else if (type == 1) {
203 char *argv[] = {nand_name, "write", p1, p2, p3};
204 printf("%s %s %s %s %s\n", argv[0], argv[1], argv[2],
206 ret = nand_func(NULL, 0, 5, argv);
207 } else if (type == 2) {
208 char *argv[] = {nand_name, "write.yaffs", p1, p2, p3};
209 printf("%s %s %s %s %s\n", argv[0], argv[1], argv[2],
211 ret = nand_func(NULL, 0, 5, argv);
212 } else if (type == 3) {
213 char *argv[] = {nand_name, "lock", p1, p2};
214 printf("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
215 ret = nand_func(NULL, 0, 4, argv);
219 printf("Error: NAND Command\n");
224 #ifdef CONFIG_CMD_UBI
225 int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
227 int ubi_cmd(int part, char *p1, char *p2, char *p3)
231 if (part == RAMDISK_PART_ID) {
232 char *argv[] = {"ubi", "write", p1, "rootfs.cramfs", p2, p3};
233 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
234 argv[3], argv[4], argv[5]);
235 ret = do_ubi(NULL, 0, 6, argv);
236 } else if (part == FILESYSTEM_PART_ID) {
237 char *argv[] = {"ubi", "write", p1, "factoryfs.cramfs", p2, p3};
238 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
239 argv[3], argv[4], argv[5]);
240 ret = do_ubi(NULL, 0, 6, argv);
241 } else if (part == FILESYSTEM2_PART_ID) {
242 char *argv[] = {"ubi", "write", p1, "datafs.ubifs", p2, p3};
243 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
244 argv[3], argv[4], argv[5]);
245 ret = do_ubi(NULL, 0, 6, argv);
252 #ifdef CONFIG_CMD_MMC
255 extern int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
257 static int mmc_cmd(int ops, char *p1, char *p2, char *p3)
262 char *argv[] = {"mmc", "write", "0", p1, p2, p3};
263 ret = do_mmcops(NULL, 0, 6, argv);
265 char *argv[] = {"mmc", "read", "0", p1, p2, p3};
266 ret = do_mmcops(NULL, 0, 6, argv);
272 #define NORMAL_PARTITION 0
273 #define EXTEND_PARTITION 1
275 #define EXTEND_PART_TYPE 5
277 #define EXTEND_MAX_PART 32
279 static unsigned int cur_blk_offset;
280 static unsigned int cur_part_size;
281 static unsigned int cur_part;
283 static unsigned int mmc_parts;
284 static unsigned int mmc_part_write;
286 static u8 part_mode = 0;
288 struct partition_info {
292 } __attribute__((packed));
294 struct partition_header {
295 u8 fat32head[16]; /* RFSHEAD identifier */
296 struct partition_info partition[EXTEND_MAX_PART];
297 u8 res[112]; /* only data (without MBR) */
298 } __attribute__((packed));
300 struct partition_table {
307 } __attribute__((packed));
311 struct partition_table partition[4];
313 } __attribute__((packed));
315 struct mul_partition_info {
316 u32 lba_begin; /* absolute address from 0 block */
318 } __attribute__((packed));
320 #define MBR_OFFSET 0x10
322 struct partition_header part_info;
323 struct mbr_table mbr_info;
324 struct mul_partition_info mul_info[EXTEND_MAX_PART];
326 static int write_mmc_partition(struct usbd_ops *usbd, u32 *ram_addr, u32 len)
329 char offset[12], length[12], ramaddr[12];
335 if (cur_part_size > len) {
336 blocks = len / usbd->mmc_blk;
339 blocks = cur_part_size / usbd->mmc_blk;
340 ret = len - cur_part_size;
343 if (len % usbd->mmc_blk)
346 loop = blocks / usbd->mmc_max;
347 if (blocks % usbd->mmc_max)
350 for (i = 0; i < loop; i++) {
352 cnt = blocks % usbd->mmc_max;
359 sprintf(length, "%x", cnt);
360 sprintf(offset, "%x", cur_blk_offset);
361 sprintf(ramaddr, "0x%x", *ram_addr);
362 mmc_cmd(OPS_WRITE, ramaddr, offset, length);
364 cur_blk_offset += cnt;
366 *ram_addr += (cnt * usbd->mmc_blk);
372 static int write_file_mmc(struct usbd_ops *usbd, char *ramaddr, u32 len,
373 char *offset, char *length)
378 struct mbr_table *mbr;
380 if (!usbd->mmc_total) {
381 printf("MMC is not supported!\n");
385 ram_addr = (u32)down_ram_addr;
387 if (cur_blk_offset == 0) {
391 memcpy(&part_info, (void *)ram_addr,
392 sizeof(struct partition_header));
394 ram_addr += sizeof(struct partition_header);
395 len -= sizeof(struct partition_header);
396 mbr = (struct mbr_table*)ram_addr;
397 mbr_blk_size = mbr->partition[0].lba_begin;
399 if (mbr->partition[0].type_code != EXTEND_PART_TYPE) {
400 part_mode = NORMAL_PARTITION;
402 /* modify sectors of p1 */
403 mbr->partition[0].num_sectors = usbd->mmc_total -
405 mbr->partition[1].num_sectors +
406 mbr->partition[2].num_sectors +
407 mbr->partition[3].num_sectors);
411 /* modify lba_begin of p2 and p3 and p4 */
412 for (i = 1; i < 4; i++) {
413 if (part_info.partition[i].size == 0)
417 mbr->partition[i].lba_begin =
418 mbr->partition[i - 1].lba_begin +
419 mbr->partition[i - 1].num_sectors;
423 memcpy(&mbr_info, mbr, sizeof(struct mbr_table));
425 printf("Total Size: 0x%08x #parts %d\n",
426 (unsigned int)usbd->mmc_total,
428 for (i = 0; i < mmc_parts; i++) {
429 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
430 mbr_info.partition[i].lba_begin,
431 mbr_info.partition[i].num_sectors);
435 sprintf(length, "%x", mbr_blk_size);
436 sprintf(offset, "%x", 0);
437 sprintf(ramaddr, "0x%x", (u32)ram_addr);
438 ret = mmc_cmd(OPS_WRITE, ramaddr, offset, length);
440 ram_addr += mbr_blk_size * usbd->mmc_blk;
441 len -= mbr_blk_size * usbd->mmc_blk;
443 cur_blk_offset = mbr_blk_size;
445 cur_part_size = part_info.partition[0].size;
447 /* modify p1's total sector */
448 bs = (boot_sector *)ram_addr;
449 bs->total_sect = mbr_info.partition[0].num_sectors;
451 printf("\nWrite Partition %d.. %d blocks\n",
453 part_info.partition[cur_part].size /
456 part_mode = EXTEND_PARTITION;
458 for (i = 0; i < EXTEND_MAX_PART; i++) {
459 if (part_info.partition[i].size == 0)
467 printf("found %d partitions\n", mmc_parts);
469 /* build partition table */
471 mul_info[0].num_sectors =
472 usbd->mmc_total - mbr_blk_size;
473 for (i = 1; i < mmc_parts; i++) {
474 mul_info[i].num_sectors =
475 part_info.partition[i].res +
476 mbr_blk_size; /* add MBR */
479 for (i = 1; i < mmc_parts; i++) {
480 mul_info[0].num_sectors -=
481 mul_info[i].num_sectors;
484 mul_info[0].lba_begin = mbr_blk_size;
485 for (i = 1; i < mmc_parts; i++) {
486 mul_info[i].lba_begin =
487 mul_info[i-1].lba_begin +
488 mul_info[i-1].num_sectors;
491 /* modify MBR of extended partition: p1 */
492 mbr->partition[0].num_sectors =
493 usbd->mmc_total - mbr_blk_size;
495 /* modify MBR of first logical partition: p5 */
496 mbr = (struct mbr_table *)
497 (ram_addr + mbr_blk_size * usbd->mmc_blk);
499 mbr->partition[0].num_sectors =
500 mul_info[0].num_sectors - mbr_blk_size;
501 mbr->partition[1].lba_begin =
502 mul_info[1].lba_begin - mbr_blk_size;
504 /* modify BPB data of p5 */
506 ((u32)mbr + mbr_blk_size * usbd->mmc_blk);
507 memset(&bs->sectors, 0, 2);
508 bs->total_sect = mbr->partition[0].num_sectors;
510 printf("Total Size: 0x%08x #parts %d\n",
511 (unsigned int)usbd->mmc_total,
513 for (i = 0; i < mmc_parts; i++) {
514 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
515 mul_info[i].lba_begin,
516 mul_info[i].num_sectors);
521 cur_part_size = part_info.partition[0].size;
523 printf("\nWrite Partition %d.. %d blocks\n",
525 part_info.partition[cur_part].size /
530 for (i = cur_part; i < mmc_parts; i++) {
531 ret = write_mmc_partition(usbd, &ram_addr, len);
534 cur_part_size -= len;
539 part_info.partition[cur_part].size;
541 if (part_mode == NORMAL_PARTITION) {
543 mbr_info.partition[cur_part].lba_begin;
546 mul_info[cur_part].lba_begin;
548 if (cur_part < mmc_parts) {
549 mbr = (struct mbr_table *)ram_addr;
550 mbr->partition[1].lba_begin =
551 mul_info[cur_part+1].lba_begin -
552 mbr->partition[0].lba_begin;
561 printf("\nWrite Partition %d.. %d blocks\n",
563 part_info.partition[cur_part].size /
571 static int write_file_mmc_part(struct usbd_ops *usbd, char *ramaddr, u32 len,
572 char *offset, char *length)
577 struct mbr_table *mbr;
580 ram_addr = (u32)down_ram_addr;
583 if (cur_blk_offset == 0) {
585 sprintf(length, "%x", (unsigned int)
586 (sizeof(struct mbr_table)/usbd->mmc_blk));
587 sprintf(offset, "%x", 0);
588 sprintf(ramaddr, "0x%x", (u32)mbr);
589 mmc_cmd(OPS_READ, ramaddr, offset, length);
591 mbr_blk_size = mbr->partition[0].lba_begin;
593 if (mbr->partition[0].type_code != EXTEND_PART_TYPE) {
594 part_mode = NORMAL_PARTITION;
596 for (i = 0; i < 4; i++) {
597 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
598 mbr_info.partition[i].lba_begin,
599 mbr_info.partition[i].num_sectors);
603 mbr->partition[mmc_part_write - 1].lba_begin;
604 cur_part = mmc_part_write - 1;
607 mbr->partition[mmc_part_write - 1].num_sectors;
609 if (mmc_part_write == 1) {
610 ram_addr += sizeof(struct mbr_table);
611 cur_blk_offset += sizeof(struct mbr_table) /
613 len -= sizeof(struct mbr_table);
616 part_mode = EXTEND_PARTITION;
618 for (i = 1; i < mmc_part_write; i++) {
619 ofs = mbr->partition[0].lba_begin +
620 mbr->partition[1].lba_begin;
621 printf("P%d start blk: 0x%x, size: 0x%x\n", i,
622 ofs, mbr->partition[1].num_sectors);
623 sprintf(length, "%x", (unsigned int)
624 (sizeof(struct mbr_table) /
626 sprintf(offset, "%x", ofs);
627 sprintf(ramaddr, "0x%x", (u32)mbr);
628 mmc_cmd(OPS_READ, ramaddr, offset, length);
631 ofs = mbr->partition[0].lba_begin +
632 mbr->partition[1].lba_begin;
633 printf("P%d start blk: 0x%x, size: 0x%x\n", i,
634 ofs, mbr->partition[1].num_sectors);
636 ofs += mbr_blk_size; /* skip MBR */
637 cur_blk_offset = ofs;
638 cur_part = mmc_part_write - 1;
641 mbr->partition[1].num_sectors;
643 if (mmc_part_write == 1) {
646 /* modify BPB data of p1 */
647 sprintf(length, "%x", (unsigned int)
648 (sizeof(struct mbr_table) /
650 sprintf(offset, "%x", cur_blk_offset);
651 sprintf(ramaddr, "0x%x", (u32)mbr);
652 mmc_cmd(OPS_READ, ramaddr, offset, length);
654 bs = (boot_sector *)mbr;
655 total_sect = bs->total_sect;
657 bs = (boot_sector *)ram_addr;
658 memset(&bs->sectors, 0, 2);
659 bs->total_sect = total_sect;
664 printf("\nWrite Partition %d.. %d blocks\n",
666 len / (int)usbd->mmc_blk);
668 write_mmc_partition(usbd, &ram_addr, len);
674 static unsigned int mbr_offset[16];
675 static int mbr_parts = 0;
677 static unsigned long memsize_parse (const char *const ptr, const char **retptr)
679 unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);
699 static void set_mbr_info(struct usbd_ops *usbd, char *ramaddr, u32 len)
705 unsigned int size[16];
708 strncpy(mbr_str, ramaddr, len);
711 for (i = 0; ; i++, p = NULL) {
712 tok = strtok(p, ",");
715 strcpy(save[i], tok);
716 printf("part%d: %s\n", i, save[i]);
720 printf("find %d partitions\n", mbr_parts);
722 for (i = 0; i < mbr_parts; i++) {
724 size[i] = memsize_parse(p, (const char **)&p) / 512;
727 puts("save the MBR Table...\n");
728 set_mbr_table(0x800, mbr_parts, size, mbr_offset);
731 static int write_mmc_image(struct usbd_ops *usbd, char *ramaddr,
732 unsigned int len, char *offset, char *length, int part_num)
736 if (mbr_parts <= part_num) {
737 printf("Error: MBR table have %d partitions (request %d)\n",
738 mbr_parts, part_num);
742 sprintf(offset, "0x%x", mbr_offset[part_num] + fs_offset);
743 sprintf(length, "0x%x", len / usbd->mmc_blk);
746 /* modify size of UMS partition */
747 if (part_num == 4 && fs_offset == 0) {
749 bs = (boot_sector *)down_ram_addr;
750 memset(&bs->sectors, 0, 2);
751 bs->total_sect = usbd->mmc_total - mbr_offset[part_num];
754 ret = mmc_cmd(OPS_WRITE, ramaddr, offset, length);
756 fs_offset += (len / usbd->mmc_blk);
761 static int write_file_system(char *ramaddr, ulong len, char *offset,
762 char *length, int part_num, int ubi_update)
764 #ifdef CONFIG_USE_YAFFS
770 #ifdef CONFIG_CMD_UBI
773 sprintf(length, "0x%x", (uint)len);
774 ret = ubi_cmd(part_id, ramaddr, length, "cont");
779 /* Erase entire partition at the first writing */
780 if (write_part == 0 && ubi_update == 0) {
781 sprintf(offset, "0x%x", (uint)parts[part_num]->offset);
782 sprintf(length, "0x%x", (uint)parts[part_num]->size);
783 nand_cmd(0, offset, length, NULL);
786 #ifdef CONFIG_USE_YAFFS
787 /* if using yaffs, wirte size must be 2112*X
788 * so, must have to realloc, and writing */
789 if (!strcmp("yaffs", getenv(parts[part_num]->name))) {
792 memcpy((void *)down_ram_addr, yaffs_data, yaffs_len);
794 actual_len = len + yaffs_len;
795 yaffs_len = actual_len % YAFFS_PAGE;
796 len = actual_len - yaffs_len;
798 memset(yaffs_data, 0x00, YAFFS_PAGE);
799 memcpy(yaffs_data, (char *)down_ram_addr + len, yaffs_len);
803 sprintf(offset, "0x%x", (uint)(parts[part_num]->offset + fs_offset));
804 sprintf(length, "0x%x", (uint)len);
806 #ifdef CONFIG_USE_YAFFS
808 ret = nand_cmd(2, ramaddr, offset, length);
810 ret = nand_cmd(1, ramaddr, offset, length);
812 if (!strcmp("yaffs", getenv(parts[part_num]->name)))
813 fs_offset += len / YAFFS_PAGE * NAND_PAGE_SIZE;
819 ret = nand_cmd(1, ramaddr, offset, length);
825 static int qboot_erase = 0;
827 /* Erase the qboot */
828 static void erase_qboot_area(void)
830 char offset[12], length[12];
836 qboot_id = get_part_id("qboot");
838 if (qboot_id != -1) {
839 printf("\nCOMMAND_ERASE_QBOOT\n");
840 sprintf(offset, "%x", parts[qboot_id]->offset);
841 sprintf(length, "%x", parts[qboot_id]->size);
842 nand_cmd(0, offset, length, NULL);
847 /* Parsing received data packet and Process data */
848 static int process_data(struct usbd_ops *usbd)
850 unsigned int cmd = 0, arg = 0, ofs = 0, len = 0, flag = 0;
851 char offset[12], length[12], ramaddr[12];
853 unsigned int blocks = 0;
859 sprintf(ramaddr, "0x%x", (uint) down_ram_addr);
862 cmd = *((ulong *) usbd->rx_data + 0);
863 arg = *((ulong *) usbd->rx_data + 1);
864 len = *((ulong *) usbd->rx_data + 2);
865 flag = *((ulong *) usbd->rx_data + 3);
867 /* Reset tx buffer */
868 memset(usbd->tx_data, 0, sizeof(usbd->tx_data));
870 ubi_mode = check_ubi_mode();
873 case COMMAND_DOWNLOAD_IMAGE:
874 printf("\nCOMMAND_DOWNLOAD_IMAGE\n");
876 #ifdef CONFIG_USE_YAFFS
877 usbd->recv_setup((char *)down_ram_addr + yaffs_len, (int)len);
878 printf("Download to 0x%08x, %d bytes\n",
879 (uint)down_ram_addr + yaffs_len, (int)len);
882 down_ram_addr = usbd->ram_addr + 0x1000000;
884 down_ram_addr = usbd->ram_addr;
886 usbd->recv_setup((char *)down_ram_addr, (int)len);
887 printf("Download to 0x%08x, %d bytes\n",
888 (uint)down_ram_addr, (int)len);
891 usbd->send_data(usbd->tx_data, usbd->tx_len);
893 /* Receive image by using dma */
894 recvlen = usbd->recv_data();
896 printf("Error: wrong image size -> %d/%d\n",
897 (int)recvlen, (int)len);
899 /* Retry this commad */
900 *((ulong *) usbd->tx_data) = STATUS_RETRY;
902 *((ulong *) usbd->tx_data) = STATUS_DONE;
904 usbd->send_data(usbd->tx_data, usbd->tx_len);
907 /* Report partition info */
908 case COMMAND_PARTITION_SYNC:
911 #ifdef CONFIG_CMD_UBI
913 if (part_id == RAMDISK_PART_ID ||
914 part_id == FILESYSTEM_PART_ID ||
915 part_id == FILESYSTEM2_PART_ID) {
916 /* change to yaffs style */
920 if (part_id == FILESYSTEM3_PART_ID) {
921 /* change ubi style */
927 if (part_id == FILESYSTEM3_PART_ID)
928 part_id = get_part_id("UBI");
929 else if (part_id == MODEM_PART_ID)
930 part_id = get_part_id("modem");
931 else if (part_id == KERNEL_PART_ID)
932 part_id = get_part_id("kernel");
933 else if (part_id == BOOT_PART_ID)
934 part_id = get_part_id("bootloader");
939 printf("COMMAND_PARTITION_SYNC - Part%d\n", part_id);
941 blocks = parts[part_id]->size / 1024 / 128;
942 printf("COMMAND_PARTITION_SYNC - Part%d, %d blocks\n",
945 *((ulong *) usbd->tx_data) = blocks;
946 usbd->send_data(usbd->tx_data, usbd->tx_len);
949 case COMMAND_WRITE_PART_0:
951 printf("COMMAND_WRITE_PART_0\n");
954 case COMMAND_WRITE_PART_1:
955 printf("COMMAND_WRITE_PART_BOOT\n");
956 part_id = get_part_id("bootloader");
960 case COMMAND_WRITE_PART_2:
961 case COMMAND_ERASE_PARAMETER:
962 printf("COMMAND_PARAMETER - not support!\n");
965 case COMMAND_WRITE_PART_3:
966 printf("COMMAND_WRITE_KERNEL\n");
967 part_id = get_part_id("kernel");
968 img_type = IMG_KERNEL;
971 case COMMAND_WRITE_PART_4:
972 printf("COMMAND_WRITE_ROOTFS\n");
973 part_id = get_part_id("Root");
974 img_type = IMG_FILESYSTEM;
978 case COMMAND_WRITE_PART_5:
979 printf("COMMAND_WRITE_FACTORYFS\n");
980 part_id = get_part_id("Fact");
981 img_type = IMG_FILESYSTEM;
985 case COMMAND_WRITE_PART_6:
986 printf("COMMAND_WRITE_DATAFS\n");
987 part_id = get_part_id("Data");
988 img_type = IMG_FILESYSTEM;
992 case COMMAND_WRITE_PART_7:
993 printf("COMMAND_WRITE_UBI\n");
994 part_id = get_part_id("UBI");
995 img_type = IMG_FILESYSTEM;
997 /* someday, it will be deleted */
1001 case COMMAND_WRITE_PART_8:
1002 printf("COMMAND_WRITE_MODEM\n");
1003 part_id = get_part_id("modem");
1004 img_type = IMG_MODEM;
1007 #ifdef CONFIG_CMD_MMC
1008 case COMMAND_WRITE_PART_9:
1009 printf("COMMAND_WRITE_MMC\n");
1011 mmc_part_write = arg;
1015 case COMMAND_WRITE_IMG_0:
1016 printf("COMMAND_WRITE_MBR\n");
1020 case COMMAND_WRITE_IMG_1:
1021 printf("COMMAND_WRITE_BOOTLOADER\n");
1022 /* TODO: Not support yet, just return */
1023 *((ulong *) usbd->tx_data) = STATUS_DONE;
1024 usbd->send_data(usbd->tx_data, usbd->tx_len);
1027 case COMMAND_WRITE_IMG_2:
1028 printf("COMMAND_WRITE_KERNEL\n");
1029 /* TODO: Not support yet, just return */
1030 *((ulong *) usbd->tx_data) = STATUS_DONE;
1031 usbd->send_data(usbd->tx_data, usbd->tx_len);
1034 case COMMAND_WRITE_IMG_3:
1035 printf("COMMAND_WRITE_MODEM\n");
1036 /* TODO: Not support yet, just return */
1037 *((ulong *) usbd->tx_data) = STATUS_DONE;
1038 usbd->send_data(usbd->tx_data, usbd->tx_len);
1041 case COMMAND_WRITE_IMG_4:
1042 printf("COMMAND_WRITE_BOOT_PART\n");
1047 case COMMAND_WRITE_IMG_5:
1048 printf("COMMAND_WRITE_SYSTEM_PART\n");
1053 case COMMAND_WRITE_IMG_6:
1054 printf("COMMAND_WRITE_UMS_PART\n");
1059 case COMMAND_WRITE_UBI_INFO:
1060 printf("COMMAND_WRITE_UBI_INFO\n");
1063 #ifdef CONFIG_CMD_UBI
1065 sprintf(length, "0x%x", (uint)len);
1066 ret = ubi_cmd(part_id, ramaddr, length, "begin");
1069 printf("Error: Not UBI mode\n");
1073 *((ulong *) usbd->tx_data) = ret;
1074 /* Write image success -> Report status */
1075 usbd->send_data(usbd->tx_data, usbd->tx_len);
1078 /* Download complete -> reset */
1079 case COMMAND_RESET_PDA:
1080 printf("\nDownload finished and Auto reset!\nWait........\n");
1085 if (usbd->cpu_reset)
1093 case COMMAND_RESET_USB:
1094 printf("\nError is occured!(maybe previous step)->\
1095 Turn off and restart!\n");
1101 case COMMAND_RAM_BOOT:
1106 case COMMAND_RAMDISK_MODE:
1107 printf("COMMAND_RAMDISK_MODE\n");
1108 #ifdef CONFIG_RAMDISK_ADDR
1110 down_ram_addr = usbd->ram_addr;
1112 down_ram_addr = CONFIG_RAMDISK_ADDR;
1118 #ifdef CONFIG_DOWN_PHONE
1119 case COMMAND_DOWN_PHONE:
1120 printf("COMMAND_RESET_PHONE\n");
1124 *((ulong *) usbd->tx_data) = STATUS_DONE;
1125 usbd->send_data(usbd->tx_data, usbd->tx_len);
1128 case COMMAND_CHANGE_USB:
1129 printf("COMMAND_CHANGE_USB\n");
1139 case COMMAND_CSA_CLEAR:
1140 printf("COMMAND_CSA_CLEAR\n");
1141 part_id = get_part_id("csa");
1142 img_type = IMG_MODEM;
1145 case COMMAND_PROGRESS:
1146 if (usbd->set_progress)
1147 usbd->set_progress(arg);
1151 printf("Error: Unknown command -> (%d)\n", (int)cmd);
1155 /* Erase and Write to NAND */
1158 ofs = parts[part_id]->offset;
1159 #ifdef CONFIG_S5PC1XX
1160 /* Workaround: for prevent revision mismatch */
1161 if (cpu_is_s5pc110() && (down_mode != MODE_FORCE)) {
1163 long *img_header = (long *)down_ram_addr;
1165 if (*img_header == 0xea000012)
1167 else if (*(img_header + 0x400) == 0xea000012)
1170 if (img_rev != s5p_get_cpu_rev()) {
1171 printf("CPU revision mismatch!\n"
1172 "bootloader is %s%s\n"
1173 "download image is %s%s\n",
1174 s5p_get_cpu_rev() ? "EVT1" : "EVT0",
1175 s5p_get_cpu_rev() == 2 ? "-Fused" : "",
1176 img_rev ? "EVT1" : "EVT0",
1177 img_rev == 2 ? "-Fused" : "");
1178 *((ulong *) usbd->tx_data) = STATUS_ERROR;
1179 usbd->send_data(usbd->tx_data, usbd->tx_len);
1185 /* Only u-boot.bin is allowed */
1187 long *img_header = (long *)down_ram_addr;
1189 if (*img_header != 0xea000018) {
1190 printf("\n!!! ERROR !!!\n"
1191 "Please download the u-boot.bin.\n"
1192 "Other images are not allowed.\n\n");
1193 *((ulong *) usbd->tx_data) = STATUS_ERROR;
1194 usbd->send_data(usbd->tx_data, usbd->tx_len);
1199 #if defined(CONFIG_ENV_IS_IN_NAND) || defined(CONFIG_ENV_IS_IN_ONENAND)
1200 /* Erase the environment also when write bootloader */
1203 param_id = get_part_id("params");
1205 if (param_id == -1) {
1206 sprintf(offset, "%x", CONFIG_ENV_ADDR);
1207 sprintf(length, "%x", CONFIG_ENV_SIZE);
1209 sprintf(offset, "%x", parts[param_id]->offset);
1210 sprintf(length, "%x", parts[param_id]->size);
1212 nand_cmd(0, offset, length, NULL);
1215 sprintf(offset, "%x", (uint)ofs);
1217 sprintf(length, "%x", parts[part_id]->size - (uint)ofs);
1219 sprintf(length, "%x", parts[part_id]->size);
1222 nand_cmd(0, offset, length, NULL);
1224 sprintf(length, "%x", (unsigned int) len);
1225 ret = nand_cmd(1, ramaddr, offset, length);
1229 sprintf(offset, "%x", parts[part_id]->offset);
1230 sprintf(length, "%x", parts[part_id]->size);
1233 nand_cmd(0, offset, length, NULL);
1235 sprintf(length, "%x", (unsigned int) len);
1236 ret = nand_cmd(1, ramaddr, offset, length);
1242 case IMG_FILESYSTEM:
1243 ret = write_file_system(ramaddr, len, offset, length,
1244 part_id, ubi_update);
1250 sprintf(offset, "%x", parts[part_id]->offset);
1251 sprintf(length, "%x", parts[part_id]->size);
1255 nand_cmd(0, offset, length, NULL);
1257 printf("CSA Clear will be skipped temporary\n");
1259 /* Check ubi image, 0x23494255 is UBI# */
1261 long *img_header = (long *)down_ram_addr;
1263 if (*img_header == 0x23494255)
1267 #ifdef CONFIG_UBIFS_MK
1268 void *dest_addr = (void *) down_ram_addr + 0xc00000;
1269 void *src_addr = (void *) down_ram_addr;
1270 int leb_size, max_leb_cnt, mkfs_min_io_size;
1271 unsigned long ubifs_dest_size, ubi_dest_size;
1272 #ifdef CONFIG_S5PC110
1273 mkfs_min_io_size = 4096;
1274 leb_size = 248 * 1024;
1276 #elif CONFIG_S5PC210
1277 mkfs_min_io_size = 2048;
1278 leb_size = 126 * 1024;
1281 printf("Start making ubifs\n");
1282 ret = mkfs(src_addr, len, dest_addr, &ubifs_dest_size,
1283 mkfs_min_io_size, leb_size, max_leb_cnt);
1285 printf("Error : making ubifs failed\n");
1288 printf("Complete making ubifs\n");
1291 #ifdef CONFIG_UBINIZE
1292 int peb_size, ubi_min_io_size, subpage_size, vid_hdr_offs;
1293 #ifdef CONFIG_S5PC110
1294 ubi_min_io_size = 4096;
1295 peb_size = 256 * 1024;
1296 subpage_size = 4096;
1298 #elif CONFIG_S5PC210
1299 ubi_min_io_size = 2048;
1300 peb_size = 128 * 1024;
1304 printf("Start ubinizing\n");
1305 ret = ubinize(dest_addr, ubifs_dest_size,
1306 src_addr, &ubi_dest_size,
1307 peb_size, ubi_min_io_size,
1308 subpage_size, vid_hdr_offs);
1310 printf("Error : ubinizing failed\n");
1313 printf("Complete ubinizing\n");
1315 len = (unsigned int) ubi_dest_size;
1319 /* Write : arg (0 Modem) / (1 CSA) */
1321 sprintf(length, "%x", (unsigned int) len);
1322 ret = nand_cmd(1, ramaddr, offset, length);
1327 #ifdef CONFIG_CMD_MMC
1331 ret = write_file_mmc_part(usbd, ramaddr,
1332 len, offset, length);
1334 ret = write_file_mmc(usbd, ramaddr,
1335 len, offset, length);
1341 ret = write_mmc_image(usbd, ramaddr, len, offset, length, part_id);
1345 set_mbr_info(usbd, (char *)down_ram_addr, len);
1354 /* Retry this commad */
1355 *((ulong *) usbd->tx_data) = STATUS_RETRY;
1356 usbd->send_data(usbd->tx_data, usbd->tx_len);
1359 *((ulong *) usbd->tx_data) = STATUS_DONE;
1361 /* Write image success -> Report status */
1362 usbd->send_data(usbd->tx_data, usbd->tx_len);
1366 /* Reset write count for another image */
1370 #ifdef CONFIG_USE_YAFFS
1378 static const char *recv_key = "SAMSUNG";
1379 static const char *tx_key = "MPL";
1381 int do_usbd_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1383 struct usbd_ops *usbd;
1387 down_mode = simple_strtoul(argv[1], NULL, 10);
1389 down_mode = MODE_NORMAL;
1391 printf("USB Downloader v%s\n", APP_VERSION);
1393 /* get partition info */
1394 err = get_part_info();
1398 /* interface setting */
1399 usbd = usbd_set_interface(&usbd_ops);
1400 down_ram_addr = usbd->ram_addr;
1403 mbr_parts = get_mbr_table(mbr_offset);
1407 puts("using default MBR\n");
1409 mbrparts = getenv("mbrparts");
1410 set_mbr_info(usbd, mbrparts, strlen(mbrparts));
1413 /* init the usb controller */
1414 if (!usbd->usb_init()) {
1415 usbd->down_cancel();
1419 /* receive setting */
1420 usbd->recv_setup(usbd->rx_data, usbd->rx_len);
1422 /* detect the download request from Host PC */
1423 if (usbd->recv_data()) {
1424 if (strncmp(usbd->rx_data, recv_key, strlen(recv_key)) == 0) {
1425 printf("Download request from the Host PC\n");
1428 strcpy(usbd->tx_data, tx_key);
1429 usbd->send_data(usbd->tx_data, usbd->tx_len);
1431 printf("No download request from the Host PC!! 1\n");
1435 usbd->down_cancel();
1440 printf("Receive the packet\n");
1442 /* receive the data from Host PC */
1444 usbd->recv_setup(usbd->rx_data, usbd->rx_len);
1446 if (usbd->recv_data()) {
1447 if (process_data(usbd) == 0)
1455 U_BOOT_CMD(usbdown, CONFIG_SYS_MAXARGS, 1, do_usbd_down,
1456 "Initialize USB device and Run USB Downloader (specific)",
1458 "usbdown mode - specific mode (0: NORAML, 1: FORCE)"