bootctrl_api.c 10 KB

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