bootctrl_api.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  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 <stdint.h>
  38. #include <pal_typedefs.h>
  39. #include <pal_log.h>
  40. #include <libavb/libavb.h>
  41. #include <part_interface.h>
  42. #include <string.h>
  43. #include <platform/mt_typedefs.h>
  44. #include <block_generic_interface.h>
  45. #include "part_dev.h"
  46. #include "bootctrl.h"
  47. #include "debug.h"
  48. #include "mmc_core.h"
  49. #include "mmc_common_inter.h"
  50. #include "ufs_aio_hcd.h"
  51. #define BOOTCTR_PARTITION "misc"
  52. static const char *suffix[2] = {BOOTCTRL_SUFFIX_A, BOOTCTRL_SUFFIX_B};
  53. static AvbABData metadata_saved;
  54. static int metadata_read = 0;
  55. int check_suffix_with_slot(const char *suffix)
  56. {
  57. int slot = -1;
  58. if (suffix == NULL) {
  59. pal_log_err("[LK] input suffix is NULL\n");
  60. return -1;
  61. }
  62. if (!strcmp(suffix, BOOTCTRL_SUFFIX_A))
  63. slot = 0;
  64. else if (!strcmp(suffix, BOOTCTRL_SUFFIX_B))
  65. slot = 1;
  66. else
  67. pal_log_err("[LK] unknow slot suffix\n");
  68. return slot;
  69. }
  70. static int read_write_partition_info_backup_restore_bootctrlv1(boot_ctrl_t *bctrl ,int mode,int offset)
  71. {
  72. ssize_t boot_ctrl_size;
  73. int ret = -1;
  74. boot_ctrl_size = sizeof(boot_ctrl_t);
  75. if (bctrl == NULL) {
  76. pal_log_err("[LK] read_write_partition_info failed, bctrl is NULL\n");
  77. return ret;
  78. }
  79. if (mode == READ_PARTITION) {
  80. ret = partition_read(BOOTCTR_PARTITION, (off_t)OFFSETOF_SLOT_SUFFIX + offset,
  81. (u8 *)bctrl, (size_t)boot_ctrl_size);
  82. if (ret < 0) {
  83. pal_log_err("[LK] partition_read failed, ret: 0x%x\n", ret);
  84. return ret;
  85. }
  86. } else if (mode == WRITE_PARTITION) {
  87. ret = partition_write(BOOTCTR_PARTITION, (off_t)OFFSETOF_SLOT_SUFFIX + offset,
  88. (u8 *)bctrl, (size_t)boot_ctrl_size);
  89. if (ret < 0) {
  90. pal_log_err("[LK] read_write_partition_info partition_write failed, unknown mode\n");
  91. return ret;
  92. }
  93. } else {
  94. pal_log_err("[LK] unknown mode, ret: 0x%x\n", ret);
  95. return ret;
  96. }
  97. return 0;
  98. }
  99. static int read_write_partition_info(AvbABData *bctrl, int mode)
  100. {
  101. ssize_t boot_ctrl_size;
  102. int ret = -1;
  103. boot_ctrl_t metadatabootctrlv1;
  104. slot_metadata_t *slotp;
  105. boot_ctrl_size = sizeof(AvbABData);
  106. if (bctrl == NULL) {
  107. pal_log_err("[LK] read_write_partition_info failed, bctrl is NULL\n");
  108. return ret;
  109. }
  110. if (mode == READ_PARTITION) {
  111. if ((metadata_read) &&
  112. (!memcmp(metadata_saved.magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN)))
  113. memcpy(bctrl, &metadata_saved, sizeof(AvbABData));
  114. else {
  115. ret = partition_read(BOOTCTR_PARTITION, (off_t)OFFSETOF_SLOT_SUFFIX,
  116. (u8 *)bctrl, (size_t)boot_ctrl_size);
  117. if (ret < 0) {
  118. pal_log_err("[LK] partition_read failed, ret: 0x%x\n", ret);
  119. return ret;
  120. } else {
  121. memcpy(&metadata_saved, bctrl, sizeof(AvbABData));
  122. metadata_read = 1;
  123. }
  124. }
  125. } else if (mode == WRITE_PARTITION) {
  126. #ifdef MTK_AVB20_SUPPORT
  127. bctrl->crc32 = avb_htobe32(
  128. avb_crc32((const uint8_t *)bctrl, sizeof(AvbABData) - sizeof(uint32_t)));
  129. #endif
  130. ret = partition_write(BOOTCTR_PARTITION, (off_t)OFFSETOF_SLOT_SUFFIX,
  131. (u8 *)bctrl, (size_t)boot_ctrl_size);
  132. if (ret < 0) {
  133. pal_log_err("[LK] read_write_partition_info partition_write failed, unknown mode\n");
  134. return ret;
  135. } else {
  136. metadata_read =
  137. 0; //force to read from partition after successful partition_write()
  138. }
  139. } else {
  140. pal_log_err("[LK] unknown mode, ret: 0x%x\n", ret);
  141. return ret;
  142. }
  143. return 0;
  144. }
  145. const char *get_suffix(void)
  146. {
  147. int slot = 0, ret = -1;
  148. AvbABData metadata;
  149. ret = read_write_partition_info(&metadata, READ_PARTITION);
  150. if (ret < 0) {
  151. pal_log_err("[LK] read_partition_info failed, ret: 0x%x\n", ret);
  152. return NULL;
  153. }
  154. if (memcmp(metadata.magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN) != 0) {
  155. pal_log_err("[LK] boot_ctrl magic number is not match %s , AVB_AB_MAGIC = %s\n",
  156. metadata.magic, AVB_AB_MAGIC);
  157. return NULL;
  158. } else {
  159. pal_log_err("[LK] boot_ctrl magic number is match, compare priority\n");
  160. if (metadata.slots[0].priority >= metadata.slots[1].priority)
  161. slot = 0;
  162. else if (metadata.slots[0].priority < metadata.slots[1].priority)
  163. slot = 1;
  164. }
  165. return suffix[slot];
  166. }
  167. static int set_boot_region(int slot)
  168. {
  169. int ret = -1;
  170. u32 boot_part = 0;
  171. boot_ctrl_t metadatabootctrlv1;
  172. slot_metadata_t *slotp;
  173. part_dev_t *dev;
  174. dev = mt_part_get_device();
  175. if(slot == 1)
  176. {
  177. // restore bootctrv1
  178. read_write_partition_info_backup_restore_bootctrlv1(&metadatabootctrlv1,READ_PARTITION,32);
  179. if(metadatabootctrlv1.magic == BOOTCTRL_MAGIC){
  180. slotp = &metadatabootctrlv1.slot_info[1];
  181. slotp->successful_boot = 0;
  182. slotp->priority = 7;
  183. slotp->retry_count = 3;
  184. slotp->normal_boot = 1;
  185. slotp = &metadatabootctrlv1.slot_info[0];
  186. slotp->successful_boot = 0;
  187. slotp->priority = 0;
  188. slotp->retry_count = 0;
  189. slotp->normal_boot = 0;
  190. read_write_partition_info_backup_restore_bootctrlv1(&metadatabootctrlv1,WRITE_PARTITION,0);
  191. }
  192. }
  193. if(slot == 0) {
  194. #if defined(MTK_EMMC_SUPPORT)
  195. if (dev->blkdev->type == BOOTDEV_SDMMC)
  196. boot_part = EMMC_PART_BOOT1;
  197. #endif
  198. #if defined(MTK_UFS_SUPPORT)
  199. if (dev->blkdev->type == BOOTDEV_UFS)
  200. boot_part = ATTR_B_BOOT_LUN_EN_BOOT_LU_A;
  201. #endif
  202. } else if(slot == 1) {
  203. #if defined(MTK_EMMC_SUPPORT)
  204. if (dev->blkdev->type == BOOTDEV_SDMMC)
  205. boot_part = EMMC_PART_BOOT2;
  206. #endif
  207. #if defined(MTK_UFS_SUPPORT)
  208. if (dev->blkdev->type == BOOTDEV_UFS)
  209. boot_part = ATTR_B_BOOT_LUN_EN_BOOT_LU_B;
  210. #endif
  211. }
  212. #if defined(MTK_EMMC_SUPPORT)
  213. if (dev->blkdev->type == BOOTDEV_SDMMC) {
  214. ret = mmc_set_boot_part(boot_part);
  215. return ret;
  216. }
  217. #endif
  218. #if defined(MTK_UFS_SUPPORT)
  219. extern struct ufs_hba g_ufs_hba;
  220. struct ufs_hba *hba = &g_ufs_hba;
  221. ret = ufs_aio_set_boot_lu(hba, boot_part);
  222. #endif
  223. return ret;
  224. }
  225. int set_active_slot(const char *suffix)
  226. {
  227. int slot = 0, slot1 = 0;
  228. int ret = -1;
  229. AvbABSlotData *slotp;
  230. AvbABData metadata;
  231. slot = check_suffix_with_slot(suffix);
  232. if (slot == -1) {
  233. pal_log_err("[LK] set_active_slot failed, slot: 0x%x\n", slot);
  234. return -1;
  235. }
  236. if (suffix == NULL) {
  237. pal_log_err("[LK] input suffix is NULL\n");
  238. return -1;
  239. }
  240. ret = read_write_partition_info(&metadata, READ_PARTITION);
  241. if (ret < 0) {
  242. pal_log_err("[LK] partition_read failed, ret: 0x%x\n", ret);
  243. return -1;
  244. }
  245. memcpy(metadata.magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN);
  246. /* Set highest priority and reset retry count */
  247. slotp = &metadata.slots[slot];
  248. slotp->successful_boot = 0;
  249. slotp->priority = AVB_AB_MAX_PRIORITY;
  250. slotp->tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  251. /* Ensure other slot doesn't have as high a priority. */
  252. slot1 = (slot == 0) ? 1 : 0;
  253. slotp = &metadata.slots[slot1];
  254. if (slotp->priority == AVB_AB_MAX_PRIORITY)
  255. slotp->priority = AVB_AB_MAX_PRIORITY - 1;
  256. /* Switch boot part in boot region */
  257. ret = set_boot_region(slot);
  258. if (ret < 0) {
  259. pal_log_err("[LK] set boot part to slot %d fail, ret: 0x%x\n", slot, ret);
  260. return -1;
  261. }
  262. ret = read_write_partition_info(&metadata, WRITE_PARTITION);
  263. if (ret < 0) {
  264. pal_log_err("[LK] partition_write failed, ret: 0x%x\n", ret);
  265. return -1;
  266. }
  267. return 0;
  268. }
  269. uint8_t get_retry_count(const char *suffix)
  270. {
  271. int slot = 0;
  272. int ret = -1;
  273. AvbABData metadata;
  274. slot = check_suffix_with_slot(suffix);
  275. if (slot == -1) {
  276. pal_log_err("[LK] get_retry_count failed, slot: 0x%x\n", slot);
  277. return 0;
  278. }
  279. ret = read_write_partition_info(&metadata, READ_PARTITION);
  280. if (ret < 0) {
  281. pal_log_err("[LK] partition_read failed, ret: 0x%x\n", ret);
  282. return 0;
  283. }
  284. return metadata.slots[slot].tries_remaining;
  285. }
  286. /* Return value:
  287. 0: phone does not boot to home screen yet
  288. 1: phone already boots to home screen
  289. -1: read misc partition error
  290. */
  291. int get_bootup_status(const char *suffix)
  292. {
  293. int slot = 0, ret = -1;
  294. AvbABData metadata;
  295. slot = check_suffix_with_slot(suffix);
  296. if (slot == -1) {
  297. pal_log_err("set_not_boot_mode failed, slot: 0x%x\n", slot);
  298. return -1;
  299. }
  300. ret = read_write_partition_info(&metadata, READ_PARTITION);
  301. if (ret < 0) {
  302. pal_log_err("partition_read failed, ret: 0x%x\n", ret);
  303. return -1;
  304. }
  305. return metadata.slots[slot].successful_boot;
  306. }
  307. /* Return value:
  308. 0: slot is unbootable , tries_remaining equal to 0
  309. 1: slot is bootable , tries_remaining larger than 0
  310. -1: read misc partition error
  311. */
  312. int get_bootable_status(const char *suffix)
  313. {
  314. int slot = 0, ret = -1;
  315. AvbABData metadata;
  316. slot = check_suffix_with_slot(suffix);
  317. if (slot == -1) {
  318. pal_log_err("get_bootable_status failed, slot: 0x%x\n", slot);
  319. return -1;
  320. }
  321. ret = read_write_partition_info(&metadata, READ_PARTITION);
  322. if (ret < 0) {
  323. pal_log_err("partition_read failed, ret: 0x%x\n", ret);
  324. return -1;
  325. }
  326. if (metadata.slots[slot].priority > 0)
  327. return 1;
  328. return 0;
  329. }
  330. int increase_tries_remaining(void)
  331. {
  332. int slot = 0, ret = -1;
  333. AvbABSlotData *slotp;
  334. AvbABData metadata;
  335. const char *suffix = NULL;
  336. suffix = get_suffix();
  337. slot = check_suffix_with_slot(suffix);
  338. if (slot == -1) {
  339. pal_log_err("[LK] check_suffix_with_slot failed, slot: 0x%x\n", slot);
  340. return -1;
  341. }
  342. ret = read_write_partition_info(&metadata, READ_PARTITION);
  343. if (ret < 0) {
  344. pal_log_err("[LK] partition_read failed, ret: 0x%x\n", ret);
  345. return -1;
  346. }
  347. slotp = &metadata.slots[slot];
  348. if (slotp->tries_remaining < AVB_AB_MAX_TRIES_REMAINING &&
  349. slotp->tries_remaining > 0 && !slotp->successful_boot)
  350. slotp->tries_remaining++;
  351. ret = read_write_partition_info(&metadata, WRITE_PARTITION);
  352. if (ret < 0) {
  353. pal_log_err("[LK] partition_write failed, ret: 0x%x\n", ret);
  354. return -1;
  355. }
  356. return 0;
  357. }