Commit 624f876980209f9073e6fb834541efa89192d484

Authored by Nitin Garg
1 parent b79371410a

ENGR00315499-10 ARM:imx6:sabresd/sabreauto Add android fastboot supporting

Support android features:
fastboot, booti command and recovery for sabresd SD, sabresd eMMC,
sabreauto SD, sabreauto NAND.

For all booting media (SD, eMMC, NAND), inherits the partitions layout
from v2009.08. Fastboot will detect the booting media to replace
hardcoding fastboot device. SATA is not supported.

FDT is supported to use the "unused" fields in bootimg header which
requires the FDT to be combined into the boot.img.
For non-FDT boot.img, the "unused" fields should left to NULL and is
compatible to boot.

Signed-off-by: Ye.Li <B37916@freescale.com>
Signed-off-by: Nitin Garg <nitin.garg@freescale.com>

Showing 18 changed files with 3872 additions and 0 deletions Side-by-side Diff

arch/arm/cpu/armv7/mx6/soc.c
... ... @@ -21,6 +21,11 @@
21 21 #include <stdbool.h>
22 22 #include <asm/arch/mxc_hdmi.h>
23 23 #include <asm/arch/crm_regs.h>
  24 +#ifdef CONFIG_FASTBOOT
  25 +#ifdef CONFIG_ANDROID_RECOVERY
  26 +#include <recovery.h>
  27 +#endif
  28 +#endif
24 29 #ifdef CONFIG_IMX_UDC
25 30 #include <asm/arch/mx6_usbphy.h>
26 31 #include <usb/imx_udc.h>
... ... @@ -460,6 +465,49 @@
460 465 {NULL, 0},
461 466 };
462 467  
  468 +enum boot_device get_boot_device(void)
  469 +{
  470 + enum boot_device boot_dev = UNKNOWN_BOOT;
  471 + uint soc_sbmr = readl(SRC_BASE_ADDR + 0x4);
  472 + uint bt_mem_ctl = (soc_sbmr & 0x000000FF) >> 4 ;
  473 + uint bt_mem_type = (soc_sbmr & 0x00000008) >> 3;
  474 + uint bt_dev_port = (soc_sbmr & 0x00001800) >> 11;
  475 +
  476 + switch (bt_mem_ctl) {
  477 + case 0x0:
  478 + if (bt_mem_type)
  479 + boot_dev = ONE_NAND_BOOT;
  480 + else
  481 + boot_dev = WEIM_NOR_BOOT;
  482 + break;
  483 + case 0x2:
  484 + boot_dev = SATA_BOOT;
  485 + break;
  486 + case 0x3:
  487 + if (bt_mem_type)
  488 + boot_dev = I2C_BOOT;
  489 + else
  490 + boot_dev = SPI_NOR_BOOT;
  491 + break;
  492 + case 0x4:
  493 + case 0x5:
  494 + boot_dev = bt_dev_port + SD1_BOOT;
  495 + break;
  496 + case 0x6:
  497 + case 0x7:
  498 + boot_dev = bt_dev_port + MMC1_BOOT;
  499 + break;
  500 + case 0x8 ... 0xf:
  501 + boot_dev = NAND_BOOT;
  502 + break;
  503 + default:
  504 + boot_dev = UNKNOWN_BOOT;
  505 + break;
  506 + }
  507 +
  508 + return boot_dev;
  509 +}
  510 +
463 511 void s_init(void)
464 512 {
465 513 struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
... ... @@ -657,6 +705,52 @@
657 705 clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
658 706 }
659 707 #endif /* !CONFIG_SYS_L2CACHE_OFF */
  708 +
  709 +#ifdef CONFIG_FASTBOOT
  710 +
  711 +#ifdef CONFIG_ANDROID_RECOVERY
  712 +#define ANDROID_RECOVERY_BOOT (1 << 7)
  713 +/* check if the recovery bit is set by kernel, it can be set by kernel
  714 + * issue a command '# reboot recovery' */
  715 +int recovery_check_and_clean_flag(void)
  716 +{
  717 + int flag_set = 0;
  718 + u32 reg;
  719 + reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR);
  720 +
  721 + flag_set = !!(reg & ANDROID_RECOVERY_BOOT);
  722 + printf("check_and_clean: reg %x, flag_set %d\n", reg, flag_set);
  723 + /* clean it in case looping infinite here.... */
  724 + if (flag_set) {
  725 + reg &= ~ANDROID_RECOVERY_BOOT;
  726 + writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR);
  727 + }
  728 +
  729 + return flag_set;
  730 +}
  731 +#endif /*CONFIG_ANDROID_RECOVERY*/
  732 +
  733 +#define ANDROID_FASTBOOT_BOOT (1 << 8)
  734 +/* check if the recovery bit is set by kernel, it can be set by kernel
  735 + * issue a command '# reboot fastboot' */
  736 +int fastboot_check_and_clean_flag(void)
  737 +{
  738 + int flag_set = 0;
  739 + u32 reg;
  740 +
  741 + reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR);
  742 +
  743 + flag_set = !!(reg & ANDROID_FASTBOOT_BOOT);
  744 +
  745 + /* clean it in case looping infinite here.... */
  746 + if (flag_set) {
  747 + reg &= ~ANDROID_FASTBOOT_BOOT;
  748 + writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR);
  749 + }
  750 +
  751 + return flag_set;
  752 +}
  753 +#endif /*CONFIG_FASTBOOT*/
660 754  
661 755 #ifdef CONFIG_IMX_UDC
662 756 void set_usboh3_clk(void)
arch/arm/include/asm/arch-mx6/imx-regs.h
... ... @@ -231,6 +231,7 @@
231 231 #define CHIP_REV_1_5 0x15
232 232 #define IRAM_SIZE 0x00040000
233 233 #define FEC_QUIRK_ENET_MAC
  234 +#define SNVS_LPGPR 0x68
234 235  
235 236 #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
236 237 #include <asm/types.h>
arch/arm/include/asm/imx-common/boot_mode.h
... ... @@ -9,6 +9,26 @@
9 9 #define MAKE_CFGVAL(cfg1, cfg2, cfg3, cfg4) \
10 10 ((cfg4) << 24) | ((cfg3) << 16) | ((cfg2) << 8) | (cfg1)
11 11  
  12 +enum boot_device {
  13 + WEIM_NOR_BOOT,
  14 + ONE_NAND_BOOT,
  15 + PATA_BOOT,
  16 + SATA_BOOT,
  17 + I2C_BOOT,
  18 + SPI_NOR_BOOT,
  19 + SD1_BOOT,
  20 + SD2_BOOT,
  21 + SD3_BOOT,
  22 + SD4_BOOT,
  23 + MMC1_BOOT,
  24 + MMC2_BOOT,
  25 + MMC3_BOOT,
  26 + MMC4_BOOT,
  27 + NAND_BOOT,
  28 + UNKNOWN_BOOT,
  29 + BOOT_DEV_NUM = UNKNOWN_BOOT,
  30 +};
  31 +
12 32 struct boot_mode {
13 33 const char *name;
14 34 unsigned cfg_val;
... ... @@ -16,6 +36,7 @@
16 36  
17 37 void add_board_boot_modes(const struct boot_mode *p);
18 38 void boot_mode_apply(unsigned cfg_val);
  39 +enum boot_device get_boot_device(void);
19 40 extern const struct boot_mode soc_boot_modes[];
20 41 #endif
arch/arm/lib/board.c
... ... @@ -44,6 +44,10 @@
44 44 #include <miiphy.h>
45 45 #endif
46 46  
  47 +#ifdef CONFIG_FASTBOOT
  48 +#include <fastboot.h>
  49 +#endif
  50 +
47 51 DECLARE_GLOBAL_DATA_PTR;
48 52  
49 53 ulong monitor_flash_len;
... ... @@ -655,6 +659,10 @@
655 659 board_late_init();
656 660 #endif
657 661  
  662 +#ifdef CONFIG_FASTBOOT
  663 + fastboot_setup();
  664 +#endif
  665 +
658 666 #ifdef CONFIG_BITBANGMII
659 667 bb_miiphy_init();
660 668 #endif
... ... @@ -692,6 +700,10 @@
692 700 sprintf((char *)memsz, "%ldk", (gd->ram_size / 1024) - pram);
693 701 setenv("mem", (char *)memsz);
694 702 }
  703 +#endif
  704 +
  705 +#ifdef CONFIG_FASTBOOT
  706 + check_fastboot();
695 707 #endif
696 708  
697 709 /* main_loop() can return to retry autoboot, if so just run it again. */
board/freescale/common/Makefile
... ... @@ -48,6 +48,9 @@
48 48 obj-$(CONFIG_P5040DS) += ics307_clk.o
49 49 obj-$(CONFIG_VSC_CROSSBAR) += vsc3316_3308.o
50 50 obj-$(CONFIG_IDT8T49N222A) += idt8t49n222a_serdes_clk.o
  51 +ifdef CONFIG_FASTBOOT
  52 +obj-${CONFIG_ANDROID_RECOVERY} += recovery.o
  53 +endif
51 54  
52 55 # deal with common files for P-series corenet based devices
53 56 obj-$(CONFIG_P2041RDB) += p_corenet/
board/freescale/common/recovery.c
  1 +/*
  2 + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +#include <common.h>
  7 +#include <malloc.h>
  8 +#include <recovery.h>
  9 +#ifdef CONFIG_MXC_KPD
  10 +#include <mxc_keyb.h>
  11 +#endif
  12 +#include <asm/imx-common/boot_mode.h>
  13 +
  14 +#ifdef CONFIG_MXC_KPD
  15 +#define PRESSED_VOL_DOWN 0x01
  16 +#define PRESSED_POWER 0x02
  17 +#define RECOVERY_KEY_MASK (PRESSED_VOL_DOWN | PRESSED_POWER)
  18 +
  19 +inline int test_key(int value, struct kpp_key_info *ki)
  20 +{
  21 + return (ki->val == value) && (ki->evt == KDepress);
  22 +}
  23 +
  24 +int check_key_pressing(void)
  25 +{
  26 + struct kpp_key_info *key_info = NULL;
  27 + int state = 0, keys, i;
  28 +
  29 + int ret = 0;
  30 +
  31 + mxc_kpp_init();
  32 + /* due to glitch suppression circuit,
  33 + wait sometime to let all keys scanned. */
  34 + udelay(1000);
  35 + keys = mxc_kpp_getc(&key_info);
  36 +
  37 + printf("Detecting VOL_DOWN+POWER key for recovery(%d:%d) ...\n",
  38 + keys, keys ? key_info->val : 0);
  39 + if (keys > 1) {
  40 + for (i = 0; i < keys; i++) {
  41 + if (test_key(CONFIG_POWER_KEY, &key_info[i]))
  42 + state |= PRESSED_POWER;
  43 + else if (test_key(CONFIG_VOL_DOWN_KEY, &key_info[i]))
  44 + state |= PRESSED_VOL_DOWN;
  45 + }
  46 + }
  47 + if ((state & RECOVERY_KEY_MASK) == RECOVERY_KEY_MASK)
  48 + ret = 1;
  49 + if (key_info)
  50 + free(key_info);
  51 + return ret;
  52 +}
  53 +#else
  54 +/* If not using mxc keypad, currently we will detect power key on board */
  55 +int check_key_pressing(void)
  56 +{
  57 + return 0;
  58 +}
  59 +#endif
  60 +
  61 +void setup_recovery_env(void)
  62 +{
  63 + board_recovery_setup();
  64 +}
  65 +
  66 +/* export to lib_arm/board.c */
  67 +void check_recovery_mode(void)
  68 +{
  69 + if (check_key_pressing()) {
  70 + puts("Fastboot: Recovery key pressing got!\n");
  71 + setup_recovery_env();
  72 + } else if (check_recovery_cmd_file()) {
  73 + puts("Fastboot: Recovery command file founded!\n");
  74 + setup_recovery_env();
  75 + } else {
  76 + puts("Fastboot: Normal\n");
  77 + }
  78 +}
board/freescale/mx6qsabreauto/mx6qsabreauto.c
... ... @@ -24,6 +24,13 @@
24 24 #include <asm/arch/sys_proto.h>
25 25 #include <i2c.h>
26 26  
  27 +#ifdef CONFIG_FASTBOOT
  28 +#include <fastboot.h>
  29 +#ifdef CONFIG_ANDROID_RECOVERY
  30 +#include <recovery.h>
  31 +#endif
  32 +#endif /*CONFIG_FASTBOOT*/
  33 +
27 34 DECLARE_GLOBAL_DATA_PTR;
28 35  
29 36 #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
... ... @@ -309,6 +316,126 @@
309 316  
310 317 return 0;
311 318 }
  319 +
  320 +#ifdef CONFIG_FASTBOOT
  321 +
  322 +void board_fastboot_setup(void)
  323 +{
  324 + switch (get_boot_device()) {
  325 +#if defined(CONFIG_FASTBOOT_STORAGE_SATA)
  326 + case SATA_BOOT:
  327 + if (!getenv("fastboot_dev"))
  328 + setenv("fastboot_dev", "sata");
  329 + if (!getenv("bootcmd"))
  330 + setenv("bootcmd", "booti sata");
  331 + break;
  332 +#endif /*CONFIG_FASTBOOT_STORAGE_SATA*/
  333 +#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
  334 + case SD1_BOOT:
  335 + case MMC1_BOOT:
  336 + if (!getenv("fastboot_dev"))
  337 + setenv("fastboot_dev", "mmc0");
  338 + if (!getenv("bootcmd"))
  339 + setenv("bootcmd", "booti mmc0");
  340 + break;
  341 + case SD3_BOOT:
  342 + case MMC3_BOOT:
  343 + if (!getenv("fastboot_dev"))
  344 + setenv("fastboot_dev", "mmc1");
  345 + if (!getenv("bootcmd"))
  346 + setenv("bootcmd", "booti mmc1");
  347 + break;
  348 +#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/
  349 +#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  350 + case NAND_BOOT:
  351 + if (!getenv("fastboot_dev"))
  352 + setenv("fastboot_dev", "nand");
  353 + if (!getenv("fbparts"))
  354 + setenv("fbparts",
  355 + "16m@16m(boot) 128m@32m(recovery) 810m@160m(android_root)ubifs");
  356 + if (!getenv("bootcmd"))
  357 + setenv("bootcmd",
  358 + "nand read ${loadaddr} ${boot_nand_offset} "
  359 + "${boot_nand_size};booti ${loadaddr}");
  360 + break;
  361 +#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/
  362 + default:
  363 + printf("unsupported boot devices\n");
  364 + break;
  365 + }
  366 +}
  367 +
  368 +#ifdef CONFIG_ANDROID_RECOVERY
  369 +
  370 +#define GPIO_VOL_DN_KEY IMX_GPIO_NR(5, 14)
  371 +iomux_v3_cfg_t const recovery_key_pads[] = {
  372 + (MX6_PAD_DISP0_DAT20__GPIO_5_14 | MUX_PAD_CTRL(NO_PAD_CTRL)),
  373 +};
  374 +
  375 +int check_recovery_cmd_file(void)
  376 +{
  377 + int button_pressed = 0;
  378 + int recovery_mode = 0;
  379 +
  380 + recovery_mode = recovery_check_and_clean_flag();
  381 +
  382 + /* Check Recovery Combo Button press or not. */
  383 + imx_iomux_v3_setup_multiple_pads(recovery_key_pads,
  384 + ARRAY_SIZE(recovery_key_pads));
  385 +
  386 + gpio_direction_input(GPIO_VOL_DN_KEY);
  387 +
  388 + if (gpio_get_value(GPIO_VOL_DN_KEY) == 0) { /* VOL_DN key is low assert */
  389 + button_pressed = 1;
  390 + printf("Recovery key pressed\n");
  391 + }
  392 +
  393 + return recovery_mode || button_pressed;
  394 +}
  395 +
  396 +void board_recovery_setup(void)
  397 +{
  398 + int bootdev = get_boot_device();
  399 +
  400 + switch (bootdev) {
  401 +#if defined(CONFIG_FASTBOOT_STORAGE_SATA)
  402 + case SATA_BOOT:
  403 + if (!getenv("bootcmd_android_recovery"))
  404 + setenv("bootcmd_android_recovery", "booti sata recovery");
  405 + break;
  406 +#endif /*CONFIG_FASTBOOT_STORAGE_SATA*/
  407 +#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
  408 + case SD1_BOOT:
  409 + case MMC1_BOOT:
  410 + if (!getenv("bootcmd_android_recovery"))
  411 + setenv("bootcmd_android_recovery", "booti mmc0 recovery");
  412 + break;
  413 + case SD3_BOOT:
  414 + case MMC3_BOOT:
  415 + if (!getenv("bootcmd_android_recovery"))
  416 + setenv("bootcmd_android_recovery", "booti mmc1 recovery");
  417 + break;
  418 +#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/
  419 +#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  420 + case NAND_BOOT:
  421 + if (!getenv("bootcmd_android_recovery"))
  422 + setenv("bootcmd_android_recovery",
  423 + "nand read ${loadaddr} ${recovery_nand_offset} "
  424 + "${recovery_nand_size};booti ${loadaddr}");
  425 + break;
  426 +#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/
  427 + default:
  428 + printf("Unsupported bootup device for recovery: dev: %d\n",
  429 + bootdev);
  430 + return;
  431 + }
  432 +
  433 + printf("setup env for recovery..\n");
  434 + setenv("bootcmd", "run bootcmd_android_recovery");
  435 +}
  436 +#endif /*CONFIG_ANDROID_RECOVERY*/
  437 +
  438 +#endif /*CONFIG_FASTBOOT*/
