Commit f322e8a2c62e765f434d14bd77ed97594b0acaa1
1 parent
654088cc21
Exists in
smarc-imx_v2018.03_4.14.78_1.0.0_ga
MA-13603 change unlock logic to firstly judge unlocked or not
to handle situations that it is not allowed to unlock but the board is already unlocked, unlock logic is modified in this patch Change-Id: I90b22c2dfbc1c64ed9514032986e98b27526c7b9 Signed-off-by: faqiang.zhu <faqiang.zhu@nxp.com>
Showing 1 changed file with 4 additions and 4 deletions Inline Diff
drivers/usb/gadget/f_fastboot.c
1 | /* | 1 | /* |
2 | * (C) Copyright 2008 - 2009 | 2 | * (C) Copyright 2008 - 2009 |
3 | * Windriver, <www.windriver.com> | 3 | * Windriver, <www.windriver.com> |
4 | * Tom Rix <Tom.Rix@windriver.com> | 4 | * Tom Rix <Tom.Rix@windriver.com> |
5 | * | 5 | * |
6 | * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 6 | * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
7 | * | 7 | * |
8 | * Copyright 2014 Linaro, Ltd. | 8 | * Copyright 2014 Linaro, Ltd. |
9 | * Rob Herring <robh@kernel.org> | 9 | * Rob Herring <robh@kernel.org> |
10 | * | 10 | * |
11 | * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. | 11 | * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. |
12 | * Copyright 2017 NXP | 12 | * Copyright 2017 NXP |
13 | * | 13 | * |
14 | * SPDX-License-Identifier: GPL-2.0+ | 14 | * SPDX-License-Identifier: GPL-2.0+ |
15 | */ | 15 | */ |
16 | #include <config.h> | 16 | #include <config.h> |
17 | #include <common.h> | 17 | #include <common.h> |
18 | #include <errno.h> | 18 | #include <errno.h> |
19 | #include <stdlib.h> | 19 | #include <stdlib.h> |
20 | #include <fastboot.h> | 20 | #include <fastboot.h> |
21 | #include <malloc.h> | 21 | #include <malloc.h> |
22 | #include <linux/usb/ch9.h> | 22 | #include <linux/usb/ch9.h> |
23 | #include <linux/usb/gadget.h> | 23 | #include <linux/usb/gadget.h> |
24 | #include <linux/usb/composite.h> | 24 | #include <linux/usb/composite.h> |
25 | #include <linux/compiler.h> | 25 | #include <linux/compiler.h> |
26 | #include <version.h> | 26 | #include <version.h> |
27 | #include <g_dnl.h> | 27 | #include <g_dnl.h> |
28 | #include "../lib/avb/fsl/utils.h" | 28 | #include "../lib/avb/fsl/utils.h" |
29 | #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV | 29 | #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV |
30 | #include <fb_mmc.h> | 30 | #include <fb_mmc.h> |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | #ifdef CONFIG_IMX_TRUSTY_OS | 33 | #ifdef CONFIG_IMX_TRUSTY_OS |
34 | #define ATAP_UUID_SIZE 32 | 34 | #define ATAP_UUID_SIZE 32 |
35 | #define ATAP_UUID_STR_SIZE ((ATAP_UUID_SIZE*2) + 1) | 35 | #define ATAP_UUID_STR_SIZE ((ATAP_UUID_SIZE*2) + 1) |
36 | 36 | ||
37 | extern int armv7_init_nonsec(void); | 37 | extern int armv7_init_nonsec(void); |
38 | extern void trusty_os_init(void); | 38 | extern void trusty_os_init(void); |
39 | #include <trusty/libtipc.h> | 39 | #include <trusty/libtipc.h> |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV | 42 | #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV |
43 | #include <fb_nand.h> | 43 | #include <fb_nand.h> |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | #ifdef CONFIG_FSL_FASTBOOT | 46 | #ifdef CONFIG_FSL_FASTBOOT |
47 | #include <asm/mach-imx/sys_proto.h> | 47 | #include <asm/mach-imx/sys_proto.h> |
48 | #include <fsl_fastboot.h> | 48 | #include <fsl_fastboot.h> |
49 | #include <mmc.h> | 49 | #include <mmc.h> |
50 | #include <android_image.h> | 50 | #include <android_image.h> |
51 | #include <asm/bootm.h> | 51 | #include <asm/bootm.h> |
52 | #include <nand.h> | 52 | #include <nand.h> |
53 | #include <part.h> | 53 | #include <part.h> |
54 | #include <sparse_format.h> | 54 | #include <sparse_format.h> |
55 | #include <image-sparse.h> | 55 | #include <image-sparse.h> |
56 | #include <image.h> | 56 | #include <image.h> |
57 | #include <asm/mach-imx/boot_mode.h> | 57 | #include <asm/mach-imx/boot_mode.h> |
58 | #include <asm/arch/sys_proto.h> | 58 | #include <asm/arch/sys_proto.h> |
59 | #include <asm/setup.h> | 59 | #include <asm/setup.h> |
60 | #include <environment.h> | 60 | #include <environment.h> |
61 | #ifdef CONFIG_ANDROID_RECOVERY | 61 | #ifdef CONFIG_ANDROID_RECOVERY |
62 | #include <recovery.h> | 62 | #include <recovery.h> |
63 | #endif | 63 | #endif |
64 | #endif | 64 | #endif |
65 | 65 | ||
66 | #ifdef CONFIG_BCB_SUPPORT | 66 | #ifdef CONFIG_BCB_SUPPORT |
67 | #include "bcb.h" | 67 | #include "bcb.h" |
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | #ifdef CONFIG_AVB_SUPPORT | 70 | #ifdef CONFIG_AVB_SUPPORT |
71 | #include <dt_table.h> | 71 | #include <dt_table.h> |
72 | #include <fsl_avb.h> | 72 | #include <fsl_avb.h> |
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT | 75 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT |
76 | #include <asm-generic/gpio.h> | 76 | #include <asm-generic/gpio.h> |
77 | #include <asm/mach-imx/gpio.h> | 77 | #include <asm/mach-imx/gpio.h> |
78 | #include "../lib/avb/fsl/fsl_avbkey.h" | 78 | #include "../lib/avb/fsl/fsl_avbkey.h" |
79 | #include "../arch/arm/include/asm/mach-imx/hab.h" | 79 | #include "../arch/arm/include/asm/mach-imx/hab.h" |
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | #ifdef CONFIG_FASTBOOT_LOCK | 82 | #ifdef CONFIG_FASTBOOT_LOCK |
83 | #include "fastboot_lock_unlock.h" | 83 | #include "fastboot_lock_unlock.h" |
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | #if defined(CONFIG_IMX_TRUSTY_OS) && defined(CONFIG_DUAL_BOOTLOADER) | 86 | #if defined(CONFIG_IMX_TRUSTY_OS) && defined(CONFIG_DUAL_BOOTLOADER) |
87 | #include "u-boot/sha256.h" | 87 | #include "u-boot/sha256.h" |
88 | #endif | 88 | #endif |
89 | 89 | ||
90 | #define FASTBOOT_VERSION "0.4" | 90 | #define FASTBOOT_VERSION "0.4" |
91 | 91 | ||
92 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) | 92 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) |
93 | #define FASTBOOT_COMMON_VAR_NUM 14 | 93 | #define FASTBOOT_COMMON_VAR_NUM 14 |
94 | #else | 94 | #else |
95 | #define FASTBOOT_COMMON_VAR_NUM 13 | 95 | #define FASTBOOT_COMMON_VAR_NUM 13 |
96 | #endif | 96 | #endif |
97 | 97 | ||
98 | #define FASTBOOT_VAR_YES "yes" | 98 | #define FASTBOOT_VAR_YES "yes" |
99 | #define FASTBOOT_VAR_NO "no" | 99 | #define FASTBOOT_VAR_NO "no" |
100 | #define FASTBOOT_INTERFACE_CLASS 0xff | 100 | #define FASTBOOT_INTERFACE_CLASS 0xff |
101 | #define FASTBOOT_INTERFACE_SUB_CLASS 0x42 | 101 | #define FASTBOOT_INTERFACE_SUB_CLASS 0x42 |
102 | #define FASTBOOT_INTERFACE_PROTOCOL 0x03 | 102 | #define FASTBOOT_INTERFACE_PROTOCOL 0x03 |
103 | 103 | ||
104 | #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) | 104 | #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) |
105 | #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) | 105 | #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) |
106 | #define TX_ENDPOINT_MAXIMUM_PACKET_SIZE (0x0040) | 106 | #define TX_ENDPOINT_MAXIMUM_PACKET_SIZE (0x0040) |
107 | 107 | ||
108 | #define EP_BUFFER_SIZE 4096 | 108 | #define EP_BUFFER_SIZE 4096 |
109 | 109 | ||
110 | #ifdef CONFIG_FSL_FASTBOOT | 110 | #ifdef CONFIG_FSL_FASTBOOT |
111 | 111 | ||
112 | #define ANDROID_GPT_OFFSET 0 | 112 | #define ANDROID_GPT_OFFSET 0 |
113 | #define ANDROID_GPT_SIZE 0x100000 | 113 | #define ANDROID_GPT_SIZE 0x100000 |
114 | #define ANDROID_GPT_END 0x4400 | 114 | #define ANDROID_GPT_END 0x4400 |
115 | 115 | ||
116 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | 116 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT |
117 | struct fastboot_device_info fastboot_firmwareinfo; | 117 | struct fastboot_device_info fastboot_firmwareinfo; |
118 | #endif | 118 | #endif |
119 | 119 | ||
120 | #if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) | 120 | #if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) |
121 | #define DST_DECOMPRESS_LEN 1024*1024*32 | 121 | #define DST_DECOMPRESS_LEN 1024*1024*32 |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | #endif | 124 | #endif |
125 | 125 | ||
126 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT | 126 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT |
127 | #define FDT_PART_NAME "oem_bootloader" | 127 | #define FDT_PART_NAME "oem_bootloader" |
128 | #else | 128 | #else |
129 | #define FDT_PART_NAME "dtbo" | 129 | #define FDT_PART_NAME "dtbo" |
130 | #endif | 130 | #endif |
131 | 131 | ||
132 | #define MEK_8QM_EMMC 0 | 132 | #define MEK_8QM_EMMC 0 |
133 | 133 | ||
134 | /* | 134 | /* |
135 | * EP_BUFFER_SIZE must always be an integral multiple of maxpacket size | 135 | * EP_BUFFER_SIZE must always be an integral multiple of maxpacket size |
136 | * (64 or 512 or 1024), else we break on certain controllers like DWC3 | 136 | * (64 or 512 or 1024), else we break on certain controllers like DWC3 |
137 | * that expect bulk OUT requests to be divisible by maxpacket size. | 137 | * that expect bulk OUT requests to be divisible by maxpacket size. |
138 | */ | 138 | */ |
139 | 139 | ||
140 | /* Offset (in u32's) of start and end fields in the zImage header. */ | 140 | /* Offset (in u32's) of start and end fields in the zImage header. */ |
141 | #define ZIMAGE_START_ADDR 10 | 141 | #define ZIMAGE_START_ADDR 10 |
142 | #define ZIMAGE_END_ADDR 11 | 142 | #define ZIMAGE_END_ADDR 11 |
143 | 143 | ||
144 | /* common variables of fastboot getvar command */ | 144 | /* common variables of fastboot getvar command */ |
145 | char *fastboot_common_var[FASTBOOT_COMMON_VAR_NUM] = { | 145 | char *fastboot_common_var[FASTBOOT_COMMON_VAR_NUM] = { |
146 | "version", | 146 | "version", |
147 | "version-bootloader", | 147 | "version-bootloader", |
148 | "version-baseband", | 148 | "version-baseband", |
149 | "product", | 149 | "product", |
150 | "secure", | 150 | "secure", |
151 | "max-download-size", | 151 | "max-download-size", |
152 | "erase-block-size", | 152 | "erase-block-size", |
153 | "logical-block-size", | 153 | "logical-block-size", |
154 | "unlocked", | 154 | "unlocked", |
155 | "off-mode-charge", | 155 | "off-mode-charge", |
156 | "battery-voltage", | 156 | "battery-voltage", |
157 | "variant", | 157 | "variant", |
158 | "battery-soc-ok", | 158 | "battery-soc-ok", |
159 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) | 159 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) |
160 | "baseboard_id" | 160 | "baseboard_id" |
161 | #endif | 161 | #endif |
162 | }; | 162 | }; |
163 | 163 | ||
164 | /* at-vboot-state variable list */ | 164 | /* at-vboot-state variable list */ |
165 | #ifdef CONFIG_AVB_ATX | 165 | #ifdef CONFIG_AVB_ATX |
166 | #define AT_VBOOT_STATE_VAR_NUM 6 | 166 | #define AT_VBOOT_STATE_VAR_NUM 6 |
167 | extern struct imx_sec_config_fuse_t const imx_sec_config_fuse; | 167 | extern struct imx_sec_config_fuse_t const imx_sec_config_fuse; |
168 | extern int fuse_read(u32 bank, u32 word, u32 *val); | 168 | extern int fuse_read(u32 bank, u32 word, u32 *val); |
169 | 169 | ||
170 | char *fastboot_at_vboot_state_var[AT_VBOOT_STATE_VAR_NUM] = { | 170 | char *fastboot_at_vboot_state_var[AT_VBOOT_STATE_VAR_NUM] = { |
171 | "bootloader-locked", | 171 | "bootloader-locked", |
172 | "bootloader-min-versions", | 172 | "bootloader-min-versions", |
173 | "avb-perm-attr-set", | 173 | "avb-perm-attr-set", |
174 | "avb-locked", | 174 | "avb-locked", |
175 | "avb-unlock-disabled", | 175 | "avb-unlock-disabled", |
176 | "avb-min-versions" | 176 | "avb-min-versions" |
177 | }; | 177 | }; |
178 | #endif | 178 | #endif |
179 | 179 | ||
180 | /* Boot metric variables */ | 180 | /* Boot metric variables */ |
181 | boot_metric metrics = { | 181 | boot_metric metrics = { |
182 | .bll_1 = 0, | 182 | .bll_1 = 0, |
183 | .ble_1 = 0, | 183 | .ble_1 = 0, |
184 | .kl = 0, | 184 | .kl = 0, |
185 | .kd = 0, | 185 | .kd = 0, |
186 | .avb = 0, | 186 | .avb = 0, |
187 | .odt = 0, | 187 | .odt = 0, |
188 | .sw = 0 | 188 | .sw = 0 |
189 | }; | 189 | }; |
190 | 190 | ||
191 | typedef struct usb_req usb_req; | 191 | typedef struct usb_req usb_req; |
192 | struct usb_req { | 192 | struct usb_req { |
193 | struct usb_request *in_req; | 193 | struct usb_request *in_req; |
194 | usb_req *next; | 194 | usb_req *next; |
195 | }; | 195 | }; |
196 | 196 | ||
197 | struct f_fastboot { | 197 | struct f_fastboot { |
198 | struct usb_function usb_function; | 198 | struct usb_function usb_function; |
199 | 199 | ||
200 | /* IN/OUT EP's and corresponding requests */ | 200 | /* IN/OUT EP's and corresponding requests */ |
201 | struct usb_ep *in_ep, *out_ep; | 201 | struct usb_ep *in_ep, *out_ep; |
202 | struct usb_request *in_req, *out_req; | 202 | struct usb_request *in_req, *out_req; |
203 | usb_req *front, *rear; | 203 | usb_req *front, *rear; |
204 | }; | 204 | }; |
205 | 205 | ||
206 | static char fb_ext_prop_name[] = "DeviceInterfaceGUID"; | 206 | static char fb_ext_prop_name[] = "DeviceInterfaceGUID"; |
207 | static char fb_ext_prop_data[] = "{4866319A-F4D6-4374-93B9-DC2DEB361BA9}"; | 207 | static char fb_ext_prop_data[] = "{4866319A-F4D6-4374-93B9-DC2DEB361BA9}"; |
208 | 208 | ||
209 | static struct usb_os_desc_ext_prop fb_ext_prop = { | 209 | static struct usb_os_desc_ext_prop fb_ext_prop = { |
210 | .type = 1, /* NUL-terminated Unicode String (REG_SZ) */ | 210 | .type = 1, /* NUL-terminated Unicode String (REG_SZ) */ |
211 | .name = fb_ext_prop_name, | 211 | .name = fb_ext_prop_name, |
212 | .data = fb_ext_prop_data, | 212 | .data = fb_ext_prop_data, |
213 | }; | 213 | }; |
214 | 214 | ||
215 | /* 16 bytes of "Compatible ID" and "Subcompatible ID" */ | 215 | /* 16 bytes of "Compatible ID" and "Subcompatible ID" */ |
216 | static char fb_cid[16] = {'W', 'I', 'N', 'U', 'S', 'B'}; | 216 | static char fb_cid[16] = {'W', 'I', 'N', 'U', 'S', 'B'}; |
217 | static struct usb_os_desc fb_os_desc = { | 217 | static struct usb_os_desc fb_os_desc = { |
218 | .ext_compat_id = fb_cid, | 218 | .ext_compat_id = fb_cid, |
219 | }; | 219 | }; |
220 | 220 | ||
221 | static struct usb_os_desc_table fb_os_desc_table = { | 221 | static struct usb_os_desc_table fb_os_desc_table = { |
222 | .os_desc = &fb_os_desc, | 222 | .os_desc = &fb_os_desc, |
223 | }; | 223 | }; |
224 | 224 | ||
225 | static inline struct f_fastboot *func_to_fastboot(struct usb_function *f) | 225 | static inline struct f_fastboot *func_to_fastboot(struct usb_function *f) |
226 | { | 226 | { |
227 | return container_of(f, struct f_fastboot, usb_function); | 227 | return container_of(f, struct f_fastboot, usb_function); |
228 | } | 228 | } |
229 | 229 | ||
230 | static struct f_fastboot *fastboot_func; | 230 | static struct f_fastboot *fastboot_func; |
231 | static unsigned int download_size; | 231 | static unsigned int download_size; |
232 | static unsigned int download_bytes; | 232 | static unsigned int download_bytes; |
233 | 233 | ||
234 | static struct usb_endpoint_descriptor fs_ep_in = { | 234 | static struct usb_endpoint_descriptor fs_ep_in = { |
235 | .bLength = USB_DT_ENDPOINT_SIZE, | 235 | .bLength = USB_DT_ENDPOINT_SIZE, |
236 | .bDescriptorType = USB_DT_ENDPOINT, | 236 | .bDescriptorType = USB_DT_ENDPOINT, |
237 | .bEndpointAddress = USB_DIR_IN, | 237 | .bEndpointAddress = USB_DIR_IN, |
238 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 238 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
239 | .wMaxPacketSize = cpu_to_le16(64), | 239 | .wMaxPacketSize = cpu_to_le16(64), |
240 | }; | 240 | }; |
241 | 241 | ||
242 | static struct usb_endpoint_descriptor fs_ep_out = { | 242 | static struct usb_endpoint_descriptor fs_ep_out = { |
243 | .bLength = USB_DT_ENDPOINT_SIZE, | 243 | .bLength = USB_DT_ENDPOINT_SIZE, |
244 | .bDescriptorType = USB_DT_ENDPOINT, | 244 | .bDescriptorType = USB_DT_ENDPOINT, |
245 | .bEndpointAddress = USB_DIR_OUT, | 245 | .bEndpointAddress = USB_DIR_OUT, |
246 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 246 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
247 | .wMaxPacketSize = cpu_to_le16(64), | 247 | .wMaxPacketSize = cpu_to_le16(64), |
248 | }; | 248 | }; |
249 | 249 | ||
250 | static struct usb_endpoint_descriptor hs_ep_in = { | 250 | static struct usb_endpoint_descriptor hs_ep_in = { |
251 | .bLength = USB_DT_ENDPOINT_SIZE, | 251 | .bLength = USB_DT_ENDPOINT_SIZE, |
252 | .bDescriptorType = USB_DT_ENDPOINT, | 252 | .bDescriptorType = USB_DT_ENDPOINT, |
253 | .bEndpointAddress = USB_DIR_IN, | 253 | .bEndpointAddress = USB_DIR_IN, |
254 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 254 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
255 | .wMaxPacketSize = cpu_to_le16(512), | 255 | .wMaxPacketSize = cpu_to_le16(512), |
256 | }; | 256 | }; |
257 | 257 | ||
258 | static struct usb_endpoint_descriptor hs_ep_out = { | 258 | static struct usb_endpoint_descriptor hs_ep_out = { |
259 | .bLength = USB_DT_ENDPOINT_SIZE, | 259 | .bLength = USB_DT_ENDPOINT_SIZE, |
260 | .bDescriptorType = USB_DT_ENDPOINT, | 260 | .bDescriptorType = USB_DT_ENDPOINT, |
261 | .bEndpointAddress = USB_DIR_OUT, | 261 | .bEndpointAddress = USB_DIR_OUT, |
262 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 262 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
263 | .wMaxPacketSize = cpu_to_le16(512), | 263 | .wMaxPacketSize = cpu_to_le16(512), |
264 | }; | 264 | }; |
265 | 265 | ||
266 | static struct usb_interface_descriptor interface_desc = { | 266 | static struct usb_interface_descriptor interface_desc = { |
267 | .bLength = USB_DT_INTERFACE_SIZE, | 267 | .bLength = USB_DT_INTERFACE_SIZE, |
268 | .bDescriptorType = USB_DT_INTERFACE, | 268 | .bDescriptorType = USB_DT_INTERFACE, |
269 | .bInterfaceNumber = 0x00, | 269 | .bInterfaceNumber = 0x00, |
270 | .bAlternateSetting = 0x00, | 270 | .bAlternateSetting = 0x00, |
271 | .bNumEndpoints = 0x02, | 271 | .bNumEndpoints = 0x02, |
272 | .bInterfaceClass = FASTBOOT_INTERFACE_CLASS, | 272 | .bInterfaceClass = FASTBOOT_INTERFACE_CLASS, |
273 | .bInterfaceSubClass = FASTBOOT_INTERFACE_SUB_CLASS, | 273 | .bInterfaceSubClass = FASTBOOT_INTERFACE_SUB_CLASS, |
274 | .bInterfaceProtocol = FASTBOOT_INTERFACE_PROTOCOL, | 274 | .bInterfaceProtocol = FASTBOOT_INTERFACE_PROTOCOL, |
275 | }; | 275 | }; |
276 | 276 | ||
277 | static struct usb_descriptor_header *fb_fs_function[] = { | 277 | static struct usb_descriptor_header *fb_fs_function[] = { |
278 | (struct usb_descriptor_header *)&interface_desc, | 278 | (struct usb_descriptor_header *)&interface_desc, |
279 | (struct usb_descriptor_header *)&fs_ep_in, | 279 | (struct usb_descriptor_header *)&fs_ep_in, |
280 | (struct usb_descriptor_header *)&fs_ep_out, | 280 | (struct usb_descriptor_header *)&fs_ep_out, |
281 | }; | 281 | }; |
282 | 282 | ||
283 | static struct usb_descriptor_header *fb_hs_function[] = { | 283 | static struct usb_descriptor_header *fb_hs_function[] = { |
284 | (struct usb_descriptor_header *)&interface_desc, | 284 | (struct usb_descriptor_header *)&interface_desc, |
285 | (struct usb_descriptor_header *)&hs_ep_in, | 285 | (struct usb_descriptor_header *)&hs_ep_in, |
286 | (struct usb_descriptor_header *)&hs_ep_out, | 286 | (struct usb_descriptor_header *)&hs_ep_out, |
287 | NULL, | 287 | NULL, |
288 | }; | 288 | }; |
289 | 289 | ||
290 | static struct usb_endpoint_descriptor * | 290 | static struct usb_endpoint_descriptor * |
291 | fb_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, | 291 | fb_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, |
292 | struct usb_endpoint_descriptor *hs) | 292 | struct usb_endpoint_descriptor *hs) |
293 | { | 293 | { |
294 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | 294 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) |
295 | return hs; | 295 | return hs; |
296 | return fs; | 296 | return fs; |
297 | } | 297 | } |
298 | 298 | ||
299 | /* | 299 | /* |
300 | * static strings, in UTF-8 | 300 | * static strings, in UTF-8 |
301 | */ | 301 | */ |
302 | static const char fastboot_name[] = "Android Fastboot"; | 302 | static const char fastboot_name[] = "Android Fastboot"; |
303 | 303 | ||
304 | static struct usb_string fastboot_string_defs[] = { | 304 | static struct usb_string fastboot_string_defs[] = { |
305 | [0].s = fastboot_name, | 305 | [0].s = fastboot_name, |
306 | { } /* end of list */ | 306 | { } /* end of list */ |
307 | }; | 307 | }; |
308 | 308 | ||
309 | static struct usb_gadget_strings stringtab_fastboot = { | 309 | static struct usb_gadget_strings stringtab_fastboot = { |
310 | .language = 0x0409, /* en-us */ | 310 | .language = 0x0409, /* en-us */ |
311 | .strings = fastboot_string_defs, | 311 | .strings = fastboot_string_defs, |
312 | }; | 312 | }; |
313 | 313 | ||
314 | static struct usb_gadget_strings *fastboot_strings[] = { | 314 | static struct usb_gadget_strings *fastboot_strings[] = { |
315 | &stringtab_fastboot, | 315 | &stringtab_fastboot, |
316 | NULL, | 316 | NULL, |
317 | }; | 317 | }; |
318 | 318 | ||
319 | static void rx_handler_command(struct usb_ep *ep, struct usb_request *req); | 319 | static void rx_handler_command(struct usb_ep *ep, struct usb_request *req); |
320 | static int strcmp_l1(const char *s1, const char *s2); | 320 | static int strcmp_l1(const char *s1, const char *s2); |
321 | 321 | ||
322 | 322 | ||
323 | static char *fb_response_str; | 323 | static char *fb_response_str; |
324 | 324 | ||
325 | #ifdef CONFIG_FSL_FASTBOOT | 325 | #ifdef CONFIG_FSL_FASTBOOT |
326 | 326 | ||
327 | #ifndef TRUSTY_OS_MMC_BLKS | 327 | #ifndef TRUSTY_OS_MMC_BLKS |
328 | #define TRUSTY_OS_MMC_BLKS 0x7FF | 328 | #define TRUSTY_OS_MMC_BLKS 0x7FF |
329 | #endif | 329 | #endif |
330 | #ifndef TEE_HWPARTITION_ID | 330 | #ifndef TEE_HWPARTITION_ID |
331 | #define TEE_HWPARTITION_ID 2 | 331 | #define TEE_HWPARTITION_ID 2 |
332 | #endif | 332 | #endif |
333 | 333 | ||
334 | #define FASTBOOT_PARTITION_ALL "all" | 334 | #define FASTBOOT_PARTITION_ALL "all" |
335 | 335 | ||
336 | #define ANDROID_MBR_OFFSET 0 | 336 | #define ANDROID_MBR_OFFSET 0 |
337 | #define ANDROID_MBR_SIZE 0x200 | 337 | #define ANDROID_MBR_SIZE 0x200 |
338 | #define ANDROID_BOOTLOADER_SIZE 0x400000 | 338 | #define ANDROID_BOOTLOADER_SIZE 0x400000 |
339 | 339 | ||
340 | #define MMC_SATA_BLOCK_SIZE 512 | 340 | #define MMC_SATA_BLOCK_SIZE 512 |
341 | #define FASTBOOT_FBPARTS_ENV_MAX_LEN 1024 | 341 | #define FASTBOOT_FBPARTS_ENV_MAX_LEN 1024 |
342 | /* To support the Android-style naming of flash */ | 342 | /* To support the Android-style naming of flash */ |
343 | #define MAX_PTN 32 | 343 | #define MAX_PTN 32 |
344 | struct fastboot_ptentry g_ptable[MAX_PTN]; | 344 | struct fastboot_ptentry g_ptable[MAX_PTN]; |
345 | unsigned int g_pcount; | 345 | unsigned int g_pcount; |
346 | struct fastboot_device_info fastboot_devinfo = {0xff, 0xff}; | 346 | struct fastboot_device_info fastboot_devinfo = {0xff, 0xff}; |
347 | 347 | ||
348 | 348 | ||
349 | enum { | 349 | enum { |
350 | PTN_GPT_INDEX = 0, | 350 | PTN_GPT_INDEX = 0, |
351 | PTN_TEE_INDEX, | 351 | PTN_TEE_INDEX, |
352 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | 352 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT |
353 | PTN_M4_OS_INDEX, | 353 | PTN_M4_OS_INDEX, |
354 | #endif | 354 | #endif |
355 | PTN_ALL_INDEX, | 355 | PTN_ALL_INDEX, |
356 | PTN_BOOTLOADER_INDEX, | 356 | PTN_BOOTLOADER_INDEX, |
357 | }; | 357 | }; |
358 | static unsigned int download_bytes_unpadded; | 358 | static unsigned int download_bytes_unpadded; |
359 | 359 | ||
360 | static struct cmd_fastboot_interface interface = { | 360 | static struct cmd_fastboot_interface interface = { |
361 | .rx_handler = NULL, | 361 | .rx_handler = NULL, |
362 | .reset_handler = NULL, | 362 | .reset_handler = NULL, |
363 | .product_name = NULL, | 363 | .product_name = NULL, |
364 | .serial_no = NULL, | 364 | .serial_no = NULL, |
365 | .nand_block_size = 0, | 365 | .nand_block_size = 0, |
366 | .transfer_buffer = (unsigned char *)0xffffffff, | 366 | .transfer_buffer = (unsigned char *)0xffffffff, |
367 | .transfer_buffer_size = 0, | 367 | .transfer_buffer_size = 0, |
368 | }; | 368 | }; |
369 | 369 | ||
370 | int read_from_partition_multi(const char* partition, | 370 | int read_from_partition_multi(const char* partition, |
371 | int64_t offset, size_t num_bytes, void* buffer, size_t* out_num_read) | 371 | int64_t offset, size_t num_bytes, void* buffer, size_t* out_num_read) |
372 | { | 372 | { |
373 | struct fastboot_ptentry *pte; | 373 | struct fastboot_ptentry *pte; |
374 | unsigned char *bdata; | 374 | unsigned char *bdata; |
375 | unsigned char *out_buf = (unsigned char *)buffer; | 375 | unsigned char *out_buf = (unsigned char *)buffer; |
376 | unsigned char *dst, *dst64 = NULL; | 376 | unsigned char *dst, *dst64 = NULL; |
377 | unsigned long blksz; | 377 | unsigned long blksz; |
378 | unsigned long s, cnt; | 378 | unsigned long s, cnt; |
379 | size_t num_read = 0; | 379 | size_t num_read = 0; |
380 | lbaint_t part_start, part_end, bs, be, bm, blk_num; | 380 | lbaint_t part_start, part_end, bs, be, bm, blk_num; |
381 | margin_pos_t margin; | 381 | margin_pos_t margin; |
382 | struct blk_desc *fs_dev_desc = NULL; | 382 | struct blk_desc *fs_dev_desc = NULL; |
383 | int dev_no; | 383 | int dev_no; |
384 | int ret; | 384 | int ret; |
385 | 385 | ||
386 | assert(buffer != NULL && out_num_read != NULL); | 386 | assert(buffer != NULL && out_num_read != NULL); |
387 | 387 | ||
388 | dev_no = mmc_get_env_dev(); | 388 | dev_no = mmc_get_env_dev(); |
389 | if ((fs_dev_desc = blk_get_dev("mmc", dev_no)) == NULL) { | 389 | if ((fs_dev_desc = blk_get_dev("mmc", dev_no)) == NULL) { |
390 | printf("mmc device not found\n"); | 390 | printf("mmc device not found\n"); |
391 | return -1; | 391 | return -1; |
392 | } | 392 | } |
393 | 393 | ||
394 | pte = fastboot_flash_find_ptn(partition); | 394 | pte = fastboot_flash_find_ptn(partition); |
395 | if (!pte) { | 395 | if (!pte) { |
396 | printf("no %s partition\n", partition); | 396 | printf("no %s partition\n", partition); |
397 | fastboot_flash_dump_ptn(); | 397 | fastboot_flash_dump_ptn(); |
398 | return -1; | 398 | return -1; |
399 | } | 399 | } |
400 | 400 | ||
401 | blksz = fs_dev_desc->blksz; | 401 | blksz = fs_dev_desc->blksz; |
402 | part_start = pte->start; | 402 | part_start = pte->start; |
403 | part_end = pte->start + pte->length - 1; | 403 | part_end = pte->start + pte->length - 1; |
404 | 404 | ||
405 | if (get_margin_pos((uint64_t)part_start, (uint64_t)part_end, blksz, | 405 | if (get_margin_pos((uint64_t)part_start, (uint64_t)part_end, blksz, |
406 | &margin, offset, num_bytes, true)) | 406 | &margin, offset, num_bytes, true)) |
407 | return -1; | 407 | return -1; |
408 | 408 | ||
409 | bs = (lbaint_t)margin.blk_start; | 409 | bs = (lbaint_t)margin.blk_start; |
410 | be = (lbaint_t)margin.blk_end; | 410 | be = (lbaint_t)margin.blk_end; |
411 | s = margin.start; | 411 | s = margin.start; |
412 | bm = margin.multi; | 412 | bm = margin.multi; |
413 | 413 | ||
414 | /* alloc a blksz mem */ | 414 | /* alloc a blksz mem */ |
415 | bdata = (unsigned char *)memalign(ALIGN_BYTES, blksz); | 415 | bdata = (unsigned char *)memalign(ALIGN_BYTES, blksz); |
416 | if (bdata == NULL) { | 416 | if (bdata == NULL) { |
417 | printf("Failed to allocate memory!\n"); | 417 | printf("Failed to allocate memory!\n"); |
418 | return -1; | 418 | return -1; |
419 | } | 419 | } |
420 | 420 | ||
421 | /* support multi blk read */ | 421 | /* support multi blk read */ |
422 | while (bs <= be) { | 422 | while (bs <= be) { |
423 | if (!s && bm > 1) { | 423 | if (!s && bm > 1) { |
424 | dst = out_buf; | 424 | dst = out_buf; |
425 | dst64 = PTR_ALIGN(out_buf, 64); /* for mmc blk read alignment */ | 425 | dst64 = PTR_ALIGN(out_buf, 64); /* for mmc blk read alignment */ |
426 | if (dst64 != dst) { | 426 | if (dst64 != dst) { |
427 | dst = dst64; | 427 | dst = dst64; |
428 | bm--; | 428 | bm--; |
429 | } | 429 | } |
430 | blk_num = bm; | 430 | blk_num = bm; |
431 | cnt = bm * blksz; | 431 | cnt = bm * blksz; |
432 | bm = 0; /* no more multi blk */ | 432 | bm = 0; /* no more multi blk */ |
433 | } else { | 433 | } else { |
434 | blk_num = 1; | 434 | blk_num = 1; |
435 | cnt = blksz - s; | 435 | cnt = blksz - s; |
436 | if (num_read + cnt > num_bytes) | 436 | if (num_read + cnt > num_bytes) |
437 | cnt = num_bytes - num_read; | 437 | cnt = num_bytes - num_read; |
438 | dst = bdata; | 438 | dst = bdata; |
439 | } | 439 | } |
440 | if (blk_dread(fs_dev_desc, bs, blk_num, dst) != blk_num) { | 440 | if (blk_dread(fs_dev_desc, bs, blk_num, dst) != blk_num) { |
441 | ret = -1; | 441 | ret = -1; |
442 | goto fail; | 442 | goto fail; |
443 | } | 443 | } |
444 | 444 | ||
445 | if (dst == bdata) | 445 | if (dst == bdata) |
446 | memcpy(out_buf, bdata + s, cnt); | 446 | memcpy(out_buf, bdata + s, cnt); |
447 | else if (dst == dst64) | 447 | else if (dst == dst64) |
448 | memcpy(out_buf, dst, cnt); /* internal copy */ | 448 | memcpy(out_buf, dst, cnt); /* internal copy */ |
449 | 449 | ||
450 | s = 0; | 450 | s = 0; |
451 | bs += blk_num; | 451 | bs += blk_num; |
452 | num_read += cnt; | 452 | num_read += cnt; |
453 | out_buf += cnt; | 453 | out_buf += cnt; |
454 | } | 454 | } |
455 | *out_num_read = num_read; | 455 | *out_num_read = num_read; |
456 | ret = 0; | 456 | ret = 0; |
457 | 457 | ||
458 | fail: | 458 | fail: |
459 | free(bdata); | 459 | free(bdata); |
460 | return ret; | 460 | return ret; |
461 | } | 461 | } |
462 | 462 | ||
463 | static void save_env(struct fastboot_ptentry *ptn, | 463 | static void save_env(struct fastboot_ptentry *ptn, |
464 | char *var, char *val) | 464 | char *var, char *val) |
465 | { | 465 | { |
466 | env_set(var, val); | 466 | env_set(var, val); |
467 | env_save(); | 467 | env_save(); |
468 | } | 468 | } |
469 | 469 | ||
470 | /* When save = 0, just parse. The input is unchanged | 470 | /* When save = 0, just parse. The input is unchanged |
471 | When save = 1, parse and do the save. The input is changed */ | 471 | When save = 1, parse and do the save. The input is changed */ |
472 | static int parse_env(void *ptn, char *err_string, int save, int debug) | 472 | static int parse_env(void *ptn, char *err_string, int save, int debug) |
473 | { | 473 | { |
474 | int ret = 1; | 474 | int ret = 1; |
475 | unsigned int sets = 0; | 475 | unsigned int sets = 0; |
476 | unsigned int comment_start = 0; | 476 | unsigned int comment_start = 0; |
477 | char *var = NULL; | 477 | char *var = NULL; |
478 | char *var_end = NULL; | 478 | char *var_end = NULL; |
479 | char *val = NULL; | 479 | char *val = NULL; |
480 | char *val_end = NULL; | 480 | char *val_end = NULL; |
481 | unsigned int i; | 481 | unsigned int i; |
482 | 482 | ||
483 | char *buff = (char *)interface.transfer_buffer; | 483 | char *buff = (char *)interface.transfer_buffer; |
484 | unsigned int size = download_bytes_unpadded; | 484 | unsigned int size = download_bytes_unpadded; |
485 | 485 | ||
486 | /* The input does not have to be null terminated. | 486 | /* The input does not have to be null terminated. |
487 | This will cause a problem in the corner case | 487 | This will cause a problem in the corner case |
488 | where the last line does not have a new line. | 488 | where the last line does not have a new line. |
489 | Put a null after the end of the input. | 489 | Put a null after the end of the input. |
490 | 490 | ||
491 | WARNING : Input buffer is assumed to be bigger | 491 | WARNING : Input buffer is assumed to be bigger |
492 | than the size of the input */ | 492 | than the size of the input */ |
493 | if (save) | 493 | if (save) |
494 | buff[size] = 0; | 494 | buff[size] = 0; |
495 | 495 | ||
496 | for (i = 0; i < size; i++) { | 496 | for (i = 0; i < size; i++) { |
497 | 497 | ||
498 | if (NULL == var) { | 498 | if (NULL == var) { |
499 | 499 | ||
500 | /* | 500 | /* |
501 | * Check for comments, comment ok only on | 501 | * Check for comments, comment ok only on |
502 | * mostly empty lines | 502 | * mostly empty lines |
503 | */ | 503 | */ |
504 | if (buff[i] == '#') | 504 | if (buff[i] == '#') |
505 | comment_start = 1; | 505 | comment_start = 1; |
506 | 506 | ||
507 | if (comment_start) { | 507 | if (comment_start) { |
508 | if ((buff[i] == '\r') || | 508 | if ((buff[i] == '\r') || |
509 | (buff[i] == '\n')) { | 509 | (buff[i] == '\n')) { |
510 | comment_start = 0; | 510 | comment_start = 0; |
511 | } | 511 | } |
512 | } else { | 512 | } else { |
513 | if (!((buff[i] == ' ') || | 513 | if (!((buff[i] == ' ') || |
514 | (buff[i] == '\t') || | 514 | (buff[i] == '\t') || |
515 | (buff[i] == '\r') || | 515 | (buff[i] == '\r') || |
516 | (buff[i] == '\n'))) { | 516 | (buff[i] == '\n'))) { |
517 | /* | 517 | /* |
518 | * Normal whitespace before the | 518 | * Normal whitespace before the |
519 | * variable | 519 | * variable |
520 | */ | 520 | */ |
521 | var = &buff[i]; | 521 | var = &buff[i]; |
522 | } | 522 | } |
523 | } | 523 | } |
524 | 524 | ||
525 | } else if (((NULL == var_end) || (NULL == val)) && | 525 | } else if (((NULL == var_end) || (NULL == val)) && |
526 | ((buff[i] == '\r') || (buff[i] == '\n'))) { | 526 | ((buff[i] == '\r') || (buff[i] == '\n'))) { |
527 | 527 | ||
528 | /* This is the case when a variable | 528 | /* This is the case when a variable |
529 | is unset. */ | 529 | is unset. */ |
530 | 530 | ||
531 | if (save) { | 531 | if (save) { |
532 | /* Set the var end to null so the | 532 | /* Set the var end to null so the |
533 | normal string routines will work | 533 | normal string routines will work |
534 | 534 | ||
535 | WARNING : This changes the input */ | 535 | WARNING : This changes the input */ |
536 | buff[i] = '\0'; | 536 | buff[i] = '\0'; |
537 | 537 | ||
538 | save_env(ptn, var, val); | 538 | save_env(ptn, var, val); |
539 | 539 | ||
540 | if (debug) | 540 | if (debug) |
541 | printf("Unsetting %s\n", var); | 541 | printf("Unsetting %s\n", var); |
542 | } | 542 | } |
543 | 543 | ||
544 | /* Clear the variable so state is parse is back | 544 | /* Clear the variable so state is parse is back |
545 | to initial. */ | 545 | to initial. */ |
546 | var = NULL; | 546 | var = NULL; |
547 | var_end = NULL; | 547 | var_end = NULL; |
548 | sets++; | 548 | sets++; |
549 | } else if (NULL == var_end) { | 549 | } else if (NULL == var_end) { |
550 | if ((buff[i] == ' ') || | 550 | if ((buff[i] == ' ') || |
551 | (buff[i] == '\t')) | 551 | (buff[i] == '\t')) |
552 | var_end = &buff[i]; | 552 | var_end = &buff[i]; |
553 | } else if (NULL == val) { | 553 | } else if (NULL == val) { |
554 | if (!((buff[i] == ' ') || | 554 | if (!((buff[i] == ' ') || |
555 | (buff[i] == '\t'))) | 555 | (buff[i] == '\t'))) |
556 | val = &buff[i]; | 556 | val = &buff[i]; |
557 | } else if (NULL == val_end) { | 557 | } else if (NULL == val_end) { |
558 | if ((buff[i] == '\r') || | 558 | if ((buff[i] == '\r') || |
559 | (buff[i] == '\n')) { | 559 | (buff[i] == '\n')) { |
560 | /* look for escaped cr or ln */ | 560 | /* look for escaped cr or ln */ |
561 | if ('\\' == buff[i - 1]) { | 561 | if ('\\' == buff[i - 1]) { |
562 | /* check for dos */ | 562 | /* check for dos */ |
563 | if ((buff[i] == '\r') && | 563 | if ((buff[i] == '\r') && |
564 | (buff[i+1] == '\n')) | 564 | (buff[i+1] == '\n')) |
565 | buff[i + 1] = ' '; | 565 | buff[i + 1] = ' '; |
566 | buff[i - 1] = buff[i] = ' '; | 566 | buff[i - 1] = buff[i] = ' '; |
567 | } else { | 567 | } else { |
568 | val_end = &buff[i]; | 568 | val_end = &buff[i]; |
569 | } | 569 | } |
570 | } | 570 | } |
571 | } else { | 571 | } else { |
572 | sprintf(err_string, "Internal Error"); | 572 | sprintf(err_string, "Internal Error"); |
573 | 573 | ||
574 | if (debug) | 574 | if (debug) |
575 | printf("Internal error at %s %d\n", | 575 | printf("Internal error at %s %d\n", |
576 | __FILE__, __LINE__); | 576 | __FILE__, __LINE__); |
577 | return 1; | 577 | return 1; |
578 | } | 578 | } |
579 | /* Check if a var / val pair is ready */ | 579 | /* Check if a var / val pair is ready */ |
580 | if (NULL != val_end) { | 580 | if (NULL != val_end) { |
581 | if (save) { | 581 | if (save) { |
582 | /* Set the end's with nulls so | 582 | /* Set the end's with nulls so |
583 | normal string routines will | 583 | normal string routines will |
584 | work. | 584 | work. |
585 | 585 | ||
586 | WARNING : This changes the input */ | 586 | WARNING : This changes the input */ |
587 | *var_end = '\0'; | 587 | *var_end = '\0'; |
588 | *val_end = '\0'; | 588 | *val_end = '\0'; |
589 | 589 | ||
590 | save_env(ptn, var, val); | 590 | save_env(ptn, var, val); |
591 | 591 | ||
592 | if (debug) | 592 | if (debug) |
593 | printf("Setting %s %s\n", var, val); | 593 | printf("Setting %s %s\n", var, val); |
594 | } | 594 | } |
595 | 595 | ||
596 | /* Clear the variable so state is parse is back | 596 | /* Clear the variable so state is parse is back |
597 | to initial. */ | 597 | to initial. */ |
598 | var = NULL; | 598 | var = NULL; |
599 | var_end = NULL; | 599 | var_end = NULL; |
600 | val = NULL; | 600 | val = NULL; |
601 | val_end = NULL; | 601 | val_end = NULL; |
602 | 602 | ||
603 | sets++; | 603 | sets++; |
604 | } | 604 | } |
605 | } | 605 | } |
606 | 606 | ||
607 | /* Corner case | 607 | /* Corner case |
608 | Check for the case that no newline at end of the input */ | 608 | Check for the case that no newline at end of the input */ |
609 | if ((NULL != var) && | 609 | if ((NULL != var) && |
610 | (NULL == val_end)) { | 610 | (NULL == val_end)) { |
611 | if (save) { | 611 | if (save) { |
612 | /* case of val / val pair */ | 612 | /* case of val / val pair */ |
613 | if (var_end) | 613 | if (var_end) |
614 | *var_end = '\0'; | 614 | *var_end = '\0'; |
615 | /* else case handled by setting 0 past | 615 | /* else case handled by setting 0 past |
616 | the end of buffer. | 616 | the end of buffer. |
617 | Similar for val_end being null */ | 617 | Similar for val_end being null */ |
618 | save_env(ptn, var, val); | 618 | save_env(ptn, var, val); |
619 | 619 | ||
620 | if (debug) { | 620 | if (debug) { |
621 | if (var_end) | 621 | if (var_end) |
622 | printf("Trailing Setting %s %s\n", var, val); | 622 | printf("Trailing Setting %s %s\n", var, val); |
623 | else | 623 | else |
624 | printf("Trailing Unsetting %s\n", var); | 624 | printf("Trailing Unsetting %s\n", var); |
625 | } | 625 | } |
626 | } | 626 | } |
627 | sets++; | 627 | sets++; |
628 | } | 628 | } |
629 | /* Did we set anything ? */ | 629 | /* Did we set anything ? */ |
630 | if (0 == sets) | 630 | if (0 == sets) |
631 | sprintf(err_string, "No variables set"); | 631 | sprintf(err_string, "No variables set"); |
632 | else | 632 | else |
633 | ret = 0; | 633 | ret = 0; |
634 | 634 | ||
635 | return ret; | 635 | return ret; |
636 | } | 636 | } |
637 | 637 | ||
638 | static int saveenv_to_ptn(struct fastboot_ptentry *ptn, char *err_string) | 638 | static int saveenv_to_ptn(struct fastboot_ptentry *ptn, char *err_string) |
639 | { | 639 | { |
640 | int ret = 1; | 640 | int ret = 1; |
641 | int save = 0; | 641 | int save = 0; |
642 | int debug = 0; | 642 | int debug = 0; |
643 | 643 | ||
644 | /* err_string is only 32 bytes | 644 | /* err_string is only 32 bytes |
645 | Initialize with a generic error message. */ | 645 | Initialize with a generic error message. */ |
646 | sprintf(err_string, "%s", "Unknown Error"); | 646 | sprintf(err_string, "%s", "Unknown Error"); |
647 | 647 | ||
648 | /* Parse the input twice. | 648 | /* Parse the input twice. |
649 | Only save to the enviroment if the entire input if correct */ | 649 | Only save to the enviroment if the entire input if correct */ |
650 | save = 0; | 650 | save = 0; |
651 | if (0 == parse_env(ptn, err_string, save, debug)) { | 651 | if (0 == parse_env(ptn, err_string, save, debug)) { |
652 | save = 1; | 652 | save = 1; |
653 | ret = parse_env(ptn, err_string, save, debug); | 653 | ret = parse_env(ptn, err_string, save, debug); |
654 | } | 654 | } |
655 | return ret; | 655 | return ret; |
656 | } | 656 | } |
657 | 657 | ||
658 | static int get_block_size(void); | 658 | static int get_block_size(void); |
659 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | 659 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT |
660 | static void process_flash_sf(const char *cmdbuf) | 660 | static void process_flash_sf(const char *cmdbuf) |
661 | { | 661 | { |
662 | int blksz = 0; | 662 | int blksz = 0; |
663 | blksz = get_block_size(); | 663 | blksz = get_block_size(); |
664 | 664 | ||
665 | if (download_bytes) { | 665 | if (download_bytes) { |
666 | struct fastboot_ptentry *ptn; | 666 | struct fastboot_ptentry *ptn; |
667 | ptn = fastboot_flash_find_ptn(cmdbuf); | 667 | ptn = fastboot_flash_find_ptn(cmdbuf); |
668 | if (ptn == 0) { | 668 | if (ptn == 0) { |
669 | fastboot_fail("partition does not exist"); | 669 | fastboot_fail("partition does not exist"); |
670 | fastboot_flash_dump_ptn(); | 670 | fastboot_flash_dump_ptn(); |
671 | } else if ((download_bytes > ptn->length * blksz)) { | 671 | } else if ((download_bytes > ptn->length * blksz)) { |
672 | fastboot_fail("image too large for partition"); | 672 | fastboot_fail("image too large for partition"); |
673 | /* TODO : Improve check for yaffs write */ | 673 | /* TODO : Improve check for yaffs write */ |
674 | } else { | 674 | } else { |
675 | int ret; | 675 | int ret; |
676 | char sf_command[128]; | 676 | char sf_command[128]; |
677 | /* Normal case */ | 677 | /* Normal case */ |
678 | /* Probe device */ | 678 | /* Probe device */ |
679 | sprintf(sf_command, "sf probe"); | 679 | sprintf(sf_command, "sf probe"); |
680 | ret = run_command(sf_command, 0); | 680 | ret = run_command(sf_command, 0); |
681 | if (ret){ | 681 | if (ret){ |
682 | fastboot_fail("Probe sf failed"); | 682 | fastboot_fail("Probe sf failed"); |
683 | return; | 683 | return; |
684 | } | 684 | } |
685 | /* Erase */ | 685 | /* Erase */ |
686 | sprintf(sf_command, "sf erase 0x%x 0x%x", ptn->start * blksz, /*start*/ | 686 | sprintf(sf_command, "sf erase 0x%x 0x%x", ptn->start * blksz, /*start*/ |
687 | ptn->length * blksz /*size*/); | 687 | ptn->length * blksz /*size*/); |
688 | ret = run_command(sf_command, 0); | 688 | ret = run_command(sf_command, 0); |
689 | if (ret) { | 689 | if (ret) { |
690 | fastboot_fail("Erasing sf failed"); | 690 | fastboot_fail("Erasing sf failed"); |
691 | return; | 691 | return; |
692 | } | 692 | } |
693 | /* Write image */ | 693 | /* Write image */ |
694 | sprintf(sf_command, "sf write 0x%x 0x%x 0x%x", | 694 | sprintf(sf_command, "sf write 0x%x 0x%x 0x%x", |
695 | (unsigned int)(ulong)interface.transfer_buffer, /* source */ | 695 | (unsigned int)(ulong)interface.transfer_buffer, /* source */ |
696 | ptn->start * blksz, /* start */ | 696 | ptn->start * blksz, /* start */ |
697 | download_bytes /*size*/); | 697 | download_bytes /*size*/); |
698 | printf("sf write '%s'\n", ptn->name); | 698 | printf("sf write '%s'\n", ptn->name); |
699 | ret = run_command(sf_command, 0); | 699 | ret = run_command(sf_command, 0); |
700 | if (ret){ | 700 | if (ret){ |
701 | fastboot_fail("Writing sf failed"); | 701 | fastboot_fail("Writing sf failed"); |
702 | return; | 702 | return; |
703 | } | 703 | } |
704 | printf("sf write finished '%s'\n", ptn->name); | 704 | printf("sf write finished '%s'\n", ptn->name); |
705 | fastboot_okay(""); | 705 | fastboot_okay(""); |
706 | } | 706 | } |
707 | } else { | 707 | } else { |
708 | fastboot_fail("no image downloaded"); | 708 | fastboot_fail("no image downloaded"); |
709 | } | 709 | } |
710 | } | 710 | } |
711 | 711 | ||
712 | #ifdef CONFIG_ARCH_IMX8M | 712 | #ifdef CONFIG_ARCH_IMX8M |
713 | /* Check if the mcu image is built for running from TCM */ | 713 | /* Check if the mcu image is built for running from TCM */ |
714 | static bool is_tcm_image(unsigned char *image_addr) | 714 | static bool is_tcm_image(unsigned char *image_addr) |
715 | { | 715 | { |
716 | u32 stack; | 716 | u32 stack; |
717 | 717 | ||
718 | stack = *(u32 *)image_addr; | 718 | stack = *(u32 *)image_addr; |
719 | 719 | ||
720 | if ((stack != (u32)ANDROID_MCU_FIRMWARE_HEADER_STACK)) { | 720 | if ((stack != (u32)ANDROID_MCU_FIRMWARE_HEADER_STACK)) { |
721 | printf("Please flash mcu firmware images for running from TCM\n"); | 721 | printf("Please flash mcu firmware images for running from TCM\n"); |
722 | return false; | 722 | return false; |
723 | } else | 723 | } else |
724 | return true; | 724 | return true; |
725 | } | 725 | } |
726 | 726 | ||
727 | static int do_bootmcu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | 727 | static int do_bootmcu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
728 | { | 728 | { |
729 | int ret; | 729 | int ret; |
730 | size_t out_num_read; | 730 | size_t out_num_read; |
731 | void *m4_base_addr = (void *)M4_BOOTROM_BASE_ADDR; | 731 | void *m4_base_addr = (void *)M4_BOOTROM_BASE_ADDR; |
732 | char command[32]; | 732 | char command[32]; |
733 | 733 | ||
734 | ret = read_from_partition_multi(FASTBOOT_MCU_FIRMWARE_PARTITION, | 734 | ret = read_from_partition_multi(FASTBOOT_MCU_FIRMWARE_PARTITION, |
735 | 0, ANDROID_MCU_FIRMWARE_SIZE, (void *)m4_base_addr, &out_num_read); | 735 | 0, ANDROID_MCU_FIRMWARE_SIZE, (void *)m4_base_addr, &out_num_read); |
736 | if ((ret != 0) || (out_num_read != ANDROID_MCU_FIRMWARE_SIZE)) { | 736 | if ((ret != 0) || (out_num_read != ANDROID_MCU_FIRMWARE_SIZE)) { |
737 | printf("Read M4 images failed!\n"); | 737 | printf("Read M4 images failed!\n"); |
738 | return 1; | 738 | return 1; |
739 | } else { | 739 | } else { |
740 | printf("run command: 'bootaux 0x%x'\n",(unsigned int)(ulong)m4_base_addr); | 740 | printf("run command: 'bootaux 0x%x'\n",(unsigned int)(ulong)m4_base_addr); |
741 | 741 | ||
742 | sprintf(command, "bootaux 0x%x", (unsigned int)(ulong)m4_base_addr); | 742 | sprintf(command, "bootaux 0x%x", (unsigned int)(ulong)m4_base_addr); |
743 | ret = run_command(command, 0); | 743 | ret = run_command(command, 0); |
744 | if (ret) { | 744 | if (ret) { |
745 | printf("run 'bootaux' command failed!\n"); | 745 | printf("run 'bootaux' command failed!\n"); |
746 | return 1; | 746 | return 1; |
747 | } | 747 | } |
748 | } | 748 | } |
749 | return 0; | 749 | return 0; |
750 | } | 750 | } |
751 | 751 | ||
752 | U_BOOT_CMD( | 752 | U_BOOT_CMD( |
753 | bootmcu, 1, 0, do_bootmcu, | 753 | bootmcu, 1, 0, do_bootmcu, |
754 | "boot mcu images\n", | 754 | "boot mcu images\n", |
755 | "boot mcu images from 'm4_os' partition, only support images run from TCM" | 755 | "boot mcu images from 'm4_os' partition, only support images run from TCM" |
756 | ); | 756 | ); |
757 | #endif | 757 | #endif |
758 | #endif /* CONFIG_FLASH_MCUFIRMWARE_SUPPORT */ | 758 | #endif /* CONFIG_FLASH_MCUFIRMWARE_SUPPORT */ |
759 | 759 | ||
760 | static ulong bootloader_mmc_offset(void) | 760 | static ulong bootloader_mmc_offset(void) |
761 | { | 761 | { |
762 | if (is_imx8m() || (is_imx8() && is_soc_rev(CHIP_REV_A))) | 762 | if (is_imx8m() || (is_imx8() && is_soc_rev(CHIP_REV_A))) |
763 | return 0x8400; | 763 | return 0x8400; |
764 | else if (is_imx8qm()) { | 764 | else if (is_imx8qm()) { |
765 | int dev_no = mmc_get_env_dev(); | 765 | int dev_no = mmc_get_env_dev(); |
766 | if (MEK_8QM_EMMC == dev_no) | 766 | if (MEK_8QM_EMMC == dev_no) |
767 | /* target device is eMMC boot0 partition, bootloader offset is 0x0 */ | 767 | /* target device is eMMC boot0 partition, bootloader offset is 0x0 */ |
768 | return 0x0; | 768 | return 0x0; |
769 | else | 769 | else |
770 | /* target device is SD card, bootloader offset is 0x8000 */ | 770 | /* target device is SD card, bootloader offset is 0x8000 */ |
771 | return 0x8000; | 771 | return 0x8000; |
772 | } | 772 | } |
773 | else if (is_imx8()) | 773 | else if (is_imx8()) |
774 | return 0x8000; | 774 | return 0x8000; |
775 | else | 775 | else |
776 | return 0x400; | 776 | return 0x400; |
777 | } | 777 | } |
778 | 778 | ||
779 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) || defined(CONFIG_FASTBOOT_STORAGE_SATA) | 779 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) || defined(CONFIG_FASTBOOT_STORAGE_SATA) |
780 | static int is_raw_partition(struct fastboot_ptentry *ptn) | 780 | static int is_raw_partition(struct fastboot_ptentry *ptn) |
781 | { | 781 | { |
782 | #ifdef CONFIG_ANDROID_AB_SUPPORT | 782 | #ifdef CONFIG_ANDROID_AB_SUPPORT |
783 | if (ptn && (!strncmp(ptn->name, FASTBOOT_PARTITION_BOOTLOADER, | 783 | if (ptn && (!strncmp(ptn->name, FASTBOOT_PARTITION_BOOTLOADER, |
784 | strlen(FASTBOOT_PARTITION_BOOTLOADER)) || | 784 | strlen(FASTBOOT_PARTITION_BOOTLOADER)) || |
785 | !strncmp(ptn->name, FASTBOOT_PARTITION_GPT, | 785 | !strncmp(ptn->name, FASTBOOT_PARTITION_GPT, |
786 | strlen(FASTBOOT_PARTITION_GPT)) || | 786 | strlen(FASTBOOT_PARTITION_GPT)) || |
787 | !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT_A, | 787 | !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT_A, |
788 | strlen(FASTBOOT_PARTITION_BOOT_A)) || | 788 | strlen(FASTBOOT_PARTITION_BOOT_A)) || |
789 | !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT_B, | 789 | !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT_B, |
790 | strlen(FASTBOOT_PARTITION_BOOT_B)) || | 790 | strlen(FASTBOOT_PARTITION_BOOT_B)) || |
791 | #ifdef CONFIG_FASTBOOT_LOCK | 791 | #ifdef CONFIG_FASTBOOT_LOCK |
792 | !strncmp(ptn->name, FASTBOOT_PARTITION_FBMISC, | 792 | !strncmp(ptn->name, FASTBOOT_PARTITION_FBMISC, |
793 | strlen(FASTBOOT_PARTITION_FBMISC)) || | 793 | strlen(FASTBOOT_PARTITION_FBMISC)) || |
794 | #endif | 794 | #endif |
795 | !strncmp(ptn->name, FASTBOOT_PARTITION_MISC, | 795 | !strncmp(ptn->name, FASTBOOT_PARTITION_MISC, |
796 | strlen(FASTBOOT_PARTITION_MISC)))) { | 796 | strlen(FASTBOOT_PARTITION_MISC)))) { |
797 | #else | 797 | #else |
798 | if (ptn && (!strncmp(ptn->name, FASTBOOT_PARTITION_BOOTLOADER, | 798 | if (ptn && (!strncmp(ptn->name, FASTBOOT_PARTITION_BOOTLOADER, |
799 | strlen(FASTBOOT_PARTITION_BOOTLOADER)) || | 799 | strlen(FASTBOOT_PARTITION_BOOTLOADER)) || |
800 | !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT, | 800 | !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT, |
801 | strlen(FASTBOOT_PARTITION_BOOT)) || | 801 | strlen(FASTBOOT_PARTITION_BOOT)) || |
802 | #ifdef CONFIG_FASTBOOT_LOCK | 802 | #ifdef CONFIG_FASTBOOT_LOCK |
803 | !strncmp(ptn->name, FASTBOOT_PARTITION_FBMISC, | 803 | !strncmp(ptn->name, FASTBOOT_PARTITION_FBMISC, |
804 | strlen(FASTBOOT_PARTITION_FBMISC)) || | 804 | strlen(FASTBOOT_PARTITION_FBMISC)) || |
805 | #endif | 805 | #endif |
806 | !strncmp(ptn->name, FASTBOOT_PARTITION_MISC, | 806 | !strncmp(ptn->name, FASTBOOT_PARTITION_MISC, |
807 | strlen(FASTBOOT_PARTITION_MISC)))) { | 807 | strlen(FASTBOOT_PARTITION_MISC)))) { |
808 | #endif | 808 | #endif |
809 | printf("support sparse flash partition for %s\n", ptn->name); | 809 | printf("support sparse flash partition for %s\n", ptn->name); |
810 | return 1; | 810 | return 1; |
811 | } else | 811 | } else |
812 | return 0; | 812 | return 0; |
813 | } | 813 | } |
814 | 814 | ||
815 | static lbaint_t mmc_sparse_write(struct sparse_storage *info, | 815 | static lbaint_t mmc_sparse_write(struct sparse_storage *info, |
816 | lbaint_t blk, lbaint_t blkcnt, const void *buffer) | 816 | lbaint_t blk, lbaint_t blkcnt, const void *buffer) |
817 | { | 817 | { |
818 | #define SPARSE_FILL_BUF_SIZE (2 * 1024 * 1024) | 818 | #define SPARSE_FILL_BUF_SIZE (2 * 1024 * 1024) |
819 | 819 | ||
820 | 820 | ||
821 | struct blk_desc *dev_desc = (struct blk_desc *)info->priv; | 821 | struct blk_desc *dev_desc = (struct blk_desc *)info->priv; |
822 | ulong ret = 0; | 822 | ulong ret = 0; |
823 | void *data; | 823 | void *data; |
824 | int fill_buf_num_blks, cnt; | 824 | int fill_buf_num_blks, cnt; |
825 | 825 | ||
826 | if ((unsigned long)buffer & (CONFIG_SYS_CACHELINE_SIZE - 1)) { | 826 | if ((unsigned long)buffer & (CONFIG_SYS_CACHELINE_SIZE - 1)) { |
827 | 827 | ||
828 | fill_buf_num_blks = SPARSE_FILL_BUF_SIZE / info->blksz; | 828 | fill_buf_num_blks = SPARSE_FILL_BUF_SIZE / info->blksz; |
829 | 829 | ||
830 | data = memalign(CONFIG_SYS_CACHELINE_SIZE, fill_buf_num_blks * info->blksz); | 830 | data = memalign(CONFIG_SYS_CACHELINE_SIZE, fill_buf_num_blks * info->blksz); |
831 | 831 | ||
832 | while (blkcnt) { | 832 | while (blkcnt) { |
833 | 833 | ||
834 | if (blkcnt > fill_buf_num_blks) | 834 | if (blkcnt > fill_buf_num_blks) |
835 | cnt = fill_buf_num_blks; | 835 | cnt = fill_buf_num_blks; |
836 | else | 836 | else |
837 | cnt = blkcnt; | 837 | cnt = blkcnt; |
838 | 838 | ||
839 | memcpy(data, buffer, cnt * info->blksz); | 839 | memcpy(data, buffer, cnt * info->blksz); |
840 | 840 | ||
841 | ret += blk_dwrite(dev_desc, blk, cnt, data); | 841 | ret += blk_dwrite(dev_desc, blk, cnt, data); |
842 | 842 | ||
843 | blk += cnt; | 843 | blk += cnt; |
844 | blkcnt -= cnt; | 844 | blkcnt -= cnt; |
845 | buffer = (void *)((unsigned long)buffer + cnt * info->blksz); | 845 | buffer = (void *)((unsigned long)buffer + cnt * info->blksz); |
846 | 846 | ||
847 | } | 847 | } |
848 | 848 | ||
849 | free(data); | 849 | free(data); |
850 | } else { | 850 | } else { |
851 | ret = blk_dwrite(dev_desc, blk, blkcnt, buffer); | 851 | ret = blk_dwrite(dev_desc, blk, blkcnt, buffer); |
852 | } | 852 | } |
853 | 853 | ||
854 | return ret; | 854 | return ret; |
855 | } | 855 | } |
856 | 856 | ||
857 | static lbaint_t mmc_sparse_reserve(struct sparse_storage *info, | 857 | static lbaint_t mmc_sparse_reserve(struct sparse_storage *info, |
858 | lbaint_t blk, lbaint_t blkcnt) | 858 | lbaint_t blk, lbaint_t blkcnt) |
859 | { | 859 | { |
860 | return blkcnt; | 860 | return blkcnt; |
861 | } | 861 | } |
862 | 862 | ||
863 | /*judge wether the gpt image and bootloader image are overlay*/ | 863 | /*judge wether the gpt image and bootloader image are overlay*/ |
864 | bool bootloader_gpt_overlay(void) | 864 | bool bootloader_gpt_overlay(void) |
865 | { | 865 | { |
866 | return (g_ptable[PTN_GPT_INDEX].partition_id == g_ptable[PTN_BOOTLOADER_INDEX].partition_id && | 866 | return (g_ptable[PTN_GPT_INDEX].partition_id == g_ptable[PTN_BOOTLOADER_INDEX].partition_id && |
867 | bootloader_mmc_offset() < ANDROID_GPT_END); | 867 | bootloader_mmc_offset() < ANDROID_GPT_END); |
868 | } | 868 | } |
869 | 869 | ||
870 | int write_backup_gpt(void) | 870 | int write_backup_gpt(void) |
871 | { | 871 | { |
872 | int mmc_no = 0; | 872 | int mmc_no = 0; |
873 | struct mmc *mmc; | 873 | struct mmc *mmc; |
874 | struct blk_desc *dev_desc; | 874 | struct blk_desc *dev_desc; |
875 | 875 | ||
876 | mmc_no = fastboot_devinfo.dev_id; | 876 | mmc_no = fastboot_devinfo.dev_id; |
877 | mmc = find_mmc_device(mmc_no); | 877 | mmc = find_mmc_device(mmc_no); |
878 | if (mmc == NULL) { | 878 | if (mmc == NULL) { |
879 | printf("invalid mmc device\n"); | 879 | printf("invalid mmc device\n"); |
880 | return -1; | 880 | return -1; |
881 | } | 881 | } |
882 | dev_desc = blk_get_dev("mmc", mmc_no); | 882 | dev_desc = blk_get_dev("mmc", mmc_no); |
883 | if (dev_desc == NULL) { | 883 | if (dev_desc == NULL) { |
884 | printf("Can't get Block device MMC %d\n", | 884 | printf("Can't get Block device MMC %d\n", |
885 | mmc_no); | 885 | mmc_no); |
886 | return -ENODEV; | 886 | return -ENODEV; |
887 | } | 887 | } |
888 | 888 | ||
889 | /* write backup get partition */ | 889 | /* write backup get partition */ |
890 | if (write_backup_gpt_partitions(dev_desc, interface.transfer_buffer)) { | 890 | if (write_backup_gpt_partitions(dev_desc, interface.transfer_buffer)) { |
891 | printf("writing GPT image fail\n"); | 891 | printf("writing GPT image fail\n"); |
892 | return -1; | 892 | return -1; |
893 | } | 893 | } |
894 | 894 | ||
895 | printf("flash backup gpt image successfully\n"); | 895 | printf("flash backup gpt image successfully\n"); |
896 | return 0; | 896 | return 0; |
897 | } | 897 | } |
898 | static int get_fastboot_target_dev(char *mmc_dev, struct fastboot_ptentry *ptn) | 898 | static int get_fastboot_target_dev(char *mmc_dev, struct fastboot_ptentry *ptn) |
899 | { | 899 | { |
900 | int dev = 0; | 900 | int dev = 0; |
901 | struct mmc *target_mmc; | 901 | struct mmc *target_mmc; |
902 | 902 | ||
903 | /* Support flash bootloader to mmc 'target_ubootdev' devices, if the | 903 | /* Support flash bootloader to mmc 'target_ubootdev' devices, if the |
904 | * 'target_ubootdev' env is not set just flash bootloader to current | 904 | * 'target_ubootdev' env is not set just flash bootloader to current |
905 | * mmc device. | 905 | * mmc device. |
906 | */ | 906 | */ |
907 | if ((!strncmp(ptn->name, FASTBOOT_PARTITION_BOOTLOADER, | 907 | if ((!strncmp(ptn->name, FASTBOOT_PARTITION_BOOTLOADER, |
908 | sizeof(FASTBOOT_PARTITION_BOOTLOADER))) && | 908 | sizeof(FASTBOOT_PARTITION_BOOTLOADER))) && |
909 | (env_get("target_ubootdev"))) { | 909 | (env_get("target_ubootdev"))) { |
910 | dev = simple_strtoul(env_get("target_ubootdev"), NULL, 10); | 910 | dev = simple_strtoul(env_get("target_ubootdev"), NULL, 10); |
911 | target_mmc = find_mmc_device(dev); | 911 | target_mmc = find_mmc_device(dev); |
912 | if ((target_mmc == NULL) || mmc_init(target_mmc)) { | 912 | if ((target_mmc == NULL) || mmc_init(target_mmc)) { |
913 | printf("MMC card init failed!\n"); | 913 | printf("MMC card init failed!\n"); |
914 | return -1; | 914 | return -1; |
915 | } else { | 915 | } else { |
916 | printf("Flash target is mmc%d\n", dev); | 916 | printf("Flash target is mmc%d\n", dev); |
917 | if (target_mmc->part_config != MMCPART_NOAVAILABLE) | 917 | if (target_mmc->part_config != MMCPART_NOAVAILABLE) |
918 | sprintf(mmc_dev, "mmc dev %x %x", dev, /*slot no*/ | 918 | sprintf(mmc_dev, "mmc dev %x %x", dev, /*slot no*/ |
919 | FASTBOOT_MMC_BOOT_PARTITION_ID/*part no*/); | 919 | FASTBOOT_MMC_BOOT_PARTITION_ID/*part no*/); |
920 | else | 920 | else |
921 | sprintf(mmc_dev, "mmc dev %x", dev); | 921 | sprintf(mmc_dev, "mmc dev %x", dev); |
922 | } | 922 | } |
923 | } else if (ptn->partition_id != FASTBOOT_MMC_NONE_PARTITION_ID) | 923 | } else if (ptn->partition_id != FASTBOOT_MMC_NONE_PARTITION_ID) |
924 | sprintf(mmc_dev, "mmc dev %x %x", | 924 | sprintf(mmc_dev, "mmc dev %x %x", |
925 | fastboot_devinfo.dev_id, /*slot no*/ | 925 | fastboot_devinfo.dev_id, /*slot no*/ |
926 | ptn->partition_id /*part no*/); | 926 | ptn->partition_id /*part no*/); |
927 | else | 927 | else |
928 | sprintf(mmc_dev, "mmc dev %x", | 928 | sprintf(mmc_dev, "mmc dev %x", |
929 | fastboot_devinfo.dev_id /*slot no*/); | 929 | fastboot_devinfo.dev_id /*slot no*/); |
930 | return 0; | 930 | return 0; |
931 | } | 931 | } |
932 | static void process_flash_mmc(const char *cmdbuf) | 932 | static void process_flash_mmc(const char *cmdbuf) |
933 | { | 933 | { |
934 | if (download_bytes) { | 934 | if (download_bytes) { |
935 | struct fastboot_ptentry *ptn; | 935 | struct fastboot_ptentry *ptn; |
936 | 936 | ||
937 | /* Next is the partition name */ | 937 | /* Next is the partition name */ |
938 | ptn = fastboot_flash_find_ptn(cmdbuf); | 938 | ptn = fastboot_flash_find_ptn(cmdbuf); |
939 | if (ptn == NULL) { | 939 | if (ptn == NULL) { |
940 | fastboot_fail("partition does not exist"); | 940 | fastboot_fail("partition does not exist"); |
941 | fastboot_flash_dump_ptn(); | 941 | fastboot_flash_dump_ptn(); |
942 | } else if ((download_bytes > | 942 | } else if ((download_bytes > |
943 | ptn->length * MMC_SATA_BLOCK_SIZE) && | 943 | ptn->length * MMC_SATA_BLOCK_SIZE) && |
944 | !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) { | 944 | !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) { |
945 | printf("Image too large for the partition\n"); | 945 | printf("Image too large for the partition\n"); |
946 | fastboot_fail("image too large for partition"); | 946 | fastboot_fail("image too large for partition"); |
947 | } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) { | 947 | } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) { |
948 | /* Since the response can only be 64 bytes, | 948 | /* Since the response can only be 64 bytes, |
949 | there is no point in having a large error message. */ | 949 | there is no point in having a large error message. */ |
950 | char err_string[32]; | 950 | char err_string[32]; |
951 | if (saveenv_to_ptn(ptn, &err_string[0])) { | 951 | if (saveenv_to_ptn(ptn, &err_string[0])) { |
952 | printf("savenv '%s' failed : %s\n", ptn->name, err_string); | 952 | printf("savenv '%s' failed : %s\n", ptn->name, err_string); |
953 | fastboot_fail(err_string); | 953 | fastboot_fail(err_string); |
954 | } else { | 954 | } else { |
955 | printf("partition '%s' saveenv-ed\n", ptn->name); | 955 | printf("partition '%s' saveenv-ed\n", ptn->name); |
956 | fastboot_okay(""); | 956 | fastboot_okay(""); |
957 | } | 957 | } |
958 | } else { | 958 | } else { |
959 | unsigned int temp; | 959 | unsigned int temp; |
960 | 960 | ||
961 | char blk_dev[128]; | 961 | char blk_dev[128]; |
962 | char blk_write[128]; | 962 | char blk_write[128]; |
963 | int blkret; | 963 | int blkret; |
964 | 964 | ||
965 | printf("writing to partition '%s'\n", ptn->name); | 965 | printf("writing to partition '%s'\n", ptn->name); |
966 | /* Get target flash device. */ | 966 | /* Get target flash device. */ |
967 | if (get_fastboot_target_dev(blk_dev, ptn) != 0) | 967 | if (get_fastboot_target_dev(blk_dev, ptn) != 0) |
968 | return; | 968 | return; |
969 | 969 | ||
970 | if (!is_raw_partition(ptn) && | 970 | if (!is_raw_partition(ptn) && |
971 | is_sparse_image(interface.transfer_buffer)) { | 971 | is_sparse_image(interface.transfer_buffer)) { |
972 | int dev_no = 0; | 972 | int dev_no = 0; |
973 | struct mmc *mmc; | 973 | struct mmc *mmc; |
974 | struct blk_desc *dev_desc; | 974 | struct blk_desc *dev_desc; |
975 | disk_partition_t info; | 975 | disk_partition_t info; |
976 | struct sparse_storage sparse; | 976 | struct sparse_storage sparse; |
977 | 977 | ||
978 | dev_no = fastboot_devinfo.dev_id; | 978 | dev_no = fastboot_devinfo.dev_id; |
979 | 979 | ||
980 | printf("sparse flash target is %s:%d\n", | 980 | printf("sparse flash target is %s:%d\n", |
981 | fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", | 981 | fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", |
982 | dev_no); | 982 | dev_no); |
983 | if (fastboot_devinfo.type == DEV_MMC) { | 983 | if (fastboot_devinfo.type == DEV_MMC) { |
984 | mmc = find_mmc_device(dev_no); | 984 | mmc = find_mmc_device(dev_no); |
985 | if (mmc && mmc_init(mmc)) | 985 | if (mmc && mmc_init(mmc)) |
986 | printf("MMC card init failed!\n"); | 986 | printf("MMC card init failed!\n"); |
987 | } | 987 | } |
988 | 988 | ||
989 | dev_desc = blk_get_dev(fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", dev_no); | 989 | dev_desc = blk_get_dev(fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", dev_no); |
990 | if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { | 990 | if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { |
991 | printf("** Block device %s %d not supported\n", | 991 | printf("** Block device %s %d not supported\n", |
992 | fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", | 992 | fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", |
993 | dev_no); | 993 | dev_no); |
994 | return; | 994 | return; |
995 | } | 995 | } |
996 | 996 | ||
997 | if( strncmp(ptn->name, FASTBOOT_PARTITION_ALL, | 997 | if( strncmp(ptn->name, FASTBOOT_PARTITION_ALL, |
998 | strlen(FASTBOOT_PARTITION_ALL)) == 0) { | 998 | strlen(FASTBOOT_PARTITION_ALL)) == 0) { |
999 | info.blksz = dev_desc->blksz; | 999 | info.blksz = dev_desc->blksz; |
1000 | info.size = dev_desc->lba; | 1000 | info.size = dev_desc->lba; |
1001 | info.start = 0; | 1001 | info.start = 0; |
1002 | } else { | 1002 | } else { |
1003 | 1003 | ||
1004 | if (part_get_info(dev_desc, | 1004 | if (part_get_info(dev_desc, |
1005 | ptn->partition_index, &info)) { | 1005 | ptn->partition_index, &info)) { |
1006 | printf("Bad partition index:%d for partition:%s\n", | 1006 | printf("Bad partition index:%d for partition:%s\n", |
1007 | ptn->partition_index, ptn->name); | 1007 | ptn->partition_index, ptn->name); |
1008 | return; | 1008 | return; |
1009 | } | 1009 | } |
1010 | } | 1010 | } |
1011 | printf("writing to partition '%s' for sparse, buffer size %d\n", | 1011 | printf("writing to partition '%s' for sparse, buffer size %d\n", |
1012 | ptn->name, download_bytes); | 1012 | ptn->name, download_bytes); |
1013 | 1013 | ||
1014 | sparse.blksz = info.blksz; | 1014 | sparse.blksz = info.blksz; |
1015 | sparse.start = info.start; | 1015 | sparse.start = info.start; |
1016 | sparse.size = info.size; | 1016 | sparse.size = info.size; |
1017 | sparse.write = mmc_sparse_write; | 1017 | sparse.write = mmc_sparse_write; |
1018 | sparse.reserve = mmc_sparse_reserve; | 1018 | sparse.reserve = mmc_sparse_reserve; |
1019 | printf("Flashing sparse image at offset " LBAFU "\n", | 1019 | printf("Flashing sparse image at offset " LBAFU "\n", |
1020 | sparse.start); | 1020 | sparse.start); |
1021 | 1021 | ||
1022 | sparse.priv = dev_desc; | 1022 | sparse.priv = dev_desc; |
1023 | write_sparse_image(&sparse, ptn->name, interface.transfer_buffer, | 1023 | write_sparse_image(&sparse, ptn->name, interface.transfer_buffer, |
1024 | download_bytes); | 1024 | download_bytes); |
1025 | 1025 | ||
1026 | } else { | 1026 | } else { |
1027 | /* Will flash images in below case: | 1027 | /* Will flash images in below case: |
1028 | * 1. Is not gpt partition. | 1028 | * 1. Is not gpt partition. |
1029 | * 2. Is gpt partition but no overlay detected. | 1029 | * 2. Is gpt partition but no overlay detected. |
1030 | * */ | 1030 | * */ |
1031 | if (strncmp(ptn->name, "gpt", 3) || !bootloader_gpt_overlay()) { | 1031 | if (strncmp(ptn->name, "gpt", 3) || !bootloader_gpt_overlay()) { |
1032 | /* block count */ | 1032 | /* block count */ |
1033 | if (strncmp(ptn->name, "gpt", 3) == 0) { | 1033 | if (strncmp(ptn->name, "gpt", 3) == 0) { |
1034 | temp = (ANDROID_GPT_END + | 1034 | temp = (ANDROID_GPT_END + |
1035 | MMC_SATA_BLOCK_SIZE - 1) / | 1035 | MMC_SATA_BLOCK_SIZE - 1) / |
1036 | MMC_SATA_BLOCK_SIZE; | 1036 | MMC_SATA_BLOCK_SIZE; |
1037 | } else { | 1037 | } else { |
1038 | temp = (download_bytes + | 1038 | temp = (download_bytes + |
1039 | MMC_SATA_BLOCK_SIZE - 1) / | 1039 | MMC_SATA_BLOCK_SIZE - 1) / |
1040 | MMC_SATA_BLOCK_SIZE; | 1040 | MMC_SATA_BLOCK_SIZE; |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | sprintf(blk_write, "%s write 0x%x 0x%x 0x%x", | 1043 | sprintf(blk_write, "%s write 0x%x 0x%x 0x%x", |
1044 | fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", | 1044 | fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", |
1045 | (unsigned int)(uintptr_t)interface.transfer_buffer, /*source*/ | 1045 | (unsigned int)(uintptr_t)interface.transfer_buffer, /*source*/ |
1046 | ptn->start, /*dest*/ | 1046 | ptn->start, /*dest*/ |
1047 | temp /*length*/); | 1047 | temp /*length*/); |
1048 | 1048 | ||
1049 | printf("Initializing '%s'\n", ptn->name); | 1049 | printf("Initializing '%s'\n", ptn->name); |
1050 | 1050 | ||
1051 | blkret = run_command(blk_dev, 0); | 1051 | blkret = run_command(blk_dev, 0); |
1052 | if (blkret) | 1052 | if (blkret) |
1053 | fastboot_fail("Init of BLK device failed"); | 1053 | fastboot_fail("Init of BLK device failed"); |
1054 | else | 1054 | else |
1055 | fastboot_okay(""); | 1055 | fastboot_okay(""); |
1056 | 1056 | ||
1057 | printf("Writing '%s'\n", ptn->name); | 1057 | printf("Writing '%s'\n", ptn->name); |
1058 | if (run_command(blk_write, 0)) { | 1058 | if (run_command(blk_write, 0)) { |
1059 | printf("Writing '%s' FAILED!\n", ptn->name); | 1059 | printf("Writing '%s' FAILED!\n", ptn->name); |
1060 | fastboot_fail("Write partition failed"); | 1060 | fastboot_fail("Write partition failed"); |
1061 | } else { | 1061 | } else { |
1062 | printf("Writing '%s' DONE!\n", ptn->name); | 1062 | printf("Writing '%s' DONE!\n", ptn->name); |
1063 | fastboot_okay(""); | 1063 | fastboot_okay(""); |
1064 | } | 1064 | } |
1065 | } | 1065 | } |
1066 | /* Write backup gpt image */ | 1066 | /* Write backup gpt image */ |
1067 | if (strncmp(ptn->name, "gpt", 3) == 0) { | 1067 | if (strncmp(ptn->name, "gpt", 3) == 0) { |
1068 | if (write_backup_gpt()) | 1068 | if (write_backup_gpt()) |
1069 | fastboot_fail("write backup GPT image fail"); | 1069 | fastboot_fail("write backup GPT image fail"); |
1070 | else | 1070 | else |
1071 | fastboot_okay(""); | 1071 | fastboot_okay(""); |
1072 | 1072 | ||
1073 | /* will force scan the device, | 1073 | /* will force scan the device, |
1074 | * so dev_desc can be re-inited | 1074 | * so dev_desc can be re-inited |
1075 | * with the latest data */ | 1075 | * with the latest data */ |
1076 | run_command(blk_dev, 0); | 1076 | run_command(blk_dev, 0); |
1077 | } | 1077 | } |
1078 | } | 1078 | } |
1079 | } | 1079 | } |
1080 | } else { | 1080 | } else { |
1081 | fastboot_fail("no image downloaded"); | 1081 | fastboot_fail("no image downloaded"); |
1082 | } | 1082 | } |
1083 | } | 1083 | } |
1084 | 1084 | ||
1085 | #endif | 1085 | #endif |
1086 | 1086 | ||
1087 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) | 1087 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) |
1088 | static void process_erase_mmc(const char *cmdbuf, char *response) | 1088 | static void process_erase_mmc(const char *cmdbuf, char *response) |
1089 | { | 1089 | { |
1090 | int mmc_no = 0; | 1090 | int mmc_no = 0; |
1091 | lbaint_t blks, blks_start, blks_size, grp_size; | 1091 | lbaint_t blks, blks_start, blks_size, grp_size; |
1092 | struct mmc *mmc; | 1092 | struct mmc *mmc; |
1093 | struct blk_desc *dev_desc; | 1093 | struct blk_desc *dev_desc; |
1094 | struct fastboot_ptentry *ptn; | 1094 | struct fastboot_ptentry *ptn; |
1095 | disk_partition_t info; | 1095 | disk_partition_t info; |
1096 | 1096 | ||
1097 | ptn = fastboot_flash_find_ptn(cmdbuf); | 1097 | ptn = fastboot_flash_find_ptn(cmdbuf); |
1098 | if ((ptn == NULL) || (ptn->flags & FASTBOOT_PTENTRY_FLAGS_UNERASEABLE)) { | 1098 | if ((ptn == NULL) || (ptn->flags & FASTBOOT_PTENTRY_FLAGS_UNERASEABLE)) { |
1099 | sprintf(response, "FAILpartition does not exist or uneraseable"); | 1099 | sprintf(response, "FAILpartition does not exist or uneraseable"); |
1100 | fastboot_flash_dump_ptn(); | 1100 | fastboot_flash_dump_ptn(); |
1101 | return; | 1101 | return; |
1102 | } | 1102 | } |
1103 | 1103 | ||
1104 | mmc_no = fastboot_devinfo.dev_id; | 1104 | mmc_no = fastboot_devinfo.dev_id; |
1105 | printf("erase target is MMC:%d\n", mmc_no); | 1105 | printf("erase target is MMC:%d\n", mmc_no); |
1106 | 1106 | ||
1107 | mmc = find_mmc_device(mmc_no); | 1107 | mmc = find_mmc_device(mmc_no); |
1108 | if ((mmc == NULL) || mmc_init(mmc)) { | 1108 | if ((mmc == NULL) || mmc_init(mmc)) { |
1109 | printf("MMC card init failed!\n"); | 1109 | printf("MMC card init failed!\n"); |
1110 | return; | 1110 | return; |
1111 | } | 1111 | } |
1112 | 1112 | ||
1113 | dev_desc = blk_get_dev("mmc", mmc_no); | 1113 | dev_desc = blk_get_dev("mmc", mmc_no); |
1114 | if (NULL == dev_desc) { | 1114 | if (NULL == dev_desc) { |
1115 | printf("Block device MMC %d not supported\n", | 1115 | printf("Block device MMC %d not supported\n", |
1116 | mmc_no); | 1116 | mmc_no); |
1117 | sprintf(response, "FAILnot valid MMC card"); | 1117 | sprintf(response, "FAILnot valid MMC card"); |
1118 | return; | 1118 | return; |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | if (part_get_info(dev_desc, | 1121 | if (part_get_info(dev_desc, |
1122 | ptn->partition_index, &info)) { | 1122 | ptn->partition_index, &info)) { |
1123 | printf("Bad partition index:%d for partition:%s\n", | 1123 | printf("Bad partition index:%d for partition:%s\n", |
1124 | ptn->partition_index, ptn->name); | 1124 | ptn->partition_index, ptn->name); |
1125 | sprintf(response, "FAILerasing of MMC card"); | 1125 | sprintf(response, "FAILerasing of MMC card"); |
1126 | return; | 1126 | return; |
1127 | } | 1127 | } |
1128 | 1128 | ||
1129 | /* Align blocks to erase group size to avoid erasing other partitions */ | 1129 | /* Align blocks to erase group size to avoid erasing other partitions */ |
1130 | grp_size = mmc->erase_grp_size; | 1130 | grp_size = mmc->erase_grp_size; |
1131 | blks_start = (info.start + grp_size - 1) & ~(grp_size - 1); | 1131 | blks_start = (info.start + grp_size - 1) & ~(grp_size - 1); |
1132 | if (info.size >= grp_size) | 1132 | if (info.size >= grp_size) |
1133 | blks_size = (info.size - (blks_start - info.start)) & | 1133 | blks_size = (info.size - (blks_start - info.start)) & |
1134 | (~(grp_size - 1)); | 1134 | (~(grp_size - 1)); |
1135 | else | 1135 | else |
1136 | blks_size = 0; | 1136 | blks_size = 0; |
1137 | 1137 | ||
1138 | printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n", | 1138 | printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n", |
1139 | blks_start, blks_start + blks_size); | 1139 | blks_start, blks_start + blks_size); |
1140 | 1140 | ||
1141 | blks = blk_derase(dev_desc, blks_start, blks_size); | 1141 | blks = blk_derase(dev_desc, blks_start, blks_size); |
1142 | if (blks != blks_size) { | 1142 | if (blks != blks_size) { |
1143 | printf("failed erasing from device %d", dev_desc->devnum); | 1143 | printf("failed erasing from device %d", dev_desc->devnum); |
1144 | sprintf(response, "FAILerasing of MMC card"); | 1144 | sprintf(response, "FAILerasing of MMC card"); |
1145 | return; | 1145 | return; |
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | printf("........ erased " LBAFU " bytes from '%s'\n", | 1148 | printf("........ erased " LBAFU " bytes from '%s'\n", |
1149 | blks_size * info.blksz, cmdbuf); | 1149 | blks_size * info.blksz, cmdbuf); |
1150 | sprintf(response, "OKAY"); | 1150 | sprintf(response, "OKAY"); |
1151 | 1151 | ||
1152 | return; | 1152 | return; |
1153 | } | 1153 | } |
1154 | #endif | 1154 | #endif |
1155 | 1155 | ||
1156 | #if defined(CONFIG_FASTBOOT_STORAGE_SATA) | 1156 | #if defined(CONFIG_FASTBOOT_STORAGE_SATA) |
1157 | static void process_erase_sata(const char *cmdbuf, char *response) | 1157 | static void process_erase_sata(const char *cmdbuf, char *response) |
1158 | { | 1158 | { |
1159 | return; | 1159 | return; |
1160 | } | 1160 | } |
1161 | #endif | 1161 | #endif |
1162 | 1162 | ||
1163 | static void rx_process_erase(const char *cmdbuf, char *response) | 1163 | static void rx_process_erase(const char *cmdbuf, char *response) |
1164 | { | 1164 | { |
1165 | switch (fastboot_devinfo.type) { | 1165 | switch (fastboot_devinfo.type) { |
1166 | #if defined(CONFIG_FASTBOOT_STORAGE_SATA) | 1166 | #if defined(CONFIG_FASTBOOT_STORAGE_SATA) |
1167 | case DEV_SATA: | 1167 | case DEV_SATA: |
1168 | process_erase_sata(cmdbuf, response); | 1168 | process_erase_sata(cmdbuf, response); |
1169 | break; | 1169 | break; |
1170 | #endif | 1170 | #endif |
1171 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) | 1171 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) |
1172 | case DEV_MMC: | 1172 | case DEV_MMC: |
1173 | process_erase_mmc(cmdbuf, response); | 1173 | process_erase_mmc(cmdbuf, response); |
1174 | break; | 1174 | break; |
1175 | #endif | 1175 | #endif |
1176 | default: | 1176 | default: |
1177 | printf("Not support flash command for current device %d\n", | 1177 | printf("Not support flash command for current device %d\n", |
1178 | fastboot_devinfo.type); | 1178 | fastboot_devinfo.type); |
1179 | sprintf(response, | 1179 | sprintf(response, |
1180 | "FAILfailed to flash device"); | 1180 | "FAILfailed to flash device"); |
1181 | break; | 1181 | break; |
1182 | } | 1182 | } |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | static void rx_process_flash(const char *cmdbuf) | 1185 | static void rx_process_flash(const char *cmdbuf) |
1186 | { | 1186 | { |
1187 | /* Check if we need to flash mcu firmware */ | 1187 | /* Check if we need to flash mcu firmware */ |
1188 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | 1188 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT |
1189 | if (!strncmp(cmdbuf, FASTBOOT_MCU_FIRMWARE_PARTITION, | 1189 | if (!strncmp(cmdbuf, FASTBOOT_MCU_FIRMWARE_PARTITION, |
1190 | sizeof(FASTBOOT_MCU_FIRMWARE_PARTITION))) { | 1190 | sizeof(FASTBOOT_MCU_FIRMWARE_PARTITION))) { |
1191 | switch (fastboot_firmwareinfo.type) { | 1191 | switch (fastboot_firmwareinfo.type) { |
1192 | case DEV_SF: | 1192 | case DEV_SF: |
1193 | process_flash_sf(cmdbuf); | 1193 | process_flash_sf(cmdbuf); |
1194 | break; | 1194 | break; |
1195 | #ifdef CONFIG_ARCH_IMX8M | 1195 | #ifdef CONFIG_ARCH_IMX8M |
1196 | case DEV_MMC: | 1196 | case DEV_MMC: |
1197 | if (is_tcm_image(interface.transfer_buffer)) | 1197 | if (is_tcm_image(interface.transfer_buffer)) |
1198 | process_flash_mmc(cmdbuf); | 1198 | process_flash_mmc(cmdbuf); |
1199 | break; | 1199 | break; |
1200 | #endif | 1200 | #endif |
1201 | default: | 1201 | default: |
1202 | printf("Don't support flash firmware\n"); | 1202 | printf("Don't support flash firmware\n"); |
1203 | } | 1203 | } |
1204 | return; | 1204 | return; |
1205 | } | 1205 | } |
1206 | #endif | 1206 | #endif |
1207 | /* Normal case */ | 1207 | /* Normal case */ |
1208 | switch (fastboot_devinfo.type) { | 1208 | switch (fastboot_devinfo.type) { |
1209 | #if defined(CONFIG_FASTBOOT_STORAGE_SATA) | 1209 | #if defined(CONFIG_FASTBOOT_STORAGE_SATA) |
1210 | case DEV_SATA: | 1210 | case DEV_SATA: |
1211 | process_flash_mmc(cmdbuf); | 1211 | process_flash_mmc(cmdbuf); |
1212 | break; | 1212 | break; |
1213 | #endif | 1213 | #endif |
1214 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) | 1214 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) |
1215 | case DEV_MMC: | 1215 | case DEV_MMC: |
1216 | process_flash_mmc(cmdbuf); | 1216 | process_flash_mmc(cmdbuf); |
1217 | break; | 1217 | break; |
1218 | #endif | 1218 | #endif |
1219 | default: | 1219 | default: |
1220 | printf("Not support flash command for current device %d\n", | 1220 | printf("Not support flash command for current device %d\n", |
1221 | fastboot_devinfo.type); | 1221 | fastboot_devinfo.type); |
1222 | fastboot_fail("failed to flash device"); | 1222 | fastboot_fail("failed to flash device"); |
1223 | break; | 1223 | break; |
1224 | } | 1224 | } |
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | 1227 | ||
1228 | static void parameters_setup(void) | 1228 | static void parameters_setup(void) |
1229 | { | 1229 | { |
1230 | interface.nand_block_size = 0; | 1230 | interface.nand_block_size = 0; |
1231 | interface.transfer_buffer = | 1231 | interface.transfer_buffer = |
1232 | (unsigned char *)env_get_ulong("fastboot_buffer", 16, CONFIG_FASTBOOT_BUF_ADDR); | 1232 | (unsigned char *)env_get_ulong("fastboot_buffer", 16, CONFIG_FASTBOOT_BUF_ADDR); |
1233 | interface.transfer_buffer_size = | 1233 | interface.transfer_buffer_size = |
1234 | CONFIG_FASTBOOT_BUF_SIZE; | 1234 | CONFIG_FASTBOOT_BUF_SIZE; |
1235 | } | 1235 | } |
1236 | 1236 | ||
1237 | static int _fastboot_setup_dev(int *switched) | 1237 | static int _fastboot_setup_dev(int *switched) |
1238 | { | 1238 | { |
1239 | char *fastboot_env; | 1239 | char *fastboot_env; |
1240 | struct fastboot_device_info devinfo;; | 1240 | struct fastboot_device_info devinfo;; |
1241 | fastboot_env = env_get("fastboot_dev"); | 1241 | fastboot_env = env_get("fastboot_dev"); |
1242 | 1242 | ||
1243 | if (fastboot_env) { | 1243 | if (fastboot_env) { |
1244 | if (!strcmp(fastboot_env, "sata")) { | 1244 | if (!strcmp(fastboot_env, "sata")) { |
1245 | devinfo.type = DEV_SATA; | 1245 | devinfo.type = DEV_SATA; |
1246 | devinfo.dev_id = 0; | 1246 | devinfo.dev_id = 0; |
1247 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) | 1247 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) |
1248 | } else if (!strncmp(fastboot_env, "mmc", 3)) { | 1248 | } else if (!strncmp(fastboot_env, "mmc", 3)) { |
1249 | devinfo.type = DEV_MMC; | 1249 | devinfo.type = DEV_MMC; |
1250 | devinfo.dev_id = mmc_get_env_dev(); | 1250 | devinfo.dev_id = mmc_get_env_dev(); |
1251 | #endif | 1251 | #endif |
1252 | } else { | 1252 | } else { |
1253 | return 1; | 1253 | return 1; |
1254 | } | 1254 | } |
1255 | } else { | 1255 | } else { |
1256 | return 1; | 1256 | return 1; |
1257 | } | 1257 | } |
1258 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | 1258 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT |
1259 | /* For imx7ulp, flash m4 images directly to spi nor-flash, M4 will | 1259 | /* For imx7ulp, flash m4 images directly to spi nor-flash, M4 will |
1260 | * run automatically after powered on. For imx8mq, flash m4 images to | 1260 | * run automatically after powered on. For imx8mq, flash m4 images to |
1261 | * physical partition 'm4_os', m4 will be kicked off by A core. */ | 1261 | * physical partition 'm4_os', m4 will be kicked off by A core. */ |
1262 | fastboot_firmwareinfo.type = ANDROID_MCU_FRIMWARE_DEV_TYPE; | 1262 | fastboot_firmwareinfo.type = ANDROID_MCU_FRIMWARE_DEV_TYPE; |
1263 | #endif | 1263 | #endif |
1264 | 1264 | ||
1265 | if (switched) { | 1265 | if (switched) { |
1266 | if (devinfo.type != fastboot_devinfo.type || devinfo.dev_id != fastboot_devinfo.dev_id) | 1266 | if (devinfo.type != fastboot_devinfo.type || devinfo.dev_id != fastboot_devinfo.dev_id) |
1267 | *switched = 1; | 1267 | *switched = 1; |
1268 | else | 1268 | else |
1269 | *switched = 0; | 1269 | *switched = 0; |
1270 | } | 1270 | } |
1271 | 1271 | ||
1272 | fastboot_devinfo.type = devinfo.type; | 1272 | fastboot_devinfo.type = devinfo.type; |
1273 | fastboot_devinfo.dev_id = devinfo.dev_id; | 1273 | fastboot_devinfo.dev_id = devinfo.dev_id; |
1274 | 1274 | ||
1275 | return 0; | 1275 | return 0; |
1276 | } | 1276 | } |
1277 | 1277 | ||
1278 | #if defined(CONFIG_FASTBOOT_STORAGE_SATA) \ | 1278 | #if defined(CONFIG_FASTBOOT_STORAGE_SATA) \ |
1279 | || defined(CONFIG_FASTBOOT_STORAGE_MMC) | 1279 | || defined(CONFIG_FASTBOOT_STORAGE_MMC) |
1280 | /** | 1280 | /** |
1281 | @mmc_dos_partition_index: the partition index in mbr. | 1281 | @mmc_dos_partition_index: the partition index in mbr. |
1282 | @mmc_partition_index: the boot partition or user partition index, | 1282 | @mmc_partition_index: the boot partition or user partition index, |
1283 | not related to the partition table. | 1283 | not related to the partition table. |
1284 | */ | 1284 | */ |
1285 | static int _fastboot_parts_add_ptable_entry(int ptable_index, | 1285 | static int _fastboot_parts_add_ptable_entry(int ptable_index, |
1286 | int mmc_dos_partition_index, | 1286 | int mmc_dos_partition_index, |
1287 | int mmc_partition_index, | 1287 | int mmc_partition_index, |
1288 | const char *name, | 1288 | const char *name, |
1289 | const char *fstype, | 1289 | const char *fstype, |
1290 | struct blk_desc *dev_desc, | 1290 | struct blk_desc *dev_desc, |
1291 | struct fastboot_ptentry *ptable) | 1291 | struct fastboot_ptentry *ptable) |
1292 | { | 1292 | { |
1293 | disk_partition_t info; | 1293 | disk_partition_t info; |
1294 | 1294 | ||
1295 | if (part_get_info(dev_desc, | 1295 | if (part_get_info(dev_desc, |
1296 | mmc_dos_partition_index, &info)) { | 1296 | mmc_dos_partition_index, &info)) { |
1297 | debug("Bad partition index:%d for partition:%s\n", | 1297 | debug("Bad partition index:%d for partition:%s\n", |
1298 | mmc_dos_partition_index, name); | 1298 | mmc_dos_partition_index, name); |
1299 | return -1; | 1299 | return -1; |
1300 | } | 1300 | } |
1301 | ptable[ptable_index].start = info.start; | 1301 | ptable[ptable_index].start = info.start; |
1302 | ptable[ptable_index].length = info.size; | 1302 | ptable[ptable_index].length = info.size; |
1303 | ptable[ptable_index].partition_id = mmc_partition_index; | 1303 | ptable[ptable_index].partition_id = mmc_partition_index; |
1304 | ptable[ptable_index].partition_index = mmc_dos_partition_index; | 1304 | ptable[ptable_index].partition_index = mmc_dos_partition_index; |
1305 | strncpy(ptable[ptable_index].name, (const char *)info.name, | 1305 | strncpy(ptable[ptable_index].name, (const char *)info.name, |
1306 | sizeof(ptable[ptable_index].name) - 1); | 1306 | sizeof(ptable[ptable_index].name) - 1); |
1307 | 1307 | ||
1308 | #ifdef CONFIG_PARTITION_UUIDS | 1308 | #ifdef CONFIG_PARTITION_UUIDS |
1309 | strcpy(ptable[ptable_index].uuid, (const char *)info.uuid); | 1309 | strcpy(ptable[ptable_index].uuid, (const char *)info.uuid); |
1310 | #endif | 1310 | #endif |
1311 | #ifdef CONFIG_ANDROID_AB_SUPPORT | 1311 | #ifdef CONFIG_ANDROID_AB_SUPPORT |
1312 | if (!strcmp((const char *)info.name, FASTBOOT_PARTITION_SYSTEM_A) || | 1312 | if (!strcmp((const char *)info.name, FASTBOOT_PARTITION_SYSTEM_A) || |
1313 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_SYSTEM_B) || | 1313 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_SYSTEM_B) || |
1314 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_OEM_A) || | 1314 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_OEM_A) || |
1315 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_VENDOR_A) || | 1315 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_VENDOR_A) || |
1316 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_OEM_B) || | 1316 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_OEM_B) || |
1317 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_VENDOR_B) || | 1317 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_VENDOR_B) || |
1318 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_DATA)) | 1318 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_DATA)) |
1319 | #else | 1319 | #else |
1320 | if (!strcmp((const char *)info.name, FASTBOOT_PARTITION_SYSTEM) || | 1320 | if (!strcmp((const char *)info.name, FASTBOOT_PARTITION_SYSTEM) || |
1321 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_DATA) || | 1321 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_DATA) || |
1322 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_DEVICE) || | 1322 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_DEVICE) || |
1323 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_CACHE)) | 1323 | !strcmp((const char *)info.name, FASTBOOT_PARTITION_CACHE)) |
1324 | #endif | 1324 | #endif |
1325 | strcpy(ptable[ptable_index].fstype, "ext4"); | 1325 | strcpy(ptable[ptable_index].fstype, "ext4"); |
1326 | else | 1326 | else |
1327 | strcpy(ptable[ptable_index].fstype, "raw"); | 1327 | strcpy(ptable[ptable_index].fstype, "raw"); |
1328 | return 0; | 1328 | return 0; |
1329 | } | 1329 | } |
1330 | 1330 | ||
1331 | static int _fastboot_parts_load_from_ptable(void) | 1331 | static int _fastboot_parts_load_from_ptable(void) |
1332 | { | 1332 | { |
1333 | int i; | 1333 | int i; |
1334 | #ifdef CONFIG_CMD_SATA | 1334 | #ifdef CONFIG_CMD_SATA |
1335 | int sata_device_no; | 1335 | int sata_device_no; |
1336 | #endif | 1336 | #endif |
1337 | 1337 | ||
1338 | /* mmc boot partition: -1 means no partition, 0 user part., 1 boot part. | 1338 | /* mmc boot partition: -1 means no partition, 0 user part., 1 boot part. |
1339 | * default is no partition, for emmc default user part, except emmc*/ | 1339 | * default is no partition, for emmc default user part, except emmc*/ |
1340 | int boot_partition = FASTBOOT_MMC_NONE_PARTITION_ID; | 1340 | int boot_partition = FASTBOOT_MMC_NONE_PARTITION_ID; |
1341 | int user_partition = FASTBOOT_MMC_NONE_PARTITION_ID; | 1341 | int user_partition = FASTBOOT_MMC_NONE_PARTITION_ID; |
1342 | 1342 | ||
1343 | struct mmc *mmc; | 1343 | struct mmc *mmc; |
1344 | struct blk_desc *dev_desc; | 1344 | struct blk_desc *dev_desc; |
1345 | struct fastboot_ptentry ptable[MAX_PTN]; | 1345 | struct fastboot_ptentry ptable[MAX_PTN]; |
1346 | 1346 | ||
1347 | /* sata case in env */ | 1347 | /* sata case in env */ |
1348 | if (fastboot_devinfo.type == DEV_SATA) { | 1348 | if (fastboot_devinfo.type == DEV_SATA) { |
1349 | #ifdef CONFIG_CMD_SATA | 1349 | #ifdef CONFIG_CMD_SATA |
1350 | puts("flash target is SATA\n"); | 1350 | puts("flash target is SATA\n"); |
1351 | if (sata_initialize()) | 1351 | if (sata_initialize()) |
1352 | return -1; | 1352 | return -1; |
1353 | sata_device_no = CONFIG_FASTBOOT_SATA_NO; | 1353 | sata_device_no = CONFIG_FASTBOOT_SATA_NO; |
1354 | if (sata_device_no >= CONFIG_SYS_SATA_MAX_DEVICE) { | 1354 | if (sata_device_no >= CONFIG_SYS_SATA_MAX_DEVICE) { |
1355 | printf("Unknown SATA(%d) device for fastboot\n", | 1355 | printf("Unknown SATA(%d) device for fastboot\n", |
1356 | sata_device_no); | 1356 | sata_device_no); |
1357 | return -1; | 1357 | return -1; |
1358 | } | 1358 | } |
1359 | dev_desc = sata_get_dev(sata_device_no); | 1359 | dev_desc = sata_get_dev(sata_device_no); |
1360 | #else /*! CONFIG_CMD_SATA*/ | 1360 | #else /*! CONFIG_CMD_SATA*/ |
1361 | puts("SATA isn't buildin\n"); | 1361 | puts("SATA isn't buildin\n"); |
1362 | return -1; | 1362 | return -1; |
1363 | #endif /*! CONFIG_CMD_SATA*/ | 1363 | #endif /*! CONFIG_CMD_SATA*/ |
1364 | } else if (fastboot_devinfo.type == DEV_MMC) { | 1364 | } else if (fastboot_devinfo.type == DEV_MMC) { |
1365 | int mmc_no = 0; | 1365 | int mmc_no = 0; |
1366 | mmc_no = fastboot_devinfo.dev_id; | 1366 | mmc_no = fastboot_devinfo.dev_id; |
1367 | 1367 | ||
1368 | printf("flash target is MMC:%d\n", mmc_no); | 1368 | printf("flash target is MMC:%d\n", mmc_no); |
1369 | mmc = find_mmc_device(mmc_no); | 1369 | mmc = find_mmc_device(mmc_no); |
1370 | 1370 | ||
1371 | if (mmc == NULL) { | 1371 | if (mmc == NULL) { |
1372 | printf("invalid mmc device %d\n", mmc_no); | 1372 | printf("invalid mmc device %d\n", mmc_no); |
1373 | return -1; | 1373 | return -1; |
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | /* Force to init mmc */ | 1376 | /* Force to init mmc */ |
1377 | mmc->has_init = 0; | 1377 | mmc->has_init = 0; |
1378 | if (mmc_init(mmc)) | 1378 | if (mmc_init(mmc)) |
1379 | printf("MMC card init failed!\n"); | 1379 | printf("MMC card init failed!\n"); |
1380 | 1380 | ||
1381 | dev_desc = blk_get_dev("mmc", mmc_no); | 1381 | dev_desc = blk_get_dev("mmc", mmc_no); |
1382 | if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { | 1382 | if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { |
1383 | printf("** Block device MMC %d not supported\n", | 1383 | printf("** Block device MMC %d not supported\n", |
1384 | mmc_no); | 1384 | mmc_no); |
1385 | return -1; | 1385 | return -1; |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | /* multiple boot paritions for eMMC 4.3 later */ | 1388 | /* multiple boot paritions for eMMC 4.3 later */ |
1389 | if (mmc->part_config != MMCPART_NOAVAILABLE) { | 1389 | if (mmc->part_config != MMCPART_NOAVAILABLE) { |
1390 | boot_partition = FASTBOOT_MMC_BOOT_PARTITION_ID; | 1390 | boot_partition = FASTBOOT_MMC_BOOT_PARTITION_ID; |
1391 | user_partition = FASTBOOT_MMC_USER_PARTITION_ID; | 1391 | user_partition = FASTBOOT_MMC_USER_PARTITION_ID; |
1392 | } | 1392 | } |
1393 | } else { | 1393 | } else { |
1394 | printf("Can't setup partition table on this device %d\n", | 1394 | printf("Can't setup partition table on this device %d\n", |
1395 | fastboot_devinfo.type); | 1395 | fastboot_devinfo.type); |
1396 | return -1; | 1396 | return -1; |
1397 | } | 1397 | } |
1398 | 1398 | ||
1399 | memset((char *)ptable, 0, | 1399 | memset((char *)ptable, 0, |
1400 | sizeof(struct fastboot_ptentry) * (MAX_PTN)); | 1400 | sizeof(struct fastboot_ptentry) * (MAX_PTN)); |
1401 | /* GPT */ | 1401 | /* GPT */ |
1402 | strcpy(ptable[PTN_GPT_INDEX].name, FASTBOOT_PARTITION_GPT); | 1402 | strcpy(ptable[PTN_GPT_INDEX].name, FASTBOOT_PARTITION_GPT); |
1403 | ptable[PTN_GPT_INDEX].start = ANDROID_GPT_OFFSET / dev_desc->blksz; | 1403 | ptable[PTN_GPT_INDEX].start = ANDROID_GPT_OFFSET / dev_desc->blksz; |
1404 | ptable[PTN_GPT_INDEX].length = ANDROID_GPT_SIZE / dev_desc->blksz; | 1404 | ptable[PTN_GPT_INDEX].length = ANDROID_GPT_SIZE / dev_desc->blksz; |
1405 | ptable[PTN_GPT_INDEX].partition_id = user_partition; | 1405 | ptable[PTN_GPT_INDEX].partition_id = user_partition; |
1406 | ptable[PTN_GPT_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE; | 1406 | ptable[PTN_GPT_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE; |
1407 | strcpy(ptable[PTN_GPT_INDEX].fstype, "raw"); | 1407 | strcpy(ptable[PTN_GPT_INDEX].fstype, "raw"); |
1408 | 1408 | ||
1409 | #ifndef CONFIG_ARM64 | 1409 | #ifndef CONFIG_ARM64 |
1410 | /* Trusty OS */ | 1410 | /* Trusty OS */ |
1411 | strcpy(ptable[PTN_TEE_INDEX].name, FASTBOOT_PARTITION_TEE); | 1411 | strcpy(ptable[PTN_TEE_INDEX].name, FASTBOOT_PARTITION_TEE); |
1412 | ptable[PTN_TEE_INDEX].start = 0; | 1412 | ptable[PTN_TEE_INDEX].start = 0; |
1413 | ptable[PTN_TEE_INDEX].length = TRUSTY_OS_MMC_BLKS; | 1413 | ptable[PTN_TEE_INDEX].length = TRUSTY_OS_MMC_BLKS; |
1414 | ptable[PTN_TEE_INDEX].partition_id = TEE_HWPARTITION_ID; | 1414 | ptable[PTN_TEE_INDEX].partition_id = TEE_HWPARTITION_ID; |
1415 | strcpy(ptable[PTN_TEE_INDEX].fstype, "raw"); | 1415 | strcpy(ptable[PTN_TEE_INDEX].fstype, "raw"); |
1416 | #endif | 1416 | #endif |
1417 | 1417 | ||
1418 | /* Add m4_os partition if we support mcu firmware image flash */ | 1418 | /* Add m4_os partition if we support mcu firmware image flash */ |
1419 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | 1419 | #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT |
1420 | strcpy(ptable[PTN_M4_OS_INDEX].name, FASTBOOT_MCU_FIRMWARE_PARTITION); | 1420 | strcpy(ptable[PTN_M4_OS_INDEX].name, FASTBOOT_MCU_FIRMWARE_PARTITION); |
1421 | ptable[PTN_M4_OS_INDEX].start = ANDROID_MCU_FIRMWARE_START / dev_desc->blksz; | 1421 | ptable[PTN_M4_OS_INDEX].start = ANDROID_MCU_FIRMWARE_START / dev_desc->blksz; |
1422 | ptable[PTN_M4_OS_INDEX].length = ANDROID_MCU_FIRMWARE_SIZE / dev_desc->blksz; | 1422 | ptable[PTN_M4_OS_INDEX].length = ANDROID_MCU_FIRMWARE_SIZE / dev_desc->blksz; |
1423 | ptable[PTN_M4_OS_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE; | 1423 | ptable[PTN_M4_OS_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE; |
1424 | ptable[PTN_M4_OS_INDEX].partition_id = user_partition; | 1424 | ptable[PTN_M4_OS_INDEX].partition_id = user_partition; |
1425 | strcpy(ptable[PTN_M4_OS_INDEX].fstype, "raw"); | 1425 | strcpy(ptable[PTN_M4_OS_INDEX].fstype, "raw"); |
1426 | #endif | 1426 | #endif |
1427 | 1427 | ||
1428 | strcpy(ptable[PTN_ALL_INDEX].name, FASTBOOT_PARTITION_ALL); | 1428 | strcpy(ptable[PTN_ALL_INDEX].name, FASTBOOT_PARTITION_ALL); |
1429 | ptable[PTN_ALL_INDEX].start = 0; | 1429 | ptable[PTN_ALL_INDEX].start = 0; |
1430 | ptable[PTN_ALL_INDEX].length = dev_desc->lba; | 1430 | ptable[PTN_ALL_INDEX].length = dev_desc->lba; |
1431 | ptable[PTN_ALL_INDEX].partition_id = user_partition; | 1431 | ptable[PTN_ALL_INDEX].partition_id = user_partition; |
1432 | strcpy(ptable[PTN_ALL_INDEX].fstype, "device"); | 1432 | strcpy(ptable[PTN_ALL_INDEX].fstype, "device"); |
1433 | 1433 | ||
1434 | /* Bootloader */ | 1434 | /* Bootloader */ |
1435 | strcpy(ptable[PTN_BOOTLOADER_INDEX].name, FASTBOOT_PARTITION_BOOTLOADER); | 1435 | strcpy(ptable[PTN_BOOTLOADER_INDEX].name, FASTBOOT_PARTITION_BOOTLOADER); |
1436 | ptable[PTN_BOOTLOADER_INDEX].start = | 1436 | ptable[PTN_BOOTLOADER_INDEX].start = |
1437 | bootloader_mmc_offset() / dev_desc->blksz; | 1437 | bootloader_mmc_offset() / dev_desc->blksz; |
1438 | ptable[PTN_BOOTLOADER_INDEX].length = | 1438 | ptable[PTN_BOOTLOADER_INDEX].length = |
1439 | ANDROID_BOOTLOADER_SIZE / dev_desc->blksz; | 1439 | ANDROID_BOOTLOADER_SIZE / dev_desc->blksz; |
1440 | ptable[PTN_BOOTLOADER_INDEX].partition_id = boot_partition; | 1440 | ptable[PTN_BOOTLOADER_INDEX].partition_id = boot_partition; |
1441 | ptable[PTN_BOOTLOADER_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE; | 1441 | ptable[PTN_BOOTLOADER_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE; |
1442 | strcpy(ptable[PTN_BOOTLOADER_INDEX].fstype, "raw"); | 1442 | strcpy(ptable[PTN_BOOTLOADER_INDEX].fstype, "raw"); |
1443 | 1443 | ||
1444 | int tbl_idx; | 1444 | int tbl_idx; |
1445 | int part_idx = 1; | 1445 | int part_idx = 1; |
1446 | int ret; | 1446 | int ret; |
1447 | for (tbl_idx = PTN_BOOTLOADER_INDEX + 1; tbl_idx < MAX_PTN; tbl_idx++) { | 1447 | for (tbl_idx = PTN_BOOTLOADER_INDEX + 1; tbl_idx < MAX_PTN; tbl_idx++) { |
1448 | ret = _fastboot_parts_add_ptable_entry(tbl_idx, | 1448 | ret = _fastboot_parts_add_ptable_entry(tbl_idx, |
1449 | part_idx++, | 1449 | part_idx++, |
1450 | user_partition, | 1450 | user_partition, |
1451 | NULL, | 1451 | NULL, |
1452 | NULL, | 1452 | NULL, |
1453 | dev_desc, ptable); | 1453 | dev_desc, ptable); |
1454 | if (ret) | 1454 | if (ret) |
1455 | break; | 1455 | break; |
1456 | } | 1456 | } |
1457 | for (i = 0; i < tbl_idx; i++) | 1457 | for (i = 0; i < tbl_idx; i++) |
1458 | fastboot_flash_add_ptn(&ptable[i]); | 1458 | fastboot_flash_add_ptn(&ptable[i]); |
1459 | 1459 | ||
1460 | return 0; | 1460 | return 0; |
1461 | } | 1461 | } |
1462 | #endif /*CONFIG_FASTBOOT_STORAGE_SATA || CONFIG_FASTBOOT_STORAGE_MMC*/ | 1462 | #endif /*CONFIG_FASTBOOT_STORAGE_SATA || CONFIG_FASTBOOT_STORAGE_MMC*/ |
1463 | 1463 | ||
1464 | static void _fastboot_load_partitions(void) | 1464 | static void _fastboot_load_partitions(void) |
1465 | { | 1465 | { |
1466 | g_pcount = 0; | 1466 | g_pcount = 0; |
1467 | #if defined(CONFIG_FASTBOOT_STORAGE_SATA) \ | 1467 | #if defined(CONFIG_FASTBOOT_STORAGE_SATA) \ |
1468 | || defined(CONFIG_FASTBOOT_STORAGE_MMC) | 1468 | || defined(CONFIG_FASTBOOT_STORAGE_MMC) |
1469 | _fastboot_parts_load_from_ptable(); | 1469 | _fastboot_parts_load_from_ptable(); |
1470 | #endif | 1470 | #endif |
1471 | } | 1471 | } |
1472 | 1472 | ||
1473 | /* | 1473 | /* |
1474 | * Android style flash utilties */ | 1474 | * Android style flash utilties */ |
1475 | void fastboot_flash_add_ptn(struct fastboot_ptentry *ptn) | 1475 | void fastboot_flash_add_ptn(struct fastboot_ptentry *ptn) |
1476 | { | 1476 | { |
1477 | if (g_pcount < MAX_PTN) { | 1477 | if (g_pcount < MAX_PTN) { |
1478 | memcpy(g_ptable + g_pcount, ptn, sizeof(struct fastboot_ptentry)); | 1478 | memcpy(g_ptable + g_pcount, ptn, sizeof(struct fastboot_ptentry)); |
1479 | g_pcount++; | 1479 | g_pcount++; |
1480 | } | 1480 | } |
1481 | } | 1481 | } |
1482 | 1482 | ||
1483 | void fastboot_flash_dump_ptn(void) | 1483 | void fastboot_flash_dump_ptn(void) |
1484 | { | 1484 | { |
1485 | unsigned int n; | 1485 | unsigned int n; |
1486 | for (n = 0; n < g_pcount; n++) { | 1486 | for (n = 0; n < g_pcount; n++) { |
1487 | struct fastboot_ptentry *ptn = g_ptable + n; | 1487 | struct fastboot_ptentry *ptn = g_ptable + n; |
1488 | printf("idx %d, ptn %d name='%s' start=%d len=%d\n", | 1488 | printf("idx %d, ptn %d name='%s' start=%d len=%d\n", |
1489 | n, ptn->partition_index, ptn->name, ptn->start, ptn->length); | 1489 | n, ptn->partition_index, ptn->name, ptn->start, ptn->length); |
1490 | } | 1490 | } |
1491 | } | 1491 | } |
1492 | 1492 | ||
1493 | 1493 | ||
1494 | struct fastboot_ptentry *fastboot_flash_find_ptn(const char *name) | 1494 | struct fastboot_ptentry *fastboot_flash_find_ptn(const char *name) |
1495 | { | 1495 | { |
1496 | unsigned int n; | 1496 | unsigned int n; |
1497 | 1497 | ||
1498 | for (n = 0; n < g_pcount; n++) { | 1498 | for (n = 0; n < g_pcount; n++) { |
1499 | /* Make sure a substring is not accepted */ | 1499 | /* Make sure a substring is not accepted */ |
1500 | if (strlen(name) == strlen(g_ptable[n].name)) { | 1500 | if (strlen(name) == strlen(g_ptable[n].name)) { |
1501 | if (0 == strcmp(g_ptable[n].name, name)) | 1501 | if (0 == strcmp(g_ptable[n].name, name)) |
1502 | return g_ptable + n; | 1502 | return g_ptable + n; |
1503 | } | 1503 | } |
1504 | } | 1504 | } |
1505 | 1505 | ||
1506 | return 0; | 1506 | return 0; |
1507 | } | 1507 | } |
1508 | 1508 | ||
1509 | int fastboot_flash_find_index(const char *name) | 1509 | int fastboot_flash_find_index(const char *name) |
1510 | { | 1510 | { |
1511 | struct fastboot_ptentry *ptentry = fastboot_flash_find_ptn(name); | 1511 | struct fastboot_ptentry *ptentry = fastboot_flash_find_ptn(name); |
1512 | if (ptentry == NULL) { | 1512 | if (ptentry == NULL) { |
1513 | printf("cannot get the partion info for %s\n",name); | 1513 | printf("cannot get the partion info for %s\n",name); |
1514 | fastboot_flash_dump_ptn(); | 1514 | fastboot_flash_dump_ptn(); |
1515 | return -1; | 1515 | return -1; |
1516 | } | 1516 | } |
1517 | return ptentry->partition_index; | 1517 | return ptentry->partition_index; |
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | struct fastboot_ptentry *fastboot_flash_get_ptn(unsigned int n) | 1520 | struct fastboot_ptentry *fastboot_flash_get_ptn(unsigned int n) |
1521 | { | 1521 | { |
1522 | if (n < g_pcount) | 1522 | if (n < g_pcount) |
1523 | return g_ptable + n; | 1523 | return g_ptable + n; |
1524 | else | 1524 | else |
1525 | return 0; | 1525 | return 0; |
1526 | } | 1526 | } |
1527 | 1527 | ||
1528 | unsigned int fastboot_flash_get_ptn_count(void) | 1528 | unsigned int fastboot_flash_get_ptn_count(void) |
1529 | { | 1529 | { |
1530 | return g_pcount; | 1530 | return g_pcount; |
1531 | } | 1531 | } |
1532 | 1532 | ||
1533 | #ifdef CONFIG_FSL_FASTBOOT | 1533 | #ifdef CONFIG_FSL_FASTBOOT |
1534 | void board_fastboot_setup(void) | 1534 | void board_fastboot_setup(void) |
1535 | { | 1535 | { |
1536 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) | 1536 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) |
1537 | static char boot_dev_part[32]; | 1537 | static char boot_dev_part[32]; |
1538 | u32 dev_no; | 1538 | u32 dev_no; |
1539 | #endif | 1539 | #endif |
1540 | switch (get_boot_device()) { | 1540 | switch (get_boot_device()) { |
1541 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) | 1541 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) |
1542 | case SD1_BOOT: | 1542 | case SD1_BOOT: |
1543 | case SD2_BOOT: | 1543 | case SD2_BOOT: |
1544 | case SD3_BOOT: | 1544 | case SD3_BOOT: |
1545 | case SD4_BOOT: | 1545 | case SD4_BOOT: |
1546 | case MMC1_BOOT: | 1546 | case MMC1_BOOT: |
1547 | case MMC2_BOOT: | 1547 | case MMC2_BOOT: |
1548 | case MMC3_BOOT: | 1548 | case MMC3_BOOT: |
1549 | case MMC4_BOOT: | 1549 | case MMC4_BOOT: |
1550 | dev_no = mmc_get_env_dev(); | 1550 | dev_no = mmc_get_env_dev(); |
1551 | sprintf(boot_dev_part,"mmc%d",dev_no); | 1551 | sprintf(boot_dev_part,"mmc%d",dev_no); |
1552 | if (!env_get("fastboot_dev")) | 1552 | if (!env_get("fastboot_dev")) |
1553 | env_set("fastboot_dev", boot_dev_part); | 1553 | env_set("fastboot_dev", boot_dev_part); |
1554 | sprintf(boot_dev_part, "boota mmc%d", dev_no); | 1554 | sprintf(boot_dev_part, "boota mmc%d", dev_no); |
1555 | if (!env_get("bootcmd")) | 1555 | if (!env_get("bootcmd")) |
1556 | env_set("bootcmd", boot_dev_part); | 1556 | env_set("bootcmd", boot_dev_part); |
1557 | break; | 1557 | break; |
1558 | case USB_BOOT: | 1558 | case USB_BOOT: |
1559 | printf("Detect USB boot. Will enter fastboot mode!\n"); | 1559 | printf("Detect USB boot. Will enter fastboot mode!\n"); |
1560 | if (!env_get("bootcmd")) | 1560 | if (!env_get("bootcmd")) |
1561 | env_set("bootcmd", "fastboot 0"); | 1561 | env_set("bootcmd", "fastboot 0"); |
1562 | break; | 1562 | break; |
1563 | #endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ | 1563 | #endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ |
1564 | default: | 1564 | default: |
1565 | if (!env_get("bootcmd")) | 1565 | if (!env_get("bootcmd")) |
1566 | printf("unsupported boot devices\n"); | 1566 | printf("unsupported boot devices\n"); |
1567 | break; | 1567 | break; |
1568 | } | 1568 | } |
1569 | 1569 | ||
1570 | /* add soc type into bootargs */ | 1570 | /* add soc type into bootargs */ |
1571 | if (is_mx6dqp()) { | 1571 | if (is_mx6dqp()) { |
1572 | if (!env_get("soc_type")) | 1572 | if (!env_get("soc_type")) |
1573 | env_set("soc_type", "imx6qp"); | 1573 | env_set("soc_type", "imx6qp"); |
1574 | } else if (is_mx6dq()) { | 1574 | } else if (is_mx6dq()) { |
1575 | if (!env_get("soc_type")) | 1575 | if (!env_get("soc_type")) |
1576 | env_set("soc_type", "imx6q"); | 1576 | env_set("soc_type", "imx6q"); |
1577 | } else if (is_mx6sdl()) { | 1577 | } else if (is_mx6sdl()) { |
1578 | if (!env_get("soc_type")) | 1578 | if (!env_get("soc_type")) |
1579 | env_set("soc_type", "imx6dl"); | 1579 | env_set("soc_type", "imx6dl"); |
1580 | } else if (is_mx6sx()) { | 1580 | } else if (is_mx6sx()) { |
1581 | if (!env_get("soc_type")) | 1581 | if (!env_get("soc_type")) |
1582 | env_set("soc_type", "imx6sx"); | 1582 | env_set("soc_type", "imx6sx"); |
1583 | } else if (is_mx6sl()) { | 1583 | } else if (is_mx6sl()) { |
1584 | if (!env_get("soc_type")) | 1584 | if (!env_get("soc_type")) |
1585 | env_set("soc_type", "imx6sl"); | 1585 | env_set("soc_type", "imx6sl"); |
1586 | } else if (is_mx6ul()) { | 1586 | } else if (is_mx6ul()) { |
1587 | if (!env_get("soc_type")) | 1587 | if (!env_get("soc_type")) |
1588 | env_set("soc_type", "imx6ul"); | 1588 | env_set("soc_type", "imx6ul"); |
1589 | } else if (is_mx7()) { | 1589 | } else if (is_mx7()) { |
1590 | if (!env_get("soc_type")) | 1590 | if (!env_get("soc_type")) |
1591 | env_set("soc_type", "imx7d"); | 1591 | env_set("soc_type", "imx7d"); |
1592 | } else if (is_mx7ulp()) { | 1592 | } else if (is_mx7ulp()) { |
1593 | if (!env_get("soc_type")) | 1593 | if (!env_get("soc_type")) |
1594 | env_set("soc_type", "imx7ulp"); | 1594 | env_set("soc_type", "imx7ulp"); |
1595 | } else if (is_imx8qm()) { | 1595 | } else if (is_imx8qm()) { |
1596 | if (!env_get("soc_type")) | 1596 | if (!env_get("soc_type")) |
1597 | env_set("soc_type", "imx8qm"); | 1597 | env_set("soc_type", "imx8qm"); |
1598 | } else if (is_imx8qxp()) { | 1598 | } else if (is_imx8qxp()) { |
1599 | if (!env_get("soc_type")) | 1599 | if (!env_get("soc_type")) |
1600 | env_set("soc_type", "imx8qxp"); | 1600 | env_set("soc_type", "imx8qxp"); |
1601 | } else if (is_imx8mq()) { | 1601 | } else if (is_imx8mq()) { |
1602 | if (!env_get("soc_type")) | 1602 | if (!env_get("soc_type")) |
1603 | env_set("soc_type", "imx8mq"); | 1603 | env_set("soc_type", "imx8mq"); |
1604 | } else if (is_imx8mm()) { | 1604 | } else if (is_imx8mm()) { |
1605 | if (!env_get("soc_type")) | 1605 | if (!env_get("soc_type")) |
1606 | env_set("soc_type", "imx8mm"); | 1606 | env_set("soc_type", "imx8mm"); |
1607 | } | 1607 | } |
1608 | } | 1608 | } |
1609 | 1609 | ||
1610 | #ifdef CONFIG_ANDROID_RECOVERY | 1610 | #ifdef CONFIG_ANDROID_RECOVERY |
1611 | void board_recovery_setup(void) | 1611 | void board_recovery_setup(void) |
1612 | { | 1612 | { |
1613 | /* boot from current mmc with avb verify */ | 1613 | /* boot from current mmc with avb verify */ |
1614 | #ifdef CONFIG_AVB_SUPPORT | 1614 | #ifdef CONFIG_AVB_SUPPORT |
1615 | if (!env_get("bootcmd_android_recovery")) | 1615 | if (!env_get("bootcmd_android_recovery")) |
1616 | env_set("bootcmd_android_recovery", "boota recovery"); | 1616 | env_set("bootcmd_android_recovery", "boota recovery"); |
1617 | #else | 1617 | #else |
1618 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) | 1618 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) |
1619 | static char boot_dev_part[32]; | 1619 | static char boot_dev_part[32]; |
1620 | u32 dev_no; | 1620 | u32 dev_no; |
1621 | #endif | 1621 | #endif |
1622 | int bootdev = get_boot_device(); | 1622 | int bootdev = get_boot_device(); |
1623 | switch (bootdev) { | 1623 | switch (bootdev) { |
1624 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) | 1624 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) |
1625 | case SD1_BOOT: | 1625 | case SD1_BOOT: |
1626 | case SD2_BOOT: | 1626 | case SD2_BOOT: |
1627 | case SD3_BOOT: | 1627 | case SD3_BOOT: |
1628 | case SD4_BOOT: | 1628 | case SD4_BOOT: |
1629 | case MMC1_BOOT: | 1629 | case MMC1_BOOT: |
1630 | case MMC2_BOOT: | 1630 | case MMC2_BOOT: |
1631 | case MMC3_BOOT: | 1631 | case MMC3_BOOT: |
1632 | case MMC4_BOOT: | 1632 | case MMC4_BOOT: |
1633 | dev_no = mmc_get_env_dev(); | 1633 | dev_no = mmc_get_env_dev(); |
1634 | sprintf(boot_dev_part,"boota mmc%d recovery",dev_no); | 1634 | sprintf(boot_dev_part,"boota mmc%d recovery",dev_no); |
1635 | if (!env_get("bootcmd_android_recovery")) | 1635 | if (!env_get("bootcmd_android_recovery")) |
1636 | env_set("bootcmd_android_recovery", boot_dev_part); | 1636 | env_set("bootcmd_android_recovery", boot_dev_part); |
1637 | break; | 1637 | break; |
1638 | #endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ | 1638 | #endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ |
1639 | default: | 1639 | default: |
1640 | printf("Unsupported bootup device for recovery: dev: %d\n", | 1640 | printf("Unsupported bootup device for recovery: dev: %d\n", |
1641 | bootdev); | 1641 | bootdev); |
1642 | return; | 1642 | return; |
1643 | } | 1643 | } |
1644 | #endif /* CONFIG_AVB_SUPPORT */ | 1644 | #endif /* CONFIG_AVB_SUPPORT */ |
1645 | printf("setup env for recovery..\n"); | 1645 | printf("setup env for recovery..\n"); |
1646 | env_set("bootcmd", env_get("bootcmd_android_recovery")); | 1646 | env_set("bootcmd", env_get("bootcmd_android_recovery")); |
1647 | } | 1647 | } |
1648 | #endif /*CONFIG_ANDROID_RECOVERY*/ | 1648 | #endif /*CONFIG_ANDROID_RECOVERY*/ |
1649 | #endif /*CONFIG_FSL_FASTBOOT*/ | 1649 | #endif /*CONFIG_FSL_FASTBOOT*/ |
1650 | 1650 | ||
1651 | #if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC) | 1651 | #if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC) |
1652 | static AvbABOps fsl_avb_ab_ops = { | 1652 | static AvbABOps fsl_avb_ab_ops = { |
1653 | .read_ab_metadata = fsl_read_ab_metadata, | 1653 | .read_ab_metadata = fsl_read_ab_metadata, |
1654 | .write_ab_metadata = fsl_write_ab_metadata, | 1654 | .write_ab_metadata = fsl_write_ab_metadata, |
1655 | .ops = NULL | 1655 | .ops = NULL |
1656 | }; | 1656 | }; |
1657 | #ifdef CONFIG_AVB_ATX | 1657 | #ifdef CONFIG_AVB_ATX |
1658 | static AvbAtxOps fsl_avb_atx_ops = { | 1658 | static AvbAtxOps fsl_avb_atx_ops = { |
1659 | .ops = NULL, | 1659 | .ops = NULL, |
1660 | .read_permanent_attributes = fsl_read_permanent_attributes, | 1660 | .read_permanent_attributes = fsl_read_permanent_attributes, |
1661 | .read_permanent_attributes_hash = fsl_read_permanent_attributes_hash, | 1661 | .read_permanent_attributes_hash = fsl_read_permanent_attributes_hash, |
1662 | #ifdef CONFIG_IMX_TRUSTY_OS | 1662 | #ifdef CONFIG_IMX_TRUSTY_OS |
1663 | .set_key_version = fsl_write_rollback_index_rpmb, | 1663 | .set_key_version = fsl_write_rollback_index_rpmb, |
1664 | #else | 1664 | #else |
1665 | .set_key_version = fsl_set_key_version, | 1665 | .set_key_version = fsl_set_key_version, |
1666 | #endif | 1666 | #endif |
1667 | .get_random = fsl_get_random | 1667 | .get_random = fsl_get_random |
1668 | }; | 1668 | }; |
1669 | #endif | 1669 | #endif |
1670 | static AvbOps fsl_avb_ops = { | 1670 | static AvbOps fsl_avb_ops = { |
1671 | .ab_ops = &fsl_avb_ab_ops, | 1671 | .ab_ops = &fsl_avb_ab_ops, |
1672 | #ifdef CONFIG_AVB_ATX | 1672 | #ifdef CONFIG_AVB_ATX |
1673 | .atx_ops = &fsl_avb_atx_ops, | 1673 | .atx_ops = &fsl_avb_atx_ops, |
1674 | #endif | 1674 | #endif |
1675 | .read_from_partition = fsl_read_from_partition_multi, | 1675 | .read_from_partition = fsl_read_from_partition_multi, |
1676 | .write_to_partition = fsl_write_to_partition, | 1676 | .write_to_partition = fsl_write_to_partition, |
1677 | #ifdef CONFIG_AVB_ATX | 1677 | #ifdef CONFIG_AVB_ATX |
1678 | .validate_vbmeta_public_key = avb_atx_validate_vbmeta_public_key, | 1678 | .validate_vbmeta_public_key = avb_atx_validate_vbmeta_public_key, |
1679 | #else | 1679 | #else |
1680 | .validate_vbmeta_public_key = fsl_validate_vbmeta_public_key_rpmb, | 1680 | .validate_vbmeta_public_key = fsl_validate_vbmeta_public_key_rpmb, |
1681 | #endif | 1681 | #endif |
1682 | .read_rollback_index = fsl_read_rollback_index_rpmb, | 1682 | .read_rollback_index = fsl_read_rollback_index_rpmb, |
1683 | .write_rollback_index = fsl_write_rollback_index_rpmb, | 1683 | .write_rollback_index = fsl_write_rollback_index_rpmb, |
1684 | .read_is_device_unlocked = fsl_read_is_device_unlocked, | 1684 | .read_is_device_unlocked = fsl_read_is_device_unlocked, |
1685 | .get_unique_guid_for_partition = fsl_get_unique_guid_for_partition, | 1685 | .get_unique_guid_for_partition = fsl_get_unique_guid_for_partition, |
1686 | .get_size_of_partition = fsl_get_size_of_partition | 1686 | .get_size_of_partition = fsl_get_size_of_partition |
1687 | }; | 1687 | }; |
1688 | #endif | 1688 | #endif |
1689 | 1689 | ||
1690 | #ifdef CONFIG_IMX_TRUSTY_OS | 1690 | #ifdef CONFIG_IMX_TRUSTY_OS |
1691 | #ifdef CONFIG_ARM64 | 1691 | #ifdef CONFIG_ARM64 |
1692 | void tee_setup(void) | 1692 | void tee_setup(void) |
1693 | { | 1693 | { |
1694 | trusty_ipc_init(); | 1694 | trusty_ipc_init(); |
1695 | } | 1695 | } |
1696 | 1696 | ||
1697 | #else | 1697 | #else |
1698 | extern bool tos_flashed; | 1698 | extern bool tos_flashed; |
1699 | 1699 | ||
1700 | void tee_setup(void) | 1700 | void tee_setup(void) |
1701 | { | 1701 | { |
1702 | /* load tee from boot1 of eMMC. */ | 1702 | /* load tee from boot1 of eMMC. */ |
1703 | int mmcc = mmc_get_env_dev(); | 1703 | int mmcc = mmc_get_env_dev(); |
1704 | struct blk_desc *dev_desc = NULL; | 1704 | struct blk_desc *dev_desc = NULL; |
1705 | 1705 | ||
1706 | struct mmc *mmc; | 1706 | struct mmc *mmc; |
1707 | mmc = find_mmc_device(mmcc); | 1707 | mmc = find_mmc_device(mmcc); |
1708 | if (!mmc) { | 1708 | if (!mmc) { |
1709 | printf("boota: cannot find '%d' mmc device\n", mmcc); | 1709 | printf("boota: cannot find '%d' mmc device\n", mmcc); |
1710 | goto fail; | 1710 | goto fail; |
1711 | } | 1711 | } |
1712 | 1712 | ||
1713 | dev_desc = blk_get_dev("mmc", mmcc); | 1713 | dev_desc = blk_get_dev("mmc", mmcc); |
1714 | if (NULL == dev_desc) { | 1714 | if (NULL == dev_desc) { |
1715 | printf("** Block device MMC %d not supported\n", mmcc); | 1715 | printf("** Block device MMC %d not supported\n", mmcc); |
1716 | goto fail; | 1716 | goto fail; |
1717 | } | 1717 | } |
1718 | 1718 | ||
1719 | /* below was i.MX mmc operation code */ | 1719 | /* below was i.MX mmc operation code */ |
1720 | if (mmc_init(mmc)) { | 1720 | if (mmc_init(mmc)) { |
1721 | printf("mmc%d init failed\n", mmcc); | 1721 | printf("mmc%d init failed\n", mmcc); |
1722 | goto fail; | 1722 | goto fail; |
1723 | } | 1723 | } |
1724 | 1724 | ||
1725 | struct fastboot_ptentry *tee_pte; | 1725 | struct fastboot_ptentry *tee_pte; |
1726 | char *tee_ptn = FASTBOOT_PARTITION_TEE; | 1726 | char *tee_ptn = FASTBOOT_PARTITION_TEE; |
1727 | tee_pte = fastboot_flash_find_ptn(tee_ptn); | 1727 | tee_pte = fastboot_flash_find_ptn(tee_ptn); |
1728 | mmc_switch_part(mmc, TEE_HWPARTITION_ID); | 1728 | mmc_switch_part(mmc, TEE_HWPARTITION_ID); |
1729 | if (!tee_pte) { | 1729 | if (!tee_pte) { |
1730 | printf("boota: cannot find tee partition!\n"); | 1730 | printf("boota: cannot find tee partition!\n"); |
1731 | fastboot_flash_dump_ptn(); | 1731 | fastboot_flash_dump_ptn(); |
1732 | } | 1732 | } |
1733 | 1733 | ||
1734 | if (blk_dread(dev_desc, tee_pte->start, | 1734 | if (blk_dread(dev_desc, tee_pte->start, |
1735 | tee_pte->length, (void *)TRUSTY_OS_ENTRY) < 0) { | 1735 | tee_pte->length, (void *)TRUSTY_OS_ENTRY) < 0) { |
1736 | printf("Failed to load tee."); | 1736 | printf("Failed to load tee."); |
1737 | } | 1737 | } |
1738 | mmc_switch_part(mmc, FASTBOOT_MMC_USER_PARTITION_ID); | 1738 | mmc_switch_part(mmc, FASTBOOT_MMC_USER_PARTITION_ID); |
1739 | 1739 | ||
1740 | tos_flashed = false; | 1740 | tos_flashed = false; |
1741 | if(!valid_tos()) { | 1741 | if(!valid_tos()) { |
1742 | printf("TOS not flashed! Will enter TOS recovery mode. Everything will be wiped!\n"); | 1742 | printf("TOS not flashed! Will enter TOS recovery mode. Everything will be wiped!\n"); |
1743 | fastboot_wipe_all(); | 1743 | fastboot_wipe_all(); |
1744 | run_command("fastboot 0", 0); | 1744 | run_command("fastboot 0", 0); |
1745 | goto fail; | 1745 | goto fail; |
1746 | } | 1746 | } |
1747 | #ifdef NON_SECURE_FASTBOOT | 1747 | #ifdef NON_SECURE_FASTBOOT |
1748 | armv7_init_nonsec(); | 1748 | armv7_init_nonsec(); |
1749 | trusty_os_init(); | 1749 | trusty_os_init(); |
1750 | trusty_ipc_init(); | 1750 | trusty_ipc_init(); |
1751 | #endif | 1751 | #endif |
1752 | 1752 | ||
1753 | fail: | 1753 | fail: |
1754 | return; | 1754 | return; |
1755 | 1755 | ||
1756 | } | 1756 | } |
1757 | #endif /* CONFIG_ARM64 */ | 1757 | #endif /* CONFIG_ARM64 */ |
1758 | #endif /* CONFIG_IMX_TRUSTY_OS */ | 1758 | #endif /* CONFIG_IMX_TRUSTY_OS */ |
1759 | 1759 | ||
1760 | void fastboot_setup(void) | 1760 | void fastboot_setup(void) |
1761 | { | 1761 | { |
1762 | int sw, ret; | 1762 | int sw, ret; |
1763 | #ifdef CONFIG_USB_GADGET | 1763 | #ifdef CONFIG_USB_GADGET |
1764 | struct tag_serialnr serialnr; | 1764 | struct tag_serialnr serialnr; |
1765 | char serial[17]; | 1765 | char serial[17]; |
1766 | 1766 | ||
1767 | get_board_serial(&serialnr); | 1767 | get_board_serial(&serialnr); |
1768 | sprintf(serial, "%08x%08x", serialnr.high, serialnr.low); | 1768 | sprintf(serial, "%08x%08x", serialnr.high, serialnr.low); |
1769 | g_dnl_set_serialnumber(serial); | 1769 | g_dnl_set_serialnumber(serial); |
1770 | #endif | 1770 | #endif |
1771 | /*execute board relevant initilizations for preparing fastboot */ | 1771 | /*execute board relevant initilizations for preparing fastboot */ |
1772 | board_fastboot_setup(); | 1772 | board_fastboot_setup(); |
1773 | 1773 | ||
1774 | /*get the fastboot dev*/ | 1774 | /*get the fastboot dev*/ |
1775 | ret = _fastboot_setup_dev(&sw); | 1775 | ret = _fastboot_setup_dev(&sw); |
1776 | 1776 | ||
1777 | /*load partitions information for the fastboot dev*/ | 1777 | /*load partitions information for the fastboot dev*/ |
1778 | if (!ret && sw) | 1778 | if (!ret && sw) |
1779 | _fastboot_load_partitions(); | 1779 | _fastboot_load_partitions(); |
1780 | 1780 | ||
1781 | parameters_setup(); | 1781 | parameters_setup(); |
1782 | #ifdef CONFIG_AVB_SUPPORT | 1782 | #ifdef CONFIG_AVB_SUPPORT |
1783 | fsl_avb_ab_ops.ops = &fsl_avb_ops; | 1783 | fsl_avb_ab_ops.ops = &fsl_avb_ops; |
1784 | #ifdef CONFIG_AVB_ATX | 1784 | #ifdef CONFIG_AVB_ATX |
1785 | fsl_avb_atx_ops.ops = &fsl_avb_ops; | 1785 | fsl_avb_atx_ops.ops = &fsl_avb_ops; |
1786 | #endif | 1786 | #endif |
1787 | #endif | 1787 | #endif |
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | /* Write the bcb with fastboot bootloader commands */ | 1790 | /* Write the bcb with fastboot bootloader commands */ |
1791 | static void enable_fastboot_command(void) | 1791 | static void enable_fastboot_command(void) |
1792 | { | 1792 | { |
1793 | #ifdef CONFIG_BCB_SUPPORT | 1793 | #ifdef CONFIG_BCB_SUPPORT |
1794 | char fastboot_command[32] = {0}; | 1794 | char fastboot_command[32] = {0}; |
1795 | strncpy(fastboot_command, FASTBOOT_BCB_CMD, 31); | 1795 | strncpy(fastboot_command, FASTBOOT_BCB_CMD, 31); |
1796 | bcb_write_command(fastboot_command); | 1796 | bcb_write_command(fastboot_command); |
1797 | #endif | 1797 | #endif |
1798 | } | 1798 | } |
1799 | 1799 | ||
1800 | /* Get the Boot mode from BCB cmd or Key pressed */ | 1800 | /* Get the Boot mode from BCB cmd or Key pressed */ |
1801 | static FbBootMode fastboot_get_bootmode(void) | 1801 | static FbBootMode fastboot_get_bootmode(void) |
1802 | { | 1802 | { |
1803 | int boot_mode = BOOTMODE_NORMAL; | 1803 | int boot_mode = BOOTMODE_NORMAL; |
1804 | #ifdef CONFIG_ANDROID_RECOVERY | 1804 | #ifdef CONFIG_ANDROID_RECOVERY |
1805 | if(is_recovery_key_pressing()) { | 1805 | if(is_recovery_key_pressing()) { |
1806 | boot_mode = BOOTMODE_RECOVERY_KEY_PRESSED; | 1806 | boot_mode = BOOTMODE_RECOVERY_KEY_PRESSED; |
1807 | return boot_mode; | 1807 | return boot_mode; |
1808 | } | 1808 | } |
1809 | #endif | 1809 | #endif |
1810 | #ifdef CONFIG_BCB_SUPPORT | 1810 | #ifdef CONFIG_BCB_SUPPORT |
1811 | int ret = 0; | 1811 | int ret = 0; |
1812 | char command[32]; | 1812 | char command[32]; |
1813 | ret = bcb_read_command(command); | 1813 | ret = bcb_read_command(command); |
1814 | if (ret < 0) { | 1814 | if (ret < 0) { |
1815 | printf("read command failed\n"); | 1815 | printf("read command failed\n"); |
1816 | return boot_mode; | 1816 | return boot_mode; |
1817 | } | 1817 | } |
1818 | if (!strcmp(command, FASTBOOT_BCB_CMD)) { | 1818 | if (!strcmp(command, FASTBOOT_BCB_CMD)) { |
1819 | boot_mode = BOOTMODE_FASTBOOT_BCB_CMD; | 1819 | boot_mode = BOOTMODE_FASTBOOT_BCB_CMD; |
1820 | } | 1820 | } |
1821 | #ifdef CONFIG_ANDROID_RECOVERY | 1821 | #ifdef CONFIG_ANDROID_RECOVERY |
1822 | else if (!strcmp(command, RECOVERY_BCB_CMD)) { | 1822 | else if (!strcmp(command, RECOVERY_BCB_CMD)) { |
1823 | boot_mode = BOOTMODE_RECOVERY_BCB_CMD; | 1823 | boot_mode = BOOTMODE_RECOVERY_BCB_CMD; |
1824 | } | 1824 | } |
1825 | #endif | 1825 | #endif |
1826 | 1826 | ||
1827 | /* Clean the mode once its read out, | 1827 | /* Clean the mode once its read out, |
1828 | no matter what in the mode string */ | 1828 | no matter what in the mode string */ |
1829 | memset(command, 0, 32); | 1829 | memset(command, 0, 32); |
1830 | bcb_write_command(command); | 1830 | bcb_write_command(command); |
1831 | #endif | 1831 | #endif |
1832 | return boot_mode; | 1832 | return boot_mode; |
1833 | } | 1833 | } |
1834 | 1834 | ||
1835 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | 1835 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT |
1836 | /* Setup booargs for taking the system parition as ramdisk */ | 1836 | /* Setup booargs for taking the system parition as ramdisk */ |
1837 | static void fastboot_setup_system_boot_args(const char *slot, bool append_root) | 1837 | static void fastboot_setup_system_boot_args(const char *slot, bool append_root) |
1838 | { | 1838 | { |
1839 | const char *system_part_name = NULL; | 1839 | const char *system_part_name = NULL; |
1840 | if(slot == NULL) | 1840 | if(slot == NULL) |
1841 | return; | 1841 | return; |
1842 | if(!strncmp(slot, "_a", strlen("_a")) || !strncmp(slot, "boot_a", strlen("boot_a"))) { | 1842 | if(!strncmp(slot, "_a", strlen("_a")) || !strncmp(slot, "boot_a", strlen("boot_a"))) { |
1843 | system_part_name = FASTBOOT_PARTITION_SYSTEM_A; | 1843 | system_part_name = FASTBOOT_PARTITION_SYSTEM_A; |
1844 | } | 1844 | } |
1845 | else if(!strncmp(slot, "_b", strlen("_b")) || !strncmp(slot, "boot_b", strlen("boot_b"))) { | 1845 | else if(!strncmp(slot, "_b", strlen("_b")) || !strncmp(slot, "boot_b", strlen("boot_b"))) { |
1846 | system_part_name = FASTBOOT_PARTITION_SYSTEM_B; | 1846 | system_part_name = FASTBOOT_PARTITION_SYSTEM_B; |
1847 | } else { | 1847 | } else { |
1848 | printf("slot invalid!\n"); | 1848 | printf("slot invalid!\n"); |
1849 | return; | 1849 | return; |
1850 | } | 1850 | } |
1851 | struct fastboot_ptentry *ptentry = fastboot_flash_find_ptn(system_part_name); | 1851 | struct fastboot_ptentry *ptentry = fastboot_flash_find_ptn(system_part_name); |
1852 | if(ptentry != NULL) { | 1852 | if(ptentry != NULL) { |
1853 | char bootargs_3rd[ANDR_BOOT_ARGS_SIZE]; | 1853 | char bootargs_3rd[ANDR_BOOT_ARGS_SIZE]; |
1854 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) | 1854 | #if defined(CONFIG_FASTBOOT_STORAGE_MMC) |
1855 | if (append_root) { | 1855 | if (append_root) { |
1856 | u32 dev_no = mmc_map_to_kernel_blk(mmc_get_env_dev()); | 1856 | u32 dev_no = mmc_map_to_kernel_blk(mmc_get_env_dev()); |
1857 | sprintf(bootargs_3rd, "skip_initramfs root=/dev/mmcblk%dp%d", | 1857 | sprintf(bootargs_3rd, "skip_initramfs root=/dev/mmcblk%dp%d", |
1858 | dev_no, | 1858 | dev_no, |
1859 | ptentry->partition_index); | 1859 | ptentry->partition_index); |
1860 | } else { | 1860 | } else { |
1861 | sprintf(bootargs_3rd, "skip_initramfs"); | 1861 | sprintf(bootargs_3rd, "skip_initramfs"); |
1862 | } | 1862 | } |
1863 | strcat(bootargs_3rd, " rootwait"); | 1863 | strcat(bootargs_3rd, " rootwait"); |
1864 | env_set("bootargs_3rd", bootargs_3rd); | 1864 | env_set("bootargs_3rd", bootargs_3rd); |
1865 | #endif | 1865 | #endif |
1866 | } else { | 1866 | } else { |
1867 | printf("Can't find partition: %s\n", system_part_name); | 1867 | printf("Can't find partition: %s\n", system_part_name); |
1868 | fastboot_flash_dump_ptn(); | 1868 | fastboot_flash_dump_ptn(); |
1869 | } | 1869 | } |
1870 | } | 1870 | } |
1871 | #endif | 1871 | #endif |
1872 | /* export to lib_arm/board.c */ | 1872 | /* export to lib_arm/board.c */ |
1873 | void fastboot_run_bootmode(void) | 1873 | void fastboot_run_bootmode(void) |
1874 | { | 1874 | { |
1875 | FbBootMode boot_mode = fastboot_get_bootmode(); | 1875 | FbBootMode boot_mode = fastboot_get_bootmode(); |
1876 | switch(boot_mode){ | 1876 | switch(boot_mode){ |
1877 | case BOOTMODE_FASTBOOT_BCB_CMD: | 1877 | case BOOTMODE_FASTBOOT_BCB_CMD: |
1878 | /* Make the boot into fastboot mode*/ | 1878 | /* Make the boot into fastboot mode*/ |
1879 | puts("Fastboot: Got bootloader commands!\n"); | 1879 | puts("Fastboot: Got bootloader commands!\n"); |
1880 | run_command("fastboot 0", 0); | 1880 | run_command("fastboot 0", 0); |
1881 | break; | 1881 | break; |
1882 | #ifdef CONFIG_ANDROID_RECOVERY | 1882 | #ifdef CONFIG_ANDROID_RECOVERY |
1883 | case BOOTMODE_RECOVERY_BCB_CMD: | 1883 | case BOOTMODE_RECOVERY_BCB_CMD: |
1884 | case BOOTMODE_RECOVERY_KEY_PRESSED: | 1884 | case BOOTMODE_RECOVERY_KEY_PRESSED: |
1885 | /* Make the boot into recovery mode */ | 1885 | /* Make the boot into recovery mode */ |
1886 | puts("Fastboot: Got Recovery key pressing or recovery commands!\n"); | 1886 | puts("Fastboot: Got Recovery key pressing or recovery commands!\n"); |
1887 | board_recovery_setup(); | 1887 | board_recovery_setup(); |
1888 | break; | 1888 | break; |
1889 | #endif | 1889 | #endif |
1890 | default: | 1890 | default: |
1891 | /* skip special mode boot*/ | 1891 | /* skip special mode boot*/ |
1892 | puts("Fastboot: Normal\n"); | 1892 | puts("Fastboot: Normal\n"); |
1893 | break; | 1893 | break; |
1894 | } | 1894 | } |
1895 | } | 1895 | } |
1896 | 1896 | ||
1897 | #ifdef CONFIG_CMD_BOOTA | 1897 | #ifdef CONFIG_CMD_BOOTA |
1898 | /* Section for Android bootimage format support | 1898 | /* Section for Android bootimage format support |
1899 | * Refer: | 1899 | * Refer: |
1900 | * http://android.git.kernel.org/?p=platform/system/core.git;a=blob; | 1900 | * http://android.git.kernel.org/?p=platform/system/core.git;a=blob; |
1901 | * f=mkbootimg/bootimg.h | 1901 | * f=mkbootimg/bootimg.h |
1902 | */ | 1902 | */ |
1903 | 1903 | ||
1904 | void | 1904 | void |
1905 | bootimg_print_image_hdr(struct andr_img_hdr *hdr) | 1905 | bootimg_print_image_hdr(struct andr_img_hdr *hdr) |
1906 | { | 1906 | { |
1907 | #ifdef DEBUG | 1907 | #ifdef DEBUG |
1908 | int i; | 1908 | int i; |
1909 | printf(" Image magic: %s\n", hdr->magic); | 1909 | printf(" Image magic: %s\n", hdr->magic); |
1910 | 1910 | ||
1911 | printf(" kernel_size: 0x%x\n", hdr->kernel_size); | 1911 | printf(" kernel_size: 0x%x\n", hdr->kernel_size); |
1912 | printf(" kernel_addr: 0x%x\n", hdr->kernel_addr); | 1912 | printf(" kernel_addr: 0x%x\n", hdr->kernel_addr); |
1913 | 1913 | ||
1914 | printf(" rdisk_size: 0x%x\n", hdr->ramdisk_size); | 1914 | printf(" rdisk_size: 0x%x\n", hdr->ramdisk_size); |
1915 | printf(" rdisk_addr: 0x%x\n", hdr->ramdisk_addr); | 1915 | printf(" rdisk_addr: 0x%x\n", hdr->ramdisk_addr); |
1916 | 1916 | ||
1917 | printf(" second_size: 0x%x\n", hdr->second_size); | 1917 | printf(" second_size: 0x%x\n", hdr->second_size); |
1918 | printf(" second_addr: 0x%x\n", hdr->second_addr); | 1918 | printf(" second_addr: 0x%x\n", hdr->second_addr); |
1919 | 1919 | ||
1920 | printf(" tags_addr: 0x%x\n", hdr->tags_addr); | 1920 | printf(" tags_addr: 0x%x\n", hdr->tags_addr); |
1921 | printf(" page_size: 0x%x\n", hdr->page_size); | 1921 | printf(" page_size: 0x%x\n", hdr->page_size); |
1922 | 1922 | ||
1923 | printf(" name: %s\n", hdr->name); | 1923 | printf(" name: %s\n", hdr->name); |
1924 | printf(" cmdline: %s\n", hdr->cmdline); | 1924 | printf(" cmdline: %s\n", hdr->cmdline); |
1925 | 1925 | ||
1926 | for (i = 0; i < 8; i++) | 1926 | for (i = 0; i < 8; i++) |
1927 | printf(" id[%d]: 0x%x\n", i, hdr->id[i]); | 1927 | printf(" id[%d]: 0x%x\n", i, hdr->id[i]); |
1928 | #endif | 1928 | #endif |
1929 | } | 1929 | } |
1930 | 1930 | ||
1931 | #if !defined(CONFIG_AVB_SUPPORT) || !defined(CONFIG_MMC) | 1931 | #if !defined(CONFIG_AVB_SUPPORT) || !defined(CONFIG_MMC) |
1932 | static struct andr_img_hdr boothdr __aligned(ARCH_DMA_MINALIGN); | 1932 | static struct andr_img_hdr boothdr __aligned(ARCH_DMA_MINALIGN); |
1933 | #endif | 1933 | #endif |
1934 | 1934 | ||
1935 | #ifdef CONFIG_IMX_TRUSTY_OS | 1935 | #ifdef CONFIG_IMX_TRUSTY_OS |
1936 | #ifdef CONFIG_DUAL_BOOTLOADER | 1936 | #ifdef CONFIG_DUAL_BOOTLOADER |
1937 | static int sha256_concatenation(uint8_t *hash_buf, uint8_t *vbh, uint8_t *image_hash) | 1937 | static int sha256_concatenation(uint8_t *hash_buf, uint8_t *vbh, uint8_t *image_hash) |
1938 | { | 1938 | { |
1939 | if ((hash_buf == NULL) || (vbh == NULL) || (image_hash == NULL)) { | 1939 | if ((hash_buf == NULL) || (vbh == NULL) || (image_hash == NULL)) { |
1940 | printf("sha256_concatenation: null buffer found!\n"); | 1940 | printf("sha256_concatenation: null buffer found!\n"); |
1941 | return -1; | 1941 | return -1; |
1942 | } | 1942 | } |
1943 | 1943 | ||
1944 | memcpy(hash_buf, vbh, AVB_SHA256_DIGEST_SIZE); | 1944 | memcpy(hash_buf, vbh, AVB_SHA256_DIGEST_SIZE); |
1945 | memcpy(hash_buf + AVB_SHA256_DIGEST_SIZE, | 1945 | memcpy(hash_buf + AVB_SHA256_DIGEST_SIZE, |
1946 | image_hash, AVB_SHA256_DIGEST_SIZE); | 1946 | image_hash, AVB_SHA256_DIGEST_SIZE); |
1947 | sha256_csum_wd((unsigned char *)hash_buf, 2 * AVB_SHA256_DIGEST_SIZE, | 1947 | sha256_csum_wd((unsigned char *)hash_buf, 2 * AVB_SHA256_DIGEST_SIZE, |
1948 | (unsigned char *)vbh, CHUNKSZ_SHA256); | 1948 | (unsigned char *)vbh, CHUNKSZ_SHA256); |
1949 | 1949 | ||
1950 | return 0; | 1950 | return 0; |
1951 | } | 1951 | } |
1952 | 1952 | ||
1953 | /* Since we use fit format to organize the atf, tee, u-boot and u-boot dtb, | 1953 | /* Since we use fit format to organize the atf, tee, u-boot and u-boot dtb, |
1954 | * so calculate the hash of fit is enough. | 1954 | * so calculate the hash of fit is enough. |
1955 | */ | 1955 | */ |
1956 | static int vbh_bootloader(uint8_t *image_hash) | 1956 | static int vbh_bootloader(uint8_t *image_hash) |
1957 | { | 1957 | { |
1958 | char* slot_suffixes[2] = {"_a", "_b"}; | 1958 | char* slot_suffixes[2] = {"_a", "_b"}; |
1959 | char partition_name[20]; | 1959 | char partition_name[20]; |
1960 | AvbABData ab_data; | 1960 | AvbABData ab_data; |
1961 | uint8_t *image_buf = NULL; | 1961 | uint8_t *image_buf = NULL; |
1962 | uint32_t image_size; | 1962 | uint32_t image_size; |
1963 | size_t image_num_read; | 1963 | size_t image_num_read; |
1964 | int target_slot; | 1964 | int target_slot; |
1965 | int ret = 0; | 1965 | int ret = 0; |
1966 | 1966 | ||
1967 | /* Load A/B metadata and decide which slot we are going to load */ | 1967 | /* Load A/B metadata and decide which slot we are going to load */ |
1968 | if (fsl_avb_ab_ops.read_ab_metadata(&fsl_avb_ab_ops, &ab_data) != | 1968 | if (fsl_avb_ab_ops.read_ab_metadata(&fsl_avb_ab_ops, &ab_data) != |
1969 | AVB_IO_RESULT_OK) { | 1969 | AVB_IO_RESULT_OK) { |
1970 | ret = -1; | 1970 | ret = -1; |
1971 | goto fail ; | 1971 | goto fail ; |
1972 | } | 1972 | } |
1973 | target_slot = get_curr_slot(&ab_data); | 1973 | target_slot = get_curr_slot(&ab_data); |
1974 | sprintf(partition_name, "bootloader%s", slot_suffixes[target_slot]); | 1974 | sprintf(partition_name, "bootloader%s", slot_suffixes[target_slot]); |
1975 | 1975 | ||
1976 | /* Read image header to find the image size */ | 1976 | /* Read image header to find the image size */ |
1977 | image_buf = (uint8_t *)malloc(MMC_SATA_BLOCK_SIZE); | 1977 | image_buf = (uint8_t *)malloc(MMC_SATA_BLOCK_SIZE); |
1978 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, partition_name, | 1978 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, partition_name, |
1979 | 0, MMC_SATA_BLOCK_SIZE, | 1979 | 0, MMC_SATA_BLOCK_SIZE, |
1980 | image_buf, &image_num_read)) { | 1980 | image_buf, &image_num_read)) { |
1981 | printf("bootloader image load error!\n"); | 1981 | printf("bootloader image load error!\n"); |
1982 | ret = -1; | 1982 | ret = -1; |
1983 | goto fail; | 1983 | goto fail; |
1984 | } | 1984 | } |
1985 | image_size = fdt_totalsize((struct image_header *)image_buf); | 1985 | image_size = fdt_totalsize((struct image_header *)image_buf); |
1986 | image_size = (image_size + 3) & ~3; | 1986 | image_size = (image_size + 3) & ~3; |
1987 | free(image_buf); | 1987 | free(image_buf); |
1988 | 1988 | ||
1989 | /* Load full fit image */ | 1989 | /* Load full fit image */ |
1990 | image_buf = (uint8_t *)malloc(image_size); | 1990 | image_buf = (uint8_t *)malloc(image_size); |
1991 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, partition_name, | 1991 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, partition_name, |
1992 | 0, image_size, | 1992 | 0, image_size, |
1993 | image_buf, &image_num_read)) { | 1993 | image_buf, &image_num_read)) { |
1994 | printf("bootloader image load error!\n"); | 1994 | printf("bootloader image load error!\n"); |
1995 | ret = -1; | 1995 | ret = -1; |
1996 | goto fail; | 1996 | goto fail; |
1997 | } | 1997 | } |
1998 | /* Calculate hash */ | 1998 | /* Calculate hash */ |
1999 | sha256_csum_wd((unsigned char *)image_buf, image_size, | 1999 | sha256_csum_wd((unsigned char *)image_buf, image_size, |
2000 | (unsigned char *)image_hash, CHUNKSZ_SHA256); | 2000 | (unsigned char *)image_hash, CHUNKSZ_SHA256); |
2001 | 2001 | ||
2002 | fail: | 2002 | fail: |
2003 | if (image_buf != NULL) | 2003 | if (image_buf != NULL) |
2004 | free(image_buf); | 2004 | free(image_buf); |
2005 | return ret; | 2005 | return ret; |
2006 | } | 2006 | } |
2007 | 2007 | ||
2008 | int vbh_calculate(uint8_t *vbh, AvbSlotVerifyData *avb_out_data) | 2008 | int vbh_calculate(uint8_t *vbh, AvbSlotVerifyData *avb_out_data) |
2009 | { | 2009 | { |
2010 | uint8_t image_hash[AVB_SHA256_DIGEST_SIZE]; | 2010 | uint8_t image_hash[AVB_SHA256_DIGEST_SIZE]; |
2011 | uint8_t hash_buf[2 * AVB_SHA256_DIGEST_SIZE]; | 2011 | uint8_t hash_buf[2 * AVB_SHA256_DIGEST_SIZE]; |
2012 | uint8_t* image_buf = NULL; | 2012 | uint8_t* image_buf = NULL; |
2013 | uint32_t image_size; | 2013 | uint32_t image_size; |
2014 | size_t image_num_read; | 2014 | size_t image_num_read; |
2015 | int ret = 0; | 2015 | int ret = 0; |
2016 | 2016 | ||
2017 | if (vbh == NULL) | 2017 | if (vbh == NULL) |
2018 | return -1; | 2018 | return -1; |
2019 | 2019 | ||
2020 | /* Initial VBH (VBH0) should be 32 bytes 0 */ | 2020 | /* Initial VBH (VBH0) should be 32 bytes 0 */ |
2021 | memset(vbh, 0, AVB_SHA256_DIGEST_SIZE); | 2021 | memset(vbh, 0, AVB_SHA256_DIGEST_SIZE); |
2022 | /* Load and calculate the sha256 hash of spl.bin */ | 2022 | /* Load and calculate the sha256 hash of spl.bin */ |
2023 | image_size = (ANDROID_SPL_SIZE + MMC_SATA_BLOCK_SIZE -1) / | 2023 | image_size = (ANDROID_SPL_SIZE + MMC_SATA_BLOCK_SIZE -1) / |
2024 | MMC_SATA_BLOCK_SIZE; | 2024 | MMC_SATA_BLOCK_SIZE; |
2025 | image_buf = (uint8_t *)malloc(image_size); | 2025 | image_buf = (uint8_t *)malloc(image_size); |
2026 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, | 2026 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, |
2027 | FASTBOOT_PARTITION_BOOTLOADER, | 2027 | FASTBOOT_PARTITION_BOOTLOADER, |
2028 | 0, image_size, | 2028 | 0, image_size, |
2029 | image_buf, &image_num_read)) { | 2029 | image_buf, &image_num_read)) { |
2030 | printf("spl image load error!\n"); | 2030 | printf("spl image load error!\n"); |
2031 | ret = -1; | 2031 | ret = -1; |
2032 | goto fail; | 2032 | goto fail; |
2033 | } | 2033 | } |
2034 | sha256_csum_wd((unsigned char *)image_buf, image_size, | 2034 | sha256_csum_wd((unsigned char *)image_buf, image_size, |
2035 | (unsigned char *)image_hash, CHUNKSZ_SHA256); | 2035 | (unsigned char *)image_hash, CHUNKSZ_SHA256); |
2036 | /* Calculate VBH1 */ | 2036 | /* Calculate VBH1 */ |
2037 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { | 2037 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { |
2038 | ret = -1; | 2038 | ret = -1; |
2039 | goto fail; | 2039 | goto fail; |
2040 | } | 2040 | } |
2041 | free(image_buf); | 2041 | free(image_buf); |
2042 | 2042 | ||
2043 | /* Load and calculate hash of bootloader.img */ | 2043 | /* Load and calculate hash of bootloader.img */ |
2044 | if (vbh_bootloader(image_hash)) { | 2044 | if (vbh_bootloader(image_hash)) { |
2045 | ret = -1; | 2045 | ret = -1; |
2046 | goto fail; | 2046 | goto fail; |
2047 | } | 2047 | } |
2048 | /* Calculate VBH2 */ | 2048 | /* Calculate VBH2 */ |
2049 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { | 2049 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { |
2050 | ret = -1; | 2050 | ret = -1; |
2051 | goto fail; | 2051 | goto fail; |
2052 | } | 2052 | } |
2053 | 2053 | ||
2054 | /* Calculate the hash of vbmeta.img */ | 2054 | /* Calculate the hash of vbmeta.img */ |
2055 | avb_slot_verify_data_calculate_vbmeta_digest(avb_out_data, | 2055 | avb_slot_verify_data_calculate_vbmeta_digest(avb_out_data, |
2056 | AVB_DIGEST_TYPE_SHA256, | 2056 | AVB_DIGEST_TYPE_SHA256, |
2057 | image_hash); | 2057 | image_hash); |
2058 | /* Calculate VBH3 */ | 2058 | /* Calculate VBH3 */ |
2059 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { | 2059 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { |
2060 | ret = -1; | 2060 | ret = -1; |
2061 | goto fail; | 2061 | goto fail; |
2062 | } | 2062 | } |
2063 | 2063 | ||
2064 | fail: | 2064 | fail: |
2065 | if (image_buf != NULL) | 2065 | if (image_buf != NULL) |
2066 | free(image_buf); | 2066 | free(image_buf); |
2067 | return ret; | 2067 | return ret; |
2068 | } | 2068 | } |
2069 | 2069 | ||
2070 | #endif | 2070 | #endif |
2071 | int trusty_setbootparameter(struct andr_img_hdr *hdr, AvbABFlowResult avb_result, | 2071 | int trusty_setbootparameter(struct andr_img_hdr *hdr, AvbABFlowResult avb_result, |
2072 | AvbSlotVerifyData *avb_out_data) { | 2072 | AvbSlotVerifyData *avb_out_data) { |
2073 | #ifdef CONFIG_DUAL_BOOTLOADER | 2073 | #ifdef CONFIG_DUAL_BOOTLOADER |
2074 | uint8_t vbh[AVB_SHA256_DIGEST_SIZE]; | 2074 | uint8_t vbh[AVB_SHA256_DIGEST_SIZE]; |
2075 | #endif | 2075 | #endif |
2076 | int ret = 0; | 2076 | int ret = 0; |
2077 | u32 os_ver = hdr->os_version >> 11; | 2077 | u32 os_ver = hdr->os_version >> 11; |
2078 | u32 os_ver_km = (((os_ver >> 14) & 0x7F) * 100 + ((os_ver >> 7) & 0x7F)) * 100 | 2078 | u32 os_ver_km = (((os_ver >> 14) & 0x7F) * 100 + ((os_ver >> 7) & 0x7F)) * 100 |
2079 | + (os_ver & 0x7F); | 2079 | + (os_ver & 0x7F); |
2080 | u32 os_lvl = hdr->os_version & ((1U << 11) - 1); | 2080 | u32 os_lvl = hdr->os_version & ((1U << 11) - 1); |
2081 | u32 os_lvl_km = ((os_lvl >> 4) + 2000) * 100 + (os_lvl & 0x0F); | 2081 | u32 os_lvl_km = ((os_lvl >> 4) + 2000) * 100 + (os_lvl & 0x0F); |
2082 | keymaster_verified_boot_t vbstatus; | 2082 | keymaster_verified_boot_t vbstatus; |
2083 | FbLockState lock_status = fastboot_get_lock_stat(); | 2083 | FbLockState lock_status = fastboot_get_lock_stat(); |
2084 | 2084 | ||
2085 | uint8_t permanent_attributes_hash[AVB_SHA256_DIGEST_SIZE]; | 2085 | uint8_t permanent_attributes_hash[AVB_SHA256_DIGEST_SIZE]; |
2086 | #ifdef CONFIG_AVB_ATX | 2086 | #ifdef CONFIG_AVB_ATX |
2087 | if (fsl_read_permanent_attributes_hash(&fsl_avb_atx_ops, permanent_attributes_hash)) { | 2087 | if (fsl_read_permanent_attributes_hash(&fsl_avb_atx_ops, permanent_attributes_hash)) { |
2088 | printf("ERROR - failed to read permanent attributes hash for keymaster\n"); | 2088 | printf("ERROR - failed to read permanent attributes hash for keymaster\n"); |
2089 | memset(permanent_attributes_hash, 0, AVB_SHA256_DIGEST_SIZE); | 2089 | memset(permanent_attributes_hash, 0, AVB_SHA256_DIGEST_SIZE); |
2090 | } | 2090 | } |
2091 | #endif | 2091 | #endif |
2092 | 2092 | ||
2093 | bool lock = (lock_status == FASTBOOT_LOCK)? true: false; | 2093 | bool lock = (lock_status == FASTBOOT_LOCK)? true: false; |
2094 | if (avb_result == AVB_AB_FLOW_RESULT_OK) | 2094 | if (avb_result == AVB_AB_FLOW_RESULT_OK) |
2095 | vbstatus = KM_VERIFIED_BOOT_VERIFIED; | 2095 | vbstatus = KM_VERIFIED_BOOT_VERIFIED; |
2096 | else | 2096 | else |
2097 | vbstatus = KM_VERIFIED_BOOT_FAILED; | 2097 | vbstatus = KM_VERIFIED_BOOT_FAILED; |
2098 | 2098 | ||
2099 | /* Calculate VBH */ | 2099 | /* Calculate VBH */ |
2100 | #ifdef CONFIG_DUAL_BOOTLOADER | 2100 | #ifdef CONFIG_DUAL_BOOTLOADER |
2101 | if (vbh_calculate(vbh, avb_out_data)) { | 2101 | if (vbh_calculate(vbh, avb_out_data)) { |
2102 | ret = -1; | 2102 | ret = -1; |
2103 | goto fail; | 2103 | goto fail; |
2104 | } | 2104 | } |
2105 | 2105 | ||
2106 | trusty_set_boot_params(os_ver_km, os_lvl_km, vbstatus, lock, | 2106 | trusty_set_boot_params(os_ver_km, os_lvl_km, vbstatus, lock, |
2107 | permanent_attributes_hash, AVB_SHA256_DIGEST_SIZE, | 2107 | permanent_attributes_hash, AVB_SHA256_DIGEST_SIZE, |
2108 | vbh, AVB_SHA256_DIGEST_SIZE); | 2108 | vbh, AVB_SHA256_DIGEST_SIZE); |
2109 | #else | 2109 | #else |
2110 | trusty_set_boot_params(os_ver_km, os_lvl_km, vbstatus, lock, | 2110 | trusty_set_boot_params(os_ver_km, os_lvl_km, vbstatus, lock, |
2111 | permanent_attributes_hash, AVB_SHA256_DIGEST_SIZE, | 2111 | permanent_attributes_hash, AVB_SHA256_DIGEST_SIZE, |
2112 | NULL, 0); | 2112 | NULL, 0); |
2113 | #endif | 2113 | #endif |
2114 | 2114 | ||
2115 | fail: | 2115 | fail: |
2116 | return ret; | 2116 | return ret; |
2117 | } | 2117 | } |
2118 | #endif | 2118 | #endif |
2119 | 2119 | ||
2120 | #if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC) | 2120 | #if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC) |
2121 | /* we can use avb to verify Trusty if we want */ | 2121 | /* we can use avb to verify Trusty if we want */ |
2122 | const char *requested_partitions_boot[] = {"boot", FDT_PART_NAME, NULL}; | 2122 | const char *requested_partitions_boot[] = {"boot", FDT_PART_NAME, NULL}; |
2123 | const char *requested_partitions_recovery[] = {"recovery", FDT_PART_NAME, NULL}; | 2123 | const char *requested_partitions_recovery[] = {"recovery", FDT_PART_NAME, NULL}; |
2124 | 2124 | ||
2125 | static bool is_load_fdt_from_part(void) | 2125 | static bool is_load_fdt_from_part(void) |
2126 | { | 2126 | { |
2127 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) | 2127 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) |
2128 | if (fastboot_flash_find_ptn("oem_bootloader_a") && | 2128 | if (fastboot_flash_find_ptn("oem_bootloader_a") && |
2129 | fastboot_flash_find_ptn("oem_bootloader_b")) { | 2129 | fastboot_flash_find_ptn("oem_bootloader_b")) { |
2130 | #elif defined(CONFIG_ANDROID_AB_SUPPORT) | 2130 | #elif defined(CONFIG_ANDROID_AB_SUPPORT) |
2131 | if (fastboot_flash_find_ptn("dtbo_a") && | 2131 | if (fastboot_flash_find_ptn("dtbo_a") && |
2132 | fastboot_flash_find_ptn("dtbo_b")) { | 2132 | fastboot_flash_find_ptn("dtbo_b")) { |
2133 | #else | 2133 | #else |
2134 | /* for legacy platfrom (imx6/7), we don't support A/B slot. */ | 2134 | /* for legacy platfrom (imx6/7), we don't support A/B slot. */ |
2135 | if (fastboot_flash_find_ptn("dtbo")) { | 2135 | if (fastboot_flash_find_ptn("dtbo")) { |
2136 | #endif | 2136 | #endif |
2137 | return true; | 2137 | return true; |
2138 | } else { | 2138 | } else { |
2139 | return false; | 2139 | return false; |
2140 | } | 2140 | } |
2141 | } | 2141 | } |
2142 | 2142 | ||
2143 | static int find_partition_data_by_name(char* part_name, | 2143 | static int find_partition_data_by_name(char* part_name, |
2144 | AvbSlotVerifyData* avb_out_data, AvbPartitionData** avb_loadpart) | 2144 | AvbSlotVerifyData* avb_out_data, AvbPartitionData** avb_loadpart) |
2145 | { | 2145 | { |
2146 | int num = 0; | 2146 | int num = 0; |
2147 | AvbPartitionData* loadpart = NULL; | 2147 | AvbPartitionData* loadpart = NULL; |
2148 | 2148 | ||
2149 | for (num = 0; num < avb_out_data->num_loaded_partitions; num++) { | 2149 | for (num = 0; num < avb_out_data->num_loaded_partitions; num++) { |
2150 | loadpart = &(avb_out_data->loaded_partitions[num]); | 2150 | loadpart = &(avb_out_data->loaded_partitions[num]); |
2151 | if (!(strncmp(loadpart->partition_name, | 2151 | if (!(strncmp(loadpart->partition_name, |
2152 | part_name, strlen(part_name)))) { | 2152 | part_name, strlen(part_name)))) { |
2153 | *avb_loadpart = loadpart; | 2153 | *avb_loadpart = loadpart; |
2154 | break; | 2154 | break; |
2155 | } | 2155 | } |
2156 | } | 2156 | } |
2157 | if (num == avb_out_data->num_loaded_partitions) { | 2157 | if (num == avb_out_data->num_loaded_partitions) { |
2158 | printf("Error! Can't find %s partition from avb partition data!\n", | 2158 | printf("Error! Can't find %s partition from avb partition data!\n", |
2159 | part_name); | 2159 | part_name); |
2160 | return -1; | 2160 | return -1; |
2161 | } | 2161 | } |
2162 | else | 2162 | else |
2163 | return 0; | 2163 | return 0; |
2164 | } | 2164 | } |
2165 | 2165 | ||
2166 | int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { | 2166 | int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { |
2167 | 2167 | ||
2168 | ulong addr = 0; | 2168 | ulong addr = 0; |
2169 | struct andr_img_hdr *hdr = NULL; | 2169 | struct andr_img_hdr *hdr = NULL; |
2170 | void *boot_buf = NULL; | 2170 | void *boot_buf = NULL; |
2171 | ulong image_size; | 2171 | ulong image_size; |
2172 | u32 avb_metric; | 2172 | u32 avb_metric; |
2173 | bool check_image_arm64 = false; | 2173 | bool check_image_arm64 = false; |
2174 | bool is_recovery_mode = false; | 2174 | bool is_recovery_mode = false; |
2175 | 2175 | ||
2176 | AvbABFlowResult avb_result; | 2176 | AvbABFlowResult avb_result; |
2177 | AvbSlotVerifyData *avb_out_data = NULL; | 2177 | AvbSlotVerifyData *avb_out_data = NULL; |
2178 | AvbPartitionData *avb_loadpart = NULL; | 2178 | AvbPartitionData *avb_loadpart = NULL; |
2179 | 2179 | ||
2180 | /* get bootmode, default to boot "boot" */ | 2180 | /* get bootmode, default to boot "boot" */ |
2181 | if (argc > 1) { | 2181 | if (argc > 1) { |
2182 | is_recovery_mode = | 2182 | is_recovery_mode = |
2183 | (strncmp(argv[1], "recovery", sizeof("recovery")) != 0) ? false: true; | 2183 | (strncmp(argv[1], "recovery", sizeof("recovery")) != 0) ? false: true; |
2184 | if (is_recovery_mode) | 2184 | if (is_recovery_mode) |
2185 | printf("Will boot from recovery!\n"); | 2185 | printf("Will boot from recovery!\n"); |
2186 | } | 2186 | } |
2187 | 2187 | ||
2188 | /* check lock state */ | 2188 | /* check lock state */ |
2189 | FbLockState lock_status = fastboot_get_lock_stat(); | 2189 | FbLockState lock_status = fastboot_get_lock_stat(); |
2190 | if (lock_status == FASTBOOT_LOCK_ERROR) { | 2190 | if (lock_status == FASTBOOT_LOCK_ERROR) { |
2191 | #ifdef CONFIG_AVB_ATX | 2191 | #ifdef CONFIG_AVB_ATX |
2192 | printf("In boota get fastboot lock status error, enter fastboot mode.\n"); | 2192 | printf("In boota get fastboot lock status error, enter fastboot mode.\n"); |
2193 | goto fail; | 2193 | goto fail; |
2194 | #else | 2194 | #else |
2195 | printf("In boota get fastboot lock status error. Set lock status\n"); | 2195 | printf("In boota get fastboot lock status error. Set lock status\n"); |
2196 | fastboot_set_lock_stat(FASTBOOT_LOCK); | 2196 | fastboot_set_lock_stat(FASTBOOT_LOCK); |
2197 | lock_status = FASTBOOT_LOCK; | 2197 | lock_status = FASTBOOT_LOCK; |
2198 | #endif | 2198 | #endif |
2199 | } | 2199 | } |
2200 | bool allow_fail = (lock_status == FASTBOOT_UNLOCK ? true : false); | 2200 | bool allow_fail = (lock_status == FASTBOOT_UNLOCK ? true : false); |
2201 | avb_metric = get_timer(0); | 2201 | avb_metric = get_timer(0); |
2202 | /* we don't need to verify fdt partition if we don't have it. */ | 2202 | /* we don't need to verify fdt partition if we don't have it. */ |
2203 | if (!is_load_fdt_from_part()) { | 2203 | if (!is_load_fdt_from_part()) { |
2204 | requested_partitions_boot[1] = NULL; | 2204 | requested_partitions_boot[1] = NULL; |
2205 | requested_partitions_recovery[1] = NULL; | 2205 | requested_partitions_recovery[1] = NULL; |
2206 | } | 2206 | } |
2207 | #ifndef CONFIG_ANDROID_AB_SUPPORT | 2207 | #ifndef CONFIG_ANDROID_AB_SUPPORT |
2208 | else if (is_recovery_mode){ | 2208 | else if (is_recovery_mode){ |
2209 | requested_partitions_recovery[1] = NULL; | 2209 | requested_partitions_recovery[1] = NULL; |
2210 | } | 2210 | } |
2211 | #endif | 2211 | #endif |
2212 | 2212 | ||
2213 | /* if in lock state, do avb verify */ | 2213 | /* if in lock state, do avb verify */ |
2214 | #ifndef CONFIG_DUAL_BOOTLOADER | 2214 | #ifndef CONFIG_DUAL_BOOTLOADER |
2215 | /* For imx6 on Android, we don't have a/b slot and we want to verify | 2215 | /* For imx6 on Android, we don't have a/b slot and we want to verify |
2216 | * boot/recovery with AVB. For imx8 and Android Things we don't have | 2216 | * boot/recovery with AVB. For imx8 and Android Things we don't have |
2217 | * recovery and support a/b slot for boot */ | 2217 | * recovery and support a/b slot for boot */ |
2218 | #ifdef CONFIG_ANDROID_AB_SUPPORT | 2218 | #ifdef CONFIG_ANDROID_AB_SUPPORT |
2219 | /* we can use avb to verify Trusty if we want */ | 2219 | /* we can use avb to verify Trusty if we want */ |
2220 | avb_result = avb_ab_flow_fast(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, | 2220 | avb_result = avb_ab_flow_fast(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, |
2221 | AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_out_data); | 2221 | AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_out_data); |
2222 | #else | 2222 | #else |
2223 | if (!is_recovery_mode) { | 2223 | if (!is_recovery_mode) { |
2224 | avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, | 2224 | avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, |
2225 | AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); | 2225 | AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); |
2226 | } else { | 2226 | } else { |
2227 | avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions_recovery, allow_fail, | 2227 | avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions_recovery, allow_fail, |
2228 | AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); | 2228 | AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); |
2229 | } | 2229 | } |
2230 | #endif | 2230 | #endif |
2231 | #else /* !CONFIG_DUAL_BOOTLOADER */ | 2231 | #else /* !CONFIG_DUAL_BOOTLOADER */ |
2232 | /* We will only verify single one slot which has been selected in SPL */ | 2232 | /* We will only verify single one slot which has been selected in SPL */ |
2233 | avb_result = avb_flow_dual_uboot(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, | 2233 | avb_result = avb_flow_dual_uboot(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, |
2234 | AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_out_data); | 2234 | AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_out_data); |
2235 | 2235 | ||
2236 | /* Goto fail early if current slot is not bootable. */ | 2236 | /* Goto fail early if current slot is not bootable. */ |
2237 | if (avb_result == AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS) { | 2237 | if (avb_result == AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS) { |
2238 | printf("boota: slot verify fail!\n"); | 2238 | printf("boota: slot verify fail!\n"); |
2239 | goto fail; | 2239 | goto fail; |
2240 | } | 2240 | } |
2241 | #endif /* !CONFIG_DUAL_BOOTLOADER */ | 2241 | #endif /* !CONFIG_DUAL_BOOTLOADER */ |
2242 | 2242 | ||
2243 | /* get the duration of avb */ | 2243 | /* get the duration of avb */ |
2244 | metrics.avb = get_timer(avb_metric); | 2244 | metrics.avb = get_timer(avb_metric); |
2245 | 2245 | ||
2246 | if ((avb_result == AVB_AB_FLOW_RESULT_OK) || | 2246 | if ((avb_result == AVB_AB_FLOW_RESULT_OK) || |
2247 | (avb_result == AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR)) { | 2247 | (avb_result == AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR)) { |
2248 | assert(avb_out_data != NULL); | 2248 | assert(avb_out_data != NULL); |
2249 | /* We may have more than one partition loaded by AVB, find the boot | 2249 | /* We may have more than one partition loaded by AVB, find the boot |
2250 | * partition first. | 2250 | * partition first. |
2251 | */ | 2251 | */ |
2252 | #ifdef CONFIG_ANDROID_AB_SUPPORT | 2252 | #ifdef CONFIG_ANDROID_AB_SUPPORT |
2253 | if (find_partition_data_by_name("boot", avb_out_data, &avb_loadpart)) | 2253 | if (find_partition_data_by_name("boot", avb_out_data, &avb_loadpart)) |
2254 | goto fail; | 2254 | goto fail; |
2255 | #else | 2255 | #else |
2256 | if (!is_recovery_mode) { | 2256 | if (!is_recovery_mode) { |
2257 | if (find_partition_data_by_name("boot", avb_out_data, &avb_loadpart)) | 2257 | if (find_partition_data_by_name("boot", avb_out_data, &avb_loadpart)) |
2258 | goto fail; | 2258 | goto fail; |
2259 | } else { | 2259 | } else { |
2260 | if (find_partition_data_by_name("recovery", avb_out_data, &avb_loadpart)) | 2260 | if (find_partition_data_by_name("recovery", avb_out_data, &avb_loadpart)) |
2261 | goto fail; | 2261 | goto fail; |
2262 | } | 2262 | } |
2263 | #endif | 2263 | #endif |
2264 | assert(avb_loadpart != NULL); | 2264 | assert(avb_loadpart != NULL); |
2265 | /* we should use avb_part_data->data as boot image */ | 2265 | /* we should use avb_part_data->data as boot image */ |
2266 | /* boot image is already read by avb */ | 2266 | /* boot image is already read by avb */ |
2267 | hdr = (struct andr_img_hdr *)avb_loadpart->data; | 2267 | hdr = (struct andr_img_hdr *)avb_loadpart->data; |
2268 | if (android_image_check_header(hdr)) { | 2268 | if (android_image_check_header(hdr)) { |
2269 | printf("boota: bad boot image magic\n"); | 2269 | printf("boota: bad boot image magic\n"); |
2270 | goto fail; | 2270 | goto fail; |
2271 | } | 2271 | } |
2272 | if (avb_result == AVB_AB_FLOW_RESULT_OK) | 2272 | if (avb_result == AVB_AB_FLOW_RESULT_OK) |
2273 | printf(" verify OK, boot '%s%s'\n", | 2273 | printf(" verify OK, boot '%s%s'\n", |
2274 | avb_loadpart->partition_name, avb_out_data->ab_suffix); | 2274 | avb_loadpart->partition_name, avb_out_data->ab_suffix); |
2275 | else { | 2275 | else { |
2276 | printf(" verify FAIL, state: UNLOCK\n"); | 2276 | printf(" verify FAIL, state: UNLOCK\n"); |
2277 | printf(" boot '%s%s' still\n", | 2277 | printf(" boot '%s%s' still\n", |
2278 | avb_loadpart->partition_name, avb_out_data->ab_suffix); | 2278 | avb_loadpart->partition_name, avb_out_data->ab_suffix); |
2279 | } | 2279 | } |
2280 | char bootargs_sec[ANDR_BOOT_EXTRA_ARGS_SIZE]; | 2280 | char bootargs_sec[ANDR_BOOT_EXTRA_ARGS_SIZE]; |
2281 | if (lock_status == FASTBOOT_LOCK) { | 2281 | if (lock_status == FASTBOOT_LOCK) { |
2282 | snprintf(bootargs_sec, sizeof(bootargs_sec), | 2282 | snprintf(bootargs_sec, sizeof(bootargs_sec), |
2283 | "androidboot.verifiedbootstate=green androidboot.slot_suffix=%s %s", | 2283 | "androidboot.verifiedbootstate=green androidboot.slot_suffix=%s %s", |
2284 | avb_out_data->ab_suffix, avb_out_data->cmdline); | 2284 | avb_out_data->ab_suffix, avb_out_data->cmdline); |
2285 | } else { | 2285 | } else { |
2286 | snprintf(bootargs_sec, sizeof(bootargs_sec), | 2286 | snprintf(bootargs_sec, sizeof(bootargs_sec), |
2287 | "androidboot.verifiedbootstate=orange androidboot.slot_suffix=%s %s", | 2287 | "androidboot.verifiedbootstate=orange androidboot.slot_suffix=%s %s", |
2288 | avb_out_data->ab_suffix, avb_out_data->cmdline); | 2288 | avb_out_data->ab_suffix, avb_out_data->cmdline); |
2289 | } | 2289 | } |
2290 | env_set("bootargs_sec", bootargs_sec); | 2290 | env_set("bootargs_sec", bootargs_sec); |
2291 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | 2291 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT |
2292 | if(!is_recovery_mode) { | 2292 | if(!is_recovery_mode) { |
2293 | if(avb_out_data->cmdline != NULL && strstr(avb_out_data->cmdline, "root=")) | 2293 | if(avb_out_data->cmdline != NULL && strstr(avb_out_data->cmdline, "root=")) |
2294 | fastboot_setup_system_boot_args(avb_out_data->ab_suffix, false); | 2294 | fastboot_setup_system_boot_args(avb_out_data->ab_suffix, false); |
2295 | else | 2295 | else |
2296 | fastboot_setup_system_boot_args(avb_out_data->ab_suffix, true); | 2296 | fastboot_setup_system_boot_args(avb_out_data->ab_suffix, true); |
2297 | } | 2297 | } |
2298 | #endif /* CONFIG_SYSTEM_RAMDISK_SUPPORT */ | 2298 | #endif /* CONFIG_SYSTEM_RAMDISK_SUPPORT */ |
2299 | image_size = avb_loadpart->data_size; | 2299 | image_size = avb_loadpart->data_size; |
2300 | #if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) | 2300 | #if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) |
2301 | /* If we are using uncompressed kernel image, copy it directly to | 2301 | /* If we are using uncompressed kernel image, copy it directly to |
2302 | * hdr->kernel_addr, if we are using compressed lz4 kernel image, | 2302 | * hdr->kernel_addr, if we are using compressed lz4 kernel image, |
2303 | * we need to decompress the kernel image first. */ | 2303 | * we need to decompress the kernel image first. */ |
2304 | if (image_arm64((void *)((ulong)hdr + hdr->page_size))) { | 2304 | if (image_arm64((void *)((ulong)hdr + hdr->page_size))) { |
2305 | memcpy((void *)(long)hdr->kernel_addr, | 2305 | memcpy((void *)(long)hdr->kernel_addr, |
2306 | (void *)((ulong)hdr + hdr->page_size), hdr->kernel_size); | 2306 | (void *)((ulong)hdr + hdr->page_size), hdr->kernel_size); |
2307 | } else { | 2307 | } else { |
2308 | #ifdef CONFIG_LZ4 | 2308 | #ifdef CONFIG_LZ4 |
2309 | size_t lz4_len = DST_DECOMPRESS_LEN; | 2309 | size_t lz4_len = DST_DECOMPRESS_LEN; |
2310 | if (ulz4fn((void *)((ulong)hdr + hdr->page_size), | 2310 | if (ulz4fn((void *)((ulong)hdr + hdr->page_size), |
2311 | hdr->kernel_size, (void *)(ulong)hdr->kernel_addr, &lz4_len) != 0) { | 2311 | hdr->kernel_size, (void *)(ulong)hdr->kernel_addr, &lz4_len) != 0) { |
2312 | printf("Decompress kernel fail!\n"); | 2312 | printf("Decompress kernel fail!\n"); |
2313 | goto fail; | 2313 | goto fail; |
2314 | } | 2314 | } |
2315 | #else /* CONFIG_LZ4 */ | 2315 | #else /* CONFIG_LZ4 */ |
2316 | printf("please enable CONFIG_LZ4 if we're using compressed lz4 kernel image!\n"); | 2316 | printf("please enable CONFIG_LZ4 if we're using compressed lz4 kernel image!\n"); |
2317 | goto fail; | 2317 | goto fail; |
2318 | #endif /* CONFIG_LZ4 */ | 2318 | #endif /* CONFIG_LZ4 */ |
2319 | } | 2319 | } |
2320 | #else /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ | 2320 | #else /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ |
2321 | /* copy kernel image and boot header to hdr->kernel_addr - hdr->page_size */ | 2321 | /* copy kernel image and boot header to hdr->kernel_addr - hdr->page_size */ |
2322 | memcpy((void *)(ulong)(hdr->kernel_addr - hdr->page_size), (void *)hdr, | 2322 | memcpy((void *)(ulong)(hdr->kernel_addr - hdr->page_size), (void *)hdr, |
2323 | hdr->page_size + ALIGN(hdr->kernel_size, hdr->page_size)); | 2323 | hdr->page_size + ALIGN(hdr->kernel_size, hdr->page_size)); |
2324 | #endif /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ | 2324 | #endif /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ |
2325 | } else { | 2325 | } else { |
2326 | /* Fall into fastboot mode if get unacceptable error from avb | 2326 | /* Fall into fastboot mode if get unacceptable error from avb |
2327 | * or verify fail in lock state. | 2327 | * or verify fail in lock state. |
2328 | */ | 2328 | */ |
2329 | if (lock_status == FASTBOOT_LOCK) | 2329 | if (lock_status == FASTBOOT_LOCK) |
2330 | printf(" verify FAIL, state: LOCK\n"); | 2330 | printf(" verify FAIL, state: LOCK\n"); |
2331 | 2331 | ||
2332 | goto fail; | 2332 | goto fail; |
2333 | } | 2333 | } |
2334 | 2334 | ||
2335 | flush_cache((ulong)load_addr, image_size); | 2335 | flush_cache((ulong)load_addr, image_size); |
2336 | check_image_arm64 = image_arm64((void *)(ulong)hdr->kernel_addr); | 2336 | check_image_arm64 = image_arm64((void *)(ulong)hdr->kernel_addr); |
2337 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | 2337 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT |
2338 | if (is_recovery_mode) | 2338 | if (is_recovery_mode) |
2339 | memcpy((void *)(ulong)hdr->ramdisk_addr, (void *)(ulong)hdr + hdr->page_size | 2339 | memcpy((void *)(ulong)hdr->ramdisk_addr, (void *)(ulong)hdr + hdr->page_size |
2340 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); | 2340 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); |
2341 | #else | 2341 | #else |
2342 | memcpy((void *)(ulong)hdr->ramdisk_addr, (void *)(ulong)hdr + hdr->page_size | 2342 | memcpy((void *)(ulong)hdr->ramdisk_addr, (void *)(ulong)hdr + hdr->page_size |
2343 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); | 2343 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); |
2344 | #endif | 2344 | #endif |
2345 | #ifdef CONFIG_OF_LIBFDT | 2345 | #ifdef CONFIG_OF_LIBFDT |
2346 | /* load the dtb file */ | 2346 | /* load the dtb file */ |
2347 | u32 fdt_size = 0; | 2347 | u32 fdt_size = 0; |
2348 | struct dt_table_header *dt_img = NULL; | 2348 | struct dt_table_header *dt_img = NULL; |
2349 | 2349 | ||
2350 | if (is_load_fdt_from_part()) { | 2350 | if (is_load_fdt_from_part()) { |
2351 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT | 2351 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT |
2352 | if (find_partition_data_by_name("oem_bootloader", | 2352 | if (find_partition_data_by_name("oem_bootloader", |
2353 | avb_out_data, &avb_loadpart)) { | 2353 | avb_out_data, &avb_loadpart)) { |
2354 | goto fail; | 2354 | goto fail; |
2355 | } else | 2355 | } else |
2356 | dt_img = (struct dt_table_header *)avb_loadpart->data; | 2356 | dt_img = (struct dt_table_header *)avb_loadpart->data; |
2357 | #elif defined(CONFIG_ANDROID_AB_SUPPORT) | 2357 | #elif defined(CONFIG_ANDROID_AB_SUPPORT) |
2358 | if (find_partition_data_by_name("dtbo", | 2358 | if (find_partition_data_by_name("dtbo", |
2359 | avb_out_data, &avb_loadpart)) { | 2359 | avb_out_data, &avb_loadpart)) { |
2360 | goto fail; | 2360 | goto fail; |
2361 | } else | 2361 | } else |
2362 | dt_img = (struct dt_table_header *)avb_loadpart->data; | 2362 | dt_img = (struct dt_table_header *)avb_loadpart->data; |
2363 | #else | 2363 | #else |
2364 | if (is_recovery_mode) { | 2364 | if (is_recovery_mode) { |
2365 | if (hdr->header_version != 1) { | 2365 | if (hdr->header_version != 1) { |
2366 | printf("boota: boot image header version error!\n"); | 2366 | printf("boota: boot image header version error!\n"); |
2367 | goto fail; | 2367 | goto fail; |
2368 | } | 2368 | } |
2369 | 2369 | ||
2370 | dt_img = (struct dt_table_header *)((void *)(ulong)hdr + | 2370 | dt_img = (struct dt_table_header *)((void *)(ulong)hdr + |
2371 | hdr->page_size + | 2371 | hdr->page_size + |
2372 | ALIGN(hdr->kernel_size, hdr->page_size) + | 2372 | ALIGN(hdr->kernel_size, hdr->page_size) + |
2373 | ALIGN(hdr->ramdisk_size, hdr->page_size) + | 2373 | ALIGN(hdr->ramdisk_size, hdr->page_size) + |
2374 | ALIGN(hdr->second_size, hdr->page_size)); | 2374 | ALIGN(hdr->second_size, hdr->page_size)); |
2375 | } else if (find_partition_data_by_name("dtbo", | 2375 | } else if (find_partition_data_by_name("dtbo", |
2376 | avb_out_data, &avb_loadpart)) { | 2376 | avb_out_data, &avb_loadpart)) { |
2377 | goto fail; | 2377 | goto fail; |
2378 | } else | 2378 | } else |
2379 | dt_img = (struct dt_table_header *)avb_loadpart->data; | 2379 | dt_img = (struct dt_table_header *)avb_loadpart->data; |
2380 | #endif | 2380 | #endif |
2381 | 2381 | ||
2382 | if (be32_to_cpu(dt_img->magic) != DT_TABLE_MAGIC) { | 2382 | if (be32_to_cpu(dt_img->magic) != DT_TABLE_MAGIC) { |
2383 | printf("boota: bad dt table magic %08x\n", | 2383 | printf("boota: bad dt table magic %08x\n", |
2384 | be32_to_cpu(dt_img->magic)); | 2384 | be32_to_cpu(dt_img->magic)); |
2385 | goto fail; | 2385 | goto fail; |
2386 | } else if (!be32_to_cpu(dt_img->dt_entry_count)) { | 2386 | } else if (!be32_to_cpu(dt_img->dt_entry_count)) { |
2387 | printf("boota: no dt entries\n"); | 2387 | printf("boota: no dt entries\n"); |
2388 | goto fail; | 2388 | goto fail; |
2389 | } | 2389 | } |
2390 | 2390 | ||
2391 | struct dt_table_entry *dt_entry; | 2391 | struct dt_table_entry *dt_entry; |
2392 | dt_entry = (struct dt_table_entry *)((ulong)dt_img + | 2392 | dt_entry = (struct dt_table_entry *)((ulong)dt_img + |
2393 | be32_to_cpu(dt_img->dt_entries_offset)); | 2393 | be32_to_cpu(dt_img->dt_entries_offset)); |
2394 | fdt_size = be32_to_cpu(dt_entry->dt_size); | 2394 | fdt_size = be32_to_cpu(dt_entry->dt_size); |
2395 | memcpy((void *)(ulong)hdr->second_addr, (void *)((ulong)dt_img + | 2395 | memcpy((void *)(ulong)hdr->second_addr, (void *)((ulong)dt_img + |
2396 | be32_to_cpu(dt_entry->dt_offset)), fdt_size); | 2396 | be32_to_cpu(dt_entry->dt_offset)), fdt_size); |
2397 | } else { | 2397 | } else { |
2398 | if (hdr->second_size && hdr->second_addr) { | 2398 | if (hdr->second_size && hdr->second_addr) { |
2399 | memcpy((void *)(ulong)hdr->second_addr, | 2399 | memcpy((void *)(ulong)hdr->second_addr, |
2400 | (void *)(ulong)hdr + hdr->page_size | 2400 | (void *)(ulong)hdr + hdr->page_size |
2401 | + ALIGN(hdr->kernel_size, hdr->page_size) | 2401 | + ALIGN(hdr->kernel_size, hdr->page_size) |
2402 | + ALIGN(hdr->ramdisk_size, hdr->page_size), | 2402 | + ALIGN(hdr->ramdisk_size, hdr->page_size), |
2403 | hdr->second_size); | 2403 | hdr->second_size); |
2404 | } | 2404 | } |
2405 | } | 2405 | } |
2406 | #endif /*CONFIG_OF_LIBFDT*/ | 2406 | #endif /*CONFIG_OF_LIBFDT*/ |
2407 | 2407 | ||
2408 | if (check_image_arm64) { | 2408 | if (check_image_arm64) { |
2409 | android_image_get_kernel(hdr, 0, NULL, NULL); | 2409 | android_image_get_kernel(hdr, 0, NULL, NULL); |
2410 | addr = hdr->kernel_addr; | 2410 | addr = hdr->kernel_addr; |
2411 | } else { | 2411 | } else { |
2412 | addr = (ulong)(hdr->kernel_addr - hdr->page_size); | 2412 | addr = (ulong)(hdr->kernel_addr - hdr->page_size); |
2413 | } | 2413 | } |
2414 | printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size); | 2414 | printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size); |
2415 | printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size); | 2415 | printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size); |
2416 | #ifdef CONFIG_OF_LIBFDT | 2416 | #ifdef CONFIG_OF_LIBFDT |
2417 | if (is_load_fdt_from_part()) { | 2417 | if (is_load_fdt_from_part()) { |
2418 | if (fdt_size) | 2418 | if (fdt_size) |
2419 | printf("fdt @ %08x (%d)\n", hdr->second_addr, fdt_size); | 2419 | printf("fdt @ %08x (%d)\n", hdr->second_addr, fdt_size); |
2420 | } else { | 2420 | } else { |
2421 | if (hdr->second_size) | 2421 | if (hdr->second_size) |
2422 | printf("fdt @ %08x (%d)\n", hdr->second_addr, hdr->second_size); | 2422 | printf("fdt @ %08x (%d)\n", hdr->second_addr, hdr->second_size); |
2423 | } | 2423 | } |
2424 | #endif /*CONFIG_OF_LIBFDT*/ | 2424 | #endif /*CONFIG_OF_LIBFDT*/ |
2425 | 2425 | ||
2426 | char boot_addr_start[12]; | 2426 | char boot_addr_start[12]; |
2427 | char ramdisk_addr[25]; | 2427 | char ramdisk_addr[25]; |
2428 | char fdt_addr[12]; | 2428 | char fdt_addr[12]; |
2429 | 2429 | ||
2430 | char *boot_args[] = { NULL, boot_addr_start, ramdisk_addr, fdt_addr}; | 2430 | char *boot_args[] = { NULL, boot_addr_start, ramdisk_addr, fdt_addr}; |
2431 | if (check_image_arm64) | 2431 | if (check_image_arm64) |
2432 | boot_args[0] = "booti"; | 2432 | boot_args[0] = "booti"; |
2433 | else | 2433 | else |
2434 | boot_args[0] = "bootm"; | 2434 | boot_args[0] = "bootm"; |
2435 | 2435 | ||
2436 | sprintf(boot_addr_start, "0x%lx", addr); | 2436 | sprintf(boot_addr_start, "0x%lx", addr); |
2437 | sprintf(ramdisk_addr, "0x%x:0x%x", hdr->ramdisk_addr, hdr->ramdisk_size); | 2437 | sprintf(ramdisk_addr, "0x%x:0x%x", hdr->ramdisk_addr, hdr->ramdisk_size); |
2438 | sprintf(fdt_addr, "0x%x", hdr->second_addr); | 2438 | sprintf(fdt_addr, "0x%x", hdr->second_addr); |
2439 | 2439 | ||
2440 | /* no need to pass ramdisk addr for normal boot mode when enable CONFIG_SYSTEM_RAMDISK_SUPPORT*/ | 2440 | /* no need to pass ramdisk addr for normal boot mode when enable CONFIG_SYSTEM_RAMDISK_SUPPORT*/ |
2441 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | 2441 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT |
2442 | if (!is_recovery_mode) | 2442 | if (!is_recovery_mode) |
2443 | boot_args[2] = NULL; | 2443 | boot_args[2] = NULL; |
2444 | #endif | 2444 | #endif |
2445 | 2445 | ||
2446 | #ifdef CONFIG_IMX_TRUSTY_OS | 2446 | #ifdef CONFIG_IMX_TRUSTY_OS |
2447 | /* Trusty keymaster needs some parameters before it work */ | 2447 | /* Trusty keymaster needs some parameters before it work */ |
2448 | if (trusty_setbootparameter(hdr, avb_result, avb_out_data)) | 2448 | if (trusty_setbootparameter(hdr, avb_result, avb_out_data)) |
2449 | goto fail; | 2449 | goto fail; |
2450 | /* lock the boot status and rollback_idx preventing Linux modify it */ | 2450 | /* lock the boot status and rollback_idx preventing Linux modify it */ |
2451 | trusty_lock_boot_state(); | 2451 | trusty_lock_boot_state(); |
2452 | /* put ql-tipc to release resource for Linux */ | 2452 | /* put ql-tipc to release resource for Linux */ |
2453 | trusty_ipc_shutdown(); | 2453 | trusty_ipc_shutdown(); |
2454 | #endif | 2454 | #endif |
2455 | 2455 | ||
2456 | if (avb_out_data != NULL) | 2456 | if (avb_out_data != NULL) |
2457 | avb_slot_verify_data_free(avb_out_data); | 2457 | avb_slot_verify_data_free(avb_out_data); |
2458 | if (boot_buf != NULL) | 2458 | if (boot_buf != NULL) |
2459 | free(boot_buf); | 2459 | free(boot_buf); |
2460 | 2460 | ||
2461 | if (check_image_arm64) { | 2461 | if (check_image_arm64) { |
2462 | #ifdef CONFIG_CMD_BOOTI | 2462 | #ifdef CONFIG_CMD_BOOTI |
2463 | do_booti(NULL, 0, 4, boot_args); | 2463 | do_booti(NULL, 0, 4, boot_args); |
2464 | #else | 2464 | #else |
2465 | debug("please enable CONFIG_CMD_BOOTI when kernel are Image"); | 2465 | debug("please enable CONFIG_CMD_BOOTI when kernel are Image"); |
2466 | #endif | 2466 | #endif |
2467 | } else { | 2467 | } else { |
2468 | do_bootm(NULL, 0, 4, boot_args); | 2468 | do_bootm(NULL, 0, 4, boot_args); |
2469 | } | 2469 | } |
2470 | 2470 | ||
2471 | /* This only happens if image is somehow faulty so we start over */ | 2471 | /* This only happens if image is somehow faulty so we start over */ |
2472 | do_reset(NULL, 0, 0, NULL); | 2472 | do_reset(NULL, 0, 0, NULL); |
2473 | 2473 | ||
2474 | return 1; | 2474 | return 1; |
2475 | 2475 | ||
2476 | fail: | 2476 | fail: |
2477 | /* avb has no recovery */ | 2477 | /* avb has no recovery */ |
2478 | if (avb_out_data != NULL) | 2478 | if (avb_out_data != NULL) |
2479 | avb_slot_verify_data_free(avb_out_data); | 2479 | avb_slot_verify_data_free(avb_out_data); |
2480 | 2480 | ||
2481 | return run_command("fastboot 0", 0); | 2481 | return run_command("fastboot 0", 0); |
2482 | } | 2482 | } |
2483 | 2483 | ||
2484 | U_BOOT_CMD( | 2484 | U_BOOT_CMD( |
2485 | boota, 2, 1, do_boota, | 2485 | boota, 2, 1, do_boota, |
2486 | "boota - boot android bootimg \n", | 2486 | "boota - boot android bootimg \n", |
2487 | "boot from current mmc with avb verify\n" | 2487 | "boot from current mmc with avb verify\n" |
2488 | ); | 2488 | ); |
2489 | #else /* CONFIG_AVB_SUPPORT */ | 2489 | #else /* CONFIG_AVB_SUPPORT */ |
2490 | /* boota <addr> [ mmc0 | mmc1 [ <partition> ] ] */ | 2490 | /* boota <addr> [ mmc0 | mmc1 [ <partition> ] ] */ |
2491 | int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | 2491 | int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
2492 | { | 2492 | { |
2493 | ulong addr = 0; | 2493 | ulong addr = 0; |
2494 | char *ptn = "boot"; | 2494 | char *ptn = "boot"; |
2495 | int mmcc = -1; | 2495 | int mmcc = -1; |
2496 | struct andr_img_hdr *hdr = &boothdr; | 2496 | struct andr_img_hdr *hdr = &boothdr; |
2497 | ulong image_size; | 2497 | ulong image_size; |
2498 | bool check_image_arm64 = false; | 2498 | bool check_image_arm64 = false; |
2499 | int i = 0; | 2499 | int i = 0; |
2500 | 2500 | ||
2501 | for (i = 0; i < argc; i++) | 2501 | for (i = 0; i < argc; i++) |
2502 | printf("%s ", argv[i]); | 2502 | printf("%s ", argv[i]); |
2503 | printf("\n"); | 2503 | printf("\n"); |
2504 | 2504 | ||
2505 | if (argc < 2) | 2505 | if (argc < 2) |
2506 | return -1; | 2506 | return -1; |
2507 | 2507 | ||
2508 | mmcc = simple_strtoul(argv[1]+3, NULL, 10); | 2508 | mmcc = simple_strtoul(argv[1]+3, NULL, 10); |
2509 | 2509 | ||
2510 | if (argc > 2) | 2510 | if (argc > 2) |
2511 | ptn = argv[2]; | 2511 | ptn = argv[2]; |
2512 | 2512 | ||
2513 | if (mmcc != -1) { | 2513 | if (mmcc != -1) { |
2514 | #ifdef CONFIG_MMC | 2514 | #ifdef CONFIG_MMC |
2515 | struct fastboot_ptentry *pte; | 2515 | struct fastboot_ptentry *pte; |
2516 | struct mmc *mmc; | 2516 | struct mmc *mmc; |
2517 | disk_partition_t info; | 2517 | disk_partition_t info; |
2518 | struct blk_desc *dev_desc = NULL; | 2518 | struct blk_desc *dev_desc = NULL; |
2519 | unsigned bootimg_sectors; | 2519 | unsigned bootimg_sectors; |
2520 | 2520 | ||
2521 | memset((void *)&info, 0 , sizeof(disk_partition_t)); | 2521 | memset((void *)&info, 0 , sizeof(disk_partition_t)); |
2522 | /* i.MX use MBR as partition table, so this will have | 2522 | /* i.MX use MBR as partition table, so this will have |
2523 | to find the start block and length for the | 2523 | to find the start block and length for the |
2524 | partition name and register the fastboot pte we | 2524 | partition name and register the fastboot pte we |
2525 | define the partition number of each partition in | 2525 | define the partition number of each partition in |
2526 | config file | 2526 | config file |
2527 | */ | 2527 | */ |
2528 | mmc = find_mmc_device(mmcc); | 2528 | mmc = find_mmc_device(mmcc); |
2529 | if (!mmc) { | 2529 | if (!mmc) { |
2530 | printf("boota: cannot find '%d' mmc device\n", mmcc); | 2530 | printf("boota: cannot find '%d' mmc device\n", mmcc); |
2531 | goto fail; | 2531 | goto fail; |
2532 | } | 2532 | } |
2533 | dev_desc = blk_get_dev("mmc", mmcc); | 2533 | dev_desc = blk_get_dev("mmc", mmcc); |
2534 | if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { | 2534 | if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { |
2535 | printf("** Block device MMC %d not supported\n", mmcc); | 2535 | printf("** Block device MMC %d not supported\n", mmcc); |
2536 | goto fail; | 2536 | goto fail; |
2537 | } | 2537 | } |
2538 | 2538 | ||
2539 | /* below was i.MX mmc operation code */ | 2539 | /* below was i.MX mmc operation code */ |
2540 | if (mmc_init(mmc)) { | 2540 | if (mmc_init(mmc)) { |
2541 | printf("mmc%d init failed\n", mmcc); | 2541 | printf("mmc%d init failed\n", mmcc); |
2542 | goto fail; | 2542 | goto fail; |
2543 | } | 2543 | } |
2544 | 2544 | ||
2545 | pte = fastboot_flash_find_ptn(ptn); | 2545 | pte = fastboot_flash_find_ptn(ptn); |
2546 | if (!pte) { | 2546 | if (!pte) { |
2547 | printf("boota: cannot find '%s' partition\n", ptn); | 2547 | printf("boota: cannot find '%s' partition\n", ptn); |
2548 | fastboot_flash_dump_ptn(); | 2548 | fastboot_flash_dump_ptn(); |
2549 | goto fail; | 2549 | goto fail; |
2550 | } | 2550 | } |
2551 | 2551 | ||
2552 | if (blk_dread(dev_desc, pte->start, | 2552 | if (blk_dread(dev_desc, pte->start, |
2553 | 1, (void *)hdr) < 0) { | 2553 | 1, (void *)hdr) < 0) { |
2554 | printf("boota: mmc failed to read bootimg header\n"); | 2554 | printf("boota: mmc failed to read bootimg header\n"); |
2555 | goto fail; | 2555 | goto fail; |
2556 | } | 2556 | } |
2557 | 2557 | ||
2558 | if (android_image_check_header(hdr)) { | 2558 | if (android_image_check_header(hdr)) { |
2559 | printf("boota: bad boot image magic\n"); | 2559 | printf("boota: bad boot image magic\n"); |
2560 | goto fail; | 2560 | goto fail; |
2561 | } | 2561 | } |
2562 | 2562 | ||
2563 | image_size = android_image_get_end(hdr) - (ulong)hdr; | 2563 | image_size = android_image_get_end(hdr) - (ulong)hdr; |
2564 | bootimg_sectors = image_size/512; | 2564 | bootimg_sectors = image_size/512; |
2565 | 2565 | ||
2566 | if (blk_dread(dev_desc, pte->start, | 2566 | if (blk_dread(dev_desc, pte->start, |
2567 | bootimg_sectors, | 2567 | bootimg_sectors, |
2568 | (void *)(hdr->kernel_addr - hdr->page_size)) < 0) { | 2568 | (void *)(hdr->kernel_addr - hdr->page_size)) < 0) { |
2569 | printf("boota: mmc failed to read bootimage\n"); | 2569 | printf("boota: mmc failed to read bootimage\n"); |
2570 | goto fail; | 2570 | goto fail; |
2571 | } | 2571 | } |
2572 | check_image_arm64 = image_arm64((void *)hdr->kernel_addr); | 2572 | check_image_arm64 = image_arm64((void *)hdr->kernel_addr); |
2573 | #ifdef CONFIG_FASTBOOT_LOCK | 2573 | #ifdef CONFIG_FASTBOOT_LOCK |
2574 | int verifyresult = -1; | 2574 | int verifyresult = -1; |
2575 | #endif | 2575 | #endif |
2576 | 2576 | ||
2577 | #ifdef CONFIG_FASTBOOT_LOCK | 2577 | #ifdef CONFIG_FASTBOOT_LOCK |
2578 | int lock_status = fastboot_get_lock_stat(); | 2578 | int lock_status = fastboot_get_lock_stat(); |
2579 | if (lock_status == FASTBOOT_LOCK_ERROR) { | 2579 | if (lock_status == FASTBOOT_LOCK_ERROR) { |
2580 | printf("In boota get fastboot lock status error. Set lock status\n"); | 2580 | printf("In boota get fastboot lock status error. Set lock status\n"); |
2581 | fastboot_set_lock_stat(FASTBOOT_LOCK); | 2581 | fastboot_set_lock_stat(FASTBOOT_LOCK); |
2582 | } | 2582 | } |
2583 | display_lock(fastboot_get_lock_stat(), verifyresult); | 2583 | display_lock(fastboot_get_lock_stat(), verifyresult); |
2584 | #endif | 2584 | #endif |
2585 | /* load the ramdisk file */ | 2585 | /* load the ramdisk file */ |
2586 | memcpy((void *)hdr->ramdisk_addr, (void *)hdr->kernel_addr | 2586 | memcpy((void *)hdr->ramdisk_addr, (void *)hdr->kernel_addr |
2587 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); | 2587 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); |
2588 | 2588 | ||
2589 | #ifdef CONFIG_OF_LIBFDT | 2589 | #ifdef CONFIG_OF_LIBFDT |
2590 | u32 fdt_size = 0; | 2590 | u32 fdt_size = 0; |
2591 | /* load the dtb file */ | 2591 | /* load the dtb file */ |
2592 | if (hdr->second_addr) { | 2592 | if (hdr->second_addr) { |
2593 | u32 zimage_size = ((u32 *)hdrload->kernel_addr)[ZIMAGE_END_ADDR] | 2593 | u32 zimage_size = ((u32 *)hdrload->kernel_addr)[ZIMAGE_END_ADDR] |
2594 | - ((u32 *)hdrload->kernel_addr)[ZIMAGE_START_ADDR]; | 2594 | - ((u32 *)hdrload->kernel_addr)[ZIMAGE_START_ADDR]; |
2595 | fdt_size = hdrload->kernel_size - zimage_size; | 2595 | fdt_size = hdrload->kernel_size - zimage_size; |
2596 | memcpy((void *)(ulong)hdrload->second_addr, | 2596 | memcpy((void *)(ulong)hdrload->second_addr, |
2597 | (void*)(ulong)hdrload->kernel_addr + zimage_size, fdt_size); | 2597 | (void*)(ulong)hdrload->kernel_addr + zimage_size, fdt_size); |
2598 | } | 2598 | } |
2599 | #endif /*CONFIG_OF_LIBFDT*/ | 2599 | #endif /*CONFIG_OF_LIBFDT*/ |
2600 | 2600 | ||
2601 | #else /*! CONFIG_MMC*/ | 2601 | #else /*! CONFIG_MMC*/ |
2602 | return -1; | 2602 | return -1; |
2603 | #endif /*! CONFIG_MMC*/ | 2603 | #endif /*! CONFIG_MMC*/ |
2604 | } else { | 2604 | } else { |
2605 | printf("boota: parameters is invalid. only support mmcX device\n"); | 2605 | printf("boota: parameters is invalid. only support mmcX device\n"); |
2606 | return -1; | 2606 | return -1; |
2607 | } | 2607 | } |
2608 | 2608 | ||
2609 | printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size); | 2609 | printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size); |
2610 | printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size); | 2610 | printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size); |
2611 | #ifdef CONFIG_OF_LIBFDT | 2611 | #ifdef CONFIG_OF_LIBFDT |
2612 | if (fdt_size) | 2612 | if (fdt_size) |
2613 | printf("fdt @ %08x (%d)\n", hdr->second_addr, fdt_size); | 2613 | printf("fdt @ %08x (%d)\n", hdr->second_addr, fdt_size); |
2614 | #endif /*CONFIG_OF_LIBFDT*/ | 2614 | #endif /*CONFIG_OF_LIBFDT*/ |
2615 | 2615 | ||
2616 | 2616 | ||
2617 | char boot_addr_start[12]; | 2617 | char boot_addr_start[12]; |
2618 | char ramdisk_addr[25]; | 2618 | char ramdisk_addr[25]; |
2619 | char fdt_addr[12]; | 2619 | char fdt_addr[12]; |
2620 | char *boot_args[] = { NULL, boot_addr_start, ramdisk_addr, fdt_addr}; | 2620 | char *boot_args[] = { NULL, boot_addr_start, ramdisk_addr, fdt_addr}; |
2621 | if (check_image_arm64 ) { | 2621 | if (check_image_arm64 ) { |
2622 | addr = hdr->kernel_addr; | 2622 | addr = hdr->kernel_addr; |
2623 | boot_args[0] = "booti"; | 2623 | boot_args[0] = "booti"; |
2624 | } else { | 2624 | } else { |
2625 | addr = hdr->kernel_addr - hdr->page_size; | 2625 | addr = hdr->kernel_addr - hdr->page_size; |
2626 | boot_args[0] = "bootm"; | 2626 | boot_args[0] = "bootm"; |
2627 | } | 2627 | } |
2628 | 2628 | ||
2629 | sprintf(boot_addr_start, "0x%lx", addr); | 2629 | sprintf(boot_addr_start, "0x%lx", addr); |
2630 | sprintf(ramdisk_addr, "0x%x:0x%x", hdr->ramdisk_addr, hdr->ramdisk_size); | 2630 | sprintf(ramdisk_addr, "0x%x:0x%x", hdr->ramdisk_addr, hdr->ramdisk_size); |
2631 | sprintf(fdt_addr, "0x%x", hdr->second_addr); | 2631 | sprintf(fdt_addr, "0x%x", hdr->second_addr); |
2632 | if (check_image_arm64) { | 2632 | if (check_image_arm64) { |
2633 | android_image_get_kernel(hdr, 0, NULL, NULL); | 2633 | android_image_get_kernel(hdr, 0, NULL, NULL); |
2634 | #ifdef CONFIG_CMD_BOOTI | 2634 | #ifdef CONFIG_CMD_BOOTI |
2635 | do_booti(NULL, 0, 4, boot_args); | 2635 | do_booti(NULL, 0, 4, boot_args); |
2636 | #else | 2636 | #else |
2637 | debug("please enable CONFIG_CMD_BOOTI when kernel are Image"); | 2637 | debug("please enable CONFIG_CMD_BOOTI when kernel are Image"); |
2638 | #endif | 2638 | #endif |
2639 | } else { | 2639 | } else { |
2640 | do_bootm(NULL, 0, 4, boot_args); | 2640 | do_bootm(NULL, 0, 4, boot_args); |
2641 | } | 2641 | } |
2642 | /* This only happens if image is somehow faulty so we start over */ | 2642 | /* This only happens if image is somehow faulty so we start over */ |
2643 | do_reset(NULL, 0, 0, NULL); | 2643 | do_reset(NULL, 0, 0, NULL); |
2644 | 2644 | ||
2645 | return 1; | 2645 | return 1; |
2646 | 2646 | ||
2647 | fail: | 2647 | fail: |
2648 | #if defined(CONFIG_FSL_FASTBOOT) | 2648 | #if defined(CONFIG_FSL_FASTBOOT) |
2649 | return run_command("fastboot 0", 0); | 2649 | return run_command("fastboot 0", 0); |
2650 | #else /*! CONFIG_FSL_FASTBOOT*/ | 2650 | #else /*! CONFIG_FSL_FASTBOOT*/ |
2651 | return -1; | 2651 | return -1; |
2652 | #endif /*! CONFIG_FSL_FASTBOOT*/ | 2652 | #endif /*! CONFIG_FSL_FASTBOOT*/ |
2653 | } | 2653 | } |
2654 | 2654 | ||
2655 | U_BOOT_CMD( | 2655 | U_BOOT_CMD( |
2656 | boota, 3, 1, do_boota, | 2656 | boota, 3, 1, do_boota, |
2657 | "boota - boot android bootimg from memory\n", | 2657 | "boota - boot android bootimg from memory\n", |
2658 | "[<addr> | mmc0 | mmc1 | mmc2 | mmcX] [<partition>]\n " | 2658 | "[<addr> | mmc0 | mmc1 | mmc2 | mmcX] [<partition>]\n " |
2659 | "- boot application image stored in memory or mmc\n" | 2659 | "- boot application image stored in memory or mmc\n" |
2660 | "\t'addr' should be the address of boot image " | 2660 | "\t'addr' should be the address of boot image " |
2661 | "which is zImage+ramdisk.img\n" | 2661 | "which is zImage+ramdisk.img\n" |
2662 | "\t'mmcX' is the mmc device you store your boot.img, " | 2662 | "\t'mmcX' is the mmc device you store your boot.img, " |
2663 | "which will read the boot.img from 1M offset('/boot' partition)\n" | 2663 | "which will read the boot.img from 1M offset('/boot' partition)\n" |
2664 | "\t 'partition' (optional) is the partition id of your device, " | 2664 | "\t 'partition' (optional) is the partition id of your device, " |
2665 | "if no partition give, will going to 'boot' partition\n" | 2665 | "if no partition give, will going to 'boot' partition\n" |
2666 | ); | 2666 | ); |
2667 | #endif /* CONFIG_AVB_SUPPORT */ | 2667 | #endif /* CONFIG_AVB_SUPPORT */ |
2668 | #endif /* CONFIG_CMD_BOOTA */ | 2668 | #endif /* CONFIG_CMD_BOOTA */ |
2669 | #endif | 2669 | #endif |
2670 | 2670 | ||
2671 | void fastboot_fail(const char *reason) | 2671 | void fastboot_fail(const char *reason) |
2672 | { | 2672 | { |
2673 | strncpy(fb_response_str, "FAIL\0", 5); | 2673 | strncpy(fb_response_str, "FAIL\0", 5); |
2674 | strncat(fb_response_str, reason, FASTBOOT_RESPONSE_LEN - 4 - 1); | 2674 | strncat(fb_response_str, reason, FASTBOOT_RESPONSE_LEN - 4 - 1); |
2675 | } | 2675 | } |
2676 | 2676 | ||
2677 | void fastboot_okay(const char *reason) | 2677 | void fastboot_okay(const char *reason) |
2678 | { | 2678 | { |
2679 | strncpy(fb_response_str, "OKAY\0", 5); | 2679 | strncpy(fb_response_str, "OKAY\0", 5); |
2680 | strncat(fb_response_str, reason, FASTBOOT_RESPONSE_LEN - 4 - 1); | 2680 | strncat(fb_response_str, reason, FASTBOOT_RESPONSE_LEN - 4 - 1); |
2681 | } | 2681 | } |
2682 | 2682 | ||
2683 | static void fastboot_fifo_complete(struct usb_ep *ep, struct usb_request *req) | 2683 | static void fastboot_fifo_complete(struct usb_ep *ep, struct usb_request *req) |
2684 | { | 2684 | { |
2685 | int status = req->status; | 2685 | int status = req->status; |
2686 | usb_req *request; | 2686 | usb_req *request; |
2687 | 2687 | ||
2688 | if (!status) { | 2688 | if (!status) { |
2689 | if (fastboot_func->front != NULL) { | 2689 | if (fastboot_func->front != NULL) { |
2690 | request = fastboot_func->front; | 2690 | request = fastboot_func->front; |
2691 | fastboot_func->front = fastboot_func->front->next; | 2691 | fastboot_func->front = fastboot_func->front->next; |
2692 | usb_ep_free_request(ep, request->in_req); | 2692 | usb_ep_free_request(ep, request->in_req); |
2693 | free(request); | 2693 | free(request); |
2694 | } else { | 2694 | } else { |
2695 | printf("fail free request\n"); | 2695 | printf("fail free request\n"); |
2696 | } | 2696 | } |
2697 | return; | 2697 | return; |
2698 | } | 2698 | } |
2699 | } | 2699 | } |
2700 | 2700 | ||
2701 | static void fastboot_complete(struct usb_ep *ep, struct usb_request *req) | 2701 | static void fastboot_complete(struct usb_ep *ep, struct usb_request *req) |
2702 | { | 2702 | { |
2703 | int status = req->status; | 2703 | int status = req->status; |
2704 | if (!status) | 2704 | if (!status) |
2705 | return; | 2705 | return; |
2706 | printf("status: %d ep '%s' trans: %d\n", status, ep->name, req->actual); | 2706 | printf("status: %d ep '%s' trans: %d\n", status, ep->name, req->actual); |
2707 | } | 2707 | } |
2708 | 2708 | ||
2709 | static int fastboot_bind(struct usb_configuration *c, struct usb_function *f) | 2709 | static int fastboot_bind(struct usb_configuration *c, struct usb_function *f) |
2710 | { | 2710 | { |
2711 | int id; | 2711 | int id; |
2712 | struct usb_gadget *gadget = c->cdev->gadget; | 2712 | struct usb_gadget *gadget = c->cdev->gadget; |
2713 | struct f_fastboot *f_fb = func_to_fastboot(f); | 2713 | struct f_fastboot *f_fb = func_to_fastboot(f); |
2714 | const char *s; | 2714 | const char *s; |
2715 | 2715 | ||
2716 | /* DYNAMIC interface numbers assignments */ | 2716 | /* DYNAMIC interface numbers assignments */ |
2717 | id = usb_interface_id(c, f); | 2717 | id = usb_interface_id(c, f); |
2718 | if (id < 0) | 2718 | if (id < 0) |
2719 | return id; | 2719 | return id; |
2720 | interface_desc.bInterfaceNumber = id; | 2720 | interface_desc.bInterfaceNumber = id; |
2721 | 2721 | ||
2722 | /* Enable OS and Extended Properties Feature Descriptor */ | 2722 | /* Enable OS and Extended Properties Feature Descriptor */ |
2723 | c->cdev->use_os_string = 1; | 2723 | c->cdev->use_os_string = 1; |
2724 | f->os_desc_table = &fb_os_desc_table; | 2724 | f->os_desc_table = &fb_os_desc_table; |
2725 | f->os_desc_n = 1; | 2725 | f->os_desc_n = 1; |
2726 | f->os_desc_table->if_id = id; | 2726 | f->os_desc_table->if_id = id; |
2727 | INIT_LIST_HEAD(&fb_os_desc.ext_prop); | 2727 | INIT_LIST_HEAD(&fb_os_desc.ext_prop); |
2728 | fb_ext_prop.name_len = strlen(fb_ext_prop.name) * 2 + 2; | 2728 | fb_ext_prop.name_len = strlen(fb_ext_prop.name) * 2 + 2; |
2729 | fb_os_desc.ext_prop_len = 10 + fb_ext_prop.name_len; | 2729 | fb_os_desc.ext_prop_len = 10 + fb_ext_prop.name_len; |
2730 | fb_os_desc.ext_prop_count = 1; | 2730 | fb_os_desc.ext_prop_count = 1; |
2731 | fb_ext_prop.data_len = strlen(fb_ext_prop.data) * 2 + 2; | 2731 | fb_ext_prop.data_len = strlen(fb_ext_prop.data) * 2 + 2; |
2732 | fb_os_desc.ext_prop_len += fb_ext_prop.data_len + 4; | 2732 | fb_os_desc.ext_prop_len += fb_ext_prop.data_len + 4; |
2733 | list_add_tail(&fb_ext_prop.entry, &fb_os_desc.ext_prop); | 2733 | list_add_tail(&fb_ext_prop.entry, &fb_os_desc.ext_prop); |
2734 | 2734 | ||
2735 | id = usb_string_id(c->cdev); | 2735 | id = usb_string_id(c->cdev); |
2736 | if (id < 0) | 2736 | if (id < 0) |
2737 | return id; | 2737 | return id; |
2738 | fastboot_string_defs[0].id = id; | 2738 | fastboot_string_defs[0].id = id; |
2739 | interface_desc.iInterface = id; | 2739 | interface_desc.iInterface = id; |
2740 | 2740 | ||
2741 | f_fb->in_ep = usb_ep_autoconfig(gadget, &fs_ep_in); | 2741 | f_fb->in_ep = usb_ep_autoconfig(gadget, &fs_ep_in); |
2742 | if (!f_fb->in_ep) | 2742 | if (!f_fb->in_ep) |
2743 | return -ENODEV; | 2743 | return -ENODEV; |
2744 | f_fb->in_ep->driver_data = c->cdev; | 2744 | f_fb->in_ep->driver_data = c->cdev; |
2745 | 2745 | ||
2746 | f_fb->out_ep = usb_ep_autoconfig(gadget, &fs_ep_out); | 2746 | f_fb->out_ep = usb_ep_autoconfig(gadget, &fs_ep_out); |
2747 | if (!f_fb->out_ep) | 2747 | if (!f_fb->out_ep) |
2748 | return -ENODEV; | 2748 | return -ENODEV; |
2749 | f_fb->out_ep->driver_data = c->cdev; | 2749 | f_fb->out_ep->driver_data = c->cdev; |
2750 | 2750 | ||
2751 | f->descriptors = fb_fs_function; | 2751 | f->descriptors = fb_fs_function; |
2752 | 2752 | ||
2753 | if (gadget_is_dualspeed(gadget)) { | 2753 | if (gadget_is_dualspeed(gadget)) { |
2754 | /* Assume endpoint addresses are the same for both speeds */ | 2754 | /* Assume endpoint addresses are the same for both speeds */ |
2755 | hs_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress; | 2755 | hs_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress; |
2756 | hs_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress; | 2756 | hs_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress; |
2757 | /* copy HS descriptors */ | 2757 | /* copy HS descriptors */ |
2758 | f->hs_descriptors = fb_hs_function; | 2758 | f->hs_descriptors = fb_hs_function; |
2759 | } | 2759 | } |
2760 | 2760 | ||
2761 | s = env_get("serial#"); | 2761 | s = env_get("serial#"); |
2762 | if (s) | 2762 | if (s) |
2763 | g_dnl_set_serialnumber((char *)s); | 2763 | g_dnl_set_serialnumber((char *)s); |
2764 | 2764 | ||
2765 | return 0; | 2765 | return 0; |
2766 | } | 2766 | } |
2767 | 2767 | ||
2768 | static void fastboot_unbind(struct usb_configuration *c, struct usb_function *f) | 2768 | static void fastboot_unbind(struct usb_configuration *c, struct usb_function *f) |
2769 | { | 2769 | { |
2770 | f->os_desc_table = NULL; | 2770 | f->os_desc_table = NULL; |
2771 | list_del(&fb_os_desc.ext_prop); | 2771 | list_del(&fb_os_desc.ext_prop); |
2772 | memset(fastboot_func, 0, sizeof(*fastboot_func)); | 2772 | memset(fastboot_func, 0, sizeof(*fastboot_func)); |
2773 | } | 2773 | } |
2774 | 2774 | ||
2775 | static void fastboot_disable(struct usb_function *f) | 2775 | static void fastboot_disable(struct usb_function *f) |
2776 | { | 2776 | { |
2777 | usb_req *req; | 2777 | usb_req *req; |
2778 | struct f_fastboot *f_fb = func_to_fastboot(f); | 2778 | struct f_fastboot *f_fb = func_to_fastboot(f); |
2779 | 2779 | ||
2780 | usb_ep_disable(f_fb->out_ep); | 2780 | usb_ep_disable(f_fb->out_ep); |
2781 | usb_ep_disable(f_fb->in_ep); | 2781 | usb_ep_disable(f_fb->in_ep); |
2782 | 2782 | ||
2783 | if (f_fb->out_req) { | 2783 | if (f_fb->out_req) { |
2784 | free(f_fb->out_req->buf); | 2784 | free(f_fb->out_req->buf); |
2785 | usb_ep_free_request(f_fb->out_ep, f_fb->out_req); | 2785 | usb_ep_free_request(f_fb->out_ep, f_fb->out_req); |
2786 | f_fb->out_req = NULL; | 2786 | f_fb->out_req = NULL; |
2787 | } | 2787 | } |
2788 | if (f_fb->in_req) { | 2788 | if (f_fb->in_req) { |
2789 | free(f_fb->in_req->buf); | 2789 | free(f_fb->in_req->buf); |
2790 | usb_ep_free_request(f_fb->in_ep, f_fb->in_req); | 2790 | usb_ep_free_request(f_fb->in_ep, f_fb->in_req); |
2791 | 2791 | ||
2792 | /* disable usb request FIFO */ | 2792 | /* disable usb request FIFO */ |
2793 | while(f_fb->front != NULL) { | 2793 | while(f_fb->front != NULL) { |
2794 | req = f_fb->front; | 2794 | req = f_fb->front; |
2795 | f_fb->front = f_fb->front->next; | 2795 | f_fb->front = f_fb->front->next; |
2796 | free(req->in_req->buf); | 2796 | free(req->in_req->buf); |
2797 | usb_ep_free_request(f_fb->in_ep, req->in_req); | 2797 | usb_ep_free_request(f_fb->in_ep, req->in_req); |
2798 | free(req); | 2798 | free(req); |
2799 | } | 2799 | } |
2800 | 2800 | ||
2801 | f_fb->rear = NULL; | 2801 | f_fb->rear = NULL; |
2802 | f_fb->in_req = NULL; | 2802 | f_fb->in_req = NULL; |
2803 | } | 2803 | } |
2804 | } | 2804 | } |
2805 | 2805 | ||
2806 | static struct usb_request *fastboot_start_ep(struct usb_ep *ep) | 2806 | static struct usb_request *fastboot_start_ep(struct usb_ep *ep) |
2807 | { | 2807 | { |
2808 | struct usb_request *req; | 2808 | struct usb_request *req; |
2809 | 2809 | ||
2810 | req = usb_ep_alloc_request(ep, 0); | 2810 | req = usb_ep_alloc_request(ep, 0); |
2811 | if (!req) | 2811 | if (!req) |
2812 | return NULL; | 2812 | return NULL; |
2813 | 2813 | ||
2814 | req->length = EP_BUFFER_SIZE; | 2814 | req->length = EP_BUFFER_SIZE; |
2815 | req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, EP_BUFFER_SIZE); | 2815 | req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, EP_BUFFER_SIZE); |
2816 | if (!req->buf) { | 2816 | if (!req->buf) { |
2817 | usb_ep_free_request(ep, req); | 2817 | usb_ep_free_request(ep, req); |
2818 | return NULL; | 2818 | return NULL; |
2819 | } | 2819 | } |
2820 | 2820 | ||
2821 | memset(req->buf, 0, req->length); | 2821 | memset(req->buf, 0, req->length); |
2822 | return req; | 2822 | return req; |
2823 | } | 2823 | } |
2824 | 2824 | ||
2825 | static int fastboot_set_alt(struct usb_function *f, | 2825 | static int fastboot_set_alt(struct usb_function *f, |
2826 | unsigned interface, unsigned alt) | 2826 | unsigned interface, unsigned alt) |
2827 | { | 2827 | { |
2828 | int ret; | 2828 | int ret; |
2829 | struct usb_composite_dev *cdev = f->config->cdev; | 2829 | struct usb_composite_dev *cdev = f->config->cdev; |
2830 | struct usb_gadget *gadget = cdev->gadget; | 2830 | struct usb_gadget *gadget = cdev->gadget; |
2831 | struct f_fastboot *f_fb = func_to_fastboot(f); | 2831 | struct f_fastboot *f_fb = func_to_fastboot(f); |
2832 | const struct usb_endpoint_descriptor *d; | 2832 | const struct usb_endpoint_descriptor *d; |
2833 | 2833 | ||
2834 | debug("%s: func: %s intf: %d alt: %d\n", | 2834 | debug("%s: func: %s intf: %d alt: %d\n", |
2835 | __func__, f->name, interface, alt); | 2835 | __func__, f->name, interface, alt); |
2836 | 2836 | ||
2837 | d = fb_ep_desc(gadget, &fs_ep_out, &hs_ep_out); | 2837 | d = fb_ep_desc(gadget, &fs_ep_out, &hs_ep_out); |
2838 | ret = usb_ep_enable(f_fb->out_ep, d); | 2838 | ret = usb_ep_enable(f_fb->out_ep, d); |
2839 | if (ret) { | 2839 | if (ret) { |
2840 | puts("failed to enable out ep\n"); | 2840 | puts("failed to enable out ep\n"); |
2841 | return ret; | 2841 | return ret; |
2842 | } | 2842 | } |
2843 | 2843 | ||
2844 | f_fb->out_req = fastboot_start_ep(f_fb->out_ep); | 2844 | f_fb->out_req = fastboot_start_ep(f_fb->out_ep); |
2845 | if (!f_fb->out_req) { | 2845 | if (!f_fb->out_req) { |
2846 | puts("failed to alloc out req\n"); | 2846 | puts("failed to alloc out req\n"); |
2847 | ret = -EINVAL; | 2847 | ret = -EINVAL; |
2848 | goto err; | 2848 | goto err; |
2849 | } | 2849 | } |
2850 | f_fb->out_req->complete = rx_handler_command; | 2850 | f_fb->out_req->complete = rx_handler_command; |
2851 | 2851 | ||
2852 | d = fb_ep_desc(gadget, &fs_ep_in, &hs_ep_in); | 2852 | d = fb_ep_desc(gadget, &fs_ep_in, &hs_ep_in); |
2853 | ret = usb_ep_enable(f_fb->in_ep, d); | 2853 | ret = usb_ep_enable(f_fb->in_ep, d); |
2854 | if (ret) { | 2854 | if (ret) { |
2855 | puts("failed to enable in ep\n"); | 2855 | puts("failed to enable in ep\n"); |
2856 | goto err; | 2856 | goto err; |
2857 | } | 2857 | } |
2858 | 2858 | ||
2859 | f_fb->in_req = fastboot_start_ep(f_fb->in_ep); | 2859 | f_fb->in_req = fastboot_start_ep(f_fb->in_ep); |
2860 | if (!f_fb->in_req) { | 2860 | if (!f_fb->in_req) { |
2861 | puts("failed alloc req in\n"); | 2861 | puts("failed alloc req in\n"); |
2862 | ret = -EINVAL; | 2862 | ret = -EINVAL; |
2863 | goto err; | 2863 | goto err; |
2864 | } | 2864 | } |
2865 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT | 2865 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT |
2866 | /* | 2866 | /* |
2867 | * fastboot host end implement to get data in one bulk package so need | 2867 | * fastboot host end implement to get data in one bulk package so need |
2868 | * large buffer for the "fastboot upload" and "fastboot get_staged". | 2868 | * large buffer for the "fastboot upload" and "fastboot get_staged". |
2869 | */ | 2869 | */ |
2870 | if (f_fb->in_req->buf) | 2870 | if (f_fb->in_req->buf) |
2871 | free(f_fb->in_req->buf); | 2871 | free(f_fb->in_req->buf); |
2872 | f_fb->in_req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, EP_BUFFER_SIZE * 32); | 2872 | f_fb->in_req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, EP_BUFFER_SIZE * 32); |
2873 | #endif | 2873 | #endif |
2874 | f_fb->in_req->complete = fastboot_complete; | 2874 | f_fb->in_req->complete = fastboot_complete; |
2875 | 2875 | ||
2876 | f_fb->front = f_fb->rear = NULL; | 2876 | f_fb->front = f_fb->rear = NULL; |
2877 | 2877 | ||
2878 | ret = usb_ep_queue(f_fb->out_ep, f_fb->out_req, 0); | 2878 | ret = usb_ep_queue(f_fb->out_ep, f_fb->out_req, 0); |
2879 | if (ret) | 2879 | if (ret) |
2880 | goto err; | 2880 | goto err; |
2881 | 2881 | ||
2882 | return 0; | 2882 | return 0; |
2883 | err: | 2883 | err: |
2884 | fastboot_disable(f); | 2884 | fastboot_disable(f); |
2885 | return ret; | 2885 | return ret; |
2886 | } | 2886 | } |
2887 | 2887 | ||
2888 | static int fastboot_add(struct usb_configuration *c) | 2888 | static int fastboot_add(struct usb_configuration *c) |
2889 | { | 2889 | { |
2890 | struct f_fastboot *f_fb = fastboot_func; | 2890 | struct f_fastboot *f_fb = fastboot_func; |
2891 | int status; | 2891 | int status; |
2892 | 2892 | ||
2893 | debug("%s: cdev: 0x%p\n", __func__, c->cdev); | 2893 | debug("%s: cdev: 0x%p\n", __func__, c->cdev); |
2894 | 2894 | ||
2895 | if (!f_fb) { | 2895 | if (!f_fb) { |
2896 | f_fb = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*f_fb)); | 2896 | f_fb = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*f_fb)); |
2897 | if (!f_fb) | 2897 | if (!f_fb) |
2898 | return -ENOMEM; | 2898 | return -ENOMEM; |
2899 | 2899 | ||
2900 | fastboot_func = f_fb; | 2900 | fastboot_func = f_fb; |
2901 | memset(f_fb, 0, sizeof(*f_fb)); | 2901 | memset(f_fb, 0, sizeof(*f_fb)); |
2902 | } | 2902 | } |
2903 | 2903 | ||
2904 | f_fb->usb_function.name = "f_fastboot"; | 2904 | f_fb->usb_function.name = "f_fastboot"; |
2905 | f_fb->usb_function.bind = fastboot_bind; | 2905 | f_fb->usb_function.bind = fastboot_bind; |
2906 | f_fb->usb_function.unbind = fastboot_unbind; | 2906 | f_fb->usb_function.unbind = fastboot_unbind; |
2907 | f_fb->usb_function.set_alt = fastboot_set_alt; | 2907 | f_fb->usb_function.set_alt = fastboot_set_alt; |
2908 | f_fb->usb_function.disable = fastboot_disable; | 2908 | f_fb->usb_function.disable = fastboot_disable; |
2909 | f_fb->usb_function.strings = fastboot_strings; | 2909 | f_fb->usb_function.strings = fastboot_strings; |
2910 | 2910 | ||
2911 | status = usb_add_function(c, &f_fb->usb_function); | 2911 | status = usb_add_function(c, &f_fb->usb_function); |
2912 | if (status) { | 2912 | if (status) { |
2913 | free(f_fb); | 2913 | free(f_fb); |
2914 | fastboot_func = NULL; | 2914 | fastboot_func = NULL; |
2915 | } | 2915 | } |
2916 | 2916 | ||
2917 | return status; | 2917 | return status; |
2918 | } | 2918 | } |
2919 | DECLARE_GADGET_BIND_CALLBACK(usb_dnl_fastboot, fastboot_add); | 2919 | DECLARE_GADGET_BIND_CALLBACK(usb_dnl_fastboot, fastboot_add); |
2920 | 2920 | ||
2921 | static int fastboot_tx_write_more(const char *buffer) | 2921 | static int fastboot_tx_write_more(const char *buffer) |
2922 | { | 2922 | { |
2923 | int ret = 0; | 2923 | int ret = 0; |
2924 | 2924 | ||
2925 | /* alloc usb request FIFO node */ | 2925 | /* alloc usb request FIFO node */ |
2926 | usb_req *req = (usb_req *)malloc(sizeof(usb_req)); | 2926 | usb_req *req = (usb_req *)malloc(sizeof(usb_req)); |
2927 | if (!req) { | 2927 | if (!req) { |
2928 | printf("failed alloc usb req!\n"); | 2928 | printf("failed alloc usb req!\n"); |
2929 | return -ENOMEM; | 2929 | return -ENOMEM; |
2930 | } | 2930 | } |
2931 | 2931 | ||
2932 | /* usb request node FIFO enquene */ | 2932 | /* usb request node FIFO enquene */ |
2933 | if ((fastboot_func->front == NULL) && (fastboot_func->rear == NULL)) { | 2933 | if ((fastboot_func->front == NULL) && (fastboot_func->rear == NULL)) { |
2934 | fastboot_func->front = fastboot_func->rear = req; | 2934 | fastboot_func->front = fastboot_func->rear = req; |
2935 | req->next = NULL; | 2935 | req->next = NULL; |
2936 | } else { | 2936 | } else { |
2937 | fastboot_func->rear->next = req; | 2937 | fastboot_func->rear->next = req; |
2938 | fastboot_func->rear = req; | 2938 | fastboot_func->rear = req; |
2939 | req->next = NULL; | 2939 | req->next = NULL; |
2940 | } | 2940 | } |
2941 | 2941 | ||
2942 | /* alloc in request for current node */ | 2942 | /* alloc in request for current node */ |
2943 | req->in_req = fastboot_start_ep(fastboot_func->in_ep); | 2943 | req->in_req = fastboot_start_ep(fastboot_func->in_ep); |
2944 | if (!req->in_req) { | 2944 | if (!req->in_req) { |
2945 | printf("failed alloc req in\n"); | 2945 | printf("failed alloc req in\n"); |
2946 | fastboot_disable(&(fastboot_func->usb_function)); | 2946 | fastboot_disable(&(fastboot_func->usb_function)); |
2947 | return -EINVAL; | 2947 | return -EINVAL; |
2948 | } | 2948 | } |
2949 | req->in_req->complete = fastboot_fifo_complete; | 2949 | req->in_req->complete = fastboot_fifo_complete; |
2950 | 2950 | ||
2951 | memcpy(req->in_req->buf, buffer, strlen(buffer)); | 2951 | memcpy(req->in_req->buf, buffer, strlen(buffer)); |
2952 | req->in_req->length = strlen(buffer); | 2952 | req->in_req->length = strlen(buffer); |
2953 | 2953 | ||
2954 | ret = usb_ep_queue(fastboot_func->in_ep, req->in_req, 0); | 2954 | ret = usb_ep_queue(fastboot_func->in_ep, req->in_req, 0); |
2955 | if (ret) { | 2955 | if (ret) { |
2956 | printf("Error %d on queue\n", ret); | 2956 | printf("Error %d on queue\n", ret); |
2957 | return -EINVAL; | 2957 | return -EINVAL; |
2958 | } | 2958 | } |
2959 | 2959 | ||
2960 | ret = 0; | 2960 | ret = 0; |
2961 | return ret; | 2961 | return ret; |
2962 | } | 2962 | } |
2963 | 2963 | ||
2964 | static int fastboot_tx_write(const char *buffer, unsigned int buffer_size) | 2964 | static int fastboot_tx_write(const char *buffer, unsigned int buffer_size) |
2965 | { | 2965 | { |
2966 | struct usb_request *in_req = fastboot_func->in_req; | 2966 | struct usb_request *in_req = fastboot_func->in_req; |
2967 | int ret; | 2967 | int ret; |
2968 | 2968 | ||
2969 | memcpy(in_req->buf, buffer, buffer_size); | 2969 | memcpy(in_req->buf, buffer, buffer_size); |
2970 | in_req->length = buffer_size; | 2970 | in_req->length = buffer_size; |
2971 | 2971 | ||
2972 | usb_ep_dequeue(fastboot_func->in_ep, in_req); | 2972 | usb_ep_dequeue(fastboot_func->in_ep, in_req); |
2973 | 2973 | ||
2974 | ret = usb_ep_queue(fastboot_func->in_ep, in_req, 0); | 2974 | ret = usb_ep_queue(fastboot_func->in_ep, in_req, 0); |
2975 | if (ret) | 2975 | if (ret) |
2976 | printf("Error %d on queue\n", ret); | 2976 | printf("Error %d on queue\n", ret); |
2977 | return 0; | 2977 | return 0; |
2978 | } | 2978 | } |
2979 | 2979 | ||
2980 | static int fastboot_tx_write_str(const char *buffer) | 2980 | static int fastboot_tx_write_str(const char *buffer) |
2981 | { | 2981 | { |
2982 | return fastboot_tx_write(buffer, strlen(buffer)); | 2982 | return fastboot_tx_write(buffer, strlen(buffer)); |
2983 | } | 2983 | } |
2984 | 2984 | ||
2985 | static void compl_do_reset(struct usb_ep *ep, struct usb_request *req) | 2985 | static void compl_do_reset(struct usb_ep *ep, struct usb_request *req) |
2986 | { | 2986 | { |
2987 | do_reset(NULL, 0, 0, NULL); | 2987 | do_reset(NULL, 0, 0, NULL); |
2988 | } | 2988 | } |
2989 | 2989 | ||
2990 | int __weak fb_set_reboot_flag(void) | 2990 | int __weak fb_set_reboot_flag(void) |
2991 | { | 2991 | { |
2992 | return -ENOSYS; | 2992 | return -ENOSYS; |
2993 | } | 2993 | } |
2994 | 2994 | ||
2995 | static void cb_reboot(struct usb_ep *ep, struct usb_request *req) | 2995 | static void cb_reboot(struct usb_ep *ep, struct usb_request *req) |
2996 | { | 2996 | { |
2997 | char *cmd = req->buf; | 2997 | char *cmd = req->buf; |
2998 | if (!strcmp_l1("reboot-bootloader", cmd)) { | 2998 | if (!strcmp_l1("reboot-bootloader", cmd)) { |
2999 | if (fb_set_reboot_flag()) { | 2999 | if (fb_set_reboot_flag()) { |
3000 | fastboot_tx_write_str("FAILCannot set reboot flag"); | 3000 | fastboot_tx_write_str("FAILCannot set reboot flag"); |
3001 | return; | 3001 | return; |
3002 | } | 3002 | } |
3003 | } | 3003 | } |
3004 | fastboot_func->in_req->complete = compl_do_reset; | 3004 | fastboot_func->in_req->complete = compl_do_reset; |
3005 | fastboot_tx_write_str("OKAY"); | 3005 | fastboot_tx_write_str("OKAY"); |
3006 | } | 3006 | } |
3007 | 3007 | ||
3008 | static int strcmp_l1(const char *s1, const char *s2) | 3008 | static int strcmp_l1(const char *s1, const char *s2) |
3009 | { | 3009 | { |
3010 | if (!s1 || !s2) | 3010 | if (!s1 || !s2) |
3011 | return -1; | 3011 | return -1; |
3012 | return strncmp(s1, s2, strlen(s1)); | 3012 | return strncmp(s1, s2, strlen(s1)); |
3013 | } | 3013 | } |
3014 | 3014 | ||
3015 | #ifdef CONFIG_FSL_FASTBOOT | 3015 | #ifdef CONFIG_FSL_FASTBOOT |
3016 | static bool is_slotvar(char *cmd) | 3016 | static bool is_slotvar(char *cmd) |
3017 | { | 3017 | { |
3018 | assert(cmd != NULL); | 3018 | assert(cmd != NULL); |
3019 | if (!strcmp_l1("has-slot:", cmd) || | 3019 | if (!strcmp_l1("has-slot:", cmd) || |
3020 | !strcmp_l1("slot-successful:", cmd) || | 3020 | !strcmp_l1("slot-successful:", cmd) || |
3021 | !strcmp_l1("slot-count", cmd) || | 3021 | !strcmp_l1("slot-count", cmd) || |
3022 | !strcmp_l1("slot-suffixes", cmd) || | 3022 | !strcmp_l1("slot-suffixes", cmd) || |
3023 | !strcmp_l1("current-slot", cmd) || | 3023 | !strcmp_l1("current-slot", cmd) || |
3024 | !strcmp_l1("slot-unbootable:", cmd) || | 3024 | !strcmp_l1("slot-unbootable:", cmd) || |
3025 | !strcmp_l1("slot-retry-count:", cmd)) | 3025 | !strcmp_l1("slot-retry-count:", cmd)) |
3026 | return true; | 3026 | return true; |
3027 | return false; | 3027 | return false; |
3028 | } | 3028 | } |
3029 | 3029 | ||
3030 | static char *get_serial(void) | 3030 | static char *get_serial(void) |
3031 | { | 3031 | { |
3032 | #ifdef CONFIG_SERIAL_TAG | 3032 | #ifdef CONFIG_SERIAL_TAG |
3033 | struct tag_serialnr serialnr; | 3033 | struct tag_serialnr serialnr; |
3034 | static char serial[32]; | 3034 | static char serial[32]; |
3035 | get_board_serial(&serialnr); | 3035 | get_board_serial(&serialnr); |
3036 | sprintf(serial, "%08x%08x", serialnr.high, serialnr.low); | 3036 | sprintf(serial, "%08x%08x", serialnr.high, serialnr.low); |
3037 | return serial; | 3037 | return serial; |
3038 | #else | 3038 | #else |
3039 | return NULL; | 3039 | return NULL; |
3040 | #endif | 3040 | #endif |
3041 | } | 3041 | } |
3042 | 3042 | ||
3043 | #if !defined(PRODUCT_NAME) | 3043 | #if !defined(PRODUCT_NAME) |
3044 | #define PRODUCT_NAME "NXP i.MX" | 3044 | #define PRODUCT_NAME "NXP i.MX" |
3045 | #endif | 3045 | #endif |
3046 | 3046 | ||
3047 | #if !defined(VARIANT_NAME) | 3047 | #if !defined(VARIANT_NAME) |
3048 | #define VARIANT_NAME "NXP i.MX" | 3048 | #define VARIANT_NAME "NXP i.MX" |
3049 | #endif | 3049 | #endif |
3050 | 3050 | ||
3051 | static int get_block_size(void) { | 3051 | static int get_block_size(void) { |
3052 | int dev_no = 0; | 3052 | int dev_no = 0; |
3053 | struct blk_desc *dev_desc; | 3053 | struct blk_desc *dev_desc; |
3054 | 3054 | ||
3055 | dev_no = fastboot_devinfo.dev_id; | 3055 | dev_no = fastboot_devinfo.dev_id; |
3056 | dev_desc = blk_get_dev(fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", dev_no); | 3056 | dev_desc = blk_get_dev(fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", dev_no); |
3057 | if (NULL == dev_desc) { | 3057 | if (NULL == dev_desc) { |
3058 | printf("** Block device %s %d not supported\n", | 3058 | printf("** Block device %s %d not supported\n", |
3059 | fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", | 3059 | fastboot_devinfo.type == DEV_SATA ? "sata" : "mmc", |
3060 | dev_no); | 3060 | dev_no); |
3061 | return 0; | 3061 | return 0; |
3062 | } | 3062 | } |
3063 | return dev_desc->blksz; | 3063 | return dev_desc->blksz; |
3064 | } | 3064 | } |
3065 | 3065 | ||
3066 | static bool is_exist(char (*partition_base_name)[16], char *buffer, int count) | 3066 | static bool is_exist(char (*partition_base_name)[16], char *buffer, int count) |
3067 | { | 3067 | { |
3068 | int n; | 3068 | int n; |
3069 | 3069 | ||
3070 | for (n = 0; n < count; n++) { | 3070 | for (n = 0; n < count; n++) { |
3071 | if (!strcmp(partition_base_name[n],buffer)) | 3071 | if (!strcmp(partition_base_name[n],buffer)) |
3072 | return true; | 3072 | return true; |
3073 | } | 3073 | } |
3074 | return false; | 3074 | return false; |
3075 | } | 3075 | } |
3076 | /*get partition base name from gpt without "_a/_b"*/ | 3076 | /*get partition base name from gpt without "_a/_b"*/ |
3077 | static int get_partition_base_name(char (*partition_base_name)[16]) | 3077 | static int get_partition_base_name(char (*partition_base_name)[16]) |
3078 | { | 3078 | { |
3079 | int n = 0; | 3079 | int n = 0; |
3080 | int count = 0; | 3080 | int count = 0; |
3081 | char *ptr1, *ptr2; | 3081 | char *ptr1, *ptr2; |
3082 | char buffer[20]; | 3082 | char buffer[20]; |
3083 | 3083 | ||
3084 | for (n = 0; n < g_pcount; n++) { | 3084 | for (n = 0; n < g_pcount; n++) { |
3085 | strcpy(buffer,g_ptable[n].name); | 3085 | strcpy(buffer,g_ptable[n].name); |
3086 | ptr1 = strstr(buffer, "_a"); | 3086 | ptr1 = strstr(buffer, "_a"); |
3087 | ptr2 = strstr(buffer, "_b"); | 3087 | ptr2 = strstr(buffer, "_b"); |
3088 | if (ptr1 != NULL) { | 3088 | if (ptr1 != NULL) { |
3089 | *ptr1 = '\0'; | 3089 | *ptr1 = '\0'; |
3090 | if (!is_exist(partition_base_name,buffer,count)) { | 3090 | if (!is_exist(partition_base_name,buffer,count)) { |
3091 | strcpy(partition_base_name[count++],buffer); | 3091 | strcpy(partition_base_name[count++],buffer); |
3092 | } | 3092 | } |
3093 | } else if (ptr2 != NULL) { | 3093 | } else if (ptr2 != NULL) { |
3094 | *ptr2 = '\0'; | 3094 | *ptr2 = '\0'; |
3095 | if (!is_exist(partition_base_name,buffer,count)) { | 3095 | if (!is_exist(partition_base_name,buffer,count)) { |
3096 | strcpy(partition_base_name[count++],buffer); | 3096 | strcpy(partition_base_name[count++],buffer); |
3097 | } | 3097 | } |
3098 | } else { | 3098 | } else { |
3099 | strcpy(partition_base_name[count++],buffer); | 3099 | strcpy(partition_base_name[count++],buffer); |
3100 | } | 3100 | } |
3101 | } | 3101 | } |
3102 | return count; | 3102 | return count; |
3103 | } | 3103 | } |
3104 | 3104 | ||
3105 | static bool is_slot(void) | 3105 | static bool is_slot(void) |
3106 | { | 3106 | { |
3107 | char slot_suffix[2][5] = {"_a","_b"}; | 3107 | char slot_suffix[2][5] = {"_a","_b"}; |
3108 | int n; | 3108 | int n; |
3109 | 3109 | ||
3110 | for (n = 0; n < g_pcount; n++) { | 3110 | for (n = 0; n < g_pcount; n++) { |
3111 | if (strstr(g_ptable[n].name, slot_suffix[0]) || | 3111 | if (strstr(g_ptable[n].name, slot_suffix[0]) || |
3112 | strstr(g_ptable[n].name, slot_suffix[1])) | 3112 | strstr(g_ptable[n].name, slot_suffix[1])) |
3113 | return true; | 3113 | return true; |
3114 | } | 3114 | } |
3115 | return false; | 3115 | return false; |
3116 | } | 3116 | } |
3117 | #ifdef CONFIG_IMX_TRUSTY_OS | 3117 | #ifdef CONFIG_IMX_TRUSTY_OS |
3118 | static void uuid_hex2string(uint8_t *uuid, char* buf, uint32_t uuid_len, uint32_t uuid_strlen) { | 3118 | static void uuid_hex2string(uint8_t *uuid, char* buf, uint32_t uuid_len, uint32_t uuid_strlen) { |
3119 | uint32_t i; | 3119 | uint32_t i; |
3120 | if (!uuid || !buf) | 3120 | if (!uuid || !buf) |
3121 | return; | 3121 | return; |
3122 | char *cp = buf; | 3122 | char *cp = buf; |
3123 | char *buf_end = buf + uuid_strlen; | 3123 | char *buf_end = buf + uuid_strlen; |
3124 | for (i = 0; i < uuid_len; i++) { | 3124 | for (i = 0; i < uuid_len; i++) { |
3125 | cp += snprintf(cp, buf_end - cp, "%02x", uuid[i]); | 3125 | cp += snprintf(cp, buf_end - cp, "%02x", uuid[i]); |
3126 | } | 3126 | } |
3127 | } | 3127 | } |
3128 | #endif | 3128 | #endif |
3129 | 3129 | ||
3130 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) | 3130 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) |
3131 | int get_imx8m_baseboard_id(void); | 3131 | int get_imx8m_baseboard_id(void); |
3132 | #endif | 3132 | #endif |
3133 | 3133 | ||
3134 | static int get_single_var(char *cmd, char *response) | 3134 | static int get_single_var(char *cmd, char *response) |
3135 | { | 3135 | { |
3136 | char *str = cmd; | 3136 | char *str = cmd; |
3137 | int chars_left; | 3137 | int chars_left; |
3138 | const char *s; | 3138 | const char *s; |
3139 | struct mmc *mmc; | 3139 | struct mmc *mmc; |
3140 | int mmc_dev_no; | 3140 | int mmc_dev_no; |
3141 | int blksz; | 3141 | int blksz; |
3142 | 3142 | ||
3143 | chars_left = FASTBOOT_RESPONSE_LEN - strlen(response) - 1; | 3143 | chars_left = FASTBOOT_RESPONSE_LEN - strlen(response) - 1; |
3144 | 3144 | ||
3145 | if ((str = strstr(cmd, "partition-size:"))) { | 3145 | if ((str = strstr(cmd, "partition-size:"))) { |
3146 | str +=strlen("partition-size:"); | 3146 | str +=strlen("partition-size:"); |
3147 | struct fastboot_ptentry* fb_part; | 3147 | struct fastboot_ptentry* fb_part; |
3148 | fb_part = fastboot_flash_find_ptn(str); | 3148 | fb_part = fastboot_flash_find_ptn(str); |
3149 | if (!fb_part) { | 3149 | if (!fb_part) { |
3150 | strncat(response, "Wrong partition name.", chars_left); | 3150 | strncat(response, "Wrong partition name.", chars_left); |
3151 | fastboot_flash_dump_ptn(); | 3151 | fastboot_flash_dump_ptn(); |
3152 | return -1; | 3152 | return -1; |
3153 | } else { | 3153 | } else { |
3154 | snprintf(response + strlen(response), chars_left, | 3154 | snprintf(response + strlen(response), chars_left, |
3155 | "0x%llx", | 3155 | "0x%llx", |
3156 | (uint64_t)fb_part->length * get_block_size()); | 3156 | (uint64_t)fb_part->length * get_block_size()); |
3157 | } | 3157 | } |
3158 | } else if ((str = strstr(cmd, "partition-type:"))) { | 3158 | } else if ((str = strstr(cmd, "partition-type:"))) { |
3159 | str +=strlen("partition-type:"); | 3159 | str +=strlen("partition-type:"); |
3160 | struct fastboot_ptentry* fb_part; | 3160 | struct fastboot_ptentry* fb_part; |
3161 | fb_part = fastboot_flash_find_ptn(str); | 3161 | fb_part = fastboot_flash_find_ptn(str); |
3162 | if (!fb_part) { | 3162 | if (!fb_part) { |
3163 | strncat(response, "Wrong partition name.", chars_left); | 3163 | strncat(response, "Wrong partition name.", chars_left); |
3164 | fastboot_flash_dump_ptn(); | 3164 | fastboot_flash_dump_ptn(); |
3165 | return -1; | 3165 | return -1; |
3166 | } else { | 3166 | } else { |
3167 | strncat(response, fb_part->fstype, chars_left); | 3167 | strncat(response, fb_part->fstype, chars_left); |
3168 | } | 3168 | } |
3169 | } else if (!strcmp_l1("version-baseband", cmd)) { | 3169 | } else if (!strcmp_l1("version-baseband", cmd)) { |
3170 | strncat(response, "N/A", chars_left); | 3170 | strncat(response, "N/A", chars_left); |
3171 | } else if (!strcmp_l1("version-bootloader", cmd) || | 3171 | } else if (!strcmp_l1("version-bootloader", cmd) || |
3172 | !strcmp_l1("bootloader-version", cmd)) { | 3172 | !strcmp_l1("bootloader-version", cmd)) { |
3173 | strncat(response, U_BOOT_VERSION, chars_left); | 3173 | strncat(response, U_BOOT_VERSION, chars_left); |
3174 | } else if (!strcmp_l1("version", cmd)) { | 3174 | } else if (!strcmp_l1("version", cmd)) { |
3175 | strncat(response, FASTBOOT_VERSION, chars_left); | 3175 | strncat(response, FASTBOOT_VERSION, chars_left); |
3176 | } else if (!strcmp_l1("battery-voltage", cmd)) { | 3176 | } else if (!strcmp_l1("battery-voltage", cmd)) { |
3177 | strncat(response, "0mV", chars_left); | 3177 | strncat(response, "0mV", chars_left); |
3178 | } else if (!strcmp_l1("battery-soc-ok", cmd)) { | 3178 | } else if (!strcmp_l1("battery-soc-ok", cmd)) { |
3179 | strncat(response, "yes", chars_left); | 3179 | strncat(response, "yes", chars_left); |
3180 | } else if (!strcmp_l1("variant", cmd)) { | 3180 | } else if (!strcmp_l1("variant", cmd)) { |
3181 | strncat(response, VARIANT_NAME, chars_left); | 3181 | strncat(response, VARIANT_NAME, chars_left); |
3182 | } else if (!strcmp_l1("off-mode-charge", cmd)) { | 3182 | } else if (!strcmp_l1("off-mode-charge", cmd)) { |
3183 | strncat(response, "1", chars_left); | 3183 | strncat(response, "1", chars_left); |
3184 | } else if (!strcmp_l1("downloadsize", cmd) || | 3184 | } else if (!strcmp_l1("downloadsize", cmd) || |
3185 | !strcmp_l1("max-download-size", cmd)) { | 3185 | !strcmp_l1("max-download-size", cmd)) { |
3186 | 3186 | ||
3187 | snprintf(response + strlen(response), chars_left, "0x%x", CONFIG_FASTBOOT_BUF_SIZE); | 3187 | snprintf(response + strlen(response), chars_left, "0x%x", CONFIG_FASTBOOT_BUF_SIZE); |
3188 | } else if (!strcmp_l1("erase-block-size", cmd)) { | 3188 | } else if (!strcmp_l1("erase-block-size", cmd)) { |
3189 | mmc_dev_no = mmc_get_env_dev(); | 3189 | mmc_dev_no = mmc_get_env_dev(); |
3190 | mmc = find_mmc_device(mmc_dev_no); | 3190 | mmc = find_mmc_device(mmc_dev_no); |
3191 | blksz = get_block_size(); | 3191 | blksz = get_block_size(); |
3192 | snprintf(response + strlen(response), chars_left, "0x%x", | 3192 | snprintf(response + strlen(response), chars_left, "0x%x", |
3193 | (blksz * mmc->erase_grp_size)); | 3193 | (blksz * mmc->erase_grp_size)); |
3194 | } else if (!strcmp_l1("logical-block-size", cmd)) { | 3194 | } else if (!strcmp_l1("logical-block-size", cmd)) { |
3195 | blksz = get_block_size(); | 3195 | blksz = get_block_size(); |
3196 | snprintf(response + strlen(response), chars_left, "0x%x", blksz); | 3196 | snprintf(response + strlen(response), chars_left, "0x%x", blksz); |
3197 | } else if (!strcmp_l1("serialno", cmd)) { | 3197 | } else if (!strcmp_l1("serialno", cmd)) { |
3198 | s = get_serial(); | 3198 | s = get_serial(); |
3199 | if (s) | 3199 | if (s) |
3200 | strncat(response, s, chars_left); | 3200 | strncat(response, s, chars_left); |
3201 | else { | 3201 | else { |
3202 | strncat(response, "FAILValue not set", chars_left); | 3202 | strncat(response, "FAILValue not set", chars_left); |
3203 | return -1; | 3203 | return -1; |
3204 | } | 3204 | } |
3205 | } else if (!strcmp_l1("product", cmd)) { | 3205 | } else if (!strcmp_l1("product", cmd)) { |
3206 | strncat(response, PRODUCT_NAME, chars_left); | 3206 | strncat(response, PRODUCT_NAME, chars_left); |
3207 | } | 3207 | } |
3208 | #ifdef CONFIG_IMX_TRUSTY_OS | 3208 | #ifdef CONFIG_IMX_TRUSTY_OS |
3209 | else if(!strcmp_l1("at-attest-uuid", cmd)) { | 3209 | else if(!strcmp_l1("at-attest-uuid", cmd)) { |
3210 | char *uuid; | 3210 | char *uuid; |
3211 | char uuid_str[ATAP_UUID_STR_SIZE]; | 3211 | char uuid_str[ATAP_UUID_STR_SIZE]; |
3212 | if (trusty_atap_read_uuid_str(&uuid)) { | 3212 | if (trusty_atap_read_uuid_str(&uuid)) { |
3213 | printf("ERROR read uuid failed!\n"); | 3213 | printf("ERROR read uuid failed!\n"); |
3214 | strncat(response, "FAILCannot get uuid!", chars_left); | 3214 | strncat(response, "FAILCannot get uuid!", chars_left); |
3215 | return -1; | 3215 | return -1; |
3216 | } else { | 3216 | } else { |
3217 | uuid_hex2string((uint8_t*)uuid, uuid_str,ATAP_UUID_SIZE, ATAP_UUID_STR_SIZE); | 3217 | uuid_hex2string((uint8_t*)uuid, uuid_str,ATAP_UUID_SIZE, ATAP_UUID_STR_SIZE); |
3218 | strncat(response, uuid_str, chars_left); | 3218 | strncat(response, uuid_str, chars_left); |
3219 | trusty_free(uuid); | 3219 | trusty_free(uuid); |
3220 | } | 3220 | } |
3221 | } | 3221 | } |
3222 | else if(!strcmp_l1("at-attest-dh", cmd)) { | 3222 | else if(!strcmp_l1("at-attest-dh", cmd)) { |
3223 | strncat(response, "1:P256,2:curve25519", chars_left); | 3223 | strncat(response, "1:P256,2:curve25519", chars_left); |
3224 | } | 3224 | } |
3225 | #endif | 3225 | #endif |
3226 | #ifdef CONFIG_FASTBOOT_LOCK | 3226 | #ifdef CONFIG_FASTBOOT_LOCK |
3227 | else if (!strcmp_l1("secure", cmd)) { | 3227 | else if (!strcmp_l1("secure", cmd)) { |
3228 | strncat(response, FASTBOOT_VAR_YES, chars_left); | 3228 | strncat(response, FASTBOOT_VAR_YES, chars_left); |
3229 | } else if (!strcmp_l1("unlocked",cmd)){ | 3229 | } else if (!strcmp_l1("unlocked",cmd)){ |
3230 | int status = fastboot_get_lock_stat(); | 3230 | int status = fastboot_get_lock_stat(); |
3231 | if (status == FASTBOOT_UNLOCK) { | 3231 | if (status == FASTBOOT_UNLOCK) { |
3232 | strncat(response, FASTBOOT_VAR_YES, chars_left); | 3232 | strncat(response, FASTBOOT_VAR_YES, chars_left); |
3233 | } else { | 3233 | } else { |
3234 | strncat(response, FASTBOOT_VAR_NO, chars_left); | 3234 | strncat(response, FASTBOOT_VAR_NO, chars_left); |
3235 | } | 3235 | } |
3236 | } | 3236 | } |
3237 | #else | 3237 | #else |
3238 | else if (!strcmp_l1("secure", cmd)) { | 3238 | else if (!strcmp_l1("secure", cmd)) { |
3239 | strncat(response, FASTBOOT_VAR_NO, chars_left); | 3239 | strncat(response, FASTBOOT_VAR_NO, chars_left); |
3240 | } else if (!strcmp_l1("unlocked",cmd)) { | 3240 | } else if (!strcmp_l1("unlocked",cmd)) { |
3241 | strncat(response, FASTBOOT_VAR_NO, chars_left); | 3241 | strncat(response, FASTBOOT_VAR_NO, chars_left); |
3242 | } | 3242 | } |
3243 | #endif | 3243 | #endif |
3244 | else if (is_slotvar(cmd)) { | 3244 | else if (is_slotvar(cmd)) { |
3245 | #ifdef CONFIG_AVB_SUPPORT | 3245 | #ifdef CONFIG_AVB_SUPPORT |
3246 | if (get_slotvar_avb(&fsl_avb_ab_ops, cmd, | 3246 | if (get_slotvar_avb(&fsl_avb_ab_ops, cmd, |
3247 | response + strlen(response), chars_left + 1) < 0) | 3247 | response + strlen(response), chars_left + 1) < 0) |
3248 | return -1; | 3248 | return -1; |
3249 | #else | 3249 | #else |
3250 | strncat(response, FASTBOOT_VAR_NO, chars_left); | 3250 | strncat(response, FASTBOOT_VAR_NO, chars_left); |
3251 | #endif | 3251 | #endif |
3252 | } | 3252 | } |
3253 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) | 3253 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) && defined(CONFIG_ARCH_IMX8M) |
3254 | else if (!strcmp_l1("baseboard_id", cmd)) { | 3254 | else if (!strcmp_l1("baseboard_id", cmd)) { |
3255 | int baseboard_id; | 3255 | int baseboard_id; |
3256 | 3256 | ||
3257 | baseboard_id = get_imx8m_baseboard_id(); | 3257 | baseboard_id = get_imx8m_baseboard_id(); |
3258 | if (baseboard_id < 0) { | 3258 | if (baseboard_id < 0) { |
3259 | printf("Get baseboard id failed!\n"); | 3259 | printf("Get baseboard id failed!\n"); |
3260 | strncat(response, "Get baseboard id failed!", chars_left); | 3260 | strncat(response, "Get baseboard id failed!", chars_left); |
3261 | return -1; | 3261 | return -1; |
3262 | } else | 3262 | } else |
3263 | snprintf(response + strlen(response), chars_left, "0x%x", baseboard_id); | 3263 | snprintf(response + strlen(response), chars_left, "0x%x", baseboard_id); |
3264 | } | 3264 | } |
3265 | #endif | 3265 | #endif |
3266 | #ifdef CONFIG_AVB_ATX | 3266 | #ifdef CONFIG_AVB_ATX |
3267 | else if (!strcmp_l1("bootloader-locked", cmd)) { | 3267 | else if (!strcmp_l1("bootloader-locked", cmd)) { |
3268 | 3268 | ||
3269 | /* Below is basically copied from is_hab_enabled() */ | 3269 | /* Below is basically copied from is_hab_enabled() */ |
3270 | struct imx_sec_config_fuse_t *fuse = | 3270 | struct imx_sec_config_fuse_t *fuse = |
3271 | (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse; | 3271 | (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse; |
3272 | uint32_t reg; | 3272 | uint32_t reg; |
3273 | int ret; | 3273 | int ret; |
3274 | 3274 | ||
3275 | /* Read the secure boot status from fuse. */ | 3275 | /* Read the secure boot status from fuse. */ |
3276 | ret = fuse_read(fuse->bank, fuse->word, ®); | 3276 | ret = fuse_read(fuse->bank, fuse->word, ®); |
3277 | if (ret) { | 3277 | if (ret) { |
3278 | printf("\nSecure boot fuse read error!\n"); | 3278 | printf("\nSecure boot fuse read error!\n"); |
3279 | strncat(response, "Secure boot fuse read error!", chars_left); | 3279 | strncat(response, "Secure boot fuse read error!", chars_left); |
3280 | return -1; | 3280 | return -1; |
3281 | } | 3281 | } |
3282 | /* Check if the secure boot bit is enabled */ | 3282 | /* Check if the secure boot bit is enabled */ |
3283 | if ((reg & 0x2000000) == 0x2000000) | 3283 | if ((reg & 0x2000000) == 0x2000000) |
3284 | strncat(response, "1", chars_left); | 3284 | strncat(response, "1", chars_left); |
3285 | else | 3285 | else |
3286 | strncat(response, "0", chars_left); | 3286 | strncat(response, "0", chars_left); |
3287 | } else if (!strcmp_l1("bootloader-min-versions", cmd)) { | 3287 | } else if (!strcmp_l1("bootloader-min-versions", cmd)) { |
3288 | #ifndef CONFIG_ARM64 | 3288 | #ifndef CONFIG_ARM64 |
3289 | /* We don't support bootloader rbindex protection for | 3289 | /* We don't support bootloader rbindex protection for |
3290 | * ARM32(like imx7d) and the format is: "bootloader,tee". */ | 3290 | * ARM32(like imx7d) and the format is: "bootloader,tee". */ |
3291 | strncat(response, "-1,-1", chars_left); | 3291 | strncat(response, "-1,-1", chars_left); |
3292 | 3292 | ||
3293 | #elif defined(CONFIG_DUAL_BOOTLOADER) | 3293 | #elif defined(CONFIG_DUAL_BOOTLOADER) |
3294 | /* Rbindex protection for bootloader is supported only when the | 3294 | /* Rbindex protection for bootloader is supported only when the |
3295 | * 'dual bootloader' feature is enabled. U-boot will get the rbindx | 3295 | * 'dual bootloader' feature is enabled. U-boot will get the rbindx |
3296 | * from RAM which is passed by spl because we can only get the rbindex | 3296 | * from RAM which is passed by spl because we can only get the rbindex |
3297 | * at spl stage. The format in this case is: "spl,atf,tee,u-boot". | 3297 | * at spl stage. The format in this case is: "spl,atf,tee,u-boot". |
3298 | */ | 3298 | */ |
3299 | struct bl_rbindex_package *bl_rbindex; | 3299 | struct bl_rbindex_package *bl_rbindex; |
3300 | uint32_t rbindex; | 3300 | uint32_t rbindex; |
3301 | 3301 | ||
3302 | bl_rbindex = (struct bl_rbindex_package *)BL_RBINDEX_LOAD_ADDR; | 3302 | bl_rbindex = (struct bl_rbindex_package *)BL_RBINDEX_LOAD_ADDR; |
3303 | if (!strncmp(bl_rbindex->magic, BL_RBINDEX_MAGIC, | 3303 | if (!strncmp(bl_rbindex->magic, BL_RBINDEX_MAGIC, |
3304 | BL_RBINDEX_MAGIC_LEN)) { | 3304 | BL_RBINDEX_MAGIC_LEN)) { |
3305 | rbindex = bl_rbindex->rbindex; | 3305 | rbindex = bl_rbindex->rbindex; |
3306 | snprintf(response + strlen(response), chars_left, | 3306 | snprintf(response + strlen(response), chars_left, |
3307 | "-1,%d,%d,%d",rbindex, rbindex, rbindex); | 3307 | "-1,%d,%d,%d",rbindex, rbindex, rbindex); |
3308 | } else { | 3308 | } else { |
3309 | printf("Error bootloader rbindex magic!\n"); | 3309 | printf("Error bootloader rbindex magic!\n"); |
3310 | strncat(response, "Get bootloader rbindex fail!", chars_left); | 3310 | strncat(response, "Get bootloader rbindex fail!", chars_left); |
3311 | return -1; | 3311 | return -1; |
3312 | } | 3312 | } |
3313 | #else | 3313 | #else |
3314 | /* Return -1 for all partition if 'dual bootloader' feature | 3314 | /* Return -1 for all partition if 'dual bootloader' feature |
3315 | * is not enabled */ | 3315 | * is not enabled */ |
3316 | strncat(response, "-1,-1,-1,-1", chars_left); | 3316 | strncat(response, "-1,-1,-1,-1", chars_left); |
3317 | #endif | 3317 | #endif |
3318 | } else if (!strcmp_l1("avb-perm-attr-set", cmd)) { | 3318 | } else if (!strcmp_l1("avb-perm-attr-set", cmd)) { |
3319 | if (perm_attr_are_fused()) | 3319 | if (perm_attr_are_fused()) |
3320 | strncat(response, "1", chars_left); | 3320 | strncat(response, "1", chars_left); |
3321 | else | 3321 | else |
3322 | strncat(response, "0", chars_left); | 3322 | strncat(response, "0", chars_left); |
3323 | } else if (!strcmp_l1("avb-locked", cmd)) { | 3323 | } else if (!strcmp_l1("avb-locked", cmd)) { |
3324 | FbLockState status; | 3324 | FbLockState status; |
3325 | 3325 | ||
3326 | status = fastboot_get_lock_stat(); | 3326 | status = fastboot_get_lock_stat(); |
3327 | if (status == FASTBOOT_LOCK) | 3327 | if (status == FASTBOOT_LOCK) |
3328 | strncat(response, "1", chars_left); | 3328 | strncat(response, "1", chars_left); |
3329 | else if (status == FASTBOOT_UNLOCK) | 3329 | else if (status == FASTBOOT_UNLOCK) |
3330 | strncat(response, "0", chars_left); | 3330 | strncat(response, "0", chars_left); |
3331 | else { | 3331 | else { |
3332 | printf("Get lock state error!\n"); | 3332 | printf("Get lock state error!\n"); |
3333 | strncat(response, "Get lock state failed!", chars_left); | 3333 | strncat(response, "Get lock state failed!", chars_left); |
3334 | return -1; | 3334 | return -1; |
3335 | } | 3335 | } |
3336 | } else if (!strcmp_l1("avb-unlock-disabled", cmd)) { | 3336 | } else if (!strcmp_l1("avb-unlock-disabled", cmd)) { |
3337 | if (at_unlock_vboot_is_disabled()) | 3337 | if (at_unlock_vboot_is_disabled()) |
3338 | strncat(response, "1", chars_left); | 3338 | strncat(response, "1", chars_left); |
3339 | else | 3339 | else |
3340 | strncat(response, "0", chars_left); | 3340 | strncat(response, "0", chars_left); |
3341 | } else if (!strcmp_l1("avb-min-versions", cmd)) { | 3341 | } else if (!strcmp_l1("avb-min-versions", cmd)) { |
3342 | int i = 0; | 3342 | int i = 0; |
3343 | /* rbindex location/value can be very large | 3343 | /* rbindex location/value can be very large |
3344 | * number so we reserve enough space here. | 3344 | * number so we reserve enough space here. |
3345 | */ | 3345 | */ |
3346 | char buffer[35]; | 3346 | char buffer[35]; |
3347 | uint32_t rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 2]; | 3347 | uint32_t rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 2]; |
3348 | uint32_t location; | 3348 | uint32_t location; |
3349 | uint64_t rbindex; | 3349 | uint64_t rbindex; |
3350 | 3350 | ||
3351 | memset(buffer, '\0', sizeof(buffer)); | 3351 | memset(buffer, '\0', sizeof(buffer)); |
3352 | 3352 | ||
3353 | /* Set rbindex locations. */ | 3353 | /* Set rbindex locations. */ |
3354 | for (i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; i++) | 3354 | for (i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; i++) |
3355 | rbindex_location[i] = i; | 3355 | rbindex_location[i] = i; |
3356 | 3356 | ||
3357 | /* Set Android Things key version rbindex locations */ | 3357 | /* Set Android Things key version rbindex locations */ |
3358 | rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS] | 3358 | rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS] |
3359 | = AVB_ATX_PIK_VERSION_LOCATION; | 3359 | = AVB_ATX_PIK_VERSION_LOCATION; |
3360 | rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 1] | 3360 | rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 1] |
3361 | = AVB_ATX_PSK_VERSION_LOCATION; | 3361 | = AVB_ATX_PSK_VERSION_LOCATION; |
3362 | 3362 | ||
3363 | /* Read rollback index and set the reponse*/ | 3363 | /* Read rollback index and set the reponse*/ |
3364 | for (i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 2; i++) { | 3364 | for (i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 2; i++) { |
3365 | location = rbindex_location[i]; | 3365 | location = rbindex_location[i]; |
3366 | if (fsl_avb_ops.read_rollback_index(&fsl_avb_ops, | 3366 | if (fsl_avb_ops.read_rollback_index(&fsl_avb_ops, |
3367 | location, &rbindex) | 3367 | location, &rbindex) |
3368 | != AVB_IO_RESULT_OK) { | 3368 | != AVB_IO_RESULT_OK) { |
3369 | printf("Read rollback index error!\n"); | 3369 | printf("Read rollback index error!\n"); |
3370 | snprintf(response, sizeof(response), | 3370 | snprintf(response, sizeof(response), |
3371 | "INFOread rollback index error when get avb-min-versions"); | 3371 | "INFOread rollback index error when get avb-min-versions"); |
3372 | return -1; | 3372 | return -1; |
3373 | } | 3373 | } |
3374 | /* Generate the "location:value" pair */ | 3374 | /* Generate the "location:value" pair */ |
3375 | snprintf(buffer, sizeof(buffer), "%d:%lld", location, rbindex); | 3375 | snprintf(buffer, sizeof(buffer), "%d:%lld", location, rbindex); |
3376 | if (i != AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 1) | 3376 | if (i != AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 1) |
3377 | strncat(buffer, ",", strlen(",")); | 3377 | strncat(buffer, ",", strlen(",")); |
3378 | 3378 | ||
3379 | if ((chars_left - (int)strlen(buffer)) >= 0) { | 3379 | if ((chars_left - (int)strlen(buffer)) >= 0) { |
3380 | strncat(response, buffer, strlen(buffer)); | 3380 | strncat(response, buffer, strlen(buffer)); |
3381 | chars_left -= strlen(buffer); | 3381 | chars_left -= strlen(buffer); |
3382 | } else { | 3382 | } else { |
3383 | strncat(response, buffer, chars_left); | 3383 | strncat(response, buffer, chars_left); |
3384 | /* reponse buffer is full, send it first */ | 3384 | /* reponse buffer is full, send it first */ |
3385 | fastboot_tx_write_more(response); | 3385 | fastboot_tx_write_more(response); |
3386 | /* reset the reponse buffer for next round */ | 3386 | /* reset the reponse buffer for next round */ |
3387 | memset(response, '\0', sizeof(response)); | 3387 | memset(response, '\0', sizeof(response)); |
3388 | strncpy(response, "INFO", 5); | 3388 | strncpy(response, "INFO", 5); |
3389 | /* Copy left strings from 'buffer' to 'response' */ | 3389 | /* Copy left strings from 'buffer' to 'response' */ |
3390 | strncat(response, buffer + chars_left, strlen(buffer)); | 3390 | strncat(response, buffer + chars_left, strlen(buffer)); |
3391 | chars_left = FASTBOOT_RESPONSE_LEN - | 3391 | chars_left = FASTBOOT_RESPONSE_LEN - |
3392 | strlen(response) - 1; | 3392 | strlen(response) - 1; |
3393 | } | 3393 | } |
3394 | } | 3394 | } |
3395 | 3395 | ||
3396 | } | 3396 | } |
3397 | #endif | 3397 | #endif |
3398 | else { | 3398 | else { |
3399 | char envstr[32]; | 3399 | char envstr[32]; |
3400 | 3400 | ||
3401 | snprintf(envstr, sizeof(envstr) - 1, "fastboot.%s", cmd); | 3401 | snprintf(envstr, sizeof(envstr) - 1, "fastboot.%s", cmd); |
3402 | s = env_get(envstr); | 3402 | s = env_get(envstr); |
3403 | if (s) { | 3403 | if (s) { |
3404 | strncat(response, s, chars_left); | 3404 | strncat(response, s, chars_left); |
3405 | } else { | 3405 | } else { |
3406 | snprintf(response, chars_left, "FAILunknown variable:%s",cmd); | 3406 | snprintf(response, chars_left, "FAILunknown variable:%s",cmd); |
3407 | printf("WARNING: unknown variable: %s\n", cmd); | 3407 | printf("WARNING: unknown variable: %s\n", cmd); |
3408 | return -1; | 3408 | return -1; |
3409 | } | 3409 | } |
3410 | } | 3410 | } |
3411 | return 0; | 3411 | return 0; |
3412 | } | 3412 | } |
3413 | 3413 | ||
3414 | static void cb_getvar(struct usb_ep *ep, struct usb_request *req) | 3414 | static void cb_getvar(struct usb_ep *ep, struct usb_request *req) |
3415 | { | 3415 | { |
3416 | int n = 0; | 3416 | int n = 0; |
3417 | int status = 0; | 3417 | int status = 0; |
3418 | int count = 0; | 3418 | int count = 0; |
3419 | char *cmd = req->buf; | 3419 | char *cmd = req->buf; |
3420 | char var_name[FASTBOOT_RESPONSE_LEN]; | 3420 | char var_name[FASTBOOT_RESPONSE_LEN]; |
3421 | char partition_base_name[MAX_PTN][16]; | 3421 | char partition_base_name[MAX_PTN][16]; |
3422 | char slot_suffix[2][5] = {"a","b"}; | 3422 | char slot_suffix[2][5] = {"a","b"}; |
3423 | char response[FASTBOOT_RESPONSE_LEN]; | 3423 | char response[FASTBOOT_RESPONSE_LEN]; |
3424 | 3424 | ||
3425 | strsep(&cmd, ":"); | 3425 | strsep(&cmd, ":"); |
3426 | if (!cmd) { | 3426 | if (!cmd) { |
3427 | pr_err("missing variable"); | 3427 | pr_err("missing variable"); |
3428 | fastboot_tx_write_str("FAILmissing var"); | 3428 | fastboot_tx_write_str("FAILmissing var"); |
3429 | return; | 3429 | return; |
3430 | } | 3430 | } |
3431 | 3431 | ||
3432 | if (!strcmp_l1("all", cmd)) { | 3432 | if (!strcmp_l1("all", cmd)) { |
3433 | 3433 | ||
3434 | memset(response, '\0', FASTBOOT_RESPONSE_LEN); | 3434 | memset(response, '\0', FASTBOOT_RESPONSE_LEN); |
3435 | 3435 | ||
3436 | 3436 | ||
3437 | /* get common variables */ | 3437 | /* get common variables */ |
3438 | for (n = 0; n < FASTBOOT_COMMON_VAR_NUM; n++) { | 3438 | for (n = 0; n < FASTBOOT_COMMON_VAR_NUM; n++) { |
3439 | snprintf(response, sizeof(response), "INFO%s:", fastboot_common_var[n]); | 3439 | snprintf(response, sizeof(response), "INFO%s:", fastboot_common_var[n]); |
3440 | get_single_var(fastboot_common_var[n], response); | 3440 | get_single_var(fastboot_common_var[n], response); |
3441 | fastboot_tx_write_more(response); | 3441 | fastboot_tx_write_more(response); |
3442 | } | 3442 | } |
3443 | 3443 | ||
3444 | /* get at-vboot-state variables */ | 3444 | /* get at-vboot-state variables */ |
3445 | #ifdef CONFIG_AVB_ATX | 3445 | #ifdef CONFIG_AVB_ATX |
3446 | for (n = 0; n < AT_VBOOT_STATE_VAR_NUM; n++) { | 3446 | for (n = 0; n < AT_VBOOT_STATE_VAR_NUM; n++) { |
3447 | snprintf(response, sizeof(response), "INFO%s:", fastboot_at_vboot_state_var[n]); | 3447 | snprintf(response, sizeof(response), "INFO%s:", fastboot_at_vboot_state_var[n]); |
3448 | get_single_var(fastboot_at_vboot_state_var[n], response); | 3448 | get_single_var(fastboot_at_vboot_state_var[n], response); |
3449 | fastboot_tx_write_more(response); | 3449 | fastboot_tx_write_more(response); |
3450 | } | 3450 | } |
3451 | #endif | 3451 | #endif |
3452 | /* get partition type */ | 3452 | /* get partition type */ |
3453 | for (n = 0; n < g_pcount; n++) { | 3453 | for (n = 0; n < g_pcount; n++) { |
3454 | snprintf(response, sizeof(response), "INFOpartition-type:%s:", g_ptable[n].name); | 3454 | snprintf(response, sizeof(response), "INFOpartition-type:%s:", g_ptable[n].name); |
3455 | snprintf(var_name, sizeof(var_name), "partition-type:%s", g_ptable[n].name); | 3455 | snprintf(var_name, sizeof(var_name), "partition-type:%s", g_ptable[n].name); |
3456 | get_single_var(var_name, response); | 3456 | get_single_var(var_name, response); |
3457 | fastboot_tx_write_more(response); | 3457 | fastboot_tx_write_more(response); |
3458 | } | 3458 | } |
3459 | /* get partition size */ | 3459 | /* get partition size */ |
3460 | for (n = 0; n < g_pcount; n++) { | 3460 | for (n = 0; n < g_pcount; n++) { |
3461 | snprintf(response, sizeof(response), "INFOpartition-size:%s:", g_ptable[n].name); | 3461 | snprintf(response, sizeof(response), "INFOpartition-size:%s:", g_ptable[n].name); |
3462 | snprintf(var_name, sizeof(var_name), "partition-size:%s", g_ptable[n].name); | 3462 | snprintf(var_name, sizeof(var_name), "partition-size:%s", g_ptable[n].name); |
3463 | get_single_var(var_name,response); | 3463 | get_single_var(var_name,response); |
3464 | fastboot_tx_write_more(response); | 3464 | fastboot_tx_write_more(response); |
3465 | } | 3465 | } |
3466 | /* slot related variables */ | 3466 | /* slot related variables */ |
3467 | if (is_slot()) { | 3467 | if (is_slot()) { |
3468 | /* get has-slot variables */ | 3468 | /* get has-slot variables */ |
3469 | count = get_partition_base_name(partition_base_name); | 3469 | count = get_partition_base_name(partition_base_name); |
3470 | for (n = 0; n < count; n++) { | 3470 | for (n = 0; n < count; n++) { |
3471 | snprintf(response, sizeof(response), "INFOhas-slot:%s:", partition_base_name[n]); | 3471 | snprintf(response, sizeof(response), "INFOhas-slot:%s:", partition_base_name[n]); |
3472 | snprintf(var_name, sizeof(var_name), "has-slot:%s", partition_base_name[n]); | 3472 | snprintf(var_name, sizeof(var_name), "has-slot:%s", partition_base_name[n]); |
3473 | get_single_var(var_name,response); | 3473 | get_single_var(var_name,response); |
3474 | fastboot_tx_write_more(response); | 3474 | fastboot_tx_write_more(response); |
3475 | } | 3475 | } |
3476 | /* get current slot */ | 3476 | /* get current slot */ |
3477 | strncpy(response, "INFOcurrent-slot:", sizeof(response)); | 3477 | strncpy(response, "INFOcurrent-slot:", sizeof(response)); |
3478 | get_single_var("current-slot", response); | 3478 | get_single_var("current-slot", response); |
3479 | fastboot_tx_write_more(response); | 3479 | fastboot_tx_write_more(response); |
3480 | /* get slot count */ | 3480 | /* get slot count */ |
3481 | strncpy(response, "INFOslot-count:", sizeof(response)); | 3481 | strncpy(response, "INFOslot-count:", sizeof(response)); |
3482 | get_single_var("slot-count", response); | 3482 | get_single_var("slot-count", response); |
3483 | fastboot_tx_write_more(response); | 3483 | fastboot_tx_write_more(response); |
3484 | /* get slot-successful variable */ | 3484 | /* get slot-successful variable */ |
3485 | for (n = 0; n < 2; n++) { | 3485 | for (n = 0; n < 2; n++) { |
3486 | snprintf(response, sizeof(response), "INFOslot-successful:%s:", slot_suffix[n]); | 3486 | snprintf(response, sizeof(response), "INFOslot-successful:%s:", slot_suffix[n]); |
3487 | snprintf(var_name, sizeof(var_name), "slot-successful:%s", slot_suffix[n]); | 3487 | snprintf(var_name, sizeof(var_name), "slot-successful:%s", slot_suffix[n]); |
3488 | get_single_var(var_name, response); | 3488 | get_single_var(var_name, response); |
3489 | fastboot_tx_write_more(response); | 3489 | fastboot_tx_write_more(response); |
3490 | } | 3490 | } |
3491 | /*get slot-unbootable variable*/ | 3491 | /*get slot-unbootable variable*/ |
3492 | for (n = 0; n < 2; n++) { | 3492 | for (n = 0; n < 2; n++) { |
3493 | snprintf(response, sizeof(response), "INFOslot-unbootable:%s:", slot_suffix[n]); | 3493 | snprintf(response, sizeof(response), "INFOslot-unbootable:%s:", slot_suffix[n]); |
3494 | snprintf(var_name, sizeof(var_name), "slot-unbootable:%s", slot_suffix[n]); | 3494 | snprintf(var_name, sizeof(var_name), "slot-unbootable:%s", slot_suffix[n]); |
3495 | get_single_var(var_name, response); | 3495 | get_single_var(var_name, response); |
3496 | fastboot_tx_write_more(response); | 3496 | fastboot_tx_write_more(response); |
3497 | } | 3497 | } |
3498 | /*get slot-retry-count variable*/ | 3498 | /*get slot-retry-count variable*/ |
3499 | for (n = 0; n < 2; n++) { | 3499 | for (n = 0; n < 2; n++) { |
3500 | snprintf(response, sizeof(response), "INFOslot-retry-count:%s:", slot_suffix[n]); | 3500 | snprintf(response, sizeof(response), "INFOslot-retry-count:%s:", slot_suffix[n]); |
3501 | snprintf(var_name, sizeof(var_name), "slot-retry-count:%s", slot_suffix[n]); | 3501 | snprintf(var_name, sizeof(var_name), "slot-retry-count:%s", slot_suffix[n]); |
3502 | get_single_var(var_name, response); | 3502 | get_single_var(var_name, response); |
3503 | fastboot_tx_write_more(response); | 3503 | fastboot_tx_write_more(response); |
3504 | } | 3504 | } |
3505 | } | 3505 | } |
3506 | 3506 | ||
3507 | strncpy(response, "OKAYDone!", 10); | 3507 | strncpy(response, "OKAYDone!", 10); |
3508 | fastboot_tx_write_more(response); | 3508 | fastboot_tx_write_more(response); |
3509 | 3509 | ||
3510 | return; | 3510 | return; |
3511 | } | 3511 | } |
3512 | #ifdef CONFIG_AVB_ATX | 3512 | #ifdef CONFIG_AVB_ATX |
3513 | else if (!strcmp_l1("at-vboot-state", cmd)) { | 3513 | else if (!strcmp_l1("at-vboot-state", cmd)) { |
3514 | /* get at-vboot-state variables */ | 3514 | /* get at-vboot-state variables */ |
3515 | for (n = 0; n < AT_VBOOT_STATE_VAR_NUM; n++) { | 3515 | for (n = 0; n < AT_VBOOT_STATE_VAR_NUM; n++) { |
3516 | snprintf(response, sizeof(response), "INFO%s:", fastboot_at_vboot_state_var[n]); | 3516 | snprintf(response, sizeof(response), "INFO%s:", fastboot_at_vboot_state_var[n]); |
3517 | get_single_var(fastboot_at_vboot_state_var[n], response); | 3517 | get_single_var(fastboot_at_vboot_state_var[n], response); |
3518 | fastboot_tx_write_more(response); | 3518 | fastboot_tx_write_more(response); |
3519 | } | 3519 | } |
3520 | 3520 | ||
3521 | strncpy(response, "OKAY", 5); | 3521 | strncpy(response, "OKAY", 5); |
3522 | fastboot_tx_write_more(response); | 3522 | fastboot_tx_write_more(response); |
3523 | 3523 | ||
3524 | return; | 3524 | return; |
3525 | } else if ((!strcmp_l1("bootloader-locked", cmd)) || | 3525 | } else if ((!strcmp_l1("bootloader-locked", cmd)) || |
3526 | (!strcmp_l1("bootloader-min-versions", cmd)) || | 3526 | (!strcmp_l1("bootloader-min-versions", cmd)) || |
3527 | (!strcmp_l1("avb-perm-attr-set", cmd)) || | 3527 | (!strcmp_l1("avb-perm-attr-set", cmd)) || |
3528 | (!strcmp_l1("avb-locked", cmd)) || | 3528 | (!strcmp_l1("avb-locked", cmd)) || |
3529 | (!strcmp_l1("avb-unlock-disabled", cmd)) || | 3529 | (!strcmp_l1("avb-unlock-disabled", cmd)) || |
3530 | (!strcmp_l1("avb-min-versions", cmd))) { | 3530 | (!strcmp_l1("avb-min-versions", cmd))) { |
3531 | 3531 | ||
3532 | printf("Can't get this variable alone, get 'at-vboot-state' instead!\n"); | 3532 | printf("Can't get this variable alone, get 'at-vboot-state' instead!\n"); |
3533 | snprintf(response, sizeof(response), | 3533 | snprintf(response, sizeof(response), |
3534 | "FAILCan't get this variable alone, get 'at-vboot-state' instead."); | 3534 | "FAILCan't get this variable alone, get 'at-vboot-state' instead."); |
3535 | fastboot_tx_write_str(response); | 3535 | fastboot_tx_write_str(response); |
3536 | return; | 3536 | return; |
3537 | } | 3537 | } |
3538 | #endif | 3538 | #endif |
3539 | else { | 3539 | else { |
3540 | 3540 | ||
3541 | strncpy(response, "OKAY", 5); | 3541 | strncpy(response, "OKAY", 5); |
3542 | status = get_single_var(cmd, response); | 3542 | status = get_single_var(cmd, response); |
3543 | if (status != 0) { | 3543 | if (status != 0) { |
3544 | strncpy(response, "FAIL", 5); | 3544 | strncpy(response, "FAIL", 5); |
3545 | } | 3545 | } |
3546 | fastboot_tx_write_str(response); | 3546 | fastboot_tx_write_str(response); |
3547 | return; | 3547 | return; |
3548 | } | 3548 | } |
3549 | } | 3549 | } |
3550 | 3550 | ||
3551 | #ifdef CONFIG_FASTBOOT_LOCK | 3551 | #ifdef CONFIG_FASTBOOT_LOCK |
3552 | 3552 | ||
3553 | int do_lock_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { | 3553 | int do_lock_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { |
3554 | FbLockState status = fastboot_get_lock_stat(); | 3554 | FbLockState status = fastboot_get_lock_stat(); |
3555 | if (status != FASTBOOT_LOCK_ERROR) { | 3555 | if (status != FASTBOOT_LOCK_ERROR) { |
3556 | if (status == FASTBOOT_LOCK) | 3556 | if (status == FASTBOOT_LOCK) |
3557 | printf("fastboot lock status: locked.\n"); | 3557 | printf("fastboot lock status: locked.\n"); |
3558 | else | 3558 | else |
3559 | printf("fastboot lock status: unlocked.\n"); | 3559 | printf("fastboot lock status: unlocked.\n"); |
3560 | } else | 3560 | } else |
3561 | printf("fastboot lock status error!\n"); | 3561 | printf("fastboot lock status error!\n"); |
3562 | 3562 | ||
3563 | display_lock(status, -1); | 3563 | display_lock(status, -1); |
3564 | 3564 | ||
3565 | return 0; | 3565 | return 0; |
3566 | 3566 | ||
3567 | } | 3567 | } |
3568 | 3568 | ||
3569 | U_BOOT_CMD( | 3569 | U_BOOT_CMD( |
3570 | lock_status, 2, 1, do_lock_status, | 3570 | lock_status, 2, 1, do_lock_status, |
3571 | "lock_status", | 3571 | "lock_status", |
3572 | "lock_status"); | 3572 | "lock_status"); |
3573 | 3573 | ||
3574 | static void wipe_all_userdata(void) | 3574 | static void wipe_all_userdata(void) |
3575 | { | 3575 | { |
3576 | char response[FASTBOOT_RESPONSE_LEN]; | 3576 | char response[FASTBOOT_RESPONSE_LEN]; |
3577 | 3577 | ||
3578 | /* Erase all user data */ | 3578 | /* Erase all user data */ |
3579 | printf("Start userdata wipe process....\n"); | 3579 | printf("Start userdata wipe process....\n"); |
3580 | /* Erase /data partition */ | 3580 | /* Erase /data partition */ |
3581 | fastboot_wipe_data_partition(); | 3581 | fastboot_wipe_data_partition(); |
3582 | 3582 | ||
3583 | #ifdef CONFIG_ANDROID_SUPPORT | 3583 | #ifdef CONFIG_ANDROID_SUPPORT |
3584 | /* Erase the misc partition. */ | 3584 | /* Erase the misc partition. */ |
3585 | process_erase_mmc(FASTBOOT_PARTITION_MISC, response); | 3585 | process_erase_mmc(FASTBOOT_PARTITION_MISC, response); |
3586 | #endif | 3586 | #endif |
3587 | 3587 | ||
3588 | #ifndef CONFIG_ANDROID_AB_SUPPORT | 3588 | #ifndef CONFIG_ANDROID_AB_SUPPORT |
3589 | /* Erase the cache partition for legacy imx6/7 */ | 3589 | /* Erase the cache partition for legacy imx6/7 */ |
3590 | process_erase_mmc(FASTBOOT_PARTITION_CACHE, response); | 3590 | process_erase_mmc(FASTBOOT_PARTITION_CACHE, response); |
3591 | #endif | 3591 | #endif |
3592 | /* The unlock permissive flag is set by user and should be wiped here. */ | 3592 | /* The unlock permissive flag is set by user and should be wiped here. */ |
3593 | set_fastboot_lock_disable(); | 3593 | set_fastboot_lock_disable(); |
3594 | 3594 | ||
3595 | 3595 | ||
3596 | #if defined(AVB_RPMB) && !defined(CONFIG_IMX_TRUSTY_OS) | 3596 | #if defined(AVB_RPMB) && !defined(CONFIG_IMX_TRUSTY_OS) |
3597 | printf("Start stored_rollback_index wipe process....\n"); | 3597 | printf("Start stored_rollback_index wipe process....\n"); |
3598 | rbkidx_erase(); | 3598 | rbkidx_erase(); |
3599 | printf("Wipe stored_rollback_index completed.\n"); | 3599 | printf("Wipe stored_rollback_index completed.\n"); |
3600 | #endif | 3600 | #endif |
3601 | printf("Wipe userdata completed.\n"); | 3601 | printf("Wipe userdata completed.\n"); |
3602 | } | 3602 | } |
3603 | 3603 | ||
3604 | static FbLockState do_fastboot_unlock(bool force) | 3604 | static FbLockState do_fastboot_unlock(bool force) |
3605 | { | 3605 | { |
3606 | int status; | 3606 | int status; |
3607 | 3607 | ||
3608 | if (fastboot_get_lock_stat() == FASTBOOT_UNLOCK) { | ||
3609 | printf("The device is already unlocked\n"); | ||
3610 | return FASTBOOT_UNLOCK; | ||
3611 | } | ||
3608 | if ((fastboot_lock_enable() == FASTBOOT_UL_ENABLE) || force) { | 3612 | if ((fastboot_lock_enable() == FASTBOOT_UL_ENABLE) || force) { |
3609 | printf("It is able to unlock device. %d\n",fastboot_lock_enable()); | 3613 | printf("It is able to unlock device. %d\n",fastboot_lock_enable()); |
3610 | if (fastboot_get_lock_stat() == FASTBOOT_UNLOCK) { | ||
3611 | printf("The device is already unlocked\n"); | ||
3612 | return FASTBOOT_UNLOCK; | ||
3613 | } | ||
3614 | status = fastboot_set_lock_stat(FASTBOOT_UNLOCK); | 3614 | status = fastboot_set_lock_stat(FASTBOOT_UNLOCK); |
3615 | if (status < 0) | 3615 | if (status < 0) |
3616 | return FASTBOOT_LOCK_ERROR; | 3616 | return FASTBOOT_LOCK_ERROR; |
3617 | 3617 | ||
3618 | wipe_all_userdata(); | 3618 | wipe_all_userdata(); |
3619 | 3619 | ||
3620 | } else { | 3620 | } else { |
3621 | printf("It is not able to unlock device."); | 3621 | printf("It is not able to unlock device."); |
3622 | return FASTBOOT_LOCK_ERROR; | 3622 | return FASTBOOT_LOCK_ERROR; |
3623 | } | 3623 | } |
3624 | 3624 | ||
3625 | return FASTBOOT_UNLOCK; | 3625 | return FASTBOOT_UNLOCK; |
3626 | } | 3626 | } |
3627 | 3627 | ||
3628 | static FbLockState do_fastboot_lock(void) | 3628 | static FbLockState do_fastboot_lock(void) |
3629 | { | 3629 | { |
3630 | int status; | 3630 | int status; |
3631 | 3631 | ||
3632 | if (fastboot_get_lock_stat() == FASTBOOT_LOCK) { | 3632 | if (fastboot_get_lock_stat() == FASTBOOT_LOCK) { |
3633 | printf("The device is already locked\n"); | 3633 | printf("The device is already locked\n"); |
3634 | return FASTBOOT_LOCK; | 3634 | return FASTBOOT_LOCK; |
3635 | } | 3635 | } |
3636 | status = fastboot_set_lock_stat(FASTBOOT_LOCK); | 3636 | status = fastboot_set_lock_stat(FASTBOOT_LOCK); |
3637 | if (status < 0) | 3637 | if (status < 0) |
3638 | return FASTBOOT_LOCK_ERROR; | 3638 | return FASTBOOT_LOCK_ERROR; |
3639 | 3639 | ||
3640 | wipe_all_userdata(); | 3640 | wipe_all_userdata(); |
3641 | 3641 | ||
3642 | return FASTBOOT_LOCK; | 3642 | return FASTBOOT_LOCK; |
3643 | } | 3643 | } |
3644 | 3644 | ||
3645 | static bool endswith(char* s, char* subs) { | 3645 | static bool endswith(char* s, char* subs) { |
3646 | if (!s || !subs) | 3646 | if (!s || !subs) |
3647 | return false; | 3647 | return false; |
3648 | uint32_t len = strlen(s); | 3648 | uint32_t len = strlen(s); |
3649 | uint32_t sublen = strlen(subs); | 3649 | uint32_t sublen = strlen(subs); |
3650 | if (len < sublen) { | 3650 | if (len < sublen) { |
3651 | return false; | 3651 | return false; |
3652 | } | 3652 | } |
3653 | if (strncmp(s + len - sublen, subs, sublen)) { | 3653 | if (strncmp(s + len - sublen, subs, sublen)) { |
3654 | return false; | 3654 | return false; |
3655 | } | 3655 | } |
3656 | return true; | 3656 | return true; |
3657 | } | 3657 | } |
3658 | 3658 | ||
3659 | static void cb_flashing(struct usb_ep *ep, struct usb_request *req) | 3659 | static void cb_flashing(struct usb_ep *ep, struct usb_request *req) |
3660 | { | 3660 | { |
3661 | char *cmd = req->buf; | 3661 | char *cmd = req->buf; |
3662 | char response[FASTBOOT_RESPONSE_LEN]; | 3662 | char response[FASTBOOT_RESPONSE_LEN]; |
3663 | FbLockState status; | 3663 | FbLockState status; |
3664 | FbLockEnableResult result; | 3664 | FbLockEnableResult result; |
3665 | if (endswith(cmd, "lock_critical")) { | 3665 | if (endswith(cmd, "lock_critical")) { |
3666 | strcpy(response, "OKAY"); | 3666 | strcpy(response, "OKAY"); |
3667 | } | 3667 | } |
3668 | #ifdef CONFIG_AVB_ATX | 3668 | #ifdef CONFIG_AVB_ATX |
3669 | else if (endswith(cmd, FASTBOOT_AVB_AT_PERM_ATTR)) { | 3669 | else if (endswith(cmd, FASTBOOT_AVB_AT_PERM_ATTR)) { |
3670 | if (avb_atx_fuse_perm_attr(interface.transfer_buffer, download_bytes)) | 3670 | if (avb_atx_fuse_perm_attr(interface.transfer_buffer, download_bytes)) |
3671 | strcpy(response, "FAILInternal error!"); | 3671 | strcpy(response, "FAILInternal error!"); |
3672 | else | 3672 | else |
3673 | strcpy(response, "OKAY"); | 3673 | strcpy(response, "OKAY"); |
3674 | } else if (endswith(cmd, FASTBOOT_AT_GET_UNLOCK_CHALLENGE)) { | 3674 | } else if (endswith(cmd, FASTBOOT_AT_GET_UNLOCK_CHALLENGE)) { |
3675 | if (avb_atx_get_unlock_challenge(fsl_avb_ops.atx_ops, | 3675 | if (avb_atx_get_unlock_challenge(fsl_avb_ops.atx_ops, |
3676 | interface.transfer_buffer, &download_bytes)) | 3676 | interface.transfer_buffer, &download_bytes)) |
3677 | strcpy(response, "FAILInternal error!"); | 3677 | strcpy(response, "FAILInternal error!"); |
3678 | else | 3678 | else |
3679 | strcpy(response, "OKAY"); | 3679 | strcpy(response, "OKAY"); |
3680 | } else if (endswith(cmd, FASTBOOT_AT_UNLOCK_VBOOT)) { | 3680 | } else if (endswith(cmd, FASTBOOT_AT_UNLOCK_VBOOT)) { |
3681 | if (at_unlock_vboot_is_disabled()) { | 3681 | if (at_unlock_vboot_is_disabled()) { |
3682 | printf("unlock vboot already disabled, can't unlock the device!\n"); | 3682 | printf("unlock vboot already disabled, can't unlock the device!\n"); |
3683 | strcpy(response, "FAILunlock vboot already disabled!."); | 3683 | strcpy(response, "FAILunlock vboot already disabled!."); |
3684 | } else { | 3684 | } else { |
3685 | #ifdef CONFIG_AT_AUTHENTICATE_UNLOCK | 3685 | #ifdef CONFIG_AT_AUTHENTICATE_UNLOCK |
3686 | if (avb_atx_verify_unlock_credential(fsl_avb_ops.atx_ops, | 3686 | if (avb_atx_verify_unlock_credential(fsl_avb_ops.atx_ops, |
3687 | interface.transfer_buffer)) | 3687 | interface.transfer_buffer)) |
3688 | strcpy(response, "FAILIncorrect unlock credential!"); | 3688 | strcpy(response, "FAILIncorrect unlock credential!"); |
3689 | else { | 3689 | else { |
3690 | #endif | 3690 | #endif |
3691 | status = do_fastboot_unlock(true); | 3691 | status = do_fastboot_unlock(true); |
3692 | if (status != FASTBOOT_LOCK_ERROR) | 3692 | if (status != FASTBOOT_LOCK_ERROR) |
3693 | strcpy(response, "OKAY"); | 3693 | strcpy(response, "OKAY"); |
3694 | else | 3694 | else |
3695 | strcpy(response, "FAILunlock device failed."); | 3695 | strcpy(response, "FAILunlock device failed."); |
3696 | #ifdef CONFIG_AT_AUTHENTICATE_UNLOCK | 3696 | #ifdef CONFIG_AT_AUTHENTICATE_UNLOCK |
3697 | } | 3697 | } |
3698 | #endif | 3698 | #endif |
3699 | } | 3699 | } |
3700 | } else if (endswith(cmd, FASTBOOT_AT_LOCK_VBOOT)) { | 3700 | } else if (endswith(cmd, FASTBOOT_AT_LOCK_VBOOT)) { |
3701 | if (perm_attr_are_fused()) { | 3701 | if (perm_attr_are_fused()) { |
3702 | status = do_fastboot_lock(); | 3702 | status = do_fastboot_lock(); |
3703 | if (status != FASTBOOT_LOCK_ERROR) | 3703 | if (status != FASTBOOT_LOCK_ERROR) |
3704 | strcpy(response, "OKAY"); | 3704 | strcpy(response, "OKAY"); |
3705 | else | 3705 | else |
3706 | strcpy(response, "FAILlock device failed."); | 3706 | strcpy(response, "FAILlock device failed."); |
3707 | } else | 3707 | } else |
3708 | strcpy(response, "FAILpermanent attributes not fused!"); | 3708 | strcpy(response, "FAILpermanent attributes not fused!"); |
3709 | } else if (endswith(cmd, FASTBOOT_AT_DISABLE_UNLOCK_VBOOT)) { | 3709 | } else if (endswith(cmd, FASTBOOT_AT_DISABLE_UNLOCK_VBOOT)) { |
3710 | /* This command can only be called after 'oem at-lock-vboot' */ | 3710 | /* This command can only be called after 'oem at-lock-vboot' */ |
3711 | status = fastboot_get_lock_stat(); | 3711 | status = fastboot_get_lock_stat(); |
3712 | if (status == FASTBOOT_LOCK) { | 3712 | if (status == FASTBOOT_LOCK) { |
3713 | if (at_unlock_vboot_is_disabled()) { | 3713 | if (at_unlock_vboot_is_disabled()) { |
3714 | printf("unlock vboot already disabled!\n"); | 3714 | printf("unlock vboot already disabled!\n"); |
3715 | strcpy(response, "OKAY"); | 3715 | strcpy(response, "OKAY"); |
3716 | } | 3716 | } |
3717 | else { | 3717 | else { |
3718 | if (!at_disable_vboot_unlock()) | 3718 | if (!at_disable_vboot_unlock()) |
3719 | strcpy(response, "OKAY"); | 3719 | strcpy(response, "OKAY"); |
3720 | else | 3720 | else |
3721 | strcpy(response, "FAILdisable unlock vboot fail!"); | 3721 | strcpy(response, "FAILdisable unlock vboot fail!"); |
3722 | } | 3722 | } |
3723 | } else | 3723 | } else |
3724 | strcpy(response, "FAILplease lock the device first!"); | 3724 | strcpy(response, "FAILplease lock the device first!"); |
3725 | } | 3725 | } |
3726 | #endif /* CONFIG_AVB_ATX */ | 3726 | #endif /* CONFIG_AVB_ATX */ |
3727 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT | 3727 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT |
3728 | else if (endswith(cmd, FASTBOOT_BOOTLOADER_VBOOT_KEY)) { | 3728 | else if (endswith(cmd, FASTBOOT_BOOTLOADER_VBOOT_KEY)) { |
3729 | strcpy(response, "OKAY"); | 3729 | strcpy(response, "OKAY"); |
3730 | } | 3730 | } |
3731 | #endif /* CONFIG_ANDROID_THINGS_SUPPORT */ | 3731 | #endif /* CONFIG_ANDROID_THINGS_SUPPORT */ |
3732 | #ifdef CONFIG_IMX_TRUSTY_OS | 3732 | #ifdef CONFIG_IMX_TRUSTY_OS |
3733 | #if defined(CONFIG_AVB_ATX) || defined(CONFIG_ANDROID_AUTO_SUPPORT) | 3733 | #if defined(CONFIG_AVB_ATX) || defined(CONFIG_ANDROID_AUTO_SUPPORT) |
3734 | else if (endswith(cmd, FASTBOOT_GET_CA_REQ)) { | 3734 | else if (endswith(cmd, FASTBOOT_GET_CA_REQ)) { |
3735 | uint8_t *ca_output; | 3735 | uint8_t *ca_output; |
3736 | uint32_t ca_length, cp_length; | 3736 | uint32_t ca_length, cp_length; |
3737 | if (trusty_atap_get_ca_request(interface.transfer_buffer, download_bytes, | 3737 | if (trusty_atap_get_ca_request(interface.transfer_buffer, download_bytes, |
3738 | &(ca_output), &ca_length)) { | 3738 | &(ca_output), &ca_length)) { |
3739 | printf("ERROR get_ca_request failed!\n"); | 3739 | printf("ERROR get_ca_request failed!\n"); |
3740 | strcpy(response, "FAILInternal error!"); | 3740 | strcpy(response, "FAILInternal error!"); |
3741 | } else { | 3741 | } else { |
3742 | cp_length = min((uint32_t)CONFIG_FASTBOOT_BUF_SIZE, ca_length); | 3742 | cp_length = min((uint32_t)CONFIG_FASTBOOT_BUF_SIZE, ca_length); |
3743 | memcpy(interface.transfer_buffer, ca_output, cp_length); | 3743 | memcpy(interface.transfer_buffer, ca_output, cp_length); |
3744 | download_bytes = ca_length; | 3744 | download_bytes = ca_length; |
3745 | strcpy(response, "OKAY"); | 3745 | strcpy(response, "OKAY"); |
3746 | } | 3746 | } |
3747 | 3747 | ||
3748 | } | 3748 | } |
3749 | else if (endswith(cmd, FASTBOOT_SET_CA_RESP)) { | 3749 | else if (endswith(cmd, FASTBOOT_SET_CA_RESP)) { |
3750 | if (trusty_atap_set_ca_response(interface.transfer_buffer,download_bytes)) { | 3750 | if (trusty_atap_set_ca_response(interface.transfer_buffer,download_bytes)) { |
3751 | printf("ERROR set_ca_response failed!\n"); | 3751 | printf("ERROR set_ca_response failed!\n"); |
3752 | strcpy(response, "FAILInternal error!"); | 3752 | strcpy(response, "FAILInternal error!"); |
3753 | } else | 3753 | } else |
3754 | strcpy(response, "OKAY"); | 3754 | strcpy(response, "OKAY"); |
3755 | } | 3755 | } |
3756 | #endif /* CONFIG_AVB_ATX || CONFIG_ANDROID_AUTO_SUPPORT */ | 3756 | #endif /* CONFIG_AVB_ATX || CONFIG_ANDROID_AUTO_SUPPORT */ |
3757 | #ifdef CONFIG_ANDROID_AUTO_SUPPORT | 3757 | #ifdef CONFIG_ANDROID_AUTO_SUPPORT |
3758 | else if (endswith(cmd, FASTBOOT_SET_RPMB_KEY)) { | 3758 | else if (endswith(cmd, FASTBOOT_SET_RPMB_KEY)) { |
3759 | if (fastboot_set_rpmb_key(interface.transfer_buffer, download_bytes)) { | 3759 | if (fastboot_set_rpmb_key(interface.transfer_buffer, download_bytes)) { |
3760 | printf("ERROR set rpmb key failed!\n"); | 3760 | printf("ERROR set rpmb key failed!\n"); |
3761 | strcpy(response, "FAILset rpmb key failed!"); | 3761 | strcpy(response, "FAILset rpmb key failed!"); |
3762 | } else | 3762 | } else |
3763 | strcpy(response, "OKAY"); | 3763 | strcpy(response, "OKAY"); |
3764 | } | 3764 | } |
3765 | #endif | 3765 | #endif |
3766 | #endif /* CONFIG_IMX_TRUSTY_OS */ | 3766 | #endif /* CONFIG_IMX_TRUSTY_OS */ |
3767 | else if (endswith(cmd, "unlock_critical")) { | 3767 | else if (endswith(cmd, "unlock_critical")) { |
3768 | strcpy(response, "OKAY"); | 3768 | strcpy(response, "OKAY"); |
3769 | } else if (endswith(cmd, "unlock")) { | 3769 | } else if (endswith(cmd, "unlock")) { |
3770 | printf("flashing unlock.\n"); | 3770 | printf("flashing unlock.\n"); |
3771 | #ifdef CONFIG_AVB_ATX | 3771 | #ifdef CONFIG_AVB_ATX |
3772 | /* We should do nothing here For Android Things which | 3772 | /* We should do nothing here For Android Things which |
3773 | * enables the authenticated unlock feature. | 3773 | * enables the authenticated unlock feature. |
3774 | */ | 3774 | */ |
3775 | strcpy(response, "OKAY"); | 3775 | strcpy(response, "OKAY"); |
3776 | #else | 3776 | #else |
3777 | status = do_fastboot_unlock(false); | 3777 | status = do_fastboot_unlock(false); |
3778 | if (status != FASTBOOT_LOCK_ERROR) | 3778 | if (status != FASTBOOT_LOCK_ERROR) |
3779 | strcpy(response, "OKAY"); | 3779 | strcpy(response, "OKAY"); |
3780 | else | 3780 | else |
3781 | strcpy(response, "FAILunlock device failed."); | 3781 | strcpy(response, "FAILunlock device failed."); |
3782 | #endif | 3782 | #endif |
3783 | } else if (endswith(cmd, "lock")) { | 3783 | } else if (endswith(cmd, "lock")) { |
3784 | #ifdef CONFIG_AVB_ATX | 3784 | #ifdef CONFIG_AVB_ATX |
3785 | /* We should do nothing here For Android Things which | 3785 | /* We should do nothing here For Android Things which |
3786 | * enables the at-lock-vboot feature. | 3786 | * enables the at-lock-vboot feature. |
3787 | */ | 3787 | */ |
3788 | strcpy(response, "OKAY"); | 3788 | strcpy(response, "OKAY"); |
3789 | #else | 3789 | #else |
3790 | printf("flashing lock.\n"); | 3790 | printf("flashing lock.\n"); |
3791 | status = do_fastboot_lock(); | 3791 | status = do_fastboot_lock(); |
3792 | if (status != FASTBOOT_LOCK_ERROR) | 3792 | if (status != FASTBOOT_LOCK_ERROR) |
3793 | strcpy(response, "OKAY"); | 3793 | strcpy(response, "OKAY"); |
3794 | else | 3794 | else |
3795 | strcpy(response, "FAILlock device failed."); | 3795 | strcpy(response, "FAILlock device failed."); |
3796 | #endif | 3796 | #endif |
3797 | } else if (endswith(cmd, "get_unlock_ability")) { | 3797 | } else if (endswith(cmd, "get_unlock_ability")) { |
3798 | result = fastboot_lock_enable(); | 3798 | result = fastboot_lock_enable(); |
3799 | if (result == FASTBOOT_UL_ENABLE) { | 3799 | if (result == FASTBOOT_UL_ENABLE) { |
3800 | fastboot_tx_write_more("INFO1"); | 3800 | fastboot_tx_write_more("INFO1"); |
3801 | strcpy(response, "OKAY"); | 3801 | strcpy(response, "OKAY"); |
3802 | } else if (result == FASTBOOT_UL_DISABLE) { | 3802 | } else if (result == FASTBOOT_UL_DISABLE) { |
3803 | fastboot_tx_write_more("INFO0"); | 3803 | fastboot_tx_write_more("INFO0"); |
3804 | strcpy(response, "OKAY"); | 3804 | strcpy(response, "OKAY"); |
3805 | } else { | 3805 | } else { |
3806 | printf("flashing get_unlock_ability fail!\n"); | 3806 | printf("flashing get_unlock_ability fail!\n"); |
3807 | strcpy(response, "FAILget unlock ability failed."); | 3807 | strcpy(response, "FAILget unlock ability failed."); |
3808 | } | 3808 | } |
3809 | } else { | 3809 | } else { |
3810 | printf("Unknown flashing command:%s\n", cmd); | 3810 | printf("Unknown flashing command:%s\n", cmd); |
3811 | strcpy(response, "FAILcommand not defined"); | 3811 | strcpy(response, "FAILcommand not defined"); |
3812 | } | 3812 | } |
3813 | fastboot_tx_write_more(response); | 3813 | fastboot_tx_write_more(response); |
3814 | } | 3814 | } |
3815 | 3815 | ||
3816 | #endif /* CONFIG_FASTBOOT_LOCK */ | 3816 | #endif /* CONFIG_FASTBOOT_LOCK */ |
3817 | 3817 | ||
3818 | #ifdef CONFIG_FSL_FASTBOOT | 3818 | #ifdef CONFIG_FSL_FASTBOOT |
3819 | #ifdef CONFIG_FASTBOOT_LOCK | 3819 | #ifdef CONFIG_FASTBOOT_LOCK |
3820 | static int partition_table_valid(void) | 3820 | static int partition_table_valid(void) |
3821 | { | 3821 | { |
3822 | int status, mmc_no; | 3822 | int status, mmc_no; |
3823 | struct blk_desc *dev_desc; | 3823 | struct blk_desc *dev_desc; |
3824 | #if defined(CONFIG_IMX_TRUSTY_OS) && !defined(CONFIG_ARM64) | 3824 | #if defined(CONFIG_IMX_TRUSTY_OS) && !defined(CONFIG_ARM64) |
3825 | //Prevent other partition accessing when no TOS flashed. | 3825 | //Prevent other partition accessing when no TOS flashed. |
3826 | if (!tos_flashed) | 3826 | if (!tos_flashed) |
3827 | return 0; | 3827 | return 0; |
3828 | #endif | 3828 | #endif |
3829 | disk_partition_t info; | 3829 | disk_partition_t info; |
3830 | mmc_no = fastboot_devinfo.dev_id; | 3830 | mmc_no = fastboot_devinfo.dev_id; |
3831 | dev_desc = blk_get_dev("mmc", mmc_no); | 3831 | dev_desc = blk_get_dev("mmc", mmc_no); |
3832 | if (dev_desc) | 3832 | if (dev_desc) |
3833 | status = part_get_info(dev_desc, 1, &info); | 3833 | status = part_get_info(dev_desc, 1, &info); |
3834 | else | 3834 | else |
3835 | status = -1; | 3835 | status = -1; |
3836 | return (status == 0); | 3836 | return (status == 0); |
3837 | } | 3837 | } |
3838 | #endif | 3838 | #endif |
3839 | #endif /* CONFIG_FASTBOOT_LOCK */ | 3839 | #endif /* CONFIG_FASTBOOT_LOCK */ |
3840 | 3840 | ||
3841 | #ifdef CONFIG_FASTBOOT_FLASH | 3841 | #ifdef CONFIG_FASTBOOT_FLASH |
3842 | static void cb_flash(struct usb_ep *ep, struct usb_request *req) | 3842 | static void cb_flash(struct usb_ep *ep, struct usb_request *req) |
3843 | { | 3843 | { |
3844 | char *cmd = req->buf; | 3844 | char *cmd = req->buf; |
3845 | char response[FASTBOOT_RESPONSE_LEN]; | 3845 | char response[FASTBOOT_RESPONSE_LEN]; |
3846 | 3846 | ||
3847 | strsep(&cmd, ":"); | 3847 | strsep(&cmd, ":"); |
3848 | if (!cmd) { | 3848 | if (!cmd) { |
3849 | pr_err("missing partition name"); | 3849 | pr_err("missing partition name"); |
3850 | fastboot_tx_write_str("FAILmissing partition name"); | 3850 | fastboot_tx_write_str("FAILmissing partition name"); |
3851 | return; | 3851 | return; |
3852 | } | 3852 | } |
3853 | 3853 | ||
3854 | /* initialize the response buffer */ | 3854 | /* initialize the response buffer */ |
3855 | fb_response_str = response; | 3855 | fb_response_str = response; |
3856 | 3856 | ||
3857 | /* Always enable image flash for Android Things. */ | 3857 | /* Always enable image flash for Android Things. */ |
3858 | #if defined(CONFIG_FASTBOOT_LOCK) && !defined(CONFIG_AVB_ATX) | 3858 | #if defined(CONFIG_FASTBOOT_LOCK) && !defined(CONFIG_AVB_ATX) |
3859 | /* for imx8 boot from USB, lock status can be ignored for uuu.*/ | 3859 | /* for imx8 boot from USB, lock status can be ignored for uuu.*/ |
3860 | if (!(is_imx8() || is_imx8m()) || !(is_boot_from_usb())) { | 3860 | if (!(is_imx8() || is_imx8m()) || !(is_boot_from_usb())) { |
3861 | int status; | 3861 | int status; |
3862 | status = fastboot_get_lock_stat(); | 3862 | status = fastboot_get_lock_stat(); |
3863 | 3863 | ||
3864 | if (status == FASTBOOT_LOCK) { | 3864 | if (status == FASTBOOT_LOCK) { |
3865 | pr_err("device is LOCKed!\n"); | 3865 | pr_err("device is LOCKed!\n"); |
3866 | strcpy(response, "FAIL device is locked."); | 3866 | strcpy(response, "FAIL device is locked."); |
3867 | fastboot_tx_write_str(response); | 3867 | fastboot_tx_write_str(response); |
3868 | return; | 3868 | return; |
3869 | 3869 | ||
3870 | } else if (status == FASTBOOT_LOCK_ERROR) { | 3870 | } else if (status == FASTBOOT_LOCK_ERROR) { |
3871 | pr_err("write lock status into device!\n"); | 3871 | pr_err("write lock status into device!\n"); |
3872 | fastboot_set_lock_stat(FASTBOOT_LOCK); | 3872 | fastboot_set_lock_stat(FASTBOOT_LOCK); |
3873 | strcpy(response, "FAILdevice is locked."); | 3873 | strcpy(response, "FAILdevice is locked."); |
3874 | fastboot_tx_write_str(response); | 3874 | fastboot_tx_write_str(response); |
3875 | return; | 3875 | return; |
3876 | } | 3876 | } |
3877 | } | 3877 | } |
3878 | #endif | 3878 | #endif |
3879 | fastboot_fail("no flash device defined"); | 3879 | fastboot_fail("no flash device defined"); |
3880 | 3880 | ||
3881 | rx_process_flash(cmd); | 3881 | rx_process_flash(cmd); |
3882 | 3882 | ||
3883 | #ifdef CONFIG_FASTBOOT_LOCK | 3883 | #ifdef CONFIG_FASTBOOT_LOCK |
3884 | if (strncmp(cmd, "gpt", 3) == 0) { | 3884 | if (strncmp(cmd, "gpt", 3) == 0) { |
3885 | int gpt_valid = 0; | 3885 | int gpt_valid = 0; |
3886 | gpt_valid = partition_table_valid(); | 3886 | gpt_valid = partition_table_valid(); |
3887 | /* If gpt is valid, load partitons table into memory. | 3887 | /* If gpt is valid, load partitons table into memory. |
3888 | So if the next command is "fastboot reboot bootloader", | 3888 | So if the next command is "fastboot reboot bootloader", |
3889 | it can find the "misc" partition to r/w. */ | 3889 | it can find the "misc" partition to r/w. */ |
3890 | if(gpt_valid) { | 3890 | if(gpt_valid) { |
3891 | _fastboot_load_partitions(); | 3891 | _fastboot_load_partitions(); |
3892 | /* Unlock device if the gpt is valid */ | 3892 | /* Unlock device if the gpt is valid */ |
3893 | do_fastboot_unlock(true); | 3893 | do_fastboot_unlock(true); |
3894 | } | 3894 | } |
3895 | } | 3895 | } |
3896 | 3896 | ||
3897 | #endif | 3897 | #endif |
3898 | fastboot_tx_write_str(response); | 3898 | fastboot_tx_write_str(response); |
3899 | } | 3899 | } |
3900 | #endif | 3900 | #endif |
3901 | 3901 | ||
3902 | #ifdef CONFIG_FASTBOOT_FLASH | 3902 | #ifdef CONFIG_FASTBOOT_FLASH |
3903 | static void cb_erase(struct usb_ep *ep, struct usb_request *req) | 3903 | static void cb_erase(struct usb_ep *ep, struct usb_request *req) |
3904 | { | 3904 | { |
3905 | char *cmd = req->buf; | 3905 | char *cmd = req->buf; |
3906 | char response[FASTBOOT_RESPONSE_LEN]; | 3906 | char response[FASTBOOT_RESPONSE_LEN]; |
3907 | 3907 | ||
3908 | strsep(&cmd, ":"); | 3908 | strsep(&cmd, ":"); |
3909 | if (!cmd) { | 3909 | if (!cmd) { |
3910 | pr_err("missing partition name"); | 3910 | pr_err("missing partition name"); |
3911 | fastboot_tx_write_str("FAILmissing partition name"); | 3911 | fastboot_tx_write_str("FAILmissing partition name"); |
3912 | return; | 3912 | return; |
3913 | } | 3913 | } |
3914 | 3914 | ||
3915 | /* initialize the response buffer */ | 3915 | /* initialize the response buffer */ |
3916 | fb_response_str = response; | 3916 | fb_response_str = response; |
3917 | 3917 | ||
3918 | #if defined(CONFIG_FASTBOOT_LOCK) && !defined(CONFIG_AVB_ATX) | 3918 | #if defined(CONFIG_FASTBOOT_LOCK) && !defined(CONFIG_AVB_ATX) |
3919 | FbLockState status; | 3919 | FbLockState status; |
3920 | status = fastboot_get_lock_stat(); | 3920 | status = fastboot_get_lock_stat(); |
3921 | if (status == FASTBOOT_LOCK) { | 3921 | if (status == FASTBOOT_LOCK) { |
3922 | pr_err("device is LOCKed!\n"); | 3922 | pr_err("device is LOCKed!\n"); |
3923 | strcpy(response, "FAIL device is locked."); | 3923 | strcpy(response, "FAIL device is locked."); |
3924 | fastboot_tx_write_str(response); | 3924 | fastboot_tx_write_str(response); |
3925 | return; | 3925 | return; |
3926 | } else if (status == FASTBOOT_LOCK_ERROR) { | 3926 | } else if (status == FASTBOOT_LOCK_ERROR) { |
3927 | pr_err("write lock status into device!\n"); | 3927 | pr_err("write lock status into device!\n"); |
3928 | fastboot_set_lock_stat(FASTBOOT_LOCK); | 3928 | fastboot_set_lock_stat(FASTBOOT_LOCK); |
3929 | strcpy(response, "FAILdevice is locked."); | 3929 | strcpy(response, "FAILdevice is locked."); |
3930 | fastboot_tx_write_str(response); | 3930 | fastboot_tx_write_str(response); |
3931 | return; | 3931 | return; |
3932 | } | 3932 | } |
3933 | #endif | 3933 | #endif |
3934 | rx_process_erase(cmd, response); | 3934 | rx_process_erase(cmd, response); |
3935 | fastboot_tx_write_str(response); | 3935 | fastboot_tx_write_str(response); |
3936 | } | 3936 | } |
3937 | #endif | 3937 | #endif |
3938 | 3938 | ||
3939 | static void cb_run_uboot_cmd(struct usb_ep *ep, struct usb_request *req) | 3939 | static void cb_run_uboot_cmd(struct usb_ep *ep, struct usb_request *req) |
3940 | { | 3940 | { |
3941 | char *cmd = req->buf; | 3941 | char *cmd = req->buf; |
3942 | strsep(&cmd, ":"); | 3942 | strsep(&cmd, ":"); |
3943 | if (!cmd) { | 3943 | if (!cmd) { |
3944 | pr_err("missing slot suffix\n"); | 3944 | pr_err("missing slot suffix\n"); |
3945 | fastboot_tx_write_str("FAILmissing command"); | 3945 | fastboot_tx_write_str("FAILmissing command"); |
3946 | return; | 3946 | return; |
3947 | } | 3947 | } |
3948 | if(run_command(cmd, 0)) { | 3948 | if(run_command(cmd, 0)) { |
3949 | fastboot_tx_write_str("FAIL"); | 3949 | fastboot_tx_write_str("FAIL"); |
3950 | } else { | 3950 | } else { |
3951 | fastboot_tx_write_str("OKAY"); | 3951 | fastboot_tx_write_str("OKAY"); |
3952 | /* cmd may impact fastboot related environment*/ | 3952 | /* cmd may impact fastboot related environment*/ |
3953 | fastboot_setup(); | 3953 | fastboot_setup(); |
3954 | } | 3954 | } |
3955 | return ; | 3955 | return ; |
3956 | } | 3956 | } |
3957 | 3957 | ||
3958 | static char g_a_cmd_buff[64]; | 3958 | static char g_a_cmd_buff[64]; |
3959 | static void do_acmd_complete(struct usb_ep *ep, struct usb_request *req) | 3959 | static void do_acmd_complete(struct usb_ep *ep, struct usb_request *req) |
3960 | { | 3960 | { |
3961 | /* When usb dequeue complete will be called | 3961 | /* When usb dequeue complete will be called |
3962 | * Meed status value before call run_command. | 3962 | * Meed status value before call run_command. |
3963 | * otherwise, host can't get last message. | 3963 | * otherwise, host can't get last message. |
3964 | */ | 3964 | */ |
3965 | if(req->status == 0) | 3965 | if(req->status == 0) |
3966 | run_command(g_a_cmd_buff, 0); | 3966 | run_command(g_a_cmd_buff, 0); |
3967 | } | 3967 | } |
3968 | 3968 | ||
3969 | static void cb_run_uboot_acmd(struct usb_ep *ep, struct usb_request *req) | 3969 | static void cb_run_uboot_acmd(struct usb_ep *ep, struct usb_request *req) |
3970 | { | 3970 | { |
3971 | char *cmd = req->buf; | 3971 | char *cmd = req->buf; |
3972 | strsep(&cmd, ":"); | 3972 | strsep(&cmd, ":"); |
3973 | if (!cmd) { | 3973 | if (!cmd) { |
3974 | pr_err("missing slot suffix\n"); | 3974 | pr_err("missing slot suffix\n"); |
3975 | fastboot_tx_write_str("FAILmissing command"); | 3975 | fastboot_tx_write_str("FAILmissing command"); |
3976 | return; | 3976 | return; |
3977 | } | 3977 | } |
3978 | strcpy(g_a_cmd_buff, cmd); | 3978 | strcpy(g_a_cmd_buff, cmd); |
3979 | fastboot_func->in_req->complete = do_acmd_complete; | 3979 | fastboot_func->in_req->complete = do_acmd_complete; |
3980 | fastboot_tx_write_str("OKAY"); | 3980 | fastboot_tx_write_str("OKAY"); |
3981 | } | 3981 | } |
3982 | 3982 | ||
3983 | #ifdef CONFIG_AVB_SUPPORT | 3983 | #ifdef CONFIG_AVB_SUPPORT |
3984 | static void cb_set_active_avb(struct usb_ep *ep, struct usb_request *req) | 3984 | static void cb_set_active_avb(struct usb_ep *ep, struct usb_request *req) |
3985 | { | 3985 | { |
3986 | AvbIOResult ret; | 3986 | AvbIOResult ret; |
3987 | int slot = 0; | 3987 | int slot = 0; |
3988 | char *cmd = req->buf; | 3988 | char *cmd = req->buf; |
3989 | 3989 | ||
3990 | strsep(&cmd, ":"); | 3990 | strsep(&cmd, ":"); |
3991 | if (!cmd) { | 3991 | if (!cmd) { |
3992 | pr_err("missing slot suffix\n"); | 3992 | pr_err("missing slot suffix\n"); |
3993 | fastboot_tx_write_str("FAILmissing slot suffix"); | 3993 | fastboot_tx_write_str("FAILmissing slot suffix"); |
3994 | return; | 3994 | return; |
3995 | } | 3995 | } |
3996 | 3996 | ||
3997 | slot = slotidx_from_suffix(cmd); | 3997 | slot = slotidx_from_suffix(cmd); |
3998 | 3998 | ||
3999 | if (slot < 0) { | 3999 | if (slot < 0) { |
4000 | fastboot_tx_write_str("FAILerr slot suffix"); | 4000 | fastboot_tx_write_str("FAILerr slot suffix"); |
4001 | return; | 4001 | return; |
4002 | } | 4002 | } |
4003 | 4003 | ||
4004 | ret = avb_ab_mark_slot_active(&fsl_avb_ab_ops, slot); | 4004 | ret = avb_ab_mark_slot_active(&fsl_avb_ab_ops, slot); |
4005 | if (ret != AVB_IO_RESULT_OK) | 4005 | if (ret != AVB_IO_RESULT_OK) |
4006 | fastboot_tx_write_str("avb IO error"); | 4006 | fastboot_tx_write_str("avb IO error"); |
4007 | else | 4007 | else |
4008 | fastboot_tx_write_str("OKAY"); | 4008 | fastboot_tx_write_str("OKAY"); |
4009 | 4009 | ||
4010 | return; | 4010 | return; |
4011 | } | 4011 | } |
4012 | #endif /*CONFIG_AVB_SUPPORT*/ | 4012 | #endif /*CONFIG_AVB_SUPPORT*/ |
4013 | 4013 | ||
4014 | static void cb_reboot_bootloader(struct usb_ep *ep, struct usb_request *req) | 4014 | static void cb_reboot_bootloader(struct usb_ep *ep, struct usb_request *req) |
4015 | { | 4015 | { |
4016 | enable_fastboot_command(); | 4016 | enable_fastboot_command(); |
4017 | fastboot_func->in_req->complete = compl_do_reset; | 4017 | fastboot_func->in_req->complete = compl_do_reset; |
4018 | fastboot_tx_write_str("OKAY"); | 4018 | fastboot_tx_write_str("OKAY"); |
4019 | } | 4019 | } |
4020 | 4020 | ||
4021 | #else /* CONFIG_FSL_FASTBOOT */ | 4021 | #else /* CONFIG_FSL_FASTBOOT */ |
4022 | 4022 | ||
4023 | static void cb_getvar(struct usb_ep *ep, struct usb_request *req) | 4023 | static void cb_getvar(struct usb_ep *ep, struct usb_request *req) |
4024 | { | 4024 | { |
4025 | char *cmd = req->buf; | 4025 | char *cmd = req->buf; |
4026 | char response[FASTBOOT_RESPONSE_LEN]; | 4026 | char response[FASTBOOT_RESPONSE_LEN]; |
4027 | const char *s; | 4027 | const char *s; |
4028 | size_t chars_left; | 4028 | size_t chars_left; |
4029 | 4029 | ||
4030 | strcpy(response, "OKAY"); | 4030 | strcpy(response, "OKAY"); |
4031 | chars_left = sizeof(response) - strlen(response) - 1; | 4031 | chars_left = sizeof(response) - strlen(response) - 1; |
4032 | 4032 | ||
4033 | strsep(&cmd, ":"); | 4033 | strsep(&cmd, ":"); |
4034 | if (!cmd) { | 4034 | if (!cmd) { |
4035 | pr_err("missing variable"); | 4035 | pr_err("missing variable"); |
4036 | fastboot_tx_write_str("FAILmissing var"); | 4036 | fastboot_tx_write_str("FAILmissing var"); |
4037 | return; | 4037 | return; |
4038 | } | 4038 | } |
4039 | 4039 | ||
4040 | if (!strcmp_l1("version", cmd)) { | 4040 | if (!strcmp_l1("version", cmd)) { |
4041 | strncat(response, FASTBOOT_VERSION, chars_left); | 4041 | strncat(response, FASTBOOT_VERSION, chars_left); |
4042 | } else if (!strcmp_l1("bootloader-version", cmd)) { | 4042 | } else if (!strcmp_l1("bootloader-version", cmd)) { |
4043 | strncat(response, U_BOOT_VERSION, chars_left); | 4043 | strncat(response, U_BOOT_VERSION, chars_left); |
4044 | } else if (!strcmp_l1("downloadsize", cmd) || | 4044 | } else if (!strcmp_l1("downloadsize", cmd) || |
4045 | !strcmp_l1("max-download-size", cmd)) { | 4045 | !strcmp_l1("max-download-size", cmd)) { |
4046 | char str_num[12]; | 4046 | char str_num[12]; |
4047 | 4047 | ||
4048 | sprintf(str_num, "0x%08x", CONFIG_FASTBOOT_BUF_SIZE); | 4048 | sprintf(str_num, "0x%08x", CONFIG_FASTBOOT_BUF_SIZE); |
4049 | strncat(response, str_num, chars_left); | 4049 | strncat(response, str_num, chars_left); |
4050 | } else if (!strcmp_l1("serialno", cmd)) { | 4050 | } else if (!strcmp_l1("serialno", cmd)) { |
4051 | s = env_get("serial#"); | 4051 | s = env_get("serial#"); |
4052 | if (s) | 4052 | if (s) |
4053 | strncat(response, s, chars_left); | 4053 | strncat(response, s, chars_left); |
4054 | else | 4054 | else |
4055 | strcpy(response, "FAILValue not set"); | 4055 | strcpy(response, "FAILValue not set"); |
4056 | } else { | 4056 | } else { |
4057 | char *envstr; | 4057 | char *envstr; |
4058 | 4058 | ||
4059 | envstr = malloc(strlen("fastboot.") + strlen(cmd) + 1); | 4059 | envstr = malloc(strlen("fastboot.") + strlen(cmd) + 1); |
4060 | if (!envstr) { | 4060 | if (!envstr) { |
4061 | fastboot_tx_write_str("FAILmalloc error"); | 4061 | fastboot_tx_write_str("FAILmalloc error"); |
4062 | return; | 4062 | return; |
4063 | } | 4063 | } |
4064 | 4064 | ||
4065 | sprintf(envstr, "fastboot.%s", cmd); | 4065 | sprintf(envstr, "fastboot.%s", cmd); |
4066 | s = env_get(envstr); | 4066 | s = env_get(envstr); |
4067 | if (s) { | 4067 | if (s) { |
4068 | strncat(response, s, chars_left); | 4068 | strncat(response, s, chars_left); |
4069 | } else { | 4069 | } else { |
4070 | printf("WARNING: unknown variable: %s\n", cmd); | 4070 | printf("WARNING: unknown variable: %s\n", cmd); |
4071 | strcpy(response, "FAILVariable not implemented"); | 4071 | strcpy(response, "FAILVariable not implemented"); |
4072 | } | 4072 | } |
4073 | 4073 | ||
4074 | free(envstr); | 4074 | free(envstr); |
4075 | } | 4075 | } |
4076 | fastboot_tx_write_str(response); | 4076 | fastboot_tx_write_str(response); |
4077 | } | 4077 | } |
4078 | 4078 | ||
4079 | #ifdef CONFIG_FASTBOOT_FLASH | 4079 | #ifdef CONFIG_FASTBOOT_FLASH |
4080 | static void cb_flash(struct usb_ep *ep, struct usb_request *req) | 4080 | static void cb_flash(struct usb_ep *ep, struct usb_request *req) |
4081 | { | 4081 | { |
4082 | char *cmd = req->buf; | 4082 | char *cmd = req->buf; |
4083 | char response[FASTBOOT_RESPONSE_LEN]; | 4083 | char response[FASTBOOT_RESPONSE_LEN]; |
4084 | 4084 | ||
4085 | strsep(&cmd, ":"); | 4085 | strsep(&cmd, ":"); |
4086 | if (!cmd) { | 4086 | if (!cmd) { |
4087 | pr_err("missing partition name"); | 4087 | pr_err("missing partition name"); |
4088 | fastboot_tx_write_str("FAILmissing partition name"); | 4088 | fastboot_tx_write_str("FAILmissing partition name"); |
4089 | return; | 4089 | return; |
4090 | } | 4090 | } |
4091 | 4091 | ||
4092 | /* initialize the response buffer */ | 4092 | /* initialize the response buffer */ |
4093 | fb_response_str = response; | 4093 | fb_response_str = response; |
4094 | 4094 | ||
4095 | fastboot_fail("no flash device defined"); | 4095 | fastboot_fail("no flash device defined"); |
4096 | #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV | 4096 | #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV |
4097 | fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR, | 4097 | fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR, |
4098 | download_bytes); | 4098 | download_bytes); |
4099 | #endif | 4099 | #endif |
4100 | #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV | 4100 | #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV |
4101 | fb_nand_flash_write(cmd, | 4101 | fb_nand_flash_write(cmd, |
4102 | (void *)CONFIG_FASTBOOT_BUF_ADDR, | 4102 | (void *)CONFIG_FASTBOOT_BUF_ADDR, |
4103 | download_bytes); | 4103 | download_bytes); |
4104 | #endif | 4104 | #endif |
4105 | fastboot_tx_write_str(response); | 4105 | fastboot_tx_write_str(response); |
4106 | } | 4106 | } |
4107 | #endif | 4107 | #endif |
4108 | 4108 | ||
4109 | static void cb_oem(struct usb_ep *ep, struct usb_request *req) | 4109 | static void cb_oem(struct usb_ep *ep, struct usb_request *req) |
4110 | { | 4110 | { |
4111 | char *cmd = req->buf; | 4111 | char *cmd = req->buf; |
4112 | #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV | 4112 | #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV |
4113 | if (strncmp("format", cmd + 4, 6) == 0) { | 4113 | if (strncmp("format", cmd + 4, 6) == 0) { |
4114 | char cmdbuf[32]; | 4114 | char cmdbuf[32]; |
4115 | sprintf(cmdbuf, "gpt write mmc %x $partitions", | 4115 | sprintf(cmdbuf, "gpt write mmc %x $partitions", |
4116 | CONFIG_FASTBOOT_FLASH_MMC_DEV); | 4116 | CONFIG_FASTBOOT_FLASH_MMC_DEV); |
4117 | if (run_command(cmdbuf, 0)) | 4117 | if (run_command(cmdbuf, 0)) |
4118 | fastboot_tx_write_str("FAIL"); | 4118 | fastboot_tx_write_str("FAIL"); |
4119 | else | 4119 | else |
4120 | fastboot_tx_write_str("OKAY"); | 4120 | fastboot_tx_write_str("OKAY"); |
4121 | } else | 4121 | } else |
4122 | #endif | 4122 | #endif |
4123 | if (strncmp("unlock", cmd + 4, 8) == 0) { | 4123 | if (strncmp("unlock", cmd + 4, 8) == 0) { |
4124 | fastboot_tx_write_str("FAILnot implemented"); | 4124 | fastboot_tx_write_str("FAILnot implemented"); |
4125 | } | 4125 | } |
4126 | else { | 4126 | else { |
4127 | fastboot_tx_write_str("FAILunknown oem command"); | 4127 | fastboot_tx_write_str("FAILunknown oem command"); |
4128 | } | 4128 | } |
4129 | } | 4129 | } |
4130 | 4130 | ||
4131 | #ifdef CONFIG_FASTBOOT_FLASH | 4131 | #ifdef CONFIG_FASTBOOT_FLASH |
4132 | static void cb_erase(struct usb_ep *ep, struct usb_request *req) | 4132 | static void cb_erase(struct usb_ep *ep, struct usb_request *req) |
4133 | { | 4133 | { |
4134 | char *cmd = req->buf; | 4134 | char *cmd = req->buf; |
4135 | char response[FASTBOOT_RESPONSE_LEN]; | 4135 | char response[FASTBOOT_RESPONSE_LEN]; |
4136 | 4136 | ||
4137 | strsep(&cmd, ":"); | 4137 | strsep(&cmd, ":"); |
4138 | if (!cmd) { | 4138 | if (!cmd) { |
4139 | pr_err("missing partition name"); | 4139 | pr_err("missing partition name"); |
4140 | fastboot_tx_write_str("FAILmissing partition name"); | 4140 | fastboot_tx_write_str("FAILmissing partition name"); |
4141 | return; | 4141 | return; |
4142 | } | 4142 | } |
4143 | 4143 | ||
4144 | /* initialize the response buffer */ | 4144 | /* initialize the response buffer */ |
4145 | fb_response_str = response; | 4145 | fb_response_str = response; |
4146 | 4146 | ||
4147 | fastboot_fail("no flash device defined"); | 4147 | fastboot_fail("no flash device defined"); |
4148 | #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV | 4148 | #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV |
4149 | fb_mmc_erase(cmd); | 4149 | fb_mmc_erase(cmd); |
4150 | #endif | 4150 | #endif |
4151 | #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV | 4151 | #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV |
4152 | fb_nand_erase(cmd); | 4152 | fb_nand_erase(cmd); |
4153 | #endif | 4153 | #endif |
4154 | fastboot_tx_write_str(response); | 4154 | fastboot_tx_write_str(response); |
4155 | } | 4155 | } |
4156 | #endif | 4156 | #endif |
4157 | 4157 | ||
4158 | #endif /* CONFIG_FSL_FASTBOOT*/ | 4158 | #endif /* CONFIG_FSL_FASTBOOT*/ |
4159 | 4159 | ||
4160 | static unsigned int rx_bytes_expected(struct usb_ep *ep) | 4160 | static unsigned int rx_bytes_expected(struct usb_ep *ep) |
4161 | { | 4161 | { |
4162 | int rx_remain = download_size - download_bytes; | 4162 | int rx_remain = download_size - download_bytes; |
4163 | unsigned int rem; | 4163 | unsigned int rem; |
4164 | unsigned int maxpacket = ep->maxpacket; | 4164 | unsigned int maxpacket = ep->maxpacket; |
4165 | 4165 | ||
4166 | if (rx_remain <= 0) | 4166 | if (rx_remain <= 0) |
4167 | return 0; | 4167 | return 0; |
4168 | else if (rx_remain > EP_BUFFER_SIZE) | 4168 | else if (rx_remain > EP_BUFFER_SIZE) |
4169 | return EP_BUFFER_SIZE; | 4169 | return EP_BUFFER_SIZE; |
4170 | 4170 | ||
4171 | /* | 4171 | /* |
4172 | * Some controllers e.g. DWC3 don't like OUT transfers to be | 4172 | * Some controllers e.g. DWC3 don't like OUT transfers to be |
4173 | * not ending in maxpacket boundary. So just make them happy by | 4173 | * not ending in maxpacket boundary. So just make them happy by |
4174 | * always requesting for integral multiple of maxpackets. | 4174 | * always requesting for integral multiple of maxpackets. |
4175 | * This shouldn't bother controllers that don't care about it. | 4175 | * This shouldn't bother controllers that don't care about it. |
4176 | */ | 4176 | */ |
4177 | rem = rx_remain % maxpacket; | 4177 | rem = rx_remain % maxpacket; |
4178 | if (rem > 0) | 4178 | if (rem > 0) |
4179 | rx_remain = rx_remain + (maxpacket - rem); | 4179 | rx_remain = rx_remain + (maxpacket - rem); |
4180 | 4180 | ||
4181 | return rx_remain; | 4181 | return rx_remain; |
4182 | } | 4182 | } |
4183 | 4183 | ||
4184 | #define BYTES_PER_DOT 0x20000 | 4184 | #define BYTES_PER_DOT 0x20000 |
4185 | static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) | 4185 | static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) |
4186 | { | 4186 | { |
4187 | char response[FASTBOOT_RESPONSE_LEN]; | 4187 | char response[FASTBOOT_RESPONSE_LEN]; |
4188 | unsigned int transfer_size = download_size - download_bytes; | 4188 | unsigned int transfer_size = download_size - download_bytes; |
4189 | const unsigned char *buffer = req->buf; | 4189 | const unsigned char *buffer = req->buf; |
4190 | unsigned int buffer_size = req->actual; | 4190 | unsigned int buffer_size = req->actual; |
4191 | unsigned int pre_dot_num, now_dot_num; | 4191 | unsigned int pre_dot_num, now_dot_num; |
4192 | void * base_addr = (void*)env_get_ulong("fastboot_buffer", 16, CONFIG_FASTBOOT_BUF_ADDR); | 4192 | void * base_addr = (void*)env_get_ulong("fastboot_buffer", 16, CONFIG_FASTBOOT_BUF_ADDR); |
4193 | 4193 | ||
4194 | if (req->status != 0) { | 4194 | if (req->status != 0) { |
4195 | printf("Bad status: %d\n", req->status); | 4195 | printf("Bad status: %d\n", req->status); |
4196 | return; | 4196 | return; |
4197 | } | 4197 | } |
4198 | 4198 | ||
4199 | if (buffer_size < transfer_size) | 4199 | if (buffer_size < transfer_size) |
4200 | transfer_size = buffer_size; | 4200 | transfer_size = buffer_size; |
4201 | 4201 | ||
4202 | memcpy(base_addr + download_bytes, | 4202 | memcpy(base_addr + download_bytes, |
4203 | buffer, transfer_size); | 4203 | buffer, transfer_size); |
4204 | 4204 | ||
4205 | pre_dot_num = download_bytes / BYTES_PER_DOT; | 4205 | pre_dot_num = download_bytes / BYTES_PER_DOT; |
4206 | download_bytes += transfer_size; | 4206 | download_bytes += transfer_size; |
4207 | now_dot_num = download_bytes / BYTES_PER_DOT; | 4207 | now_dot_num = download_bytes / BYTES_PER_DOT; |
4208 | 4208 | ||
4209 | if (pre_dot_num != now_dot_num) { | 4209 | if (pre_dot_num != now_dot_num) { |
4210 | putc('.'); | 4210 | putc('.'); |
4211 | if (!(now_dot_num % 74)) | 4211 | if (!(now_dot_num % 74)) |
4212 | putc('\n'); | 4212 | putc('\n'); |
4213 | } | 4213 | } |
4214 | 4214 | ||
4215 | /* Check if transfer is done */ | 4215 | /* Check if transfer is done */ |
4216 | if (download_bytes >= download_size) { | 4216 | if (download_bytes >= download_size) { |
4217 | /* | 4217 | /* |
4218 | * Reset global transfer variable, keep download_bytes because | 4218 | * Reset global transfer variable, keep download_bytes because |
4219 | * it will be used in the next possible flashing command | 4219 | * it will be used in the next possible flashing command |
4220 | */ | 4220 | */ |
4221 | download_size = 0; | 4221 | download_size = 0; |
4222 | req->complete = rx_handler_command; | 4222 | req->complete = rx_handler_command; |
4223 | req->length = EP_BUFFER_SIZE; | 4223 | req->length = EP_BUFFER_SIZE; |
4224 | 4224 | ||
4225 | strcpy(response, "OKAY"); | 4225 | strcpy(response, "OKAY"); |
4226 | fastboot_tx_write_str(response); | 4226 | fastboot_tx_write_str(response); |
4227 | env_set_hex("fastboot_bytes", download_bytes); | 4227 | env_set_hex("fastboot_bytes", download_bytes); |
4228 | 4228 | ||
4229 | printf("\ndownloading of %d bytes finished\n", download_bytes); | 4229 | printf("\ndownloading of %d bytes finished\n", download_bytes); |
4230 | } else { | 4230 | } else { |
4231 | req->length = rx_bytes_expected(ep); | 4231 | req->length = rx_bytes_expected(ep); |
4232 | } | 4232 | } |
4233 | 4233 | ||
4234 | req->actual = 0; | 4234 | req->actual = 0; |
4235 | usb_ep_queue(ep, req, 0); | 4235 | usb_ep_queue(ep, req, 0); |
4236 | } | 4236 | } |
4237 | 4237 | ||
4238 | static void cb_upload(struct usb_ep *ep, struct usb_request *req) | 4238 | static void cb_upload(struct usb_ep *ep, struct usb_request *req) |
4239 | { | 4239 | { |
4240 | char response[FASTBOOT_RESPONSE_LEN]; | 4240 | char response[FASTBOOT_RESPONSE_LEN]; |
4241 | 4241 | ||
4242 | if (!download_bytes || download_bytes > (EP_BUFFER_SIZE * 32)) { | 4242 | if (!download_bytes || download_bytes > (EP_BUFFER_SIZE * 32)) { |
4243 | sprintf(response, "FAIL"); | 4243 | sprintf(response, "FAIL"); |
4244 | fastboot_tx_write_str(response); | 4244 | fastboot_tx_write_str(response); |
4245 | return; | 4245 | return; |
4246 | } | 4246 | } |
4247 | 4247 | ||
4248 | printf("Will upload %d bytes.\n", download_bytes); | 4248 | printf("Will upload %d bytes.\n", download_bytes); |
4249 | snprintf(response, FASTBOOT_RESPONSE_LEN, "DATA%08x", download_bytes); | 4249 | snprintf(response, FASTBOOT_RESPONSE_LEN, "DATA%08x", download_bytes); |
4250 | fastboot_tx_write_more(response); | 4250 | fastboot_tx_write_more(response); |
4251 | 4251 | ||
4252 | fastboot_tx_write((const char *)(interface.transfer_buffer), download_bytes); | 4252 | fastboot_tx_write((const char *)(interface.transfer_buffer), download_bytes); |
4253 | 4253 | ||
4254 | snprintf(response,FASTBOOT_RESPONSE_LEN, "OKAY"); | 4254 | snprintf(response,FASTBOOT_RESPONSE_LEN, "OKAY"); |
4255 | fastboot_tx_write_more(response); | 4255 | fastboot_tx_write_more(response); |
4256 | } | 4256 | } |
4257 | 4257 | ||
4258 | static void cb_download(struct usb_ep *ep, struct usb_request *req) | 4258 | static void cb_download(struct usb_ep *ep, struct usb_request *req) |
4259 | { | 4259 | { |
4260 | char *cmd = req->buf; | 4260 | char *cmd = req->buf; |
4261 | char response[FASTBOOT_RESPONSE_LEN]; | 4261 | char response[FASTBOOT_RESPONSE_LEN]; |
4262 | 4262 | ||
4263 | strsep(&cmd, ":"); | 4263 | strsep(&cmd, ":"); |
4264 | download_size = simple_strtoul(cmd, NULL, 16); | 4264 | download_size = simple_strtoul(cmd, NULL, 16); |
4265 | download_bytes = 0; | 4265 | download_bytes = 0; |
4266 | 4266 | ||
4267 | printf("Starting download of %d bytes\n", download_size); | 4267 | printf("Starting download of %d bytes\n", download_size); |
4268 | 4268 | ||
4269 | if (0 == download_size) { | 4269 | if (0 == download_size) { |
4270 | strcpy(response, "FAILdata invalid size"); | 4270 | strcpy(response, "FAILdata invalid size"); |
4271 | } else if (download_size > CONFIG_FASTBOOT_BUF_SIZE) { | 4271 | } else if (download_size > CONFIG_FASTBOOT_BUF_SIZE) { |
4272 | download_size = 0; | 4272 | download_size = 0; |
4273 | strcpy(response, "FAILdata too large"); | 4273 | strcpy(response, "FAILdata too large"); |
4274 | } else { | 4274 | } else { |
4275 | sprintf(response, "DATA%08x", download_size); | 4275 | sprintf(response, "DATA%08x", download_size); |
4276 | req->complete = rx_handler_dl_image; | 4276 | req->complete = rx_handler_dl_image; |
4277 | req->length = rx_bytes_expected(ep); | 4277 | req->length = rx_bytes_expected(ep); |
4278 | } | 4278 | } |
4279 | fastboot_tx_write_str(response); | 4279 | fastboot_tx_write_str(response); |
4280 | } | 4280 | } |
4281 | 4281 | ||
4282 | static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req) | 4282 | static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req) |
4283 | { | 4283 | { |
4284 | char boot_addr_start[12]; | 4284 | char boot_addr_start[12]; |
4285 | #ifdef CONFIG_FSL_FASTBOOT | 4285 | #ifdef CONFIG_FSL_FASTBOOT |
4286 | char *bootm_args[] = { "boota", boot_addr_start, NULL }; | 4286 | char *bootm_args[] = { "boota", boot_addr_start, NULL }; |
4287 | sprintf(boot_addr_start, "0x%lx", load_addr); | 4287 | sprintf(boot_addr_start, "0x%lx", load_addr); |
4288 | #else | 4288 | #else |
4289 | char *bootm_args[] = { "bootm", boot_addr_start, NULL }; | 4289 | char *bootm_args[] = { "bootm", boot_addr_start, NULL }; |
4290 | sprintf(boot_addr_start, "0x%lx", (long)CONFIG_FASTBOOT_BUF_ADDR); | 4290 | sprintf(boot_addr_start, "0x%lx", (long)CONFIG_FASTBOOT_BUF_ADDR); |
4291 | #endif | 4291 | #endif |
4292 | 4292 | ||
4293 | puts("Booting kernel..\n"); | 4293 | puts("Booting kernel..\n"); |
4294 | 4294 | ||
4295 | do_bootm(NULL, 0, 2, bootm_args); | 4295 | do_bootm(NULL, 0, 2, bootm_args); |
4296 | 4296 | ||
4297 | /* This only happens if image is somehow faulty so we start over */ | 4297 | /* This only happens if image is somehow faulty so we start over */ |
4298 | do_reset(NULL, 0, 0, NULL); | 4298 | do_reset(NULL, 0, 0, NULL); |
4299 | } | 4299 | } |
4300 | 4300 | ||
4301 | static void cb_boot(struct usb_ep *ep, struct usb_request *req) | 4301 | static void cb_boot(struct usb_ep *ep, struct usb_request *req) |
4302 | { | 4302 | { |
4303 | fastboot_func->in_req->complete = do_bootm_on_complete; | 4303 | fastboot_func->in_req->complete = do_bootm_on_complete; |
4304 | fastboot_tx_write_str("OKAY"); | 4304 | fastboot_tx_write_str("OKAY"); |
4305 | } | 4305 | } |
4306 | 4306 | ||
4307 | static void do_exit_on_complete(struct usb_ep *ep, struct usb_request *req) | 4307 | static void do_exit_on_complete(struct usb_ep *ep, struct usb_request *req) |
4308 | { | 4308 | { |
4309 | g_dnl_trigger_detach(); | 4309 | g_dnl_trigger_detach(); |
4310 | } | 4310 | } |
4311 | 4311 | ||
4312 | static void cb_continue(struct usb_ep *ep, struct usb_request *req) | 4312 | static void cb_continue(struct usb_ep *ep, struct usb_request *req) |
4313 | { | 4313 | { |
4314 | fastboot_func->in_req->complete = do_exit_on_complete; | 4314 | fastboot_func->in_req->complete = do_exit_on_complete; |
4315 | fastboot_tx_write_str("OKAY"); | 4315 | fastboot_tx_write_str("OKAY"); |
4316 | } | 4316 | } |
4317 | 4317 | ||
4318 | struct cmd_dispatch_info { | 4318 | struct cmd_dispatch_info { |
4319 | char *cmd; | 4319 | char *cmd; |
4320 | void (*cb)(struct usb_ep *ep, struct usb_request *req); | 4320 | void (*cb)(struct usb_ep *ep, struct usb_request *req); |
4321 | }; | 4321 | }; |
4322 | 4322 | ||
4323 | static const struct cmd_dispatch_info cmd_dispatch_info[] = { | 4323 | static const struct cmd_dispatch_info cmd_dispatch_info[] = { |
4324 | #ifdef CONFIG_FSL_FASTBOOT | 4324 | #ifdef CONFIG_FSL_FASTBOOT |
4325 | { | 4325 | { |
4326 | .cmd = "reboot-bootloader", | 4326 | .cmd = "reboot-bootloader", |
4327 | .cb = cb_reboot_bootloader, | 4327 | .cb = cb_reboot_bootloader, |
4328 | }, | 4328 | }, |
4329 | { | 4329 | { |
4330 | .cmd = "upload", | 4330 | .cmd = "upload", |
4331 | .cb = cb_upload, | 4331 | .cb = cb_upload, |
4332 | }, | 4332 | }, |
4333 | { | 4333 | { |
4334 | .cmd = "get_staged", | 4334 | .cmd = "get_staged", |
4335 | .cb = cb_upload, | 4335 | .cb = cb_upload, |
4336 | }, | 4336 | }, |
4337 | #ifdef CONFIG_FASTBOOT_LOCK | 4337 | #ifdef CONFIG_FASTBOOT_LOCK |
4338 | { | 4338 | { |
4339 | .cmd = "flashing", | 4339 | .cmd = "flashing", |
4340 | .cb = cb_flashing, | 4340 | .cb = cb_flashing, |
4341 | }, | 4341 | }, |
4342 | { | 4342 | { |
4343 | .cmd = "oem", | 4343 | .cmd = "oem", |
4344 | .cb = cb_flashing, | 4344 | .cb = cb_flashing, |
4345 | }, | 4345 | }, |
4346 | #endif | 4346 | #endif |
4347 | #ifdef CONFIG_AVB_SUPPORT | 4347 | #ifdef CONFIG_AVB_SUPPORT |
4348 | { | 4348 | { |
4349 | .cmd = "set_active", | 4349 | .cmd = "set_active", |
4350 | .cb = cb_set_active_avb, | 4350 | .cb = cb_set_active_avb, |
4351 | }, | 4351 | }, |
4352 | #endif | 4352 | #endif |
4353 | { | 4353 | { |
4354 | .cmd = "UCmd:", | 4354 | .cmd = "UCmd:", |
4355 | .cb = cb_run_uboot_cmd, | 4355 | .cb = cb_run_uboot_cmd, |
4356 | }, | 4356 | }, |
4357 | { .cmd ="ACmd:", | 4357 | { .cmd ="ACmd:", |
4358 | .cb = cb_run_uboot_acmd, | 4358 | .cb = cb_run_uboot_acmd, |
4359 | }, | 4359 | }, |
4360 | #endif | 4360 | #endif |
4361 | { | 4361 | { |
4362 | .cmd = "reboot", | 4362 | .cmd = "reboot", |
4363 | .cb = cb_reboot, | 4363 | .cb = cb_reboot, |
4364 | }, { | 4364 | }, { |
4365 | .cmd = "getvar:", | 4365 | .cmd = "getvar:", |
4366 | .cb = cb_getvar, | 4366 | .cb = cb_getvar, |
4367 | }, { | 4367 | }, { |
4368 | .cmd = "download:", | 4368 | .cmd = "download:", |
4369 | .cb = cb_download, | 4369 | .cb = cb_download, |
4370 | }, { | 4370 | }, { |
4371 | .cmd = "boot", | 4371 | .cmd = "boot", |
4372 | .cb = cb_boot, | 4372 | .cb = cb_boot, |
4373 | }, { | 4373 | }, { |
4374 | .cmd = "continue", | 4374 | .cmd = "continue", |
4375 | .cb = cb_continue, | 4375 | .cb = cb_continue, |
4376 | }, | 4376 | }, |
4377 | #ifdef CONFIG_FASTBOOT_FLASH | 4377 | #ifdef CONFIG_FASTBOOT_FLASH |
4378 | { | 4378 | { |
4379 | .cmd = "flash", | 4379 | .cmd = "flash", |
4380 | .cb = cb_flash, | 4380 | .cb = cb_flash, |
4381 | }, { | 4381 | }, { |
4382 | .cmd = "erase", | 4382 | .cmd = "erase", |
4383 | .cb = cb_erase, | 4383 | .cb = cb_erase, |
4384 | }, | 4384 | }, |
4385 | #endif | 4385 | #endif |
4386 | #ifndef CONFIG_FSL_FASTBOOT | 4386 | #ifndef CONFIG_FSL_FASTBOOT |
4387 | { | 4387 | { |
4388 | .cmd = "oem", | 4388 | .cmd = "oem", |
4389 | .cb = cb_oem, | 4389 | .cb = cb_oem, |
4390 | }, | 4390 | }, |
4391 | #endif | 4391 | #endif |
4392 | #ifdef CONFIG_AVB_ATX | 4392 | #ifdef CONFIG_AVB_ATX |
4393 | { | 4393 | { |
4394 | .cmd = "stage", | 4394 | .cmd = "stage", |
4395 | .cb = cb_download, | 4395 | .cb = cb_download, |
4396 | }, | 4396 | }, |
4397 | #endif | 4397 | #endif |
4398 | }; | 4398 | }; |
4399 | 4399 | ||
4400 | static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) | 4400 | static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) |
4401 | { | 4401 | { |
4402 | char *cmdbuf = req->buf; | 4402 | char *cmdbuf = req->buf; |
4403 | void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL; | 4403 | void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL; |
4404 | int i; | 4404 | int i; |
4405 | 4405 | ||
4406 | /* init in request FIFO pointer */ | 4406 | /* init in request FIFO pointer */ |
4407 | fastboot_func->front = NULL; | 4407 | fastboot_func->front = NULL; |
4408 | fastboot_func->rear = NULL; | 4408 | fastboot_func->rear = NULL; |
4409 | 4409 | ||
4410 | if (req->status != 0 || req->length == 0) | 4410 | if (req->status != 0 || req->length == 0) |
4411 | return; | 4411 | return; |
4412 | 4412 | ||
4413 | for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) { | 4413 | for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) { |
4414 | if (!strcmp_l1(cmd_dispatch_info[i].cmd, cmdbuf)) { | 4414 | if (!strcmp_l1(cmd_dispatch_info[i].cmd, cmdbuf)) { |
4415 | func_cb = cmd_dispatch_info[i].cb; | 4415 | func_cb = cmd_dispatch_info[i].cb; |
4416 | break; | 4416 | break; |
4417 | } | 4417 | } |
4418 | } | 4418 | } |
4419 | 4419 | ||
4420 | if (!func_cb) { | 4420 | if (!func_cb) { |
4421 | pr_err("unknown command: %.*s", req->actual, cmdbuf); | 4421 | pr_err("unknown command: %.*s", req->actual, cmdbuf); |
4422 | fastboot_tx_write_str("FAILunknown command"); | 4422 | fastboot_tx_write_str("FAILunknown command"); |
4423 | } else { | 4423 | } else { |
4424 | if (req->actual < req->length) { | 4424 | if (req->actual < req->length) { |
4425 | u8 *buf = (u8 *)req->buf; | 4425 | u8 *buf = (u8 *)req->buf; |
4426 | buf[req->actual] = 0; | 4426 | buf[req->actual] = 0; |
4427 | func_cb(ep, req); | 4427 | func_cb(ep, req); |
4428 | } else { | 4428 | } else { |
4429 | pr_err("buffer overflow"); | 4429 | pr_err("buffer overflow"); |
4430 | fastboot_tx_write_str("FAILbuffer overflow"); | 4430 | fastboot_tx_write_str("FAILbuffer overflow"); |
4431 | } | 4431 | } |
4432 | } | 4432 | } |
4433 | 4433 | ||
4434 | *cmdbuf = '\0'; | 4434 | *cmdbuf = '\0'; |