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.5.3"
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>
33 static const char pszMe[] = "usbd: ";
35 static struct usbd_ops usbd_ops;
37 static unsigned int part_id;
38 static unsigned int write_part = 0;
39 static unsigned long fs_offset = 0x0;
41 #ifdef CONFIG_USE_YAFFS
42 static unsigned int yaffs_len = 0;
43 static unsigned char yaffs_data[2112];
44 #define YAFFS_PAGE 2112
47 #define NAND_PAGE_SIZE 2048
49 static unsigned long down_ram_addr;
53 /* cpu/${CPU} dependent */
54 extern void do_reset(void);
57 extern int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
58 extern int do_run(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
60 int mtdparts_init(void);
61 int find_dev_and_part(const char*, struct mtd_device**, u8*, struct part_info**);
63 /* common/cmd_jffs2.c */
64 extern struct list_head devices;
66 static u8 count_mtdparts(void)
68 struct list_head *dentry, *pentry;
69 struct mtd_device *dev;
72 list_for_each(dentry, &devices) {
73 dev = list_entry(dentry, struct mtd_device, link);
75 /* list partitions for given device */
76 list_for_each(pentry, &dev->parts)
84 static int check_ubi_mode(void)
89 env_ubifs = getenv("ubi");
90 ubi_mode = !strcmp(env_ubifs, "enabled");
95 #define check_ubi_mode() 0
98 #ifdef CONFIG_MTD_PARTITIONS
99 static int get_part_info(void)
101 struct mtd_device *dev;
109 #if defined(CONFIG_CMD_NAND)
110 sprintf(nand_name, "nand0");
111 #elif defined(CONFIG_CMD_ONENAND)
112 sprintf(nand_name, "onenand0");
114 printf("Configure your NAND sub-system\n");
121 ubi_mode = check_ubi_mode();
123 part_num = count_mtdparts();
124 for (i = 0; i < part_num; i++) {
125 sprintf(part_name, "%s,%d", nand_name, i);
127 if (find_dev_and_part(part_name, &dev, &out_partnum, &parts[i]))
134 static int get_part_id(char *name)
136 int nparts = count_mtdparts();
139 for (i = 0; i < nparts; i++) {
140 if (strcmp(parts[i]->name, name) == 0)
144 printf("Error: Unknown partition -> %s\n", name);
148 static int get_part_info(void)
150 printf("Error: Can't get patition information\n");
154 static int get_part_id(char *name)
160 static void boot_cmd(char *addr)
162 char *argv[] = { "bootm", addr };
163 do_bootm(NULL, 0, 2, argv);
166 static void run_cmd(char *cmd)
168 char *argv[] = { "run", cmd };
169 do_run(NULL, 0, 2, argv);
172 #if defined(CONFIG_CMD_NAND)
173 extern int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
174 #elif defined(CONFIG_CMD_ONENAND)
175 extern int do_onenand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
178 /* NAND erase and write using nand command */
179 static int nand_cmd(int type, char *p1, char *p2, char *p3)
183 int (*nand_func) (cmd_tbl_t *, int, int, char **);
185 #if defined(CONFIG_CMD_NAND)
186 sprintf(nand_name, "nand");
188 #elif defined(CONFIG_CMD_ONENAND)
189 sprintf(nand_name, "onenand");
190 nand_func = do_onenand;
192 printf("Configure your NAND sub-system\n");
197 char *argv[] = {nand_name, "erase", p1, p2};
198 printf("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
199 ret = nand_func(NULL, 0, 4, argv);
200 } else if (type == 1) {
201 char *argv[] = {nand_name, "write", p1, p2, p3};
202 printf("%s %s %s %s %s\n", argv[0], argv[1], argv[2],
204 ret = nand_func(NULL, 0, 5, argv);
205 } else if (type == 2) {
206 char *argv[] = {nand_name, "write.yaffs", p1, p2, p3};
207 printf("%s %s %s %s %s\n", argv[0], argv[1], argv[2],
209 ret = nand_func(NULL, 0, 5, argv);
210 } else if (type == 3) {
211 char *argv[] = {nand_name, "lock", p1, p2};
212 printf("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
213 ret = nand_func(NULL, 0, 4, argv);
217 printf("Error: NAND Command\n");
222 #ifdef CONFIG_CMD_UBI
223 int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
225 int ubi_cmd(int part, char *p1, char *p2, char *p3)
229 if (part == RAMDISK_PART_ID) {
230 char *argv[] = {"ubi", "write", p1, "rootfs.cramfs", p2, p3};
231 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
232 argv[3], argv[4], argv[5]);
233 ret = do_ubi(NULL, 0, 6, argv);
234 } else if (part == FILESYSTEM_PART_ID) {
235 char *argv[] = {"ubi", "write", p1, "factoryfs.cramfs", p2, p3};
236 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
237 argv[3], argv[4], argv[5]);
238 ret = do_ubi(NULL, 0, 6, argv);
239 } else if (part == FILESYSTEM2_PART_ID) {
240 char *argv[] = {"ubi", "write", p1, "datafs.ubifs", p2, p3};
241 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
242 argv[3], argv[4], argv[5]);
243 ret = do_ubi(NULL, 0, 6, argv);
250 #ifdef CONFIG_CMD_MMC
253 extern int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
255 static int mmc_cmd(int ops, char *p1, char *p2, char *p3)
260 char *argv[] = {"mmc", "write", "0", p1, p2, p3};
261 ret = do_mmcops(NULL, 0, 6, argv);
263 char *argv[] = {"mmc", "read", "0", p1, p2, p3};
264 ret = do_mmcops(NULL, 0, 6, argv);
270 #define NORMAL_PARTITION 0
271 #define EXTEND_PARTITION 1
273 #define EXTEND_PART_TYPE 5
275 #define EXTEND_MAX_PART 32
277 static unsigned int cur_blk_offset;
278 static unsigned int cur_part_size;
279 static unsigned int cur_part;
281 static unsigned int mmc_parts;
282 static unsigned int mmc_part_write;
284 static u8 part_mode = 0;
286 struct partition_info {
290 } __attribute__((packed));
292 struct partition_header {
293 u8 fat32head[16]; /* RFSHEAD identifier */
294 struct partition_info partition[EXTEND_MAX_PART];
295 u8 res[112]; /* reserved */
296 } __attribute__((packed));
298 struct partition_table {
305 } __attribute__((packed));
309 struct partition_table partition[4];
311 } __attribute__((packed));
313 struct mul_partition_info {
316 } __attribute__((packed));
318 #define MBR_OFFSET 0x10
320 struct partition_header part_info;
321 struct mbr_table mbr_info;
322 struct mul_partition_info mul_info[EXTEND_MAX_PART];
324 static int write_mmc_partition(struct usbd_ops *usbd, u32 *ram_addr, u32 len)
327 char offset[12], length[12], ramaddr[12];
333 if (cur_part_size > len) {
334 blocks = len / usbd->mmc_blk;
337 blocks = cur_part_size / usbd->mmc_blk;
338 ret = len - cur_part_size;
341 if (len % usbd->mmc_blk)
344 loop = blocks / usbd->mmc_max;
345 if (blocks % usbd->mmc_max)
348 for (i = 0; i < loop; i++) {
350 cnt = blocks % usbd->mmc_max;
357 sprintf(length, "%x", cnt);
358 sprintf(offset, "%x", cur_blk_offset);
359 sprintf(ramaddr, "0x%x", *ram_addr);
360 mmc_cmd(OPS_WRITE, ramaddr, offset, length);
362 cur_blk_offset += cnt;
364 *ram_addr += (cnt * usbd->mmc_blk);
370 static int write_file_mmc(struct usbd_ops *usbd, char *ramaddr, u32 len,
371 char *offset, char *length)
376 struct mbr_table *mbr;
378 if (!usbd->mmc_total) {
379 printf("MMC is not supported!\n");
383 ram_addr = (u32)down_ram_addr;
385 if (cur_blk_offset == 0) {
389 memcpy(&part_info, (void *)ram_addr,
390 sizeof(struct partition_header));
392 ram_addr += sizeof(struct partition_header);
393 len -= sizeof(struct partition_header);
394 mbr = (struct mbr_table*)ram_addr;
395 mbr_blk_size = mbr->partition[0].lba_begin;
397 if (mbr->partition[0].type_code != EXTEND_PART_TYPE) {
398 part_mode = NORMAL_PARTITION;
400 /* modify sectors of p1 */
401 mbr->partition[0].num_sectors = usbd->mmc_total -
403 mbr->partition[1].num_sectors +
404 mbr->partition[2].num_sectors +
405 mbr->partition[3].num_sectors);
409 /* modify lba_begin of p2 and p3 and p4 */
410 for (i = 1; i < 4; i++) {
411 if (part_info.partition[i].size == 0)
415 mbr->partition[i].lba_begin =
416 mbr->partition[i - 1].lba_begin +
417 mbr->partition[i - 1].num_sectors;
421 memcpy(&mbr_info, mbr, sizeof(struct mbr_table));
423 printf("Total Size: 0x%08x #parts %d\n",
424 (unsigned int)usbd->mmc_total,
426 for (i = 0; i < mmc_parts; i++) {
427 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
428 mbr_info.partition[i].lba_begin,
429 mbr_info.partition[i].num_sectors);
433 sprintf(length, "%x", mbr_blk_size);
434 sprintf(offset, "%x", 0);
435 sprintf(ramaddr, "0x%x", (u32)ram_addr);
436 ret = mmc_cmd(OPS_WRITE, ramaddr, offset, length);
438 ram_addr += mbr_blk_size * usbd->mmc_blk;
439 len -= mbr_blk_size * usbd->mmc_blk;
441 cur_blk_offset = mbr_blk_size;
443 cur_part_size = part_info.partition[0].size;
445 /* modify p1's total sector */
446 bs = (boot_sector *)ram_addr;
447 bs->total_sect = mbr_info.partition[0].num_sectors;
449 printf("\nWrite Partition %d.. %d blocks\n",
451 part_info.partition[cur_part].size /
454 part_mode = EXTEND_PARTITION;
456 for (i = 0; i < EXTEND_MAX_PART; i++) {
457 if (part_info.partition[i].size == 0)
465 printf("found %d partitions\n", mmc_parts);
467 /* build partition table */
469 mul_info[0].num_sectors =
470 usbd->mmc_total - mbr_blk_size * 2;
471 for (i = 1; i < mmc_parts; i++) {
472 mul_info[i].num_sectors =
473 part_info.partition[i].res;
476 for (i = 1; i < mmc_parts; i++) {
477 mul_info[0].num_sectors -=
478 mul_info[i].num_sectors;
481 mul_info[0].lba_begin = mbr->partition[0].lba_begin;
482 for (i = 1; i < mmc_parts; i++) {
483 mul_info[i].lba_begin =
484 mul_info[i-1].lba_begin +
485 mul_info[i-1].num_sectors;
488 /* modify main MBR */
489 mbr->partition[0].num_sectors =
490 usbd->mmc_total - mbr_blk_size;
492 /* modify MBR data of p1 */
493 mbr = (struct mbr_table *)
494 (ram_addr + mbr_blk_size * usbd->mmc_blk);
496 mbr->partition[0].num_sectors =
497 mul_info[0].num_sectors - mbr_blk_size;
498 mbr->partition[1].lba_begin =
499 mul_info[1].lba_begin - mbr_blk_size;
501 /* modify BPB data of p1 */
503 ((u32)mbr + mbr_blk_size * usbd->mmc_blk);
504 memset(&bs->sectors, 0, 2);
505 bs->total_sect = mbr->partition[0].num_sectors;
507 printf("Total Size: 0x%08x #parts %d\n",
508 (unsigned int)usbd->mmc_total,
510 for (i = 0; i < mmc_parts; i++) {
511 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
512 mul_info[i].lba_begin,
513 mul_info[i].num_sectors);
518 cur_part_size = part_info.partition[0].size;
520 printf("\nWrite Partition %d.. %d blocks\n",
522 part_info.partition[cur_part].size /
527 for (i = cur_part; i < mmc_parts; i++) {
528 ret = write_mmc_partition(usbd, &ram_addr, len);
531 cur_part_size -= len;
536 part_info.partition[cur_part].size;
538 if (part_mode == NORMAL_PARTITION) {
540 mbr_info.partition[cur_part].lba_begin;
543 mul_info[cur_part].lba_begin;
545 if (cur_part <= mmc_parts) {
546 mbr = (struct mbr_table *)ram_addr;
547 mbr->partition[1].lba_begin =
548 mul_info[cur_part+1].lba_begin -
549 mbr->partition[0].lba_begin;
558 printf("\nWrite Partition %d.. %d blocks\n",
560 part_info.partition[cur_part].size /
568 static int write_file_mmc_part(struct usbd_ops *usbd, char *ramaddr, u32 len,
569 char *offset, char *length)
574 struct mbr_table *mbr;
577 ram_addr = (u32)down_ram_addr;
580 if (cur_blk_offset == 0) {
582 sprintf(length, "%x", (unsigned int)
583 (sizeof(struct mbr_table)/usbd->mmc_blk));
584 sprintf(offset, "%x", 0);
585 sprintf(ramaddr, "0x%x", (u32)mbr);
586 mmc_cmd(OPS_READ, ramaddr, offset, length);
588 mbr_blk_size = mbr->partition[0].lba_begin;
590 if (mbr->partition[0].type_code != EXTEND_PART_TYPE) {
591 part_mode = NORMAL_PARTITION;
593 for (i = 0; i < 4; i++) {
594 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
595 mbr_info.partition[i].lba_begin,
596 mbr_info.partition[i].num_sectors);
600 mbr->partition[mmc_part_write - 1].lba_begin;
601 cur_part = mmc_part_write - 1;
604 if (mmc_part_write == 1) {
605 ram_addr += sizeof(struct mbr_table);
606 cur_blk_offset += sizeof(struct mbr_table) /
608 len -= sizeof(struct mbr_table);
611 part_mode = EXTEND_PARTITION;
613 mbr_blk_size = mbr->partition[0].lba_begin;
615 for (i = 1; i < mmc_part_write; i++) {
616 ofs = mbr->partition[0].lba_begin +
617 mbr->partition[1].lba_begin;
618 printf("P%d start blk: 0x%x, size: 0x%x\n", i,
619 ofs, mbr->partition[0].num_sectors);
620 sprintf(length, "%x", (unsigned int)
621 (sizeof(struct mbr_table) /
623 sprintf(offset, "%x", ofs);
624 sprintf(ramaddr, "0x%x", (u32)mbr);
625 mmc_cmd(OPS_READ, ramaddr, offset, length);
628 ofs = mbr->partition[0].lba_begin +
629 mbr->partition[1].lba_begin;
631 ofs += mbr_blk_size; /* skip MBR */
632 cur_blk_offset = ofs;
633 cur_part = mmc_part_write - 1;
636 if (mmc_part_write == 1) {
640 /* modify BPB data of p1 */
641 sprintf(length, "%x", (unsigned int)
642 (sizeof(struct mbr_table) /
644 sprintf(offset, "%x", cur_blk_offset);
645 sprintf(ramaddr, "0x%x", (u32)mbr);
646 mmc_cmd(OPS_READ, ramaddr, offset, length);
648 bs = (boot_sector *)mbr;
649 total_sect = bs->total_sect;
651 bs = (boot_sector *)ram_addr;
652 memset(&bs->sectors, 0, 2);
653 bs->total_sect = total_sect;
658 printf("\nWrite Partition %d.. %d blocks\n",
660 len / (int)usbd->mmc_blk);
662 write_mmc_partition(usbd, &ram_addr, len);
668 static int write_file_system(char *ramaddr, ulong len, char *offset,
669 char *length, int part_num, int ubi_update)
671 #ifdef CONFIG_USE_YAFFS
677 #ifdef CONFIG_CMD_UBI
680 sprintf(length, "0x%x", (uint)len);
681 ret = ubi_cmd(part_id, ramaddr, length, "cont");
686 /* Erase entire partition at the first writing */
687 if (write_part == 0 && ubi_update == 0) {
688 sprintf(offset, "0x%x", (uint)parts[part_num]->offset);
689 sprintf(length, "0x%x", (uint)parts[part_num]->size);
690 nand_cmd(0, offset, length, NULL);
693 #ifdef CONFIG_USE_YAFFS
694 /* if using yaffs, wirte size must be 2112*X
695 * so, must have to realloc, and writing */
696 if (!strcmp("yaffs", getenv(parts[part_num]->name))) {
699 memcpy((void *)down_ram_addr, yaffs_data, yaffs_len);
701 actual_len = len + yaffs_len;
702 yaffs_len = actual_len % YAFFS_PAGE;
703 len = actual_len - yaffs_len;
705 memset(yaffs_data, 0x00, YAFFS_PAGE);
706 memcpy(yaffs_data, (char *)down_ram_addr + len, yaffs_len);
710 sprintf(offset, "0x%x", (uint)(parts[part_num]->offset + fs_offset));
711 sprintf(length, "0x%x", (uint)len);
713 #ifdef CONFIG_USE_YAFFS
715 ret = nand_cmd(2, ramaddr, offset, length);
717 ret = nand_cmd(1, ramaddr, offset, length);
719 if (!strcmp("yaffs", getenv(parts[part_num]->name)))
720 fs_offset += len / YAFFS_PAGE * NAND_PAGE_SIZE;
726 ret = nand_cmd(1, ramaddr, offset, length);
732 static int qboot_erase = 0;
734 /* Erase the qboot */
735 static void erase_qboot_area(void)
737 char offset[12], length[12];
743 qboot_id = get_part_id("qboot");
745 if (qboot_id != -1) {
746 printf("\nCOMMAND_ERASE_QBOOT\n");
747 sprintf(offset, "%x", parts[qboot_id]->offset);
748 sprintf(length, "%x", parts[qboot_id]->size);
749 nand_cmd(0, offset, length, NULL);
754 /* Parsing received data packet and Process data */
755 static int process_data(struct usbd_ops *usbd)
757 ulong cmd = 0, arg = 0, ofs = 0, len = 0, flag = 0;
758 char offset[12], length[12], ramaddr[12];
760 unsigned int blocks = 0;
766 sprintf(ramaddr, "0x%x", (uint) down_ram_addr);
769 cmd = *((ulong *) usbd->rx_data + 0);
770 arg = *((ulong *) usbd->rx_data + 1);
771 len = *((ulong *) usbd->rx_data + 2);
772 flag = *((ulong *) usbd->rx_data + 3);
774 /* Reset tx buffer */
775 memset(usbd->tx_data, 0, sizeof(usbd->tx_data));
777 ubi_mode = check_ubi_mode();
780 case COMMAND_DOWNLOAD_IMAGE:
781 printf("\nCOMMAND_DOWNLOAD_IMAGE\n");
783 #ifdef CONFIG_USE_YAFFS
784 usbd->recv_setup((char *)down_ram_addr + yaffs_len, (int)len);
785 printf("Download to 0x%08x, %d bytes\n",
786 (uint)down_ram_addr + yaffs_len, (int)len);
788 usbd->recv_setup((char *)down_ram_addr, (int)len);
789 printf("Download to 0x%08x, %d bytes\n",
790 (uint)down_ram_addr, (int)len);
793 usbd->send_data(usbd->tx_data, usbd->tx_len);
795 /* Receive image by using dma */
796 recvlen = usbd->recv_data();
798 printf("Error: wrong image size -> %d/%d\n",
799 (int)recvlen, (int)len);
801 /* Retry this commad */
802 *((ulong *) usbd->tx_data) = STATUS_RETRY;
804 *((ulong *) usbd->tx_data) = STATUS_DONE;
806 usbd->send_data(usbd->tx_data, usbd->tx_len);
809 /* Report partition info */
810 case COMMAND_PARTITION_SYNC:
813 #ifdef CONFIG_CMD_UBI
815 if (part_id == RAMDISK_PART_ID ||
816 part_id == FILESYSTEM_PART_ID ||
817 part_id == FILESYSTEM2_PART_ID) {
818 /* change to yaffs style */
822 if (part_id == FILESYSTEM3_PART_ID) {
823 /* change ubi style */
829 if (part_id == FILESYSTEM3_PART_ID)
830 part_id = get_part_id("UBI");
831 else if (part_id == MODEM_PART_ID)
832 part_id = get_part_id("modem");
833 else if (part_id == KERNEL_PART_ID)
834 part_id = get_part_id("kernel");
839 printf("COMMAND_PARTITION_SYNC - Part%d\n", part_id);
841 blocks = parts[part_id]->size / 1024 / 128;
842 printf("COMMAND_PARTITION_SYNC - Part%d, %d blocks\n",
845 *((ulong *) usbd->tx_data) = blocks;
846 usbd->send_data(usbd->tx_data, usbd->tx_len);
849 case COMMAND_WRITE_PART_0:
851 printf("COMMAND_WRITE_PART_0\n");
854 case COMMAND_WRITE_PART_1:
855 printf("COMMAND_WRITE_PART_BOOT\n");
856 part_id = get_part_id("bootloader");
860 case COMMAND_WRITE_PART_2:
861 case COMMAND_ERASE_PARAMETER:
862 printf("COMMAND_PARAMETER - not support!\n");
865 case COMMAND_WRITE_PART_3:
866 printf("COMMAND_WRITE_KERNEL\n");
867 part_id = get_part_id("kernel");
868 img_type = IMG_KERNEL;
871 case COMMAND_WRITE_PART_4:
872 printf("COMMAND_WRITE_ROOTFS\n");
873 part_id = get_part_id("Root");
874 img_type = IMG_FILESYSTEM;
878 case COMMAND_WRITE_PART_5:
879 printf("COMMAND_WRITE_FACTORYFS\n");
880 part_id = get_part_id("Fact");
881 img_type = IMG_FILESYSTEM;
885 case COMMAND_WRITE_PART_6:
886 printf("COMMAND_WRITE_DATAFS\n");
887 part_id = get_part_id("Data");
888 img_type = IMG_FILESYSTEM;
892 case COMMAND_WRITE_PART_7:
893 printf("COMMAND_WRITE_UBI\n");
894 part_id = get_part_id("UBI");
895 img_type = IMG_FILESYSTEM;
897 /* someday, it will be deleted */
901 case COMMAND_WRITE_PART_8:
902 printf("COMMAND_WRITE_MODEM\n");
903 part_id = get_part_id("modem");
904 img_type = IMG_MODEM;
907 #ifdef CONFIG_CMD_MMC
908 case COMMAND_WRITE_PART_9:
909 printf("COMMAND_WRITE_MMC\n");
911 mmc_part_write = arg;
915 case COMMAND_WRITE_UBI_INFO:
916 printf("COMMAND_WRITE_UBI_INFO\n");
919 #ifdef CONFIG_CMD_UBI
921 sprintf(length, "0x%x", (uint)len);
922 ret = ubi_cmd(part_id, ramaddr, length, "begin");
925 printf("Error: Not UBI mode\n");
929 *((ulong *) usbd->tx_data) = ret;
930 /* Write image success -> Report status */
931 usbd->send_data(usbd->tx_data, usbd->tx_len);
934 /* Download complete -> reset */
935 case COMMAND_RESET_PDA:
936 printf("\nDownload finished and Auto reset!\nWait........\n");
949 case COMMAND_RESET_USB:
950 printf("\nError is occured!(maybe previous step)->\
951 Turn off and restart!\n");
957 case COMMAND_RAM_BOOT:
962 case COMMAND_RAMDISK_MODE:
963 printf("COMMAND_RAMDISK_MODE\n");
964 #ifdef CONFIG_RAMDISK_ADDR
966 down_ram_addr = usbd->ram_addr;
968 down_ram_addr = CONFIG_RAMDISK_ADDR;
974 #ifdef CONFIG_DOWN_PHONE
975 case COMMAND_DOWN_PHONE:
976 printf("COMMAND_RESET_PHONE\n");
980 *((ulong *) usbd->tx_data) = STATUS_DONE;
981 usbd->send_data(usbd->tx_data, usbd->tx_len);
984 case COMMAND_CHANGE_USB:
985 printf("COMMAND_CHANGE_USB\n");
995 case COMMAND_CSA_CLEAR:
996 printf("COMMAND_CSA_CLEAR\n");
997 part_id = get_part_id("csa");
998 img_type = IMG_MODEM;
1001 case COMMAND_PROGRESS:
1002 if (usbd->set_progress)
1003 usbd->set_progress(arg);
1007 printf("Error: Unknown command -> (%d)\n", (int)cmd);
1011 /* Erase and Write to NAND */
1014 ofs = parts[part_id]->offset;
1015 #ifdef CONFIG_RECOVERY
1018 1m = ipl(16k)+recovery(240k)+bootloader(768k)*/
1019 long *buf = (long *)down_ram_addr;
1021 u32 bootloader_edge = parts[part_id]->size;
1022 u32 bootloader_addr = bootloader_edge >> 2;
1023 u32 recovery_edge = bootloader_addr;
1024 u32 recovery_addr = recovery_edge >> 4;
1027 if (len > bootloader_addr) {
1028 ofst = bootloader_addr / sizeof(buf);
1029 if (*(buf + ofst) == 0xea000012) {
1030 /* case: ipl + recovery + bootloader */
1031 printf("target: ipl + recovery + loader\n");
1034 /* case: unknown format */
1035 printf("target: unknown\n");
1036 *((ulong *) usbd->tx_data) = STATUS_ERROR;
1037 usbd->send_data(usbd->tx_data, usbd->tx_len);
1041 ofst = recovery_addr/sizeof(buf);
1042 if (*(buf + ofst) == 0xea000012 &&
1043 *(buf + ofst - 1) == 0x00000000) {
1044 /* case: ipl + bootloader (old type) */
1045 printf("target: ipl + bootloader\n");
1048 /* case: bootloader only */
1049 printf("target: bootloader\n");
1050 ofs = bootloader_addr;
1052 /* skip revision check */
1053 down_mode = MODE_FORCE;
1057 sprintf(offset, "%x", (uint)ofs);
1058 sprintf(length, "%x", parts[part_id]->size);
1060 /* check block is locked/locked-tight */
1061 ret = nand_cmd(3, offset, length, NULL);
1063 printf("target is locked%s\n",
1064 (ret == 1) ? "-tight" : "");
1065 printf("-> try at recovery mode "
1066 "to update 'system'.\n");
1067 printf(" how-to: reset "
1068 "while pressing volume up and down.\n");
1069 *((ulong *) usbd->tx_data) = STATUS_ERROR;
1070 usbd->send_data(usbd->tx_data, usbd->tx_len);
1075 #ifdef CONFIG_S5PC1XX
1076 /* Workaround: for prevent revision mismatch */
1077 if (cpu_is_s5pc110() && (down_mode != MODE_FORCE)) {
1079 long *img_header = (long *)down_ram_addr;
1081 if (*img_header == 0xea000012)
1083 else if (*(img_header + 0x400) == 0xea000012)
1086 if (img_rev != s5p_get_cpu_rev()) {
1087 printf("CPU revision mismatch!\n"
1088 "bootloader is %s%s\n"
1089 "download image is %s%s\n",
1090 s5p_get_cpu_rev() ? "EVT1" : "EVT0",
1091 s5p_get_cpu_rev() == 2 ? "-Fused" : "",
1092 img_rev ? "EVT1" : "EVT0",
1093 img_rev == 2 ? "-Fused" : "");
1094 *((ulong *) usbd->tx_data) = STATUS_ERROR;
1095 usbd->send_data(usbd->tx_data, usbd->tx_len);
1100 #if defined(CONFIG_ENV_IS_IN_NAND) || defined(CONFIG_ENV_IS_IN_ONENAND)
1101 /* Erase the environment also when write bootloader */
1104 param_id = get_part_id("params");
1106 if (param_id == -1) {
1107 sprintf(offset, "%x", CONFIG_ENV_ADDR);
1108 sprintf(length, "%x", CONFIG_ENV_SIZE);
1110 sprintf(offset, "%x", parts[param_id]->offset);
1111 sprintf(length, "%x", parts[param_id]->size);
1113 nand_cmd(0, offset, length, NULL);
1116 sprintf(offset, "%x", (uint)ofs);
1118 sprintf(length, "%x", parts[part_id]->size - (uint)ofs);
1120 sprintf(length, "%x", parts[part_id]->size);
1123 nand_cmd(0, offset, length, NULL);
1125 sprintf(length, "%x", (unsigned int) len);
1126 ret = nand_cmd(1, ramaddr, offset, length);
1130 sprintf(offset, "%x", parts[part_id]->offset);
1131 sprintf(length, "%x", parts[part_id]->size);
1134 nand_cmd(0, offset, length, NULL);
1136 sprintf(length, "%x", (unsigned int) len);
1137 ret = nand_cmd(1, ramaddr, offset, length);
1143 case IMG_FILESYSTEM:
1144 ret = write_file_system(ramaddr, len, offset, length,
1145 part_id, ubi_update);
1151 sprintf(offset, "%x", parts[part_id]->offset);
1152 sprintf(length, "%x", parts[part_id]->size);
1156 nand_cmd(0, offset, length, NULL);
1158 printf("CSA Clear will be skipped temporary\n");
1160 #ifdef CONFIG_UBIFS_MK
1162 void *src_addr = (void *) down_ram_addr;
1163 int leb_size, max_leb_cnt, mkfs_min_io_size;
1164 unsigned long ubifs_dest_size, ubi_dest_size;
1165 #ifdef CONFIG_S5PC110
1166 mkfs_min_io_size = 4096;
1167 leb_size = 248 * 1024;
1169 #elif CONFIG_S5PC210
1170 mkfs_min_io_size = 2048;
1171 leb_size = 126 * 1024;
1174 printf("Start making ubifs\n");
1175 ret = mkfs(src_addr, len, &dest_addr, &ubifs_dest_size,
1176 mkfs_min_io_size, leb_size, max_leb_cnt);
1178 printf("Error : making ubifs failed\n");
1181 printf("Complete making ubifs\n");
1184 #ifdef CONFIG_UBINIZE
1185 int peb_size, ubi_min_io_size, subpage_size, vid_hdr_offs;
1186 #ifdef CONFIG_S5PC110
1187 ubi_min_io_size = 4096;
1188 peb_size = 256 * 1024;
1189 subpage_size = 4096;
1191 #elif CONFIG_S5PC210
1192 ubi_min_io_size = 2048;
1193 peb_size = 128 * 1024;
1197 printf("Start ubinizing\n");
1198 ret = ubinize(dest_addr, ubifs_dest_size,
1199 src_addr, &ubi_dest_size,
1200 peb_size, ubi_min_io_size,
1201 subpage_size, vid_hdr_offs);
1203 printf("Error : ubinizing failed\n");
1206 printf("Complete ubinizing\n");
1208 len = (unsigned int) ubi_dest_size;
1212 /* Write : arg (0 Modem) / (1 CSA) */
1214 sprintf(length, "%x", (unsigned int) len);
1215 ret = nand_cmd(1, ramaddr, offset, length);
1220 #ifdef CONFIG_CMD_MMC
1224 ret = write_file_mmc_part(usbd, ramaddr,
1225 len, offset, length);
1227 ret = write_file_mmc(usbd, ramaddr,
1228 len, offset, length);
1240 /* Retry this commad */
1241 *((ulong *) usbd->tx_data) = STATUS_RETRY;
1242 usbd->send_data(usbd->tx_data, usbd->tx_len);
1245 *((ulong *) usbd->tx_data) = STATUS_DONE;
1247 /* Write image success -> Report status */
1248 usbd->send_data(usbd->tx_data, usbd->tx_len);
1252 /* Reset write count for another image */
1256 #ifdef CONFIG_USE_YAFFS
1264 static const char *recv_key = "SAMSUNG";
1265 static const char *tx_key = "MPL";
1267 int do_usbd_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1269 struct usbd_ops *usbd;
1273 down_mode = simple_strtoul(argv[1], NULL, 10);
1275 down_mode = MODE_NORMAL;
1277 printf("USB Downloader v%s\n", APP_VERSION);
1279 /* get partition info */
1280 err = get_part_info();
1284 /* interface setting */
1285 usbd = usbd_set_interface(&usbd_ops);
1286 down_ram_addr = usbd->ram_addr;
1288 /* init the usb controller */
1291 /* receive setting */
1292 usbd->recv_setup(usbd->rx_data, usbd->rx_len);
1294 /* detect the download request from Host PC */
1295 if (usbd->recv_data()) {
1296 if (strncmp(usbd->rx_data, recv_key, strlen(recv_key)) == 0) {
1297 printf("Download request from the Host PC\n");
1300 strcpy(usbd->tx_data, tx_key);
1301 usbd->send_data(usbd->tx_data, usbd->tx_len);
1303 printf("No download request from the Host PC!! 1\n");
1307 printf("No download request from the Host PC!!\n");
1311 printf("Receive the packet\n");
1313 /* receive the data from Host PC */
1315 usbd->recv_setup(usbd->rx_data, usbd->rx_len);
1317 if (usbd->recv_data()) {
1318 if (process_data(usbd) == 0)
1326 U_BOOT_CMD(usbdown, CONFIG_SYS_MAXARGS, 1, do_usbd_down,
1327 "Initialize USB device and Run USB Downloader (specific)",
1329 "usbdown mode - specific mode (0: NORAML, 1: FORCE)"