ccci_lk_load_img_plat.c 43 KB

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