312 439  
313 440 int checkboard(void)
314 441 {
board/freescale/mx6sabresd/mx6sabresd.c
... ... @@ -33,6 +33,13 @@
33 33 #include <i2c.h>
34 34 #include <asm/imx-common/mxc_i2c.h>
35 35 #endif
  36 +#ifdef CONFIG_FASTBOOT
  37 +#include <fastboot.h>
  38 +#ifdef CONFIG_ANDROID_RECOVERY
  39 +#include <recovery.h>
  40 +#endif
  41 +#endif /*CONFIG_FASTBOOT*/
  42 +
36 43 DECLARE_GLOBAL_DATA_PTR;
37 44  
38 45 #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
... ... @@ -908,6 +915,122 @@
908 915 gpio_set_value(IMX_GPIO_NR(2, 20), 0);
909 916 }
910 917 #endif
  918 +
  919 +
  920 +#ifdef CONFIG_FASTBOOT
  921 +
  922 +void board_fastboot_setup(void)
  923 +{
  924 + switch (get_boot_device()) {
  925 +#if defined(CONFIG_FASTBOOT_STORAGE_SATA)
  926 + case SATA_BOOT:
  927 + if (!getenv("fastboot_dev"))
  928 + setenv("fastboot_dev", "sata");
  929 + if (!getenv("bootcmd"))
  930 + setenv("bootcmd", "booti sata");
  931 + break;
  932 +#endif /*CONFIG_FASTBOOT_STORAGE_SATA*/
  933 +#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
  934 + case SD2_BOOT:
  935 + case MMC2_BOOT:
  936 + if (!getenv("fastboot_dev"))
  937 + setenv("fastboot_dev", "mmc0");
  938 + if (!getenv("bootcmd"))
  939 + setenv("bootcmd", "booti mmc0");
  940 + break;
  941 + case SD3_BOOT:
  942 + case MMC3_BOOT:
  943 + if (!getenv("fastboot_dev"))
  944 + setenv("fastboot_dev", "mmc1");
  945 + if (!getenv("bootcmd"))
  946 + setenv("bootcmd", "booti mmc1");
  947 + break;
  948 + case MMC4_BOOT:
  949 + if (!getenv("fastboot_dev"))
  950 + setenv("fastboot_dev", "mmc2");
  951 + if (!getenv("bootcmd"))
  952 + setenv("bootcmd", "booti mmc2");
  953 + break;
  954 +#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/
  955 + default:
  956 + printf("unsupported boot devices\n");
  957 + break;
  958 + }
  959 +
  960 +}
  961 +
  962 +#ifdef CONFIG_ANDROID_RECOVERY
  963 +
  964 +#define GPIO_VOL_DN_KEY IMX_GPIO_NR(1, 5)
  965 +iomux_v3_cfg_t const recovery_key_pads[] = {
  966 + (MX6_PAD_GPIO_5__GPIO1_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
  967 +};
  968 +
  969 +int check_recovery_cmd_file(void)
  970 +{
  971 + int button_pressed = 0;
  972 + int recovery_mode = 0;
  973 +
  974 + recovery_mode = recovery_check_and_clean_flag();
  975 +
  976 + /* Check Recovery Combo Button press or not. */
  977 + imx_iomux_v3_setup_multiple_pads(recovery_key_pads,
  978 + ARRAY_SIZE(recovery_key_pads));
  979 +
  980 + gpio_direction_input(GPIO_VOL_DN_KEY);
  981 +
  982 + if (gpio_get_value(GPIO_VOL_DN_KEY) == 0) { /* VOL_DN key is low assert */
  983 + button_pressed = 1;
  984 + printf("Recovery key pressed\n");
  985 + }
  986 +
  987 + return recovery_mode || button_pressed;
  988 +}
  989 +
  990 +void board_recovery_setup(void)
  991 +{
  992 + int bootdev = get_boot_device();
  993 +
  994 + switch (bootdev) {
  995 +#if defined(CONFIG_FASTBOOT_STORAGE_SATA)
  996 + case SATA_BOOT:
  997 + if (!getenv("bootcmd_android_recovery"))
  998 + setenv("bootcmd_android_recovery",
  999 + "booti sata recovery");
  1000 + break;
  1001 +#endif /*CONFIG_FASTBOOT_STORAGE_SATA*/
  1002 +#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
  1003 + case SD2_BOOT:
  1004 + case MMC2_BOOT:
  1005 + if (!getenv("bootcmd_android_recovery"))
  1006 + setenv("bootcmd_android_recovery",
  1007 + "booti mmc0 recovery");
  1008 + break;
  1009 + case SD3_BOOT:
  1010 + case MMC3_BOOT:
  1011 + if (!getenv("bootcmd_android_recovery"))
  1012 + setenv("bootcmd_android_recovery",
  1013 + "booti mmc1 recovery");
  1014 + break;
  1015 + case MMC4_BOOT:
  1016 + if (!getenv("bootcmd_android_recovery"))
  1017 + setenv("bootcmd_android_recovery",
  1018 + "booti mmc2 recovery");
  1019 + break;
  1020 +#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/
  1021 + default:
  1022 + printf("Unsupported bootup device for recovery: dev: %d\n",
  1023 + bootdev);
  1024 + return;
  1025 + }
  1026 +
  1027 + printf("setup env for recovery..\n");
  1028 + setenv("bootcmd", "run bootcmd_android_recovery");
  1029 +}
  1030 +
  1031 +#endif /*CONFIG_ANDROID_RECOVERY*/
  1032 +
  1033 +#endif /*CONFIG_FASTBOOT*/
911 1034  
912 1035 #ifdef CONFIG_IMX_UDC
913 1036 iomux_v3_cfg_t const otg_udc_pads[] = {
... ... @@ -189,6 +189,7 @@
189 189 obj-$(CONFIG_MODEM_SUPPORT) += modem.o
190 190 obj-$(CONFIG_UPDATE_TFTP) += update.o
191 191 obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
  192 +obj-$(CONFIG_FASTBOOT) += cmd_fastboot.o
192 193 obj-$(CONFIG_CMD_DFU) += cmd_dfu.o
193 194 obj-$(CONFIG_CMD_GPT) += cmd_gpt.o
194 195 endif
... ... @@ -55,6 +55,9 @@
55 55 #include <dm/root.h>
56 56 #include <linux/compiler.h>
57 57 #include <linux/err.h>
  58 +#ifdef CONFIG_FASTBOOT
  59 +#include <fastboot.h>
  60 +#endif
58 61  
59 62 DECLARE_GLOBAL_DATA_PTR;
60 63  
... ... @@ -714,6 +717,20 @@
714 717 }
715 718 #endif
716 719  
  720 +#ifdef CONFIG_FASTBOOT
  721 +static int initr_fastboot_setup(void)
  722 +{
  723 + fastboot_setup();
  724 + return 0;
  725 +}
  726 +
  727 +static int initr_check_fastboot(void)
  728 +{
  729 + check_fastboot();
  730 + return 0;
  731 +}
  732 +#endif
  733 +
717 734 static int run_main_loop(void)
718 735 {
719 736 #ifdef CONFIG_SANDBOX
... ... @@ -885,6 +902,9 @@
885 902 #ifdef CONFIG_BOARD_LATE_INIT
886 903 board_late_init,
887 904 #endif
  905 +#ifdef CONFIG_FASTBOOT
  906 + initr_fastboot_setup,
  907 +#endif
888 908 #ifdef CONFIG_CMD_SCSI
889 909 INIT_FUNC_WATCHDOG_RESET
890 910 initr_scsi,
... ... @@ -930,6 +950,9 @@
930 950 #endif
931 951 #ifdef CONFIG_MODEM_SUPPORT
932 952 initr_modem,
  953 +#endif
  954 +#ifdef CONFIG_FASTBOOT
  955 + initr_check_fastboot,
933 956 #endif
934 957 run_main_loop,
935 958 };
common/cmd_fastboot.c
Changes suppressed. Click to show
  1 +/*
  2 + * Copyright 2008 - 2009 (C) Wind River Systems, Inc.
  3 + * Tom Rix <Tom.Rix@windriver.com>
  4 + *
  5 + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
  6 + *
  7 + * This program is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU General Public License as
  9 + * published by the Free Software Foundation; either version 2 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This program is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + * GNU General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU General Public License
  18 + * along with this program; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 + * MA 02111-1307 USA
  21 + *
  22 + * Part of the rx_handler were copied from the Android project.
  23 + * Specifically rx command parsing in the usb_rx_data_complete
  24 + * function of the file bootable/bootloader/legacy/usbloader/usbloader.c
  25 + *
  26 + * The logical naming of flash comes from the Android project
  27 + * Thse structures and functions that look like fastboot_flash_*
  28 + * They come from bootable/bootloader/legacy/libboot/flash.c
  29 + *
  30 + * This is their Copyright:
  31 + *
  32 + * Copyright (C) 2008 The Android Open Source Project
  33 + * All rights reserved.
  34 + *
  35 + * Redistribution and use in source and binary forms, with or without
  36 + * modification, are permitted provided that the following conditions
  37 + * are met:
  38 + * * Redistributions of source code must retain the above copyright
  39 + * notice, this list of conditions and the following disclaimer.
  40 + * * Redistributions in binary form must reproduce the above copyright
  41 + * notice, this list of conditions and the following disclaimer in
  42 + * the documentation and/or other materials provided with the
  43 + * distribution.
  44 + *
  45 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  46 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  47 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  48 + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  49 + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  50 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  51 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  52 + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  53 + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  54 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  55 + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  56 + * SUCH DAMAGE.
  57 + */
  58 +#include <asm/byteorder.h>
  59 +#include <common.h>
  60 +#include <command.h>
  61 +#include <nand.h>
  62 +#include <fastboot.h>
  63 +#include <environment.h>
  64 +#include <mmc.h>
  65 +
  66 +
  67 +#ifdef CONFIG_FASTBOOT
  68 +
  69 +int do_booti(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
  70 +extern int do_bootm_linux(int flag, int argc,
  71 + char *argv[], bootm_headers_t *images);
  72 +
  73 +/* Forward decl */
  74 +static int tx_handler(void);
  75 +static int rx_handler(const unsigned char *buffer, unsigned int buffer_size);
  76 +static void reset_handler(void);
  77 +
  78 +static struct cmd_fastboot_interface interface = {
  79 + .rx_handler = rx_handler,
  80 + .reset_handler = reset_handler,
  81 + .product_name = NULL,
  82 + .serial_no = NULL,
  83 + .nand_block_size = 0,
  84 + .transfer_buffer = (unsigned char *)0xffffffff,
  85 + .transfer_buffer_size = 0,
  86 +};
  87 +
  88 +static unsigned int download_size;
  89 +static unsigned int download_bytes;
  90 +static unsigned int download_bytes_unpadded;
  91 +static unsigned int download_error;
  92 +static unsigned int continue_booting;
  93 +static unsigned int upload_size;
  94 +static unsigned int upload_bytes;
  95 +static unsigned int upload_error;
  96 +
  97 +#define MMC_SATA_BLOCK_SIZE 512
  98 +
  99 +#ifdef CONFIG_FASTBOOT_STORAGE_NAND
  100 +static void save_env(struct fastboot_ptentry *ptn,
  101 + char *var, char *val)
  102 +{
  103 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  104 + char lock[128], unlock[128];
  105 +#endif
  106 +
  107 + setenv(var, val);
  108 +
  109 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  110 + sprintf(lock, "nand lock 0x%x 0x%x", ptn->start, ptn->length);
  111 + sprintf(unlock, "nand unlock 0x%x 0x%x", ptn->start, ptn->length);
  112 +
  113 + /* This could be a problem is there is an outstanding lock */
  114 + run_command(unlock, 0);
  115 +#endif
  116 + saveenv();
  117 +
  118 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  119 + run_command(lock, 0);
  120 +#endif
  121 +}
  122 +
  123 +void save_parts_values(struct fastboot_ptentry *ptn,
  124 + unsigned int offset,
  125 + unsigned int size)
  126 +{
  127 + char var[64], val[32];
  128 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  129 + char lock[128], unlock[128];
  130 + struct fastboot_ptentry *env_ptn;
  131 +#endif
  132 +
  133 + printf("saving it..\n");
  134 +
  135 +
  136 + sprintf(var, "%s_nand_offset", ptn->name);
  137 + sprintf(val, "0x%x", offset);
  138 +
  139 + printf("setenv %s %s\n", var, val);
  140 +
  141 + setenv(var, val);
  142 +
  143 + sprintf(var, "%s_nand_size", ptn->name);
  144 + sprintf(val, "0x%x", size);
  145 +
  146 + printf("setenv %s %s\n", var, val);
  147 +
  148 + setenv(var, val);
  149 +
  150 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  151 + /* Warning :
  152 + The environment is assumed to be in a partition named 'enviroment'.
  153 + It is very possible that your board stores the enviroment
  154 + someplace else. */
  155 + env_ptn = fastboot_flash_find_ptn("environment");
  156 +
  157 + if (env_ptn) {
  158 + sprintf(lock, "nand lock 0x%x 0x%x",
  159 + env_ptn->start, env_ptn->length);
  160 + sprintf(unlock, "nand unlock 0x%x 0x%x",
  161 + env_ptn->start, env_ptn->length);
  162 +
  163 + run_command(unlock, 0);
  164 + }
  165 +#endif
  166 + saveenv();
  167 +
  168 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  169 + if (env_ptn)
  170 + run_command(lock, 0);
  171 +#endif
  172 +}
  173 +
  174 +int check_parts_values(struct fastboot_ptentry *ptn)
  175 +{
  176 + char var[64];
  177 +
  178 + sprintf(var, "%s_nand_offset", ptn->name);
  179 + if (!getenv(var))
  180 + return 1;
  181 +
  182 + sprintf(var, "%s_nand_size", ptn->name);
  183 + if (!getenv(var))
  184 + return 1;
  185 +
  186 + return 0;
  187 +}
  188 +
  189 +static int write_to_ptn(struct fastboot_ptentry *ptn)
  190 +{
  191 + int ret = 1;
  192 + char length[32];
  193 + char write_type[32];
  194 + int repeat, repeat_max;
  195 +
  196 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  197 + char lock[128];
  198 + char unlock[128];
  199 +#endif
  200 + char write[128];
  201 + char erase[128];
  202 +
  203 + printf("flashing '%s'\n", ptn->name);
  204 +
  205 + /* Which flavor of write to use */
  206 + if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_I)
  207 + sprintf(write_type, "write.i");
  208 +#ifdef CONFIG_CMD_NAND_TRIMFFS
  209 + else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_TRIMFFS)
  210 + sprintf(write_type, "write.trimffs");
  211 +#endif
  212 + else
  213 + sprintf(write_type, "write");
  214 +
  215 + /* Some flashing requires writing the same data in multiple,
  216 + consecutive flash partitions */
  217 + repeat_max = 1;
  218 + if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK) {
  219 + if (ptn->flags &
  220 + FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK) {
  221 + printf("Warning can not do both 'contiguous block' "
  222 + "and 'repeat' writes for for partition '%s'\n", ptn->name);
  223 + printf("Ignoring repeat flag\n");
  224 + } else {
  225 + repeat_max = ptn->flags &
  226 + FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK;
  227 + }
  228 + }
  229 +
  230 + /* Unlock the whole partition instead of trying to
  231 + manage special cases */
  232 + sprintf(length, "0x%x", ptn->length * repeat_max);
  233 +
  234 + for (repeat = 0; repeat < repeat_max; repeat++) {
  235 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  236 + sprintf(lock, "nand lock 0x%x %s",
  237 + ptn->start + (repeat * ptn->length), length);
  238 + sprintf(unlock, "nand unlock 0x%x %s",
  239 + ptn->start + (repeat * ptn->length), length);
  240 +#endif
  241 + sprintf(erase, "nand erase 0x%x %s",
  242 + ptn->start + (repeat * ptn->length), length);
  243 +
  244 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  245 + run_command(unlock, 0);
  246 +#endif
  247 + run_command(erase, 0);
  248 +
  249 + if ((ptn->flags &
  250 + FASTBOOT_PTENTRY_FLAGS_WRITE_NEXT_GOOD_BLOCK) &&
  251 + (ptn->flags &
  252 + FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK)) {
  253 + /* Both can not be true */
  254 + printf("Warning can not do 'next good block' and \
  255 + 'contiguous block' for partition '%s'\n",
  256 + ptn->name);
  257 + printf("Ignoring these flags\n");
  258 + } else if (ptn->flags &
  259 + FASTBOOT_PTENTRY_FLAGS_WRITE_NEXT_GOOD_BLOCK) {
  260 + /* Keep writing until you get a good block
  261 + transfer_buffer should already be aligned */
  262 + if (interface.nand_block_size) {
  263 + unsigned int blocks = download_bytes /
  264 + interface.nand_block_size;
  265 + unsigned int i = 0;
  266 + unsigned int offset = 0;
  267 +
  268 + while (i < blocks) {
  269 + /* Check for overflow */
  270 + if (offset >= ptn->length)
  271 + break;
  272 +
  273 + /* download's address only advance
  274 + if last write was successful */
  275 +
  276 + /* nand's address always advances */
  277 + sprintf(write, "nand %s 0x%p 0x%x 0x%x", write_type,
  278 + interface.transfer_buffer +
  279 + (i * interface.nand_block_size),
  280 + ptn->start + (repeat * ptn->length) + offset,
  281 + interface.nand_block_size);
  282 +
  283 + ret = run_command(write, 0);
  284 + if (ret)
  285 + break;
  286 + else
  287 + i++;
  288 +
  289 + /* Go to next nand block */
  290 + offset += interface.nand_block_size;
  291 + }
  292 + } else {
  293 + printf("Warning nand block size can not be 0 \
  294 + when using 'next good block' for \
  295 + partition '%s'\n", ptn->name);
  296 + printf("Ignoring write request\n");
  297 + }
  298 + } else if (ptn->flags &
  299 + FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK) {
  300 + /* Keep writing until you get a good block
  301 + transfer_buffer should already be aligned */
  302 + if (interface.nand_block_size) {
  303 + if (0 == nand_curr_device) {
  304 + nand_info_t *nand;
  305 + unsigned long off;
  306 + unsigned int ok_start;
  307 +
  308 + nand = &nand_info[nand_curr_device];
  309 +
  310 + printf("\nDevice %d bad blocks:\n",
  311 + nand_curr_device);
  312 +
  313 + /* Initialize the ok_start to the
  314 + start of the partition
  315 + Then try to find a block large
  316 + enough for the download */
  317 + ok_start = ptn->start;
  318 +
  319 + /* It is assumed that the start and
  320 + length are multiples of block size */
  321 + for (off = ptn->start;
  322 + off < ptn->start + ptn->length;
  323 + off += nand->erasesize) {
  324 + if (nand_block_isbad(nand, off)) {
  325 + /* Reset the ok_start
  326 + to the next block */
  327 + ok_start = off +
  328 + nand->erasesize;
  329 + }
  330 +
  331 + /* Check if we have enough
  332 + blocks */
  333 + if ((ok_start - off) >=
  334 + download_bytes)
  335 + break;
  336 + }
  337 +
  338 + /* Check if there is enough space */
  339 + if (ok_start + download_bytes <=
  340 + ptn->start + ptn->length) {
  341 +
  342 + sprintf(write, "nand %s 0x%p 0x%x 0x%x", write_type,
  343 + interface.transfer_buffer,
  344 + ok_start,
  345 + download_bytes);
  346 +
  347 + ret = run_command(write, 0);
  348 +
  349 + /* Save the results into an
  350 + environment variable on the
  351 + format
  352 + ptn_name + 'offset'
  353 + ptn_name + 'size' */
  354 + if (ret) {
  355 + /* failed */
  356 + save_parts_values(ptn, ptn->start, 0);
  357 + } else {
  358 + /* success */
  359 + save_parts_values(ptn, ok_start, download_bytes);
  360 + }
  361 + } else {
  362 + printf("Error could not find enough contiguous space "
  363 + "in partition '%s'\n", ptn->name);
  364 + printf("Ignoring write request\n");
  365 + }
  366 + } else {
  367 + /* TBD : Generalize flash handling */
  368 + printf("Error only handling 1 NAND per board");
  369 + printf("Ignoring write request\n");
  370 + }
  371 + } else {
  372 + printf("Warning nand block size can not be 0 \
  373 + when using 'continuous block' for \
  374 + partition '%s'\n", ptn->name);
  375 + printf("Ignoring write request\n");
  376 + }
  377 + } else {
  378 + /* Normal case */
  379 + sprintf(write, "nand %s 0x%p 0x%x 0x%x", write_type,
  380 + interface.transfer_buffer,
  381 + ptn->start + (repeat * ptn->length),
  382 + download_bytes);
  383 +#ifdef CONFIG_CMD_NAND_TRIMFFS
  384 + if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_TRIMFFS) {
  385 + sprintf(write, "nand %s 0x%p 0x%x 0x%x", write_type,
  386 + interface.transfer_buffer,
  387 + ptn->start + (repeat * ptn->length),
  388 + download_bytes_unpadded);
  389 + }
  390 +#endif
  391 +
  392 + ret = run_command(write, 0);
  393 +
  394 + if (0 == repeat) {
  395 + if (ret) /* failed */
  396 + save_parts_values(ptn, ptn->start, 0);
  397 + else /* success */
  398 + save_parts_values(ptn, ptn->start,
  399 + download_bytes);
  400 + }
  401 + }
  402 +
  403 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  404 + run_command(lock, 0);
  405 +#endif
  406 +
  407 + if (ret)
  408 + break;
  409 + }
  410 +
  411 + return ret;
  412 +}
  413 +#else
  414 +static void save_env(struct fastboot_ptentry *ptn,
  415 + char *var, char *val)
  416 +{
  417 + setenv(var, val);
  418 + saveenv();
  419 +}
  420 +#endif
  421 +
  422 +/* When save = 0, just parse. The input is unchanged
  423 + When save = 1, parse and do the save. The input is changed */
  424 +static int parse_env(void *ptn, char *err_string, int save, int debug)
  425 +{
  426 + int ret = 1;
  427 + unsigned int sets = 0;
  428 + unsigned int comment_start = 0;
  429 + char *var = NULL;
  430 + char *var_end = NULL;
  431 + char *val = NULL;
  432 + char *val_end = NULL;
  433 + unsigned int i;
  434 +
  435 + char *buff = (char *)interface.transfer_buffer;
  436 + unsigned int size = download_bytes_unpadded;
  437 +
  438 + /* The input does not have to be null terminated.
  439 + This will cause a problem in the corner case
  440 + where the last line does not have a new line.
  441 + Put a null after the end of the input.
  442 +
  443 + WARNING : Input buffer is assumed to be bigger
  444 + than the size of the input */
  445 + if (save)
  446 + buff[size] = 0;
  447 +
  448 + for (i = 0; i < size; i++) {
  449 +
  450 + if (NULL == var) {
  451 +
  452 + /*
  453 + * Check for comments, comment ok only on
  454 + * mostly empty lines
  455 + */
  456 + if (buff[i] == '#')
  457 + comment_start = 1;
  458 +
  459 + if (comment_start) {
  460 + if ((buff[i] == '\r') ||
  461 + (buff[i] == '\n')) {
  462 + comment_start = 0;
  463 + }
  464 + } else {
  465 + if (!((buff[i] == ' ') ||
  466 + (buff[i] == '\t') ||
  467 + (buff[i] == '\r') ||
  468 + (buff[i] == '\n'))) {
  469 + /*
  470 + * Normal whitespace before the
  471 + * variable
  472 + */
  473 + var = &buff[i];
  474 + }
  475 + }
  476 +
  477 + } else if (((NULL == var_end) || (NULL == val)) &&
  478 + ((buff[i] == '\r') || (buff[i] == '\n'))) {
  479 +
  480 + /* This is the case when a variable
  481 + is unset. */
  482 +
  483 + if (save) {
  484 + /* Set the var end to null so the
  485 + normal string routines will work
  486 +
  487 + WARNING : This changes the input */
  488 + buff[i] = '\0';
  489 +
  490 + save_env(ptn, var, val);
  491 +
  492 + if (debug)
  493 + printf("Unsetting %s\n", var);
  494 + }
  495 +
  496 + /* Clear the variable so state is parse is back
  497 + to initial. */
  498 + var = NULL;
  499 + var_end = NULL;
  500 + sets++;
  501 + } else if (NULL == var_end) {
  502 + if ((buff[i] == ' ') ||
  503 + (buff[i] == '\t'))
  504 + var_end = &buff[i];
  505 + } else if (NULL == val) {
  506 + if (!((buff[i] == ' ') ||
  507 + (buff[i] == '\t')))
  508 + val = &buff[i];
  509 + } else if (NULL == val_end) {
  510 + if ((buff[i] == '\r') ||
  511 + (buff[i] == '\n')) {
  512 + /* look for escaped cr or ln */
  513 + if ('\\' == buff[i - 1]) {
  514 + /* check for dos */
  515 + if ((buff[i] == '\r') &&
  516 + (buff[i+1] == '\n'))
  517 + buff[i + 1] = ' ';
  518 + buff[i - 1] = buff[i] = ' ';
  519 + } else {
  520 + val_end = &buff[i];
  521 + }
  522 + }
  523 + } else {
  524 + sprintf(err_string, "Internal Error");
  525 +
  526 + if (debug)
  527 + printf("Internal error at %s %d\n",
  528 + __FILE__, __LINE__);
  529 + return 1;
  530 + }
  531 + /* Check if a var / val pair is ready */
  532 + if (NULL != val_end) {
  533 + if (save) {
  534 + /* Set the end's with nulls so
  535 + normal string routines will
  536 + work.
  537 +
  538 + WARNING : This changes the input */
  539 + *var_end = '\0';
  540 + *val_end = '\0';
  541 +
  542 + save_env(ptn, var, val);
  543 +
  544 + if (debug)
  545 + printf("Setting %s %s\n", var, val);
  546 + }
  547 +
  548 + /* Clear the variable so state is parse is back
  549 + to initial. */
  550 + var = NULL;
  551 + var_end = NULL;
  552 + val = NULL;
  553 + val_end = NULL;
  554 +
  555 + sets++;
  556 + }
  557 + }
  558 +
  559 + /* Corner case
  560 + Check for the case that no newline at end of the input */
  561 + if ((NULL != var) &&
  562 + (NULL == val_end)) {
  563 + if (save) {
  564 + /* case of val / val pair */
  565 + if (var_end)
  566 + *var_end = '\0';
  567 + /* else case handled by setting 0 past
  568 + the end of buffer.
  569 + Similar for val_end being null */
  570 + save_env(ptn, var, val);
  571 +
  572 + if (debug) {
  573 + if (var_end)
  574 + printf("Trailing Setting %s %s\n", var, val);
  575 + else
  576 + printf("Trailing Unsetting %s\n", var);
  577 + }
  578 + }
  579 + sets++;
  580 + }
  581 + /* Did we set anything ? */
  582 + if (0 == sets)
  583 + sprintf(err_string, "No variables set");
  584 + else
  585 + ret = 0;
  586 +
  587 + return ret;
  588 +}
  589 +
  590 +static int saveenv_to_ptn(struct fastboot_ptentry *ptn, char *err_string)
  591 +{
  592 + int ret = 1;
  593 + int save = 0;
  594 + int debug = 0;
  595 +
  596 + /* err_string is only 32 bytes
  597 + Initialize with a generic error message. */
  598 + sprintf(err_string, "%s", "Unknown Error");
  599 +
  600 + /* Parse the input twice.
  601 + Only save to the enviroment if the entire input if correct */
  602 + save = 0;
  603 + if (0 == parse_env(ptn, err_string, save, debug)) {
  604 + save = 1;
  605 + ret = parse_env(ptn, err_string, save, debug);
  606 + }
  607 + return ret;
  608 +}
  609 +
  610 +
  611 +#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  612 +
  613 +static void process_flash_nand(const char *cmdbuf, char *response)
  614 +{
  615 + if (download_bytes) {
  616 + struct fastboot_ptentry *ptn;
  617 +
  618 + ptn = fastboot_flash_find_ptn(cmdbuf + 6);
  619 + if (ptn == 0) {
  620 + sprintf(response, "FAILpartition does not exist");
  621 + } else if ((download_bytes > ptn->length) &&
  622 + !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) {
  623 + sprintf(response, "FAILimage too large for partition");
  624 + /* TODO : Improve check for yaffs write */
  625 + } else {
  626 + /* Check if this is not really a flash write
  627 + but rather a saveenv */
  628 + if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) {
  629 + /* Since the response can only be 64 bytes,
  630 + there is no point in having a large error message. */
  631 + char err_string[32];
  632 + if (saveenv_to_ptn(ptn, &err_string[0])) {
  633 + printf("savenv '%s' failed : %s\n",
  634 + ptn->name, err_string);
  635 + sprintf(response, "FAIL%s", err_string);
  636 + } else {
  637 + printf("partition '%s' saveenv-ed\n", ptn->name);
  638 + sprintf(response, "OKAY");
  639 + }
  640 + } else {
  641 + /* Normal case */
  642 + if (write_to_ptn(ptn)) {
  643 + printf("flashing '%s' failed\n", ptn->name);
  644 + sprintf(response, "FAILfailed to flash partition");
  645 + } else {
  646 + printf("partition '%s' flashed\n", ptn->name);
  647 + sprintf(response, "OKAY");
  648 + }
  649 + }
  650 + }
  651 + } else {
  652 + sprintf(response, "FAILno image downloaded");
  653 + }
  654 +
  655 +}
  656 +#endif
  657 +
  658 +#if defined(CONFIG_FASTBOOT_STORAGE_SATA)
  659 +static void process_flash_sata(const char *cmdbuf, char *response)
  660 +{
  661 + if (download_bytes) {
  662 + struct fastboot_ptentry *ptn;
  663 +
  664 + /* Next is the partition name */
  665 + ptn = fastboot_flash_find_ptn(cmdbuf + 6);
  666 + if (ptn == 0) {
  667 + printf("Partition:'%s' does not exist\n", ptn->name);
  668 + sprintf(response, "FAILpartition does not exist");
  669 + } else if ((download_bytes >
  670 + ptn->length * MMC_SATA_BLOCK_SIZE) &&
  671 + !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) {
  672 + printf("Image too large for the partition\n");
  673 + sprintf(response, "FAILimage too large for partition");
  674 + } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) {
  675 + /* Since the response can only be 64 bytes,
  676 + there is no point in having a large error message. */
  677 + char err_string[32];
  678 + if (saveenv_to_ptn(ptn, &err_string[0])) {
  679 + printf("savenv '%s' failed : %s\n", ptn->name, err_string);
  680 + sprintf(response, "FAIL%s", err_string);
  681 + } else {
  682 + printf("partition '%s' saveenv-ed\n", ptn->name);
  683 + sprintf(response, "OKAY");
  684 + }
  685 + } else {
  686 + unsigned int temp;
  687 + char sata_write[128];
  688 +
  689 + /* block count */
  690 + temp = (download_bytes +
  691 + MMC_SATA_BLOCK_SIZE - 1) /
  692 + MMC_SATA_BLOCK_SIZE;
  693 +
  694 + sprintf(sata_write, "sata write 0x%x 0x%x 0x%x",
  695 + (unsigned int)interface.transfer_buffer,
  696 + ptn->start,
  697 + temp)
  698 +
  699 + if (run_command(sata_write, 0)) {
  700 + printf("Writing '%s' FAILED!\n",
  701 + ptn->name);
  702 + sprintf(response,
  703 + "FAIL: Write partition");
  704 + } else {
  705 + printf("Writing '%s' DONE!\n",
  706 + ptn->name);
  707 + sprintf(response, "OKAY");
  708 + }
  709 + }
  710 + } else {
  711 + sprintf(response, "FAILno image downloaded");
  712 + }
  713 +
  714 +}
  715 +#endif
  716 +
  717 +#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
  718 +static void process_flash_mmc(const char *cmdbuf, char *response)
  719 +{
  720 + if (download_bytes) {
  721 + struct fastboot_ptentry *ptn;
  722 +
  723 + /* Next is the partition name */
  724 + ptn = fastboot_flash_find_ptn(cmdbuf + 6);
  725 + if (ptn == 0) {
  726 + printf("Partition:'%s' does not exist\n", ptn->name);
  727 + sprintf(response, "FAILpartition does not exist");
  728 + } else if ((download_bytes >
  729 + ptn->length * MMC_SATA_BLOCK_SIZE) &&
  730 + !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) {
  731 + printf("Image too large for the partition\n");
  732 + sprintf(response, "FAILimage too large for partition");
  733 + } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) {
  734 + /* Since the response can only be 64 bytes,
  735 + there is no point in having a large error message. */
  736 + char err_string[32];
  737 + if (saveenv_to_ptn(ptn, &err_string[0])) {
  738 + printf("savenv '%s' failed : %s\n", ptn->name, err_string);
  739 + sprintf(response, "FAIL%s", err_string);
  740 + } else {
  741 + printf("partition '%s' saveenv-ed\n", ptn->name);
  742 + sprintf(response, "OKAY");
  743 + }
  744 + } else {
  745 + unsigned int temp;
  746 +
  747 + char mmc_dev[128];
  748 + char mmc_write[128];
  749 + int mmcret;
  750 +
  751 + printf("writing to partition '%s'\n", ptn->name);
  752 +
  753 + if (ptn->partition_id != FASTBOOT_MMC_NONE_PARTITION_ID)
  754 + sprintf(mmc_dev, "mmc dev %x %x",
  755 + fastboot_devinfo.dev_id, /*slot no*/
  756 + ptn->partition_id /*part no*/);
  757 + else
  758 + sprintf(mmc_dev, "mmc dev %x",
  759 + fastboot_devinfo.dev_id /*slot no*/);
  760 +
  761 + /* block count */
  762 + temp = (download_bytes +
  763 + MMC_SATA_BLOCK_SIZE - 1) /
  764 + MMC_SATA_BLOCK_SIZE;
  765 +
  766 + sprintf(mmc_write, "mmc write 0x%x 0x%x 0x%x",
  767 + (unsigned int)interface.transfer_buffer, /*source*/
  768 + ptn->start, /*dest*/
  769 + temp /*length*/);
  770 +
  771 + printf("Initializing '%s'\n", ptn->name);
  772 +
  773 + mmcret = run_command(mmc_dev, 0);
  774 + if (mmcret)
  775 + sprintf(response, "FAIL:Init of MMC card");
  776 + else
  777 + sprintf(response, "OKAY");
  778 +
  779 + printf("Writing '%s'\n", ptn->name);
  780 + if (run_command(mmc_write, 0)) {
  781 + printf("Writing '%s' FAILED!\n", ptn->name);
  782 + sprintf(response, "FAIL: Write partition");
  783 + } else {
  784 + printf("Writing '%s' DONE!\n", ptn->name);
  785 + sprintf(response, "OKAY");
  786 + }
  787 + }
  788 + } else {
  789 + sprintf(response, "FAILno image downloaded");
  790 + }
  791 +}
  792 +
  793 +#endif
  794 +
  795 +static void reset_handler ()
  796 +{
  797 + /* If there was a download going on, bail */
  798 + download_size = 0;
  799 + download_bytes = 0;
  800 + download_bytes_unpadded = 0;
  801 + download_error = 0;
  802 + continue_booting = 0;
  803 + upload_size = 0;
  804 + upload_bytes = 0;
  805 + upload_error = 0;
  806 +}
  807 +
  808 +static void rx_process_getvar(const char *cmdbuf, char *response)
  809 +{
  810 + int temp_len = 0;
  811 +
  812 + strcpy(response, "OKAY");
  813 +
  814 + temp_len = strlen("getvar:");
  815 + if (!strcmp(cmdbuf + temp_len, "version")) {
  816 + strcpy(response + 4, FASTBOOT_VERSION);
  817 + } else if (!strcmp(cmdbuf + temp_len,
  818 + "product")) {
  819 + if (interface.product_name)
  820 + strcpy(response + 4, interface.product_name);
  821 +
  822 + } else if (!strcmp(cmdbuf + temp_len,
  823 + "serialno")) {
  824 + if (interface.serial_no)
  825 + strcpy(response + 4, interface.serial_no);
  826 +
  827 + } else if (!strcmp(cmdbuf + temp_len,
  828 + "downloadsize")) {
  829 + if (interface.transfer_buffer_size)
  830 + sprintf(response + 4, "0x%x",
  831 + interface.transfer_buffer_size);
  832 + } else {
  833 + fastboot_getvar(cmdbuf + 7, response + 4);
  834 + }
  835 +}
  836 +
  837 +static void rx_process_reboot(const char *cmdbuf, char *response)
  838 +{
  839 + sprintf(response, "OKAY");
  840 + fastboot_tx_status(response, strlen(response));
  841 + udelay(1000000); /* 1 sec */
  842 +
  843 + do_reset(NULL, 0, 0, NULL);
  844 +}
  845 +
  846 +static int rx_process_erase(const char *cmdbuf, char *response)
  847 +{
  848 +#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  849 + struct fastboot_ptentry *ptn;
  850 +
  851 + ptn = fastboot_flash_find_ptn(cmdbuf + 6);
  852 + if (ptn == 0) {
  853 + sprintf(response, "FAILpartition does not exist");
  854 + } else {
  855 + int status, repeat, repeat_max;
  856 +
  857 + printf("erasing '%s'\n", ptn->name);
  858 +
  859 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  860 + char lock[128];
  861 + char unlock[128];
  862 +#endif
  863 + char erase[128];
  864 +
  865 + repeat_max = 1;
  866 + if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK)
  867 + repeat_max = ptn->flags & FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK;
  868 +
  869 + for (repeat = 0; repeat < repeat_max;
  870 + repeat++) {
  871 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  872 + sprintf(lock, "nand lock 0x%x 0x%x",
  873 + ptn->start + (repeat * ptn->length),
  874 + ptn->length);
  875 + sprintf(unlock, "nand unlock 0x%x 0x%x",
  876 + ptn->start + (repeat * ptn->length),
  877 + ptn->length);
  878 +#endif
  879 + sprintf(erase, "nand erase 0x%x 0x%x",
  880 + ptn->start + (repeat * ptn->length),
  881 + ptn->length);
  882 +
  883 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  884 + run_command(unlock, 0);
  885 +#endif
  886 + status = run_command(erase, 0);
  887 +#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  888 + run_command(lock, 0);
  889 +#endif
  890 +
  891 + if (status)
  892 + break;
  893 + }
  894 +
  895 + if (status) {
  896 + sprintf(response,
  897 + "FAILfailed to erase partition");
  898 + } else {
  899 + printf("partition '%s' erased\n", ptn->name);
  900 + sprintf(response, "OKAY");
  901 + }
  902 + }
  903 + return 0;
  904 +#else
  905 + printf("Not support erase command for EMMC\n");
  906 + return -1;
  907 +#endif
  908 +
  909 +}
  910 +
  911 +static void rx_process_flash(const char *cmdbuf, char *response)
  912 +{
  913 + switch (fastboot_devinfo.type) {
  914 +#if defined(CONFIG_FASTBOOT_STORAGE_SATA)
  915 + case DEV_SATA:
  916 + process_flash_sata(cmdbuf, response);
  917 + break;
  918 +#endif
  919 +#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
  920 + case DEV_MMC:
  921 + process_flash_mmc(cmdbuf, response);
  922 + break;
  923 +#endif
  924 +#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  925 + case DEV_NAND:
  926 + process_flash_nand(cmdbuf, response);
  927 + break;
  928 +#endif
  929 + default:
  930 + printf("Not support flash command for current device %d\n",
  931 + fastboot_devinfo.type);
  932 + sprintf(response,
  933 + "FAILfailed to flash device");
  934 + break;
  935 + }
  936 +}
  937 +
  938 +static void rx_process_boot(const char *cmdbuf, char *response)
  939 +{
  940 + if ((download_bytes) &&
  941 + (CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE <
  942 + download_bytes)) {
  943 + char start[32];
  944 + char *booti_args[4] = {"booti", NULL, "boot", NULL};
  945 +
  946 + /*
  947 + * Use this later to determine if a command line was passed
  948 + * for the kernel.
  949 + */
  950 + /* struct fastboot_boot_img_hdr *fb_hdr = */
  951 + /* (struct fastboot_boot_img_hdr *) interface.transfer_buffer; */
  952 +
  953 + /* Skip the mkbootimage header */
  954 + /* image_header_t *hdr = */
  955 + /* (image_header_t *) */
  956 + /* &interface.transfer_buffer[CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE]; */
  957 +
  958 + booti_args[1] = start;
  959 + sprintf(start, "0x%x", (unsigned int)interface.transfer_buffer);
  960 +
  961 + /* Execution should jump to kernel so send the response
  962 + now and wait a bit. */
  963 + sprintf(response, "OKAY");
  964 + fastboot_tx_status(response, strlen(response));
  965 +
  966 + printf("Booting kernel...\n");
  967 +
  968 +
  969 + /* Reserve for further use, this can
  970 + * be more convient for developer. */
  971 + /* if (strlen ((char *) &fb_hdr->cmdline[0])) */
  972 + /* set_env("bootargs", (char *) &fb_hdr->cmdline[0]); */
  973 +
  974 + /* boot the boot.img */
  975 + do_booti(NULL, 0, 3, booti_args);
  976 +
  977 +
  978 + }
  979 + sprintf(response, "FAILinvalid boot image");
  980 +}
  981 +
  982 +static void rx_process_upload(const char *cmdbuf, char *response)
  983 +{
  984 +#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  985 + unsigned int adv, delim_index, len;
  986 + struct fastboot_ptentry *ptn;
  987 + unsigned int is_raw = 0;
  988 +
  989 + /* Is this a raw read ? */
  990 + if (memcmp(cmdbuf, "uploadraw:", 10) == 0) {
  991 + is_raw = 1;
  992 + adv = 10;
  993 + } else {
  994 + adv = 7;
  995 + }
  996 +
  997 + /* Scan to the next ':' to find when the size starts */
  998 + len = strlen(cmdbuf);
  999 + for (delim_index = adv;
  1000 + delim_index < len; delim_index++) {
  1001 + if (cmdbuf[delim_index] == ':') {
  1002 + /* WARNING, cmdbuf is being modified. */
  1003 + *((char *) &cmdbuf[delim_index]) = 0;
  1004 + break;
  1005 + }
  1006 + }
  1007 +
  1008 + ptn = fastboot_flash_find_ptn(cmdbuf + adv);
  1009 + if (ptn == 0) {
  1010 + sprintf(response,
  1011 + "FAILpartition does not exist");
  1012 + } else {
  1013 + /* This is how much the user is expecting */
  1014 + unsigned int user_size;
  1015 + /*
  1016 + * This is the maximum size needed for
  1017 + * this partition
  1018 + */
  1019 + unsigned int size;
  1020 + /* This is the length of the data */
  1021 + unsigned int length;
  1022 + /*
  1023 + * Used to check previous write of
  1024 + * the parition
  1025 + */
  1026 + char env_ptn_length_var[128];
  1027 + char *env_ptn_length_val;
  1028 +
  1029 + user_size = 0;
  1030 + if (delim_index < len)
  1031 + user_size =
  1032 + simple_strtoul(cmdbuf + delim_index + 1,
  1033 + NULL, 16);
  1034 +
  1035 + /* Make sure output is padded to block size */
  1036 + length = ptn->length;
  1037 + sprintf(env_ptn_length_var,
  1038 + "%s_nand_size", ptn->name);
  1039 + env_ptn_length_val = getenv(env_ptn_length_var);
  1040 + if (env_ptn_length_val) {
  1041 + length =
  1042 + simple_strtoul(env_ptn_length_val,
  1043 + NULL, 16);
  1044 + /* Catch possible problems */
  1045 + if (!length)
  1046 + length = ptn->length;
  1047 + }
  1048 +
  1049 + size = length / interface.nand_block_size;
  1050 + size *= interface.nand_block_size;
  1051 + if (length % interface.nand_block_size)
  1052 + size += interface.nand_block_size;
  1053 +
  1054 + if (is_raw)
  1055 + size += (size /
  1056 + interface.nand_block_size) *
  1057 + interface.nand_oob_size;
  1058 +
  1059 + if (size > interface.transfer_buffer_size) {
  1060 +
  1061 + sprintf(response, "FAILdata too large");
  1062 +
  1063 + } else if (user_size == 0) {
  1064 +
  1065 + /* Send the data response */
  1066 + sprintf(response, "DATA%08x", size);
  1067 +
  1068 + } else if (user_size != size) {
  1069 + /* This is the wrong size */
  1070 + sprintf(response, "FAIL");
  1071 + } else {
  1072 + /*
  1073 + * This is where the transfer
  1074 + * buffer is populated
  1075 + */
  1076 + unsigned char *buf =
  1077 + interface.transfer_buffer;
  1078 + char read[128];
  1079 +
  1080 + /*
  1081 + * Setting upload_size causes
  1082 + * transfer to happen in main loop
  1083 + */
  1084 + upload_size = size;
  1085 + upload_bytes = 0;
  1086 + upload_error = 0;
  1087 +
  1088 + /*
  1089 + * Poison the transfer buffer, 0xff
  1090 + * is erase value of nand
  1091 + */
  1092 + memset(buf, 0xff, upload_size);
  1093 +
  1094 + /* Which flavor of read to use */
  1095 + if (is_raw)
  1096 + sprintf(read, "nand read.raw 0x%x 0x%x 0x%x",
  1097 + (unsigned int)(interface.transfer_buffer),
  1098 + ptn->start,
  1099 + upload_size);
  1100 + else
  1101 + sprintf(read, "nand read.i 0x%x 0x%x 0x%x",
  1102 + (unsigned int)(interface.transfer_buffer),
  1103 + ptn->start,
  1104 + upload_size);
  1105 +
  1106 + run_command(read, 0);
  1107 +
  1108 + /* Send the data response */
  1109 + sprintf(response, "DATA%08x", size);
  1110 + }
  1111 + }
  1112 +#endif
  1113 +
  1114 +}
  1115 +
  1116 +static int tx_handler(void)
  1117 +{
  1118 + if (upload_size) {
  1119 +
  1120 + int bytes_written;
  1121 + bytes_written = fastboot_tx(interface.transfer_buffer +
  1122 + upload_bytes, upload_size -
  1123 + upload_bytes);
  1124 + if (bytes_written > 0) {
  1125 +
  1126 + upload_bytes += bytes_written;
  1127 + /* Check if this is the last */
  1128 + if (upload_bytes == upload_size) {
  1129 +
  1130 + /* Reset upload */
  1131 + upload_size = 0;
  1132 + upload_bytes = 0;
  1133 + upload_error = 0;
  1134 + }
  1135 + }
  1136 + }
  1137 + return upload_error;
  1138 +}
  1139 +
  1140 +static int rx_handler (const unsigned char *buffer, unsigned int buffer_size)
  1141 +{
  1142 + int ret = 1;
  1143 +
  1144 + /*response buffer, Use 65 instead of 64
  1145 + null gets dropped. strcpy's need the extra byte */
  1146 + char response[FASTBOOT_RESPONSE_SIZE];
  1147 +
  1148 + if (download_size) {
  1149 + /* Something to download */
  1150 +
  1151 + if (buffer_size) {
  1152 + /* Handle possible overflow */
  1153 + unsigned int transfer_size =
  1154 + download_size - download_bytes;
  1155 +
  1156 + if (buffer_size < transfer_size)
  1157 + transfer_size = buffer_size;
  1158 +
  1159 + /* Save the data to the transfer buffer */
  1160 + memcpy(interface.transfer_buffer + download_bytes,
  1161 + buffer, transfer_size);
  1162 +
  1163 + download_bytes += transfer_size;
  1164 +
  1165 + /* Check if transfer is done */
  1166 + if (download_bytes >= download_size) {
  1167 + /* Reset global transfer variable,
  1168 + Keep download_bytes because it will be
  1169 + used in the next possible flashing command */
  1170 + download_size = 0;
  1171 +
  1172 + if (download_error) {
  1173 + /* There was an earlier error */
  1174 + sprintf(response, "ERROR");
  1175 + } else {
  1176 + /* Everything has transferred,
  1177 + send the OK response */
  1178 + sprintf(response, "OKAY");
  1179 + }
  1180 + fastboot_tx_status(response, strlen(response));
  1181 +
  1182 + printf("\ndownloading of %d bytes finished\n",
  1183 + download_bytes);
  1184 +
  1185 +#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  1186 + /* Pad to block length
  1187 + In most cases, padding the download to be
  1188 + block aligned is correct. The exception is
  1189 + when the following flash writes to the oob
  1190 + area. This happens when the image is a
  1191 + YAFFS image. Since we do not know what
  1192 + the download is until it is flashed,
  1193 + go ahead and pad it, but save the true
  1194 + size in case if should have
  1195 + been unpadded */
  1196 + download_bytes_unpadded = download_bytes;
  1197 + if (interface.nand_block_size) {
  1198 + if (download_bytes %
  1199 + interface.nand_block_size) {
  1200 + unsigned int pad =
  1201 + interface.nand_block_size -
  1202 + (download_bytes % interface.nand_block_size);
  1203 + unsigned int i;
  1204 +
  1205 + for (i = 0; i < pad; i++) {
  1206 + if (download_bytes >=
  1207 + interface.transfer_buffer_size)
  1208 + break;
  1209 +
  1210 + interface.transfer_buffer[download_bytes] = 0;
  1211 + download_bytes++;
  1212 + }
  1213 + }
  1214 + }
  1215 +#endif
  1216 + }
  1217 +
  1218 + /* Provide some feedback */
  1219 + if (download_bytes &&
  1220 + 0 == (download_bytes %
  1221 + (16 * interface.nand_block_size))) {
  1222 + /* Some feeback that the
  1223 + download is happening */
  1224 + if (download_error)
  1225 + printf("X");
  1226 + else
  1227 + printf(".");
  1228 + if (0 == (download_bytes %
  1229 + (80 * 16 *
  1230 + interface.nand_block_size)))
  1231 + printf("\n");
  1232 +
  1233 + }
  1234 + } else {
  1235 + /* Ignore empty buffers */
  1236 + printf("Warning empty download buffer\n");
  1237 + printf("Ignoring\n");
  1238 + }
  1239 + ret = 0;
  1240 + } else {
  1241 + /* A command */
  1242 +
  1243 + /* Cast to make compiler happy with string functions */
  1244 + const char *cmdbuf = (char *) buffer;
  1245 + printf("cmdbuf: %s\n", cmdbuf);
  1246 +
  1247 + /* Generic failed response */
  1248 + sprintf(response, "FAIL");
  1249 +
  1250 + /* reboot
  1251 + Reboot the board. */
  1252 + if (memcmp(cmdbuf, "reboot", 6) == 0) {
  1253 + rx_process_reboot(cmdbuf, response);
  1254 + /* This code is unreachable,
  1255 + leave it to make the compiler happy */
  1256 + return 0;
  1257 + }
  1258 +
  1259 + /* getvar
  1260 + Get common fastboot variables
  1261 + Board has a chance to handle other variables */
  1262 + if (memcmp(cmdbuf, "getvar:", 7) == 0) {
  1263 + rx_process_getvar(cmdbuf, response);
  1264 + ret = 0;
  1265 + }
  1266 +
  1267 + /* erase
  1268 + Erase a register flash partition
  1269 + Board has to set up flash partitions */
  1270 + if (memcmp(cmdbuf, "erase:", 6) == 0)
  1271 + ret = rx_process_erase(cmdbuf, response);
  1272 +
  1273 + /* download
  1274 + download something ..
  1275 + What happens to it depends on the next command after data */
  1276 +
  1277 + if (memcmp(cmdbuf, "download:", 9) == 0) {
  1278 +
  1279 + /* save the size */
  1280 + download_size = simple_strtoul(cmdbuf + 9, NULL, 16);
  1281 + /* Reset the bytes count, now it is safe */
  1282 + download_bytes = 0;
  1283 + /* Reset error */
  1284 + download_error = 0;
  1285 +
  1286 + printf("Starting download of %d bytes\n",
  1287 + download_size);
  1288 +
  1289 + if (0 == download_size) {
  1290 + /* bad user input */
  1291 + sprintf(response, "FAILdata invalid size");
  1292 + } else if (download_size >
  1293 + interface.transfer_buffer_size) {
  1294 + /* set download_size to 0 because this is an error */
  1295 + download_size = 0;
  1296 + sprintf(response, "FAILdata too large");
  1297 + } else {
  1298 + /* The default case, the transfer fits
  1299 + completely in the interface buffer */
  1300 + sprintf(response, "DATA%08x", download_size);
  1301 + }
  1302 + ret = 0;
  1303 + }
  1304 +
  1305 + /* boot
  1306 + boot what was downloaded
  1307 +
  1308 + WARNING WARNING WARNING
  1309 +
  1310 + This is not what you expect.
  1311 + The fastboot client does its own packaging of the
  1312 + kernel. The layout is defined in the android header
  1313 + file bootimage.h. This layeout is copiedlooks like this,
  1314 +
  1315 + **
  1316 + ** +-----------------+
  1317 + ** | boot header | 1 page
  1318 + ** +-----------------+
  1319 + ** | kernel | n pages
  1320 + ** +-----------------+
  1321 + ** | ramdisk | m pages
  1322 + ** +-----------------+
  1323 + ** | second stage | o pages
  1324 + ** +-----------------+
  1325 + **
  1326 +
  1327 + We only care about the kernel.
  1328 + So we have to jump past a page.
  1329 +
  1330 + What is a page size ?
  1331 + The fastboot client uses 2048
  1332 +
  1333 + The is the default value of
  1334 +
  1335 + CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE
  1336 +
  1337 + */
  1338 +
  1339 + if (memcmp(cmdbuf, "boot", 4) == 0) {
  1340 + rx_process_boot(cmdbuf, response);
  1341 + ret = 0;
  1342 + }
  1343 +
  1344 + /* flash
  1345 + Flash what was downloaded */
  1346 + if (memcmp(cmdbuf, "flash:", 6) == 0) {
  1347 + rx_process_flash(cmdbuf, response);
  1348 + ret = 0;
  1349 + }
  1350 +
  1351 + /* continue
  1352 + Stop doing fastboot */
  1353 + if (memcmp(cmdbuf, "continue", 8) == 0) {
  1354 + sprintf(response, "OKAY");
  1355 + continue_booting = 1;
  1356 + ret = 0;
  1357 + }
  1358 +
  1359 + /* upload
  1360 + Upload just the data in a partition */
  1361 + if ((memcmp(cmdbuf, "upload:", 7) == 0) ||
  1362 + (memcmp(cmdbuf, "uploadraw:", 10) == 0)) {
  1363 + rx_process_upload(cmdbuf, response);
  1364 + ret = 0;
  1365 + }
  1366 +
  1367 + fastboot_tx_status(response, strlen(response));
  1368 +
  1369 + } /* End of command */
  1370 +
  1371 + return ret;
  1372 +}
  1373 +
  1374 +int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  1375 +{
  1376 + int ret = 1;
  1377 + int check_timeout = 0;
  1378 + uint64_t timeout_endtime = 0;
  1379 + uint64_t timeout_ticks = 1000;
  1380 + int continue_from_disconnect = 0;
  1381 +
  1382 + do {
  1383 + continue_from_disconnect = 0;
  1384 +
  1385 + /* Initialize the board specific support */
  1386 + if (0 == fastboot_init(&interface)) {
  1387 +
  1388 + int poll_status;
  1389 +
  1390 + /* If we got this far, we are a success */
  1391 + ret = 0;
  1392 + printf("fastboot initialized\n");
  1393 +
  1394 + timeout_endtime = get_timer(0);
  1395 + timeout_endtime += timeout_ticks;
  1396 +
  1397 + while (1) {
  1398 + uint64_t current_time = 0;
  1399 + poll_status = fastboot_poll();
  1400 +
  1401 + if (1 == check_timeout)
  1402 + current_time = get_timer(0);
  1403 +
  1404 + if (FASTBOOT_ERROR == poll_status) {
  1405 + /* Error */
  1406 + break;
  1407 + } else if (FASTBOOT_DISCONNECT == poll_status) {
  1408 + /* beak, cleanup and re-init */
  1409 + printf("Fastboot disconnect detected\n");
  1410 + continue_from_disconnect = 1;
  1411 + break;
  1412 + } else if ((1 == check_timeout) &&
  1413 + (FASTBOOT_INACTIVE == poll_status)) {
  1414 +
  1415 + /* No activity */
  1416 + if (current_time >= timeout_endtime) {
  1417 + printf("Fastboot inactivity detected\n");
  1418 + break;
  1419 + }
  1420 + } else {
  1421 + /* Something happened */
  1422 + if (1 == check_timeout) {
  1423 + /* Update the timeout endtime */
  1424 + timeout_endtime = current_time;
  1425 + timeout_endtime += timeout_ticks;
  1426 + }
  1427 + }
  1428 +
  1429 + /* Check if the user wanted to terminate with ^C */
  1430 + if ((FASTBOOT_INACTIVE == poll_status) &&
  1431 + (ctrlc())) {
  1432 + printf("Fastboot ended by user\n");
  1433 + break;
  1434 + }
  1435 +
  1436 + /*
  1437 + * Check if the fastboot client wanted to
  1438 + * continue booting
  1439 + */
  1440 + if (continue_booting) {
  1441 + printf("Fastboot ended by client\n");
  1442 + break;
  1443 + }
  1444 +
  1445 + /* Check if there is something to upload */
  1446 + tx_handler();
  1447 + }
  1448 + }
  1449 +
  1450 + /* Reset the board specific support */
  1451 + fastboot_shutdown();
  1452 +
  1453 + /* restart the loop if a disconnect was detected */
  1454 + } while (continue_from_disconnect);
  1455 +
  1456 + return ret;
  1457 +}
  1458 +
  1459 +U_BOOT_CMD(
  1460 + fastboot, 2, 1, do_fastboot,
  1461 + "fastboot- use USB Fastboot protocol\n",
  1462 + "[inactive timeout]\n"
  1463 + " - Run as a fastboot usb device.\n"
  1464 + " - The optional inactive timeout is the decimal seconds before\n"
  1465 + " - the normal console resumes\n"
  1466 +);
  1467 +
  1468 +
  1469 +#ifdef CONFIG_CMD_BOOTI
  1470 + /* Section for Android bootimage format support
  1471 + * Refer:
  1472 + * http://android.git.kernel.org/?p=platform/system/core.git;a=blob;
  1473 + * f=mkbootimg/bootimg.h
  1474 + */
  1475 +
  1476 +void
  1477 +bootimg_print_image_hdr(struct fastboot_boot_img_hdr *hdr)
  1478 +{
  1479 +#ifdef DEBUG
  1480 + int i;
  1481 + printf(" Image magic: %s\n", hdr->magic);
  1482 +
  1483 + printf(" kernel_size: 0x%x\n", hdr->kernel_size);
  1484 + printf(" kernel_addr: 0x%x\n", hdr->kernel_addr);
  1485 +
  1486 + printf(" rdisk_size: 0x%x\n", hdr->ramdisk_size);
  1487 + printf(" rdisk_addr: 0x%x\n", hdr->ramdisk_addr);
  1488 +
  1489 + printf(" second_size: 0x%x\n", hdr->second_size);
  1490 + printf(" second_addr: 0x%x\n", hdr->second_addr);
  1491 +
  1492 + printf(" tags_addr: 0x%x\n", hdr->tags_addr);
  1493 + printf(" page_size: 0x%x\n", hdr->page_size);
  1494 +
  1495 + printf(" name: %s\n", hdr->name);
  1496 + printf(" cmdline: %s%x\n", hdr->cmdline);
  1497 +
  1498 + for (i = 0; i < 8; i++)
  1499 + printf(" id[%d]: 0x%x\n", i, hdr->id[i]);
  1500 +#endif
  1501 +}
  1502 +
  1503 +static unsigned char boothdr[512] __aligned(ARCH_DMA_MINALIGN);
  1504 +
  1505 +#define ALIGN_SECTOR(n, pagesz) ((n + (pagesz - 1)) & (~(pagesz - 1)))
  1506 +
  1507 +#ifdef CONFIG_LMB
  1508 +static void boot_start_lmb(bootm_headers_t *images)
  1509 +{
  1510 + ulong mem_start;
  1511 + phys_size_t mem_size;
  1512 +
  1513 + lmb_init(&images->lmb);
  1514 +
  1515 + mem_start = getenv_bootm_low();
  1516 + mem_size = getenv_bootm_size();
  1517 +
  1518 + lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
  1519 +
  1520 + arch_lmb_reserve(&images->lmb);
  1521 + board_lmb_reserve(&images->lmb);
  1522 +}
  1523 +#else
  1524 +#define lmb_reserve(lmb, base, size)
  1525 +static inline void boot_start_lmb(bootm_headers_t *images) { }
  1526 +#endif
  1527 +
  1528 +/* booti <addr> [ mmc0 | mmc1 [ <partition> ] ] */
  1529 +int do_booti(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  1530 +{
  1531 + unsigned addr = 0;
  1532 + char *ptn = "boot";
  1533 + int mmcc = -1;
  1534 + struct fastboot_boot_img_hdr *hdr = (void *)boothdr;
  1535 +#ifdef CONFIG_SECURE_BOOT
  1536 + u_int32_t load_addr;
  1537 + uint32_t image_size;
  1538 +#endif
  1539 + int i = 0;
  1540 + bootm_headers_t images;
  1541 +
  1542 + for (i = 0; i < argc; i++)
  1543 + printf("%s ", argv[i]);
  1544 + printf("\n");
  1545 +
  1546 + if (argc < 2)
  1547 + return -1;
  1548 +
  1549 + if (!strncmp(argv[1], "mmc", 3))
  1550 + mmcc = simple_strtoul(argv[1]+3, NULL, 10);
  1551 + else
  1552 + addr = simple_strtoul(argv[1], NULL, 16);
  1553 +
  1554 + if (argc > 2)
  1555 + ptn = argv[2];
  1556 +
  1557 + if (mmcc != -1) {
  1558 +#ifdef CONFIG_MMC
  1559 + struct fastboot_ptentry *pte;
  1560 + struct mmc *mmc;
  1561 + disk_partition_t info;
  1562 + block_dev_desc_t *dev_desc = NULL;
  1563 + unsigned sector;
  1564 +
  1565 + memset((void *)&info, 0 , sizeof(disk_partition_t));
  1566 + /* i.MX use MBR as partition table, so this will have
  1567 + to find the start block and length for the
  1568 + partition name and register the fastboot pte we
  1569 + define the partition number of each partition in
  1570 + config file
  1571 + */
  1572 + mmc = find_mmc_device(mmcc);
  1573 + if (!mmc) {
  1574 + printf("booti: cannot find '%d' mmc device\n", mmcc);
  1575 + goto fail;
  1576 + }
  1577 + dev_desc = get_dev("mmc", mmcc);
  1578 + if (NULL == dev_desc) {
  1579 + printf("** Block device MMC %d not supported\n", mmcc);
  1580 + goto fail;
  1581 + }
  1582 +
  1583 + /* below was i.MX mmc operation code */
  1584 + if (mmc_init(mmc)) {
  1585 + printf("mmc%d init failed\n", mmcc);
  1586 + goto fail;
  1587 + }
  1588 +
  1589 + pte = fastboot_flash_find_ptn(ptn);
  1590 + if (!pte) {
  1591 + printf("booti: cannot find '%s' partition\n", ptn);
  1592 + goto fail;
  1593 + }
  1594 +
  1595 + if (mmc->block_dev.block_read(mmcc, pte->start,
  1596 + 1, (void *)hdr) < 0) {
  1597 + printf("booti: mmc failed to read bootimg header\n");
  1598 + goto fail;
  1599 + }
  1600 +
  1601 + if (memcmp(hdr->magic, FASTBOOT_BOOT_MAGIC, 8)) {
  1602 + printf("booti: bad boot image magic\n");
  1603 + goto fail;
  1604 + }
  1605 +
  1606 + sector = pte->start + (hdr->page_size / 512);
  1607 +
  1608 + if (mmc->block_dev.block_read(mmcc, sector,
  1609 + (hdr->kernel_size / 512) + 1,
  1610 + (void *)hdr->kernel_addr) < 0) {
  1611 + printf("booti: mmc failed to read kernel\n");
  1612 + goto fail;
  1613 + }
  1614 + /* flush cache after read */
  1615 + flush_cache((ulong)hdr->kernel_addr, hdr->kernel_size); /* FIXME */
  1616 + sector += ALIGN_SECTOR(hdr->kernel_size, hdr->page_size) / 512;
  1617 + if (mmc->block_dev.block_read(mmcc, sector,
  1618 + (hdr->ramdisk_size / 512) + 1,
  1619 + (void *)hdr->ramdisk_addr) < 0) {
  1620 + printf("booti: mmc failed to read ramdisk\n");
  1621 + goto fail;
  1622 + }
  1623 + /* flush cache after read */
  1624 + flush_cache((ulong)hdr->ramdisk_addr, hdr->ramdisk_size); /* FIXME */
  1625 +
  1626 +#ifdef CONFIG_OF_LIBFDT
  1627 + /* load the dtb file */
  1628 + if (hdr->second_size && hdr->second_addr) {
  1629 + sector += ALIGN_SECTOR(hdr->ramdisk_size, hdr->page_size) / 512;
  1630 + if (mmc->block_dev.block_read(mmcc, sector,
  1631 + (hdr->second_size / 512) + 1,
  1632 + (void *)hdr->second_addr) < 0) {
  1633 + printf("booti: mmc failed to dtb\n");
  1634 + goto fail;
  1635 + }
  1636 + /* flush cache after read */
  1637 + flush_cache((ulong)hdr->second_addr, hdr->second_size); /* FIXME */
  1638 + }
  1639 +#endif /*CONFIG_OF_LIBFDT*/
  1640 +
  1641 +#else /*! CONFIG_MMC*/
  1642 + return -1;
  1643 +#endif /*! CONFIG_MMC*/
  1644 + } else {
  1645 + unsigned kaddr, raddr, end;
  1646 +#ifdef CONFIG_OF_LIBFDT
  1647 + unsigned fdtaddr = 0;
  1648 +#endif
  1649 +
  1650 + /* set this aside somewhere safe */
  1651 + memcpy(hdr, (void *) addr, sizeof(*hdr));
  1652 +
  1653 + if (memcmp(hdr->magic, FASTBOOT_BOOT_MAGIC, 8)) {
  1654 + printf("booti: bad boot image magic\n");
  1655 + return 1;
  1656 + }
  1657 +
  1658 + bootimg_print_image_hdr(hdr);
  1659 +
  1660 + kaddr = addr + hdr->page_size;
  1661 + raddr = kaddr + ALIGN_SECTOR(hdr->kernel_size, hdr->page_size);
  1662 + end = raddr + hdr->ramdisk_size;
  1663 +#ifdef CONFIG_OF_LIBFDT
  1664 + if (hdr->second_size) {
  1665 + fdtaddr = raddr + ALIGN_SECTOR(hdr->ramdisk_size, hdr->page_size);
  1666 + end = fdtaddr + hdr->second_size;
  1667 + }
  1668 +#endif /*CONFIG_OF_LIBFDT*/
  1669 + if (kaddr != hdr->kernel_addr) {
  1670 + /*check overlap*/
  1671 + if (((hdr->kernel_addr >= addr) &&
  1672 + (hdr->kernel_addr <= end)) ||
  1673 + ((addr >= hdr->kernel_addr) &&
  1674 + (addr <= hdr->kernel_addr + hdr->kernel_size))) {
  1675 + printf("Fail: booti address overlap with kernel address\n");
  1676 + return 1;
  1677 + }
  1678 + memmove((void *) hdr->kernel_addr,
  1679 + (void *)kaddr, hdr->kernel_size);
  1680 + }
  1681 + if (raddr != hdr->ramdisk_addr) {
  1682 + /*check overlap*/
  1683 + if (((hdr->ramdisk_addr >= addr) &&
  1684 + (hdr->ramdisk_addr <= end)) ||
  1685 + ((addr >= hdr->ramdisk_addr) &&
  1686 + (addr <= hdr->ramdisk_addr + hdr->ramdisk_size))) {
  1687 + printf("Fail: booti address overlap with ramdisk address\n");
  1688 + return 1;
  1689 + }
  1690 + memmove((void *) hdr->ramdisk_addr,
  1691 + (void *)raddr, hdr->ramdisk_size);
  1692 + }
  1693 +
  1694 +#ifdef CONFIG_OF_LIBFDT
  1695 + if (hdr->second_size && fdtaddr != hdr->second_addr) {
  1696 + /*check overlap*/
  1697 + if (((hdr->second_addr >= addr) &&
  1698 + (hdr->second_addr <= end)) ||
  1699 + ((addr >= hdr->second_addr) &&
  1700 + (addr <= hdr->second_addr + hdr->second_size))) {
  1701 + printf("Fail: booti address overlap with FDT address\n");
  1702 + return 1;
  1703 + }
  1704 + memmove((void *) hdr->second_addr,
  1705 + (void *)fdtaddr, hdr->second_size);
  1706 + }
  1707 +#endif /*CONFIG_OF_LIBFDT*/
  1708 + }
  1709 +
  1710 + printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size);
  1711 + printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size);
  1712 +#ifdef CONFIG_OF_LIBFDT
  1713 + if (hdr->second_size)
  1714 + printf("fdt @ %08x (%d)\n", hdr->second_addr, hdr->second_size);
  1715 +#endif /*CONFIG_OF_LIBFDT*/
  1716 +
  1717 +#ifdef CONFIG_SECURE_BOOT
  1718 +#define IVT_SIZE 0x20
  1719 +#define CSF_PAD_SIZE 0x2000
  1720 + extern uint32_t authenticate_image(uint32_t ddr_start,
  1721 + uint32_t image_size);
  1722 +
  1723 + image_size = hdr->ramdisk_addr + hdr->ramdisk_size - hdr->kernel_addr -
  1724 + IVT_SIZE - CSF_PAD_SIZE;
  1725 +
  1726 + if (authenticate_image(hdr->kernel_addr, image_size)) {
  1727 + printf("Authenticate OK\n");
  1728 + } else {
  1729 + printf("Authenticate image Fail, Please check\n\n");
  1730 + return 1;
  1731 + }
  1732 +#endif /*CONFIG_SECURE_BOOT*/
  1733 +
  1734 +#ifdef CONFIG_CMDLINE_TAG
  1735 + char *commandline = getenv("bootargs");
  1736 +
  1737 + /* If no bootargs env, just use hdr command line */
  1738 + if (!commandline) {
  1739 + commandline = (char *)hdr->cmdline;
  1740 + setenv("bootargs", commandline);
  1741 + }
  1742 +
  1743 + /* XXX: in production, you should always use boot.img 's cmdline !!! */
  1744 + printf("kernel cmdline:\n");
  1745 + printf("\tuse boot.img ");
  1746 + printf("command line:\n\t%s\n", commandline);
  1747 +#endif /*CONFIG_CMDLINE_TAG*/
  1748 +
  1749 + memset(&images, 0, sizeof(images));
  1750 +
  1751 + /*Setup lmb for memory reserve*/
  1752 + boot_start_lmb(&images);
  1753 +
  1754 + images.ep = hdr->kernel_addr;
  1755 + images.rd_start = hdr->ramdisk_addr;
  1756 + images.rd_end = hdr->ramdisk_addr + hdr->ramdisk_size;
  1757 +
  1758 + /*Reserve memory for kernel image*/
  1759 + lmb_reserve(&images.lmb, images.ep, hdr->kernel_size);
  1760 +
  1761 +#ifdef CONFIG_OF_LIBFDT
  1762 + /*use secondary fields for fdt, second_size= fdt size, second_addr= fdt addr*/
  1763 + images.ft_addr = (char *)(hdr->second_addr);
  1764 + images.ft_len = (ulong)(hdr->second_size);
  1765 + set_working_fdt_addr(images.ft_addr);
  1766 +#endif /*CONFIG_OF_LIBFDT*/
  1767 +
  1768 + arch_preboot_os();
  1769 +
  1770 + do_bootm_linux(0, 0, NULL, &images);
  1771 +
  1772 + puts("booti: Control returned to monitor - resetting...\n");
  1773 + do_reset(cmdtp, flag, argc, argv);
  1774 + return 1;
  1775 +
  1776 +fail:
  1777 +#ifdef CONFIG_FASTBOOT
  1778 + return do_fastboot(NULL, 0, 0, NULL);
  1779 +#else /*! CONFIG_FASTBOOT*/
  1780 + return -1;
  1781 +#endif /*! CONFIG_FASTBOOT*/
  1782 +}
  1783 +
  1784 +U_BOOT_CMD(
  1785 + booti, 3, 1, do_booti,
  1786 + "booti - boot android bootimg from memory\n",
  1787 + "[<addr> | mmc0 | mmc1 | mmc2 | mmcX] [<partition>]\n "
  1788 + "- boot application image stored in memory or mmc\n"
  1789 + "\t'addr' should be the address of boot image "
  1790 + "which is zImage+ramdisk.img\n"
  1791 + "\t'mmcX' is the mmc device you store your boot.img, "
  1792 + "which will read the boot.img from 1M offset('/boot' partition)\n"
  1793 + "\t 'partition' (optional) is the partition id of your device, "
  1794 + "if no partition give, will going to 'boot' partition\n"
  1795 +);
  1796 +#endif /* CONFIG_CMD_BOOTI */
  1797 +
  1798 +#endif /* CONFIG_FASTBOOT */
