ccci_lk_load_img_plat.c 52 KB

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