ccci_lk_load_img_plat.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105
  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 <sys/types.h>
  32. #include <stdint.h>
  33. #include <platform/partition.h>
  34. #include <platform/mt_typedefs.h>
  35. #include <platform/boot_mode.h>
  36. #include <platform/mt_reg_base.h>
  37. #include <platform/errno.h>
  38. #include <printf.h>
  39. #include <string.h>
  40. #include <malloc.h>
  41. #include <libfdt.h>
  42. #include <platform/mt_gpt.h>
  43. #include <platform/emi_mpu.h>
  44. #include <debug.h>
  45. #include <assert.h>
  46. #include <mt_boot.h>
  47. #define MODULE_NAME "LK_LD_MD"
  48. #include "ccci_ld_md_core.h"
  49. #include "ccci_ld_md_errno.h"
  50. #define CCCI_SMEM_SIZE_LWA (0) // (8*1024*1024)
  51. #define CCCI_SMEM_SIZE_PHY_C_L0 (0*1024*1024)
  52. #define CCCI_SMEM_SIZE_PHY_C_L1 (32*1024*1024)
  53. #define CCCI_SMEM_SIZE_PHY_C_L2 (64*1024*1024)
  54. #define CCCI_SMEM_SIZE_PHY_C_L3 (128*1024*1024)
  55. #define CCCI_SMEM_SIZE_PHY_C_L4 (222*1024*1024)
  56. #define CCB_DATA_BUF_DEFAULT_GEAR 2 /* NOTE: This value may be different at different platform */
  57. /***************************************************************************************************
  58. ** Feature Option setting part
  59. ***************************************************************************************************/
  60. #define ENABLE_EMI_PROTECTION
  61. /***************************************************************************************************
  62. ** HW remap section
  63. ***************************************************************************************************/
  64. extern unsigned int ddr_enable_4gb(void)__attribute__((weak));
  65. static int is_4gb_ddr_support_en(void)
  66. {
  67. int ret;
  68. if (ddr_enable_4gb) {
  69. ret = ddr_enable_4gb();
  70. ALWAYS_LOG("ddr_enable_4GB sta:%d\n", ret);
  71. return ret;
  72. } else {
  73. ALWAYS_LOG("ddr 4GB disable\n");
  74. return 0;
  75. }
  76. }
  77. /*-------- Register base part -------------------------------*/
  78. /* HW remap for MD1 */
  79. #define INFRA_AO_BASE (0x10001000)
  80. /* -- MD1 Bank 0 */
  81. #define MD1_BANK0_MAP0 (INFRA_AO_BASE + 0x300)
  82. #define MD1_BANK0_MAP1 (INFRA_AO_BASE + 0x304)
  83. #define MD1_BANK0_MAP2 (INFRA_AO_BASE + 0x308)
  84. #define MD1_BANK0_MAP3 (INFRA_AO_BASE + 0x30C)
  85. /* -- MD1 Bank 1 */
  86. #define MD1_BANK1_MAP0 (INFRA_AO_BASE + 0x310)
  87. #define MD1_BANK1_MAP1 (INFRA_AO_BASE + 0x314)
  88. #define MD1_BANK1_MAP2 (INFRA_AO_BASE + 0x318)
  89. #define MD1_BANK1_MAP3 (INFRA_AO_BASE + 0x31C)
  90. /* -- MD1 Bank 4 */
  91. #define MD1_BANK4_MAP0 (INFRA_AO_BASE + 0x320)
  92. #define MD1_BANK4_MAP1 (INFRA_AO_BASE + 0x324)
  93. #define MD1_BANK4_MAP2 (INFRA_AO_BASE + 0x328)
  94. #define MD1_BANK4_MAP3 (INFRA_AO_BASE + 0x32C)
  95. /* HW remap lock register */
  96. #define MD_HW_REMAP_LOCK (INFRA_AO_BASE + 0xF80)
  97. #define MD1_LOCK (1<<16)
  98. static int md_mem_ro_rw_remapping(unsigned int md_id, unsigned long long addr)
  99. {
  100. unsigned long long md_img_start_addr;
  101. unsigned int hw_remapping_bank0_map0 = 0;
  102. unsigned int hw_remapping_bank0_map1 = 0;
  103. unsigned int hw_remapping_bank0_map2 = 0;
  104. unsigned int hw_remapping_bank0_map3 = 0;
  105. unsigned int write_val;
  106. switch (md_id) {
  107. case 0: // MD1
  108. hw_remapping_bank0_map0 = MD1_BANK0_MAP0;
  109. hw_remapping_bank0_map1 = MD1_BANK0_MAP1;
  110. hw_remapping_bank0_map2 = MD1_BANK0_MAP2;
  111. hw_remapping_bank0_map3 = MD1_BANK0_MAP3;
  112. break;
  113. default:
  114. ALWAYS_LOG("Invalid md id:%d\n", md_id);
  115. return -1;
  116. }
  117. md_img_start_addr = addr;
  118. ALWAYS_LOG("---> Map 0x00000000 to 0x%llx for MD%d\n", addr, md_id+1);
  119. /* For MDx_BANK0_MAP0 */
  120. write_val = (((md_img_start_addr >> 24) | 0x1) & 0x3FF)
  121. + ((((md_img_start_addr + 0x2000000*1) >> 8) | 1<<16) & 0x3FF0000);
  122. DRV_WriteReg32(hw_remapping_bank0_map0, write_val);
  123. ALWAYS_LOG("BANK0_MAP0 value:0x%X\n", DRV_Reg32(hw_remapping_bank0_map0));
  124. /* For MDx_BANK0_MAP1 */
  125. write_val = ((((md_img_start_addr + 0x2000000*2) >> 24) | 0x1) & 0x3FF)
  126. + ((((md_img_start_addr + 0x2000000*3) >> 8) | 1<<16) & 0x3FF0000);
  127. DRV_WriteReg32(hw_remapping_bank0_map1, write_val);
  128. ALWAYS_LOG("BANK0_MAP1 value:0x%X\n", DRV_Reg32(hw_remapping_bank0_map1));
  129. /* For MDx_BANK0_MAP2 */
  130. write_val = ((((md_img_start_addr + 0x2000000*4) >> 24) | 0x1) & 0x3FF)
  131. + ((((md_img_start_addr + 0x2000000*5) >> 8) | 1<<16) & 0x3FF0000);
  132. DRV_WriteReg32(hw_remapping_bank0_map2, write_val);
  133. ALWAYS_LOG("BANK0_MAP2 value:0x%X\n", DRV_Reg32(hw_remapping_bank0_map2));
  134. /* For MDx_BANK0_MAP3 */
  135. write_val = ((((md_img_start_addr + 0x2000000*6) >> 24) | 0x1) & 0x3FF)
  136. + ((((md_img_start_addr + 0x2000000*7) >> 8) | 1<<16) & 0x3FF0000);
  137. DRV_WriteReg32(hw_remapping_bank0_map3, write_val);
  138. ALWAYS_LOG("BANK0_MAP3 value:0x%X\n", DRV_Reg32(hw_remapping_bank0_map3));
  139. #ifdef DUMMY_AP_MODE
  140. /* For 256~512MB */
  141. if (md_id == MD_SYS1) {
  142. write_val = ((((md_img_start_addr + 0x2000000*8) >> 24) | 0x1) & 0x3FF)
  143. + ((((md_img_start_addr + 0x2000000*9) >> 8) | 1<<16) & 0x3FF0000);
  144. DRV_WriteReg32(MD1_BANK1_MAP0, write_val);
  145. ALWAYS_LOG("BANK1_MAP0 value:0x%X\n", DRV_Reg32(MD1_BANK1_MAP0));
  146. write_val = ((((md_img_start_addr + 0x2000000*10) >> 24) | 0x1) & 0x3FF)
  147. + ((((md_img_start_addr + 0x2000000*11) >> 8) | 1<<16) & 0x3FF0000);
  148. DRV_WriteReg32(MD1_BANK1_MAP1, write_val);
  149. ALWAYS_LOG("BANK1_MAP1 value:0x%X\n", DRV_Reg32(MD1_BANK1_MAP1));
  150. write_val = ((((md_img_start_addr + 0x2000000*12) >> 24) | 0x1) & 0x3FF)
  151. + ((((md_img_start_addr + 0x2000000*13) >> 8) | 1<<16) & 0x3FF0000);
  152. DRV_WriteReg32(MD1_BANK1_MAP2, write_val);
  153. ALWAYS_LOG("BANK1_MAP2 value:0x%X\n", DRV_Reg32(MD1_BANK1_MAP2));
  154. write_val = ((((md_img_start_addr + 0x2000000*14) >> 24) | 0x1) & 0x3FF)
  155. + ((((md_img_start_addr + 0x2000000*15) >> 8) | 1<<16) & 0x3FF0000);
  156. DRV_WriteReg32(MD1_BANK1_MAP3, write_val);
  157. ALWAYS_LOG("BANK1_MAP3 value:0x%X\n", DRV_Reg32(MD1_BANK1_MAP3));
  158. }
  159. #endif
  160. return 0;
  161. }
  162. static int md_bank4_remapping_by_slot(unsigned int md_id, unsigned long long addr, int slot)
  163. {
  164. unsigned int hw_remapping_bank4_map0 = 0;
  165. unsigned int hw_remapping_bank4_map1 = 0;
  166. unsigned int hw_remapping_bank4_map2 = 0;
  167. unsigned int hw_remapping_bank4_map3 = 0;
  168. unsigned int curr_val;
  169. switch (md_id) {
  170. case 0: // MD1
  171. hw_remapping_bank4_map0 = MD1_BANK4_MAP0;
  172. hw_remapping_bank4_map1 = MD1_BANK4_MAP1;
  173. hw_remapping_bank4_map2 = MD1_BANK4_MAP2;
  174. hw_remapping_bank4_map3 = MD1_BANK4_MAP3;
  175. break;
  176. default:
  177. ALWAYS_LOG("Invalid md id:%d\n", md_id);
  178. return -1;
  179. }
  180. switch(slot) {
  181. case 0:
  182. curr_val = DRV_Reg32(hw_remapping_bank4_map0);
  183. curr_val &= ~0x3FF;
  184. curr_val |= (((addr >> 24) | 0x1) & 0x3FF);
  185. DRV_WriteReg32(hw_remapping_bank4_map0, curr_val);
  186. ALWAYS_LOG("BANK4_MAP0 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map0));
  187. break;
  188. case 1:
  189. curr_val = DRV_Reg32(hw_remapping_bank4_map0);
  190. curr_val &= ~0x3FF0000;
  191. curr_val |= (((addr >> 8) | (1<<16)) & 0x3FF0000);
  192. DRV_WriteReg32(hw_remapping_bank4_map0, curr_val);
  193. ALWAYS_LOG("BANK4_MAP0 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map0));
  194. break;
  195. case 2:
  196. curr_val = DRV_Reg32(hw_remapping_bank4_map1);
  197. curr_val &= ~0x3FF;
  198. curr_val |= (((addr >> 24) | 0x1) & 0x3FF);
  199. DRV_WriteReg32(hw_remapping_bank4_map1, curr_val);
  200. ALWAYS_LOG("BANK4_MAP1 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map1));
  201. break;
  202. case 3:
  203. curr_val = DRV_Reg32(hw_remapping_bank4_map1);
  204. curr_val &= ~0x3FF0000;
  205. curr_val |= (((addr >> 8) | (1<<16)) & 0x3FF0000);
  206. DRV_WriteReg32(hw_remapping_bank4_map1, curr_val);
  207. ALWAYS_LOG("BANK4_MAP1 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map1));
  208. break;
  209. case 4:
  210. curr_val = DRV_Reg32(hw_remapping_bank4_map2);
  211. curr_val &= ~0x3FF;
  212. curr_val |= (((addr >> 24) | 0x1) & 0x3FF);
  213. DRV_WriteReg32(hw_remapping_bank4_map2, curr_val);
  214. ALWAYS_LOG("BANK4_MAP2 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map2));
  215. break;
  216. case 5:
  217. curr_val = DRV_Reg32(hw_remapping_bank4_map2);
  218. curr_val &= ~0x3FF0000;
  219. curr_val |= (((addr >> 8) | (1<<16)) & 0x3FF0000);
  220. DRV_WriteReg32(hw_remapping_bank4_map2, curr_val);
  221. ALWAYS_LOG("BANK4_MAP2 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map2));
  222. break;
  223. case 6:
  224. curr_val = DRV_Reg32(hw_remapping_bank4_map3);
  225. curr_val &= ~0x3FF;
  226. curr_val |= (((addr >> 24) | 0x1) & 0x3FF);
  227. DRV_WriteReg32(hw_remapping_bank4_map3, curr_val);
  228. ALWAYS_LOG("BANK4_MAP3 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map3));
  229. break;
  230. case 7:
  231. curr_val = DRV_Reg32(hw_remapping_bank4_map3);
  232. curr_val &= ~0x3FF0000;
  233. curr_val |= (((addr >> 8) | (1<<16)) & 0x3FF0000);
  234. DRV_WriteReg32(hw_remapping_bank4_map3, curr_val);
  235. ALWAYS_LOG("BANK4_MAP3 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map3));
  236. break;
  237. default:
  238. ALWAYS_LOG("Invalid slot id:%d\n", slot);
  239. return -1;
  240. }
  241. return 0;
  242. }
  243. static int md_smem_rw_remapping(unsigned int md_id, unsigned long long addr)
  244. {
  245. unsigned int i;
  246. ALWAYS_LOG("---> Map 0x40000000 to 0x%llx for MD%d\n", addr, md_id+1);
  247. for (i = 0; i < 8; i++)
  248. md_bank4_remapping_by_slot(md_id, addr + 0x2000000*i, i);
  249. return 0;
  250. }
  251. static void md_emi_remapping_lock(unsigned int md_id)
  252. {
  253. unsigned int reg_val;
  254. unsigned int lock_bit;
  255. switch (md_id) {
  256. case 0: // MD1
  257. lock_bit = MD1_LOCK;
  258. break;
  259. default:
  260. ALWAYS_LOG("Invalid md id:%d for lock\n", md_id);
  261. return;
  262. }
  263. reg_val = DRV_Reg32(MD_HW_REMAP_LOCK);
  264. ALWAYS_LOG("before hw remap lock: MD1[%d]\n", !!(reg_val&MD1_LOCK));
  265. DRV_WriteReg32(MD_HW_REMAP_LOCK, (reg_val|lock_bit));
  266. reg_val = DRV_Reg32(MD_HW_REMAP_LOCK);
  267. ALWAYS_LOG("before hw remap lock: MD1[%d]\n", !!(reg_val&MD1_LOCK));
  268. }
  269. /* =================================================== */
  270. /* MPU Region defination */
  271. /* =================================================== */
  272. /* Note: This structure should sync with Kernel!!!! */
  273. typedef unsigned long long mpu_att_t;
  274. typedef struct _mpu_cfg {
  275. unsigned int start;
  276. unsigned int end;
  277. int region;
  278. mpu_att_t permission;
  279. int relate_region;
  280. } mpu_cfg_t;
  281. #define MPU_REGION_ID_MD1_ROM 8
  282. #define MPU_REGION_ID_MD1_MCURW_HWRO 9
  283. #define MPU_REGION_ID_MD1_MCURO_HWRW 10
  284. #define MPU_REGION_ID_MD1_MCURW_HWRW 13
  285. #define MPU_REGION_ID_MD_DRDI 7 /*DRDI*/
  286. #define MPU_REGION_ID_MD_DSP1 11 /*DSP RO*/
  287. #define MPU_REGION_ID_MD_DSP2 12 /*DSP RW*/
  288. /* #define MPU_REGION_ID_PADDING1 13 */
  289. #define MPU_REGION_ID_PADDING2 14
  290. #define MPU_REGION_ID_PADDING3 15
  291. #define MPU_REGION_ID_PADDING4 16
  292. #define MPU_REGION_ID_PADDING5 17
  293. #define MPU_REGION_ID_MD_PROTECT 18
  294. #define MPU_REGION_ID_MD1_CCB 19
  295. #define MPU_REGION_ID_MD1_SMEM 20
  296. #define MPU_REGION_ID_AP 23
  297. #define MPU_REGION_ID_TOTAL_NUM (MPU_REGION_ID_AP + 1)
  298. #define MPU_MDOMAIN_ID_AP 0
  299. #define MPU_MDOMAIN_ID_MD1 1
  300. #define MPU_MDOMAIN_ID_MDHW 7
  301. #define MPU_MDOMAIN_ID_TOTAL_NUM 8
  302. static const mpu_att_t mpu_att_default[MPU_REGION_ID_TOTAL_NUM][MPU_MDOMAIN_ID_TOTAL_NUM] = {
  303. /*===================================================================================================================*/
  304. /* No | | D0(AP) | D1(MD1) | D2(CONN) | D3(Rsv) | D4(MM) | D5(Rsv ) | D6(MFG) | D7(MDHW) |*/
  305. /*--------------+----------------------------------------------------------------------------------------------------*/
  306. /* 0*/{}, /*Secure OS*/
  307. /* 1*/{}, /*ATF*/
  308. /* 2*/{}, /*Secure Memory*/
  309. /* 3*/{}, /*Set in TEE Trust UI*/
  310. /* 4*/{}, /*Security CCCI share memory(MD0 Secure Share)*/
  311. /* 5*/{}, /*Security CCCI share memory(MD1 Secure Share)*/
  312. /* 6*/{}, /*MD Dynamic*/
  313. /* 7*/{ SEC_R_NSEC_R, SEC_R_NSEC_R, [2 ... 6] = FORBIDDEN, SEC_R_NSEC_R},
  314. /* 8*/{ SEC_R_NSEC_R, SEC_R_NSEC_R, [2 ... 6] = FORBIDDEN, SEC_R_NSEC_R},
  315. /* 9*/{ SEC_R_NSEC_R, NO_PROTECTION, [2 ... 6] = FORBIDDEN, SEC_R_NSEC_R},
  316. /*10*/{ SEC_R_NSEC_R, SEC_R_NSEC_R, [2 ... 6] = FORBIDDEN, NO_PROTECTION},
  317. /*11*/{ SEC_R_NSEC_R, SEC_R_NSEC_R, [2 ... 6] = FORBIDDEN, SEC_R_NSEC_R},
  318. /*12*/{ SEC_R_NSEC_R, NO_PROTECTION, [2 ... 6] = FORBIDDEN, NO_PROTECTION},
  319. /*13*/{ SEC_R_NSEC_R, NO_PROTECTION, [2 ... 6] = FORBIDDEN, NO_PROTECTION},
  320. /*14*/{ SEC_R_NSEC_R, FORBIDDEN, [2 ... 6] = FORBIDDEN, FORBIDDEN},
  321. /*15*/{ SEC_R_NSEC_R, FORBIDDEN, [2 ... 6] = FORBIDDEN, FORBIDDEN},
  322. /*16*/{ SEC_R_NSEC_R, FORBIDDEN, [2 ... 6] = FORBIDDEN, FORBIDDEN},
  323. /*17*/{ SEC_R_NSEC_R, FORBIDDEN, [2 ... 6] = FORBIDDEN, FORBIDDEN},
  324. /*18*/{ NO_PROTECTION, SEC_R_NSEC_R, [2 ... 3] = FORBIDDEN, NO_PROTECTION, FORBIDDEN, SEC_R_NSEC_RW,
  325. [7] = FORBIDDEN},
  326. /*19*/{ NO_PROTECTION, NO_PROTECTION, [2 ... 6] = FORBIDDEN, NO_PROTECTION},
  327. /*20*/{ NO_PROTECTION, NO_PROTECTION, [2 ... 6] = FORBIDDEN, NO_PROTECTION},
  328. /*21*/{}, /*WIFI EMI FW*/
  329. /*22*/{},/*WDT*/
  330. /*23*/{ NO_PROTECTION, FORBIDDEN, [2 ... 3] = FORBIDDEN, NO_PROTECTION, FORBIDDEN, SEC_R_NSEC_RW,
  331. [7] = FORBIDDEN},
  332. };
  333. #define MPU_STR_BUF_SIZE 64
  334. static void get_mpu_attr_str(int lock, mpu_att_t curr_attr, char buf[], int size)
  335. {
  336. char ch = lock?'L':'U';
  337. snprintf(buf, size, "%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld(%c)",
  338. curr_attr&7, (curr_attr>>3)&7, (curr_attr>>6)&7, (curr_attr>>9)&7,
  339. (curr_attr>>12)&7, (curr_attr>>15)&7, (curr_attr>>18)&7, (curr_attr>>21)&7,
  340. (curr_attr>>32)&7, (curr_attr>>35)&7, (curr_attr>>38)&7, (curr_attr>>41)&7,
  341. (curr_attr>>44)&7, (curr_attr>>47)&7, (curr_attr>>50)&7, (curr_attr>>53)&7, ch);
  342. }
  343. static const unsigned char region_mapping_at_hdr_md1[] = {
  344. MPU_REGION_ID_MD1_ROM, MPU_REGION_ID_MD1_MCURO_HWRW, MPU_REGION_ID_MD1_MCURW_HWRO,
  345. MPU_REGION_ID_MD1_MCURW_HWRW
  346. };
  347. static const int free_mpu_region[] = {MPU_REGION_ID_PADDING2,
  348. MPU_REGION_ID_PADDING3, MPU_REGION_ID_PADDING4, MPU_REGION_ID_PADDING5, MPU_REGION_ID_MD_PROTECT, -1};
  349. static int curr_free_mpu_idx;
  350. static int get_free_mpu_region(void)
  351. {
  352. int ret;
  353. if (curr_free_mpu_idx < (int)(sizeof(free_mpu_region)/sizeof(int))) {
  354. ret = free_mpu_region[curr_free_mpu_idx];
  355. curr_free_mpu_idx++;
  356. } else
  357. ret = -LD_ERR_PLAT_MPU_REGION_EMPTY;
  358. return ret;
  359. }
  360. /*make sure protect region is the last valid region*/
  361. static int get_md_protect_mpu_region(void)
  362. {
  363. int last_index;
  364. last_index = (int)(sizeof(free_mpu_region)/sizeof(int)) -1;
  365. if (free_mpu_region[last_index] < 0) /*free region end by -1*/
  366. last_index--; /*make sure it is index of last valid region*/
  367. if (curr_free_mpu_idx > last_index)
  368. return -LD_ERR_PLAT_MPU_REGION_EMPTY;
  369. return free_mpu_region[last_index];
  370. }
  371. static mpu_att_t get_mpu_region_default_access_att(int region, int lock)
  372. {
  373. return SET_ACCESS_PERMISSON(lock, mpu_att_default[region][7], mpu_att_default[region][6],
  374. mpu_att_default[region][5], mpu_att_default[region][4],
  375. mpu_att_default[region][3], mpu_att_default[region][2],
  376. mpu_att_default[region][1], mpu_att_default[region][0]);
  377. }
  378. static unsigned long long mpu_attr_calculate(int region_id, unsigned int request_attr)
  379. {
  380. mpu_att_t tmp_mpu_att[MPU_MDOMAIN_ID_TOTAL_NUM], i;
  381. for (i = 0; i < MPU_MDOMAIN_ID_TOTAL_NUM; i++)
  382. tmp_mpu_att[i] = mpu_att_default[region_id][i];
  383. /* AP MD1 MDHW: AP */
  384. if ((request_attr & 0xF) <= FORBIDDEN)
  385. tmp_mpu_att[MPU_MDOMAIN_ID_AP] = (request_attr & 0xF);
  386. /* AP MD1 MDHW: MD1 */
  387. request_attr = (request_attr >> 4);
  388. if ((request_attr & 0xF) <= FORBIDDEN)
  389. tmp_mpu_att[MPU_MDOMAIN_ID_MD1] = (request_attr & 0xF);
  390. /* AP MD1 MDHW: MDHW */
  391. request_attr = (request_attr >> 4);
  392. if ((request_attr & 0xF) <= FORBIDDEN)
  393. tmp_mpu_att[MPU_MDOMAIN_ID_MDHW] = (request_attr & 0xF);
  394. /* MPU region lock */
  395. return SET_ACCESS_PERMISSON(1, tmp_mpu_att[7], tmp_mpu_att[6],
  396. tmp_mpu_att[5], tmp_mpu_att[4],
  397. tmp_mpu_att[3], tmp_mpu_att[2],
  398. tmp_mpu_att[1], tmp_mpu_att[0]);
  399. }
  400. static void ccci_mem_access_cfg(mpu_cfg_t *mpu_cfg_list, int clear)
  401. {
  402. #ifdef ENABLE_EMI_PROTECTION
  403. mpu_cfg_t *curr;
  404. mpu_att_t curr_attr;
  405. char buf[MPU_STR_BUF_SIZE];
  406. if (NULL == mpu_cfg_list)
  407. return;
  408. curr = mpu_cfg_list;
  409. curr_attr = SET_ACCESS_PERMISSON(0, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION,
  410. NO_PROTECTION, NO_PROTECTION, NO_PROTECTION);
  411. while (curr->region != -1) {
  412. if (clear) {
  413. emi_mpu_set_region_protection( 0, /*START_ADDR*/
  414. 0, /*END_ADDR*/
  415. curr->region, /*region*/
  416. curr_attr);
  417. ALWAYS_LOG("Clr MPU:S:0x%x E:0x%x A:<%d>[0~7]%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld\n", 0, 0,
  418. curr->region, curr_attr&7, (curr_attr>>3)&7, (curr_attr>>6)&7,
  419. (curr_attr>>9)&7, (curr_attr>>12)&7, (curr_attr>>15)&7,
  420. (curr_attr>>18)&7, (curr_attr>>21)&7);
  421. } else {
  422. emi_mpu_set_region_protection( curr->start, /*START_ADDR*/
  423. curr->end, /*END_ADDR*/
  424. curr->region, /*region*/
  425. curr->permission);
  426. curr_attr = curr->permission;
  427. get_mpu_attr_str(0, curr_attr, buf, MPU_STR_BUF_SIZE);
  428. ALWAYS_LOG("Set MPU:S:0x%x E:0x%x A:<%d>[0~7]%s\n", curr->start,
  429. curr->end, curr->region, buf);
  430. }
  431. curr++;
  432. }
  433. #endif
  434. }
  435. /*--------- Implement one by one -------------------------------------------------------------------------------*/
  436. int plat_get_padding_mpu_num(void)
  437. {
  438. return (int)(sizeof(free_mpu_region)/sizeof(unsigned int)) - 1;
  439. }
  440. /*---------------------------------------------------------------------------------------------------*/
  441. /* Global variable for share memory */
  442. /*---------------------------------------------------------------------------------------------------*/
  443. static unsigned int ap_md1_smem_size_at_lk_env;
  444. static unsigned int md1_md3_smem_size_at_lk_env;
  445. static unsigned int ap_md3_smem_size_at_lk_env;
  446. static unsigned int ap_md1_smem_size_at_img;
  447. #define AP_MD1_SMEM_SIZE 0x100000
  448. #define MAX_SMEM_SIZE 0x4000000 //history: 6M-->256M-->64M
  449. typedef struct _smem_layout {
  450. unsigned long long base_addr;
  451. unsigned int ap_md1_smem_offset;
  452. unsigned int ap_md1_smem_size;
  453. unsigned int ap_md3_smem_offset;
  454. unsigned int ap_md3_smem_size;
  455. unsigned int md1_md3_smem_offset;
  456. unsigned int md1_md3_smem_size;
  457. unsigned int total_smem_size;
  458. } smem_layout_t;
  459. static smem_layout_t smem_info;
  460. typedef struct _ccb_layout {
  461. unsigned long long ccb_data_buffer_addr;
  462. unsigned int ccb_data_buffer_size;
  463. } ccb_layout_t;
  464. static ccb_layout_t ccb_info;
  465. unsigned int md1_phy_cap_size;
  466. void plat_notify_secure(unsigned long base_addr)
  467. {
  468. unsigned long addr_get;
  469. mt_secure_call(MTK_SIP_LK_AMMS_MD_BASE_ADDR_AARCH32, base_addr, 0, 0);
  470. addr_get = mt_secure_call(MTK_SIP_LK_AMMS_GET_MD_BASE_ADDR_AARCH32, 0, 0, 0);
  471. ALWAYS_LOG("mt_secure_call: set_addr = 0x%lx, get_addr = 0x%lx\n", base_addr, addr_get);
  472. }
  473. /*---------------------------------------------------------------------------------------------------*/
  474. /* HW remap function implement */
  475. /*---------------------------------------------------------------------------------------------------*/
  476. int plat_apply_hw_remap_for_md_ro_rw(void* info)
  477. {
  478. modem_info_t *md_ld_info = (modem_info_t *)info;
  479. plat_notify_secure(md_ld_info->base_addr);
  480. return md_mem_ro_rw_remapping((unsigned int)md_ld_info->md_id, md_ld_info->base_addr);
  481. }
  482. int plat_apply_hw_remap_for_md_smem(void *addr, int size)
  483. {
  484. /* For share memory final size depends on MD number, just store start address and size
  485. ** actual setting will do later
  486. */
  487. smem_info.base_addr = (unsigned long long)((unsigned long)addr);
  488. return 0;
  489. }
  490. int get_ccci_md_view_smem_addr(unsigned long long *ap_addr, unsigned int *md_addr)
  491. {
  492. int ret = 0;
  493. if (ap_addr)
  494. *ap_addr = smem_info.base_addr + smem_info.ap_md1_smem_offset + 0x100000;
  495. else
  496. ret = -1;
  497. if (md_addr)
  498. *md_addr = 0x40000000 + smem_info.ap_md1_smem_offset + 0x100000;
  499. else
  500. ret = -2;
  501. if (ret >= 0)
  502. ALWAYS_LOG("[ccci]get_md_view_smem: ap_addr = 0x%llx, 0x%x\n", *ap_addr, *md_addr);
  503. else
  504. ALWAYS_LOG("[ccci]get_md_view_smem: param error, ret = %d\n", ret);
  505. return ret;
  506. }
  507. /*---------------------------------------------------------------------------------------------------*/
  508. /* check header info collection by plat_post_hdr_info */
  509. /*---------------------------------------------------------------------------------------------------*/
  510. void plat_post_hdr_info(void* hdr, int ver, int id)
  511. {
  512. if (id == MD_SYS1) {
  513. ap_md1_smem_size_at_img = ((struct md_check_header_v6*)hdr)->ap_md_smem_size;
  514. }
  515. }
  516. /*---------------------------------------------------------------------------------------------------*/
  517. /* MPU static global variable and mpu relate function implement */
  518. /*---------------------------------------------------------------------------------------------------*/
  519. #define MPU_REGION_TOTAL_NUM (16) /* = MD1+MD3 */
  520. static mpu_cfg_t mpu_tbl[MPU_REGION_TOTAL_NUM];
  521. static int s_g_curr_mpu_num;
  522. /*
  523. ** if set start=0x0, end=0x10000, the actural protected area will be 0x0-0x1FFFF,
  524. ** here we use 64KB align, MPU actually request 32KB align since MT6582, but this works...
  525. ** we assume emi_mpu_set_region_protection will round end address down to 64KB align.
  526. */
  527. static void dump_received_pure_mpu_setting(struct image_section_desc *mem_info, int item_num)
  528. {
  529. int i;
  530. for (i =0; i < item_num; i++)
  531. MPU_DBG_LOG("mpu sec dec %d: offset:%x, size:%x, mpu_attr:%x, ext_flag:%x, relate_idx:%x\n", i,
  532. mem_info[i].offset, mem_info[i].size, mem_info[i].mpu_attr,
  533. mem_info[i].ext_flag, mem_info[i].relate_idx);
  534. }
  535. static int find_bind_mpu_region(mpu_cfg_t *mpu_tbl_hdr, int item_num, unsigned int bind_key)
  536. {
  537. int i;
  538. for (i = 0; i < item_num; i++) {
  539. if (mpu_tbl_hdr[i].relate_region == (int)bind_key)
  540. return i;
  541. }
  542. return -1;
  543. }
  544. static int md1_mpu_setting_process(void *p_md_ld_info, void *p_mem_info, mpu_cfg_t *mpu_tbl_hdr)
  545. {
  546. modem_info_t *md_ld_info = (modem_info_t *)p_md_ld_info;
  547. struct image_section_desc *mem_info = (struct image_section_desc *)p_mem_info;
  548. int normal_region_num = 0;
  549. int total_region_num = 0;
  550. int curr_idx = 0;
  551. int i;
  552. int all_range_region_idx = -1;
  553. int bind_idx;
  554. int free_region_id;
  555. int didi_region_idx = -1;
  556. /* Calculate mpu num and padding num */
  557. for (i = 0; i < MPU_REGION_TOTAL_NUM; i++) {
  558. if ((mem_info[i].offset == 0) && (mem_info[i].size == 0))
  559. break;
  560. if (mem_info[i].ext_flag & MD_ALL_RANGE)
  561. all_range_region_idx = i;
  562. if (mem_info[i].ext_flag & MD_DRDI_REGION)
  563. didi_region_idx = i;
  564. }
  565. total_region_num = i;
  566. dump_received_pure_mpu_setting(mem_info, total_region_num);
  567. for (i = 0; i < total_region_num; i++) {
  568. if (mem_info[i].ext_flag & (MD_DRDI_REGION|MD_ALL_RANGE|NEED_REMOVE|NEED_MPU_MORE))
  569. continue;
  570. /* Process normal case first */
  571. if (curr_idx >= (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char))) {
  572. ALWAYS_LOG("[error]md%d: mpu region too more %d\n", md_ld_info->md_id+1,
  573. (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char)));
  574. return -LD_ERR_PLAT_MPU_REGION_TOO_MORE;
  575. }
  576. mpu_tbl_hdr[curr_idx].start = (unsigned int)md_ld_info->base_addr + mem_info[i].offset;
  577. mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + mem_info[i].size;
  578. mpu_tbl_hdr[curr_idx].end = ((mpu_tbl_hdr[curr_idx].end + 0xFFFF)&(~0xFFFF)) - 1;/* 64K align */
  579. mpu_tbl_hdr[curr_idx].permission =
  580. mpu_attr_calculate(region_mapping_at_hdr_md1[curr_idx], mem_info[i].mpu_attr);
  581. mpu_tbl_hdr[curr_idx].region = (int)region_mapping_at_hdr_md1[curr_idx];
  582. mpu_tbl_hdr[curr_idx].relate_region = mem_info[i].relate_idx;
  583. curr_idx++;
  584. normal_region_num++;
  585. }
  586. if (normal_region_num != (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char))) {
  587. ALWAYS_LOG("[error]md%d: mpu region not sync %d:%d\n", md_ld_info->md_id+1, normal_region_num,
  588. (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char)));
  589. return -LD_ERR_PLAT_MPU_REGION_NUM_NOT_SYNC;
  590. }
  591. for (i = 0; i < total_region_num; i++) {
  592. if (mem_info[i].ext_flag & NEED_MPU_MORE) {
  593. bind_idx = find_bind_mpu_region(mpu_tbl_hdr, curr_idx, mem_info[i].relate_idx);
  594. if (bind_idx >= 0) {
  595. mpu_tbl_hdr[curr_idx].start = (unsigned int)md_ld_info->base_addr + mem_info[i].offset;
  596. mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + mem_info[i].size;
  597. /* 64K align */
  598. mpu_tbl_hdr[curr_idx].end = ((mpu_tbl_hdr[curr_idx].end + 0xFFFF)&(~0xFFFF)) - 1;
  599. mpu_tbl_hdr[curr_idx].permission = mpu_tbl_hdr[bind_idx].permission;
  600. /* setting relate region */
  601. free_region_id = get_free_mpu_region();
  602. if (free_region_id < 0) {
  603. ALWAYS_LOG("[error]abnormal free region id %d +\n", free_region_id);
  604. return -LD_ERR_PLAT_ABNORMAL_FREE_REGION;
  605. }
  606. mpu_tbl_hdr[curr_idx].region = free_region_id;
  607. mpu_tbl_hdr[curr_idx].relate_region = mem_info[i].relate_idx;
  608. mpu_tbl_hdr[bind_idx].relate_region = free_region_id;
  609. curr_idx++;
  610. } else {
  611. ALWAYS_LOG("md%d: padding array abnormal\n", md_ld_info->md_id+1);
  612. return -LD_ERR_PLAT_ABNORMAL_PAD_ARRAY;
  613. }
  614. }
  615. }
  616. /* Apply DRDI if needed */
  617. if (didi_region_idx >= 0) {
  618. mpu_tbl_hdr[curr_idx].permission = get_mpu_region_default_access_att(MPU_REGION_ID_MD_DRDI, 1);
  619. mpu_tbl_hdr[curr_idx].start = (unsigned int)md_ld_info->base_addr + mem_info[didi_region_idx].offset;
  620. mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + mem_info[didi_region_idx].size;
  621. /* 64K align */
  622. mpu_tbl_hdr[curr_idx].end = ((mpu_tbl_hdr[curr_idx].end + 0xFFFF)&(~0xFFFF)) - 1;
  623. mpu_tbl_hdr[curr_idx].region = MPU_REGION_ID_MD_DRDI;
  624. mpu_tbl_hdr[curr_idx].relate_region = 0;
  625. curr_idx++;
  626. }
  627. /* Apply MD all range mpu protect setting */
  628. free_region_id = get_md_protect_mpu_region(); //get_free_mpu_region();
  629. if (free_region_id < 0) {
  630. ALWAYS_LOG("[error]no more free region\n");
  631. return -LD_ERR_PLAT_NO_MORE_FREE_REGION;
  632. }
  633. mpu_tbl_hdr[curr_idx].permission = get_mpu_region_default_access_att(free_region_id, 1);
  634. mpu_tbl_hdr[curr_idx].start = (unsigned int)md_ld_info->base_addr + mem_info[all_range_region_idx].offset;
  635. /*mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + mem_info[all_range_region_idx].size;*/
  636. mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + 256 * 1024 * 1024;
  637. /* 64K align */
  638. mpu_tbl_hdr[curr_idx].end = ((mpu_tbl_hdr[curr_idx].end + 0xFFFF)&(~0xFFFF)) - 1;
  639. mpu_tbl_hdr[curr_idx].region = free_region_id;
  640. mpu_tbl_hdr[curr_idx].relate_region = 0;
  641. curr_idx++;
  642. /* Clear logic relate index to 0 to mark as end */
  643. for (i = 0; i < curr_idx; i++) {
  644. if (mpu_tbl_hdr[i].relate_region >= LOGIC_BINDING_IDX_START)
  645. mpu_tbl_hdr[i].relate_region = 0;
  646. }
  647. return curr_idx;
  648. }
  649. int plat_send_mpu_info_to_platorm(void *p_md_ld_info, void *p_mem_info)
  650. {
  651. modem_info_t *md_ld_info = (modem_info_t *)p_md_ld_info;
  652. struct image_section_desc *mem_info = (struct image_section_desc *)p_mem_info;
  653. int md_id = md_ld_info->md_id;
  654. int ret;
  655. int i;
  656. char buf[MPU_STR_BUF_SIZE];
  657. if (md_id == MD_SYS1) {
  658. ret = md1_mpu_setting_process(p_md_ld_info, p_mem_info, &mpu_tbl[s_g_curr_mpu_num]);
  659. if (ret > 0)
  660. s_g_curr_mpu_num += ret;
  661. } else if (md_id == MD1_DSP) {
  662. /* RO part */
  663. mpu_tbl[s_g_curr_mpu_num].permission = get_mpu_region_default_access_att(MPU_REGION_ID_MD_DSP1, 1);
  664. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)md_ld_info->base_addr + mem_info[0].offset;
  665. mpu_tbl[s_g_curr_mpu_num].end = mpu_tbl[s_g_curr_mpu_num].start + mem_info[0].size;
  666. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD_DSP1;
  667. /* 64K align */
  668. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  669. s_g_curr_mpu_num++;
  670. /* RW part */
  671. mpu_tbl[s_g_curr_mpu_num].permission = get_mpu_region_default_access_att(MPU_REGION_ID_MD_DSP2, 1);
  672. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)md_ld_info->base_addr + mem_info[1].offset;
  673. mpu_tbl[s_g_curr_mpu_num].end = mpu_tbl[s_g_curr_mpu_num].start + mem_info[1].size;
  674. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD_DSP2;
  675. /* 64K align */
  676. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  677. s_g_curr_mpu_num++;
  678. }
  679. for (i =0; i < s_g_curr_mpu_num; i++) {
  680. get_mpu_attr_str(0, mpu_tbl[i].permission, buf, MPU_STR_BUF_SIZE);
  681. MPU_DBG_LOG("plat mpu dec %d: region:%d[%d], start:0x%x, end:0x%x, attr:%s\n", i,
  682. mpu_tbl[i].region, mpu_tbl[i].relate_region, mpu_tbl[i].start, mpu_tbl[i].end, buf);
  683. }
  684. return 0;
  685. }
  686. struct ccb_gear_id_mapping {
  687. unsigned int gear_id;
  688. unsigned int size;
  689. };
  690. const struct ccb_gear_id_mapping ccb_support_tbl[] = {
  691. {1, 22 * 1024 * 1024},
  692. {2, 12 * 1024 * 1024},
  693. {3, 0 * 1024 * 1024},
  694. {11, 4 * 1024 * 1024}
  695. };
  696. static unsigned int get_ccb_size_from_gear_id(unsigned int gear_id)
  697. {
  698. int i;
  699. for (i = 0; i < (int)(sizeof(ccb_support_tbl)/sizeof(struct ccb_gear_id_mapping)); i++) {
  700. if (gear_id == ccb_support_tbl[i].gear_id)
  701. return ccb_support_tbl[i].size;
  702. }
  703. return 0xFFFFFFFF;
  704. }
  705. static void set_ccb_gear_val(unsigned int gear_id)
  706. {
  707. int ret;
  708. char env_buf[12];
  709. memset(env_buf, 0, sizeof(env_buf));
  710. snprintf(env_buf, sizeof(env_buf), "%u", gear_id);
  711. ret = set_env("md1_ccb_cap_gear", env_buf);
  712. if (ret < 0) {
  713. ALWAYS_LOG("set env[md1_ccb_cap_gear]fail, ret=%d\n", ret);
  714. assert(0);
  715. } else
  716. ALWAYS_LOG("set env[md1_ccb_cap_gear]%d\n", gear_id);
  717. }
  718. static unsigned int get_ccb_gear_val(void)
  719. {
  720. unsigned int md1_ccb_cap_gear;
  721. unsigned int md1_ccb_size;
  722. if (g_boot_mode == META_BOOT || true == get_atm_enable_status()) {
  723. ALWAYS_LOG("meta mode[md1_ccb_cap_gear]%d\n", CCB_DATA_BUF_DEFAULT_GEAR);
  724. set_ccb_gear_val(CCB_DATA_BUF_DEFAULT_GEAR);
  725. return CCB_DATA_BUF_DEFAULT_GEAR;
  726. }
  727. md1_ccb_cap_gear = str2uint(get_env("md1_ccb_cap_gear"));
  728. if (md1_ccb_cap_gear != 0) {
  729. md1_ccb_size = get_ccb_size_from_gear_id(md1_ccb_cap_gear);
  730. if (md1_ccb_size == 0xFFFFFFFF) {
  731. ALWAYS_LOG("CCB cfg abnormal!!! un-support ccb gear id: %d\n", md1_ccb_cap_gear);
  732. assert(0);
  733. }
  734. ALWAYS_LOG("get env[md1_ccb_cap_gear]%d\n", md1_ccb_cap_gear);
  735. return md1_ccb_cap_gear;
  736. } else {
  737. #ifdef MTK_DYNAMIC_CCB_BUFFER_GEAR_ID
  738. md1_ccb_cap_gear = MTK_DYNAMIC_CCB_BUFFER_GEAR_ID;
  739. #else
  740. md1_ccb_cap_gear = CCB_DATA_BUF_DEFAULT_GEAR;
  741. #endif
  742. set_ccb_gear_val(md1_ccb_cap_gear);
  743. return md1_ccb_cap_gear;
  744. }
  745. }
  746. static void set_gear_id_list()
  747. {
  748. int ret;
  749. ret = set_env("md1_ccb_gear_list",
  750. "1(2,20);2(2,10);3(0,0);11(2,2)");
  751. if (ret) {
  752. ALWAYS_LOG("set_gear_id_list error: %x\n", ret);
  753. }
  754. }
  755. /*------------------------------------------------------------------------------------------------*/
  756. /* Suppor function for share memory calculate */
  757. /*------------------------------------------------------------------------------------------------*/
  758. static int cal_share_mem_layout(int load_flag)
  759. {
  760. unsigned int md1_phy_cap_gear, md1_ccb_cap_gear;
  761. unsigned int md1_bank4_cache_offset;
  762. unsigned int md1_ccb_size;
  763. unsigned char * ccb_data_buf = NULL;
  764. ap_md1_smem_size_at_lk_env = str2uint(get_env("apmd1_smem"));
  765. md1_md3_smem_size_at_lk_env = str2uint(get_env("md1md3_smem"));
  766. ap_md3_smem_size_at_lk_env = str2uint(get_env("apmd3_smem"));
  767. md1_phy_cap_gear = str2uint(get_env("md1_phy_cap_gear"));
  768. ALWAYS_LOG("env[apmd1_smem]%x.\n", ap_md1_smem_size_at_lk_env);
  769. ALWAYS_LOG("env[md1md3_smem]%x.\n", md1_md3_smem_size_at_lk_env);
  770. ALWAYS_LOG("env[apmd3_smem]%x.\n", ap_md3_smem_size_at_lk_env);
  771. ALWAYS_LOG("env[md1_phy_cap_gear]%x.\n", md1_phy_cap_gear);
  772. md1_ccb_cap_gear = get_ccb_gear_val();
  773. md1_ccb_size = get_ccb_size_from_gear_id(md1_ccb_cap_gear);
  774. ALWAYS_LOG("allocate ccb data buffer 0x%x [%d]\n", md1_ccb_size, md1_ccb_cap_gear);
  775. set_gear_id_list();
  776. if (insert_ccci_tag_inf("ccb_gear_id", (char*)&md1_ccb_cap_gear, sizeof(unsigned int)) < 0)
  777. ALWAYS_LOG("insert ccb_gear_id fail\n");
  778. if (md1_ccb_size != 0)
  779. ccb_data_buf = ccci_request_mem(md1_ccb_size, 0x78000000LL, 0x2000000L);
  780. if (ccb_data_buf == NULL) {
  781. ccb_info.ccb_data_buffer_addr = 0;
  782. ccb_info.ccb_data_buffer_size = 0;
  783. if (md1_ccb_size != 0)
  784. ALWAYS_LOG("allocate ccb data buffer share memory fail\n");
  785. else
  786. ALWAYS_LOG("CCB disabled\n");
  787. } else {
  788. ccb_info.ccb_data_buffer_addr = (unsigned long long)((unsigned long)ccb_data_buf);
  789. ccb_info.ccb_data_buffer_size = md1_ccb_size;
  790. if (insert_ccci_tag_inf("ccb_info", (char*)&ccb_info, sizeof(ccb_layout_t)) < 0)
  791. ALWAYS_LOG("insert ccb_info fail\n");
  792. ALWAYS_LOG("ccb_info.ccb_data_buffer_addr: %x\n", (unsigned int)ccb_info.ccb_data_buffer_addr);
  793. ALWAYS_LOG("ccb_info.ccb_data_buffer_size: %x\n", ccb_info.ccb_data_buffer_size);
  794. /* CCB must in last 32M */
  795. md1_bank4_cache_offset = 224 * 1024 * 1024;
  796. if (insert_ccci_tag_inf("md1_smem_cahce_offset", (char*)&md1_bank4_cache_offset,
  797. sizeof(md1_bank4_cache_offset)) < 0)
  798. ALWAYS_LOG("insert md1_smem_cahce_offset fail\n");
  799. }
  800. switch(md1_phy_cap_gear)
  801. {
  802. case 0:
  803. md1_phy_cap_size = CCCI_SMEM_SIZE_PHY_C_L0;
  804. break;
  805. case 1:
  806. md1_phy_cap_size = CCCI_SMEM_SIZE_PHY_C_L1;
  807. break;
  808. case 2:
  809. md1_phy_cap_size = CCCI_SMEM_SIZE_PHY_C_L2;
  810. break;
  811. case 3:
  812. md1_phy_cap_size = CCCI_SMEM_SIZE_PHY_C_L3;
  813. break;
  814. case 4:
  815. md1_phy_cap_size = CCCI_SMEM_SIZE_PHY_C_L4;
  816. break;
  817. default:
  818. md1_phy_cap_size = CCCI_SMEM_SIZE_PHY_C_L0;
  819. break;
  820. }
  821. ALWAYS_LOG("md1 phy capture size: %x\n", md1_phy_cap_size);
  822. if (insert_ccci_tag_inf("md1_phy_cap", (char*)&md1_phy_cap_size, sizeof(md1_phy_cap_size)) < 0)
  823. ALWAYS_LOG("insert md1_phy_cap fail\n");
  824. /* MD Share memory layout */
  825. /* AP <--> MD1 */
  826. {
  827. smem_info.ap_md1_smem_offset = 0;
  828. if (ap_md1_smem_size_at_lk_env)
  829. smem_info.ap_md1_smem_size = ap_md1_smem_size_at_lk_env;
  830. else if (ap_md1_smem_size_at_img)
  831. smem_info.ap_md1_smem_size = ap_md1_smem_size_at_img;
  832. else
  833. smem_info.ap_md1_smem_size = AP_MD1_SMEM_SIZE;
  834. smem_info.md1_md3_smem_offset = 0;
  835. smem_info.md1_md3_smem_size = 0;
  836. smem_info.ap_md3_smem_offset = 0;
  837. smem_info.ap_md3_smem_size = 0;
  838. /* add 2M for SIB header to avoid MD MPU violation if SIB exist */
  839. if(md1_phy_cap_size != CCCI_SMEM_SIZE_PHY_C_L0)
  840. smem_info.ap_md1_smem_size += 2 * 1024 * 1024;
  841. smem_info.total_smem_size = smem_info.ap_md1_smem_size;
  842. }
  843. /* insert share memory layout to lk info */
  844. if (insert_ccci_tag_inf("smem_layout", (char*)&smem_info, sizeof(smem_layout_t)) < 0)
  845. ALWAYS_LOG("insert smem_layout fail\n");
  846. ALWAYS_LOG("smem_info.base_addr: %x\n", (unsigned int)smem_info.base_addr);
  847. ALWAYS_LOG("smem_info.ap_md1_smem_offset: %x\n", smem_info.ap_md1_smem_offset);
  848. ALWAYS_LOG("smem_info.ap_md1_smem_size: %x\n", smem_info.ap_md1_smem_size);
  849. ALWAYS_LOG("smem_info.ap_md3_smem_offset: %x\n", smem_info.ap_md3_smem_offset);
  850. ALWAYS_LOG("smem_info.ap_md3_smem_size: %x\n", smem_info.ap_md3_smem_size);
  851. ALWAYS_LOG("smem_info.md1_md3_smem_offset: %x\n", smem_info.md1_md3_smem_offset);
  852. ALWAYS_LOG("smem_info.md1_md3_smem_size: %x\n", smem_info.md1_md3_smem_size);
  853. ALWAYS_LOG("smem_info.total_smem_size: %x\n", smem_info.total_smem_size);
  854. return (int)smem_info.total_smem_size + md1_phy_cap_size;
  855. }
  856. static void boot_to_dummy_ap_mode(int load_md_flag);
  857. /*------------------------------------------------------------------------------------------------*/
  858. /* Note: This function using global variable
  859. ** if set start=0x0, end=0x10000, the actural protected area will be 0x0-0x1FFFF,
  860. ** here we use 64KB align, MPU actually request 32KB align since MT6582, but this works...
  861. ** we assume emi_mpu_set_region_protection will round end address down to 64KB align.
  862. */
  863. int plat_apply_platform_setting(int load_md_flag)
  864. {
  865. int smem_final_size;
  866. #ifdef DUMMY_AP_MODE
  867. /* This function will never return */
  868. ALWAYS_LOG("boot to dummy ap mode!!!\n");
  869. boot_to_dummy_ap_mode(load_md_flag);
  870. return 0;
  871. #endif
  872. /* Check loading validation */
  873. if (((load_md_flag & (1<<MD_SYS1)) == 0) && (load_md_flag & (1<<MD_SYS3))) {
  874. ALWAYS_LOG("md3 depends on md1,but md1 not loaded\n");
  875. return -LD_ERR_PLAT_MD1_NOT_RDY;
  876. }
  877. if ((load_md_flag & ((1<<MD_SYS1)|(1<<MD_SYS3))) == 0) {
  878. ALWAYS_LOG("both md1 and md3 not enable\n");
  879. return 0;
  880. }
  881. smem_final_size = cal_share_mem_layout(load_md_flag);
  882. ALWAYS_LOG("ap md1 share mem MPU need configure\n");
  883. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD1_SMEM;
  884. mpu_tbl[s_g_curr_mpu_num].permission = get_mpu_region_default_access_att(MPU_REGION_ID_MD1_SMEM, 0);
  885. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)smem_info.base_addr + smem_info.ap_md1_smem_offset;
  886. mpu_tbl[s_g_curr_mpu_num].end = (unsigned int)smem_info.base_addr + smem_info.ap_md1_smem_offset
  887. + smem_info.ap_md1_smem_size + md1_phy_cap_size;
  888. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  889. s_g_curr_mpu_num++;
  890. /* add for ccb data buffer mpu */
  891. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD1_CCB;
  892. mpu_tbl[s_g_curr_mpu_num].permission = get_mpu_region_default_access_att(MPU_REGION_ID_MD1_CCB, 0);
  893. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)ccb_info.ccb_data_buffer_addr;
  894. mpu_tbl[s_g_curr_mpu_num].end = (unsigned int)ccb_info.ccb_data_buffer_addr + ccb_info.ccb_data_buffer_size;
  895. //ccb_data_buf + CCB_DATA_BUF_SIZE;
  896. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  897. s_g_curr_mpu_num++;
  898. mpu_tbl[s_g_curr_mpu_num].region = -1; /* mark for end */
  899. /* Insert mpu tag info */
  900. if (insert_ccci_tag_inf("md_mpu_inf", (char*)mpu_tbl, sizeof(mpu_cfg_t)*s_g_curr_mpu_num) < 0)
  901. ALWAYS_LOG("insert md_mpu_inf fail\n");
  902. if (insert_ccci_tag_inf("md_mpu_num", (char*)&s_g_curr_mpu_num, sizeof(int)) < 0)
  903. ALWAYS_LOG("insert md_mpu_num fail\n");
  904. /* Apply all MPU setting */
  905. ccci_mem_access_cfg(mpu_tbl, 0);
  906. /* Apply share memory HW remap setting and lock it */
  907. if (load_md_flag & (1<<MD_SYS1)) {
  908. md_smem_rw_remapping(MD_SYS1, (unsigned int)(smem_info.base_addr + smem_info.ap_md1_smem_offset));
  909. /* remapping CCB to last 32M in bank4 */
  910. md_bank4_remapping_by_slot(MD_SYS1, ccb_info.ccb_data_buffer_addr, 7);
  911. md_emi_remapping_lock(MD_SYS1);
  912. }
  913. return smem_final_size;
  914. }
  915. /*------------------------------------------------------------------------------------------------*/
  916. /* platform configure setting info. */
  917. /*------------------------------------------------------------------------------------------------*/
  918. long long plat_ccci_get_ld_md_plat_setting(char cfg_name[])
  919. {
  920. if (strcmp(cfg_name, "share_memory_size") == 0) {
  921. #ifdef DUMMY_AP_MODE
  922. return 0x200000;
  923. #endif
  924. return (long long)(MAX_SMEM_SIZE);
  925. }
  926. if (strcmp(cfg_name, "share_mem_limit") == 0)
  927. return 0x78000000LL;
  928. if (strcmp(cfg_name, "ro_rw_mem_limit") == 0) {
  929. #ifdef DUMMY_AP_MODE
  930. return 0xA0000000LL;
  931. #endif
  932. return 0x78000000LL;
  933. }
  934. if (strcmp(cfg_name, "ro_rw_mem_align") == 0)
  935. return 0x2000000LL;
  936. if (strcmp(cfg_name, "share_mem_align") == 0)
  937. return 0x2000000LL;
  938. if (strcmp(cfg_name, "ld_version") == 0) {
  939. #ifdef DUMMY_AP_MODE
  940. return 0x20001;
  941. #endif
  942. return 0x20000;/* xxxx_yyyy, xxxx: main id, yyyy sub id */
  943. }
  944. if (strcmp(cfg_name, "rat_plat_ver") == 0)
  945. return RAT_VER_93;
  946. return -1LL;
  947. }
  948. #ifdef DUMMY_AP_MODE
  949. #include <platform/mt_irq.h>
  950. extern void dummy_ap_boot_up_md(int md_en_flag);
  951. extern void load_modem_image(void);
  952. extern int dummy_ap_irq_helper(unsigned int);
  953. /* Remember add this function to file platform.c(platform code) */
  954. void dummy_ap_entry(void)
  955. {
  956. load_modem_image();
  957. }
  958. /* Remember add this function to file interrupts.c(platform code) */
  959. void dummy_ap_irq_handler(unsigned int irq)
  960. {
  961. if (dummy_ap_irq_helper(irq)) {
  962. mt_irq_ack(irq);
  963. mt_irq_unmask(irq);
  964. }
  965. }
  966. void boot_to_dummy_ap_mode(int load_md_flag)
  967. {
  968. md_smem_rw_remapping(MD_SYS1, smem_info.base_addr);
  969. /* Before boot dummy AP, clear share memory */
  970. memset((void*)((unsigned long)smem_info.base_addr), 0, 0x200000);
  971. dummy_ap_boot_up_md(load_md_flag);
  972. }
  973. #endif