bootctrl_api.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein is
  5. * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
  6. * the prior written permission of MediaTek inc. and/or its licensors, any
  7. * reproduction, modification, use or disclosure of MediaTek Software, and
  8. * information contained herein, in whole or in part, shall be strictly
  9. * prohibited.
  10. *
  11. * MediaTek Inc. (C) 2016. All rights reserved.
  12. *
  13. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  14. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  15. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
  16. * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
  17. * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  19. * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
  20. * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
  21. * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
  22. * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
  23. * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
  24. * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
  25. * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
  26. * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  27. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
  28. * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
  29. * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
  30. * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
  31. * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  32. *
  33. * The following software/firmware and/or related documentation ("MediaTek
  34. * Software") have been modified by MediaTek Inc. All revisions are subject to
  35. * any receiver's applicable license agreements with MediaTek Inc.
  36. */
  37. #include "bootctrl.h"
  38. #include "platform.h"
  39. #include "avb_util.h"
  40. #include "storage_api.h"
  41. #include <partition_api.h>
  42. #include <partition_active.h>
  43. #include <pal_log.h>
  44. #define BOOTCTR_MISC_PARTITION "misc"
  45. #define BOOTCTR_PARA_PARTITION "para"
  46. #define MOD "bootctrl"
  47. /******************************************************************************
  48. * DEBUG
  49. ******************************************************************************/
  50. static const char* suffix[2] = {BOOTCTRL_SUFFIX_A, BOOTCTRL_SUFFIX_B};
  51. static AvbABData metadata_saved;
  52. static int metadata_read = 0;
  53. static boot_ctrl_t zero_metadata;
  54. int check_suffix_with_slot(const char *suffix)
  55. {
  56. int slot = -1;
  57. if(suffix == NULL) {
  58. pal_log_err("suffix NULL\n");
  59. return -1;
  60. }
  61. if(strcmp(suffix, BOOTCTRL_SUFFIX_A) == 0) {
  62. slot = 0;
  63. }
  64. else if(strcmp(suffix, BOOTCTRL_SUFFIX_B) == 0) {
  65. slot = 1;
  66. }
  67. return slot;
  68. }
  69. static int read_write_partition_info_backup_restore_bootctrlv1(boot_ctrl_t *bctrl ,int mode,int offset)
  70. {
  71. blkdev_t *bootdev = NULL;
  72. part_t *part = NULL;
  73. u64 src = 0;
  74. u32 part_id = 0;
  75. int ret = -1, storage_type = 0;
  76. storage_type = ab_get_storage_type();
  77. if(storage_type == -1) {
  78. pal_log_err("unknown device\n");
  79. return -1;
  80. }
  81. if (NULL == (bootdev = blkdev_get(CFG_BOOT_DEV))) {
  82. pal_log_err("[%s] can't find boot device(%d)\n", MOD, CFG_BOOT_DEV);
  83. return -1;
  84. }
  85. part = part_get(BOOTCTR_MISC_PARTITION);
  86. if(part == NULL)
  87. part = part_get(BOOTCTR_PARA_PARTITION);
  88. if(part == NULL) {
  89. #if (CFG_DRAM_CALIB_OPTIMIZATION || EARLY_PARTITION_ACCESS)
  90. pal_log_debug("[%s] Try to query by sram\n", MOD);
  91. /* The fail might caused by dram not init yet, using sram query then */
  92. src = get_part_addr(BOOTCTR_MISC_PARTITION);
  93. if (src == 0) {
  94. pal_log_err("[%s] get part misc fail try para\n", MOD);
  95. src = get_part_addr(BOOTCTR_PARA_PARTITION);
  96. if (src == 0)
  97. pal_log_err("[%s] get part para fail\n", MOD);
  98. }
  99. part_id = storage_get_part_id(STORAGE_PHYS_PART_USER);
  100. #else
  101. pal_log_err("[%s] part_get fail\n", MOD);
  102. #endif
  103. } else {
  104. src = (u64)part->start_sect * bootdev->blksz;
  105. part_id = part->part_id;
  106. }
  107. src += OFFSETOF_SLOT_SUFFIX + offset;
  108. if(bctrl == NULL) {
  109. pal_log_err("bctrl is NULL\n");
  110. return ret;
  111. }
  112. if(mode == READ_PARTITION) {
  113. if (-1 == blkdev_read(bootdev, src, (u32)sizeof(boot_ctrl_t), (char *)bctrl, part_id)) {
  114. pal_log_err("[%s] part_load fail\n", MOD);
  115. return ret;
  116. }
  117. }
  118. else if(mode == WRITE_PARTITION) {
  119. if (-1 == blkdev_write(bootdev, src, (u32)sizeof(boot_ctrl_t), (char *)bctrl, part_id)) {
  120. pal_log_err("[%s] part_load fail\n", MOD);
  121. return ret;
  122. }
  123. }
  124. else {
  125. pal_log_err("unknown mode\n");
  126. return ret;
  127. }
  128. ret = 0;
  129. return ret;
  130. }
  131. static int read_write_partition_info(AvbABData *bctrl ,int mode)
  132. {
  133. blkdev_t *bootdev = NULL;
  134. part_t *part = NULL;
  135. u64 src = 0;
  136. u32 part_id = 0;
  137. int ret = -1, storage_type = 0;
  138. storage_type = ab_get_storage_type();
  139. if(storage_type == -1) {
  140. pal_log_err("unknown device\n");
  141. return -1;
  142. }
  143. if (NULL == (bootdev = blkdev_get(CFG_BOOT_DEV))) {
  144. pal_log_err("[%s] can't find boot device(%d)\n", MOD, CFG_BOOT_DEV);
  145. return -1;
  146. }
  147. part = part_get(BOOTCTR_MISC_PARTITION);
  148. if(part == NULL)
  149. part = part_get(BOOTCTR_PARA_PARTITION);
  150. if(part == NULL) {
  151. #if (CFG_DRAM_CALIB_OPTIMIZATION || EARLY_PARTITION_ACCESS)
  152. pal_log_debug("[%s] Try to query by sram\n", MOD);
  153. /* The fail might caused by dram not init yet, using sram query then */
  154. src = get_part_addr(BOOTCTR_MISC_PARTITION);
  155. if (src == 0) {
  156. pal_log_err("[%s] get part misc fail try para\n", MOD);
  157. src = get_part_addr(BOOTCTR_PARA_PARTITION);
  158. if (src == 0)
  159. pal_log_err("[%s] get part para fail\n", MOD);
  160. }
  161. part_id = storage_get_part_id(STORAGE_PHYS_PART_USER);
  162. #else
  163. pal_log_err("[%s] part_get fail\n", MOD);
  164. #endif
  165. } else {
  166. src = (u64)part->start_sect * bootdev->blksz;
  167. part_id = part->part_id;
  168. }
  169. src += OFFSETOF_SLOT_SUFFIX;
  170. if(bctrl == NULL) {
  171. pal_log_err("bctrl is NULL\n");
  172. return ret;
  173. }
  174. if(mode == READ_PARTITION) {
  175. if ((metadata_read) && (!memcmp(metadata_saved.magic ,AVB_AB_MAGIC, AVB_AB_MAGIC_LEN))) {
  176. memcpy(bctrl, &metadata_saved, sizeof(AvbABData));
  177. }
  178. else {
  179. if (-1 == blkdev_read(bootdev, src, (u32)sizeof(AvbABData), (char *)bctrl, part_id)) {
  180. pal_log_err("[%s] part_load fail\n", MOD);
  181. return ret;
  182. }
  183. else {
  184. memcpy(&metadata_saved, bctrl, sizeof(AvbABData));
  185. metadata_read = 1;
  186. }
  187. }
  188. }
  189. else if(mode == WRITE_PARTITION) {
  190. bctrl->crc32 = avb_htobe32(
  191. avb_crc32((const uint8_t*)bctrl, sizeof(AvbABData) - sizeof(uint32_t)));
  192. if (-1 == blkdev_write(bootdev, src, (u32)sizeof(AvbABData), (char *)bctrl, part_id)) {
  193. pal_log_err("[%s] part_load fail\n", MOD);
  194. return ret;
  195. }
  196. else {
  197. metadata_read = 0; //force to read from partition after successful blkdev_write()
  198. }
  199. }
  200. else {
  201. pal_log_err("unknown mode\n");
  202. return ret;
  203. }
  204. ret = 0;
  205. return ret;
  206. }
  207. static int ab_metadata_init(const char *suffix) {
  208. int slot = 0 ,slot1 = 0;
  209. int ret = -1 ,storage_type = -1;
  210. AvbABSlotData *slotp;
  211. AvbABData metadata;
  212. slot = check_suffix_with_slot(suffix);
  213. storage_type = ab_get_storage_type();
  214. if(storage_type == -1) {
  215. pal_log_err("unknown device\n");
  216. return -1;
  217. }
  218. if(slot == -1) {
  219. pal_log_err("ab init fail, slot: 0x%x\n", slot);
  220. return -1;
  221. }
  222. if(suffix == NULL) {
  223. pal_log_err("suffix is NULL\n");
  224. return -1;
  225. }
  226. ret = read_write_partition_info(&metadata, READ_PARTITION);
  227. if(ret < 0) {
  228. pal_log_err("partition_read fail, ret: 0x%x\n", ret);
  229. return -1;
  230. }
  231. memcpy(metadata.magic ,AVB_AB_MAGIC, AVB_AB_MAGIC_LEN);
  232. /* Set highest priority and reset retry count */
  233. slotp = &metadata.slots[slot];
  234. slotp->successful_boot = 0;
  235. slotp->priority = AVB_AB_MAX_PRIORITY;
  236. slotp->tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  237. /* Re-set arg to another slot */
  238. slot1 = (slot == 0) ? 1 : 0;
  239. slotp = &metadata.slots[slot1];
  240. slotp->successful_boot = 0;
  241. slotp->priority = AVB_AB_MAX_PRIORITY - 1;
  242. slotp->tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  243. ret = read_write_partition_info(&metadata, WRITE_PARTITION);
  244. if (ret < 0) {
  245. pal_log_err("partition_write fail, ret: 0x%x\n", ret);
  246. return -1;
  247. }
  248. return 0;
  249. }
  250. const char *get_suffix(void)
  251. {
  252. int slot = 0, ret = -1;
  253. AvbABData metadata;
  254. boot_ctrl_t metadatabootctrlv1;
  255. boot_ctrl_t metadatabootctrlv2;
  256. boot_part_t bootpart =BOOT_PART_NONE;
  257. int slot_bootctrlv1 = 0;
  258. ret = read_write_partition_info(&metadata, READ_PARTITION);
  259. if (ret < 0) {
  260. pal_log_err("get_suffix fail, ret: 0x%x\n", ret);
  261. return NULL;
  262. }
  263. if(memcmp(metadata.magic , AVB_AB_MAGIC, AVB_AB_MAGIC_LEN) != 0) {
  264. pal_log_err("booctrl magic not match init default value\n");
  265. read_write_partition_info_backup_restore_bootctrlv1(&metadatabootctrlv1,READ_PARTITION,0);
  266. if(metadatabootctrlv1.magic == BOOTCTRL_MAGIC){
  267. if(metadatabootctrlv1.slot_info[0].priority > metadatabootctrlv1.slot_info[1].priority){
  268. //bootctrlv1 in B part, so we need to backup bootctrv1
  269. read_write_partition_info_backup_restore_bootctrlv1(&metadatabootctrlv2,READ_PARTITION,32);
  270. //if not backup need backup (mark)
  271. if(metadatabootctrlv2.magic != BOOTCTRL_MAGIC)
  272. read_write_partition_info_backup_restore_bootctrlv1(&metadatabootctrlv1,WRITE_PARTITION,32);
  273. slot = 0;
  274. pal_log_err("reinit to BOOTCTRL_SUFFIX_A \n");
  275. ab_metadata_init(BOOTCTRL_SUFFIX_A);
  276. }else{
  277. //bootctrv1 in A part,no need deal, if hasbackup,need wipe
  278. read_write_partition_info_backup_restore_bootctrlv1(&metadatabootctrlv2,READ_PARTITION,32);
  279. if(metadatabootctrlv2.magic == BOOTCTRL_MAGIC){
  280. //wipe out
  281. memcpy(&metadatabootctrlv2,&zero_metadata,sizeof(boot_ctrl_t));
  282. read_write_partition_info_backup_restore_bootctrlv1(&metadatabootctrlv2,WRITE_PARTITION,32);
  283. }
  284. slot = 1;
  285. pal_log_err("reinit to BOOTCTRL_SUFFIX_B \n");
  286. ab_metadata_init(BOOTCTRL_SUFFIX_B);
  287. }
  288. }else{
  289. slot = 0;
  290. pal_log_err("reinit to BOOTCTRL_SUFFIX_A \n");
  291. ab_metadata_init(BOOTCTRL_SUFFIX_A);
  292. }
  293. }
  294. else {
  295. if(metadata.slots[0].priority >= metadata.slots[1].priority)
  296. slot = 0;
  297. else if (metadata.slots[0].priority < metadata.slots[1].priority)
  298. slot = 1;
  299. }
  300. return suffix[slot];
  301. }
  302. int rollback_slot(const char *suffix) {
  303. int slot = 0 ,slot1 = 0;
  304. int ret = -1;
  305. AvbABSlotData *slotp;
  306. AvbABData metadata;
  307. slot = check_suffix_with_slot(suffix);
  308. if(slot == -1) {
  309. pal_log_err("rollback_slot fail, slot: 0x%x\n", slot);
  310. return -1;
  311. }
  312. if(suffix == NULL) {
  313. pal_log_err("suffix NULL\n");
  314. return -1;
  315. }
  316. ret = read_write_partition_info(&metadata, READ_PARTITION);
  317. if(ret < 0) {
  318. pal_log_err("rollback_slot fail, ret: 0x%x\n", ret);
  319. return -1;
  320. }
  321. memcpy(metadata.magic ,AVB_AB_MAGIC, AVB_AB_MAGIC_LEN);
  322. /* Set highest priority and reset retry count */
  323. slotp = &metadata.slots[slot];
  324. slotp->priority = AVB_AB_MAX_PRIORITY;
  325. /* Ensure other slot doesn't have as high a priority. */
  326. slot1 = (slot == 0) ? 1 : 0;
  327. slotp = &metadata.slots[slot1];
  328. if(slotp->priority == AVB_AB_MAX_PRIORITY)
  329. slotp->priority = AVB_AB_MAX_PRIORITY - 1;
  330. ret = read_write_partition_info(&metadata, WRITE_PARTITION);
  331. if (ret < 0) {
  332. pal_log_err("partition_write fail, ret: 0x%x\n", ret);
  333. return -1;
  334. }
  335. return 0;
  336. }
  337. uint8_t get_retry_count(const char *suffix)
  338. {
  339. int slot = 0;
  340. int ret = -1;
  341. AvbABSlotData *slotp;
  342. AvbABData metadata;
  343. slot = check_suffix_with_slot(suffix);
  344. if(slot == -1) {
  345. pal_log_err("check fail, slot: 0x%x\n", slot);
  346. return -1;
  347. }
  348. ret = read_write_partition_info(&metadata, READ_PARTITION);
  349. if (ret < 0) {
  350. pal_log_err("partition_read fail, ret: 0x%x\n", ret);
  351. return -1;
  352. }
  353. slotp = &metadata.slots[slot];
  354. return slotp->tries_remaining;
  355. }
  356. int reduce_retry_count(const char *suffix)
  357. {
  358. int slot = 0, ret = -1;
  359. AvbABSlotData *slotp;
  360. AvbABData metadata;
  361. slot = check_suffix_with_slot(suffix);
  362. if(slot == -1) {
  363. pal_log_err("check fail, slot: 0x%x\n", slot);
  364. return -1;
  365. }
  366. ret = read_write_partition_info(&metadata, READ_PARTITION);
  367. if(ret < 0) {
  368. pal_log_err("partition_read fail, ret: 0x%x\n", ret);
  369. return -1;
  370. }
  371. slotp = &metadata.slots[slot];
  372. if(slotp->tries_remaining > 0)
  373. slotp->tries_remaining--;
  374. ret = read_write_partition_info(&metadata, WRITE_PARTITION);
  375. if(ret < 0) {
  376. pal_log_err("partition_write fail, ret: 0x%x\n", ret);
  377. return -1;
  378. }
  379. return 0;
  380. }
  381. int check_valid_slot(void)
  382. {
  383. int slot = 0, ret = -1;
  384. AvbABData metadata;
  385. ret = read_write_partition_info(&metadata, READ_PARTITION);
  386. if (ret < 0) {
  387. pal_log_err("write partition fail, ret: 0x%x\n", ret);
  388. return -1;
  389. }
  390. if(metadata.slots[0].priority > 0)
  391. return 0;
  392. else if (metadata.slots[1].priority > 0)
  393. return 0;
  394. return -1;
  395. }
  396. int mark_slot_invalid(const char *suffix)
  397. {
  398. int slot = 0, slot2 = 0, ret = -1;
  399. AvbABSlotData *slotp;
  400. AvbABData metadata;
  401. slot = check_suffix_with_slot(suffix);
  402. if(slot == -1) {
  403. pal_log_err("invliad slot , slot: 0x%x\n", slot);
  404. return -1;
  405. }
  406. ret = read_write_partition_info(&metadata, READ_PARTITION);
  407. if(ret < 0) {
  408. pal_log_err("part read fail, ret: 0x%x\n", ret);
  409. return -1;
  410. }
  411. slotp = &metadata.slots[slot];
  412. slotp->successful_boot = 0;
  413. slotp->priority = 0;
  414. ret = read_write_partition_info(&metadata, WRITE_PARTITION);
  415. if(ret < 0) {
  416. pal_log_err("part write fail, ret: 0x%x\n", ret);
  417. return -1;
  418. }
  419. return 0;
  420. }
  421. int get_bootup_status(const char *suffix)
  422. {
  423. int slot = 0, ret = -1;
  424. AvbABSlotData *slotp;
  425. AvbABData metadata;
  426. slot = check_suffix_with_slot(suffix);
  427. if(slot == -1) {
  428. pal_log_err("invliad slot, slot: 0x%x\n", slot);
  429. return -1;
  430. }
  431. ret = read_write_partition_info(&metadata, READ_PARTITION);
  432. if(ret < 0) {
  433. pal_log_err("part read fail, ret: 0x%x\n", ret);
  434. return -1;
  435. }
  436. slotp = &metadata.slots[slot];
  437. return slotp->successful_boot;
  438. return 0;
  439. }
  440. int ab_get_storage_type(void)
  441. {
  442. blkdev_t *bootdev = NULL;
  443. bootdev = blkdev_get(CFG_BOOT_DEV);
  444. if (bootdev == NULL) {
  445. pal_log_debug("%s can't find boot device(%d)\n", MOD, CFG_BOOT_DEV);
  446. return -1;
  447. }
  448. if (bootdev->type == BOOTDEV_SDMMC) {
  449. pal_log_debug("device is EMMC\n");
  450. return BOOTDEV_SDMMC;
  451. } else if (bootdev->type == BOOTDEV_UFS) {
  452. pal_log_debug("device is UFS\n");
  453. return BOOTDEV_UFS;
  454. }
  455. pal_log_debug("unknown device\n");
  456. return -1;
  457. }
  458. int ab_get_boot_part(u32 *bootpart)
  459. {
  460. int ret = 0, storage_type = 0;
  461. u32 boot_part = 0;
  462. storage_type = ab_get_storage_type();
  463. if(storage_type == -1) {
  464. pal_log_debug("unknown device\n");
  465. return -1;
  466. }
  467. if (storage_type == BOOTDEV_SDMMC) {
  468. ret = mmc_get_boot_part(&boot_part);
  469. if(boot_part == EMMC_PART_BOOT1)
  470. *bootpart = BOOT_PART_A;
  471. else if(boot_part == EMMC_PART_BOOT2)
  472. *bootpart = BOOT_PART_B;
  473. } else if (storage_type == BOOTDEV_UFS) {
  474. ret = ufs_get_boot_part(&boot_part);
  475. if(boot_part == STORAGE_PHYS_PART_BOOT1)
  476. *bootpart = BOOT_PART_A;
  477. else if(boot_part == STORAGE_PHYS_PART_BOOT2)
  478. *bootpart = BOOT_PART_B;
  479. }
  480. return ret;
  481. }
  482. int ab_set_boot_part(u32 bootpart)
  483. {
  484. int storage_type = 0;
  485. int slot = 0;
  486. boot_ctrl_t metadatabootctrlv1;
  487. if (bootpart ==BOOT_PART_B)
  488. restore_bootctrv1_slotB();
  489. storage_type = ab_get_storage_type();
  490. if(storage_type == -1) {
  491. pal_log_debug("unknown device\n");
  492. return -1;
  493. }
  494. if (storage_type == BOOTDEV_SDMMC) {
  495. return mmc_set_boot_part(bootpart);
  496. } else if (storage_type == BOOTDEV_UFS) {
  497. if (bootpart == BOOT_PART_A)
  498. bootpart = STORAGE_PHYS_PART_BOOT1;
  499. else if (bootpart == BOOT_PART_B)
  500. bootpart = STORAGE_PHYS_PART_BOOT2;
  501. return ufs_set_boot_part(bootpart);
  502. }
  503. }
  504. int restore_bootctrv1_slotB()
  505. {
  506. boot_ctrl_t metadatabootctrlv1;
  507. read_write_partition_info_backup_restore_bootctrlv1(&metadatabootctrlv1,READ_PARTITION,32);
  508. if(metadatabootctrlv1.magic == BOOTCTRL_MAGIC){
  509. set_active_slot(BOOTCTRL_SUFFIX_B);
  510. }
  511. return 0;
  512. }
  513. int set_active_slot(const char *suffix) {
  514. int slot = 0 ,slot1 = 0;
  515. int ret = -1;
  516. slot_metadata_t *slotp;
  517. boot_ctrl_t metadata;
  518. slot = check_suffix_with_slot(suffix);
  519. if(slot == -1) {
  520. pal_log_err("set_active_slot failed, slot: 0x%x\n", slot);
  521. return -1;
  522. }
  523. if(suffix == NULL) {
  524. pal_log_err("input suffix is NULL\n");
  525. return -1;
  526. }
  527. ret = read_write_partition_info_backup_restore_bootctrlv1(&metadata,READ_PARTITION,0);
  528. if(ret < 0) {
  529. pal_log_err("partition_read failed, ret: 0x%x\n", ret);
  530. return -1;
  531. }
  532. metadata.magic = BOOTCTRL_MAGIC;
  533. /* Set highest priority and reset retry count */
  534. slotp = &metadata.slot_info[slot];
  535. slotp->successful_boot = 0;
  536. slotp->priority = 7;
  537. slotp->retry_count = 3;
  538. slotp->normal_boot = 1;
  539. /* Re-set arg to another slot */
  540. slot1 = (slot == 0) ? 1 : 0;
  541. slotp = &metadata.slot_info[slot1];
  542. slotp->successful_boot = 0;
  543. slotp->priority = 0;
  544. slotp->retry_count = 0;
  545. slotp->normal_boot = 0;
  546. ret = read_write_partition_info_backup_restore_bootctrlv1(&metadata,WRITE_PARTITION,0);
  547. if (ret < 0) {
  548. pal_log_err("partition_write failed, ret: 0x%x\n", ret);
  549. return -1;
  550. }
  551. return 0;
  552. }