blob: d526915f29cc0080fd568fed5dcd8adc899dfdd4 [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 }
Xindong Xud9441422024-01-18 10:20:45 +0800810 } else {
811 strncpy(name, cmd_parameter, 31);
812 }
813 strcat(name, "\0");
814
815#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
816 if (dynamic_partition) {
817 if (is_partition_logical(name) == 0) {
818 printf("logic partition, can not write here.......\n");
819 fastboot_fail("logic partition", response);
820 return;
821 }
822 }
823#endif
824
825#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
826 fastboot_mmc_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000827 response);
828#endif
829#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800830 fastboot_nand_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000831 response);
832#endif
Xindong Xud9441422024-01-18 10:20:45 +0800833
834 if (strcmp(name, "bootloader") == 0) {
835 env_set("default_env", "1");
836#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
837 run_command("update_env_part -p default_env;", 0);
838#else
839 run_command("defenv_reserve;saveenv;", 0);
840#endif// #if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
841 }
842
843 if (strcmp(name, "bootloader-boot0") == 0 ||
844 strcmp(name, "bootloader-boot1") == 0) {
845 printf("try to switch back to user\n");
846 run_command("mmc dev 1 0;", 0);
847 }
848
849#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
850 if (mmc && aml_gpt_valid(mmc) == 0) {
851 if (vendor_boot_partition) {
852 if (strcmp_l1("vendor_boot", name) == 0) {
853 printf("gpt mode, write dts to reserve\n");
854 write_dts_reserve();
855 }
856 } else {
857 if (strcmp_l1("boot", name) == 0) {
858 printf("gpt mode, write dts to reserve\n");
859 write_dts_reserve();
860 }
861 }
862 }
863#endif
864
865#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000866}
867
868/**
869 * erase() - erase the indicated partition.
870 *
871 * @cmd_parameter: Pointer to partition name
872 * @response: Pointer to fastboot response buffer
873 *
874 * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
875 * to response.
876 */
877static void erase(char *cmd_parameter, char *response)
878{
Xindong Xud9441422024-01-18 10:20:45 +0800879#ifdef CONFIG_AMLOGIC_MODIFY
880 char name[32] = {0};
881 u64 rc = 0;
882
883 if (check_lock() == 1) {
884 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
885 fastboot_fail("locked device", response);
886 return;
887 }
888
889 printf("cmd_parameter: %s\n", cmd_parameter);
890
891#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
892 struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
893 if ((mmc != NULL) && strcmp(cmd_parameter, "bootloader") == 0 && (aml_gpt_valid(mmc) == 0)) {
894 printf("we write gpt partition table to bootloader now\n");
895 printf("plese write bootloader to bootloader-boot0/bootloader-boot1\n");
896 fastboot_okay("gpt mode, skip", response);
897 return;
898 }
899#endif
900
901 if (strcmp(cmd_parameter, "avb_custom_key") == 0) {
902 char* buffer = NULL;
903 char *partition = "misc";
904
905 rc = store_part_size(partition);
906 buffer = (char *)malloc(AVB_CUSTOM_KEY_LEN_MAX);
907 if (!buffer) {
908 printf("malloc error\n");
909 fastboot_fail("malloc error", response);
910 return;
911 }
912 memset(buffer, 0, AVB_CUSTOM_KEY_LEN_MAX);
913
914 store_write((const char *)partition, rc - AVB_CUSTOM_KEY_LEN_MAX,
915 AVB_CUSTOM_KEY_LEN_MAX, (unsigned char *)buffer);
916
917 fastboot_okay(NULL, response);
918 free(buffer);
919 return;
920 }
921
922 if (strcmp(cmd_parameter, "env") == 0) {
923 char *fastboot_step = env_get("fastboot_step");
924
925 if (fastboot_step && strcmp(fastboot_step, "0")) {
926 printf("fastboot_step: %s, run defenv_reserv\n", fastboot_step);
927 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
928 run_command("run bcb_cmd", 0);
929 fastboot_okay(NULL, response);
930 return;
931 }
932 }
933
934 if (strcmp(cmd_parameter, "misc") == 0) {
935 char* buffer = NULL;
936 char *partition = "misc";
937
938 rc = store_part_size(partition);
939 buffer = (char *)malloc(rc - AVB_CUSTOM_KEY_LEN_MAX);
940 if (!buffer) {
941 printf("malloc error\n");
942 fastboot_fail("malloc error", response);
943 return;
944 }
945 memset(buffer, 0, rc - AVB_CUSTOM_KEY_LEN_MAX);
946
947 store_write((const char *)partition, 0, rc - AVB_CUSTOM_KEY_LEN_MAX,
948 (unsigned char *)buffer);
949
950 fastboot_okay(NULL, response);
951 free(buffer);
952 return;
953 }
954
955 if (strcmp(cmd_parameter, "userdata") == 0 || strcmp(cmd_parameter, "data") == 0) {
956 rc = store_part_size("userdata");
957 if (-1 == rc)
958 strcpy(name, "data");
959 else
960 strcpy(name, "userdata");
961 } else if (strcmp(cmd_parameter, "dts") == 0) {
962 strcpy(name, "dtb");
963 } else {
964 strncpy(name, cmd_parameter, 31);
965 }
966 strcat(name, "\0");
967
968#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
969 if (dynamic_partition) {
970 if (is_partition_logical(name) == 0) {
971 printf("logic partition, can not erase here.......\n");
972 fastboot_fail("logic partition", response);
973 return;
974 }
975 }
976#endif
977
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000978#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
Xindong Xud9441422024-01-18 10:20:45 +0800979 fastboot_mmc_erase(name, response);
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000980#endif
981#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800982 fastboot_nand_erase(name, response);
983#endif
984
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000985#endif
986}
987#endif
Xindong Xud9441422024-01-18 10:20:45 +0800988#endif
989
990#ifdef CONFIG_FASTBOOT_WRITING_CMD
991
992#ifdef CONFIG_AMLOGIC_MODIFY
993static u64 my_ato11(const char *str)
994{
995 u64 result = 0;
996 int len, i;
997
998 len = strlen(str);
999 for (i = 0; i < len; i++) {
1000 if (*str >= '0' && *str <= '9')
1001 result = result * 16 + (*str - '0');
1002 else if (*str >= 'A' && *str <= 'F')
1003 result = result * 16 + (*str - 'A') + 10;
1004 else if (*str >= 'a' && *str <= 'f')
1005 result = result * 16 + (*str - 'a') + 10;
1006 str++;
1007 }
1008
1009 return result;
1010}
1011
1012static void fetch(char *cmd_parameter, char *response)
1013{
1014 int len;
1015 int i = 0;
1016 char *cmd;
1017 char name[32] = {0};
1018 u64 offset = 0;
1019 u64 read_size = 0;
1020 size_t size = 0;
1021
1022 if (check_lock() == 1) {
1023 printf("device is locked, can not run this cmd\n");
1024 fastboot_fail("locked device", response);
1025 return;
1026 }
1027
1028 cmd = cmd_parameter;
1029 len = strlen(cmd_parameter);
1030 while (strsep(&cmd, ":"))
1031 i++;
1032
1033 for (cmd = cmd_parameter, i = 0; cmd < (cmd_parameter + len); i++) {
1034 /* Skip to next assignment */
1035 if (i == 0) {
1036 strncpy(name, cmd, 31);
1037 strcat(name, "\0");
1038 } else if (i == 1) {
1039 offset = my_ato11(cmd);
1040 } else if (i == 2) {
1041 read_size = my_ato11(cmd);
1042 }
1043
1044 for (cmd += strlen(cmd); cmd < (cmd_parameter + len) && !*cmd;)
1045 cmd++;
1046 }
1047
1048 printf("name: %s\n", name);
1049 if (strncmp("vendor_boot", name, strlen("vendor_boot")) != 0) {
1050 printf("We can only %s vendor_boot\n", __func__);
1051 fastboot_fail("Fetch is only allowed on vendor_boot", response);
1052 return;
1053 }
1054
1055#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
1056 struct blk_desc *dev_desc;
1057 disk_partition_t part_info;
1058 int r;
1059
1060 r = fastboot_mmc_get_part_info(name, &dev_desc, &part_info,
1061 response);
1062 if (r >= 0)
1063 size = part_info.size * 512;
1064#endif
1065#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
1066 struct part_info *part_info;
1067 int r;
1068
1069 r = fastboot_nand_get_part_info(name, &part_info, response);
1070 if (r >= 0)
1071 size = part_info->size * 512;
1072#endif
1073
1074 if (offset > size) {
1075 printf("Invalid offset: 0x%llx, partition size is 0x%lx\n",
1076 offset, size);
1077 fastboot_fail("Invalid offset", response);
1078 return;
1079 }
1080
1081 if (read_size == 0 || read_size > size - offset ||
1082 read_size > kMaxFetchSizeDefault) {
1083 printf("Invalid read size: 0x%llx, partition size is 0x%lx\n",
1084 offset, size);
1085 fastboot_fail("Invalid read size", response);
1086 return;
1087 }
1088
1089 printf("Start read %s partition datas!\n", name);
1090 void *buffer;
1091 char str[128] = {0};
1092
1093 buffer = (void *)CONFIG_FASTBOOT_BUF_ADDR;
1094 sprintf(str, "DATA%12llx", read_size);
1095 printf("str: %s, len: %ld\n", str, strlen(str));
1096 memcpy(buffer, str, strlen(str));
1097
1098 if (store_read((const char *)name, offset, read_size,
1099 (unsigned char *)buffer + strlen(str)) < 0) {
1100 printf("failed to store read %s.\n", name);
1101 fastboot_fail("read partition data error", response);
1102 return;
1103 }
1104
1105 fastboot_readInfo.transferredBytes = 0;
1106 fastboot_readInfo.totalBytes = read_size + strlen(str);
1107 fastboot_response("DATA", response, "%12llx", read_size);
1108}
1109
1110static void set_active_cmd(char *cmd_parameter, char *response)
1111{
1112 char *cmd;
1113 int ret = 0;
1114 char str[128];
1115
1116 printf("cmd cb_set_active is %s\n", cmd_parameter);
1117 cmd = cmd_parameter;
1118
1119 if (check_lock() == 1) {
1120 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1121 fastboot_fail("locked device", response);
1122 return;
1123 }
1124
1125 sprintf(str, "set_active_slot %s", cmd);
1126 printf("command: %s\n", str);
1127 ret = run_command(str, 0);
1128 printf("ret = %d\n", ret);
1129 if (ret == 0)
1130 fastboot_okay(NULL, response);
1131 else
1132 fastboot_fail("set slot error", response);
1133}
1134
1135#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
1136static void try_unlock_dev(u64 rc)
1137{
1138#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1139 if (is_avb_arb_available()) {
1140 if (avb_unlock()) {
1141 if (-1 == rc) {
1142 printf("unlocking device. Erasing data partition!\n");
1143 run_command("store erase data 0 0", 0);
1144 } else {
1145 printf("unlocking device. Erasing userdata partition!\n");
1146 run_command("store erase userdata 0 0", 0);
1147 }
1148 printf("unlocking device. Erasing metadata partition!\n");
1149 run_command("store erase metadata 0 0", 0);
1150 } else {
1151 printf("unlock failed!\n");
1152 }
1153
1154 return;
1155 }
1156#endif
1157 if (-1 == rc) {
1158 printf("unlocking device. Erasing data partition!\n");
1159 run_command("store erase data 0 0", 0);
1160 } else {
1161 printf("unlocking device. Erasing userdata partition!\n");
1162 run_command("store erase userdata 0 0", 0);
1163 }
1164 printf("unlocking device. Erasing metadata partition!\n");
1165 run_command("store erase metadata 0 0", 0);
1166}
1167
1168static void try_lock_dev(u64 rc)
1169{
1170#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1171 if (is_avb_arb_available()) {
1172 if (avb_lock()) {
1173 if (-1 == rc) {
1174 printf("locking device. Erasing data partition!\n");
1175 run_command("store erase data 0 0", 0);
1176 } else {
1177 printf("locking device. Erasing userdata partition!\n");
1178 run_command("store erase userdata 0 0", 0);
1179 }
1180 printf("locking device. Erasing metadata partition!\n");
1181 run_command("store erase metadata 0 0", 0);
1182 } else {
1183 printf("lock failed!\n");
1184 }
1185
1186 return;
1187 }
1188#endif
1189 if (-1 == rc) {
1190 printf("locking device. Erasing data partition!\n");
1191 run_command("store erase data 0 0", 0);
1192 } else {
1193 printf("locking device. Erasing userdata partition!\n");
1194 run_command("store erase userdata 0 0", 0);
1195 }
1196 printf("locking device. Erasing metadata partition!\n");
1197 run_command("store erase metadata 0 0", 0);
1198}
1199
1200/**
1201 * flashing() - lock/unlock.
1202 *
1203 * @cmd_parameter: Pointer to partition name
1204 * @response: Pointer to fastboot response buffer
1205 *
1206 * Writes the previously downloaded image to the partition indicated by
1207 * cmd_parameter. Writes to response.
1208 */
1209static void flashing(char *cmd_parameter, char *response)
1210{
1211 char *cmd;
1212 char* lock_s;
1213 LockData_t info = {0};
1214 char lock_d[LOCK_DATA_SIZE];
1215 u64 rc;
1216 int debug_flag = 0;
1217
1218 if (IS_FEAT_BOOT_VERIFY()) {
1219 printf("device is secure mode, can not run this cmd.\n");
1220 fastboot_fail("secure boot device", response);
1221 return;
1222 }
1223
1224 lock_s = env_get("lock");
1225 if (!lock_s) {
1226 printf("lock state is NULL \n");
1227 memcpy(lock_d, "10101000", 8);
1228 lock_s = "10101000";
1229 env_set("lock", "10101000");
1230#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1231 run_command("update_env_part -p lock;", 0);
1232#else
1233 run_command("defenv_reserv; saveenv;", 0);
1234#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1235 } else {
1236 printf("lock state: %s\n", lock_s);
1237 if (strlen(lock_s) > 15)
1238 strncpy(lock_d, lock_s, 15);
1239 else
1240 strncpy(lock_d, lock_s, strlen(lock_s));
1241 }
1242
1243 info.version_major = (int)(lock_d[0] - '0');
1244 info.version_minor = (int)(lock_d[1] - '0');
1245 info.unlock_ability = (int)(lock_d[2] - '0');
1246 info.lock_state = (int)(lock_d[4] - '0');
1247 info.lock_critical_state = (int)(lock_d[5] - '0');
1248 info.lock_bootloader = (int)(lock_d[6] - '0');
1249 dump_lock_info(info);
1250
1251 printf("cb_flashing cmd_parameter: %s\n", cmd_parameter);
1252 cmd = cmd_parameter;
1253 strsep(&cmd, " ");
1254 printf("cb_flashing: %s\n", cmd);
1255 if (!cmd) {
1256 printf("missing variable\n");
1257 fastboot_fail("missing var", response);
1258 return;
1259 }
1260
1261 boot_img_hdr_t *hdr_addr = NULL;
1262 const int preloadsz = 0x1000 * 2;//4k not enough for signed
1263 unsigned char *pbuffpreload = 0;
1264 char partname[32] = {0};
1265 char *slot_name;
1266 char cmdline[4096];
1267 char *result = NULL;
1268
1269 slot_name = env_get("slot-suffixes");
1270 if (slot_name && (strcmp(slot_name, "0") == 0))
1271 strcpy((char *)partname, "boot_a");
1272 else if (slot_name && (strcmp(slot_name, "1") == 0))
1273 strcpy((char *)partname, "boot_b");
1274 else
1275 strcpy((char *)partname, "boot");
1276
1277 pbuffpreload = malloc(preloadsz);
1278 if (!pbuffpreload) {
1279 printf("Fail to allocate memory!\n");
1280 goto next;
1281 }
1282
1283 hdr_addr = (boot_img_hdr_t *)pbuffpreload;
1284
1285 printf("read from part: %s\n", partname);
1286 rc = store_logic_read(partname, 0, preloadsz, pbuffpreload);
1287 if (rc) {
1288 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1289 preloadsz, partname);
1290 free(pbuffpreload);
1291 pbuffpreload = 0;
1292 goto next;
1293 }
1294
1295 if (is_android_r_image((void *)hdr_addr)) {
1296 char partname_r[32] = {0};
1297 const int preloadsz_r = 0x1000 * 2;//4k not enough for signed
1298 unsigned char *pbuffpreload_r = 0;
1299 int ret_r = __LINE__;
1300
1301 if (slot_name && (strcmp(slot_name, "0") == 0))
1302 strcpy((char *)partname_r, "vendor_boot_a");
1303 else if (slot_name && (strcmp(slot_name, "1") == 0))
1304 strcpy((char *)partname_r, "vendor_boot_b");
1305 else
1306 strcpy((char *)partname_r, "vendor_boot");
1307
1308 pbuffpreload_r = malloc(preloadsz_r);
1309
1310 if (!pbuffpreload_r) {
1311 printf("Fail to allocate memory for %s!\n",
1312 partname_r);
1313 goto next;
1314 }
1315
1316 printf("read from part: %s\n", partname_r);
1317 ret_r = store_logic_read(partname_r, 0,
1318 preloadsz_r, pbuffpreload_r);
1319 if (ret_r) {
1320 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1321 preloadsz_r, partname_r);
1322 free(pbuffpreload_r);
1323 pbuffpreload_r = 0;
1324 goto next;
1325 }
1326
1327 p_vendor_boot_img_hdr_t vb_hdr = (p_vendor_boot_img_hdr_t)pbuffpreload_r;
1328
1329 if (*vb_hdr->cmdline) {
1330 printf("Kernel command line: %s\n", vb_hdr->cmdline);
1331 sprintf(cmdline, "%s", vb_hdr->cmdline);
1332 }
1333 free(pbuffpreload_r);
1334 pbuffpreload_r = 0;
1335 } else {
1336 if (*hdr_addr->cmdline) {
1337 printf("Kernel command line: %s\n", hdr_addr->cmdline);
1338 sprintf(cmdline, "%s", hdr_addr->cmdline);
1339 }
1340 }
1341
1342 free(pbuffpreload);
1343 pbuffpreload = 0;
1344
1345 result = strtok(cmdline, " ");
1346 while (result) {
1347 printf("result: %s\n", result);
1348 if (strcmp(result, "buildvariant=userdebug") == 0 ||
1349 strcmp(result, "buildvariant=eng") == 0)
1350 debug_flag = 1;
1351 result = strtok(NULL, " ");
1352 }
1353
1354 if (info.unlock_ability == 0 && debug_flag == 1) {
1355 printf("userdebug mode can ignore\n");
1356 info.unlock_ability = 1;
1357 }
1358
1359next:
1360 rc = store_part_size("userdata");
1361
1362 if (!strcmp_l1("unlock_critical", cmd)) {
1363 info.lock_critical_state = 0;
1364 fastboot_okay(NULL, response);
1365 } else if (!strcmp_l1("lock_critical", cmd)) {
1366 info.lock_critical_state = 1;
1367 fastboot_okay(NULL, response);
1368 } else if (!strcmp_l1("get_unlock_ability", cmd)) {
1369 char str[32];
1370 static bool is_unlock_ability_sent = false;
1371 if (is_unlock_ability_sent) {
1372 is_unlock_ability_sent = false;
1373 fastboot_okay(NULL, response);
1374 busy_flag = 0;
1375 } else {
1376 sprintf(str, "get_unlock_ability: %d",
1377 info.unlock_ability);
1378 fastboot_response("INFO", response, "%s", str);
1379 is_unlock_ability_sent = true;
1380 busy_flag = 1;
1381 }
1382 return;
1383 } else if (!strcmp_l1("get_unlock_bootloader_nonce", cmd)) {
1384 char str_num[8];
1385 sprintf(str_num, "%d", info.lock_critical_state);
1386 fastboot_response("OKAY", response, "%s", str_num);
1387 } else if (!strcmp_l1("lock_bootloader", cmd)) {
1388 info.lock_bootloader = 1;
1389 } else if (!strcmp_l1("unlock", cmd)) {
1390 if (info.unlock_ability == 1) {
1391 if (info.lock_state == 1) {
1392 char *avb_s;
1393
1394 run_command("get_avb_mode;", 0);
1395 avb_s = env_get("avb2");
1396 printf("avb2: %s\n", avb_s);
1397 if (strcmp(avb_s, "1") == 0) {
1398 try_unlock_dev(rc);
1399 }
1400 }
1401 info.lock_state = 0;
1402 info.lock_critical_state = 0;
1403 env_set("lock_state", "green");
1404 fastboot_okay(NULL, response);
1405 } else {
1406 printf("unlock_ability is 0, can not unlock, please set it in android setting\n");
1407 fastboot_response("FAIL", response, "%s", "unlock_ability is 0, can not unlock");
1408 }
1409 } else if (!strcmp_l1("lock", cmd)) {
1410 if (info.lock_state == 0) {
1411 char *avb_s;
1412
1413 run_command("get_avb_mode;", 0);
1414 avb_s = env_get("avb2");
1415 printf("avb2: %s\n", avb_s);
1416 if (strcmp(avb_s, "1") == 0) {
1417 try_lock_dev(rc);
1418 }
1419 }
1420 info.lock_state = 1;
1421 env_set("lock_state", "orange");
1422 fastboot_okay(NULL, response);
1423 } else {
1424 printf("unknown variable: %s\n", cmd);
1425 fastboot_response("FAIL", response, "%s", "Variable not implemented");
1426 }
1427
1428 sprintf(lock_d, "%d%d%d0%d%d%d0", info.version_major, info.version_minor,
1429 info.unlock_ability, info.lock_state, info.lock_critical_state,
1430 info.lock_bootloader);
1431 printf("lock_d state: %s\n", lock_d);
1432 env_set("lock", lock_d);
1433#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1434 run_command("update_env_part -p lock;", 0);
1435#else
1436 run_command("defenv_reserv; saveenv;", 0);
1437#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1438 return;
1439}
1440#endif// #if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
1441#endif
1442#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001443
Heiko Schocherbc820d52021-02-10 09:29:03 +01001444#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
1445/**
1446 * run_ucmd() - Execute the UCmd command
1447 *
1448 * @cmd_parameter: Pointer to command parameter
1449 * @response: Pointer to fastboot response buffer
1450 */
1451static void run_ucmd(char *cmd_parameter, char *response)
1452{
1453 if (!cmd_parameter) {
1454 pr_err("missing slot suffix\n");
1455 fastboot_fail("missing command", response);
1456 return;
1457 }
1458
1459 if (run_command(cmd_parameter, 0))
1460 fastboot_fail("", response);
1461 else
1462 fastboot_okay(NULL, response);
1463}
1464
1465static char g_a_cmd_buff[64];
1466
1467void fastboot_acmd_complete(void)
1468{
1469 run_command(g_a_cmd_buff, 0);
1470}
1471
1472/**
1473 * run_acmd() - Execute the ACmd command
1474 *
1475 * @cmd_parameter: Pointer to command parameter
1476 * @response: Pointer to fastboot response buffer
1477 */
1478static void run_acmd(char *cmd_parameter, char *response)
1479{
1480 if (!cmd_parameter) {
1481 pr_err("missing slot suffix\n");
1482 fastboot_fail("missing command", response);
1483 return;
1484 }
1485
1486 if (strlen(cmd_parameter) > sizeof(g_a_cmd_buff)) {
1487 pr_err("too long command\n");
1488 fastboot_fail("too long command", response);
1489 return;
1490 }
1491
1492 strcpy(g_a_cmd_buff, cmd_parameter);
1493 fastboot_okay(NULL, response);
1494}
1495#endif
1496
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001497/**
1498 * reboot_bootloader() - Sets reboot bootloader flag.
1499 *
1500 * @cmd_parameter: Pointer to command parameter
1501 * @response: Pointer to fastboot response buffer
1502 */
1503static void reboot_bootloader(char *cmd_parameter, char *response)
1504{
Xindong Xud9441422024-01-18 10:20:45 +08001505#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi851737a2020-07-28 23:35:32 +03001506 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_BOOTLOADER))
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001507 fastboot_fail("Cannot set reboot flag", response);
1508 else
Xindong Xud9441422024-01-18 10:20:45 +08001509#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001510 fastboot_okay(NULL, response);
1511}
Alex Kiernan3845b902018-05-29 15:30:54 +00001512
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001513/**
1514 * reboot_fastbootd() - Sets reboot fastboot flag.
1515 *
1516 * @cmd_parameter: Pointer to command parameter
1517 * @response: Pointer to fastboot response buffer
1518 */
1519static void reboot_fastbootd(char *cmd_parameter, char *response)
1520{
Xindong Xud9441422024-01-18 10:20:45 +08001521#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001522 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_FASTBOOTD))
Xindong Xud9441422024-01-18 10:20:45 +08001523 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001524 else
Xindong Xud9441422024-01-18 10:20:45 +08001525#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001526 fastboot_okay(NULL, response);
1527}
1528
1529/**
1530 * reboot_recovery() - Sets reboot recovery flag.
1531 *
1532 * @cmd_parameter: Pointer to command parameter
1533 * @response: Pointer to fastboot response buffer
1534 */
1535static void reboot_recovery(char *cmd_parameter, char *response)
1536{
Xindong Xud9441422024-01-18 10:20:45 +08001537#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001538 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_RECOVERY))
Xindong Xud9441422024-01-18 10:20:45 +08001539 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001540 else
Xindong Xud9441422024-01-18 10:20:45 +08001541#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001542 fastboot_okay(NULL, response);
1543}
1544
Xindong Xud9441422024-01-18 10:20:45 +08001545#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernan3845b902018-05-29 15:30:54 +00001546#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
1547/**
1548 * oem_format() - Execute the OEM format command
1549 *
1550 * @cmd_parameter: Pointer to command parameter
1551 * @response: Pointer to fastboot response buffer
1552 */
1553static void oem_format(char *cmd_parameter, char *response)
1554{
1555 char cmdbuf[32];
1556
Xindong Xud9441422024-01-18 10:20:45 +08001557#ifdef CONFIG_AMLOGIC_MODIFY
1558 if (IS_FEAT_BOOT_VERIFY()) {
1559 printf("device is secure mode, can not run this cmd.\n");
1560 fastboot_fail("secure boot device", response);
1561 return;
1562 }
1563
1564 if (check_lock() == 1) {
1565 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1566 fastboot_fail("locked device", response);
1567 return;
1568 }
1569#endif
1570
Alex Kiernan3845b902018-05-29 15:30:54 +00001571 if (!env_get("partitions")) {
1572 fastboot_fail("partitions not set", response);
1573 } else {
1574 sprintf(cmdbuf, "gpt write mmc %x $partitions",
1575 CONFIG_FASTBOOT_FLASH_MMC_DEV);
1576 if (run_command(cmdbuf, 0))
1577 fastboot_fail("", response);
1578 else
1579 fastboot_okay(NULL, response);
1580 }
1581}
1582#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +01001583
1584#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
1585/**
1586 * oem_partconf() - Execute the OEM partconf command
1587 *
1588 * @cmd_parameter: Pointer to command parameter
1589 * @response: Pointer to fastboot response buffer
1590 */
1591static void oem_partconf(char *cmd_parameter, char *response)
1592{
1593 char cmdbuf[32];
1594
1595 if (!cmd_parameter) {
1596 fastboot_fail("Expected command parameter", response);
1597 return;
1598 }
1599
1600 /* execute 'mmc partconfg' command with cmd_parameter arguments*/
1601 snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0",
1602 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1603 printf("Execute: %s\n", cmdbuf);
1604 if (run_command(cmdbuf, 0))
1605 fastboot_fail("Cannot set oem partconf", response);
1606 else
1607 fastboot_okay(NULL, response);
1608}
1609#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +01001610
1611#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
1612/**
1613 * oem_bootbus() - Execute the OEM bootbus command
1614 *
1615 * @cmd_parameter: Pointer to command parameter
1616 * @response: Pointer to fastboot response buffer
1617 */
1618static void oem_bootbus(char *cmd_parameter, char *response)
1619{
1620 char cmdbuf[32];
1621
1622 if (!cmd_parameter) {
1623 fastboot_fail("Expected command parameter", response);
1624 return;
1625 }
1626
1627 /* execute 'mmc bootbus' command with cmd_parameter arguments*/
1628 snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s",
1629 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1630 printf("Execute: %s\n", cmdbuf);
1631 if (run_command(cmdbuf, 0))
1632 fastboot_fail("Cannot set oem bootbus", response);
1633 else
1634 fastboot_okay(NULL, response);
1635}
1636#endif
Xindong Xud9441422024-01-18 10:20:45 +08001637#endif