blob: 777884df0bba57166fb12a0195576812c60ac769 [file] [log] [blame]
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001// SPDX-License-Identifier: BSD-2-Clause
2/*
3 * Copyright (C) 2016 The Android Open Source Project
4 */
5
6#include <common.h>
Simon Glass288b29e2019-11-14 12:57:43 -07007#include <command.h>
Simon Glassc7694dd2019-08-01 09:46:46 -06008#include <env.h>
Alex Kiernanf73a7df2018-05-29 15:30:53 +00009#include <fastboot.h>
10#include <fastboot-internal.h>
11#include <fb_mmc.h>
12#include <fb_nand.h>
13#include <part.h>
14#include <stdlib.h>
Xindong Xud9441422024-01-18 10:20:45 +080015#ifdef CONFIG_AMLOGIC_MODIFY
16#include <amlogic/emmc_partitions.h>
17#include <amlogic/storage.h>
18#include <amlogic/aml_efuse.h>
19#include <amlogic/aml_mmc.h>
20
21#include <android_image.h>
22#include <image.h>
23#include <amlogic/store_wrapper.h>
24#include <malloc.h>
25#include <amlogic/image_check.h>
26#include <fs.h>
Xindong Xuac88caf2024-10-28 17:10:12 +080027#include <version.h>
Xindong Xud9441422024-01-18 10:20:45 +080028#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
29#include <amlogic/anti-rollback.h>
30#endif
31#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000032
33/**
34 * image_size - final fastboot image size
35 */
36static u32 image_size;
37
38/**
39 * fastboot_bytes_received - number of bytes received in the current download
40 */
41static u32 fastboot_bytes_received;
42
43/**
44 * fastboot_bytes_expected - number of bytes expected in the current download
45 */
46static u32 fastboot_bytes_expected;
47
Xindong Xud9441422024-01-18 10:20:45 +080048#ifdef CONFIG_AMLOGIC_MODIFY
49int busy_flag;
50#endif
51
Alex Kiernanf73a7df2018-05-29 15:30:53 +000052static void okay(char *, char *);
53static void getvar(char *, char *);
Xindong Xud9441422024-01-18 10:20:45 +080054
55#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +000056static void download(char *, char *);
57#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
58static void flash(char *, char *);
59static void erase(char *, char *);
60#endif
Xindong Xud9441422024-01-18 10:20:45 +080061#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000062static void reboot_bootloader(char *, char *);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +030063static void reboot_fastbootd(char *, char *);
64static void reboot_recovery(char *, char *);
Xindong Xud9441422024-01-18 10:20:45 +080065#ifdef CONFIG_FASTBOOT_WRITING_CMD
66#ifdef CONFIG_AMLOGIC_MODIFY
67static void fetch(char *, char *);
68#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
69static void flashing(char *, char *);
70#endif
71#endif
Alex Kiernan3845b902018-05-29 15:30:54 +000072#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
73static void oem_format(char *, char *);
74#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +010075#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
76static void oem_partconf(char *, char *);
77#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +010078#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
79static void oem_bootbus(char *, char *);
80#endif
Xindong Xud9441422024-01-18 10:20:45 +080081static void set_active_cmd(char *, char *);
82#endif
83
84#ifdef CONFIG_AMLOGIC_MODIFY
85extern int is_partition_logical(char* partition_name);
86#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +000087
Heiko Schocherbc820d52021-02-10 09:29:03 +010088#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
89static void run_ucmd(char *, char *);
90static void run_acmd(char *, char *);
91#endif
92
Alex Kiernanf73a7df2018-05-29 15:30:53 +000093static const struct {
94 const char *command;
95 void (*dispatch)(char *cmd_parameter, char *response);
96} commands[FASTBOOT_COMMAND_COUNT] = {
97 [FASTBOOT_COMMAND_GETVAR] = {
98 .command = "getvar",
99 .dispatch = getvar
100 },
Xindong Xud9441422024-01-18 10:20:45 +0800101#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000102 [FASTBOOT_COMMAND_DOWNLOAD] = {
103 .command = "download",
104 .dispatch = download
105 },
Xindong Xud9441422024-01-18 10:20:45 +0800106#ifdef CONFIG_AMLOGIC_MODIFY
107#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
108 [FASTBOOT_COMMAND_FLASHING] = {
109 .command = "flashing",
110 .dispatch = flashing
111 },
112#endif
113 [FASTBOOT_COMMAND_FETCH] = {
114 .command = "fetch",
115 .dispatch = fetch
116 },
117#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000118#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
119 [FASTBOOT_COMMAND_FLASH] = {
120 .command = "flash",
121 .dispatch = flash
122 },
123 [FASTBOOT_COMMAND_ERASE] = {
124 .command = "erase",
125 .dispatch = erase
126 },
127#endif
128 [FASTBOOT_COMMAND_BOOT] = {
129 .command = "boot",
130 .dispatch = okay
131 },
Xindong Xud9441422024-01-18 10:20:45 +0800132#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000133 [FASTBOOT_COMMAND_CONTINUE] = {
134 .command = "continue",
135 .dispatch = okay
136 },
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000137 [FASTBOOT_COMMAND_REBOOT_BOOTLOADER] = {
138 .command = "reboot-bootloader",
139 .dispatch = reboot_bootloader
140 },
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +0300141 [FASTBOOT_COMMAND_REBOOT_FASTBOOTD] = {
142 .command = "reboot-fastboot",
143 .dispatch = reboot_fastbootd
144 },
145 [FASTBOOT_COMMAND_REBOOT_RECOVERY] = {
146 .command = "reboot-recovery",
147 .dispatch = reboot_recovery
148 },
Xindong Xud9441422024-01-18 10:20:45 +0800149 [FASTBOOT_COMMAND_REBOOT] = {
150 .command = "reboot",
151 .dispatch = okay
152 },
153#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000154 [FASTBOOT_COMMAND_SET_ACTIVE] = {
155 .command = "set_active",
Xindong Xud9441422024-01-18 10:20:45 +0800156#ifdef CONFIG_AMLOGIC_MODIFY
157 .dispatch = set_active_cmd
158#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000159 .dispatch = okay
Xindong Xud9441422024-01-18 10:20:45 +0800160#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000161 },
Alex Kiernan3845b902018-05-29 15:30:54 +0000162#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
163 [FASTBOOT_COMMAND_OEM_FORMAT] = {
164 .command = "oem format",
165 .dispatch = oem_format,
166 },
167#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +0100168#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
169 [FASTBOOT_COMMAND_OEM_PARTCONF] = {
170 .command = "oem partconf",
171 .dispatch = oem_partconf,
172 },
173#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +0100174#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
175 [FASTBOOT_COMMAND_OEM_BOOTBUS] = {
176 .command = "oem bootbus",
177 .dispatch = oem_bootbus,
178 },
179#endif
Xindong Xud9441422024-01-18 10:20:45 +0800180#endif
Heiko Schocherbc820d52021-02-10 09:29:03 +0100181#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
182 [FASTBOOT_COMMAND_UCMD] = {
183 .command = "UCmd",
184 .dispatch = run_ucmd,
185 },
186 [FASTBOOT_COMMAND_ACMD] = {
187 .command = "ACmd",
188 .dispatch = run_acmd,
189 },
190#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000191};
192
Xindong Xud9441422024-01-18 10:20:45 +0800193#ifdef CONFIG_AMLOGIC_MODIFY
194struct fastboot_read fastboot_readInfo;
195
196static int strcmp_l1(const char *s1, const char *s2)
197{
198 if (!s1 || !s2)
199 return -1;
200 return strncmp(s1, s2, strlen(s1));
201}
202#endif
203
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000204/**
205 * fastboot_handle_command - Handle fastboot command
206 *
207 * @cmd_string: Pointer to command string
208 * @response: Pointer to fastboot response buffer
209 *
210 * Return: Executed command, or -1 if not recognized
211 */
212int fastboot_handle_command(char *cmd_string, char *response)
213{
214 int i;
215 char *cmd_parameter;
216
217 cmd_parameter = cmd_string;
218 strsep(&cmd_parameter, ":");
219
220 for (i = 0; i < FASTBOOT_COMMAND_COUNT; i++) {
Xindong Xud9441422024-01-18 10:20:45 +0800221#ifdef CONFIG_AMLOGIC_MODIFY
222 if (!strcmp_l1(commands[i].command, cmd_string)) {
223 if (commands[i].dispatch) {
224 if (cmd_parameter) {
225 commands[i].dispatch(cmd_parameter,
226 response);
227 } else {
228 commands[i].dispatch(cmd_string,
229 response);
230 }
231 return i;
232 } else {
233 break;
234 }
235 }
236#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000237 if (!strcmp(commands[i].command, cmd_string)) {
238 if (commands[i].dispatch) {
239 commands[i].dispatch(cmd_parameter,
240 response);
241 return i;
242 } else {
243 break;
244 }
245 }
Xindong Xud9441422024-01-18 10:20:45 +0800246#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000247 }
248
249 pr_err("command %s not recognized.\n", cmd_string);
250 fastboot_fail("unrecognized command", response);
251 return -1;
252}
253
254/**
255 * okay() - Send bare OKAY response
256 *
257 * @cmd_parameter: Pointer to command parameter
258 * @response: Pointer to fastboot response buffer
259 *
260 * Send a bare OKAY fastboot response. This is used where the command is
261 * valid, but all the work is done after the response has been sent (e.g.
262 * boot, reboot etc.)
263 */
264static void okay(char *cmd_parameter, char *response)
265{
266 fastboot_okay(NULL, response);
267}
268
Xindong Xud9441422024-01-18 10:20:45 +0800269#ifdef CONFIG_AMLOGIC_MODIFY
270void dump_lock_info(LockData_t info)
271{
272#if 0
273 printf("info.version_major = %d\n", info.version_major);
274 printf("info.version_minor = %d\n", info.version_minor);
275 printf("info.unlock_ability = %d\n", info.unlock_ability);
276 printf("info.lock_state = %d\n", info.lock_state);
277 printf("info.lock_critical_state = %d\n", info.lock_critical_state);
278 printf("info.lock_bootloader = %d\n", info.lock_bootloader);
279#endif
280}
281
282static const char* getvar_list[] = {
283 "version-baseband", "version-bootloader", "version", "hw-revision", "max-download-size",
284 "serialno", "product", "off-mode-charge", "variant", "battery-soc-ok",
285 "battery-voltage", "partition-type:boot", "partition-size:boot",
286 "partition-type:system", "partition-size:system", "partition-type:vendor", "partition-size:vendor",
287 "partition-type:odm", "partition-size:odm", "partition-type:data", "partition-size:data",
288 "erase-block-size", "logical-block-size", "secure", "unlocked",
289};
290
291static const char* getvar_list_dynamic[] = {
292 "hw-revision", "battery-voltage", "is-userspace", "is-logical:data",
293 "is-logical:metadata", "is-logical:misc", "is-logical:super", "is-logical:boot",
294 "is-logical:system", "is-logical:vendor", "is-logical:product", "is-logical:odm",
295 "slot-count", "max-download-size", "serialno", "product", "unlocked",
296 "secure", "super-partition-name", "version-baseband", "version-bootloader",
297 "partition-size:boot", "partition-size:metadata", "partition-size:misc",
298 "partition-size:super", "partition-size:data", "version",
299};
300
301static const char* getvar_list_dynamic_ab[] = {
302 "hw-revision", "battery-voltage", "is-userspace", "is-logical:data",
303 "is-logical:misc", "is-logical:super",
304 "is-logical:boot_a", "is-logical:boot_b", "is-logical:system_a", "is-logical:system_b",
305 "is-logical:vendor_a", "is-logical:vendor_b", "is-logical:product_a", "is-logical:product_b",
306 "is-logical:odm_a", "is-logical:odm_b",
307 "slot-count", "max-download-size", "serialno", "product", "unlocked", "has-slot:data",
308 "has-slot:metadata", "has-slot:misc", "has-slot:super", "has-slot:boot",
309 "has-slot:system", "has-slot:vendor", "has-slot:product", "has-slot:odm", "current-slot",
310 "secure", "super-partition-name", "version-baseband", "version-bootloader",
311 "partition-size:super",
312 "partition-size:boot_a", "partition-size:boot_b", "partition-size:misc",
313 "partition-size:data", "version",
314};
315
316
317static const char* getvar_list_ab[] = {
318 "version-baseband", "version-bootloader", "version", "hw-revision", "max-download-size",
319 "serialno", "product", "off-mode-charge", "variant", "battery-soc-ok",
320 "battery-voltage", "partition-type:boot_a", "partition-size:boot_a",
321 "partition-type:system_a", "partition-size:system_a", "partition-type:vendor_a", "partition-size:vendor_a",
322 "partition-type:odm_a", "partition-size:odm_a", "partition-type:data", "partition-size:data",
323 "erase-block-size", "logical-block-size", "secure", "unlocked",
324 "slot-count", "slot-suffixes","current-slot", "has-slot:bootloader", "has-slot:boot",
325 "has-slot:system", "has-slot:vendor", "has-slot:odm", "has-slot:vbmeta",
326 "has-slot:metadata", "has-slot:product", "has-slot:dtbo",
327 "slot-successful:a", "slot-unbootable:a", "slot-retry-count:a",
328 "slot-successful:b", "slot-unbootable:b", "slot-retry-count:b",
329};
330#endif
331
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000332/**
333 * getvar() - Read a config/version variable
334 *
335 * @cmd_parameter: Pointer to command parameter
336 * @response: Pointer to fastboot response buffer
337 */
338static void getvar(char *cmd_parameter, char *response)
339{
Xindong Xud9441422024-01-18 10:20:45 +0800340#ifdef CONFIG_AMLOGIC_MODIFY
341 run_command("get_valid_slot", 0);
342 if (!strncmp(cmd_parameter, "all", 3)) {
343 static int cmdIndex = 0;
344 int getvar_num = 0;
345 char* cmd=cmd_parameter;
346
347 busy_flag = 1;
348
349 if (dynamic_partition && has_boot_slot == 1 && strlen(getvar_list_dynamic_ab[cmdIndex]) < 64) {
350 strncpy(cmd, getvar_list_dynamic_ab[cmdIndex], 64);
351 getvar_num = (sizeof(getvar_list_dynamic_ab) / sizeof(getvar_list_dynamic_ab[0]));
352 } else if (has_boot_slot == 1 && strlen(getvar_list_ab[cmdIndex]) < 64) {
353 strncpy(cmd, getvar_list_ab[cmdIndex], 64);
354 getvar_num = (sizeof(getvar_list_ab) / sizeof(getvar_list_ab[0]));
355 } else if (dynamic_partition && strlen(getvar_list_dynamic[cmdIndex]) < 64) {
356 strncpy(cmd, getvar_list_dynamic[cmdIndex], 64);//only support no-arg cmd
357 getvar_num = (sizeof(getvar_list_dynamic) / sizeof(getvar_list_dynamic[0]));
358 } else if (strlen(getvar_list[cmdIndex]) < 64) {
359 strncpy(cmd, getvar_list[cmdIndex], 64);//only support no-arg cmd
360 getvar_num = (sizeof(getvar_list) / sizeof(getvar_list[0]));
361 }
362 //printf("getvar_num: %d\n", getvar_num);
363 //printf("all cmd:%s\n", cmd);
364 if ( ++cmdIndex >= getvar_num) {
365 cmdIndex = 0;
366 busy_flag = 0;
367 fastboot_okay(NULL, response);
368 } else {
369 fastboot_getvar(cmd, response);
370 }
371
372 }else {
373#endif
374 fastboot_getvar(cmd_parameter, response);
375#ifdef CONFIG_AMLOGIC_MODIFY
376 }
377#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000378}
379
380/**
381 * fastboot_download() - Start a download transfer from the client
382 *
383 * @cmd_parameter: Pointer to command parameter
384 * @response: Pointer to fastboot response buffer
385 */
Xindong Xud9441422024-01-18 10:20:45 +0800386#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000387static void download(char *cmd_parameter, char *response)
388{
389 char *tmp;
390
Xindong Xud9441422024-01-18 10:20:45 +0800391#ifdef CONFIG_AMLOGIC_MODIFY
392 if (check_lock() == 1) {
393 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
394 fastboot_fail("locked device", response);
395 return;
396 }
397#endif
398
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000399 if (!cmd_parameter) {
400 fastboot_fail("Expected command parameter", response);
401 return;
402 }
403 fastboot_bytes_received = 0;
Simon Glass7e5f4602021-07-24 09:03:29 -0600404 fastboot_bytes_expected = hextoul(cmd_parameter, &tmp);
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000405 if (fastboot_bytes_expected == 0) {
406 fastboot_fail("Expected nonzero image size", response);
407 return;
408 }
409 /*
410 * Nothing to download yet. Response is of the form:
411 * [DATA|FAIL]$cmd_parameter
412 *
413 * where cmd_parameter is an 8 digit hexadecimal number
414 */
415 if (fastboot_bytes_expected > fastboot_buf_size) {
Xindong Xud9441422024-01-18 10:20:45 +0800416#ifdef CONFIG_AMLOGIC_MODIFY
417 char str[128] = {0};
418
419 printf("fastboot_bytes_expected %d > fastboot_buf_size %d\n",
420 fastboot_bytes_expected, fastboot_buf_size);
421 sprintf(str, "data too large, please add -S %dM",
422 (fastboot_buf_size / 1024 / 1024));
423 fastboot_fail(str, response);
424#else
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000425 fastboot_fail(cmd_parameter, response);
Xindong Xud9441422024-01-18 10:20:45 +0800426#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000427 } else {
428 printf("Starting download of %d bytes\n",
429 fastboot_bytes_expected);
430 fastboot_response("DATA", response, "%s", cmd_parameter);
431 }
432}
Xindong Xud9441422024-01-18 10:20:45 +0800433#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000434/**
435 * fastboot_data_remaining() - return bytes remaining in current transfer
436 *
437 * Return: Number of bytes left in the current download
438 */
439u32 fastboot_data_remaining(void)
440{
441 return fastboot_bytes_expected - fastboot_bytes_received;
442}
443
444/**
445 * fastboot_data_download() - Copy image data to fastboot_buf_addr.
446 *
447 * @fastboot_data: Pointer to received fastboot data
448 * @fastboot_data_len: Length of received fastboot data
449 * @response: Pointer to fastboot response buffer
450 *
451 * Copies image data from fastboot_data to fastboot_buf_addr. Writes to
452 * response. fastboot_bytes_received is updated to indicate the number
453 * of bytes that have been transferred.
454 *
455 * On completion sets image_size and ${filesize} to the total size of the
456 * downloaded image.
457 */
458void fastboot_data_download(const void *fastboot_data,
459 unsigned int fastboot_data_len,
460 char *response)
461{
462#define BYTES_PER_DOT 0x20000
463 u32 pre_dot_num, now_dot_num;
464
465 if (fastboot_data_len == 0 ||
466 (fastboot_bytes_received + fastboot_data_len) >
467 fastboot_bytes_expected) {
468 fastboot_fail("Received invalid data length",
469 response);
470 return;
471 }
472 /* Download data to fastboot_buf_addr */
473 memcpy(fastboot_buf_addr + fastboot_bytes_received,
474 fastboot_data, fastboot_data_len);
475
476 pre_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
477 fastboot_bytes_received += fastboot_data_len;
478 now_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
479
480 if (pre_dot_num != now_dot_num) {
481 putc('.');
482 if (!(now_dot_num % 74))
483 putc('\n');
484 }
485 *response = '\0';
486}
487
488/**
489 * fastboot_data_complete() - Mark current transfer complete
490 *
491 * @response: Pointer to fastboot response buffer
492 *
493 * Set image_size and ${filesize} to the total size of the downloaded image.
494 */
495void fastboot_data_complete(char *response)
496{
497 /* Download complete. Respond with "OKAY" */
498 fastboot_okay(NULL, response);
499 printf("\ndownloading of %d bytes finished\n", fastboot_bytes_received);
500 image_size = fastboot_bytes_received;
501 env_set_hex("filesize", image_size);
502 fastboot_bytes_expected = 0;
503 fastboot_bytes_received = 0;
504}
505
Xindong Xud9441422024-01-18 10:20:45 +0800506#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000507#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
Xindong Xud9441422024-01-18 10:20:45 +0800508
509#ifdef CONFIG_AMLOGIC_MODIFY
510static void write_dts_reserve(void)
511{
512 int ret;
513 void *addr = NULL;
514 char *mem_addr;
515
516 if (run_command("imgread dtb ${boot_part} ${dtb_mem_addr}", 0)) {
517 printf("Fail in load dtb\n");
518 } else {
519 mem_addr = env_get("dtb_mem_addr");
520
521 if (mem_addr) {
522 addr = (void *)simple_strtoul(mem_addr, NULL, 16);
523 ret = dtb_write(addr);
524 if (ret)
525 printf("write dtb error\n");
526 else
527 printf("write dtb ok\n");
528 }
529 }
530}
531
Xindong Xu0afe60a2024-05-21 16:15:13 +0800532static int clear_misc_partition(void)
533{
534 char *partition = "misc";
535 char *buffer = NULL;
536 u64 rc = 0;
537
538 rc = store_part_size(partition);
539 buffer = (char *)malloc(rc - AVB_CUSTOM_KEY_LEN_MAX);
540 if (!buffer) {
541 printf("malloc error\n");
542 return -1;
543 }
544 memset(buffer, 0, rc - AVB_CUSTOM_KEY_LEN_MAX);
545
546 store_write((const char *)partition, 0, rc - AVB_CUSTOM_KEY_LEN_MAX,
547 (unsigned char *)buffer);
548
549 free(buffer);
550
551 return 0;
552}
553
Xindong Xu22e8daf2024-03-12 18:08:41 +0800554static void set_fastboot_flag(int flag)
Xindong Xud9441422024-01-18 10:20:45 +0800555{
556 env_set("default_env", "1");
Xindong Xu22e8daf2024-03-12 18:08:41 +0800557 if (flag == 1)
558 env_set("fastboot_step", "1");
Xindong Xud9441422024-01-18 10:20:45 +0800559#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
560 run_command("update_env_part -p default_env;", 0);
Xindong Xu22e8daf2024-03-12 18:08:41 +0800561 if (flag == 1)
562 run_command("update_env_part -p fastboot_step;", 0);
Xindong Xud9441422024-01-18 10:20:45 +0800563#else
564 run_command("defenv_reserve;", 0);
565 run_command("setenv default_env 1;", 0);
Xindong Xu22e8daf2024-03-12 18:08:41 +0800566 if (flag == 1)
567 run_command("setenv fastboot_step 1;", 0);
Xindong Xud9441422024-01-18 10:20:45 +0800568 run_command("saveenv;", 0);
569#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
570}
571#endif
572
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000573/**
574 * flash() - write the downloaded image to the indicated partition.
575 *
576 * @cmd_parameter: Pointer to partition name
577 * @response: Pointer to fastboot response buffer
578 *
579 * Writes the previously downloaded image to the partition indicated by
580 * cmd_parameter. Writes to response.
581 */
582static void flash(char *cmd_parameter, char *response)
583{
Xindong Xud9441422024-01-18 10:20:45 +0800584#ifdef CONFIG_AMLOGIC_MODIFY
585 char name[32] = {0};
586 u64 rc = 0;
587 int gpt_flag = -1;
588 int ret = -1;
589
590 if (check_lock() == 1) {
591 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
592 fastboot_fail("locked device", response);
593 return;
594 }
595
596 printf("cmd_parameter: %s\n", cmd_parameter);
597
598#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
599 struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
600 if (mmc && strcmp(cmd_parameter, "bootloader") == 0) {
601 printf("try to read gpt data from bootloader.img\n");
602 struct blk_desc *dev_desc;
603 int erase_flag = 0;
Xindong Xu22e8daf2024-03-12 18:08:41 +0800604 char *bootloaderindex;
605 char *slot_name = NULL;
606 char partname[32] = {0};
Xindong Xud9441422024-01-18 10:20:45 +0800607
Zhigang Yua69e3f92024-06-18 03:13:38 +0000608 ret = update_boot_hdr_4_s7d_reva(fastboot_buf_addr, image_size, 0);
609 if (ret) {
610 printf("Failed to write s7d reva boot0\n");
611 fastboot_fail("Failed to write s7d reva boot0", response);
612 return;
613 }
614
Xindong Xu22e8daf2024-03-12 18:08:41 +0800615 slot_name = env_get("active_slot");
616 if (slot_name && (strcmp(slot_name, "_a") == 0))
617 strcpy((char *)partname, "bootloader_a");
618 else if (slot_name && (strcmp(slot_name, "_b") == 0))
619 strcpy((char *)partname, "bootloader_b");
620 else
621 strcpy((char *)partname, "bootloader_up");
622
623 rc = store_part_size(partname);
Xindong Xud9441422024-01-18 10:20:45 +0800624 if (rc != -1) {
Xindong Xu22e8daf2024-03-12 18:08:41 +0800625 fastboot_mmc_erase(partname, response);
626 fastboot_mmc_flash_write(partname, fastboot_buf_addr, image_size,
Xindong Xud9441422024-01-18 10:20:45 +0800627 response);
628 }
629
630 /* the max size of bootloader.img is 4M, we reserve 128k for gpt.bin
631 * so we put gpt.bin at offset 0x3DFE00
632 * 0 ~ 512 bootloader secure boot, we don't care it here.
633 * 512 ~ 0x3DFDFF original bootloader.img and 0
634 * 0x3DFE00 ~ end gpt.bin
635 */
636
637 dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
638 if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
639 printf("invalid mmc device\n");
640 fastboot_fail("invalid mmc device", response);
641 return;
642 }
643
644 if (is_valid_gpt_buf(dev_desc, fastboot_buf_addr + 0x3DFE00)) {
645 printf("printf normal bootloader.img, no gpt partition table\n");
646 } else {
647 printf("find gpt partition table, update it\n"
648 "and write bootloader to boot0/boot1\n");
649
650 erase_flag = check_gpt_part(dev_desc, fastboot_buf_addr + 0x3DFE00);
651
652 if (erase_flag == 1) {
653 printf("partition changes, erase emmc\n");
654 //run_command("store erase.chip 0;", 0);
655 if (usb_burn_erase_data(0x3)) {
656 printf("partition erase failed!\n");
657 return;
658 }
659 }
660
661 if (write_mbr_and_gpt_partitions(dev_desc, fastboot_buf_addr + 0x3DFE00)) {
662 printf("%s: writing GPT partitions failed\n", __func__);
663 fastboot_fail("writing GPT partitions failed", response);
664 return;
665 }
666
667 if (mmc_device_init(mmc) != 0) {
668 printf(" update gpt partition table fail\n");
669 fastboot_fail("fastboot update gpt partition fail", response);
670 return;
671 }
672 printf("%s: writing GPT partitions ok\n", __func__);
673
674 char *mem_addr;
675 void *addr = NULL;
676 int ret;
677
678 mem_addr = env_get("dtb_mem_addr");
679
680 if (mem_addr && erase_flag == 1) {
681 printf("partition changes, erase emmc\n");
682 //run_command("store erase.chip 0;", 0);
683 if (usb_burn_erase_data(0x3)) {
684 printf("partition erase failed!\n");
685 return;
686 }
687 printf("write _aml_dtb\n");
688 addr = (void *)simple_strtoul(mem_addr, NULL, 16);
689 ret = dtb_write(addr);
690 if (ret)
691 printf("write _aml_dtb error\n");
692 else
693 printf("write _aml_dtb ok\n");
694 }
695 }
696
Xindong Xu0afe60a2024-05-21 16:15:13 +0800697 ret = clear_misc_partition();
698 if (ret) {
699 printf("clear misc partition error\n");
700 fastboot_fail("clear misc partition fail", response);
701 return;
702 }
703
Xindong Xud9441422024-01-18 10:20:45 +0800704 gpt_flag = aml_gpt_valid(mmc);
705 if (gpt_flag == 0)
706 ret = 0;
707
708#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
709 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
710
711 if (*efuse_field.data == 1) {
712 wrnP("efuse_field.data == 1\n");
713 ret = 0;
714 env_set("nocs_mode", "true");
715 } else {
716 wrnP("efuse_field.data != 1\n");
717 env_set("nocs_mode", "false");
718 }
719#endif//#ifdef CONFIG_EFUSE_OBJ_API
720
Xindong Xu22e8daf2024-03-12 18:08:41 +0800721 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
722
723 if (ret == 0) {
724 printf("gpt/nocs mode\n");
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000725#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
Xindong Xu22e8daf2024-03-12 18:08:41 +0800726 fastboot_mmc_flash_write("bootloader-boot1", fastboot_buf_addr, image_size,
727 response);
728 if (strcmp(bootloaderindex, "1") != 0) {
729 printf("boot from boot1, means boot0 is error, rewrite it\n");
730 fastboot_mmc_flash_write("bootloader-boot0",
731 fastboot_buf_addr, image_size, response);
732 run_command("mmc dev 1 0;", 0);
733 set_fastboot_flag(0);
734 } else {
735 printf("need to set fastboot_step\n");
736 run_command("mmc dev 1 0;", 0);
737 set_fastboot_flag(1);
738 }
Xindong Xud9441422024-01-18 10:20:45 +0800739#endif
Xindong Xu22e8daf2024-03-12 18:08:41 +0800740 return;
741 } else {
742 printf("normal mode\n");
743#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
744 fastboot_mmc_flash_write("bootloader-boot0", fastboot_buf_addr, image_size,
745 response);
746 fastboot_mmc_flash_write("bootloader-boot1", fastboot_buf_addr, image_size,
747 response);
748 if (strcmp(bootloaderindex, "0") != 0) {
749 printf("boot from boot0, rewrite user bootloader is error\n");
750 fastboot_mmc_flash_write("bootloader",
751 fastboot_buf_addr, image_size, response);
752 run_command("mmc dev 1 0;", 0);
753 set_fastboot_flag(0);
754 } else {
755 run_command("mmc dev 1 0;", 0);
756 set_fastboot_flag(1);
757 }
758#endif
759 return;
760 }
Xindong Xud9441422024-01-18 10:20:45 +0800761 }
762#endif
763
764 if (strcmp(cmd_parameter, "avb_custom_key") == 0) {
765 char* buffer = NULL;
766 char *partition = "misc";
767 AvbKey_t key;
768 printf("avb_custom_key image_size: %d\n", image_size);
769
770 if (image_size > AVB_CUSTOM_KEY_LEN_MAX - sizeof(AvbKey_t)) {
771 printf("key size is too large\n");
772 fastboot_fail("size error", response);
773 return;
774 }
775
776 memcpy(key.magic_name, "AVBK", 4);
777 key.size = image_size;
778 rc = store_part_size(partition);
779
780 buffer = (char *)malloc(AVB_CUSTOM_KEY_LEN_MAX);
781 if (!buffer) {
782 printf("malloc error\n");
783 fastboot_fail("malloc error", response);
784 return;
785 }
786 memset(buffer, 0, AVB_CUSTOM_KEY_LEN_MAX);
787 memcpy(buffer, &key, sizeof(AvbKey_t));
788 memcpy(buffer + sizeof(AvbKey_t), fastboot_buf_addr, image_size);
789
790 store_write((const char *)partition, rc - AVB_CUSTOM_KEY_LEN_MAX,
791 AVB_CUSTOM_KEY_LEN_MAX, (unsigned char *)buffer);
792
793 fastboot_okay(NULL, response);
794 free(buffer);
795 return;
796 }
797
798 if (strcmp(cmd_parameter, "userdata") == 0 || strcmp(cmd_parameter, "data") == 0) {
799 fastboot_okay(NULL, response);
800 return;
801 } else if (strcmp(cmd_parameter, "dts") == 0) {
802 strcpy(name, "dtb");
Zhigang Yua69e3f92024-06-18 03:13:38 +0000803 } else if (!strcmp(cmd_parameter, "bootloader-boot0") ||
804 !strcmp(cmd_parameter, "bootloader-boot1")) {
805 ret = update_boot_hdr_4_s7d_reva(fastboot_buf_addr, image_size, 0);
806 if (ret) {
807 printf("Failed to write s7d reva boot0\n");
808 fastboot_fail("Failed to write s7d reva boot0-1", response);
809 return;
810 }
hao.qi278cfd32024-06-28 16:09:50 +0800811 strlcpy(name, cmd_parameter, 31);
Xindong Xud9441422024-01-18 10:20:45 +0800812 } else {
hao.qi278cfd32024-06-28 16:09:50 +0800813 strlcpy(name, cmd_parameter, 31);
Xindong Xud9441422024-01-18 10:20:45 +0800814 }
815 strcat(name, "\0");
816
817#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
818 if (dynamic_partition) {
819 if (is_partition_logical(name) == 0) {
820 printf("logic partition, can not write here.......\n");
821 fastboot_fail("logic partition", response);
822 return;
823 }
824 }
825#endif
826
827#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
828 fastboot_mmc_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000829 response);
830#endif
831#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800832 fastboot_nand_flash_write(name, fastboot_buf_addr, image_size,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000833 response);
834#endif
Xindong Xud9441422024-01-18 10:20:45 +0800835
836 if (strcmp(name, "bootloader") == 0) {
837 env_set("default_env", "1");
838#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
839 run_command("update_env_part -p default_env;", 0);
840#else
841 run_command("defenv_reserve;saveenv;", 0);
842#endif// #if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
843 }
844
845 if (strcmp(name, "bootloader-boot0") == 0 ||
846 strcmp(name, "bootloader-boot1") == 0) {
847 printf("try to switch back to user\n");
848 run_command("mmc dev 1 0;", 0);
849 }
850
851#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
852 if (mmc && aml_gpt_valid(mmc) == 0) {
853 if (vendor_boot_partition) {
854 if (strcmp_l1("vendor_boot", name) == 0) {
855 printf("gpt mode, write dts to reserve\n");
856 write_dts_reserve();
857 }
858 } else {
859 if (strcmp_l1("boot", name) == 0) {
860 printf("gpt mode, write dts to reserve\n");
861 write_dts_reserve();
862 }
863 }
864 }
865#endif
866
867#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000868}
869
870/**
871 * erase() - erase the indicated partition.
872 *
873 * @cmd_parameter: Pointer to partition name
874 * @response: Pointer to fastboot response buffer
875 *
876 * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
877 * to response.
878 */
879static void erase(char *cmd_parameter, char *response)
880{
Xindong Xud9441422024-01-18 10:20:45 +0800881#ifdef CONFIG_AMLOGIC_MODIFY
882 char name[32] = {0};
883 u64 rc = 0;
884
885 if (check_lock() == 1) {
886 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
887 fastboot_fail("locked device", response);
888 return;
889 }
890
891 printf("cmd_parameter: %s\n", cmd_parameter);
892
893#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
894 struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
895 if ((mmc != NULL) && strcmp(cmd_parameter, "bootloader") == 0 && (aml_gpt_valid(mmc) == 0)) {
896 printf("we write gpt partition table to bootloader now\n");
897 printf("plese write bootloader to bootloader-boot0/bootloader-boot1\n");
898 fastboot_okay("gpt mode, skip", response);
899 return;
900 }
901#endif
902
903 if (strcmp(cmd_parameter, "avb_custom_key") == 0) {
904 char* buffer = NULL;
905 char *partition = "misc";
906
907 rc = store_part_size(partition);
908 buffer = (char *)malloc(AVB_CUSTOM_KEY_LEN_MAX);
909 if (!buffer) {
910 printf("malloc error\n");
911 fastboot_fail("malloc error", response);
912 return;
913 }
914 memset(buffer, 0, AVB_CUSTOM_KEY_LEN_MAX);
915
916 store_write((const char *)partition, rc - AVB_CUSTOM_KEY_LEN_MAX,
917 AVB_CUSTOM_KEY_LEN_MAX, (unsigned char *)buffer);
918
919 fastboot_okay(NULL, response);
920 free(buffer);
921 return;
922 }
923
924 if (strcmp(cmd_parameter, "env") == 0) {
925 char *fastboot_step = env_get("fastboot_step");
926
927 if (fastboot_step && strcmp(fastboot_step, "0")) {
928 printf("fastboot_step: %s, run defenv_reserv\n", fastboot_step);
929 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
930 run_command("run bcb_cmd", 0);
931 fastboot_okay(NULL, response);
932 return;
933 }
934 }
935
936 if (strcmp(cmd_parameter, "misc") == 0) {
937 char* buffer = NULL;
938 char *partition = "misc";
939
940 rc = store_part_size(partition);
941 buffer = (char *)malloc(rc - AVB_CUSTOM_KEY_LEN_MAX);
942 if (!buffer) {
943 printf("malloc error\n");
944 fastboot_fail("malloc error", response);
945 return;
946 }
947 memset(buffer, 0, rc - AVB_CUSTOM_KEY_LEN_MAX);
948
949 store_write((const char *)partition, 0, rc - AVB_CUSTOM_KEY_LEN_MAX,
950 (unsigned char *)buffer);
951
952 fastboot_okay(NULL, response);
953 free(buffer);
954 return;
955 }
956
957 if (strcmp(cmd_parameter, "userdata") == 0 || strcmp(cmd_parameter, "data") == 0) {
958 rc = store_part_size("userdata");
959 if (-1 == rc)
960 strcpy(name, "data");
961 else
962 strcpy(name, "userdata");
963 } else if (strcmp(cmd_parameter, "dts") == 0) {
964 strcpy(name, "dtb");
965 } else {
966 strncpy(name, cmd_parameter, 31);
967 }
968 strcat(name, "\0");
969
970#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
971 if (dynamic_partition) {
972 if (is_partition_logical(name) == 0) {
973 printf("logic partition, can not erase here.......\n");
974 fastboot_fail("logic partition", response);
975 return;
976 }
977 }
978#endif
979
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000980#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
Xindong Xud9441422024-01-18 10:20:45 +0800981 fastboot_mmc_erase(name, response);
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000982#endif
983#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
Xindong Xud9441422024-01-18 10:20:45 +0800984 fastboot_nand_erase(name, response);
985#endif
986
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000987#endif
988}
989#endif
Xindong Xud9441422024-01-18 10:20:45 +0800990#endif
991
992#ifdef CONFIG_FASTBOOT_WRITING_CMD
993
994#ifdef CONFIG_AMLOGIC_MODIFY
995static u64 my_ato11(const char *str)
996{
997 u64 result = 0;
998 int len, i;
999
1000 len = strlen(str);
1001 for (i = 0; i < len; i++) {
1002 if (*str >= '0' && *str <= '9')
1003 result = result * 16 + (*str - '0');
1004 else if (*str >= 'A' && *str <= 'F')
1005 result = result * 16 + (*str - 'A') + 10;
1006 else if (*str >= 'a' && *str <= 'f')
1007 result = result * 16 + (*str - 'a') + 10;
1008 str++;
1009 }
1010
1011 return result;
1012}
1013
1014static void fetch(char *cmd_parameter, char *response)
1015{
1016 int len;
1017 int i = 0;
1018 char *cmd;
1019 char name[32] = {0};
1020 u64 offset = 0;
1021 u64 read_size = 0;
1022 size_t size = 0;
1023
1024 if (check_lock() == 1) {
1025 printf("device is locked, can not run this cmd\n");
1026 fastboot_fail("locked device", response);
1027 return;
1028 }
1029
1030 cmd = cmd_parameter;
1031 len = strlen(cmd_parameter);
1032 while (strsep(&cmd, ":"))
1033 i++;
1034
1035 for (cmd = cmd_parameter, i = 0; cmd < (cmd_parameter + len); i++) {
1036 /* Skip to next assignment */
1037 if (i == 0) {
1038 strncpy(name, cmd, 31);
1039 strcat(name, "\0");
1040 } else if (i == 1) {
1041 offset = my_ato11(cmd);
1042 } else if (i == 2) {
1043 read_size = my_ato11(cmd);
1044 }
1045
1046 for (cmd += strlen(cmd); cmd < (cmd_parameter + len) && !*cmd;)
1047 cmd++;
1048 }
1049
1050 printf("name: %s\n", name);
1051 if (strncmp("vendor_boot", name, strlen("vendor_boot")) != 0) {
1052 printf("We can only %s vendor_boot\n", __func__);
1053 fastboot_fail("Fetch is only allowed on vendor_boot", response);
1054 return;
1055 }
1056
1057#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
1058 struct blk_desc *dev_desc;
1059 disk_partition_t part_info;
1060 int r;
1061
1062 r = fastboot_mmc_get_part_info(name, &dev_desc, &part_info,
1063 response);
1064 if (r >= 0)
1065 size = part_info.size * 512;
1066#endif
1067#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
1068 struct part_info *part_info;
1069 int r;
1070
1071 r = fastboot_nand_get_part_info(name, &part_info, response);
1072 if (r >= 0)
1073 size = part_info->size * 512;
1074#endif
1075
1076 if (offset > size) {
1077 printf("Invalid offset: 0x%llx, partition size is 0x%lx\n",
1078 offset, size);
1079 fastboot_fail("Invalid offset", response);
1080 return;
1081 }
1082
1083 if (read_size == 0 || read_size > size - offset ||
1084 read_size > kMaxFetchSizeDefault) {
1085 printf("Invalid read size: 0x%llx, partition size is 0x%lx\n",
1086 offset, size);
1087 fastboot_fail("Invalid read size", response);
1088 return;
1089 }
1090
1091 printf("Start read %s partition datas!\n", name);
1092 void *buffer;
1093 char str[128] = {0};
1094
1095 buffer = (void *)CONFIG_FASTBOOT_BUF_ADDR;
1096 sprintf(str, "DATA%12llx", read_size);
1097 printf("str: %s, len: %ld\n", str, strlen(str));
1098 memcpy(buffer, str, strlen(str));
1099
1100 if (store_read((const char *)name, offset, read_size,
1101 (unsigned char *)buffer + strlen(str)) < 0) {
1102 printf("failed to store read %s.\n", name);
1103 fastboot_fail("read partition data error", response);
1104 return;
1105 }
1106
1107 fastboot_readInfo.transferredBytes = 0;
1108 fastboot_readInfo.totalBytes = read_size + strlen(str);
1109 fastboot_response("DATA", response, "%12llx", read_size);
1110}
1111
1112static void set_active_cmd(char *cmd_parameter, char *response)
1113{
1114 char *cmd;
1115 int ret = 0;
1116 char str[128];
1117
1118 printf("cmd cb_set_active is %s\n", cmd_parameter);
1119 cmd = cmd_parameter;
1120
1121 if (check_lock() == 1) {
1122 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1123 fastboot_fail("locked device", response);
1124 return;
1125 }
1126
1127 sprintf(str, "set_active_slot %s", cmd);
1128 printf("command: %s\n", str);
1129 ret = run_command(str, 0);
1130 printf("ret = %d\n", ret);
1131 if (ret == 0)
1132 fastboot_okay(NULL, response);
1133 else
1134 fastboot_fail("set slot error", response);
1135}
1136
1137#if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
1138static void try_unlock_dev(u64 rc)
1139{
1140#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1141 if (is_avb_arb_available()) {
1142 if (avb_unlock()) {
1143 if (-1 == rc) {
1144 printf("unlocking device. Erasing data partition!\n");
1145 run_command("store erase data 0 0", 0);
1146 } else {
1147 printf("unlocking device. Erasing userdata partition!\n");
1148 run_command("store erase userdata 0 0", 0);
1149 }
1150 printf("unlocking device. Erasing metadata partition!\n");
1151 run_command("store erase metadata 0 0", 0);
1152 } else {
1153 printf("unlock failed!\n");
1154 }
1155
1156 return;
1157 }
1158#endif
1159 if (-1 == rc) {
1160 printf("unlocking device. Erasing data partition!\n");
1161 run_command("store erase data 0 0", 0);
1162 } else {
1163 printf("unlocking device. Erasing userdata partition!\n");
1164 run_command("store erase userdata 0 0", 0);
1165 }
1166 printf("unlocking device. Erasing metadata partition!\n");
1167 run_command("store erase metadata 0 0", 0);
1168}
1169
1170static void try_lock_dev(u64 rc)
1171{
1172#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1173 if (is_avb_arb_available()) {
1174 if (avb_lock()) {
1175 if (-1 == rc) {
1176 printf("locking device. Erasing data partition!\n");
1177 run_command("store erase data 0 0", 0);
1178 } else {
1179 printf("locking device. Erasing userdata partition!\n");
1180 run_command("store erase userdata 0 0", 0);
1181 }
1182 printf("locking device. Erasing metadata partition!\n");
1183 run_command("store erase metadata 0 0", 0);
1184 } else {
1185 printf("lock failed!\n");
1186 }
1187
1188 return;
1189 }
1190#endif
1191 if (-1 == rc) {
1192 printf("locking device. Erasing data partition!\n");
1193 run_command("store erase data 0 0", 0);
1194 } else {
1195 printf("locking device. Erasing userdata partition!\n");
1196 run_command("store erase userdata 0 0", 0);
1197 }
1198 printf("locking device. Erasing metadata partition!\n");
1199 run_command("store erase metadata 0 0", 0);
1200}
1201
1202/**
1203 * flashing() - lock/unlock.
1204 *
1205 * @cmd_parameter: Pointer to partition name
1206 * @response: Pointer to fastboot response buffer
1207 *
1208 * Writes the previously downloaded image to the partition indicated by
1209 * cmd_parameter. Writes to response.
1210 */
1211static void flashing(char *cmd_parameter, char *response)
1212{
1213 char *cmd;
1214 char* lock_s;
1215 LockData_t info = {0};
1216 char lock_d[LOCK_DATA_SIZE];
1217 u64 rc;
1218 int debug_flag = 0;
1219
Xindong Xu2e748322024-11-22 09:24:46 +08001220#ifndef CONFIG_REFERENCE
Xindong Xud9441422024-01-18 10:20:45 +08001221 if (IS_FEAT_BOOT_VERIFY()) {
1222 printf("device is secure mode, can not run this cmd.\n");
1223 fastboot_fail("secure boot device", response);
1224 return;
1225 }
Xindong Xu2e748322024-11-22 09:24:46 +08001226#endif
Xindong Xud9441422024-01-18 10:20:45 +08001227
1228 lock_s = env_get("lock");
1229 if (!lock_s) {
1230 printf("lock state is NULL \n");
1231 memcpy(lock_d, "10101000", 8);
1232 lock_s = "10101000";
1233 env_set("lock", "10101000");
1234#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1235 run_command("update_env_part -p lock;", 0);
1236#else
1237 run_command("defenv_reserv; saveenv;", 0);
1238#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1239 } else {
1240 printf("lock state: %s\n", lock_s);
1241 if (strlen(lock_s) > 15)
1242 strncpy(lock_d, lock_s, 15);
1243 else
1244 strncpy(lock_d, lock_s, strlen(lock_s));
1245 }
1246
1247 info.version_major = (int)(lock_d[0] - '0');
1248 info.version_minor = (int)(lock_d[1] - '0');
1249 info.unlock_ability = (int)(lock_d[2] - '0');
1250 info.lock_state = (int)(lock_d[4] - '0');
1251 info.lock_critical_state = (int)(lock_d[5] - '0');
1252 info.lock_bootloader = (int)(lock_d[6] - '0');
1253 dump_lock_info(info);
1254
1255 printf("cb_flashing cmd_parameter: %s\n", cmd_parameter);
1256 cmd = cmd_parameter;
1257 strsep(&cmd, " ");
1258 printf("cb_flashing: %s\n", cmd);
1259 if (!cmd) {
1260 printf("missing variable\n");
1261 fastboot_fail("missing var", response);
1262 return;
1263 }
1264
1265 boot_img_hdr_t *hdr_addr = NULL;
1266 const int preloadsz = 0x1000 * 2;//4k not enough for signed
1267 unsigned char *pbuffpreload = 0;
1268 char partname[32] = {0};
1269 char *slot_name;
1270 char cmdline[4096];
1271 char *result = NULL;
1272
1273 slot_name = env_get("slot-suffixes");
1274 if (slot_name && (strcmp(slot_name, "0") == 0))
1275 strcpy((char *)partname, "boot_a");
1276 else if (slot_name && (strcmp(slot_name, "1") == 0))
1277 strcpy((char *)partname, "boot_b");
1278 else
1279 strcpy((char *)partname, "boot");
1280
1281 pbuffpreload = malloc(preloadsz);
1282 if (!pbuffpreload) {
1283 printf("Fail to allocate memory!\n");
1284 goto next;
1285 }
1286
1287 hdr_addr = (boot_img_hdr_t *)pbuffpreload;
1288
1289 printf("read from part: %s\n", partname);
1290 rc = store_logic_read(partname, 0, preloadsz, pbuffpreload);
1291 if (rc) {
1292 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1293 preloadsz, partname);
1294 free(pbuffpreload);
1295 pbuffpreload = 0;
1296 goto next;
1297 }
1298
1299 if (is_android_r_image((void *)hdr_addr)) {
1300 char partname_r[32] = {0};
1301 const int preloadsz_r = 0x1000 * 2;//4k not enough for signed
1302 unsigned char *pbuffpreload_r = 0;
1303 int ret_r = __LINE__;
1304
1305 if (slot_name && (strcmp(slot_name, "0") == 0))
1306 strcpy((char *)partname_r, "vendor_boot_a");
1307 else if (slot_name && (strcmp(slot_name, "1") == 0))
1308 strcpy((char *)partname_r, "vendor_boot_b");
1309 else
1310 strcpy((char *)partname_r, "vendor_boot");
1311
1312 pbuffpreload_r = malloc(preloadsz_r);
1313
1314 if (!pbuffpreload_r) {
1315 printf("Fail to allocate memory for %s!\n",
1316 partname_r);
1317 goto next;
1318 }
1319
1320 printf("read from part: %s\n", partname_r);
1321 ret_r = store_logic_read(partname_r, 0,
1322 preloadsz_r, pbuffpreload_r);
1323 if (ret_r) {
1324 printf("Fail to read 0x%xB from part[%s] at offset 0\n",
1325 preloadsz_r, partname_r);
1326 free(pbuffpreload_r);
1327 pbuffpreload_r = 0;
1328 goto next;
1329 }
1330
1331 p_vendor_boot_img_hdr_t vb_hdr = (p_vendor_boot_img_hdr_t)pbuffpreload_r;
1332
1333 if (*vb_hdr->cmdline) {
1334 printf("Kernel command line: %s\n", vb_hdr->cmdline);
1335 sprintf(cmdline, "%s", vb_hdr->cmdline);
1336 }
1337 free(pbuffpreload_r);
1338 pbuffpreload_r = 0;
1339 } else {
1340 if (*hdr_addr->cmdline) {
1341 printf("Kernel command line: %s\n", hdr_addr->cmdline);
1342 sprintf(cmdline, "%s", hdr_addr->cmdline);
1343 }
1344 }
1345
1346 free(pbuffpreload);
1347 pbuffpreload = 0;
1348
1349 result = strtok(cmdline, " ");
1350 while (result) {
1351 printf("result: %s\n", result);
1352 if (strcmp(result, "buildvariant=userdebug") == 0 ||
1353 strcmp(result, "buildvariant=eng") == 0)
1354 debug_flag = 1;
1355 result = strtok(NULL, " ");
1356 }
1357
1358 if (info.unlock_ability == 0 && debug_flag == 1) {
1359 printf("userdebug mode can ignore\n");
1360 info.unlock_ability = 1;
1361 }
1362
1363next:
1364 rc = store_part_size("userdata");
1365
1366 if (!strcmp_l1("unlock_critical", cmd)) {
1367 info.lock_critical_state = 0;
1368 fastboot_okay(NULL, response);
1369 } else if (!strcmp_l1("lock_critical", cmd)) {
1370 info.lock_critical_state = 1;
1371 fastboot_okay(NULL, response);
1372 } else if (!strcmp_l1("get_unlock_ability", cmd)) {
1373 char str[32];
1374 static bool is_unlock_ability_sent = false;
1375 if (is_unlock_ability_sent) {
1376 is_unlock_ability_sent = false;
1377 fastboot_okay(NULL, response);
1378 busy_flag = 0;
1379 } else {
1380 sprintf(str, "get_unlock_ability: %d",
1381 info.unlock_ability);
1382 fastboot_response("INFO", response, "%s", str);
1383 is_unlock_ability_sent = true;
1384 busy_flag = 1;
1385 }
1386 return;
1387 } else if (!strcmp_l1("get_unlock_bootloader_nonce", cmd)) {
1388 char str_num[8];
1389 sprintf(str_num, "%d", info.lock_critical_state);
1390 fastboot_response("OKAY", response, "%s", str_num);
1391 } else if (!strcmp_l1("lock_bootloader", cmd)) {
1392 info.lock_bootloader = 1;
1393 } else if (!strcmp_l1("unlock", cmd)) {
hao.qi40c37a02024-07-15 13:40:47 +08001394#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
hao.qi0696a542024-09-12 14:58:03 +08001395 u32 rpmb_lock_state = 0;
1396 bool ret = get_avb_lock_state(&rpmb_lock_state);
hao.qi40c37a02024-07-15 13:40:47 +08001397
hao.qi0696a542024-09-12 14:58:03 +08001398 if (info.lock_state == 1 || (ret && rpmb_lock_state == 1)) {
hao.qi40c37a02024-07-15 13:40:47 +08001399#else
hao.qi0696a542024-09-12 14:58:03 +08001400 if (info.lock_state == 1) {
hao.qi40c37a02024-07-15 13:40:47 +08001401#endif
Xindong Xuac88caf2024-10-28 17:10:12 +08001402#ifdef CONFIG_AVB2
1403 try_unlock_dev(rc);
1404#endif
Xindong Xud9441422024-01-18 10:20:45 +08001405 }
hao.qi0696a542024-09-12 14:58:03 +08001406 info.lock_state = 0;
1407 info.lock_critical_state = 0;
1408 env_set("lock_state", "green");
1409 fastboot_okay(NULL, response);
Xindong Xud9441422024-01-18 10:20:45 +08001410 } else if (!strcmp_l1("lock", cmd)) {
hao.qi40c37a02024-07-15 13:40:47 +08001411#if defined(CONFIG_AML_ANTIROLLBACK) || defined(CONFIG_AML_AVB2_ANTIROLLBACK)
1412 u32 rpmb_lock_state = 0;
1413 bool ret = get_avb_lock_state(&rpmb_lock_state);
1414
1415 if (info.lock_state == 0 || (ret && rpmb_lock_state == 0)) {
1416#else
Xindong Xud9441422024-01-18 10:20:45 +08001417 if (info.lock_state == 0) {
hao.qi40c37a02024-07-15 13:40:47 +08001418#endif
Xindong Xuac88caf2024-10-28 17:10:12 +08001419#ifdef CONFIG_AVB2
1420 try_lock_dev(rc);
1421#endif
Xindong Xud9441422024-01-18 10:20:45 +08001422 }
1423 info.lock_state = 1;
1424 env_set("lock_state", "orange");
1425 fastboot_okay(NULL, response);
1426 } else {
1427 printf("unknown variable: %s\n", cmd);
1428 fastboot_response("FAIL", response, "%s", "Variable not implemented");
1429 }
1430
1431 sprintf(lock_d, "%d%d%d0%d%d%d0", info.version_major, info.version_minor,
1432 info.unlock_ability, info.lock_state, info.lock_critical_state,
1433 info.lock_bootloader);
1434 printf("lock_d state: %s\n", lock_d);
1435 env_set("lock", lock_d);
1436#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1437 run_command("update_env_part -p lock;", 0);
1438#else
1439 run_command("defenv_reserv; saveenv;", 0);
1440#endif//#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
1441 return;
1442}
1443#endif// #if !CONFIG_IS_ENABLED(NO_FASTBOOT_FLASHING)
1444#endif
1445#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001446
Heiko Schocherbc820d52021-02-10 09:29:03 +01001447#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
1448/**
1449 * run_ucmd() - Execute the UCmd command
1450 *
1451 * @cmd_parameter: Pointer to command parameter
1452 * @response: Pointer to fastboot response buffer
1453 */
1454static void run_ucmd(char *cmd_parameter, char *response)
1455{
1456 if (!cmd_parameter) {
1457 pr_err("missing slot suffix\n");
1458 fastboot_fail("missing command", response);
1459 return;
1460 }
1461
1462 if (run_command(cmd_parameter, 0))
1463 fastboot_fail("", response);
1464 else
1465 fastboot_okay(NULL, response);
1466}
1467
1468static char g_a_cmd_buff[64];
1469
1470void fastboot_acmd_complete(void)
1471{
1472 run_command(g_a_cmd_buff, 0);
1473}
1474
1475/**
1476 * run_acmd() - Execute the ACmd command
1477 *
1478 * @cmd_parameter: Pointer to command parameter
1479 * @response: Pointer to fastboot response buffer
1480 */
1481static void run_acmd(char *cmd_parameter, char *response)
1482{
1483 if (!cmd_parameter) {
1484 pr_err("missing slot suffix\n");
1485 fastboot_fail("missing command", response);
1486 return;
1487 }
1488
1489 if (strlen(cmd_parameter) > sizeof(g_a_cmd_buff)) {
1490 pr_err("too long command\n");
1491 fastboot_fail("too long command", response);
1492 return;
1493 }
1494
1495 strcpy(g_a_cmd_buff, cmd_parameter);
1496 fastboot_okay(NULL, response);
1497}
1498#endif
1499
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001500/**
1501 * reboot_bootloader() - Sets reboot bootloader flag.
1502 *
1503 * @cmd_parameter: Pointer to command parameter
1504 * @response: Pointer to fastboot response buffer
1505 */
1506static void reboot_bootloader(char *cmd_parameter, char *response)
1507{
Xindong Xud9441422024-01-18 10:20:45 +08001508#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi851737a2020-07-28 23:35:32 +03001509 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_BOOTLOADER))
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001510 fastboot_fail("Cannot set reboot flag", response);
1511 else
Xindong Xud9441422024-01-18 10:20:45 +08001512#endif
Alex Kiernanf73a7df2018-05-29 15:30:53 +00001513 fastboot_okay(NULL, response);
1514}
Alex Kiernan3845b902018-05-29 15:30:54 +00001515
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001516/**
1517 * reboot_fastbootd() - Sets reboot fastboot flag.
1518 *
1519 * @cmd_parameter: Pointer to command parameter
1520 * @response: Pointer to fastboot response buffer
1521 */
1522static void reboot_fastbootd(char *cmd_parameter, char *response)
1523{
Xindong Xud9441422024-01-18 10:20:45 +08001524#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001525 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_FASTBOOTD))
Xindong Xud9441422024-01-18 10:20:45 +08001526 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001527 else
Xindong Xud9441422024-01-18 10:20:45 +08001528#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001529 fastboot_okay(NULL, response);
1530}
1531
1532/**
1533 * reboot_recovery() - Sets reboot recovery flag.
1534 *
1535 * @cmd_parameter: Pointer to command parameter
1536 * @response: Pointer to fastboot response buffer
1537 */
1538static void reboot_recovery(char *cmd_parameter, char *response)
1539{
Xindong Xud9441422024-01-18 10:20:45 +08001540#ifndef CONFIG_AMLOGIC_MODIFY
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001541 if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_RECOVERY))
Xindong Xud9441422024-01-18 10:20:45 +08001542 fastboot_fail("Cannot set reboot flag", response);
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001543 else
Xindong Xud9441422024-01-18 10:20:45 +08001544#endif
Roman Kovalivskyi2b2a7712020-07-28 23:35:33 +03001545 fastboot_okay(NULL, response);
1546}
1547
Xindong Xud9441422024-01-18 10:20:45 +08001548#ifdef CONFIG_FASTBOOT_WRITING_CMD
Alex Kiernan3845b902018-05-29 15:30:54 +00001549#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
1550/**
1551 * oem_format() - Execute the OEM format command
1552 *
1553 * @cmd_parameter: Pointer to command parameter
1554 * @response: Pointer to fastboot response buffer
1555 */
1556static void oem_format(char *cmd_parameter, char *response)
1557{
1558 char cmdbuf[32];
1559
Xindong Xud9441422024-01-18 10:20:45 +08001560#ifdef CONFIG_AMLOGIC_MODIFY
Xindong Xu2e748322024-11-22 09:24:46 +08001561#ifndef CONFIG_REFERENCE
Xindong Xud9441422024-01-18 10:20:45 +08001562 if (IS_FEAT_BOOT_VERIFY()) {
1563 printf("device is secure mode, can not run this cmd.\n");
1564 fastboot_fail("secure boot device", response);
1565 return;
1566 }
Xindong Xu2e748322024-11-22 09:24:46 +08001567#endif
Xindong Xud9441422024-01-18 10:20:45 +08001568
1569 if (check_lock() == 1) {
1570 printf("device is locked, can not run this cmd.Please flashing unlock & flashing unlock_critical\n");
1571 fastboot_fail("locked device", response);
1572 return;
1573 }
1574#endif
1575
Alex Kiernan3845b902018-05-29 15:30:54 +00001576 if (!env_get("partitions")) {
1577 fastboot_fail("partitions not set", response);
1578 } else {
1579 sprintf(cmdbuf, "gpt write mmc %x $partitions",
1580 CONFIG_FASTBOOT_FLASH_MMC_DEV);
1581 if (run_command(cmdbuf, 0))
1582 fastboot_fail("", response);
1583 else
1584 fastboot_okay(NULL, response);
1585 }
1586}
1587#endif
Patrick Delaunayb2f6b972021-01-27 14:46:48 +01001588
1589#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
1590/**
1591 * oem_partconf() - Execute the OEM partconf command
1592 *
1593 * @cmd_parameter: Pointer to command parameter
1594 * @response: Pointer to fastboot response buffer
1595 */
1596static void oem_partconf(char *cmd_parameter, char *response)
1597{
1598 char cmdbuf[32];
1599
1600 if (!cmd_parameter) {
1601 fastboot_fail("Expected command parameter", response);
1602 return;
1603 }
1604
1605 /* execute 'mmc partconfg' command with cmd_parameter arguments*/
1606 snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0",
1607 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1608 printf("Execute: %s\n", cmdbuf);
1609 if (run_command(cmdbuf, 0))
1610 fastboot_fail("Cannot set oem partconf", response);
1611 else
1612 fastboot_okay(NULL, response);
1613}
1614#endif
Patrick Delaunay0c0394b2021-01-27 14:46:49 +01001615
1616#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
1617/**
1618 * oem_bootbus() - Execute the OEM bootbus command
1619 *
1620 * @cmd_parameter: Pointer to command parameter
1621 * @response: Pointer to fastboot response buffer
1622 */
1623static void oem_bootbus(char *cmd_parameter, char *response)
1624{
1625 char cmdbuf[32];
1626
1627 if (!cmd_parameter) {
1628 fastboot_fail("Expected command parameter", response);
1629 return;
1630 }
1631
1632 /* execute 'mmc bootbus' command with cmd_parameter arguments*/
1633 snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s",
1634 CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
1635 printf("Execute: %s\n", cmdbuf);
1636 if (run_command(cmdbuf, 0))
1637 fastboot_fail("Cannot set oem bootbus", response);
1638 else
1639 fastboot_okay(NULL, response);
1640}
1641#endif
Xindong Xud9441422024-01-18 10:20:45 +08001642#endif