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