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 #if defined(CONFIG_CMD_NAND)
169 extern int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
170 #elif defined(CONFIG_CMD_ONENAND)
171 extern int do_onenand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
174 /* NAND erase and write using nand command */
175 static int nand_cmd(int type, char *p1, char *p2, char *p3)
179 int (*nand_func) (cmd_tbl_t *, int, int, char **);
181 #if defined(CONFIG_CMD_NAND)
182 sprintf(nand_name, "nand");
184 #elif defined(CONFIG_CMD_ONENAND)
185 sprintf(nand_name, "onenand");
186 nand_func = do_onenand;
188 printf("Configure your NAND sub-system\n");
193 char *argv[] = {nand_name, "erase", p1, p2};
194 printf("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
195 ret = nand_func(NULL, 0, 4, argv);
196 } else if (type == 1) {
197 char *argv[] = {nand_name, "write", p1, p2, p3};
198 printf("%s %s %s %s %s\n", argv[0], argv[1], argv[2],
200 ret = nand_func(NULL, 0, 5, argv);
201 } else if (type == 2) {
202 char *argv[] = {nand_name, "write.yaffs", p1, p2, p3};
203 printf("%s %s %s %s %s\n", argv[0], argv[1], argv[2],
205 ret = nand_func(NULL, 0, 5, argv);
206 } else if (type == 3) {
207 char *argv[] = {nand_name, "lock", p1, p2};
208 printf("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
209 ret = nand_func(NULL, 0, 4, argv);
213 printf("Error: NAND Command\n");
218 #ifdef CONFIG_CMD_UBI
219 int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
221 int ubi_cmd(int part, char *p1, char *p2, char *p3)
225 if (part == RAMDISK_PART_ID) {
226 char *argv[] = {"ubi", "write", p1, "rootfs.cramfs", p2, p3};
227 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
228 argv[3], argv[4], argv[5]);
229 ret = do_ubi(NULL, 0, 6, argv);
230 } else if (part == FILESYSTEM_PART_ID) {
231 char *argv[] = {"ubi", "write", p1, "factoryfs.cramfs", p2, p3};
232 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
233 argv[3], argv[4], argv[5]);
234 ret = do_ubi(NULL, 0, 6, argv);
235 } else if (part == FILESYSTEM2_PART_ID) {
236 char *argv[] = {"ubi", "write", p1, "datafs.ubifs", p2, p3};
237 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
238 argv[3], argv[4], argv[5]);
239 ret = do_ubi(NULL, 0, 6, argv);
246 #ifdef CONFIG_CMD_MMC
250 static struct mmc *mmc;
252 static int mmc_cmd(int ops, int dev_num, ulong start, lbaint_t cnt, void *addr)
257 printf("mmc write 0x%x 0x%x\n", start, cnt);
258 ret = mmc->block_dev.block_write(dev_num, start, cnt, addr);
260 printf("mmc read 0x%x 0x%x\n", start, cnt);
261 ret = mmc->block_dev.block_read(dev_num, start, cnt, addr);
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 mul_partition_info {
301 u32 lba_begin; /* absolute address from 0 block */
303 } __attribute__((packed));
305 #define MBR_OFFSET 0x10
307 struct partition_header part_info;
309 struct mul_partition_info mul_info[EXTEND_MAX_PART];
311 static int write_mmc_partition(struct usbd_ops *usbd, u32 *ram_addr, u32 len)
319 if (cur_part_size > len) {
320 blocks = len / usbd->mmc_blk;
323 blocks = cur_part_size / usbd->mmc_blk;
324 ret = len - cur_part_size;
327 if (len % usbd->mmc_blk)
330 loop = blocks / usbd->mmc_max;
331 if (blocks % usbd->mmc_max)
334 for (i = 0; i < loop; i++) {
336 cnt = blocks % usbd->mmc_max;
343 mmc_cmd(OPS_WRITE, usbd->mmc_dev, cur_blk_offset,
344 cnt, (void *)*ram_addr);
346 cur_blk_offset += cnt;
348 *ram_addr += (cnt * usbd->mmc_blk);
354 static int write_file_mmc(struct usbd_ops *usbd, u32 len)
361 if (!usbd->mmc_total) {
362 printf("MMC is not supported!\n");
366 ram_addr = (u32)down_ram_addr;
368 if (cur_blk_offset == 0) {
372 memcpy(&part_info, (void *)ram_addr,
373 sizeof(struct partition_header));
375 ram_addr += sizeof(struct partition_header);
376 len -= sizeof(struct partition_header);
377 mbr = (struct mbr *)ram_addr;
378 mbr_blk_size = mbr->parts[0].lba;
380 if (mbr->parts[0].partition_type != EXTEND_PART_TYPE) {
381 part_mode = NORMAL_PARTITION;
383 /* modify sectors of p1 */
384 mbr->parts[0].nsectors = usbd->mmc_total -
386 mbr->parts[1].nsectors +
387 mbr->parts[2].nsectors +
388 mbr->parts[3].nsectors);
392 /* modify lba_begin of p2 and p3 and p4 */
393 for (i = 1; i < 4; i++) {
394 if (part_info.partition[i].size == 0)
399 mbr->parts[i - 1].lba +
400 mbr->parts[i - 1].nsectors;
404 memcpy(&mbr_info, mbr, sizeof(struct mbr));
406 printf("Total Size: 0x%08x #parts %d\n",
407 (unsigned int)usbd->mmc_total,
409 for (i = 0; i < mmc_parts; i++) {
410 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
411 mbr_info.parts[i].lba,
412 mbr_info.parts[i].nsectors);
416 mmc_cmd(OPS_WRITE, usbd->mmc_dev, 0,
417 mbr_blk_size, (void *)ram_addr);
419 ram_addr += mbr_blk_size * usbd->mmc_blk;
420 len -= mbr_blk_size * usbd->mmc_blk;
422 cur_blk_offset = mbr_blk_size;
424 cur_part_size = part_info.partition[0].size;
426 /* modify p1's total sector */
427 bs = (boot_sector *)ram_addr;
428 bs->total_sect = mbr_info.parts[0].nsectors;
430 printf("\nWrite Partition %d.. %d blocks\n",
432 part_info.partition[cur_part].size /
435 part_mode = EXTEND_PARTITION;
437 for (i = 0; i < EXTEND_MAX_PART; i++) {
438 if (part_info.partition[i].size == 0)
446 printf("found %d partitions\n", mmc_parts);
448 /* build partition table */
450 mul_info[0].num_sectors =
451 usbd->mmc_total - mbr_blk_size;
452 for (i = 1; i < mmc_parts; i++) {
453 mul_info[i].num_sectors =
454 part_info.partition[i].res +
455 mbr_blk_size; /* add MBR */
458 for (i = 1; i < mmc_parts; i++) {
459 mul_info[0].num_sectors -=
460 mul_info[i].num_sectors;
463 mul_info[0].lba_begin = mbr_blk_size;
464 for (i = 1; i < mmc_parts; i++) {
465 mul_info[i].lba_begin =
466 mul_info[i-1].lba_begin +
467 mul_info[i-1].num_sectors;
470 /* modify MBR of extended partition: p1 */
471 mbr->parts[0].nsectors =
472 usbd->mmc_total - mbr_blk_size;
474 /* modify MBR of first logical partition: p5 */
476 (ram_addr + mbr_blk_size * usbd->mmc_blk);
478 mbr->parts[0].nsectors =
479 mul_info[0].num_sectors - mbr_blk_size;
481 mul_info[1].lba_begin - mbr_blk_size;
483 /* modify BPB data of p5 */
485 ((u32)mbr + mbr_blk_size * usbd->mmc_blk);
486 memset(&bs->sectors, 0, 2);
487 bs->total_sect = mbr->parts[0].nsectors;
489 printf("Total Size: 0x%08x #parts %d\n",
490 (unsigned int)usbd->mmc_total,
492 for (i = 0; i < mmc_parts; i++) {
493 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
494 mul_info[i].lba_begin,
495 mul_info[i].num_sectors);
500 cur_part_size = part_info.partition[0].size;
502 printf("\nWrite Partition %d.. %d blocks\n",
504 part_info.partition[cur_part].size /
509 for (i = cur_part; i < mmc_parts; i++) {
510 ret = write_mmc_partition(usbd, &ram_addr, len);
513 cur_part_size -= len;
518 part_info.partition[cur_part].size;
520 if (part_mode == NORMAL_PARTITION) {
522 mbr_info.parts[cur_part].lba;
525 mul_info[cur_part].lba_begin;
527 if (cur_part < mmc_parts) {
528 mbr = (struct mbr *)ram_addr;
530 mul_info[cur_part+1].lba_begin -
540 printf("\nWrite Partition %d.. %d blocks\n",
542 part_info.partition[cur_part].size /
550 static int write_file_mmc_part(struct usbd_ops *usbd, u32 len)
558 ram_addr = (u32)down_ram_addr;
561 if (cur_blk_offset == 0) {
563 mmc_cmd(OPS_READ, usbd->mmc_dev, 0,
564 sizeof(struct mbr)/usbd->mmc_blk, (void *)mbr);
566 mbr_blk_size = mbr->parts[0].lba;
568 if (mbr->parts[0].partition_type != EXTEND_PART_TYPE) {
569 part_mode = NORMAL_PARTITION;
571 for (i = 0; i < 4; i++) {
572 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
573 mbr_info.parts[i].lba,
574 mbr_info.parts[i].nsectors);
578 mbr->parts[mmc_part_write - 1].lba;
579 cur_part = mmc_part_write - 1;
582 mbr->parts[mmc_part_write - 1].nsectors;
584 if (mmc_part_write == 1) {
585 ram_addr += sizeof(struct mbr);
586 cur_blk_offset += sizeof(struct mbr) /
588 len -= sizeof(struct mbr);
591 part_mode = EXTEND_PARTITION;
593 for (i = 1; i < mmc_part_write; i++) {
594 ofs = mbr->parts[0].lba + mbr->parts[1].lba;
595 printf("P%d start blk: 0x%x, size: 0x%x\n", i,
596 ofs, mbr->parts[1].nsectors);
597 mmc_cmd(OPS_READ, usbd->mmc_dev, ofs,
598 (sizeof(struct mbr) / usbd->mmc_blk),
602 ofs = mbr->parts[0].lba + mbr->parts[1].lba;
603 printf("P%d start blk: 0x%x, size: 0x%x\n", i,
604 ofs, mbr->parts[1].nsectors);
606 ofs += mbr_blk_size; /* skip MBR */
607 cur_blk_offset = ofs;
608 cur_part = mmc_part_write - 1;
611 mbr->parts[1].nsectors;
613 if (mmc_part_write == 1) {
616 /* modify BPB data of p1 */
617 mmc_cmd(OPS_READ, usbd->mmc_dev, cur_blk_offset,
618 (sizeof(struct mbr) / usbd->mmc_blk),
621 bs = (boot_sector *)mbr;
622 total_sect = bs->total_sect;
624 bs = (boot_sector *)ram_addr;
625 memset(&bs->sectors, 0, 2);
626 bs->total_sect = total_sect;
631 printf("\nWrite Partition %d.. %d blocks\n",
633 len / (int)usbd->mmc_blk);
635 write_mmc_partition(usbd, &ram_addr, len);
641 static unsigned int mbr_offset[16];
642 static int mbr_parts = 0;
644 static unsigned long memsize_parse (const char *const ptr, const char **retptr)
646 unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);
666 static void set_mbr_info(struct usbd_ops *usbd, char *ramaddr, u32 len)
672 unsigned int size[16];
675 strncpy(mbr_str, ramaddr, len);
678 for (i = 0; ; i++, p = NULL) {
679 tok = strtok(p, ",");
682 strcpy(save[i], tok);
683 printf("part%d: %s\n", i, save[i]);
687 printf("find %d partitions\n", mbr_parts);
689 for (i = 0; i < mbr_parts; i++) {
691 size[i] = memsize_parse(p, (const char **)&p) / 512;
694 puts("save the MBR Table...\n");
695 set_mbr_table(0x800, mbr_parts, size, mbr_offset);
698 static int write_mmc_image(struct usbd_ops *usbd, unsigned int len, int part_num)
702 if (mbr_parts <= part_num) {
703 printf("Error: MBR table have %d partitions (request %d)\n",
704 mbr_parts, part_num);
709 /* modify size of UMS partition */
710 if (part_num == 4 && fs_offset == 0) {
712 bs = (boot_sector *)down_ram_addr;
713 memset(&bs->sectors, 0, 2);
714 bs->total_sect = usbd->mmc_total - mbr_offset[part_num];
717 ret = mmc_cmd(OPS_WRITE, usbd->mmc_dev,
718 mbr_offset[part_num] + fs_offset,
720 (void *)down_ram_addr);
722 fs_offset += (len / usbd->mmc_blk);
727 static int write_fat_file(struct usbd_ops *usbd, char *file_name,
728 int part_id, int len)
730 #ifdef CONFIG_FAT_WRITE
733 ret = fat_register_device(&mmc->block_dev, part_id);
735 printf("error : fat_register_divce\n");
739 ret = file_fat_write(file_name, (void *)down_ram_addr, len);
741 printf("error : writing uImage\n");
745 printf("error: doesn't support fat_write\n");
750 static int write_file_system(char *ramaddr, ulong len, char *offset,
751 char *length, int part_num, int ubi_update)
753 #ifdef CONFIG_USE_YAFFS
759 #ifdef CONFIG_CMD_UBI
762 sprintf(length, "0x%x", (uint)len);
763 ret = ubi_cmd(part_id, ramaddr, length, "cont");
768 /* Erase entire partition at the first writing */
769 if (write_part == 0 && ubi_update == 0) {
770 sprintf(offset, "0x%x", (uint)parts[part_num]->offset);
771 sprintf(length, "0x%x", (uint)parts[part_num]->size);
772 nand_cmd(0, offset, length, NULL);
775 #ifdef CONFIG_USE_YAFFS
776 /* if using yaffs, wirte size must be 2112*X
777 * so, must have to realloc, and writing */
778 if (!strcmp("yaffs", getenv(parts[part_num]->name))) {
781 memcpy((void *)down_ram_addr, yaffs_data, yaffs_len);
783 actual_len = len + yaffs_len;
784 yaffs_len = actual_len % YAFFS_PAGE;
785 len = actual_len - yaffs_len;
787 memset(yaffs_data, 0x00, YAFFS_PAGE);
788 memcpy(yaffs_data, (char *)down_ram_addr + len, yaffs_len);
792 sprintf(offset, "0x%x", (uint)(parts[part_num]->offset + fs_offset));
793 sprintf(length, "0x%x", (uint)len);
795 #ifdef CONFIG_USE_YAFFS
797 ret = nand_cmd(2, ramaddr, offset, length);
799 ret = nand_cmd(1, ramaddr, offset, length);
801 if (!strcmp("yaffs", getenv(parts[part_num]->name)))
802 fs_offset += len / YAFFS_PAGE * NAND_PAGE_SIZE;
808 ret = nand_cmd(1, ramaddr, offset, length);
814 static int qboot_erase = 0;
816 /* Erase the qboot */
817 static void erase_qboot_area(void)
819 char offset[12], length[12];
825 qboot_id = get_part_id("qboot");
827 if (qboot_id != -1) {
828 printf("\nCOMMAND_ERASE_QBOOT\n");
829 sprintf(offset, "%x", parts[qboot_id]->offset);
830 sprintf(length, "%x", parts[qboot_id]->size);
831 nand_cmd(0, offset, length, NULL);
836 /* Erase the environment */
837 static void erase_env_area(struct usbd_ops *usbd)
839 #if defined(CONFIG_ENV_IS_IN_NAND) || defined(CONFIG_ENV_IS_IN_ONENAND)
841 char offset[12], length[12];
843 param_id = get_part_id("params");
845 if (param_id == -1) {
846 sprintf(offset, "%x", CONFIG_ENV_ADDR);
847 sprintf(length, "%x", CONFIG_ENV_SIZE);
849 sprintf(offset, "%x", parts[param_id]->offset);
850 sprintf(length, "%x", parts[param_id]->size);
852 nand_cmd(0, offset, length, NULL);
853 #elif defined(CONFIG_ENV_IS_IN_MMC)
854 char buf[usbd->mmc_blk];
856 memset(buf, 0x0, usbd->mmc_blk);
857 mmc_cmd(OPS_WRITE, CONFIG_SYS_MMC_ENV_DEV,
858 CONFIG_ENV_OFFSET / usbd->mmc_blk,
863 /* Parsing received data packet and Process data */
864 static int process_data(struct usbd_ops *usbd)
866 unsigned int cmd = 0, arg = 0, ofs = 0, len = 0, flag = 0;
867 char offset[12], length[12], ramaddr[12];
869 unsigned int blocks = 0;
875 sprintf(ramaddr, "0x%x", (uint) down_ram_addr);
878 cmd = *((ulong *) usbd->rx_data + 0);
879 arg = *((ulong *) usbd->rx_data + 1);
880 len = *((ulong *) usbd->rx_data + 2);
881 flag = *((ulong *) usbd->rx_data + 3);
883 /* Reset tx buffer */
884 memset(usbd->tx_data, 0, sizeof(usbd->tx_data));
886 ubi_mode = check_ubi_mode();
889 case COMMAND_DOWNLOAD_IMAGE:
890 printf("\nCOMMAND_DOWNLOAD_IMAGE\n");
892 #ifdef CONFIG_USE_YAFFS
893 usbd->recv_setup((char *)down_ram_addr + yaffs_len, (int)len);
894 printf("Download to 0x%08x, %d bytes\n",
895 (uint)down_ram_addr + yaffs_len, (int)len);
898 down_ram_addr = usbd->ram_addr + 0x1000000;
900 down_ram_addr = usbd->ram_addr;
902 usbd->recv_setup((char *)down_ram_addr, (int)len);
903 printf("Download to 0x%08x, %d bytes\n",
904 (uint)down_ram_addr, (int)len);
907 usbd->send_data(usbd->tx_data, usbd->tx_len);
909 /* Receive image by using dma */
910 recvlen = usbd->recv_data();
912 printf("Error: wrong image size -> %d/%d\n",
913 (int)recvlen, (int)len);
915 /* Retry this commad */
916 *((ulong *) usbd->tx_data) = STATUS_RETRY;
918 *((ulong *) usbd->tx_data) = STATUS_DONE;
920 usbd->send_data(usbd->tx_data, usbd->tx_len);
923 /* Report partition info */
924 case COMMAND_PARTITION_SYNC:
927 #ifdef CONFIG_CMD_UBI
929 if (part_id == RAMDISK_PART_ID ||
930 part_id == FILESYSTEM_PART_ID ||
931 part_id == FILESYSTEM2_PART_ID) {
932 /* change to yaffs style */
936 if (part_id == FILESYSTEM3_PART_ID) {
937 /* change ubi style */
943 if (part_id == FILESYSTEM3_PART_ID)
944 part_id = get_part_id("UBI");
945 else if (part_id == MODEM_PART_ID)
946 part_id = get_part_id("modem");
947 else if (part_id == KERNEL_PART_ID)
948 part_id = get_part_id("kernel");
949 else if (part_id == BOOT_PART_ID)
950 part_id = get_part_id("bootloader");
955 printf("COMMAND_PARTITION_SYNC - Part%d\n", part_id);
957 blocks = parts[part_id]->size / 1024 / 128;
958 printf("COMMAND_PARTITION_SYNC - Part%d, %d blocks\n",
961 *((ulong *) usbd->tx_data) = blocks;
962 usbd->send_data(usbd->tx_data, usbd->tx_len);
965 case COMMAND_WRITE_PART_0:
967 printf("COMMAND_WRITE_PART_0\n");
970 case COMMAND_WRITE_PART_1:
971 printf("COMMAND_WRITE_PART_BOOT\n");
972 part_id = get_part_id("bootloader");
976 case COMMAND_WRITE_PART_2:
977 case COMMAND_ERASE_PARAMETER:
978 printf("COMMAND_PARAMETER - not support!\n");
981 case COMMAND_WRITE_PART_3:
982 printf("COMMAND_WRITE_KERNEL\n");
983 part_id = get_part_id("kernel");
984 img_type = IMG_KERNEL;
987 case COMMAND_WRITE_PART_4:
988 printf("COMMAND_WRITE_ROOTFS\n");
989 part_id = get_part_id("Root");
990 img_type = IMG_FILESYSTEM;
994 case COMMAND_WRITE_PART_5:
995 printf("COMMAND_WRITE_FACTORYFS\n");
996 part_id = get_part_id("Fact");
997 img_type = IMG_FILESYSTEM;
1001 case COMMAND_WRITE_PART_6:
1002 printf("COMMAND_WRITE_DATAFS\n");
1003 part_id = get_part_id("Data");
1004 img_type = IMG_FILESYSTEM;
1008 case COMMAND_WRITE_PART_7:
1009 printf("COMMAND_WRITE_UBI\n");
1010 part_id = get_part_id("UBI");
1011 img_type = IMG_FILESYSTEM;
1013 /* someday, it will be deleted */
1017 case COMMAND_WRITE_PART_8:
1018 printf("COMMAND_WRITE_MODEM\n");
1019 part_id = get_part_id("modem");
1020 img_type = IMG_MODEM;
1023 #ifdef CONFIG_CMD_MMC
1024 case COMMAND_WRITE_PART_9:
1025 printf("COMMAND_WRITE_MMC\n");
1027 mmc_part_write = arg;
1031 case COMMAND_WRITE_IMG_0:
1032 printf("COMMAND_WRITE_MBR\n");
1036 case COMMAND_WRITE_IMG_1:
1037 printf("COMMAND_WRITE_BOOTLOADER\n");
1038 img_type = IMG_BOOTLOADER;
1041 case COMMAND_WRITE_IMG_2:
1042 printf("COMMAND_WRITE_KERNEL\n");
1043 img_type = IMG_KERNEL_V2;
1047 case COMMAND_WRITE_IMG_3:
1048 printf("COMMAND_WRITE_MODEM\n");
1049 img_type = IMG_MODEM_V2;
1053 case COMMAND_WRITE_IMG_4:
1054 printf("COMMAND_WRITE_BOOT_PART\n");
1059 case COMMAND_WRITE_IMG_5:
1060 printf("COMMAND_WRITE_SYSTEM_PART\n");
1065 case COMMAND_WRITE_IMG_6:
1066 printf("COMMAND_WRITE_UMS_PART\n");
1071 case COMMAND_WRITE_UBI_INFO:
1072 printf("COMMAND_WRITE_UBI_INFO\n");
1075 #ifdef CONFIG_CMD_UBI
1077 sprintf(length, "0x%x", (uint)len);
1078 ret = ubi_cmd(part_id, ramaddr, length, "begin");
1081 printf("Error: Not UBI mode\n");
1085 *((ulong *) usbd->tx_data) = ret;
1086 /* Write image success -> Report status */
1087 usbd->send_data(usbd->tx_data, usbd->tx_len);
1090 /* Download complete -> reset */
1091 case COMMAND_RESET_PDA:
1092 printf("\nDownload finished and Auto reset!\nWait........\n");
1097 if (usbd->cpu_reset)
1105 case COMMAND_RESET_USB:
1106 printf("\nError is occured!(maybe previous step)->\
1107 Turn off and restart!\n");
1113 case COMMAND_RAM_BOOT:
1118 case COMMAND_RAMDISK_MODE:
1119 printf("COMMAND_RAMDISK_MODE\n");
1120 #ifdef CONFIG_RAMDISK_ADDR
1122 down_ram_addr = usbd->ram_addr;
1124 down_ram_addr = CONFIG_RAMDISK_ADDR;
1125 run_command("run ramboot", 0);
1130 #ifdef CONFIG_DOWN_PHONE
1131 case COMMAND_DOWN_PHONE:
1132 printf("COMMAND_RESET_PHONE\n");
1136 *((ulong *) usbd->tx_data) = STATUS_DONE;
1137 usbd->send_data(usbd->tx_data, usbd->tx_len);
1140 case COMMAND_CHANGE_USB:
1141 printf("COMMAND_CHANGE_USB\n");
1151 case COMMAND_CSA_CLEAR:
1152 printf("COMMAND_CSA_CLEAR\n");
1153 part_id = get_part_id("csa");
1154 img_type = IMG_MODEM;
1157 case COMMAND_PROGRESS:
1158 if (usbd->set_progress)
1159 usbd->set_progress(arg);
1163 printf("Error: Unknown command -> (%d)\n", (int)cmd);
1167 /* Erase and Write to NAND */
1170 ofs = parts[part_id]->offset;
1171 #ifdef CONFIG_S5PC1XX
1172 /* Workaround: for prevent revision mismatch */
1173 if (cpu_is_s5pc110() && (down_mode != MODE_FORCE)) {
1175 long *img_header = (long *)down_ram_addr;
1177 if (*img_header == 0xea000012)
1179 else if (*(img_header + 0x400) == 0xea000012)
1182 if (img_rev != s5p_get_cpu_rev()) {
1183 printf("CPU revision mismatch!\n"
1184 "bootloader is %s%s\n"
1185 "download image is %s%s\n",
1186 s5p_get_cpu_rev() ? "EVT1" : "EVT0",
1187 s5p_get_cpu_rev() == 2 ? "-Fused" : "",
1188 img_rev ? "EVT1" : "EVT0",
1189 img_rev == 2 ? "-Fused" : "");
1190 *((ulong *) usbd->tx_data) = STATUS_ERROR;
1191 usbd->send_data(usbd->tx_data, usbd->tx_len);
1197 /* Only u-boot.bin is allowed */
1199 long *img_header = (long *)down_ram_addr;
1201 if (*img_header != 0xea000018) {
1202 printf("\n!!! ERROR !!!\n"
1203 "Please download the u-boot.bin.\n"
1204 "Other images are not allowed.\n\n");
1205 *((ulong *) usbd->tx_data) = STATUS_ERROR;
1206 usbd->send_data(usbd->tx_data, usbd->tx_len);
1212 erase_env_area(usbd);
1214 sprintf(offset, "%x", (uint)ofs);
1216 sprintf(length, "%x", parts[part_id]->size - (uint)ofs);
1218 sprintf(length, "%x", parts[part_id]->size);
1221 nand_cmd(0, offset, length, NULL);
1223 sprintf(length, "%x", (unsigned int) len);
1224 ret = nand_cmd(1, ramaddr, offset, length);
1228 sprintf(offset, "%x", parts[part_id]->offset);
1229 sprintf(length, "%x", parts[part_id]->size);
1232 nand_cmd(0, offset, length, NULL);
1234 sprintf(length, "%x", (unsigned int) len);
1235 ret = nand_cmd(1, ramaddr, offset, length);
1241 case IMG_FILESYSTEM:
1242 ret = write_file_system(ramaddr, len, offset, length,
1243 part_id, ubi_update);
1249 sprintf(offset, "%x", parts[part_id]->offset);
1250 sprintf(length, "%x", parts[part_id]->size);
1254 nand_cmd(0, offset, length, NULL);
1256 printf("CSA Clear will be skipped temporary\n");
1258 /* Check ubi image, 0x23494255 is UBI# */
1260 long *img_header = (long *)down_ram_addr;
1262 if (*img_header == 0x23494255)
1266 #ifdef CONFIG_UBIFS_MK
1267 void *dest_addr = (void *) down_ram_addr + 0xc00000;
1268 void *src_addr = (void *) down_ram_addr;
1269 int leb_size, max_leb_cnt, mkfs_min_io_size;
1270 unsigned long ubifs_dest_size, ubi_dest_size;
1271 #ifdef CONFIG_S5PC110
1272 mkfs_min_io_size = 4096;
1273 leb_size = 248 * 1024;
1275 #elif CONFIG_S5PC210
1276 mkfs_min_io_size = 2048;
1277 leb_size = 126 * 1024;
1280 printf("Start making ubifs\n");
1281 ret = mkfs(src_addr, len, dest_addr, &ubifs_dest_size,
1282 mkfs_min_io_size, leb_size, max_leb_cnt);
1284 printf("Error : making ubifs failed\n");
1287 printf("Complete making ubifs\n");
1290 #ifdef CONFIG_UBINIZE
1291 int peb_size, ubi_min_io_size, subpage_size, vid_hdr_offs;
1292 #ifdef CONFIG_S5PC110
1293 ubi_min_io_size = 4096;
1294 peb_size = 256 * 1024;
1295 subpage_size = 4096;
1297 #elif CONFIG_S5PC210
1298 ubi_min_io_size = 2048;
1299 peb_size = 128 * 1024;
1303 printf("Start ubinizing\n");
1304 ret = ubinize(dest_addr, ubifs_dest_size,
1305 src_addr, &ubi_dest_size,
1306 peb_size, ubi_min_io_size,
1307 subpage_size, vid_hdr_offs);
1309 printf("Error : ubinizing failed\n");
1312 printf("Complete ubinizing\n");
1314 len = (unsigned int) ubi_dest_size;
1318 /* Write : arg (0 Modem) / (1 CSA) */
1320 sprintf(length, "%x", (unsigned int) len);
1321 ret = nand_cmd(1, ramaddr, offset, length);
1326 #ifdef CONFIG_CMD_MMC
1330 ret = write_file_mmc_part(usbd, len);
1332 ret = write_file_mmc(usbd, len);
1338 ret = write_mmc_image(usbd, len, part_id);
1342 #ifdef CONFIG_CMD_MBR
1343 set_mbr_info(usbd, (char *)down_ram_addr, len);
1347 case IMG_BOOTLOADER:
1348 #ifdef CONFIG_BOOTLADER_SECTOR
1349 erase_env_area(usbd);
1351 ret = mmc_cmd(OPS_WRITE, usbd->mmc_dev,
1352 CONFIG_BOOTLOADER_SECTOR,
1353 len / usbd->mmc_blk + 1,
1354 (void *)down_ram_addr);
1359 ret = write_fat_file(usbd, "uImage", part_id, len);
1363 ret = write_fat_file(usbd, "modem.bin", part_id, len);
1372 /* Retry this commad */
1373 *((ulong *) usbd->tx_data) = STATUS_RETRY;
1374 usbd->send_data(usbd->tx_data, usbd->tx_len);
1377 *((ulong *) usbd->tx_data) = STATUS_DONE;
1379 /* Write image success -> Report status */
1380 usbd->send_data(usbd->tx_data, usbd->tx_len);
1384 /* Reset write count for another image */
1388 #ifdef CONFIG_USE_YAFFS
1396 static const char *recv_key = "SAMSUNG";
1397 static const char *tx_key = "MPL";
1399 int do_usbd_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1401 struct usbd_ops *usbd;
1405 down_mode = simple_strtoul(argv[1], NULL, 10);
1407 down_mode = MODE_NORMAL;
1409 printf("USB Downloader v%s\n", APP_VERSION);
1411 /* get partition info */
1412 err = get_part_info();
1416 /* interface setting */
1417 usbd = usbd_set_interface(&usbd_ops);
1418 down_ram_addr = usbd->ram_addr;
1420 #ifdef CONFIG_CMD_MBR
1422 mbr_parts = get_mbr_table(mbr_offset);
1426 puts("using default MBR\n");
1428 mbrparts = getenv("mbrparts");
1429 set_mbr_info(usbd, mbrparts, strlen(mbrparts));
1433 /* init the usb controller */
1434 if (!usbd->usb_init()) {
1435 usbd->down_cancel();
1438 mmc = find_mmc_device(usbd->mmc_dev);
1441 /* receive setting */
1442 usbd->recv_setup(usbd->rx_data, usbd->rx_len);
1444 /* detect the download request from Host PC */
1445 if (usbd->recv_data()) {
1446 if (strncmp(usbd->rx_data, recv_key, strlen(recv_key)) == 0) {
1447 printf("Download request from the Host PC\n");
1450 strcpy(usbd->tx_data, tx_key);
1451 usbd->send_data(usbd->tx_data, usbd->tx_len);
1453 printf("No download request from the Host PC!! 1\n");
1457 usbd->down_cancel();
1462 printf("Receive the packet\n");
1464 /* receive the data from Host PC */
1466 usbd->recv_setup(usbd->rx_data, usbd->rx_len);
1468 if (usbd->recv_data()) {
1469 if (process_data(usbd) == 0)
1477 U_BOOT_CMD(usbdown, CONFIG_SYS_MAXARGS, 1, do_usbd_down,
1478 "Initialize USB device and Run USB Downloader (specific)",
1480 "usbdown mode - specific mode (0: NORAML, 1: FORCE)"