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