fdt_op.c 30 KB

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