ccci_lk_load_img_plat.c 55 KB

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