ccci_lk_load_img_plat.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897
  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. #define MODULE_NAME "LK_LD_MD"
  46. #include "ccci_ld_md_core.h"
  47. #include "ccci_ld_md_errno.h"
  48. /***************************************************************************************************
  49. ** Feature Option setting part
  50. ***************************************************************************************************/
  51. #define ENABLE_EMI_PROTECTION
  52. /***************************************************************************************************
  53. ** HW remap section
  54. ***************************************************************************************************/
  55. extern unsigned int ddr_enable_4gb(void)__attribute__((weak));
  56. static int is_4gb_ddr_support_en(void)
  57. {
  58. int ret;
  59. if (ddr_enable_4gb) {
  60. ret = ddr_enable_4gb();
  61. ALWAYS_LOG("ddr_enable_4GB sta:%d\n", ret);
  62. return ret;
  63. } else {
  64. ALWAYS_LOG("ddr 4GB disable\n");
  65. return 0;
  66. }
  67. }
  68. /*-------- Register base part -------------------------------*/
  69. /* HW remap for MD1 */
  70. #define MD1_BANK0_MAP0 (0x10001300)
  71. #define MD1_BANK0_MAP1 (0x10001304)
  72. #define MD1_BANK1_MAP0 (0x10001308)
  73. #define MD1_BANK1_MAP1 (0x1000130C)
  74. #define MD1_BANK4_MAP0 (0x10001310)
  75. #define MD1_BANK4_MAP1 (0x10001314)
  76. /* HW remap for MD3(C2K) */
  77. #define MD2_BANK0_MAP0 (0x10001320)
  78. #define MD2_BANK0_MAP1 (0x10001324)
  79. #define MD2_BANK4_MAP0 (0x10001330)
  80. #define MD2_BANK4_MAP1 (0x10001334)
  81. /* HW remap lock register */
  82. #define MD_HW_REMAP_LOCK (0x10001F80)
  83. #define MD1_LOCK (1<<16)
  84. #define MD3_LOCK (1<<17)
  85. static int md_mem_ro_rw_remapping(unsigned int md_id, unsigned int addr)
  86. {
  87. unsigned int md_img_start_addr;
  88. unsigned int hw_remapping_bank0_map0;
  89. unsigned int hw_remapping_bank0_map1 = 0;
  90. unsigned int write_val;
  91. switch (md_id) {
  92. case 0: // MD1
  93. hw_remapping_bank0_map0 = MD1_BANK0_MAP0;
  94. hw_remapping_bank0_map1 = MD1_BANK0_MAP1;
  95. break;
  96. case 2: // MD3
  97. hw_remapping_bank0_map0 = MD2_BANK0_MAP0;
  98. hw_remapping_bank0_map1 = MD2_BANK0_MAP1;
  99. break;
  100. default:
  101. ALWAYS_LOG("Invalid md id:%d\n", md_id);
  102. return -1;
  103. }
  104. if (is_4gb_ddr_support_en()) {
  105. md_img_start_addr = addr & 0xFFFFFFFF;
  106. ALWAYS_LOG("---> Map 0x00000000 to 0x%x for MD%d(4G)\n", addr, md_id+1);
  107. } else {
  108. md_img_start_addr = addr - 0x40000000;
  109. ALWAYS_LOG("---> Map 0x00000000 to 0x%x for MD%d\n", addr, md_id+1);
  110. }
  111. /* For MDx_BANK0_MAP0 */
  112. write_val = (((md_img_start_addr >> 24) | 1) & 0xFF) \
  113. + ((((md_img_start_addr + 0x02000000) >> 16) | 1<<8) & 0xFF00) \
  114. + ((((md_img_start_addr + 0x04000000) >> 8) | 1<<16) & 0xFF0000) \
  115. + ((((md_img_start_addr + 0x06000000) >> 0) | 1<<24) & 0xFF000000);
  116. DRV_WriteReg32(hw_remapping_bank0_map0, write_val);
  117. ALWAYS_LOG("BANK0_MAP0 value:0x%X\n", DRV_Reg32(hw_remapping_bank0_map0));
  118. /* For MDx_BANK0_MAP1 */
  119. write_val = ((((md_img_start_addr + 0x08000000) >> 24) | 1) & 0xFF) \
  120. + ((((md_img_start_addr + 0x0A000000) >> 16) | 1<<8) & 0xFF00) \
  121. + ((((md_img_start_addr + 0x0C000000) >> 8) | 1<<16) & 0xFF0000) \
  122. + ((((md_img_start_addr + 0x0E000000) >> 0) | 1<<24) & 0xFF000000);
  123. DRV_WriteReg32(hw_remapping_bank0_map1, write_val);
  124. ALWAYS_LOG("BANK0_MAP1 value:0x%X\n", DRV_Reg32(hw_remapping_bank0_map1));
  125. #ifdef DUMMY_AP_MODE
  126. /* For 256~512MB */
  127. if (md_id == MD_SYS1) {
  128. /* For MD1_BANK1_MAP0 */
  129. write_val = ((((md_img_start_addr + 0x10000000) >> 24) | 1) & 0xFF) \
  130. + ((((md_img_start_addr + 0x12000000) >> 16) | 1<<8) & 0xFF00) \
  131. + ((((md_img_start_addr + 0x14000000) >> 8) | 1<<16) & 0xFF0000) \
  132. + ((((md_img_start_addr + 0x16000000) >> 0) | 1<<24) & 0xFF000000);
  133. DRV_WriteReg32(MD1_BANK1_MAP0, write_val);
  134. ALWAYS_LOG("BANK1_MAP0 value:0x%X\n", DRV_Reg32(MD1_BANK1_MAP0));
  135. /* For MD1_BANK1_MAP1 */
  136. write_val = ((((md_img_start_addr + 0x18000000) >> 24) | 1) & 0xFF) \
  137. + ((((md_img_start_addr + 0x1A000000) >> 16) | 1<<8) & 0xFF00) \
  138. + ((((md_img_start_addr + 0x1C000000) >> 8) | 1<<16) & 0xFF0000) \
  139. + ((((md_img_start_addr + 0x1E000000) >> 0) | 1<<24) & 0xFF000000);
  140. DRV_WriteReg32(MD1_BANK1_MAP1, write_val);
  141. ALWAYS_LOG("BANK1_MAP1 value:0x%X\n", DRV_Reg32(MD1_BANK1_MAP1));
  142. }
  143. #endif
  144. return 0;
  145. }
  146. static int md_smem_rw_remapping(unsigned int md_id, unsigned int addr)
  147. {
  148. unsigned int md_smem_start_addr;
  149. unsigned int hw_remapping_bank4_map0;
  150. unsigned int hw_remapping_bank4_map1 = 0;
  151. unsigned int write_val;
  152. switch (md_id) {
  153. case 0: // MD1
  154. hw_remapping_bank4_map0 = MD1_BANK4_MAP0;
  155. hw_remapping_bank4_map1 = MD1_BANK4_MAP1;
  156. break;
  157. case 2: // MD3
  158. hw_remapping_bank4_map0 = MD2_BANK4_MAP0;
  159. hw_remapping_bank4_map1 = MD2_BANK4_MAP1;
  160. break;
  161. default:
  162. ALWAYS_LOG("Invalid md id:%d\n", md_id);
  163. return -LD_ERR_PLAT_INVALID_MD_ID;
  164. }
  165. if (is_4gb_ddr_support_en()) {
  166. md_smem_start_addr = addr & 0xFFFFFFFF;
  167. ALWAYS_LOG("---> Map 0x40000000 to 0x%x for MD%d(4G)\n", addr, md_id+1);
  168. } else {
  169. md_smem_start_addr = addr - 0x40000000;
  170. ALWAYS_LOG("---> Map 0x40000000 to 0x%x for MD%d\n", addr, md_id+1);
  171. }
  172. /* For MDx_BANK0_MAP0 */
  173. write_val = (((md_smem_start_addr >> 24) | 1) & 0xFF) \
  174. + ((((md_smem_start_addr + 0x02000000) >> 16) | 1<<8) & 0xFF00) \
  175. + ((((md_smem_start_addr + 0x04000000) >> 8) | 1<<16) & 0xFF0000) \
  176. + ((((md_smem_start_addr + 0x06000000) >> 0) | 1<<24) & 0xFF000000);
  177. DRV_WriteReg32(hw_remapping_bank4_map0, write_val);
  178. ALWAYS_LOG("BANK4_MAP0 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map0));
  179. /* For MDx_BANK0_MAP1 */
  180. write_val = ((((md_smem_start_addr + 0x08000000) >> 24) | 1) & 0xFF) \
  181. + ((((md_smem_start_addr + 0x0A000000) >> 16) | 1<<8) & 0xFF00) \
  182. + ((((md_smem_start_addr + 0x0C000000) >> 8) | 1<<16) & 0xFF0000) \
  183. + ((((md_smem_start_addr + 0x0E000000) >> 0) | 1<<24) & 0xFF000000);
  184. DRV_WriteReg32(hw_remapping_bank4_map1, write_val);
  185. ALWAYS_LOG("BANK4_MAP1 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map1));
  186. return 0;
  187. }
  188. static void md_emi_remapping_lock(unsigned int md_id)
  189. {
  190. unsigned int reg_val;
  191. unsigned int lock_bit;
  192. switch (md_id) {
  193. case 0: // MD1
  194. lock_bit = MD1_LOCK;
  195. break;
  196. case 2: // MD3
  197. lock_bit = MD3_LOCK;
  198. break;
  199. default:
  200. ALWAYS_LOG("Invalid md id:%d for lock\n", md_id);
  201. return;
  202. }
  203. reg_val = DRV_Reg32(MD_HW_REMAP_LOCK);
  204. ALWAYS_LOG("before hw remap lock: MD1[%d], MD3[%d]\n", !!(reg_val&MD1_LOCK), !!(reg_val&MD3_LOCK));
  205. DRV_WriteReg32(MD_HW_REMAP_LOCK, (reg_val|lock_bit));
  206. reg_val = DRV_Reg32(MD_HW_REMAP_LOCK);
  207. ALWAYS_LOG("before hw remap lock: MD1[%d], MD3[%d]\n", !!(reg_val&MD1_LOCK), !!(reg_val&MD3_LOCK));
  208. }
  209. /* =================================================== */
  210. /* MPU Region defination */
  211. /* =================================================== */
  212. /* Note: This structure should sync with Kernel!!!! */
  213. typedef struct _mpu_cfg {
  214. unsigned int start;
  215. unsigned int end;
  216. int region;
  217. unsigned int permission;
  218. int relate_region;
  219. } mpu_cfg_t;
  220. #define MPU_REGION_ID_SEC_OS 0
  221. #define MPU_REGION_ID_ATF 1
  222. /* #define MPU_REGION_ID_MD32_SMEM 2 */
  223. #define MPU_REGION_ID_TRUSTED_UI 3
  224. #define MPU_REGION_ID_MD1_SEC_SMEM 4
  225. #define MPU_REGION_ID_MD1_SMEM 5
  226. #define MPU_REGION_ID_MD3_SMEM 6
  227. #define MPU_REGION_ID_MD1MD3_SMEM 7
  228. #define MPU_REGION_ID_MD1_MCURW_HWRW 8
  229. #define MPU_REGION_ID_MD1_ROM 9 /* contain DSP in Jade */
  230. #define MPU_REGION_ID_MD1_MCURW_HWRO 10
  231. #define MPU_REGION_ID_MD1_MCURO_HWRW 11
  232. #define MPU_REGION_ID_WIFI_EMI_FW 12
  233. #define MPU_REGION_ID_WMT 13
  234. #define MPU_REGION_ID_MD1_RW 14
  235. #define MPU_REGION_ID_MD3_ROM 15
  236. #define MPU_REGION_ID_MD3_RW 16
  237. #define MPU_REGION_ID_RESERVED1 17
  238. #define MPU_REGION_ID_RESERVED2 18
  239. #define MPU_REGION_ID_AP 19
  240. #define MPU_REGION_ID_TOTAL_NUM (MPU_REGION_ID_AP + 1)
  241. #define MPU_MDOMAIN_ID_AP 0
  242. #define MPU_MDOMAIN_ID_MD 1
  243. #define MPU_MDOMAIN_ID_MD3 5
  244. #define MPU_MDOMAIN_ID_MDHW 7
  245. #define MPU_MDOMAIN_ID_TOTAL_NUM 8
  246. static const unsigned int mpu_att_default[MPU_REGION_ID_TOTAL_NUM][MPU_MDOMAIN_ID_TOTAL_NUM] = {
  247. /*===================================================================================================================*/
  248. /* No | | D0(AP) | D1(MD1) | D2(CONN) | D3(Res) | D4(MM) | D5(MD3 ) | D6(MFG) | D7(MDHW) |*/
  249. /*--------------+----------------------------------------------------------------------------------------------------*/
  250. /* 0*/{ SEC_RW , FORBIDDEN , FORBIDDEN , FORBIDDEN, SEC_RW , FORBIDDEN , FORBIDDEN , FORBIDDEN},
  251. /* 1*/{ SEC_RW , FORBIDDEN , FORBIDDEN , FORBIDDEN, FORBIDDEN , FORBIDDEN , FORBIDDEN , FORBIDDEN},
  252. /* 2*/{ SEC_RW , FORBIDDEN , FORBIDDEN , FORBIDDEN, SEC_RW , FORBIDDEN , FORBIDDEN , FORBIDDEN},
  253. /* 3*/{ SEC_RW , FORBIDDEN , FORBIDDEN , FORBIDDEN, SEC_RW , FORBIDDEN , FORBIDDEN , FORBIDDEN},
  254. /* 4*/{ SEC_R_NSEC_R , NO_PROTECTION, FORBIDDEN , FORBIDDEN, FORBIDDEN , NO_PROTECTION, FORBIDDEN , FORBIDDEN},
  255. /* 5*/{ NO_PROTECTION, NO_PROTECTION, FORBIDDEN , FORBIDDEN, FORBIDDEN , FORBIDDEN , FORBIDDEN , FORBIDDEN},
  256. /* 6*/{ NO_PROTECTION, FORBIDDEN , FORBIDDEN , FORBIDDEN, FORBIDDEN , NO_PROTECTION, FORBIDDEN , FORBIDDEN},
  257. /* 7*/{ NO_PROTECTION , NO_PROTECTION, FORBIDDEN , FORBIDDEN, FORBIDDEN , NO_PROTECTION, FORBIDDEN , FORBIDDEN},
  258. /* 8*/{ SEC_R_NSEC_R , NO_PROTECTION, FORBIDDEN , FORBIDDEN, FORBIDDEN , FORBIDDEN , FORBIDDEN, NO_PROTECTION},
  259. /* 9*/{ SEC_R_NSEC_R , SEC_R_NSEC_R , FORBIDDEN , FORBIDDEN, FORBIDDEN , FORBIDDEN , FORBIDDEN, SEC_R_NSEC_R },
  260. /*10*/{ SEC_R_NSEC_R , NO_PROTECTION, FORBIDDEN , FORBIDDEN, FORBIDDEN , FORBIDDEN , FORBIDDEN, SEC_R_NSEC_R },
  261. /*11*/{ SEC_R_NSEC_R , NO_PROTECTION, FORBIDDEN , FORBIDDEN, FORBIDDEN , FORBIDDEN , FORBIDDEN, NO_PROTECTION},
  262. /*12*/{ FORBIDDEN , FORBIDDEN , NO_PROTECTION, FORBIDDEN, FORBIDDEN , FORBIDDEN , FORBIDDEN , FORBIDDEN},
  263. /*13*/{ NO_PROTECTION, FORBIDDEN , NO_PROTECTION, FORBIDDEN, FORBIDDEN , FORBIDDEN , FORBIDDEN , FORBIDDEN},
  264. /*14*/{ SEC_R_NSEC_R , NO_PROTECTION, FORBIDDEN , FORBIDDEN, FORBIDDEN , FORBIDDEN , FORBIDDEN, SEC_R_NSEC_R },
  265. /*15*/{ SEC_R_NSEC_R , FORBIDDEN , FORBIDDEN , FORBIDDEN, FORBIDDEN , SEC_R_NSEC_R , FORBIDDEN , FORBIDDEN},
  266. /*16*/{ SEC_R_NSEC_R , FORBIDDEN , FORBIDDEN , FORBIDDEN, FORBIDDEN , NO_PROTECTION, FORBIDDEN , FORBIDDEN},
  267. /*17*/{ NO_PROTECTION, FORBIDDEN , FORBIDDEN , FORBIDDEN, NO_PROTECTION, FORBIDDEN , NO_PROTECTION, FORBIDDEN},
  268. /*18*/{ NO_PROTECTION, SEC_R_NSEC_R , FORBIDDEN , FORBIDDEN, NO_PROTECTION, FORBIDDEN , NO_PROTECTION, SEC_R_NSEC_R},
  269. }; /*=================================================================================================================*/
  270. static void get_mpu_attr_str(int lock, int curr_attr, char buf[], int size)
  271. {
  272. char ch = lock?'L':'U';
  273. snprintf(buf, 24, "%d-%d-%d-%d-%d-%d-%d-%d(%c)",
  274. curr_attr&7, (curr_attr>>3)&7, (curr_attr>>6)&7, (curr_attr>>9)&7,
  275. (curr_attr>>12)&7, (curr_attr>>15)&7, (curr_attr>>18)&7, (curr_attr>>21)&7, ch);
  276. }
  277. static const unsigned char region_mapping_at_hdr_md1[] = {
  278. MPU_REGION_ID_MD1_ROM, MPU_REGION_ID_MD1_MCURW_HWRO, MPU_REGION_ID_MD1_MCURO_HWRW,
  279. MPU_REGION_ID_MD1_MCURW_HWRW, MPU_REGION_ID_MD1_RW
  280. };
  281. static const int free_mpu_region[] = {MPU_REGION_ID_RESERVED1, MPU_REGION_ID_RESERVED2, -1};
  282. static int curr_free_mpu_idx;
  283. static int get_free_mpu_region(void)
  284. {
  285. int ret;
  286. if (curr_free_mpu_idx < (int)(sizeof(free_mpu_region)/sizeof(int))) {
  287. ret = free_mpu_region[curr_free_mpu_idx];
  288. curr_free_mpu_idx++;
  289. } else
  290. ret = -LD_ERR_PLAT_MPU_REGION_EMPTY;
  291. return ret;
  292. }
  293. static unsigned int get_mpu_region_default_access_att(int region, int lock)
  294. {
  295. return SET_ACCESS_PERMISSON(lock, mpu_att_default[region][7], mpu_att_default[region][6],
  296. mpu_att_default[region][5], mpu_att_default[region][4],
  297. mpu_att_default[region][3], mpu_att_default[region][2],
  298. mpu_att_default[region][1], mpu_att_default[region][0]);
  299. }
  300. static unsigned int mpu_attr_calculate(int region_id, unsigned int request_attr)
  301. {
  302. /* |D0(AP)|D1(MD1)|D2(CONN)|D3(Res)|D4(MM)|D5(MD3)|D6(MFG)|D7(MDHW)*/
  303. unsigned int tmp_mpu_att[8], i;
  304. for (i = 0; i < 8; i++)
  305. tmp_mpu_att[i] = mpu_att_default[region_id][i];
  306. /* AP MD1 MDHW: AP */
  307. if ((request_attr & 0xF) <= FORBIDDEN)
  308. tmp_mpu_att[0] = (request_attr & 0xF);
  309. /* AP MD1 MDHW: MD1 */
  310. request_attr = (request_attr >> 4);
  311. if ((request_attr & 0xF) <= FORBIDDEN)
  312. tmp_mpu_att[1] = (request_attr & 0xF);
  313. /* AP MD1 MDHW: MDHW */
  314. request_attr = (request_attr >> 4);
  315. if ((request_attr & 0xF) <= FORBIDDEN)
  316. tmp_mpu_att[7] = (request_attr & 0xF);
  317. /* MPU_REGION_ID_MD1_MCURO_HWRW can't lock, other region lock OK */
  318. if (region_id != MPU_REGION_ID_MD1_MCURO_HWRW) {
  319. return SET_ACCESS_PERMISSON(1, tmp_mpu_att[7], tmp_mpu_att[6], tmp_mpu_att[5], tmp_mpu_att[4],
  320. tmp_mpu_att[3], tmp_mpu_att[2], tmp_mpu_att[1], tmp_mpu_att[0]);
  321. } else {
  322. return SET_ACCESS_PERMISSON(0, tmp_mpu_att[7], tmp_mpu_att[6], tmp_mpu_att[5], tmp_mpu_att[4],
  323. tmp_mpu_att[3], tmp_mpu_att[2], tmp_mpu_att[1], tmp_mpu_att[0]);
  324. }
  325. }
  326. static void ccci_mem_access_cfg(mpu_cfg_t *mpu_cfg_list, int clear)
  327. {
  328. #ifdef ENABLE_EMI_PROTECTION
  329. mpu_cfg_t *curr;
  330. unsigned int curr_attr;
  331. char buf[24];
  332. if (NULL == mpu_cfg_list)
  333. return;
  334. curr = mpu_cfg_list;
  335. curr_attr = SET_ACCESS_PERMISSON(0, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION,
  336. NO_PROTECTION, NO_PROTECTION, NO_PROTECTION);
  337. while (curr->region != -1) {
  338. if (clear) {
  339. emi_mpu_set_region_protection( 0, /*START_ADDR*/
  340. 0, /*END_ADDR*/
  341. curr->region, /*region*/
  342. curr_attr);
  343. ALWAYS_LOG("Clr MPU:S:0x%x E:0x%x A:<%d>[0~7]%d-%d-%d-%d-%d-%d-%d-%d\n", 0, 0,
  344. curr->region, curr_attr&7, (curr_attr>>3)&7, (curr_attr>>6)&7,
  345. (curr_attr>>9)&7, (curr_attr>>12)&7, (curr_attr>>15)&7,
  346. (curr_attr>>18)&7, (curr_attr>>21)&7);
  347. } else {
  348. emi_mpu_set_region_protection( curr->start, /*START_ADDR*/
  349. curr->end, /*END_ADDR*/
  350. curr->region, /*region*/
  351. curr->permission);
  352. curr_attr = curr->permission;
  353. get_mpu_attr_str(0, curr_attr, buf, 24);
  354. ALWAYS_LOG("Set MPU:S:0x%x E:0x%x A:<%d>[0~7]%s\n", curr->start,
  355. curr->end, curr->region, buf);
  356. }
  357. curr++;
  358. }
  359. #endif
  360. }
  361. /*--------- Implement one by one -------------------------------------------------------------------------------*/
  362. int plat_get_padding_mpu_num(void)
  363. {
  364. return (int)(sizeof(free_mpu_region)/sizeof(unsigned int)) - 1;
  365. }
  366. int plat_dt_reserve_mem_size_fixup(void *fdt)
  367. {
  368. int offset, sub_offset;
  369. /* -------- Remove device tree item ----------------------- */
  370. offset = fdt_path_offset(fdt, "/reserved-memory");
  371. if (offset < 0) {
  372. ALWAYS_LOG("plat_dt_reserve_mem_size_fixup fail\n");
  373. return;
  374. }
  375. sub_offset = fdt_subnode_offset(fdt, offset, "reserve-memory-ccci_md1");
  376. if (sub_offset) {
  377. DT_DBG_LOG("get md1 reserve-mem success. offset: %d, sub_off: %d\n",
  378. offset, sub_offset);
  379. /* kill this node */
  380. fdt_del_node(fdt, sub_offset);
  381. } else
  382. ALWAYS_LOG("ignore md1 reserve-mem.\n");
  383. sub_offset = fdt_subnode_offset(fdt, offset, "reserve-memory-ccci_md3_ccif");
  384. if (sub_offset) {
  385. DT_DBG_LOG("get md3 reserve-mem success. offset: %d, sub_off: %d\n",
  386. offset, sub_offset);
  387. /* kill this node */
  388. fdt_del_node(fdt, sub_offset);
  389. } else
  390. ALWAYS_LOG("ignore md3 reserve-mem.\n");
  391. sub_offset = fdt_subnode_offset(fdt, offset, "reserve-memory-ccci_share");
  392. if (sub_offset) {
  393. DT_DBG_LOG("get ap md reserve-smem szie success. offset: %d, sub_off: %d\n",
  394. offset, sub_offset);
  395. /* kill this node */
  396. fdt_del_node(fdt, sub_offset);
  397. } else
  398. ALWAYS_LOG("ignore reserve-share-mem.\n");
  399. return 0;
  400. }
  401. /*---------------------------------------------------------------------------------------------------*/
  402. /* Global variable for share memory */
  403. /*---------------------------------------------------------------------------------------------------*/
  404. static unsigned int ap_md1_smem_size_at_lk_env;
  405. static unsigned int md1_md3_smem_size_at_lk_env;
  406. static unsigned int ap_md3_smem_size_at_lk_env;
  407. static unsigned int ap_md1_smem_size_at_img;
  408. static unsigned int md1_md3_smem_size_at_img;
  409. static unsigned int ap_md3_smem_size_at_img;
  410. #define AP_MD1_SMEM_SIZE 0x20000 /* 128k */
  411. #define MD1_MD3_SMEM_SIZE 0x60000 /* 384k */
  412. #define AP_MD3_SMEM_SIZE 0xD0000 /* 832k */
  413. #define MAX_SMEM_SIZE 0x8000000/*Change from 6M to 128M,0x600000*/
  414. typedef struct _smem_layout {
  415. unsigned long long base_addr;
  416. unsigned int ap_md1_smem_offset;
  417. unsigned int ap_md1_smem_size;
  418. unsigned int ap_md3_smem_offset;
  419. unsigned int ap_md3_smem_size;
  420. unsigned int md1_md3_smem_offset;
  421. unsigned int md1_md3_smem_size;
  422. unsigned int total_smem_size;
  423. } smem_layout_t;
  424. static smem_layout_t smem_info;
  425. /*---------------------------------------------------------------------------------------------------*/
  426. /* HW remap function implement */
  427. /*---------------------------------------------------------------------------------------------------*/
  428. int plat_apply_hw_remap_for_md_ro_rw(void* info)
  429. {
  430. modem_info_t *md_ld_info = (modem_info_t *)info;
  431. return md_mem_ro_rw_remapping((unsigned int)md_ld_info->md_id, (unsigned int)md_ld_info->base_addr);
  432. }
  433. int plat_apply_hw_remap_for_md_smem(void *addr, int size)
  434. {
  435. /* For share memory final size depends on MD number, just store start address and size
  436. ** actual setting will do later
  437. */
  438. smem_info.base_addr = (unsigned long long)((unsigned long)addr);
  439. return 0;
  440. }
  441. /*---------------------------------------------------------------------------------------------------*/
  442. /* check header info collection by plat_post_hdr_info */
  443. /*---------------------------------------------------------------------------------------------------*/
  444. void plat_post_hdr_info(void* hdr, int ver, int id)
  445. {
  446. if (id == MD_SYS1) {
  447. ap_md1_smem_size_at_img = ((struct md_check_header_v5*)hdr)->ap_md_smem_size;
  448. md1_md3_smem_size_at_img = ((struct md_check_header_v5*)hdr)->md_to_md_smem_size;
  449. } else if (id == MD_SYS3) {
  450. ap_md3_smem_size_at_img = ((struct md_check_header_v1*)hdr)->ap_md_smem_size;
  451. }
  452. }
  453. /*---------------------------------------------------------------------------------------------------*/
  454. /* MPU static global variable and mpu relate function implement */
  455. /*---------------------------------------------------------------------------------------------------*/
  456. #define MPU_REGION_TOTAL_NUM (16) /* = MD1+MD3 */
  457. static mpu_cfg_t mpu_tbl[MPU_REGION_TOTAL_NUM];
  458. static int s_g_curr_mpu_num;
  459. /*
  460. ** if set start=0x0, end=0x10000, the actural protected area will be 0x0-0x1FFFF,
  461. ** here we use 64KB align, MPU actually request 32KB align since MT6582, but this works...
  462. ** we assume emi_mpu_set_region_protection will round end address down to 64KB align.
  463. */
  464. static void dump_received_pure_mpu_setting(struct image_section_desc *mem_info, int item_num)
  465. {
  466. int i;
  467. for (i =0; i < item_num; i++)
  468. MPU_DBG_LOG("mpu sec dec %d: offset:%x, size:%x, mpu_attr:%x, ext_flag:%x, relate_idx:%x\n", i,
  469. mem_info[i].offset, mem_info[i].size, mem_info[i].mpu_attr,
  470. mem_info[i].ext_flag, mem_info[i].relate_idx);
  471. }
  472. static int find_bind_mpu_region(mpu_cfg_t *mpu_tbl_hdr, int item_num, unsigned int bind_key)
  473. {
  474. int i;
  475. for (i = 0; i < item_num; i++) {
  476. if (mpu_tbl_hdr[i].relate_region == (int)bind_key)
  477. return i;
  478. }
  479. return -1;
  480. }
  481. static int md1_mpu_setting_process(void *p_md_ld_info, void *p_mem_info, mpu_cfg_t *mpu_tbl_hdr)
  482. {
  483. modem_info_t *md_ld_info = (modem_info_t *)p_md_ld_info;
  484. struct image_section_desc *mem_info = (struct image_section_desc *)p_mem_info;
  485. int normal_region_num = 0;
  486. int total_region_num = 0;
  487. int curr_idx = 0;
  488. int i;
  489. int had_padding = 0;
  490. int all_range_region_idx = -1;
  491. int bind_idx;
  492. int free_region_id;
  493. /* Calculate mpu num and padding num */
  494. for (i = 0; i < MPU_REGION_TOTAL_NUM; i++) {
  495. if ((mem_info[i].offset == 0) && (mem_info[i].size == 0))
  496. break;
  497. if (mem_info[i].ext_flag & VALID_PADDING)
  498. had_padding = 1;
  499. if (mem_info[i].ext_flag & MD_ALL_RANGE)
  500. all_range_region_idx = i;
  501. }
  502. total_region_num = i;
  503. dump_received_pure_mpu_setting(mem_info, total_region_num);
  504. for (i = 0; i < total_region_num; i++) {
  505. if (mem_info[i].ext_flag & (MD_ALL_RANGE|NEED_REMOVE|NEED_MPU_MORE))
  506. continue;
  507. /* Process normal case first */
  508. if (curr_idx >= (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char))) {
  509. ALWAYS_LOG("[error]md%d: mpu region too more %d\n", md_ld_info->md_id+1,
  510. (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char)));
  511. return -LD_ERR_PLAT_MPU_REGION_TOO_MORE;
  512. }
  513. mpu_tbl_hdr[curr_idx].start = (unsigned int)md_ld_info->base_addr + mem_info[i].offset;
  514. mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + mem_info[i].size;
  515. mpu_tbl_hdr[curr_idx].end = ((mpu_tbl_hdr[curr_idx].end + 0xFFFF)&(~0xFFFF)) - 1;/* 64K align */
  516. mpu_tbl_hdr[curr_idx].permission =
  517. mpu_attr_calculate(region_mapping_at_hdr_md1[curr_idx], mem_info[i].mpu_attr);
  518. mpu_tbl_hdr[curr_idx].region = (int)region_mapping_at_hdr_md1[curr_idx];
  519. mpu_tbl_hdr[curr_idx].relate_region = mem_info[i].relate_idx;
  520. curr_idx++;
  521. normal_region_num++;
  522. }
  523. if (normal_region_num != (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char))) {
  524. ALWAYS_LOG("[error]md%d: mpu region not sync %d:%d\n", md_ld_info->md_id+1, normal_region_num,
  525. (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char)));
  526. return -LD_ERR_PLAT_MPU_REGION_NUM_NOT_SYNC;
  527. }
  528. for (i = 0; i < total_region_num; i++) {
  529. if (mem_info[i].ext_flag & NEED_MPU_MORE) {
  530. bind_idx = find_bind_mpu_region(mpu_tbl_hdr, normal_region_num, mem_info[i].relate_idx);
  531. if (bind_idx >= 0) {
  532. mpu_tbl_hdr[curr_idx].start = (unsigned int)md_ld_info->base_addr + mem_info[i].offset;
  533. mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + mem_info[i].size;
  534. /* 64K align */
  535. mpu_tbl_hdr[curr_idx].end = ((mpu_tbl_hdr[curr_idx].end + 0xFFFF)&(~0xFFFF)) - 1;
  536. mpu_tbl_hdr[curr_idx].permission = mpu_tbl_hdr[bind_idx].permission;
  537. /* setting relate region */
  538. free_region_id = get_free_mpu_region();
  539. if (free_region_id < 0) {
  540. ALWAYS_LOG("[error]abnormal free region id %d +\n", free_region_id);
  541. return -LD_ERR_PLAT_ABNORMAL_FREE_REGION;
  542. }
  543. mpu_tbl_hdr[curr_idx].region = free_region_id;
  544. mpu_tbl_hdr[curr_idx].relate_region = mpu_tbl_hdr[bind_idx].region;
  545. mpu_tbl_hdr[bind_idx].relate_region = free_region_id;
  546. curr_idx++;
  547. } else {
  548. ALWAYS_LOG("md%d: padding array abnormal\n", md_ld_info->md_id+1);
  549. return -LD_ERR_PLAT_ABNORMAL_PAD_ARRAY;
  550. }
  551. }
  552. }
  553. /* Apply MD all range mpu protect setting */
  554. if (had_padding) {
  555. free_region_id = get_free_mpu_region();
  556. if (free_region_id < 0) {
  557. ALWAYS_LOG("[error]no more free region\n");
  558. return -LD_ERR_PLAT_NO_MORE_FREE_REGION;
  559. }
  560. mpu_tbl_hdr[curr_idx].permission = get_mpu_region_default_access_att(free_region_id, 1);
  561. mpu_tbl_hdr[curr_idx].start = (unsigned int)md_ld_info->base_addr + mem_info[all_range_region_idx].offset;
  562. mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + mem_info[all_range_region_idx].size;
  563. /* 64K align */
  564. mpu_tbl_hdr[curr_idx].end = ((mpu_tbl_hdr[curr_idx].end + 0xFFFF)&(~0xFFFF)) - 1;
  565. mpu_tbl_hdr[curr_idx].region = free_region_id;
  566. mpu_tbl_hdr[curr_idx].relate_region = 0;
  567. curr_idx++;
  568. }
  569. return curr_idx;
  570. }
  571. int plat_send_mpu_info_to_platorm(void *p_md_ld_info, void *p_mem_info)
  572. {
  573. modem_info_t *md_ld_info = (modem_info_t *)p_md_ld_info;
  574. struct image_section_desc *mem_info = (struct image_section_desc *)p_mem_info;
  575. int md_id = md_ld_info->md_id;
  576. int ret;
  577. int i;
  578. char buf[24];
  579. if (md_id == MD_SYS1) {
  580. ret = md1_mpu_setting_process(p_md_ld_info, p_mem_info, &mpu_tbl[s_g_curr_mpu_num]);
  581. if (ret > 0)
  582. s_g_curr_mpu_num += ret;
  583. } else if (md_id == MD_SYS3) {
  584. /* RO part */
  585. mpu_tbl[s_g_curr_mpu_num].permission = get_mpu_region_default_access_att(MPU_REGION_ID_MD3_ROM, 1);
  586. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)md_ld_info->base_addr + mem_info[0].offset;
  587. mpu_tbl[s_g_curr_mpu_num].end = mpu_tbl[s_g_curr_mpu_num].start + mem_info[0].size;
  588. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD3_ROM;
  589. /* 64K align */
  590. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  591. s_g_curr_mpu_num++;
  592. /* RW part */
  593. mpu_tbl[s_g_curr_mpu_num].permission = get_mpu_region_default_access_att(MPU_REGION_ID_MD3_RW, 1);
  594. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)md_ld_info->base_addr + mem_info[1].offset;
  595. mpu_tbl[s_g_curr_mpu_num].end = mpu_tbl[s_g_curr_mpu_num].start + mem_info[1].size;
  596. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD3_RW;
  597. /* 64K align */
  598. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  599. s_g_curr_mpu_num++;
  600. }
  601. for (i =0; i < s_g_curr_mpu_num; i++) {
  602. get_mpu_attr_str(0, mpu_tbl[i].permission, buf, 24);
  603. MPU_DBG_LOG("plat mpu dec %d: region:%d[%d], start:0x%x, end:0x%x, attr:%s\n", i,
  604. mpu_tbl[i].region, mpu_tbl[i].relate_region, mpu_tbl[i].start, mpu_tbl[i].end, buf);
  605. }
  606. return 0;
  607. }
  608. /*------------------------------------------------------------------------------------------------*/
  609. /* Suppor function for share memory calculate */
  610. /*------------------------------------------------------------------------------------------------*/
  611. static int cal_share_mem_layout(int load_flag)
  612. {
  613. ap_md1_smem_size_at_lk_env = str2uint(get_env("apmd1_smem"));
  614. md1_md3_smem_size_at_lk_env = str2uint(get_env("md1md3_smem"));
  615. ap_md3_smem_size_at_lk_env = str2uint(get_env("apmd3_smem"));
  616. ALWAYS_LOG("env[apmd1_smem]%x.\n", ap_md1_smem_size_at_lk_env);
  617. ALWAYS_LOG("env[md1md3_smem]%x.\n", md1_md3_smem_size_at_lk_env);
  618. ALWAYS_LOG("env[apmd3_smem]%x.\n", ap_md3_smem_size_at_lk_env);
  619. /* MD Share memory layout */
  620. /* AP <--> MD1 */
  621. /* MD1 <--> MD3 */
  622. /* AP <--> MD3 */
  623. if (load_flag & (1<<MD_SYS3)) {
  624. smem_info.ap_md1_smem_offset = 0;
  625. if (ap_md1_smem_size_at_lk_env)
  626. smem_info.ap_md1_smem_size = ap_md1_smem_size_at_lk_env;
  627. else if (ap_md1_smem_size_at_img)
  628. smem_info.ap_md1_smem_size = ap_md1_smem_size_at_img;
  629. else
  630. smem_info.ap_md1_smem_size = AP_MD1_SMEM_SIZE;
  631. smem_info.md1_md3_smem_offset = (smem_info.ap_md1_smem_offset + smem_info.ap_md1_smem_size + 0x10000 - 1)&(~(0x10000 - 1));
  632. if (md1_md3_smem_size_at_lk_env)
  633. smem_info.md1_md3_smem_size = md1_md3_smem_size_at_lk_env;
  634. else if (md1_md3_smem_size_at_img)
  635. smem_info.md1_md3_smem_size = md1_md3_smem_size_at_img;
  636. else
  637. smem_info.md1_md3_smem_size = MD1_MD3_SMEM_SIZE;
  638. smem_info.ap_md3_smem_offset = smem_info.md1_md3_smem_offset + smem_info.md1_md3_smem_size;
  639. if (ap_md3_smem_size_at_lk_env)
  640. smem_info.ap_md3_smem_size = ap_md3_smem_size_at_lk_env;
  641. else if (ap_md3_smem_size_at_img)
  642. smem_info.ap_md3_smem_size = ap_md3_smem_size_at_img;
  643. else
  644. smem_info.ap_md3_smem_size = AP_MD3_SMEM_SIZE;
  645. smem_info.total_smem_size = smem_info.ap_md3_smem_offset + smem_info.ap_md3_smem_size;
  646. } else {
  647. smem_info.ap_md1_smem_offset = 0;
  648. if (ap_md1_smem_size_at_lk_env)
  649. smem_info.ap_md1_smem_size = ap_md1_smem_size_at_lk_env;
  650. else if (ap_md1_smem_size_at_img)
  651. smem_info.ap_md1_smem_size = ap_md1_smem_size_at_img;
  652. else
  653. smem_info.ap_md1_smem_size = AP_MD1_SMEM_SIZE;
  654. smem_info.md1_md3_smem_offset = 0;
  655. smem_info.md1_md3_smem_size = 0;
  656. smem_info.ap_md3_smem_offset = 0;
  657. smem_info.ap_md3_smem_size = 0;
  658. smem_info.total_smem_size = smem_info.ap_md1_smem_size;
  659. }
  660. /* insert share memory layout to lk info */
  661. if (insert_ccci_tag_inf("smem_layout", (char*)&smem_info, sizeof(smem_layout_t)) < 0)
  662. ALWAYS_LOG("insert smem_layout fail\n");
  663. ALWAYS_LOG("smem_info.base_addr: %x\n", (unsigned int)smem_info.base_addr);
  664. ALWAYS_LOG("smem_info.ap_md1_smem_offset: %x\n", smem_info.ap_md1_smem_offset);
  665. ALWAYS_LOG("smem_info.ap_md1_smem_size: %x\n", smem_info.ap_md1_smem_size);
  666. ALWAYS_LOG("smem_info.ap_md3_smem_offset: %x\n", smem_info.ap_md3_smem_offset);
  667. ALWAYS_LOG("smem_info.ap_md3_smem_size: %x\n", smem_info.ap_md3_smem_size);
  668. ALWAYS_LOG("smem_info.md1_md3_smem_offset: %x\n", smem_info.md1_md3_smem_offset);
  669. ALWAYS_LOG("smem_info.md1_md3_smem_size: %x\n", smem_info.md1_md3_smem_size);
  670. ALWAYS_LOG("smem_info.total_smem_size: %x\n", smem_info.total_smem_size);
  671. return (int)smem_info.total_smem_size;
  672. }
  673. static void boot_to_dummy_ap_mode(int load_md_flag);
  674. /*------------------------------------------------------------------------------------------------*/
  675. /* Note: This function using global variable
  676. ** if set start=0x0, end=0x10000, the actural protected area will be 0x0-0x1FFFF,
  677. ** here we use 64KB align, MPU actually request 32KB align since MT6582, but this works...
  678. ** we assume emi_mpu_set_region_protection will round end address down to 64KB align.
  679. */
  680. int plat_apply_platform_setting(int load_md_flag)
  681. {
  682. int smem_final_size;
  683. #ifdef DUMMY_AP_MODE
  684. /* This function will never return */
  685. boot_to_dummy_ap_mode(load_md_flag);
  686. return 0;
  687. #endif
  688. /* Check loading validation */
  689. if (((load_md_flag & (1<<MD_SYS1)) == 0) && (load_md_flag & (1<<MD_SYS3))) {
  690. ALWAYS_LOG("md3 depends on md1,but md1 not loaded\n");
  691. return -LD_ERR_PLAT_MD1_NOT_RDY;
  692. }
  693. if ((load_md_flag & ((1<<MD_SYS1)|(1<<MD_SYS3))) == 0) {
  694. ALWAYS_LOG("both md1 and md3 not enable\n");
  695. return 0;
  696. }
  697. smem_final_size = cal_share_mem_layout(load_md_flag);
  698. ALWAYS_LOG("ap md1 share mem MPU need configure\n");
  699. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD1_SMEM;
  700. mpu_tbl[s_g_curr_mpu_num].permission = get_mpu_region_default_access_att(MPU_REGION_ID_MD1_SMEM, 0);
  701. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)smem_info.base_addr + smem_info.ap_md1_smem_offset;
  702. mpu_tbl[s_g_curr_mpu_num].end = (unsigned int)smem_info.base_addr + smem_info.ap_md1_smem_offset
  703. + smem_info.ap_md1_smem_size;
  704. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  705. s_g_curr_mpu_num++;
  706. if (load_md_flag & (1<<MD_SYS3)) {
  707. ALWAYS_LOG("md1 md3 share mem MPU need configure\n");
  708. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD1MD3_SMEM;
  709. mpu_tbl[s_g_curr_mpu_num].permission = get_mpu_region_default_access_att(MPU_REGION_ID_MD1MD3_SMEM, 0);
  710. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)smem_info.base_addr + smem_info.md1_md3_smem_offset;
  711. mpu_tbl[s_g_curr_mpu_num].end = (unsigned int)smem_info.base_addr + smem_info.md1_md3_smem_offset
  712. + smem_info.md1_md3_smem_size;
  713. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  714. s_g_curr_mpu_num++;
  715. ALWAYS_LOG("ap md3 share mem MPU need configure\n");
  716. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD3_SMEM;
  717. mpu_tbl[s_g_curr_mpu_num].permission = get_mpu_region_default_access_att(MPU_REGION_ID_MD3_SMEM, 0);
  718. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)smem_info.base_addr + smem_info.ap_md3_smem_offset;
  719. mpu_tbl[s_g_curr_mpu_num].end = (unsigned int)smem_info.base_addr + smem_info.ap_md3_smem_offset
  720. + smem_info.ap_md3_smem_size;
  721. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  722. s_g_curr_mpu_num++;
  723. }
  724. mpu_tbl[s_g_curr_mpu_num].region = -1; /* mark for end */
  725. /* Insert mpu tag info */
  726. if (insert_ccci_tag_inf("md_mpu_inf", (char*)mpu_tbl, sizeof(mpu_cfg_t)*s_g_curr_mpu_num) < 0)
  727. ALWAYS_LOG("insert md_mpu_inf fail\n");
  728. if (insert_ccci_tag_inf("md_mpu_num", (char*)s_g_curr_mpu_num, sizeof(int)) < 0)
  729. ALWAYS_LOG("insert md_mpu_num fail\n");
  730. /* Apply all MPU setting */
  731. ccci_mem_access_cfg(mpu_tbl, 0);
  732. /* Apply share memory HW remap setting and lock it */
  733. if (load_md_flag & (1<<MD_SYS1)) {
  734. md_smem_rw_remapping(MD_SYS1, (unsigned int)(smem_info.base_addr + smem_info.ap_md1_smem_offset));
  735. md_emi_remapping_lock(MD_SYS1);
  736. }
  737. if (load_md_flag & (1<<MD_SYS3)) {
  738. md_smem_rw_remapping(MD_SYS3, (unsigned int)(smem_info.base_addr + smem_info.md1_md3_smem_offset));
  739. md_emi_remapping_lock(MD_SYS3);
  740. }
  741. return smem_final_size;
  742. }
  743. /*------------------------------------------------------------------------------------------------*/
  744. /* platform configure setting info. */
  745. /*------------------------------------------------------------------------------------------------*/
  746. long long plat_ccci_get_ld_md_plat_setting(char cfg_name[])
  747. {
  748. if (strcmp(cfg_name, "share_memory_size") == 0) {
  749. #ifdef DUMMY_AP_MODE
  750. return 0x200000;
  751. #endif
  752. return (long long)(MAX_SMEM_SIZE);
  753. }
  754. if (strcmp(cfg_name, "share_mem_limit") == 0)
  755. return 0xa0000000LL;
  756. if (strcmp(cfg_name, "ro_rw_mem_limit") == 0) {
  757. #ifdef DUMMY_AP_MODE
  758. return 0xa0000000LL;
  759. #endif
  760. return 0xa0000000LL;
  761. }
  762. if (strcmp(cfg_name, "ro_rw_mem_align") == 0)
  763. return 0x2000000LL;
  764. if (strcmp(cfg_name, "share_mem_align") == 0)
  765. return 0x2000000LL;
  766. if (strcmp(cfg_name, "ld_version") == 0) {
  767. #ifdef DUMMY_AP_MODE
  768. return 0x10001;
  769. #endif
  770. return 0x10000;/* xxxx_yyyy, xxxx: main id, yyyy sub id */
  771. }
  772. return -1LL;
  773. }
  774. #ifdef DUMMY_AP_MODE
  775. #include <platform/mt_irq.h>
  776. extern void dummy_ap_boot_up_md(int md_en_flag);
  777. extern void load_modem_image(void);
  778. extern int dummy_ap_irq_helper(unsigned int);
  779. /* Remember add this function to file platform.c(platform code) */
  780. void dummy_ap_entry(void)
  781. {
  782. load_modem_image();
  783. }
  784. /* Remember add this function to file interrupts.c(platform code) */
  785. void dummy_ap_irq_handler(unsigned int irq)
  786. {
  787. if (dummy_ap_irq_helper(irq)) {
  788. mt_irq_ack(irq);
  789. mt_irq_unmask(irq);
  790. }
  791. }
  792. void boot_to_dummy_ap_mode(int load_md_flag)
  793. {
  794. md_smem_rw_remapping(MD_SYS1, (unsigned int)smem_info.base_addr);
  795. md_smem_rw_remapping(MD_SYS3, (unsigned int)smem_info.base_addr);
  796. /* Before boot dummy AP, clear share memory */
  797. memset((void*)((unsigned long)smem_info.base_addr), 0, 0x200000);
  798. dummy_ap_boot_up_md(load_md_flag);
  799. }
  800. #endif