efi.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  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 <printf.h>
  32. #include <malloc.h>
  33. #include <string.h>
  34. #include <lib/crc.h>
  35. #include <platform/mt_typedefs.h>
  36. #include <platform/partition.h>
  37. #include <efi.h>
  38. #include <part_interface.h>
  39. #include <block_generic_interface.h>
  40. #include <pal_log.h>
  41. #ifndef min
  42. #define min(x, y) (x < y ? x : y)
  43. #endif
  44. extern bool cmdline_append(const char *append_string);
  45. static int is_gpt_header_valid(gpt_header * header, u64 header_lba);
  46. static int is_gpt_entries_valid(gpt_header * header, gpt_entry * entries);
  47. static part_t *g_part_ptr = NULL;
  48. u32 sgpt_partition_lba_size;
  49. static u64 g_gpt_entry_cnt = 0;
  50. /*
  51. ********** Definition of Debug Macro **********
  52. */
  53. #define TAG "[GPT_LK]"
  54. #define LEVEL_ERR (0x0001)
  55. #define LEVEL_INFO (0x0004)
  56. #define DEBUG_LEVEL (LEVEL_ERR | LEVEL_INFO)
  57. #define efi_err(fmt, args...) \
  58. do { \
  59. if (DEBUG_LEVEL & LEVEL_ERR) { \
  60. pal_log_err(fmt, ##args); \
  61. } \
  62. } while (0)
  63. #define efi_critical(fmt, args...) \
  64. do { \
  65. if (DEBUG_LEVEL & LEVEL_INFO) { \
  66. pal_log_err(fmt, ##args); \
  67. } \
  68. } while (0)
  69. /*
  70. ********** Definition of GPT buffer **********
  71. */
  72. static u32 efi_crc32(u8 *p, u32 len)
  73. {
  74. return (crc32_no_comp(~0L, p, len) ^ ~0L); /* from zlib */
  75. }
  76. static void w2s(u8 *dst, int dst_max, u16 *src, int src_max)
  77. {
  78. int i = 0;
  79. int len = min(src_max, dst_max - 1);
  80. while (i < len) {
  81. if (!src[i]) {
  82. break;
  83. }
  84. dst[i] = src[i] & 0xFF;
  85. i++;
  86. }
  87. dst[i] = 0;
  88. return;
  89. }
  90. u64 get_entry_count()
  91. {
  92. return g_gpt_entry_cnt;
  93. }
  94. extern u64 g_emmc_user_size;
  95. u64 last_lba(u32 part_id)
  96. {
  97. part_dev_t *dev;
  98. dev = mt_part_get_device();
  99. if (!dev) {
  100. efi_err("%s%s, err(no dev)\n", TAG, __func__);
  101. return 1;
  102. }
  103. /* Only support USER region now */
  104. #if (defined(MTK_EMMC_SUPPORT) || defined(MTK_UFS_SUPPORT))
  105. if (dev->blkdev->type == BOOTDEV_SDMMC) {
  106. return g_emmc_user_size / dev->blkdev->blksz - 1;
  107. } else if (dev->blkdev->type == BOOTDEV_UFS) {
  108. u64 bytes;
  109. bytes = dev->get_part_size(dev, part_id);
  110. if (bytes)
  111. return bytes / dev->blkdev->blksz - 1;
  112. else
  113. return 0;
  114. }
  115. #endif
  116. return 0;
  117. }
  118. static void set_spgt_partition_lba_size(u32 size)
  119. {
  120. sgpt_partition_lba_size = size;
  121. }
  122. static u32 get_spgt_partition_lba_size()
  123. {
  124. return sgpt_partition_lba_size;
  125. }
  126. static u64 get_gpt_header_last_usable_lba()
  127. {
  128. part_dev_t *dev = mt_part_get_device();
  129. return (last_lba(dev->blkdev->part_user)-get_spgt_partition_lba_size());
  130. }
  131. static u32 entries_crc32;
  132. static void set_entries_crc32(u32 crc32)
  133. {
  134. entries_crc32 = crc32;
  135. }
  136. static u32 get_entries_crc32(void)
  137. {
  138. return entries_crc32;
  139. }
  140. static int read_data(u8 *buf, u32 part_id, u64 lba, u64 size)
  141. {
  142. int err;
  143. part_dev_t *dev;
  144. dev = mt_part_get_device();
  145. if (!dev) {
  146. efi_err("%sread data, err(no dev)\n", TAG);
  147. return 1;
  148. }
  149. err = dev->read(dev, lba * dev->blkdev->blksz, buf, (int)size, part_id);
  150. if (err != (int)size) {
  151. efi_err("%sread data, err(%d)\n", TAG, err);
  152. return err;
  153. }
  154. return 0;
  155. }
  156. static int write_data(u64 lba, u8 *buf, u64 size, u32 part_id)
  157. {
  158. int err;
  159. part_dev_t *dev;
  160. dev = mt_part_get_device();
  161. if (!dev) {
  162. efi_err("%swrite data, err(no dev)\n", TAG);
  163. return 1;
  164. }
  165. err = dev->write(dev, buf, lba * dev->blkdev->blksz, (int)size, part_id);
  166. if (err != (int)size) {
  167. efi_err("%s write data, err(%d)\n", TAG, err);
  168. return err;
  169. }
  170. return 0;
  171. }
  172. const char hex_asc[] = "0123456789abcdef";
  173. #define hex_asc_lo(x) hex_asc[((x)&0x0f)];
  174. #define hex_asc_hi(x) hex_asc[((x)&0xf0)>>4];
  175. static inline char *hex_byte_pack(char *buf, u8 byte)
  176. {
  177. *buf++ = hex_asc_hi(byte);
  178. *buf++ = hex_asc_lo(byte);
  179. return buf;
  180. }
  181. static u8 *string(u8 *buf, u8 *end, const char *s)
  182. {
  183. int len, i;
  184. len = strnlen(s, PART_META_INFO_UUIDLEN);
  185. for (i = 0; i < len; ++i) {
  186. if (buf < end)
  187. *buf = *s;
  188. ++buf;
  189. ++s;
  190. }
  191. if (buf < end)
  192. *buf = 0;
  193. return buf;
  194. }
  195. static u8 *uuid_string(u8 *buf, u8 *args)
  196. {
  197. /* uuid format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx, which contains 16*2 + 4('-') + 1 ('\0') = 37 bytes*/
  198. char uuid[PART_META_INFO_UUIDLEN];
  199. char *p = uuid;
  200. int i;
  201. static const u8 index[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15};
  202. u8 *end;
  203. end = buf + PART_META_INFO_UUIDLEN;
  204. for (i = 0; i < 16; i++) {
  205. p = hex_byte_pack(p, args[index[i]]);
  206. switch(i) {
  207. case 3:
  208. case 5:
  209. case 7:
  210. case 9:
  211. *p++ = '-';
  212. break;
  213. default:
  214. break;
  215. }
  216. }
  217. *p = 0;
  218. return string(buf, end, uuid);
  219. }
  220. static inline u8 *efi_guid_unparse(efi_guid_t *guid, u8 *out)
  221. {
  222. if (NULL == uuid_string(out, guid->b)) {
  223. efi_err("parse uuid string format fail!\n");
  224. return NULL;
  225. }
  226. return out;
  227. }
  228. static int parse_gpt_header(u32 part_id, u64 header_lba, u8 *header_buf, u8 *entries_buf)
  229. {
  230. int i;
  231. int err;
  232. u64 entries_read_size, num_block_entry;
  233. part_dev_t *dev = mt_part_get_device();
  234. gpt_header *header = (gpt_header *)header_buf;
  235. gpt_entry *entries = (gpt_entry *)entries_buf;
  236. struct part_meta_info *info;
  237. if (!dev) {
  238. efi_err("%s%s, err(no dev)\n", TAG, __func__);
  239. return 1;
  240. }
  241. if (g_part_ptr == NULL) {
  242. efi_err("%sg_part_ptr is NULL, partition table was not initialized\n", TAG);
  243. return 1;
  244. }
  245. if (header_buf == NULL) {
  246. efi_err("%sheader_buf is NULL\n", TAG);
  247. return 1;
  248. }
  249. if (entries_buf == NULL) {
  250. efi_err("%sentries_buf is NULL\n", TAG);
  251. return 1;
  252. }
  253. err = read_data(header_buf, part_id, header_lba, dev->blkdev->blksz);
  254. if (err) {
  255. efi_err("%sread header(part_id=%d,lba=%llx), err(%d)\n",
  256. TAG, part_id, header_lba, err);
  257. return err;
  258. }
  259. if (is_gpt_header_valid(header, header_lba) != 0)
  260. return 1;
  261. num_block_entry = (u64)(dev->blkdev->blksz / header->sizeof_partition_entry);
  262. entries_read_size = (u64)((header->num_partition_entries + (num_block_entry -1)) / num_block_entry) * dev->blkdev->blksz;
  263. err = read_data(entries_buf, part_id, header->partition_entry_lba, entries_read_size);
  264. if (err) {
  265. efi_err("%sread entries(part_id=%d,lba=%llx), err(%d)\n",
  266. TAG, part_id, header->partition_entry_lba, err);
  267. return err;
  268. }
  269. if (is_gpt_entries_valid(header, entries) != 0)
  270. return 1;
  271. efi_critical("%s user part id = %d\n", TAG, dev->blkdev->part_user);
  272. for (i = 0; (u32)i < header->num_partition_entries; i++) {
  273. /* break if the partition entry is empty */
  274. if (!entries[i].starting_lba) {
  275. break;
  276. }
  277. g_part_ptr[i].start_sect = (unsigned long)entries[i].starting_lba;
  278. g_part_ptr[i].nr_sects = (unsigned long)(entries[i].ending_lba - entries[i].starting_lba + 1);
  279. g_part_ptr[i].part_attr = (unsigned long)entries[i].attributes;
  280. g_part_ptr[i].part_id = dev->blkdev->part_user;
  281. info = malloc(sizeof(*info));
  282. if (!info) {
  283. continue;
  284. }
  285. g_part_ptr[i].info = info;
  286. if ((entries[i].partition_name[0] & 0xFF00) == 0) {
  287. w2s(g_part_ptr[i].info->name, PART_META_INFO_NAMELEN, entries[i].partition_name, GPT_ENTRY_NAME_LEN);
  288. } else {
  289. memcpy(g_part_ptr[i].info->name, entries[i].partition_name, 64);
  290. }
  291. if (NULL == efi_guid_unparse(&entries[i].unique_partition_guid, g_part_ptr[i].info->uuid)) {
  292. efi_err("efi parse uuid string fail!\n");
  293. return 1;
  294. }
  295. efi_critical("%s[%d]name=%s, start_sect=0x%lx, nr_sects=0x%lx, uuid=%s\n", TAG, i,
  296. g_part_ptr[i].info ? (char *)g_part_ptr[i].info->name : "unknown",
  297. g_part_ptr[i].start_sect, g_part_ptr[i].nr_sects,
  298. g_part_ptr[i].info ? (char *)g_part_ptr[i].info->uuid : "");
  299. }
  300. // record the total entry count
  301. g_gpt_entry_cnt = i;
  302. return 0;
  303. }
  304. int read_gpt(part_t *part)
  305. {
  306. int err;
  307. u64 lba;
  308. u8 *pgpt_header, *pgpt_entries;
  309. u8 *sgpt_header, *sgpt_entries;
  310. u32 part_id, gpt_entries_size;
  311. part_dev_t *dev = mt_part_get_device();
  312. if (!dev) {
  313. efi_err("%s%s, err(no dev)\n", TAG, __func__);
  314. return 1;
  315. }
  316. part_id = dev->blkdev->part_user;
  317. gpt_entries_size = sizeof(gpt_entry) * PART_MAX_COUNT;
  318. g_part_ptr = part;
  319. efi_critical("%sParsing Primary GPT now...\n", TAG);
  320. pgpt_header = (u8 *)malloc(dev->blkdev->blksz);
  321. if (!pgpt_header) {
  322. efi_err("%smalloc memory(pgpt header), err\n", TAG);
  323. goto next_try;
  324. }
  325. memset(pgpt_header, 0, dev->blkdev->blksz);
  326. pgpt_entries = (u8 *)malloc(gpt_entries_size);
  327. if (!pgpt_entries) {
  328. free(pgpt_header);
  329. efi_err("%smalloc memory(pgpt entries), err\n", TAG);
  330. goto next_try;
  331. }
  332. memset(pgpt_entries, 0, gpt_entries_size);
  333. err = parse_gpt_header(part_id, 1, pgpt_header, pgpt_entries);
  334. /* Free pgpt buffers after using it */
  335. free(pgpt_header);
  336. free(pgpt_entries);
  337. if (!err) {
  338. goto find;
  339. }
  340. next_try:
  341. efi_critical("%sParsing Secondary GPT now...\n", TAG);
  342. sgpt_header = (u8 *)malloc(dev->blkdev->blksz);
  343. if (!sgpt_header) {
  344. efi_err("%smalloc memory(sgpt header), err\n", TAG);
  345. return 1;
  346. }
  347. memset(sgpt_header, 0, dev->blkdev->blksz);
  348. sgpt_entries = (u8 *)malloc(gpt_entries_size);
  349. if (!sgpt_entries) {
  350. free(sgpt_header);
  351. efi_err("%smalloc memory(sgpt entries), err\n", TAG);
  352. return 1;
  353. }
  354. memset(sgpt_entries, 0, gpt_entries_size);
  355. lba = last_lba(part_id);
  356. if (!lba) {
  357. free(sgpt_header);
  358. free(sgpt_entries);
  359. efi_err("%sFailure to find last lba.\n", TAG);
  360. return 1;
  361. }
  362. err = parse_gpt_header(part_id, lba, sgpt_header, sgpt_entries);
  363. /* Free sgpt buffers after using it */
  364. free(sgpt_header);
  365. free(sgpt_entries);
  366. if (!err) {
  367. goto find;
  368. }
  369. efi_err("%sFailure to find valid GPT.\n", TAG);
  370. return err;
  371. find:
  372. efi_critical("%sSuccess to find valid GPT.\n", TAG);
  373. return 0;
  374. }
  375. static void pack_pmbr_data(void *ptr)
  376. {
  377. pmbr *mbr = (pmbr *)ptr;
  378. u64 nr_sects;
  379. u16 nr_sects_split[2];
  380. u16 *nr_sects_split_ptr;
  381. part_dev_t *dev = mt_part_get_device();
  382. if (!dev) {
  383. efi_err("%s%s, err(no dev)\n", TAG, __func__);
  384. return;
  385. }
  386. nr_sects = last_lba(dev->blkdev->part_user) + 1;
  387. mbr->partition_record[0].sys_ind = GPT_PROTECTIVE_MBR;
  388. mbr->partition_record[0].start_sector = 0x1;
  389. /* Suffer from mbr->partition_record[0].nr_sects address not 4-byte aligned(data abort will occur if directly write u32 data), split it into two 2-byte */
  390. nr_sects_split[0] = ((nr_sects < 0xFFFFFFFF) ? (nr_sects - 1) : 0xFFFFFFFF) & 0xFFFF;
  391. nr_sects_split[1] = (((nr_sects < 0xFFFFFFFF) ? (nr_sects - 1) : 0xFFFFFFFF) >> 16) & 0xFFFF;
  392. nr_sects_split_ptr = (u16 *)(&((mbr->partition_record[0].nr_sects)));
  393. *nr_sects_split_ptr = nr_sects_split[0];
  394. *(nr_sects_split_ptr +1) = nr_sects_split[1];
  395. mbr->signature = 0xAA55;
  396. }
  397. static void pack_pheader_data(void *data)
  398. {
  399. part_dev_t *dev = mt_part_get_device();
  400. if (!dev) {
  401. efi_err("%s%s, err(no dev)\n", TAG, __func__);
  402. return;
  403. }
  404. gpt_header *header = (gpt_header *)data;
  405. header->reserved = 0;
  406. header->alternate_lba = last_lba(dev->blkdev->part_user);
  407. header->last_usable_lba = get_gpt_header_last_usable_lba();
  408. header->partition_entry_array_crc32 = get_entries_crc32();
  409. header->header_crc32 = 0;
  410. header->header_crc32 = efi_crc32(data, sizeof(gpt_header));
  411. }
  412. static void pack_entries_data(void *data)
  413. {
  414. int i;
  415. int nr_parts = 0;
  416. part_dev_t *dev = mt_part_get_device();
  417. gpt_entry *entries = (gpt_entry *)data;
  418. if (!dev) {
  419. efi_err("%s%s, err(no dev)\n", TAG, __func__);
  420. return;
  421. }
  422. //calculate how many partitions
  423. for (i = 0; i < PART_MAX_COUNT; i++) {
  424. if (!entries[i].partition_name[0]) {
  425. nr_parts = i;
  426. break;
  427. }
  428. }
  429. efi_err("%snumber of partitions: %d.\n", TAG, nr_parts);
  430. /* Update gpt entries */
  431. for (i = nr_parts-1; i >= 0; i--) {
  432. /* it's last partition (do not have reserved partition ex: no flashinfo, otp), only need to update last partition */
  433. /* may not go to here unless customer remove flashinfo partition */
  434. if (i == nr_parts-1 && !entries[i].starting_lba && !entries[i].ending_lba) {
  435. entries[i].ending_lba = last_lba(dev->blkdev->part_user) - get_spgt_partition_lba_size() ;
  436. entries[i].starting_lba = entries[i-1].ending_lba + 1;
  437. break;
  438. }
  439. /* Process reserved partitions(flashinfo, otp) and last partition before reserved partition(ex: userdata or intsd) */
  440. /* Reserved partition size is stored in ending_lba, sgpt partition size can be retrived from get_spgt_partition_size()(stored in header->reserved)*/
  441. if (!entries[i].starting_lba) {
  442. /* it's a reserved partition and it's last partition, entries[i].ending_lba not empty(partition size is here) */
  443. if (i == nr_parts-1 && entries[i].ending_lba) {
  444. entries[i].starting_lba = last_lba(dev->blkdev->part_user) - get_spgt_partition_lba_size() - entries[i].ending_lba + 1;
  445. entries[i].ending_lba = last_lba(dev->blkdev->part_user) - get_spgt_partition_lba_size() ;
  446. }
  447. /* reserved parttiion but not last one */
  448. /* may not go to here uless there exists more than one reserved partitions (ex: otp + flashinfo)*/
  449. else if (entries[i].ending_lba) {
  450. entries[i].starting_lba = entries[i+1].starting_lba - entries[i].ending_lba;
  451. entries[i].ending_lba = entries[i+1].starting_lba - 1;
  452. }
  453. /* userdata or intsed */
  454. else {
  455. entries[i].starting_lba = entries[i-1].ending_lba + 1;
  456. entries[i].ending_lba = entries[i+1].starting_lba - 1;
  457. }
  458. }
  459. }
  460. set_entries_crc32(efi_crc32(data, PART_MAX_COUNT * sizeof(gpt_entry)));
  461. }
  462. static void pack_sheader_data(void *data)
  463. {
  464. gpt_header *header = (gpt_header *)data;
  465. header->header_crc32 = 0;
  466. header->my_lba = header->alternate_lba;
  467. header->alternate_lba = 1;
  468. header->partition_entry_lba = get_gpt_header_last_usable_lba() + 1;
  469. header->partition_entry_array_crc32 = get_entries_crc32();
  470. header->header_crc32 = efi_crc32(data, sizeof(gpt_header));
  471. }
  472. int write_primary_gpt(void *data, unsigned sz)
  473. {
  474. int err, part_entries_cnt_per_block;
  475. u64 pentries_write_size;
  476. gpt_header *header;
  477. gpt_entry *entries;
  478. pmbr *mbr;
  479. int with_pmbr; /* 0: data is without pmbr, 1: data is with pmbr*/
  480. part_dev_t *dev = mt_part_get_device();
  481. if (!dev) {
  482. efi_err("%s%s, err(no dev)\n", TAG, __func__);
  483. return -1;
  484. }
  485. /* fastboot PGPT image check */
  486. if (sz == (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz)) {
  487. with_pmbr = 0;
  488. mbr = NULL;
  489. header = (gpt_header *)data;
  490. entries = (gpt_entry *)(data + dev->blkdev->blksz);
  491. } else if (sz == (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz * 2)) {
  492. with_pmbr = 1;
  493. mbr = (pmbr *)data;
  494. header = (gpt_header *)(data + dev->blkdev->blksz);
  495. entries = (gpt_entry *)(data + dev->blkdev->blksz * 2);
  496. } else {
  497. err = -1;
  498. efi_err("[GPT_Update]PGPT size not correct, err(%d), expect: 0x%lx read: 0x%x\n", err, (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz), sz);
  499. return err;
  500. }
  501. if (header->signature != GPT_HEADER_SIGNATURE) {
  502. err = -1;
  503. efi_err("[GPT_Update] %scheck header, err(signature 0x%llx!=0x%llx)\n",
  504. TAG, header->signature, GPT_HEADER_SIGNATURE);
  505. return err;
  506. }
  507. if (!with_pmbr) {
  508. mbr = (pmbr *)malloc(dev->blkdev->blksz);
  509. if (!mbr) {
  510. err = -1;
  511. efi_err("%s malloc memory(pmbr header), err\n", TAG);
  512. return err;
  513. }
  514. memset(mbr, 0, dev->blkdev->blksz);
  515. }
  516. if (header->alternate_lba != last_lba(dev->blkdev->part_user)) {
  517. set_spgt_partition_lba_size(header->alternate_lba); //sgpt partition size is hrere
  518. } else {
  519. set_spgt_partition_lba_size(last_lba(dev->blkdev->part_user) - header->last_usable_lba);
  520. }
  521. pack_entries_data((void *)entries); //move to gpt entries
  522. pack_pheader_data((void *)header); //update pheader
  523. pack_pmbr_data((void *)mbr);
  524. /* Write pmbr */
  525. err = write_data(0, (u8 *)mbr, (u64)dev->blkdev->blksz, dev->blkdev->part_user);
  526. if (!with_pmbr)
  527. free(mbr); /* Free pmbr after use it */
  528. if (err) {
  529. efi_err("[GPT_Update]write pmbr, err(%d)\n", err);
  530. return err;
  531. }
  532. /* Write pheader */
  533. err = write_data(1, (u8 *)header, (u64)dev->blkdev->blksz, dev->blkdev->part_user);
  534. if (err) {
  535. efi_err("[GPT_Update]write pheader, err(%d)\n", err);
  536. return err;
  537. }
  538. /* Write gpt entries */
  539. part_entries_cnt_per_block = dev->blkdev->blksz / header->sizeof_partition_entry;
  540. pentries_write_size = (u64)((PART_MAX_COUNT + part_entries_cnt_per_block - 1) / part_entries_cnt_per_block) * dev->blkdev->blksz;
  541. err = write_data(2, (u8 *)entries, pentries_write_size, dev->blkdev->part_user);
  542. if (err) {
  543. efi_err("[GPT_Update]write pentries, err(%d)\n", err);
  544. return err;
  545. }
  546. return 0;
  547. }
  548. int write_secondary_gpt(void *data, unsigned sz)
  549. {
  550. int err, part_entries_cnt_per_block;
  551. u64 pentries_write_size;
  552. u64 sentries_start_lba;
  553. gpt_header *header;
  554. gpt_entry *entries;
  555. part_dev_t *dev = mt_part_get_device();
  556. if (!dev) {
  557. efi_err("%s%s, err(no dev)\n", TAG, __func__);
  558. return -1;
  559. }
  560. /* fastboot PGPT image check */
  561. if (sz == (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz)) {
  562. header = (gpt_header *)data;
  563. entries = (gpt_entry *)(data + dev->blkdev->blksz);
  564. } else if (sz == (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz * 2)) {
  565. header = (gpt_header *)(data + dev->blkdev->blksz);
  566. entries = (gpt_entry *)(data + dev->blkdev->blksz * 2);
  567. } else {
  568. err = -1;
  569. efi_err("[GPT_Update]SGPT size not correct, err(%d), expect: 0x%lx read: 0x%x\n", err, (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz), sz);
  570. return err;
  571. }
  572. if (header->signature != GPT_HEADER_SIGNATURE) {
  573. err = -1;
  574. efi_err("[GPT_Update] %s check header, err(signature 0x%llx!=0x%llx)\n",
  575. TAG, header->signature, GPT_HEADER_SIGNATURE);
  576. return err;
  577. }
  578. pack_sheader_data(header); //update sheader
  579. /* Write sheader */
  580. err = write_data(last_lba(dev->blkdev->part_user), (u8 *)header, (u64)dev->blkdev->blksz, dev->blkdev->part_user);
  581. if (err) {
  582. efi_err("[GPT_Update]write sheader, err(%d)\n", err);
  583. return err;
  584. }
  585. /* Write gpt entries */
  586. sentries_start_lba = get_gpt_header_last_usable_lba() + 1;
  587. part_entries_cnt_per_block = dev->blkdev->blksz / header->sizeof_partition_entry;
  588. pentries_write_size = (u64)((PART_MAX_COUNT + part_entries_cnt_per_block - 1) / part_entries_cnt_per_block) * dev->blkdev->blksz;
  589. err = write_data(sentries_start_lba, (u8 *)entries, pentries_write_size, dev->blkdev->part_user);
  590. if (err) {
  591. efi_err("[GPT_Update]write pentries, err(%d)\n", err);
  592. return err;
  593. }
  594. return 0;
  595. }
  596. unsigned int *target_commandline_force_gpt(char *cmd)
  597. {
  598. cmdline_append("gpt=1");
  599. return 0;
  600. }
  601. static int is_gpt_header_valid(gpt_header * header, u64 header_lba)
  602. {
  603. u32 calc_crc, orig_header_crc;
  604. if (header->signature != GPT_HEADER_SIGNATURE) {
  605. efi_err("%s check header, err(signature 0x%llx!=0x%llx)\n",
  606. TAG, header->signature, GPT_HEADER_SIGNATURE);
  607. return -1;
  608. }
  609. // header crc32 check
  610. orig_header_crc = header->header_crc32;
  611. header->header_crc32 = 0;
  612. calc_crc = efi_crc32((u8 *)header, header->header_size);
  613. if (orig_header_crc != calc_crc) {
  614. efi_err("%scheck header, err(crc 0x%x!=0x%x(calc))\n",
  615. TAG, orig_header_crc, calc_crc);
  616. return -1;
  617. }
  618. header->header_crc32 = orig_header_crc;
  619. if (header->num_partition_entries > PART_MAX_COUNT) {
  620. efi_err("%scheck header, num_partition_entries(%d) exceeds\n",
  621. TAG, header->num_partition_entries);
  622. return -1;
  623. }
  624. if (header->my_lba != header_lba) {
  625. efi_err("%scheck header, err(my_lba 0x%llx!=0x%llx)\n",
  626. TAG, header->my_lba, header_lba);
  627. return -1;
  628. }
  629. return 0;
  630. }
  631. static int is_gpt_entries_valid(gpt_header * header, gpt_entry * entries)
  632. {
  633. u64 entries_real_size;
  634. u32 calc_crc;
  635. entries_real_size = (u64)header->num_partition_entries * header->sizeof_partition_entry;
  636. calc_crc = efi_crc32((u8 *)entries, (u32)entries_real_size);
  637. if (header->partition_entry_array_crc32 != calc_crc) {
  638. efi_err("%scheck header, err(entries crc 0x%x!=0x%x(calc))\n",
  639. TAG, header->partition_entry_array_crc32, calc_crc);
  640. return -1;
  641. }
  642. return 0;
  643. }
  644. int is_gpt_valid(const u8 * gpt_raw, u64 header_lba)
  645. {
  646. gpt_header *header;
  647. gpt_entry *entries;
  648. part_dev_t *dev = mt_part_get_device();
  649. header = (gpt_header *)gpt_raw;
  650. entries = (gpt_entry *)(gpt_raw + dev->blkdev->blksz);
  651. if (is_gpt_header_valid(header, header_lba) != 0 ||
  652. is_gpt_entries_valid(header, entries) != 0)
  653. return -1;
  654. return 0;
  655. }