... ... @@ -13,5 +13,6 @@
13 13 obj-y += twserial/
14 14 obj-y += video/
15 15 obj-y += watchdog/
  16 +obj-y += fastboot/
16 17 obj-$(CONFIG_QE) += qe/
drivers/fastboot/Makefile
  1 +#
  2 +# (C) Copyright 2000-2007
  3 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4 +#
  5 +# SPDX-License-Identifier: GPL-2.0+
  6 +#
  7 +
  8 +obj-$(CONFIG_FASTBOOT) += fastboot.o
drivers/fastboot/fastboot.c
Changes suppressed. Click to show
  1 +/*
  2 + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +
  7 +#include <common.h>
  8 +#include <config.h>
  9 +#include <malloc.h>
  10 +#include <fastboot.h>
  11 +#include <usb/imx_udc.h>
  12 +#include <asm/io.h>
  13 +#include <usbdevice.h>
  14 +#include <mmc.h>
  15 +#include <sata.h>
  16 +#ifdef CONFIG_ANDROID_RECOVERY
  17 +#include <recovery.h>
  18 +#endif
  19 +
  20 +/*
  21 + * Defines
  22 + */
  23 +#define NUM_ENDPOINTS 2
  24 +
  25 +#define CONFIG_USBD_OUT_PKTSIZE 0x200
  26 +#define CONFIG_USBD_IN_PKTSIZE 0x200
  27 +#define MAX_BUFFER_SIZE 0x200
  28 +
  29 +/*
  30 + * imx family android layout
  31 + * mbr - 0 ~ 0x3FF byte
  32 + * bootloader - 0x400 ~ 0xFFFFF byte
  33 + * kernel - 0x100000 ~ 5FFFFF byte
  34 + * uramedisk - 0x600000 ~ 0x6FFFFF supposing 1M temporarily
  35 + * SYSTEM partition - /dev/mmcblk0p2 or /dev/sda2
  36 + * RECOVERY parittion - dev/mmcblk0p4 or /dev/sda4
  37 + */
  38 +#define ANDROID_MBR_OFFSET 0
  39 +#define ANDROID_MBR_SIZE 0x200
  40 +#define ANDROID_BOOTLOADER_OFFSET 0x400
  41 +#define ANDROID_BOOTLOADER_SIZE 0xFFC00
  42 +#define ANDROID_KERNEL_OFFSET 0x100000
  43 +#define ANDROID_KERNEL_SIZE 0x500000
  44 +#define ANDROID_URAMDISK_OFFSET 0x600000
  45 +#define ANDROID_URAMDISK_SIZE 0x100000
  46 +
  47 +#define STR_LANG_INDEX 0x00
  48 +#define STR_MANUFACTURER_INDEX 0x01
  49 +#define STR_PRODUCT_INDEX 0x02
  50 +#define STR_SERIAL_INDEX 0x03
  51 +#define STR_CONFIG_INDEX 0x04
  52 +#define STR_DATA_INTERFACE_INDEX 0x05
  53 +#define STR_CTRL_INTERFACE_INDEX 0x06
  54 +#define STR_COUNT 0x07
  55 +
  56 +#define FASTBOOT_FBPARTS_ENV_MAX_LEN 1024
  57 +/* To support the Android-style naming of flash */
  58 +#define MAX_PTN 16
  59 +
  60 +
  61 +/*pentry index internally*/
  62 +enum {
  63 + PTN_MBR_INDEX = 0,
  64 + PTN_BOOTLOADER_INDEX,
  65 + PTN_KERNEL_INDEX,
  66 + PTN_URAMDISK_INDEX,
  67 + PTN_SYSTEM_INDEX,
  68 + PTN_RECOVERY_INDEX
  69 +};
  70 +
  71 +struct fastboot_device_info fastboot_devinfo;
  72 +
  73 +/* defined and used by gadget/ep0.c */
  74 +extern struct usb_string_descriptor **usb_strings;
  75 +
  76 +static struct usb_device_instance device_instance[1];
  77 +static struct usb_bus_instance bus_instance[1];
  78 +static struct usb_configuration_instance config_instance[1];
  79 +static struct usb_interface_instance interface_instance[1];
  80 +static struct usb_alternate_instance alternate_instance[1];
  81 +/* one extra for control endpoint */
  82 +static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1];
  83 +
  84 +static struct cmd_fastboot_interface *fastboot_interface;
  85 +static int fastboot_configured_flag;
  86 +static int usb_disconnected;
  87 +
  88 +/* Indicies, References */
  89 +static u8 rx_endpoint;
  90 +static u8 tx_endpoint;
  91 +static struct usb_string_descriptor *fastboot_string_table[STR_COUNT];
  92 +
  93 +/* USB Descriptor Strings */
  94 +static u8 wstrLang[4] = {4, USB_DT_STRING, 0x9, 0x4};
  95 +static u8 wstrManufacturer[2 * (sizeof(CONFIG_FASTBOOT_MANUFACTURER_STR))];
  96 +static u8 wstrProduct[2 * (sizeof(CONFIG_FASTBOOT_PRODUCT_NAME_STR))];
  97 +static u8 wstrSerial[2*(sizeof(CONFIG_FASTBOOT_SERIAL_NUM))];
  98 +static u8 wstrConfiguration[2 * (sizeof(CONFIG_FASTBOOT_CONFIGURATION_STR))];
  99 +static u8 wstrDataInterface[2 * (sizeof(CONFIG_FASTBOOT_INTERFACE_STR))];
  100 +
  101 +/* Standard USB Data Structures */
  102 +static struct usb_interface_descriptor interface_descriptors[1];
  103 +static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS];
  104 +static struct usb_configuration_descriptor *configuration_descriptor;
  105 +static struct usb_device_descriptor device_descriptor = {
  106 + .bLength = sizeof(struct usb_device_descriptor),
  107 + .bDescriptorType = USB_DT_DEVICE,
  108 + .bcdUSB = cpu_to_le16(USB_BCD_VERSION),
  109 + .bDeviceClass = 0xff,
  110 + .bDeviceSubClass = 0xff,
  111 + .bDeviceProtocol = 0xff,
  112 + .bMaxPacketSize0 = 0x40,
  113 + .idVendor = cpu_to_le16(CONFIG_FASTBOOT_VENDOR_ID),
  114 + .idProduct = cpu_to_le16(CONFIG_FASTBOOT_PRODUCT_ID),
  115 + .bcdDevice = cpu_to_le16(CONFIG_FASTBOOT_BCD_DEVICE),
  116 + .iManufacturer = STR_MANUFACTURER_INDEX,
  117 + .iProduct = STR_PRODUCT_INDEX,
  118 + .iSerialNumber = STR_SERIAL_INDEX,
  119 + .bNumConfigurations = 1
  120 +};
  121 +
  122 +/*
  123 + * Static Generic Serial specific data
  124 + */
  125 +
  126 +struct fastboot_config_desc {
  127 + struct usb_configuration_descriptor configuration_desc;
  128 + struct usb_interface_descriptor interface_desc[1];
  129 + struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS];
  130 +};
  131 +
  132 +static struct fastboot_config_desc
  133 +fastboot_configuration_descriptors[1] = {
  134 + {
  135 + .configuration_desc = {
  136 + .bLength = sizeof(struct usb_configuration_descriptor),
  137 + .bDescriptorType = USB_DT_CONFIG,
  138 + .wTotalLength =
  139 + cpu_to_le16(sizeof(struct fastboot_config_desc)),
  140 + .bNumInterfaces = 1,
  141 + .bConfigurationValue = 1,
  142 + .iConfiguration = STR_CONFIG_INDEX,
  143 + .bmAttributes =
  144 + BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
  145 + .bMaxPower = 0x32
  146 + },
  147 + .interface_desc = {
  148 + {
  149 + .bLength =
  150 + sizeof(struct usb_interface_descriptor),
  151 + .bDescriptorType = USB_DT_INTERFACE,
  152 + .bInterfaceNumber = 0,
  153 + .bAlternateSetting = 0,
  154 + .bNumEndpoints = NUM_ENDPOINTS,
  155 + .bInterfaceClass =
  156 + FASTBOOT_INTERFACE_CLASS,
  157 + .bInterfaceSubClass =
  158 + FASTBOOT_INTERFACE_SUB_CLASS,
  159 + .bInterfaceProtocol =
  160 + FASTBOOT_INTERFACE_PROTOCOL,
  161 + .iInterface = STR_DATA_INTERFACE_INDEX
  162 + },
  163 + },
  164 + .data_endpoints = {
  165 + {
  166 + .bLength =
  167 + sizeof(struct usb_endpoint_descriptor),
  168 + .bDescriptorType = USB_DT_ENDPOINT,
  169 + .bEndpointAddress = UDC_OUT_ENDPOINT |
  170 + USB_DIR_OUT,
  171 + .bmAttributes = USB_ENDPOINT_XFER_BULK,
  172 + .wMaxPacketSize =
  173 + cpu_to_le16(CONFIG_USBD_OUT_PKTSIZE),
  174 + .bInterval = 0x00,
  175 + },
  176 + {
  177 + .bLength =
  178 + sizeof(struct usb_endpoint_descriptor),
  179 + .bDescriptorType = USB_DT_ENDPOINT,
  180 + .bEndpointAddress = UDC_IN_ENDPOINT |
  181 + USB_DIR_IN,
  182 + .bmAttributes = USB_ENDPOINT_XFER_BULK,
  183 + .wMaxPacketSize =
  184 + cpu_to_le16(CONFIG_USBD_IN_PKTSIZE),
  185 + .bInterval = 0x00,
  186 + },
  187 + },
  188 + },
  189 +};
  190 +
  191 +
  192 +
  193 +static struct fastboot_ptentry ptable[MAX_PTN];
  194 +static unsigned int pcount;
  195 +
  196 +
  197 +/* Static Function Prototypes */
  198 +static void _fastboot_init_strings(void);
  199 +static void _fastboot_init_instances(void);
  200 +static void _fastboot_init_endpoints(void);
  201 +static void _fastboot_event_handler(struct usb_device_instance *device,
  202 + usb_device_event_t event, int data);
  203 +static int _fastboot_cdc_setup(struct usb_device_request *request,
  204 + struct urb *urb);
  205 +static int _fastboot_usb_configured(void);
  206 +#if defined(CONFIG_FASTBOOT_STORAGE_SATA) \
  207 + || defined(CONFIG_FASTBOOT_STORAGE_MMC)
  208 +static int _fastboot_parts_load_from_ptable(void);
  209 +#endif
  210 +#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  211 +static int _fastboot_parts_load_from_env(void);
  212 +#endif
  213 +static int _fastboot_setup_dev(void);
  214 +static void _fastboot_load_partitions(void);
  215 +
  216 +/* utility function for converting char* to wide string used by USB */
  217 +static void str2wide(char *str, u16 * wide)
  218 +{
  219 + int i;
  220 + for (i = 0; i < strlen(str) && str[i]; i++) {
  221 + #if defined(__LITTLE_ENDIAN)
  222 + wide[i] = (u16) str[i];
  223 + #elif defined(__BIG_ENDIAN)
  224 + wide[i] = ((u16)(str[i])<<8);
  225 + #else
  226 + #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined"
  227 + #endif
  228 + }
  229 +}
  230 +
  231 +/*
  232 + Get mmc control number from passed string, eg, "mmc1" mean device 1. Only
  233 + support "mmc0" to "mmc9" currently. It will be treated as device 0 for
  234 + other string.
  235 +*/
  236 +static int _fastboot_get_mmc_no(char *env_str)
  237 +{
  238 + int digit = 0;
  239 + unsigned char a;
  240 +
  241 + if (env_str && (strlen(env_str) >= 4) &&
  242 + !strncmp(env_str, "mmc", 3)) {
  243 + a = env_str[3];
  244 + if (a >= '0' && a <= '9')
  245 + digit = a - '0';
  246 + }
  247 +
  248 + return digit;
  249 +}
  250 +
  251 +static int _fastboot_setup_dev(void)
  252 +{
  253 + char *fastboot_env;
  254 + fastboot_env = getenv("fastboot_dev");
  255 +
  256 + if (fastboot_env) {
  257 + if (!strcmp(fastboot_env, "sata")) {
  258 + fastboot_devinfo.type = DEV_SATA;
  259 + fastboot_devinfo.dev_id = 0;
  260 + } else if (!strcmp(fastboot_env, "nand")) {
  261 + fastboot_devinfo.type = DEV_NAND;
  262 + fastboot_devinfo.dev_id = 0;
  263 + } else if (!strncmp(fastboot_env, "mmc", 3)) {
  264 + fastboot_devinfo.type = DEV_MMC;
  265 + fastboot_devinfo.dev_id = _fastboot_get_mmc_no(fastboot_env);
  266 + }
  267 + } else {
  268 + return 1;
  269 + }
  270 +
  271 + return 0;
  272 +}
  273 +
  274 +
  275 +/*
  276 + * Initialize fastboot
  277 + */
  278 +int fastboot_init(struct cmd_fastboot_interface *interface)
  279 +{
  280 + printf("fastboot is in init......");
  281 +
  282 + fastboot_interface = interface;
  283 + fastboot_interface->product_name = CONFIG_FASTBOOT_PRODUCT_NAME_STR;
  284 + fastboot_interface->serial_no = CONFIG_FASTBOOT_SERIAL_NUM;
  285 + fastboot_interface->nand_block_size = 4096;
  286 + fastboot_interface->transfer_buffer =
  287 + (unsigned char *)CONFIG_FASTBOOT_TRANSFER_BUF;
  288 + fastboot_interface->transfer_buffer_size =
  289 + CONFIG_FASTBOOT_TRANSFER_BUF_SIZE;
  290 +
  291 + _fastboot_init_strings();
  292 + /* Basic USB initialization */
  293 + udc_init();
  294 +
  295 + _fastboot_init_instances();
  296 +
  297 + udc_startup_events(device_instance);
  298 + udc_connect(); /* Enable pullup for host detection */
  299 +
  300 + return 0;
  301 +}
  302 +
  303 +static void _fastboot_init_strings(void)
  304 +{
  305 + struct usb_string_descriptor *string;
  306 +
  307 + fastboot_string_table[STR_LANG_INDEX] =
  308 + (struct usb_string_descriptor *)wstrLang;
  309 +
  310 + string = (struct usb_string_descriptor *)wstrManufacturer;
  311 + string->bLength = sizeof(wstrManufacturer);
  312 + string->bDescriptorType = USB_DT_STRING;
  313 + str2wide(CONFIG_FASTBOOT_MANUFACTURER_STR, string->wData);
  314 + fastboot_string_table[STR_MANUFACTURER_INDEX] = string;
  315 +
  316 + string = (struct usb_string_descriptor *)wstrProduct;
  317 + string->bLength = sizeof(wstrProduct);
  318 + string->bDescriptorType = USB_DT_STRING;
  319 + str2wide(CONFIG_FASTBOOT_PRODUCT_NAME_STR, string->wData);
  320 + fastboot_string_table[STR_PRODUCT_INDEX] = string;
  321 +
  322 + string = (struct usb_string_descriptor *)wstrSerial;
  323 + string->bLength = sizeof(wstrSerial);
  324 + string->bDescriptorType = USB_DT_STRING;
  325 + str2wide(CONFIG_FASTBOOT_SERIAL_NUM, string->wData);
  326 + fastboot_string_table[STR_SERIAL_INDEX] = string;
  327 +
  328 + string = (struct usb_string_descriptor *)wstrConfiguration;
  329 + string->bLength = sizeof(wstrConfiguration);
  330 + string->bDescriptorType = USB_DT_STRING;
  331 + str2wide(CONFIG_FASTBOOT_CONFIGURATION_STR, string->wData);
  332 + fastboot_string_table[STR_CONFIG_INDEX] = string;
  333 +
  334 + string = (struct usb_string_descriptor *) wstrDataInterface;
  335 + string->bLength = sizeof(wstrDataInterface);
  336 + string->bDescriptorType = USB_DT_STRING;
  337 + str2wide(CONFIG_FASTBOOT_INTERFACE_STR, string->wData);
  338 + fastboot_string_table[STR_DATA_INTERFACE_INDEX] = string;
  339 +
  340 + /* Now, initialize the string table for ep0 handling */
  341 + usb_strings = fastboot_string_table;
  342 +}
  343 +
  344 +static void _fastboot_init_instances(void)
  345 +{
  346 + int i;
  347 + u16 temp;
  348 +
  349 + /* Assign endpoint descriptors */
  350 + ep_descriptor_ptrs[0] =
  351 + &fastboot_configuration_descriptors[0].data_endpoints[0];
  352 + ep_descriptor_ptrs[1] =
  353 + &fastboot_configuration_descriptors[0].data_endpoints[1];
  354 +
  355 + /* Configuration Descriptor */
  356 + configuration_descriptor =
  357 + (struct usb_configuration_descriptor *)
  358 + &fastboot_configuration_descriptors;
  359 +
  360 + fastboot_configured_flag = 0;
  361 +
  362 + /* initialize device instance */
  363 + memset(device_instance, 0, sizeof(struct usb_device_instance));
  364 + device_instance->device_state = STATE_INIT;
  365 + device_instance->device_descriptor = &device_descriptor;
  366 + device_instance->event = _fastboot_event_handler;
  367 + device_instance->cdc_recv_setup = _fastboot_cdc_setup;
  368 + device_instance->bus = bus_instance;
  369 + device_instance->configurations = 1;
  370 + device_instance->configuration_instance_array = config_instance;
  371 +
  372 + /* initialize bus instance */
  373 + memset(bus_instance, 0, sizeof(struct usb_bus_instance));
  374 + bus_instance->device = device_instance;
  375 + bus_instance->endpoint_array = endpoint_instance;
  376 + bus_instance->max_endpoints = NUM_ENDPOINTS + 1;
  377 + bus_instance->maxpacketsize = 0xFF;
  378 + bus_instance->serial_number_str = CONFIG_FASTBOOT_SERIAL_NUM;
  379 +
  380 + /* configuration instance */
  381 + memset(config_instance, 0,
  382 + sizeof(struct usb_configuration_instance));
  383 + config_instance->interfaces = 1;
  384 + config_instance->configuration_descriptor = configuration_descriptor;
  385 + config_instance->interface_instance_array = interface_instance;
  386 +
  387 + /* interface instance */
  388 + memset(interface_instance, 0,
  389 + sizeof(struct usb_interface_instance));
  390 + interface_instance->alternates = 1;
  391 + interface_instance->alternates_instance_array = alternate_instance;
  392 +
  393 + /* alternates instance */
  394 + memset(alternate_instance, 0,
  395 + sizeof(struct usb_alternate_instance));
  396 + alternate_instance->interface_descriptor = interface_descriptors;
  397 + alternate_instance->endpoints = NUM_ENDPOINTS;
  398 + alternate_instance->endpoints_descriptor_array = ep_descriptor_ptrs;
  399 +
  400 + /* endpoint instances */
  401 + memset(&endpoint_instance[0], 0,
  402 + sizeof(struct usb_endpoint_instance));
  403 + endpoint_instance[0].endpoint_address = 0;
  404 + endpoint_instance[0].rcv_packetSize = EP0_MAX_PACKET_SIZE;
  405 + endpoint_instance[0].rcv_attributes = USB_ENDPOINT_XFER_CONTROL;
  406 + endpoint_instance[0].tx_packetSize = EP0_MAX_PACKET_SIZE;
  407 + endpoint_instance[0].tx_attributes = USB_ENDPOINT_XFER_CONTROL;
  408 + udc_setup_ep(device_instance, 0, &endpoint_instance[0]);
  409 +
  410 + for (i = 1; i <= NUM_ENDPOINTS; i++) {
  411 + memset(&endpoint_instance[i], 0,
  412 + sizeof(struct usb_endpoint_instance));
  413 +
  414 + endpoint_instance[i].endpoint_address =
  415 + ep_descriptor_ptrs[i - 1]->bEndpointAddress;
  416 +
  417 + endpoint_instance[i].rcv_attributes =
  418 + ep_descriptor_ptrs[i - 1]->bmAttributes;
  419 +
  420 + /*fix the abort caused by unalignment*/
  421 + temp = *(u8 *)&ep_descriptor_ptrs[i - 1]->wMaxPacketSize;
  422 + temp |=
  423 + (*(((u8 *)&ep_descriptor_ptrs[i - 1]->wMaxPacketSize) + 1) << 8);
  424 +
  425 + endpoint_instance[i].rcv_packetSize =
  426 + le16_to_cpu(temp);
  427 +
  428 + endpoint_instance[i].tx_attributes =
  429 + ep_descriptor_ptrs[i - 1]->bmAttributes;
  430 +
  431 + endpoint_instance[i].tx_packetSize =
  432 + le16_to_cpu(temp);
  433 +
  434 + endpoint_instance[i].tx_attributes =
  435 + ep_descriptor_ptrs[i - 1]->bmAttributes;
  436 +
  437 + urb_link_init(&endpoint_instance[i].rcv);
  438 + urb_link_init(&endpoint_instance[i].rdy);
  439 + urb_link_init(&endpoint_instance[i].tx);
  440 + urb_link_init(&endpoint_instance[i].done);
  441 +
  442 + if (endpoint_instance[i].endpoint_address & USB_DIR_IN) {
  443 + tx_endpoint = i;
  444 + endpoint_instance[i].tx_urb =
  445 + usbd_alloc_urb(device_instance,
  446 + &endpoint_instance[i]);
  447 + } else {
  448 + rx_endpoint = i;
  449 + endpoint_instance[i].rcv_urb =
  450 + usbd_alloc_urb(device_instance,
  451 + &endpoint_instance[i]);
  452 + }
  453 + }
  454 +}
  455 +
  456 +static void _fastboot_init_endpoints(void)
  457 +{
  458 + int i;
  459 +
  460 + bus_instance->max_endpoints = NUM_ENDPOINTS + 1;
  461 + for (i = 1; i <= NUM_ENDPOINTS; i++)
  462 + udc_setup_ep(device_instance, i, &endpoint_instance[i]);
  463 +}
  464 +
  465 +static void _fastboot_destroy_endpoints(void)
  466 +{
  467 + int i;
  468 + struct urb *tx_urb;
  469 +
  470 + for (i = 1; i <= NUM_ENDPOINTS; i++) {
  471 + /*dealloc urb*/
  472 + if (endpoint_instance[i].endpoint_address & USB_DIR_IN) {
  473 + if (endpoint_instance[i].tx_urb)
  474 + usbd_dealloc_urb(endpoint_instance[i].tx_urb);
  475 +
  476 + while (endpoint_instance[i].tx_queue) {
  477 + tx_urb = first_urb_detached(&endpoint_instance[i].tx);
  478 + if (tx_urb) {
  479 + usbd_dealloc_urb(tx_urb);
  480 + endpoint_instance[i].tx_queue--;
  481 + } else {
  482 + break;
  483 + }
  484 + }
  485 + endpoint_instance[i].tx_queue = 0;
  486 +
  487 + do {
  488 + tx_urb = first_urb_detached(&endpoint_instance[i].done);
  489 + if (tx_urb)
  490 + usbd_dealloc_urb(tx_urb);
  491 + } while (tx_urb);
  492 +
  493 + } else {
  494 + if (endpoint_instance[i].rcv_urb)
  495 + usbd_dealloc_urb(endpoint_instance[i].rcv_urb);
  496 + }
  497 +
  498 + udc_destroy_ep(device_instance, &endpoint_instance[i]);
  499 + }
  500 +}
  501 +
  502 +
  503 +static int _fill_buffer(u8 *buf)
  504 +{
  505 + struct usb_endpoint_instance *endpoint =
  506 + &endpoint_instance[rx_endpoint];
  507 +
  508 + if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) {
  509 + unsigned int nb = 0;
  510 + char *src = (char *)endpoint->rcv_urb->buffer;
  511 + unsigned int rx_avail = MAX_BUFFER_SIZE;
  512 +
  513 + if (rx_avail >= endpoint->rcv_urb->actual_length) {
  514 + nb = endpoint->rcv_urb->actual_length;
  515 + memcpy(buf, src, nb);
  516 + endpoint->rcv_urb->actual_length = 0;
  517 + }
  518 + return nb;
  519 + }
  520 + return 0;
  521 +}
  522 +
  523 +static struct urb *_next_urb(struct usb_device_instance *device,
  524 + struct usb_endpoint_instance *endpoint)
  525 +{
  526 + struct urb *current_urb = NULL;
  527 + int space;
  528 +
  529 + /* If there's a queue, then we should add to the last urb */
  530 + if (!endpoint->tx_queue)
  531 + current_urb = endpoint->tx_urb;
  532 + else
  533 + /* Last urb from tx chain */
  534 + current_urb =
  535 + p2surround(struct urb, link, endpoint->tx.prev);
  536 +
  537 + /* Make sure this one has enough room */
  538 + space = current_urb->buffer_length - current_urb->actual_length;
  539 + if (space > 0)
  540 + return current_urb;
  541 + else { /* No space here */
  542 + /* First look at done list */
  543 + current_urb = first_urb_detached(&endpoint->done);
  544 + if (!current_urb)
  545 + current_urb = usbd_alloc_urb(device, endpoint);
  546 +
  547 + urb_append(&endpoint->tx, current_urb);
  548 + endpoint->tx_queue++;
  549 + }
  550 + return current_urb;
  551 +}
  552 +
  553 +static int _fastboot_usb_configured(void)
  554 +{
  555 + return fastboot_configured_flag;
  556 +}
  557 +
  558 +static void _fastboot_event_handler(struct usb_device_instance *device,
  559 + usb_device_event_t event, int data)
  560 +{
  561 + switch (event) {
  562 + case DEVICE_RESET:
  563 + case DEVICE_BUS_INACTIVE:
  564 + fastboot_configured_flag = 0;
  565 + break;
  566 + case DEVICE_CONFIGURED:
  567 + fastboot_configured_flag = 1;
  568 + _fastboot_init_endpoints();
  569 + break;
  570 + case DEVICE_ADDRESS_ASSIGNED:
  571 + default:
  572 + break;
  573 + }
  574 +}
  575 +
  576 +static int _fastboot_cdc_setup(struct usb_device_request *request,
  577 + struct urb *urb)
  578 +{
  579 + return 0;
  580 +}
  581 +
  582 +
  583 +/*!
  584 + * Function to receive data from host through channel
  585 + *
  586 + * @buf buffer to fill in
  587 + * @count read data size
  588 + *
  589 + * @return 0
  590 + */
  591 +int fastboot_usb_recv(u8 *buf, int count)
  592 +{
  593 + int len = 0;
  594 +
  595 + while (!_fastboot_usb_configured())
  596 + udc_irq();
  597 +
  598 + /* update rxqueue to wait new data */
  599 + mxc_udc_rxqueue_update(2, count);
  600 +
  601 + while (!len) {
  602 + if (is_usb_disconnected()) {
  603 + /*it will not unconfigure when disconnect
  604 + from host, so here needs manual unconfigure
  605 + anyway, it's just a workaround*/
  606 + fastboot_configured_flag = 0;
  607 + usb_disconnected = 1;
  608 + return 0;
  609 + }
  610 + udc_irq();
  611 + if (_fastboot_usb_configured())
  612 + len = _fill_buffer(buf);
  613 + }
  614 + return len;
  615 +}
  616 +
  617 +int fastboot_getvar(const char *rx_buffer, char *tx_buffer)
  618 +{
  619 + /* Place board specific variables here */
  620 + return 0;
  621 +}
  622 +
  623 +int fastboot_poll()
  624 +{
  625 + u8 buffer[MAX_BUFFER_SIZE];
  626 + int length = 0;
  627 +
  628 + memset(buffer, 0, MAX_BUFFER_SIZE);
  629 +
  630 + length = fastboot_usb_recv(buffer, MAX_BUFFER_SIZE);
  631 +
  632 + /* If usb disconnected, blocked here to wait */
  633 + if (usb_disconnected) {
  634 + udc_disconnect();
  635 + udc_connect();
  636 + /*the udc_connect will be blocked until connect to host
  637 + so, the usb_disconnect should be 0 after udc_connect,
  638 + and should be set manually. Anyway, it's just a workaround*/
  639 + usb_disconnected = 0;
  640 + }
  641 +
  642 + if (!length)
  643 + return FASTBOOT_INACTIVE;
  644 +
  645 + /* Pass this up to the interface's handler */
  646 + if (fastboot_interface && fastboot_interface->rx_handler) {
  647 + if (!fastboot_interface->rx_handler(buffer, length))
  648 + return FASTBOOT_OK;
  649 + }
  650 + return FASTBOOT_OK;
  651 +}
  652 +
  653 +int fastboot_tx(unsigned char *buffer, unsigned int buffer_size)
  654 +{
  655 + /* Not realized yet */
  656 + return 0;
  657 +}
  658 +
  659 +static int _fastboot_write_buffer(const char *buffer,
  660 + unsigned int buffer_size)
  661 +{
  662 + struct usb_endpoint_instance *endpoint =
  663 + (struct usb_endpoint_instance *)&endpoint_instance[tx_endpoint];
  664 + struct urb *current_urb = NULL;
  665 +
  666 + if (!_fastboot_usb_configured())
  667 + return 0;
  668 +
  669 + current_urb = _next_urb(device_instance, endpoint);
  670 + if (buffer_size) {
  671 + char *dest;
  672 + int space_avail, popnum, count, total = 0;
  673 +
  674 + /* Break buffer into urb sized pieces,
  675 + * and link each to the endpoint
  676 + */
  677 + count = buffer_size;
  678 + while (count > 0) {
  679 + if (!current_urb) {
  680 + printf("current_urb is NULL, buffer_size %d\n",
  681 + buffer_size);
  682 + return total;
  683 + }
  684 +
  685 + dest = (char *)current_urb->buffer +
  686 + current_urb->actual_length;
  687 +
  688 + space_avail = current_urb->buffer_length -
  689 + current_urb->actual_length;
  690 + popnum = MIN(space_avail, count);
  691 + if (popnum == 0)
  692 + break;
  693 +
  694 + memcpy(dest, buffer + total, popnum);
  695 + printf("send: %s\n", (char *)buffer);
  696 +
  697 + current_urb->actual_length += popnum;
  698 + total += popnum;
  699 +
  700 + if (udc_endpoint_write(endpoint))
  701 + /* Write pre-empted by RX */
  702 + return 0;
  703 + count -= popnum;
  704 + } /* end while */
  705 + return total;
  706 + }
  707 + return 0;
  708 +}
  709 +
  710 +int fastboot_tx_status(const char *buffer, unsigned int buffer_size)
  711 +{
  712 + int len = 0;
  713 +
  714 + while (buffer_size > 0) {
  715 + len = _fastboot_write_buffer(buffer + len, buffer_size);
  716 + buffer_size -= len;
  717 +
  718 + udc_irq();
  719 + }
  720 + udc_irq();
  721 +
  722 + return 0;
  723 +}
  724 +
  725 +void fastboot_shutdown(void)
  726 +{
  727 + usb_shutdown();
  728 +
  729 + /* Reset interface*/
  730 + if (fastboot_interface &&
  731 + fastboot_interface->reset_handler) {
  732 + fastboot_interface->reset_handler();
  733 + }
  734 +
  735 + /* Reset some globals */
  736 + _fastboot_destroy_endpoints();
  737 + fastboot_interface = NULL;
  738 + fastboot_configured_flag = 0;
  739 + usb_disconnected = 0;
  740 +
  741 + /*free memory*/
  742 + udc_destroy();
  743 +}
  744 +
  745 +/*
  746 + * CPU and board-specific fastboot initializations. Aliased function
  747 + * signals caller to move on
  748 + */
  749 +static void __def_fastboot_setup(void)
  750 +{
  751 + /*do nothing here*/
  752 +}
  753 +void board_fastboot_setup(void) \
  754 + __attribute__((weak, alias("__def_fastboot_setup")));
  755 +
  756 +
  757 +void fastboot_setup(void)
  758 +{
  759 + /*execute board relevant initilizations for preparing fastboot */
  760 + board_fastboot_setup();
  761 +
  762 + /*get the fastboot dev*/
  763 + _fastboot_setup_dev();
  764 +
  765 + /*check if we need to setup recovery*/
  766 +#ifdef CONFIG_ANDROID_RECOVERY
  767 + check_recovery_mode();
  768 +#endif
  769 +
  770 + /*load partitions information for the fastboot dev*/
  771 + _fastboot_load_partitions();
  772 +}
  773 +
  774 +/* export to lib_arm/board.c */
  775 +void check_fastboot(void)
  776 +{
  777 + if (fastboot_check_and_clean_flag())
  778 + do_fastboot(NULL, 0, 0, 0);
  779 +}
  780 +
  781 +#if defined(CONFIG_FASTBOOT_STORAGE_SATA) \
  782 + || defined(CONFIG_FASTBOOT_STORAGE_MMC)
  783 +/**
  784 + @mmc_dos_partition_index: the partition index in mbr.
  785 + @mmc_partition_index: the boot partition or user partition index,
  786 + not related to the partition table.
  787 + */
  788 +static int _fastboot_parts_add_ptable_entry(int ptable_index,
  789 + int mmc_dos_partition_index,
  790 + int mmc_partition_index,
  791 + const char *name,
  792 + block_dev_desc_t *dev_desc,
  793 + struct fastboot_ptentry *ptable)
  794 +{
  795 + disk_partition_t info;
  796 + strcpy(ptable[ptable_index].name, name);
  797 +
  798 + if (get_partition_info(dev_desc,
  799 + mmc_dos_partition_index, &info)) {
  800 + printf("Bad partition index:%d for partition:%s\n",
  801 + mmc_dos_partition_index, name);
  802 + return -1;
  803 + } else {
  804 + ptable[ptable_index].start = info.start;
  805 + ptable[ptable_index].length = info.size;
  806 + ptable[ptable_index].partition_id = mmc_partition_index;
  807 + }
  808 + return 0;
  809 +}
  810 +
  811 +static int _fastboot_parts_load_from_ptable(void)
  812 +{
  813 + int i;
  814 +#ifdef CONFIG_CMD_SATA
  815 + int sata_device_no;
  816 +#endif
  817 +
  818 + /* mmc boot partition: -1 means no partition, 0 user part., 1 boot part.
  819 + * default is no partition, for emmc default user part, except emmc*/
  820 + int boot_partition = FASTBOOT_MMC_NONE_PARTITION_ID;
  821 + int user_partition = FASTBOOT_MMC_NONE_PARTITION_ID;
  822 +
  823 + struct mmc *mmc;
  824 + block_dev_desc_t *dev_desc;
  825 + struct fastboot_ptentry ptable[PTN_RECOVERY_INDEX + 1];
  826 +
  827 + /* sata case in env */
  828 + if (fastboot_devinfo.type == DEV_SATA) {
  829 +#ifdef CONFIG_CMD_SATA
  830 + puts("flash target is SATA\n");
  831 + if (sata_initialize())
  832 + return -1;
  833 + sata_device_no = CONFIG_FASTBOOT_SATA_NO;
  834 + if (sata_device_no >= CONFIG_SYS_SATA_MAX_DEVICE) {
  835 + printf("Unknown SATA(%d) device for fastboot\n",
  836 + sata_device_no);
  837 + return -1;
  838 + }
  839 + dev_desc = sata_get_dev(sata_device_no);
  840 +#else /*! CONFIG_CMD_SATA*/
  841 + puts("SATA isn't buildin\n");
  842 + return -1;
  843 +#endif /*! CONFIG_CMD_SATA*/
  844 + } else if (fastboot_devinfo.type == DEV_MMC) {
  845 + int mmc_no = 0;
  846 + mmc_no = fastboot_devinfo.dev_id;
  847 +
  848 + printf("flash target is MMC:%d\n", mmc_no);
  849 + mmc = find_mmc_device(mmc_no);
  850 + if (mmc && mmc_init(mmc))
  851 + printf("MMC card init failed!\n");
  852 +
  853 + dev_desc = get_dev("mmc", mmc_no);
  854 + if (NULL == dev_desc) {
  855 + printf("** Block device MMC %d not supported\n",
  856 + mmc_no);
  857 + return -1;
  858 + }
  859 +
  860 + /* multiple boot paritions for eMMC 4.3 later */
  861 + if (mmc->part_config != MMCPART_NOAVAILABLE) {
  862 + boot_partition = FASTBOOT_MMC_BOOT_PARTITION_ID;
  863 + user_partition = FASTBOOT_MMC_USER_PARTITION_ID;
  864 + }
  865 + } else {
  866 + printf("Can't setup partition table on this device %d\n",
  867 + fastboot_devinfo.type);
  868 + return -1;
  869 + }
  870 +
  871 + memset((char *)ptable, 0,
  872 + sizeof(struct fastboot_ptentry) * (PTN_RECOVERY_INDEX + 1));
  873 + /* MBR */
  874 + strcpy(ptable[PTN_MBR_INDEX].name, "mbr");
  875 + ptable[PTN_MBR_INDEX].start = ANDROID_MBR_OFFSET / dev_desc->blksz;
  876 + ptable[PTN_MBR_INDEX].length = ANDROID_MBR_SIZE / dev_desc->blksz;
  877 + ptable[PTN_MBR_INDEX].partition_id = user_partition;
  878 + /* Bootloader */
  879 + strcpy(ptable[PTN_BOOTLOADER_INDEX].name, "bootloader");
  880 + ptable[PTN_BOOTLOADER_INDEX].start =
  881 + ANDROID_BOOTLOADER_OFFSET / dev_desc->blksz;
  882 + ptable[PTN_BOOTLOADER_INDEX].length =
  883 + ANDROID_BOOTLOADER_SIZE / dev_desc->blksz;
  884 + ptable[PTN_BOOTLOADER_INDEX].partition_id = boot_partition;
  885 +
  886 + _fastboot_parts_add_ptable_entry(PTN_KERNEL_INDEX,
  887 + CONFIG_ANDROID_BOOT_PARTITION_MMC,
  888 + user_partition, "boot", dev_desc, ptable);
  889 + _fastboot_parts_add_ptable_entry(PTN_RECOVERY_INDEX,
  890 + CONFIG_ANDROID_RECOVERY_PARTITION_MMC,
  891 + user_partition,
  892 + "recovery", dev_desc, ptable);
  893 + _fastboot_parts_add_ptable_entry(PTN_SYSTEM_INDEX,
  894 + CONFIG_ANDROID_SYSTEM_PARTITION_MMC,
  895 + user_partition,
  896 + "system", dev_desc, ptable);
  897 +
  898 + for (i = 0; i <= PTN_RECOVERY_INDEX; i++)
  899 + fastboot_flash_add_ptn(&ptable[i]);
  900 +
  901 + return 0;
  902 +}
  903 +#endif /*CONFIG_FASTBOOT_STORAGE_SATA || CONFIG_FASTBOOT_STORAGE_MMC*/
  904 +
  905 +#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  906 +static unsigned long long _memparse(char *ptr, char **retptr)
  907 +{
  908 + char *endptr; /* local pointer to end of parsed string */
  909 +
  910 + unsigned long ret = simple_strtoul(ptr, &endptr, 0);
  911 +
  912 + switch (*endptr) {
  913 + case 'M':
  914 + case 'm':
  915 + ret <<= 10;
  916 + case 'K':
  917 + case 'k':
  918 + ret <<= 10;
  919 + endptr++;
  920 + default:
  921 + break;
  922 + }
  923 +
  924 + if (retptr)
  925 + *retptr = endptr;
  926 +
  927 + return ret;
  928 +}
  929 +
  930 +static int _fastboot_parts_add_env_entry(char *s, char **retptr)
  931 +{
  932 + unsigned long size;
  933 + unsigned long offset = 0;
  934 + char *name;
  935 + int name_len;
  936 + int delim;
  937 + unsigned int flags;
  938 + struct fastboot_ptentry part;
  939 +
  940 + size = _memparse(s, &s);
  941 + if (0 == size) {
  942 + printf("Error:FASTBOOT size of parition is 0\n");
  943 + return 1;
  944 + }
  945 +
  946 + /* fetch partition name and flags */
  947 + flags = 0; /* this is going to be a regular partition */
  948 + delim = 0;
  949 + /* check for offset */
  950 + if (*s == '@') {
  951 + s++;
  952 + offset = _memparse(s, &s);
  953 + } else {
  954 + printf("Error:FASTBOOT offset of parition is not given\n");
  955 + return 1;
  956 + }
  957 +
  958 + /* now look for name */
  959 + if (*s == '(')
  960 + delim = ')';
  961 +
  962 + if (delim) {
  963 + char *p;
  964 +
  965 + name = ++s;
  966 + p = strchr((const char *)name, delim);
  967 + if (!p) {
  968 + printf("Error:FASTBOOT no closing %c found in partition name\n",
  969 + delim);
  970 + return 1;
  971 + }
  972 + name_len = p - name;
  973 + s = p + 1;
  974 + } else {
  975 + printf("Error:FASTBOOT no partition name for \'%s\'\n", s);
  976 + return 1;
  977 + }
  978 +
  979 + /* check for options */
  980 + while (1) {
  981 + if (strncmp(s, "i", 1) == 0) {
  982 + flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_I;
  983 + s += 1;
  984 + } else if (strncmp(s, "ubifs", 5) == 0) {
  985 + /* ubifs */
  986 + flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_TRIMFFS;
  987 + s += 5;
  988 + } else {
  989 + break;
  990 + }
  991 + if (strncmp(s, "|", 1) == 0)
  992 + s += 1;
  993 + }
  994 +
  995 + /* enter this partition (offset will be calculated later if it is zero at this point) */
  996 + part.length = size;
  997 + part.start = offset;
  998 + part.flags = flags;
  999 +
  1000 + if (name) {
  1001 + if (name_len >= sizeof(part.name)) {
  1002 + printf("Error:FASTBOOT partition name is too long\n");
  1003 + return 1;
  1004 + }
  1005 + strncpy(&part.name[0], name, name_len);
  1006 + /* name is not null terminated */
  1007 + part.name[name_len] = '\0';
  1008 + } else {
  1009 + printf("Error:FASTBOOT no name\n");
  1010 + return 1;
  1011 + }
  1012 +
  1013 + fastboot_flash_add_ptn(&part);
  1014 +
  1015 + /*if the nand partitions envs are not initialized, try to init them*/
  1016 + if (check_parts_values(&part))
  1017 + save_parts_values(&part, part.start, part.length);
  1018 +
  1019 + /* return (updated) pointer command line string */
  1020 + *retptr = s;
  1021 +
  1022 + /* return partition table */
  1023 + return 0;
  1024 +}
  1025 +
  1026 +static int _fastboot_parts_load_from_env(void)
  1027 +{
  1028 + char fbparts[FASTBOOT_FBPARTS_ENV_MAX_LEN], *env;
  1029 +
  1030 + env = getenv("fbparts");
  1031 + if (env) {
  1032 + unsigned int len;
  1033 + len = strlen(env);
  1034 + if (len && len < FASTBOOT_FBPARTS_ENV_MAX_LEN) {
  1035 + char *s, *e;
  1036 +
  1037 + memcpy(&fbparts[0], env, len + 1);
  1038 + printf("Fastboot: Adding partitions from environment\n");
  1039 + s = &fbparts[0];
  1040 + e = s + len;
  1041 + while (s < e) {
  1042 + if (_fastboot_parts_add_env_entry(s, &s)) {
  1043 + printf("Error:Fastboot: Abort adding partitions\n");
  1044 + pcount = 0;
  1045 + return 1;
  1046 + }
  1047 + /* Skip a bunch of delimiters */
  1048 + while (s < e) {
  1049 + if ((' ' == *s) ||
  1050 + ('\t' == *s) ||
  1051 + ('\n' == *s) ||
  1052 + ('\r' == *s) ||
  1053 + (',' == *s)) {
  1054 + s++;
  1055 + } else {
  1056 + break;
  1057 + }
  1058 + }
  1059 + }
  1060 + }
  1061 + }
  1062 +
  1063 + return 0;
  1064 +}
  1065 +#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/
  1066 +
  1067 +static void _fastboot_load_partitions(void)
  1068 +{
  1069 + pcount = 0;
  1070 +#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  1071 + _fastboot_parts_load_from_env();
  1072 +#elif defined(CONFIG_FASTBOOT_STORAGE_SATA) \
  1073 + || defined(CONFIG_FASTBOOT_STORAGE_MMC)
  1074 + _fastboot_parts_load_from_ptable();
  1075 +#endif
  1076 +}
  1077 +
  1078 +/*
  1079 + * Android style flash utilties */
  1080 +void fastboot_flash_add_ptn(struct fastboot_ptentry *ptn)
  1081 +{
  1082 + if (pcount < MAX_PTN) {
  1083 + memcpy(ptable + pcount, ptn, sizeof(struct fastboot_ptentry));
  1084 + pcount++;
  1085 + }
  1086 +}
  1087 +
  1088 +void fastboot_flash_dump_ptn(void)
  1089 +{
  1090 + unsigned int n;
  1091 + for (n = 0; n < pcount; n++) {
  1092 + struct fastboot_ptentry *ptn = ptable + n;
  1093 + printf("ptn %d name='%s' start=%d len=%d\n",
  1094 + n, ptn->name, ptn->start, ptn->length);
  1095 + }
  1096 +}
  1097 +
  1098 +
  1099 +struct fastboot_ptentry *fastboot_flash_find_ptn(const char *name)
  1100 +{
  1101 + unsigned int n;
  1102 +
  1103 + for (n = 0; n < pcount; n++) {
  1104 + /* Make sure a substring is not accepted */
  1105 + if (strlen(name) == strlen(ptable[n].name)) {
  1106 + if (0 == strcmp(ptable[n].name, name))
  1107 + return ptable + n;
  1108 + }
  1109 + }
  1110 +
  1111 + printf("can't find partition: %s, dump the partition table\n", name);
  1112 + fastboot_flash_dump_ptn();
  1113 + return 0;
  1114 +}
  1115 +
  1116 +struct fastboot_ptentry *fastboot_flash_get_ptn(unsigned int n)
  1117 +{
  1118 + if (n < pcount)
  1119 + return ptable + n;
  1120 + else
  1121 + return 0;
  1122 +}
  1123 +
  1124 +unsigned int fastboot_flash_get_ptn_count(void)
  1125 +{
  1126 + return pcount;
  1127 +}
