fdt_op.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  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) 2018. 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 <stdio.h>
  32. #include <stdlib.h>
  33. #include <stddef.h>
  34. #include <assert.h>
  35. #include <bootargs.h>
  36. #include <errno.h>
  37. #include <string.h>
  38. #include <pal_assert.h>
  39. #include <pal_typedefs.h>
  40. #include <pal_log.h>
  41. #include <memory_layout.h>
  42. #include <libfdt.h>
  43. #include <profiling.h>
  44. #include <odm_mdtbo.h>
  45. #include <boot_opt.h>
  46. #include <boot_info.h>
  47. #include <part_interface.h>
  48. #include <ufdt_overlay.h>
  49. #include <fdt_op.h>
  50. #include <bootimg.h>
  51. #include <mt_boot.h>
  52. #include <arch/arm/mmu.h>
  53. #include <load_vfy_boot.h>
  54. #include <mt_rtc.h>
  55. #include <part_interface.h>
  56. #include <part_status.h>
  57. #include <mkimg.h>
  58. #include <platform/mt_gpt.h>
  59. #include <odm_mdtbo.h>
  60. #include <boot_info.h>
  61. #include <platform/errno.h>
  62. #include <lk_builtin_dtb.h>
  63. #include <platform/verified_boot.h>
  64. void *g_fdt;
  65. DTBO_SRC g_dtbo_load_src = DTBO_FROM_STANDALONE;
  66. extern u32 g_64bit_dtb_size;
  67. extern int g_is_64bit_kernel;
  68. extern char *p_AB_suffix;
  69. #define DTBO_PART_NEW_A_NAME "dtbo_a"
  70. static char *dtbo_one_part_name = "dtbo";
  71. #ifndef MTK_AB_OTA_UPDATER
  72. static char *dtbo_part_names[] = {"dtbo1", "dtbo2"};
  73. #endif
  74. static char *dtbo_fallback_part_name= "odmdtbo";
  75. static char dtbo_part_name_full[DTBO_PART_NAME_LEN + 1];
  76. extern int mboot_recovery_load_raw_part(char *part_name, unsigned long *addr, unsigned int size);
  77. extern int unshield_recovery_detection(void);
  78. extern int mboot_common_load_part(char *part_name, char *img_name, unsigned long addr);
  79. DTBO_SRC get_dtbo_src(void)
  80. {
  81. return g_dtbo_load_src;
  82. }
  83. void setup_kernel_fdt(void *fdt)
  84. {
  85. g_fdt = fdt;
  86. }
  87. void *get_kernel_fdt(void)
  88. {
  89. return g_fdt;
  90. }
  91. /***********************************************************************
  92. * API to retrieve where dtbo partition from, the name is fallback iterated
  93. ************************************************************************/
  94. char *get_dtbo_part_name(void)
  95. {
  96. char *part_name = NULL;
  97. static uint32_t dtbo_part_name_inited = 0;
  98. if (!dtbo_part_name_inited) {
  99. #ifdef MTK_AB_OTA_UPDATER
  100. part_name = dtbo_part_name_full;
  101. if (partition_exists(DTBO_PART_NEW_A_NAME) == PART_OK)
  102. strncpy(part_name,dtbo_one_part_name, DTBO_PART_NAME_LEN);
  103. else
  104. strncpy(part_name, dtbo_fallback_part_name, DTBO_PART_NAME_LEN);
  105. int part_name_len = strlen(part_name);
  106. if (p_AB_suffix) {
  107. strncpy((void *)&part_name[part_name_len], (void *)p_AB_suffix,
  108. DTBO_PART_NAME_LEN - part_name_len);
  109. }
  110. #else
  111. int i;
  112. int array_size = (int)(sizeof(dtbo_part_names) / sizeof(dtbo_part_names[0]));
  113. /* check "dtbo" */
  114. if (partition_exists(dtbo_one_part_name) == PART_OK) {
  115. part_name = dtbo_one_part_name;
  116. goto partname_selected;
  117. }
  118. /* check "dtbo1" */
  119. if (partition_exists(dtbo_part_names[0]) == PART_OK) {
  120. for (i = 0; i < array_size; i++) {
  121. if (partition_get_active_bit_by_name(dtbo_part_names[i]))
  122. part_name = dtbo_part_names[i];
  123. }
  124. if(part_name == NULL)
  125. part_name = dtbo_part_names[0];
  126. } else
  127. /* Fallback to old style */
  128. part_name = dtbo_fallback_part_name;
  129. partname_selected:
  130. strncpy(dtbo_part_name_full, part_name, DTBO_PART_NAME_LEN);
  131. #endif
  132. if (strlen(part_name) > DTBO_PART_NAME_LEN) {
  133. pal_log_err("The length of DTBO partition name:%s > %d!\n", part_name,
  134. DTBO_PART_NAME_LEN);
  135. assert(0);
  136. }
  137. dtbo_part_name_full[DTBO_PART_NAME_LEN] = '\0';
  138. dtbo_part_name_inited = 1;
  139. }
  140. return dtbo_part_name_full;
  141. }
  142. #if defined(MTK_DCONFIG_SUPPORT)
  143. #define DCONFIG_DTB_SIZE 131072
  144. #define DCONFIG_PART "boot_para"
  145. #define DCONFIG_DT_NAME "dconfig-dt"
  146. static u8 *dtb_dconfig_load(void)
  147. {
  148. static bool dconfig_dtb_failed = false;
  149. u8 *dconfig_dtb = NULL;
  150. int len = 0;
  151. if (dconfig_dtb_failed) {
  152. pal_log_info("dconfig-dt already load failed, don't do it again\n");
  153. return NULL;
  154. }
  155. #ifdef MTK_SECURITY_SW_SUPPORT
  156. unsigned int policy_entry_idx = 0;
  157. unsigned int img_auth_required = 0;
  158. policy_entry_idx = get_policy_entry_idx(DCONFIG_PART);
  159. img_auth_required = get_vfy_policy(policy_entry_idx);
  160. if (img_auth_required) {
  161. uint32_t sec_ret = sec_img_auth_init(DCONFIG_PART, DCONFIG_DT_NAME, 0);
  162. if (sec_ret) {
  163. dconfig_dtb_failed = true;
  164. pal_log_err("dconfig image cert verify failed\n");
  165. return NULL;
  166. }
  167. }
  168. #endif
  169. dconfig_dtb = malloc(DCONFIG_DTB_SIZE);
  170. if (dconfig_dtb == NULL) {
  171. dconfig_dtb_failed = true;
  172. pal_log_err("Not enough memory\n");
  173. return NULL;
  174. }
  175. len = mboot_common_load_part(DCONFIG_PART, DCONFIG_DT_NAME,
  176. (unsigned long)dconfig_dtb);
  177. if (len <= 0) {
  178. dconfig_dtb_failed = true;
  179. pal_log_info("partition_read failed, return value %d\n", len);
  180. free(dconfig_dtb);
  181. return NULL;
  182. }
  183. #ifdef MTK_SECURITY_SW_SUPPORT
  184. if (img_auth_required) {
  185. uint32_t sec_ret = sec_img_auth(dconfig_dtb, len);
  186. if (sec_ret) {
  187. dconfig_dtb_failed = true;
  188. pal_log_err("dconfig image verify failed\n");
  189. free(dconfig_dtb);
  190. return NULL;
  191. }
  192. }
  193. #endif
  194. return dconfig_dtb;
  195. }
  196. bool dtb_dconfig_overlay(void *target_fdt)
  197. {
  198. int ret = 0;
  199. if (target_fdt == NULL) {
  200. pal_log_err("dconfig: passing target fdt with null\n");
  201. return TRUE;
  202. }
  203. u8 *dconfig_dtb = dtb_dconfig_load();
  204. if (dconfig_dtb == NULL) {
  205. return TRUE;
  206. }
  207. struct fdt_header *dconfig_fdth = (struct fdt_header *) dconfig_dtb;
  208. if (fdt_magic(dconfig_fdth) != FDT_MAGIC) {
  209. pal_log_info("FDT magic number miss match : magic %x\n",
  210. fdt_magic(dconfig_fdth));
  211. free(dconfig_dtb);
  212. return TRUE;
  213. }
  214. if (fdt_totalsize(dconfig_fdth) >= DCONFIG_DTB_SIZE) {
  215. pal_log_err("Dconfig's DT size too large %d\n", fdt_totalsize(dconfig_fdth));
  216. free(dconfig_dtb);
  217. return TRUE;
  218. }
  219. struct fdt_header *blob = ufdt_install_blob(target_fdt, DTB_MAX_SIZE);
  220. if (!blob) {
  221. pal_log_err("ufdt_install_blob() failed\n");
  222. free(dconfig_dtb);
  223. return FALSE;
  224. }
  225. void *merged_fdt = ufdt_apply_overlay(blob, fdt_totalsize(blob), dconfig_fdth,
  226. fdt_totalsize(dconfig_fdth));
  227. if (!merged_fdt) {
  228. pal_log_err("dconfig: ufdt_apply_overlay failed\n");
  229. free(dconfig_dtb);
  230. return FALSE;
  231. }
  232. ret = fdt_pack(merged_fdt);
  233. if (ret) {
  234. pal_log_err("dconfig: fdt_pack failed\n");
  235. free(merged_fdt);
  236. free(dconfig_dtb);
  237. return FALSE;
  238. }
  239. int merged_size = fdt_totalsize(merged_fdt);
  240. if (merged_size > DTB_MAX_SIZE) {
  241. pal_log_err("dconfig: merged size %d > DTB_MAX_SIZE\n", merged_size);
  242. free(merged_fdt);
  243. free(dconfig_dtb);
  244. return FALSE;
  245. }
  246. if (fdt_open_into(merged_fdt, target_fdt, DTB_MAX_SIZE) != 0) {
  247. pal_log_err("dconfig: DTB replace failed\n");
  248. free(merged_fdt);
  249. free(dconfig_dtb);
  250. return FALSE;
  251. }
  252. free(merged_fdt);
  253. free(dconfig_dtb);
  254. return TRUE;
  255. }
  256. #else
  257. bool dtb_dconfig_overlay(void *target_fdt)
  258. {
  259. return TRUE;
  260. }
  261. #endif
  262. #ifndef LK_MAIN_DTB_BUILT_IN
  263. void *get_lk_overlayed_dtb(void){return g_fdt;}
  264. int32_t prepare_kernel_dtb(void){return 0;}
  265. /***********************************************************************
  266. * Done after bldr_load_dtb, overlay from associated dtbo partition
  267. ************************************************************************/
  268. bool dtb_overlay(void *fdt, int size, uint64_t recovery_dtbo_offset)
  269. {
  270. size_t overlay_len = 0;
  271. char *part_name = NULL;
  272. g_fdt = fdt;
  273. if (fdt == NULL) {
  274. pal_log_err("fdt is NULL\n");
  275. return FALSE;
  276. }
  277. if (size == 0) {
  278. pal_log_err("fdt size is zero\n");
  279. return FALSE;
  280. }
  281. #ifdef MTK_AB_OTA_UPDATER
  282. part_name = get_dtbo_part_name();
  283. #else
  284. /* for non-AB supporting bootimg hdr version 1, get dtbo from recovery */
  285. if (recovery_dtbo_offset == 0) {
  286. part_name = get_dtbo_part_name();
  287. }
  288. else {
  289. part_name = "recovery";
  290. g_dtbo_load_src = DTBO_FROM_RECOVERY;
  291. }
  292. #endif // MTK_AB_OTA_UPDATER
  293. // Note: A buffer is allocated in load_overlay_dtbo() to store the loaded
  294. // odm dtb.
  295. char *overlay_buf = load_overlay_dtbo(part_name, &overlay_len, (uint64_t)recovery_dtbo_offset);
  296. // check overlay dtbo
  297. if (overlay_buf == NULL) {
  298. pal_log_err("load overlay dtbo failed !\n");
  299. return FALSE;
  300. }
  301. // check len of overlay dtbo
  302. if (overlay_len == 0) {
  303. pal_log_err("size of overlay dtbo is 0 !\n");
  304. free(overlay_buf);
  305. return FALSE;
  306. }
  307. struct fdt_header *fdth = (struct fdt_header *)g_fdt;
  308. fdth->totalsize = cpu_to_fdt32(size);
  309. int ret = fdt_open_into(g_fdt, g_fdt, size);
  310. if (ret) {
  311. pal_log_err("fdt_open_into failed \n");
  312. free(overlay_buf);
  313. return FALSE;
  314. }
  315. ret = fdt_check_header(g_fdt);
  316. if (ret) {
  317. pal_log_err("fdt_check_header check failed !\n");
  318. free(overlay_buf);
  319. return FALSE;
  320. }
  321. char *base_buf = fdt;
  322. size_t blob_len = size;
  323. struct fdt_header *blob = ufdt_install_blob(base_buf, blob_len);
  324. if (!blob) {
  325. pal_log_err("ufdt_install_blob() failed!\n");
  326. free(overlay_buf);
  327. return FALSE;
  328. }
  329. pal_log_info("blob_len: 0x%x, overlay_len: 0x%x\n", blob_len, overlay_len);
  330. void *merged_fdt = NULL;
  331. PROFILING_START("Overlay");
  332. // Note: A buffer is allocated in ufdt_apply_overlay() to store the merge
  333. // device tree.
  334. merged_fdt = ufdt_apply_overlay(blob, blob_len, overlay_buf, overlay_len);
  335. if (!merged_fdt) {
  336. pal_log_err("ufdt_apply_overlay() failed!\n");
  337. free(overlay_buf);
  338. assert(0);
  339. return FALSE;
  340. }
  341. PROFILING_END();
  342. // Compact the merged device tree so that the size of the device tree can
  343. // be known.
  344. ret = fdt_pack(merged_fdt);
  345. if (ret) {
  346. pal_log_err("fdt_pack(merged_fdt) failed !\n");
  347. free(merged_fdt);
  348. free(overlay_buf);
  349. return FALSE;
  350. }
  351. int merged_size = fdt_totalsize(merged_fdt);
  352. pal_log_info("fdt merged_size: %d\n", merged_size);
  353. if (merged_size > DTB_MAX_SIZE) {
  354. pal_log_err("Error: merged size %d > DTB_MAX_SIZE!\n", merged_size);
  355. free(merged_fdt);
  356. free(overlay_buf);
  357. return FALSE;
  358. }
  359. // The memory pointed to by "g_fdt" is the location that the Linux kernel
  360. // expects to find the device tree, and it is at least a few mega-bytes
  361. // free. The merged device tree is therefore copied to that space.
  362. memcpy(g_fdt, merged_fdt, merged_size);
  363. // Make the totalsize of the device tree larger so that properties can
  364. // be inserted into the device tree.
  365. ((struct fdt_header *)g_fdt)->totalsize = cpu_to_fdt32(DTB_MAX_SIZE);
  366. free(merged_fdt);
  367. free(overlay_buf);
  368. return TRUE;
  369. }
  370. /*******************************************************************
  371. * mmap fdt buffer and sanity check it before doing any operation
  372. ********************************************************************/
  373. bool setup_fdt(void *fdt, int size)
  374. {
  375. int ret;
  376. g_fdt = fdt;
  377. #ifdef MTK_3LEVEL_PAGETABLE
  378. u32 addr = (u32)fdt;
  379. arch_mmu_map((uint64_t)ROUNDDOWN(addr, PAGE_SIZE),
  380. (uint32_t)ROUNDDOWN(addr, PAGE_SIZE),
  381. MMU_MEMORY_TYPE_NORMAL_WRITE_BACK | MMU_MEMORY_AP_P_RW_U_NA,
  382. ROUNDUP(size, PAGE_SIZE));
  383. #endif
  384. ret = fdt_open_into(g_fdt, g_fdt, size); //DTB maximum size is 2MB
  385. if (ret) return FALSE;
  386. ret = fdt_check_header(g_fdt);
  387. if (ret) return FALSE;
  388. return TRUE;
  389. }
  390. /**************************************************************************
  391. * Load dtb from boot/recovery, does MMU map and relocate
  392. ***************************************************************************/
  393. int bldr_load_dtb_from_boot(char *part_name, u32 *dtb_final_addr, uint64_t *recovery_dtbo_offset)
  394. {
  395. int ret = 0;
  396. char *ptr;
  397. char *dtb_sz;
  398. u32 zimage_addr, zimage_size, dtb_size, addr, tmp;
  399. u32 dtb_addr = 0;
  400. u32 offset = 0;
  401. unsigned char *magic;
  402. struct bootimg_hdr *p_boot_hdr;
  403. ptr = malloc(DTB_MAX_SIZE);
  404. if (ptr == NULL) {
  405. pal_log_err("dtb malloc failed!\n");
  406. return -1;
  407. }
  408. //load boot hdr
  409. ret = mboot_recovery_load_raw_part(part_name, (unsigned long *)ptr,
  410. sizeof(struct bootimg_hdr) + 0x800);
  411. if (ret < 0) {
  412. pal_log_err("mboot_recovery_load_raw_part(%s, %d) failed, ret: 0x%x\n",
  413. part_name, sizeof(struct bootimg_hdr) + 0x800, ret);
  414. goto _end;
  415. }
  416. if (0 == bootimg_hdr_valid((uint8_t *)ptr)) {
  417. pal_log_err("bootimg_hdr_valid failed\n");
  418. ret = -1;
  419. goto _end;
  420. }
  421. p_boot_hdr = (void *)ptr;
  422. *dtb_final_addr = p_boot_hdr->tags_addr;
  423. /* Under recovery, get dtbo info from bootimg hdr version 1 */
  424. if (!strcmp(part_name, "recovery")) {
  425. if (p_boot_hdr->header_version >= BOOT_HEADER_VERSION_ONE) {
  426. *recovery_dtbo_offset = (uint64_t)p_boot_hdr->recovery_dtbo_offset;
  427. pal_log_err("bldr_load_dtb: recovery_dtbo_offset = 0x%llx\n", (uint64_t)*recovery_dtbo_offset);
  428. /* If offset is 0, implies dtbo in its standalone partition */
  429. /* In that case, recovery is not self-sufficient */
  430. if (*recovery_dtbo_offset == 0)
  431. pal_log_err("Warning: check recovery dtbo location!\n");
  432. }
  433. }
  434. /* Claim the DT/kernel/ramdisk addr from mblock */
  435. mboot_allocate_bootimg_from_mblock(p_boot_hdr);
  436. /* decide whether this is 64bit kernel from cmdline */
  437. platform_parse_bootopt(p_boot_hdr->cmdline);
  438. if (p_boot_hdr->header_version >= BOOT_HEADER_VERSION_TWO) {
  439. dtb_size = p_boot_hdr->dtb_size;
  440. tmp = p_boot_hdr->page_sz
  441. + ROUNDUP(p_boot_hdr->kernel_sz, p_boot_hdr->page_sz)
  442. + ROUNDUP(p_boot_hdr->ramdisk_sz, p_boot_hdr->page_sz)
  443. + ROUNDUP(p_boot_hdr->second_sz, p_boot_hdr->page_sz)
  444. + ROUNDUP(p_boot_hdr->recovery_dtbo_size, p_boot_hdr->page_sz);
  445. if (dtb_size == 0) {
  446. pal_log_err("can't find v2 dtb\n");
  447. ret = -1;
  448. goto _end;
  449. }
  450. ret = partition_read(part_name, (off_t)tmp, (u8 *)ptr,
  451. (size_t)ROUNDUP(dtb_size, p_boot_hdr->page_sz));
  452. if (ret < 0) {
  453. pal_log_err("partition_read for v2 dtb failed, ret: 0x%x\n", ret);
  454. goto _end;
  455. }
  456. /* Check dtb format comes with mkdtimg (table_header+table_entry+fdt_body) */
  457. if (DT_TABLE_MAGIC == fdt_magic(ptr))
  458. {
  459. struct dt_table_header *hdr = (struct dt_table_header *)ptr;
  460. uint32_t dt_entry_count = fdt32_to_cpu(hdr->dt_entry_count);
  461. dtb_addr = (u32)ptr + sizeof(struct dt_table_header)
  462. + dt_entry_count * sizeof(struct dt_table_entry);
  463. pal_log_err("find v2 dtb with mkdtimg format, dtb file offset: 0x%x\n", tmp);
  464. }
  465. else if (FDT_MAGIC == fdt_magic(ptr))
  466. {
  467. dtb_addr = (u32)ptr;
  468. pal_log_err("find v2 dtb with fdt format only, dtb file offset: 0x%x\n", tmp);
  469. }
  470. goto _dt_relocate;
  471. }
  472. if (!g_is_64bit_kernel) {
  473. //Offset into zImage Value Description
  474. //0x24 0x016F2818 Magic number used to identify this is an ARM Linux zImage
  475. //0x28 start address The address the zImage starts at
  476. //0x2C end address The address the zImage ends at
  477. /* bootimg header size is 0x800, the kernel img text is next to the header */
  478. zimage_addr = (u32)ptr + p_boot_hdr->page_sz;
  479. if (*(unsigned int *)((unsigned int)zimage_addr) == MKIMG_MAGIC) {
  480. zimage_addr += MKIMG_HDR_SZ;
  481. offset += MKIMG_HDR_SZ;
  482. }
  483. zimage_size = *(unsigned int *)((unsigned int)zimage_addr + 0x2c) -
  484. *(unsigned int *)((unsigned int)zimage_addr + 0x28);
  485. //dtb_addr = (unsigned int)zimage_addr + zimage_size;
  486. offset += (p_boot_hdr->page_sz + zimage_size);
  487. tmp = ROUNDDOWN(offset, p_boot_hdr->page_sz);
  488. ret = partition_read(part_name, (off_t)tmp, (u8 *)ptr, (size_t)DTB_MAX_SIZE);
  489. if (ret < 0) {
  490. pal_log_err("partition_read failed, ret: 0x%x\n", ret);
  491. goto _end;
  492. }
  493. dtb_addr = (u32)ptr + offset - tmp;
  494. dtb_size = fdt32_to_cpu(*(unsigned int *)(ptr + (offset - tmp) + 0x4));
  495. } else {
  496. /* bootimg header size is 0x800, the kernel img text is next to the header */
  497. int i;
  498. zimage_size = p_boot_hdr->kernel_sz;
  499. offset = p_boot_hdr->page_sz + p_boot_hdr->kernel_sz - DTB_MAX_SIZE;
  500. tmp = ROUNDUP(offset, p_boot_hdr->page_sz);
  501. ret = partition_read(part_name, (off_t)tmp, (u8 *)ptr, (size_t)DTB_MAX_SIZE);
  502. if (ret < 0) {
  503. pal_log_err("partition_read failed, ret: 0x%x\n", ret);
  504. goto _end;
  505. }
  506. dtb_addr = 0;
  507. dtb_size = 0;
  508. addr = (u32)ptr + DTB_MAX_SIZE - 4;
  509. for (i = 0; i < (DTB_MAX_SIZE - 4); i++, addr--) {
  510. //FDT_MAGIC 0xd00dfeed
  511. //dtb append after image.gz may not 4 byte alignment
  512. magic = (unsigned char *)addr;
  513. if (*(magic + 3) == 0xED && *(magic + 2) == 0xFE &&
  514. *(magic + 1) == 0x0D && *(magic + 0) == 0xD0) {
  515. dtb_addr = addr;
  516. break;
  517. }
  518. }
  519. if (dtb_addr == 0) {
  520. pal_log_err("can't find dtb\n");
  521. ret = -1;
  522. goto _end;
  523. }
  524. dtb_sz = (char *)(dtb_addr + 4);
  525. dtb_size = *(dtb_sz) * 0x1000000 + *(dtb_sz + 1) * 0x10000 +
  526. *(dtb_sz + 2) * 0x100 + *(dtb_sz + 3);
  527. g_64bit_dtb_size = dtb_size;
  528. pal_log_err("Kernel(%d) zimage_size:0x%x,dtb_addr:0x%x(dtb_size:0x%x)\n",
  529. g_is_64bit_kernel, zimage_size, dtb_addr, dtb_size);
  530. }
  531. _dt_relocate:
  532. if (dtb_size > DTB_MAX_SIZE) {
  533. pal_log_err("dtb_size too large: 0x%x\n", dtb_size);
  534. ret = -1;
  535. goto _end;
  536. }
  537. #ifdef MTK_3LEVEL_PAGETABLE
  538. arch_mmu_map((uint64_t)ROUNDDOWN(*dtb_final_addr, PAGE_SIZE),
  539. (uint32_t)ROUNDDOWN(*dtb_final_addr, PAGE_SIZE),
  540. MMU_MEMORY_TYPE_NORMAL_WRITE_BACK | MMU_MEMORY_AP_P_RW_U_NA,
  541. ROUNDUP(dtb_size, PAGE_SIZE));
  542. #endif
  543. pal_log_err("Copy DTB from 0x%x to 0x%x(size: 0x%x)\n", dtb_addr,
  544. *dtb_final_addr, dtb_size);
  545. memcpy((void *)*dtb_final_addr, (void *)dtb_addr, dtb_size);
  546. _end:
  547. free(ptr);
  548. return ret;
  549. }
  550. /**************************************************************************
  551. * Please refer to bootimg.h for boot image header structure.
  552. * bootimg header size is 0x800, the kernel img text is next to the header
  553. ***************************************************************************/
  554. int bldr_load_dtb(char *boot_load_partition)
  555. {
  556. int ret = 0;
  557. u32 dtb_final_addr;
  558. char part_name[16];
  559. uint64_t recovery_dtbo_offset = 0;
  560. #ifdef MTK_AB_OTA_UPDATER
  561. /* no more recovery partition in A/B system update, instead choose boot_a or boot_b */
  562. snprintf(part_name, sizeof(part_name), "boot%s", p_AB_suffix);
  563. #else
  564. snprintf(part_name, sizeof(part_name), "%s", boot_load_partition);
  565. #endif
  566. /* load dtb from boot */
  567. ret = bldr_load_dtb_from_boot(part_name, &dtb_final_addr, &recovery_dtbo_offset);
  568. if (ret < 0)
  569. return ret;
  570. // Place setup_fdt() after bldr_load_dtb() because it sets "fdt_header->totalsize".
  571. ret = setup_fdt((void *)dtb_final_addr, DTB_MAX_SIZE);
  572. pal_log_err("[LK] fdt setup addr:0x%x status:%d!!!\n", dtb_final_addr, ret);
  573. if (ret == FALSE) {
  574. pal_log_err("setup_fdt fail, ret: 0x%x!\n", ret);
  575. ret = -1;
  576. }
  577. /* load odmdtbo and overlay */
  578. ret = dtb_overlay(g_fdt, DTB_MAX_SIZE, (uint64_t)recovery_dtbo_offset);
  579. if (ret == TRUE) {
  580. if (!strcmp(part_name, "recovery")) {
  581. set_recovery_dtbo_loaded();
  582. pal_log_err("dtb_overlay for recovery done !\n");
  583. }
  584. }
  585. /* command line buffer init */
  586. bootargs_init(g_fdt);
  587. return ret;
  588. }
  589. #else /* LK_MAIN_DTB_BUILT_IN */
  590. #define DT_TBL_HDR_SIZE (sizeof(struct dt_table_header))
  591. int32_t load_dtbo_buffer(void **dtbo_ptr, uint32_t *dtbo_size)
  592. {
  593. void *dtbo_buffer = NULL;
  594. struct dt_table_header *dt_tbl_hdr_buffer = NULL;
  595. size_t pre_read_dt_tbl_hdr_size = DT_TBL_HDR_SIZE;
  596. size_t dtbo_total_len;
  597. void *dtbo_total_buffer = NULL;
  598. void *selected_dtbo_body_ptr;
  599. ssize_t len;
  600. int32_t ret = 0;
  601. uint32_t dtbo_offset;
  602. uint32_t dtbo_entry_idx;
  603. uint32_t _dtbo_size;
  604. char *dtbo_from_part_name = get_dtbo_part_name();
  605. #ifdef MTK_SECURITY_SW_SUPPORT
  606. uint32_t sec_ret;
  607. uint32_t vfy_time;
  608. unsigned int policy_entry_idx = 0;
  609. unsigned int img_auth_required = 0;
  610. char *img_name = "dtbo";
  611. policy_entry_idx = get_policy_entry_idx(dtbo_from_part_name);
  612. img_auth_required = get_vfy_policy(policy_entry_idx);
  613. /* verify cert chain of boot img */
  614. if (img_auth_required) {
  615. vfy_time = get_timer(0);
  616. sec_ret = sec_img_auth_init(dtbo_from_part_name, img_name, 0);
  617. if (sec_ret) {
  618. ret = -1;
  619. goto end;
  620. }
  621. dprintf(CRITICAL, "[SBC] image %s cert vfy pass(%d ms)\n", img_name, (unsigned int)get_timer(vfy_time));
  622. #ifdef MTK_SECURITY_ANTI_ROLLBACK
  623. sec_ret = sec_rollback_check(1);
  624. if (sec_ret) {
  625. dprintf(CRITICAL, "[SBC] image %s ver check fail...(0x%x)\n", img_name, sec_ret);
  626. ret = -1;
  627. goto end;
  628. }
  629. #endif
  630. }
  631. #endif
  632. dt_tbl_hdr_buffer = (struct dt_table_header *)malloc(pre_read_dt_tbl_hdr_size);
  633. if (dt_tbl_hdr_buffer == NULL) {
  634. ret = -ENOMEM;
  635. goto end;
  636. }
  637. /* init dt_tbl_hdr_buffer */
  638. memset(dt_tbl_hdr_buffer, 0x0, pre_read_dt_tbl_hdr_size);
  639. len = partition_read(dtbo_from_part_name, (off_t)0, (uint8_t *)dt_tbl_hdr_buffer, pre_read_dt_tbl_hdr_size);
  640. if (len < 0) {
  641. ret = len;
  642. goto end;
  643. }
  644. if (fdt32_to_cpu(dt_tbl_hdr_buffer->magic) != DT_TABLE_MAGIC) {
  645. pal_log_err("dt_table_header magic is not correct:0x%x\n",
  646. fdt32_to_cpu(dt_tbl_hdr_buffer->magic));
  647. ret = -EINVAL;
  648. goto end;
  649. }
  650. dtbo_total_len = fdt32_to_cpu(dt_tbl_hdr_buffer->total_size);
  651. if (dtbo_total_len > DTB_MAX_SIZE) {
  652. ret = -1;
  653. goto end;
  654. }
  655. dtbo_total_buffer = malloc(dtbo_total_len);
  656. if (dtbo_total_buffer == NULL){
  657. ret = -ENOMEM;
  658. goto end;
  659. }
  660. len = partition_read(dtbo_from_part_name, (off_t)0, (uint8_t *)dtbo_total_buffer, dtbo_total_len);
  661. if (len < 0) {
  662. ret = len;
  663. goto end;
  664. }
  665. #ifdef MTK_SECURITY_SW_SUPPORT
  666. if (img_auth_required) {
  667. vfy_time = get_timer(0);
  668. sec_ret = sec_img_auth((uint8_t *)(dtbo_total_buffer + pre_read_dt_tbl_hdr_size), (len - pre_read_dt_tbl_hdr_size));
  669. if (sec_ret) {
  670. dprintf(CRITICAL, "[SBC] %s vfy fail(%d ms)\n", img_name, (unsigned int)get_timer(vfy_time));
  671. ret = -2;
  672. goto end;
  673. }
  674. dprintf(CRITICAL, "[SBC] %s vfy pass(%d ms)\n", img_name, (unsigned int)get_timer(vfy_time));
  675. }
  676. #endif
  677. /* select dtbo via HW index */
  678. ret = parse_dtbo_tbl((struct dt_table_header *)dtbo_total_buffer, (uint32_t)get_odm_mdtbo_index(),
  679. &dtbo_entry_idx,
  680. (uint32_t *)&_dtbo_size, (uint32_t *)&dtbo_offset);
  681. if(ret < 0) {
  682. goto end;
  683. }
  684. if (_dtbo_size > DTB_MAX_SIZE) {
  685. ret = -EPERM;
  686. goto end;
  687. }
  688. *dtbo_size = _dtbo_size;
  689. set_dtbo_index(dtbo_entry_idx);
  690. dtbo_buffer = malloc(_dtbo_size);
  691. if (dtbo_buffer == NULL){
  692. ret = -ENOMEM;
  693. goto end;
  694. }
  695. selected_dtbo_body_ptr = dtbo_total_buffer + dtbo_offset;
  696. memcpy(dtbo_buffer, selected_dtbo_body_ptr, _dtbo_size);
  697. *dtbo_ptr = dtbo_buffer;
  698. end:
  699. if (dtbo_total_buffer)
  700. free(dtbo_total_buffer);
  701. if (dt_tbl_hdr_buffer)
  702. free(dt_tbl_hdr_buffer);
  703. /* fail case */
  704. if (ret != 0) {
  705. if (dtbo_buffer)
  706. free(dtbo_buffer);
  707. *dtbo_ptr = NULL;
  708. }
  709. return ret;
  710. }
  711. int32_t prepare_kernel_dtb(void)
  712. {
  713. int ret_overlay;
  714. uint32_t ret = 0;
  715. void *overlayed_dtb = NULL;
  716. void *dtbo = NULL;
  717. uint32_t dtbo_size = get_dtbo_img_size();
  718. uint32_t overlayed_dtb_size = 0;
  719. /*
  720. * dtbo address may not native pointer alignment,
  721. * which will cause unalignment fault.
  722. */
  723. if (!IS_ALIGNED(get_dtbo_load_addr(), sizeof(void *))) {
  724. dtbo = malloc(dtbo_size);
  725. if (dtbo == NULL) {
  726. pal_log_err("Fail to malloc %s dtbo\n", __func__);
  727. ret = -1;
  728. goto end;
  729. }
  730. memcpy(dtbo, (void *)get_dtbo_load_addr(), dtbo_size);
  731. }
  732. /* overlay dtbo with main dtb */
  733. ret_overlay = dtb_overlay((void *)get_main_dtb_load_addr(),
  734. get_main_dtb_size(),
  735. dtbo ? dtbo : (void *)get_dtbo_load_addr(),
  736. dtbo_size,
  737. &overlayed_dtb, DTB_MAX_SIZE);
  738. if (ret_overlay == 0) {
  739. if (overlayed_dtb != NULL) {
  740. overlayed_dtb_size = fdt_totalsize(overlayed_dtb);
  741. if (overlayed_dtb_size > DTB_MAX_SIZE) {
  742. pal_log_err("fdt_totalsize(overlayed_dtb):%u is too large!\n", overlayed_dtb_size);
  743. ret = -1;
  744. goto end;
  745. }
  746. memcpy(get_kernel_fdt(), overlayed_dtb, overlayed_dtb_size);
  747. /* enlarge kernel's fdt for further property setting */
  748. fdt_set_totalsize(get_kernel_fdt(), DTB_MAX_SIZE);
  749. } else {
  750. ret = -1;
  751. pal_log_err("overlayed_dtb is NULL");
  752. }
  753. } else {
  754. pal_log_err("boot image dtb_overlay fail");
  755. ret = -2;
  756. }
  757. end:
  758. if (dtbo)
  759. free(dtbo);
  760. if (overlayed_dtb)
  761. free(overlayed_dtb);
  762. return ret;
  763. }
  764. int32_t dtb_overlay(void *main_dtb_addr, uint32_t main_dtb_size,
  765. void *dtbo_addr, uint32_t dtbo_size,
  766. void **merged_dtb, uint32_t merged_max_size)
  767. {
  768. int ret;
  769. struct fdt_header *blob;
  770. struct fdt_header *merged_fdt;
  771. PAL_ASSERT(main_dtb_addr);
  772. PAL_ASSERT(main_dtb_size);
  773. PAL_ASSERT(dtbo_addr);
  774. PAL_ASSERT(dtbo_size);
  775. PAL_ASSERT(merged_dtb);
  776. if (merged_max_size < (main_dtb_size + dtbo_size)) {
  777. pal_log_err("merged_max_size:%u, main_dtb_size + dtbo_size:%u\n",
  778. merged_max_size, main_dtb_size + dtbo_size);
  779. return -EINVAL;
  780. }
  781. ret = fdt_open_into(main_dtb_addr, main_dtb_addr, main_dtb_size);
  782. if (ret < 0) {
  783. pal_log_err("fdt_open_into failed \n");
  784. return ret;
  785. }
  786. blob = ufdt_install_blob(main_dtb_addr, main_dtb_size);
  787. if (blob == NULL) {
  788. pal_log_err("ufdt_install_blob() failed!\n");
  789. return -1;
  790. }
  791. merged_fdt = ufdt_apply_overlay(blob, main_dtb_size, dtbo_addr, dtbo_size);
  792. if (merged_fdt == NULL) {
  793. pal_log_err("ufdt_apply_overlay() failed!\n");
  794. return -1;
  795. }
  796. /*
  797. * Compact the merged device tree so that the size of the device tree can
  798. * be known.
  799. */
  800. ret = fdt_pack((void *)merged_fdt);
  801. if (ret < 0) {
  802. pal_log_err("fdt_pack(merged_fdt) failed !\n");
  803. if (merged_fdt)
  804. free(merged_fdt);
  805. return -1;
  806. }
  807. *merged_dtb = (void *)merged_fdt;
  808. return ret;
  809. }
  810. #endif
  811. /**************************************************************************************
  812. * Main device tree loading function, considering loading accordingly from different boot mode
  813. ***************************************************************************************/
  814. void load_device_tree(void)
  815. {
  816. #ifndef LK_MAIN_DTB_BUILT_IN
  817. PROFILING_START("early load dtb");
  818. char *part_name = "boot";
  819. /* If RECOVERY_AS_BOOT is enabled, there is no recovery partition. */
  820. #if !defined(NO_BOOT_MODE_SEL) && !defined(RECOVERY_AS_BOOT)
  821. if (Check_RTC_Recovery_Mode() || unshield_recovery_detection())
  822. part_name = "recovery";
  823. else
  824. part_name = "boot";
  825. #endif
  826. #if defined(CFG_DTB_EARLY_LOADER_SUPPORT)
  827. if (bldr_load_dtb(part_name) < 0)
  828. dprintf(CRITICAL, "Error: %s failed\n", __func__);
  829. #endif
  830. PROFILING_END();
  831. #else /* LK_MAIN_DTB_BUILT_IN */
  832. lk_dtb_init();
  833. #endif
  834. }
  835. int32_t parse_dtbo_tbl(struct dt_table_header *dt_tbl_hdr_buffer,
  836. uint32_t hw_board_idx, uint32_t *dtbo_entry_idx_out,
  837. uint32_t *dtbo_size, uint32_t *dtbo_offset)
  838. {
  839. struct dt_table_entry *dt_entry_head;
  840. struct dt_table_entry *dt_entry_selected;
  841. uint32_t dt_entry_cnt;
  842. uint32_t dtbo_entry_idx;
  843. assert(dt_tbl_hdr_buffer);
  844. assert(dtbo_entry_idx_out);
  845. assert(dtbo_size);
  846. assert(dtbo_offset);
  847. /* sanity check */
  848. if (fdt32_to_cpu(dt_tbl_hdr_buffer->magic) != DT_TABLE_MAGIC) {
  849. pal_log_err("dt_table_header magic is not correct:0x%x\n",
  850. fdt_magic(dt_tbl_hdr_buffer));
  851. return -EINVAL;
  852. }
  853. dt_entry_cnt = fdt32_to_cpu(dt_tbl_hdr_buffer->dt_entry_count);
  854. if (dt_entry_cnt > DTBO_ENTRY_CNT_MAX) {
  855. pal_log_err("dt_entry_cnt is out of bound: %u, max:%u\n", dt_entry_cnt, DTBO_ENTRY_CNT_MAX);
  856. return -EINVAL;
  857. }
  858. dt_entry_head = (struct dt_table_entry *)(dt_tbl_hdr_buffer + 1);
  859. /*
  860. * traverse dt_table_entry list, compare
  861. * dt_table_entry->id with hw_board_idx
  862. */
  863. for(dtbo_entry_idx = 0; dtbo_entry_idx < dt_entry_cnt ; dtbo_entry_idx++) {
  864. if (hw_board_idx == fdt32_to_cpu((dt_entry_head + dtbo_entry_idx)->id)) {
  865. break;
  866. }
  867. }
  868. /* traverse end */
  869. if (dtbo_entry_idx >= dt_entry_cnt) {
  870. dprintf(CRITICAL, "Error: dtbo_entry_idx %d >= num_of_dtbo %d.\n",
  871. dtbo_entry_idx, dt_entry_cnt);
  872. dprintf(CRITICAL, "Set dtbo_entry_idx to 0 for error handling!\n");
  873. dtbo_entry_idx = 0;
  874. }
  875. *dtbo_entry_idx_out = dtbo_entry_idx;
  876. dt_entry_selected = dt_entry_head + dtbo_entry_idx;
  877. *dtbo_size = fdt32_to_cpu(dt_entry_selected->dt_size);
  878. *dtbo_offset = fdt32_to_cpu(dt_entry_selected->dt_offset);
  879. return 0;
  880. }