blob: 90fa298b111221fe220984387ddae174524bb159 [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;
Zhigang Yu6852d932024-02-26 11:32:53 +0000359 int iret = 0;
Bo Lv72d0e902023-01-02 14:27:34 +0000360 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
Zhigang Yu6852d932024-02-26 11:32:53 +0000386 iret = store_logic_read(partname, 0, BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, buffer);
387 if (iret) {
Bo Lv72d0e902023-01-02 14:27:34 +0000388 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
Zhigang Yu6852d932024-02-26 11:32:53 +0000394 iret = store_boot_write("bootloader", 1, BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, buffer);
395 if (iret) {
Bo Lv72d0e902023-01-02 14:27:34 +0000396 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
hao.qi4c4dc762024-03-11 10:38:23 +0800429// according to the value of the board,
430// reset the product to set the serial
431// to distinguish different products.
432void set_product(void)
433{
434 char *board = env_get("board");
435 char *str = NULL;
436 char *dup_str = NULL;
437
438 str = strstr(board, "_");
439 dup_str = strdup(str);
440 if (!(strstr(dup_str, "_")))
441 env_set("product", str + 1);
442 else
443 env_set("product", strtok(str, "_"));
444 free(dup_str);
445}
446
Bo Lv72d0e902023-01-02 14:27:34 +0000447static int do_secureboot_check(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) {
448 int match_flag = 0;
449 char *rebootstatus = NULL;
450 char *checkresult = NULL;
451 char *bootloaderindex = NULL;
452 char *expect_index = NULL;
453 char *robustota = NULL;
454 char *update_env = NULL;
455 char *rebootmode = NULL;
456 int gpt_flag = -1;
457 int ret = -1;
458
hao.qi4c4dc762024-03-11 10:38:23 +0800459// set product first to set serial.
460 set_product();
461
Bo Lv72d0e902023-01-02 14:27:34 +0000462#ifdef CONFIG_MMC_MESON_GX
463 struct mmc *mmc = NULL;
464 //int capacity_boot = 0;
465
466 if (store_get_type() == BOOT_EMMC)
467 mmc = find_mmc_device(1);
468#endif
469 //unsupport update dt in boothal, update dt in uboot
470 run_command("update_dt;", 0);
471
472 bootloader_wp();
473
474 //set default env before check
475 env_set("recovery_mode", "false");
476
477 //if recovery mode, need disable dv, if factoryreset, need default uboot env
478 aml_recovery();
479
480#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
481 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
482
483 if (*efuse_field.data == 1) {
484 wrnP("efuse_field.data == 1\n");
485 env_set("nocs_mode", "true");
486 } else {
487 wrnP("efuse_field.data != 1\n");
488 env_set("nocs_mode", "false");
489 }
490#endif//#ifdef CONFIG_EFUSE_OBJ_API
491
492 char *write_boot = env_get("write_boot");
493
494 if (!strcmp(write_boot, "1")) {
495 printf("need to write boot0\n");
496 if (write_boot0()) {
497 printf("write boot0 fail, need to rollback!\n");
498 update_rollback();
499 } else {
500 printf("write boot0 success, need to reset!\n");
501 }
502
503 env_set("write_boot", "0");
504 env_set("reboot_status", "reboot_next");
505 env_set("expect_index", "1");
506 env_set("update_env", "1");
507 run_command("saveenv", 0);
508 run_command("reset", 0);
509 }
510 run_command("get_rebootmode", 0);
511 rebootmode = env_get("reboot_mode");
512 if (!rebootmode) {
513 wrnP("can not get reboot mode, so skip secure check\n");
514 return -1;
515 }
516 printf("rebootmode is %s\n", rebootmode);
517 if (rebootmode && (strcmp(rebootmode, "rescueparty") == 0)) {
518 printf("rebootmode is rescueparty, need rollback\n");
519 char *slot;
520
521#ifdef CONFIG_MMC_MESON_GX
522 if (mmc)
523 gpt_flag = aml_gpt_valid(mmc);
524#endif
525 if (gpt_flag == 0)
526 ret = 0;
527
528#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
529 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
530
531 //dis_user_flag = run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
532 if (*efuse_field.data == 1)
533 ret = 0;
534#endif//#ifdef CONFIG_EFUSE_OBJ_API
535
536#ifdef CONFIG_FASTBOOT
537 struct misc_virtual_ab_message message;
538
539 set_mergestatus_cancel(&message);
540#endif
541
542 slot = env_get("slot-suffixes");
543 if (!slot) {
544 run_command("get_valid_slot", 0);
545 slot = env_get("slot-suffixes");
546 }
547 if (strcmp(slot, "0") == 0) {
548 if (ret != 0) {
549 wrnP("normal mode\n");
550 write_bootloader_back("2", 0);
551 env_set("expect_index", "0");
552 } else {
553 wrnP("gpt or disable user bootloader mode\n");
554 write_bootloader_back("2", 1);
555 env_set("expect_index", "1");
556 }
557 wrnP("back to slot b\n");
558 run_command("set_roll_flag 1", 0);
559 run_command("set_active_slot b", 0);
560 } else if (strcmp(slot, "1") == 0) {
561 if (ret != 0) {
562 wrnP("normal mode\n");
563 write_bootloader_back("1", 0);
564 env_set("expect_index", "0");
565 } else {
566 wrnP("gpt or disable user bootloader mode\n");
567 write_bootloader_back("2", 1);
568 env_set("expect_index", "1");
569 }
570 wrnP("back to slot a\n");
571 run_command("set_roll_flag 1", 0);
572 run_command("set_active_slot a", 0);
573 }
574
575 env_set("update_env", "1");
576 env_set("reboot_status", "reboot_next");
577 run_command("saveenv", 0);
578 run_command("reset", 0);
579 }
580
581 //check_result init
582 checkresult = env_get("check_result");
583 if (checkresult == NULL) {
584 env_set("check_result","succ");
585 }
586
587 //reboot_status init
588 rebootstatus = env_get("reboot_status");
589 if (rebootstatus == NULL) {
590 env_set("reboot_status","reboot_init");
591 rebootstatus = env_get("reboot_status");
592 }
593
594 if (rebootstatus == NULL) {
595 printf("rebootstatus is NULL, skip check\n");
596 return -1;
597 }
598
599 //check reboot_end
600 if (!strcmp(rebootstatus, "reboot_end")) {
601 env_set("reboot_status","reboot_init");
602 run_command("saveenv", 0);
603 }
604
605 //get boot status
606 run_command("amlbootsta -p -s", 0);
607
608 //get forUpgrade_robustOta and check if support robustota
609 robustota = env_get("forUpgrade_robustOta");
610 if ((robustota == NULL) || !strcmp(robustota, "false")) {
611 return -1;
612 }
613
614 //get bootloader index
615 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
616 if (bootloaderindex == NULL) {
617 wrnP("can not get bootloader index, so skip secure check\n");
618 return -1;
619 }
620/*
621#ifdef CONFIG_MMC_MESON_GX
622 if (mmc) {
623 struct blk_desc *dev_desc = mmc_get_blk_desc(mmc);
624
625 if (dev_desc && !strcmp(bootloaderindex, "0")) {
626 unsigned char *buffer = NULL;
627 capacity_boot = mmc->capacity_boot;
628
629 printf("do_secureboot_check_capacity_boot: %x\n", capacity_boot);
630
631 buffer = (unsigned char *)malloc(capacity_boot);
632 if (buffer) {
633 memset(buffer, 0, capacity_boot);
634 ret = store_boot_read("bootloader", 0, 0, buffer);
635 if (ret == 0) {
636 wrnP("--read bootloader ok, check valib gpt---\n");
637 if (is_valid_gpt_buf(dev_desc, buffer + 0x3DFE00)) {
638 printf("no gpt partition table\n");
639 } else {
640 printf("find gpt partition table, update it\n"
641 "and write bootloader to boot0/boot1\n");
642 ret = write_mbr_and_gpt_partitions(dev_desc,
643 buffer + 0x3DFE00);
644 if (ret == 0) {
645 printf("write gpt ok, reset\n");
646 write_bootloader_back(bootloaderindex, 1);
647 write_bootloader_back(bootloaderindex, 2);
648 run_command("reboot bootloader", 0);
649 }
650 }
651 }
652 free(buffer);
653 }
654 }
655 }
656#endif
657*/
658
659 //no secure check need
660 if (!strcmp(rebootstatus, "reboot_init")) {
661 printf("rebootstatus is reboot_init, skip check\n");
662 return -1;
663 }
664
665 //get expect index
666 expect_index = env_get("expect_index");
667 if (expect_index == NULL) {
668 wrnP("can not get expect index, so skip secure check\n");
669 return -1;
670 }
671
672 wrnP("expect_index is : %s\n", expect_index);
673
674 match_flag = strcmp(bootloaderindex, expect_index);
675
676 //ignore reboot next check if power off during reboot next to finish
677 if (rebootmode && (strcmp(rebootmode, "cold_boot") == 0)) {
678 if (!strcmp(rebootstatus, "reboot_finish")) {
679 match_flag = 0;
680 }
681 }
682
683
684 //first reboot, command from recovery, need reboot next
685 if (!strcmp(rebootstatus,"reboot_next")) {
686 wrnP("--secure check reboot_next---\n");
687 //bootloader index, expect == current, no need reboot next
688 if (match_flag == 0) {
689 wrnP("current index is expect, no need reboot next, run cache recovery\n");
690 if (has_boot_slot == 1) {
691 wrnP("ab mode\n");
692 update_env = env_get("update_env");
693 if (!update_env) {
694 errorP("can not get update_env\n");
695 return -1;
696 }
697 if (strcmp(update_env, "1") == 0) {
698 printf("ab mode, default all uboot env\n");
699 run_command("defenv_reserv;saveenv;", 0);
700 env_set("update_env","0");
701 }
702 } else {
703 run_recovery_from_cache();
704 return 0;
705 }
706 } else {
707 wrnP("now ready start reboot next\n");
708 if (has_boot_slot == 1) {
709#ifdef CONFIG_MMC_MESON_GX
710 if (mmc != NULL)
711 gpt_flag = aml_gpt_valid(mmc);
712#endif
713 if (gpt_flag == 0)
714 ret = 0;
715
716#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
717 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
718
719 if (*efuse_field.data == 1)
720 ret = 0;
721#endif//#ifdef CONFIG_EFUSE_OBJ_API
722 if (ret == 0) {
723 wrnP("gpt or disable user bootloader mode, write boot1 to boot0\n");
724 write_bootloader_back("2", 1);
725#ifdef CONFIG_FASTBOOT
726 struct misc_virtual_ab_message message;
727
728 set_mergestatus_cancel(&message);
729#endif
730 char *slot;
731
732 slot = env_get("slot-suffixes");
733 if (!slot) {
734 run_command("get_valid_slot", 0);
735 slot = env_get("slot-suffixes");
736 }
737 if (strcmp(slot, "0") == 0) {
738 wrnP("back to slot b\n");
739 run_command("set_roll_flag 1", 0);
740 run_command("set_active_slot b", 0);
741 } else if (strcmp(slot, "1") == 0) {
742 wrnP("back to slot a\n");
743 run_command("set_roll_flag 1", 0);
744 run_command("set_active_slot a", 0);
745 }
746 env_set("expect_index", "1");
747 } else {
748 write_bootloader_back(bootloaderindex, 0);
749#ifdef CONFIG_FASTBOOT
750 struct misc_virtual_ab_message message;
751 set_mergestatus_cancel(&message);
752#endif
753 if (strcmp(bootloaderindex, "1") == 0) {
754 wrnP("back to slot a\n");
755 run_command("set_roll_flag 1", 0);
756 run_command("set_active_slot a", 0);
757 } else if (strcmp(bootloaderindex, "2") == 0) {
758 wrnP("back to slot b\n");
759 run_command("set_roll_flag 1", 0);
760 run_command("set_active_slot b", 0);
761 }
762 env_set("expect_index", "0");
763 }
764
765 env_set("update_env", "1");
766 env_set("reboot_status", "reboot_next");
767 run_command("saveenv", 0);
768 run_command("reset", 0);
769 } else {
770 env_set("reboot_status","reboot_finish");
771 run_command("saveenv", 0);
772 run_command("get_rebootmode", 0);
773 run_command("if test ${reboot_mode} = quiescent; then reboot next,quiescent; else reboot next; fi;", 0);
774 }
775 return 0;
776 }
777 } else if (!strcmp(rebootstatus,"reboot_finish")) {//second reboot, reboot next from uboot
778 wrnP("--secure check reboot_finish---\n");
779 env_set("reboot_status","reboot_end");
780 run_command("saveenv", 0);
781
782 if (match_flag == 0) {
783 wrnP("reboot next succ, bootloader secure check pass......\n");
784 if (has_boot_slot == 1) {
785 printf("ab mode, default all uboot env\n");
786 update_env = env_get("update_env");
787 if (!update_env) {
788 errorP("can not get update_env\n");
789 return -1;
790 }
791 if (strcmp(update_env, "1") == 0) {
792 printf("ab mode, default all uboot env\n");
793 run_command("defenv_reserv;saveenv;", 0);
794 env_set("update_env","0");
795
796 if (strcmp(bootloaderindex, "2") == 0) {
797 wrnP("rom always boot as boot0--> boot1\n");
798 wrnP("So if boot1 is ok, write it to boot0\n");
799 run_command("copy_slot_bootable 2 1", 0);
800 }
801 run_command("saveenv", 0);
802 }
803 } else {
804 run_recovery_from_cache();
805 return 0;
806 }
807 } else {
808 //bootloader check failed, run recovery show error
809 wrnP("reboot next fail, bootloader secure check fail(curr:%s, expect:%s)......\n",bootloaderindex, expect_index);
810 env_set("check_result","bootloader_fail");
811 run_command("saveenv", 0);
812 if (has_boot_slot == 1) {
813 wrnP("ab mode\n");
814#ifdef CONFIG_FASTBOOT
815 struct misc_virtual_ab_message message;
816 set_mergestatus_cancel(&message);
817#endif
818 if (strcmp(bootloaderindex, "1") == 0) {
819 wrnP("back to slot a\n");
820 run_command("set_roll_flag 1", 0);
821 run_command("set_active_slot a", 0);
822 } else if (strcmp(bootloaderindex, "2") == 0) {
823 wrnP("back to slot b\n");
824 run_command("set_roll_flag 1", 0);
825 run_command("set_active_slot b", 0);
826 }
827
828#ifdef CONFIG_MMC_MESON_GX
829 if (mmc != NULL)
830 gpt_flag = aml_gpt_valid(mmc);
831#endif
832
833 if (gpt_flag == 0)
834 ret = 0;
835
836#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
837 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
838
839 if (*efuse_field.data == 1)
840 ret = 0;
841#endif//#ifdef CONFIG_EFUSE_OBJ_API
842
843 if (ret == 0) {
844 wrnP("gpt or disable user bootloader mode\n");
845 env_set("update_env","0");
846 env_set("reboot_status","reboot_init");
847 run_command("saveenv", 0);
848 } else {
849 write_bootloader_back(bootloaderindex, 0);
850 env_set("update_env","1");
851 env_set("reboot_status","reboot_next");
852 env_set("expect_index","0");
853 run_command("saveenv", 0);
854 run_command("reset", 0);
855 }
856
857 } else {
858 run_recovery_from_flash();
859 return 0;
860 }
861 }
862 } else if (!strcmp(rebootstatus,"reboot_recovery")) {
863 //recovery check failed, run recovery show error
864 wrnP("--secure check reboot_recovery---\n");
865 env_set("reboot_status","reboot_end");
866 run_command("saveenv", 0);
867 run_recovery_from_flash();
868 return 0;
869 } else {
870 env_set("check_result","succ");
871 }
872
873 return 0;
874}
875
876
877U_BOOT_CMD_COMPLETE(
878 amlbootsta, 3, 0, do_get_bootloader_status,
879 "get bootloader status in env",
880 "[-p] print bootloader status\n"
881 "[-s] saveenv after generate bootloader status\n",
882 var_complete
883);
884
885U_BOOT_CMD_COMPLETE(
886 amlsecurecheck, 1, 0, do_secureboot_check,
887 "try bootloader/dtb/recovery secure check",
888 ""
889 "",
890 var_complete
891);
892
893