bootctrl.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  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 <errno.h>
  38. #include <fcntl.h>
  39. #include <unistd.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <hardware/hardware.h>
  44. #include <hardware/boot_control.h>
  45. #include <android-base/logging.h>
  46. #include <cutils/properties.h>
  47. #define LOG_TAG "bootctrlHAL"
  48. #include <log/log.h>
  49. #include "bootctrl.h"
  50. #if !defined(ARCH_X86)
  51. #include <linux/scsi/ufs/ufs-mtk-ioctl.h>
  52. #include <linux/mmc/mmc-mtk-ioctl.h>
  53. #include <sys/ioctl.h>
  54. #endif
  55. #include <fstab.h>
  56. #include "avb/libavb/avb_util.h"
  57. #include <bootloader_message/bootloader_message.h>
  58. // Debug for update_engine_sideload
  59. //#define ALOGE printf
  60. //#define ALOGI printf
  61. using android::fs_mgr::Fstab;
  62. using android::fs_mgr::GetEntryForMountPoint;
  63. using android::fs_mgr::ReadDefaultFstab;
  64. static char *blk_dev_path = NULL;
  65. static int bootctrl_read_metadata(AvbABData *bctrl)
  66. {
  67. int fd, err;
  68. ssize_t sz, size;
  69. char *buf = (char *)bctrl;
  70. fd = open(blk_dev_path, O_RDONLY);
  71. if (fd < 0) {
  72. err = errno;
  73. ALOGE("%s Error opening metadata file: %s\n", __func__ ,strerror(errno));
  74. return -err;
  75. }
  76. if (lseek(fd, OFFSETOF_SLOT_SUFFIX, SEEK_SET) < 0) {
  77. err = errno;
  78. ALOGE("%s Error seeking to metadata offset: %s\n", __func__ ,strerror(errno));
  79. close(fd);
  80. return -err;
  81. }
  82. size = sizeof(AvbABData);
  83. do {
  84. sz = read(fd, buf, size);
  85. if (sz == 0) {
  86. break;
  87. } else if (sz < 0) {
  88. if (errno == EINTR) {
  89. continue;
  90. }
  91. err = -errno;
  92. ALOGE("%s Error reading metadata file\n", __func__);
  93. close(fd);
  94. return err;
  95. }
  96. size -= sz;
  97. buf += sz;
  98. } while(size > 0);
  99. close(fd);
  100. /* Check bootctrl magic number */
  101. if (memcmp(bctrl->magic , AVB_AB_MAGIC, AVB_AB_MAGIC_LEN) != 0) {
  102. ALOGE("metadata is not initialised or corrupted.\n");
  103. return -EIO;
  104. }
  105. return 0;
  106. }
  107. static int bootctrl_read_metadata_offset(boot_ctrl_t *bctrl,int offset)
  108. {
  109. int fd, err;
  110. ssize_t sz, size;
  111. char *buf = (char *)bctrl;
  112. fd = open(blk_dev_path, O_RDONLY);
  113. if (fd < 0) {
  114. err = errno;
  115. ALOGE("%s Error opening metadata file: %s\n", __func__ ,strerror(errno));
  116. return -err;
  117. }
  118. if (lseek(fd, OFFSETOF_SLOT_SUFFIX + offset, SEEK_SET) < 0) {
  119. err = errno;
  120. ALOGE("%s Error seeking to metadata offset: %s\n", __func__ ,strerror(errno));
  121. close(fd);
  122. return -err;
  123. }
  124. size = sizeof(boot_ctrl_t);
  125. do {
  126. sz = read(fd, buf, size);
  127. if (sz == 0) {
  128. break;
  129. } else if (sz < 0) {
  130. if (errno == EINTR) {
  131. continue;
  132. }
  133. err = -errno;
  134. ALOGE("%s Error reading metadata file\n", __func__);
  135. close(fd);
  136. return err;
  137. }
  138. size -= sz;
  139. buf += sz;
  140. } while(size > 0);
  141. close(fd);
  142. /* Check bootctrl magic number */
  143. if (bctrl->magic == BOOTCTRL_MAGIC) {
  144. ALOGE("backup exist, need restore.\n");
  145. return 1;
  146. }
  147. return 0;
  148. }
  149. static int bootctrl_write_metadata_bootctrv1(boot_ctrl_t *bctrl)
  150. {
  151. int fd, err;
  152. ssize_t sz, size;
  153. char *buf = (char *)bctrl;
  154. fd = open(blk_dev_path, O_RDWR);
  155. if (fd < 0) {
  156. err = errno;
  157. ALOGE("%s Error opening metadata file: %s\n", __func__,strerror(errno));
  158. return -err;
  159. }
  160. if (lseek(fd, OFFSETOF_SLOT_SUFFIX, SEEK_SET) < 0) {
  161. err = errno;
  162. ALOGE("%s Error seeking to metadata offset: %s\n", __func__ ,strerror(errno));
  163. close(fd);
  164. return -err;
  165. }
  166. size = sizeof(boot_ctrl_t);
  167. do {
  168. sz = write(fd, buf, size);
  169. if (sz == 0) {
  170. break;
  171. } else if (sz < 0) {
  172. if (errno == EINTR) {
  173. continue;
  174. }
  175. err = -errno;
  176. ALOGE("%s Error Writing metadata file\n",__func__);
  177. close(fd);
  178. return err;
  179. }
  180. size -= sz;
  181. buf += sz;
  182. } while(size > 0);
  183. close(fd);
  184. return 0;
  185. }
  186. static int bootctrl_write_metadata(AvbABData *bctrl)
  187. {
  188. int fd, err;
  189. ssize_t sz, size;
  190. char *buf = (char *)bctrl;
  191. fd = open(blk_dev_path, O_RDWR);
  192. if (fd < 0) {
  193. err = errno;
  194. ALOGE("%s Error opening metadata file: %s\n", __func__,strerror(errno));
  195. return -err;
  196. }
  197. if (lseek(fd, OFFSETOF_SLOT_SUFFIX, SEEK_SET) < 0) {
  198. err = errno;
  199. ALOGE("%s Error seeking to metadata offset: %s\n", __func__ ,strerror(errno));
  200. close(fd);
  201. return -err;
  202. }
  203. size = sizeof(AvbABData);
  204. bctrl->crc32 = avb_htobe32(
  205. avb_crc32((const uint8_t*)bctrl, sizeof(AvbABData) - sizeof(uint32_t)));
  206. do {
  207. sz = write(fd, buf, size);
  208. if (sz == 0) {
  209. break;
  210. } else if (sz < 0) {
  211. if (errno == EINTR) {
  212. continue;
  213. }
  214. err = -errno;
  215. ALOGE("%s Error Writing metadata file\n",__func__);
  216. close(fd);
  217. return err;
  218. }
  219. size -= sz;
  220. buf += sz;
  221. } while(size > 0);
  222. close(fd);
  223. return 0;
  224. }
  225. void bootctrl_init(boot_control_module_t *module __unused)
  226. {
  227. static Fstab fstab;
  228. ALOGI("boot control HAL init");
  229. if(blk_dev_path == NULL) {
  230. /* Initial read fstab */
  231. if(!ReadDefaultFstab(&fstab)) {
  232. ALOGE("bootctrl read fstab fail\n");
  233. return;
  234. }
  235. auto v = GetEntryForMountPoint(&fstab, "/misc");
  236. if (v == nullptr) {
  237. LOG(ERROR)<<"failed to get block device path by mount point";
  238. return;
  239. }
  240. blk_dev_path = strdup(v->blk_device.c_str());
  241. }
  242. ALOGI("%s misc blk device path = %s\n", __func__ ,blk_dev_path);
  243. }
  244. unsigned bootctrl_get_number_slots(boot_control_module_t *module __unused)
  245. {
  246. return 2;
  247. }
  248. int bootctrl_get_active_slot()
  249. {
  250. int fd, err, slot;
  251. ssize_t size = COMMAND_LINE_SIZE, sz;
  252. char *buf, *ptr;
  253. char *str;
  254. fd = open(COMMAND_LINE_PATH, O_RDONLY);
  255. if (fd < 0) {
  256. err = -errno;
  257. ALOGE("%s error reading commandline\n", __func__);
  258. return err;
  259. }
  260. ptr = buf = (char *)malloc(size);
  261. if (!buf) {
  262. err = -errno;
  263. ALOGE("%s Error allocating memory\n", __func__);
  264. close(fd);
  265. return err;
  266. }
  267. do {
  268. sz = read(fd, buf, size);
  269. if (sz == 0) {
  270. break;
  271. } else if (sz < 0) {
  272. if (errno == EINTR) {
  273. continue;
  274. }
  275. err = -errno;
  276. ALOGE("%s Error reading file\n",__func__);
  277. free(ptr);
  278. close(fd);
  279. return err;
  280. }
  281. size -= sz;
  282. buf += sz;
  283. } while(size > 0);
  284. str = strstr((char *)ptr, SLOT_SUFFIX_STR);
  285. if (!str) {
  286. err = -EIO;
  287. ALOGE("%s cannot find %s in kernel commandline.\n", __func__ , SLOT_SUFFIX_STR);
  288. free(ptr);
  289. close(fd);
  290. return err;
  291. }
  292. str += sizeof(SLOT_SUFFIX_STR);
  293. slot = (*str == 'a') ? 0 : 1;
  294. free(ptr);
  295. close(fd);
  296. return slot;
  297. }
  298. static int mmc_read_extcsd(int fd, __u8 *ext_csd)
  299. {
  300. int ret = 0;
  301. struct mmc_ioc_cmd mmc_ioctl_cmd;
  302. memset(ext_csd, 0, sizeof(__u8) * 512);
  303. memset(&mmc_ioctl_cmd, 0, sizeof(mmc_ioctl_cmd));
  304. mmc_ioctl_cmd.blocks = 1;
  305. mmc_ioctl_cmd.blksz = 512;
  306. mmc_ioctl_cmd.opcode = MMC_SEND_EXT_CSD;
  307. mmc_ioctl_cmd.flags = MMC_CMD_ADTC | MMC_RSP_R1;
  308. mmc_ioc_cmd_set_data(mmc_ioctl_cmd, ext_csd);
  309. ret = ioctl(fd, MMC_IOC_CMD, &mmc_ioctl_cmd);
  310. if (ret)
  311. ALOGE("ioctl error, mmc_read_extcsd fail, ret = %d\n", ret);
  312. return ret;
  313. }
  314. static int mmc_switch_bootpart(int fd, __u8 *ext_csd, __u8 bootpart)
  315. {
  316. int ret = 0;
  317. struct mmc_ioc_cmd mmc_ioctl_cmd;
  318. __u8 val;
  319. val = (ext_csd[EXT_CSD_PART_CONFIG] & ~(0x38)) | (bootpart << 3);
  320. memset(&mmc_ioctl_cmd, 0, sizeof(mmc_ioctl_cmd));
  321. mmc_ioctl_cmd.opcode = MMC_SWITCH;
  322. mmc_ioctl_cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24)
  323. | (EXT_CSD_PART_CONFIG << 16)
  324. | val << 8
  325. | EXT_CSD_CMD_SET_NORMAL;
  326. mmc_ioctl_cmd.flags = MMC_CMD_AC | MMC_RSP_R1B;
  327. mmc_ioc_cmd_set_data(mmc_ioctl_cmd, ext_csd);
  328. ret = ioctl(fd, MMC_IOC_CMD, &mmc_ioctl_cmd);
  329. if (ret)
  330. ALOGE("ioctl error, mmc_switch_bootpart fail ret = %d\n", ret);
  331. return ret;
  332. }
  333. static int emmc_set_active_boot_part(int bootpart)
  334. {
  335. __u8 ext_csd[512];
  336. __u8 cur_bootpart;
  337. int ret;
  338. int fd= open("/dev/block/mmcblk0", O_RDWR);
  339. if (fd >= 0) {
  340. ret = mmc_read_extcsd(fd, ext_csd);
  341. if (ret) {
  342. ALOGE("Could not read EXT_CSD, error=%d\n", ret);
  343. close(fd);
  344. return 1;
  345. }
  346. /* check current boot part */
  347. cur_bootpart = (ext_csd[EXT_CSD_PART_CONFIG] >> 3) & 0x7;
  348. if (cur_bootpart == bootpart)
  349. {
  350. ALOGI("Current boot part is boot%d, no neeed switch\n", cur_bootpart);
  351. printf("Current boot part is boot%d, no neeed switch\n", cur_bootpart);
  352. } else {
  353. ALOGI("Current boot part is boot%d, need switch to %d\n",cur_bootpart, bootpart);
  354. printf("Current boot part is boot%d, need switch to %d\n",cur_bootpart, bootpart);
  355. ret = mmc_switch_bootpart(fd, ext_csd, bootpart);
  356. if(ret) {
  357. ALOGE("Could not switch boot part, error=%d\n", ret);
  358. close(fd);
  359. return 1;
  360. }
  361. }
  362. close(fd);
  363. return 0;
  364. } else {
  365. ALOGE("open /dev/block/mmcblk0 fail\n");
  366. return 1;
  367. }
  368. }
  369. static int ufs_set_active_boot_part(int boot)
  370. {
  371. struct ufs_ioctl_query_data idata;
  372. unsigned char buf[1];
  373. int fd, ret = 0;
  374. fd = open("/dev/block/sdc", O_RDWR);
  375. if (fd < 0) {
  376. printf("%s: open device failed, err: %d\n", __func__, fd);
  377. ret = -1;
  378. goto out;
  379. }
  380. buf[0] = boot; /* 1: BootLU A, 2: BootLU B */
  381. idata.opcode = UPIU_QUERY_OPCODE_WRITE_ATTR;
  382. idata.idn = QUERY_ATTR_IDN_BOOT_LUN_EN;
  383. idata.idx = 0;
  384. idata.buf_ptr = &buf[0];
  385. idata.buf_byte = 1;
  386. ret = ioctl(fd, UFS_IOCTL_QUERY, &idata);
  387. if(ret < 0)
  388. printf("ufs_set boot_part fail: %s\n", strerror(errno));
  389. out:
  390. if(fd >= 0)
  391. close(fd);
  392. return ret;
  393. }
  394. static int get_boot_type(void) {
  395. int fd;
  396. size_t s;
  397. char boot_type[4] = {'0'};
  398. fd = open("/sys/class/BOOT/BOOT/boot/boot_type", O_RDONLY);
  399. if (fd < 0) {
  400. ALOGE("fail to open: %s\n", "/sys/class/BOOT/BOOT/boot/boot_type");
  401. return -1;
  402. }
  403. s = read(fd, boot_type, sizeof(boot_type) - 1);
  404. close(fd);
  405. if (s <= 0) {
  406. ALOGE("could not read boot type sys file\n");
  407. return -1;
  408. }
  409. boot_type[s] = '\0';
  410. return atoi(boot_type);
  411. }
  412. static int set_ota_result(int result, int offset) {
  413. if (blk_dev_path == NULL) {
  414. printf("Error: blk_dev_path is NULL\n");
  415. return -1;
  416. }
  417. int dev = -1;
  418. int count;
  419. dev = open(blk_dev_path, O_WRONLY | O_SYNC);
  420. if (dev < 0) {
  421. printf("Can't open %s\n(%s)\n", blk_dev_path, strerror(errno));
  422. return -1;
  423. }
  424. if (lseek(dev, offset, SEEK_SET) == -1) {
  425. printf("Failed seeking %s\n(%s)\n", blk_dev_path, strerror(errno));
  426. close(dev);
  427. return -1;
  428. }
  429. count = write(dev, &result, sizeof(result));
  430. if (count != sizeof(result)) {
  431. printf("Failed writing %s\n(%s)\n", blk_dev_path, strerror(errno));
  432. close(dev);
  433. return -1;
  434. }
  435. if (close(dev) != 0) {
  436. printf("Failed closing %s\n(%s)\n", blk_dev_path, strerror(errno));
  437. return -1;
  438. }
  439. sync();
  440. return 1;
  441. }
  442. static int SetOTAResultForDMVerity(void) {
  443. int ota_result_offset, ret = -1;
  444. ota_result_offset = sizeof(bootloader_message_ab);
  445. ret = set_ota_result(1, ota_result_offset);
  446. return ret;
  447. }
  448. int switch_pl_boot_part(unsigned slot)
  449. {
  450. int ret = 0;
  451. int boot_part = 0;
  452. boot_ctrl_t metadata;
  453. slot_metadata_t *slotp;
  454. /* slot 0 is A , slot 1 is B */
  455. if (slot >= 2) {
  456. ALOGE("%s Wrong Slot value %u\n", __func__ , slot);
  457. return -1;
  458. }
  459. if(slot)
  460. boot_part = 2;
  461. else
  462. boot_part = 1;
  463. int mt_boot_type = get_boot_type();
  464. if(mt_boot_type == -1) {
  465. ALOGI("Get boot type failed then use default device type\n");
  466. mt_boot_type = FS_TYPE_EMMC;
  467. }
  468. if(slot ==1)
  469. {
  470. //restore backup bootctrv1
  471. if(bootctrl_read_metadata_offset(&metadata,32))
  472. {
  473. slotp = &metadata.slot_info[1];
  474. slotp->successful_boot = 0;
  475. slotp->priority = 7;
  476. slotp->retry_count = 3;
  477. slotp->normal_boot = 1;
  478. slotp = &metadata.slot_info[0];
  479. slotp->successful_boot = 0;
  480. slotp->priority = 0;
  481. slotp->retry_count = 0;
  482. slotp->normal_boot = 0;
  483. bootctrl_write_metadata_bootctrv1(&metadata);
  484. }
  485. }
  486. /* EMMC */
  487. if(mt_boot_type == FS_TYPE_EMMC) {
  488. ALOGI("emmc_set_active_boot_part\n");
  489. ret = emmc_set_active_boot_part(boot_part);
  490. if(ret) {
  491. ALOGE("emmc set boot_part fail\n");
  492. return -1;
  493. }
  494. return 1;
  495. }
  496. /* UFS */
  497. if(mt_boot_type == FS_TYPE_UFS) {
  498. ALOGI ("boot_type is UFS\n");
  499. ret = ufs_set_active_boot_part(boot_part);
  500. if(ret) {
  501. ALOGE("ufs set boot_part fail\n");
  502. return -1;
  503. }
  504. return 1;
  505. }
  506. ALOGE("Un support phone type\n");
  507. return -1;
  508. }
  509. uint32_t bootctrl_get_current_slot(boot_control_module_t *module __unused)
  510. {
  511. ALOGI("boot control bootctrl_get_current_slot\n");
  512. uint32_t slot = 0;
  513. slot = bootctrl_get_active_slot();
  514. ALOGI("bootctrl_get_current_slot %d\n", slot);
  515. return slot;
  516. }
  517. int bootctrl_mark_boot_successful(boot_control_module_t *module __unused)
  518. {
  519. ALOGI("boot control bootctrl_mark_boot_successful\n");
  520. int ret;
  521. uint32_t slot = 0;
  522. AvbABData metadata;
  523. AvbABSlotData *slotp;
  524. ret = bootctrl_read_metadata(&metadata);
  525. if (ret < 0) {
  526. return ret;
  527. }
  528. slot = bootctrl_get_active_slot();
  529. if (slot < 0) {
  530. ALOGE("bootctrl_mark_boot_successful fail , slot = \n");
  531. return slot;
  532. }
  533. slotp = &metadata.slots[slot];
  534. slotp->successful_boot = 1;
  535. slotp->tries_remaining = 0;
  536. return bootctrl_write_metadata(&metadata);
  537. }
  538. int bootctrl_set_active_boot_slot(boot_control_module_t *module __unused,
  539. unsigned slot)
  540. {
  541. ALOGI("boot control bootctrl_set_active_boot_slot , slot is %d\n", slot);
  542. int ret, slot2;
  543. AvbABData metadata;
  544. AvbABSlotData *slotp;
  545. if (slot >= 2) {
  546. ALOGE("%s Wrong Slot value %u\n", __func__ , slot);
  547. return -EINVAL;
  548. }
  549. ret = bootctrl_read_metadata(&metadata);
  550. if (ret < 0) {
  551. return ret;
  552. }
  553. /* Set highest priority and reset retry count */
  554. slotp = &metadata.slots[slot];
  555. slotp->successful_boot = 0;
  556. slotp->priority = AVB_AB_MAX_PRIORITY;
  557. slotp->tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  558. /* Ensure other slot doesn't have as high a priority. */
  559. slot2 = (slot == 0) ? 1 : 0;
  560. slotp = &metadata.slots[slot2];
  561. if(slotp->priority == AVB_AB_MAX_PRIORITY)
  562. slotp->priority = AVB_AB_MAX_PRIORITY - 1;
  563. ret = bootctrl_write_metadata(&metadata);
  564. if (ret < 0) {
  565. return ret;
  566. }
  567. ret = switch_pl_boot_part(slot);
  568. if (ret < 0) {
  569. ALOGE("bootctrl_set_active_boot_slot switch boot part fail\n");
  570. return ret;
  571. }
  572. ret = SetOTAResultForDMVerity();
  573. if (ret < 0) {
  574. ALOGE("bootctrl_set_active_boot_slot SetOTAResultForDMVerity fail\n");
  575. return ret;
  576. }
  577. return 0;
  578. }
  579. int bootctrl_set_slot_as_unbootable(boot_control_module_t *module __unused,
  580. unsigned slot)
  581. {
  582. ALOGI("boot control bootctrl_set_slot_as_unbootable\n");
  583. int ret;
  584. AvbABData metadata;
  585. AvbABSlotData *slotp;
  586. if (slot >= 2) {
  587. ALOGE("%s Wrong Slot value %u\n", __func__ , slot);
  588. return -EINVAL;
  589. }
  590. ret = bootctrl_read_metadata(&metadata);
  591. if (ret < 0) {
  592. return ret;
  593. }
  594. /* Set zero to priority ,successful_boot and tries_remaining */
  595. slotp = &metadata.slots[slot];
  596. slotp->successful_boot = 0;
  597. slotp->priority = 0;
  598. slotp->tries_remaining = 0;
  599. ret = bootctrl_write_metadata(&metadata);
  600. if (ret < 0) {
  601. return ret;
  602. }
  603. return 0;
  604. }
  605. int bootctrl_is_slot_bootable(boot_control_module_t *module __unused,
  606. unsigned slot)
  607. {
  608. ALOGI("boot control bootctrl_is_slot_bootable\n");
  609. int ret;
  610. AvbABData metadata;
  611. /* slot 0 is A , slot 1 is B */
  612. if (slot >= 2) {
  613. ALOGE("%s Wrong slot value %u\n", __func__,slot);
  614. return -EINVAL;
  615. }
  616. ret = bootctrl_read_metadata(&metadata);
  617. if (ret < 0) {
  618. return ret;
  619. }
  620. return (metadata.slots[slot].priority != 0);
  621. }
  622. int bootctrl_get_bootup_status(boot_control_module_t *module __unused,
  623. unsigned slot)
  624. {
  625. ALOGI("bootctrl bootctrl_get_bootup_status\n");
  626. int ret = -1;
  627. AvbABSlotData *slotp;
  628. AvbABData metadata;
  629. if(slot >= 2) {
  630. ALOGE("%s Wrong slot value %u\n", __func__,slot);
  631. return -1;
  632. }
  633. ret = bootctrl_read_metadata(&metadata);
  634. if (ret < 0) {
  635. return ret;
  636. }
  637. slotp = &metadata.slots[slot];
  638. ALOGI("bootctrl bootctrl_get_bootup_status = %d\n", slotp->successful_boot);
  639. return slotp->successful_boot;
  640. }
  641. const char *bootctrl_get_suffix(boot_control_module_t *module __unused,
  642. unsigned slot)
  643. {
  644. ALOGI("boot control bootctrl_get_suffix\n");
  645. static const char* suffix[2] = {BOOTCTRL_SUFFIX_A, BOOTCTRL_SUFFIX_B};
  646. if (slot >= 2)
  647. return NULL;
  648. return suffix[slot];
  649. }
  650. static struct hw_module_methods_t bootctrl_methods = {
  651. .open = NULL,
  652. };
  653. /* Boot Control Module implementation */
  654. boot_control_module_t HAL_MODULE_INFO_SYM = {
  655. .common = {
  656. .tag = HARDWARE_MODULE_TAG,
  657. .module_api_version = BOOT_CONTROL_MODULE_API_VERSION_0_1,
  658. .hal_api_version = HARDWARE_HAL_API_VERSION,
  659. .id = BOOT_CONTROL_HARDWARE_MODULE_ID,
  660. .name = "boot_control HAL",
  661. .author = "Mediatek Corporation",
  662. .methods = &bootctrl_methods,
  663. },
  664. .init = bootctrl_init,
  665. .getNumberSlots = bootctrl_get_number_slots,
  666. .getCurrentSlot = bootctrl_get_current_slot,
  667. .markBootSuccessful = bootctrl_mark_boot_successful,
  668. .setActiveBootSlot = bootctrl_set_active_boot_slot,
  669. .setSlotAsUnbootable = bootctrl_set_slot_as_unbootable,
  670. .isSlotBootable = bootctrl_is_slot_bootable,
  671. .isSlotMarkedSuccessful = bootctrl_get_bootup_status,
  672. .getSuffix = bootctrl_get_suffix,
  673. };