blob: a6a1664f1af52a78625618898b1661612f19bb7d [file] [log] [blame]
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001// SPDX-License-Identifier: BSD-2-Clause
2/*
3 * Copyright (C) 2016 The Android Open Source Project
4 */
5
6#include <common.h>
Simon Glass288b29e2019-11-14 12:57:43 -07007#include <command.h>
Simon Glassc7694dd2019-08-01 09:46:46 -06008#include <env.h>
Alex Kiernanf73a7df2018-05-29 15:30:53 +00009#include <fastboot.h>
10#include <fastboot-internal.h>
11#include <fb_mmc.h>
12#include <fb_nand.h>
13#include <part.h>
14#include <stdlib.h>
Xindong Xud9441422024-01-18 10:20:45 +080015#ifdef CONFIG_AMLOGIC_MODIFY
16#include <amlogic/emmc_partitions.h>
17#include <amlogic/storage.h>
18#include <amlogic/aml_efuse.h>
19#include <amlogic/aml_mmc.h>
20
21#include <android_image.h>
22#include <image.h>
23#include <amlogic/store_wrapper.h>
24#include <malloc.h>
25#include <amlogic/image_check.h>
26#include <fs.h>
Xindong Xuac88caf2024-10-28 17:10:12 +080027#include <version.h>
Xindong Xud9441422024-01-18 10:20:45 +080028#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
29#include <amlogic/anti-rollback.h>
30#endif
31#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000032
33/**
34 * image_size - final fastboot image size
35 */
36static u32 image_size;
37
38/**
39 * fastboot_bytes_received - number of bytes received in the current download
40 */
41static u32 fastboot_bytes_received;
42
43/**
44 * fastboot_bytes_expected - number of bytes expected in the current download
45 */
46static u32 fastboot_bytes_expected;
47
Xindong Xud9441422024-01-18 10:20:45 +080048#ifdef CONFIG_AMLOGIC_MODIFY
49int busy_flag;
50#endif
51
Alex Kiernanf73a7df2018-05-29 15:30:53 +000052static void okay(char *, char *);
53static void getvar(char *, char *);
Xindong Xud9441422024-01-18 10:20:45 +080054
55#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +000056static void download(char *, char *);
57#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
58static void flash(char *, char *);
59static void erase(char *, char *);
60#endif
Xindong Xud9441422024-01-18 10:20:45 +080061#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000062static void reboot_bootloader(char *, char *);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +030063static void reboot_fastbootd(char *, char *);
64static void reboot_recovery(char *, char *);
Xindong Xud9441422024-01-18 10:20:45 +080065#ifdef CONFIG_FASTBOOT_WRITING_CMD
66#ifdef CONFIG_AMLOGIC_MODIFY
67static void fetch(char *, char *);
Xindong Xub3cf2a82024-12-25 10:23:47 +080068static void oem_cmd(char *, char *);
Xindong Xud9441422024-01-18 10:20:45 +080069#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
70static void flashing(char *, char *);
71#endif
72#endif
Alex Kiernan3845b902018-05-29 15:30:54 +000073#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
74static void oem_format(char *, char *);
75#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +010076#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
77static void oem_partconf(char *, char *);
78#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +010079#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
80static void oem_bootbus(char *, char *);
81#endif
Xindong Xud9441422024-01-18 10:20:45 +080082static void set_active_cmd(char *, char *);
83#endif
84
85#ifdef CONFIG_AMLOGIC_MODIFY
86extern int is_partition_logical(char* partition_name);
87#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000088
Heiko Schocherbc820d52021-02-10 09:29:03 +010089#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
90static void run_ucmd(char *, char *);
91static void run_acmd(char *, char *);
92#endif
93
Alex Kiernanf73a7df2018-05-29 15:30:53 +000094static const struct {
95 const char *command;
96 void (*dispatch)(char *cmd_parameter, char *response);
97} commands[FASTBOOT_COMMAND_COUNT] = {
98 [FASTBOOT_COMMAND_GETVAR] = {
99 .command = "getvar",
100 .dispatch = getvar
101 },
Xindong Xud9441422024-01-18 10:20:45 +0800102#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000103 [FASTBOOT_COMMAND_DOWNLOAD] = {
104 .command = "download",
105 .dispatch = download
106 },
Xindong Xud9441422024-01-18 10:20:45 +0800107#ifdef CONFIG_AMLOGIC_MODIFY
108#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
109 [FASTBOOT_COMMAND_FLASHING] = {
110 .command = "flashing",
111 .dispatch = flashing
112 },
113#endif
114 [FASTBOOT_COMMAND_FETCH] = {
115 .command = "fetch",
116 .dispatch = fetch
117 },
Xindong Xub3cf2a82024-12-25 10:23:47 +0800118 [FASTBOOT_COMMAND_OEM] = {
119 .command = "oem",
120 .dispatch = oem_cmd,
121 },
Xindong Xud9441422024-01-18 10:20:45 +0800122#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000123#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
124 [FASTBOOT_COMMAND_FLASH] = {
125 .command = "flash",
126 .dispatch = flash
127 },
128 [FASTBOOT_COMMAND_ERASE] = {
129 .command = "erase",
130 .dispatch = erase
131 },
132#endif
133 [FASTBOOT_COMMAND_BOOT] = {
134 .command = "boot",
135 .dispatch = okay
136 },
Xindong Xud9441422024-01-18 10:20:45 +0800137#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000138 [FASTBOOT_COMMAND_CONTINUE] = {
139 .command = "continue",
140 .dispatch = okay
141 },
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000142 [FASTBOOT_COMMAND_REBOOT_BOOTLOADER] = {
143 .command = "reboot-bootloader",
144 .dispatch = reboot_bootloader
145 },
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +0300146 [FASTBOOT_COMMAND_REBOOT_FASTBOOTD] = {
147 .command = "reboot-fastboot",
148 .dispatch = reboot_fastbootd
149 },
150 [FASTBOOT_COMMAND_REBOOT_RECOVERY] = {
151 .command = "reboot-recovery",
152 .dispatch = reboot_recovery
153 },
Xindong Xud9441422024-01-18 10:20:45 +0800154 [FASTBOOT_COMMAND_REBOOT] = {
155 .command = "reboot",
156 .dispatch = okay
157 },
158#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000159 [FASTBOOT_COMMAND_SET_ACTIVE] = {
160 .command = "set_active",
Xindong Xud9441422024-01-18 10:20:45 +0800161#ifdef CONFIG_AMLOGIC_MODIFY
162 .dispatch = set_active_cmd
163#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000164 .dispatch = okay
Xindong Xud9441422024-01-18 10:20:45 +0800165#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000166 },
Alex Kiernan3845b902018-05-29 15:30:54 +0000167#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
168 [FASTBOOT_COMMAND_OEM_FORMAT] = {
169 .command = "oem format",
170 .dispatch = oem_format,
171 },
172#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +0100173#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
174 [FASTBOOT_COMMAND_OEM_PARTCONF] = {
175 .command = "oem partconf",
176 .dispatch = oem_partconf,
177 },
178#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +0100179#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
180 [FASTBOOT_COMMAND_OEM_BOOTBUS] = {
181 .command = "oem bootbus",
182 .dispatch = oem_bootbus,
183 },
184#endif
Xindong Xud9441422024-01-18 10:20:45 +0800185#endif
Heiko Schocherbc820d52021-02-10 09:29:03 +0100186#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
187 [FASTBOOT_COMMAND_UCMD] = {
188 .command = "UCmd",
189 .dispatch = run_ucmd,
190 },
191 [FASTBOOT_COMMAND_ACMD] = {
192 .command = "ACmd",
193 .dispatch = run_acmd,
194 },
195#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000196};
197
Xindong Xud9441422024-01-18 10:20:45 +0800198#ifdef CONFIG_AMLOGIC_MODIFY
199struct fastboot_read fastboot_readInfo;
200
201static int strcmp_l1(const char *s1, const char *s2)
202{
203 if (!s1 || !s2)
204 return -1;
205 return strncmp(s1, s2, strlen(s1));
206}
207#endif
208
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000209/**
210 * fastboot_handle_command - Handle fastboot command
211 *
212 * @cmd_string: Pointer to command string
213 * @response: Pointer to fastboot response buffer
214 *
215 * Return: Executed command, or -1 if not recognized
216 */
217int fastboot_handle_command(char *cmd_string, char *response)
218{
219 int i;
220 char *cmd_parameter;
221
222 cmd_parameter = cmd_string;
223 strsep(&cmd_parameter, ":");
224
225 for (i = 0; i < FASTBOOT_COMMAND_COUNT; i++) {
Xindong Xud9441422024-01-18 10:20:45 +0800226#ifdef CONFIG_AMLOGIC_MODIFY
227 if (!strcmp_l1(commands[i].command, cmd_string)) {
228 if (commands[i].dispatch) {
229 if (cmd_parameter) {
230 commands[i].dispatch(cmd_parameter,
231 response);
232 } else {
233 commands[i].dispatch(cmd_string,
234 response);
235 }
236 return i;
237 } else {
238 break;
239 }
240 }
241#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000242 if (!strcmp(commands[i].command, cmd_string)) {
243 if (commands[i].dispatch) {
244 commands[i].dispatch(cmd_parameter,
245 response);
246 return i;
247 } else {
248 break;
249 }
250 }
Xindong Xud9441422024-01-18 10:20:45 +0800251#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000252 }
253
254 pr_err("command %s not recognized.\n", cmd_string);
255 fastboot_fail("unrecognized command", response);
256 return -1;
257}
258
259/**
260 * okay() - Send bare OKAY response
261 *
262 * @cmd_parameter: Pointer to command parameter
263 * @response: Pointer to fastboot response buffer
264 *
265 * Send a bare OKAY fastboot response. This is used where the command is
266 * valid, but all the work is done after the response has been sent (e.g.
267 * boot, reboot etc.)
268 */
269static void okay(char *cmd_parameter, char *response)
270{
271 fastboot_okay(NULL, response);
272}
273
Xindong Xud9441422024-01-18 10:20:45 +0800274#ifdef CONFIG_AMLOGIC_MODIFY
275void dump_lock_info(LockData_t info)
276{
277#if 0
278 printf("info.version_major = %d\n", info.version_major);
279 printf("info.version_minor = %d\n", info.version_minor);
280 printf("info.unlock_ability = %d\n", info.unlock_ability);
281 printf("info.lock_state = %d\n", info.lock_state);
282 printf("info.lock_critical_state = %d\n", info.lock_critical_state);
283 printf("info.lock_bootloader = %d\n", info.lock_bootloader);
284#endif
285}
286
287static const char* getvar_list[] = {
288 "version-baseband", "version-bootloader", "version", "hw-revision", "max-download-size",
289 "serialno", "product", "off-mode-charge", "variant", "battery-soc-ok",
290 "battery-voltage", "partition-type:boot", "partition-size:boot",
291 "partition-type:system", "partition-size:system", "partition-type:vendor", "partition-size:vendor",
292 "partition-type:odm", "partition-size:odm", "partition-type:data", "partition-size:data",
293 "erase-block-size", "logical-block-size", "secure", "unlocked",
294};
295
296static const char* getvar_list_dynamic[] = {
297 "hw-revision", "battery-voltage", "is-userspace", "is-logical:data",
298 "is-logical:metadata", "is-logical:misc", "is-logical:super", "is-logical:boot",
299 "is-logical:system", "is-logical:vendor", "is-logical:product", "is-logical:odm",
300 "slot-count", "max-download-size", "serialno", "product", "unlocked",
301 "secure", "super-partition-name", "version-baseband", "version-bootloader",
302 "partition-size:boot", "partition-size:metadata", "partition-size:misc",
303 "partition-size:super", "partition-size:data", "version",
304};
305
306static const char* getvar_list_dynamic_ab[] = {
307 "hw-revision", "battery-voltage", "is-userspace", "is-logical:data",
308 "is-logical:misc", "is-logical:super",
309 "is-logical:boot_a", "is-logical:boot_b", "is-logical:system_a", "is-logical:system_b",
310 "is-logical:vendor_a", "is-logical:vendor_b", "is-logical:product_a", "is-logical:product_b",
311 "is-logical:odm_a", "is-logical:odm_b",
312 "slot-count", "max-download-size", "serialno", "product", "unlocked", "has-slot:data",
313 "has-slot:metadata", "has-slot:misc", "has-slot:super", "has-slot:boot",
314 "has-slot:system", "has-slot:vendor", "has-slot:product", "has-slot:odm", "current-slot",
315 "secure", "super-partition-name", "version-baseband", "version-bootloader",
316 "partition-size:super",
317 "partition-size:boot_a", "partition-size:boot_b", "partition-size:misc",
318 "partition-size:data", "version",
319};
320
321
322static const char* getvar_list_ab[] = {
323 "version-baseband", "version-bootloader", "version", "hw-revision", "max-download-size",
324 "serialno", "product", "off-mode-charge", "variant", "battery-soc-ok",
325 "battery-voltage", "partition-type:boot_a", "partition-size:boot_a",
326 "partition-type:system_a", "partition-size:system_a", "partition-type:vendor_a", "partition-size:vendor_a",
327 "partition-type:odm_a", "partition-size:odm_a", "partition-type:data", "partition-size:data",
328 "erase-block-size", "logical-block-size", "secure", "unlocked",
329 "slot-count", "slot-suffixes","current-slot", "has-slot:bootloader", "has-slot:boot",
330 "has-slot:system", "has-slot:vendor", "has-slot:odm", "has-slot:vbmeta",
331 "has-slot:metadata", "has-slot:product", "has-slot:dtbo",
332 "slot-successful:a", "slot-unbootable:a", "slot-retry-count:a",
333 "slot-successful:b", "slot-unbootable:b", "slot-retry-count:b",
334};
335#endif
336
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000337/**
338 * getvar() - Read a config/version variable
339 *
340 * @cmd_parameter: Pointer to command parameter
341 * @response: Pointer to fastboot response buffer
342 */
343static void getvar(char *cmd_parameter, char *response)
344{
Xindong Xud9441422024-01-18 10:20:45 +0800345#ifdef CONFIG_AMLOGIC_MODIFY
346 run_command("get_valid_slot", 0);
347 if (!strncmp(cmd_parameter, "all", 3)) {
348 static int cmdIndex = 0;
349 int getvar_num = 0;
350 char* cmd=cmd_parameter;
351
352 busy_flag = 1;
353
354 if (dynamic_partition && has_boot_slot == 1 && strlen(getvar_list_dynamic_ab[cmdIndex]) < 64) {
355 strncpy(cmd, getvar_list_dynamic_ab[cmdIndex], 64);
356 getvar_num = (sizeof(getvar_list_dynamic_ab) / sizeof(getvar_list_dynamic_ab[0]));
357 } else if (has_boot_slot == 1 && strlen(getvar_list_ab[cmdIndex]) < 64) {
358 strncpy(cmd, getvar_list_ab[cmdIndex], 64);
359 getvar_num = (sizeof(getvar_list_ab) / sizeof(getvar_list_ab[0]));
360 } else if (dynamic_partition && strlen(getvar_list_dynamic[cmdIndex]) < 64) {
361 strncpy(cmd, getvar_list_dynamic[cmdIndex], 64);//only support no-arg cmd
362 getvar_num = (sizeof(getvar_list_dynamic) / sizeof(getvar_list_dynamic[0]));
363 } else if (strlen(getvar_list[cmdIndex]) < 64) {
364 strncpy(cmd, getvar_list[cmdIndex], 64);//only support no-arg cmd
365 getvar_num = (sizeof(getvar_list) / sizeof(getvar_list[0]));
366 }
367 //printf("getvar_num: %d\n", getvar_num);
368 //printf("all cmd:%s\n", cmd);
369 if ( ++cmdIndex >= getvar_num) {
370 cmdIndex = 0;
371 busy_flag = 0;
372 fastboot_okay(NULL, response);
373 } else {
374 fastboot_getvar(cmd, response);
375 }
376
377 }else {
378#endif
379 fastboot_getvar(cmd_parameter, response);
380#ifdef CONFIG_AMLOGIC_MODIFY
381 }
382#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000383}
384
385/**
386 * fastboot_download() - Start a download transfer from the client
387 *
388 * @cmd_parameter: Pointer to command parameter
389 * @response: Pointer to fastboot response buffer
390 */
Xindong Xud9441422024-01-18 10:20:45 +0800391#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000392static void download(char *cmd_parameter, char *response)
393{
394 char *tmp;
395
Xindong Xud9441422024-01-18 10:20:45 +0800396#ifdef CONFIG_AMLOGIC_MODIFY
397 if (check_lock() == 1) {
398 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
399 fastboot_fail("locked device", response);
400 return;
401 }
402#endif
403
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000404 if (!cmd_parameter) {
405 fastboot_fail("Expected command parameter", response);
406 return;
407 }
408 fastboot_bytes_received = 0;
Simon Glass7e5f4602021-07-24 09:03:29 -0600409 fastboot_bytes_expected = hextoul(cmd_parameter, &tmp);
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000410 if (fastboot_bytes_expected == 0) {
411 fastboot_fail("Expected nonzero image size", response);
412 return;
413 }
414 /*
415 * Nothing to download yet. Response is of the form:
416 * [DATA|FAIL]$cmd_parameter
417 *
418 * where cmd_parameter is an 8 digit hexadecimal number
419 */
420 if (fastboot_bytes_expected > fastboot_buf_size) {
Xindong Xud9441422024-01-18 10:20:45 +0800421#ifdef CONFIG_AMLOGIC_MODIFY
422 char str[128] = {0};
423
424 printf("fastboot_bytes_expected %d > fastboot_buf_size %d\n",
425 fastboot_bytes_expected, fastboot_buf_size);
426 sprintf(str, "data too large, please add -S %dM",
427 (fastboot_buf_size / 1024 / 1024));
428 fastboot_fail(str, response);
429#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000430 fastboot_fail(cmd_parameter, response);
Xindong Xud9441422024-01-18 10:20:45 +0800431#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000432 } else {
433 printf("Starting download of %d bytes\n",
434 fastboot_bytes_expected);
435 fastboot_response("DATA", response, "%s", cmd_parameter);
436 }
437}
Xindong Xud9441422024-01-18 10:20:45 +0800438#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000439/**
440 * fastboot_data_remaining() - return bytes remaining in current transfer
441 *
442 * Return: Number of bytes left in the current download
443 */
444u32 fastboot_data_remaining(void)
445{
446 return fastboot_bytes_expected - fastboot_bytes_received;
447}
448
449/**
450 * fastboot_data_download() - Copy image data to fastboot_buf_addr.
451 *
452 * @fastboot_data: Pointer to received fastboot data
453 * @fastboot_data_len: Length of received fastboot data
454 * @response: Pointer to fastboot response buffer
455 *
456 * Copies image data from fastboot_data to fastboot_buf_addr. Writes to
457 * response. fastboot_bytes_received is updated to indicate the number
458 * of bytes that have been transferred.
459 *
460 * On completion sets image_size and ${filesize} to the total size of the
461 * downloaded image.
462 */
463void fastboot_data_download(const void *fastboot_data,
464 unsigned int fastboot_data_len,
465 char *response)
466{
467#define BYTES_PER_DOT 0x20000
468 u32 pre_dot_num, now_dot_num;
469
470 if (fastboot_data_len == 0 ||
471 (fastboot_bytes_received + fastboot_data_len) >
472 fastboot_bytes_expected) {
473 fastboot_fail("Received invalid data length",
474 response);
475 return;
476 }
477 /* Download data to fastboot_buf_addr */
478 memcpy(fastboot_buf_addr + fastboot_bytes_received,
479 fastboot_data, fastboot_data_len);
480
481 pre_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
482 fastboot_bytes_received += fastboot_data_len;
483 now_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
484
485 if (pre_dot_num != now_dot_num) {
486 putc('.');
487 if (!(now_dot_num % 74))
488 putc('\n');
489 }
490 *response = '\0';
491}
492
493/**
494 * fastboot_data_complete() - Mark current transfer complete
495 *
496 * @response: Pointer to fastboot response buffer
497 *
498 * Set image_size and ${filesize} to the total size of the downloaded image.
499 */
500void fastboot_data_complete(char *response)
501{
502 /* Download complete. Respond with "OKAY" */
503 fastboot_okay(NULL, response);
504 printf("\ndownloading of %d bytes finished\n", fastboot_bytes_received);
505 image_size = fastboot_bytes_received;
506 env_set_hex("filesize", image_size);
507 fastboot_bytes_expected = 0;
508 fastboot_bytes_received = 0;
509}
510
Xindong Xud9441422024-01-18 10:20:45 +0800511#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000512#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
Xindong Xud9441422024-01-18 10:20:45 +0800513
514#ifdef CONFIG_AMLOGIC_MODIFY
515static void write_dts_reserve(void)
516{
517 int ret;
518 void *addr = NULL;
519 char *mem_addr;
520
521 if (run_command("imgread dtb ${boot_part} ${dtb_mem_addr}", 0)) {
522 printf("Fail in load dtb\n");
523 } else {
524 mem_addr = env_get("dtb_mem_addr");
525
526 if (mem_addr) {
527 addr = (void *)simple_strtoul(mem_addr, NULL, 16);
528 ret = dtb_write(addr);
529 if (ret)
530 printf("write dtb error\n");
531 else
532 printf("write dtb ok\n");
533 }
534 }
535}
536
Xindong Xu0afe60a2024-05-21 16:15:13 +0800537static int clear_misc_partition(void)
538{
539 char *partition = "misc";
540 char *buffer = NULL;
541 u64 rc = 0;
542
543 rc = store_part_size(partition);
544 buffer = (char *)malloc(rc - AVB_CUSTOM_KEY_LEN_MAX);
545 if (!buffer) {
546 printf("malloc error\n");
547 return -1;
548 }
549 memset(buffer, 0, rc - AVB_CUSTOM_KEY_LEN_MAX);
550
551 store_write((const char *)partition, 0, rc - AVB_CUSTOM_KEY_LEN_MAX,
552 (unsigned char *)buffer);
553
554 free(buffer);
555
556 return 0;
557}
558
Xindong Xu22e8daf2024-03-12 18:08:41 +0800559static void set_fastboot_flag(int flag)
Xindong Xud9441422024-01-18 10:20:45 +0800560{
561 env_set("default_env", "1");
Xindong Xu22e8daf2024-03-12 18:08:41 +0800562 if (flag == 1)
563 env_set("fastboot_step", "1");
Xindong Xud9441422024-01-18 10:20:45 +0800564#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
565 run_command("update_env_part -p default_env;", 0);
Xindong Xu22e8daf2024-03-12 18:08:41 +0800566 if (flag == 1)
567 run_command("update_env_part -p fastboot_step;", 0);
Xindong Xud9441422024-01-18 10:20:45 +0800568#else
569 run_command("defenv_reserve;", 0);
570 run_command("setenv default_env 1;", 0);
Xindong Xu22e8daf2024-03-12 18:08:41 +0800571 if (flag == 1)
572 run_command("setenv fastboot_step 1;", 0);
Xindong Xud9441422024-01-18 10:20:45 +0800573 run_command("saveenv;", 0);
574#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
575}
576#endif
577
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000578/**
579 * flash() - write the downloaded image to the indicated partition.
580 *
581 * @cmd_parameter: Pointer to partition name
582 * @response: Pointer to fastboot response buffer
583 *
584 * Writes the previously downloaded image to the partition indicated by
585 * cmd_parameter. Writes to response.
586 */
587static void flash(char *cmd_parameter, char *response)
588{
Xindong Xud9441422024-01-18 10:20:45 +0800589#ifdef CONFIG_AMLOGIC_MODIFY
590 char name[32] = {0};
591 u64 rc = 0;
592 int gpt_flag = -1;
593 int ret = -1;
594
595 if (check_lock() == 1) {
596 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
597 fastboot_fail("locked device", response);
598 return;
599 }
600
601 printf("cmd_parameter: %s\n", cmd_parameter);
602
603#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
604 struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
605 if (mmc && strcmp(cmd_parameter, "bootloader") == 0) {
606 printf("try to read gpt data from bootloader.img\n");
607 struct blk_desc *dev_desc;
608 int erase_flag = 0;
Xindong Xu22e8daf2024-03-12 18:08:41 +0800609 char *bootloaderindex;
610 char *slot_name = NULL;
611 char partname[32] = {0};
Xindong Xud9441422024-01-18 10:20:45 +0800612
Zhigang Yua69e3f92024-06-18 03:13:38 +0000613 ret = update_boot_hdr_4_s7d_reva(fastboot_buf_addr, image_size, 0);
614 if (ret) {
615 printf("Failed to write s7d reva boot0\n");
616 fastboot_fail("Failed to write s7d reva boot0", response);
617 return;
618 }
619
Xindong Xu22e8daf2024-03-12 18:08:41 +0800620 slot_name = env_get("active_slot");
621 if (slot_name && (strcmp(slot_name, "_a") == 0))
622 strcpy((char *)partname, "bootloader_a");
623 else if (slot_name && (strcmp(slot_name, "_b") == 0))
624 strcpy((char *)partname, "bootloader_b");
625 else
626 strcpy((char *)partname, "bootloader_up");
627
628 rc = store_part_size(partname);
Xindong Xud9441422024-01-18 10:20:45 +0800629 if (rc != -1) {
Xindong Xu22e8daf2024-03-12 18:08:41 +0800630 fastboot_mmc_erase(partname, response);
631 fastboot_mmc_flash_write(partname, fastboot_buf_addr, image_size,
Xindong Xud9441422024-01-18 10:20:45 +0800632 response);
633 }
634
635 /* the max size of bootloader.img is 4M, we reserve 128k for gpt.bin
636 * so we put gpt.bin at offset 0x3DFE00
637 * 0 ~ 512 bootloader secure boot, we don't care it here.
638 * 512 ~ 0x3DFDFF original bootloader.img and 0
639 * 0x3DFE00 ~ end gpt.bin
640 */
641
642 dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
643 if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
644 printf("invalid mmc device\n");
645 fastboot_fail("invalid mmc device", response);
646 return;
647 }
648
649 if (is_valid_gpt_buf(dev_desc, fastboot_buf_addr + 0x3DFE00)) {
650 printf("printf normal bootloader.img, no gpt partition table\n");
651 } else {
652 printf("find gpt partition table, update it\n"
653 "and write bootloader to boot0/boot1\n");
654
655 erase_flag = check_gpt_part(dev_desc, fastboot_buf_addr + 0x3DFE00);
656
657 if (erase_flag == 1) {
658 printf("partition changes, erase emmc\n");
659 //run_command("store erase.chip 0;", 0);
660 if (usb_burn_erase_data(0x3)) {
661 printf("partition erase failed!\n");
662 return;
663 }
664 }
665
666 if (write_mbr_and_gpt_partitions(dev_desc, fastboot_buf_addr + 0x3DFE00)) {
667 printf("%s: writing GPT partitions failed\n", __func__);
668 fastboot_fail("writing GPT partitions failed", response);
669 return;
670 }
671
672 if (mmc_device_init(mmc) != 0) {
673 printf(" update gpt partition table fail\n");
674 fastboot_fail("fastboot update gpt partition fail", response);
675 return;
676 }
677 printf("%s: writing GPT partitions ok\n", __func__);
678
679 char *mem_addr;
680 void *addr = NULL;
681 int ret;
682
683 mem_addr = env_get("dtb_mem_addr");
684
685 if (mem_addr && erase_flag == 1) {
686 printf("partition changes, erase emmc\n");
687 //run_command("store erase.chip 0;", 0);
688 if (usb_burn_erase_data(0x3)) {
689 printf("partition erase failed!\n");
690 return;
691 }
692 printf("write _aml_dtb\n");
693 addr = (void *)simple_strtoul(mem_addr, NULL, 16);
694 ret = dtb_write(addr);
695 if (ret)
696 printf("write _aml_dtb error\n");
697 else
698 printf("write _aml_dtb ok\n");
699 }
700 }
701
Xindong Xu0afe60a2024-05-21 16:15:13 +0800702 ret = clear_misc_partition();
703 if (ret) {
704 printf("clear misc partition error\n");
705 fastboot_fail("clear misc partition fail", response);
706 return;
707 }
708
Xindong Xud9441422024-01-18 10:20:45 +0800709 gpt_flag = aml_gpt_valid(mmc);
710 if (gpt_flag == 0)
711 ret = 0;
712
713#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
714 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
715
716 if (*efuse_field.data == 1) {
717 wrnP("efuse_field.data == 1\n");
718 ret = 0;
719 env_set("nocs_mode", "true");
720 } else {
721 wrnP("efuse_field.data != 1\n");
722 env_set("nocs_mode", "false");
723 }
724#endif//#ifdef CONFIG_EFUSE_OBJ_API
725
Xindong Xu22e8daf2024-03-12 18:08:41 +0800726 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
727
728 if (ret == 0) {
729 printf("gpt/nocs mode\n");
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000730#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
Xindong Xu22e8daf2024-03-12 18:08:41 +0800731 fastboot_mmc_flash_write("bootloader-boot1", fastboot_buf_addr, image_size,
732 response);
733 if (strcmp(bootloaderindex, "1") != 0) {
734 printf("boot from boot1, means boot0 is error, rewrite it\n");
735 fastboot_mmc_flash_write("bootloader-boot0",
736 fastboot_buf_addr, image_size, response);
737 run_command("mmc dev 1 0;", 0);
738 set_fastboot_flag(0);
739 } else {
740 printf("need to set fastboot_step\n");
741 run_command("mmc dev 1 0;", 0);
742 set_fastboot_flag(1);
743 }
Xindong Xud9441422024-01-18 10:20:45 +0800744#endif
Xindong Xu22e8daf2024-03-12 18:08:41 +0800745 return;
746 } else {
747 printf("normal mode\n");
748#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
749 fastboot_mmc_flash_write("bootloader-boot0", fastboot_buf_addr, image_size,
750 response);
751 fastboot_mmc_flash_write("bootloader-boot1", fastboot_buf_addr, image_size,
752 response);
753 if (strcmp(bootloaderindex, "0") != 0) {
754 printf("boot from boot0, rewrite user bootloader is error\n");
755 fastboot_mmc_flash_write("bootloader",
756 fastboot_buf_addr, image_size, response);
757 run_command("mmc dev 1 0;", 0);
758 set_fastboot_flag(0);
759 } else {
760 run_command("mmc dev 1 0;", 0);
761 set_fastboot_flag(1);
762 }
763#endif
764 return;
765 }
Xindong Xud9441422024-01-18 10:20:45 +0800766 }
767#endif
768
769 if (strcmp(cmd_parameter, "avb_custom_key") == 0) {
770 char* buffer = NULL;
771 char *partition = "misc";
772 AvbKey_t key;
773 printf("avb_custom_key image_size: %d\n", image_size);
774
775 if (image_size > AVB_CUSTOM_KEY_LEN_MAX - sizeof(AvbKey_t)) {
776 printf("key size is too large\n");
777 fastboot_fail("size error", response);
778 return;
779 }
780
781 memcpy(key.magic_name, "AVBK", 4);
782 key.size = image_size;
783 rc = store_part_size(partition);
784
785 buffer = (char *)malloc(AVB_CUSTOM_KEY_LEN_MAX);
786 if (!buffer) {
787 printf("malloc error\n");
788 fastboot_fail("malloc error", response);
789 return;
790 }
791 memset(buffer, 0, AVB_CUSTOM_KEY_LEN_MAX);
792 memcpy(buffer, &key, sizeof(AvbKey_t));
793 memcpy(buffer + sizeof(AvbKey_t), fastboot_buf_addr, image_size);
794
795 store_write((const char *)partition, rc - AVB_CUSTOM_KEY_LEN_MAX,
796 AVB_CUSTOM_KEY_LEN_MAX, (unsigned char *)buffer);
797
798 fastboot_okay(NULL, response);
799 free(buffer);
800 return;
801 }
802
803 if (strcmp(cmd_parameter, "userdata") == 0 || strcmp(cmd_parameter, "data") == 0) {
804 fastboot_okay(NULL, response);
805 return;
806 } else if (strcmp(cmd_parameter, "dts") == 0) {
807 strcpy(name, "dtb");
Zhigang Yua69e3f92024-06-18 03:13:38 +0000808 } else if (!strcmp(cmd_parameter, "bootloader-boot0") ||
809 !strcmp(cmd_parameter, "bootloader-boot1")) {
810 ret = update_boot_hdr_4_s7d_reva(fastboot_buf_addr, image_size, 0);
811 if (ret) {
812 printf("Failed to write s7d reva boot0\n");
813 fastboot_fail("Failed to write s7d reva boot0-1", response);
814 return;
815 }
hao.qi278cfd32024-06-28 16:09:50 +0800816 strlcpy(name, cmd_parameter, 31);
Xindong Xud9441422024-01-18 10:20:45 +0800817 } else {
hao.qi278cfd32024-06-28 16:09:50 +0800818 strlcpy(name, cmd_parameter, 31);
Xindong Xud9441422024-01-18 10:20:45 +0800819 }
820 strcat(name, "\0");
821
822#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
823 if (dynamic_partition) {
824 if (is_partition_logical(name) == 0) {
825 printf("logic partition, can not write here.......\n");
826 fastboot_fail("logic partition", response);
827 return;
828 }
829 }
830#endif
831
832#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
833 fastboot_mmc_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000834 response);
835#endif
836#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800837 fastboot_nand_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000838 response);
839#endif
Xindong Xud9441422024-01-18 10:20:45 +0800840
841 if (strcmp(name, "bootloader") == 0) {
842 env_set("default_env", "1");
843#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
844 run_command("update_env_part -p default_env;", 0);
845#else
846 run_command("defenv_reserve;saveenv;", 0);
847#endif// #if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
848 }
849
850 if (strcmp(name, "bootloader-boot0") == 0 ||
851 strcmp(name, "bootloader-boot1") == 0) {
852 printf("try to switch back to user\n");
853 run_command("mmc dev 1 0;", 0);
854 }
855
856#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
857 if (mmc && aml_gpt_valid(mmc) == 0) {
858 if (vendor_boot_partition) {
859 if (strcmp_l1("vendor_boot", name) == 0) {
860 printf("gpt mode, write dts to reserve\n");
861 write_dts_reserve();
862 }
863 } else {
864 if (strcmp_l1("boot", name) == 0) {
865 printf("gpt mode, write dts to reserve\n");
866 write_dts_reserve();
867 }
868 }
869 }
870#endif
871
872#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000873}
874
875/**
876 * erase() - erase the indicated partition.
877 *
878 * @cmd_parameter: Pointer to partition name
879 * @response: Pointer to fastboot response buffer
880 *
881 * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
882 * to response.
883 */
884static void erase(char *cmd_parameter, char *response)
885{
Xindong Xud9441422024-01-18 10:20:45 +0800886#ifdef CONFIG_AMLOGIC_MODIFY
887 char name[32] = {0};
888 u64 rc = 0;
889
890 if (check_lock() == 1) {
891 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
892 fastboot_fail("locked device", response);
893 return;
894 }
895
896 printf("cmd_parameter: %s\n", cmd_parameter);
897
898#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
899 struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
900 if ((mmc != NULL) && strcmp(cmd_parameter, "bootloader") == 0 && (aml_gpt_valid(mmc) == 0)) {
901 printf("we write gpt partition table to bootloader now\n");
902 printf("plese write bootloader to bootloader-boot0/bootloader-boot1\n");
903 fastboot_okay("gpt mode, skip", response);
904 return;
905 }
906#endif
907
908 if (strcmp(cmd_parameter, "avb_custom_key") == 0) {
909 char* buffer = NULL;
910 char *partition = "misc";
911
912 rc = store_part_size(partition);
913 buffer = (char *)malloc(AVB_CUSTOM_KEY_LEN_MAX);
914 if (!buffer) {
915 printf("malloc error\n");
916 fastboot_fail("malloc error", response);
917 return;
918 }
919 memset(buffer, 0, AVB_CUSTOM_KEY_LEN_MAX);
920
921 store_write((const char *)partition, rc - AVB_CUSTOM_KEY_LEN_MAX,
922 AVB_CUSTOM_KEY_LEN_MAX, (unsigned char *)buffer);
923
924 fastboot_okay(NULL, response);
925 free(buffer);
926 return;
927 }
928
929 if (strcmp(cmd_parameter, "env") == 0) {
930 char *fastboot_step = env_get("fastboot_step");
931
932 if (fastboot_step && strcmp(fastboot_step, "0")) {
933 printf("fastboot_step: %s, run defenv_reserv\n", fastboot_step);
934 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
935 run_command("run bcb_cmd", 0);
936 fastboot_okay(NULL, response);
937 return;
938 }
939 }
940
941 if (strcmp(cmd_parameter, "misc") == 0) {
942 char* buffer = NULL;
943 char *partition = "misc";
944
945 rc = store_part_size(partition);
946 buffer = (char *)malloc(rc - AVB_CUSTOM_KEY_LEN_MAX);
947 if (!buffer) {
948 printf("malloc error\n");
949 fastboot_fail("malloc error", response);
950 return;
951 }
952 memset(buffer, 0, rc - AVB_CUSTOM_KEY_LEN_MAX);
953
954 store_write((const char *)partition, 0, rc - AVB_CUSTOM_KEY_LEN_MAX,
955 (unsigned char *)buffer);
956
957 fastboot_okay(NULL, response);
958 free(buffer);
959 return;
960 }
961
962 if (strcmp(cmd_parameter, "userdata") == 0 || strcmp(cmd_parameter, "data") == 0) {
963 rc = store_part_size("userdata");
964 if (-1 == rc)
965 strcpy(name, "data");
966 else
967 strcpy(name, "userdata");
968 } else if (strcmp(cmd_parameter, "dts") == 0) {
969 strcpy(name, "dtb");
970 } else {
971 strncpy(name, cmd_parameter, 31);
972 }
973 strcat(name, "\0");
974
975#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
976 if (dynamic_partition) {
977 if (is_partition_logical(name) == 0) {
978 printf("logic partition, can not erase here.......\n");
979 fastboot_fail("logic partition", response);
980 return;
981 }
982 }
983#endif
984
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000985#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
Xindong Xud9441422024-01-18 10:20:45 +0800986 fastboot_mmc_erase(name, response);
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000987#endif
988#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800989 fastboot_nand_erase(name, response);
990#endif
991
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000992#endif
993}
994#endif
Xindong Xud9441422024-01-18 10:20:45 +0800995#endif
996
997#ifdef CONFIG_FASTBOOT_WRITING_CMD
998
999#ifdef CONFIG_AMLOGIC_MODIFY
1000static u64 my_ato11(const char *str)
1001{
1002 u64 result = 0;
1003 int len, i;
1004
1005 len = strlen(str);
1006 for (i = 0; i < len; i++) {
1007 if (*str >= '0' && *str <= '9')
1008 result = result * 16 + (*str - '0');
1009 else if (*str >= 'A' && *str <= 'F')
1010 result = result * 16 + (*str - 'A') + 10;
1011 else if (*str >= 'a' && *str <= 'f')
1012 result = result * 16 + (*str - 'a') + 10;
1013 str++;
1014 }
1015
1016 return result;
1017}
1018
1019static void fetch(char *cmd_parameter, char *response)
1020{
1021 int len;
1022 int i = 0;
1023 char *cmd;
1024 char name[32] = {0};
1025 u64 offset = 0;
1026 u64 read_size = 0;
1027 size_t size = 0;
1028
1029 if (check_lock() == 1) {
1030 printf("device is locked, can not run this cmd\n");
1031 fastboot_fail("locked device", response);
1032 return;
1033 }
1034
1035 cmd = cmd_parameter;
1036 len = strlen(cmd_parameter);
1037 while (strsep(&cmd, ":"))
1038 i++;
1039
1040 for (cmd = cmd_parameter, i = 0; cmd < (cmd_parameter + len); i++) {
1041 /* Skip to next assignment */
1042 if (i == 0) {
1043 strncpy(name, cmd, 31);
1044 strcat(name, "\0");
1045 } else if (i == 1) {
1046 offset = my_ato11(cmd);
1047 } else if (i == 2) {
1048 read_size = my_ato11(cmd);
1049 }
1050
1051 for (cmd += strlen(cmd); cmd < (cmd_parameter + len) && !*cmd;)
1052 cmd++;
1053 }
1054
1055 printf("name: %s\n", name);
1056 if (strncmp("vendor_boot", name, strlen("vendor_boot")) != 0) {
1057 printf("We can only %s vendor_boot\n", __func__);
1058 fastboot_fail("Fetch is only allowed on vendor_boot", response);
1059 return;
1060 }
1061
1062#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
1063 struct blk_desc *dev_desc;
1064 disk_partition_t part_info;
1065 int r;
1066
1067 r = fastboot_mmc_get_part_info(name, &dev_desc, &part_info,
1068 response);
1069 if (r >= 0)
1070 size = part_info.size * 512;
1071#endif
1072#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
1073 struct part_info *part_info;
1074 int r;
1075
1076 r = fastboot_nand_get_part_info(name, &part_info, response);
1077 if (r >= 0)
1078 size = part_info->size * 512;
1079#endif
1080
1081 if (offset > size) {
1082 printf("Invalid offset: 0x%llx, partition size is 0x%lx\n",
1083 offset, size);
1084 fastboot_fail("Invalid offset", response);
1085 return;
1086 }
1087
1088 if (read_size == 0 || read_size > size - offset ||
1089 read_size > kMaxFetchSizeDefault) {
1090 printf("Invalid read size: 0x%llx, partition size is 0x%lx\n",
1091 offset, size);
1092 fastboot_fail("Invalid read size", response);
1093 return;
1094 }
1095
1096 printf("Start read %s partition datas!\n", name);
1097 void *buffer;
1098 char str[128] = {0};
1099
1100 buffer = (void *)CONFIG_FASTBOOT_BUF_ADDR;
1101 sprintf(str, "DATA%12llx", read_size);
1102 printf("str: %s, len: %ld\n", str, strlen(str));
1103 memcpy(buffer, str, strlen(str));
1104
1105 if (store_read((const char *)name, offset, read_size,
1106 (unsigned char *)buffer + strlen(str)) < 0) {
1107 printf("failed to store read %s.\n", name);
1108 fastboot_fail("read partition data error", response);
1109 return;
1110 }
1111
1112 fastboot_readInfo.transferredBytes = 0;
1113 fastboot_readInfo.totalBytes = read_size + strlen(str);
1114 fastboot_response("DATA", response, "%12llx", read_size);
1115}
1116
Xindong Xub3cf2a82024-12-25 10:23:47 +08001117static void oem_cmd(char *cmd_parameter, char *response)
1118{
1119 char *cmd;
1120 int i = 0, len = 0, j = 0;
1121 char cmd_str[FASTBOOT_RESPONSE_LEN];
1122
1123 printf("oem cmd_parameter: %s\n", cmd_parameter);
1124
1125 if (IS_FEAT_BOOT_VERIFY()) {
1126 printf("device is secure mode, can not run this cmd.\n");
1127 fastboot_fail("secure boot device", response);
1128 return;
1129 }
1130
1131 if (check_lock() == 1) {
1132 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1133 fastboot_fail("locked device", response);
1134 return;
1135 }
1136
1137 cmd = cmd_parameter;
1138 strsep(&cmd, " ");
1139 printf("To run cmd[%s]\n", cmd);
1140
1141 len = strlen(cmd);
1142 for (i = 0; i < len; i++) {
1143 if (cmd[i] != '\'')
1144 cmd_str[j++] = cmd[i];
1145 }
1146 cmd_str[j] = '\0';
1147 printf("cmd_str2: %s\n", cmd_str);
1148
1149 run_command(cmd_str, 0);
1150
1151 fastboot_okay(NULL, response);
1152}
1153
Xindong Xud9441422024-01-18 10:20:45 +08001154static void set_active_cmd(char *cmd_parameter, char *response)
1155{
1156 char *cmd;
1157 int ret = 0;
1158 char str[128];
1159
1160 printf("cmd cb_set_active is %s\n", cmd_parameter);
1161 cmd = cmd_parameter;
1162
1163 if (check_lock() == 1) {
1164 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1165 fastboot_fail("locked device", response);
1166 return;
1167 }
1168
1169 sprintf(str, "set_active_slot %s", cmd);
1170 printf("command: %s\n", str);
1171 ret = run_command(str, 0);
1172 printf("ret = %d\n", ret);
1173 if (ret == 0)
1174 fastboot_okay(NULL, response);
1175 else
1176 fastboot_fail("set slot error", response);
1177}
1178
1179#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
Xindong Xub3cf2a82024-12-25 10:23:47 +08001180#ifdef CONFIG_AVB2
Xindong Xud9441422024-01-18 10:20:45 +08001181static void try_unlock_dev(u64 rc)
1182{
1183#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1184 if (is_avb_arb_available()) {
1185 if (avb_unlock()) {
1186 if (-1 == rc) {
1187 printf("unlocking device. Erasing data partition!\n");
1188 run_command("store erase data 0 0", 0);
1189 } else {
1190 printf("unlocking device. Erasing userdata partition!\n");
1191 run_command("store erase userdata 0 0", 0);
1192 }
1193 printf("unlocking device. Erasing metadata partition!\n");
1194 run_command("store erase metadata 0 0", 0);
1195 } else {
1196 printf("unlock failed!\n");
1197 }
1198
1199 return;
1200 }
1201#endif
1202 if (-1 == rc) {
1203 printf("unlocking device. Erasing data partition!\n");
1204 run_command("store erase data 0 0", 0);
1205 } else {
1206 printf("unlocking device. Erasing userdata partition!\n");
1207 run_command("store erase userdata 0 0", 0);
1208 }
1209 printf("unlocking device. Erasing metadata partition!\n");
1210 run_command("store erase metadata 0 0", 0);
1211}
1212
1213static void try_lock_dev(u64 rc)
1214{
1215#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1216 if (is_avb_arb_available()) {
1217 if (avb_lock()) {
1218 if (-1 == rc) {
1219 printf("locking device. Erasing data partition!\n");
1220 run_command("store erase data 0 0", 0);
1221 } else {
1222 printf("locking device. Erasing userdata partition!\n");
1223 run_command("store erase userdata 0 0", 0);
1224 }
1225 printf("locking device. Erasing metadata partition!\n");
1226 run_command("store erase metadata 0 0", 0);
1227 } else {
1228 printf("lock failed!\n");
1229 }
1230
1231 return;
1232 }
1233#endif
1234 if (-1 == rc) {
1235 printf("locking device. Erasing data partition!\n");
1236 run_command("store erase data 0 0", 0);
1237 } else {
1238 printf("locking device. Erasing userdata partition!\n");
1239 run_command("store erase userdata 0 0", 0);
1240 }
1241 printf("locking device. Erasing metadata partition!\n");
1242 run_command("store erase metadata 0 0", 0);
1243}
Xindong Xub3cf2a82024-12-25 10:23:47 +08001244#endif
Xindong Xud9441422024-01-18 10:20:45 +08001245
1246/**
1247 * flashing() - lock/unlock.
1248 *
1249 * @cmd_parameter: Pointer to partition name
1250 * @response: Pointer to fastboot response buffer
1251 *
1252 * Writes the previously downloaded image to the partition indicated by
1253 * cmd_parameter. Writes to response.
1254 */
1255static void flashing(char *cmd_parameter, char *response)
1256{
1257 char *cmd;
1258 char* lock_s;
1259 LockData_t info = {0};
1260 char lock_d[LOCK_DATA_SIZE];
1261 u64 rc;
1262 int debug_flag = 0;
1263
Xindong Xu2e748322024-11-22 09:24:46 +08001264#ifndef CONFIG_REFERENCE
Xindong Xud9441422024-01-18 10:20:45 +08001265 if (IS_FEAT_BOOT_VERIFY()) {
1266 printf("device is secure mode, can not run this cmd.\n");
1267 fastboot_fail("secure boot device", response);
1268 return;
1269 }
Xindong Xu2e748322024-11-22 09:24:46 +08001270#endif
Xindong Xud9441422024-01-18 10:20:45 +08001271
1272 lock_s = env_get("lock");
1273 if (!lock_s) {
1274 printf("lock state is NULL \n");
1275 memcpy(lock_d, "10101000", 8);
1276 lock_s = "10101000";
1277 env_set("lock", "10101000");
1278#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1279 run_command("update_env_part -p lock;", 0);
1280#else
1281 run_command("defenv_reserv; saveenv;", 0);
1282#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1283 } else {
1284 printf("lock state: %s\n", lock_s);
1285 if (strlen(lock_s) > 15)
1286 strncpy(lock_d, lock_s, 15);
1287 else
1288 strncpy(lock_d, lock_s, strlen(lock_s));
1289 }
1290
1291 info.version_major = (int)(lock_d[0] - '0');
1292 info.version_minor = (int)(lock_d[1] - '0');
1293 info.unlock_ability = (int)(lock_d[2] - '0');
1294 info.lock_state = (int)(lock_d[4] - '0');
1295 info.lock_critical_state = (int)(lock_d[5] - '0');
1296 info.lock_bootloader = (int)(lock_d[6] - '0');
1297 dump_lock_info(info);
1298
1299 printf("cb_flashing cmd_parameter: %s\n", cmd_parameter);
1300 cmd = cmd_parameter;
1301 strsep(&cmd, " ");
1302 printf("cb_flashing: %s\n", cmd);
1303 if (!cmd) {
1304 printf("missing variable\n");
1305 fastboot_fail("missing var", response);
1306 return;
1307 }
1308
1309 boot_img_hdr_t *hdr_addr = NULL;
1310 const int preloadsz = 0x1000 * 2;//4k not enough for signed
1311 unsigned char *pbuffpreload = 0;
1312 char partname[32] = {0};
1313 char *slot_name;
1314 char cmdline[4096];
1315 char *result = NULL;
1316
1317 slot_name = env_get("slot-suffixes");
1318 if (slot_name && (strcmp(slot_name, "0") == 0))
1319 strcpy((char *)partname, "boot_a");
1320 else if (slot_name && (strcmp(slot_name, "1") == 0))
1321 strcpy((char *)partname, "boot_b");
1322 else
1323 strcpy((char *)partname, "boot");
1324
1325 pbuffpreload = malloc(preloadsz);
1326 if (!pbuffpreload) {
1327 printf("Fail to allocate memory!\n");
1328 goto next;
1329 }
1330
1331 hdr_addr = (boot_img_hdr_t *)pbuffpreload;
1332
1333 printf("read from part: %s\n", partname);
1334 rc = store_logic_read(partname, 0, preloadsz, pbuffpreload);
1335 if (rc) {
1336 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1337 preloadsz, partname);
1338 free(pbuffpreload);
1339 pbuffpreload = 0;
1340 goto next;
1341 }
1342
1343 if (is_android_r_image((void *)hdr_addr)) {
1344 char partname_r[32] = {0};
1345 const int preloadsz_r = 0x1000 * 2;//4k not enough for signed
1346 unsigned char *pbuffpreload_r = 0;
1347 int ret_r = __LINE__;
1348
1349 if (slot_name && (strcmp(slot_name, "0") == 0))
1350 strcpy((char *)partname_r, "vendor_boot_a");
1351 else if (slot_name && (strcmp(slot_name, "1") == 0))
1352 strcpy((char *)partname_r, "vendor_boot_b");
1353 else
1354 strcpy((char *)partname_r, "vendor_boot");
1355
1356 pbuffpreload_r = malloc(preloadsz_r);
1357
1358 if (!pbuffpreload_r) {
1359 printf("Fail to allocate memory for %s!\n",
1360 partname_r);
1361 goto next;
1362 }
1363
1364 printf("read from part: %s\n", partname_r);
1365 ret_r = store_logic_read(partname_r, 0,
1366 preloadsz_r, pbuffpreload_r);
1367 if (ret_r) {
1368 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1369 preloadsz_r, partname_r);
1370 free(pbuffpreload_r);
1371 pbuffpreload_r = 0;
1372 goto next;
1373 }
1374
1375 p_vendor_boot_img_hdr_t vb_hdr = (p_vendor_boot_img_hdr_t)pbuffpreload_r;
1376
1377 if (*vb_hdr->cmdline) {
1378 printf("Kernel command line: %s\n", vb_hdr->cmdline);
1379 sprintf(cmdline, "%s", vb_hdr->cmdline);
1380 }
1381 free(pbuffpreload_r);
1382 pbuffpreload_r = 0;
1383 } else {
1384 if (*hdr_addr->cmdline) {
1385 printf("Kernel command line: %s\n", hdr_addr->cmdline);
1386 sprintf(cmdline, "%s", hdr_addr->cmdline);
1387 }
1388 }
1389
1390 free(pbuffpreload);
1391 pbuffpreload = 0;
1392
1393 result = strtok(cmdline, " ");
1394 while (result) {
1395 printf("result: %s\n", result);
1396 if (strcmp(result, "buildvariant=userdebug") == 0 ||
1397 strcmp(result, "buildvariant=eng") == 0)
1398 debug_flag = 1;
1399 result = strtok(NULL, " ");
1400 }
1401
1402 if (info.unlock_ability == 0 && debug_flag == 1) {
1403 printf("userdebug mode can ignore\n");
1404 info.unlock_ability = 1;
1405 }
1406
1407next:
1408 rc = store_part_size("userdata");
1409
1410 if (!strcmp_l1("unlock_critical", cmd)) {
1411 info.lock_critical_state = 0;
1412 fastboot_okay(NULL, response);
1413 } else if (!strcmp_l1("lock_critical", cmd)) {
1414 info.lock_critical_state = 1;
1415 fastboot_okay(NULL, response);
1416 } else if (!strcmp_l1("get_unlock_ability", cmd)) {
1417 char str[32];
1418 static bool is_unlock_ability_sent = false;
1419 if (is_unlock_ability_sent) {
1420 is_unlock_ability_sent = false;
1421 fastboot_okay(NULL, response);
1422 busy_flag = 0;
1423 } else {
1424 sprintf(str, "get_unlock_ability: %d",
1425 info.unlock_ability);
1426 fastboot_response("INFO", response, "%s", str);
1427 is_unlock_ability_sent = true;
1428 busy_flag = 1;
1429 }
1430 return;
1431 } else if (!strcmp_l1("get_unlock_bootloader_nonce", cmd)) {
1432 char str_num[8];
1433 sprintf(str_num, "%d", info.lock_critical_state);
1434 fastboot_response("OKAY", response, "%s", str_num);
1435 } else if (!strcmp_l1("lock_bootloader", cmd)) {
1436 info.lock_bootloader = 1;
1437 } else if (!strcmp_l1("unlock", cmd)) {
hao.qi40c37a02024-07-15 13:40:47 +08001438#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
hao.qi0696a542024-09-12 14:58:03 +08001439 u32 rpmb_lock_state = 0;
1440 bool ret = get_avb_lock_state(&rpmb_lock_state);
hao.qi40c37a02024-07-15 13:40:47 +08001441
hao.qi0696a542024-09-12 14:58:03 +08001442 if (info.lock_state == 1 || (ret && rpmb_lock_state == 1)) {
hao.qi40c37a02024-07-15 13:40:47 +08001443#else
hao.qi0696a542024-09-12 14:58:03 +08001444 if (info.lock_state == 1) {
hao.qi40c37a02024-07-15 13:40:47 +08001445#endif
Xindong Xuac88caf2024-10-28 17:10:12 +08001446#ifdef CONFIG_AVB2
1447 try_unlock_dev(rc);
1448#endif
Xindong Xud9441422024-01-18 10:20:45 +08001449 }
hao.qi0696a542024-09-12 14:58:03 +08001450 info.lock_state = 0;
1451 info.lock_critical_state = 0;
1452 env_set("lock_state", "green");
1453 fastboot_okay(NULL, response);
Xindong Xud9441422024-01-18 10:20:45 +08001454 } else if (!strcmp_l1("lock", cmd)) {
hao.qi40c37a02024-07-15 13:40:47 +08001455#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1456 u32 rpmb_lock_state = 0;
1457 bool ret = get_avb_lock_state(&rpmb_lock_state);
1458
1459 if (info.lock_state == 0 || (ret && rpmb_lock_state == 0)) {
1460#else
Xindong Xud9441422024-01-18 10:20:45 +08001461 if (info.lock_state == 0) {
hao.qi40c37a02024-07-15 13:40:47 +08001462#endif
Xindong Xuac88caf2024-10-28 17:10:12 +08001463#ifdef CONFIG_AVB2
1464 try_lock_dev(rc);
1465#endif
Xindong Xud9441422024-01-18 10:20:45 +08001466 }
1467 info.lock_state = 1;
1468 env_set("lock_state", "orange");
1469 fastboot_okay(NULL, response);
1470 } else {
1471 printf("unknown variable: %s\n", cmd);
1472 fastboot_response("FAIL", response, "%s", "Variable not implemented");
1473 }
1474
1475 sprintf(lock_d, "%d%d%d0%d%d%d0", info.version_major, info.version_minor,
1476 info.unlock_ability, info.lock_state, info.lock_critical_state,
1477 info.lock_bootloader);
1478 printf("lock_d state: %s\n", lock_d);
1479 env_set("lock", lock_d);
1480#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1481 run_command("update_env_part -p lock;", 0);
1482#else
1483 run_command("defenv_reserv; saveenv;", 0);
1484#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1485 return;
1486}
1487#endif// #if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
1488#endif
1489#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001490
Heiko Schocherbc820d52021-02-10 09:29:03 +01001491#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
1492/**
1493 * run_ucmd() - Execute the UCmd command
1494 *
1495 * @cmd_parameter: Pointer to command parameter
1496 * @response: Pointer to fastboot response buffer
1497 */
1498static void run_ucmd(char *cmd_parameter, char *response)
1499{
1500 if (!cmd_parameter) {
1501 pr_err("missing slot suffix\n");
1502 fastboot_fail("missing command", response);
1503 return;
1504 }
1505
1506 if (run_command(cmd_parameter, 0))
1507 fastboot_fail("", response);
1508 else
1509 fastboot_okay(NULL, response);
1510}
1511
1512static char g_a_cmd_buff[64];
1513
1514void fastboot_acmd_complete(void)
1515{
1516 run_command(g_a_cmd_buff, 0);
1517}
1518
1519/**
1520 * run_acmd() - Execute the ACmd command
1521 *
1522 * @cmd_parameter: Pointer to command parameter
1523 * @response: Pointer to fastboot response buffer
1524 */
1525static void run_acmd(char *cmd_parameter, char *response)
1526{
1527 if (!cmd_parameter) {
1528 pr_err("missing slot suffix\n");
1529 fastboot_fail("missing command", response);
1530 return;
1531 }
1532
1533 if (strlen(cmd_parameter) > sizeof(g_a_cmd_buff)) {
1534 pr_err("too long command\n");
1535 fastboot_fail("too long command", response);
1536 return;
1537 }
1538
1539 strcpy(g_a_cmd_buff, cmd_parameter);
1540 fastboot_okay(NULL, response);
1541}
1542#endif
1543
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001544/**
1545 * reboot_bootloader() - Sets reboot bootloader flag.
1546 *
1547 * @cmd_parameter: Pointer to command parameter
1548 * @response: Pointer to fastboot response buffer
1549 */
1550static void reboot_bootloader(char *cmd_parameter, char *response)
1551{
Xindong Xud9441422024-01-18 10:20:45 +08001552#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi851737a2020-07-28 23:35:32 +03001553 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_BOOTLOADER))
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001554 fastboot_fail("Cannot set reboot flag", response);
1555 else
Xindong Xud9441422024-01-18 10:20:45 +08001556#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001557 fastboot_okay(NULL, response);
1558}
Alex Kiernan3845b902018-05-29 15:30:54 +00001559
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001560/**
1561 * reboot_fastbootd() - Sets reboot fastboot flag.
1562 *
1563 * @cmd_parameter: Pointer to command parameter
1564 * @response: Pointer to fastboot response buffer
1565 */
1566static void reboot_fastbootd(char *cmd_parameter, char *response)
1567{
Xindong Xud9441422024-01-18 10:20:45 +08001568#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001569 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_FASTBOOTD))
Xindong Xud9441422024-01-18 10:20:45 +08001570 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001571 else
Xindong Xud9441422024-01-18 10:20:45 +08001572#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001573 fastboot_okay(NULL, response);
1574}
1575
1576/**
1577 * reboot_recovery() - Sets reboot recovery flag.
1578 *
1579 * @cmd_parameter: Pointer to command parameter
1580 * @response: Pointer to fastboot response buffer
1581 */
1582static void reboot_recovery(char *cmd_parameter, char *response)
1583{
Xindong Xud9441422024-01-18 10:20:45 +08001584#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001585 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_RECOVERY))
Xindong Xud9441422024-01-18 10:20:45 +08001586 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001587 else
Xindong Xud9441422024-01-18 10:20:45 +08001588#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001589 fastboot_okay(NULL, response);
1590}
1591
Xindong Xud9441422024-01-18 10:20:45 +08001592#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernan3845b902018-05-29 15:30:54 +00001593#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
1594/**
1595 * oem_format() - Execute the OEM format command
1596 *
1597 * @cmd_parameter: Pointer to command parameter
1598 * @response: Pointer to fastboot response buffer
1599 */
1600static void oem_format(char *cmd_parameter, char *response)
1601{
1602 char cmdbuf[32];
1603
Xindong Xud9441422024-01-18 10:20:45 +08001604#ifdef CONFIG_AMLOGIC_MODIFY
Xindong Xu2e748322024-11-22 09:24:46 +08001605#ifndef CONFIG_REFERENCE
Xindong Xud9441422024-01-18 10:20:45 +08001606 if (IS_FEAT_BOOT_VERIFY()) {
1607 printf("device is secure mode, can not run this cmd.\n");
1608 fastboot_fail("secure boot device", response);
1609 return;
1610 }
Xindong Xu2e748322024-11-22 09:24:46 +08001611#endif
Xindong Xud9441422024-01-18 10:20:45 +08001612
1613 if (check_lock() == 1) {
1614 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1615 fastboot_fail("locked device", response);
1616 return;
1617 }
1618#endif
1619
Alex Kiernan3845b902018-05-29 15:30:54 +00001620 if (!env_get("partitions")) {
1621 fastboot_fail("partitions not set", response);
1622 } else {
1623 sprintf(cmdbuf, "gpt write mmc %x $partitions",
1624 CONFIG_FASTBOOT_FLASH_MMC_DEV);
1625 if (run_command(cmdbuf, 0))
1626 fastboot_fail("", response);
1627 else
1628 fastboot_okay(NULL, response);
1629 }
1630}
1631#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +01001632
1633#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
1634/**
1635 * oem_partconf() - Execute the OEM partconf command
1636 *
1637 * @cmd_parameter: Pointer to command parameter
1638 * @response: Pointer to fastboot response buffer
1639 */
1640static void oem_partconf(char *cmd_parameter, char *response)
1641{
1642 char cmdbuf[32];
1643
1644 if (!cmd_parameter) {
1645 fastboot_fail("Expected command parameter", response);
1646 return;
1647 }
1648
1649 /* execute 'mmc partconfg' command with cmd_parameter arguments*/
1650 snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0",
1651 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1652 printf("Execute: %s\n", cmdbuf);
1653 if (run_command(cmdbuf, 0))
1654 fastboot_fail("Cannot set oem partconf", response);
1655 else
1656 fastboot_okay(NULL, response);
1657}
1658#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +01001659
1660#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
1661/**
1662 * oem_bootbus() - Execute the OEM bootbus command
1663 *
1664 * @cmd_parameter: Pointer to command parameter
1665 * @response: Pointer to fastboot response buffer
1666 */
1667static void oem_bootbus(char *cmd_parameter, char *response)
1668{
1669 char cmdbuf[32];
1670
1671 if (!cmd_parameter) {
1672 fastboot_fail("Expected command parameter", response);
1673 return;
1674 }
1675
1676 /* execute 'mmc bootbus' command with cmd_parameter arguments*/
1677 snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s",
1678 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1679 printf("Execute: %s\n", cmdbuf);
1680 if (run_command(cmdbuf, 0))
1681 fastboot_fail("Cannot set oem bootbus", response);
1682 else
1683 fastboot_okay(NULL, response);
1684}
1685#endif
Xindong Xud9441422024-01-18 10:20:45 +08001686#endif