blob: 5650311a4dc44d4bb2b5b3d81b95b0a61dbdb7a7 [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
yihui wu7935bce2024-12-17 01:17:08 +0800613#ifdef CONFIG_MESON_S7D
Zhigang Yua69e3f92024-06-18 03:13:38 +0000614 ret = update_boot_hdr_4_s7d_reva(fastboot_buf_addr, image_size, 0);
615 if (ret) {
616 printf("Failed to write s7d reva boot0\n");
617 fastboot_fail("Failed to write s7d reva boot0", response);
618 return;
619 }
yihui wu7935bce2024-12-17 01:17:08 +0800620#endif//#ifdef CONFIG_MESON_S7D
Zhigang Yua69e3f92024-06-18 03:13:38 +0000621
Xindong Xu22e8daf2024-03-12 18:08:41 +0800622 slot_name = env_get("active_slot");
623 if (slot_name && (strcmp(slot_name, "_a") == 0))
624 strcpy((char *)partname, "bootloader_a");
625 else if (slot_name && (strcmp(slot_name, "_b") == 0))
626 strcpy((char *)partname, "bootloader_b");
627 else
628 strcpy((char *)partname, "bootloader_up");
629
630 rc = store_part_size(partname);
Xindong Xud9441422024-01-18 10:20:45 +0800631 if (rc != -1) {
Xindong Xu22e8daf2024-03-12 18:08:41 +0800632 fastboot_mmc_erase(partname, response);
633 fastboot_mmc_flash_write(partname, fastboot_buf_addr, image_size,
Xindong Xud9441422024-01-18 10:20:45 +0800634 response);
635 }
636
637 /* the max size of bootloader.img is 4M, we reserve 128k for gpt.bin
638 * so we put gpt.bin at offset 0x3DFE00
639 * 0 ~ 512 bootloader secure boot, we don't care it here.
640 * 512 ~ 0x3DFDFF original bootloader.img and 0
641 * 0x3DFE00 ~ end gpt.bin
642 */
643
644 dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
645 if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
646 printf("invalid mmc device\n");
647 fastboot_fail("invalid mmc device", response);
648 return;
649 }
650
651 if (is_valid_gpt_buf(dev_desc, fastboot_buf_addr + 0x3DFE00)) {
652 printf("printf normal bootloader.img, no gpt partition table\n");
653 } else {
654 printf("find gpt partition table, update it\n"
655 "and write bootloader to boot0/boot1\n");
656
657 erase_flag = check_gpt_part(dev_desc, fastboot_buf_addr + 0x3DFE00);
658
659 if (erase_flag == 1) {
660 printf("partition changes, erase emmc\n");
661 //run_command("store erase.chip 0;", 0);
662 if (usb_burn_erase_data(0x3)) {
663 printf("partition erase failed!\n");
664 return;
665 }
666 }
667
668 if (write_mbr_and_gpt_partitions(dev_desc, fastboot_buf_addr + 0x3DFE00)) {
669 printf("%s: writing GPT partitions failed\n", __func__);
670 fastboot_fail("writing GPT partitions failed", response);
671 return;
672 }
673
674 if (mmc_device_init(mmc) != 0) {
675 printf(" update gpt partition table fail\n");
676 fastboot_fail("fastboot update gpt partition fail", response);
677 return;
678 }
679 printf("%s: writing GPT partitions ok\n", __func__);
680
681 char *mem_addr;
682 void *addr = NULL;
683 int ret;
684
685 mem_addr = env_get("dtb_mem_addr");
686
687 if (mem_addr && erase_flag == 1) {
688 printf("partition changes, erase emmc\n");
689 //run_command("store erase.chip 0;", 0);
690 if (usb_burn_erase_data(0x3)) {
691 printf("partition erase failed!\n");
692 return;
693 }
694 printf("write _aml_dtb\n");
695 addr = (void *)simple_strtoul(mem_addr, NULL, 16);
696 ret = dtb_write(addr);
697 if (ret)
698 printf("write _aml_dtb error\n");
699 else
700 printf("write _aml_dtb ok\n");
701 }
702 }
703
Xindong Xu0afe60a2024-05-21 16:15:13 +0800704 ret = clear_misc_partition();
705 if (ret) {
706 printf("clear misc partition error\n");
707 fastboot_fail("clear misc partition fail", response);
708 return;
709 }
710
Xindong Xud9441422024-01-18 10:20:45 +0800711 gpt_flag = aml_gpt_valid(mmc);
712 if (gpt_flag == 0)
713 ret = 0;
714
715#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
716 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
717
718 if (*efuse_field.data == 1) {
719 wrnP("efuse_field.data == 1\n");
720 ret = 0;
721 env_set("nocs_mode", "true");
722 } else {
723 wrnP("efuse_field.data != 1\n");
724 env_set("nocs_mode", "false");
725 }
726#endif//#ifdef CONFIG_EFUSE_OBJ_API
727
Xindong Xu22e8daf2024-03-12 18:08:41 +0800728 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
729
730 if (ret == 0) {
731 printf("gpt/nocs mode\n");
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000732#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
Xindong Xu22e8daf2024-03-12 18:08:41 +0800733 fastboot_mmc_flash_write("bootloader-boot1", fastboot_buf_addr, image_size,
734 response);
735 if (strcmp(bootloaderindex, "1") != 0) {
736 printf("boot from boot1, means boot0 is error, rewrite it\n");
737 fastboot_mmc_flash_write("bootloader-boot0",
738 fastboot_buf_addr, image_size, response);
739 run_command("mmc dev 1 0;", 0);
740 set_fastboot_flag(0);
741 } else {
742 printf("need to set fastboot_step\n");
743 run_command("mmc dev 1 0;", 0);
744 set_fastboot_flag(1);
745 }
Xindong Xud9441422024-01-18 10:20:45 +0800746#endif
Xindong Xu22e8daf2024-03-12 18:08:41 +0800747 return;
748 } else {
749 printf("normal mode\n");
750#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
751 fastboot_mmc_flash_write("bootloader-boot0", fastboot_buf_addr, image_size,
752 response);
753 fastboot_mmc_flash_write("bootloader-boot1", fastboot_buf_addr, image_size,
754 response);
755 if (strcmp(bootloaderindex, "0") != 0) {
756 printf("boot from boot0, rewrite user bootloader is error\n");
757 fastboot_mmc_flash_write("bootloader",
758 fastboot_buf_addr, image_size, response);
759 run_command("mmc dev 1 0;", 0);
760 set_fastboot_flag(0);
761 } else {
762 run_command("mmc dev 1 0;", 0);
763 set_fastboot_flag(1);
764 }
765#endif
766 return;
767 }
Xindong Xud9441422024-01-18 10:20:45 +0800768 }
769#endif
770
771 if (strcmp(cmd_parameter, "avb_custom_key") == 0) {
772 char* buffer = NULL;
773 char *partition = "misc";
774 AvbKey_t key;
775 printf("avb_custom_key image_size: %d\n", image_size);
776
777 if (image_size > AVB_CUSTOM_KEY_LEN_MAX - sizeof(AvbKey_t)) {
778 printf("key size is too large\n");
779 fastboot_fail("size error", response);
780 return;
781 }
782
783 memcpy(key.magic_name, "AVBK", 4);
784 key.size = image_size;
785 rc = store_part_size(partition);
786
787 buffer = (char *)malloc(AVB_CUSTOM_KEY_LEN_MAX);
788 if (!buffer) {
789 printf("malloc error\n");
790 fastboot_fail("malloc error", response);
791 return;
792 }
793 memset(buffer, 0, AVB_CUSTOM_KEY_LEN_MAX);
794 memcpy(buffer, &key, sizeof(AvbKey_t));
795 memcpy(buffer + sizeof(AvbKey_t), fastboot_buf_addr, image_size);
796
797 store_write((const char *)partition, rc - AVB_CUSTOM_KEY_LEN_MAX,
798 AVB_CUSTOM_KEY_LEN_MAX, (unsigned char *)buffer);
799
800 fastboot_okay(NULL, response);
801 free(buffer);
802 return;
803 }
804
805 if (strcmp(cmd_parameter, "userdata") == 0 || strcmp(cmd_parameter, "data") == 0) {
806 fastboot_okay(NULL, response);
807 return;
808 } else if (strcmp(cmd_parameter, "dts") == 0) {
809 strcpy(name, "dtb");
Zhigang Yua69e3f92024-06-18 03:13:38 +0000810 } else if (!strcmp(cmd_parameter, "bootloader-boot0") ||
811 !strcmp(cmd_parameter, "bootloader-boot1")) {
yihui wu7935bce2024-12-17 01:17:08 +0800812#ifdef CONFIG_MESON_S7D
Zhigang Yua69e3f92024-06-18 03:13:38 +0000813 ret = update_boot_hdr_4_s7d_reva(fastboot_buf_addr, image_size, 0);
814 if (ret) {
815 printf("Failed to write s7d reva boot0\n");
816 fastboot_fail("Failed to write s7d reva boot0-1", response);
817 return;
818 }
yihui wu7935bce2024-12-17 01:17:08 +0800819#endif//#ifdef CONFIG_MESON_S7D
hao.qi278cfd32024-06-28 16:09:50 +0800820 strlcpy(name, cmd_parameter, 31);
Xindong Xud9441422024-01-18 10:20:45 +0800821 } else {
hao.qi278cfd32024-06-28 16:09:50 +0800822 strlcpy(name, cmd_parameter, 31);
Xindong Xud9441422024-01-18 10:20:45 +0800823 }
824 strcat(name, "\0");
825
826#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
827 if (dynamic_partition) {
828 if (is_partition_logical(name) == 0) {
829 printf("logic partition, can not write here.......\n");
830 fastboot_fail("logic partition", response);
831 return;
832 }
833 }
834#endif
835
836#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
837 fastboot_mmc_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000838 response);
839#endif
840#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800841 fastboot_nand_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000842 response);
843#endif
Xindong Xud9441422024-01-18 10:20:45 +0800844
845 if (strcmp(name, "bootloader") == 0) {
846 env_set("default_env", "1");
847#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
848 run_command("update_env_part -p default_env;", 0);
849#else
850 run_command("defenv_reserve;saveenv;", 0);
851#endif// #if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
852 }
853
854 if (strcmp(name, "bootloader-boot0") == 0 ||
855 strcmp(name, "bootloader-boot1") == 0) {
856 printf("try to switch back to user\n");
857 run_command("mmc dev 1 0;", 0);
858 }
859
860#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
861 if (mmc && aml_gpt_valid(mmc) == 0) {
862 if (vendor_boot_partition) {
863 if (strcmp_l1("vendor_boot", name) == 0) {
864 printf("gpt mode, write dts to reserve\n");
865 write_dts_reserve();
866 }
867 } else {
868 if (strcmp_l1("boot", name) == 0) {
869 printf("gpt mode, write dts to reserve\n");
870 write_dts_reserve();
871 }
872 }
873 }
874#endif
875
876#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000877}
878
879/**
880 * erase() - erase the indicated partition.
881 *
882 * @cmd_parameter: Pointer to partition name
883 * @response: Pointer to fastboot response buffer
884 *
885 * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
886 * to response.
887 */
888static void erase(char *cmd_parameter, char *response)
889{
Xindong Xud9441422024-01-18 10:20:45 +0800890#ifdef CONFIG_AMLOGIC_MODIFY
891 char name[32] = {0};
892 u64 rc = 0;
893
894 if (check_lock() == 1) {
895 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
896 fastboot_fail("locked device", response);
897 return;
898 }
899
900 printf("cmd_parameter: %s\n", cmd_parameter);
901
902#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
903 struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
904 if ((mmc != NULL) && strcmp(cmd_parameter, "bootloader") == 0 && (aml_gpt_valid(mmc) == 0)) {
905 printf("we write gpt partition table to bootloader now\n");
906 printf("plese write bootloader to bootloader-boot0/bootloader-boot1\n");
907 fastboot_okay("gpt mode, skip", response);
908 return;
909 }
910#endif
911
912 if (strcmp(cmd_parameter, "avb_custom_key") == 0) {
913 char* buffer = NULL;
914 char *partition = "misc";
915
916 rc = store_part_size(partition);
917 buffer = (char *)malloc(AVB_CUSTOM_KEY_LEN_MAX);
918 if (!buffer) {
919 printf("malloc error\n");
920 fastboot_fail("malloc error", response);
921 return;
922 }
923 memset(buffer, 0, AVB_CUSTOM_KEY_LEN_MAX);
924
925 store_write((const char *)partition, rc - AVB_CUSTOM_KEY_LEN_MAX,
926 AVB_CUSTOM_KEY_LEN_MAX, (unsigned char *)buffer);
927
928 fastboot_okay(NULL, response);
929 free(buffer);
930 return;
931 }
932
933 if (strcmp(cmd_parameter, "env") == 0) {
934 char *fastboot_step = env_get("fastboot_step");
935
936 if (fastboot_step && strcmp(fastboot_step, "0")) {
937 printf("fastboot_step: %s, run defenv_reserv\n", fastboot_step);
938 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
939 run_command("run bcb_cmd", 0);
940 fastboot_okay(NULL, response);
941 return;
942 }
943 }
944
945 if (strcmp(cmd_parameter, "misc") == 0) {
946 char* buffer = NULL;
947 char *partition = "misc";
948
949 rc = store_part_size(partition);
950 buffer = (char *)malloc(rc - AVB_CUSTOM_KEY_LEN_MAX);
951 if (!buffer) {
952 printf("malloc error\n");
953 fastboot_fail("malloc error", response);
954 return;
955 }
956 memset(buffer, 0, rc - AVB_CUSTOM_KEY_LEN_MAX);
957
958 store_write((const char *)partition, 0, rc - AVB_CUSTOM_KEY_LEN_MAX,
959 (unsigned char *)buffer);
960
961 fastboot_okay(NULL, response);
962 free(buffer);
963 return;
964 }
965
966 if (strcmp(cmd_parameter, "userdata") == 0 || strcmp(cmd_parameter, "data") == 0) {
967 rc = store_part_size("userdata");
968 if (-1 == rc)
969 strcpy(name, "data");
970 else
971 strcpy(name, "userdata");
972 } else if (strcmp(cmd_parameter, "dts") == 0) {
973 strcpy(name, "dtb");
974 } else {
975 strncpy(name, cmd_parameter, 31);
976 }
977 strcat(name, "\0");
978
979#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
980 if (dynamic_partition) {
981 if (is_partition_logical(name) == 0) {
982 printf("logic partition, can not erase here.......\n");
983 fastboot_fail("logic partition", response);
984 return;
985 }
986 }
987#endif
988
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000989#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
Xindong Xud9441422024-01-18 10:20:45 +0800990 fastboot_mmc_erase(name, response);
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000991#endif
992#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800993 fastboot_nand_erase(name, response);
994#endif
995
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000996#endif
997}
998#endif
Xindong Xud9441422024-01-18 10:20:45 +0800999#endif
1000
1001#ifdef CONFIG_FASTBOOT_WRITING_CMD
1002
1003#ifdef CONFIG_AMLOGIC_MODIFY
1004static u64 my_ato11(const char *str)
1005{
1006 u64 result = 0;
1007 int len, i;
1008
1009 len = strlen(str);
1010 for (i = 0; i < len; i++) {
1011 if (*str >= '0' && *str <= '9')
1012 result = result * 16 + (*str - '0');
1013 else if (*str >= 'A' && *str <= 'F')
1014 result = result * 16 + (*str - 'A') + 10;
1015 else if (*str >= 'a' && *str <= 'f')
1016 result = result * 16 + (*str - 'a') + 10;
1017 str++;
1018 }
1019
1020 return result;
1021}
1022
1023static void fetch(char *cmd_parameter, char *response)
1024{
1025 int len;
1026 int i = 0;
1027 char *cmd;
1028 char name[32] = {0};
1029 u64 offset = 0;
1030 u64 read_size = 0;
1031 size_t size = 0;
1032
1033 if (check_lock() == 1) {
1034 printf("device is locked, can not run this cmd\n");
1035 fastboot_fail("locked device", response);
1036 return;
1037 }
1038
1039 cmd = cmd_parameter;
1040 len = strlen(cmd_parameter);
1041 while (strsep(&cmd, ":"))
1042 i++;
1043
1044 for (cmd = cmd_parameter, i = 0; cmd < (cmd_parameter + len); i++) {
1045 /* Skip to next assignment */
1046 if (i == 0) {
1047 strncpy(name, cmd, 31);
1048 strcat(name, "\0");
1049 } else if (i == 1) {
1050 offset = my_ato11(cmd);
1051 } else if (i == 2) {
1052 read_size = my_ato11(cmd);
1053 }
1054
1055 for (cmd += strlen(cmd); cmd < (cmd_parameter + len) && !*cmd;)
1056 cmd++;
1057 }
1058
1059 printf("name: %s\n", name);
1060 if (strncmp("vendor_boot", name, strlen("vendor_boot")) != 0) {
1061 printf("We can only %s vendor_boot\n", __func__);
1062 fastboot_fail("Fetch is only allowed on vendor_boot", response);
1063 return;
1064 }
1065
1066#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
1067 struct blk_desc *dev_desc;
1068 disk_partition_t part_info;
1069 int r;
1070
1071 r = fastboot_mmc_get_part_info(name, &dev_desc, &part_info,
1072 response);
1073 if (r >= 0)
1074 size = part_info.size * 512;
1075#endif
1076#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
1077 struct part_info *part_info;
1078 int r;
1079
1080 r = fastboot_nand_get_part_info(name, &part_info, response);
1081 if (r >= 0)
1082 size = part_info->size * 512;
1083#endif
1084
1085 if (offset > size) {
1086 printf("Invalid offset: 0x%llx, partition size is 0x%lx\n",
1087 offset, size);
1088 fastboot_fail("Invalid offset", response);
1089 return;
1090 }
1091
1092 if (read_size == 0 || read_size > size - offset ||
1093 read_size > kMaxFetchSizeDefault) {
1094 printf("Invalid read size: 0x%llx, partition size is 0x%lx\n",
1095 offset, size);
1096 fastboot_fail("Invalid read size", response);
1097 return;
1098 }
1099
1100 printf("Start read %s partition datas!\n", name);
1101 void *buffer;
1102 char str[128] = {0};
1103
1104 buffer = (void *)CONFIG_FASTBOOT_BUF_ADDR;
1105 sprintf(str, "DATA%12llx", read_size);
1106 printf("str: %s, len: %ld\n", str, strlen(str));
1107 memcpy(buffer, str, strlen(str));
1108
1109 if (store_read((const char *)name, offset, read_size,
1110 (unsigned char *)buffer + strlen(str)) < 0) {
1111 printf("failed to store read %s.\n", name);
1112 fastboot_fail("read partition data error", response);
1113 return;
1114 }
1115
1116 fastboot_readInfo.transferredBytes = 0;
1117 fastboot_readInfo.totalBytes = read_size + strlen(str);
1118 fastboot_response("DATA", response, "%12llx", read_size);
1119}
1120
Xindong Xub3cf2a82024-12-25 10:23:47 +08001121static void oem_cmd(char *cmd_parameter, char *response)
1122{
1123 char *cmd;
1124 int i = 0, len = 0, j = 0;
1125 char cmd_str[FASTBOOT_RESPONSE_LEN];
1126
1127 printf("oem cmd_parameter: %s\n", cmd_parameter);
1128
1129 if (IS_FEAT_BOOT_VERIFY()) {
1130 printf("device is secure mode, can not run this cmd.\n");
1131 fastboot_fail("secure boot device", response);
1132 return;
1133 }
1134
1135 if (check_lock() == 1) {
1136 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1137 fastboot_fail("locked device", response);
1138 return;
1139 }
1140
1141 cmd = cmd_parameter;
1142 strsep(&cmd, " ");
1143 printf("To run cmd[%s]\n", cmd);
1144
1145 len = strlen(cmd);
1146 for (i = 0; i < len; i++) {
1147 if (cmd[i] != '\'')
1148 cmd_str[j++] = cmd[i];
1149 }
1150 cmd_str[j] = '\0';
1151 printf("cmd_str2: %s\n", cmd_str);
1152
1153 run_command(cmd_str, 0);
1154
1155 fastboot_okay(NULL, response);
1156}
1157
Xindong Xud9441422024-01-18 10:20:45 +08001158static void set_active_cmd(char *cmd_parameter, char *response)
1159{
1160 char *cmd;
1161 int ret = 0;
1162 char str[128];
1163
1164 printf("cmd cb_set_active is %s\n", cmd_parameter);
1165 cmd = cmd_parameter;
1166
1167 if (check_lock() == 1) {
1168 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1169 fastboot_fail("locked device", response);
1170 return;
1171 }
1172
1173 sprintf(str, "set_active_slot %s", cmd);
1174 printf("command: %s\n", str);
1175 ret = run_command(str, 0);
1176 printf("ret = %d\n", ret);
1177 if (ret == 0)
1178 fastboot_okay(NULL, response);
1179 else
1180 fastboot_fail("set slot error", response);
1181}
1182
1183#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
Xindong Xub3cf2a82024-12-25 10:23:47 +08001184#ifdef CONFIG_AVB2
Xindong Xud9441422024-01-18 10:20:45 +08001185static void try_unlock_dev(u64 rc)
1186{
1187#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1188 if (is_avb_arb_available()) {
1189 if (avb_unlock()) {
1190 if (-1 == rc) {
1191 printf("unlocking device. Erasing data partition!\n");
1192 run_command("store erase data 0 0", 0);
1193 } else {
1194 printf("unlocking device. Erasing userdata partition!\n");
1195 run_command("store erase userdata 0 0", 0);
1196 }
1197 printf("unlocking device. Erasing metadata partition!\n");
1198 run_command("store erase metadata 0 0", 0);
1199 } else {
1200 printf("unlock failed!\n");
1201 }
1202
1203 return;
1204 }
1205#endif
1206 if (-1 == rc) {
1207 printf("unlocking device. Erasing data partition!\n");
1208 run_command("store erase data 0 0", 0);
1209 } else {
1210 printf("unlocking device. Erasing userdata partition!\n");
1211 run_command("store erase userdata 0 0", 0);
1212 }
1213 printf("unlocking device. Erasing metadata partition!\n");
1214 run_command("store erase metadata 0 0", 0);
1215}
1216
1217static void try_lock_dev(u64 rc)
1218{
1219#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1220 if (is_avb_arb_available()) {
1221 if (avb_lock()) {
1222 if (-1 == rc) {
1223 printf("locking device. Erasing data partition!\n");
1224 run_command("store erase data 0 0", 0);
1225 } else {
1226 printf("locking device. Erasing userdata partition!\n");
1227 run_command("store erase userdata 0 0", 0);
1228 }
1229 printf("locking device. Erasing metadata partition!\n");
1230 run_command("store erase metadata 0 0", 0);
1231 } else {
1232 printf("lock failed!\n");
1233 }
1234
1235 return;
1236 }
1237#endif
1238 if (-1 == rc) {
1239 printf("locking device. Erasing data partition!\n");
1240 run_command("store erase data 0 0", 0);
1241 } else {
1242 printf("locking device. Erasing userdata partition!\n");
1243 run_command("store erase userdata 0 0", 0);
1244 }
1245 printf("locking device. Erasing metadata partition!\n");
1246 run_command("store erase metadata 0 0", 0);
1247}
Xindong Xub3cf2a82024-12-25 10:23:47 +08001248#endif
Xindong Xud9441422024-01-18 10:20:45 +08001249
1250/**
1251 * flashing() - lock/unlock.
1252 *
1253 * @cmd_parameter: Pointer to partition name
1254 * @response: Pointer to fastboot response buffer
1255 *
1256 * Writes the previously downloaded image to the partition indicated by
1257 * cmd_parameter. Writes to response.
1258 */
1259static void flashing(char *cmd_parameter, char *response)
1260{
1261 char *cmd;
1262 char* lock_s;
1263 LockData_t info = {0};
1264 char lock_d[LOCK_DATA_SIZE];
1265 u64 rc;
1266 int debug_flag = 0;
1267
Xindong Xu2e748322024-11-22 09:24:46 +08001268#ifndef CONFIG_REFERENCE
Xindong Xud9441422024-01-18 10:20:45 +08001269 if (IS_FEAT_BOOT_VERIFY()) {
1270 printf("device is secure mode, can not run this cmd.\n");
1271 fastboot_fail("secure boot device", response);
1272 return;
1273 }
Xindong Xu2e748322024-11-22 09:24:46 +08001274#endif
Xindong Xud9441422024-01-18 10:20:45 +08001275
1276 lock_s = env_get("lock");
1277 if (!lock_s) {
1278 printf("lock state is NULL \n");
1279 memcpy(lock_d, "10101000", 8);
1280 lock_s = "10101000";
1281 env_set("lock", "10101000");
1282#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1283 run_command("update_env_part -p lock;", 0);
1284#else
1285 run_command("defenv_reserv; saveenv;", 0);
1286#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1287 } else {
1288 printf("lock state: %s\n", lock_s);
1289 if (strlen(lock_s) > 15)
1290 strncpy(lock_d, lock_s, 15);
1291 else
1292 strncpy(lock_d, lock_s, strlen(lock_s));
1293 }
1294
1295 info.version_major = (int)(lock_d[0] - '0');
1296 info.version_minor = (int)(lock_d[1] - '0');
1297 info.unlock_ability = (int)(lock_d[2] - '0');
1298 info.lock_state = (int)(lock_d[4] - '0');
1299 info.lock_critical_state = (int)(lock_d[5] - '0');
1300 info.lock_bootloader = (int)(lock_d[6] - '0');
1301 dump_lock_info(info);
1302
1303 printf("cb_flashing cmd_parameter: %s\n", cmd_parameter);
1304 cmd = cmd_parameter;
1305 strsep(&cmd, " ");
1306 printf("cb_flashing: %s\n", cmd);
1307 if (!cmd) {
1308 printf("missing variable\n");
1309 fastboot_fail("missing var", response);
1310 return;
1311 }
1312
1313 boot_img_hdr_t *hdr_addr = NULL;
1314 const int preloadsz = 0x1000 * 2;//4k not enough for signed
1315 unsigned char *pbuffpreload = 0;
1316 char partname[32] = {0};
1317 char *slot_name;
1318 char cmdline[4096];
1319 char *result = NULL;
1320
1321 slot_name = env_get("slot-suffixes");
1322 if (slot_name && (strcmp(slot_name, "0") == 0))
1323 strcpy((char *)partname, "boot_a");
1324 else if (slot_name && (strcmp(slot_name, "1") == 0))
1325 strcpy((char *)partname, "boot_b");
1326 else
1327 strcpy((char *)partname, "boot");
1328
1329 pbuffpreload = malloc(preloadsz);
1330 if (!pbuffpreload) {
1331 printf("Fail to allocate memory!\n");
1332 goto next;
1333 }
1334
1335 hdr_addr = (boot_img_hdr_t *)pbuffpreload;
1336
1337 printf("read from part: %s\n", partname);
1338 rc = store_logic_read(partname, 0, preloadsz, pbuffpreload);
1339 if (rc) {
1340 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1341 preloadsz, partname);
1342 free(pbuffpreload);
1343 pbuffpreload = 0;
1344 goto next;
1345 }
1346
1347 if (is_android_r_image((void *)hdr_addr)) {
1348 char partname_r[32] = {0};
1349 const int preloadsz_r = 0x1000 * 2;//4k not enough for signed
1350 unsigned char *pbuffpreload_r = 0;
1351 int ret_r = __LINE__;
1352
1353 if (slot_name && (strcmp(slot_name, "0") == 0))
1354 strcpy((char *)partname_r, "vendor_boot_a");
1355 else if (slot_name && (strcmp(slot_name, "1") == 0))
1356 strcpy((char *)partname_r, "vendor_boot_b");
1357 else
1358 strcpy((char *)partname_r, "vendor_boot");
1359
1360 pbuffpreload_r = malloc(preloadsz_r);
1361
1362 if (!pbuffpreload_r) {
1363 printf("Fail to allocate memory for %s!\n",
1364 partname_r);
1365 goto next;
1366 }
1367
1368 printf("read from part: %s\n", partname_r);
1369 ret_r = store_logic_read(partname_r, 0,
1370 preloadsz_r, pbuffpreload_r);
1371 if (ret_r) {
1372 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1373 preloadsz_r, partname_r);
1374 free(pbuffpreload_r);
1375 pbuffpreload_r = 0;
1376 goto next;
1377 }
1378
1379 p_vendor_boot_img_hdr_t vb_hdr = (p_vendor_boot_img_hdr_t)pbuffpreload_r;
1380
1381 if (*vb_hdr->cmdline) {
1382 printf("Kernel command line: %s\n", vb_hdr->cmdline);
1383 sprintf(cmdline, "%s", vb_hdr->cmdline);
1384 }
1385 free(pbuffpreload_r);
1386 pbuffpreload_r = 0;
1387 } else {
1388 if (*hdr_addr->cmdline) {
1389 printf("Kernel command line: %s\n", hdr_addr->cmdline);
1390 sprintf(cmdline, "%s", hdr_addr->cmdline);
1391 }
1392 }
1393
1394 free(pbuffpreload);
1395 pbuffpreload = 0;
1396
1397 result = strtok(cmdline, " ");
1398 while (result) {
1399 printf("result: %s\n", result);
1400 if (strcmp(result, "buildvariant=userdebug") == 0 ||
1401 strcmp(result, "buildvariant=eng") == 0)
1402 debug_flag = 1;
1403 result = strtok(NULL, " ");
1404 }
1405
1406 if (info.unlock_ability == 0 && debug_flag == 1) {
1407 printf("userdebug mode can ignore\n");
1408 info.unlock_ability = 1;
1409 }
1410
1411next:
1412 rc = store_part_size("userdata");
1413
1414 if (!strcmp_l1("unlock_critical", cmd)) {
1415 info.lock_critical_state = 0;
1416 fastboot_okay(NULL, response);
1417 } else if (!strcmp_l1("lock_critical", cmd)) {
1418 info.lock_critical_state = 1;
1419 fastboot_okay(NULL, response);
1420 } else if (!strcmp_l1("get_unlock_ability", cmd)) {
1421 char str[32];
1422 static bool is_unlock_ability_sent = false;
1423 if (is_unlock_ability_sent) {
1424 is_unlock_ability_sent = false;
1425 fastboot_okay(NULL, response);
1426 busy_flag = 0;
1427 } else {
1428 sprintf(str, "get_unlock_ability: %d",
1429 info.unlock_ability);
1430 fastboot_response("INFO", response, "%s", str);
1431 is_unlock_ability_sent = true;
1432 busy_flag = 1;
1433 }
1434 return;
1435 } else if (!strcmp_l1("get_unlock_bootloader_nonce", cmd)) {
1436 char str_num[8];
1437 sprintf(str_num, "%d", info.lock_critical_state);
1438 fastboot_response("OKAY", response, "%s", str_num);
1439 } else if (!strcmp_l1("lock_bootloader", cmd)) {
1440 info.lock_bootloader = 1;
1441 } else if (!strcmp_l1("unlock", cmd)) {
hao.qi40c37a02024-07-15 13:40:47 +08001442#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
hao.qi0696a542024-09-12 14:58:03 +08001443 u32 rpmb_lock_state = 0;
1444 bool ret = get_avb_lock_state(&rpmb_lock_state);
hao.qi40c37a02024-07-15 13:40:47 +08001445
hao.qi0696a542024-09-12 14:58:03 +08001446 if (info.lock_state == 1 || (ret && rpmb_lock_state == 1)) {
hao.qi40c37a02024-07-15 13:40:47 +08001447#else
hao.qi0696a542024-09-12 14:58:03 +08001448 if (info.lock_state == 1) {
hao.qi40c37a02024-07-15 13:40:47 +08001449#endif
Xindong Xuac88caf2024-10-28 17:10:12 +08001450#ifdef CONFIG_AVB2
1451 try_unlock_dev(rc);
1452#endif
Xindong Xud9441422024-01-18 10:20:45 +08001453 }
hao.qi0696a542024-09-12 14:58:03 +08001454 info.lock_state = 0;
1455 info.lock_critical_state = 0;
1456 env_set("lock_state", "green");
1457 fastboot_okay(NULL, response);
Xindong Xud9441422024-01-18 10:20:45 +08001458 } else if (!strcmp_l1("lock", cmd)) {
hao.qi40c37a02024-07-15 13:40:47 +08001459#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1460 u32 rpmb_lock_state = 0;
1461 bool ret = get_avb_lock_state(&rpmb_lock_state);
1462
1463 if (info.lock_state == 0 || (ret && rpmb_lock_state == 0)) {
1464#else
Xindong Xud9441422024-01-18 10:20:45 +08001465 if (info.lock_state == 0) {
hao.qi40c37a02024-07-15 13:40:47 +08001466#endif
Xindong Xuac88caf2024-10-28 17:10:12 +08001467#ifdef CONFIG_AVB2
1468 try_lock_dev(rc);
1469#endif
Xindong Xud9441422024-01-18 10:20:45 +08001470 }
1471 info.lock_state = 1;
1472 env_set("lock_state", "orange");
1473 fastboot_okay(NULL, response);
1474 } else {
1475 printf("unknown variable: %s\n", cmd);
1476 fastboot_response("FAIL", response, "%s", "Variable not implemented");
1477 }
1478
1479 sprintf(lock_d, "%d%d%d0%d%d%d0", info.version_major, info.version_minor,
1480 info.unlock_ability, info.lock_state, info.lock_critical_state,
1481 info.lock_bootloader);
1482 printf("lock_d state: %s\n", lock_d);
1483 env_set("lock", lock_d);
1484#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1485 run_command("update_env_part -p lock;", 0);
1486#else
1487 run_command("defenv_reserv; saveenv;", 0);
1488#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1489 return;
1490}
1491#endif// #if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
1492#endif
1493#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001494
Heiko Schocherbc820d52021-02-10 09:29:03 +01001495#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
1496/**
1497 * run_ucmd() - Execute the UCmd command
1498 *
1499 * @cmd_parameter: Pointer to command parameter
1500 * @response: Pointer to fastboot response buffer
1501 */
1502static void run_ucmd(char *cmd_parameter, char *response)
1503{
1504 if (!cmd_parameter) {
1505 pr_err("missing slot suffix\n");
1506 fastboot_fail("missing command", response);
1507 return;
1508 }
1509
1510 if (run_command(cmd_parameter, 0))
1511 fastboot_fail("", response);
1512 else
1513 fastboot_okay(NULL, response);
1514}
1515
1516static char g_a_cmd_buff[64];
1517
1518void fastboot_acmd_complete(void)
1519{
1520 run_command(g_a_cmd_buff, 0);
1521}
1522
1523/**
1524 * run_acmd() - Execute the ACmd command
1525 *
1526 * @cmd_parameter: Pointer to command parameter
1527 * @response: Pointer to fastboot response buffer
1528 */
1529static void run_acmd(char *cmd_parameter, char *response)
1530{
1531 if (!cmd_parameter) {
1532 pr_err("missing slot suffix\n");
1533 fastboot_fail("missing command", response);
1534 return;
1535 }
1536
1537 if (strlen(cmd_parameter) > sizeof(g_a_cmd_buff)) {
1538 pr_err("too long command\n");
1539 fastboot_fail("too long command", response);
1540 return;
1541 }
1542
1543 strcpy(g_a_cmd_buff, cmd_parameter);
1544 fastboot_okay(NULL, response);
1545}
1546#endif
1547
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001548/**
1549 * reboot_bootloader() - Sets reboot bootloader flag.
1550 *
1551 * @cmd_parameter: Pointer to command parameter
1552 * @response: Pointer to fastboot response buffer
1553 */
1554static void reboot_bootloader(char *cmd_parameter, char *response)
1555{
Xindong Xud9441422024-01-18 10:20:45 +08001556#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi851737a2020-07-28 23:35:32 +03001557 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_BOOTLOADER))
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001558 fastboot_fail("Cannot set reboot flag", response);
1559 else
Xindong Xud9441422024-01-18 10:20:45 +08001560#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001561 fastboot_okay(NULL, response);
1562}
Alex Kiernan3845b902018-05-29 15:30:54 +00001563
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001564/**
1565 * reboot_fastbootd() - Sets reboot fastboot flag.
1566 *
1567 * @cmd_parameter: Pointer to command parameter
1568 * @response: Pointer to fastboot response buffer
1569 */
1570static void reboot_fastbootd(char *cmd_parameter, char *response)
1571{
Xindong Xud9441422024-01-18 10:20:45 +08001572#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001573 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_FASTBOOTD))
Xindong Xud9441422024-01-18 10:20:45 +08001574 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001575 else
Xindong Xud9441422024-01-18 10:20:45 +08001576#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001577 fastboot_okay(NULL, response);
1578}
1579
1580/**
1581 * reboot_recovery() - Sets reboot recovery flag.
1582 *
1583 * @cmd_parameter: Pointer to command parameter
1584 * @response: Pointer to fastboot response buffer
1585 */
1586static void reboot_recovery(char *cmd_parameter, char *response)
1587{
Xindong Xud9441422024-01-18 10:20:45 +08001588#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001589 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_RECOVERY))
Xindong Xud9441422024-01-18 10:20:45 +08001590 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001591 else
Xindong Xud9441422024-01-18 10:20:45 +08001592#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001593 fastboot_okay(NULL, response);
1594}
1595
Xindong Xud9441422024-01-18 10:20:45 +08001596#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernan3845b902018-05-29 15:30:54 +00001597#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
1598/**
1599 * oem_format() - Execute the OEM format command
1600 *
1601 * @cmd_parameter: Pointer to command parameter
1602 * @response: Pointer to fastboot response buffer
1603 */
1604static void oem_format(char *cmd_parameter, char *response)
1605{
1606 char cmdbuf[32];
1607
Xindong Xud9441422024-01-18 10:20:45 +08001608#ifdef CONFIG_AMLOGIC_MODIFY
Xindong Xu2e748322024-11-22 09:24:46 +08001609#ifndef CONFIG_REFERENCE
Xindong Xud9441422024-01-18 10:20:45 +08001610 if (IS_FEAT_BOOT_VERIFY()) {
1611 printf("device is secure mode, can not run this cmd.\n");
1612 fastboot_fail("secure boot device", response);
1613 return;
1614 }
Xindong Xu2e748322024-11-22 09:24:46 +08001615#endif
Xindong Xud9441422024-01-18 10:20:45 +08001616
1617 if (check_lock() == 1) {
1618 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1619 fastboot_fail("locked device", response);
1620 return;
1621 }
1622#endif
1623
Alex Kiernan3845b902018-05-29 15:30:54 +00001624 if (!env_get("partitions")) {
1625 fastboot_fail("partitions not set", response);
1626 } else {
1627 sprintf(cmdbuf, "gpt write mmc %x $partitions",
1628 CONFIG_FASTBOOT_FLASH_MMC_DEV);
1629 if (run_command(cmdbuf, 0))
1630 fastboot_fail("", response);
1631 else
1632 fastboot_okay(NULL, response);
1633 }
1634}
1635#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +01001636
1637#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
1638/**
1639 * oem_partconf() - Execute the OEM partconf command
1640 *
1641 * @cmd_parameter: Pointer to command parameter
1642 * @response: Pointer to fastboot response buffer
1643 */
1644static void oem_partconf(char *cmd_parameter, char *response)
1645{
1646 char cmdbuf[32];
1647
1648 if (!cmd_parameter) {
1649 fastboot_fail("Expected command parameter", response);
1650 return;
1651 }
1652
1653 /* execute 'mmc partconfg' command with cmd_parameter arguments*/
1654 snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0",
1655 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1656 printf("Execute: %s\n", cmdbuf);
1657 if (run_command(cmdbuf, 0))
1658 fastboot_fail("Cannot set oem partconf", response);
1659 else
1660 fastboot_okay(NULL, response);
1661}
1662#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +01001663
1664#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
1665/**
1666 * oem_bootbus() - Execute the OEM bootbus command
1667 *
1668 * @cmd_parameter: Pointer to command parameter
1669 * @response: Pointer to fastboot response buffer
1670 */
1671static void oem_bootbus(char *cmd_parameter, char *response)
1672{
1673 char cmdbuf[32];
1674
1675 if (!cmd_parameter) {
1676 fastboot_fail("Expected command parameter", response);
1677 return;
1678 }
1679
1680 /* execute 'mmc bootbus' command with cmd_parameter arguments*/
1681 snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s",
1682 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1683 printf("Execute: %s\n", cmdbuf);
1684 if (run_command(cmdbuf, 0))
1685 fastboot_fail("Cannot set oem bootbus", response);
1686 else
1687 fastboot_okay(NULL, response);
1688}
1689#endif
Xindong Xud9441422024-01-18 10:20:45 +08001690#endif