blob: c2db22faf51a1f9bcabe00ee1bed73a8905b3a11 [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>
27#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
28#include <amlogic/anti-rollback.h>
29#endif
30#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000031
32/**
33 * image_size - final fastboot image size
34 */
35static u32 image_size;
36
37/**
38 * fastboot_bytes_received - number of bytes received in the current download
39 */
40static u32 fastboot_bytes_received;
41
42/**
43 * fastboot_bytes_expected - number of bytes expected in the current download
44 */
45static u32 fastboot_bytes_expected;
46
Xindong Xud9441422024-01-18 10:20:45 +080047#ifdef CONFIG_AMLOGIC_MODIFY
48int busy_flag;
49#endif
50
Alex Kiernanf73a7df2018-05-29 15:30:53 +000051static void okay(char *, char *);
52static void getvar(char *, char *);
Xindong Xud9441422024-01-18 10:20:45 +080053
54#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +000055static void download(char *, char *);
56#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
57static void flash(char *, char *);
58static void erase(char *, char *);
59#endif
Xindong Xud9441422024-01-18 10:20:45 +080060#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000061static void reboot_bootloader(char *, char *);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +030062static void reboot_fastbootd(char *, char *);
63static void reboot_recovery(char *, char *);
Xindong Xud9441422024-01-18 10:20:45 +080064#ifdef CONFIG_FASTBOOT_WRITING_CMD
65#ifdef CONFIG_AMLOGIC_MODIFY
66static void fetch(char *, char *);
67#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
68static void flashing(char *, char *);
69#endif
70#endif
Alex Kiernan3845b902018-05-29 15:30:54 +000071#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
72static void oem_format(char *, char *);
73#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +010074#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
75static void oem_partconf(char *, char *);
76#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +010077#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
78static void oem_bootbus(char *, char *);
79#endif
Xindong Xud9441422024-01-18 10:20:45 +080080static void set_active_cmd(char *, char *);
81#endif
82
83#ifdef CONFIG_AMLOGIC_MODIFY
84extern int is_partition_logical(char* partition_name);
85#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000086
Heiko Schocherbc820d52021-02-10 09:29:03 +010087#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
88static void run_ucmd(char *, char *);
89static void run_acmd(char *, char *);
90#endif
91
Alex Kiernanf73a7df2018-05-29 15:30:53 +000092static const struct {
93 const char *command;
94 void (*dispatch)(char *cmd_parameter, char *response);
95} commands[FASTBOOT_COMMAND_COUNT] = {
96 [FASTBOOT_COMMAND_GETVAR] = {
97 .command = "getvar",
98 .dispatch = getvar
99 },
Xindong Xud9441422024-01-18 10:20:45 +0800100#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000101 [FASTBOOT_COMMAND_DOWNLOAD] = {
102 .command = "download",
103 .dispatch = download
104 },
Xindong Xud9441422024-01-18 10:20:45 +0800105#ifdef CONFIG_AMLOGIC_MODIFY
106#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
107 [FASTBOOT_COMMAND_FLASHING] = {
108 .command = "flashing",
109 .dispatch = flashing
110 },
111#endif
112 [FASTBOOT_COMMAND_FETCH] = {
113 .command = "fetch",
114 .dispatch = fetch
115 },
116#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000117#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
118 [FASTBOOT_COMMAND_FLASH] = {
119 .command = "flash",
120 .dispatch = flash
121 },
122 [FASTBOOT_COMMAND_ERASE] = {
123 .command = "erase",
124 .dispatch = erase
125 },
126#endif
127 [FASTBOOT_COMMAND_BOOT] = {
128 .command = "boot",
129 .dispatch = okay
130 },
Xindong Xud9441422024-01-18 10:20:45 +0800131#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000132 [FASTBOOT_COMMAND_CONTINUE] = {
133 .command = "continue",
134 .dispatch = okay
135 },
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000136 [FASTBOOT_COMMAND_REBOOT_BOOTLOADER] = {
137 .command = "reboot-bootloader",
138 .dispatch = reboot_bootloader
139 },
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +0300140 [FASTBOOT_COMMAND_REBOOT_FASTBOOTD] = {
141 .command = "reboot-fastboot",
142 .dispatch = reboot_fastbootd
143 },
144 [FASTBOOT_COMMAND_REBOOT_RECOVERY] = {
145 .command = "reboot-recovery",
146 .dispatch = reboot_recovery
147 },
Xindong Xud9441422024-01-18 10:20:45 +0800148 [FASTBOOT_COMMAND_REBOOT] = {
149 .command = "reboot",
150 .dispatch = okay
151 },
152#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000153 [FASTBOOT_COMMAND_SET_ACTIVE] = {
154 .command = "set_active",
Xindong Xud9441422024-01-18 10:20:45 +0800155#ifdef CONFIG_AMLOGIC_MODIFY
156 .dispatch = set_active_cmd
157#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000158 .dispatch = okay
Xindong Xud9441422024-01-18 10:20:45 +0800159#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000160 },
Alex Kiernan3845b902018-05-29 15:30:54 +0000161#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
162 [FASTBOOT_COMMAND_OEM_FORMAT] = {
163 .command = "oem format",
164 .dispatch = oem_format,
165 },
166#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +0100167#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
168 [FASTBOOT_COMMAND_OEM_PARTCONF] = {
169 .command = "oem partconf",
170 .dispatch = oem_partconf,
171 },
172#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +0100173#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
174 [FASTBOOT_COMMAND_OEM_BOOTBUS] = {
175 .command = "oem bootbus",
176 .dispatch = oem_bootbus,
177 },
178#endif
Xindong Xud9441422024-01-18 10:20:45 +0800179#endif
Heiko Schocherbc820d52021-02-10 09:29:03 +0100180#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
181 [FASTBOOT_COMMAND_UCMD] = {
182 .command = "UCmd",
183 .dispatch = run_ucmd,
184 },
185 [FASTBOOT_COMMAND_ACMD] = {
186 .command = "ACmd",
187 .dispatch = run_acmd,
188 },
189#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000190};
191
Xindong Xud9441422024-01-18 10:20:45 +0800192#ifdef CONFIG_AMLOGIC_MODIFY
193struct fastboot_read fastboot_readInfo;
194
195static int strcmp_l1(const char *s1, const char *s2)
196{
197 if (!s1 || !s2)
198 return -1;
199 return strncmp(s1, s2, strlen(s1));
200}
201#endif
202
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000203/**
204 * fastboot_handle_command - Handle fastboot command
205 *
206 * @cmd_string: Pointer to command string
207 * @response: Pointer to fastboot response buffer
208 *
209 * Return: Executed command, or -1 if not recognized
210 */
211int fastboot_handle_command(char *cmd_string, char *response)
212{
213 int i;
214 char *cmd_parameter;
215
216 cmd_parameter = cmd_string;
217 strsep(&cmd_parameter, ":");
218
219 for (i = 0; i < FASTBOOT_COMMAND_COUNT; i++) {
Xindong Xud9441422024-01-18 10:20:45 +0800220#ifdef CONFIG_AMLOGIC_MODIFY
221 if (!strcmp_l1(commands[i].command, cmd_string)) {
222 if (commands[i].dispatch) {
223 if (cmd_parameter) {
224 commands[i].dispatch(cmd_parameter,
225 response);
226 } else {
227 commands[i].dispatch(cmd_string,
228 response);
229 }
230 return i;
231 } else {
232 break;
233 }
234 }
235#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000236 if (!strcmp(commands[i].command, cmd_string)) {
237 if (commands[i].dispatch) {
238 commands[i].dispatch(cmd_parameter,
239 response);
240 return i;
241 } else {
242 break;
243 }
244 }
Xindong Xud9441422024-01-18 10:20:45 +0800245#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000246 }
247
248 pr_err("command %s not recognized.\n", cmd_string);
249 fastboot_fail("unrecognized command", response);
250 return -1;
251}
252
253/**
254 * okay() - Send bare OKAY response
255 *
256 * @cmd_parameter: Pointer to command parameter
257 * @response: Pointer to fastboot response buffer
258 *
259 * Send a bare OKAY fastboot response. This is used where the command is
260 * valid, but all the work is done after the response has been sent (e.g.
261 * boot, reboot etc.)
262 */
263static void okay(char *cmd_parameter, char *response)
264{
265 fastboot_okay(NULL, response);
266}
267
Xindong Xud9441422024-01-18 10:20:45 +0800268#ifdef CONFIG_AMLOGIC_MODIFY
269void dump_lock_info(LockData_t info)
270{
271#if 0
272 printf("info.version_major = %d\n", info.version_major);
273 printf("info.version_minor = %d\n", info.version_minor);
274 printf("info.unlock_ability = %d\n", info.unlock_ability);
275 printf("info.lock_state = %d\n", info.lock_state);
276 printf("info.lock_critical_state = %d\n", info.lock_critical_state);
277 printf("info.lock_bootloader = %d\n", info.lock_bootloader);
278#endif
279}
280
281static const char* getvar_list[] = {
282 "version-baseband", "version-bootloader", "version", "hw-revision", "max-download-size",
283 "serialno", "product", "off-mode-charge", "variant", "battery-soc-ok",
284 "battery-voltage", "partition-type:boot", "partition-size:boot",
285 "partition-type:system", "partition-size:system", "partition-type:vendor", "partition-size:vendor",
286 "partition-type:odm", "partition-size:odm", "partition-type:data", "partition-size:data",
287 "erase-block-size", "logical-block-size", "secure", "unlocked",
288};
289
290static const char* getvar_list_dynamic[] = {
291 "hw-revision", "battery-voltage", "is-userspace", "is-logical:data",
292 "is-logical:metadata", "is-logical:misc", "is-logical:super", "is-logical:boot",
293 "is-logical:system", "is-logical:vendor", "is-logical:product", "is-logical:odm",
294 "slot-count", "max-download-size", "serialno", "product", "unlocked",
295 "secure", "super-partition-name", "version-baseband", "version-bootloader",
296 "partition-size:boot", "partition-size:metadata", "partition-size:misc",
297 "partition-size:super", "partition-size:data", "version",
298};
299
300static const char* getvar_list_dynamic_ab[] = {
301 "hw-revision", "battery-voltage", "is-userspace", "is-logical:data",
302 "is-logical:misc", "is-logical:super",
303 "is-logical:boot_a", "is-logical:boot_b", "is-logical:system_a", "is-logical:system_b",
304 "is-logical:vendor_a", "is-logical:vendor_b", "is-logical:product_a", "is-logical:product_b",
305 "is-logical:odm_a", "is-logical:odm_b",
306 "slot-count", "max-download-size", "serialno", "product", "unlocked", "has-slot:data",
307 "has-slot:metadata", "has-slot:misc", "has-slot:super", "has-slot:boot",
308 "has-slot:system", "has-slot:vendor", "has-slot:product", "has-slot:odm", "current-slot",
309 "secure", "super-partition-name", "version-baseband", "version-bootloader",
310 "partition-size:super",
311 "partition-size:boot_a", "partition-size:boot_b", "partition-size:misc",
312 "partition-size:data", "version",
313};
314
315
316static const char* getvar_list_ab[] = {
317 "version-baseband", "version-bootloader", "version", "hw-revision", "max-download-size",
318 "serialno", "product", "off-mode-charge", "variant", "battery-soc-ok",
319 "battery-voltage", "partition-type:boot_a", "partition-size:boot_a",
320 "partition-type:system_a", "partition-size:system_a", "partition-type:vendor_a", "partition-size:vendor_a",
321 "partition-type:odm_a", "partition-size:odm_a", "partition-type:data", "partition-size:data",
322 "erase-block-size", "logical-block-size", "secure", "unlocked",
323 "slot-count", "slot-suffixes","current-slot", "has-slot:bootloader", "has-slot:boot",
324 "has-slot:system", "has-slot:vendor", "has-slot:odm", "has-slot:vbmeta",
325 "has-slot:metadata", "has-slot:product", "has-slot:dtbo",
326 "slot-successful:a", "slot-unbootable:a", "slot-retry-count:a",
327 "slot-successful:b", "slot-unbootable:b", "slot-retry-count:b",
328};
329#endif
330
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000331/**
332 * getvar() - Read a config/version variable
333 *
334 * @cmd_parameter: Pointer to command parameter
335 * @response: Pointer to fastboot response buffer
336 */
337static void getvar(char *cmd_parameter, char *response)
338{
Xindong Xud9441422024-01-18 10:20:45 +0800339#ifdef CONFIG_AMLOGIC_MODIFY
340 run_command("get_valid_slot", 0);
341 if (!strncmp(cmd_parameter, "all", 3)) {
342 static int cmdIndex = 0;
343 int getvar_num = 0;
344 char* cmd=cmd_parameter;
345
346 busy_flag = 1;
347
348 if (dynamic_partition && has_boot_slot == 1 && strlen(getvar_list_dynamic_ab[cmdIndex]) < 64) {
349 strncpy(cmd, getvar_list_dynamic_ab[cmdIndex], 64);
350 getvar_num = (sizeof(getvar_list_dynamic_ab) / sizeof(getvar_list_dynamic_ab[0]));
351 } else if (has_boot_slot == 1 && strlen(getvar_list_ab[cmdIndex]) < 64) {
352 strncpy(cmd, getvar_list_ab[cmdIndex], 64);
353 getvar_num = (sizeof(getvar_list_ab) / sizeof(getvar_list_ab[0]));
354 } else if (dynamic_partition && strlen(getvar_list_dynamic[cmdIndex]) < 64) {
355 strncpy(cmd, getvar_list_dynamic[cmdIndex], 64);//only support no-arg cmd
356 getvar_num = (sizeof(getvar_list_dynamic) / sizeof(getvar_list_dynamic[0]));
357 } else if (strlen(getvar_list[cmdIndex]) < 64) {
358 strncpy(cmd, getvar_list[cmdIndex], 64);//only support no-arg cmd
359 getvar_num = (sizeof(getvar_list) / sizeof(getvar_list[0]));
360 }
361 //printf("getvar_num: %d\n", getvar_num);
362 //printf("all cmd:%s\n", cmd);
363 if ( ++cmdIndex >= getvar_num) {
364 cmdIndex = 0;
365 busy_flag = 0;
366 fastboot_okay(NULL, response);
367 } else {
368 fastboot_getvar(cmd, response);
369 }
370
371 }else {
372#endif
373 fastboot_getvar(cmd_parameter, response);
374#ifdef CONFIG_AMLOGIC_MODIFY
375 }
376#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000377}
378
379/**
380 * fastboot_download() - Start a download transfer from the client
381 *
382 * @cmd_parameter: Pointer to command parameter
383 * @response: Pointer to fastboot response buffer
384 */
Xindong Xud9441422024-01-18 10:20:45 +0800385#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000386static void download(char *cmd_parameter, char *response)
387{
388 char *tmp;
389
Xindong Xud9441422024-01-18 10:20:45 +0800390#ifdef CONFIG_AMLOGIC_MODIFY
391 if (check_lock() == 1) {
392 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
393 fastboot_fail("locked device", response);
394 return;
395 }
396#endif
397
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000398 if (!cmd_parameter) {
399 fastboot_fail("Expected command parameter", response);
400 return;
401 }
402 fastboot_bytes_received = 0;
Simon Glass7e5f4602021-07-24 09:03:29 -0600403 fastboot_bytes_expected = hextoul(cmd_parameter, &tmp);
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000404 if (fastboot_bytes_expected == 0) {
405 fastboot_fail("Expected nonzero image size", response);
406 return;
407 }
408 /*
409 * Nothing to download yet. Response is of the form:
410 * [DATA|FAIL]$cmd_parameter
411 *
412 * where cmd_parameter is an 8 digit hexadecimal number
413 */
414 if (fastboot_bytes_expected > fastboot_buf_size) {
Xindong Xud9441422024-01-18 10:20:45 +0800415#ifdef CONFIG_AMLOGIC_MODIFY
416 char str[128] = {0};
417
418 printf("fastboot_bytes_expected %d > fastboot_buf_size %d\n",
419 fastboot_bytes_expected, fastboot_buf_size);
420 sprintf(str, "data too large, please add -S %dM",
421 (fastboot_buf_size / 1024 / 1024));
422 fastboot_fail(str, response);
423#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000424 fastboot_fail(cmd_parameter, response);
Xindong Xud9441422024-01-18 10:20:45 +0800425#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000426 } else {
427 printf("Starting download of %d bytes\n",
428 fastboot_bytes_expected);
429 fastboot_response("DATA", response, "%s", cmd_parameter);
430 }
431}
Xindong Xud9441422024-01-18 10:20:45 +0800432#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000433/**
434 * fastboot_data_remaining() - return bytes remaining in current transfer
435 *
436 * Return: Number of bytes left in the current download
437 */
438u32 fastboot_data_remaining(void)
439{
440 return fastboot_bytes_expected - fastboot_bytes_received;
441}
442
443/**
444 * fastboot_data_download() - Copy image data to fastboot_buf_addr.
445 *
446 * @fastboot_data: Pointer to received fastboot data
447 * @fastboot_data_len: Length of received fastboot data
448 * @response: Pointer to fastboot response buffer
449 *
450 * Copies image data from fastboot_data to fastboot_buf_addr. Writes to
451 * response. fastboot_bytes_received is updated to indicate the number
452 * of bytes that have been transferred.
453 *
454 * On completion sets image_size and ${filesize} to the total size of the
455 * downloaded image.
456 */
457void fastboot_data_download(const void *fastboot_data,
458 unsigned int fastboot_data_len,
459 char *response)
460{
461#define BYTES_PER_DOT 0x20000
462 u32 pre_dot_num, now_dot_num;
463
464 if (fastboot_data_len == 0 ||
465 (fastboot_bytes_received + fastboot_data_len) >
466 fastboot_bytes_expected) {
467 fastboot_fail("Received invalid data length",
468 response);
469 return;
470 }
471 /* Download data to fastboot_buf_addr */
472 memcpy(fastboot_buf_addr + fastboot_bytes_received,
473 fastboot_data, fastboot_data_len);
474
475 pre_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
476 fastboot_bytes_received += fastboot_data_len;
477 now_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
478
479 if (pre_dot_num != now_dot_num) {
480 putc('.');
481 if (!(now_dot_num % 74))
482 putc('\n');
483 }
484 *response = '\0';
485}
486
487/**
488 * fastboot_data_complete() - Mark current transfer complete
489 *
490 * @response: Pointer to fastboot response buffer
491 *
492 * Set image_size and ${filesize} to the total size of the downloaded image.
493 */
494void fastboot_data_complete(char *response)
495{
496 /* Download complete. Respond with "OKAY" */
497 fastboot_okay(NULL, response);
498 printf("\ndownloading of %d bytes finished\n", fastboot_bytes_received);
499 image_size = fastboot_bytes_received;
500 env_set_hex("filesize", image_size);
501 fastboot_bytes_expected = 0;
502 fastboot_bytes_received = 0;
503}
504
Xindong Xud9441422024-01-18 10:20:45 +0800505#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000506#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
Xindong Xud9441422024-01-18 10:20:45 +0800507
508#ifdef CONFIG_AMLOGIC_MODIFY
509static void write_dts_reserve(void)
510{
511 int ret;
512 void *addr = NULL;
513 char *mem_addr;
514
515 if (run_command("imgread dtb ${boot_part} ${dtb_mem_addr}", 0)) {
516 printf("Fail in load dtb\n");
517 } else {
518 mem_addr = env_get("dtb_mem_addr");
519
520 if (mem_addr) {
521 addr = (void *)simple_strtoul(mem_addr, NULL, 16);
522 ret = dtb_write(addr);
523 if (ret)
524 printf("write dtb error\n");
525 else
526 printf("write dtb ok\n");
527 }
528 }
529}
530
Xindong Xu0afe60a2024-05-21 16:15:13 +0800531static int clear_misc_partition(void)
532{
533 char *partition = "misc";
534 char *buffer = NULL;
535 u64 rc = 0;
536
537 rc = store_part_size(partition);
538 buffer = (char *)malloc(rc - AVB_CUSTOM_KEY_LEN_MAX);
539 if (!buffer) {
540 printf("malloc error\n");
541 return -1;
542 }
543 memset(buffer, 0, rc - AVB_CUSTOM_KEY_LEN_MAX);
544
545 store_write((const char *)partition, 0, rc - AVB_CUSTOM_KEY_LEN_MAX,
546 (unsigned char *)buffer);
547
548 free(buffer);
549
550 return 0;
551}
552
Xindong Xu22e8daf2024-03-12 18:08:41 +0800553static void set_fastboot_flag(int flag)
Xindong Xud9441422024-01-18 10:20:45 +0800554{
555 env_set("default_env", "1");
Xindong Xu22e8daf2024-03-12 18:08:41 +0800556 if (flag == 1)
557 env_set("fastboot_step", "1");
Xindong Xud9441422024-01-18 10:20:45 +0800558#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
559 run_command("update_env_part -p default_env;", 0);
Xindong Xu22e8daf2024-03-12 18:08:41 +0800560 if (flag == 1)
561 run_command("update_env_part -p fastboot_step;", 0);
Xindong Xud9441422024-01-18 10:20:45 +0800562#else
563 run_command("defenv_reserve;", 0);
564 run_command("setenv default_env 1;", 0);
Xindong Xu22e8daf2024-03-12 18:08:41 +0800565 if (flag == 1)
566 run_command("setenv fastboot_step 1;", 0);
Xindong Xud9441422024-01-18 10:20:45 +0800567 run_command("saveenv;", 0);
568#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
569}
570#endif
571
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000572/**
573 * flash() - write the downloaded image to the indicated partition.
574 *
575 * @cmd_parameter: Pointer to partition name
576 * @response: Pointer to fastboot response buffer
577 *
578 * Writes the previously downloaded image to the partition indicated by
579 * cmd_parameter. Writes to response.
580 */
581static void flash(char *cmd_parameter, char *response)
582{
Xindong Xud9441422024-01-18 10:20:45 +0800583#ifdef CONFIG_AMLOGIC_MODIFY
584 char name[32] = {0};
585 u64 rc = 0;
586 int gpt_flag = -1;
587 int ret = -1;
588
589 if (check_lock() == 1) {
590 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
591 fastboot_fail("locked device", response);
592 return;
593 }
594
595 printf("cmd_parameter: %s\n", cmd_parameter);
596
597#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
598 struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
599 if (mmc && strcmp(cmd_parameter, "bootloader") == 0) {
600 printf("try to read gpt data from bootloader.img\n");
601 struct blk_desc *dev_desc;
602 int erase_flag = 0;
Xindong Xu22e8daf2024-03-12 18:08:41 +0800603 char *bootloaderindex;
604 char *slot_name = NULL;
605 char partname[32] = {0};
Xindong Xud9441422024-01-18 10:20:45 +0800606
Zhigang Yua69e3f92024-06-18 03:13:38 +0000607 ret = update_boot_hdr_4_s7d_reva(fastboot_buf_addr, image_size, 0);
608 if (ret) {
609 printf("Failed to write s7d reva boot0\n");
610 fastboot_fail("Failed to write s7d reva boot0", response);
611 return;
612 }
613
Xindong Xu22e8daf2024-03-12 18:08:41 +0800614 slot_name = env_get("active_slot");
615 if (slot_name && (strcmp(slot_name, "_a") == 0))
616 strcpy((char *)partname, "bootloader_a");
617 else if (slot_name && (strcmp(slot_name, "_b") == 0))
618 strcpy((char *)partname, "bootloader_b");
619 else
620 strcpy((char *)partname, "bootloader_up");
621
622 rc = store_part_size(partname);
Xindong Xud9441422024-01-18 10:20:45 +0800623 if (rc != -1) {
Xindong Xu22e8daf2024-03-12 18:08:41 +0800624 fastboot_mmc_erase(partname, response);
625 fastboot_mmc_flash_write(partname, fastboot_buf_addr, image_size,
Xindong Xud9441422024-01-18 10:20:45 +0800626 response);
627 }
628
629 /* the max size of bootloader.img is 4M, we reserve 128k for gpt.bin
630 * so we put gpt.bin at offset 0x3DFE00
631 * 0 ~ 512 bootloader secure boot, we don't care it here.
632 * 512 ~ 0x3DFDFF original bootloader.img and 0
633 * 0x3DFE00 ~ end gpt.bin
634 */
635
636 dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
637 if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
638 printf("invalid mmc device\n");
639 fastboot_fail("invalid mmc device", response);
640 return;
641 }
642
643 if (is_valid_gpt_buf(dev_desc, fastboot_buf_addr + 0x3DFE00)) {
644 printf("printf normal bootloader.img, no gpt partition table\n");
645 } else {
646 printf("find gpt partition table, update it\n"
647 "and write bootloader to boot0/boot1\n");
648
649 erase_flag = check_gpt_part(dev_desc, fastboot_buf_addr + 0x3DFE00);
650
651 if (erase_flag == 1) {
652 printf("partition changes, erase emmc\n");
653 //run_command("store erase.chip 0;", 0);
654 if (usb_burn_erase_data(0x3)) {
655 printf("partition erase failed!\n");
656 return;
657 }
658 }
659
660 if (write_mbr_and_gpt_partitions(dev_desc, fastboot_buf_addr + 0x3DFE00)) {
661 printf("%s: writing GPT partitions failed\n", __func__);
662 fastboot_fail("writing GPT partitions failed", response);
663 return;
664 }
665
666 if (mmc_device_init(mmc) != 0) {
667 printf(" update gpt partition table fail\n");
668 fastboot_fail("fastboot update gpt partition fail", response);
669 return;
670 }
671 printf("%s: writing GPT partitions ok\n", __func__);
672
673 char *mem_addr;
674 void *addr = NULL;
675 int ret;
676
677 mem_addr = env_get("dtb_mem_addr");
678
679 if (mem_addr && erase_flag == 1) {
680 printf("partition changes, erase emmc\n");
681 //run_command("store erase.chip 0;", 0);
682 if (usb_burn_erase_data(0x3)) {
683 printf("partition erase failed!\n");
684 return;
685 }
686 printf("write _aml_dtb\n");
687 addr = (void *)simple_strtoul(mem_addr, NULL, 16);
688 ret = dtb_write(addr);
689 if (ret)
690 printf("write _aml_dtb error\n");
691 else
692 printf("write _aml_dtb ok\n");
693 }
694 }
695
Xindong Xu0afe60a2024-05-21 16:15:13 +0800696 ret = clear_misc_partition();
697 if (ret) {
698 printf("clear misc partition error\n");
699 fastboot_fail("clear misc partition fail", response);
700 return;
701 }
702
Xindong Xud9441422024-01-18 10:20:45 +0800703 gpt_flag = aml_gpt_valid(mmc);
704 if (gpt_flag == 0)
705 ret = 0;
706
707#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
708 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
709
710 if (*efuse_field.data == 1) {
711 wrnP("efuse_field.data == 1\n");
712 ret = 0;
713 env_set("nocs_mode", "true");
714 } else {
715 wrnP("efuse_field.data != 1\n");
716 env_set("nocs_mode", "false");
717 }
718#endif//#ifdef CONFIG_EFUSE_OBJ_API
719
Xindong Xu22e8daf2024-03-12 18:08:41 +0800720 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
721
722 if (ret == 0) {
723 printf("gpt/nocs mode\n");
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000724#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
Xindong Xu22e8daf2024-03-12 18:08:41 +0800725 fastboot_mmc_flash_write("bootloader-boot1", fastboot_buf_addr, image_size,
726 response);
727 if (strcmp(bootloaderindex, "1") != 0) {
728 printf("boot from boot1, means boot0 is error, rewrite it\n");
729 fastboot_mmc_flash_write("bootloader-boot0",
730 fastboot_buf_addr, image_size, response);
731 run_command("mmc dev 1 0;", 0);
732 set_fastboot_flag(0);
733 } else {
734 printf("need to set fastboot_step\n");
735 run_command("mmc dev 1 0;", 0);
736 set_fastboot_flag(1);
737 }
Xindong Xud9441422024-01-18 10:20:45 +0800738#endif
Xindong Xu22e8daf2024-03-12 18:08:41 +0800739 return;
740 } else {
741 printf("normal mode\n");
742#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
743 fastboot_mmc_flash_write("bootloader-boot0", fastboot_buf_addr, image_size,
744 response);
745 fastboot_mmc_flash_write("bootloader-boot1", fastboot_buf_addr, image_size,
746 response);
747 if (strcmp(bootloaderindex, "0") != 0) {
748 printf("boot from boot0, rewrite user bootloader is error\n");
749 fastboot_mmc_flash_write("bootloader",
750 fastboot_buf_addr, image_size, response);
751 run_command("mmc dev 1 0;", 0);
752 set_fastboot_flag(0);
753 } else {
754 run_command("mmc dev 1 0;", 0);
755 set_fastboot_flag(1);
756 }
757#endif
758 return;
759 }
Xindong Xud9441422024-01-18 10:20:45 +0800760 }
761#endif
762
763 if (strcmp(cmd_parameter, "avb_custom_key") == 0) {
764 char* buffer = NULL;
765 char *partition = "misc";
766 AvbKey_t key;
767 printf("avb_custom_key image_size: %d\n", image_size);
768
769 if (image_size > AVB_CUSTOM_KEY_LEN_MAX - sizeof(AvbKey_t)) {
770 printf("key size is too large\n");
771 fastboot_fail("size error", response);
772 return;
773 }
774
775 memcpy(key.magic_name, "AVBK", 4);
776 key.size = image_size;
777 rc = store_part_size(partition);
778
779 buffer = (char *)malloc(AVB_CUSTOM_KEY_LEN_MAX);
780 if (!buffer) {
781 printf("malloc error\n");
782 fastboot_fail("malloc error", response);
783 return;
784 }
785 memset(buffer, 0, AVB_CUSTOM_KEY_LEN_MAX);
786 memcpy(buffer, &key, sizeof(AvbKey_t));
787 memcpy(buffer + sizeof(AvbKey_t), fastboot_buf_addr, image_size);
788
789 store_write((const char *)partition, rc - AVB_CUSTOM_KEY_LEN_MAX,
790 AVB_CUSTOM_KEY_LEN_MAX, (unsigned char *)buffer);
791
792 fastboot_okay(NULL, response);
793 free(buffer);
794 return;
795 }
796
797 if (strcmp(cmd_parameter, "userdata") == 0 || strcmp(cmd_parameter, "data") == 0) {
798 fastboot_okay(NULL, response);
799 return;
800 } else if (strcmp(cmd_parameter, "dts") == 0) {
801 strcpy(name, "dtb");
Zhigang Yua69e3f92024-06-18 03:13:38 +0000802 } else if (!strcmp(cmd_parameter, "bootloader-boot0") ||
803 !strcmp(cmd_parameter, "bootloader-boot1")) {
804 ret = update_boot_hdr_4_s7d_reva(fastboot_buf_addr, image_size, 0);
805 if (ret) {
806 printf("Failed to write s7d reva boot0\n");
807 fastboot_fail("Failed to write s7d reva boot0-1", response);
808 return;
809 }
hao.qi278cfd32024-06-28 16:09:50 +0800810 strlcpy(name, cmd_parameter, 31);
Xindong Xud9441422024-01-18 10:20:45 +0800811 } else {
hao.qi278cfd32024-06-28 16:09:50 +0800812 strlcpy(name, cmd_parameter, 31);
Xindong Xud9441422024-01-18 10:20:45 +0800813 }
814 strcat(name, "\0");
815
816#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
817 if (dynamic_partition) {
818 if (is_partition_logical(name) == 0) {
819 printf("logic partition, can not write here.......\n");
820 fastboot_fail("logic partition", response);
821 return;
822 }
823 }
824#endif
825
826#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
827 fastboot_mmc_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000828 response);
829#endif
830#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800831 fastboot_nand_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000832 response);
833#endif
Xindong Xud9441422024-01-18 10:20:45 +0800834
835 if (strcmp(name, "bootloader") == 0) {
836 env_set("default_env", "1");
837#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
838 run_command("update_env_part -p default_env;", 0);
839#else
840 run_command("defenv_reserve;saveenv;", 0);
841#endif// #if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
842 }
843
844 if (strcmp(name, "bootloader-boot0") == 0 ||
845 strcmp(name, "bootloader-boot1") == 0) {
846 printf("try to switch back to user\n");
847 run_command("mmc dev 1 0;", 0);
848 }
849
850#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
851 if (mmc && aml_gpt_valid(mmc) == 0) {
852 if (vendor_boot_partition) {
853 if (strcmp_l1("vendor_boot", name) == 0) {
854 printf("gpt mode, write dts to reserve\n");
855 write_dts_reserve();
856 }
857 } else {
858 if (strcmp_l1("boot", name) == 0) {
859 printf("gpt mode, write dts to reserve\n");
860 write_dts_reserve();
861 }
862 }
863 }
864#endif
865
866#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000867}
868
869/**
870 * erase() - erase the indicated partition.
871 *
872 * @cmd_parameter: Pointer to partition name
873 * @response: Pointer to fastboot response buffer
874 *
875 * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
876 * to response.
877 */
878static void erase(char *cmd_parameter, char *response)
879{
Xindong Xud9441422024-01-18 10:20:45 +0800880#ifdef CONFIG_AMLOGIC_MODIFY
881 char name[32] = {0};
882 u64 rc = 0;
883
884 if (check_lock() == 1) {
885 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
886 fastboot_fail("locked device", response);
887 return;
888 }
889
890 printf("cmd_parameter: %s\n", cmd_parameter);
891
892#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
893 struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
894 if ((mmc != NULL) && strcmp(cmd_parameter, "bootloader") == 0 && (aml_gpt_valid(mmc) == 0)) {
895 printf("we write gpt partition table to bootloader now\n");
896 printf("plese write bootloader to bootloader-boot0/bootloader-boot1\n");
897 fastboot_okay("gpt mode, skip", response);
898 return;
899 }
900#endif
901
902 if (strcmp(cmd_parameter, "avb_custom_key") == 0) {
903 char* buffer = NULL;
904 char *partition = "misc";
905
906 rc = store_part_size(partition);
907 buffer = (char *)malloc(AVB_CUSTOM_KEY_LEN_MAX);
908 if (!buffer) {
909 printf("malloc error\n");
910 fastboot_fail("malloc error", response);
911 return;
912 }
913 memset(buffer, 0, AVB_CUSTOM_KEY_LEN_MAX);
914
915 store_write((const char *)partition, rc - AVB_CUSTOM_KEY_LEN_MAX,
916 AVB_CUSTOM_KEY_LEN_MAX, (unsigned char *)buffer);
917
918 fastboot_okay(NULL, response);
919 free(buffer);
920 return;
921 }
922
923 if (strcmp(cmd_parameter, "env") == 0) {
924 char *fastboot_step = env_get("fastboot_step");
925
926 if (fastboot_step && strcmp(fastboot_step, "0")) {
927 printf("fastboot_step: %s, run defenv_reserv\n", fastboot_step);
928 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
929 run_command("run bcb_cmd", 0);
930 fastboot_okay(NULL, response);
931 return;
932 }
933 }
934
935 if (strcmp(cmd_parameter, "misc") == 0) {
936 char* buffer = NULL;
937 char *partition = "misc";
938
939 rc = store_part_size(partition);
940 buffer = (char *)malloc(rc - AVB_CUSTOM_KEY_LEN_MAX);
941 if (!buffer) {
942 printf("malloc error\n");
943 fastboot_fail("malloc error", response);
944 return;
945 }
946 memset(buffer, 0, rc - AVB_CUSTOM_KEY_LEN_MAX);
947
948 store_write((const char *)partition, 0, rc - AVB_CUSTOM_KEY_LEN_MAX,
949 (unsigned char *)buffer);
950
951 fastboot_okay(NULL, response);
952 free(buffer);
953 return;
954 }
955
956 if (strcmp(cmd_parameter, "userdata") == 0 || strcmp(cmd_parameter, "data") == 0) {
957 rc = store_part_size("userdata");
958 if (-1 == rc)
959 strcpy(name, "data");
960 else
961 strcpy(name, "userdata");
962 } else if (strcmp(cmd_parameter, "dts") == 0) {
963 strcpy(name, "dtb");
964 } else {
965 strncpy(name, cmd_parameter, 31);
966 }
967 strcat(name, "\0");
968
969#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
970 if (dynamic_partition) {
971 if (is_partition_logical(name) == 0) {
972 printf("logic partition, can not erase here.......\n");
973 fastboot_fail("logic partition", response);
974 return;
975 }
976 }
977#endif
978
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000979#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
Xindong Xud9441422024-01-18 10:20:45 +0800980 fastboot_mmc_erase(name, response);
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000981#endif
982#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800983 fastboot_nand_erase(name, response);
984#endif
985
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000986#endif
987}
988#endif
Xindong Xud9441422024-01-18 10:20:45 +0800989#endif
990
991#ifdef CONFIG_FASTBOOT_WRITING_CMD
992
993#ifdef CONFIG_AMLOGIC_MODIFY
994static u64 my_ato11(const char *str)
995{
996 u64 result = 0;
997 int len, i;
998
999 len = strlen(str);
1000 for (i = 0; i < len; i++) {
1001 if (*str >= '0' && *str <= '9')
1002 result = result * 16 + (*str - '0');
1003 else if (*str >= 'A' && *str <= 'F')
1004 result = result * 16 + (*str - 'A') + 10;
1005 else if (*str >= 'a' && *str <= 'f')
1006 result = result * 16 + (*str - 'a') + 10;
1007 str++;
1008 }
1009
1010 return result;
1011}
1012
1013static void fetch(char *cmd_parameter, char *response)
1014{
1015 int len;
1016 int i = 0;
1017 char *cmd;
1018 char name[32] = {0};
1019 u64 offset = 0;
1020 u64 read_size = 0;
1021 size_t size = 0;
1022
1023 if (check_lock() == 1) {
1024 printf("device is locked, can not run this cmd\n");
1025 fastboot_fail("locked device", response);
1026 return;
1027 }
1028
1029 cmd = cmd_parameter;
1030 len = strlen(cmd_parameter);
1031 while (strsep(&cmd, ":"))
1032 i++;
1033
1034 for (cmd = cmd_parameter, i = 0; cmd < (cmd_parameter + len); i++) {
1035 /* Skip to next assignment */
1036 if (i == 0) {
1037 strncpy(name, cmd, 31);
1038 strcat(name, "\0");
1039 } else if (i == 1) {
1040 offset = my_ato11(cmd);
1041 } else if (i == 2) {
1042 read_size = my_ato11(cmd);
1043 }
1044
1045 for (cmd += strlen(cmd); cmd < (cmd_parameter + len) && !*cmd;)
1046 cmd++;
1047 }
1048
1049 printf("name: %s\n", name);
1050 if (strncmp("vendor_boot", name, strlen("vendor_boot")) != 0) {
1051 printf("We can only %s vendor_boot\n", __func__);
1052 fastboot_fail("Fetch is only allowed on vendor_boot", response);
1053 return;
1054 }
1055
1056#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
1057 struct blk_desc *dev_desc;
1058 disk_partition_t part_info;
1059 int r;
1060
1061 r = fastboot_mmc_get_part_info(name, &dev_desc, &part_info,
1062 response);
1063 if (r >= 0)
1064 size = part_info.size * 512;
1065#endif
1066#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
1067 struct part_info *part_info;
1068 int r;
1069
1070 r = fastboot_nand_get_part_info(name, &part_info, response);
1071 if (r >= 0)
1072 size = part_info->size * 512;
1073#endif
1074
1075 if (offset > size) {
1076 printf("Invalid offset: 0x%llx, partition size is 0x%lx\n",
1077 offset, size);
1078 fastboot_fail("Invalid offset", response);
1079 return;
1080 }
1081
1082 if (read_size == 0 || read_size > size - offset ||
1083 read_size > kMaxFetchSizeDefault) {
1084 printf("Invalid read size: 0x%llx, partition size is 0x%lx\n",
1085 offset, size);
1086 fastboot_fail("Invalid read size", response);
1087 return;
1088 }
1089
1090 printf("Start read %s partition datas!\n", name);
1091 void *buffer;
1092 char str[128] = {0};
1093
1094 buffer = (void *)CONFIG_FASTBOOT_BUF_ADDR;
1095 sprintf(str, "DATA%12llx", read_size);
1096 printf("str: %s, len: %ld\n", str, strlen(str));
1097 memcpy(buffer, str, strlen(str));
1098
1099 if (store_read((const char *)name, offset, read_size,
1100 (unsigned char *)buffer + strlen(str)) < 0) {
1101 printf("failed to store read %s.\n", name);
1102 fastboot_fail("read partition data error", response);
1103 return;
1104 }
1105
1106 fastboot_readInfo.transferredBytes = 0;
1107 fastboot_readInfo.totalBytes = read_size + strlen(str);
1108 fastboot_response("DATA", response, "%12llx", read_size);
1109}
1110
1111static void set_active_cmd(char *cmd_parameter, char *response)
1112{
1113 char *cmd;
1114 int ret = 0;
1115 char str[128];
1116
1117 printf("cmd cb_set_active is %s\n", cmd_parameter);
1118 cmd = cmd_parameter;
1119
1120 if (check_lock() == 1) {
1121 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1122 fastboot_fail("locked device", response);
1123 return;
1124 }
1125
1126 sprintf(str, "set_active_slot %s", cmd);
1127 printf("command: %s\n", str);
1128 ret = run_command(str, 0);
1129 printf("ret = %d\n", ret);
1130 if (ret == 0)
1131 fastboot_okay(NULL, response);
1132 else
1133 fastboot_fail("set slot error", response);
1134}
1135
1136#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
1137static void try_unlock_dev(u64 rc)
1138{
1139#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1140 if (is_avb_arb_available()) {
1141 if (avb_unlock()) {
1142 if (-1 == rc) {
1143 printf("unlocking device. Erasing data partition!\n");
1144 run_command("store erase data 0 0", 0);
1145 } else {
1146 printf("unlocking device. Erasing userdata partition!\n");
1147 run_command("store erase userdata 0 0", 0);
1148 }
1149 printf("unlocking device. Erasing metadata partition!\n");
1150 run_command("store erase metadata 0 0", 0);
1151 } else {
1152 printf("unlock failed!\n");
1153 }
1154
1155 return;
1156 }
1157#endif
1158 if (-1 == rc) {
1159 printf("unlocking device. Erasing data partition!\n");
1160 run_command("store erase data 0 0", 0);
1161 } else {
1162 printf("unlocking device. Erasing userdata partition!\n");
1163 run_command("store erase userdata 0 0", 0);
1164 }
1165 printf("unlocking device. Erasing metadata partition!\n");
1166 run_command("store erase metadata 0 0", 0);
1167}
1168
1169static void try_lock_dev(u64 rc)
1170{
1171#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1172 if (is_avb_arb_available()) {
1173 if (avb_lock()) {
1174 if (-1 == rc) {
1175 printf("locking device. Erasing data partition!\n");
1176 run_command("store erase data 0 0", 0);
1177 } else {
1178 printf("locking device. Erasing userdata partition!\n");
1179 run_command("store erase userdata 0 0", 0);
1180 }
1181 printf("locking device. Erasing metadata partition!\n");
1182 run_command("store erase metadata 0 0", 0);
1183 } else {
1184 printf("lock failed!\n");
1185 }
1186
1187 return;
1188 }
1189#endif
1190 if (-1 == rc) {
1191 printf("locking device. Erasing data partition!\n");
1192 run_command("store erase data 0 0", 0);
1193 } else {
1194 printf("locking device. Erasing userdata partition!\n");
1195 run_command("store erase userdata 0 0", 0);
1196 }
1197 printf("locking device. Erasing metadata partition!\n");
1198 run_command("store erase metadata 0 0", 0);
1199}
1200
1201/**
1202 * flashing() - lock/unlock.
1203 *
1204 * @cmd_parameter: Pointer to partition name
1205 * @response: Pointer to fastboot response buffer
1206 *
1207 * Writes the previously downloaded image to the partition indicated by
1208 * cmd_parameter. Writes to response.
1209 */
1210static void flashing(char *cmd_parameter, char *response)
1211{
1212 char *cmd;
1213 char* lock_s;
1214 LockData_t info = {0};
1215 char lock_d[LOCK_DATA_SIZE];
1216 u64 rc;
1217 int debug_flag = 0;
1218
1219 if (IS_FEAT_BOOT_VERIFY()) {
1220 printf("device is secure mode, can not run this cmd.\n");
1221 fastboot_fail("secure boot device", response);
1222 return;
1223 }
1224
1225 lock_s = env_get("lock");
1226 if (!lock_s) {
1227 printf("lock state is NULL \n");
1228 memcpy(lock_d, "10101000", 8);
1229 lock_s = "10101000";
1230 env_set("lock", "10101000");
1231#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1232 run_command("update_env_part -p lock;", 0);
1233#else
1234 run_command("defenv_reserv; saveenv;", 0);
1235#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1236 } else {
1237 printf("lock state: %s\n", lock_s);
1238 if (strlen(lock_s) > 15)
1239 strncpy(lock_d, lock_s, 15);
1240 else
1241 strncpy(lock_d, lock_s, strlen(lock_s));
1242 }
1243
1244 info.version_major = (int)(lock_d[0] - '0');
1245 info.version_minor = (int)(lock_d[1] - '0');
1246 info.unlock_ability = (int)(lock_d[2] - '0');
1247 info.lock_state = (int)(lock_d[4] - '0');
1248 info.lock_critical_state = (int)(lock_d[5] - '0');
1249 info.lock_bootloader = (int)(lock_d[6] - '0');
1250 dump_lock_info(info);
1251
1252 printf("cb_flashing cmd_parameter: %s\n", cmd_parameter);
1253 cmd = cmd_parameter;
1254 strsep(&cmd, " ");
1255 printf("cb_flashing: %s\n", cmd);
1256 if (!cmd) {
1257 printf("missing variable\n");
1258 fastboot_fail("missing var", response);
1259 return;
1260 }
1261
1262 boot_img_hdr_t *hdr_addr = NULL;
1263 const int preloadsz = 0x1000 * 2;//4k not enough for signed
1264 unsigned char *pbuffpreload = 0;
1265 char partname[32] = {0};
1266 char *slot_name;
1267 char cmdline[4096];
1268 char *result = NULL;
1269
1270 slot_name = env_get("slot-suffixes");
1271 if (slot_name && (strcmp(slot_name, "0") == 0))
1272 strcpy((char *)partname, "boot_a");
1273 else if (slot_name && (strcmp(slot_name, "1") == 0))
1274 strcpy((char *)partname, "boot_b");
1275 else
1276 strcpy((char *)partname, "boot");
1277
1278 pbuffpreload = malloc(preloadsz);
1279 if (!pbuffpreload) {
1280 printf("Fail to allocate memory!\n");
1281 goto next;
1282 }
1283
1284 hdr_addr = (boot_img_hdr_t *)pbuffpreload;
1285
1286 printf("read from part: %s\n", partname);
1287 rc = store_logic_read(partname, 0, preloadsz, pbuffpreload);
1288 if (rc) {
1289 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1290 preloadsz, partname);
1291 free(pbuffpreload);
1292 pbuffpreload = 0;
1293 goto next;
1294 }
1295
1296 if (is_android_r_image((void *)hdr_addr)) {
1297 char partname_r[32] = {0};
1298 const int preloadsz_r = 0x1000 * 2;//4k not enough for signed
1299 unsigned char *pbuffpreload_r = 0;
1300 int ret_r = __LINE__;
1301
1302 if (slot_name && (strcmp(slot_name, "0") == 0))
1303 strcpy((char *)partname_r, "vendor_boot_a");
1304 else if (slot_name && (strcmp(slot_name, "1") == 0))
1305 strcpy((char *)partname_r, "vendor_boot_b");
1306 else
1307 strcpy((char *)partname_r, "vendor_boot");
1308
1309 pbuffpreload_r = malloc(preloadsz_r);
1310
1311 if (!pbuffpreload_r) {
1312 printf("Fail to allocate memory for %s!\n",
1313 partname_r);
1314 goto next;
1315 }
1316
1317 printf("read from part: %s\n", partname_r);
1318 ret_r = store_logic_read(partname_r, 0,
1319 preloadsz_r, pbuffpreload_r);
1320 if (ret_r) {
1321 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1322 preloadsz_r, partname_r);
1323 free(pbuffpreload_r);
1324 pbuffpreload_r = 0;
1325 goto next;
1326 }
1327
1328 p_vendor_boot_img_hdr_t vb_hdr = (p_vendor_boot_img_hdr_t)pbuffpreload_r;
1329
1330 if (*vb_hdr->cmdline) {
1331 printf("Kernel command line: %s\n", vb_hdr->cmdline);
1332 sprintf(cmdline, "%s", vb_hdr->cmdline);
1333 }
1334 free(pbuffpreload_r);
1335 pbuffpreload_r = 0;
1336 } else {
1337 if (*hdr_addr->cmdline) {
1338 printf("Kernel command line: %s\n", hdr_addr->cmdline);
1339 sprintf(cmdline, "%s", hdr_addr->cmdline);
1340 }
1341 }
1342
1343 free(pbuffpreload);
1344 pbuffpreload = 0;
1345
1346 result = strtok(cmdline, " ");
1347 while (result) {
1348 printf("result: %s\n", result);
1349 if (strcmp(result, "buildvariant=userdebug") == 0 ||
1350 strcmp(result, "buildvariant=eng") == 0)
1351 debug_flag = 1;
1352 result = strtok(NULL, " ");
1353 }
1354
1355 if (info.unlock_ability == 0 && debug_flag == 1) {
1356 printf("userdebug mode can ignore\n");
1357 info.unlock_ability = 1;
1358 }
1359
1360next:
1361 rc = store_part_size("userdata");
1362
1363 if (!strcmp_l1("unlock_critical", cmd)) {
1364 info.lock_critical_state = 0;
1365 fastboot_okay(NULL, response);
1366 } else if (!strcmp_l1("lock_critical", cmd)) {
1367 info.lock_critical_state = 1;
1368 fastboot_okay(NULL, response);
1369 } else if (!strcmp_l1("get_unlock_ability", cmd)) {
1370 char str[32];
1371 static bool is_unlock_ability_sent = false;
1372 if (is_unlock_ability_sent) {
1373 is_unlock_ability_sent = false;
1374 fastboot_okay(NULL, response);
1375 busy_flag = 0;
1376 } else {
1377 sprintf(str, "get_unlock_ability: %d",
1378 info.unlock_ability);
1379 fastboot_response("INFO", response, "%s", str);
1380 is_unlock_ability_sent = true;
1381 busy_flag = 1;
1382 }
1383 return;
1384 } else if (!strcmp_l1("get_unlock_bootloader_nonce", cmd)) {
1385 char str_num[8];
1386 sprintf(str_num, "%d", info.lock_critical_state);
1387 fastboot_response("OKAY", response, "%s", str_num);
1388 } else if (!strcmp_l1("lock_bootloader", cmd)) {
1389 info.lock_bootloader = 1;
1390 } else if (!strcmp_l1("unlock", cmd)) {
hao.qi40c37a02024-07-15 13:40:47 +08001391#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
hao.qi0696a542024-09-12 14:58:03 +08001392 u32 rpmb_lock_state = 0;
1393 bool ret = get_avb_lock_state(&rpmb_lock_state);
hao.qi40c37a02024-07-15 13:40:47 +08001394
hao.qi0696a542024-09-12 14:58:03 +08001395 if (info.lock_state == 1 || (ret && rpmb_lock_state == 1)) {
hao.qi40c37a02024-07-15 13:40:47 +08001396#else
hao.qi0696a542024-09-12 14:58:03 +08001397 if (info.lock_state == 1) {
hao.qi40c37a02024-07-15 13:40:47 +08001398#endif
hao.qi0696a542024-09-12 14:58:03 +08001399 char *avb_s;
Xindong Xud9441422024-01-18 10:20:45 +08001400
hao.qi0696a542024-09-12 14:58:03 +08001401 run_command("get_avb_mode;", 0);
1402 avb_s = env_get("avb2");
1403 printf("avb2: %s\n", avb_s);
1404 if (strcmp(avb_s, "1") == 0)
1405 try_unlock_dev(rc);
Xindong Xud9441422024-01-18 10:20:45 +08001406 }
hao.qi0696a542024-09-12 14:58:03 +08001407 info.lock_state = 0;
1408 info.lock_critical_state = 0;
1409 env_set("lock_state", "green");
1410 fastboot_okay(NULL, response);
Xindong Xud9441422024-01-18 10:20:45 +08001411 } else if (!strcmp_l1("lock", cmd)) {
hao.qi40c37a02024-07-15 13:40:47 +08001412#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1413 u32 rpmb_lock_state = 0;
1414 bool ret = get_avb_lock_state(&rpmb_lock_state);
1415
1416 if (info.lock_state == 0 || (ret && rpmb_lock_state == 0)) {
1417#else
Xindong Xud9441422024-01-18 10:20:45 +08001418 if (info.lock_state == 0) {
hao.qi40c37a02024-07-15 13:40:47 +08001419#endif
Xindong Xud9441422024-01-18 10:20:45 +08001420 char *avb_s;
1421
1422 run_command("get_avb_mode;", 0);
1423 avb_s = env_get("avb2");
1424 printf("avb2: %s\n", avb_s);
1425 if (strcmp(avb_s, "1") == 0) {
1426 try_lock_dev(rc);
1427 }
1428 }
1429 info.lock_state = 1;
1430 env_set("lock_state", "orange");
1431 fastboot_okay(NULL, response);
1432 } else {
1433 printf("unknown variable: %s\n", cmd);
1434 fastboot_response("FAIL", response, "%s", "Variable not implemented");
1435 }
1436
1437 sprintf(lock_d, "%d%d%d0%d%d%d0", info.version_major, info.version_minor,
1438 info.unlock_ability, info.lock_state, info.lock_critical_state,
1439 info.lock_bootloader);
1440 printf("lock_d state: %s\n", lock_d);
1441 env_set("lock", lock_d);
1442#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1443 run_command("update_env_part -p lock;", 0);
1444#else
1445 run_command("defenv_reserv; saveenv;", 0);
1446#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1447 return;
1448}
1449#endif// #if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
1450#endif
1451#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001452
Heiko Schocherbc820d52021-02-10 09:29:03 +01001453#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
1454/**
1455 * run_ucmd() - Execute the UCmd command
1456 *
1457 * @cmd_parameter: Pointer to command parameter
1458 * @response: Pointer to fastboot response buffer
1459 */
1460static void run_ucmd(char *cmd_parameter, char *response)
1461{
1462 if (!cmd_parameter) {
1463 pr_err("missing slot suffix\n");
1464 fastboot_fail("missing command", response);
1465 return;
1466 }
1467
1468 if (run_command(cmd_parameter, 0))
1469 fastboot_fail("", response);
1470 else
1471 fastboot_okay(NULL, response);
1472}
1473
1474static char g_a_cmd_buff[64];
1475
1476void fastboot_acmd_complete(void)
1477{
1478 run_command(g_a_cmd_buff, 0);
1479}
1480
1481/**
1482 * run_acmd() - Execute the ACmd command
1483 *
1484 * @cmd_parameter: Pointer to command parameter
1485 * @response: Pointer to fastboot response buffer
1486 */
1487static void run_acmd(char *cmd_parameter, char *response)
1488{
1489 if (!cmd_parameter) {
1490 pr_err("missing slot suffix\n");
1491 fastboot_fail("missing command", response);
1492 return;
1493 }
1494
1495 if (strlen(cmd_parameter) > sizeof(g_a_cmd_buff)) {
1496 pr_err("too long command\n");
1497 fastboot_fail("too long command", response);
1498 return;
1499 }
1500
1501 strcpy(g_a_cmd_buff, cmd_parameter);
1502 fastboot_okay(NULL, response);
1503}
1504#endif
1505
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001506/**
1507 * reboot_bootloader() - Sets reboot bootloader flag.
1508 *
1509 * @cmd_parameter: Pointer to command parameter
1510 * @response: Pointer to fastboot response buffer
1511 */
1512static void reboot_bootloader(char *cmd_parameter, char *response)
1513{
Xindong Xud9441422024-01-18 10:20:45 +08001514#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi851737a2020-07-28 23:35:32 +03001515 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_BOOTLOADER))
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001516 fastboot_fail("Cannot set reboot flag", response);
1517 else
Xindong Xud9441422024-01-18 10:20:45 +08001518#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001519 fastboot_okay(NULL, response);
1520}
Alex Kiernan3845b902018-05-29 15:30:54 +00001521
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001522/**
1523 * reboot_fastbootd() - Sets reboot fastboot flag.
1524 *
1525 * @cmd_parameter: Pointer to command parameter
1526 * @response: Pointer to fastboot response buffer
1527 */
1528static void reboot_fastbootd(char *cmd_parameter, char *response)
1529{
Xindong Xud9441422024-01-18 10:20:45 +08001530#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001531 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_FASTBOOTD))
Xindong Xud9441422024-01-18 10:20:45 +08001532 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001533 else
Xindong Xud9441422024-01-18 10:20:45 +08001534#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001535 fastboot_okay(NULL, response);
1536}
1537
1538/**
1539 * reboot_recovery() - Sets reboot recovery flag.
1540 *
1541 * @cmd_parameter: Pointer to command parameter
1542 * @response: Pointer to fastboot response buffer
1543 */
1544static void reboot_recovery(char *cmd_parameter, char *response)
1545{
Xindong Xud9441422024-01-18 10:20:45 +08001546#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001547 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_RECOVERY))
Xindong Xud9441422024-01-18 10:20:45 +08001548 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001549 else
Xindong Xud9441422024-01-18 10:20:45 +08001550#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001551 fastboot_okay(NULL, response);
1552}
1553
Xindong Xud9441422024-01-18 10:20:45 +08001554#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernan3845b902018-05-29 15:30:54 +00001555#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
1556/**
1557 * oem_format() - Execute the OEM format command
1558 *
1559 * @cmd_parameter: Pointer to command parameter
1560 * @response: Pointer to fastboot response buffer
1561 */
1562static void oem_format(char *cmd_parameter, char *response)
1563{
1564 char cmdbuf[32];
1565
Xindong Xud9441422024-01-18 10:20:45 +08001566#ifdef CONFIG_AMLOGIC_MODIFY
1567 if (IS_FEAT_BOOT_VERIFY()) {
1568 printf("device is secure mode, can not run this cmd.\n");
1569 fastboot_fail("secure boot device", response);
1570 return;
1571 }
1572
1573 if (check_lock() == 1) {
1574 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1575 fastboot_fail("locked device", response);
1576 return;
1577 }
1578#endif
1579
Alex Kiernan3845b902018-05-29 15:30:54 +00001580 if (!env_get("partitions")) {
1581 fastboot_fail("partitions not set", response);
1582 } else {
1583 sprintf(cmdbuf, "gpt write mmc %x $partitions",
1584 CONFIG_FASTBOOT_FLASH_MMC_DEV);
1585 if (run_command(cmdbuf, 0))
1586 fastboot_fail("", response);
1587 else
1588 fastboot_okay(NULL, response);
1589 }
1590}
1591#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +01001592
1593#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
1594/**
1595 * oem_partconf() - Execute the OEM partconf command
1596 *
1597 * @cmd_parameter: Pointer to command parameter
1598 * @response: Pointer to fastboot response buffer
1599 */
1600static void oem_partconf(char *cmd_parameter, char *response)
1601{
1602 char cmdbuf[32];
1603
1604 if (!cmd_parameter) {
1605 fastboot_fail("Expected command parameter", response);
1606 return;
1607 }
1608
1609 /* execute 'mmc partconfg' command with cmd_parameter arguments*/
1610 snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0",
1611 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1612 printf("Execute: %s\n", cmdbuf);
1613 if (run_command(cmdbuf, 0))
1614 fastboot_fail("Cannot set oem partconf", response);
1615 else
1616 fastboot_okay(NULL, response);
1617}
1618#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +01001619
1620#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
1621/**
1622 * oem_bootbus() - Execute the OEM bootbus command
1623 *
1624 * @cmd_parameter: Pointer to command parameter
1625 * @response: Pointer to fastboot response buffer
1626 */
1627static void oem_bootbus(char *cmd_parameter, char *response)
1628{
1629 char cmdbuf[32];
1630
1631 if (!cmd_parameter) {
1632 fastboot_fail("Expected command parameter", response);
1633 return;
1634 }
1635
1636 /* execute 'mmc bootbus' command with cmd_parameter arguments*/
1637 snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s",
1638 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1639 printf("Execute: %s\n", cmdbuf);
1640 if (run_command(cmdbuf, 0))
1641 fastboot_fail("Cannot set oem bootbus", response);
1642 else
1643 fastboot_okay(NULL, response);
1644}
1645#endif
Xindong Xud9441422024-01-18 10:20:45 +08001646#endif