blob: 02bd04d2582a07267ff49d3ee256e092d19f1618 [file] [log] [blame]
Bo Lv72d0e902023-01-02 14:27:34 +00001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include <config.h>
7#include <common.h>
8#include <linux/kernel.h>
9#include <amlogic/aml_efuse.h>
10#include <amlogic/cpu_id.h>
11#include <amlogic/storage.h>
12#include <amlogic/partition_table.h>
13#include <fastboot.h>
14#include <amlogic/emmc_partitions.h>
15#include <asm/amlogic/arch/efuse.h>
16#include <android_image.h>
17#include <amlogic/android_vab.h>
Mingyen Hung6e468002023-01-04 23:43:04 -080018#include <amlogic/aml_rollback.h>
Xindong Xu22e8daf2024-03-12 18:08:41 +080019#include <cli.h>
Bo Lv72d0e902023-01-02 14:27:34 +000020
21#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
22extern efuse_obj_field_t efuse_field;
23#endif//#ifdef CONFIG_EFUSE_OBJ_API
24
Bo Lv72d0e902023-01-02 14:27:34 +000025int __attribute__((weak)) store_logic_read(const char *name, loff_t off, size_t size, void *buf)
26{ return store_read(name, off, size, buf);}
27
Bo Lv72d0e902023-01-02 14:27:34 +000028#define debugP(fmt...) //printf("[DbgBootSta]L%d:", __LINE__),printf(fmt)
29#define errorP(fmt...) printf("ErrBootSta(L%d):", __LINE__),printf(fmt)
30#define wrnP(fmt...) printf("wrn:"fmt)
31#define MsgP(fmt...) printf("[BootSta]"fmt)
32
33#define BOOTLOADER_OFFSET 512
34#define BOOTLOADER_MAX_SIZE (4 * 1024 * 1024)
Zhigang Yude5719e2024-03-08 09:14:23 +000035#define MIB_SIZE (1024 * 1024)
36
Bo Lv72d0e902023-01-02 14:27:34 +000037
38//check SWPL-31296 for details
39static int do_get_bootloader_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
40{
41 bool printStat = false;
42 bool saveenv = false;
43 debugP("Initial value for argc=%d\n", argc);
44 while (argc > 1 && **(argv + 1) == '-') {
45 char *arg = *++argv;
46
47 --argc;
48 while (*++arg) {
49 switch (*arg) {
50 case 'p': /* print */
51 printStat = true;
52 break;
53 case 's': /* saveenv */
54 saveenv = true;
55 break;
56 default:
57 return CMD_RET_USAGE;
58 }
59 }
60 }
61 debugP("Final value for argc=%d\n", argc);
62 //1,forUpgrade_socType, cpu familyId
63 const cpu_id_t cpuid = get_cpu_id();
64 const int familyId = cpuid.family_id;
65 env_set_hex("forUpgrade_socType", familyId);
66
67 //2,forUpgrade_secureBoot
68 const bool secureboot = IS_FEAT_BOOT_VERIFY();
69 env_set("forUpgrade_secureBoot", secureboot ? "true" : "false");
70
71 //3,forUpgrade_robustOta
72 bool supportRobustOta = false;
73 switch (familyId) {
74 case 0x32://sc2
75 case 0x36://t7
76 case 0x37://s4
77 case 0x38://t3
78 case 0x3A://s4d
79 supportRobustOta = true;
80 break;
81 default:
82 {
83 if (familyId > 0x3A) {
84 supportRobustOta = true;
85 }
86 }
87 break;
88 }
89 env_set("forUpgrade_robustOta", supportRobustOta ? "true" : "false");
90
91 //4,forUpgrade_flashType
92 const char* BootDevices[] = {
93 "BOOT_EMMC", "BOOT_SD",
94 "BOOT_NAND_NFTL", "BOOT_NAND_MTD",
95 "BOOT_SNAND", "BOOT_SNOR",
96 };
97 const char* bootDevice = "BOOT_NONE";
98 enum boot_type_e bootType = store_get_type();
99 int i = 0;
100 for (; i < ARRAY_SIZE(BootDevices); ++i) {
101 if ((1<<i) != bootType) continue;
102 bootDevice = BootDevices[i];
103 break;
104 }
105 env_set("forUpgrade_flashType", bootDevice);
106
107 //5,forUpgrade_bootloaderCopies, how many copies supported
108 int bootCopies = 1;
109 switch (bootType) {
110 case BOOT_EMMC: bootCopies = 3; break;
111 default:break;
112 }
113 env_set_ulong("forUpgrade_bootloaderCopies", bootCopies);
114
115 //6,forUpgrade_bootloaderIndex
116 //for emmc, 0/1/2 is user/boot0/boot1
117 const int bootCpyIndex = store_bootup_bootidx("bootloader");
118 env_set_ulong("forUpgrade_bootloaderIndex", bootCpyIndex);
119
120 //7,get first boot index, for defendkey
121 const int firstBootCpyIndex = store_boot_copy_start();
122 env_set_ulong("forUpgrade_1stBootIndex", firstBootCpyIndex);
123
124 if (printStat) run_command("printenv forUpgrade_socType forUpgrade_secureBoot "
125 " forUpgrade_robustOta forUpgrade_flashType forUpgrade_bootloaderCopies "
126 " forUpgrade_bootloaderIndex forUpgrade_1stBootIndex", 0);
127
Sam Wu6f3d40e2023-04-22 01:10:27 +0800128 if (saveenv) {
129 if (CONFIG_IS_ENABLED(AML_UPDATE_ENV))
130 run_command("update_env_part -p forUpgrade_robustOta "\
131 "forUpgrade_bootloaderIndex", 0);
132 else
133 run_command("saveenv", 0);
134 }
135
Bo Lv72d0e902023-01-02 14:27:34 +0000136
137 return CMD_RET_SUCCESS;
138}
139
140static void run_recovery_from_flash(void) {
141 env_set("dolby_status","0");
142 run_command("run init_display", 0);
143 run_command("run storeargs", 0);
144 run_command("get_rebootmode", 0);
145 run_command("if test ${reboot_mode} = quiescent; then "\
146 "setenv bootconfig ${bootconfig} androidboot.quiescent=1; fi;", 0);
147 run_command("if test ${reboot_mode} = recovery_quiescent; then "\
148 "setenv bootconfig ${bootconfig} androidboot.quiescent=1; fi;", 0);
149 run_command("run recovery_from_flash", 0);
150}
151
Bo Lv72d0e902023-01-02 14:27:34 +0000152int write_bootloader_back(const char* bootloaderindex, int dstindex) {
153 int iRet = 0;
154 int copy = 0;
155 int ret = -1;
156 unsigned char* buffer = NULL;
157 int capacity_boot = 0;
158
159 if (strcmp(bootloaderindex, "1") == 0) {
160 copy = 1;
161 } else if (strcmp(bootloaderindex, "2") == 0) {
162 copy = 2;
163 } else if (strcmp(bootloaderindex, "0") == 0) {
164 copy = 0;
165 }
166
167#ifdef CONFIG_MMC_MESON_GX
168 struct mmc *mmc = NULL;
169
170 if (store_get_type() == BOOT_EMMC)
171 mmc = find_mmc_device(1);
172
173 if (mmc)
174 capacity_boot = mmc->capacity_boot;
175#endif
176
177 printf("write_bootloader_back_capacity_boot: %x\n", capacity_boot);
178
179 buffer = (unsigned char *)malloc(capacity_boot);
180 if (!buffer)
181 {
182 printf("ERROR! fail to allocate memory ...\n");
183 goto exit;
184 }
185 memset(buffer, 0, capacity_boot);
186 iRet = store_boot_read("bootloader", copy, 0, buffer);
187 if (iRet) {
188 errorP("Fail read bootloader from rsv with sz\n");
189 goto exit;
190 }
191 iRet = store_boot_write("bootloader", dstindex, 0, buffer);
192 if (iRet) {
193 printf("Failed to write bootloader\n");
194 goto exit;
195 } else {
196 ret = 0;
197 }
198
199exit:
200 if (buffer)
201 {
202 free(buffer);
203 //buffer = NULL;
204 }
205 return ret;
206}
207
208//bootloader write protect
209static void bootloader_wp(void)
210{
211#ifdef CONFIG_MMC_MESON_GX
212 if (store_get_type() == BOOT_EMMC) {//emmc device
213 if (IS_FEAT_BOOT_VERIFY()) { //secure boot enable
214 if (BOOTLOADER_MODE_ADVANCE_INIT) { //new arch chip
215 env_set("bootloader_wp", "1");
216 }
217 }
218 }
219#endif
220}
221
222static void aml_recovery(void) {
223 char *mode = NULL;
224 char command[32];
225 char miscbuf[4096] = {0};
226
227 run_command("get_rebootmode", 0);
228
229 //get reboot_mode
230 mode = env_get("reboot_mode");
231 if (mode == NULL) {
232 wrnP("can not get reboot mode, so skip recovery check\n");
233 } else {
234 if ((!strcmp(mode, "factory_reset")) || (!strcmp(mode, "update"))) {
235 env_set("dolby_status","0");
236 }
237 }
238
239#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
240 int ret = 0;
241 extern int boot_info_open_partition(char *miscbuf);
242 ret = boot_info_open_partition(miscbuf);
243 if (ret != 0) {
244 wrnP("open misc partition failed, so skip recovery check");
245 return;
246 }
247#endif
248
249 //if run recovery, need disable dolby
250 memcpy(command, miscbuf, 32);
251 if (!memcmp(command, "boot-recovery", strlen("boot-recovery"))) {
252 env_set("dolby_status","0");
253 return;
254 }
255}
256
257void update_rollback(void)
258{
259 char *slot = NULL;
260 int ret = -1;
261 int gpt_flag = -1;
262
263#ifdef CONFIG_MMC_MESON_GX
264 struct mmc *mmc = NULL;
265
266 if (store_get_type() == BOOT_EMMC)
267 mmc = find_mmc_device(1);
268
269 if (mmc)
270 gpt_flag = aml_gpt_valid(mmc);
271#endif
272 if (gpt_flag == 0)
273 ret = 0;
274
275#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
276 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
277
278 //dis_user_flag = run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
279 if (*efuse_field.data == 1)
280 ret = 0;
281#endif//#ifdef CONFIG_EFUSE_OBJ_API
282
283 slot = env_get("slot-suffixes");
284 if (!slot) {
285 run_command("get_valid_slot", 0);
286 slot = env_get("slot-suffixes");
287 }
288 if (strcmp(slot, "0") == 0) {
289 if (ret != 0) {
290 wrnP("normal mode\n");
291 write_bootloader_back("2", 0);
292 env_set("expect_index", "0");
293 } else {
294 wrnP("gpt or disable user bootloader mode\n");
295 write_bootloader_back("2", 1);
296 env_set("expect_index", "1");
297 }
298 wrnP("back to slot b\n");
299 run_command("set_roll_flag 1", 0);
300 run_command("set_active_slot b", 0);
301 } else if (strcmp(slot, "1") == 0) {
302 if (ret != 0) {
303 wrnP("normal mode\n");
304 write_bootloader_back("1", 0);
305 env_set("expect_index", "0");
306 } else {
307 wrnP("gpt or disable user bootloader mode\n");
308 write_bootloader_back("2", 1);
309 env_set("expect_index", "1");
310 }
311 wrnP("back to slot a\n");
312 run_command("set_roll_flag 1", 0);
313 run_command("set_active_slot a", 0);
314 }
315 env_set("update_env", "1");
316 env_set("reboot_status", "reboot_next");
317}
318
Zhigang Yude5719e2024-03-08 09:14:23 +0000319static int write_bootloader(int i)
Bo Lv72d0e902023-01-02 14:27:34 +0000320{
321 unsigned char *buffer = NULL;
Sam Wu6f3d40e2023-04-22 01:10:27 +0800322 int capacity_boot = 0x2000 * 512;
Zhigang Yu6852d932024-02-26 11:32:53 +0000323 int iret = 0;
Bo Lv72d0e902023-01-02 14:27:34 +0000324 char partname[32] = {0};
325 char *slot_name = NULL;
326
327#ifdef CONFIG_MMC_MESON_GX
328 struct mmc *mmc = NULL;
329
330 if (store_get_type() == BOOT_EMMC)
331 mmc = find_mmc_device(1);
332
333 if (mmc)
334 capacity_boot = mmc->capacity_boot;
335#endif
336 printf("capacity_boot: 0x%x\n", capacity_boot);
337 buffer = (unsigned char *)malloc(capacity_boot);
338 if (!buffer) {
339 printf("ERROR! fail to allocate memory ...\n");
340 return -1;
341 }
342 memset(buffer, 0, capacity_boot);
343
344 slot_name = env_get("active_slot");
345 if (slot_name && (strcmp(slot_name, "_a") == 0))
346 strcpy((char *)partname, "bootloader_a");
347 else if (slot_name && (strcmp(slot_name, "_b") == 0))
348 strcpy((char *)partname, "bootloader_b");
Zhigang Yude5719e2024-03-08 09:14:23 +0000349 else
350 strcpy((char *)partname, "bootloader_up");
Bo Lv72d0e902023-01-02 14:27:34 +0000351
Zhigang Yu6852d932024-02-26 11:32:53 +0000352 iret = store_logic_read(partname, 0, BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, buffer);
353 if (iret) {
Bo Lv72d0e902023-01-02 14:27:34 +0000354 errorP("Fail to read 0x%xB from part[%s] at offset 0\n",
355 BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, partname);
Sam Wu6f3d40e2023-04-22 01:10:27 +0800356 free(buffer);
Bo Lv72d0e902023-01-02 14:27:34 +0000357 return -1;
358 }
359
Zhigang Yude5719e2024-03-08 09:14:23 +0000360 iret = store_boot_write("bootloader", i, BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, buffer);
Zhigang Yu6852d932024-02-26 11:32:53 +0000361 if (iret) {
Bo Lv72d0e902023-01-02 14:27:34 +0000362 printf("Failed to write boot0\n");
Sam Wu6f3d40e2023-04-22 01:10:27 +0800363 free(buffer);
Bo Lv72d0e902023-01-02 14:27:34 +0000364 return -1;
365 }
Sam Wu6f3d40e2023-04-22 01:10:27 +0800366
367 free(buffer);
Bo Lv72d0e902023-01-02 14:27:34 +0000368 return 0;
369}
370
371/**
372 *set merge status
373*/
374int set_mergestatus_cancel(struct misc_virtual_ab_message *message)
375{
376 char *partition = "misc";
377 char vab_buf[1024] = {0};
378
379 if (store_read((const char *)partition,
380 SYSTEM_SPACE_OFFSET_IN_MISC, 1024, (unsigned char *)vab_buf) < 0) {
381 printf("failed to store read %s.\n", partition);
382 return -1;
383 }
384
385 memcpy(message, vab_buf, sizeof(struct misc_virtual_ab_message));
386 printf("message.merge_status: %d\n", message->merge_status);
387 if (message->merge_status == SNAPSHOTTED || message->merge_status == MERGING) {
388 message->merge_status = CANCELLED;
389 printf("set message.merge_status CANCELLED\n");
390 }
391 store_write((const char *)partition, SYSTEM_SPACE_OFFSET_IN_MISC, 1024, (unsigned char *)vab_buf);
392 return 0;
393}
394
hao.qi4c4dc762024-03-11 10:38:23 +0800395// according to the value of the board,
396// reset the product to set the serial
397// to distinguish different products.
398void set_product(void)
399{
400 char *board = env_get("board");
401 char *str = NULL;
402 char *dup_str = NULL;
403
404 str = strstr(board, "_");
405 dup_str = strdup(str);
406 if (!(strstr(dup_str, "_")))
407 env_set("product", str + 1);
408 else
409 env_set("product", strtok(str, "_"));
410 free(dup_str);
411}
412
Zhigang Yude5719e2024-03-08 09:14:23 +0000413void fastboot_step_check(char *rebootmode, int gpt_flag)
414{
415 char *bootloaderindex = NULL;
416 struct mmc *mmc = NULL;
417
418 if (store_get_type() == BOOT_EMMC)
419 mmc = find_mmc_device(1);
420
421 //get bootloader index
422 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
423 if (!bootloaderindex) {
424 wrnP("can not get bootloader index, so skip fastboot step check\n");
425 return;
426 }
427
428 char *fastboot_step = env_get("fastboot_step");
429
430 if (mmc && fastboot_step && (strcmp(fastboot_step, "1") == 0)) {
431 printf("reboot to new bootloader burned by fastboot\n");
432 env_set("update_env", "1");
433 env_set("fastboot_step", "2");
434 run_command("saveenv", 0);
435 if (rebootmode && (strcmp(rebootmode, "fastboot") == 0))
436 run_command("reboot next,bootloader", 0);
437 else
438 run_command("reboot next", 0);
439 }
440 if (mmc && fastboot_step && (strcmp(fastboot_step, "2") == 0)) {
441 struct blk_desc *dev_desc = mmc_get_blk_desc(mmc);
442
443 if (dev_desc && ((gpt_flag == 1 && !strcmp(bootloaderindex, "1")) ||
444 (gpt_flag == 0 && !strcmp(bootloaderindex, "0")))) {
445 printf("new bootloader error, please fastboot to another one\n");
446 env_set("fastboot_step", "0");
447 if (CONFIG_IS_ENABLED(AML_UPDATE_ENV))
448 run_command("update_env_part -p fastboot_step;", 0);
449 else
450 run_command("defenv_reserve;setenv fastboot_step 0;saveenv;", 0);
451 cli_init();
452 cli_loop();
453 }
454 }
455}
456
Xindong Xu15e83fa2024-03-15 08:56:00 +0800457static int update_gpt(int flag)
458{
459 int ret = 0;
460#ifdef CONFIG_MMC_MESON_GX
461 unsigned char *buffer = NULL;
462 int capacity_boot = 0x2000 * 512;
463 int iRet = 0;
464 struct mmc *mmc = NULL;
465 struct blk_desc *dev_desc;
466
467 if (store_get_type() == BOOT_EMMC)
468 mmc = find_mmc_device(1);
469
470 if (mmc)
471 capacity_boot = mmc->capacity_boot;
472
473 printf("capacity_boot: 0x%x\n", capacity_boot);
474 buffer = (unsigned char *)malloc(capacity_boot);
475 if (!buffer) {
476 printf("ERROR! fail to allocate memory ...\n");
477 return -1;
478 }
479 memset(buffer, 0, capacity_boot);
480
481 if (flag == 0) {
482 iRet = store_boot_read("bootloader", 1, 0, buffer);
483 if (iRet) {
484 printf("Failed to read boot0\n");
485 ret = -1;
486 goto exit;
487 }
488 } else if (flag == 1 || flag == 2) {
489 iRet = store_boot_read("bootloader", 0, 0, buffer);
490 if (iRet) {
491 printf("Failed to read bootloader\n");
492 ret = -1;
493 goto exit;
494 }
495 } else if (flag == 3) {
496 printf("null ab mode\n");
497 iRet = store_logic_read("bootloader_up", 0,
498 BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, buffer);
499 if (iRet) {
500 printf("Fail to read 0x%xB from bootloader_up\n",
501 BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET);
502 ret = -1;
503 goto exit;
504 }
505 }
506
507 if (mmc) {
508 printf("try to read gpt data from bootloader.img\n");
509 int erase_flag = 0;
510
511 dev_desc = blk_get_dev("mmc", 1);
512 if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
513 printf("invalid mmc device\n");
514 ret = -1;
515 goto exit;
516 }
517
518 if (is_valid_gpt_buf(dev_desc, buffer + 0x3DFE00)) {
519 printf("printf normal bootloader.img, no gpt partition table\n");
520 ret = -1;
521 goto exit;
522 } else {
523 erase_flag = check_gpt_change(dev_desc, buffer + 0x3DFE00);
524
525 if (erase_flag == 4 && has_boot_slot == 0) {
526 printf("null ab critical partition change, refused to upgrade\n");
527 ret = -1;
528 goto exit;
529 } else if (has_boot_slot == 1 && (erase_flag == 3 || erase_flag == 4)) {
530 printf("Important partition changes, refused to upgrade\n");
531 ret = 1;
532 goto exit;
533 } else if (erase_flag == 0) {
534 printf("partition doesn't change, needn't update\n");
535 ret = -1;
536 goto exit;
537 }
538
539 if (flag == 1 || flag == 2) {
540 printf("update from dts to gpt, erase first\n");
541 erase_gpt_part_table(dev_desc);
542 }
543
544 if (flag == 2) {
545#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
546 env_set("dts_to_gpt", "1");
547 run_command("update_env_part -p dts_to_gpt;", 0);
548#else
549 run_command("defenv_reserve;setenv dts_to_gpt 1;saveenv;", 0);
550#endif
551 }
552
553 if (write_mbr_and_gpt_partitions(dev_desc, buffer + 0x3DFE00)) {
554 printf("%s: writing GPT partitions failed\n", __func__);
555 ret = 1;
556 goto exit;
557 }
558
559 if (mmc_device_init(mmc) != 0) {
560 printf(" update gpt partition table fail\n");
561 ret = 2;
562 goto exit;
563 }
564 printf("%s: writing GPT partitions ok\n", __func__);
565 }
566 }
567
568 if (has_boot_slot == 1 && (flag == 1 || flag == 2)) {
569 printf("update from dts to gpt, backup old bootloader\n");
570 char *slot = NULL;
571
572 slot = env_get("slot-suffixes");
573 if (!slot) {
574 run_command("get_valid_slot", 0);
575 slot = env_get("slot-suffixes");
576 }
577 if (strcmp(slot, "0") == 0) {
578 printf("active is a, b is old, don't need backup\n");
579 } else if (strcmp(slot, "1") == 0) {
580 printf("active is b, a is old, backup boot0 to boot1\n");
581 iRet = write_bootloader_back("1", 2);
582 if (iRet != 0) {
583 printf("Failed to write boot1\n");
584 ret = 3;
585 goto exit;
586 }
587 }
588 iRet = store_boot_write("bootloader", 1, 0, buffer);
589 if (iRet) {
590 printf("Failed to write boot0\n");
591 ret = 4;
592 goto exit;
593 }
594 }
595
596exit:
597 if (buffer)
598 free(buffer);
599
600 if (mmc)
601 run_command("mmc dev 1 0;", 0);
602
603 if (mmc && ret > 0) {
604 if (ret == 1 || ret == 2 || ret == 3) {
605 printf("rollback\n");
606 update_rollback();
607 } else if (ret == 4) {
608 printf("write back boot0, rollback\n");
609 write_bootloader_back("2", 1);
610 update_rollback();
611 }
612 }
613#endif
614 return ret;
615}
616
Zhigang Yude5719e2024-03-08 09:14:23 +0000617int recovery_update(void)
618{
619 if (IS_ENABLED(CONFIG_MMC_MESON_GX)) {
620 char bufcmd[64];
621 unsigned long long size = 0;
622 char *recovery_need_update = NULL;
623 struct partitions *partition = NULL;
624 //"ANDROID!"
625 const unsigned char imghead[] = { 0x41, 0x4e, 0x44, 0x52, 0x4f, 0x49, 0x44, 0x21 };
626
627 if (store_get_type() != BOOT_EMMC)
628 return 0;
629
630 //check recoverybak partition exist
631 partition = find_mmc_partition_by_name("recoverybak");
632 if (!partition) {
633 printf("can not find recoverybak, skip\n");
634 return 0;
635 }
636
637 //check if need update recovery from recoverybak
638 recovery_need_update = env_get("recovery_need_update");
639 if (!recovery_need_update || strcmp(recovery_need_update, "1"))
640 return 0;
641
642 //read recoverybak header data for check
643 sprintf(bufcmd, "store read $loadaddr recoverybak 0 0x%x", 16);
644 run_command(bufcmd, 0);
645
646 unsigned char *loadaddr = NULL;
647
648 loadaddr = (unsigned char *)simple_strtoul(env_get("loadaddr"), NULL, 16);
649
650 //check recoverybak head is start "ANDROID!"
651 if (memcmp((void *)imghead, loadaddr, 8)) {
652 printf("not valid recovery image, skip update recovery\n");
653 return 0;
654 }
655
656 //write recoverybak data to recovery
657 while (size < partition->size) {
658 unsigned long long write_size = 0;
659 unsigned long long left_size = partition->size - size;
660
661 if (left_size > 10 * MIB_SIZE)
662 write_size = 10 * MIB_SIZE;
663 else
664 write_size = partition->size - size;
665
666 sprintf(bufcmd, "store read $loadaddr recoverybak 0x%llx 0x%llx",
667 size, write_size);
668 run_command(bufcmd, 0);
669 sprintf(bufcmd, "store write $loadaddr recovery 0x%llx 0x%llx",
670 size, write_size);
671 run_command(bufcmd, 0);
672 size += write_size;
673 }
674
675 //clean recovery_need_update to 0
676 env_set("recovery_need_update", "0");
677 if (CONFIG_IS_ENABLED(AML_UPDATE_ENV))
678 run_command("update_env_part -p recovery_need_update;", 0);
679 else
680 run_command("saveenv", 0);
681 }
682 return 0;
683}
684
685//add non ab recovery update flow here
686int non_ab_update(char *rebootmode)
687{
Bo Lv72d0e902023-01-02 14:27:34 +0000688 int match_flag = 0;
689 char *rebootstatus = NULL;
690 char *checkresult = NULL;
691 char *bootloaderindex = NULL;
692 char *expect_index = NULL;
693 char *robustota = NULL;
Bo Lv72d0e902023-01-02 14:27:34 +0000694
695 char *write_boot = env_get("write_boot");
696
Zhigang Yude5719e2024-03-08 09:14:23 +0000697 if (write_boot && (!strcmp(write_boot, "1"))) {
698 printf("non ab for kernel 5.15 update bootloader\n");
699 write_bootloader(1);
700 write_bootloader(2);
701 env_set("write_boot", "0");
702 env_set("upgrade_step", "1");
703 run_command("saveenv", 0);
704 run_command("reset", 0);
705 }
706
707 recovery_update();
708
709 //check_result init
710 checkresult = env_get("check_result");
711 if (!checkresult)
712 env_set("check_result", "succ");
713
714 //reboot_status init
715 rebootstatus = env_get("reboot_status");
716 if (!rebootstatus) {
717 env_set("reboot_status", "reboot_init");
718 rebootstatus = env_get("reboot_status");
719 }
720
721 if (!rebootstatus) {
722 printf("rebootstatus is NULL, skip check\n");
723 return -1;
724 }
725
726 //check reboot_end
727 if (!strcmp(rebootstatus, "reboot_end")) {
728 env_set("reboot_status", "reboot_init");
729 run_command("saveenv", 0);
730 }
731
732 //get forUpgrade_robustOta and check if support robustota
733 robustota = env_get("forUpgrade_robustOta");
734 if (!robustota || !strcmp(robustota, "false"))
735 return -1;
736
737 //no secure check need
738 if (!strcmp(rebootstatus, "reboot_init")) {
739 printf("rebootstatus is reboot_init, skip check\n");
740 return -1;
741 }
742
743 //get bootloader index
744 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
745 if (!bootloaderindex) {
746 wrnP("can not get bootloader index, so skip secure check\n");
747 return -1;
748 }
749
750 //get expect index
751 expect_index = env_get("expect_index");
752 if (!expect_index) {
753 wrnP("can not get expect index, so skip secure check\n");
754 return -1;
755 }
756
757 wrnP("expect_index is : %s\n", expect_index);
758
759 match_flag = strcmp(bootloaderindex, expect_index);
760
761 //ignore reboot next check if power off during reboot next to finish
762 if (rebootmode && (strcmp(rebootmode, "cold_boot") == 0)) {
763 if (!strcmp(rebootstatus, "reboot_finish"))
764 match_flag = 0;
765 }
766
767 if (!strcmp(rebootstatus, "reboot_next")) {
768 env_set("reboot_status", "reboot_finish");
769 run_command("saveenv", 0);
770 run_command("get_rebootmode", 0);
771 if (rebootmode && (strcmp(rebootmode, "quiescent") == 0))
772 run_command("reboot next,quiescent", 0);
773 else
774 run_command("reboot next", 0);
775 } else if (!strcmp(rebootstatus, "reboot_finish")) {
776 wrnP("--secure check reboot_finish---\n");
777 env_set("reboot_status", "reboot_end");
778 run_command("saveenv", 0);
779 if (match_flag == 0) {
780 wrnP("reboot next succ, bootloader secure check pass......\n");
781 } else {
782 //bootloader check failed, run recovery show error
783 wrnP("reboot next fail, bootloader secure check fail(curr:%s, expect:%s)\n",
784 bootloaderindex, expect_index);
785 env_set("check_result", "bootloader_fail");
786 run_command("saveenv", 0);
787 }
788 run_recovery_from_flash();
789 return 0;
790 } else {
791 env_set("check_result", "succ");
792 }
793 return 0;
794}
795
796//add ab update and ab rollback flow here
797int ab_update_rollback(char *rebootmode, int gpt_flag)
798{
799 int match_flag = 0;
800 char *rebootstatus = NULL;
801 char *bootloaderindex = NULL;
802 char *expect_index = NULL;
803
804 //update bootloader_a/b/up to boot0
805 char *write_boot = env_get("write_boot");
806
807 if (write_boot && !strcmp(write_boot, "1")) {
Bo Lv72d0e902023-01-02 14:27:34 +0000808 printf("need to write boot0\n");
Zhigang Yude5719e2024-03-08 09:14:23 +0000809 if (write_bootloader(1)) {
Bo Lv72d0e902023-01-02 14:27:34 +0000810 printf("write boot0 fail, need to rollback!\n");
811 update_rollback();
812 } else {
Xindong Xu15e83fa2024-03-15 08:56:00 +0800813 update_gpt(0);
Bo Lv72d0e902023-01-02 14:27:34 +0000814 printf("write boot0 success, need to reset!\n");
815 }
816
817 env_set("write_boot", "0");
818 env_set("reboot_status", "reboot_next");
819 env_set("expect_index", "1");
820 env_set("update_env", "1");
821 run_command("saveenv", 0);
822 run_command("reset", 0);
823 }
Zhigang Yude5719e2024-03-08 09:14:23 +0000824
825 //check rescueparty and rollback
Bo Lv72d0e902023-01-02 14:27:34 +0000826 if (rebootmode && (strcmp(rebootmode, "rescueparty") == 0)) {
827 printf("rebootmode is rescueparty, need rollback\n");
828 char *slot;
829
Bo Lv72d0e902023-01-02 14:27:34 +0000830#ifdef CONFIG_FASTBOOT
831 struct misc_virtual_ab_message message;
Bo Lv72d0e902023-01-02 14:27:34 +0000832 set_mergestatus_cancel(&message);
833#endif
834
835 slot = env_get("slot-suffixes");
836 if (!slot) {
837 run_command("get_valid_slot", 0);
838 slot = env_get("slot-suffixes");
839 }
840 if (strcmp(slot, "0") == 0) {
Zhigang Yude5719e2024-03-08 09:14:23 +0000841 if (gpt_flag == 0) {
Bo Lv72d0e902023-01-02 14:27:34 +0000842 wrnP("normal mode\n");
843 write_bootloader_back("2", 0);
844 env_set("expect_index", "0");
845 } else {
846 wrnP("gpt or disable user bootloader mode\n");
847 write_bootloader_back("2", 1);
848 env_set("expect_index", "1");
849 }
850 wrnP("back to slot b\n");
851 run_command("set_roll_flag 1", 0);
852 run_command("set_active_slot b", 0);
853 } else if (strcmp(slot, "1") == 0) {
Zhigang Yude5719e2024-03-08 09:14:23 +0000854 if (gpt_flag == 0) {
Bo Lv72d0e902023-01-02 14:27:34 +0000855 wrnP("normal mode\n");
856 write_bootloader_back("1", 0);
857 env_set("expect_index", "0");
858 } else {
859 wrnP("gpt or disable user bootloader mode\n");
860 write_bootloader_back("2", 1);
861 env_set("expect_index", "1");
862 }
863 wrnP("back to slot a\n");
864 run_command("set_roll_flag 1", 0);
865 run_command("set_active_slot a", 0);
866 }
867
868 env_set("update_env", "1");
869 env_set("reboot_status", "reboot_next");
870 run_command("saveenv", 0);
871 run_command("reset", 0);
872 }
873
Bo Lv72d0e902023-01-02 14:27:34 +0000874 //get bootloader index
875 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
876 if (bootloaderindex == NULL) {
877 wrnP("can not get bootloader index, so skip secure check\n");
878 return -1;
879 }
Xindong Xu22e8daf2024-03-12 18:08:41 +0800880
Bo Lv72d0e902023-01-02 14:27:34 +0000881 //get expect index
882 expect_index = env_get("expect_index");
883 if (expect_index == NULL) {
884 wrnP("can not get expect index, so skip secure check\n");
885 return -1;
886 }
887
888 wrnP("expect_index is : %s\n", expect_index);
889
890 match_flag = strcmp(bootloaderindex, expect_index);
891
Zhigang Yude5719e2024-03-08 09:14:23 +0000892 rebootstatus = env_get("reboot_status");
Bo Lv72d0e902023-01-02 14:27:34 +0000893
Zhigang Yude5719e2024-03-08 09:14:23 +0000894 //if reboot next need check bootloader rollback
895 if (rebootstatus && !strcmp(rebootstatus, "reboot_next")) {
Bo Lv72d0e902023-01-02 14:27:34 +0000896 wrnP("--secure check reboot_next---\n");
897 //bootloader index, expect == current, no need reboot next
Zhigang Yude5719e2024-03-08 09:14:23 +0000898 if (match_flag != 0) {
899 wrnP("bootloader wrong, start rollback\n");
900 if (gpt_flag == 1) {
901 wrnP("gpt or disable user bootloader mode, write boot1 to boot0\n");
902 write_bootloader_back("2", 1);
Bo Lv72d0e902023-01-02 14:27:34 +0000903#ifdef CONFIG_FASTBOOT
Zhigang Yude5719e2024-03-08 09:14:23 +0000904 struct misc_virtual_ab_message message;
Bo Lv72d0e902023-01-02 14:27:34 +0000905
Zhigang Yude5719e2024-03-08 09:14:23 +0000906 set_mergestatus_cancel(&message);
Bo Lv72d0e902023-01-02 14:27:34 +0000907#endif
Zhigang Yude5719e2024-03-08 09:14:23 +0000908 char *slot;
Bo Lv72d0e902023-01-02 14:27:34 +0000909
Zhigang Yude5719e2024-03-08 09:14:23 +0000910 slot = env_get("slot-suffixes");
911 if (!slot) {
912 run_command("get_valid_slot", 0);
Bo Lv72d0e902023-01-02 14:27:34 +0000913 slot = env_get("slot-suffixes");
Bo Lv72d0e902023-01-02 14:27:34 +0000914 }
Zhigang Yude5719e2024-03-08 09:14:23 +0000915 if (strcmp(slot, "0") == 0) {
916 wrnP("back to slot b\n");
917 run_command("set_roll_flag 1", 0);
918 run_command("set_active_slot b", 0);
919 } else if (strcmp(slot, "1") == 0) {
920 wrnP("back to slot a\n");
921 run_command("set_roll_flag 1", 0);
922 run_command("set_active_slot a", 0);
923 }
924 env_set("expect_index", "1");
Bo Lv72d0e902023-01-02 14:27:34 +0000925 } else {
Zhigang Yude5719e2024-03-08 09:14:23 +0000926 write_bootloader_back(bootloaderindex, 0);
Bo Lv72d0e902023-01-02 14:27:34 +0000927#ifdef CONFIG_FASTBOOT
928 struct misc_virtual_ab_message message;
929 set_mergestatus_cancel(&message);
930#endif
931 if (strcmp(bootloaderindex, "1") == 0) {
932 wrnP("back to slot a\n");
933 run_command("set_roll_flag 1", 0);
934 run_command("set_active_slot a", 0);
935 } else if (strcmp(bootloaderindex, "2") == 0) {
936 wrnP("back to slot b\n");
937 run_command("set_roll_flag 1", 0);
938 run_command("set_active_slot b", 0);
939 }
Zhigang Yude5719e2024-03-08 09:14:23 +0000940 env_set("expect_index", "0");
Bo Lv72d0e902023-01-02 14:27:34 +0000941 }
Zhigang Yude5719e2024-03-08 09:14:23 +0000942
943 env_set("update_env", "1");
944 env_set("reboot_status", "reboot_next");
Bo Lv72d0e902023-01-02 14:27:34 +0000945 run_command("saveenv", 0);
Zhigang Yude5719e2024-03-08 09:14:23 +0000946 run_command("reset", 0);
Bo Lv72d0e902023-01-02 14:27:34 +0000947 return 0;
Zhigang Yude5719e2024-03-08 09:14:23 +0000948 }
Bo Lv72d0e902023-01-02 14:27:34 +0000949 }
950
951 return 0;
952}
953
Zhigang Yude5719e2024-03-08 09:14:23 +0000954static int do_secureboot_check(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
955{
956 char *rebootmode = NULL;
957 int gpt_flag = 0;
958 int ret = -1;
959
960 // set product first to set serial.
961 set_product();
962
963#ifdef CONFIG_MMC_MESON_GX
964 struct mmc *mmc = NULL;
965 //int capacity_boot = 0;
966
967 if (store_get_type() == BOOT_EMMC) {
968 mmc = find_mmc_device(1);
969 if (mmc)
970 ret = aml_gpt_valid(mmc);
971 }
972#endif
973
974 //check is gpt mode
975 if (ret == 0)
976 gpt_flag = 1;
977
978 //unsupport update dt in boothal, update dt in uboot
979 run_command("update_dt;", 0);
980
981 bootloader_wp();
982
983 //set default env before check
984 env_set("recovery_mode", "false");
985
986 //if recovery mode, need disable dv, if factoryreset, need default uboot env
987 aml_recovery();
988
989#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
990 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
991
992 if (*efuse_field.data == 1) {
993 wrnP("efuse_field.data == 1\n");
994 env_set("nocs_mode", "true");
995 gpt_flag = 1;
996 } else {
997 wrnP("efuse_field.data != 1\n");
998 env_set("nocs_mode", "false");
999 }
1000#endif//#ifdef CONFIG_EFUSE_OBJ_API
1001
1002
1003 run_command("get_rebootmode", 0);
1004 rebootmode = env_get("reboot_mode");
1005 if (!rebootmode) {
1006 wrnP("can not get reboot mode, so skip secure check\n");
1007 return -1;
1008 }
1009 printf("rebootmode is %s\n", rebootmode);
1010
1011 //get boot status
1012 run_command("amlbootsta -p -s", 0);
1013
1014 if (IS_ENABLED(CONFIG_MMC_MESON_GX))
1015 fastboot_step_check(rebootmode, gpt_flag);
1016
1017 if (has_boot_slot == 1)
1018 ab_update_rollback(rebootmode, gpt_flag);
1019 else
1020 non_ab_update(rebootmode);
1021
1022 return 0;
1023}
1024
1025
1026static int do_update_uboot_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1027{
1028 const int write_boot = env_get_ulong("write_boot", 10, 0);
1029 const int update_dts_gpt = env_get_ulong("update_dts_gpt", 10, 0);
1030
1031 //skip update env if need update bootloader
1032 if (write_boot || update_dts_gpt) {
1033 run_command("echo write_boot ${write_boot}, update_dts_gpt ${update_dts_gpt}", 0);
1034 return 0;
1035 }
1036
1037 //default uboot env need before anyone use it
1038 //after factory reset
1039 if (env_get("default_env")) {
1040 printf("factory reset, need default all uboot env.\n");
1041 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
1042 }
1043
1044 //after ab update
1045 char *update_env = env_get("update_env");
1046
1047 if (update_env && (strcmp(update_env, "1") == 0)) {
1048 printf("ab mode, default all uboot env\n");
1049 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
1050 }
1051
1052 //after recovery update
1053 char *upgrade_step = env_get("upgrade_step");
1054
1055 if (upgrade_step && (strcmp(upgrade_step, "1") == 0)) {
1056 printf("after recovery update, need update uboot env\n");
1057 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
1058 }
1059
1060 return 0;
1061}
Bo Lv72d0e902023-01-02 14:27:34 +00001062
1063U_BOOT_CMD_COMPLETE(
1064 amlbootsta, 3, 0, do_get_bootloader_status,
1065 "get bootloader status in env",
1066 "[-p] print bootloader status\n"
1067 "[-s] saveenv after generate bootloader status\n",
1068 var_complete
1069);
1070
1071U_BOOT_CMD_COMPLETE(
1072 amlsecurecheck, 1, 0, do_secureboot_check,
1073 "try bootloader/dtb/recovery secure check",
1074 ""
1075 "",
1076 var_complete
1077);
1078
Zhigang Yude5719e2024-03-08 09:14:23 +00001079U_BOOT_CMD(aml_update_env, 1, 0, do_update_uboot_env,
1080 "aml_update_env",
1081 "\nThis command will update uboot env\n"
1082 "So you can execute command: aml_update_env"
1083);
1084
Bo Lv72d0e902023-01-02 14:27:34 +00001085