Commit 8cb9cd7e436a395ea772763c56788cb19e8c0b83

Authored by Haoran.Wang
Committed by Ji Luo
1 parent a6ea228bd7

MA-16457-2 support reboot-fastboot command in u-boot

Android implement the userspace fastboot in Android Recovery.
Follow Google's spec, added below 2 fastboot command support:
  * fastboot getvar is-userspace
  * fastboot reboot fastboot

TEST: fastboot commands.

Change-Id: Ib6047413be0a45b3c00626cdb8594809eb8a2b6b
Signed-off-by: Haoran.Wang <elven.wang@nxp.com>
(cherry picked from commit 314bded076dfc3e544cc7094ce3f6c4c330be4dd)

Showing 7 changed files with 94 additions and 2 deletions Inline Diff

drivers/fastboot/fb_fsl/bcb.h
1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+
2 /* 2 /*
3 * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. 3 * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
4 */ 4 */
5 5
6 #ifndef BCB_H 6 #ifndef BCB_H
7 #define BCB_H 7 #define BCB_H
8 #include <linux/types.h> 8 #include <linux/types.h>
9 #include <linux/stat.h> 9 #include <linux/stat.h>
10 10
11 #define FASTBOOT_BCB_CMD "bootonce-bootloader" 11 #define FASTBOOT_BCB_CMD "bootonce-bootloader"
12 #ifdef CONFIG_ANDROID_RECOVERY 12 #ifdef CONFIG_ANDROID_RECOVERY
13 #define RECOVERY_BCB_CMD "boot-recovery" 13 #define RECOVERY_BCB_CMD "boot-recovery"
14 #define RECOVERY_FASTBOOT_ARG "recovery\n--fastboot"
14 #endif 15 #endif
15 /* keep same as bootable/recovery/bootloader.h */ 16 /* keep same as bootable/recovery/bootloader.h */
16 struct bootloader_message { 17 struct bootloader_message {
17 char command[32]; 18 char command[32];
18 char status[32]; 19 char status[32];
19 char recovery[768]; 20 char recovery[768];
20 21
21 /* The 'recovery' field used to be 1024 bytes. It has only ever 22 /* The 'recovery' field used to be 1024 bytes. It has only ever
22 been used to store the recovery command line, so 768 bytes 23 been used to store the recovery command line, so 768 bytes
23 should be plenty. We carve off the last 256 bytes to store the 24 should be plenty. We carve off the last 256 bytes to store the
24 stage string (for multistage packages) and possible future 25 stage string (for multistage packages) and possible future
25 expansion. */ 26 expansion. */
26 char stage[32]; 27 char stage[32];
27 28
28 /* The 'reserved' field used to be 224 bytes when it was initially 29 /* The 'reserved' field used to be 224 bytes when it was initially
29 carved off from the 1024-byte recovery field. Bump it up to 30 carved off from the 1024-byte recovery field. Bump it up to
30 1184-byte so that the entire bootloader_message struct rounds up 31 1184-byte so that the entire bootloader_message struct rounds up
31 to 2048-byte. 32 to 2048-byte.
32 */ 33 */
33 char reserved[1184]; 34 char reserved[1184];
34 }; 35 };
35 36
36 struct bootloader_message_ab { 37 struct bootloader_message_ab {
37 struct bootloader_message message; 38 struct bootloader_message message;
38 char slot_suffix[32]; 39 char slot_suffix[32];
39 40
40 /* Round up the entire struct to 4096-byte. */ 41 /* Round up the entire struct to 4096-byte. */
41 char reserved[2016]; 42 char reserved[2016];
42 }; 43 };
43 44
44 /* start from bootloader_message_ab.slot_suffix[BOOTCTRL_IDX] */ 45 /* start from bootloader_message_ab.slot_suffix[BOOTCTRL_IDX] */
45 #define BOOTCTRL_IDX 0 46 #define BOOTCTRL_IDX 0
46 #define MISC_COMMAND_IDX 0 47 #define MISC_COMMAND_IDX 0
47 #define BOOTCTRL_OFFSET \ 48 #define BOOTCTRL_OFFSET \
48 (u32)(&(((struct bootloader_message_ab *)0)->slot_suffix[BOOTCTRL_IDX])) 49 (u32)(&(((struct bootloader_message_ab *)0)->slot_suffix[BOOTCTRL_IDX]))
49 #define MISC_COMMAND \ 50 #define MISC_COMMAND \
50 (u32)(uintptr_t)(&(((struct bootloader_message *)0)->command[MISC_COMMAND_IDX])) 51 (u32)(uintptr_t)(&(((struct bootloader_message *)0)->command[MISC_COMMAND_IDX]))
52
53 #ifdef CONFIG_ANDROID_RECOVERY
54 #define RECOVERY_OPTIONS\
55 (u32)(uintptr_t)(&(((struct bootloader_message *)0)->recovery[0]))
56 #endif
51 int bcb_rw_block(bool bread, char **ppblock, 57 int bcb_rw_block(bool bread, char **ppblock,
52 uint *pblksize, char *pblock_write, uint offset, uint size); 58 uint *pblksize, char *pblock_write, uint offset, uint size);
53 59
54 int bcb_write_command(char *bcb_command); 60 int bcb_write_command(char *bcb_command);
55 int bcb_read_command(char *command); 61 int bcb_read_command(char *command);
56 62
63 #ifdef CONFIG_ANDROID_RECOVERY
64 int bcb_write_recovery_opt(char *opts);
65 #endif
57 #endif 66 #endif
58 67
drivers/fastboot/fb_fsl/command.c
1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+
2 /* 2 /*
3 * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. 3 * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
4 */ 4 */
5 5
6 #include <common.h> 6 #include <common.h>
7 #include <g_dnl.h> 7 #include <g_dnl.h>
8 #include "bcb.h" 8 #include "bcb.h"
9 9
10 int bcb_read_command(char *command) 10 int bcb_read_command(char *command)
11 { 11 {
12 int ret = 0; 12 int ret = 0;
13 char *p_block = NULL; 13 char *p_block = NULL;
14 uint offset_in_block = 0; 14 uint offset_in_block = 0;
15 uint blk_size = 0; 15 uint blk_size = 0;
16 16
17 if (command == NULL) 17 if (command == NULL)
18 return -1; 18 return -1;
19 19
20 ret = bcb_rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32); 20 ret = bcb_rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32);
21 if (ret) { 21 if (ret) {
22 printf("read_bootctl, bcb_rw_block read failed\n"); 22 printf("read_bootctl, bcb_rw_block read failed\n");
23 return -1; 23 return -1;
24 } 24 }
25 25
26 offset_in_block = MISC_COMMAND%blk_size; 26 offset_in_block = MISC_COMMAND%blk_size;
27 memcpy(command, p_block + offset_in_block, 32); 27 memcpy(command, p_block + offset_in_block, 32);
28 free(p_block); 28 free(p_block);
29 29
30 return 0; 30 return 0;
31 } 31 }
32 int bcb_write_command(char *bcb_command) 32 int bcb_write_command(char *bcb_command)
33 { 33 {
34 int ret = 0; 34 int ret = 0;
35 char *p_block = NULL; 35 char *p_block = NULL;
36 uint offset_in_block = 0; 36 uint offset_in_block = 0;
37 uint blk_size = 0; 37 uint blk_size = 0;
38 38
39 if (bcb_command == NULL) 39 if (bcb_command == NULL)
40 return -1; 40 return -1;
41 41
42 42
43 ret = bcb_rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32); 43 ret = bcb_rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32);
44 if (ret) { 44 if (ret) {
45 printf("write_bootctl, bcb_rw_block read failed\n"); 45 printf("write_bootctl, bcb_rw_block read failed\n");
46 return -1; 46 return -1;
47 } 47 }
48 48
49 offset_in_block = MISC_COMMAND%blk_size; 49 offset_in_block = MISC_COMMAND%blk_size;
50 memcpy(p_block + offset_in_block, bcb_command, 32); 50 memcpy(p_block + offset_in_block, bcb_command, 32);
51 51
52 ret = bcb_rw_block(false, NULL, NULL, p_block, MISC_COMMAND, 32); 52 ret = bcb_rw_block(false, NULL, NULL, p_block, MISC_COMMAND, 32);
53 if (ret) { 53 if (ret) {
54 free(p_block); 54 free(p_block);
55 printf("write_bootctl, bcb_rw_block write failed\n"); 55 printf("write_bootctl, bcb_rw_block write failed\n");
56 return -1; 56 return -1;
57 } 57 }
58 58
59 free(p_block); 59 free(p_block);
60 return 0; 60 return 0;
61 } 61 }
62
63 #ifdef CONFIG_ANDROID_RECOVERY
64 int bcb_write_recovery_opt(char *opts)
65 {
66 int ret = 0;
67 char *p_block = NULL;
68 uint offset_in_block = 0;
69 uint blk_size = 0;
70
71 if (opts == NULL)
72 return -1;
73
74
75 ret = bcb_rw_block(true, &p_block, &blk_size, NULL, RECOVERY_OPTIONS, 32);
76 if (ret) {
77 printf("write_bootctl, bcb_rw_block read failed\n");
78 return -1;
79 }
80
81 offset_in_block = RECOVERY_OPTIONS%blk_size;
82 memcpy(p_block + offset_in_block, opts, 32);
83
84 ret = bcb_rw_block(false, NULL, NULL, p_block, RECOVERY_OPTIONS, 32);
85 if (ret) {
86 free(p_block);
87 printf("write_bootctl, bcb_rw_block write failed\n");
88 return -1;
89 }
90
91 free(p_block);
92 return 0;
93 }
94 #endif
62 95
drivers/fastboot/fb_fsl/fb_fsl_command.c
1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+
2 /* 2 /*
3 * Copyright 2019 NXP 3 * Copyright 2019 NXP
4 */ 4 */
5 5
6 #include <asm/mach-imx/sys_proto.h> 6 #include <asm/mach-imx/sys_proto.h>
7 #include <fb_fsl.h> 7 #include <fb_fsl.h>
8 #include <fastboot.h> 8 #include <fastboot.h>
9 #include <fastboot-internal.h> 9 #include <fastboot-internal.h>
10 #include <mmc.h> 10 #include <mmc.h>
11 #include <android_image.h> 11 #include <android_image.h>
12 #include <asm/bootm.h> 12 #include <asm/bootm.h>
13 #include <nand.h> 13 #include <nand.h>
14 #include <part.h> 14 #include <part.h>
15 #include <sparse_format.h> 15 #include <sparse_format.h>
16 #include <image-sparse.h> 16 #include <image-sparse.h>
17 #include <image.h> 17 #include <image.h>
18 #include <asm/mach-imx/boot_mode.h> 18 #include <asm/mach-imx/boot_mode.h>
19 #include <asm/arch/sys_proto.h> 19 #include <asm/arch/sys_proto.h>
20 #include <asm/setup.h> 20 #include <asm/setup.h>
21 #include <env.h> 21 #include <env.h>
22 #ifdef CONFIG_ANDROID_RECOVERY 22 #ifdef CONFIG_ANDROID_RECOVERY
23 #include <recovery.h> 23 #include <recovery.h>
24 #endif 24 #endif
25 25
26 #ifdef CONFIG_BCB_SUPPORT 26 #ifdef CONFIG_BCB_SUPPORT
27 #include "bcb.h" 27 #include "bcb.h"
28 #endif 28 #endif
29 29
30 #ifdef CONFIG_AVB_SUPPORT 30 #ifdef CONFIG_AVB_SUPPORT
31 #include <dt_table.h> 31 #include <dt_table.h>
32 #include <fsl_avb.h> 32 #include <fsl_avb.h>
33 #endif 33 #endif
34 34
35 #ifdef CONFIG_ANDROID_THINGS_SUPPORT 35 #ifdef CONFIG_ANDROID_THINGS_SUPPORT
36 #include <asm-generic/gpio.h> 36 #include <asm-generic/gpio.h>
37 #include <asm/mach-imx/gpio.h> 37 #include <asm/mach-imx/gpio.h>
38 #include "../lib/avb/fsl/fsl_avbkey.h" 38 #include "../lib/avb/fsl/fsl_avbkey.h"
39 #include "../arch/arm/include/asm/mach-imx/hab.h" 39 #include "../arch/arm/include/asm/mach-imx/hab.h"
40 #endif 40 #endif
41 41
42 #if defined(CONFIG_FASTBOOT_LOCK) 42 #if defined(CONFIG_FASTBOOT_LOCK)
43 #include "fastboot_lock_unlock.h" 43 #include "fastboot_lock_unlock.h"
44 #endif 44 #endif
45 45
46 #ifdef CONFIG_IMX_TRUSTY_OS 46 #ifdef CONFIG_IMX_TRUSTY_OS
47 #include "u-boot/sha256.h" 47 #include "u-boot/sha256.h"
48 #include <trusty/libtipc.h> 48 #include <trusty/libtipc.h>
49 #endif 49 #endif
50 50
51 #include "fb_fsl_common.h" 51 #include "fb_fsl_common.h"
52 52
53 #define EP_BUFFER_SIZE 4096 53 #define EP_BUFFER_SIZE 4096
54 54
55 /** 55 /**
56 * fastboot_bytes_received - number of bytes received in the current download 56 * fastboot_bytes_received - number of bytes received in the current download
57 */ 57 */
58 static u32 fastboot_bytes_received; 58 static u32 fastboot_bytes_received;
59 59
60 /** 60 /**
61 * fastboot_bytes_expected - number of bytes expected in the current download 61 * fastboot_bytes_expected - number of bytes expected in the current download
62 */ 62 */
63 static u32 fastboot_bytes_expected; 63 static u32 fastboot_bytes_expected;
64 64
65 /* Write the bcb with fastboot bootloader commands */ 65 /* Write the bcb with fastboot bootloader commands */
66 static void enable_fastboot_command(void) 66 static void enable_fastboot_command(void)
67 { 67 {
68 #ifdef CONFIG_BCB_SUPPORT 68 #ifdef CONFIG_BCB_SUPPORT
69 char fastboot_command[32] = {0}; 69 char fastboot_command[32] = {0};
70 strncpy(fastboot_command, FASTBOOT_BCB_CMD, 31); 70 strncpy(fastboot_command, FASTBOOT_BCB_CMD, 31);
71 bcb_write_command(fastboot_command); 71 bcb_write_command(fastboot_command);
72 #endif 72 #endif
73 } 73 }
74 74
75 #ifdef CONFIG_ANDROID_RECOVERY
76 /* Write the recovery options with fastboot bootloader commands */
77 static void enable_recovery_fastboot(void)
78 {
79 #ifdef CONFIG_BCB_SUPPORT
80 char msg[32] = {0};
81 strncpy(msg, RECOVERY_BCB_CMD, 31);
82 bcb_write_command(msg);
83 strncpy(msg, RECOVERY_FASTBOOT_ARG, 31);
84 bcb_write_recovery_opt(msg);
85 #endif
86 }
87 #endif
88
75 /* Get the Boot mode from BCB cmd or Key pressed */ 89 /* Get the Boot mode from BCB cmd or Key pressed */
76 static FbBootMode fastboot_get_bootmode(void) 90 static FbBootMode fastboot_get_bootmode(void)
77 { 91 {
78 int boot_mode = BOOTMODE_NORMAL; 92 int boot_mode = BOOTMODE_NORMAL;
79 #ifdef CONFIG_ANDROID_RECOVERY 93 #ifdef CONFIG_ANDROID_RECOVERY
80 if(is_recovery_key_pressing()) { 94 if(is_recovery_key_pressing()) {
81 boot_mode = BOOTMODE_RECOVERY_KEY_PRESSED; 95 boot_mode = BOOTMODE_RECOVERY_KEY_PRESSED;
82 return boot_mode; 96 return boot_mode;
83 } 97 }
84 #endif 98 #endif
85 #ifdef CONFIG_BCB_SUPPORT 99 #ifdef CONFIG_BCB_SUPPORT
86 int ret = 0; 100 int ret = 0;
87 char command[32]; 101 char command[32];
88 ret = bcb_read_command(command); 102 ret = bcb_read_command(command);
89 if (ret < 0) { 103 if (ret < 0) {
90 printf("read command failed\n"); 104 printf("read command failed\n");
91 return boot_mode; 105 return boot_mode;
92 } 106 }
93 if (!strcmp(command, FASTBOOT_BCB_CMD)) { 107 if (!strcmp(command, FASTBOOT_BCB_CMD)) {
94 boot_mode = BOOTMODE_FASTBOOT_BCB_CMD; 108 boot_mode = BOOTMODE_FASTBOOT_BCB_CMD;
95 } 109 }
96 #ifdef CONFIG_ANDROID_RECOVERY 110 #ifdef CONFIG_ANDROID_RECOVERY
97 else if (!strcmp(command, RECOVERY_BCB_CMD)) { 111 else if (!strcmp(command, RECOVERY_BCB_CMD)) {
98 boot_mode = BOOTMODE_RECOVERY_BCB_CMD; 112 boot_mode = BOOTMODE_RECOVERY_BCB_CMD;
99 } 113 }
100 #endif 114 #endif
101 115
102 /* Clean the mode once its read out, 116 /* Clean the mode once its read out,
103 no matter what in the mode string */ 117 no matter what in the mode string */
104 memset(command, 0, 32); 118 memset(command, 0, 32);
105 bcb_write_command(command); 119 bcb_write_command(command);
106 #endif 120 #endif
107 return boot_mode; 121 return boot_mode;
108 } 122 }
109 123
110 /* export to lib_arm/board.c */ 124 /* export to lib_arm/board.c */
111 void fastboot_run_bootmode(void) 125 void fastboot_run_bootmode(void)
112 { 126 {
113 FbBootMode boot_mode = fastboot_get_bootmode(); 127 FbBootMode boot_mode = fastboot_get_bootmode();
114 switch(boot_mode){ 128 switch(boot_mode){
115 case BOOTMODE_FASTBOOT_BCB_CMD: 129 case BOOTMODE_FASTBOOT_BCB_CMD:
116 /* Make the boot into fastboot mode*/ 130 /* Make the boot into fastboot mode*/
117 puts("Fastboot: Got bootloader commands!\n"); 131 puts("Fastboot: Got bootloader commands!\n");
118 run_command("fastboot 0", 0); 132 run_command("fastboot 0", 0);
119 break; 133 break;
120 #ifdef CONFIG_ANDROID_RECOVERY 134 #ifdef CONFIG_ANDROID_RECOVERY
121 case BOOTMODE_RECOVERY_BCB_CMD: 135 case BOOTMODE_RECOVERY_BCB_CMD:
122 case BOOTMODE_RECOVERY_KEY_PRESSED: 136 case BOOTMODE_RECOVERY_KEY_PRESSED:
123 /* Make the boot into recovery mode */ 137 /* Make the boot into recovery mode */
124 puts("Fastboot: Got Recovery key pressing or recovery commands!\n"); 138 puts("Fastboot: Got Recovery key pressing or recovery commands!\n");
125 board_recovery_setup(); 139 board_recovery_setup();
126 break; 140 break;
127 #endif 141 #endif
128 default: 142 default:
129 /* skip special mode boot*/ 143 /* skip special mode boot*/
130 puts("Fastboot: Normal\n"); 144 puts("Fastboot: Normal\n");
131 break; 145 break;
132 } 146 }
133 } 147 }
134 148
135 149
136 150
137 /** 151 /**
138 * okay() - Send bare OKAY response 152 * okay() - Send bare OKAY response
139 * 153 *
140 * @cmd_parameter: Pointer to command parameter 154 * @cmd_parameter: Pointer to command parameter
141 * @response: Pointer to fastboot response buffer 155 * @response: Pointer to fastboot response buffer
142 * 156 *
143 * Send a bare OKAY fastboot response. This is used where the command is 157 * Send a bare OKAY fastboot response. This is used where the command is
144 * valid, but all the work is done after the response has been sent (e.g. 158 * valid, but all the work is done after the response has been sent (e.g.
145 * boot, reboot etc.) 159 * boot, reboot etc.)
146 */ 160 */
147 static void okay(char *cmd_parameter, char *response) 161 static void okay(char *cmd_parameter, char *response)
148 { 162 {
149 fastboot_okay(NULL, response); 163 fastboot_okay(NULL, response);
150 } 164 }
151 165
152 /** 166 /**
153 * getvar() - Read a config/version variable 167 * getvar() - Read a config/version variable
154 * 168 *
155 * @cmd_parameter: Pointer to command parameter 169 * @cmd_parameter: Pointer to command parameter
156 * @response: Pointer to fastboot response buffer 170 * @response: Pointer to fastboot response buffer
157 */ 171 */
158 static void getvar(char *cmd_parameter, char *response) 172 static void getvar(char *cmd_parameter, char *response)
159 { 173 {
160 fastboot_getvar(cmd_parameter, response); 174 fastboot_getvar(cmd_parameter, response);
161 } 175 }
162 176
163 /** 177 /**
164 * reboot_bootloader() - Sets reboot bootloader flag. 178 * reboot_bootloader() - Sets reboot bootloader flag.
165 * 179 *
166 * @cmd_parameter: Pointer to command parameter 180 * @cmd_parameter: Pointer to command parameter
167 * @response: Pointer to fastboot response buffer 181 * @response: Pointer to fastboot response buffer
168 */ 182 */
169 static void reboot_bootloader(char *cmd_parameter, char *response) 183 static void reboot_bootloader(char *cmd_parameter, char *response)
170 { 184 {
171 enable_fastboot_command(); 185 enable_fastboot_command();
172 186
173 if (fastboot_set_reboot_flag()) 187 if (fastboot_set_reboot_flag())
174 fastboot_fail("Cannot set reboot flag", response); 188 fastboot_fail("Cannot set reboot flag", response);
175 else 189 else
176 fastboot_okay(NULL, response); 190 fastboot_okay(NULL, response);
177 } 191 }
178 192
193 #ifdef CONFIG_ANDROID_RECOVERY
194 /**
195 * reboot_fastboot() - Sets reboot fastboot flag.
196 *
197 * @cmd_parameter: Pointer to command parameter
198 * @response: Pointer to fastboot response buffer
199 */
200 static void reboot_fastboot(char *cmd_parameter, char *response)
201 {
202 enable_recovery_fastboot();
203
204 if (fastboot_set_reboot_flag())
205 fastboot_fail("Cannot set reboot flag", response);
206 else
207 fastboot_okay(NULL, response);
208 }
209 #endif
210
179 static void upload(char *cmd_parameter, char *response) 211 static void upload(char *cmd_parameter, char *response)
180 { 212 {
181 if (!fastboot_bytes_received || fastboot_bytes_received > (EP_BUFFER_SIZE * 32)) { 213 if (!fastboot_bytes_received || fastboot_bytes_received > (EP_BUFFER_SIZE * 32)) {
182 fastboot_fail("", response); 214 fastboot_fail("", response);
183 return; 215 return;
184 } 216 }
185 217
186 printf("Will upload %d bytes.\n", fastboot_bytes_received); 218 printf("Will upload %d bytes.\n", fastboot_bytes_received);
187 snprintf(response, FASTBOOT_RESPONSE_LEN, "DATA%08x", fastboot_bytes_received); 219 snprintf(response, FASTBOOT_RESPONSE_LEN, "DATA%08x", fastboot_bytes_received);
188 fastboot_tx_write_more(response); 220 fastboot_tx_write_more(response);
189 221
190 fastboot_tx_write((const char *)(fastboot_buf_addr), fastboot_bytes_received); 222 fastboot_tx_write((const char *)(fastboot_buf_addr), fastboot_bytes_received);
191 223
192 snprintf(response,FASTBOOT_RESPONSE_LEN, "OKAY"); 224 snprintf(response,FASTBOOT_RESPONSE_LEN, "OKAY");
193 fastboot_tx_write_more(response); 225 fastboot_tx_write_more(response);
194 226
195 fastboot_none_resp(response); 227 fastboot_none_resp(response);
196 } 228 }
197 229
198 /** 230 /**
199 * fastboot_download() - Start a download transfer from the client 231 * fastboot_download() - Start a download transfer from the client
200 * 232 *
201 * @cmd_parameter: Pointer to command parameter 233 * @cmd_parameter: Pointer to command parameter
202 * @response: Pointer to fastboot response buffer 234 * @response: Pointer to fastboot response buffer
203 */ 235 */
204 static void download(char *cmd_parameter, char *response) 236 static void download(char *cmd_parameter, char *response)
205 { 237 {
206 char *tmp; 238 char *tmp;
207 239
208 if (!cmd_parameter) { 240 if (!cmd_parameter) {
209 fastboot_fail("Expected command parameter", response); 241 fastboot_fail("Expected command parameter", response);
210 return; 242 return;
211 } 243 }
212 fastboot_bytes_received = 0; 244 fastboot_bytes_received = 0;
213 fastboot_bytes_expected = simple_strtoul(cmd_parameter, &tmp, 16); 245 fastboot_bytes_expected = simple_strtoul(cmd_parameter, &tmp, 16);
214 if (fastboot_bytes_expected == 0) { 246 if (fastboot_bytes_expected == 0) {
215 fastboot_fail("Expected nonzero image size", response); 247 fastboot_fail("Expected nonzero image size", response);
216 return; 248 return;
217 } 249 }
218 /* 250 /*
219 * Nothing to download yet. Response is of the form: 251 * Nothing to download yet. Response is of the form:
220 * [DATA|FAIL]$cmd_parameter 252 * [DATA|FAIL]$cmd_parameter
221 * 253 *
222 * where cmd_parameter is an 8 digit hexadecimal number 254 * where cmd_parameter is an 8 digit hexadecimal number
223 */ 255 */
224 if (fastboot_bytes_expected > fastboot_buf_size) { 256 if (fastboot_bytes_expected > fastboot_buf_size) {
225 fastboot_fail(cmd_parameter, response); 257 fastboot_fail(cmd_parameter, response);
226 } else { 258 } else {
227 printf("Starting download of %d bytes\n", 259 printf("Starting download of %d bytes\n",
228 fastboot_bytes_expected); 260 fastboot_bytes_expected);
229 fastboot_response("DATA", response, "%s", cmd_parameter); 261 fastboot_response("DATA", response, "%s", cmd_parameter);
230 } 262 }
231 } 263 }
232 264
233 /** 265 /**
234 * fastboot_data_remaining() - return bytes remaining in current transfer 266 * fastboot_data_remaining() - return bytes remaining in current transfer
235 * 267 *
236 * Return: Number of bytes left in the current download 268 * Return: Number of bytes left in the current download
237 */ 269 */
238 u32 fastboot_data_remaining(void) 270 u32 fastboot_data_remaining(void)
239 { 271 {
240 if (fastboot_bytes_received >= fastboot_bytes_expected) 272 if (fastboot_bytes_received >= fastboot_bytes_expected)
241 return 0; 273 return 0;
242 274
243 return fastboot_bytes_expected - fastboot_bytes_received; 275 return fastboot_bytes_expected - fastboot_bytes_received;
244 } 276 }
245 277
246 /** 278 /**
247 * fastboot_data_download() - Copy image data to fastboot_buf_addr. 279 * fastboot_data_download() - Copy image data to fastboot_buf_addr.
248 * 280 *
249 * @fastboot_data: Pointer to received fastboot data 281 * @fastboot_data: Pointer to received fastboot data
250 * @fastboot_data_len: Length of received fastboot data 282 * @fastboot_data_len: Length of received fastboot data
251 * @response: Pointer to fastboot response buffer 283 * @response: Pointer to fastboot response buffer
252 * 284 *
253 * Copies image data from fastboot_data to fastboot_buf_addr. Writes to 285 * Copies image data from fastboot_data to fastboot_buf_addr. Writes to
254 * response. fastboot_bytes_received is updated to indicate the number 286 * response. fastboot_bytes_received is updated to indicate the number
255 * of bytes that have been transferred. 287 * of bytes that have been transferred.
256 * 288 *
257 * On completion sets image_size and ${filesize} to the total size of the 289 * On completion sets image_size and ${filesize} to the total size of the
258 * downloaded image. 290 * downloaded image.
259 */ 291 */
260 void fastboot_data_download(const void *fastboot_data, 292 void fastboot_data_download(const void *fastboot_data,
261 unsigned int fastboot_data_len, 293 unsigned int fastboot_data_len,
262 char *response) 294 char *response)
263 { 295 {
264 #define BYTES_PER_DOT 0x20000 296 #define BYTES_PER_DOT 0x20000
265 u32 pre_dot_num, now_dot_num; 297 u32 pre_dot_num, now_dot_num;
266 298
267 if (fastboot_data_len == 0 || 299 if (fastboot_data_len == 0 ||
268 (fastboot_bytes_received + fastboot_data_len) > 300 (fastboot_bytes_received + fastboot_data_len) >
269 fastboot_bytes_expected) { 301 fastboot_bytes_expected) {
270 fastboot_fail("Received invalid data length", 302 fastboot_fail("Received invalid data length",
271 response); 303 response);
272 return; 304 return;
273 } 305 }
274 /* Download data to fastboot_buf_addr */ 306 /* Download data to fastboot_buf_addr */
275 memcpy(fastboot_buf_addr + fastboot_bytes_received, 307 memcpy(fastboot_buf_addr + fastboot_bytes_received,
276 fastboot_data, fastboot_data_len); 308 fastboot_data, fastboot_data_len);
277 309
278 pre_dot_num = fastboot_bytes_received / BYTES_PER_DOT; 310 pre_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
279 fastboot_bytes_received += fastboot_data_len; 311 fastboot_bytes_received += fastboot_data_len;
280 now_dot_num = fastboot_bytes_received / BYTES_PER_DOT; 312 now_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
281 313
282 if (pre_dot_num != now_dot_num) { 314 if (pre_dot_num != now_dot_num) {
283 putc('.'); 315 putc('.');
284 if (!(now_dot_num % 74)) 316 if (!(now_dot_num % 74))
285 putc('\n'); 317 putc('\n');
286 } 318 }
287 *response = '\0'; 319 *response = '\0';
288 } 320 }
289 321
290 /** 322 /**
291 * fastboot_data_complete() - Mark current transfer complete 323 * fastboot_data_complete() - Mark current transfer complete
292 * 324 *
293 * @response: Pointer to fastboot response buffer 325 * @response: Pointer to fastboot response buffer
294 * 326 *
295 * Set image_size and ${filesize} to the total size of the downloaded image. 327 * Set image_size and ${filesize} to the total size of the downloaded image.
296 */ 328 */
297 void fastboot_data_complete(char *response) 329 void fastboot_data_complete(char *response)
298 { 330 {
299 /* Download complete. Respond with "OKAY" */ 331 /* Download complete. Respond with "OKAY" */
300 fastboot_okay(NULL, response); 332 fastboot_okay(NULL, response);
301 printf("\ndownloading of %d bytes finished\n", fastboot_bytes_received); 333 printf("\ndownloading of %d bytes finished\n", fastboot_bytes_received);
302 env_set_hex("filesize", fastboot_bytes_received); 334 env_set_hex("filesize", fastboot_bytes_received);
303 env_set_hex("fastboot_bytes", fastboot_bytes_received); 335 env_set_hex("fastboot_bytes", fastboot_bytes_received);
304 fastboot_bytes_expected = 0; 336 fastboot_bytes_expected = 0;
305 } 337 }
306 338
307 #if defined(CONFIG_FASTBOOT_LOCK) 339 #if defined(CONFIG_FASTBOOT_LOCK)
308 static int partition_table_valid(void) 340 static int partition_table_valid(void)
309 { 341 {
310 int status, mmc_no; 342 int status, mmc_no;
311 struct blk_desc *dev_desc; 343 struct blk_desc *dev_desc;
312 #if defined(CONFIG_IMX_TRUSTY_OS) && !defined(CONFIG_ARM64) 344 #if defined(CONFIG_IMX_TRUSTY_OS) && !defined(CONFIG_ARM64)
313 /* Prevent other partition accessing when no TOS flashed. */ 345 /* Prevent other partition accessing when no TOS flashed. */
314 if (!tos_flashed) 346 if (!tos_flashed)
315 return 0; 347 return 0;
316 #endif 348 #endif
317 disk_partition_t info; 349 disk_partition_t info;
318 mmc_no = fastboot_devinfo.dev_id; 350 mmc_no = fastboot_devinfo.dev_id;
319 dev_desc = blk_get_dev("mmc", mmc_no); 351 dev_desc = blk_get_dev("mmc", mmc_no);
320 if (dev_desc) 352 if (dev_desc)
321 status = part_get_info(dev_desc, 1, &info); 353 status = part_get_info(dev_desc, 1, &info);
322 else 354 else
323 status = -1; 355 status = -1;
324 return (status == 0); 356 return (status == 0);
325 } 357 }
326 358
327 static void wipe_all_userdata(void) 359 static void wipe_all_userdata(void)
328 { 360 {
329 char response[FASTBOOT_RESPONSE_LEN]; 361 char response[FASTBOOT_RESPONSE_LEN];
330 362
331 /* Erase all user data */ 363 /* Erase all user data */
332 printf("Start userdata wipe process....\n"); 364 printf("Start userdata wipe process....\n");
333 /* Erase /data partition */ 365 /* Erase /data partition */
334 fastboot_wipe_data_partition(); 366 fastboot_wipe_data_partition();
335 367
336 #if defined (CONFIG_ANDROID_SUPPORT) || defined (CONFIG_ANDROID_AUTO_SUPPORT) 368 #if defined (CONFIG_ANDROID_SUPPORT) || defined (CONFIG_ANDROID_AUTO_SUPPORT)
337 /* Erase the misc partition. */ 369 /* Erase the misc partition. */
338 process_erase_mmc(FASTBOOT_PARTITION_MISC, response); 370 process_erase_mmc(FASTBOOT_PARTITION_MISC, response);
339 #endif 371 #endif
340 372
341 #ifndef CONFIG_ANDROID_AB_SUPPORT 373 #ifndef CONFIG_ANDROID_AB_SUPPORT
342 /* Erase the cache partition for legacy imx6/7 */ 374 /* Erase the cache partition for legacy imx6/7 */
343 process_erase_mmc(FASTBOOT_PARTITION_CACHE, response); 375 process_erase_mmc(FASTBOOT_PARTITION_CACHE, response);
344 #endif 376 #endif
345 377
346 #if defined(AVB_RPMB) && !defined(CONFIG_IMX_TRUSTY_OS) 378 #if defined(AVB_RPMB) && !defined(CONFIG_IMX_TRUSTY_OS)
347 printf("Start stored_rollback_index wipe process....\n"); 379 printf("Start stored_rollback_index wipe process....\n");
348 rbkidx_erase(); 380 rbkidx_erase();
349 printf("Wipe stored_rollback_index completed.\n"); 381 printf("Wipe stored_rollback_index completed.\n");
350 #endif 382 #endif
351 printf("Wipe userdata completed.\n"); 383 printf("Wipe userdata completed.\n");
352 } 384 }
353 385
354 static FbLockState do_fastboot_unlock(bool force) 386 static FbLockState do_fastboot_unlock(bool force)
355 { 387 {
356 int status; 388 int status;
357 389
358 if (fastboot_get_lock_stat() == FASTBOOT_UNLOCK) { 390 if (fastboot_get_lock_stat() == FASTBOOT_UNLOCK) {
359 printf("The device is already unlocked\n"); 391 printf("The device is already unlocked\n");
360 return FASTBOOT_UNLOCK; 392 return FASTBOOT_UNLOCK;
361 } 393 }
362 if ((fastboot_lock_enable() == FASTBOOT_UL_ENABLE) || force) { 394 if ((fastboot_lock_enable() == FASTBOOT_UL_ENABLE) || force) {
363 printf("It is able to unlock device. %d\n",fastboot_lock_enable()); 395 printf("It is able to unlock device. %d\n",fastboot_lock_enable());
364 396
365 #if defined(CONFIG_SECURE_UNLOCK) && defined(CONFIG_IMX_TRUSTY_OS) 397 #if defined(CONFIG_SECURE_UNLOCK) && defined(CONFIG_IMX_TRUSTY_OS)
366 if ((fastboot_bytes_received == 0) || !hab_is_enabled()) { 398 if ((fastboot_bytes_received == 0) || !hab_is_enabled()) {
367 printf("No unlock credential found or hab is not closed!\n"); 399 printf("No unlock credential found or hab is not closed!\n");
368 return FASTBOOT_LOCK_ERROR; 400 return FASTBOOT_LOCK_ERROR;
369 } else { 401 } else {
370 char *serial = get_serial(); 402 char *serial = get_serial();
371 status = trusty_verify_secure_unlock(fastboot_buf_addr, 403 status = trusty_verify_secure_unlock(fastboot_buf_addr,
372 fastboot_bytes_received, 404 fastboot_bytes_received,
373 serial, 16); 405 serial, 16);
374 if (status < 0) { 406 if (status < 0) {
375 printf("verify secure unlock credential fail due Trusty return %d\n", status); 407 printf("verify secure unlock credential fail due Trusty return %d\n", status);
376 return FASTBOOT_LOCK_ERROR; 408 return FASTBOOT_LOCK_ERROR;
377 } 409 }
378 } 410 }
379 #endif 411 #endif
380 wipe_all_userdata(); 412 wipe_all_userdata();
381 status = fastboot_set_lock_stat(FASTBOOT_UNLOCK); 413 status = fastboot_set_lock_stat(FASTBOOT_UNLOCK);
382 if (status < 0) 414 if (status < 0)
383 return FASTBOOT_LOCK_ERROR; 415 return FASTBOOT_LOCK_ERROR;
384 } else { 416 } else {
385 printf("It is not able to unlock device."); 417 printf("It is not able to unlock device.");
386 return FASTBOOT_LOCK_ERROR; 418 return FASTBOOT_LOCK_ERROR;
387 } 419 }
388 420
389 return FASTBOOT_UNLOCK; 421 return FASTBOOT_UNLOCK;
390 } 422 }
391 423
392 static FbLockState do_fastboot_lock(void) 424 static FbLockState do_fastboot_lock(void)
393 { 425 {
394 int status; 426 int status;
395 427
396 if (fastboot_get_lock_stat() == FASTBOOT_LOCK) { 428 if (fastboot_get_lock_stat() == FASTBOOT_LOCK) {
397 printf("The device is already locked\n"); 429 printf("The device is already locked\n");
398 return FASTBOOT_LOCK; 430 return FASTBOOT_LOCK;
399 } 431 }
400 432
401 wipe_all_userdata(); 433 wipe_all_userdata();
402 status = fastboot_set_lock_stat(FASTBOOT_LOCK); 434 status = fastboot_set_lock_stat(FASTBOOT_LOCK);
403 if (status < 0) 435 if (status < 0)
404 return FASTBOOT_LOCK_ERROR; 436 return FASTBOOT_LOCK_ERROR;
405 437
406 return FASTBOOT_LOCK; 438 return FASTBOOT_LOCK;
407 } 439 }
408 440
409 static bool endswith(char* s, char* subs) { 441 static bool endswith(char* s, char* subs) {
410 if (!s || !subs) 442 if (!s || !subs)
411 return false; 443 return false;
412 uint32_t len = strlen(s); 444 uint32_t len = strlen(s);
413 uint32_t sublen = strlen(subs); 445 uint32_t sublen = strlen(subs);
414 if (len < sublen) { 446 if (len < sublen) {
415 return false; 447 return false;
416 } 448 }
417 if (strncmp(s + len - sublen, subs, sublen)) { 449 if (strncmp(s + len - sublen, subs, sublen)) {
418 return false; 450 return false;
419 } 451 }
420 return true; 452 return true;
421 } 453 }
422 454
423 static void flashing(char *cmd, char *response) 455 static void flashing(char *cmd, char *response)
424 { 456 {
425 FbLockState status; 457 FbLockState status;
426 FbLockEnableResult result; 458 FbLockEnableResult result;
427 if (endswith(cmd, "lock_critical")) { 459 if (endswith(cmd, "lock_critical")) {
428 strcpy(response, "OKAY"); 460 strcpy(response, "OKAY");
429 } 461 }
430 #ifdef CONFIG_AVB_ATX 462 #ifdef CONFIG_AVB_ATX
431 else if (endswith(cmd, FASTBOOT_AVB_AT_PERM_ATTR)) { 463 else if (endswith(cmd, FASTBOOT_AVB_AT_PERM_ATTR)) {
432 if (avb_atx_fuse_perm_attr(fastboot_buf_addr, fastboot_bytes_received)) 464 if (avb_atx_fuse_perm_attr(fastboot_buf_addr, fastboot_bytes_received))
433 strcpy(response, "FAILInternal error!"); 465 strcpy(response, "FAILInternal error!");
434 else 466 else
435 strcpy(response, "OKAY"); 467 strcpy(response, "OKAY");
436 } else if (endswith(cmd, FASTBOOT_AT_GET_UNLOCK_CHALLENGE)) { 468 } else if (endswith(cmd, FASTBOOT_AT_GET_UNLOCK_CHALLENGE)) {
437 if (avb_atx_get_unlock_challenge(fsl_avb_ops.atx_ops, 469 if (avb_atx_get_unlock_challenge(fsl_avb_ops.atx_ops,
438 fastboot_buf_addr, &fastboot_bytes_received)) 470 fastboot_buf_addr, &fastboot_bytes_received))
439 strcpy(response, "FAILInternal error!"); 471 strcpy(response, "FAILInternal error!");
440 else 472 else
441 strcpy(response, "OKAY"); 473 strcpy(response, "OKAY");
442 } else if (endswith(cmd, FASTBOOT_AT_UNLOCK_VBOOT)) { 474 } else if (endswith(cmd, FASTBOOT_AT_UNLOCK_VBOOT)) {
443 if (at_unlock_vboot_is_disabled()) { 475 if (at_unlock_vboot_is_disabled()) {
444 printf("unlock vboot already disabled, can't unlock the device!\n"); 476 printf("unlock vboot already disabled, can't unlock the device!\n");
445 strcpy(response, "FAILunlock vboot already disabled!."); 477 strcpy(response, "FAILunlock vboot already disabled!.");
446 } else { 478 } else {
447 #ifdef CONFIG_AT_AUTHENTICATE_UNLOCK 479 #ifdef CONFIG_AT_AUTHENTICATE_UNLOCK
448 if (avb_atx_verify_unlock_credential(fsl_avb_ops.atx_ops, 480 if (avb_atx_verify_unlock_credential(fsl_avb_ops.atx_ops,
449 fastboot_buf_addr)) 481 fastboot_buf_addr))
450 strcpy(response, "FAILIncorrect unlock credential!"); 482 strcpy(response, "FAILIncorrect unlock credential!");
451 else { 483 else {
452 #endif 484 #endif
453 status = do_fastboot_unlock(true); 485 status = do_fastboot_unlock(true);
454 if (status != FASTBOOT_LOCK_ERROR) 486 if (status != FASTBOOT_LOCK_ERROR)
455 strcpy(response, "OKAY"); 487 strcpy(response, "OKAY");
456 else 488 else
457 strcpy(response, "FAILunlock device failed."); 489 strcpy(response, "FAILunlock device failed.");
458 #ifdef CONFIG_AT_AUTHENTICATE_UNLOCK 490 #ifdef CONFIG_AT_AUTHENTICATE_UNLOCK
459 } 491 }
460 #endif 492 #endif
461 } 493 }
462 } else if (endswith(cmd, FASTBOOT_AT_LOCK_VBOOT)) { 494 } else if (endswith(cmd, FASTBOOT_AT_LOCK_VBOOT)) {
463 if (perm_attr_are_fused()) { 495 if (perm_attr_are_fused()) {
464 status = do_fastboot_lock(); 496 status = do_fastboot_lock();
465 if (status != FASTBOOT_LOCK_ERROR) 497 if (status != FASTBOOT_LOCK_ERROR)
466 strcpy(response, "OKAY"); 498 strcpy(response, "OKAY");
467 else 499 else
468 strcpy(response, "FAILlock device failed."); 500 strcpy(response, "FAILlock device failed.");
469 } else 501 } else
470 strcpy(response, "FAILpermanent attributes not fused!"); 502 strcpy(response, "FAILpermanent attributes not fused!");
471 } else if (endswith(cmd, FASTBOOT_AT_DISABLE_UNLOCK_VBOOT)) { 503 } else if (endswith(cmd, FASTBOOT_AT_DISABLE_UNLOCK_VBOOT)) {
472 /* This command can only be called after 'oem at-lock-vboot' */ 504 /* This command can only be called after 'oem at-lock-vboot' */
473 status = fastboot_get_lock_stat(); 505 status = fastboot_get_lock_stat();
474 if (status == FASTBOOT_LOCK) { 506 if (status == FASTBOOT_LOCK) {
475 if (at_unlock_vboot_is_disabled()) { 507 if (at_unlock_vboot_is_disabled()) {
476 printf("unlock vboot already disabled!\n"); 508 printf("unlock vboot already disabled!\n");
477 strcpy(response, "OKAY"); 509 strcpy(response, "OKAY");
478 } 510 }
479 else { 511 else {
480 if (!at_disable_vboot_unlock()) 512 if (!at_disable_vboot_unlock())
481 strcpy(response, "OKAY"); 513 strcpy(response, "OKAY");
482 else 514 else
483 strcpy(response, "FAILdisable unlock vboot fail!"); 515 strcpy(response, "FAILdisable unlock vboot fail!");
484 } 516 }
485 } else 517 } else
486 strcpy(response, "FAILplease lock the device first!"); 518 strcpy(response, "FAILplease lock the device first!");
487 } 519 }
488 #endif /* CONFIG_AVB_ATX */ 520 #endif /* CONFIG_AVB_ATX */
489 #ifdef CONFIG_ANDROID_THINGS_SUPPORT 521 #ifdef CONFIG_ANDROID_THINGS_SUPPORT
490 else if (endswith(cmd, FASTBOOT_BOOTLOADER_VBOOT_KEY)) { 522 else if (endswith(cmd, FASTBOOT_BOOTLOADER_VBOOT_KEY)) {
491 strcpy(response, "OKAY"); 523 strcpy(response, "OKAY");
492 } 524 }
493 #endif /* CONFIG_ANDROID_THINGS_SUPPORT */ 525 #endif /* CONFIG_ANDROID_THINGS_SUPPORT */
494 #ifdef CONFIG_IMX_TRUSTY_OS 526 #ifdef CONFIG_IMX_TRUSTY_OS
495 else if (endswith(cmd, FASTBOOT_GET_CA_REQ)) { 527 else if (endswith(cmd, FASTBOOT_GET_CA_REQ)) {
496 uint8_t *ca_output; 528 uint8_t *ca_output;
497 uint32_t ca_length, cp_length; 529 uint32_t ca_length, cp_length;
498 if (trusty_atap_get_ca_request(fastboot_buf_addr, fastboot_bytes_received, 530 if (trusty_atap_get_ca_request(fastboot_buf_addr, fastboot_bytes_received,
499 &(ca_output), &ca_length)) { 531 &(ca_output), &ca_length)) {
500 printf("ERROR get_ca_request failed!\n"); 532 printf("ERROR get_ca_request failed!\n");
501 strcpy(response, "FAILInternal error!"); 533 strcpy(response, "FAILInternal error!");
502 } else { 534 } else {
503 cp_length = min((uint32_t)CONFIG_FASTBOOT_BUF_SIZE, ca_length); 535 cp_length = min((uint32_t)CONFIG_FASTBOOT_BUF_SIZE, ca_length);
504 memcpy(fastboot_buf_addr, ca_output, cp_length); 536 memcpy(fastboot_buf_addr, ca_output, cp_length);
505 fastboot_bytes_received = ca_length; 537 fastboot_bytes_received = ca_length;
506 strcpy(response, "OKAY"); 538 strcpy(response, "OKAY");
507 } 539 }
508 540
509 } else if (endswith(cmd, FASTBOOT_SET_CA_RESP)) { 541 } else if (endswith(cmd, FASTBOOT_SET_CA_RESP)) {
510 if (trusty_atap_set_ca_response(fastboot_buf_addr, fastboot_bytes_received)) { 542 if (trusty_atap_set_ca_response(fastboot_buf_addr, fastboot_bytes_received)) {
511 printf("ERROR set_ca_response failed!\n"); 543 printf("ERROR set_ca_response failed!\n");
512 strcpy(response, "FAILInternal error!"); 544 strcpy(response, "FAILInternal error!");
513 } else 545 } else
514 strcpy(response, "OKAY"); 546 strcpy(response, "OKAY");
515 } else if (endswith(cmd, FASTBOOT_SET_RSA_ATTESTATION_KEY_ENC)) { 547 } else if (endswith(cmd, FASTBOOT_SET_RSA_ATTESTATION_KEY_ENC)) {
516 if (trusty_set_attestation_key_enc(fastboot_buf_addr, 548 if (trusty_set_attestation_key_enc(fastboot_buf_addr,
517 fastboot_bytes_received, 549 fastboot_bytes_received,
518 KM_ALGORITHM_RSA)) { 550 KM_ALGORITHM_RSA)) {
519 printf("ERROR set rsa attestation key failed!\n"); 551 printf("ERROR set rsa attestation key failed!\n");
520 strcpy(response, "FAILInternal error!"); 552 strcpy(response, "FAILInternal error!");
521 } else { 553 } else {
522 printf("Set rsa attestation key successfully!\n"); 554 printf("Set rsa attestation key successfully!\n");
523 strcpy(response, "OKAY"); 555 strcpy(response, "OKAY");
524 } 556 }
525 } else if (endswith(cmd, FASTBOOT_SET_EC_ATTESTATION_KEY_ENC)) { 557 } else if (endswith(cmd, FASTBOOT_SET_EC_ATTESTATION_KEY_ENC)) {
526 if (trusty_set_attestation_key_enc(fastboot_buf_addr, 558 if (trusty_set_attestation_key_enc(fastboot_buf_addr,
527 fastboot_bytes_received, 559 fastboot_bytes_received,
528 KM_ALGORITHM_EC)) { 560 KM_ALGORITHM_EC)) {
529 printf("ERROR set ec attestation key failed!\n"); 561 printf("ERROR set ec attestation key failed!\n");
530 strcpy(response, "FAILInternal error!"); 562 strcpy(response, "FAILInternal error!");
531 } else { 563 } else {
532 printf("Set ec attestation key successfully!\n"); 564 printf("Set ec attestation key successfully!\n");
533 strcpy(response, "OKAY"); 565 strcpy(response, "OKAY");
534 } 566 }
535 } else if (endswith(cmd, FASTBOOT_APPEND_RSA_ATTESTATION_CERT_ENC)) { 567 } else if (endswith(cmd, FASTBOOT_APPEND_RSA_ATTESTATION_CERT_ENC)) {
536 if (trusty_append_attestation_cert_chain_enc(fastboot_buf_addr, 568 if (trusty_append_attestation_cert_chain_enc(fastboot_buf_addr,
537 fastboot_bytes_received, 569 fastboot_bytes_received,
538 KM_ALGORITHM_RSA)) { 570 KM_ALGORITHM_RSA)) {
539 printf("ERROR append rsa attestation cert chain failed!\n"); 571 printf("ERROR append rsa attestation cert chain failed!\n");
540 strcpy(response, "FAILInternal error!"); 572 strcpy(response, "FAILInternal error!");
541 } else { 573 } else {
542 printf("Append rsa attestation key successfully!\n"); 574 printf("Append rsa attestation key successfully!\n");
543 strcpy(response, "OKAY"); 575 strcpy(response, "OKAY");
544 } 576 }
545 } else if (endswith(cmd, FASTBOOT_APPEND_EC_ATTESTATION_CERT_ENC)) { 577 } else if (endswith(cmd, FASTBOOT_APPEND_EC_ATTESTATION_CERT_ENC)) {
546 if (trusty_append_attestation_cert_chain_enc(fastboot_buf_addr, 578 if (trusty_append_attestation_cert_chain_enc(fastboot_buf_addr,
547 fastboot_bytes_received, 579 fastboot_bytes_received,
548 KM_ALGORITHM_EC)) { 580 KM_ALGORITHM_EC)) {
549 printf("ERROR append ec attestation cert chain failed!\n"); 581 printf("ERROR append ec attestation cert chain failed!\n");
550 strcpy(response, "FAILInternal error!"); 582 strcpy(response, "FAILInternal error!");
551 } else { 583 } else {
552 printf("Append ec attestation key successfully!\n"); 584 printf("Append ec attestation key successfully!\n");
553 strcpy(response, "OKAY"); 585 strcpy(response, "OKAY");
554 } 586 }
555 } else if (endswith(cmd, FASTBOOT_SET_RSA_ATTESTATION_KEY)) { 587 } else if (endswith(cmd, FASTBOOT_SET_RSA_ATTESTATION_KEY)) {
556 if (trusty_set_attestation_key(fastboot_buf_addr, 588 if (trusty_set_attestation_key(fastboot_buf_addr,
557 fastboot_bytes_received, 589 fastboot_bytes_received,
558 KM_ALGORITHM_RSA)) { 590 KM_ALGORITHM_RSA)) {
559 printf("ERROR set rsa attestation key failed!\n"); 591 printf("ERROR set rsa attestation key failed!\n");
560 strcpy(response, "FAILInternal error!"); 592 strcpy(response, "FAILInternal error!");
561 } else { 593 } else {
562 printf("Set rsa attestation key successfully!\n"); 594 printf("Set rsa attestation key successfully!\n");
563 strcpy(response, "OKAY"); 595 strcpy(response, "OKAY");
564 } 596 }
565 } else if (endswith(cmd, FASTBOOT_SET_EC_ATTESTATION_KEY)) { 597 } else if (endswith(cmd, FASTBOOT_SET_EC_ATTESTATION_KEY)) {
566 if (trusty_set_attestation_key(fastboot_buf_addr, 598 if (trusty_set_attestation_key(fastboot_buf_addr,
567 fastboot_bytes_received, 599 fastboot_bytes_received,
568 KM_ALGORITHM_EC)) { 600 KM_ALGORITHM_EC)) {
569 printf("ERROR set ec attestation key failed!\n"); 601 printf("ERROR set ec attestation key failed!\n");
570 strcpy(response, "FAILInternal error!"); 602 strcpy(response, "FAILInternal error!");
571 } else { 603 } else {
572 printf("Set ec attestation key successfully!\n"); 604 printf("Set ec attestation key successfully!\n");
573 strcpy(response, "OKAY"); 605 strcpy(response, "OKAY");
574 } 606 }
575 } else if (endswith(cmd, FASTBOOT_APPEND_RSA_ATTESTATION_CERT)) { 607 } else if (endswith(cmd, FASTBOOT_APPEND_RSA_ATTESTATION_CERT)) {
576 if (trusty_append_attestation_cert_chain(fastboot_buf_addr, 608 if (trusty_append_attestation_cert_chain(fastboot_buf_addr,
577 fastboot_bytes_received, 609 fastboot_bytes_received,
578 KM_ALGORITHM_RSA)) { 610 KM_ALGORITHM_RSA)) {
579 printf("ERROR append rsa attestation cert chain failed!\n"); 611 printf("ERROR append rsa attestation cert chain failed!\n");
580 strcpy(response, "FAILInternal error!"); 612 strcpy(response, "FAILInternal error!");
581 } else { 613 } else {
582 printf("Append rsa attestation key successfully!\n"); 614 printf("Append rsa attestation key successfully!\n");
583 strcpy(response, "OKAY"); 615 strcpy(response, "OKAY");
584 } 616 }
585 } else if (endswith(cmd, FASTBOOT_APPEND_EC_ATTESTATION_CERT)) { 617 } else if (endswith(cmd, FASTBOOT_APPEND_EC_ATTESTATION_CERT)) {
586 if (trusty_append_attestation_cert_chain(fastboot_buf_addr, 618 if (trusty_append_attestation_cert_chain(fastboot_buf_addr,
587 fastboot_bytes_received, 619 fastboot_bytes_received,
588 KM_ALGORITHM_EC)) { 620 KM_ALGORITHM_EC)) {
589 printf("ERROR append ec attestation cert chain failed!\n"); 621 printf("ERROR append ec attestation cert chain failed!\n");
590 strcpy(response, "FAILInternal error!"); 622 strcpy(response, "FAILInternal error!");
591 } else { 623 } else {
592 printf("Append ec attestation key successfully!\n"); 624 printf("Append ec attestation key successfully!\n");
593 strcpy(response, "OKAY"); 625 strcpy(response, "OKAY");
594 } 626 }
595 } else if (endswith(cmd, FASTBOOT_GET_MPPUBK)) { 627 } else if (endswith(cmd, FASTBOOT_GET_MPPUBK)) {
596 if (fastboot_get_mppubk(fastboot_buf_addr, &fastboot_bytes_received)) { 628 if (fastboot_get_mppubk(fastboot_buf_addr, &fastboot_bytes_received)) {
597 printf("ERROR Generate mppubk failed!\n"); 629 printf("ERROR Generate mppubk failed!\n");
598 strcpy(response, "FAILGenerate mppubk failed!"); 630 strcpy(response, "FAILGenerate mppubk failed!");
599 } else { 631 } else {
600 printf("mppubk generated!\n"); 632 printf("mppubk generated!\n");
601 strcpy(response, "OKAY"); 633 strcpy(response, "OKAY");
602 } 634 }
603 } else if (endswith(cmd, FASTBOOT_GET_SERIAL_NUMBER)) { 635 } else if (endswith(cmd, FASTBOOT_GET_SERIAL_NUMBER)) {
604 char *serial = get_serial(); 636 char *serial = get_serial();
605 637
606 if (!serial) 638 if (!serial)
607 strcpy(response, "FAILSerial number not support!"); 639 strcpy(response, "FAILSerial number not support!");
608 else { 640 else {
609 /* Serial number will not exceed 16 bytes.*/ 641 /* Serial number will not exceed 16 bytes.*/
610 strncpy(fastboot_buf_addr, serial, 16); 642 strncpy(fastboot_buf_addr, serial, 16);
611 fastboot_bytes_received = 16; 643 fastboot_bytes_received = 16;
612 printf("Serial number generated!\n"); 644 printf("Serial number generated!\n");
613 strcpy(response, "OKAY"); 645 strcpy(response, "OKAY");
614 } 646 }
615 } 647 }
616 #ifndef CONFIG_AVB_ATX 648 #ifndef CONFIG_AVB_ATX
617 else if (endswith(cmd, FASTBOOT_SET_RPMB_KEY)) { 649 else if (endswith(cmd, FASTBOOT_SET_RPMB_KEY)) {
618 if (fastboot_set_rpmb_key(fastboot_buf_addr, fastboot_bytes_received)) { 650 if (fastboot_set_rpmb_key(fastboot_buf_addr, fastboot_bytes_received)) {
619 printf("ERROR set rpmb key failed!\n"); 651 printf("ERROR set rpmb key failed!\n");
620 strcpy(response, "FAILset rpmb key failed!"); 652 strcpy(response, "FAILset rpmb key failed!");
621 } else 653 } else
622 strcpy(response, "OKAY"); 654 strcpy(response, "OKAY");
623 } else if (endswith(cmd, FASTBOOT_SET_RPMB_RANDOM_KEY)) { 655 } else if (endswith(cmd, FASTBOOT_SET_RPMB_RANDOM_KEY)) {
624 if (fastboot_set_rpmb_random_key()) { 656 if (fastboot_set_rpmb_random_key()) {
625 printf("ERROR set rpmb random key failed!\n"); 657 printf("ERROR set rpmb random key failed!\n");
626 strcpy(response, "FAILset rpmb random key failed!"); 658 strcpy(response, "FAILset rpmb random key failed!");
627 } else 659 } else
628 strcpy(response, "OKAY"); 660 strcpy(response, "OKAY");
629 } else if (endswith(cmd, FASTBOOT_SET_VBMETA_PUBLIC_KEY)) { 661 } else if (endswith(cmd, FASTBOOT_SET_VBMETA_PUBLIC_KEY)) {
630 if (avb_set_public_key(fastboot_buf_addr, 662 if (avb_set_public_key(fastboot_buf_addr,
631 fastboot_bytes_received)) 663 fastboot_bytes_received))
632 strcpy(response, "FAILcan't set public key!"); 664 strcpy(response, "FAILcan't set public key!");
633 else 665 else
634 strcpy(response, "OKAY"); 666 strcpy(response, "OKAY");
635 } 667 }
636 #endif /* !CONFIG_AVB_ATX */ 668 #endif /* !CONFIG_AVB_ATX */
637 #endif /* CONFIG_IMX_TRUSTY_OS */ 669 #endif /* CONFIG_IMX_TRUSTY_OS */
638 else if (endswith(cmd, "unlock_critical")) { 670 else if (endswith(cmd, "unlock_critical")) {
639 strcpy(response, "OKAY"); 671 strcpy(response, "OKAY");
640 } else if (endswith(cmd, "unlock")) { 672 } else if (endswith(cmd, "unlock")) {
641 printf("flashing unlock.\n"); 673 printf("flashing unlock.\n");
642 #ifdef CONFIG_AVB_ATX 674 #ifdef CONFIG_AVB_ATX
643 /* We should do nothing here For Android Things which 675 /* We should do nothing here For Android Things which
644 * enables the authenticated unlock feature. 676 * enables the authenticated unlock feature.
645 */ 677 */
646 strcpy(response, "OKAY"); 678 strcpy(response, "OKAY");
647 #else 679 #else
648 status = do_fastboot_unlock(false); 680 status = do_fastboot_unlock(false);
649 if (status != FASTBOOT_LOCK_ERROR) 681 if (status != FASTBOOT_LOCK_ERROR)
650 strcpy(response, "OKAY"); 682 strcpy(response, "OKAY");
651 else 683 else
652 strcpy(response, "FAILunlock device failed."); 684 strcpy(response, "FAILunlock device failed.");
653 #endif 685 #endif
654 } else if (endswith(cmd, "lock")) { 686 } else if (endswith(cmd, "lock")) {
655 #ifdef CONFIG_AVB_ATX 687 #ifdef CONFIG_AVB_ATX
656 /* We should do nothing here For Android Things which 688 /* We should do nothing here For Android Things which
657 * enables the at-lock-vboot feature. 689 * enables the at-lock-vboot feature.
658 */ 690 */
659 strcpy(response, "OKAY"); 691 strcpy(response, "OKAY");
660 #else 692 #else
661 printf("flashing lock.\n"); 693 printf("flashing lock.\n");
662 status = do_fastboot_lock(); 694 status = do_fastboot_lock();
663 if (status != FASTBOOT_LOCK_ERROR) 695 if (status != FASTBOOT_LOCK_ERROR)
664 strcpy(response, "OKAY"); 696 strcpy(response, "OKAY");
665 else 697 else
666 strcpy(response, "FAILlock device failed."); 698 strcpy(response, "FAILlock device failed.");
667 #endif 699 #endif
668 } else if (endswith(cmd, "get_unlock_ability")) { 700 } else if (endswith(cmd, "get_unlock_ability")) {
669 result = fastboot_lock_enable(); 701 result = fastboot_lock_enable();
670 if (result == FASTBOOT_UL_ENABLE) { 702 if (result == FASTBOOT_UL_ENABLE) {
671 fastboot_tx_write_more("INFO1"); 703 fastboot_tx_write_more("INFO1");
672 strcpy(response, "OKAY"); 704 strcpy(response, "OKAY");
673 } else if (result == FASTBOOT_UL_DISABLE) { 705 } else if (result == FASTBOOT_UL_DISABLE) {
674 fastboot_tx_write_more("INFO0"); 706 fastboot_tx_write_more("INFO0");
675 strcpy(response, "OKAY"); 707 strcpy(response, "OKAY");
676 } else { 708 } else {
677 printf("flashing get_unlock_ability fail!\n"); 709 printf("flashing get_unlock_ability fail!\n");
678 strcpy(response, "FAILget unlock ability failed."); 710 strcpy(response, "FAILget unlock ability failed.");
679 } 711 }
680 } else { 712 } else {
681 printf("Unknown flashing command:%s\n", cmd); 713 printf("Unknown flashing command:%s\n", cmd);
682 strcpy(response, "FAILcommand not defined"); 714 strcpy(response, "FAILcommand not defined");
683 } 715 }
684 fastboot_tx_write_more(response); 716 fastboot_tx_write_more(response);
685 717
686 /* Must call fastboot_none_resp before returning from the dispatch function 718 /* Must call fastboot_none_resp before returning from the dispatch function
687 * which uses fastboot_tx_write_more 719 * which uses fastboot_tx_write_more
688 */ 720 */
689 fastboot_none_resp(response); 721 fastboot_none_resp(response);
690 } 722 }
691 #endif /* CONFIG_FASTBOOT_LOCK */ 723 #endif /* CONFIG_FASTBOOT_LOCK */
692 724
693 #ifdef CONFIG_AVB_SUPPORT 725 #ifdef CONFIG_AVB_SUPPORT
694 static void set_active_avb(char *cmd, char *response) 726 static void set_active_avb(char *cmd, char *response)
695 { 727 {
696 AvbIOResult ret; 728 AvbIOResult ret;
697 int slot = 0; 729 int slot = 0;
698 730
699 if (!cmd) { 731 if (!cmd) {
700 pr_err("missing slot suffix\n"); 732 pr_err("missing slot suffix\n");
701 fastboot_fail("missing slot suffix", response); 733 fastboot_fail("missing slot suffix", response);
702 return; 734 return;
703 } 735 }
704 736
705 slot = slotidx_from_suffix(cmd); 737 slot = slotidx_from_suffix(cmd);
706 738
707 if (slot < 0) { 739 if (slot < 0) {
708 fastboot_fail("err slot suffix", response); 740 fastboot_fail("err slot suffix", response);
709 return; 741 return;
710 } 742 }
711 743
712 ret = avb_ab_mark_slot_active(&fsl_avb_ab_ops, slot); 744 ret = avb_ab_mark_slot_active(&fsl_avb_ab_ops, slot);
713 if (ret != AVB_IO_RESULT_OK) 745 if (ret != AVB_IO_RESULT_OK)
714 fastboot_fail("avb IO error", response); 746 fastboot_fail("avb IO error", response);
715 else 747 else
716 fastboot_okay(NULL, response); 748 fastboot_okay(NULL, response);
717 749
718 return; 750 return;
719 } 751 }
720 #endif /*CONFIG_AVB_SUPPORT*/ 752 #endif /*CONFIG_AVB_SUPPORT*/
721 753
722 #if CONFIG_IS_ENABLED(FASTBOOT_FLASH) 754 #if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
723 static void flash(char *cmd, char *response) 755 static void flash(char *cmd, char *response)
724 { 756 {
725 if (!cmd) { 757 if (!cmd) {
726 pr_err("missing partition name"); 758 pr_err("missing partition name");
727 fastboot_fail("missing partition name", response); 759 fastboot_fail("missing partition name", response);
728 return; 760 return;
729 } 761 }
730 762
731 /* Always enable image flash for Android Things. */ 763 /* Always enable image flash for Android Things. */
732 #if defined(CONFIG_FASTBOOT_LOCK) && !defined(CONFIG_AVB_ATX) 764 #if defined(CONFIG_FASTBOOT_LOCK) && !defined(CONFIG_AVB_ATX)
733 int status; 765 int status;
734 status = fastboot_get_lock_stat(); 766 status = fastboot_get_lock_stat();
735 767
736 if (status == FASTBOOT_LOCK) { 768 if (status == FASTBOOT_LOCK) {
737 pr_err("device is LOCKed!\n"); 769 pr_err("device is LOCKed!\n");
738 fastboot_fail("device is locked.", response); 770 fastboot_fail("device is locked.", response);
739 return; 771 return;
740 772
741 } else if (status == FASTBOOT_LOCK_ERROR) { 773 } else if (status == FASTBOOT_LOCK_ERROR) {
742 pr_err("write lock status into device!\n"); 774 pr_err("write lock status into device!\n");
743 fastboot_set_lock_stat(FASTBOOT_LOCK); 775 fastboot_set_lock_stat(FASTBOOT_LOCK);
744 fastboot_fail("device is locked.", response); 776 fastboot_fail("device is locked.", response);
745 return; 777 return;
746 } 778 }
747 #endif 779 #endif
748 780
749 fastboot_process_flash(cmd, fastboot_buf_addr, 781 fastboot_process_flash(cmd, fastboot_buf_addr,
750 fastboot_bytes_received, response); 782 fastboot_bytes_received, response);
751 783
752 #if defined(CONFIG_FASTBOOT_LOCK) 784 #if defined(CONFIG_FASTBOOT_LOCK)
753 if (strncmp(cmd, "gpt", 3) == 0) { 785 if (strncmp(cmd, "gpt", 3) == 0) {
754 int gpt_valid = 0; 786 int gpt_valid = 0;
755 gpt_valid = partition_table_valid(); 787 gpt_valid = partition_table_valid();
756 /* If gpt is valid, load partitons table into memory. 788 /* If gpt is valid, load partitons table into memory.
757 So if the next command is "fastboot reboot bootloader", 789 So if the next command is "fastboot reboot bootloader",
758 it can find the "misc" partition to r/w. */ 790 it can find the "misc" partition to r/w. */
759 if(gpt_valid) { 791 if(gpt_valid) {
760 fastboot_load_partitions(); 792 fastboot_load_partitions();
761 /* Unlock device if the gpt is valid */ 793 /* Unlock device if the gpt is valid */
762 do_fastboot_unlock(true); 794 do_fastboot_unlock(true);
763 } 795 }
764 } 796 }
765 797
766 #endif 798 #endif
767 } 799 }
768 800
769 static void erase(char *cmd, char *response) 801 static void erase(char *cmd, char *response)
770 { 802 {
771 if (!cmd) { 803 if (!cmd) {
772 pr_err("missing partition name"); 804 pr_err("missing partition name");
773 fastboot_fail("missing partition name", response); 805 fastboot_fail("missing partition name", response);
774 return; 806 return;
775 } 807 }
776 808
777 #if defined(CONFIG_FASTBOOT_LOCK) && !defined(CONFIG_AVB_ATX) 809 #if defined(CONFIG_FASTBOOT_LOCK) && !defined(CONFIG_AVB_ATX)
778 FbLockState status; 810 FbLockState status;
779 status = fastboot_get_lock_stat(); 811 status = fastboot_get_lock_stat();
780 if (status == FASTBOOT_LOCK) { 812 if (status == FASTBOOT_LOCK) {
781 pr_err("device is LOCKed!\n"); 813 pr_err("device is LOCKed!\n");
782 fastboot_fail("device is locked.", response); 814 fastboot_fail("device is locked.", response);
783 return; 815 return;
784 } else if (status == FASTBOOT_LOCK_ERROR) { 816 } else if (status == FASTBOOT_LOCK_ERROR) {
785 pr_err("write lock status into device!\n"); 817 pr_err("write lock status into device!\n");
786 fastboot_set_lock_stat(FASTBOOT_LOCK); 818 fastboot_set_lock_stat(FASTBOOT_LOCK);
787 fastboot_fail("device is locked.", response); 819 fastboot_fail("device is locked.", response);
788 return; 820 return;
789 } 821 }
790 #endif 822 #endif
791 fastboot_process_erase(cmd, response); 823 fastboot_process_erase(cmd, response);
792 } 824 }
793 #endif 825 #endif
794 826
795 /** 827 /**
796 * fastboot_set_reboot_flag() - Set flag to indicate reboot-bootloader 828 * fastboot_set_reboot_flag() - Set flag to indicate reboot-bootloader
797 * 829 *
798 * This is a redefinition, since BSP dose not need the function of 830 * This is a redefinition, since BSP dose not need the function of
799 * "reboot into bootloader", and with BCB support, the flag can be 831 * "reboot into bootloader", and with BCB support, the flag can be
800 * set with another way. Redefine this function to override the weak 832 * set with another way. Redefine this function to override the weak
801 * definition to avoid error return value. 833 * definition to avoid error return value.
802 */ 834 */
803 int fastboot_set_reboot_flag(void) 835 int fastboot_set_reboot_flag(void)
804 { 836 {
805 return 0; 837 return 0;
806 } 838 }
807 839
808 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) 840 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
809 /** 841 /**
810 * run_ucmd() - Execute the UCmd command 842 * run_ucmd() - Execute the UCmd command
811 * 843 *
812 * @cmd_parameter: Pointer to command parameter 844 * @cmd_parameter: Pointer to command parameter
813 * @response: Pointer to fastboot response buffer 845 * @response: Pointer to fastboot response buffer
814 */ 846 */
815 static void run_ucmd(char *cmd_parameter, char *response) 847 static void run_ucmd(char *cmd_parameter, char *response)
816 { 848 {
817 if (!cmd_parameter) { 849 if (!cmd_parameter) {
818 pr_err("missing slot suffix\n"); 850 pr_err("missing slot suffix\n");
819 fastboot_fail("missing command", response); 851 fastboot_fail("missing command", response);
820 return; 852 return;
821 } 853 }
822 if(run_command(cmd_parameter, 0)) { 854 if(run_command(cmd_parameter, 0)) {
823 fastboot_fail("", response); 855 fastboot_fail("", response);
824 } else { 856 } else {
825 fastboot_okay(NULL, response); 857 fastboot_okay(NULL, response);
826 /* cmd may impact fastboot related environment*/ 858 /* cmd may impact fastboot related environment*/
827 fastboot_setup(); 859 fastboot_setup();
828 } 860 }
829 } 861 }
830 862
831 static char g_a_cmd_buff[64]; 863 static char g_a_cmd_buff[64];
832 864
833 void fastboot_acmd_complete(void) 865 void fastboot_acmd_complete(void)
834 { 866 {
835 run_command(g_a_cmd_buff, 0); 867 run_command(g_a_cmd_buff, 0);
836 } 868 }
837 869
838 /** 870 /**
839 * run_acmd() - Execute the ACmd command 871 * run_acmd() - Execute the ACmd command
840 * 872 *
841 * @cmd_parameter: Pointer to command parameter 873 * @cmd_parameter: Pointer to command parameter
842 * @response: Pointer to fastboot response buffer 874 * @response: Pointer to fastboot response buffer
843 */ 875 */
844 static void run_acmd(char *cmd_parameter, char *response) 876 static void run_acmd(char *cmd_parameter, char *response)
845 { 877 {
846 if (!cmd_parameter) { 878 if (!cmd_parameter) {
847 pr_err("missing slot suffix\n"); 879 pr_err("missing slot suffix\n");
848 fastboot_fail("missing command", response); 880 fastboot_fail("missing command", response);
849 return; 881 return;
850 } 882 }
851 strcpy(g_a_cmd_buff, cmd_parameter); 883 strcpy(g_a_cmd_buff, cmd_parameter);
852 fastboot_okay(NULL, response); 884 fastboot_okay(NULL, response);
853 } 885 }
854 #endif 886 #endif
855 887
856 static const struct { 888 static const struct {
857 const char *command; 889 const char *command;
858 void (*dispatch)(char *cmd_parameter, char *response); 890 void (*dispatch)(char *cmd_parameter, char *response);
859 } commands[FASTBOOT_COMMAND_COUNT] = { 891 } commands[FASTBOOT_COMMAND_COUNT] = {
860 [FASTBOOT_COMMAND_REBOOT_BOOTLOADER] = { 892 [FASTBOOT_COMMAND_REBOOT_BOOTLOADER] = {
861 .command = "reboot-bootloader", 893 .command = "reboot-bootloader",
862 .dispatch = reboot_bootloader, 894 .dispatch = reboot_bootloader,
863 }, 895 },
864 [FASTBOOT_COMMAND_UPLOAD] = { 896 [FASTBOOT_COMMAND_UPLOAD] = {
865 .command = "upload", 897 .command = "upload",
866 .dispatch = upload, 898 .dispatch = upload,
867 }, 899 },
868 [FASTBOOT_COMMAND_GETSTAGED] = { 900 [FASTBOOT_COMMAND_GETSTAGED] = {
869 .command = "get_staged", 901 .command = "get_staged",
870 .dispatch = upload, 902 .dispatch = upload,
871 }, 903 },
872 #if defined(CONFIG_FASTBOOT_LOCK) 904 #if defined(CONFIG_FASTBOOT_LOCK)
873 [FASTBOOT_COMMAND_FLASHING] = { 905 [FASTBOOT_COMMAND_FLASHING] = {
874 .command = "flashing", 906 .command = "flashing",
875 .dispatch = flashing, 907 .dispatch = flashing,
876 }, 908 },
877 [FASTBOOT_COMMAND_OEM] = { 909 [FASTBOOT_COMMAND_OEM] = {
878 .command = "oem", 910 .command = "oem",
879 .dispatch = flashing, 911 .dispatch = flashing,
880 }, 912 },
881 #endif 913 #endif
882 #ifdef CONFIG_AVB_SUPPORT 914 #ifdef CONFIG_AVB_SUPPORT
883 [FASTBOOT_COMMAND_SETACTIVE] = { 915 [FASTBOOT_COMMAND_SETACTIVE] = {
884 .command = "set_active", 916 .command = "set_active",
885 .dispatch = set_active_avb, 917 .dispatch = set_active_avb,
886 }, 918 },
887 #endif 919 #endif
888 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) 920 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
889 [FASTBOOT_COMMAND_UCMD] = { 921 [FASTBOOT_COMMAND_UCMD] = {
890 .command = "UCmd", 922 .command = "UCmd",
891 .dispatch = run_ucmd, 923 .dispatch = run_ucmd,
892 }, 924 },
893 [FASTBOOT_COMMAND_ACMD] = { 925 [FASTBOOT_COMMAND_ACMD] = {
894 .command ="ACmd", 926 .command ="ACmd",
895 .dispatch = run_acmd, 927 .dispatch = run_acmd,
896 }, 928 },
897 #endif 929 #endif
898 [FASTBOOT_COMMAND_REBOOT] = { 930 [FASTBOOT_COMMAND_REBOOT] = {
899 .command = "reboot", 931 .command = "reboot",
900 .dispatch = okay, 932 .dispatch = okay,
901 }, 933 },
902 [FASTBOOT_COMMAND_GETVAR] = { 934 [FASTBOOT_COMMAND_GETVAR] = {
903 .command = "getvar", 935 .command = "getvar",
904 .dispatch = getvar, 936 .dispatch = getvar,
905 }, 937 },
906 [FASTBOOT_COMMAND_DOWNLOAD] = { 938 [FASTBOOT_COMMAND_DOWNLOAD] = {
907 .command = "download", 939 .command = "download",
908 .dispatch = download, 940 .dispatch = download,
909 }, 941 },
910 [FASTBOOT_COMMAND_BOOT] = { 942 [FASTBOOT_COMMAND_BOOT] = {
911 .command = "boot", 943 .command = "boot",
912 .dispatch = okay, 944 .dispatch = okay,
913 }, 945 },
914 [FASTBOOT_COMMAND_CONTINUE] = { 946 [FASTBOOT_COMMAND_CONTINUE] = {
915 .command = "continue", 947 .command = "continue",
916 .dispatch = okay, 948 .dispatch = okay,
917 }, 949 },
918 #ifdef CONFIG_FASTBOOT_FLASH 950 #ifdef CONFIG_FASTBOOT_FLASH
919 [FASTBOOT_COMMAND_FLASH] = { 951 [FASTBOOT_COMMAND_FLASH] = {
920 .command = "flash", 952 .command = "flash",
921 .dispatch = flash, 953 .dispatch = flash,
922 }, 954 },
923 [FASTBOOT_COMMAND_ERASE] = { 955 [FASTBOOT_COMMAND_ERASE] = {
924 .command = "erase", 956 .command = "erase",
925 .dispatch = erase, 957 .dispatch = erase,
926 }, 958 },
927 #endif 959 #endif
928 #ifdef CONFIG_AVB_ATX 960 #ifdef CONFIG_AVB_ATX
929 [FASTBOOT_COMMAND_STAGE] = { 961 [FASTBOOT_COMMAND_STAGE] = {
930 .command = "stage", 962 .command = "stage",
931 .dispatch = download, 963 .dispatch = download,
964 },
965 #endif
966 #ifdef CONFIG_ANDROID_RECOVERY
967 [FASTBOOT_COMMAND_RECOVERY_FASTBOOT] = {
968 .command = "reboot-fastboot",
969 .dispatch = reboot_fastboot,
932 }, 970 },
933 #endif 971 #endif
934 }; 972 };
935 973
936 /** 974 /**
937 * fastboot_handle_command - Handle fastboot command 975 * fastboot_handle_command - Handle fastboot command
938 * 976 *
939 * @cmd_string: Pointer to command string 977 * @cmd_string: Pointer to command string
940 * @response: Pointer to fastboot response buffer 978 * @response: Pointer to fastboot response buffer
941 * 979 *
942 * Return: Executed command, or -1 if not recognized 980 * Return: Executed command, or -1 if not recognized
943 */ 981 */
944 int fastboot_handle_command(char *cmd_string, char *response) 982 int fastboot_handle_command(char *cmd_string, char *response)
945 { 983 {
946 int i; 984 int i;
947 char *cmd_parameter; 985 char *cmd_parameter;
948 986
949 cmd_parameter = cmd_string; 987 cmd_parameter = cmd_string;
950 strsep(&cmd_parameter, ":"); 988 strsep(&cmd_parameter, ":");
951 /* separate cmdstring for "fastboot oem/flashing" with a blank */ 989 /* separate cmdstring for "fastboot oem/flashing" with a blank */
952 if(cmd_parameter == NULL) 990 if(cmd_parameter == NULL)
953 { 991 {
954 cmd_parameter = cmd_string; 992 cmd_parameter = cmd_string;
955 strsep(&cmd_parameter, " "); 993 strsep(&cmd_parameter, " ");
956 } 994 }
957 995
958 for (i = 0; i < ARRAY_SIZE(commands); i++) { 996 for (i = 0; i < ARRAY_SIZE(commands); i++) {
959 if (commands[i].command != NULL && 997 if (commands[i].command != NULL &&
960 !strcmp(commands[i].command, cmd_string)) { 998 !strcmp(commands[i].command, cmd_string)) {
961 if (commands[i].dispatch) { 999 if (commands[i].dispatch) {
962 commands[i].dispatch(cmd_parameter, 1000 commands[i].dispatch(cmd_parameter,
963 response); 1001 response);
964 return i; 1002 return i;
965 } else { 1003 } else {
966 break; 1004 break;
967 } 1005 }
968 } 1006 }
969 } 1007 }
970 1008
971 pr_err("command %s not recognized.\n", cmd_string); 1009 pr_err("command %s not recognized.\n", cmd_string);
972 fastboot_fail("unrecognized command", response); 1010 fastboot_fail("unrecognized command", response);
973 return -1; 1011 return -1;
974 } 1012 }
975 1013
drivers/fastboot/fb_fsl/fb_fsl_getvar.c
1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+
2 /* 2 /*
3 * Copyright 2019 NXP 3 * Copyright 2019 NXP
4 */ 4 */
5 5
6 #include <common.h> 6 #include <common.h>
7 #include <asm/mach-imx/sys_proto.h> 7 #include <asm/mach-imx/sys_proto.h>
8 #include <fb_fsl.h> 8 #include <fb_fsl.h>
9 #include <fastboot.h> 9 #include <fastboot.h>
10 #include <mmc.h> 10 #include <mmc.h>
11 #include <android_image.h> 11 #include <android_image.h>
12 #include <asm/bootm.h> 12 #include <asm/bootm.h>
13 #include <nand.h> 13 #include <nand.h>
14 #include <part.h> 14 #include <part.h>
15 #include <sparse_format.h> 15 #include <sparse_format.h>
16 #include <image-sparse.h> 16 #include <image-sparse.h>
17 #include <image.h> 17 #include <image.h>
18 #include <asm/mach-imx/boot_mode.h> 18 #include <asm/mach-imx/boot_mode.h>
19 #include <asm/arch/sys_proto.h> 19 #include <asm/arch/sys_proto.h>
20 #include <asm/setup.h> 20 #include <asm/setup.h>
21 #include <env.h> 21 #include <env.h>
22 #include <version.h> 22 #include <version.h>
23 23
24 #ifdef CONFIG_AVB_SUPPORT 24 #ifdef CONFIG_AVB_SUPPORT
25 #include <dt_table.h> 25 #include <dt_table.h>
26 #include <fsl_avb.h> 26 #include <fsl_avb.h>
27 #endif 27 #endif
28 28
29 #ifdef CONFIG_ANDROID_THINGS_SUPPORT 29 #ifdef CONFIG_ANDROID_THINGS_SUPPORT
30 #include <asm-generic/gpio.h> 30 #include <asm-generic/gpio.h>
31 #include <asm/mach-imx/gpio.h> 31 #include <asm/mach-imx/gpio.h>
32 #include "../lib/avb/fsl/fsl_avbkey.h" 32 #include "../lib/avb/fsl/fsl_avbkey.h"
33 #include "../arch/arm/include/asm/mach-imx/hab.h" 33 #include "../arch/arm/include/asm/mach-imx/hab.h"
34 #endif 34 #endif
35 35
36 #if defined(CONFIG_FASTBOOT_LOCK) 36 #if defined(CONFIG_FASTBOOT_LOCK)
37 #include "fastboot_lock_unlock.h" 37 #include "fastboot_lock_unlock.h"
38 #endif 38 #endif
39 39
40 #include "fb_fsl_common.h" 40 #include "fb_fsl_common.h"
41 41
42 #ifdef CONFIG_IMX_TRUSTY_OS 42 #ifdef CONFIG_IMX_TRUSTY_OS
43 #include "u-boot/sha256.h" 43 #include "u-boot/sha256.h"
44 #include <trusty/libtipc.h> 44 #include <trusty/libtipc.h>
45 45
46 #define ATAP_UUID_SIZE 32 46 #define ATAP_UUID_SIZE 32
47 #define ATAP_UUID_STR_SIZE ((ATAP_UUID_SIZE*2) + 1) 47 #define ATAP_UUID_STR_SIZE ((ATAP_UUID_SIZE*2) + 1)
48 #endif 48 #endif
49 49
50 #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) 50 #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M)
51 #define FASTBOOT_COMMON_VAR_NUM 14 51 #define FASTBOOT_COMMON_VAR_NUM 15
52 #else 52 #else
53 #define FASTBOOT_COMMON_VAR_NUM 13 53 #define FASTBOOT_COMMON_VAR_NUM 14
54 #endif 54 #endif
55 55
56 #define FASTBOOT_VAR_YES "yes" 56 #define FASTBOOT_VAR_YES "yes"
57 #define FASTBOOT_VAR_NO "no" 57 #define FASTBOOT_VAR_NO "no"
58 58
59 /* common variables of fastboot getvar command */ 59 /* common variables of fastboot getvar command */
60 char *fastboot_common_var[FASTBOOT_COMMON_VAR_NUM] = { 60 char *fastboot_common_var[FASTBOOT_COMMON_VAR_NUM] = {
61 "version", 61 "version",
62 "version-bootloader", 62 "version-bootloader",
63 "version-baseband", 63 "version-baseband",
64 "product", 64 "product",
65 "secure", 65 "secure",
66 "max-download-size", 66 "max-download-size",
67 "erase-block-size", 67 "erase-block-size",
68 "logical-block-size", 68 "logical-block-size",
69 "unlocked", 69 "unlocked",
70 "off-mode-charge", 70 "off-mode-charge",
71 "battery-voltage", 71 "battery-voltage",
72 "variant", 72 "variant",
73 "battery-soc-ok", 73 "battery-soc-ok",
74 "is-userspace",
74 #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) 75 #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M)
75 "baseboard_id" 76 "baseboard_id"
76 #endif 77 #endif
77 }; 78 };
78 79
79 /* at-vboot-state variable list */ 80 /* at-vboot-state variable list */
80 #ifdef CONFIG_AVB_ATX 81 #ifdef CONFIG_AVB_ATX
81 #define AT_VBOOT_STATE_VAR_NUM 6 82 #define AT_VBOOT_STATE_VAR_NUM 6
82 extern struct imx_sec_config_fuse_t const imx_sec_config_fuse; 83 extern struct imx_sec_config_fuse_t const imx_sec_config_fuse;
83 extern int fuse_read(u32 bank, u32 word, u32 *val); 84 extern int fuse_read(u32 bank, u32 word, u32 *val);
84 85
85 char *fastboot_at_vboot_state_var[AT_VBOOT_STATE_VAR_NUM] = { 86 char *fastboot_at_vboot_state_var[AT_VBOOT_STATE_VAR_NUM] = {
86 "bootloader-locked", 87 "bootloader-locked",
87 "bootloader-min-versions", 88 "bootloader-min-versions",
88 "avb-perm-attr-set", 89 "avb-perm-attr-set",
89 "avb-locked", 90 "avb-locked",
90 "avb-unlock-disabled", 91 "avb-unlock-disabled",
91 "avb-min-versions" 92 "avb-min-versions"
92 }; 93 };
93 #endif 94 #endif
94 95
95 static int strcmp_l1(const char *s1, const char *s2) 96 static int strcmp_l1(const char *s1, const char *s2)
96 { 97 {
97 if (!s1 || !s2) 98 if (!s1 || !s2)
98 return -1; 99 return -1;
99 return strncmp(s1, s2, strlen(s1)); 100 return strncmp(s1, s2, strlen(s1));
100 } 101 }
101 102
102 static bool is_slotvar(char *cmd) 103 static bool is_slotvar(char *cmd)
103 { 104 {
104 assert(cmd != NULL); 105 assert(cmd != NULL);
105 if (!strcmp_l1("has-slot:", cmd) || 106 if (!strcmp_l1("has-slot:", cmd) ||
106 !strcmp_l1("slot-successful:", cmd) || 107 !strcmp_l1("slot-successful:", cmd) ||
107 !strcmp_l1("slot-count", cmd) || 108 !strcmp_l1("slot-count", cmd) ||
108 !strcmp_l1("slot-suffixes", cmd) || 109 !strcmp_l1("slot-suffixes", cmd) ||
109 !strcmp_l1("current-slot", cmd) || 110 !strcmp_l1("current-slot", cmd) ||
110 !strcmp_l1("slot-unbootable:", cmd) || 111 !strcmp_l1("slot-unbootable:", cmd) ||
111 !strcmp_l1("slot-retry-count:", cmd)) 112 !strcmp_l1("slot-retry-count:", cmd))
112 return true; 113 return true;
113 return false; 114 return false;
114 } 115 }
115 116
116 static char serial[IMX_SERIAL_LEN]; 117 static char serial[IMX_SERIAL_LEN];
117 118
118 char *get_serial(void) 119 char *get_serial(void)
119 { 120 {
120 #ifdef CONFIG_SERIAL_TAG 121 #ifdef CONFIG_SERIAL_TAG
121 struct tag_serialnr serialnr; 122 struct tag_serialnr serialnr;
122 memset(serial, 0, IMX_SERIAL_LEN); 123 memset(serial, 0, IMX_SERIAL_LEN);
123 124
124 get_board_serial(&serialnr); 125 get_board_serial(&serialnr);
125 sprintf(serial, "%08x%08x", serialnr.high, serialnr.low); 126 sprintf(serial, "%08x%08x", serialnr.high, serialnr.low);
126 return serial; 127 return serial;
127 #else 128 #else
128 return NULL; 129 return NULL;
129 #endif 130 #endif
130 } 131 }
131 132
132 #if !defined(PRODUCT_NAME) 133 #if !defined(PRODUCT_NAME)
133 #define PRODUCT_NAME "NXP i.MX" 134 #define PRODUCT_NAME "NXP i.MX"
134 #endif 135 #endif
135 136
136 #if !defined(VARIANT_NAME) 137 #if !defined(VARIANT_NAME)
137 #define VARIANT_NAME "NXP i.MX" 138 #define VARIANT_NAME "NXP i.MX"
138 #endif 139 #endif
139 140
140 #ifdef CONFIG_IMX_TRUSTY_OS 141 #ifdef CONFIG_IMX_TRUSTY_OS
141 static void uuid_hex2string(uint8_t *uuid, char* buf, uint32_t uuid_len, uint32_t uuid_strlen) { 142 static void uuid_hex2string(uint8_t *uuid, char* buf, uint32_t uuid_len, uint32_t uuid_strlen) {
142 uint32_t i; 143 uint32_t i;
143 if (!uuid || !buf) 144 if (!uuid || !buf)
144 return; 145 return;
145 char *cp = buf; 146 char *cp = buf;
146 char *buf_end = buf + uuid_strlen; 147 char *buf_end = buf + uuid_strlen;
147 for (i = 0; i < uuid_len; i++) { 148 for (i = 0; i < uuid_len; i++) {
148 cp += snprintf(cp, buf_end - cp, "%02x", uuid[i]); 149 cp += snprintf(cp, buf_end - cp, "%02x", uuid[i]);
149 } 150 }
150 } 151 }
151 #endif 152 #endif
152 153
153 #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) 154 #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M)
154 int get_imx8m_baseboard_id(void); 155 int get_imx8m_baseboard_id(void);
155 #endif 156 #endif
156 157
157 static int get_single_var(char *cmd, char *response) 158 static int get_single_var(char *cmd, char *response)
158 { 159 {
159 char *str = cmd; 160 char *str = cmd;
160 int chars_left; 161 int chars_left;
161 const char *s; 162 const char *s;
162 struct mmc *mmc; 163 struct mmc *mmc;
163 int mmc_dev_no; 164 int mmc_dev_no;
164 int blksz; 165 int blksz;
165 166
166 chars_left = FASTBOOT_RESPONSE_LEN - strlen(response) - 1; 167 chars_left = FASTBOOT_RESPONSE_LEN - strlen(response) - 1;
167 168
168 if ((str = strstr(cmd, "partition-size:"))) { 169 if ((str = strstr(cmd, "partition-size:"))) {
169 str +=strlen("partition-size:"); 170 str +=strlen("partition-size:");
170 struct fastboot_ptentry* fb_part; 171 struct fastboot_ptentry* fb_part;
171 fb_part = fastboot_flash_find_ptn(str); 172 fb_part = fastboot_flash_find_ptn(str);
172 if (!fb_part) { 173 if (!fb_part) {
173 strncat(response, "Wrong partition name.", chars_left); 174 strncat(response, "Wrong partition name.", chars_left);
174 fastboot_flash_dump_ptn(); 175 fastboot_flash_dump_ptn();
175 return -1; 176 return -1;
176 } else { 177 } else {
177 snprintf(response + strlen(response), chars_left, 178 snprintf(response + strlen(response), chars_left,
178 "0x%llx", 179 "0x%llx",
179 (uint64_t)fb_part->length * get_block_size()); 180 (uint64_t)fb_part->length * get_block_size());
180 } 181 }
181 } else if ((str = strstr(cmd, "partition-type:"))) { 182 } else if ((str = strstr(cmd, "partition-type:"))) {
182 str +=strlen("partition-type:"); 183 str +=strlen("partition-type:");
183 struct fastboot_ptentry* fb_part; 184 struct fastboot_ptentry* fb_part;
184 fb_part = fastboot_flash_find_ptn(str); 185 fb_part = fastboot_flash_find_ptn(str);
185 if (!fb_part) { 186 if (!fb_part) {
186 strncat(response, "Wrong partition name.", chars_left); 187 strncat(response, "Wrong partition name.", chars_left);
187 fastboot_flash_dump_ptn(); 188 fastboot_flash_dump_ptn();
188 return -1; 189 return -1;
189 } else { 190 } else {
190 strncat(response, fb_part->fstype, chars_left); 191 strncat(response, fb_part->fstype, chars_left);
191 } 192 }
192 } else if ((str = strstr(cmd, "is-logical:"))) { 193 } else if ((str = strstr(cmd, "is-logical:"))) {
193 str +=strlen("is-logical:"); 194 str +=strlen("is-logical:");
194 struct fastboot_ptentry* fb_part; 195 struct fastboot_ptentry* fb_part;
195 fb_part = fastboot_flash_find_ptn(str); 196 fb_part = fastboot_flash_find_ptn(str);
196 if (!fb_part) { 197 if (!fb_part) {
197 return -1; 198 return -1;
198 } else { 199 } else {
199 snprintf(response + strlen(response), chars_left, "no"); 200 snprintf(response + strlen(response), chars_left, "no");
200 } 201 }
201 } else if (!strcmp_l1("version-baseband", cmd)) { 202 } else if (!strcmp_l1("version-baseband", cmd)) {
202 strncat(response, "N/A", chars_left); 203 strncat(response, "N/A", chars_left);
203 } else if (!strcmp_l1("version-bootloader", cmd) || 204 } else if (!strcmp_l1("version-bootloader", cmd) ||
204 !strcmp_l1("bootloader-version", cmd)) { 205 !strcmp_l1("bootloader-version", cmd)) {
205 strncat(response, U_BOOT_VERSION, chars_left); 206 strncat(response, U_BOOT_VERSION, chars_left);
206 } else if (!strcmp_l1("version", cmd)) { 207 } else if (!strcmp_l1("version", cmd)) {
207 strncat(response, FASTBOOT_VERSION, chars_left); 208 strncat(response, FASTBOOT_VERSION, chars_left);
208 } else if (!strcmp_l1("battery-voltage", cmd)) { 209 } else if (!strcmp_l1("battery-voltage", cmd)) {
209 strncat(response, "0mV", chars_left); 210 strncat(response, "0mV", chars_left);
210 } else if (!strcmp_l1("battery-soc-ok", cmd)) { 211 } else if (!strcmp_l1("battery-soc-ok", cmd)) {
211 strncat(response, "yes", chars_left); 212 strncat(response, "yes", chars_left);
212 } else if (!strcmp_l1("variant", cmd)) { 213 } else if (!strcmp_l1("variant", cmd)) {
213 strncat(response, VARIANT_NAME, chars_left); 214 strncat(response, VARIANT_NAME, chars_left);
214 } else if (!strcmp_l1("off-mode-charge", cmd)) { 215 } else if (!strcmp_l1("off-mode-charge", cmd)) {
215 strncat(response, "1", chars_left); 216 strncat(response, "1", chars_left);
217 } else if (!strcmp_l1("is-userspace", cmd)) {
218 strncat(response, FASTBOOT_VAR_NO, chars_left);
216 } else if (!strcmp_l1("downloadsize", cmd) || 219 } else if (!strcmp_l1("downloadsize", cmd) ||
217 !strcmp_l1("max-download-size", cmd)) { 220 !strcmp_l1("max-download-size", cmd)) {
218 221
219 snprintf(response + strlen(response), chars_left, "0x%x", CONFIG_FASTBOOT_BUF_SIZE); 222 snprintf(response + strlen(response), chars_left, "0x%x", CONFIG_FASTBOOT_BUF_SIZE);
220 } else if (!strcmp_l1("erase-block-size", cmd)) { 223 } else if (!strcmp_l1("erase-block-size", cmd)) {
221 mmc_dev_no = mmc_get_env_dev(); 224 mmc_dev_no = mmc_get_env_dev();
222 mmc = find_mmc_device(mmc_dev_no); 225 mmc = find_mmc_device(mmc_dev_no);
223 blksz = get_block_size(); 226 blksz = get_block_size();
224 snprintf(response + strlen(response), chars_left, "0x%x", 227 snprintf(response + strlen(response), chars_left, "0x%x",
225 (blksz * mmc->erase_grp_size)); 228 (blksz * mmc->erase_grp_size));
226 } else if (!strcmp_l1("logical-block-size", cmd)) { 229 } else if (!strcmp_l1("logical-block-size", cmd)) {
227 blksz = get_block_size(); 230 blksz = get_block_size();
228 snprintf(response + strlen(response), chars_left, "0x%x", blksz); 231 snprintf(response + strlen(response), chars_left, "0x%x", blksz);
229 } else if (!strcmp_l1("serialno", cmd)) { 232 } else if (!strcmp_l1("serialno", cmd)) {
230 s = get_serial(); 233 s = get_serial();
231 if (s) 234 if (s)
232 strncat(response, s, chars_left); 235 strncat(response, s, chars_left);
233 else { 236 else {
234 strncat(response, "FAILValue not set", chars_left); 237 strncat(response, "FAILValue not set", chars_left);
235 return -1; 238 return -1;
236 } 239 }
237 } else if (!strcmp_l1("product", cmd)) { 240 } else if (!strcmp_l1("product", cmd)) {
238 strncat(response, PRODUCT_NAME, chars_left); 241 strncat(response, PRODUCT_NAME, chars_left);
239 } 242 }
240 #ifdef CONFIG_IMX_TRUSTY_OS 243 #ifdef CONFIG_IMX_TRUSTY_OS
241 else if(!strcmp_l1("at-attest-uuid", cmd)) { 244 else if(!strcmp_l1("at-attest-uuid", cmd)) {
242 char *uuid; 245 char *uuid;
243 char uuid_str[ATAP_UUID_STR_SIZE]; 246 char uuid_str[ATAP_UUID_STR_SIZE];
244 if (trusty_atap_read_uuid_str(&uuid)) { 247 if (trusty_atap_read_uuid_str(&uuid)) {
245 printf("ERROR read uuid failed!\n"); 248 printf("ERROR read uuid failed!\n");
246 strncat(response, "FAILCannot get uuid!", chars_left); 249 strncat(response, "FAILCannot get uuid!", chars_left);
247 return -1; 250 return -1;
248 } else { 251 } else {
249 uuid_hex2string((uint8_t*)uuid, uuid_str,ATAP_UUID_SIZE, ATAP_UUID_STR_SIZE); 252 uuid_hex2string((uint8_t*)uuid, uuid_str,ATAP_UUID_SIZE, ATAP_UUID_STR_SIZE);
250 strncat(response, uuid_str, chars_left); 253 strncat(response, uuid_str, chars_left);
251 trusty_free(uuid); 254 trusty_free(uuid);
252 } 255 }
253 } 256 }
254 else if(!strcmp_l1("at-attest-dh", cmd)) { 257 else if(!strcmp_l1("at-attest-dh", cmd)) {
255 strncat(response, "1:P256,2:curve25519", chars_left); 258 strncat(response, "1:P256,2:curve25519", chars_left);
256 } 259 }
257 #endif 260 #endif
258 #if defined(CONFIG_FASTBOOT_LOCK) 261 #if defined(CONFIG_FASTBOOT_LOCK)
259 else if (!strcmp_l1("secure", cmd)) { 262 else if (!strcmp_l1("secure", cmd)) {
260 strncat(response, FASTBOOT_VAR_YES, chars_left); 263 strncat(response, FASTBOOT_VAR_YES, chars_left);
261 } else if (!strcmp_l1("unlocked",cmd)){ 264 } else if (!strcmp_l1("unlocked",cmd)){
262 int status = fastboot_get_lock_stat(); 265 int status = fastboot_get_lock_stat();
263 if (status == FASTBOOT_UNLOCK) { 266 if (status == FASTBOOT_UNLOCK) {
264 strncat(response, FASTBOOT_VAR_YES, chars_left); 267 strncat(response, FASTBOOT_VAR_YES, chars_left);
265 } else { 268 } else {
266 strncat(response, FASTBOOT_VAR_NO, chars_left); 269 strncat(response, FASTBOOT_VAR_NO, chars_left);
267 } 270 }
268 } 271 }
269 #else 272 #else
270 else if (!strcmp_l1("secure", cmd)) { 273 else if (!strcmp_l1("secure", cmd)) {
271 strncat(response, FASTBOOT_VAR_NO, chars_left); 274 strncat(response, FASTBOOT_VAR_NO, chars_left);
272 } else if (!strcmp_l1("unlocked",cmd)) { 275 } else if (!strcmp_l1("unlocked",cmd)) {
273 strncat(response, FASTBOOT_VAR_NO, chars_left); 276 strncat(response, FASTBOOT_VAR_NO, chars_left);
274 } 277 }
275 #endif 278 #endif
276 else if (is_slotvar(cmd)) { 279 else if (is_slotvar(cmd)) {
277 #ifdef CONFIG_AVB_SUPPORT 280 #ifdef CONFIG_AVB_SUPPORT
278 if (get_slotvar_avb(&fsl_avb_ab_ops, cmd, 281 if (get_slotvar_avb(&fsl_avb_ab_ops, cmd,
279 response + strlen(response), chars_left + 1) < 0) 282 response + strlen(response), chars_left + 1) < 0)
280 return -1; 283 return -1;
281 #else 284 #else
282 strncat(response, FASTBOOT_VAR_NO, chars_left); 285 strncat(response, FASTBOOT_VAR_NO, chars_left);
283 #endif 286 #endif
284 } 287 }
285 #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) 288 #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M)
286 else if (!strcmp_l1("baseboard_id", cmd)) { 289 else if (!strcmp_l1("baseboard_id", cmd)) {
287 int baseboard_id; 290 int baseboard_id;
288 291
289 baseboard_id = get_imx8m_baseboard_id(); 292 baseboard_id = get_imx8m_baseboard_id();
290 if (baseboard_id < 0) { 293 if (baseboard_id < 0) {
291 printf("Get baseboard id failed!\n"); 294 printf("Get baseboard id failed!\n");
292 strncat(response, "Get baseboard id failed!", chars_left); 295 strncat(response, "Get baseboard id failed!", chars_left);
293 return -1; 296 return -1;
294 } else 297 } else
295 snprintf(response + strlen(response), chars_left, "0x%x", baseboard_id); 298 snprintf(response + strlen(response), chars_left, "0x%x", baseboard_id);
296 } 299 }
297 #endif 300 #endif
298 #ifdef CONFIG_AVB_ATX 301 #ifdef CONFIG_AVB_ATX
299 else if (!strcmp_l1("bootloader-locked", cmd)) { 302 else if (!strcmp_l1("bootloader-locked", cmd)) {
300 303
301 /* Below is basically copied from is_hab_enabled() */ 304 /* Below is basically copied from is_hab_enabled() */
302 struct imx_sec_config_fuse_t *fuse = 305 struct imx_sec_config_fuse_t *fuse =
303 (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse; 306 (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse;
304 uint32_t reg; 307 uint32_t reg;
305 int ret; 308 int ret;
306 309
307 /* Read the secure boot status from fuse. */ 310 /* Read the secure boot status from fuse. */
308 ret = fuse_read(fuse->bank, fuse->word, &reg); 311 ret = fuse_read(fuse->bank, fuse->word, &reg);
309 if (ret) { 312 if (ret) {
310 printf("\nSecure boot fuse read error!\n"); 313 printf("\nSecure boot fuse read error!\n");
311 strncat(response, "Secure boot fuse read error!", chars_left); 314 strncat(response, "Secure boot fuse read error!", chars_left);
312 return -1; 315 return -1;
313 } 316 }
314 /* Check if the secure boot bit is enabled */ 317 /* Check if the secure boot bit is enabled */
315 if ((reg & 0x2000000) == 0x2000000) 318 if ((reg & 0x2000000) == 0x2000000)
316 strncat(response, "1", chars_left); 319 strncat(response, "1", chars_left);
317 else 320 else
318 strncat(response, "0", chars_left); 321 strncat(response, "0", chars_left);
319 } else if (!strcmp_l1("bootloader-min-versions", cmd)) { 322 } else if (!strcmp_l1("bootloader-min-versions", cmd)) {
320 #ifndef CONFIG_ARM64 323 #ifndef CONFIG_ARM64
321 /* We don't support bootloader rbindex protection for 324 /* We don't support bootloader rbindex protection for
322 * ARM32(like imx7d) and the format is: "bootloader,tee". */ 325 * ARM32(like imx7d) and the format is: "bootloader,tee". */
323 strncat(response, "-1,-1", chars_left); 326 strncat(response, "-1,-1", chars_left);
324 327
325 #elif defined(CONFIG_DUAL_BOOTLOADER) 328 #elif defined(CONFIG_DUAL_BOOTLOADER)
326 /* Rbindex protection for bootloader is supported only when the 329 /* Rbindex protection for bootloader is supported only when the
327 * 'dual bootloader' feature is enabled. U-boot will get the rbindx 330 * 'dual bootloader' feature is enabled. U-boot will get the rbindx
328 * from RAM which is passed by spl because we can only get the rbindex 331 * from RAM which is passed by spl because we can only get the rbindex
329 * at spl stage. The format in this case is: "spl,atf,tee,u-boot". 332 * at spl stage. The format in this case is: "spl,atf,tee,u-boot".
330 */ 333 */
331 struct bl_rbindex_package *bl_rbindex; 334 struct bl_rbindex_package *bl_rbindex;
332 uint32_t rbindex; 335 uint32_t rbindex;
333 336
334 bl_rbindex = (struct bl_rbindex_package *)BL_RBINDEX_LOAD_ADDR; 337 bl_rbindex = (struct bl_rbindex_package *)BL_RBINDEX_LOAD_ADDR;
335 if (!strncmp(bl_rbindex->magic, BL_RBINDEX_MAGIC, 338 if (!strncmp(bl_rbindex->magic, BL_RBINDEX_MAGIC,
336 BL_RBINDEX_MAGIC_LEN)) { 339 BL_RBINDEX_MAGIC_LEN)) {
337 rbindex = bl_rbindex->rbindex; 340 rbindex = bl_rbindex->rbindex;
338 snprintf(response + strlen(response), chars_left, 341 snprintf(response + strlen(response), chars_left,
339 "-1,%d,%d,%d",rbindex, rbindex, rbindex); 342 "-1,%d,%d,%d",rbindex, rbindex, rbindex);
340 } else { 343 } else {
341 printf("Error bootloader rbindex magic!\n"); 344 printf("Error bootloader rbindex magic!\n");
342 strncat(response, "Get bootloader rbindex fail!", chars_left); 345 strncat(response, "Get bootloader rbindex fail!", chars_left);
343 return -1; 346 return -1;
344 } 347 }
345 #else 348 #else
346 /* Return -1 for all partition if 'dual bootloader' feature 349 /* Return -1 for all partition if 'dual bootloader' feature
347 * is not enabled */ 350 * is not enabled */
348 strncat(response, "-1,-1,-1,-1", chars_left); 351 strncat(response, "-1,-1,-1,-1", chars_left);
349 #endif 352 #endif
350 } else if (!strcmp_l1("avb-perm-attr-set", cmd)) { 353 } else if (!strcmp_l1("avb-perm-attr-set", cmd)) {
351 if (perm_attr_are_fused()) 354 if (perm_attr_are_fused())
352 strncat(response, "1", chars_left); 355 strncat(response, "1", chars_left);
353 else 356 else
354 strncat(response, "0", chars_left); 357 strncat(response, "0", chars_left);
355 } else if (!strcmp_l1("avb-locked", cmd)) { 358 } else if (!strcmp_l1("avb-locked", cmd)) {
356 FbLockState status; 359 FbLockState status;
357 360
358 status = fastboot_get_lock_stat(); 361 status = fastboot_get_lock_stat();
359 if (status == FASTBOOT_LOCK) 362 if (status == FASTBOOT_LOCK)
360 strncat(response, "1", chars_left); 363 strncat(response, "1", chars_left);
361 else if (status == FASTBOOT_UNLOCK) 364 else if (status == FASTBOOT_UNLOCK)
362 strncat(response, "0", chars_left); 365 strncat(response, "0", chars_left);
363 else { 366 else {
364 printf("Get lock state error!\n"); 367 printf("Get lock state error!\n");
365 strncat(response, "Get lock state failed!", chars_left); 368 strncat(response, "Get lock state failed!", chars_left);
366 return -1; 369 return -1;
367 } 370 }
368 } else if (!strcmp_l1("avb-unlock-disabled", cmd)) { 371 } else if (!strcmp_l1("avb-unlock-disabled", cmd)) {
369 if (at_unlock_vboot_is_disabled()) 372 if (at_unlock_vboot_is_disabled())
370 strncat(response, "1", chars_left); 373 strncat(response, "1", chars_left);
371 else 374 else
372 strncat(response, "0", chars_left); 375 strncat(response, "0", chars_left);
373 } else if (!strcmp_l1("avb-min-versions", cmd)) { 376 } else if (!strcmp_l1("avb-min-versions", cmd)) {
374 int i = 0; 377 int i = 0;
375 /* rbindex location/value can be very large 378 /* rbindex location/value can be very large
376 * number so we reserve enough space here. 379 * number so we reserve enough space here.
377 */ 380 */
378 char buffer[35]; 381 char buffer[35];
379 uint32_t rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 2]; 382 uint32_t rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 2];
380 uint32_t location; 383 uint32_t location;
381 uint64_t rbindex; 384 uint64_t rbindex;
382 385
383 memset(buffer, '\0', sizeof(buffer)); 386 memset(buffer, '\0', sizeof(buffer));
384 387
385 /* Set rbindex locations. */ 388 /* Set rbindex locations. */
386 for (i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; i++) 389 for (i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; i++)
387 rbindex_location[i] = i; 390 rbindex_location[i] = i;
388 391
389 /* Set Android Things key version rbindex locations */ 392 /* Set Android Things key version rbindex locations */
390 rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS] 393 rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS]
391 = AVB_ATX_PIK_VERSION_LOCATION; 394 = AVB_ATX_PIK_VERSION_LOCATION;
392 rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 1] 395 rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 1]
393 = AVB_ATX_PSK_VERSION_LOCATION; 396 = AVB_ATX_PSK_VERSION_LOCATION;
394 397
395 /* Read rollback index and set the reponse*/ 398 /* Read rollback index and set the reponse*/
396 for (i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 2; i++) { 399 for (i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 2; i++) {
397 location = rbindex_location[i]; 400 location = rbindex_location[i];
398 if (fsl_avb_ops.read_rollback_index(&fsl_avb_ops, 401 if (fsl_avb_ops.read_rollback_index(&fsl_avb_ops,
399 location, &rbindex) 402 location, &rbindex)
400 != AVB_IO_RESULT_OK) { 403 != AVB_IO_RESULT_OK) {
401 printf("Read rollback index error!\n"); 404 printf("Read rollback index error!\n");
402 snprintf(response, FASTBOOT_RESPONSE_LEN, 405 snprintf(response, FASTBOOT_RESPONSE_LEN,
403 "INFOread rollback index error when get avb-min-versions"); 406 "INFOread rollback index error when get avb-min-versions");
404 return -1; 407 return -1;
405 } 408 }
406 /* Generate the "location:value" pair */ 409 /* Generate the "location:value" pair */
407 snprintf(buffer, sizeof(buffer), "%d:%lld", location, rbindex); 410 snprintf(buffer, sizeof(buffer), "%d:%lld", location, rbindex);
408 if (i != AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 1) 411 if (i != AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 1)
409 strncat(buffer, ",", strlen(",")); 412 strncat(buffer, ",", strlen(","));
410 413
411 if ((chars_left - (int)strlen(buffer)) >= 0) { 414 if ((chars_left - (int)strlen(buffer)) >= 0) {
412 strncat(response, buffer, strlen(buffer)); 415 strncat(response, buffer, strlen(buffer));
413 chars_left -= strlen(buffer); 416 chars_left -= strlen(buffer);
414 } else { 417 } else {
415 strncat(response, buffer, chars_left); 418 strncat(response, buffer, chars_left);
416 /* reponse buffer is full, send it first */ 419 /* reponse buffer is full, send it first */
417 fastboot_tx_write_more(response); 420 fastboot_tx_write_more(response);
418 /* reset the reponse buffer for next round */ 421 /* reset the reponse buffer for next round */
419 memset(response, '\0', FASTBOOT_RESPONSE_LEN); 422 memset(response, '\0', FASTBOOT_RESPONSE_LEN);
420 strncpy(response, "INFO", 5); 423 strncpy(response, "INFO", 5);
421 /* Copy left strings from 'buffer' to 'response' */ 424 /* Copy left strings from 'buffer' to 'response' */
422 strncat(response, buffer + chars_left, strlen(buffer)); 425 strncat(response, buffer + chars_left, strlen(buffer));
423 chars_left = FASTBOOT_RESPONSE_LEN - 426 chars_left = FASTBOOT_RESPONSE_LEN -
424 strlen(response) - 1; 427 strlen(response) - 1;
425 } 428 }
426 } 429 }
427 430
428 } 431 }
429 #endif 432 #endif
430 else { 433 else {
431 char envstr[32]; 434 char envstr[32];
432 435
433 snprintf(envstr, sizeof(envstr) - 1, "fastboot.%s", cmd); 436 snprintf(envstr, sizeof(envstr) - 1, "fastboot.%s", cmd);
434 s = env_get(envstr); 437 s = env_get(envstr);
435 if (s) { 438 if (s) {
436 strncat(response, s, chars_left); 439 strncat(response, s, chars_left);
437 } else { 440 } else {
438 snprintf(response, chars_left, "FAILunknown variable:%s",cmd); 441 snprintf(response, chars_left, "FAILunknown variable:%s",cmd);
439 printf("WARNING: unknown variable: %s\n", cmd); 442 printf("WARNING: unknown variable: %s\n", cmd);
440 return -1; 443 return -1;
441 } 444 }
442 } 445 }
443 return 0; 446 return 0;
444 } 447 }
445 448
446 void fastboot_getvar(char *cmd, char *response) 449 void fastboot_getvar(char *cmd, char *response)
447 { 450 {
448 int n = 0; 451 int n = 0;
449 int status = 0; 452 int status = 0;
450 int count = 0; 453 int count = 0;
451 char var_name[FASTBOOT_RESPONSE_LEN]; 454 char var_name[FASTBOOT_RESPONSE_LEN];
452 char partition_base_name[MAX_PTN][16]; 455 char partition_base_name[MAX_PTN][16];
453 char slot_suffix[2][5] = {"a","b"}; 456 char slot_suffix[2][5] = {"a","b"};
454 457
455 if (!cmd) { 458 if (!cmd) {
456 pr_err("missing variable"); 459 pr_err("missing variable");
457 fastboot_fail("missing var", response); 460 fastboot_fail("missing var", response);
458 return; 461 return;
459 } 462 }
460 463
461 if (!strcmp_l1("all", cmd)) { 464 if (!strcmp_l1("all", cmd)) {
462 465
463 memset(response, '\0', FASTBOOT_RESPONSE_LEN); 466 memset(response, '\0', FASTBOOT_RESPONSE_LEN);
464 467
465 468
466 /* get common variables */ 469 /* get common variables */
467 for (n = 0; n < FASTBOOT_COMMON_VAR_NUM; n++) { 470 for (n = 0; n < FASTBOOT_COMMON_VAR_NUM; n++) {
468 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFO%s:", fastboot_common_var[n]); 471 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFO%s:", fastboot_common_var[n]);
469 get_single_var(fastboot_common_var[n], response); 472 get_single_var(fastboot_common_var[n], response);
470 fastboot_tx_write_more(response); 473 fastboot_tx_write_more(response);
471 } 474 }
472 475
473 /* get at-vboot-state variables */ 476 /* get at-vboot-state variables */
474 #ifdef CONFIG_AVB_ATX 477 #ifdef CONFIG_AVB_ATX
475 for (n = 0; n < AT_VBOOT_STATE_VAR_NUM; n++) { 478 for (n = 0; n < AT_VBOOT_STATE_VAR_NUM; n++) {
476 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFO%s:", fastboot_at_vboot_state_var[n]); 479 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFO%s:", fastboot_at_vboot_state_var[n]);
477 get_single_var(fastboot_at_vboot_state_var[n], response); 480 get_single_var(fastboot_at_vboot_state_var[n], response);
478 fastboot_tx_write_more(response); 481 fastboot_tx_write_more(response);
479 } 482 }
480 #endif 483 #endif
481 /* get partition type */ 484 /* get partition type */
482 for (n = 0; n < g_pcount; n++) { 485 for (n = 0; n < g_pcount; n++) {
483 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOpartition-type:%s:", g_ptable[n].name); 486 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOpartition-type:%s:", g_ptable[n].name);
484 snprintf(var_name, sizeof(var_name), "partition-type:%s", g_ptable[n].name); 487 snprintf(var_name, sizeof(var_name), "partition-type:%s", g_ptable[n].name);
485 get_single_var(var_name, response); 488 get_single_var(var_name, response);
486 fastboot_tx_write_more(response); 489 fastboot_tx_write_more(response);
487 } 490 }
488 /* get partition size */ 491 /* get partition size */
489 for (n = 0; n < g_pcount; n++) { 492 for (n = 0; n < g_pcount; n++) {
490 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOpartition-size:%s:", g_ptable[n].name); 493 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOpartition-size:%s:", g_ptable[n].name);
491 snprintf(var_name, sizeof(var_name), "partition-size:%s", g_ptable[n].name); 494 snprintf(var_name, sizeof(var_name), "partition-size:%s", g_ptable[n].name);
492 get_single_var(var_name,response); 495 get_single_var(var_name,response);
493 fastboot_tx_write_more(response); 496 fastboot_tx_write_more(response);
494 } 497 }
495 /* slot related variables */ 498 /* slot related variables */
496 if (fastboot_parts_is_slot()) { 499 if (fastboot_parts_is_slot()) {
497 /* get has-slot variables */ 500 /* get has-slot variables */
498 count = fastboot_parts_get_name(partition_base_name); 501 count = fastboot_parts_get_name(partition_base_name);
499 for (n = 0; n < count; n++) { 502 for (n = 0; n < count; n++) {
500 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOhas-slot:%s:", partition_base_name[n]); 503 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOhas-slot:%s:", partition_base_name[n]);
501 snprintf(var_name, sizeof(var_name), "has-slot:%s", partition_base_name[n]); 504 snprintf(var_name, sizeof(var_name), "has-slot:%s", partition_base_name[n]);
502 get_single_var(var_name,response); 505 get_single_var(var_name,response);
503 fastboot_tx_write_more(response); 506 fastboot_tx_write_more(response);
504 } 507 }
505 /* get current slot */ 508 /* get current slot */
506 strncpy(response, "INFOcurrent-slot:", FASTBOOT_RESPONSE_LEN); 509 strncpy(response, "INFOcurrent-slot:", FASTBOOT_RESPONSE_LEN);
507 get_single_var("current-slot", response); 510 get_single_var("current-slot", response);
508 fastboot_tx_write_more(response); 511 fastboot_tx_write_more(response);
509 /* get slot count */ 512 /* get slot count */
510 strncpy(response, "INFOslot-count:", FASTBOOT_RESPONSE_LEN); 513 strncpy(response, "INFOslot-count:", FASTBOOT_RESPONSE_LEN);
511 get_single_var("slot-count", response); 514 get_single_var("slot-count", response);
512 fastboot_tx_write_more(response); 515 fastboot_tx_write_more(response);
513 /* get slot-successful variable */ 516 /* get slot-successful variable */
514 for (n = 0; n < 2; n++) { 517 for (n = 0; n < 2; n++) {
515 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOslot-successful:%s:", slot_suffix[n]); 518 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOslot-successful:%s:", slot_suffix[n]);
516 snprintf(var_name, sizeof(var_name), "slot-successful:%s", slot_suffix[n]); 519 snprintf(var_name, sizeof(var_name), "slot-successful:%s", slot_suffix[n]);
517 get_single_var(var_name, response); 520 get_single_var(var_name, response);
518 fastboot_tx_write_more(response); 521 fastboot_tx_write_more(response);
519 } 522 }
520 /*get slot-unbootable variable*/ 523 /*get slot-unbootable variable*/
521 for (n = 0; n < 2; n++) { 524 for (n = 0; n < 2; n++) {
522 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOslot-unbootable:%s:", slot_suffix[n]); 525 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOslot-unbootable:%s:", slot_suffix[n]);
523 snprintf(var_name, sizeof(var_name), "slot-unbootable:%s", slot_suffix[n]); 526 snprintf(var_name, sizeof(var_name), "slot-unbootable:%s", slot_suffix[n]);
524 get_single_var(var_name, response); 527 get_single_var(var_name, response);
525 fastboot_tx_write_more(response); 528 fastboot_tx_write_more(response);
526 } 529 }
527 /*get slot-retry-count variable*/ 530 /*get slot-retry-count variable*/
528 for (n = 0; n < 2; n++) { 531 for (n = 0; n < 2; n++) {
529 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOslot-retry-count:%s:", slot_suffix[n]); 532 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFOslot-retry-count:%s:", slot_suffix[n]);
530 snprintf(var_name, sizeof(var_name), "slot-retry-count:%s", slot_suffix[n]); 533 snprintf(var_name, sizeof(var_name), "slot-retry-count:%s", slot_suffix[n]);
531 get_single_var(var_name, response); 534 get_single_var(var_name, response);
532 fastboot_tx_write_more(response); 535 fastboot_tx_write_more(response);
533 } 536 }
534 } 537 }
535 538
536 strncpy(response, "OKAYDone!", 10); 539 strncpy(response, "OKAYDone!", 10);
537 fastboot_tx_write_more(response); 540 fastboot_tx_write_more(response);
538 fastboot_none_resp(response); 541 fastboot_none_resp(response);
539 542
540 return; 543 return;
541 } 544 }
542 #ifdef CONFIG_AVB_ATX 545 #ifdef CONFIG_AVB_ATX
543 else if (!strcmp_l1("at-vboot-state", cmd)) { 546 else if (!strcmp_l1("at-vboot-state", cmd)) {
544 /* get at-vboot-state variables */ 547 /* get at-vboot-state variables */
545 for (n = 0; n < AT_VBOOT_STATE_VAR_NUM; n++) { 548 for (n = 0; n < AT_VBOOT_STATE_VAR_NUM; n++) {
546 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFO%s:", fastboot_at_vboot_state_var[n]); 549 snprintf(response, FASTBOOT_RESPONSE_LEN, "INFO%s:", fastboot_at_vboot_state_var[n]);
547 get_single_var(fastboot_at_vboot_state_var[n], response); 550 get_single_var(fastboot_at_vboot_state_var[n], response);
548 fastboot_tx_write_more(response); 551 fastboot_tx_write_more(response);
549 } 552 }
550 553
551 strncpy(response, "OKAY", 5); 554 strncpy(response, "OKAY", 5);
552 fastboot_tx_write_more(response); 555 fastboot_tx_write_more(response);
553 fastboot_none_resp(response); 556 fastboot_none_resp(response);
554 557
555 return; 558 return;
556 } else if ((!strcmp_l1("bootloader-locked", cmd)) || 559 } else if ((!strcmp_l1("bootloader-locked", cmd)) ||
557 (!strcmp_l1("bootloader-min-versions", cmd)) || 560 (!strcmp_l1("bootloader-min-versions", cmd)) ||
558 (!strcmp_l1("avb-perm-attr-set", cmd)) || 561 (!strcmp_l1("avb-perm-attr-set", cmd)) ||
559 (!strcmp_l1("avb-locked", cmd)) || 562 (!strcmp_l1("avb-locked", cmd)) ||
560 (!strcmp_l1("avb-unlock-disabled", cmd)) || 563 (!strcmp_l1("avb-unlock-disabled", cmd)) ||
561 (!strcmp_l1("avb-min-versions", cmd))) { 564 (!strcmp_l1("avb-min-versions", cmd))) {
562 565
563 printf("Can't get this variable alone, get 'at-vboot-state' instead!\n"); 566 printf("Can't get this variable alone, get 'at-vboot-state' instead!\n");
564 fastboot_fail("Can't get this variable alone, get 'at-vboot-state' instead.", response); 567 fastboot_fail("Can't get this variable alone, get 'at-vboot-state' instead.", response);
565 return; 568 return;
566 } 569 }
567 #endif 570 #endif
568 else { 571 else {
569 char reason[FASTBOOT_RESPONSE_LEN]; 572 char reason[FASTBOOT_RESPONSE_LEN];
570 memset(reason, '\0', FASTBOOT_RESPONSE_LEN); 573 memset(reason, '\0', FASTBOOT_RESPONSE_LEN);
571 574
572 status = get_single_var(cmd, reason); 575 status = get_single_var(cmd, reason);
573 if (status != 0) 576 if (status != 0)
574 fastboot_fail(reason, response); 577 fastboot_fail(reason, response);
575 else 578 else
576 fastboot_okay(reason, response); 579 fastboot_okay(reason, response);
577 580
578 return; 581 return;
579 } 582 }
580 } 583 }
581 584
drivers/usb/gadget/f_fastboot.c
1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+
2 /* 2 /*
3 * (C) Copyright 2008 - 2009 3 * (C) Copyright 2008 - 2009
4 * Windriver, <www.windriver.com> 4 * Windriver, <www.windriver.com>
5 * Tom Rix <Tom.Rix@windriver.com> 5 * Tom Rix <Tom.Rix@windriver.com>
6 * 6 *
7 * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de> 7 * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8 * 8 *
9 * Copyright 2014 Linaro, Ltd. 9 * Copyright 2014 Linaro, Ltd.
10 * Rob Herring <robh@kernel.org> 10 * Rob Herring <robh@kernel.org>
11 */ 11 */
12 #include <config.h> 12 #include <config.h>
13 #include <common.h> 13 #include <common.h>
14 #include <env.h> 14 #include <env.h>
15 #include <errno.h> 15 #include <errno.h>
16 #include <fastboot.h> 16 #include <fastboot.h>
17 #include <malloc.h> 17 #include <malloc.h>
18 #include <linux/usb/ch9.h> 18 #include <linux/usb/ch9.h>
19 #include <linux/usb/gadget.h> 19 #include <linux/usb/gadget.h>
20 #include <linux/usb/composite.h> 20 #include <linux/usb/composite.h>
21 #include <linux/compiler.h> 21 #include <linux/compiler.h>
22 #include <g_dnl.h> 22 #include <g_dnl.h>
23 #include <serial.h> 23 #include <serial.h>
24 #include <stdio_dev.h> 24 #include <stdio_dev.h>
25 25
26 #define FASTBOOT_INTERFACE_CLASS 0xff 26 #define FASTBOOT_INTERFACE_CLASS 0xff
27 #define FASTBOOT_INTERFACE_SUB_CLASS 0x42 27 #define FASTBOOT_INTERFACE_SUB_CLASS 0x42
28 #define FASTBOOT_INTERFACE_PROTOCOL 0x03 28 #define FASTBOOT_INTERFACE_PROTOCOL 0x03
29 29
30 #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) 30 #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200)
31 #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) 31 #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040)
32 #define TX_ENDPOINT_MAXIMUM_PACKET_SIZE (0x0040) 32 #define TX_ENDPOINT_MAXIMUM_PACKET_SIZE (0x0040)
33 33
34 #define EP_BUFFER_SIZE 4096 34 #define EP_BUFFER_SIZE 4096
35 /* 35 /*
36 * EP_BUFFER_SIZE must always be an integral multiple of maxpacket size 36 * EP_BUFFER_SIZE must always be an integral multiple of maxpacket size
37 * (64 or 512 or 1024), else we break on certain controllers like DWC3 37 * (64 or 512 or 1024), else we break on certain controllers like DWC3
38 * that expect bulk OUT requests to be divisible by maxpacket size. 38 * that expect bulk OUT requests to be divisible by maxpacket size.
39 */ 39 */
40 40
41 typedef struct usb_req usb_req; 41 typedef struct usb_req usb_req;
42 struct usb_req { 42 struct usb_req {
43 struct usb_request *in_req; 43 struct usb_request *in_req;
44 usb_req *next; 44 usb_req *next;
45 }; 45 };
46 46
47 struct f_fastboot { 47 struct f_fastboot {
48 struct usb_function usb_function; 48 struct usb_function usb_function;
49 49
50 /* IN/OUT EP's and corresponding requests */ 50 /* IN/OUT EP's and corresponding requests */
51 struct usb_ep *in_ep, *out_ep; 51 struct usb_ep *in_ep, *out_ep;
52 struct usb_request *in_req, *out_req; 52 struct usb_request *in_req, *out_req;
53 53
54 usb_req *front, *rear; 54 usb_req *front, *rear;
55 }; 55 };
56 56
57 static char fb_ext_prop_name[] = "DeviceInterfaceGUID"; 57 static char fb_ext_prop_name[] = "DeviceInterfaceGUID";
58 static char fb_ext_prop_data[] = "{4866319A-F4D6-4374-93B9-DC2DEB361BA9}"; 58 static char fb_ext_prop_data[] = "{4866319A-F4D6-4374-93B9-DC2DEB361BA9}";
59 59
60 static struct usb_os_desc_ext_prop fb_ext_prop = { 60 static struct usb_os_desc_ext_prop fb_ext_prop = {
61 .type = 1, /* NUL-terminated Unicode String (REG_SZ) */ 61 .type = 1, /* NUL-terminated Unicode String (REG_SZ) */
62 .name = fb_ext_prop_name, 62 .name = fb_ext_prop_name,
63 .data = fb_ext_prop_data, 63 .data = fb_ext_prop_data,
64 }; 64 };
65 65
66 /* 16 bytes of "Compatible ID" and "Subcompatible ID" */ 66 /* 16 bytes of "Compatible ID" and "Subcompatible ID" */
67 static char fb_cid[16] = {'W', 'I', 'N', 'U', 'S', 'B'}; 67 static char fb_cid[16] = {'W', 'I', 'N', 'U', 'S', 'B'};
68 static struct usb_os_desc fb_os_desc = { 68 static struct usb_os_desc fb_os_desc = {
69 .ext_compat_id = fb_cid, 69 .ext_compat_id = fb_cid,
70 }; 70 };
71 71
72 static struct usb_os_desc_table fb_os_desc_table = { 72 static struct usb_os_desc_table fb_os_desc_table = {
73 .os_desc = &fb_os_desc, 73 .os_desc = &fb_os_desc,
74 }; 74 };
75 75
76 static inline struct f_fastboot *func_to_fastboot(struct usb_function *f) 76 static inline struct f_fastboot *func_to_fastboot(struct usb_function *f)
77 { 77 {
78 return container_of(f, struct f_fastboot, usb_function); 78 return container_of(f, struct f_fastboot, usb_function);
79 } 79 }
80 80
81 static struct f_fastboot *fastboot_func; 81 static struct f_fastboot *fastboot_func;
82 82
83 static struct usb_endpoint_descriptor fs_ep_in = { 83 static struct usb_endpoint_descriptor fs_ep_in = {
84 .bLength = USB_DT_ENDPOINT_SIZE, 84 .bLength = USB_DT_ENDPOINT_SIZE,
85 .bDescriptorType = USB_DT_ENDPOINT, 85 .bDescriptorType = USB_DT_ENDPOINT,
86 .bEndpointAddress = USB_DIR_IN, 86 .bEndpointAddress = USB_DIR_IN,
87 .bmAttributes = USB_ENDPOINT_XFER_BULK, 87 .bmAttributes = USB_ENDPOINT_XFER_BULK,
88 .wMaxPacketSize = cpu_to_le16(64), 88 .wMaxPacketSize = cpu_to_le16(64),
89 }; 89 };
90 90
91 static struct usb_endpoint_descriptor fs_ep_out = { 91 static struct usb_endpoint_descriptor fs_ep_out = {
92 .bLength = USB_DT_ENDPOINT_SIZE, 92 .bLength = USB_DT_ENDPOINT_SIZE,
93 .bDescriptorType = USB_DT_ENDPOINT, 93 .bDescriptorType = USB_DT_ENDPOINT,
94 .bEndpointAddress = USB_DIR_OUT, 94 .bEndpointAddress = USB_DIR_OUT,
95 .bmAttributes = USB_ENDPOINT_XFER_BULK, 95 .bmAttributes = USB_ENDPOINT_XFER_BULK,
96 .wMaxPacketSize = cpu_to_le16(64), 96 .wMaxPacketSize = cpu_to_le16(64),
97 }; 97 };
98 98
99 static struct usb_endpoint_descriptor hs_ep_in = { 99 static struct usb_endpoint_descriptor hs_ep_in = {
100 .bLength = USB_DT_ENDPOINT_SIZE, 100 .bLength = USB_DT_ENDPOINT_SIZE,
101 .bDescriptorType = USB_DT_ENDPOINT, 101 .bDescriptorType = USB_DT_ENDPOINT,
102 .bEndpointAddress = USB_DIR_IN, 102 .bEndpointAddress = USB_DIR_IN,
103 .bmAttributes = USB_ENDPOINT_XFER_BULK, 103 .bmAttributes = USB_ENDPOINT_XFER_BULK,
104 .wMaxPacketSize = cpu_to_le16(512), 104 .wMaxPacketSize = cpu_to_le16(512),
105 }; 105 };
106 106
107 static struct usb_endpoint_descriptor hs_ep_out = { 107 static struct usb_endpoint_descriptor hs_ep_out = {
108 .bLength = USB_DT_ENDPOINT_SIZE, 108 .bLength = USB_DT_ENDPOINT_SIZE,
109 .bDescriptorType = USB_DT_ENDPOINT, 109 .bDescriptorType = USB_DT_ENDPOINT,
110 .bEndpointAddress = USB_DIR_OUT, 110 .bEndpointAddress = USB_DIR_OUT,
111 .bmAttributes = USB_ENDPOINT_XFER_BULK, 111 .bmAttributes = USB_ENDPOINT_XFER_BULK,
112 .wMaxPacketSize = cpu_to_le16(512), 112 .wMaxPacketSize = cpu_to_le16(512),
113 }; 113 };
114 114
115 static struct usb_interface_descriptor interface_desc = { 115 static struct usb_interface_descriptor interface_desc = {
116 .bLength = USB_DT_INTERFACE_SIZE, 116 .bLength = USB_DT_INTERFACE_SIZE,
117 .bDescriptorType = USB_DT_INTERFACE, 117 .bDescriptorType = USB_DT_INTERFACE,
118 .bInterfaceNumber = 0x00, 118 .bInterfaceNumber = 0x00,
119 .bAlternateSetting = 0x00, 119 .bAlternateSetting = 0x00,
120 .bNumEndpoints = 0x02, 120 .bNumEndpoints = 0x02,
121 .bInterfaceClass = FASTBOOT_INTERFACE_CLASS, 121 .bInterfaceClass = FASTBOOT_INTERFACE_CLASS,
122 .bInterfaceSubClass = FASTBOOT_INTERFACE_SUB_CLASS, 122 .bInterfaceSubClass = FASTBOOT_INTERFACE_SUB_CLASS,
123 .bInterfaceProtocol = FASTBOOT_INTERFACE_PROTOCOL, 123 .bInterfaceProtocol = FASTBOOT_INTERFACE_PROTOCOL,
124 }; 124 };
125 125
126 static struct usb_descriptor_header *fb_fs_function[] = { 126 static struct usb_descriptor_header *fb_fs_function[] = {
127 (struct usb_descriptor_header *)&interface_desc, 127 (struct usb_descriptor_header *)&interface_desc,
128 (struct usb_descriptor_header *)&fs_ep_in, 128 (struct usb_descriptor_header *)&fs_ep_in,
129 (struct usb_descriptor_header *)&fs_ep_out, 129 (struct usb_descriptor_header *)&fs_ep_out,
130 }; 130 };
131 131
132 static struct usb_descriptor_header *fb_hs_function[] = { 132 static struct usb_descriptor_header *fb_hs_function[] = {
133 (struct usb_descriptor_header *)&interface_desc, 133 (struct usb_descriptor_header *)&interface_desc,
134 (struct usb_descriptor_header *)&hs_ep_in, 134 (struct usb_descriptor_header *)&hs_ep_in,
135 (struct usb_descriptor_header *)&hs_ep_out, 135 (struct usb_descriptor_header *)&hs_ep_out,
136 NULL, 136 NULL,
137 }; 137 };
138 138
139 /* Super speed */ 139 /* Super speed */
140 static struct usb_endpoint_descriptor ss_ep_in = { 140 static struct usb_endpoint_descriptor ss_ep_in = {
141 .bLength = USB_DT_ENDPOINT_SIZE, 141 .bLength = USB_DT_ENDPOINT_SIZE,
142 .bDescriptorType = USB_DT_ENDPOINT, 142 .bDescriptorType = USB_DT_ENDPOINT,
143 .bEndpointAddress = USB_DIR_IN, 143 .bEndpointAddress = USB_DIR_IN,
144 .bmAttributes = USB_ENDPOINT_XFER_BULK, 144 .bmAttributes = USB_ENDPOINT_XFER_BULK,
145 .wMaxPacketSize = cpu_to_le16(1024), 145 .wMaxPacketSize = cpu_to_le16(1024),
146 }; 146 };
147 147
148 static struct usb_endpoint_descriptor ss_ep_out = { 148 static struct usb_endpoint_descriptor ss_ep_out = {
149 .bLength = USB_DT_ENDPOINT_SIZE, 149 .bLength = USB_DT_ENDPOINT_SIZE,
150 .bDescriptorType = USB_DT_ENDPOINT, 150 .bDescriptorType = USB_DT_ENDPOINT,
151 .bEndpointAddress = USB_DIR_OUT, 151 .bEndpointAddress = USB_DIR_OUT,
152 .bmAttributes = USB_ENDPOINT_XFER_BULK, 152 .bmAttributes = USB_ENDPOINT_XFER_BULK,
153 .wMaxPacketSize = cpu_to_le16(1024), 153 .wMaxPacketSize = cpu_to_le16(1024),
154 }; 154 };
155 155
156 static struct usb_ss_ep_comp_descriptor fb_ss_bulk_comp_desc = { 156 static struct usb_ss_ep_comp_descriptor fb_ss_bulk_comp_desc = {
157 .bLength = sizeof(fb_ss_bulk_comp_desc), 157 .bLength = sizeof(fb_ss_bulk_comp_desc),
158 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, 158 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
159 }; 159 };
160 160
161 static struct usb_descriptor_header *fb_ss_function[] = { 161 static struct usb_descriptor_header *fb_ss_function[] = {
162 (struct usb_descriptor_header *)&interface_desc, 162 (struct usb_descriptor_header *)&interface_desc,
163 (struct usb_descriptor_header *)&ss_ep_in, 163 (struct usb_descriptor_header *)&ss_ep_in,
164 (struct usb_descriptor_header *)&fb_ss_bulk_comp_desc, 164 (struct usb_descriptor_header *)&fb_ss_bulk_comp_desc,
165 (struct usb_descriptor_header *)&ss_ep_out, 165 (struct usb_descriptor_header *)&ss_ep_out,
166 (struct usb_descriptor_header *)&fb_ss_bulk_comp_desc, 166 (struct usb_descriptor_header *)&fb_ss_bulk_comp_desc,
167 NULL, 167 NULL,
168 }; 168 };
169 169
170 static struct usb_endpoint_descriptor * 170 static struct usb_endpoint_descriptor *
171 fb_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, 171 fb_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
172 struct usb_endpoint_descriptor *hs, 172 struct usb_endpoint_descriptor *hs,
173 struct usb_endpoint_descriptor *ss) 173 struct usb_endpoint_descriptor *ss)
174 { 174 {
175 if (gadget_is_superspeed(g) && g->speed >= USB_SPEED_SUPER) 175 if (gadget_is_superspeed(g) && g->speed >= USB_SPEED_SUPER)
176 return ss; 176 return ss;
177 177
178 if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) 178 if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
179 return hs; 179 return hs;
180 return fs; 180 return fs;
181 } 181 }
182 182
183 /* 183 /*
184 * static strings, in UTF-8 184 * static strings, in UTF-8
185 */ 185 */
186 static const char fastboot_name[] = "Android Fastboot"; 186 static const char fastboot_name[] = "Android Fastboot";
187 187
188 static struct usb_string fastboot_string_defs[] = { 188 static struct usb_string fastboot_string_defs[] = {
189 [0].s = fastboot_name, 189 [0].s = fastboot_name,
190 { } /* end of list */ 190 { } /* end of list */
191 }; 191 };
192 192
193 static struct usb_gadget_strings stringtab_fastboot = { 193 static struct usb_gadget_strings stringtab_fastboot = {
194 .language = 0x0409, /* en-us */ 194 .language = 0x0409, /* en-us */
195 .strings = fastboot_string_defs, 195 .strings = fastboot_string_defs,
196 }; 196 };
197 197
198 static struct usb_gadget_strings *fastboot_strings[] = { 198 static struct usb_gadget_strings *fastboot_strings[] = {
199 &stringtab_fastboot, 199 &stringtab_fastboot,
200 NULL, 200 NULL,
201 }; 201 };
202 202
203 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) 203 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
204 extern struct stdio_dev g_fastboot_stdio; 204 extern struct stdio_dev g_fastboot_stdio;
205 #endif 205 #endif
206 206
207 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req); 207 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req);
208 208
209 static void fastboot_fifo_complete(struct usb_ep *ep, struct usb_request *req) 209 static void fastboot_fifo_complete(struct usb_ep *ep, struct usb_request *req)
210 { 210 {
211 int status = req->status; 211 int status = req->status;
212 usb_req *request; 212 usb_req *request;
213 213
214 if (!status) { 214 if (!status) {
215 if (fastboot_func->front != NULL) { 215 if (fastboot_func->front != NULL) {
216 request = fastboot_func->front; 216 request = fastboot_func->front;
217 fastboot_func->front = fastboot_func->front->next; 217 fastboot_func->front = fastboot_func->front->next;
218 usb_ep_free_request(ep, request->in_req); 218 usb_ep_free_request(ep, request->in_req);
219 free(request); 219 free(request);
220 } else { 220 } else {
221 printf("fail free request\n"); 221 printf("fail free request\n");
222 } 222 }
223 return; 223 return;
224 } 224 }
225 } 225 }
226 226
227 static void fastboot_complete(struct usb_ep *ep, struct usb_request *req) 227 static void fastboot_complete(struct usb_ep *ep, struct usb_request *req)
228 { 228 {
229 int status = req->status; 229 int status = req->status;
230 if (!status) 230 if (!status)
231 return; 231 return;
232 printf("status: %d ep '%s' trans: %d\n", status, ep->name, req->actual); 232 printf("status: %d ep '%s' trans: %d\n", status, ep->name, req->actual);
233 } 233 }
234 234
235 static int fastboot_bind(struct usb_configuration *c, struct usb_function *f) 235 static int fastboot_bind(struct usb_configuration *c, struct usb_function *f)
236 { 236 {
237 int id; 237 int id;
238 struct usb_gadget *gadget = c->cdev->gadget; 238 struct usb_gadget *gadget = c->cdev->gadget;
239 struct f_fastboot *f_fb = func_to_fastboot(f); 239 struct f_fastboot *f_fb = func_to_fastboot(f);
240 const char *s; 240 const char *s;
241 241
242 /* DYNAMIC interface numbers assignments */ 242 /* DYNAMIC interface numbers assignments */
243 id = usb_interface_id(c, f); 243 id = usb_interface_id(c, f);
244 if (id < 0) 244 if (id < 0)
245 return id; 245 return id;
246 interface_desc.bInterfaceNumber = id; 246 interface_desc.bInterfaceNumber = id;
247 247
248 /* Enable OS and Extended Properties Feature Descriptor */ 248 /* Enable OS and Extended Properties Feature Descriptor */
249 c->cdev->use_os_string = 1; 249 c->cdev->use_os_string = 1;
250 f->os_desc_table = &fb_os_desc_table; 250 f->os_desc_table = &fb_os_desc_table;
251 f->os_desc_n = 1; 251 f->os_desc_n = 1;
252 f->os_desc_table->if_id = id; 252 f->os_desc_table->if_id = id;
253 INIT_LIST_HEAD(&fb_os_desc.ext_prop); 253 INIT_LIST_HEAD(&fb_os_desc.ext_prop);
254 fb_ext_prop.name_len = strlen(fb_ext_prop.name) * 2 + 2; 254 fb_ext_prop.name_len = strlen(fb_ext_prop.name) * 2 + 2;
255 fb_os_desc.ext_prop_len = 10 + fb_ext_prop.name_len; 255 fb_os_desc.ext_prop_len = 10 + fb_ext_prop.name_len;
256 fb_os_desc.ext_prop_count = 1; 256 fb_os_desc.ext_prop_count = 1;
257 fb_ext_prop.data_len = strlen(fb_ext_prop.data) * 2 + 2; 257 fb_ext_prop.data_len = strlen(fb_ext_prop.data) * 2 + 2;
258 fb_os_desc.ext_prop_len += fb_ext_prop.data_len + 4; 258 fb_os_desc.ext_prop_len += fb_ext_prop.data_len + 4;
259 list_add_tail(&fb_ext_prop.entry, &fb_os_desc.ext_prop); 259 list_add_tail(&fb_ext_prop.entry, &fb_os_desc.ext_prop);
260 260
261 id = usb_string_id(c->cdev); 261 id = usb_string_id(c->cdev);
262 if (id < 0) 262 if (id < 0)
263 return id; 263 return id;
264 fastboot_string_defs[0].id = id; 264 fastboot_string_defs[0].id = id;
265 interface_desc.iInterface = id; 265 interface_desc.iInterface = id;
266 266
267 f_fb->in_ep = usb_ep_autoconfig(gadget, &fs_ep_in); 267 f_fb->in_ep = usb_ep_autoconfig(gadget, &fs_ep_in);
268 if (!f_fb->in_ep) 268 if (!f_fb->in_ep)
269 return -ENODEV; 269 return -ENODEV;
270 f_fb->in_ep->driver_data = c->cdev; 270 f_fb->in_ep->driver_data = c->cdev;
271 271
272 f_fb->out_ep = usb_ep_autoconfig(gadget, &fs_ep_out); 272 f_fb->out_ep = usb_ep_autoconfig(gadget, &fs_ep_out);
273 if (!f_fb->out_ep) 273 if (!f_fb->out_ep)
274 return -ENODEV; 274 return -ENODEV;
275 f_fb->out_ep->driver_data = c->cdev; 275 f_fb->out_ep->driver_data = c->cdev;
276 276
277 f->descriptors = fb_fs_function; 277 f->descriptors = fb_fs_function;
278 278
279 if (gadget_is_dualspeed(gadget)) { 279 if (gadget_is_dualspeed(gadget)) {
280 /* Assume endpoint addresses are the same for both speeds */ 280 /* Assume endpoint addresses are the same for both speeds */
281 hs_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress; 281 hs_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress;
282 hs_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress; 282 hs_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress;
283 /* copy HS descriptors */ 283 /* copy HS descriptors */
284 f->hs_descriptors = fb_hs_function; 284 f->hs_descriptors = fb_hs_function;
285 } 285 }
286 286
287 if (gadget_is_superspeed(gadget)) { 287 if (gadget_is_superspeed(gadget)) {
288 ss_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress; 288 ss_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress;
289 ss_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress; 289 ss_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress;
290 f->ss_descriptors = fb_ss_function; 290 f->ss_descriptors = fb_ss_function;
291 } 291 }
292 292
293 s = env_get("serial#"); 293 s = env_get("serial#");
294 if (s) 294 if (s)
295 g_dnl_set_serialnumber((char *)s); 295 g_dnl_set_serialnumber((char *)s);
296 296
297 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) 297 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
298 stdio_register(&g_fastboot_stdio); 298 stdio_register(&g_fastboot_stdio);
299 #endif 299 #endif
300 300
301 return 0; 301 return 0;
302 } 302 }
303 303
304 static void fastboot_unbind(struct usb_configuration *c, struct usb_function *f) 304 static void fastboot_unbind(struct usb_configuration *c, struct usb_function *f)
305 { 305 {
306 f->os_desc_table = NULL; 306 f->os_desc_table = NULL;
307 list_del(&fb_os_desc.ext_prop); 307 list_del(&fb_os_desc.ext_prop);
308 memset(fastboot_func, 0, sizeof(*fastboot_func)); 308 memset(fastboot_func, 0, sizeof(*fastboot_func));
309 309
310 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) && CONFIG_IS_ENABLED(SYS_STDIO_DEREGISTER) 310 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) && CONFIG_IS_ENABLED(SYS_STDIO_DEREGISTER)
311 stdio_deregister("fastboot", 1); 311 stdio_deregister("fastboot", 1);
312 #endif 312 #endif
313 313
314 } 314 }
315 315
316 static void fastboot_disable(struct usb_function *f) 316 static void fastboot_disable(struct usb_function *f)
317 { 317 {
318 struct f_fastboot *f_fb = func_to_fastboot(f); 318 struct f_fastboot *f_fb = func_to_fastboot(f);
319 319
320 usb_ep_disable(f_fb->out_ep); 320 usb_ep_disable(f_fb->out_ep);
321 usb_ep_disable(f_fb->in_ep); 321 usb_ep_disable(f_fb->in_ep);
322 322
323 if (f_fb->out_req) { 323 if (f_fb->out_req) {
324 free(f_fb->out_req->buf); 324 free(f_fb->out_req->buf);
325 usb_ep_free_request(f_fb->out_ep, f_fb->out_req); 325 usb_ep_free_request(f_fb->out_ep, f_fb->out_req);
326 f_fb->out_req = NULL; 326 f_fb->out_req = NULL;
327 } 327 }
328 if (f_fb->in_req) { 328 if (f_fb->in_req) {
329 free(f_fb->in_req->buf); 329 free(f_fb->in_req->buf);
330 usb_ep_free_request(f_fb->in_ep, f_fb->in_req); 330 usb_ep_free_request(f_fb->in_ep, f_fb->in_req);
331 f_fb->in_req = NULL; 331 f_fb->in_req = NULL;
332 } 332 }
333 } 333 }
334 334
335 static struct usb_request *fastboot_start_ep(struct usb_ep *ep) 335 static struct usb_request *fastboot_start_ep(struct usb_ep *ep)
336 { 336 {
337 struct usb_request *req; 337 struct usb_request *req;
338 338
339 req = usb_ep_alloc_request(ep, 0); 339 req = usb_ep_alloc_request(ep, 0);
340 if (!req) 340 if (!req)
341 return NULL; 341 return NULL;
342 342
343 req->length = EP_BUFFER_SIZE; 343 req->length = EP_BUFFER_SIZE;
344 req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, EP_BUFFER_SIZE); 344 req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, EP_BUFFER_SIZE);
345 if (!req->buf) { 345 if (!req->buf) {
346 usb_ep_free_request(ep, req); 346 usb_ep_free_request(ep, req);
347 return NULL; 347 return NULL;
348 } 348 }
349 349
350 memset(req->buf, 0, req->length); 350 memset(req->buf, 0, req->length);
351 return req; 351 return req;
352 } 352 }
353 353
354 static int fastboot_set_alt(struct usb_function *f, 354 static int fastboot_set_alt(struct usb_function *f,
355 unsigned interface, unsigned alt) 355 unsigned interface, unsigned alt)
356 { 356 {
357 int ret; 357 int ret;
358 struct usb_composite_dev *cdev = f->config->cdev; 358 struct usb_composite_dev *cdev = f->config->cdev;
359 struct usb_gadget *gadget = cdev->gadget; 359 struct usb_gadget *gadget = cdev->gadget;
360 struct f_fastboot *f_fb = func_to_fastboot(f); 360 struct f_fastboot *f_fb = func_to_fastboot(f);
361 const struct usb_endpoint_descriptor *d; 361 const struct usb_endpoint_descriptor *d;
362 362
363 debug("%s: func: %s intf: %d alt: %d\n", 363 debug("%s: func: %s intf: %d alt: %d\n",
364 __func__, f->name, interface, alt); 364 __func__, f->name, interface, alt);
365 365
366 d = fb_ep_desc(gadget, &fs_ep_out, &hs_ep_out, &ss_ep_out); 366 d = fb_ep_desc(gadget, &fs_ep_out, &hs_ep_out, &ss_ep_out);
367 ret = usb_ep_enable(f_fb->out_ep, d); 367 ret = usb_ep_enable(f_fb->out_ep, d);
368 if (ret) { 368 if (ret) {
369 puts("failed to enable out ep\n"); 369 puts("failed to enable out ep\n");
370 return ret; 370 return ret;
371 } 371 }
372 372
373 f_fb->out_req = fastboot_start_ep(f_fb->out_ep); 373 f_fb->out_req = fastboot_start_ep(f_fb->out_ep);
374 if (!f_fb->out_req) { 374 if (!f_fb->out_req) {
375 puts("failed to alloc out req\n"); 375 puts("failed to alloc out req\n");
376 ret = -EINVAL; 376 ret = -EINVAL;
377 goto err; 377 goto err;
378 } 378 }
379 f_fb->out_req->complete = rx_handler_command; 379 f_fb->out_req->complete = rx_handler_command;
380 380
381 d = fb_ep_desc(gadget, &fs_ep_in, &hs_ep_in, &ss_ep_in); 381 d = fb_ep_desc(gadget, &fs_ep_in, &hs_ep_in, &ss_ep_in);
382 ret = usb_ep_enable(f_fb->in_ep, d); 382 ret = usb_ep_enable(f_fb->in_ep, d);
383 if (ret) { 383 if (ret) {
384 puts("failed to enable in ep\n"); 384 puts("failed to enable in ep\n");
385 goto err; 385 goto err;
386 } 386 }
387 387
388 f_fb->in_req = fastboot_start_ep(f_fb->in_ep); 388 f_fb->in_req = fastboot_start_ep(f_fb->in_ep);
389 if (!f_fb->in_req) { 389 if (!f_fb->in_req) {
390 puts("failed alloc req in\n"); 390 puts("failed alloc req in\n");
391 ret = -EINVAL; 391 ret = -EINVAL;
392 goto err; 392 goto err;
393 } 393 }
394 f_fb->in_req->complete = fastboot_complete; 394 f_fb->in_req->complete = fastboot_complete;
395 395
396 ret = usb_ep_queue(f_fb->out_ep, f_fb->out_req, 0); 396 ret = usb_ep_queue(f_fb->out_ep, f_fb->out_req, 0);
397 if (ret) 397 if (ret)
398 goto err; 398 goto err;
399 399
400 return 0; 400 return 0;
401 err: 401 err:
402 fastboot_disable(f); 402 fastboot_disable(f);
403 return ret; 403 return ret;
404 } 404 }
405 405
406 static int fastboot_add(struct usb_configuration *c) 406 static int fastboot_add(struct usb_configuration *c)
407 { 407 {
408 struct f_fastboot *f_fb = fastboot_func; 408 struct f_fastboot *f_fb = fastboot_func;
409 int status; 409 int status;
410 410
411 debug("%s: cdev: 0x%p\n", __func__, c->cdev); 411 debug("%s: cdev: 0x%p\n", __func__, c->cdev);
412 412
413 if (!f_fb) { 413 if (!f_fb) {
414 f_fb = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*f_fb)); 414 f_fb = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*f_fb));
415 if (!f_fb) 415 if (!f_fb)
416 return -ENOMEM; 416 return -ENOMEM;
417 417
418 fastboot_func = f_fb; 418 fastboot_func = f_fb;
419 memset(f_fb, 0, sizeof(*f_fb)); 419 memset(f_fb, 0, sizeof(*f_fb));
420 } 420 }
421 421
422 f_fb->usb_function.name = "f_fastboot"; 422 f_fb->usb_function.name = "f_fastboot";
423 f_fb->usb_function.bind = fastboot_bind; 423 f_fb->usb_function.bind = fastboot_bind;
424 f_fb->usb_function.unbind = fastboot_unbind; 424 f_fb->usb_function.unbind = fastboot_unbind;
425 f_fb->usb_function.set_alt = fastboot_set_alt; 425 f_fb->usb_function.set_alt = fastboot_set_alt;
426 f_fb->usb_function.disable = fastboot_disable; 426 f_fb->usb_function.disable = fastboot_disable;
427 f_fb->usb_function.strings = fastboot_strings; 427 f_fb->usb_function.strings = fastboot_strings;
428 428
429 status = usb_add_function(c, &f_fb->usb_function); 429 status = usb_add_function(c, &f_fb->usb_function);
430 if (status) { 430 if (status) {
431 free(f_fb); 431 free(f_fb);
432 fastboot_func = f_fb; 432 fastboot_func = f_fb;
433 } 433 }
434 434
435 return status; 435 return status;
436 } 436 }
437 DECLARE_GADGET_BIND_CALLBACK(usb_dnl_fastboot, fastboot_add); 437 DECLARE_GADGET_BIND_CALLBACK(usb_dnl_fastboot, fastboot_add);
438 438
439 int fastboot_tx_write_more(const char *buffer) 439 int fastboot_tx_write_more(const char *buffer)
440 { 440 {
441 int ret = 0; 441 int ret = 0;
442 442
443 /* alloc usb request FIFO node */ 443 /* alloc usb request FIFO node */
444 usb_req *req = (usb_req *)malloc(sizeof(usb_req)); 444 usb_req *req = (usb_req *)malloc(sizeof(usb_req));
445 if (!req) { 445 if (!req) {
446 printf("failed alloc usb req!\n"); 446 printf("failed alloc usb req!\n");
447 return -ENOMEM; 447 return -ENOMEM;
448 } 448 }
449 449
450 /* usb request node FIFO enquene */ 450 /* usb request node FIFO enquene */
451 if ((fastboot_func->front == NULL) && (fastboot_func->rear == NULL)) { 451 if ((fastboot_func->front == NULL) && (fastboot_func->rear == NULL)) {
452 fastboot_func->front = fastboot_func->rear = req; 452 fastboot_func->front = fastboot_func->rear = req;
453 req->next = NULL; 453 req->next = NULL;
454 } else { 454 } else {
455 fastboot_func->rear->next = req; 455 fastboot_func->rear->next = req;
456 fastboot_func->rear = req; 456 fastboot_func->rear = req;
457 req->next = NULL; 457 req->next = NULL;
458 } 458 }
459 459
460 /* alloc in request for current node */ 460 /* alloc in request for current node */
461 req->in_req = fastboot_start_ep(fastboot_func->in_ep); 461 req->in_req = fastboot_start_ep(fastboot_func->in_ep);
462 if (!req->in_req) { 462 if (!req->in_req) {
463 printf("failed alloc req in\n"); 463 printf("failed alloc req in\n");
464 fastboot_disable(&(fastboot_func->usb_function)); 464 fastboot_disable(&(fastboot_func->usb_function));
465 return -EINVAL; 465 return -EINVAL;
466 } 466 }
467 req->in_req->complete = fastboot_fifo_complete; 467 req->in_req->complete = fastboot_fifo_complete;
468 468
469 memcpy(req->in_req->buf, buffer, strlen(buffer)); 469 memcpy(req->in_req->buf, buffer, strlen(buffer));
470 req->in_req->length = strlen(buffer); 470 req->in_req->length = strlen(buffer);
471 471
472 ret = usb_ep_queue(fastboot_func->in_ep, req->in_req, 0); 472 ret = usb_ep_queue(fastboot_func->in_ep, req->in_req, 0);
473 if (ret) { 473 if (ret) {
474 printf("Error %d on queue\n", ret); 474 printf("Error %d on queue\n", ret);
475 return -EINVAL; 475 return -EINVAL;
476 } 476 }
477 477
478 ret = 0; 478 ret = 0;
479 return ret; 479 return ret;
480 } 480 }
481 481
482 int fastboot_tx_write(const char *buffer, unsigned int buffer_size) 482 int fastboot_tx_write(const char *buffer, unsigned int buffer_size)
483 { 483 {
484 struct usb_request *in_req = fastboot_func->in_req; 484 struct usb_request *in_req = fastboot_func->in_req;
485 int ret; 485 int ret;
486 486
487 if (!buffer_size) 487 if (!buffer_size)
488 return 0; 488 return 0;
489 489
490 memcpy(in_req->buf, buffer, buffer_size); 490 memcpy(in_req->buf, buffer, buffer_size);
491 in_req->length = buffer_size; 491 in_req->length = buffer_size;
492 492
493 usb_ep_dequeue(fastboot_func->in_ep, in_req); 493 usb_ep_dequeue(fastboot_func->in_ep, in_req);
494 494
495 ret = usb_ep_queue(fastboot_func->in_ep, in_req, 0); 495 ret = usb_ep_queue(fastboot_func->in_ep, in_req, 0);
496 if (ret) 496 if (ret)
497 printf("Error %d on queue\n", ret); 497 printf("Error %d on queue\n", ret);
498 return 0; 498 return 0;
499 } 499 }
500 500
501 static int fastboot_tx_write_str(const char *buffer) 501 static int fastboot_tx_write_str(const char *buffer)
502 { 502 {
503 return fastboot_tx_write(buffer, strlen(buffer)); 503 return fastboot_tx_write(buffer, strlen(buffer));
504 } 504 }
505 505
506 static void compl_do_reset(struct usb_ep *ep, struct usb_request *req) 506 static void compl_do_reset(struct usb_ep *ep, struct usb_request *req)
507 { 507 {
508 do_reset(NULL, 0, 0, NULL); 508 do_reset(NULL, 0, 0, NULL);
509 } 509 }
510 510
511 static unsigned int rx_bytes_expected(struct usb_ep *ep) 511 static unsigned int rx_bytes_expected(struct usb_ep *ep)
512 { 512 {
513 int rx_remain = fastboot_data_remaining(); 513 int rx_remain = fastboot_data_remaining();
514 unsigned int rem; 514 unsigned int rem;
515 unsigned int maxpacket = usb_endpoint_maxp(ep->desc); 515 unsigned int maxpacket = usb_endpoint_maxp(ep->desc);
516 516
517 if (rx_remain <= 0) 517 if (rx_remain <= 0)
518 return 0; 518 return 0;
519 else if (rx_remain > EP_BUFFER_SIZE) 519 else if (rx_remain > EP_BUFFER_SIZE)
520 return EP_BUFFER_SIZE; 520 return EP_BUFFER_SIZE;
521 521
522 /* 522 /*
523 * Some controllers e.g. DWC3 don't like OUT transfers to be 523 * Some controllers e.g. DWC3 don't like OUT transfers to be
524 * not ending in maxpacket boundary. So just make them happy by 524 * not ending in maxpacket boundary. So just make them happy by
525 * always requesting for integral multiple of maxpackets. 525 * always requesting for integral multiple of maxpackets.
526 * This shouldn't bother controllers that don't care about it. 526 * This shouldn't bother controllers that don't care about it.
527 */ 527 */
528 rem = rx_remain % maxpacket; 528 rem = rx_remain % maxpacket;
529 if (rem > 0) 529 if (rem > 0)
530 rx_remain = rx_remain + (maxpacket - rem); 530 rx_remain = rx_remain + (maxpacket - rem);
531 531
532 return rx_remain; 532 return rx_remain;
533 } 533 }
534 534
535 static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) 535 static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
536 { 536 {
537 char response[FASTBOOT_RESPONSE_LEN] = {0}; 537 char response[FASTBOOT_RESPONSE_LEN] = {0};
538 unsigned int transfer_size = fastboot_data_remaining(); 538 unsigned int transfer_size = fastboot_data_remaining();
539 const unsigned char *buffer = req->buf; 539 const unsigned char *buffer = req->buf;
540 unsigned int buffer_size = req->actual; 540 unsigned int buffer_size = req->actual;
541 541
542 if (req->status != 0) { 542 if (req->status != 0) {
543 printf("Bad status: %d\n", req->status); 543 printf("Bad status: %d\n", req->status);
544 return; 544 return;
545 } 545 }
546 546
547 if (buffer_size < transfer_size) 547 if (buffer_size < transfer_size)
548 transfer_size = buffer_size; 548 transfer_size = buffer_size;
549 549
550 fastboot_data_download(buffer, transfer_size, response); 550 fastboot_data_download(buffer, transfer_size, response);
551 if (response[0]) { 551 if (response[0]) {
552 fastboot_tx_write_str(response); 552 fastboot_tx_write_str(response);
553 } else if (!fastboot_data_remaining()) { 553 } else if (!fastboot_data_remaining()) {
554 fastboot_data_complete(response); 554 fastboot_data_complete(response);
555 555
556 /* 556 /*
557 * Reset global transfer variable 557 * Reset global transfer variable
558 */ 558 */
559 req->complete = rx_handler_command; 559 req->complete = rx_handler_command;
560 req->length = EP_BUFFER_SIZE; 560 req->length = EP_BUFFER_SIZE;
561 561
562 fastboot_tx_write_str(response); 562 fastboot_tx_write_str(response);
563 } else { 563 } else {
564 req->length = rx_bytes_expected(ep); 564 req->length = rx_bytes_expected(ep);
565 } 565 }
566 566
567 req->actual = 0; 567 req->actual = 0;
568 usb_ep_queue(ep, req, 0); 568 usb_ep_queue(ep, req, 0);
569 } 569 }
570 570
571 static void do_exit_on_complete(struct usb_ep *ep, struct usb_request *req) 571 static void do_exit_on_complete(struct usb_ep *ep, struct usb_request *req)
572 { 572 {
573 g_dnl_trigger_detach(); 573 g_dnl_trigger_detach();
574 } 574 }
575 575
576 static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req) 576 static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
577 { 577 {
578 fastboot_boot(); 578 fastboot_boot();
579 do_exit_on_complete(ep, req); 579 do_exit_on_complete(ep, req);
580 } 580 }
581 581
582 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) 582 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
583 static void do_acmd_complete(struct usb_ep *ep, struct usb_request *req) 583 static void do_acmd_complete(struct usb_ep *ep, struct usb_request *req)
584 { 584 {
585 /* When usb dequeue complete will be called 585 /* When usb dequeue complete will be called
586 * Need status value before call run_command. 586 * Need status value before call run_command.
587 * otherwise, host can't get last message. 587 * otherwise, host can't get last message.
588 */ 588 */
589 if(req->status == 0) 589 if(req->status == 0)
590 fastboot_acmd_complete(); 590 fastboot_acmd_complete();
591 } 591 }
592 #endif 592 #endif
593 593
594 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) 594 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
595 { 595 {
596 char *cmdbuf = req->buf; 596 char *cmdbuf = req->buf;
597 char response[FASTBOOT_RESPONSE_LEN] = {0}; 597 char response[FASTBOOT_RESPONSE_LEN] = {0};
598 int cmd = -1; 598 int cmd = -1;
599 599
600 /* init in request FIFO pointer */ 600 /* init in request FIFO pointer */
601 fastboot_func->front = NULL; 601 fastboot_func->front = NULL;
602 fastboot_func->rear = NULL; 602 fastboot_func->rear = NULL;
603 603
604 if (req->status != 0 || req->length == 0) 604 if (req->status != 0 || req->length == 0)
605 return; 605 return;
606 606
607 if (req->actual < req->length) { 607 if (req->actual < req->length) {
608 cmdbuf[req->actual] = '\0'; 608 cmdbuf[req->actual] = '\0';
609 cmd = fastboot_handle_command(cmdbuf, response); 609 cmd = fastboot_handle_command(cmdbuf, response);
610 } else { 610 } else {
611 pr_err("buffer overflow"); 611 pr_err("buffer overflow");
612 fastboot_fail("buffer overflow", response); 612 fastboot_fail("buffer overflow", response);
613 } 613 }
614 614
615 if (!strncmp("DATA", response, 4)) { 615 if (!strncmp("DATA", response, 4)) {
616 req->complete = rx_handler_dl_image; 616 req->complete = rx_handler_dl_image;
617 req->length = rx_bytes_expected(ep); 617 req->length = rx_bytes_expected(ep);
618 } 618 }
619 619
620 fastboot_tx_write_str(response); 620 fastboot_tx_write_str(response);
621 621
622 if (!strncmp("OKAY", response, 4)) { 622 if (!strncmp("OKAY", response, 4)) {
623 switch (cmd) { 623 switch (cmd) {
624 case FASTBOOT_COMMAND_BOOT: 624 case FASTBOOT_COMMAND_BOOT:
625 fastboot_func->in_req->complete = do_bootm_on_complete; 625 fastboot_func->in_req->complete = do_bootm_on_complete;
626 break; 626 break;
627 627
628 case FASTBOOT_COMMAND_CONTINUE: 628 case FASTBOOT_COMMAND_CONTINUE:
629 fastboot_func->in_req->complete = do_exit_on_complete; 629 fastboot_func->in_req->complete = do_exit_on_complete;
630 break; 630 break;
631 631
632 case FASTBOOT_COMMAND_REBOOT: 632 case FASTBOOT_COMMAND_REBOOT:
633 case FASTBOOT_COMMAND_REBOOT_BOOTLOADER: 633 case FASTBOOT_COMMAND_REBOOT_BOOTLOADER:
634 #ifdef CONFIG_ANDROID_RECOVERY
635 case FASTBOOT_COMMAND_RECOVERY_FASTBOOT:
636 #endif
634 fastboot_func->in_req->complete = compl_do_reset; 637 fastboot_func->in_req->complete = compl_do_reset;
635 break; 638 break;
636 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) 639 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
637 case FASTBOOT_COMMAND_ACMD: 640 case FASTBOOT_COMMAND_ACMD:
638 fastboot_func->in_req->complete = do_acmd_complete; 641 fastboot_func->in_req->complete = do_acmd_complete;
639 break; 642 break;
640 #endif 643 #endif
641 } 644 }
642 } 645 }
643 646
644 *cmdbuf = '\0'; 647 *cmdbuf = '\0';
645 req->actual = 0; 648 req->actual = 0;
646 usb_ep_queue(ep, req, 0); 649 usb_ep_queue(ep, req, 0);
647 } 650 }
648 651
1 /* SPDX-License-Identifier: GPL-2.0+ */ 1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /* 2 /*
3 * (C) Copyright 2008 - 2009 3 * (C) Copyright 2008 - 2009
4 * Windriver, <www.windriver.com> 4 * Windriver, <www.windriver.com>
5 * Tom Rix <Tom.Rix@windriver.com> 5 * Tom Rix <Tom.Rix@windriver.com>
6 * 6 *
7 * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de> 7 * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8 * 8 *
9 * Copyright 2014 Linaro, Ltd. 9 * Copyright 2014 Linaro, Ltd.
10 * Rob Herring <robh@kernel.org> 10 * Rob Herring <robh@kernel.org>
11 */ 11 */
12 #ifndef _FASTBOOT_H_ 12 #ifndef _FASTBOOT_H_
13 #define _FASTBOOT_H_ 13 #define _FASTBOOT_H_
14 14
15 #define FASTBOOT_VERSION "0.4" 15 #define FASTBOOT_VERSION "0.4"
16 16
17 /* The 64 defined bytes plus \0 */ 17 /* The 64 defined bytes plus \0 */
18 #define FASTBOOT_COMMAND_LEN (64 + 1) 18 #define FASTBOOT_COMMAND_LEN (64 + 1)
19 #define FASTBOOT_RESPONSE_LEN (64 + 1) 19 #define FASTBOOT_RESPONSE_LEN (64 + 1)
20 20
21 /** 21 /**
22 * All known commands to fastboot 22 * All known commands to fastboot
23 */ 23 */
24 enum { 24 enum {
25 FASTBOOT_COMMAND_GETVAR = 0, 25 FASTBOOT_COMMAND_GETVAR = 0,
26 FASTBOOT_COMMAND_DOWNLOAD, 26 FASTBOOT_COMMAND_DOWNLOAD,
27 #if CONFIG_IS_ENABLED(FASTBOOT_FLASH) 27 #if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
28 FASTBOOT_COMMAND_FLASH, 28 FASTBOOT_COMMAND_FLASH,
29 FASTBOOT_COMMAND_ERASE, 29 FASTBOOT_COMMAND_ERASE,
30 #endif 30 #endif
31 FASTBOOT_COMMAND_BOOT, 31 FASTBOOT_COMMAND_BOOT,
32 FASTBOOT_COMMAND_CONTINUE, 32 FASTBOOT_COMMAND_CONTINUE,
33 FASTBOOT_COMMAND_REBOOT, 33 FASTBOOT_COMMAND_REBOOT,
34 FASTBOOT_COMMAND_REBOOT_BOOTLOADER, 34 FASTBOOT_COMMAND_REBOOT_BOOTLOADER,
35 FASTBOOT_COMMAND_SET_ACTIVE, 35 FASTBOOT_COMMAND_SET_ACTIVE,
36 #if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT) 36 #if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
37 FASTBOOT_COMMAND_OEM_FORMAT, 37 FASTBOOT_COMMAND_OEM_FORMAT,
38 #endif 38 #endif
39 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) 39 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
40 FASTBOOT_COMMAND_ACMD, 40 FASTBOOT_COMMAND_ACMD,
41 FASTBOOT_COMMAND_UCMD, 41 FASTBOOT_COMMAND_UCMD,
42 #endif 42 #endif
43 #ifdef CONFIG_FSL_FASTBOOT 43 #ifdef CONFIG_FSL_FASTBOOT
44 FASTBOOT_COMMAND_UPLOAD, 44 FASTBOOT_COMMAND_UPLOAD,
45 FASTBOOT_COMMAND_GETSTAGED, 45 FASTBOOT_COMMAND_GETSTAGED,
46 #ifdef CONFIG_FASTBOOT_LOCK 46 #ifdef CONFIG_FASTBOOT_LOCK
47 FASTBOOT_COMMAND_FLASHING, 47 FASTBOOT_COMMAND_FLASHING,
48 FASTBOOT_COMMAND_OEM, 48 FASTBOOT_COMMAND_OEM,
49 #endif 49 #endif
50 #ifdef CONFIG_AVB_SUPPORT 50 #ifdef CONFIG_AVB_SUPPORT
51 FASTBOOT_COMMAND_SETACTIVE, 51 FASTBOOT_COMMAND_SETACTIVE,
52 #endif 52 #endif
53 #ifdef CONFIG_AVB_ATX 53 #ifdef CONFIG_AVB_ATX
54 FASTBOOT_COMMAND_STAGE, 54 FASTBOOT_COMMAND_STAGE,
55 #endif 55 #endif
56 #endif 56 #endif
57 #ifdef CONFIG_ANDROID_RECOVERY
58 FASTBOOT_COMMAND_RECOVERY_FASTBOOT,
59 #endif
57 FASTBOOT_COMMAND_COUNT 60 FASTBOOT_COMMAND_COUNT
58 }; 61 };
59 62
60 /** 63 /**
61 * fastboot_response() - Writes a response of the form "$tag$reason". 64 * fastboot_response() - Writes a response of the form "$tag$reason".
62 * 65 *
63 * @tag: The first part of the response 66 * @tag: The first part of the response
64 * @response: Pointer to fastboot response buffer 67 * @response: Pointer to fastboot response buffer
65 * @format: printf style format string 68 * @format: printf style format string
66 */ 69 */
67 void fastboot_response(const char *tag, char *response, 70 void fastboot_response(const char *tag, char *response,
68 const char *format, ...) 71 const char *format, ...)
69 __attribute__ ((format (__printf__, 3, 4))); 72 __attribute__ ((format (__printf__, 3, 4)));
70 73
71 /** 74 /**
72 * fastboot_fail() - Write a FAIL response of the form "FAIL$reason". 75 * fastboot_fail() - Write a FAIL response of the form "FAIL$reason".
73 * 76 *
74 * @reason: Pointer to returned reason string 77 * @reason: Pointer to returned reason string
75 * @response: Pointer to fastboot response buffer 78 * @response: Pointer to fastboot response buffer
76 */ 79 */
77 void fastboot_fail(const char *reason, char *response); 80 void fastboot_fail(const char *reason, char *response);
78 81
79 /** 82 /**
80 * fastboot_okay() - Write an OKAY response of the form "OKAY$reason". 83 * fastboot_okay() - Write an OKAY response of the form "OKAY$reason".
81 * 84 *
82 * @reason: Pointer to returned reason string, or NULL to send a bare "OKAY" 85 * @reason: Pointer to returned reason string, or NULL to send a bare "OKAY"
83 * @response: Pointer to fastboot response buffer 86 * @response: Pointer to fastboot response buffer
84 */ 87 */
85 void fastboot_okay(const char *reason, char *response); 88 void fastboot_okay(const char *reason, char *response);
86 89
87 /** 90 /**
88 * fastboot_set_reboot_flag() - Set flag to indicate reboot-bootloader 91 * fastboot_set_reboot_flag() - Set flag to indicate reboot-bootloader
89 * 92 *
90 * Set flag which indicates that we should reboot into the bootloader 93 * Set flag which indicates that we should reboot into the bootloader
91 * following the reboot that fastboot executes after this function. 94 * following the reboot that fastboot executes after this function.
92 * 95 *
93 * This function should be overridden in your board file with one 96 * This function should be overridden in your board file with one
94 * which sets whatever flag your board specific Android bootloader flow 97 * which sets whatever flag your board specific Android bootloader flow
95 * requires in order to re-enter the bootloader. 98 * requires in order to re-enter the bootloader.
96 */ 99 */
97 int fastboot_set_reboot_flag(void); 100 int fastboot_set_reboot_flag(void);
98 101
99 /** 102 /**
100 * fastboot_set_progress_callback() - set progress callback 103 * fastboot_set_progress_callback() - set progress callback
101 * 104 *
102 * @progress: Pointer to progress callback 105 * @progress: Pointer to progress callback
103 * 106 *
104 * Set a callback which is invoked periodically during long running operations 107 * Set a callback which is invoked periodically during long running operations
105 * (flash and erase). This can be used (for example) by the UDP transport to 108 * (flash and erase). This can be used (for example) by the UDP transport to
106 * send INFO responses to keep the client alive whilst those commands are 109 * send INFO responses to keep the client alive whilst those commands are
107 * executing. 110 * executing.
108 */ 111 */
109 void fastboot_set_progress_callback(void (*progress)(const char *msg)); 112 void fastboot_set_progress_callback(void (*progress)(const char *msg));
110 113
111 /* 114 /*
112 * fastboot_init() - initialise new fastboot protocol session 115 * fastboot_init() - initialise new fastboot protocol session
113 * 116 *
114 * @buf_addr: Pointer to download buffer, or NULL for default 117 * @buf_addr: Pointer to download buffer, or NULL for default
115 * @buf_size: Size of download buffer, or zero for default 118 * @buf_size: Size of download buffer, or zero for default
116 */ 119 */
117 void fastboot_init(void *buf_addr, u32 buf_size); 120 void fastboot_init(void *buf_addr, u32 buf_size);
118 121
119 /** 122 /**
120 * fastboot_boot() - Execute fastboot boot command 123 * fastboot_boot() - Execute fastboot boot command
121 * 124 *
122 * If ${fastboot_bootcmd} is set, run that command to execute the boot 125 * If ${fastboot_bootcmd} is set, run that command to execute the boot
123 * process, if that returns, then exit the fastboot server and return 126 * process, if that returns, then exit the fastboot server and return
124 * control to the caller. 127 * control to the caller.
125 * 128 *
126 * Otherwise execute "bootm <fastboot_buf_addr>", if that fails, reset 129 * Otherwise execute "bootm <fastboot_buf_addr>", if that fails, reset
127 * the board. 130 * the board.
128 */ 131 */
129 void fastboot_boot(void); 132 void fastboot_boot(void);
130 133
131 /** 134 /**
132 * fastboot_handle_command() - Handle fastboot command 135 * fastboot_handle_command() - Handle fastboot command
133 * 136 *
134 * @cmd_string: Pointer to command string 137 * @cmd_string: Pointer to command string
135 * @response: Pointer to fastboot response buffer 138 * @response: Pointer to fastboot response buffer
136 * 139 *
137 * Return: Executed command, or -1 if not recognized 140 * Return: Executed command, or -1 if not recognized
138 */ 141 */
139 int fastboot_handle_command(char *cmd_string, char *response); 142 int fastboot_handle_command(char *cmd_string, char *response);
140 143
141 /** 144 /**
142 * fastboot_data_remaining() - return bytes remaining in current transfer 145 * fastboot_data_remaining() - return bytes remaining in current transfer
143 * 146 *
144 * Return: Number of bytes left in the current download 147 * Return: Number of bytes left in the current download
145 */ 148 */
146 u32 fastboot_data_remaining(void); 149 u32 fastboot_data_remaining(void);
147 150
148 /** 151 /**
149 * fastboot_data_download() - Copy image data to fastboot_buf_addr. 152 * fastboot_data_download() - Copy image data to fastboot_buf_addr.
150 * 153 *
151 * @fastboot_data: Pointer to received fastboot data 154 * @fastboot_data: Pointer to received fastboot data
152 * @fastboot_data_len: Length of received fastboot data 155 * @fastboot_data_len: Length of received fastboot data
153 * @response: Pointer to fastboot response buffer 156 * @response: Pointer to fastboot response buffer
154 * 157 *
155 * Copies image data from fastboot_data to fastboot_buf_addr. Writes to 158 * Copies image data from fastboot_data to fastboot_buf_addr. Writes to
156 * response. fastboot_bytes_received is updated to indicate the number 159 * response. fastboot_bytes_received is updated to indicate the number
157 * of bytes that have been transferred. 160 * of bytes that have been transferred.
158 */ 161 */
159 void fastboot_data_download(const void *fastboot_data, 162 void fastboot_data_download(const void *fastboot_data,
160 unsigned int fastboot_data_len, char *response); 163 unsigned int fastboot_data_len, char *response);
161 164
162 /** 165 /**
163 * fastboot_data_complete() - Mark current transfer complete 166 * fastboot_data_complete() - Mark current transfer complete
164 * 167 *
165 * @response: Pointer to fastboot response buffer 168 * @response: Pointer to fastboot response buffer
166 * 169 *
167 * Set image_size and ${filesize} to the total size of the downloaded image. 170 * Set image_size and ${filesize} to the total size of the downloaded image.
168 */ 171 */
169 void fastboot_data_complete(char *response); 172 void fastboot_data_complete(char *response);
170 173
171 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) 174 #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
172 void fastboot_acmd_complete(void); 175 void fastboot_acmd_complete(void);
173 #endif 176 #endif
174 177
175 int fastboot_tx_write_more(const char *buffer); 178 int fastboot_tx_write_more(const char *buffer);
176 179
177 int fastboot_tx_write(const char *buffer, unsigned int buffer_size); 180 int fastboot_tx_write(const char *buffer, unsigned int buffer_size);
178 181
179 #endif /* _FASTBOOT_H_ */ 182 #endif /* _FASTBOOT_H_ */
180 183
1 // SPDX-License-Identifier: BSD-2-Clause 1 // SPDX-License-Identifier: BSD-2-Clause
2 /* 2 /*
3 * Copyright (C) 2016 The Android Open Source Project 3 * Copyright (C) 2016 The Android Open Source Project
4 */ 4 */
5 5
6 #include <common.h> 6 #include <common.h>
7 #include <fastboot.h> 7 #include <fastboot.h>
8 #include <net.h> 8 #include <net.h>
9 #include <net/fastboot.h> 9 #include <net/fastboot.h>
10 10
11 /* Fastboot port # defined in spec */ 11 /* Fastboot port # defined in spec */
12 #define WELL_KNOWN_PORT 5554 12 #define WELL_KNOWN_PORT 5554
13 13
14 enum { 14 enum {
15 FASTBOOT_ERROR = 0, 15 FASTBOOT_ERROR = 0,
16 FASTBOOT_QUERY = 1, 16 FASTBOOT_QUERY = 1,
17 FASTBOOT_INIT = 2, 17 FASTBOOT_INIT = 2,
18 FASTBOOT_FASTBOOT = 3, 18 FASTBOOT_FASTBOOT = 3,
19 }; 19 };
20 20
21 struct __packed fastboot_header { 21 struct __packed fastboot_header {
22 uchar id; 22 uchar id;
23 uchar flags; 23 uchar flags;
24 unsigned short seq; 24 unsigned short seq;
25 }; 25 };
26 26
27 #define PACKET_SIZE 1024 27 #define PACKET_SIZE 1024
28 #define DATA_SIZE (PACKET_SIZE - sizeof(struct fastboot_header)) 28 #define DATA_SIZE (PACKET_SIZE - sizeof(struct fastboot_header))
29 29
30 /* Sequence number sent for every packet */ 30 /* Sequence number sent for every packet */
31 static unsigned short sequence_number = 1; 31 static unsigned short sequence_number = 1;
32 static const unsigned short packet_size = PACKET_SIZE; 32 static const unsigned short packet_size = PACKET_SIZE;
33 static const unsigned short udp_version = 1; 33 static const unsigned short udp_version = 1;
34 34
35 /* Keep track of last packet for resubmission */ 35 /* Keep track of last packet for resubmission */
36 static uchar last_packet[PACKET_SIZE]; 36 static uchar last_packet[PACKET_SIZE];
37 static unsigned int last_packet_len; 37 static unsigned int last_packet_len;
38 38
39 static struct in_addr fastboot_remote_ip; 39 static struct in_addr fastboot_remote_ip;
40 /* The UDP port at their end */ 40 /* The UDP port at their end */
41 static int fastboot_remote_port; 41 static int fastboot_remote_port;
42 /* The UDP port at our end */ 42 /* The UDP port at our end */
43 static int fastboot_our_port; 43 static int fastboot_our_port;
44 44
45 static void boot_downloaded_image(void); 45 static void boot_downloaded_image(void);
46 46
47 #if CONFIG_IS_ENABLED(FASTBOOT_FLASH) 47 #if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
48 /** 48 /**
49 * fastboot_udp_send_info() - Send an INFO packet during long commands. 49 * fastboot_udp_send_info() - Send an INFO packet during long commands.
50 * 50 *
51 * @msg: String describing the reason for waiting 51 * @msg: String describing the reason for waiting
52 */ 52 */
53 static void fastboot_udp_send_info(const char *msg) 53 static void fastboot_udp_send_info(const char *msg)
54 { 54 {
55 uchar *packet; 55 uchar *packet;
56 uchar *packet_base; 56 uchar *packet_base;
57 int len = 0; 57 int len = 0;
58 char response[FASTBOOT_RESPONSE_LEN] = {0}; 58 char response[FASTBOOT_RESPONSE_LEN] = {0};
59 59
60 struct fastboot_header response_header = { 60 struct fastboot_header response_header = {
61 .id = FASTBOOT_FASTBOOT, 61 .id = FASTBOOT_FASTBOOT,
62 .flags = 0, 62 .flags = 0,
63 .seq = htons(sequence_number) 63 .seq = htons(sequence_number)
64 }; 64 };
65 ++sequence_number; 65 ++sequence_number;
66 packet = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE; 66 packet = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
67 packet_base = packet; 67 packet_base = packet;
68 68
69 /* Write headers */ 69 /* Write headers */
70 memcpy(packet, &response_header, sizeof(response_header)); 70 memcpy(packet, &response_header, sizeof(response_header));
71 packet += sizeof(response_header); 71 packet += sizeof(response_header);
72 /* Write response */ 72 /* Write response */
73 fastboot_response("INFO", response, "%s", msg); 73 fastboot_response("INFO", response, "%s", msg);
74 memcpy(packet, response, strlen(response)); 74 memcpy(packet, response, strlen(response));
75 packet += strlen(response); 75 packet += strlen(response);
76 76
77 len = packet - packet_base; 77 len = packet - packet_base;
78 78
79 /* Save packet for retransmitting */ 79 /* Save packet for retransmitting */
80 last_packet_len = len; 80 last_packet_len = len;
81 memcpy(last_packet, packet_base, last_packet_len); 81 memcpy(last_packet, packet_base, last_packet_len);
82 82
83 net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip, 83 net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
84 fastboot_remote_port, fastboot_our_port, len); 84 fastboot_remote_port, fastboot_our_port, len);
85 } 85 }
86 86
87 /** 87 /**
88 * fastboot_timed_send_info() - Send INFO packet every 30 seconds 88 * fastboot_timed_send_info() - Send INFO packet every 30 seconds
89 * 89 *
90 * @msg: String describing the reason for waiting 90 * @msg: String describing the reason for waiting
91 * 91 *
92 * Send an INFO packet during long commands based on timer. An INFO packet 92 * Send an INFO packet during long commands based on timer. An INFO packet
93 * is sent if the time is 30 seconds after start. Else, noop. 93 * is sent if the time is 30 seconds after start. Else, noop.
94 */ 94 */
95 static void fastboot_timed_send_info(const char *msg) 95 static void fastboot_timed_send_info(const char *msg)
96 { 96 {
97 static ulong start; 97 static ulong start;
98 98
99 /* Initialize timer */ 99 /* Initialize timer */
100 if (start == 0) 100 if (start == 0)
101 start = get_timer(0); 101 start = get_timer(0);
102 ulong time = get_timer(start); 102 ulong time = get_timer(start);
103 /* Send INFO packet to host every 30 seconds */ 103 /* Send INFO packet to host every 30 seconds */
104 if (time >= 30000) { 104 if (time >= 30000) {
105 start = get_timer(0); 105 start = get_timer(0);
106 fastboot_udp_send_info(msg); 106 fastboot_udp_send_info(msg);
107 } 107 }
108 } 108 }
109 #endif 109 #endif
110 110
111 /** 111 /**
112 * fastboot_send() - Sends a packet in response to received fastboot packet 112 * fastboot_send() - Sends a packet in response to received fastboot packet
113 * 113 *
114 * @header: Header for response packet 114 * @header: Header for response packet
115 * @fastboot_data: Pointer to received fastboot data 115 * @fastboot_data: Pointer to received fastboot data
116 * @fastboot_data_len: Length of received fastboot data 116 * @fastboot_data_len: Length of received fastboot data
117 * @retransmit: Nonzero if sending last sent packet 117 * @retransmit: Nonzero if sending last sent packet
118 */ 118 */
119 static void fastboot_send(struct fastboot_header header, char *fastboot_data, 119 static void fastboot_send(struct fastboot_header header, char *fastboot_data,
120 unsigned int fastboot_data_len, uchar retransmit) 120 unsigned int fastboot_data_len, uchar retransmit)
121 { 121 {
122 uchar *packet; 122 uchar *packet;
123 uchar *packet_base; 123 uchar *packet_base;
124 int len = 0; 124 int len = 0;
125 const char *error_msg = "An error occurred."; 125 const char *error_msg = "An error occurred.";
126 short tmp; 126 short tmp;
127 struct fastboot_header response_header = header; 127 struct fastboot_header response_header = header;
128 static char command[FASTBOOT_COMMAND_LEN]; 128 static char command[FASTBOOT_COMMAND_LEN];
129 static int cmd = -1; 129 static int cmd = -1;
130 static bool pending_command; 130 static bool pending_command;
131 char response[FASTBOOT_RESPONSE_LEN] = {0}; 131 char response[FASTBOOT_RESPONSE_LEN] = {0};
132 132
133 /* 133 /*
134 * We will always be sending some sort of packet, so 134 * We will always be sending some sort of packet, so
135 * cobble together the packet headers now. 135 * cobble together the packet headers now.
136 */ 136 */
137 packet = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE; 137 packet = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
138 packet_base = packet; 138 packet_base = packet;
139 139
140 /* Resend last packet */ 140 /* Resend last packet */
141 if (retransmit) { 141 if (retransmit) {
142 memcpy(packet, last_packet, last_packet_len); 142 memcpy(packet, last_packet, last_packet_len);
143 net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip, 143 net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
144 fastboot_remote_port, fastboot_our_port, 144 fastboot_remote_port, fastboot_our_port,
145 last_packet_len); 145 last_packet_len);
146 return; 146 return;
147 } 147 }
148 148
149 response_header.seq = htons(response_header.seq); 149 response_header.seq = htons(response_header.seq);
150 memcpy(packet, &response_header, sizeof(response_header)); 150 memcpy(packet, &response_header, sizeof(response_header));
151 packet += sizeof(response_header); 151 packet += sizeof(response_header);
152 152
153 switch (header.id) { 153 switch (header.id) {
154 case FASTBOOT_QUERY: 154 case FASTBOOT_QUERY:
155 tmp = htons(sequence_number); 155 tmp = htons(sequence_number);
156 memcpy(packet, &tmp, sizeof(tmp)); 156 memcpy(packet, &tmp, sizeof(tmp));
157 packet += sizeof(tmp); 157 packet += sizeof(tmp);
158 break; 158 break;
159 case FASTBOOT_INIT: 159 case FASTBOOT_INIT:
160 tmp = htons(udp_version); 160 tmp = htons(udp_version);
161 memcpy(packet, &tmp, sizeof(tmp)); 161 memcpy(packet, &tmp, sizeof(tmp));
162 packet += sizeof(tmp); 162 packet += sizeof(tmp);
163 tmp = htons(packet_size); 163 tmp = htons(packet_size);
164 memcpy(packet, &tmp, sizeof(tmp)); 164 memcpy(packet, &tmp, sizeof(tmp));
165 packet += sizeof(tmp); 165 packet += sizeof(tmp);
166 break; 166 break;
167 case FASTBOOT_ERROR: 167 case FASTBOOT_ERROR:
168 memcpy(packet, error_msg, strlen(error_msg)); 168 memcpy(packet, error_msg, strlen(error_msg));
169 packet += strlen(error_msg); 169 packet += strlen(error_msg);
170 break; 170 break;
171 case FASTBOOT_FASTBOOT: 171 case FASTBOOT_FASTBOOT:
172 if (cmd == FASTBOOT_COMMAND_DOWNLOAD) { 172 if (cmd == FASTBOOT_COMMAND_DOWNLOAD) {
173 if (!fastboot_data_len && !fastboot_data_remaining()) { 173 if (!fastboot_data_len && !fastboot_data_remaining()) {
174 fastboot_data_complete(response); 174 fastboot_data_complete(response);
175 } else { 175 } else {
176 fastboot_data_download(fastboot_data, 176 fastboot_data_download(fastboot_data,
177 fastboot_data_len, 177 fastboot_data_len,
178 response); 178 response);
179 } 179 }
180 } else if (!pending_command) { 180 } else if (!pending_command) {
181 strlcpy(command, fastboot_data, 181 strlcpy(command, fastboot_data,
182 min((size_t)fastboot_data_len + 1, 182 min((size_t)fastboot_data_len + 1,
183 sizeof(command))); 183 sizeof(command)));
184 pending_command = true; 184 pending_command = true;
185 } else { 185 } else {
186 cmd = fastboot_handle_command(command, response); 186 cmd = fastboot_handle_command(command, response);
187 pending_command = false; 187 pending_command = false;
188 } 188 }
189 /* 189 /*
190 * Sent some INFO packets, need to update sequence number in 190 * Sent some INFO packets, need to update sequence number in
191 * header 191 * header
192 */ 192 */
193 if (header.seq != sequence_number) { 193 if (header.seq != sequence_number) {
194 response_header.seq = htons(sequence_number); 194 response_header.seq = htons(sequence_number);
195 memcpy(packet_base, &response_header, 195 memcpy(packet_base, &response_header,
196 sizeof(response_header)); 196 sizeof(response_header));
197 } 197 }
198 /* Write response to packet */ 198 /* Write response to packet */
199 memcpy(packet, response, strlen(response)); 199 memcpy(packet, response, strlen(response));
200 packet += strlen(response); 200 packet += strlen(response);
201 break; 201 break;
202 default: 202 default:
203 pr_err("ID %d not implemented.\n", header.id); 203 pr_err("ID %d not implemented.\n", header.id);
204 return; 204 return;
205 } 205 }
206 206
207 len = packet - packet_base; 207 len = packet - packet_base;
208 208
209 /* Save packet for retransmitting */ 209 /* Save packet for retransmitting */
210 last_packet_len = len; 210 last_packet_len = len;
211 memcpy(last_packet, packet_base, last_packet_len); 211 memcpy(last_packet, packet_base, last_packet_len);
212 212
213 net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip, 213 net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
214 fastboot_remote_port, fastboot_our_port, len); 214 fastboot_remote_port, fastboot_our_port, len);
215 215
216 /* Continue boot process after sending response */ 216 /* Continue boot process after sending response */
217 if (!strncmp("OKAY", response, 4)) { 217 if (!strncmp("OKAY", response, 4)) {
218 switch (cmd) { 218 switch (cmd) {
219 case FASTBOOT_COMMAND_BOOT: 219 case FASTBOOT_COMMAND_BOOT:
220 boot_downloaded_image(); 220 boot_downloaded_image();
221 break; 221 break;
222 222
223 case FASTBOOT_COMMAND_CONTINUE: 223 case FASTBOOT_COMMAND_CONTINUE:
224 net_set_state(NETLOOP_SUCCESS); 224 net_set_state(NETLOOP_SUCCESS);
225 break; 225 break;
226 226
227 case FASTBOOT_COMMAND_REBOOT: 227 case FASTBOOT_COMMAND_REBOOT:
228 case FASTBOOT_COMMAND_REBOOT_BOOTLOADER: 228 case FASTBOOT_COMMAND_REBOOT_BOOTLOADER:
229 #ifdef CONFIG_ANDROID_RECOVERY
230 case FASTBOOT_COMMAND_RECOVERY_FASTBOOT:
231 #endif
229 do_reset(NULL, 0, 0, NULL); 232 do_reset(NULL, 0, 0, NULL);
230 break; 233 break;
231 } 234 }
232 } 235 }
233 236
234 if (!strncmp("OKAY", response, 4) || !strncmp("FAIL", response, 4)) 237 if (!strncmp("OKAY", response, 4) || !strncmp("FAIL", response, 4))
235 cmd = -1; 238 cmd = -1;
236 } 239 }
237 240
238 /** 241 /**
239 * boot_downloaded_image() - Boots into downloaded image. 242 * boot_downloaded_image() - Boots into downloaded image.
240 */ 243 */
241 static void boot_downloaded_image(void) 244 static void boot_downloaded_image(void)
242 { 245 {
243 fastboot_boot(); 246 fastboot_boot();
244 net_set_state(NETLOOP_SUCCESS); 247 net_set_state(NETLOOP_SUCCESS);
245 } 248 }
246 249
247 /** 250 /**
248 * fastboot_handler() - Incoming UDP packet handler. 251 * fastboot_handler() - Incoming UDP packet handler.
249 * 252 *
250 * @packet: Pointer to incoming UDP packet 253 * @packet: Pointer to incoming UDP packet
251 * @dport: Destination UDP port 254 * @dport: Destination UDP port
252 * @sip: Source IP address 255 * @sip: Source IP address
253 * @sport: Source UDP port 256 * @sport: Source UDP port
254 * @len: Packet length 257 * @len: Packet length
255 */ 258 */
256 static void fastboot_handler(uchar *packet, unsigned int dport, 259 static void fastboot_handler(uchar *packet, unsigned int dport,
257 struct in_addr sip, unsigned int sport, 260 struct in_addr sip, unsigned int sport,
258 unsigned int len) 261 unsigned int len)
259 { 262 {
260 struct fastboot_header header; 263 struct fastboot_header header;
261 char fastboot_data[DATA_SIZE] = {0}; 264 char fastboot_data[DATA_SIZE] = {0};
262 unsigned int fastboot_data_len = 0; 265 unsigned int fastboot_data_len = 0;
263 266
264 if (dport != fastboot_our_port) 267 if (dport != fastboot_our_port)
265 return; 268 return;
266 269
267 fastboot_remote_ip = sip; 270 fastboot_remote_ip = sip;
268 fastboot_remote_port = sport; 271 fastboot_remote_port = sport;
269 272
270 if (len < sizeof(struct fastboot_header) || len > PACKET_SIZE) 273 if (len < sizeof(struct fastboot_header) || len > PACKET_SIZE)
271 return; 274 return;
272 memcpy(&header, packet, sizeof(header)); 275 memcpy(&header, packet, sizeof(header));
273 header.flags = 0; 276 header.flags = 0;
274 header.seq = ntohs(header.seq); 277 header.seq = ntohs(header.seq);
275 packet += sizeof(header); 278 packet += sizeof(header);
276 len -= sizeof(header); 279 len -= sizeof(header);
277 280
278 switch (header.id) { 281 switch (header.id) {
279 case FASTBOOT_QUERY: 282 case FASTBOOT_QUERY:
280 fastboot_send(header, fastboot_data, 0, 0); 283 fastboot_send(header, fastboot_data, 0, 0);
281 break; 284 break;
282 case FASTBOOT_INIT: 285 case FASTBOOT_INIT:
283 case FASTBOOT_FASTBOOT: 286 case FASTBOOT_FASTBOOT:
284 fastboot_data_len = len; 287 fastboot_data_len = len;
285 if (len > 0) 288 if (len > 0)
286 memcpy(fastboot_data, packet, len); 289 memcpy(fastboot_data, packet, len);
287 if (header.seq == sequence_number) { 290 if (header.seq == sequence_number) {
288 fastboot_send(header, fastboot_data, 291 fastboot_send(header, fastboot_data,
289 fastboot_data_len, 0); 292 fastboot_data_len, 0);
290 sequence_number++; 293 sequence_number++;
291 } else if (header.seq == sequence_number - 1) { 294 } else if (header.seq == sequence_number - 1) {
292 /* Retransmit last sent packet */ 295 /* Retransmit last sent packet */
293 fastboot_send(header, fastboot_data, 296 fastboot_send(header, fastboot_data,
294 fastboot_data_len, 1); 297 fastboot_data_len, 1);
295 } 298 }
296 break; 299 break;
297 default: 300 default:
298 pr_err("ID %d not implemented.\n", header.id); 301 pr_err("ID %d not implemented.\n", header.id);
299 header.id = FASTBOOT_ERROR; 302 header.id = FASTBOOT_ERROR;
300 fastboot_send(header, fastboot_data, 0, 0); 303 fastboot_send(header, fastboot_data, 0, 0);
301 break; 304 break;
302 } 305 }
303 } 306 }
304 307
305 void fastboot_start_server(void) 308 void fastboot_start_server(void)
306 { 309 {
307 printf("Using %s device\n", eth_get_name()); 310 printf("Using %s device\n", eth_get_name());
308 printf("Listening for fastboot command on %pI4\n", &net_ip); 311 printf("Listening for fastboot command on %pI4\n", &net_ip);
309 312
310 fastboot_our_port = WELL_KNOWN_PORT; 313 fastboot_our_port = WELL_KNOWN_PORT;
311 314
312 #if CONFIG_IS_ENABLED(FASTBOOT_FLASH) 315 #if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
313 fastboot_set_progress_callback(fastboot_timed_send_info); 316 fastboot_set_progress_callback(fastboot_timed_send_info);
314 #endif 317 #endif
315 net_set_udp_handler(fastboot_handler); 318 net_set_udp_handler(fastboot_handler);
316 319
317 /* zero out server ether in case the server ip has changed */ 320 /* zero out server ether in case the server ip has changed */
318 memset(net_server_ethaddr, 0, 6); 321 memset(net_server_ethaddr, 0, 6);
319 } 322 }
320 323