blob: d9da34ba369801c5ab990fa316ecca7571f62bf2 [file] [log] [blame]
Bo Lv72d0e902023-01-02 14:27:34 +00001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include <config.h>
7#include <common.h>
8#include <linux/kernel.h>
9#include <amlogic/aml_efuse.h>
10#include <amlogic/cpu_id.h>
11#include <amlogic/storage.h>
12#include <amlogic/partition_table.h>
13#include <fastboot.h>
14#include <amlogic/emmc_partitions.h>
15#include <asm/amlogic/arch/efuse.h>
16#include <android_image.h>
17#include <amlogic/android_vab.h>
Mingyen Hung6e468002023-01-04 23:43:04 -080018#include <amlogic/aml_rollback.h>
Xindong Xu22e8daf2024-03-12 18:08:41 +080019#include <cli.h>
Bo Lv72d0e902023-01-02 14:27:34 +000020
21#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
22extern efuse_obj_field_t efuse_field;
23#endif//#ifdef CONFIG_EFUSE_OBJ_API
24
Bo Lv72d0e902023-01-02 14:27:34 +000025int __attribute__((weak)) store_logic_read(const char *name, loff_t off, size_t size, void *buf)
26{ return store_read(name, off, size, buf);}
27
Bo Lv72d0e902023-01-02 14:27:34 +000028#define debugP(fmt...) //printf("[DbgBootSta]L%d:", __LINE__),printf(fmt)
29#define errorP(fmt...) printf("ErrBootSta(L%d):", __LINE__),printf(fmt)
30#define wrnP(fmt...) printf("wrn:"fmt)
31#define MsgP(fmt...) printf("[BootSta]"fmt)
32
33#define BOOTLOADER_OFFSET 512
34#define BOOTLOADER_MAX_SIZE (4 * 1024 * 1024)
Zhigang Yude5719e2024-03-08 09:14:23 +000035#define MIB_SIZE (1024 * 1024)
36
Bo Lv72d0e902023-01-02 14:27:34 +000037
38//check SWPL-31296 for details
39static int do_get_bootloader_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
40{
41 bool printStat = false;
42 bool saveenv = false;
43 debugP("Initial value for argc=%d\n", argc);
44 while (argc > 1 && **(argv + 1) == '-') {
45 char *arg = *++argv;
46
47 --argc;
48 while (*++arg) {
49 switch (*arg) {
50 case 'p': /* print */
51 printStat = true;
52 break;
53 case 's': /* saveenv */
54 saveenv = true;
55 break;
56 default:
57 return CMD_RET_USAGE;
58 }
59 }
60 }
61 debugP("Final value for argc=%d\n", argc);
62 //1,forUpgrade_socType, cpu familyId
63 const cpu_id_t cpuid = get_cpu_id();
64 const int familyId = cpuid.family_id;
65 env_set_hex("forUpgrade_socType", familyId);
66
67 //2,forUpgrade_secureBoot
68 const bool secureboot = IS_FEAT_BOOT_VERIFY();
69 env_set("forUpgrade_secureBoot", secureboot ? "true" : "false");
70
71 //3,forUpgrade_robustOta
72 bool supportRobustOta = false;
73 switch (familyId) {
74 case 0x32://sc2
75 case 0x36://t7
76 case 0x37://s4
77 case 0x38://t3
78 case 0x3A://s4d
79 supportRobustOta = true;
80 break;
81 default:
82 {
83 if (familyId > 0x3A) {
84 supportRobustOta = true;
85 }
86 }
87 break;
88 }
89 env_set("forUpgrade_robustOta", supportRobustOta ? "true" : "false");
90
91 //4,forUpgrade_flashType
92 const char* BootDevices[] = {
93 "BOOT_EMMC", "BOOT_SD",
94 "BOOT_NAND_NFTL", "BOOT_NAND_MTD",
95 "BOOT_SNAND", "BOOT_SNOR",
96 };
97 const char* bootDevice = "BOOT_NONE";
98 enum boot_type_e bootType = store_get_type();
99 int i = 0;
100 for (; i < ARRAY_SIZE(BootDevices); ++i) {
101 if ((1<<i) != bootType) continue;
102 bootDevice = BootDevices[i];
103 break;
104 }
105 env_set("forUpgrade_flashType", bootDevice);
106
107 //5,forUpgrade_bootloaderCopies, how many copies supported
108 int bootCopies = 1;
109 switch (bootType) {
110 case BOOT_EMMC: bootCopies = 3; break;
111 default:break;
112 }
113 env_set_ulong("forUpgrade_bootloaderCopies", bootCopies);
114
115 //6,forUpgrade_bootloaderIndex
116 //for emmc, 0/1/2 is user/boot0/boot1
117 const int bootCpyIndex = store_bootup_bootidx("bootloader");
118 env_set_ulong("forUpgrade_bootloaderIndex", bootCpyIndex);
119
120 //7,get first boot index, for defendkey
121 const int firstBootCpyIndex = store_boot_copy_start();
122 env_set_ulong("forUpgrade_1stBootIndex", firstBootCpyIndex);
123
124 if (printStat) run_command("printenv forUpgrade_socType forUpgrade_secureBoot "
125 " forUpgrade_robustOta forUpgrade_flashType forUpgrade_bootloaderCopies "
126 " forUpgrade_bootloaderIndex forUpgrade_1stBootIndex", 0);
127
Sam Wu6f3d40e2023-04-22 01:10:27 +0800128 if (saveenv) {
129 if (CONFIG_IS_ENABLED(AML_UPDATE_ENV))
130 run_command("update_env_part -p forUpgrade_robustOta "\
131 "forUpgrade_bootloaderIndex", 0);
132 else
133 run_command("saveenv", 0);
134 }
135
Bo Lv72d0e902023-01-02 14:27:34 +0000136
137 return CMD_RET_SUCCESS;
138}
139
140static void run_recovery_from_flash(void) {
141 env_set("dolby_status","0");
142 run_command("run init_display", 0);
143 run_command("run storeargs", 0);
144 run_command("get_rebootmode", 0);
145 run_command("if test ${reboot_mode} = quiescent; then "\
146 "setenv bootconfig ${bootconfig} androidboot.quiescent=1; fi;", 0);
147 run_command("if test ${reboot_mode} = recovery_quiescent; then "\
148 "setenv bootconfig ${bootconfig} androidboot.quiescent=1; fi;", 0);
149 run_command("run recovery_from_flash", 0);
150}
151
Bo Lv72d0e902023-01-02 14:27:34 +0000152int write_bootloader_back(const char* bootloaderindex, int dstindex) {
153 int iRet = 0;
154 int copy = 0;
155 int ret = -1;
156 unsigned char* buffer = NULL;
157 int capacity_boot = 0;
158
159 if (strcmp(bootloaderindex, "1") == 0) {
160 copy = 1;
161 } else if (strcmp(bootloaderindex, "2") == 0) {
162 copy = 2;
163 } else if (strcmp(bootloaderindex, "0") == 0) {
164 copy = 0;
165 }
166
167#ifdef CONFIG_MMC_MESON_GX
168 struct mmc *mmc = NULL;
169
170 if (store_get_type() == BOOT_EMMC)
171 mmc = find_mmc_device(1);
172
173 if (mmc)
174 capacity_boot = mmc->capacity_boot;
175#endif
176
177 printf("write_bootloader_back_capacity_boot: %x\n", capacity_boot);
178
179 buffer = (unsigned char *)malloc(capacity_boot);
180 if (!buffer)
181 {
182 printf("ERROR! fail to allocate memory ...\n");
183 goto exit;
184 }
185 memset(buffer, 0, capacity_boot);
186 iRet = store_boot_read("bootloader", copy, 0, buffer);
187 if (iRet) {
188 errorP("Fail read bootloader from rsv with sz\n");
189 goto exit;
190 }
191 iRet = store_boot_write("bootloader", dstindex, 0, buffer);
192 if (iRet) {
193 printf("Failed to write bootloader\n");
194 goto exit;
195 } else {
196 ret = 0;
197 }
198
199exit:
200 if (buffer)
201 {
202 free(buffer);
203 //buffer = NULL;
204 }
205 return ret;
206}
207
208//bootloader write protect
209static void bootloader_wp(void)
210{
211#ifdef CONFIG_MMC_MESON_GX
212 if (store_get_type() == BOOT_EMMC) {//emmc device
213 if (IS_FEAT_BOOT_VERIFY()) { //secure boot enable
214 if (BOOTLOADER_MODE_ADVANCE_INIT) { //new arch chip
215 env_set("bootloader_wp", "1");
216 }
217 }
218 }
219#endif
220}
221
222static void aml_recovery(void) {
223 char *mode = NULL;
224 char command[32];
225 char miscbuf[4096] = {0};
226
227 run_command("get_rebootmode", 0);
228
229 //get reboot_mode
230 mode = env_get("reboot_mode");
231 if (mode == NULL) {
232 wrnP("can not get reboot mode, so skip recovery check\n");
233 } else {
234 if ((!strcmp(mode, "factory_reset")) || (!strcmp(mode, "update"))) {
235 env_set("dolby_status","0");
236 }
237 }
238
239#ifdef CONFIG_BOOTLOADER_CONTROL_BLOCK
240 int ret = 0;
241 extern int boot_info_open_partition(char *miscbuf);
242 ret = boot_info_open_partition(miscbuf);
243 if (ret != 0) {
244 wrnP("open misc partition failed, so skip recovery check");
245 return;
246 }
247#endif
248
249 //if run recovery, need disable dolby
250 memcpy(command, miscbuf, 32);
251 if (!memcmp(command, "boot-recovery", strlen("boot-recovery"))) {
252 env_set("dolby_status","0");
253 return;
254 }
255}
256
257void update_rollback(void)
258{
259 char *slot = NULL;
260 int ret = -1;
261 int gpt_flag = -1;
262
263#ifdef CONFIG_MMC_MESON_GX
264 struct mmc *mmc = NULL;
265
266 if (store_get_type() == BOOT_EMMC)
267 mmc = find_mmc_device(1);
268
269 if (mmc)
270 gpt_flag = aml_gpt_valid(mmc);
271#endif
272 if (gpt_flag == 0)
273 ret = 0;
274
275#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
276 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
277
278 //dis_user_flag = run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
279 if (*efuse_field.data == 1)
280 ret = 0;
281#endif//#ifdef CONFIG_EFUSE_OBJ_API
282
283 slot = env_get("slot-suffixes");
284 if (!slot) {
285 run_command("get_valid_slot", 0);
286 slot = env_get("slot-suffixes");
287 }
288 if (strcmp(slot, "0") == 0) {
289 if (ret != 0) {
290 wrnP("normal mode\n");
291 write_bootloader_back("2", 0);
292 env_set("expect_index", "0");
293 } else {
294 wrnP("gpt or disable user bootloader mode\n");
295 write_bootloader_back("2", 1);
296 env_set("expect_index", "1");
297 }
298 wrnP("back to slot b\n");
299 run_command("set_roll_flag 1", 0);
300 run_command("set_active_slot b", 0);
301 } else if (strcmp(slot, "1") == 0) {
302 if (ret != 0) {
303 wrnP("normal mode\n");
304 write_bootloader_back("1", 0);
305 env_set("expect_index", "0");
306 } else {
307 wrnP("gpt or disable user bootloader mode\n");
308 write_bootloader_back("2", 1);
309 env_set("expect_index", "1");
310 }
311 wrnP("back to slot a\n");
312 run_command("set_roll_flag 1", 0);
313 run_command("set_active_slot a", 0);
314 }
315 env_set("update_env", "1");
316 env_set("reboot_status", "reboot_next");
317}
318
Zhigang Yude5719e2024-03-08 09:14:23 +0000319static int write_bootloader(int i)
Bo Lv72d0e902023-01-02 14:27:34 +0000320{
321 unsigned char *buffer = NULL;
Sam Wu6f3d40e2023-04-22 01:10:27 +0800322 int capacity_boot = 0x2000 * 512;
Zhigang Yu6852d932024-02-26 11:32:53 +0000323 int iret = 0;
Bo Lv72d0e902023-01-02 14:27:34 +0000324 char partname[32] = {0};
325 char *slot_name = NULL;
326
327#ifdef CONFIG_MMC_MESON_GX
328 struct mmc *mmc = NULL;
329
330 if (store_get_type() == BOOT_EMMC)
331 mmc = find_mmc_device(1);
332
333 if (mmc)
334 capacity_boot = mmc->capacity_boot;
335#endif
336 printf("capacity_boot: 0x%x\n", capacity_boot);
337 buffer = (unsigned char *)malloc(capacity_boot);
338 if (!buffer) {
339 printf("ERROR! fail to allocate memory ...\n");
340 return -1;
341 }
342 memset(buffer, 0, capacity_boot);
343
344 slot_name = env_get("active_slot");
345 if (slot_name && (strcmp(slot_name, "_a") == 0))
346 strcpy((char *)partname, "bootloader_a");
347 else if (slot_name && (strcmp(slot_name, "_b") == 0))
348 strcpy((char *)partname, "bootloader_b");
Zhigang Yude5719e2024-03-08 09:14:23 +0000349 else
350 strcpy((char *)partname, "bootloader_up");
Bo Lv72d0e902023-01-02 14:27:34 +0000351
Zhigang Yu6852d932024-02-26 11:32:53 +0000352 iret = store_logic_read(partname, 0, BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, buffer);
353 if (iret) {
Bo Lv72d0e902023-01-02 14:27:34 +0000354 errorP("Fail to read 0x%xB from part[%s] at offset 0\n",
355 BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, partname);
Sam Wu6f3d40e2023-04-22 01:10:27 +0800356 free(buffer);
Bo Lv72d0e902023-01-02 14:27:34 +0000357 return -1;
358 }
359
Zhigang Yude5719e2024-03-08 09:14:23 +0000360 iret = store_boot_write("bootloader", i, BOOTLOADER_MAX_SIZE - BOOTLOADER_OFFSET, buffer);
Zhigang Yu6852d932024-02-26 11:32:53 +0000361 if (iret) {
Bo Lv72d0e902023-01-02 14:27:34 +0000362 printf("Failed to write boot0\n");
Sam Wu6f3d40e2023-04-22 01:10:27 +0800363 free(buffer);
Bo Lv72d0e902023-01-02 14:27:34 +0000364 return -1;
365 }
Sam Wu6f3d40e2023-04-22 01:10:27 +0800366
367 free(buffer);
Bo Lv72d0e902023-01-02 14:27:34 +0000368 return 0;
369}
370
371/**
372 *set merge status
373*/
374int set_mergestatus_cancel(struct misc_virtual_ab_message *message)
375{
376 char *partition = "misc";
377 char vab_buf[1024] = {0};
378
379 if (store_read((const char *)partition,
380 SYSTEM_SPACE_OFFSET_IN_MISC, 1024, (unsigned char *)vab_buf) < 0) {
381 printf("failed to store read %s.\n", partition);
382 return -1;
383 }
384
385 memcpy(message, vab_buf, sizeof(struct misc_virtual_ab_message));
386 printf("message.merge_status: %d\n", message->merge_status);
387 if (message->merge_status == SNAPSHOTTED || message->merge_status == MERGING) {
388 message->merge_status = CANCELLED;
389 printf("set message.merge_status CANCELLED\n");
390 }
391 store_write((const char *)partition, SYSTEM_SPACE_OFFSET_IN_MISC, 1024, (unsigned char *)vab_buf);
392 return 0;
393}
394
hao.qi4c4dc762024-03-11 10:38:23 +0800395// according to the value of the board,
396// reset the product to set the serial
397// to distinguish different products.
398void set_product(void)
399{
400 char *board = env_get("board");
401 char *str = NULL;
402 char *dup_str = NULL;
403
404 str = strstr(board, "_");
405 dup_str = strdup(str);
406 if (!(strstr(dup_str, "_")))
407 env_set("product", str + 1);
408 else
409 env_set("product", strtok(str, "_"));
410 free(dup_str);
411}
412
Zhigang Yude5719e2024-03-08 09:14:23 +0000413void fastboot_step_check(char *rebootmode, int gpt_flag)
414{
415 char *bootloaderindex = NULL;
416 struct mmc *mmc = NULL;
417
418 if (store_get_type() == BOOT_EMMC)
419 mmc = find_mmc_device(1);
420
421 //get bootloader index
422 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
423 if (!bootloaderindex) {
424 wrnP("can not get bootloader index, so skip fastboot step check\n");
425 return;
426 }
427
428 char *fastboot_step = env_get("fastboot_step");
429
430 if (mmc && fastboot_step && (strcmp(fastboot_step, "1") == 0)) {
431 printf("reboot to new bootloader burned by fastboot\n");
432 env_set("update_env", "1");
433 env_set("fastboot_step", "2");
434 run_command("saveenv", 0);
435 if (rebootmode && (strcmp(rebootmode, "fastboot") == 0))
436 run_command("reboot next,bootloader", 0);
437 else
438 run_command("reboot next", 0);
439 }
440 if (mmc && fastboot_step && (strcmp(fastboot_step, "2") == 0)) {
441 struct blk_desc *dev_desc = mmc_get_blk_desc(mmc);
442
443 if (dev_desc && ((gpt_flag == 1 && !strcmp(bootloaderindex, "1")) ||
444 (gpt_flag == 0 && !strcmp(bootloaderindex, "0")))) {
445 printf("new bootloader error, please fastboot to another one\n");
446 env_set("fastboot_step", "0");
447 if (CONFIG_IS_ENABLED(AML_UPDATE_ENV))
448 run_command("update_env_part -p fastboot_step;", 0);
449 else
450 run_command("defenv_reserve;setenv fastboot_step 0;saveenv;", 0);
451 cli_init();
452 cli_loop();
453 }
454 }
455}
456
457int recovery_update(void)
458{
459 if (IS_ENABLED(CONFIG_MMC_MESON_GX)) {
460 char bufcmd[64];
461 unsigned long long size = 0;
462 char *recovery_need_update = NULL;
463 struct partitions *partition = NULL;
464 //"ANDROID!"
465 const unsigned char imghead[] = { 0x41, 0x4e, 0x44, 0x52, 0x4f, 0x49, 0x44, 0x21 };
466
467 if (store_get_type() != BOOT_EMMC)
468 return 0;
469
470 //check recoverybak partition exist
471 partition = find_mmc_partition_by_name("recoverybak");
472 if (!partition) {
473 printf("can not find recoverybak, skip\n");
474 return 0;
475 }
476
477 //check if need update recovery from recoverybak
478 recovery_need_update = env_get("recovery_need_update");
479 if (!recovery_need_update || strcmp(recovery_need_update, "1"))
480 return 0;
481
482 //read recoverybak header data for check
483 sprintf(bufcmd, "store read $loadaddr recoverybak 0 0x%x", 16);
484 run_command(bufcmd, 0);
485
486 unsigned char *loadaddr = NULL;
487
488 loadaddr = (unsigned char *)simple_strtoul(env_get("loadaddr"), NULL, 16);
489
490 //check recoverybak head is start "ANDROID!"
491 if (memcmp((void *)imghead, loadaddr, 8)) {
492 printf("not valid recovery image, skip update recovery\n");
493 return 0;
494 }
495
496 //write recoverybak data to recovery
497 while (size < partition->size) {
498 unsigned long long write_size = 0;
499 unsigned long long left_size = partition->size - size;
500
501 if (left_size > 10 * MIB_SIZE)
502 write_size = 10 * MIB_SIZE;
503 else
504 write_size = partition->size - size;
505
506 sprintf(bufcmd, "store read $loadaddr recoverybak 0x%llx 0x%llx",
507 size, write_size);
508 run_command(bufcmd, 0);
509 sprintf(bufcmd, "store write $loadaddr recovery 0x%llx 0x%llx",
510 size, write_size);
511 run_command(bufcmd, 0);
512 size += write_size;
513 }
514
515 //clean recovery_need_update to 0
516 env_set("recovery_need_update", "0");
517 if (CONFIG_IS_ENABLED(AML_UPDATE_ENV))
518 run_command("update_env_part -p recovery_need_update;", 0);
519 else
520 run_command("saveenv", 0);
521 }
522 return 0;
523}
524
525//add non ab recovery update flow here
526int non_ab_update(char *rebootmode)
527{
Bo Lv72d0e902023-01-02 14:27:34 +0000528 int match_flag = 0;
529 char *rebootstatus = NULL;
530 char *checkresult = NULL;
531 char *bootloaderindex = NULL;
532 char *expect_index = NULL;
533 char *robustota = NULL;
Bo Lv72d0e902023-01-02 14:27:34 +0000534
535 char *write_boot = env_get("write_boot");
536
Zhigang Yude5719e2024-03-08 09:14:23 +0000537 if (write_boot && (!strcmp(write_boot, "1"))) {
538 printf("non ab for kernel 5.15 update bootloader\n");
539 write_bootloader(1);
540 write_bootloader(2);
541 env_set("write_boot", "0");
542 env_set("upgrade_step", "1");
543 run_command("saveenv", 0);
544 run_command("reset", 0);
545 }
546
547 recovery_update();
548
549 //check_result init
550 checkresult = env_get("check_result");
551 if (!checkresult)
552 env_set("check_result", "succ");
553
554 //reboot_status init
555 rebootstatus = env_get("reboot_status");
556 if (!rebootstatus) {
557 env_set("reboot_status", "reboot_init");
558 rebootstatus = env_get("reboot_status");
559 }
560
561 if (!rebootstatus) {
562 printf("rebootstatus is NULL, skip check\n");
563 return -1;
564 }
565
566 //check reboot_end
567 if (!strcmp(rebootstatus, "reboot_end")) {
568 env_set("reboot_status", "reboot_init");
569 run_command("saveenv", 0);
570 }
571
572 //get forUpgrade_robustOta and check if support robustota
573 robustota = env_get("forUpgrade_robustOta");
574 if (!robustota || !strcmp(robustota, "false"))
575 return -1;
576
577 //no secure check need
578 if (!strcmp(rebootstatus, "reboot_init")) {
579 printf("rebootstatus is reboot_init, skip check\n");
580 return -1;
581 }
582
583 //get bootloader index
584 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
585 if (!bootloaderindex) {
586 wrnP("can not get bootloader index, so skip secure check\n");
587 return -1;
588 }
589
590 //get expect index
591 expect_index = env_get("expect_index");
592 if (!expect_index) {
593 wrnP("can not get expect index, so skip secure check\n");
594 return -1;
595 }
596
597 wrnP("expect_index is : %s\n", expect_index);
598
599 match_flag = strcmp(bootloaderindex, expect_index);
600
601 //ignore reboot next check if power off during reboot next to finish
602 if (rebootmode && (strcmp(rebootmode, "cold_boot") == 0)) {
603 if (!strcmp(rebootstatus, "reboot_finish"))
604 match_flag = 0;
605 }
606
607 if (!strcmp(rebootstatus, "reboot_next")) {
608 env_set("reboot_status", "reboot_finish");
609 run_command("saveenv", 0);
610 run_command("get_rebootmode", 0);
611 if (rebootmode && (strcmp(rebootmode, "quiescent") == 0))
612 run_command("reboot next,quiescent", 0);
613 else
614 run_command("reboot next", 0);
615 } else if (!strcmp(rebootstatus, "reboot_finish")) {
616 wrnP("--secure check reboot_finish---\n");
617 env_set("reboot_status", "reboot_end");
618 run_command("saveenv", 0);
619 if (match_flag == 0) {
620 wrnP("reboot next succ, bootloader secure check pass......\n");
621 } else {
622 //bootloader check failed, run recovery show error
623 wrnP("reboot next fail, bootloader secure check fail(curr:%s, expect:%s)\n",
624 bootloaderindex, expect_index);
625 env_set("check_result", "bootloader_fail");
626 run_command("saveenv", 0);
627 }
628 run_recovery_from_flash();
629 return 0;
630 } else {
631 env_set("check_result", "succ");
632 }
633 return 0;
634}
635
636//add ab update and ab rollback flow here
637int ab_update_rollback(char *rebootmode, int gpt_flag)
638{
639 int match_flag = 0;
640 char *rebootstatus = NULL;
641 char *bootloaderindex = NULL;
642 char *expect_index = NULL;
643
644 //update bootloader_a/b/up to boot0
645 char *write_boot = env_get("write_boot");
646
647 if (write_boot && !strcmp(write_boot, "1")) {
Bo Lv72d0e902023-01-02 14:27:34 +0000648 printf("need to write boot0\n");
Zhigang Yude5719e2024-03-08 09:14:23 +0000649 if (write_bootloader(1)) {
Bo Lv72d0e902023-01-02 14:27:34 +0000650 printf("write boot0 fail, need to rollback!\n");
651 update_rollback();
652 } else {
653 printf("write boot0 success, need to reset!\n");
654 }
655
656 env_set("write_boot", "0");
657 env_set("reboot_status", "reboot_next");
658 env_set("expect_index", "1");
659 env_set("update_env", "1");
660 run_command("saveenv", 0);
661 run_command("reset", 0);
662 }
Zhigang Yude5719e2024-03-08 09:14:23 +0000663
664 //check rescueparty and rollback
Bo Lv72d0e902023-01-02 14:27:34 +0000665 if (rebootmode && (strcmp(rebootmode, "rescueparty") == 0)) {
666 printf("rebootmode is rescueparty, need rollback\n");
667 char *slot;
668
Bo Lv72d0e902023-01-02 14:27:34 +0000669#ifdef CONFIG_FASTBOOT
670 struct misc_virtual_ab_message message;
Bo Lv72d0e902023-01-02 14:27:34 +0000671 set_mergestatus_cancel(&message);
672#endif
673
674 slot = env_get("slot-suffixes");
675 if (!slot) {
676 run_command("get_valid_slot", 0);
677 slot = env_get("slot-suffixes");
678 }
679 if (strcmp(slot, "0") == 0) {
Zhigang Yude5719e2024-03-08 09:14:23 +0000680 if (gpt_flag == 0) {
Bo Lv72d0e902023-01-02 14:27:34 +0000681 wrnP("normal mode\n");
682 write_bootloader_back("2", 0);
683 env_set("expect_index", "0");
684 } else {
685 wrnP("gpt or disable user bootloader mode\n");
686 write_bootloader_back("2", 1);
687 env_set("expect_index", "1");
688 }
689 wrnP("back to slot b\n");
690 run_command("set_roll_flag 1", 0);
691 run_command("set_active_slot b", 0);
692 } else if (strcmp(slot, "1") == 0) {
Zhigang Yude5719e2024-03-08 09:14:23 +0000693 if (gpt_flag == 0) {
Bo Lv72d0e902023-01-02 14:27:34 +0000694 wrnP("normal mode\n");
695 write_bootloader_back("1", 0);
696 env_set("expect_index", "0");
697 } else {
698 wrnP("gpt or disable user bootloader mode\n");
699 write_bootloader_back("2", 1);
700 env_set("expect_index", "1");
701 }
702 wrnP("back to slot a\n");
703 run_command("set_roll_flag 1", 0);
704 run_command("set_active_slot a", 0);
705 }
706
707 env_set("update_env", "1");
708 env_set("reboot_status", "reboot_next");
709 run_command("saveenv", 0);
710 run_command("reset", 0);
711 }
712
Bo Lv72d0e902023-01-02 14:27:34 +0000713 //get bootloader index
714 bootloaderindex = env_get("forUpgrade_bootloaderIndex");
715 if (bootloaderindex == NULL) {
716 wrnP("can not get bootloader index, so skip secure check\n");
717 return -1;
718 }
Xindong Xu22e8daf2024-03-12 18:08:41 +0800719
Bo Lv72d0e902023-01-02 14:27:34 +0000720 //get expect index
721 expect_index = env_get("expect_index");
722 if (expect_index == NULL) {
723 wrnP("can not get expect index, so skip secure check\n");
724 return -1;
725 }
726
727 wrnP("expect_index is : %s\n", expect_index);
728
729 match_flag = strcmp(bootloaderindex, expect_index);
730
Zhigang Yude5719e2024-03-08 09:14:23 +0000731 rebootstatus = env_get("reboot_status");
Bo Lv72d0e902023-01-02 14:27:34 +0000732
Zhigang Yude5719e2024-03-08 09:14:23 +0000733 //if reboot next need check bootloader rollback
734 if (rebootstatus && !strcmp(rebootstatus, "reboot_next")) {
Bo Lv72d0e902023-01-02 14:27:34 +0000735 wrnP("--secure check reboot_next---\n");
736 //bootloader index, expect == current, no need reboot next
Zhigang Yude5719e2024-03-08 09:14:23 +0000737 if (match_flag != 0) {
738 wrnP("bootloader wrong, start rollback\n");
739 if (gpt_flag == 1) {
740 wrnP("gpt or disable user bootloader mode, write boot1 to boot0\n");
741 write_bootloader_back("2", 1);
Bo Lv72d0e902023-01-02 14:27:34 +0000742#ifdef CONFIG_FASTBOOT
Zhigang Yude5719e2024-03-08 09:14:23 +0000743 struct misc_virtual_ab_message message;
Bo Lv72d0e902023-01-02 14:27:34 +0000744
Zhigang Yude5719e2024-03-08 09:14:23 +0000745 set_mergestatus_cancel(&message);
Bo Lv72d0e902023-01-02 14:27:34 +0000746#endif
Zhigang Yude5719e2024-03-08 09:14:23 +0000747 char *slot;
Bo Lv72d0e902023-01-02 14:27:34 +0000748
Zhigang Yude5719e2024-03-08 09:14:23 +0000749 slot = env_get("slot-suffixes");
750 if (!slot) {
751 run_command("get_valid_slot", 0);
Bo Lv72d0e902023-01-02 14:27:34 +0000752 slot = env_get("slot-suffixes");
Bo Lv72d0e902023-01-02 14:27:34 +0000753 }
Zhigang Yude5719e2024-03-08 09:14:23 +0000754 if (strcmp(slot, "0") == 0) {
755 wrnP("back to slot b\n");
756 run_command("set_roll_flag 1", 0);
757 run_command("set_active_slot b", 0);
758 } else if (strcmp(slot, "1") == 0) {
759 wrnP("back to slot a\n");
760 run_command("set_roll_flag 1", 0);
761 run_command("set_active_slot a", 0);
762 }
763 env_set("expect_index", "1");
Bo Lv72d0e902023-01-02 14:27:34 +0000764 } else {
Zhigang Yude5719e2024-03-08 09:14:23 +0000765 write_bootloader_back(bootloaderindex, 0);
Bo Lv72d0e902023-01-02 14:27:34 +0000766#ifdef CONFIG_FASTBOOT
767 struct misc_virtual_ab_message message;
768 set_mergestatus_cancel(&message);
769#endif
770 if (strcmp(bootloaderindex, "1") == 0) {
771 wrnP("back to slot a\n");
772 run_command("set_roll_flag 1", 0);
773 run_command("set_active_slot a", 0);
774 } else if (strcmp(bootloaderindex, "2") == 0) {
775 wrnP("back to slot b\n");
776 run_command("set_roll_flag 1", 0);
777 run_command("set_active_slot b", 0);
778 }
Zhigang Yude5719e2024-03-08 09:14:23 +0000779 env_set("expect_index", "0");
Bo Lv72d0e902023-01-02 14:27:34 +0000780 }
Zhigang Yude5719e2024-03-08 09:14:23 +0000781
782 env_set("update_env", "1");
783 env_set("reboot_status", "reboot_next");
Bo Lv72d0e902023-01-02 14:27:34 +0000784 run_command("saveenv", 0);
Zhigang Yude5719e2024-03-08 09:14:23 +0000785 run_command("reset", 0);
Bo Lv72d0e902023-01-02 14:27:34 +0000786 return 0;
Zhigang Yude5719e2024-03-08 09:14:23 +0000787 }
Bo Lv72d0e902023-01-02 14:27:34 +0000788 }
789
790 return 0;
791}
792
Zhigang Yude5719e2024-03-08 09:14:23 +0000793static int do_secureboot_check(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
794{
795 char *rebootmode = NULL;
796 int gpt_flag = 0;
797 int ret = -1;
798
799 // set product first to set serial.
800 set_product();
801
802#ifdef CONFIG_MMC_MESON_GX
803 struct mmc *mmc = NULL;
804 //int capacity_boot = 0;
805
806 if (store_get_type() == BOOT_EMMC) {
807 mmc = find_mmc_device(1);
808 if (mmc)
809 ret = aml_gpt_valid(mmc);
810 }
811#endif
812
813 //check is gpt mode
814 if (ret == 0)
815 gpt_flag = 1;
816
817 //unsupport update dt in boothal, update dt in uboot
818 run_command("update_dt;", 0);
819
820 bootloader_wp();
821
822 //set default env before check
823 env_set("recovery_mode", "false");
824
825 //if recovery mode, need disable dv, if factoryreset, need default uboot env
826 aml_recovery();
827
828#if defined(CONFIG_EFUSE_OBJ_API) && defined(CONFIG_CMD_EFUSE)
829 run_command("efuse_obj get FEAT_DISABLE_EMMC_USER", 0);
830
831 if (*efuse_field.data == 1) {
832 wrnP("efuse_field.data == 1\n");
833 env_set("nocs_mode", "true");
834 gpt_flag = 1;
835 } else {
836 wrnP("efuse_field.data != 1\n");
837 env_set("nocs_mode", "false");
838 }
839#endif//#ifdef CONFIG_EFUSE_OBJ_API
840
841
842 run_command("get_rebootmode", 0);
843 rebootmode = env_get("reboot_mode");
844 if (!rebootmode) {
845 wrnP("can not get reboot mode, so skip secure check\n");
846 return -1;
847 }
848 printf("rebootmode is %s\n", rebootmode);
849
850 //get boot status
851 run_command("amlbootsta -p -s", 0);
852
853 if (IS_ENABLED(CONFIG_MMC_MESON_GX))
854 fastboot_step_check(rebootmode, gpt_flag);
855
856 if (has_boot_slot == 1)
857 ab_update_rollback(rebootmode, gpt_flag);
858 else
859 non_ab_update(rebootmode);
860
861 return 0;
862}
863
864
865static int do_update_uboot_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
866{
867 const int write_boot = env_get_ulong("write_boot", 10, 0);
868 const int update_dts_gpt = env_get_ulong("update_dts_gpt", 10, 0);
869
870 //skip update env if need update bootloader
871 if (write_boot || update_dts_gpt) {
872 run_command("echo write_boot ${write_boot}, update_dts_gpt ${update_dts_gpt}", 0);
873 return 0;
874 }
875
876 //default uboot env need before anyone use it
877 //after factory reset
878 if (env_get("default_env")) {
879 printf("factory reset, need default all uboot env.\n");
880 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
881 }
882
883 //after ab update
884 char *update_env = env_get("update_env");
885
886 if (update_env && (strcmp(update_env, "1") == 0)) {
887 printf("ab mode, default all uboot env\n");
888 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
889 }
890
891 //after recovery update
892 char *upgrade_step = env_get("upgrade_step");
893
894 if (upgrade_step && (strcmp(upgrade_step, "1") == 0)) {
895 printf("after recovery update, need update uboot env\n");
896 run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
897 }
898
899 return 0;
900}
Bo Lv72d0e902023-01-02 14:27:34 +0000901
902U_BOOT_CMD_COMPLETE(
903 amlbootsta, 3, 0, do_get_bootloader_status,
904 "get bootloader status in env",
905 "[-p] print bootloader status\n"
906 "[-s] saveenv after generate bootloader status\n",
907 var_complete
908);
909
910U_BOOT_CMD_COMPLETE(
911 amlsecurecheck, 1, 0, do_secureboot_check,
912 "try bootloader/dtb/recovery secure check",
913 ""
914 "",
915 var_complete
916);
917
Zhigang Yude5719e2024-03-08 09:14:23 +0000918U_BOOT_CMD(aml_update_env, 1, 0, do_update_uboot_env,
919 "aml_update_env",
920 "\nThis command will update uboot env\n"
921 "So you can execute command: aml_update_env"
922);
923
Bo Lv72d0e902023-01-02 14:27:34 +0000924