ccci_lk_load_img_plat.c 53 KB

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