ccci_lk_load_img_plat.c 46 KB

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