include/configs/mx6sabre_common.h
... ... @@ -290,5 +290,9 @@
290 290 #define CONFIG_SYS_I2C_SPEED 100000
291 291 #define CONFIG_SYS_I2C_SLAVE 0x8
292 292  
  293 +#if defined(CONFIG_ANDROID_SUPPORT)
  294 +#include "mx6sabreandroid_common.h"
  295 +#endif
  296 +
293 297 #endif /* __MX6QSABRE_COMMON_CONFIG_H */
include/configs/mx6sabreandroid_common.h
  1 +/*
  2 + * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +
  7 +#ifndef MX6_SABRE_ANDROID_COMMON_H
  8 +#define MX6_SABRE_ANDROID_COMMON_H
  9 +
  10 +#define CONFIG_USB_DEVICE
  11 +#define CONFIG_IMX_UDC 1
  12 +
  13 +#define CONFIG_FASTBOOT 1
  14 +#define CONFIG_FASTBOOT_VENDOR_ID 0x18d1
  15 +#define CONFIG_FASTBOOT_PRODUCT_ID 0x0d02
  16 +#define CONFIG_FASTBOOT_BCD_DEVICE 0x311
  17 +#define CONFIG_FASTBOOT_MANUFACTURER_STR "Freescale"
  18 +#define CONFIG_FASTBOOT_PRODUCT_NAME_STR "i.mx6 Sabre Board"
  19 +#define CONFIG_FASTBOOT_INTERFACE_STR "Android fastboot"
  20 +#define CONFIG_FASTBOOT_CONFIGURATION_STR "Android fastboot"
  21 +#define CONFIG_FASTBOOT_SERIAL_NUM "12345"
  22 +#define CONFIG_FASTBOOT_SATA_NO 0
  23 +
  24 +#if defined CONFIG_SYS_BOOT_NAND
  25 +#define CONFIG_FASTBOOT_STORAGE_NAND
  26 +#elif defined CONFIG_SYS_BOOT_SATA
  27 +#define CONFIG_FASTBOOT_STORAGE_SATA
  28 +#else
  29 +#define CONFIG_FASTBOOT_STORAGE_MMC
  30 +#endif
  31 +
  32 +/* For system.img growing up more than 256MB, more buffer needs
  33 +* to receive the system.img*/
  34 +#define CONFIG_FASTBOOT_TRANSFER_BUF 0x2c000000
  35 +#define CONFIG_FASTBOOT_TRANSFER_BUF_SIZE 0x19000000 /* 400M byte */
  36 +
  37 +
  38 +#define CONFIG_CMD_BOOTI
  39 +#define CONFIG_ANDROID_RECOVERY
  40 +/* which mmc bus is your main storage ? */
  41 +#define CONFIG_ANDROID_MAIN_MMC_BUS 2
  42 +#define CONFIG_ANDROID_BOOT_PARTITION_MMC 1
  43 +#define CONFIG_ANDROID_SYSTEM_PARTITION_MMC 5
  44 +#define CONFIG_ANDROID_RECOVERY_PARTITION_MMC 2
  45 +#define CONFIG_ANDROID_CACHE_PARTITION_MMC 6
  46 +
  47 +#undef CONFIG_EXTRA_ENV_SETTINGS
  48 +#undef CONFIG_BOOTCOMMAND
  49 +
  50 +#define CONFIG_EXTRA_ENV_SETTINGS \
  51 + "splashpos=m,m\0" \
  52 + "fdt_high=0xffffffff\0" \
  53 + "initrd_high=0xffffffff\0" \
  54 +
  55 +#endif /* MX6_SABRE_ANDROID_COMMON_H */
  1 +/*
  2 + * (C) Copyright 2008 - 2009
  3 + * Windriver, <www.windriver.com>
  4 + * Tom Rix <Tom.Rix@windriver.com>
  5 + *
  6 + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of
  11 + * the License, or (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + *
  23 + * The logical naming of flash comes from the Android project
  24 + * Thse structures and functions that look like fastboot_flash_*
  25 + * They come from bootloader/legacy/include/boot/flash.h
  26 + *
  27 + * The boot_img_hdr structure and associated magic numbers also
  28 + * come from the Android project. They are from
  29 + * system/core/mkbootimg/bootimg.h
  30 + *
  31 + * Here are their copyrights
  32 + *
  33 + * Copyright (C) 2008 The Android Open Source Project
  34 + * All rights reserved.
  35 + *
  36 + * Redistribution and use in source and binary forms, with or without
  37 + * modification, are permitted provided that the following conditions
  38 + * are met:
  39 + * * Redistributions of source code must retain the above copyright
  40 + * notice, this list of conditions and the following disclaimer.
  41 + * * Redistributions in binary form must reproduce the above copyright
  42 + * notice, this list of conditions and the following disclaimer in
  43 + * the documentation and/or other materials provided with the
  44 + * distribution.
  45 + *
  46 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  47 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  48 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  49 + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  50 + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  51 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  52 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  53 + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  54 + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  55 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  56 + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  57 + * SUCH DAMAGE.
  58 + *
  59 + */
  60 +
  61 +#ifndef FASTBOOT_H
  62 +#define FASTBOOT_H
  63 +
  64 +#include <common.h>
  65 +#include <command.h>
  66 +
  67 +/* This is the interface file between the common cmd_fastboot.c and
  68 + the board specific support.
  69 +
  70 + To use this interface, define CONFIG_FASTBOOT in your board config file.
  71 + An example is include/configs/mx6slevkandroid.h
  72 + ...
  73 + #define CONFIG_FASTBOOT 1 / * Using fastboot interface * /
  74 + ...
  75 +
  76 +*/
  77 +
  78 +/* From fastboot client.. */
  79 +#define FASTBOOT_INTERFACE_CLASS 0xff
  80 +#define FASTBOOT_INTERFACE_SUB_CLASS 0x42
  81 +#define FASTBOOT_INTERFACE_PROTOCOL 0x03
  82 +
  83 +#define FASTBOOT_VERSION "0.5"
  84 +
  85 +/* Max size of responses from us to host */
  86 +#define FASTBOOT_RESPONSE_SIZE 65
  87 +
  88 +/* The fastboot client uses a value of 2048 for the
  89 + page size of it boot.img file format.
  90 + Reset this in your board config file as needed. */
  91 +#ifndef CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE
  92 +#define CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE 2048
  93 +#endif
  94 +
  95 +/* Lower byte shows if the read/write/erase operation in
  96 + repeated. The base address is incremented.
  97 + Either 0 or 1 is ok for a default */
  98 +
  99 +#define FASTBOOT_PTENTRY_FLAGS_REPEAT(n) (n & 0x0f)
  100 +#define FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK 0x0000000F
  101 +
  102 +/* Writes happen a block at a time.
  103 + If the write fails, go to next block
  104 + NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set */
  105 +#define FASTBOOT_PTENTRY_FLAGS_WRITE_NEXT_GOOD_BLOCK 0x00000010
  106 +
  107 +/* Find a contiguous block big enough for a the whole file
  108 + NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set */
  109 +#define FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK 0x00000020
  110 +
  111 +/* Write the file with write.i */
  112 +#define FASTBOOT_PTENTRY_FLAGS_WRITE_I 0x00000100
  113 +
  114 +/* Write the file with write.trimffs */
  115 +#define FASTBOOT_PTENTRY_FLAGS_WRITE_TRIMFFS 0x00000200
  116 +
  117 +/* Write the file as a series of variable/value pairs
  118 + using the setenv and saveenv commands */
  119 +#define FASTBOOT_PTENTRY_FLAGS_WRITE_ENV 0x00000400
  120 +
  121 +/* Status values */
  122 +#define FASTBOOT_OK 0
  123 +#define FASTBOOT_ERROR -1
  124 +#define FASTBOOT_DISCONNECT 1
  125 +#define FASTBOOT_INACTIVE 2
  126 +
  127 +/* Android bootimage file format */
  128 +#define FASTBOOT_BOOT_MAGIC "ANDROID!"
  129 +#define FASTBOOT_BOOT_MAGIC_SIZE 8
  130 +#define FASTBOOT_BOOT_NAME_SIZE 16
  131 +#define FASTBOOT_BOOT_ARGS_SIZE 512
  132 +
  133 +#define FASTBOOT_MMC_BOOT_PARTITION_ID 1
  134 +#define FASTBOOT_MMC_USER_PARTITION_ID 0
  135 +#define FASTBOOT_MMC_NONE_PARTITION_ID -1
  136 +
  137 +enum {
  138 + DEV_SATA,
  139 + DEV_MMC,
  140 + DEV_NAND
  141 +};
  142 +
  143 +struct cmd_fastboot_interface {
  144 + /* This function is called when a buffer has been
  145 + recieved from the client app.
  146 + The buffer is a supplied by the board layer and must be unmodified.
  147 + The buffer_size is how much data is passed in.
  148 + Returns 0 on success
  149 + Returns 1 on failure
  150 +
  151 + Set by cmd_fastboot */
  152 + int (*rx_handler)(const unsigned char *buffer,
  153 + unsigned int buffer_size);
  154 +
  155 + /* This function is called when an exception has
  156 + occurred in the device code and the state
  157 + off fastboot needs to be reset
  158 +
  159 + Set by cmd_fastboot */
  160 + void (*reset_handler)(void);
  161 +
  162 + /* A getvar string for the product name
  163 + It can have a maximum of 60 characters
  164 +
  165 + Set by board */
  166 + char *product_name;
  167 +
  168 + /* A getvar string for the serial number
  169 + It can have a maximum of 60 characters
  170 +
  171 + Set by board */
  172 + char *serial_no;
  173 +
  174 + /* Nand block size
  175 + Supports the write option WRITE_NEXT_GOOD_BLOCK
  176 +
  177 + Set by board */
  178 + unsigned int nand_block_size;
  179 +
  180 + /* Nand oob size
  181 + Set by board */
  182 + unsigned int nand_oob_size;
  183 +
  184 + /* Transfer buffer, for handling flash updates
  185 + Should be multiple of the nand_block_size
  186 + Care should be take so it does not overrun bootloader memory
  187 + Controlled by the configure variable CFG_FASTBOOT_TRANSFER_BUFFER
  188 +
  189 + Set by board */
  190 + unsigned char *transfer_buffer;
  191 +
  192 + /* How big is the transfer buffer
  193 + Controlled by the configure variable
  194 + CFG_FASTBOOT_TRANSFER_BUFFER_SIZE
  195 +
  196 + Set by board */
  197 + unsigned int transfer_buffer_size;
  198 +
  199 +};
  200 +
  201 +/* flash partitions are defined in terms of blocks
  202 +** (flash erase units)
  203 +*/
  204 +struct fastboot_ptentry {
  205 + /* The logical name for this partition, null terminated */
  206 + char name[16];
  207 + /* The start wrt the nand part, must be multiple of nand block size */
  208 + unsigned int start;
  209 + /* The length of the partition, must be multiple of nand block size */
  210 + unsigned int length;
  211 + /* Controls the details of how operations are done on the partition
  212 + See the FASTBOOT_PTENTRY_FLAGS_*'s defined below */
  213 + unsigned int flags;
  214 + /* partition id: 0 - normal partition; 1 - boot partition */
  215 + unsigned int partition_id;
  216 +};
  217 +
  218 +struct fastboot_device_info {
  219 + unsigned char type;
  220 + unsigned char dev_id;
  221 +};
  222 +
  223 +/* Boot img hdr structure comes from the Android project
  224 + * See it in: system/core/mkbootimg/bootimg.h
  225 + */
  226 +struct fastboot_boot_img_hdr {
  227 + unsigned char magic[FASTBOOT_BOOT_MAGIC_SIZE];
  228 +
  229 + unsigned kernel_size; /* size in bytes */
  230 + unsigned kernel_addr; /* physical load addr */
  231 +
  232 + unsigned ramdisk_size; /* size in bytes */
  233 + unsigned ramdisk_addr; /* physical load addr */
  234 +
  235 + unsigned second_size; /* size in bytes */
  236 + unsigned second_addr; /* physical load addr */
  237 +
  238 + unsigned tags_addr; /* physical addr for kernel tags */
  239 + unsigned page_size; /* flash page size we assume */
  240 + unsigned unused[2]; /* future expansion: should be 0 */
  241 +
  242 + unsigned char name[FASTBOOT_BOOT_NAME_SIZE]; /* asciiz product name */
  243 +
  244 + unsigned char cmdline[FASTBOOT_BOOT_ARGS_SIZE];
  245 +
  246 + unsigned id[8]; /* timestamp / checksum / sha1 / etc */
  247 +};
  248 +
  249 +#ifdef CONFIG_FASTBOOT
  250 +
  251 +extern struct fastboot_device_info fastboot_devinfo;
  252 +
  253 +/* Prepare the fastboot environments,
  254 + * should be executed before "fastboot" cmd
  255 + */
  256 +void fastboot_setup(void);
  257 +
  258 +/* Initizes the board specific fastboot
  259 + * Returns 0 on success
  260 + * Returns 1 on failure
  261 + */
  262 +int fastboot_init(struct cmd_fastboot_interface *interface);
  263 +
  264 +/* Cleans up the board specific fastboot */
  265 +void fastboot_shutdown(void);
  266 +
  267 +/*
  268 + * Handles board specific usb protocol exchanges
  269 + * Returns 0 on success
  270 + * Returns 1 on disconnects, break out of loop
  271 + * Returns 2 if no USB activity detected
  272 + * Returns -1 on failure, unhandled usb requests and other error conditions
  273 +*/
  274 +int fastboot_poll(void);
  275 +
  276 +/* Is this high speed (2.0) or full speed (1.1) ?
  277 + * Returns 0 on full speed
  278 + * Returns 1 on high speed
  279 + */
  280 +int fastboot_is_highspeed(void);
  281 +
  282 +/* Return the size of the fifo */
  283 +int fastboot_fifo_size(void);
  284 +
  285 +/* Send a status reply to the client app
  286 + * buffer does not have to be null terminated.
  287 + * buffer_size must be not be larger than what is returned by
  288 + * fastboot_fifo_size
  289 + * Returns 0 on success
  290 + * Returns 1 on failure
  291 + */
  292 +int fastboot_tx_status(const char *buffer, unsigned int buffer_size);
  293 +
  294 +/*
  295 + * Send some data to the client app
  296 + * buffer does not have to be null terminated.
  297 + * buffer_size can be larger than what is returned by
  298 + * fastboot_fifo_size
  299 + * Returns number of bytes written
  300 + */
  301 +int fastboot_tx(unsigned char *buffer, unsigned int buffer_size);
  302 +
  303 +/* A board specific variable handler.
  304 + * The size of the buffers is governed by the fastboot spec.
  305 + * rx_buffer is at most 57 bytes
  306 + * tx_buffer is at most 60 bytes
  307 + * Returns 0 on success
  308 + * Returns 1 on failure
  309 + */
  310 +int fastboot_getvar(const char *rx_buffer, char *tx_buffer);
  311 +
  312 +/* The Android-style flash handling */
  313 +
  314 +/* tools to populate and query the partition table */
  315 +void fastboot_flash_add_ptn(struct fastboot_ptentry *ptn);
  316 +struct fastboot_ptentry *fastboot_flash_find_ptn(const char *name);
  317 +struct fastboot_ptentry *fastboot_flash_get_ptn(unsigned n);
  318 +unsigned int fastboot_flash_get_ptn_count(void);
  319 +void fastboot_flash_dump_ptn(void);
  320 +
  321 +
  322 +/* Check the board special boot mode reboot to fastboot mode. */
  323 +int fastboot_check_and_clean_flag(void);
  324 +
  325 +/*fastboot command handling function*/
  326 +int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
  327 +
  328 +/*check if fastboot mode is requested by user*/
  329 +void check_fastboot(void);
  330 +
  331 +/*Setup board-relative fastboot environment */
  332 +void board_fastboot_setup(void);
  333 +
  334 +#ifdef CONFIG_FASTBOOT_STORAGE_NAND
  335 +/*Save parameters for NAND storage partitions */
  336 +void save_parts_values(struct fastboot_ptentry *ptn,
  337 + unsigned int offset, unsigned int size);
  338 +
  339 +/* Checks parameters for NAND storage partitions
  340 + * Return 1 if the parameter is not set
  341 + * Return 0 if the parameter has been set
  342 + */
  343 +int check_parts_values(struct fastboot_ptentry *ptn);
  344 +#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/
  345 +
  346 +#else /*! CONFIG_FASTBOOT*/
  347 +
  348 +/* Stubs for when CONFIG_FASTBOOT is not defined */
  349 +#define fastboot_setup() 0
  350 +#define fastboot_init(a) 1
  351 +#define fastboot_shutdown()
  352 +#define fastboot_poll() 1
  353 +#define fastboot_is_highspeed() 0
  354 +#define fastboot_fifo_size() 0
  355 +#define fastboot_tx_status(a, b) 1
  356 +#define fastboot_getvar(a, b) 1
  357 +#define fastboot_tx(a, b) 1
  358 +
  359 +#define fastboot_flash_add_ptn(a)
  360 +#define fastboot_flash_find_ptn(a) NULL
  361 +#define fastboot_flash_get_ptn(a) NULL
  362 +#define fastboot_flash_get_ptn_count() 0
  363 +#define fastboot_flash_dump_ptn()
  364 +#define do_fastboot(a, b, c, d) 0
  365 +
  366 +#define fastboot_quick(a) 0
  367 +#define fastboot_get_ep_num(a, b) 0
  368 +#define fastboot_dump_memory(a, b) 0
  369 +#define DBG_ALWS(x...)
  370 +#define DBG_ERR(x...)
  371 +#define DBG_DEBUG(x...)
  372 +#define DBG_INFO(x...)
  373 +
  374 +
  375 +#endif /*! CONFIG_FASTBOOT*/
  376 +#endif /* FASTBOOT_H */
  1 +/*
  2 + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +
  7 +#ifndef __RECOVERY_H_
  8 +#define __RECOVERY_H_
  9 +
  10 +struct reco_envs {
  11 + char *cmd;
  12 + char *args;
  13 +};
  14 +
  15 +void check_recovery_mode(void);
  16 +int recovery_check_and_clean_flag(void);
  17 +int check_recovery_cmd_file(void);
  18 +void board_recovery_setup(void);
  19 +
  20 +#endif