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