blob: 597f0576036f79e703cbda508fc099c4022951b1 [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)
35
36//check SWPL-31296 for details
37static int do_get_bootloader_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
38{
39 bool printStat = false;
40 bool saveenv = false;
41 debugP("Initial value for argc=%d\n", argc);
42 while (argc > 1 && **(argv + 1) == '-') {
43 char *arg = *++argv;
44
45 --argc;
46 while (*++arg) {
47 switch (*arg) {
48 case 'p': /* print */
49 printStat = true;
50 break;
51 case 's': /* saveenv */
52 saveenv = true;
53 break;
54 default:
55 return CMD_RET_USAGE;
56 }
57 }
58 }
59 debugP("Final value for argc=%d\n", argc);
60 //1,forUpgrade_socType, cpu familyId
61 const cpu_id_t cpuid = get_cpu_id();
62 const int familyId = cpuid.family_id;
63 env_set_hex("forUpgrade_socType", familyId);
64
65 //2,forUpgrade_secureBoot
66 const bool secureboot = IS_FEAT_BOOT_VERIFY();
67 env_set("forUpgrade_secureBoot", secureboot ? "true" : "false");
68
69 //3,forUpgrade_robustOta
70 bool supportRobustOta = false;
71 switch (familyId) {
72 case 0x32://sc2
73 case 0x36://t7
74 case 0x37://s4
75 case 0x38://t3
76 case 0x3A://s4d
77 supportRobustOta = true;
78 break;
79 default:
80 {
81 if (familyId > 0x3A) {
82 supportRobustOta = true;
83 }
84 }
85 break;
86 }
87 env_set("forUpgrade_robustOta", supportRobustOta ? "true" : "false");
88
89 //4,forUpgrade_flashType
90 const char* BootDevices[] = {
91 "BOOT_EMMC", "BOOT_SD",
92 "BOOT_NAND_NFTL", "BOOT_NAND_MTD",
93 "BOOT_SNAND", "BOOT_SNOR",
94 };
95 const char* bootDevice = "BOOT_NONE";
96 enum boot_type_e bootType = store_get_type();
97 int i = 0;
98 for (; i < ARRAY_SIZE(BootDevices); ++i) {
99 if ((1<<i) != bootType) continue;
100 bootDevice = BootDevices[i];
101 break;
102 }
103 env_set("forUpgrade_flashType", bootDevice);
104
105 //5,forUpgrade_bootloaderCopies, how many copies supported
106 int bootCopies = 1;
107 switch (bootType) {
108 case BOOT_EMMC: bootCopies = 3; break;
109 default:break;
110 }
111 env_set_ulong("forUpgrade_bootloaderCopies", bootCopies);
112
113 //6,forUpgrade_bootloaderIndex
114 //for emmc, 0/1/2 is user/boot0/boot1
115 const int bootCpyIndex = store_bootup_bootidx("bootloader");
116 env_set_ulong("forUpgrade_bootloaderIndex", bootCpyIndex);
117
118 //7,get first boot index, for defendkey
119 const int firstBootCpyIndex = store_boot_copy_start();
120 env_set_ulong("forUpgrade_1stBootIndex", firstBootCpyIndex);
121
122 if (printStat) run_command("printenv forUpgrade_socType forUpgrade_secureBoot "
123 " forUpgrade_robustOta forUpgrade_flashType forUpgrade_bootloaderCopies "
124 " forUpgrade_bootloaderIndex forUpgrade_1stBootIndex", 0);
125
Sam Wu6f3d40e2023-04-22 01:10:27 +0800126 if (saveenv) {
127 if (CONFIG_IS_ENABLED(AML_UPDATE_ENV))
128 run_command("update_env_part -p forUpgrade_robustOta "\
129 "forUpgrade_bootloaderIndex", 0);
130 else
131 run_command("saveenv", 0);
132 }
133
Bo Lv72d0e902023-01-02 14:27:34 +0000134
135 return CMD_RET_SUCCESS;
136}
137
138static void run_recovery_from_flash(void) {
139 env_set("dolby_status","0");
140 run_command("run init_display", 0);
141 run_command("run storeargs", 0);
142 run_command("get_rebootmode", 0);
143 run_command("if test ${reboot_mode} = quiescent; then "\
144 "setenv bootconfig ${bootconfig} androidboot.quiescent=1; fi;", 0);
145 run_command("if test ${reboot_mode} = recovery_quiescent; then "\
146 "setenv bootconfig ${bootconfig} androidboot.quiescent=1; fi;", 0);
147 run_command("run recovery_from_flash", 0);
148}
149
150static void run_recovery_from_cache(void) {
151
152 char *loadaddr_kernel = env_get("loadaddr_kernel");
153 if (loadaddr_kernel != NULL) {
154 env_set("loadaddr",loadaddr_kernel);
155 } else {
156 env_set("loadaddr","0x01080000");
157 }
158 env_set("dolby_status","0");
159 run_command("run bcb_cmd;", 0);
160 run_command("run init_display", 0);
161 run_command("run storeargs", 0);
162 run_command("get_rebootmode", 0);
163
164 run_command("if test ${reboot_mode} = quiescent; then "\
165 "setenv bootconfig ${bootconfig} androidboot.quiescent=1; fi;", 0);
166 run_command("if test ${reboot_mode} = recovery_quiescent; then "\
167 "setenv bootconfig ${bootconfig} androidboot.quiescent=1; fi;", 0);
168 run_command("if ext4load mmc 1:2 ${dtb_mem_addr} /recovery/dtb.img; then echo cache dtb.img loaded; fi;", 0);
169
170 run_command("if test ${reboot_vendor_boot} = true; then "\
171 "setenv vendor_boot_mode true; fi;", 0);
172
173 run_command("if test ${vendor_boot_mode} = true; then "\
174 "setenv bootargs ${bootargs} ${fs_type} aml_dt=${aml_dt} recovery_part=${recovery_part} recovery_offset=${recovery_offset};"\
175 "imgread kernel ${recovery_part} ${loadaddr} ${recovery_offset};"\
176 "else "\
177 "if ext4load mmc 1:2 ${loadaddr} /recovery/recovery.img; then echo cache recovery.img loaded; fi;"\
178 "fi;", 0);
179
180 env_set("check_result","recovery_succ");
181 env_set("recovery_mode", "true");
182 run_command("bootm ${loadaddr}", 0);
183 env_set("check_result","recovery_fail");
184 env_set("reboot_status","reboot_recovery");
185 run_command("saveenv", 0);
186 run_command("reboot", 0);//need reboot old bootloader
187}
188
189int write_bootloader_back(const char* bootloaderindex, int dstindex) {
190 int iRet = 0;
191 int copy = 0;
192 int ret = -1;
193 unsigned char* buffer = NULL;
194 int capacity_boot = 0;
195
196 if (strcmp(bootloaderindex, "1") == 0) {
197 copy = 1;
198 } else if (strcmp(bootloaderindex, "2") == 0) {
199 copy = 2;
200 } else if (strcmp(bootloaderindex, "0") == 0) {
201 copy = 0;
202 }
203
204#ifdef CONFIG_MMC_MESON_GX
205 struct mmc *mmc = NULL;
206
207 if (store_get_type() == BOOT_EMMC)
208 mmc = find_mmc_device(1);
209
210 if (mmc)
211 capacity_boot = mmc->capacity_boot;
212#endif
213
214 printf("write_bootloader_back_capacity_boot: %x\n", capacity_boot);
215
216 buffer = (unsigned char *)malloc(capacity_boot);
217 if (!buffer)
218 {
219 printf("ERROR! fail to allocate memory ...\n");
220 goto exit;
221 }
222 memset(buffer, 0, capacity_boot);
223 iRet = store_boot_read("bootloader", copy, 0, buffer);
224 if (iRet) {
225 errorP("Fail read bootloader from rsv with sz\n");
226 goto exit;
227 }
228 iRet = store_boot_write("bootloader", dstindex, 0, buffer);
229 if (iRet) {
230 printf("Failed to write bootloader\n");
231 goto exit;
232 } else {
233 ret = 0;
234 }
235
236exit:
237 if (buffer)
238 {
239 free(buffer);
240 //buffer = NULL;
241 }
242 return ret;
243}
244
245//bootloader write protect
246static void bootloader_wp(void)
247{
248#ifdef CONFIG_MMC_MESON_GX
249 if (store_get_type() == BOOT_EMMC) {//emmc device
250 if (IS_FEAT_BOOT_VERIFY()) { //secure boot enable
251 if (BOOTLOADER_MODE_ADVANCE_INIT) { //new arch chip
252 env_set("bootloader_wp", "1");
253 }
254 }
255 }
256#endif
257}
258
259static void aml_recovery(void) {
260 char *mode = NULL;
261 char command[32];
262 char miscbuf[4096] = {0};
263
264 run_command("get_rebootmode", 0);
265
266 //get reboot_mode
267 mode = env_get("reboot_mode");
268 if (mode == NULL) {
269 wrnP("can not get reboot mode, so skip recovery check\n");
270 } else {
271 if ((!strcmp(mode, "factory_reset")) || (!strcmp(mode, "update"))) {
272 env_set("dolby_status","0");
273 }
274 }
275
276#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
277 int ret = 0;
278 extern int boot_info_open_partition(char *miscbuf);
279 ret = boot_info_open_partition(miscbuf);
280 if (ret != 0) {
281 wrnP("open misc partition failed, so skip recovery check");
282 return;
283 }
284#endif
285
286 //if run recovery, need disable dolby
287 memcpy(command, miscbuf, 32);
288 if (!memcmp(command, "boot-recovery", strlen("boot-recovery"))) {
289 env_set("dolby_status","0");
290 return;
291 }
292}
293
294void update_rollback(void)
295{
296 char *slot = NULL;
297 int ret = -1;
298 int gpt_flag = -1;
299
300#ifdef CONFIG_MMC_MESON_GX
301 struct mmc *mmc = NULL;
302
303 if (store_get_type() == BOOT_EMMC)
304 mmc = find_mmc_device(1);
305
306 if (mmc)
307 gpt_flag = aml_gpt_valid(mmc);
308#endif
309 if (gpt_flag == 0)
310 ret = 0;
311
312#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
313 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
314
315 //dis_user_flag = run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
316 if (*efuse_field.data == 1)
317 ret = 0;
318#endif//#ifdef CONFIG_EFUSE_OBJ_API
319
320 slot = env_get("slot-suffixes");
321 if (!slot) {
322 run_command("get_valid_slot", 0);
323 slot = env_get("slot-suffixes");
324 }
325 if (strcmp(slot, "0") == 0) {
326 if (ret != 0) {
327 wrnP("normal mode\n");
328 write_bootloader_back("2", 0);
329 env_set("expect_index", "0");
330 } else {
331 wrnP("gpt or disable user bootloader mode\n");
332 write_bootloader_back("2", 1);
333 env_set("expect_index", "1");
334 }
335 wrnP("back to slot b\n");
336 run_command("set_roll_flag 1", 0);
337 run_command("set_active_slot b", 0);
338 } else if (strcmp(slot, "1") == 0) {
339 if (ret != 0) {
340 wrnP("normal mode\n");
341 write_bootloader_back("1", 0);
342 env_set("expect_index", "0");
343 } else {
344 wrnP("gpt or disable user bootloader mode\n");
345 write_bootloader_back("2", 1);
346 env_set("expect_index", "1");
347 }
348 wrnP("back to slot a\n");
349 run_command("set_roll_flag 1", 0);
350 run_command("set_active_slot a", 0);
351 }
352 env_set("update_env", "1");
353 env_set("reboot_status", "reboot_next");
354}
355
356static int write_boot0(void)
357{
358 unsigned char *buffer = NULL;
Sam Wu6f3d40e2023-04-22 01:10:27 +0800359 int capacity_boot = 0x2000 * 512;
Zhigang Yu6852d932024-02-26 11:32:53 +0000360 int iret = 0;
Bo Lv72d0e902023-01-02 14:27:34 +0000361 char partname[32] = {0};
362 char *slot_name = NULL;
363
364#ifdef CONFIG_MMC_MESON_GX
365 struct mmc *mmc = NULL;
366
367 if (store_get_type() == BOOT_EMMC)
368 mmc = find_mmc_device(1);
369
370 if (mmc)
371 capacity_boot = mmc->capacity_boot;
372#endif
373 printf("capacity_boot: 0x%x\n", capacity_boot);
374 buffer = (unsigned char *)malloc(capacity_boot);
375 if (!buffer) {
376 printf("ERROR! fail to allocate memory ...\n");
377 return -1;
378 }
379 memset(buffer, 0, capacity_boot);
380
381 slot_name = env_get("active_slot");
382 if (slot_name && (strcmp(slot_name, "_a") == 0))
383 strcpy((char *)partname, "bootloader_a");
384 else if (slot_name && (strcmp(slot_name, "_b") == 0))
385 strcpy((char *)partname, "bootloader_b");
386
Zhigang Yu6852d932024-02-26 11:32:53 +0000387 iret = store_logic_read(partname, 0, BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, buffer);
388 if (iret) {
Bo Lv72d0e902023-01-02 14:27:34 +0000389 errorP("Fail to read 0x%xB from part[%s] at offset 0\n",
390 BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, partname);
Sam Wu6f3d40e2023-04-22 01:10:27 +0800391 free(buffer);
Bo Lv72d0e902023-01-02 14:27:34 +0000392 return -1;
393 }
394
Zhigang Yu6852d932024-02-26 11:32:53 +0000395 iret = store_boot_write("bootloader", 1, BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, buffer);
396 if (iret) {
Bo Lv72d0e902023-01-02 14:27:34 +0000397 printf("Failed to write boot0\n");
Sam Wu6f3d40e2023-04-22 01:10:27 +0800398 free(buffer);
Bo Lv72d0e902023-01-02 14:27:34 +0000399 return -1;
400 }
Sam Wu6f3d40e2023-04-22 01:10:27 +0800401
402 free(buffer);
Bo Lv72d0e902023-01-02 14:27:34 +0000403 return 0;
404}
405
406/**
407 *set merge status
408*/
409int set_mergestatus_cancel(struct misc_virtual_ab_message *message)
410{
411 char *partition = "misc";
412 char vab_buf[1024] = {0};
413
414 if (store_read((const char *)partition,
415 SYSTEM_SPACE_OFFSET_IN_MISC, 1024, (unsigned char *)vab_buf) < 0) {
416 printf("failed to store read %s.\n", partition);
417 return -1;
418 }
419
420 memcpy(message, vab_buf, sizeof(struct misc_virtual_ab_message));
421 printf("message.merge_status: %d\n", message->merge_status);
422 if (message->merge_status == SNAPSHOTTED || message->merge_status == MERGING) {
423 message->merge_status = CANCELLED;
424 printf("set message.merge_status CANCELLED\n");
425 }
426 store_write((const char *)partition, SYSTEM_SPACE_OFFSET_IN_MISC, 1024, (unsigned char *)vab_buf);
427 return 0;
428}
429
hao.qi4c4dc762024-03-11 10:38:23 +0800430// according to the value of the board,
431// reset the product to set the serial
432// to distinguish different products.
433void set_product(void)
434{
435 char *board = env_get("board");
436 char *str = NULL;
437 char *dup_str = NULL;
438
439 str = strstr(board, "_");
440 dup_str = strdup(str);
441 if (!(strstr(dup_str, "_")))
442 env_set("product", str + 1);
443 else
444 env_set("product", strtok(str, "_"));
445 free(dup_str);
446}
447
Bo Lv72d0e902023-01-02 14:27:34 +0000448static int do_secureboot_check(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) {
449 int match_flag = 0;
450 char *rebootstatus = NULL;
451 char *checkresult = NULL;
452 char *bootloaderindex = NULL;
453 char *expect_index = NULL;
454 char *robustota = NULL;
455 char *update_env = NULL;
456 char *rebootmode = NULL;
457 int gpt_flag = -1;
458 int ret = -1;
459
hao.qi4c4dc762024-03-11 10:38:23 +0800460// set product first to set serial.
461 set_product();
462
Bo Lv72d0e902023-01-02 14:27:34 +0000463#ifdef CONFIG_MMC_MESON_GX
464 struct mmc *mmc = NULL;
465 //int capacity_boot = 0;
466
467 if (store_get_type() == BOOT_EMMC)
468 mmc = find_mmc_device(1);
469#endif
470 //unsupport update dt in boothal, update dt in uboot
471 run_command("update_dt;", 0);
472
473 bootloader_wp();
474
475 //set default env before check
476 env_set("recovery_mode", "false");
477
478 //if recovery mode, need disable dv, if factoryreset, need default uboot env
479 aml_recovery();
480
481#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
482 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
483
484 if (*efuse_field.data == 1) {
485 wrnP("efuse_field.data == 1\n");
486 env_set("nocs_mode", "true");
487 } else {
488 wrnP("efuse_field.data != 1\n");
489 env_set("nocs_mode", "false");
490 }
491#endif//#ifdef CONFIG_EFUSE_OBJ_API
492
493 char *write_boot = env_get("write_boot");
494
495 if (!strcmp(write_boot, "1")) {
496 printf("need to write boot0\n");
497 if (write_boot0()) {
498 printf("write boot0 fail, need to rollback!\n");
499 update_rollback();
500 } else {
501 printf("write boot0 success, need to reset!\n");
502 }
503
504 env_set("write_boot", "0");
505 env_set("reboot_status", "reboot_next");
506 env_set("expect_index", "1");
507 env_set("update_env", "1");
508 run_command("saveenv", 0);
509 run_command("reset", 0);
510 }
511 run_command("get_rebootmode", 0);
512 rebootmode = env_get("reboot_mode");
513 if (!rebootmode) {
514 wrnP("can not get reboot mode, so skip secure check\n");
515 return -1;
516 }
517 printf("rebootmode is %s\n", rebootmode);
518 if (rebootmode && (strcmp(rebootmode, "rescueparty") == 0)) {
519 printf("rebootmode is rescueparty, need rollback\n");
520 char *slot;
521
522#ifdef CONFIG_MMC_MESON_GX
523 if (mmc)
524 gpt_flag = aml_gpt_valid(mmc);
525#endif
526 if (gpt_flag == 0)
527 ret = 0;
528
529#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
530 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
531
532 //dis_user_flag = run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
533 if (*efuse_field.data == 1)
534 ret = 0;
535#endif//#ifdef CONFIG_EFUSE_OBJ_API
536
537#ifdef CONFIG_FASTBOOT
538 struct misc_virtual_ab_message message;
539
540 set_mergestatus_cancel(&message);
541#endif
542
543 slot = env_get("slot-suffixes");
544 if (!slot) {
545 run_command("get_valid_slot", 0);
546 slot = env_get("slot-suffixes");
547 }
548 if (strcmp(slot, "0") == 0) {
549 if (ret != 0) {
550 wrnP("normal mode\n");
551 write_bootloader_back("2", 0);
552 env_set("expect_index", "0");
553 } else {
554 wrnP("gpt or disable user bootloader mode\n");
555 write_bootloader_back("2", 1);
556 env_set("expect_index", "1");
557 }
558 wrnP("back to slot b\n");
559 run_command("set_roll_flag 1", 0);
560 run_command("set_active_slot b", 0);
561 } else if (strcmp(slot, "1") == 0) {
562 if (ret != 0) {
563 wrnP("normal mode\n");
564 write_bootloader_back("1", 0);
565 env_set("expect_index", "0");
566 } else {
567 wrnP("gpt or disable user bootloader mode\n");
568 write_bootloader_back("2", 1);
569 env_set("expect_index", "1");
570 }
571 wrnP("back to slot a\n");
572 run_command("set_roll_flag 1", 0);
573 run_command("set_active_slot a", 0);
574 }
575
576 env_set("update_env", "1");
577 env_set("reboot_status", "reboot_next");
578 run_command("saveenv", 0);
579 run_command("reset", 0);
580 }
581
582 //check_result init
583 checkresult = env_get("check_result");
584 if (checkresult == NULL) {
585 env_set("check_result","succ");
586 }
587
588 //reboot_status init
589 rebootstatus = env_get("reboot_status");
590 if (rebootstatus == NULL) {
591 env_set("reboot_status","reboot_init");
592 rebootstatus = env_get("reboot_status");
593 }
594
595 if (rebootstatus == NULL) {
596 printf("rebootstatus is NULL, skip check\n");
597 return -1;
598 }
599
600 //check reboot_end
601 if (!strcmp(rebootstatus, "reboot_end")) {
602 env_set("reboot_status","reboot_init");
603 run_command("saveenv", 0);
604 }
605
606 //get boot status
607 run_command("amlbootsta -p -s", 0);
608
609 //get forUpgrade_robustOta and check if support robustota
610 robustota = env_get("forUpgrade_robustOta");
611 if ((robustota == NULL) || !strcmp(robustota, "false")) {
612 return -1;
613 }
614
615 //get bootloader index
616 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
617 if (bootloaderindex == NULL) {
618 wrnP("can not get bootloader index, so skip secure check\n");
619 return -1;
620 }
Xindong Xu22e8daf2024-03-12 18:08:41 +0800621
Bo Lv72d0e902023-01-02 14:27:34 +0000622#ifdef CONFIG_MMC_MESON_GX
Xindong Xu22e8daf2024-03-12 18:08:41 +0800623 char *fastboot_step = env_get("fastboot_step");
624
625 if (mmc && fastboot_step && (strcmp(fastboot_step, "1") == 0)) {
626 printf("reboot to new bootloader burned by fastboot\n");
627 env_set("update_env", "1");
628 env_set("fastboot_step", "2");
629 run_command("saveenv", 0);
630 if (rebootmode && (strcmp(rebootmode, "fastboot") == 0))
631 run_command("reboot next,bootloader", 0);
632 else
633 run_command("reboot next", 0);
634 }
635 if (mmc && fastboot_step && (strcmp(fastboot_step, "2") == 0)) {
Bo Lv72d0e902023-01-02 14:27:34 +0000636 struct blk_desc *dev_desc = mmc_get_blk_desc(mmc);
637
Xindong Xu22e8daf2024-03-12 18:08:41 +0800638 if (dev_desc && ((ret == 0 && !strcmp(bootloaderindex, "1")) ||
639 (ret != 0 && !strcmp(bootloaderindex, "0")))) {
640 printf("new bootloader error, please fastboot to another one\n");
641 env_set("fastboot_step", "0");
642#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
643 run_command("update_env_part -p fastboot_step;", 0);
644#else
645 run_command("defenv_reserve;setenv fastboot_step 0;saveenv;", 0);
646#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000647
Xindong Xu22e8daf2024-03-12 18:08:41 +0800648 cli_init();
649 cli_loop();
Bo Lv72d0e902023-01-02 14:27:34 +0000650 }
651 }
652#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000653
654 //no secure check need
655 if (!strcmp(rebootstatus, "reboot_init")) {
656 printf("rebootstatus is reboot_init, skip check\n");
657 return -1;
658 }
659
660 //get expect index
661 expect_index = env_get("expect_index");
662 if (expect_index == NULL) {
663 wrnP("can not get expect index, so skip secure check\n");
664 return -1;
665 }
666
667 wrnP("expect_index is : %s\n", expect_index);
668
669 match_flag = strcmp(bootloaderindex, expect_index);
670
671 //ignore reboot next check if power off during reboot next to finish
672 if (rebootmode && (strcmp(rebootmode, "cold_boot") == 0)) {
673 if (!strcmp(rebootstatus, "reboot_finish")) {
674 match_flag = 0;
675 }
676 }
677
678
679 //first reboot, command from recovery, need reboot next
680 if (!strcmp(rebootstatus,"reboot_next")) {
681 wrnP("--secure check reboot_next---\n");
682 //bootloader index, expect == current, no need reboot next
683 if (match_flag == 0) {
684 wrnP("current index is expect, no need reboot next, run cache recovery\n");
685 if (has_boot_slot == 1) {
686 wrnP("ab mode\n");
687 update_env = env_get("update_env");
688 if (!update_env) {
689 errorP("can not get update_env\n");
690 return -1;
691 }
692 if (strcmp(update_env, "1") == 0) {
693 printf("ab mode, default all uboot env\n");
694 run_command("defenv_reserv;saveenv;", 0);
695 env_set("update_env","0");
696 }
697 } else {
698 run_recovery_from_cache();
699 return 0;
700 }
701 } else {
702 wrnP("now ready start reboot next\n");
703 if (has_boot_slot == 1) {
704#ifdef CONFIG_MMC_MESON_GX
705 if (mmc != NULL)
706 gpt_flag = aml_gpt_valid(mmc);
707#endif
708 if (gpt_flag == 0)
709 ret = 0;
710
711#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
712 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
713
714 if (*efuse_field.data == 1)
715 ret = 0;
716#endif//#ifdef CONFIG_EFUSE_OBJ_API
717 if (ret == 0) {
718 wrnP("gpt or disable user bootloader mode, write boot1 to boot0\n");
719 write_bootloader_back("2", 1);
720#ifdef CONFIG_FASTBOOT
721 struct misc_virtual_ab_message message;
722
723 set_mergestatus_cancel(&message);
724#endif
725 char *slot;
726
727 slot = env_get("slot-suffixes");
728 if (!slot) {
729 run_command("get_valid_slot", 0);
730 slot = env_get("slot-suffixes");
731 }
732 if (strcmp(slot, "0") == 0) {
733 wrnP("back to slot b\n");
734 run_command("set_roll_flag 1", 0);
735 run_command("set_active_slot b", 0);
736 } else if (strcmp(slot, "1") == 0) {
737 wrnP("back to slot a\n");
738 run_command("set_roll_flag 1", 0);
739 run_command("set_active_slot a", 0);
740 }
741 env_set("expect_index", "1");
742 } else {
743 write_bootloader_back(bootloaderindex, 0);
744#ifdef CONFIG_FASTBOOT
745 struct misc_virtual_ab_message message;
746 set_mergestatus_cancel(&message);
747#endif
748 if (strcmp(bootloaderindex, "1") == 0) {
749 wrnP("back to slot a\n");
750 run_command("set_roll_flag 1", 0);
751 run_command("set_active_slot a", 0);
752 } else if (strcmp(bootloaderindex, "2") == 0) {
753 wrnP("back to slot b\n");
754 run_command("set_roll_flag 1", 0);
755 run_command("set_active_slot b", 0);
756 }
757 env_set("expect_index", "0");
758 }
759
760 env_set("update_env", "1");
761 env_set("reboot_status", "reboot_next");
762 run_command("saveenv", 0);
763 run_command("reset", 0);
764 } else {
765 env_set("reboot_status","reboot_finish");
766 run_command("saveenv", 0);
767 run_command("get_rebootmode", 0);
768 run_command("if test ${reboot_mode} = quiescent; then reboot next,quiescent; else reboot next; fi;", 0);
769 }
770 return 0;
771 }
772 } else if (!strcmp(rebootstatus,"reboot_finish")) {//second reboot, reboot next from uboot
773 wrnP("--secure check reboot_finish---\n");
774 env_set("reboot_status","reboot_end");
775 run_command("saveenv", 0);
776
777 if (match_flag == 0) {
778 wrnP("reboot next succ, bootloader secure check pass......\n");
779 if (has_boot_slot == 1) {
780 printf("ab mode, default all uboot env\n");
781 update_env = env_get("update_env");
782 if (!update_env) {
783 errorP("can not get update_env\n");
784 return -1;
785 }
786 if (strcmp(update_env, "1") == 0) {
787 printf("ab mode, default all uboot env\n");
788 run_command("defenv_reserv;saveenv;", 0);
789 env_set("update_env","0");
790
791 if (strcmp(bootloaderindex, "2") == 0) {
792 wrnP("rom always boot as boot0--> boot1\n");
793 wrnP("So if boot1 is ok, write it to boot0\n");
794 run_command("copy_slot_bootable 2 1", 0);
795 }
796 run_command("saveenv", 0);
797 }
798 } else {
799 run_recovery_from_cache();
800 return 0;
801 }
802 } else {
803 //bootloader check failed, run recovery show error
804 wrnP("reboot next fail, bootloader secure check fail(curr:%s, expect:%s)......\n",bootloaderindex, expect_index);
805 env_set("check_result","bootloader_fail");
806 run_command("saveenv", 0);
807 if (has_boot_slot == 1) {
808 wrnP("ab mode\n");
809#ifdef CONFIG_FASTBOOT
810 struct misc_virtual_ab_message message;
811 set_mergestatus_cancel(&message);
812#endif
813 if (strcmp(bootloaderindex, "1") == 0) {
814 wrnP("back to slot a\n");
815 run_command("set_roll_flag 1", 0);
816 run_command("set_active_slot a", 0);
817 } else if (strcmp(bootloaderindex, "2") == 0) {
818 wrnP("back to slot b\n");
819 run_command("set_roll_flag 1", 0);
820 run_command("set_active_slot b", 0);
821 }
822
823#ifdef CONFIG_MMC_MESON_GX
824 if (mmc != NULL)
825 gpt_flag = aml_gpt_valid(mmc);
826#endif
827
828 if (gpt_flag == 0)
829 ret = 0;
830
831#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
832 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
833
834 if (*efuse_field.data == 1)
835 ret = 0;
836#endif//#ifdef CONFIG_EFUSE_OBJ_API
837
838 if (ret == 0) {
839 wrnP("gpt or disable user bootloader mode\n");
840 env_set("update_env","0");
841 env_set("reboot_status","reboot_init");
842 run_command("saveenv", 0);
843 } else {
844 write_bootloader_back(bootloaderindex, 0);
845 env_set("update_env","1");
846 env_set("reboot_status","reboot_next");
847 env_set("expect_index","0");
848 run_command("saveenv", 0);
849 run_command("reset", 0);
850 }
851
852 } else {
853 run_recovery_from_flash();
854 return 0;
855 }
856 }
857 } else if (!strcmp(rebootstatus,"reboot_recovery")) {
858 //recovery check failed, run recovery show error
859 wrnP("--secure check reboot_recovery---\n");
860 env_set("reboot_status","reboot_end");
861 run_command("saveenv", 0);
862 run_recovery_from_flash();
863 return 0;
864 } else {
865 env_set("check_result","succ");
866 }
867
868 return 0;
869}
870
871
872U_BOOT_CMD_COMPLETE(
873 amlbootsta, 3, 0, do_get_bootloader_status,
874 "get bootloader status in env",
875 "[-p] print bootloader status\n"
876 "[-s] saveenv after generate bootloader status\n",
877 var_complete
878);
879
880U_BOOT_CMD_COMPLETE(
881 amlsecurecheck, 1, 0, do_secureboot_check,
882 "try bootloader/dtb/recovery secure check",
883 ""
884 "",
885 var_complete
886);
887
888