ccci_lk_load_img_plat.c 42 KB

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