part_common.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <platform/mt_typedefs.h>
  32. #ifdef MTK_GPT_SCHEME_SUPPORT
  33. #include <platform/partition.h>
  34. #else
  35. #include <mt_partition.h>
  36. #endif
  37. #include <platform/errno.h>
  38. #include <platform/mt_reg_base.h> // to get bootdevice base address
  39. #include <debug.h>
  40. #include <string.h>
  41. #include <stdlib.h>
  42. #include <part_interface.h>
  43. #include <part_status.h>
  44. #include <pal_log.h>
  45. #include <block_generic_interface.h>
  46. #ifdef MTK_AB_OTA_UPDATER
  47. #include <bootctrl.h>
  48. #endif
  49. #if defined(MTK_UFS_SUPPORT)
  50. #include "ufs_aio_core.h"
  51. #include "ufs_aio_platform.h"
  52. #endif
  53. #if defined(MTK_EMMC_SUPPORT)
  54. #include "mmc_core.h"
  55. #endif
  56. typedef struct {
  57. char official_name[12];
  58. char alt_name1[12];
  59. char alt_name2[12];
  60. char alt_name3[12];
  61. } PART_TRANS_TBL_ENTRY;
  62. const PART_TRANS_TBL_ENTRY g_part_name_trans_tbl[] = {
  63. {"misc", "para", "NULL", "NULL" },
  64. {"preloader", "PRELOADER", "NULL", "NULL" },
  65. {"seccfg", "SECCFG", "SECCNFG", "NULL" },
  66. {"uboot", "UBOOT", "lk", "LK" },
  67. {"boot", "BOOT", "bootimg", "BOOTIMG" },
  68. {"recovery", "RECOVERY", "NULL", "NULL" },
  69. {"secro", "SECRO", "sec_ro", "SEC_RO" },
  70. {"logo", "LOGO", "NULL", "NULL" },
  71. {"system", "SYSTEM", "android", "ANDROID" },
  72. {"userdata", "USERDATA", "usrdata", "USRDATA" },
  73. {"frp", "FRP", "NULL", "NULL" },
  74. {"scp1", "SCP1", "NULL", "NULL" },
  75. {"scp2", "SCP2", "NULL", "NULL" },
  76. {"odmdtbo", "ODMDTBO", "dtbo", "DTBO" },
  77. {"NULL", "NULL", "NULL", "NULL" },
  78. };
  79. #ifdef MTK_PARTITION_COMMON
  80. int real_partition_count = 0;
  81. part_t *g_partition_all, *partition;;
  82. extern struct part_name_map g_part_name_map[PART_MAX_COUNT];
  83. extern bool cmdline_append(const char *append_string);
  84. extern u64 get_entry_count();
  85. #if (defined(MTK_EMMC_SUPPORT) || defined(MTK_UFS_SUPPORT))
  86. extern int mmc_get_boot_part(u32 *bootpart);
  87. #ifdef MTK_UFS_SUPPORT
  88. extern int ufs_lk_get_active_boot_part(u32 *active_boot_part);
  89. #endif
  90. #endif
  91. int partition_get_index(const char * name)
  92. {
  93. int i;
  94. #ifdef MTK_AB_OTA_UPDATER
  95. char last_char[2];
  96. const char *part_suffix;
  97. char alt_name[PART_META_INFO_NAMELEN + BOOTCTRL_SUFFIX_MAXLEN];
  98. int check_alt_name = 0, len_ck;
  99. #endif
  100. if (name == NULL)
  101. return -1;
  102. #ifdef MTK_AB_OTA_UPDATER
  103. /* get_suffix will call partition_read to get para partition information, which will cause infinite function call */
  104. if (!strncmp(name, "para", PART_META_INFO_NAMELEN) || !strncmp(name, "misc", PART_META_INFO_NAMELEN))
  105. part_suffix = NULL;
  106. else
  107. part_suffix = get_suffix();
  108. if ((int)strlen(name) - 2 >= 0) {
  109. last_char[0] = name[strlen(name) - 2];
  110. last_char[1] = name[strlen(name) - 1];
  111. } else {
  112. memset(last_char, 0, sizeof(last_char));
  113. }
  114. if (part_suffix != NULL) {
  115. if (!(part_suffix[0] == last_char[0] && part_suffix[1] == last_char[1])) {
  116. len_ck = snprintf(alt_name, PART_META_INFO_NAMELEN + BOOTCTRL_SUFFIX_MAXLEN, "%s%s", name, part_suffix);
  117. if (len_ck < 0) {
  118. pal_log_err(PART_COMMON_TAG"%s snprintf string %d into %d\n",
  119. __func__, PART_META_INFO_NAMELEN + BOOTCTRL_SUFFIX_MAXLEN, len_ck);
  120. return -1;
  121. }
  122. check_alt_name = 1;
  123. }
  124. }
  125. #endif
  126. for (i = 0; i < PART_MAX_COUNT; i++) {
  127. if (!g_partition_all[i].info)
  128. continue;
  129. if (!strncmp(name, (const char *)g_partition_all[i].info->name, PART_META_INFO_NAMELEN)) {
  130. pal_log_info(PART_COMMON_TAG"[%s]find %s index %d\n", __FUNCTION__, name, i);
  131. return i;
  132. }
  133. #ifdef MTK_AB_OTA_UPDATER
  134. if (check_alt_name == 1 && !strncmp(alt_name, (const char *)g_partition_all[i].info->name, PART_META_INFO_NAMELEN)) {
  135. pal_log_info(PART_COMMON_TAG"[%s]find %s(add suffix for %s) index %d\n", __FUNCTION__, alt_name, name, i);
  136. return i;
  137. }
  138. #endif
  139. }
  140. return -1;
  141. }
  142. static int partition_map_search(const char *name)
  143. {
  144. int i, ret = -1;
  145. char last_char[2];
  146. char *new_name;
  147. int loops = sizeof(g_part_name_map) / sizeof(struct part_name_map);
  148. if (name == NULL)
  149. return ret;
  150. new_name = (char *)strdup(name);
  151. if (new_name == NULL)
  152. return ret;
  153. if ((int)strlen(name) - 2 >= 0) {
  154. last_char[0] = name[strlen(name) - 2];
  155. last_char[1] = name[strlen(name) - 1];
  156. } else {
  157. memset(last_char, 0, sizeof(last_char));
  158. }
  159. for (i = 0; i < loops; i++) {
  160. if (!g_part_name_map[i].fb_name[0])
  161. break;
  162. if (!strncmp(name, g_part_name_map[i].r_name, PART_META_INFO_NAMELEN)) {
  163. ret = i;
  164. break;
  165. }
  166. if ((last_char[1] == 'a' || last_char[1] == 'b') && last_char[0] == '_') { // AB partition
  167. new_name[strlen(name) - 2] = 0;
  168. }
  169. if (last_char[1] <= '9' || last_char[1] >= '0') { // xxx_1 or xxx1 partition
  170. if (last_char[0] == '_') { // ends with _[1-3]
  171. new_name[strlen(name) - 2] = 0;
  172. } else { // ends with [1-3] without _ such as tee1 and tee2
  173. new_name[strlen(name) - 1] = 0;
  174. }
  175. }
  176. if (!strncmp(new_name, g_part_name_map[i].r_name, PART_META_INFO_NAMELEN)) {
  177. pal_log_info(PART_COMMON_TAG"map partition %s(from %s) with %s\n", new_name, name, g_part_name_map[i].r_name);
  178. ret = i;
  179. break;
  180. }
  181. }
  182. free(new_name);
  183. return ret;
  184. }
  185. unsigned int partition_get_region(int index)
  186. {
  187. if (index < 0 || index >= PART_MAX_COUNT)
  188. return -1;
  189. if (!g_partition_all[index].nr_sects)
  190. return -1;
  191. return g_partition_all[index].part_id;
  192. }
  193. int partition_get_type(int index, char **p_type)
  194. {
  195. int i;
  196. if (index < 0 || index >= PART_MAX_COUNT)
  197. return -1;
  198. if (p_type == NULL)
  199. return -1;
  200. if (!g_partition_all[index].nr_sects)
  201. return -1;
  202. if (!g_partition_all[index].info)
  203. return -1;
  204. i = partition_map_search((const char*)g_partition_all[index].info->name);
  205. if (i < 0)
  206. return -1;
  207. *p_type = g_part_name_map[i].partition_type;
  208. return 0;
  209. }
  210. u64 partition_get_offset(int index)
  211. {
  212. part_dev_t *dev = mt_part_get_device();
  213. if (!dev) {
  214. pal_log_err(PART_COMMON_TAG"%s, err(no dev)\n", __func__);
  215. return -1;
  216. }
  217. if (index < 0 || index >= PART_MAX_COUNT)
  218. return -1;
  219. if (!g_partition_all[index].nr_sects)
  220. return -1;
  221. return (u64)g_partition_all[index].start_sect * dev->blkdev->blksz;
  222. }
  223. u64 partition_get_size(int index)
  224. {
  225. part_dev_t *dev = mt_part_get_device();
  226. if (!dev) {
  227. pal_log_err(PART_COMMON_TAG"%s, err(no dev)\n", __func__);
  228. return -1;
  229. }
  230. if (index < 0 || index >= PART_MAX_COUNT)
  231. return -1;
  232. if (!g_partition_all[index].nr_sects)
  233. return -1;
  234. return (u64)g_partition_all[index].nr_sects * dev->blkdev->blksz;
  235. }
  236. int partition_get_name(int index, char **p_name)
  237. {
  238. if (index < 0 || index >= PART_MAX_COUNT)
  239. return -1;
  240. if (p_name == NULL)
  241. return -1;
  242. if (!g_partition_all[index].nr_sects)
  243. return -1;
  244. if (!g_partition_all[index].info)
  245. return -1;
  246. *p_name = (char *) g_partition_all[index].info->name;
  247. return 0;
  248. }
  249. u8* partition_get_uuid_by_name(const char *part_name)
  250. {
  251. int index;
  252. index = partition_get_index_by_name(part_name);
  253. if (index == -1)
  254. return NULL;
  255. if (index < 0 || index >= PART_MAX_COUNT)
  256. return NULL;
  257. if (!g_partition_all[index].nr_sects)
  258. return NULL;
  259. return g_partition_all[index].info->uuid;
  260. }
  261. int partition_get_active_bit_by_name(const char *part_name)
  262. {
  263. int index;
  264. index = partition_get_index_by_name(part_name);
  265. if (index == -1)
  266. return -1;
  267. return (g_partition_all[index].part_attr & PART_ATTR_LEGACY_BIOS_BOOTABLE);
  268. }
  269. int partition_support_erase(const char *part_name)
  270. {
  271. int index;
  272. index = partition_get_index_by_name(part_name);
  273. if (index < 0 || index >= PART_MAX_COUNT)
  274. return PART_NOT_EXIST;
  275. if (!g_partition_all[index].nr_sects)
  276. return -1;
  277. if (!g_partition_all[index].info)
  278. return -1;
  279. index = partition_map_search((const char*)g_partition_all[index].info->name);
  280. if (index < 0)
  281. return -1;
  282. return g_part_name_map[index].is_support_erase;
  283. }
  284. int partition_support_flash(const char *part_name)
  285. {
  286. int index;
  287. index = partition_get_index_by_name(part_name);
  288. if (index < 0 || index >= PART_MAX_COUNT)
  289. return PART_NOT_EXIST;
  290. if (!g_partition_all[index].nr_sects)
  291. return -1;
  292. if (!g_partition_all[index].info)
  293. return -1;
  294. index = partition_map_search((const char*)g_partition_all[index].info->name);
  295. if (index < 0)
  296. return -1;
  297. return g_part_name_map[index].is_support_dl;
  298. }
  299. int gpt_partition_table_update(const char *arg, void *data, unsigned sz)
  300. {
  301. int err;
  302. /* Currently always write pgpt and sgpt to avoid misjudge of efi signature after update gpt power-loss */
  303. err = write_primary_gpt(data, sz);
  304. if (err) {
  305. pal_log_err(PART_COMMON_TAG"[GPT_Update]write write_primary_gpt, err(%d)\n", err);
  306. return err;
  307. }
  308. err = write_secondary_gpt(data, sz);
  309. if (err) {
  310. pal_log_err(PART_COMMON_TAG"[GPT_Update]write write_secondary_gpt, err(%d)\n", err);
  311. return err;
  312. }
  313. return 0;
  314. }
  315. /**/
  316. /*fastboot*/
  317. /**/
  318. unsigned int write_partition(unsigned size, unsigned char *partition)
  319. {
  320. return 0;
  321. }
  322. #define CMDLINE_BUF_SIZE (256)
  323. #define BOOT_DEV_BUF_SIZE (64)
  324. static void partition_commandline_bootdevice(void)
  325. {
  326. char cmdline_buf[CMDLINE_BUF_SIZE];
  327. char bootdev_buf[BOOT_DEV_BUF_SIZE];
  328. char *boot_device = cmdline_buf;
  329. int ret = 0;
  330. int remain = CMDLINE_BUF_SIZE;
  331. ret = snprintf(cmdline_buf, CMDLINE_BUF_SIZE, "androidboot.boot_devices=bootdevice");
  332. if (ret < 0) {
  333. pal_log_err(PART_COMMON_TAG"append bootdevice to command line fail\n");
  334. return;
  335. }
  336. remain -= ret;
  337. #ifdef MSDC0_BASE
  338. ret = snprintf(bootdev_buf, BOOT_DEV_BUF_SIZE, ",soc/%08x.mmc", MSDC0_BASE);
  339. if (ret < 0) {
  340. pal_log_err(PART_COMMON_TAG"append MSDC0_BASE(0x%08x) to command line fail\n", MSDC0_BASE);
  341. return;
  342. }
  343. boot_device = strncat(boot_device, bootdev_buf, remain);
  344. if (boot_device == NULL) {
  345. pal_log_err(PART_COMMON_TAG"cannot cat bootdevice %s to cmdline buffer\n", bootdev_buf);
  346. return;
  347. }
  348. remain -= ret;
  349. ret = snprintf(bootdev_buf, BOOT_DEV_BUF_SIZE, ",%08x.mmc", MSDC0_BASE);
  350. if (ret < 0) {
  351. pal_log_err(PART_COMMON_TAG"append MSDC0_BASE(0x%08x) to command line fail\n", MSDC0_BASE);
  352. return;
  353. }
  354. boot_device = strncat(boot_device, bootdev_buf, remain);
  355. if (boot_device == NULL) {
  356. pal_log_err(PART_COMMON_TAG"cannot cat bootdevice %s to cmdline buffer\n", bootdev_buf);
  357. return;
  358. }
  359. remain -= ret;
  360. #endif
  361. #ifdef UFS_HCI_BASE
  362. ret = snprintf(bootdev_buf, BOOT_DEV_BUF_SIZE, ",soc/%08x.ufshci", UFS_HCI_BASE);
  363. if (ret < 0) {
  364. pal_log_err(PART_COMMON_TAG"append UFS_HCI_BASE(0x%08x) to command line fail\n", UFS_HCI_BASE);
  365. return;
  366. }
  367. boot_device = strncat(boot_device, bootdev_buf, remain);
  368. if (boot_device == NULL) {
  369. pal_log_err(PART_COMMON_TAG"cannot cat bootdevice %s to cmdline buffer\n", bootdev_buf);
  370. return;
  371. }
  372. remain -= ret;
  373. ret = snprintf(bootdev_buf, BOOT_DEV_BUF_SIZE, ",%08x.ufshci", UFS_HCI_BASE);
  374. if (ret < 0) {
  375. pal_log_err(PART_COMMON_TAG"append UFS_HCI_BASE(0x%08x) to command line fail\n", UFS_HCI_BASE);
  376. return;
  377. }
  378. boot_device = strncat(boot_device, bootdev_buf, remain);
  379. if (boot_device == NULL) {
  380. pal_log_err(PART_COMMON_TAG"cannot cat bootdevice %s to cmdline buffer\n", bootdev_buf);
  381. return;
  382. }
  383. remain -= ret;
  384. #endif
  385. pal_log_err(PART_COMMON_TAG"boot_device str is %s.\n", boot_device);
  386. cmdline_append(cmdline_buf);
  387. }
  388. int part_init(part_dev_t *dev)
  389. {
  390. part_t *part_ptr;
  391. part_t *part_pgpt, *part_sgpt;
  392. int offset = 0, len_ck;
  393. struct part_meta_info *info;
  394. pal_log_err(PART_COMMON_TAG"[partition init]\n");
  395. #ifdef MTK_AB_OTA_UPDATER
  396. int predef_part_num = 3; // preloader, preloader_a, preloader_b
  397. #else
  398. int predef_part_num = 1; // preloader
  399. #endif
  400. part_ptr = (part_t *) calloc(PART_MAX_COUNT + predef_part_num + 2/*pgpt and spgt*/, sizeof(part_t));
  401. if (!part_ptr)
  402. return -1;
  403. g_partition_all = part_ptr;
  404. partition = part_ptr + predef_part_num + 1 /*pgpt*/;
  405. partition->part_id = dev->blkdev->part_user;
  406. read_gpt(partition);
  407. // add pgpt in global partition arrary
  408. part_pgpt = part_ptr + predef_part_num;
  409. part_pgpt->start_sect = 0x0;
  410. part_pgpt->nr_sects = partition_get_offset(predef_part_num + 1)/ dev->blkdev->blksz;
  411. part_pgpt->part_id = dev->blkdev->part_user;
  412. info = malloc(sizeof(*info));
  413. if (!info) {
  414. pal_log_err(PART_COMMON_TAG"[PART_INIT]lacking of memory\n");
  415. return -1;
  416. }
  417. part_pgpt->info = info;
  418. len_ck = snprintf((char*)part_pgpt->info->name, strlen("pgpt")+1, "%s", "pgpt");
  419. if (len_ck < 0) {
  420. pal_log_err(PART_COMMON_TAG"%s snprintf string %d into %d\n",
  421. __func__, strlen("pgpt")+1, len_ck);
  422. return -1;
  423. }
  424. // add sgpt in global partition arrary
  425. offset = get_entry_count() + predef_part_num + 1;
  426. part_sgpt = part_ptr + offset;
  427. part_sgpt->start_sect = (partition_get_offset(offset -1) + partition_get_size(offset-1))/ dev->blkdev->blksz;
  428. part_sgpt->nr_sects = last_lba(dev->blkdev->part_user) - part_sgpt->start_sect + 1;
  429. part_sgpt->part_id = dev->blkdev->part_user;
  430. info = malloc(sizeof(*info));
  431. if (!info) {
  432. pal_log_err(PART_COMMON_TAG"[PART_INIT]lacking of memory\n");
  433. return -1;
  434. }
  435. part_sgpt->info = info;
  436. len_ck = snprintf((char*)part_sgpt->info->name, strlen("sgpt")+1, "%s", "sgpt");
  437. if (len_ck < 0) {
  438. pal_log_err(PART_COMMON_TAG"%s snprintf string %d into %d\n",
  439. __func__, strlen("sgpt")+1, len_ck);
  440. return -1;
  441. }
  442. // set pre-defined partition entry for active preloader
  443. g_partition_all[0].start_sect = 0x0;
  444. g_partition_all[0].nr_sects = PART_PRELOADER_SIZE;
  445. #if (defined(MTK_EMMC_SUPPORT) || defined(MTK_UFS_SUPPORT))
  446. if (dev->blkdev->type == BOOTDEV_SDMMC)
  447. mmc_get_boot_part((u32 *)&g_partition_all[0].part_id); // get active boot partition
  448. #ifdef MTK_UFS_SUPPORT
  449. else if (dev->blkdev->type == BOOTDEV_UFS)
  450. ufs_lk_get_active_boot_part((u32 *)&g_partition_all[0].part_id);
  451. #endif
  452. #endif
  453. g_partition_all[0].info = malloc(sizeof(struct part_meta_info));
  454. if (g_partition_all[0].info) {
  455. len_ck = snprintf((char*)g_partition_all[0].info->name, strlen("preloader")+1, "%s", "preloader");
  456. if (len_ck < 0) {
  457. pal_log_err(PART_COMMON_TAG"%s snprintf string %d into %d\n",
  458. __func__, strlen("preloader")+1, len_ck);
  459. return -1;
  460. }
  461. }
  462. #ifdef MTK_AB_OTA_UPDATER
  463. // set pre-defined partition entry for preloader_a
  464. memcpy(&g_partition_all[1], &g_partition_all[0], sizeof(part_t));
  465. #if defined(MTK_EMMC_SUPPORT)
  466. if (dev->blkdev->type == BOOTDEV_SDMMC)
  467. g_partition_all[1].part_id = EMMC_PART_BOOT1;
  468. #endif
  469. #if defined(MTK_UFS_SUPPORT)
  470. if (dev->blkdev->type == BOOTDEV_UFS)
  471. g_partition_all[1].part_id = UFS_LU_BOOT1;
  472. #endif
  473. g_partition_all[1].info = malloc(sizeof(struct part_meta_info));
  474. if (g_partition_all[1].info) {
  475. len_ck = snprintf((char*)g_partition_all[1].info->name, strlen("preloader_a")+1, "%s", "preloader_a");
  476. if (len_ck < 0) {
  477. pal_log_err(PART_COMMON_TAG"%s snprintf string %d into %d\n",
  478. __func__, strlen("preloader_a")+1, len_ck);
  479. return -1;
  480. }
  481. }
  482. // set pre-defined partition entry for preloader_b
  483. memcpy(&g_partition_all[2], &g_partition_all[0], sizeof(part_t));
  484. #if defined(MTK_EMMC_SUPPORT)
  485. if (dev->blkdev->type == BOOTDEV_SDMMC)
  486. g_partition_all[2].part_id = EMMC_PART_BOOT2;
  487. #endif
  488. #if defined(MTK_UFS_SUPPORT)
  489. if (dev->blkdev->type == BOOTDEV_UFS)
  490. g_partition_all[2].part_id = UFS_LU_BOOT2;
  491. #endif
  492. g_partition_all[2].info = malloc(sizeof(struct part_meta_info));
  493. if (g_partition_all[2].info) {
  494. len_ck = snprintf((char*)g_partition_all[2].info->name, strlen("preloader_b")+1, "%s", "preloader_b");
  495. if (len_ck < 0) {
  496. pal_log_err(PART_COMMON_TAG"%s snprintf string %d into %d\n",
  497. __func__, strlen("preloader_b")+1, len_ck);
  498. return -1;
  499. }
  500. }
  501. #endif
  502. partition_commandline_bootdevice();
  503. return 0;
  504. }
  505. void mt_part_dump(void)
  506. {
  507. int i = 0;
  508. part_dev_t *dev = mt_part_get_device();
  509. if (!dev) {
  510. pal_log_err(PART_COMMON_TAG"%s, err(no dev)\n", __func__);
  511. return;
  512. }
  513. pal_log_info(PART_COMMON_TAG"Part Info.(1blk=%luB):\n", dev->blkdev->blksz);
  514. for (i = 0; i < real_partition_count; i++) {
  515. pal_log_info("[0x%016llx-0x%016llx] (%.8ld blocks): \"%s\"\n",
  516. (u64)g_partition_all[i].start_sect * dev->blkdev->blksz,
  517. (u64)(g_partition_all[i].start_sect + g_partition_all[i].nr_sects) * dev->blkdev->blksz - 1,
  518. g_partition_all[i].nr_sects, (g_partition_all[i].info) ? (char *)g_partition_all[i].info->name : "unknown");
  519. }
  520. pal_log_info("\n");
  521. }
  522. int get_gpt_entry_index(const char * part_name)
  523. {
  524. int i;
  525. for (i=0; i<PART_MAX_COUNT; i++)
  526. if (strncmp((const char *)g_partition_all[i].info->name, "pgpt", strlen("pgpt")) != 0 &&
  527. strncmp((const char *)g_partition_all[i].info->name, "preloader", strlen("preloader")) != 0)
  528. return partition_get_index_by_name(part_name) - i;
  529. pal_log_err(PART_COMMON_TAG"fail to get index in %s\n", __func__);
  530. return -1;
  531. }
  532. #endif // #ifdef MTK_PARTITION_COMMON
  533. /* name: should be translated to official name first, used for backward compatible */
  534. int partition_get_index_by_name(const char *part_name)
  535. {
  536. int index = -1;
  537. int found = 0;
  538. const PART_TRANS_TBL_ENTRY *entry = g_part_name_trans_tbl;
  539. if (part_name == NULL)
  540. return index;
  541. /* if name matches one of the official names, use translation table */
  542. for (; 0 != strcmp(entry->official_name, "NULL"); entry++) {
  543. if (0 == strcmp(part_name, entry->official_name)) {
  544. found = 1;
  545. break;
  546. }
  547. }
  548. if (found) {
  549. index = partition_get_index(entry->official_name);
  550. if (index != -1)
  551. return index;
  552. /* try alt_name1 */
  553. index = partition_get_index(entry->alt_name1);
  554. if (index != -1)
  555. return index;
  556. /* try alt_name2 */
  557. index = partition_get_index(entry->alt_name2);
  558. if (index != -1)
  559. return index;
  560. /* try alt_name3 */
  561. index = partition_get_index(entry->alt_name3);
  562. if (index != -1)
  563. return index;
  564. } else {
  565. /* don't do name translation if name is not found in table */
  566. index = partition_get_index(part_name);
  567. if (index != -1)
  568. return index;
  569. }
  570. return index;
  571. }
  572. u64 partition_get_size_by_name(const char *part_name)
  573. {
  574. int index;
  575. index = partition_get_index_by_name(part_name);
  576. return partition_get_size(index);
  577. }
  578. u64 partition_get_offset_by_name(const char *part_name)
  579. {
  580. int index;
  581. index = partition_get_index_by_name(part_name);
  582. return partition_get_offset(index);
  583. }
  584. char* partition_get_real_name(const char *part_name)
  585. {
  586. int index;
  587. char *p_name = NULL;
  588. index = partition_get_index_by_name(part_name);
  589. if (index == -1)
  590. return NULL;
  591. partition_get_name(index, &p_name);
  592. return p_name;
  593. }
  594. int partition_exists(const char *part_name)
  595. {
  596. if (partition_get_index_by_name(part_name) == -1)
  597. return PART_NOT_EXIST;
  598. else
  599. return PART_OK;
  600. }
  601. int partition_get_region_by_name(const char *part_name)
  602. {
  603. int index;
  604. index = partition_get_index_by_name(part_name);
  605. return partition_get_region(index);
  606. }
  607. int partition_get_type_by_name(const char *part_name, char **p_type)
  608. {
  609. int index;
  610. index = partition_get_index_by_name(part_name);
  611. return partition_get_type(index, p_type);
  612. }