mt_dpm.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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 <stdlib.h> /* for atoi() */
  32. #include <stdint.h>
  33. #include <string.h>
  34. #include <debug.h>
  35. #include <platform/mt_gpt.h> // for get_timer()
  36. #include <arch/ops.h> // for arch_sync_cache_range()
  37. #include <platform/boot_mode.h>
  38. #include <platform/verified_boot.h>
  39. #include <verified_boot_common.h>
  40. #include <platform/sec_policy.h>
  41. #include <part_interface.h>
  42. #include <env.h>
  43. #include <platform/mt_reg_base.h>
  44. #include <assert.h>
  45. #include <platform/mt_dpm.h>
  46. #include <platform/errno.h>
  47. #ifdef MTK_AB_OTA_UPDATER
  48. #include "bootctrl.h"
  49. #endif
  50. extern void dsb(void);
  51. extern int mboot_common_load_part(char *part_name, char *img_name, unsigned long addr);
  52. static int verify_load_DPM_image(char *part_name, void *addr);
  53. extern BOOT_ARGUMENT *g_boot_arg;
  54. static void *dpm_dram_addr;
  55. static char *dpm_part_name[] = {"dpm_1", "dpm_2"};
  56. static int load_DPM_image(char *part_name, char *img_name, void *addr)
  57. {
  58. uint32_t sec_ret;
  59. uint32_t DPM_vfy_time;
  60. int ret;
  61. #ifdef MTK_SECURITY_SW_SUPPORT
  62. unsigned int policy_entry_idx = 0;
  63. unsigned int img_auth_required = 0;
  64. policy_entry_idx = get_policy_entry_idx(part_name);
  65. img_auth_required = get_vfy_policy(policy_entry_idx);
  66. /* verify cert chain of boot img */
  67. if (img_auth_required) {
  68. DPM_vfy_time = get_timer(0);
  69. sec_ret = sec_img_auth_init(part_name, img_name, 0);
  70. if (sec_ret)
  71. return -1; //if user load call assert, if eng load, pass the information to kernel, and then trigger a kernel api dump
  72. dprintf(CRITICAL, "[SBC] image %s cert vfy pass(%d ms)\n", img_name, (unsigned int)get_timer(DPM_vfy_time));
  73. #ifdef MTK_SECURITY_ANTI_ROLLBACK
  74. sec_ret = sec_rollback_check(1);
  75. if (sec_ret) {
  76. dprintf(CRITICAL, "%s ver check fail...(0x%x)\n", img_name, sec_ret);
  77. return -1; //if user load call assert, if eng load, pass the information to kernel, and then trigger a kernel api dump
  78. }
  79. #endif
  80. }
  81. #endif
  82. ret = mboot_common_load_part(part_name, img_name, (unsigned long)addr);
  83. dprintf(INFO, "%s(): load %s ret=%d\n", __func__, img_name, ret);
  84. if (ret <= 0)
  85. return -1; //if user load call assert, if eng load, pass the information to kernel, and then trigger a kernel api dump
  86. /* Sync cache to make sure all data flush to DRAM */
  87. //arch_sync_cache_range((addr_t)addr, DPM_DRAM_SIZE);
  88. #ifdef MTK_SECURITY_SW_SUPPORT
  89. if (img_auth_required) {
  90. DPM_vfy_time = get_timer(0);
  91. sec_ret = sec_img_auth(addr, ret);
  92. if (sec_ret)
  93. return -1; //if user load call assert, if eng load, pass the information to kernel, and then trigger a kernel api dump
  94. dprintf(CRITICAL, "[SBC] %s vfy pass(%d ms)\n", img_name, (unsigned int)get_timer(DPM_vfy_time));
  95. }
  96. #endif
  97. return ret;
  98. }
  99. static char *dpm_partition_name(void)
  100. {
  101. int array_size = (int)(sizeof(dpm_part_name) / sizeof(dpm_part_name[0]));
  102. int i;
  103. for (i = 0; i < array_size; i++) {
  104. /*
  105. * >0: partition active
  106. * 0: partition inactive
  107. * -1: partition doesn't exist
  108. */
  109. if (partition_get_active_bit_by_name(dpm_part_name[i]) > 0)
  110. return dpm_part_name[i];
  111. }
  112. dprintf(CRITICAL, "no DPM partition with active bit marked, load %s\n", dpm_part_name[0]);
  113. return dpm_part_name[0];
  114. }
  115. /******************************************************************************
  116. ******************************************************************************/
  117. int load_dpm(void)
  118. {
  119. int ret;
  120. #ifdef MTK_AB_OTA_UPDATER
  121. #define DPM_PARTITION_NAME_SIZE 10
  122. char part_name[DPM_PARTITION_NAME_SIZE];
  123. #else
  124. char *part_name;
  125. #endif
  126. dpm_dram_addr = (void *)(unsigned int)mblock_reserve_ext(&g_boot_arg->mblock_info,
  127. DPM_DRAM_SIZE, DPM_DRAM_SIZE, DRAM_ADDR_MAX, 0, "DPM-reserved");
  128. dprintf(INFO, "[DPM] %s: dpm_dram_addr=%p\n", __func__, dpm_dram_addr);
  129. if (dpm_dram_addr == ((void *) 0)) {
  130. dprintf(CRITICAL, "[DPM] mblock_reserve fail\n");
  131. //if user load call assert, if eng load, pass the information to kernel, and then trigger a kernel api dump
  132. return -1;
  133. }
  134. #ifdef MTK_AB_OTA_UPDATER
  135. /* Compose the partition name for A/B systems. */
  136. strcpy (part_name,"dpm");
  137. char *p_AB_suffix;
  138. int part_name_len = strlen(part_name);
  139. p_AB_suffix = get_suffix();
  140. if (p_AB_suffix) {
  141. strncpy((void*)&part_name[part_name_len], (void*)p_AB_suffix,
  142. sizeof(part_name) - part_name_len);
  143. }
  144. part_name[sizeof(part_name) - 1] = '\0';
  145. #else
  146. part_name = dpm_partition_name();
  147. #endif /* MTK_AB_OTA_UPDATER*/
  148. if (!part_name) {
  149. dprintf(CRITICAL, "[DPM]get partition failed\n");
  150. //if user load call assert, if eng load, pass the information to kernel, and then trigger a kernel api dump
  151. return -1;
  152. }
  153. ret = verify_load_DPM_image(part_name, dpm_dram_addr);
  154. if (ret < 0) {
  155. //if user load call assert, if eng load, pass the information to kernel, and then trigger a kernel api dump
  156. return -1;
  157. }
  158. dprintf(INFO, "%s(): done\n", __func__);
  159. return 0;
  160. }
  161. static int verify_load_DPM_image(char *part_name, void *addr)
  162. {
  163. void *pm_ptr, *dm_ptr;
  164. int pm_size, dm_size;
  165. // step 1: load/verify pm
  166. pm_ptr = addr;
  167. pm_size = load_DPM_image(part_name, DPM_PM, pm_ptr);
  168. if (pm_size <= 0) {
  169. dprintf(CRITICAL, "[DPM] load_DPM_image fail %s\n", DPM_PM);
  170. return -1;
  171. }
  172. // step 2: load/verify dm
  173. dm_ptr = addr + DPM_DM_OFFSET;
  174. dm_size = load_DPM_image(part_name, DPM_DM, dm_ptr);
  175. if (dm_size <= 0) {
  176. dprintf(CRITICAL, "[DPM] load_DPM_image fail %s\n", DPM_DM);
  177. return -1;
  178. }
  179. //config DPM SRAM layout
  180. dprintf(INFO, "[DPM] %s: pm_ptr=%p pm_size=%d dm_ptr=%p dm_size=%d\n", __func__, pm_ptr, pm_size, dm_ptr, dm_size);
  181. if (pm_size > 0x6000) { //pm > 24K
  182. //bigger than sram size
  183. return -1;
  184. }
  185. else if (pm_size > 0x4000) { //pm > 16K
  186. //DRV_WriteReg32(DPM_CFG_CH0, DRV_Reg32(DPM_CFG_CH0)|0x0);
  187. }
  188. else if (pm_size > 0x2000) { //pm > 8K
  189. DRV_WriteReg32(DPM_CFG_CH0, DRV_Reg32(DPM_CFG_CH0)|0x10000000);
  190. }
  191. else { //pm < 8K
  192. DRV_WriteReg32(DPM_CFG_CH0, DRV_Reg32(DPM_CFG_CH0)|0x20000000);
  193. }
  194. // DPM DRAM layout
  195. /***********************
  196. * PM: 24/16/8 *
  197. ************************
  198. * DM *
  199. ************************/
  200. // step 6: copy PM to DPM_SRAM
  201. memcpy((void *) DPM_PM1_SRAM_BASE, pm_ptr, pm_size);
  202. memcpy((void *) DPM_DM1_SRAM_BASE, dm_ptr, dm_size);
  203. // step 7: write bootargs
  204. DRV_WriteReg32(DPM_BARGS_CH0_REG0, 0x00000000);
  205. DRV_WriteReg32(DPM_BARGS_CH0_REG1, 0x00000000);
  206. dsb();
  207. //RST of CH0
  208. DRV_WriteReg32(DPM_CFG_CH0, DRV_Reg32(DPM_CFG_CH0)|0x1);
  209. return 0;
  210. }